Merge branch 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 31 Jan 2013 06:10:36 +0000 (17:10 +1100)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 31 Jan 2013 06:10:36 +0000 (17:10 +1100)
Pull x86 EFI fixes from Peter Anvin:
 "This is a collection of fixes for the EFI support.  The controversial
  bit here is a set of patches which bumps the boot protocol version as
  part of fixing some serious problems with the EFI handover protocol,
  used when booting under EFI using a bootloader as opposed to directly
  from EFI.  These changes should also make it a lot saner to support
  cross-mode 32/64-bit EFI booting in the future.  Getting these changes
  into 3.8 means we avoid presenting an inconsistent ABI to bootloaders.

  Other changes are display detection and fixing efivarfs."

* 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86, efi: remove attribute check from setup_efi_pci
  x86, build: Dynamically find entry points in compressed startup code
  x86, efi: Fix PCI ROM handing in EFI boot stub, in 32-bit mode
  x86, efi: Fix 32-bit EFI handover protocol entry point
  x86, efi: Fix display detection in EFI boot stub
  x86, boot: Define the 2.12 bzImage boot protocol
  x86/boot: Fix minor fd leakage in tools/relocs.c
  x86, efi: Set runtime_version to the EFI spec revision
  x86, efi: fix 32-bit warnings in setup_efi_pci()
  efivarfs: Delete dentry from dcache in efivarfs_file_write()
  efivarfs: Never return ENOENT from firmware
  efi, x86: Pass a proper identity mapping in efi_call_phys_prelog
  efivarfs: Drop link count of the right inode

207 files changed:
Documentation/device-mapper/dm-raid.txt
MAINTAINERS
arch/powerpc/kernel/entry_32.S
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/kgdb.c
arch/powerpc/kernel/time.c
arch/powerpc/oprofile/op_model_power4.c
arch/powerpc/platforms/pasemi/cpufreq.c
arch/s390/include/asm/pgtable.h
arch/x86/Kconfig
arch/x86/include/asm/efi.h
arch/x86/include/asm/uv/uv.h
arch/x86/kernel/entry_64.S
arch/x86/kernel/head_32.S
arch/x86/kernel/msr.c
arch/x86/kernel/pci-dma.c
arch/x86/kernel/reboot.c
arch/x86/kernel/setup.c
arch/x86/platform/efi/efi.c
arch/x86/platform/uv/tlb_uv.c
drivers/acpi/osl.c
drivers/bluetooth/ath3k.c
drivers/bluetooth/btusb.c
drivers/edac/edac_mc.c
drivers/edac/edac_pci_sysfs.c
drivers/firmware/dmi_scan.c
drivers/firmware/efivars.c
drivers/firmware/iscsi_ibft_find.c
drivers/gpu/drm/exynos/Kconfig
drivers/gpu/drm/exynos/exynos_drm_connector.c
drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
drivers/gpu/drm/exynos/exynos_drm_drv.h
drivers/gpu/drm/exynos/exynos_drm_g2d.c
drivers/gpu/drm/exynos/exynos_drm_hdmi.c
drivers/gpu/drm/exynos/exynos_drm_hdmi.h
drivers/gpu/drm/exynos/exynos_drm_ipp.c
drivers/gpu/drm/exynos/exynos_drm_rotator.c
drivers/gpu/drm/exynos/exynos_drm_vidi.c
drivers/gpu/drm/exynos/exynos_hdmi.c
drivers/gpu/drm/exynos/exynos_mixer.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/radeon/ni.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/radeon_cs.c
drivers/gpu/drm/radeon/radeon_cursor.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/iommu/amd_iommu_init.c
drivers/iommu/intel-iommu.c
drivers/isdn/gigaset/capi.c
drivers/md/dm-raid.c
drivers/mfd/Kconfig
drivers/mfd/ab8500-core.c
drivers/mfd/arizona-core.c
drivers/mfd/arizona-irq.c
drivers/mfd/da9052-i2c.c
drivers/mfd/db8500-prcmu.c
drivers/mfd/max77686.c
drivers/mfd/max77693.c
drivers/mfd/pcf50633-core.c
drivers/mfd/rtl8411.c
drivers/mfd/rts5209.c
drivers/mfd/rts5229.c
drivers/mfd/rtsx_pcr.c
drivers/mfd/tc3589x.c
drivers/mfd/twl4030-power.c
drivers/mfd/vexpress-config.c
drivers/mfd/wm5102-tables.c
drivers/mmc/host/rtsx_pci_sdmmc.c
drivers/net/can/c_can/c_can.c
drivers/net/can/pch_can.c
drivers/net/can/ti_hecc.c
drivers/net/ethernet/3com/3c574_cs.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/calxeda/xgmac.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
drivers/net/ethernet/intel/ixgbe/Makefile
drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c
drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
drivers/net/ethernet/mellanox/mlx4/en_tx.c
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
drivers/net/ethernet/realtek/r8169.c
drivers/net/hyperv/hyperv_net.h
drivers/net/hyperv/netvsc_drv.c
drivers/net/loopback.c
drivers/net/macvlan.c
drivers/net/phy/icplus.c
drivers/net/phy/marvell.c
drivers/net/tun.c
drivers/net/usb/cdc_mbim.c
drivers/net/usb/cdc_ncm.c
drivers/net/usb/dm9601.c
drivers/net/usb/qmi_wwan.c
drivers/net/usb/usbnet.c
drivers/net/virtio_net.c
drivers/net/wireless/ath/ath9k/ar9003_calib.c
drivers/net/wireless/ath/ath9k/ar9003_phy.c
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/beacon.c
drivers/net/wireless/ath/ath9k/debug.c
drivers/net/wireless/ath/ath9k/debug.h
drivers/net/wireless/ath/ath9k/htc_hst.c
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
drivers/net/wireless/iwlegacy/common.c
drivers/net/wireless/iwlwifi/dvm/tx.c
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/pcie.c
drivers/net/wireless/mwifiex/sta_ioctl.c
drivers/net/wireless/rtlwifi/Kconfig
drivers/pinctrl/Kconfig
drivers/pinctrl/mvebu/pinctrl-dove.c
drivers/pinctrl/mvebu/pinctrl-kirkwood.c
drivers/pinctrl/pinctrl-exynos5440.c
drivers/pinctrl/pinctrl-mxs.c
drivers/pinctrl/pinctrl-nomadik.c
drivers/pinctrl/pinctrl-single.c
drivers/platform/x86/ibm_rtl.c
drivers/platform/x86/samsung-laptop.c
drivers/regulator/dbx500-prcmu.c
drivers/regulator/tps80031-regulator.c
drivers/scsi/isci/init.c
fs/gfs2/lock_dlm.c
fs/xfs/xfs_aops.c
fs/xfs/xfs_bmap.c
fs/xfs/xfs_buf.c
fs/xfs/xfs_buf_item.c
fs/xfs/xfs_dfrag.c
fs/xfs/xfs_iomap.c
fs/xfs/xfs_mount.c
fs/xfs/xfs_trace.h
include/linux/efi.h
include/linux/mfd/abx500.h
include/linux/mfd/abx500/ab8500-bm.h
include/linux/mfd/da9052/da9052.h
include/linux/mfd/da9052/reg.h
include/linux/mfd/rtsx_common.h
include/linux/mfd/rtsx_pci.h
include/linux/security.h
include/linux/usb/usbnet.h
include/net/ip.h
include/net/netfilter/nf_conntrack_core.h
init/main.c
kernel/printk.c
kernel/smp.c
net/batman-adv/distributed-arp-table.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/hidp/core.c
net/bluetooth/l2cap_core.c
net/bluetooth/sco.c
net/core/request_sock.c
net/core/scm.c
net/core/skbuff.c
net/ipv4/ah4.c
net/ipv4/datagram.c
net/ipv4/esp4.c
net/ipv4/ip_gre.c
net/ipv4/ipcomp.c
net/ipv4/ping.c
net/ipv4/raw.c
net/ipv4/route.c
net/ipv4/tcp_ipv4.c
net/ipv4/udp.c
net/ipv6/ah6.c
net/ipv6/esp6.c
net/ipv6/icmp.c
net/ipv6/ip6_output.c
net/ipv6/ip6mr.c
net/mac80211/cfg.c
net/mac80211/ieee80211_i.h
net/mac80211/mesh_hwmp.c
net/mac80211/offchannel.c
net/mac80211/scan.c
net/mac80211/tx.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_standalone.c
net/netfilter/x_tables.c
net/netfilter/xt_CT.c
net/sctp/outqueue.c
net/sctp/sm_statefuns.c
net/sctp/sysctl.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_replay.c
security/capability.c
security/security.c
security/selinux/hooks.c
security/selinux/include/classmap.h
security/selinux/include/objsec.h
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_realtek.c
sound/soc/codecs/arizona.c
sound/soc/codecs/wm2200.c
sound/soc/codecs/wm5102.c
sound/soc/codecs/wm5110.c
sound/soc/codecs/wm_adsp.c
sound/soc/fsl/Kconfig
sound/soc/fsl/Makefile
sound/soc/fsl/imx-pcm.c
sound/soc/soc-dapm.c
sound/usb/mixer.c

index 728c38c242d631b88117958360c6f8441a72be4b..56fb62b09fc59ad757fc81de6ad6e478b3b0184b 100644 (file)
@@ -141,3 +141,4 @@ Version History
 1.2.0  Handle creation of arrays that contain failed devices.
 1.3.0  Added support for RAID 10
 1.3.1  Allow device replacement/rebuild for RAID 10
+1.3.2   Fix/improve redundancy checking for RAID10
index 8ae709e34523c4eb25c7cde1e4e4a9afb7e9704d..212c255b93472ada8cba2016b014eea3b7aa8369 100644 (file)
@@ -2966,7 +2966,7 @@ S:        Maintained
 F:     drivers/net/ethernet/i825xx/eexpress.*
 
 ETHERNET BRIDGE
-M:     Stephen Hemminger <shemminger@vyatta.com>
+M:     Stephen Hemminger <stephen@networkplumber.org>
 L:     bridge@lists.linux-foundation.org
 L:     netdev@vger.kernel.org
 W:     http://www.linuxfoundation.org/en/Net:Bridge
@@ -4905,7 +4905,7 @@ S:        Maintained
 
 MARVELL GIGABIT ETHERNET DRIVERS (skge/sky2)
 M:     Mirko Lindner <mlindner@marvell.com>
-M:     Stephen Hemminger <shemminger@vyatta.com>
+M:     Stephen Hemminger <stephen@networkplumber.org>
 L:     netdev@vger.kernel.org
 S:     Maintained
 F:     drivers/net/ethernet/marvell/sk*
@@ -5180,7 +5180,7 @@ S:        Supported
 F:     drivers/infiniband/hw/nes/
 
 NETEM NETWORK EMULATOR
-M:     Stephen Hemminger <shemminger@vyatta.com>
+M:     Stephen Hemminger <stephen@networkplumber.org>
 L:     netem@lists.linux-foundation.org
 S:     Maintained
 F:     net/sched/sch_netem.c
@@ -7088,7 +7088,7 @@ F:        include/uapi/sound/
 F:     sound/
 
 SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC)
-M:     Liam Girdwood <lrg@ti.com>
+M:     Liam Girdwood <lgirdwood@gmail.com>
 M:     Mark Brown <broonie@opensource.wolfsonmicro.com>
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
 L:     alsa-devel@alsa-project.org (moderated for non-subscribers)
index d22e73e4618b7924879517f1f59cb99dcd63b43e..e514de57a125333a4ce174cb399070b6cc62e3b4 100644 (file)
@@ -439,6 +439,8 @@ ret_from_fork:
 ret_from_kernel_thread:
        REST_NVGPRS(r1)
        bl      schedule_tail
+       li      r3,0
+       stw     r3,0(r1)
        mtlr    r14
        mr      r3,r15
        PPC440EP_ERR42
index b310a0573625dec8a672c267ab6158f8e90b37a6..3d990d3bd8baf5923d019208f7782d42e7f8a458 100644 (file)
@@ -664,6 +664,19 @@ resume_kernel:
        ld      r4,TI_FLAGS(r9)
        andi.   r0,r4,_TIF_NEED_RESCHED
        bne     1b
+
+       /*
+        * arch_local_irq_restore() from preempt_schedule_irq above may
+        * enable hard interrupt but we really should disable interrupts
+        * when we return from the interrupt, and so that we don't get
+        * interrupted after loading SRR0/1.
+        */
+#ifdef CONFIG_PPC_BOOK3E
+       wrteei  0
+#else
+       ld      r10,PACAKMSR(r13) /* Get kernel MSR without EE */
+       mtmsrd  r10,1             /* Update machine state */
+#endif /* CONFIG_PPC_BOOK3E */
 #endif /* CONFIG_PREEMPT */
 
        .globl  fast_exc_return_irq
index c470a40b29f5d4937883cfcd8a40dd1c6bbdcfd1..a7bc7521c0645c6eb697308f039fb74eaad6b4af 100644 (file)
@@ -154,12 +154,12 @@ static int kgdb_handle_breakpoint(struct pt_regs *regs)
 static int kgdb_singlestep(struct pt_regs *regs)
 {
        struct thread_info *thread_info, *exception_thread_info;
-       struct thread_info *backup_current_thread_info = \
-               (struct thread_info *)kmalloc(sizeof(struct thread_info), GFP_KERNEL);
+       struct thread_info *backup_current_thread_info;
 
        if (user_mode(regs))
                return 0;
 
+       backup_current_thread_info = (struct thread_info *)kmalloc(sizeof(struct thread_info), GFP_KERNEL);
        /*
         * On Book E and perhaps other processors, singlestep is handled on
         * the critical exception stack.  This causes current_thread_info()
@@ -185,6 +185,7 @@ static int kgdb_singlestep(struct pt_regs *regs)
                /* Restore current_thread_info lastly. */
                memcpy(exception_thread_info, backup_current_thread_info, sizeof *thread_info);
 
+       kfree(backup_current_thread_info);
        return 1;
 }
 
index 6f6b1cccc91662037115e69dc072ac1f7a376be5..127361e093f49931a87f3fdbc8cad4c88eae5679 100644 (file)
@@ -494,10 +494,15 @@ void timer_interrupt(struct pt_regs * regs)
        set_dec(DECREMENTER_MAX);
 
        /* Some implementations of hotplug will get timer interrupts while
-        * offline, just ignore these
+        * offline, just ignore these and we also need to set
+        * decrementers_next_tb as MAX to make sure __check_irq_replay
+        * don't replay timer interrupt when return, otherwise we'll trap
+        * here infinitely :(
         */
-       if (!cpu_online(smp_processor_id()))
+       if (!cpu_online(smp_processor_id())) {
+               *next_tb = ~(u64)0;
                return;
+       }
 
        /* Conditionally hard-enable interrupts now that the DEC has been
         * bumped to its maximum value
index 315f9495e9b2b5aa42a6c9aaba5a6307ac03ddde..f444b94935f560f6a7abf1a1de46d88cd32e71d5 100644 (file)
@@ -52,7 +52,7 @@ static int power7_marked_instr_event(u64 mmcr1)
        for (pmc = 0; pmc < 4; pmc++) {
                psel = mmcr1 & (OPROFILE_PM_PMCSEL_MSK
                                << (OPROFILE_MAX_PMC_NUM - pmc)
-                               * OPROFILE_MAX_PMC_NUM);
+                               * OPROFILE_PMSEL_FIELD_WIDTH);
                psel = (psel >> ((OPROFILE_MAX_PMC_NUM - pmc)
                                 * OPROFILE_PMSEL_FIELD_WIDTH)) & ~1ULL;
                unit = mmcr1 & (OPROFILE_PM_UNIT_MSK
index 95d00173029f52c498902a586a24917f09e99d4b..890f30e70f98fc52a39f063172cfbadc5e8713b4 100644 (file)
@@ -236,6 +236,13 @@ out:
 
 static int pas_cpufreq_cpu_exit(struct cpufreq_policy *policy)
 {
+       /*
+        * We don't support CPU hotplug. Don't unmap after the system
+        * has already made it to a running state.
+        */
+       if (system_state != SYSTEM_BOOTING)
+               return 0;
+
        if (sdcasr_mapbase)
                iounmap(sdcasr_mapbase);
        if (sdcpwr_mapbase)
index c1d7930a82f4527657fa6eda9501dae446c164a9..098adbb62660be234d4d2ed5171d5c0615027f31 100644 (file)
@@ -1365,6 +1365,18 @@ static inline void pmdp_invalidate(struct vm_area_struct *vma,
        __pmd_idte(address, pmdp);
 }
 
+#define __HAVE_ARCH_PMDP_SET_WRPROTECT
+static inline void pmdp_set_wrprotect(struct mm_struct *mm,
+                                     unsigned long address, pmd_t *pmdp)
+{
+       pmd_t pmd = *pmdp;
+
+       if (pmd_write(pmd)) {
+               __pmd_idte(address, pmdp);
+               set_pmd_at(mm, address, pmdp, pmd_wrprotect(pmd));
+       }
+}
+
 static inline pmd_t mk_pmd_phys(unsigned long physpage, pgprot_t pgprot)
 {
        pmd_t __pmd;
index 79795af598105e9998f0de234b279fb6c61ca42f..225543bf45a5ca551f9609b18cf8711f729f71e7 100644 (file)
@@ -2138,6 +2138,7 @@ config OLPC_XO1_RTC
 config OLPC_XO1_SCI
        bool "OLPC XO-1 SCI extras"
        depends on OLPC && OLPC_XO1_PM
+       depends on INPUT=y
        select POWER_SUPPLY
        select GPIO_CS5535
        select MFD_CORE
index 6e8fdf5ad1135c0100c8b7a5220bb79db2359ddb..28677c55113f8cea59e59c67e7cd53cfcd615b6d 100644 (file)
@@ -94,6 +94,7 @@ extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size,
 #endif /* CONFIG_X86_32 */
 
 extern int add_efi_memmap;
+extern unsigned long x86_efi_facility;
 extern void efi_set_executable(efi_memory_desc_t *md, bool executable);
 extern int efi_memblock_x86_reserve_range(void);
 extern void efi_call_phys_prelog(void);
index b47c2a82ff1546a7efcd77a820a990d1e08bef00..062921ef34e9136100d3b4820826642dd45f223b 100644 (file)
@@ -16,7 +16,7 @@ extern void uv_system_init(void);
 extern const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
                                                 struct mm_struct *mm,
                                                 unsigned long start,
-                                                unsigned end,
+                                                unsigned long end,
                                                 unsigned int cpu);
 
 #else  /* X86_UV */
index 07a7a04529bc5d7849ffc21b79819edd7b23ffd9..cb3c591339aa3d4242e420d181b83f3a62ced2c3 100644 (file)
@@ -1781,6 +1781,7 @@ first_nmi:
         * Leave room for the "copied" frame
         */
        subq $(5*8), %rsp
+       CFI_ADJUST_CFA_OFFSET 5*8
 
        /* Copy the stack frame to the Saved frame */
        .rept 5
@@ -1863,10 +1864,8 @@ end_repeat_nmi:
 nmi_swapgs:
        SWAPGS_UNSAFE_STACK
 nmi_restore:
-       RESTORE_ALL 8
-
-       /* Pop the extra iret frame */
-       addq $(5*8), %rsp
+       /* Pop the extra iret frame at once */
+       RESTORE_ALL 6*8
 
        /* Clear the NMI executing stack variable */
        movq $0, 5*8(%rsp)
index 8e7f6556028f7ff50d90c73eac405d3cdcb7b881..c8932c79e78bbaad99c4969a1ea1a0ff2f7f1802 100644 (file)
@@ -300,6 +300,12 @@ ENTRY(startup_32_smp)
        leal -__PAGE_OFFSET(%ecx),%esp
 
 default_entry:
+#define CR0_STATE      (X86_CR0_PE | X86_CR0_MP | X86_CR0_ET | \
+                        X86_CR0_NE | X86_CR0_WP | X86_CR0_AM | \
+                        X86_CR0_PG)
+       movl $(CR0_STATE & ~X86_CR0_PG),%eax
+       movl %eax,%cr0
+
 /*
  *     New page tables may be in 4Mbyte page mode and may
  *     be using the global pages. 
@@ -364,8 +370,7 @@ default_entry:
  */
        movl $pa(initial_page_table), %eax
        movl %eax,%cr3          /* set the page table pointer.. */
-       movl %cr0,%eax
-       orl  $X86_CR0_PG,%eax
+       movl $CR0_STATE,%eax
        movl %eax,%cr0          /* ..and set paging (PG) bit */
        ljmp $__BOOT_CS,$1f     /* Clear prefetch and normalize %eip */
 1:
index a7c5661f84962a2f6eb80509c1791392352a6fc8..4929502c1372db979d7e1b176b22a9981e8ec96e 100644 (file)
@@ -174,6 +174,9 @@ static int msr_open(struct inode *inode, struct file *file)
        unsigned int cpu;
        struct cpuinfo_x86 *c;
 
+       if (!capable(CAP_SYS_RAWIO))
+               return -EPERM;
+
        cpu = iminor(file->f_path.dentry->d_inode);
        if (cpu >= nr_cpu_ids || !cpu_online(cpu))
                return -ENXIO;  /* No such CPU */
index 0f5dec5c80e0fccbba37474463e724970503faf2..872079a67e4d262151dfdbe74f537033be5ebcc0 100644 (file)
@@ -56,7 +56,7 @@ struct device x86_dma_fallback_dev = {
 EXPORT_SYMBOL(x86_dma_fallback_dev);
 
 /* Number of entries preallocated for DMA-API debugging */
-#define PREALLOC_DMA_DEBUG_ENTRIES       32768
+#define PREALLOC_DMA_DEBUG_ENTRIES       65536
 
 int dma_set_mask(struct device *dev, u64 mask)
 {
index 4e8ba39eaf0fd93cbca557eaecf3efcd954ee05b..76fa1e9a2b39399b1944e4a13c68a054c9a5c386 100644 (file)
@@ -584,7 +584,7 @@ static void native_machine_emergency_restart(void)
                        break;
 
                case BOOT_EFI:
-                       if (efi_enabled)
+                       if (efi_enabled(EFI_RUNTIME_SERVICES))
                                efi.reset_system(reboot_mode ?
                                                 EFI_RESET_WARM :
                                                 EFI_RESET_COLD,
index 00f6c1472b850472e5f9759dd5ad9613f6c026be..8b24289cc10c0f2239623918e587810b81c43c9b 100644 (file)
@@ -807,15 +807,15 @@ void __init setup_arch(char **cmdline_p)
 #ifdef CONFIG_EFI
        if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature,
                     "EL32", 4)) {
-               efi_enabled = 1;
-               efi_64bit = false;
+               set_bit(EFI_BOOT, &x86_efi_facility);
        } else if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature,
                     "EL64", 4)) {
-               efi_enabled = 1;
-               efi_64bit = true;
+               set_bit(EFI_BOOT, &x86_efi_facility);
+               set_bit(EFI_64BIT, &x86_efi_facility);
        }
-       if (efi_enabled && efi_memblock_x86_reserve_range())
-               efi_enabled = 0;
+
+       if (efi_enabled(EFI_BOOT))
+               efi_memblock_x86_reserve_range();
 #endif
 
        x86_init.oem.arch_setup();
@@ -888,7 +888,7 @@ void __init setup_arch(char **cmdline_p)
 
        finish_e820_parsing();
 
-       if (efi_enabled)
+       if (efi_enabled(EFI_BOOT))
                efi_init();
 
        dmi_scan_machine();
@@ -971,7 +971,7 @@ void __init setup_arch(char **cmdline_p)
         * The EFI specification says that boot service code won't be called
         * after ExitBootServices(). This is, in fact, a lie.
         */
-       if (efi_enabled)
+       if (efi_enabled(EFI_MEMMAP))
                efi_reserve_boot_services();
 
        /* preallocate 4k for mptable mpc */
@@ -1114,7 +1114,7 @@ void __init setup_arch(char **cmdline_p)
 
 #ifdef CONFIG_VT
 #if defined(CONFIG_VGA_CONSOLE)
-       if (!efi_enabled || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY))
+       if (!efi_enabled(EFI_BOOT) || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY))
                conswitchp = &vga_con;
 #elif defined(CONFIG_DUMMY_CONSOLE)
        conswitchp = &dummy_con;
@@ -1131,14 +1131,14 @@ void __init setup_arch(char **cmdline_p)
        register_refined_jiffies(CLOCK_TICK_RATE);
 
 #ifdef CONFIG_EFI
-       /* Once setup is done above, disable efi_enabled on mismatched
-        * firmware/kernel archtectures since there is no support for
-        * runtime services.
+       /* Once setup is done above, unmap the EFI memory map on
+        * mismatched firmware/kernel archtectures since there is no
+        * support for runtime services.
         */
-       if (efi_enabled && IS_ENABLED(CONFIG_X86_64) != efi_64bit) {
+       if (efi_enabled(EFI_BOOT) &&
+           IS_ENABLED(CONFIG_X86_64) != efi_enabled(EFI_64BIT)) {
                pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n");
                efi_unmap_memmap();
-               efi_enabled = 0;
        }
 #endif
 }
index 35682489f6d6672025b349d5c0126a3a0611d719..77cf0090c0a3ef7890ea24d4e5e47d1d68e0b024 100644 (file)
@@ -51,9 +51,6 @@
 
 #define EFI_DEBUG      1
 
-int efi_enabled;
-EXPORT_SYMBOL(efi_enabled);
-
 struct efi __read_mostly efi = {
        .mps        = EFI_INVALID_TABLE_ADDR,
        .acpi       = EFI_INVALID_TABLE_ADDR,
@@ -69,19 +66,28 @@ EXPORT_SYMBOL(efi);
 
 struct efi_memory_map memmap;
 
-bool efi_64bit;
-
 static struct efi efi_phys __initdata;
 static efi_system_table_t efi_systab __initdata;
 
 static inline bool efi_is_native(void)
 {
-       return IS_ENABLED(CONFIG_X86_64) == efi_64bit;
+       return IS_ENABLED(CONFIG_X86_64) == efi_enabled(EFI_64BIT);
+}
+
+unsigned long x86_efi_facility;
+
+/*
+ * Returns 1 if 'facility' is enabled, 0 otherwise.
+ */
+int efi_enabled(int facility)
+{
+       return test_bit(facility, &x86_efi_facility) != 0;
 }
+EXPORT_SYMBOL(efi_enabled);
 
 static int __init setup_noefi(char *arg)
 {
-       efi_enabled = 0;
+       clear_bit(EFI_BOOT, &x86_efi_facility);
        return 0;
 }
 early_param("noefi", setup_noefi);
@@ -426,6 +432,7 @@ void __init efi_reserve_boot_services(void)
 
 void __init efi_unmap_memmap(void)
 {
+       clear_bit(EFI_MEMMAP, &x86_efi_facility);
        if (memmap.map) {
                early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size);
                memmap.map = NULL;
@@ -460,7 +467,7 @@ void __init efi_free_boot_services(void)
 
 static int __init efi_systab_init(void *phys)
 {
-       if (efi_64bit) {
+       if (efi_enabled(EFI_64BIT)) {
                efi_system_table_64_t *systab64;
                u64 tmp = 0;
 
@@ -552,7 +559,7 @@ static int __init efi_config_init(u64 tables, int nr_tables)
        void *config_tables, *tablep;
        int i, sz;
 
-       if (efi_64bit)
+       if (efi_enabled(EFI_64BIT))
                sz = sizeof(efi_config_table_64_t);
        else
                sz = sizeof(efi_config_table_32_t);
@@ -572,7 +579,7 @@ static int __init efi_config_init(u64 tables, int nr_tables)
                efi_guid_t guid;
                unsigned long table;
 
-               if (efi_64bit) {
+               if (efi_enabled(EFI_64BIT)) {
                        u64 table64;
                        guid = ((efi_config_table_64_t *)tablep)->guid;
                        table64 = ((efi_config_table_64_t *)tablep)->table;
@@ -684,7 +691,6 @@ void __init efi_init(void)
        if (boot_params.efi_info.efi_systab_hi ||
            boot_params.efi_info.efi_memmap_hi) {
                pr_info("Table located above 4GB, disabling EFI.\n");
-               efi_enabled = 0;
                return;
        }
        efi_phys.systab = (efi_system_table_t *)boot_params.efi_info.efi_systab;
@@ -694,10 +700,10 @@ void __init efi_init(void)
                          ((__u64)boot_params.efi_info.efi_systab_hi<<32));
 #endif
 
-       if (efi_systab_init(efi_phys.systab)) {
-               efi_enabled = 0;
+       if (efi_systab_init(efi_phys.systab))
                return;
-       }
+
+       set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility);
 
        /*
         * Show what we know for posterity
@@ -715,10 +721,10 @@ void __init efi_init(void)
                efi.systab->hdr.revision >> 16,
                efi.systab->hdr.revision & 0xffff, vendor);
 
-       if (efi_config_init(efi.systab->tables, efi.systab->nr_tables)) {
-               efi_enabled = 0;
+       if (efi_config_init(efi.systab->tables, efi.systab->nr_tables))
                return;
-       }
+
+       set_bit(EFI_CONFIG_TABLES, &x86_efi_facility);
 
        /*
         * Note: We currently don't support runtime services on an EFI
@@ -727,15 +733,17 @@ void __init efi_init(void)
 
        if (!efi_is_native())
                pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n");
-       else if (efi_runtime_init()) {
-               efi_enabled = 0;
-               return;
+       else {
+               if (efi_runtime_init())
+                       return;
+               set_bit(EFI_RUNTIME_SERVICES, &x86_efi_facility);
        }
 
-       if (efi_memmap_init()) {
-               efi_enabled = 0;
+       if (efi_memmap_init())
                return;
-       }
+
+       set_bit(EFI_MEMMAP, &x86_efi_facility);
+
 #ifdef CONFIG_X86_32
        if (efi_is_native()) {
                x86_platform.get_wallclock = efi_get_time;
@@ -969,6 +977,9 @@ u32 efi_mem_type(unsigned long phys_addr)
        efi_memory_desc_t *md;
        void *p;
 
+       if (!efi_enabled(EFI_MEMMAP))
+               return 0;
+
        for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
                md = p;
                if ((md->phys_addr <= phys_addr) &&
index b8b3a37c80cd75e96559e67876206ad603b53741..dbbdca5f508c45bdfb34395aeeb42e500e9f1f1f 100644 (file)
@@ -1034,7 +1034,8 @@ static int set_distrib_bits(struct cpumask *flush_mask, struct bau_control *bcp,
  * globally purge translation cache of a virtual address or all TLB's
  * @cpumask: mask of all cpu's in which the address is to be removed
  * @mm: mm_struct containing virtual address range
- * @va: virtual address to be removed (or TLB_FLUSH_ALL for all TLB's on cpu)
+ * @start: start virtual address to be removed from TLB
+ * @end: end virtual address to be remove from TLB
  * @cpu: the current cpu
  *
  * This is the entry point for initiating any UV global TLB shootdown.
@@ -1056,7 +1057,7 @@ static int set_distrib_bits(struct cpumask *flush_mask, struct bau_control *bcp,
  */
 const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
                                struct mm_struct *mm, unsigned long start,
-                               unsigned end, unsigned int cpu)
+                               unsigned long end, unsigned int cpu)
 {
        int locals = 0;
        int remotes = 0;
@@ -1113,7 +1114,10 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
 
        record_send_statistics(stat, locals, hubs, remotes, bau_desc);
 
-       bau_desc->payload.address = start;
+       if (!end || (end - start) <= PAGE_SIZE)
+               bau_desc->payload.address = start;
+       else
+               bau_desc->payload.address = TLB_FLUSH_ALL;
        bau_desc->payload.sending_cpu = cpu;
        /*
         * uv_flush_send_and_wait returns 0 if all cpu's were messaged,
index 3ff267861541f7570a5b110b7893e0cb012f5917..bd22f8667eed65e3889e61dcc357d85f5f3d1239 100644 (file)
@@ -250,7 +250,7 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
                return acpi_rsdp;
 #endif
 
-       if (efi_enabled) {
+       if (efi_enabled(EFI_CONFIG_TABLES)) {
                if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
                        return efi.acpi20;
                else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
index b00000e8aef6f9cb06955049d3fa4faaba25e38b..33c9a44a967899ac5b46e9b3e9951b2e80ff164d 100644 (file)
@@ -77,10 +77,15 @@ static struct usb_device_id ath3k_table[] = {
        { USB_DEVICE(0x0CF3, 0x311D) },
        { USB_DEVICE(0x13d3, 0x3375) },
        { USB_DEVICE(0x04CA, 0x3005) },
+       { USB_DEVICE(0x04CA, 0x3006) },
+       { USB_DEVICE(0x04CA, 0x3008) },
        { USB_DEVICE(0x13d3, 0x3362) },
        { USB_DEVICE(0x0CF3, 0xE004) },
        { USB_DEVICE(0x0930, 0x0219) },
        { USB_DEVICE(0x0489, 0xe057) },
+       { USB_DEVICE(0x13d3, 0x3393) },
+       { USB_DEVICE(0x0489, 0xe04e) },
+       { USB_DEVICE(0x0489, 0xe056) },
 
        /* Atheros AR5BBU12 with sflash firmware */
        { USB_DEVICE(0x0489, 0xE02C) },
@@ -104,10 +109,15 @@ static struct usb_device_id ath3k_blist_tbl[] = {
        { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
 
        /* Atheros AR5BBU22 with sflash firmware */
        { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
index a1d4ede5b892d4516b294f91aca91633864e7d43..7e351e345476c1bcc2141f95e41fe43a3e65e612 100644 (file)
@@ -135,10 +135,15 @@ static struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
 
        /* Atheros AR5BBU12 with sflash firmware */
        { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
index 281f566a5513d907fefc67da9237a2ec41ab8679..d1e9eb191f2bd77ff72614c0819885d31dcf473d 100644 (file)
@@ -340,7 +340,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
        /*
         * Alocate and fill the csrow/channels structs
         */
-       mci->csrows = kcalloc(sizeof(*mci->csrows), tot_csrows, GFP_KERNEL);
+       mci->csrows = kcalloc(tot_csrows, sizeof(*mci->csrows), GFP_KERNEL);
        if (!mci->csrows)
                goto error;
        for (row = 0; row < tot_csrows; row++) {
@@ -351,7 +351,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
                csr->csrow_idx = row;
                csr->mci = mci;
                csr->nr_channels = tot_channels;
-               csr->channels = kcalloc(sizeof(*csr->channels), tot_channels,
+               csr->channels = kcalloc(tot_channels, sizeof(*csr->channels),
                                        GFP_KERNEL);
                if (!csr->channels)
                        goto error;
@@ -369,7 +369,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
        /*
         * Allocate and fill the dimm structs
         */
-       mci->dimms  = kcalloc(sizeof(*mci->dimms), tot_dimms, GFP_KERNEL);
+       mci->dimms  = kcalloc(tot_dimms, sizeof(*mci->dimms), GFP_KERNEL);
        if (!mci->dimms)
                goto error;
 
index dc6e905ee1a5402126496bd06838302a1b26165f..0056c4dae9d52cc24985200dbb58b724be73c3ed 100644 (file)
@@ -256,7 +256,7 @@ static ssize_t edac_pci_dev_store(struct kobject *kobj,
        struct edac_pci_dev_attribute *edac_pci_dev;
        edac_pci_dev = (struct edac_pci_dev_attribute *)attr;
 
-       if (edac_pci_dev->show)
+       if (edac_pci_dev->store)
                return edac_pci_dev->store(edac_pci_dev->value, buffer, count);
        return -EIO;
 }
index fd3ae6290d71ecfd927cc4447a942c099bd223ea..982f1f5f5742f21da9206f62fa622ce17adefe9f 100644 (file)
@@ -471,7 +471,7 @@ void __init dmi_scan_machine(void)
        char __iomem *p, *q;
        int rc;
 
-       if (efi_enabled) {
+       if (efi_enabled(EFI_CONFIG_TABLES)) {
                if (efi.smbios == EFI_INVALID_TABLE_ADDR)
                        goto error;
 
index 2ed59dc1c48a9bb008143b926242c61aa250cc71..f5596db0cf583dc16226bc629a42977de0f9fa05 100644 (file)
@@ -1783,7 +1783,7 @@ efivars_init(void)
        printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION,
               EFIVARS_DATE);
 
-       if (!efi_enabled)
+       if (!efi_enabled(EFI_RUNTIME_SERVICES))
                return 0;
 
        /* For now we'll register the efi directory at /sys/firmware/efi */
@@ -1823,7 +1823,7 @@ err_put:
 static void __exit
 efivars_exit(void)
 {
-       if (efi_enabled) {
+       if (efi_enabled(EFI_RUNTIME_SERVICES)) {
                unregister_efivars(&__efivars);
                kobject_put(efi_kobj);
        }
index 4da4eb9ae92604c35349ebaeb39b4a612bac3ed6..2224f1dc074b1329d7ce9c80b78bef4fffc6e98b 100644 (file)
@@ -99,7 +99,7 @@ unsigned long __init find_ibft_region(unsigned long *sizep)
        /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
         * only use ACPI for this */
 
-       if (!efi_enabled)
+       if (!efi_enabled(EFI_BOOT))
                find_ibft_in_mem();
 
        if (ibft_addr) {
index 1d1f1e5e33f0ff267daa1d8ed4818b0a4e00fc7e..046bcda36abe7aa0f60e53f79f9988eaef61bd17 100644 (file)
@@ -24,7 +24,7 @@ config DRM_EXYNOS_DMABUF
 
 config DRM_EXYNOS_FIMD
        bool "Exynos DRM FIMD"
-       depends on DRM_EXYNOS && !FB_S3C
+       depends on DRM_EXYNOS && !FB_S3C && !ARCH_MULTIPLATFORM
        help
          Choose this option if you want to use Exynos FIMD for DRM.
 
@@ -48,7 +48,7 @@ config DRM_EXYNOS_G2D
 
 config DRM_EXYNOS_IPP
        bool "Exynos DRM IPP"
-       depends on DRM_EXYNOS
+       depends on DRM_EXYNOS && !ARCH_MULTIPLATFORM
        help
          Choose this option if you want to use IPP feature for DRM.
 
index ab37437bad8a9f0f5baa8b0425584ba95f5eb2c0..4c5b6859c9ea5cab2aa856ce43d3675f0240235e 100644 (file)
@@ -18,7 +18,6 @@
 #include "exynos_drm_drv.h"
 #include "exynos_drm_encoder.h"
 
-#define MAX_EDID 256
 #define to_exynos_connector(x) container_of(x, struct exynos_drm_connector,\
                                drm_connector)
 
@@ -96,7 +95,9 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)
                                        to_exynos_connector(connector);
        struct exynos_drm_manager *manager = exynos_connector->manager;
        struct exynos_drm_display_ops *display_ops = manager->display_ops;
-       unsigned int count;
+       struct edid *edid = NULL;
+       unsigned int count = 0;
+       int ret;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
@@ -114,27 +115,21 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)
         * because lcd panel has only one mode.
         */
        if (display_ops->get_edid) {
-               int ret;
-               void *edid;
-
-               edid = kzalloc(MAX_EDID, GFP_KERNEL);
-               if (!edid) {
-                       DRM_ERROR("failed to allocate edid\n");
-                       return 0;
+               edid = display_ops->get_edid(manager->dev, connector);
+               if (IS_ERR_OR_NULL(edid)) {
+                       ret = PTR_ERR(edid);
+                       edid = NULL;
+                       DRM_ERROR("Panel operation get_edid failed %d\n", ret);
+                       goto out;
                }
 
-               ret = display_ops->get_edid(manager->dev, connector,
-                                               edid, MAX_EDID);
-               if (ret < 0) {
-                       DRM_ERROR("failed to get edid data.\n");
-                       kfree(edid);
-                       edid = NULL;
-                       return 0;
+               count = drm_add_edid_modes(connector, edid);
+               if (count < 0) {
+                       DRM_ERROR("Add edid modes failed %d\n", count);
+                       goto out;
                }
 
                drm_mode_connector_update_edid_property(connector, edid);
-               count = drm_add_edid_modes(connector, edid);
-               kfree(edid);
        } else {
                struct exynos_drm_panel_info *panel;
                struct drm_display_mode *mode = drm_mode_create(connector->dev);
@@ -161,6 +156,8 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)
                count = 1;
        }
 
+out:
+       kfree(edid);
        return count;
 }
 
index 9df97714b6c0b8a2244fa1f61da5eb4a76c774dd..ba0a3aa785474f27ca0ba23b181e71d7d5bf82a9 100644 (file)
@@ -19,6 +19,7 @@
 struct exynos_drm_dmabuf_attachment {
        struct sg_table sgt;
        enum dma_data_direction dir;
+       bool is_mapped;
 };
 
 static int exynos_gem_attach_dma_buf(struct dma_buf *dmabuf,
@@ -72,17 +73,10 @@ static struct sg_table *
 
        DRM_DEBUG_PRIME("%s\n", __FILE__);
 
-       if (WARN_ON(dir == DMA_NONE))
-               return ERR_PTR(-EINVAL);
-
        /* just return current sgt if already requested. */
-       if (exynos_attach->dir == dir)
+       if (exynos_attach->dir == dir && exynos_attach->is_mapped)
                return &exynos_attach->sgt;
 
-       /* reattaching is not allowed. */
-       if (WARN_ON(exynos_attach->dir != DMA_NONE))
-               return ERR_PTR(-EBUSY);
-
        buf = gem_obj->buffer;
        if (!buf) {
                DRM_ERROR("buffer is null.\n");
@@ -107,13 +101,17 @@ static struct sg_table *
                wr = sg_next(wr);
        }
 
-       nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
-       if (!nents) {
-               DRM_ERROR("failed to map sgl with iommu.\n");
-               sgt = ERR_PTR(-EIO);
-               goto err_unlock;
+       if (dir != DMA_NONE) {
+               nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
+               if (!nents) {
+                       DRM_ERROR("failed to map sgl with iommu.\n");
+                       sg_free_table(sgt);
+                       sgt = ERR_PTR(-EIO);
+                       goto err_unlock;
+               }
        }
 
+       exynos_attach->is_mapped = true;
        exynos_attach->dir = dir;
        attach->priv = exynos_attach;
 
index b9e51bc09e81ad3ba81943e860ebb7a2580e0f2d..4606fac7241a0f2762dd0f10e8674efda02ac7d3 100644 (file)
@@ -148,8 +148,8 @@ struct exynos_drm_overlay {
 struct exynos_drm_display_ops {
        enum exynos_drm_output_type type;
        bool (*is_connected)(struct device *dev);
-       int (*get_edid)(struct device *dev, struct drm_connector *connector,
-                               u8 *edid, int len);
+       struct edid *(*get_edid)(struct device *dev,
+                       struct drm_connector *connector);
        void *(*get_panel)(struct device *dev);
        int (*check_timing)(struct device *dev, void *timing);
        int (*power_on)(struct device *dev, int mode);
index 36c3905536a65e824766ec61a385bb44a5f6c3f9..9a4c08e7453c35b2566c2c76b3bc7fa4406d7696 100644 (file)
@@ -324,7 +324,7 @@ out:
        g2d_userptr = NULL;
 }
 
-dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev,
+static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev,
                                        unsigned long userptr,
                                        unsigned long size,
                                        struct drm_file *filp,
index 850e9950b7da06c44d7fddaed4afdee812ce88ac..28644539b3056620912df744aaac7cccad6fa9a4 100644 (file)
@@ -108,18 +108,17 @@ static bool drm_hdmi_is_connected(struct device *dev)
        return false;
 }
 
-static int drm_hdmi_get_edid(struct device *dev,
-               struct drm_connector *connector, u8 *edid, int len)
+static struct edid *drm_hdmi_get_edid(struct device *dev,
+                       struct drm_connector *connector)
 {
        struct drm_hdmi_context *ctx = to_context(dev);
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
        if (hdmi_ops && hdmi_ops->get_edid)
-               return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector, edid,
-                                         len);
+               return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector);
 
-       return 0;
+       return NULL;
 }
 
 static int drm_hdmi_check_timing(struct device *dev, void *timing)
index 784a7e9a766c4a178e2f73e628e63adce5f6c364..d80516fc9ed7efd4675dd582ba3601118a4ffbad 100644 (file)
@@ -30,8 +30,8 @@ struct exynos_drm_hdmi_context {
 struct exynos_hdmi_ops {
        /* display */
        bool (*is_connected)(void *ctx);
-       int (*get_edid)(void *ctx, struct drm_connector *connector,
-                       u8 *edid, int len);
+       struct edid *(*get_edid)(void *ctx,
+                       struct drm_connector *connector);
        int (*check_timing)(void *ctx, void *timing);
        int (*power_on)(void *ctx, int mode);
 
index 0bda96454a02fe6e8cf31ced93c37249355a5f99..1a556354e92fa15ee5b051600662a9f0d98a868b 100644 (file)
@@ -869,7 +869,7 @@ static void ipp_put_event(struct drm_exynos_ipp_cmd_node *c_node,
        }
 }
 
-void ipp_handle_cmd_work(struct device *dev,
+static void ipp_handle_cmd_work(struct device *dev,
                struct exynos_drm_ippdrv *ippdrv,
                struct drm_exynos_ipp_cmd_work *cmd_work,
                struct drm_exynos_ipp_cmd_node *c_node)
index e9e83ef688f0c3a4ccf0253154975eebddb1d378..f976e29def6effa8adc973e92b28ba9f9add4443 100644 (file)
@@ -734,7 +734,7 @@ static int rotator_remove(struct platform_device *pdev)
        return 0;
 }
 
-struct rot_limit_table rot_limit_tbl = {
+static struct rot_limit_table rot_limit_tbl = {
        .ycbcr420_2p = {
                .min_w = 32,
                .min_h = 32,
@@ -751,7 +751,7 @@ struct rot_limit_table rot_limit_tbl = {
        },
 };
 
-struct platform_device_id rotator_driver_ids[] = {
+static struct platform_device_id rotator_driver_ids[] = {
        {
                .name           = "exynos-rot",
                .driver_data    = (unsigned long)&rot_limit_tbl,
index d0ca3c4e06c60bbeca05e87b783d1e7e4b690f16..13ccbd4bcfaa8c863f27d24870101c32166ecb47 100644 (file)
@@ -98,10 +98,12 @@ static bool vidi_display_is_connected(struct device *dev)
        return ctx->connected ? true : false;
 }
 
-static int vidi_get_edid(struct device *dev, struct drm_connector *connector,
-                               u8 *edid, int len)
+static struct edid *vidi_get_edid(struct device *dev,
+                       struct drm_connector *connector)
 {
        struct vidi_context *ctx = get_vidi_context(dev);
+       struct edid *edid;
+       int edid_len;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
@@ -111,13 +113,18 @@ static int vidi_get_edid(struct device *dev, struct drm_connector *connector,
         */
        if (!ctx->raw_edid) {
                DRM_DEBUG_KMS("raw_edid is null.\n");
-               return -EFAULT;
+               return ERR_PTR(-EFAULT);
        }
 
-       memcpy(edid, ctx->raw_edid, min((1 + ctx->raw_edid->extensions)
-                                       * EDID_LENGTH, len));
+       edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH;
+       edid = kzalloc(edid_len, GFP_KERNEL);
+       if (!edid) {
+               DRM_DEBUG_KMS("failed to allocate edid\n");
+               return ERR_PTR(-ENOMEM);
+       }
 
-       return 0;
+       memcpy(edid, ctx->raw_edid, edid_len);
+       return edid;
 }
 
 static void *vidi_get_panel(struct device *dev)
@@ -514,7 +521,6 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
        struct exynos_drm_manager *manager;
        struct exynos_drm_display_ops *display_ops;
        struct drm_exynos_vidi_connection *vidi = data;
-       struct edid *raw_edid;
        int edid_len;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -551,11 +557,11 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
        }
 
        if (vidi->connection) {
-               if (!vidi->edid) {
-                       DRM_DEBUG_KMS("edid data is null.\n");
+               struct edid *raw_edid  = (struct edid *)(uint32_t)vidi->edid;
+               if (!drm_edid_is_valid(raw_edid)) {
+                       DRM_DEBUG_KMS("edid data is invalid.\n");
                        return -EINVAL;
                }
-               raw_edid = (struct edid *)(uint32_t)vidi->edid;
                edid_len = (1 + raw_edid->extensions) * EDID_LENGTH;
                ctx->raw_edid = kzalloc(edid_len, GFP_KERNEL);
                if (!ctx->raw_edid) {
index 41ff79d8ac8ec27db3f4b5cd3edadb0d86dde241..fbab3c4686031ce9c07a1b19546ab73ddb4f92e7 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/regulator/consumer.h>
 #include <linux/io.h>
 #include <linux/of_gpio.h>
-#include <plat/gpio-cfg.h>
 
 #include <drm/exynos_drm.h>
 
@@ -98,8 +97,7 @@ struct hdmi_context {
 
        void __iomem                    *regs;
        void                            *parent_ctx;
-       int                             external_irq;
-       int                             internal_irq;
+       int                             irq;
 
        struct i2c_client               *ddc_port;
        struct i2c_client               *hdmiphy_port;
@@ -1391,8 +1389,7 @@ static bool hdmi_is_connected(void *ctx)
        return hdata->hpd;
 }
 
-static int hdmi_get_edid(void *ctx, struct drm_connector *connector,
-                               u8 *edid, int len)
+static struct edid *hdmi_get_edid(void *ctx, struct drm_connector *connector)
 {
        struct edid *raw_edid;
        struct hdmi_context *hdata = ctx;
@@ -1400,22 +1397,18 @@ static int hdmi_get_edid(void *ctx, struct drm_connector *connector,
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
        if (!hdata->ddc_port)
-               return -ENODEV;
+               return ERR_PTR(-ENODEV);
 
        raw_edid = drm_get_edid(connector, hdata->ddc_port->adapter);
-       if (raw_edid) {
-               hdata->dvi_mode = !drm_detect_hdmi_monitor(raw_edid);
-               memcpy(edid, raw_edid, min((1 + raw_edid->extensions)
-                                       * EDID_LENGTH, len));
-               DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n",
-                       (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
-                       raw_edid->width_cm, raw_edid->height_cm);
-               kfree(raw_edid);
-       } else {
-               return -ENODEV;
-       }
+       if (!raw_edid)
+               return ERR_PTR(-ENODEV);
 
-       return 0;
+       hdata->dvi_mode = !drm_detect_hdmi_monitor(raw_edid);
+       DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n",
+               (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
+               raw_edid->width_cm, raw_edid->height_cm);
+
+       return raw_edid;
 }
 
 static int hdmi_v13_check_timing(struct fb_videomode *check_timing)
@@ -1652,16 +1645,16 @@ static void hdmi_conf_reset(struct hdmi_context *hdata)
 
        /* resetting HDMI core */
        hdmi_reg_writemask(hdata, reg,  0, HDMI_CORE_SW_RSTOUT);
-       mdelay(10);
+       usleep_range(10000, 12000);
        hdmi_reg_writemask(hdata, reg, ~0, HDMI_CORE_SW_RSTOUT);
-       mdelay(10);
+       usleep_range(10000, 12000);
 }
 
 static void hdmi_conf_init(struct hdmi_context *hdata)
 {
        struct hdmi_infoframe infoframe;
 
-       /* disable HPD interrupts */
+       /* disable HPD interrupts from HDMI IP block, use GPIO instead */
        hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
                HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
 
@@ -1779,7 +1772,7 @@ static void hdmi_v13_timing_apply(struct hdmi_context *hdata)
                u32 val = hdmi_reg_read(hdata, HDMI_V13_PHY_STATUS);
                if (val & HDMI_PHY_STATUS_READY)
                        break;
-               mdelay(1);
+               usleep_range(1000, 2000);
        }
        /* steady state not achieved */
        if (tries == 0) {
@@ -1946,7 +1939,7 @@ static void hdmi_v14_timing_apply(struct hdmi_context *hdata)
                u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS_0);
                if (val & HDMI_PHY_STATUS_READY)
                        break;
-               mdelay(1);
+               usleep_range(1000, 2000);
        }
        /* steady state not achieved */
        if (tries == 0) {
@@ -1998,9 +1991,9 @@ static void hdmiphy_conf_reset(struct hdmi_context *hdata)
 
        /* reset hdmiphy */
        hdmi_reg_writemask(hdata, reg, ~0, HDMI_PHY_SW_RSTOUT);
-       mdelay(10);
+       usleep_range(10000, 12000);
        hdmi_reg_writemask(hdata, reg,  0, HDMI_PHY_SW_RSTOUT);
-       mdelay(10);
+       usleep_range(10000, 12000);
 }
 
 static void hdmiphy_poweron(struct hdmi_context *hdata)
@@ -2048,7 +2041,7 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata)
                return;
        }
 
-       mdelay(10);
+       usleep_range(10000, 12000);
 
        /* operation mode */
        operation[0] = 0x1f;
@@ -2170,6 +2163,13 @@ static void hdmi_commit(void *ctx)
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
+       mutex_lock(&hdata->hdmi_mutex);
+       if (!hdata->powered) {
+               mutex_unlock(&hdata->hdmi_mutex);
+               return;
+       }
+       mutex_unlock(&hdata->hdmi_mutex);
+
        hdmi_conf_apply(hdata);
 }
 
@@ -2265,7 +2265,7 @@ static struct exynos_hdmi_ops hdmi_ops = {
        .dpms           = hdmi_dpms,
 };
 
-static irqreturn_t hdmi_external_irq_thread(int irq, void *arg)
+static irqreturn_t hdmi_irq_thread(int irq, void *arg)
 {
        struct exynos_drm_hdmi_context *ctx = arg;
        struct hdmi_context *hdata = ctx->ctx;
@@ -2280,31 +2280,6 @@ static irqreturn_t hdmi_external_irq_thread(int irq, void *arg)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t hdmi_internal_irq_thread(int irq, void *arg)
-{
-       struct exynos_drm_hdmi_context *ctx = arg;
-       struct hdmi_context *hdata = ctx->ctx;
-       u32 intc_flag;
-
-       intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG);
-       /* clearing flags for HPD plug/unplug */
-       if (intc_flag & HDMI_INTC_FLAG_HPD_UNPLUG) {
-               DRM_DEBUG_KMS("unplugged\n");
-               hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0,
-                       HDMI_INTC_FLAG_HPD_UNPLUG);
-       }
-       if (intc_flag & HDMI_INTC_FLAG_HPD_PLUG) {
-               DRM_DEBUG_KMS("plugged\n");
-               hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0,
-                       HDMI_INTC_FLAG_HPD_PLUG);
-       }
-
-       if (ctx->drm_dev)
-               drm_helper_hpd_irq_event(ctx->drm_dev);
-
-       return IRQ_HANDLED;
-}
-
 static int hdmi_resources_init(struct hdmi_context *hdata)
 {
        struct device *dev = hdata->dev;
@@ -2555,39 +2530,24 @@ static int hdmi_probe(struct platform_device *pdev)
 
        hdata->hdmiphy_port = hdmi_hdmiphy;
 
-       hdata->external_irq = gpio_to_irq(hdata->hpd_gpio);
-       if (hdata->external_irq < 0) {
-               DRM_ERROR("failed to get GPIO external irq\n");
-               ret = hdata->external_irq;
-               goto err_hdmiphy;
-       }
-
-       hdata->internal_irq = platform_get_irq(pdev, 0);
-       if (hdata->internal_irq < 0) {
-               DRM_ERROR("failed to get platform internal irq\n");
-               ret = hdata->internal_irq;
+       hdata->irq = gpio_to_irq(hdata->hpd_gpio);
+       if (hdata->irq < 0) {
+               DRM_ERROR("failed to get GPIO irq\n");
+               ret = hdata->irq;
                goto err_hdmiphy;
        }
 
        hdata->hpd = gpio_get_value(hdata->hpd_gpio);
 
-       ret = request_threaded_irq(hdata->external_irq, NULL,
-                       hdmi_external_irq_thread, IRQF_TRIGGER_RISING |
+       ret = request_threaded_irq(hdata->irq, NULL,
+                       hdmi_irq_thread, IRQF_TRIGGER_RISING |
                        IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
-                       "hdmi_external", drm_hdmi_ctx);
+                       "hdmi", drm_hdmi_ctx);
        if (ret) {
-               DRM_ERROR("failed to register hdmi external interrupt\n");
+               DRM_ERROR("failed to register hdmi interrupt\n");
                goto err_hdmiphy;
        }
 
-       ret = request_threaded_irq(hdata->internal_irq, NULL,
-                       hdmi_internal_irq_thread, IRQF_ONESHOT,
-                       "hdmi_internal", drm_hdmi_ctx);
-       if (ret) {
-               DRM_ERROR("failed to register hdmi internal interrupt\n");
-               goto err_free_irq;
-       }
-
        /* Attach HDMI Driver to common hdmi. */
        exynos_hdmi_drv_attach(drm_hdmi_ctx);
 
@@ -2598,8 +2558,6 @@ static int hdmi_probe(struct platform_device *pdev)
 
        return 0;
 
-err_free_irq:
-       free_irq(hdata->external_irq, drm_hdmi_ctx);
 err_hdmiphy:
        i2c_del_driver(&hdmiphy_driver);
 err_ddc:
@@ -2617,8 +2575,7 @@ static int hdmi_remove(struct platform_device *pdev)
 
        pm_runtime_disable(dev);
 
-       free_irq(hdata->internal_irq, hdata);
-       free_irq(hdata->external_irq, hdata);
+       free_irq(hdata->irq, hdata);
 
 
        /* hdmiphy i2c driver */
@@ -2637,8 +2594,7 @@ static int hdmi_suspend(struct device *dev)
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
-       disable_irq(hdata->internal_irq);
-       disable_irq(hdata->external_irq);
+       disable_irq(hdata->irq);
 
        hdata->hpd = false;
        if (ctx->drm_dev)
@@ -2663,8 +2619,7 @@ static int hdmi_resume(struct device *dev)
 
        hdata->hpd = gpio_get_value(hdata->hpd_gpio);
 
-       enable_irq(hdata->external_irq);
-       enable_irq(hdata->internal_irq);
+       enable_irq(hdata->irq);
 
        if (!pm_runtime_suspended(dev)) {
                DRM_DEBUG_KMS("%s : Already resumed\n", __func__);
index c187ea33b748c031b91d10e45479d98368b297f6..c414584bfbaecf36d285be933e9e212fbea7784d 100644 (file)
@@ -600,7 +600,7 @@ static void vp_win_reset(struct mixer_context *ctx)
                /* waiting until VP_SRESET_PROCESSING is 0 */
                if (~vp_reg_read(res, VP_SRESET) & VP_SRESET_PROCESSING)
                        break;
-               mdelay(10);
+               usleep_range(10000, 12000);
        }
        WARN(tries == 0, "failed to reset Video Processor\n");
 }
@@ -776,6 +776,13 @@ static void mixer_win_commit(void *ctx, int win)
 
        DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
 
+       mutex_lock(&mixer_ctx->mixer_mutex);
+       if (!mixer_ctx->powered) {
+               mutex_unlock(&mixer_ctx->mixer_mutex);
+               return;
+       }
+       mutex_unlock(&mixer_ctx->mixer_mutex);
+
        if (win > 1 && mixer_ctx->vp_enabled)
                vp_video_buffer(mixer_ctx, win);
        else
index 7944d301518ac80f2ef1b72e1b5e29b5213bc33f..9d4a2c2adf0e0883d76d13070fa09f7aa32e1526 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/debugfs.h>
 #include <linux/slab.h>
 #include <linux/export.h>
+#include <generated/utsrelease.h>
 #include <drm/drmP.h>
 #include "intel_drv.h"
 #include "intel_ringbuffer.h"
@@ -690,6 +691,7 @@ static int i915_error_state(struct seq_file *m, void *unused)
 
        seq_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec,
                   error->time.tv_usec);
+       seq_printf(m, "Kernel: " UTS_RELEASE);
        seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device);
        seq_printf(m, "EIR: 0x%08x\n", error->eir);
        seq_printf(m, "IER: 0x%08x\n", error->ier);
index b401788e1791f2057cee7d17a1e3c1024adfa99a..59afb7eb6db635cf2f9bbe5477ffc8bd75fddd30 100644 (file)
 #define MI_MODE                0x0209c
 # define VS_TIMER_DISPATCH                             (1 << 6)
 # define MI_FLUSH_ENABLE                               (1 << 12)
+# define ASYNC_FLIP_PERF_DISABLE                       (1 << 14)
 
 #define GEN6_GT_MODE   0x20d0
 #define   GEN6_GT_MODE_HI                              (1 << 9)
index ae253e04c39105502fa1b82e05889970139f123f..42ff97d667d2b84ad339b27ab1f59110ba5831e8 100644 (file)
@@ -505,13 +505,25 @@ static int init_render_ring(struct intel_ring_buffer *ring)
        struct drm_i915_private *dev_priv = dev->dev_private;
        int ret = init_ring_common(ring);
 
-       if (INTEL_INFO(dev)->gen > 3) {
+       if (INTEL_INFO(dev)->gen > 3)
                I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(VS_TIMER_DISPATCH));
-               if (IS_GEN7(dev))
-                       I915_WRITE(GFX_MODE_GEN7,
-                                  _MASKED_BIT_DISABLE(GFX_TLB_INVALIDATE_ALWAYS) |
-                                  _MASKED_BIT_ENABLE(GFX_REPLAY_MODE));
-       }
+
+       /* We need to disable the AsyncFlip performance optimisations in order
+        * to use MI_WAIT_FOR_EVENT within the CS. It should already be
+        * programmed to '1' on all products.
+        */
+       if (INTEL_INFO(dev)->gen >= 6)
+               I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(ASYNC_FLIP_PERF_DISABLE));
+
+       /* Required for the hardware to program scanline values for waiting */
+       if (INTEL_INFO(dev)->gen == 6)
+               I915_WRITE(GFX_MODE,
+                          _MASKED_BIT_ENABLE(GFX_TLB_INVALIDATE_ALWAYS));
+
+       if (IS_GEN7(dev))
+               I915_WRITE(GFX_MODE_GEN7,
+                          _MASKED_BIT_DISABLE(GFX_TLB_INVALIDATE_ALWAYS) |
+                          _MASKED_BIT_ENABLE(GFX_REPLAY_MODE));
 
        if (INTEL_INFO(dev)->gen >= 5) {
                ret = init_pipe_control(ring);
index 59acabb45c9b94a0798e75ded14c8d12d221a795..835992d8d067bf199bdf2ec633e634133ed16a4a 100644 (file)
@@ -1216,7 +1216,7 @@ void cayman_dma_stop(struct radeon_device *rdev)
 int cayman_dma_resume(struct radeon_device *rdev)
 {
        struct radeon_ring *ring;
-       u32 rb_cntl, dma_cntl;
+       u32 rb_cntl, dma_cntl, ib_cntl;
        u32 rb_bufsz;
        u32 reg_offset, wb_offset;
        int i, r;
@@ -1265,7 +1265,11 @@ int cayman_dma_resume(struct radeon_device *rdev)
                WREG32(DMA_RB_BASE + reg_offset, ring->gpu_addr >> 8);
 
                /* enable DMA IBs */
-               WREG32(DMA_IB_CNTL + reg_offset, DMA_IB_ENABLE | CMD_VMID_FORCE);
+               ib_cntl = DMA_IB_ENABLE | CMD_VMID_FORCE;
+#ifdef __BIG_ENDIAN
+               ib_cntl |= DMA_IB_SWAP_ENABLE;
+#endif
+               WREG32(DMA_IB_CNTL + reg_offset, ib_cntl);
 
                dma_cntl = RREG32(DMA_CNTL + reg_offset);
                dma_cntl &= ~CTXEMPTY_INT_ENABLE;
index 3cb9d6089373250165af9b33ad7f53aa762d8c3f..bc2540b17c5effb5f065a715218f1c9be472898d 100644 (file)
@@ -2313,7 +2313,7 @@ void r600_dma_stop(struct radeon_device *rdev)
 int r600_dma_resume(struct radeon_device *rdev)
 {
        struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
-       u32 rb_cntl, dma_cntl;
+       u32 rb_cntl, dma_cntl, ib_cntl;
        u32 rb_bufsz;
        int r;
 
@@ -2353,7 +2353,11 @@ int r600_dma_resume(struct radeon_device *rdev)
        WREG32(DMA_RB_BASE, ring->gpu_addr >> 8);
 
        /* enable DMA IBs */
-       WREG32(DMA_IB_CNTL, DMA_IB_ENABLE);
+       ib_cntl = DMA_IB_ENABLE;
+#ifdef __BIG_ENDIAN
+       ib_cntl |= DMA_IB_SWAP_ENABLE;
+#endif
+       WREG32(DMA_IB_CNTL, ib_cntl);
 
        dma_cntl = RREG32(DMA_CNTL);
        dma_cntl &= ~CTXEMPTY_INT_ENABLE;
index 469661fd190331f53230a6d1a524bbaebb040012..5407459e56d2b5dd9619e698c2ec306c56104f4a 100644 (file)
@@ -286,6 +286,8 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
                            p->chunks[p->chunk_ib_idx].kpage[1] == NULL) {
                                kfree(p->chunks[p->chunk_ib_idx].kpage[0]);
                                kfree(p->chunks[p->chunk_ib_idx].kpage[1]);
+                               p->chunks[p->chunk_ib_idx].kpage[0] = NULL;
+                               p->chunks[p->chunk_ib_idx].kpage[1] = NULL;
                                return -ENOMEM;
                        }
                }
index ad6df625e8b8a1cf869ac06bb898503022406a6b..0d67674b64b13e9a4618548fb1ca3d2d2211f797 100644 (file)
@@ -241,7 +241,8 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc,
                y = 0;
        }
 
-       if (ASIC_IS_AVIVO(rdev)) {
+       /* fixed on DCE6 and newer */
+       if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE6(rdev)) {
                int i = 0;
                struct drm_crtc *crtc_p;
 
index edfc54e41842248f4dad035c1ece973ca08837b5..0d6562bb0c93e61e7b57e4fd09f31a802ba34d99 100644 (file)
@@ -429,7 +429,8 @@ bool radeon_card_posted(struct radeon_device *rdev)
 {
        uint32_t reg;
 
-       if (efi_enabled && rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE)
+       if (efi_enabled(EFI_BOOT) &&
+           rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE)
                return false;
 
        /* first check CRTCs */
index 1da2386d7cf74a9eac82674a53ac2cee3e8e52a5..ff3def7846197bc9f69b929f9fe745d01759f537 100644 (file)
@@ -1122,7 +1122,7 @@ radeon_user_framebuffer_create(struct drm_device *dev,
        if (ret) {
                kfree(radeon_fb);
                drm_gem_object_unreference_unlocked(obj);
-               return NULL;
+               return ERR_PTR(ret);
        }
 
        return &radeon_fb->base;
index 81837b0710a9ba0240b1eba3c1b3f8b51d997e2f..faf10ba1ed9ad1dcfcd00dabc26c725cf7e9ad00 100644 (file)
@@ -974,6 +974,38 @@ static void __init free_iommu_all(void)
        }
 }
 
+/*
+ * Family15h Model 10h-1fh erratum 746 (IOMMU Logging May Stall Translations)
+ * Workaround:
+ *     BIOS should disable L2B micellaneous clock gating by setting
+ *     L2_L2B_CK_GATE_CONTROL[CKGateL2BMiscDisable](D0F2xF4_x90[2]) = 1b
+ */
+static void __init amd_iommu_erratum_746_workaround(struct amd_iommu *iommu)
+{
+       u32 value;
+
+       if ((boot_cpu_data.x86 != 0x15) ||
+           (boot_cpu_data.x86_model < 0x10) ||
+           (boot_cpu_data.x86_model > 0x1f))
+               return;
+
+       pci_write_config_dword(iommu->dev, 0xf0, 0x90);
+       pci_read_config_dword(iommu->dev, 0xf4, &value);
+
+       if (value & BIT(2))
+               return;
+
+       /* Select NB indirect register 0x90 and enable writing */
+       pci_write_config_dword(iommu->dev, 0xf0, 0x90 | (1 << 8));
+
+       pci_write_config_dword(iommu->dev, 0xf4, value | 0x4);
+       pr_info("AMD-Vi: Applying erratum 746 workaround for IOMMU at %s\n",
+               dev_name(&iommu->dev->dev));
+
+       /* Clear the enable writing bit */
+       pci_write_config_dword(iommu->dev, 0xf0, 0x90);
+}
+
 /*
  * This function clues the initialization function for one IOMMU
  * together and also allocates the command buffer and programs the
@@ -1172,6 +1204,8 @@ static int iommu_init_pci(struct amd_iommu *iommu)
                        iommu->stored_l2[i] = iommu_read_l2(iommu, i);
        }
 
+       amd_iommu_erratum_746_workaround(iommu);
+
        return pci_enable_device(iommu->dev);
 }
 
index b9d091157884570f636492be2e49e2e346697664..eca28014ef3e4a9d509d9d5472fc73da707806ef 100644 (file)
@@ -4234,6 +4234,21 @@ static struct iommu_ops intel_iommu_ops = {
        .pgsize_bitmap  = INTEL_IOMMU_PGSIZES,
 };
 
+static void quirk_iommu_g4x_gfx(struct pci_dev *dev)
+{
+       /* G4x/GM45 integrated gfx dmar support is totally busted. */
+       printk(KERN_INFO "DMAR: Disabling IOMMU for graphics on this chipset\n");
+       dmar_map_gfx = 0;
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_g4x_gfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_g4x_gfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_g4x_gfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_g4x_gfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_g4x_gfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_g4x_gfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_g4x_gfx);
+
 static void quirk_iommu_rwbf(struct pci_dev *dev)
 {
        /*
@@ -4242,12 +4257,6 @@ static void quirk_iommu_rwbf(struct pci_dev *dev)
         */
        printk(KERN_INFO "DMAR: Forcing write-buffer flush capability\n");
        rwbf_quirk = 1;
-
-       /* https://bugzilla.redhat.com/show_bug.cgi?id=538163 */
-       if (dev->revision == 0x07) {
-               printk(KERN_INFO "DMAR: Disabling IOMMU for graphics on this chipset\n");
-               dmar_map_gfx = 0;
-       }
 }
 
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
index 68452b768da23dc31c5409b113446802476886c2..03a0a01a405451c8a85e0e9b83647c105a710f53 100644 (file)
@@ -248,6 +248,8 @@ static inline void dump_rawmsg(enum debuglevel level, const char *tag,
                CAPIMSG_APPID(data), CAPIMSG_MSGID(data), l,
                CAPIMSG_CONTROL(data));
        l -= 12;
+       if (l <= 0)
+               return;
        dbgline = kmalloc(3 * l, GFP_ATOMIC);
        if (!dbgline)
                return;
index 3d8984edeff79b4dda6910670d95d34802411f6e..9e58dbd8d8cba839da9613e5f4e4060795cd0dc1 100644 (file)
@@ -340,24 +340,22 @@ static int validate_region_size(struct raid_set *rs, unsigned long region_size)
 }
 
 /*
- * validate_rebuild_devices
+ * validate_raid_redundancy
  * @rs
  *
- * Determine if the devices specified for rebuild can result in a valid
- * usable array that is capable of rebuilding the given devices.
+ * Determine if there are enough devices in the array that haven't
+ * failed (or are being rebuilt) to form a usable array.
  *
  * Returns: 0 on success, -EINVAL on failure.
  */
-static int validate_rebuild_devices(struct raid_set *rs)
+static int validate_raid_redundancy(struct raid_set *rs)
 {
        unsigned i, rebuild_cnt = 0;
        unsigned rebuilds_per_group, copies, d;
 
-       if (!(rs->print_flags & DMPF_REBUILD))
-               return 0;
-
        for (i = 0; i < rs->md.raid_disks; i++)
-               if (!test_bit(In_sync, &rs->dev[i].rdev.flags))
+               if (!test_bit(In_sync, &rs->dev[i].rdev.flags) ||
+                   !rs->dev[i].rdev.sb_page)
                        rebuild_cnt++;
 
        switch (rs->raid_type->level) {
@@ -393,27 +391,24 @@ static int validate_rebuild_devices(struct raid_set *rs)
                 *          A    A    B    B    C
                 *          C    D    D    E    E
                 */
-               rebuilds_per_group = 0;
                for (i = 0; i < rs->md.raid_disks * copies; i++) {
+                       if (!(i % copies))
+                               rebuilds_per_group = 0;
                        d = i % rs->md.raid_disks;
-                       if (!test_bit(In_sync, &rs->dev[d].rdev.flags) &&
+                       if ((!rs->dev[d].rdev.sb_page ||
+                            !test_bit(In_sync, &rs->dev[d].rdev.flags)) &&
                            (++rebuilds_per_group >= copies))
                                goto too_many;
-                       if (!((i + 1) % copies))
-                               rebuilds_per_group = 0;
                }
                break;
        default:
-               DMERR("The rebuild parameter is not supported for %s",
-                     rs->raid_type->name);
-               rs->ti->error = "Rebuild not supported for this RAID type";
-               return -EINVAL;
+               if (rebuild_cnt)
+                       return -EINVAL;
        }
 
        return 0;
 
 too_many:
-       rs->ti->error = "Too many rebuild devices specified";
        return -EINVAL;
 }
 
@@ -664,9 +659,6 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
        }
        rs->md.dev_sectors = sectors_per_dev;
 
-       if (validate_rebuild_devices(rs))
-               return -EINVAL;
-
        /* Assume there are no metadata devices until the drives are parsed */
        rs->md.persistent = 0;
        rs->md.external = 1;
@@ -995,28 +987,10 @@ static int super_validate(struct mddev *mddev, struct md_rdev *rdev)
 static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
 {
        int ret;
-       unsigned redundancy = 0;
        struct raid_dev *dev;
        struct md_rdev *rdev, *tmp, *freshest;
        struct mddev *mddev = &rs->md;
 
-       switch (rs->raid_type->level) {
-       case 1:
-               redundancy = rs->md.raid_disks - 1;
-               break;
-       case 4:
-       case 5:
-       case 6:
-               redundancy = rs->raid_type->parity_devs;
-               break;
-       case 10:
-               redundancy = raid10_md_layout_to_copies(mddev->layout) - 1;
-               break;
-       default:
-               ti->error = "Unknown RAID type";
-               return -EINVAL;
-       }
-
        freshest = NULL;
        rdev_for_each_safe(rdev, tmp, mddev) {
                /*
@@ -1045,44 +1019,43 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
                        break;
                default:
                        dev = container_of(rdev, struct raid_dev, rdev);
-                       if (redundancy--) {
-                               if (dev->meta_dev)
-                                       dm_put_device(ti, dev->meta_dev);
-
-                               dev->meta_dev = NULL;
-                               rdev->meta_bdev = NULL;
+                       if (dev->meta_dev)
+                               dm_put_device(ti, dev->meta_dev);
 
-                               if (rdev->sb_page)
-                                       put_page(rdev->sb_page);
+                       dev->meta_dev = NULL;
+                       rdev->meta_bdev = NULL;
 
-                               rdev->sb_page = NULL;
+                       if (rdev->sb_page)
+                               put_page(rdev->sb_page);
 
-                               rdev->sb_loaded = 0;
+                       rdev->sb_page = NULL;
 
-                               /*
-                                * We might be able to salvage the data device
-                                * even though the meta device has failed.  For
-                                * now, we behave as though '- -' had been
-                                * set for this device in the table.
-                                */
-                               if (dev->data_dev)
-                                       dm_put_device(ti, dev->data_dev);
+                       rdev->sb_loaded = 0;
 
-                               dev->data_dev = NULL;
-                               rdev->bdev = NULL;
+                       /*
+                        * We might be able to salvage the data device
+                        * even though the meta device has failed.  For
+                        * now, we behave as though '- -' had been
+                        * set for this device in the table.
+                        */
+                       if (dev->data_dev)
+                               dm_put_device(ti, dev->data_dev);
 
-                               list_del(&rdev->same_set);
+                       dev->data_dev = NULL;
+                       rdev->bdev = NULL;
 
-                               continue;
-                       }
-                       ti->error = "Failed to load superblock";
-                       return ret;
+                       list_del(&rdev->same_set);
                }
        }
 
        if (!freshest)
                return 0;
 
+       if (validate_raid_redundancy(rs)) {
+               rs->ti->error = "Insufficient redundancy to activate array";
+               return -EINVAL;
+       }
+
        /*
         * Validation of the freshest device provides the source of
         * validation for the remaining devices.
@@ -1432,7 +1405,7 @@ static void raid_resume(struct dm_target *ti)
 
 static struct target_type raid_target = {
        .name = "raid",
-       .version = {1, 4, 0},
+       .version = {1, 4, 1},
        .module = THIS_MODULE,
        .ctr = raid_ctr,
        .dtr = raid_dtr,
index 47ad4e270877706e3b3e864ac1e8f77ac7b11c42..ff553babf455025c2a5ce303297a15f404d2d5e3 100644 (file)
@@ -237,6 +237,7 @@ config MFD_TPS65910
        depends on I2C=y && GPIOLIB
        select MFD_CORE
        select REGMAP_I2C
+       select REGMAP_IRQ
        select IRQ_DOMAIN
        help
          if you say yes here you get support for the TPS65910 series of
index e1650badd106da6e3992b219e77fdc35e20ad1c8..4778bb124efe09b27da77446896dfd6ae9e97f0e 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/mfd/core.h>
 #include <linux/mfd/abx500.h>
 #include <linux/mfd/abx500/ab8500.h>
+#include <linux/mfd/abx500/ab8500-bm.h>
 #include <linux/mfd/dbx500-prcmu.h>
 #include <linux/regulator/ab8500.h>
 #include <linux/of.h>
index bc8a3edb6bbf2b2fdc9c3f15a425eafb0bcb23af..222c03a5ddc0b3d3e9a37af453d4a1745f1b35e3 100644 (file)
@@ -239,7 +239,12 @@ static int arizona_runtime_resume(struct device *dev)
                return ret;
        }
 
-       regcache_sync(arizona->regmap);
+       ret = regcache_sync(arizona->regmap);
+       if (ret != 0) {
+               dev_err(arizona->dev, "Failed to restore register cache\n");
+               regulator_disable(arizona->dcvdd);
+               return ret;
+       }
 
        return 0;
 }
index 74713bf5371fa42361dbb2342407c0dfe9c039b6..2bec5f0db3ee5e80733a88043d96b3219405d2f0 100644 (file)
@@ -176,14 +176,7 @@ int arizona_irq_init(struct arizona *arizona)
                aod = &wm5102_aod;
                irq = &wm5102_irq;
 
-               switch (arizona->rev) {
-               case 0:
-               case 1:
-                       ctrlif_error = false;
-                       break;
-               default:
-                       break;
-               }
+               ctrlif_error = false;
                break;
 #endif
 #ifdef CONFIG_MFD_WM5110
@@ -191,14 +184,7 @@ int arizona_irq_init(struct arizona *arizona)
                aod = &wm5110_aod;
                irq = &wm5110_irq;
 
-               switch (arizona->rev) {
-               case 0:
-               case 1:
-                       ctrlif_error = false;
-                       break;
-               default:
-                       break;
-               }
+               ctrlif_error = false;
                break;
 #endif
        default:
index ac74a4d1daead1848ef00e9ac096013d69e67a21..885e567803583a42473ffb532beead311ad68cf2 100644 (file)
 #include <linux/of_device.h>
 #endif
 
+/* I2C safe register check */
+static inline bool i2c_safe_reg(unsigned char reg)
+{
+       switch (reg) {
+       case DA9052_STATUS_A_REG:
+       case DA9052_STATUS_B_REG:
+       case DA9052_STATUS_C_REG:
+       case DA9052_STATUS_D_REG:
+       case DA9052_ADC_RES_L_REG:
+       case DA9052_ADC_RES_H_REG:
+       case DA9052_VDD_RES_REG:
+       case DA9052_ICHG_AV_REG:
+       case DA9052_TBAT_RES_REG:
+       case DA9052_ADCIN4_RES_REG:
+       case DA9052_ADCIN5_RES_REG:
+       case DA9052_ADCIN6_RES_REG:
+       case DA9052_TJUNC_RES_REG:
+       case DA9052_TSI_X_MSB_REG:
+       case DA9052_TSI_Y_MSB_REG:
+       case DA9052_TSI_LSB_REG:
+       case DA9052_TSI_Z_MSB_REG:
+               return true;
+       default:
+               return false;
+       }
+}
+
+/*
+ * There is an issue with DA9052 and DA9053_AA/BA/BB PMIC where the PMIC
+ * gets lockup up or fails to respond following a system reset.
+ * This fix is to follow any read or write with a dummy read to a safe
+ * register.
+ */
+int da9052_i2c_fix(struct da9052 *da9052, unsigned char reg)
+{
+       int val;
+
+       switch (da9052->chip_id) {
+       case DA9052:
+       case DA9053_AA:
+       case DA9053_BA:
+       case DA9053_BB:
+               /* A dummy read to a safe register address. */
+       if (!i2c_safe_reg(reg))
+                       return regmap_read(da9052->regmap,
+                                          DA9052_PARK_REGISTER,
+                                          &val);
+               break;
+       default:
+               /*
+                * For other chips parking of I2C register
+                * to a safe place is not required.
+                */
+               break;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(da9052_i2c_fix);
+
 static int da9052_i2c_enable_multiwrite(struct da9052 *da9052)
 {
        int reg_val, ret;
@@ -83,6 +143,7 @@ static int da9052_i2c_probe(struct i2c_client *client,
 
        da9052->dev = &client->dev;
        da9052->chip_irq = client->irq;
+       da9052->fix_io = da9052_i2c_fix;
 
        i2c_set_clientdata(client, da9052);
 
index dc8826d8d69da0d1ee8c29911dc6c95ade7f1da2..268f45d4239427bdb172f65e8c1768d4cd2bd435 100644 (file)
@@ -2524,7 +2524,7 @@ static bool read_mailbox_0(void)
 
                for (n = 0; n < NUM_PRCMU_WAKEUPS; n++) {
                        if (ev & prcmu_irq_bit[n])
-                               generic_handle_irq(IRQ_PRCMU_BASE + n);
+                               generic_handle_irq(irq_find_mapping(db8500_irq_domain, n));
                }
                r = true;
                break;
@@ -2737,13 +2737,14 @@ static int db8500_irq_map(struct irq_domain *d, unsigned int virq,
 }
 
 static struct irq_domain_ops db8500_irq_ops = {
-        .map    = db8500_irq_map,
-        .xlate  = irq_domain_xlate_twocell,
+       .map    = db8500_irq_map,
+       .xlate  = irq_domain_xlate_twocell,
 };
 
 static int db8500_irq_init(struct device_node *np)
 {
-       int irq_base = -1;
+       int irq_base = 0;
+       int i;
 
        /* In the device tree case, just take some IRQs */
        if (!np)
@@ -2758,6 +2759,10 @@ static int db8500_irq_init(struct device_node *np)
                return -ENOSYS;
        }
 
+       /* All wakeups will be used, so create mappings for all */
+       for (i = 0; i < NUM_PRCMU_WAKEUPS; i++)
+               irq_create_mapping(db8500_irq_domain, i);
+
        return 0;
 }
 
index f6878f8db57d105b663d399bc2830bbb0ce0b4bf..4d73963cd8f0188d2f9e09c9bbdcde0cf5c35007 100644 (file)
@@ -93,15 +93,6 @@ static int max77686_i2c_probe(struct i2c_client *i2c,
        if (max77686 == NULL)
                return -ENOMEM;
 
-       max77686->regmap = regmap_init_i2c(i2c, &max77686_regmap_config);
-       if (IS_ERR(max77686->regmap)) {
-               ret = PTR_ERR(max77686->regmap);
-               dev_err(max77686->dev, "Failed to allocate register map: %d\n",
-                               ret);
-               kfree(max77686);
-               return ret;
-       }
-
        i2c_set_clientdata(i2c, max77686);
        max77686->dev = &i2c->dev;
        max77686->i2c = i2c;
@@ -111,6 +102,15 @@ static int max77686_i2c_probe(struct i2c_client *i2c,
        max77686->irq_gpio = pdata->irq_gpio;
        max77686->irq = i2c->irq;
 
+       max77686->regmap = regmap_init_i2c(i2c, &max77686_regmap_config);
+       if (IS_ERR(max77686->regmap)) {
+               ret = PTR_ERR(max77686->regmap);
+               dev_err(max77686->dev, "Failed to allocate register map: %d\n",
+                               ret);
+               kfree(max77686);
+               return ret;
+       }
+
        if (regmap_read(max77686->regmap,
                         MAX77686_REG_DEVICE_ID, &data) < 0) {
                dev_err(max77686->dev,
index cc5155e20494726c2ae6954e64128f61973ebafd..9e60fed5ff82a81dbf774c7d8af7547f12861516 100644 (file)
@@ -114,35 +114,37 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
        u8 reg_data;
        int ret = 0;
 
+       if (!pdata) {
+               dev_err(&i2c->dev, "No platform data found.\n");
+               return -EINVAL;
+       }
+
        max77693 = devm_kzalloc(&i2c->dev,
                        sizeof(struct max77693_dev), GFP_KERNEL);
        if (max77693 == NULL)
                return -ENOMEM;
 
-       max77693->regmap = devm_regmap_init_i2c(i2c, &max77693_regmap_config);
-       if (IS_ERR(max77693->regmap)) {
-               ret = PTR_ERR(max77693->regmap);
-               dev_err(max77693->dev,"failed to allocate register map: %d\n",
-                               ret);
-               goto err_regmap;
-       }
-
        i2c_set_clientdata(i2c, max77693);
        max77693->dev = &i2c->dev;
        max77693->i2c = i2c;
        max77693->irq = i2c->irq;
        max77693->type = id->driver_data;
 
-       if (!pdata)
-               goto err_regmap;
+       max77693->regmap = devm_regmap_init_i2c(i2c, &max77693_regmap_config);
+       if (IS_ERR(max77693->regmap)) {
+               ret = PTR_ERR(max77693->regmap);
+               dev_err(max77693->dev, "failed to allocate register map: %d\n",
+                               ret);
+               return ret;
+       }
 
        max77693->wakeup = pdata->wakeup;
 
-       if (max77693_read_reg(max77693->regmap,
-                               MAX77693_PMIC_REG_PMIC_ID2, &reg_data) < 0) {
+       ret = max77693_read_reg(max77693->regmap, MAX77693_PMIC_REG_PMIC_ID2,
+                               &reg_data);
+       if (ret < 0) {
                dev_err(max77693->dev, "device not found on this channel\n");
-               ret = -ENODEV;
-               goto err_regmap;
+               return ret;
        } else
                dev_info(max77693->dev, "device ID: 0x%x\n", reg_data);
 
@@ -163,7 +165,7 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
                ret = PTR_ERR(max77693->regmap_muic);
                dev_err(max77693->dev,
                        "failed to allocate register map: %d\n", ret);
-               goto err_regmap;
+               goto err_regmap_muic;
        }
 
        ret = max77693_irq_init(max77693);
@@ -184,9 +186,9 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
 err_mfd:
        max77693_irq_exit(max77693);
 err_irq:
+err_regmap_muic:
        i2c_unregister_device(max77693->muic);
        i2c_unregister_device(max77693->haptic);
-err_regmap:
        return ret;
 }
 
index 64803f13bcecc4f6e8f221ecacf814e419d07104..d11567307fbed6c930f955abf198de1157dfb237 100644 (file)
@@ -208,6 +208,8 @@ static int pcf50633_probe(struct i2c_client *client,
        if (!pcf)
                return -ENOMEM;
 
+       i2c_set_clientdata(client, pcf);
+       pcf->dev = &client->dev;
        pcf->pdata = pdata;
 
        mutex_init(&pcf->lock);
@@ -219,9 +221,6 @@ static int pcf50633_probe(struct i2c_client *client,
                return ret;
        }
 
-       i2c_set_clientdata(client, pcf);
-       pcf->dev = &client->dev;
-
        version = pcf50633_reg_read(pcf, 0);
        variant = pcf50633_reg_read(pcf, 1);
        if (version < 0 || variant < 0) {
index 89f046ca9e410292b9b1a51423544ab1a40aebf2..3d3b4addf81a9b73b480ae3874e2675e1678b52b 100644 (file)
@@ -112,6 +112,21 @@ static int rtl8411_card_power_off(struct rtsx_pcr *pcr, int card)
                        BPP_LDO_POWB, BPP_LDO_SUSPEND);
 }
 
+static int rtl8411_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
+{
+       u8 mask, val;
+
+       mask = (BPP_REG_TUNED18 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_MASK;
+       if (voltage == OUTPUT_3V3)
+               val = (BPP_ASIC_3V3 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_3V3;
+       else if (voltage == OUTPUT_1V8)
+               val = (BPP_ASIC_1V8 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_1V8;
+       else
+               return -EINVAL;
+
+       return rtsx_pci_write_register(pcr, LDO_CTL, mask, val);
+}
+
 static unsigned int rtl8411_cd_deglitch(struct rtsx_pcr *pcr)
 {
        unsigned int card_exist;
@@ -163,6 +178,18 @@ static unsigned int rtl8411_cd_deglitch(struct rtsx_pcr *pcr)
        return card_exist;
 }
 
+static int rtl8411_conv_clk_and_div_n(int input, int dir)
+{
+       int output;
+
+       if (dir == CLK_TO_DIV_N)
+               output = input * 4 / 5 - 2;
+       else
+               output = (input + 2) * 5 / 4;
+
+       return output;
+}
+
 static const struct pcr_ops rtl8411_pcr_ops = {
        .extra_init_hw = rtl8411_extra_init_hw,
        .optimize_phy = NULL,
@@ -172,7 +199,9 @@ static const struct pcr_ops rtl8411_pcr_ops = {
        .disable_auto_blink = rtl8411_disable_auto_blink,
        .card_power_on = rtl8411_card_power_on,
        .card_power_off = rtl8411_card_power_off,
+       .switch_output_voltage = rtl8411_switch_output_voltage,
        .cd_deglitch = rtl8411_cd_deglitch,
+       .conv_clk_and_div_n = rtl8411_conv_clk_and_div_n,
 };
 
 /* SD Pull Control Enable:
index 283a4f148084ab29f34d2444d8f264e72345e846..98fe0f39463ed1596f1e0881f5d7352349da400d 100644 (file)
@@ -144,6 +144,25 @@ static int rts5209_card_power_off(struct rtsx_pcr *pcr, int card)
        return rtsx_pci_send_cmd(pcr, 100);
 }
 
+static int rts5209_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
+{
+       int err;
+
+       if (voltage == OUTPUT_3V3) {
+               err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24);
+               if (err < 0)
+                       return err;
+       } else if (voltage == OUTPUT_1V8) {
+               err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24);
+               if (err < 0)
+                       return err;
+       } else {
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 static const struct pcr_ops rts5209_pcr_ops = {
        .extra_init_hw = rts5209_extra_init_hw,
        .optimize_phy = rts5209_optimize_phy,
@@ -153,7 +172,9 @@ static const struct pcr_ops rts5209_pcr_ops = {
        .disable_auto_blink = rts5209_disable_auto_blink,
        .card_power_on = rts5209_card_power_on,
        .card_power_off = rts5209_card_power_off,
+       .switch_output_voltage = rts5209_switch_output_voltage,
        .cd_deglitch = NULL,
+       .conv_clk_and_div_n = NULL,
 };
 
 /* SD Pull Control Enable:
index b9dbab266fdadc9f3f60e219f6dc5e25b9322036..29d889cbb9c5183262897bc5e29818c536bb227d 100644 (file)
@@ -114,6 +114,25 @@ static int rts5229_card_power_off(struct rtsx_pcr *pcr, int card)
        return rtsx_pci_send_cmd(pcr, 100);
 }
 
+static int rts5229_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
+{
+       int err;
+
+       if (voltage == OUTPUT_3V3) {
+               err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24);
+               if (err < 0)
+                       return err;
+       } else if (voltage == OUTPUT_1V8) {
+               err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24);
+               if (err < 0)
+                       return err;
+       } else {
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 static const struct pcr_ops rts5229_pcr_ops = {
        .extra_init_hw = rts5229_extra_init_hw,
        .optimize_phy = rts5229_optimize_phy,
@@ -123,7 +142,9 @@ static const struct pcr_ops rts5229_pcr_ops = {
        .disable_auto_blink = rts5229_disable_auto_blink,
        .card_power_on = rts5229_card_power_on,
        .card_power_off = rts5229_card_power_off,
+       .switch_output_voltage = rts5229_switch_output_voltage,
        .cd_deglitch = NULL,
+       .conv_clk_and_div_n = NULL,
 };
 
 /* SD Pull Control Enable:
index 7a7b0bda4618926fffea21dc23a3f386e1303777..9fc57009e22813fe257481b39352533f2fbd5d45 100644 (file)
@@ -630,7 +630,10 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
        if (clk == pcr->cur_clock)
                return 0;
 
-       N = (u8)(clk - 2);
+       if (pcr->ops->conv_clk_and_div_n)
+               N = (u8)pcr->ops->conv_clk_and_div_n(clk, CLK_TO_DIV_N);
+       else
+               N = (u8)(clk - 2);
        if ((clk <= 2) || (N > max_N))
                return -EINVAL;
 
@@ -641,7 +644,14 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
        /* Make sure that the SSC clock div_n is equal or greater than min_N */
        div = CLK_DIV_1;
        while ((N < min_N) && (div < max_div)) {
-               N = (N + 2) * 2 - 2;
+               if (pcr->ops->conv_clk_and_div_n) {
+                       int dbl_clk = pcr->ops->conv_clk_and_div_n(N,
+                                       DIV_N_TO_CLK) * 2;
+                       N = (u8)pcr->ops->conv_clk_and_div_n(dbl_clk,
+                                       CLK_TO_DIV_N);
+               } else {
+                       N = (N + 2) * 2 - 2;
+               }
                div++;
        }
        dev_dbg(&(pcr->pci->dev), "N = %d, div = %d\n", N, div);
@@ -703,6 +713,15 @@ int rtsx_pci_card_power_off(struct rtsx_pcr *pcr, int card)
 }
 EXPORT_SYMBOL_GPL(rtsx_pci_card_power_off);
 
+int rtsx_pci_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
+{
+       if (pcr->ops->switch_output_voltage)
+               return pcr->ops->switch_output_voltage(pcr, voltage);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_switch_output_voltage);
+
 unsigned int rtsx_pci_card_exist(struct rtsx_pcr *pcr)
 {
        unsigned int val;
@@ -767,10 +786,10 @@ static void rtsx_pci_card_detect(struct work_struct *work)
 
        spin_unlock_irqrestore(&pcr->lock, flags);
 
-       if (card_detect & SD_EXIST)
+       if ((card_detect & SD_EXIST) && pcr->slots[RTSX_SD_CARD].card_event)
                pcr->slots[RTSX_SD_CARD].card_event(
                                pcr->slots[RTSX_SD_CARD].p_dev);
-       if (card_detect & MS_EXIST)
+       if ((card_detect & MS_EXIST) && pcr->slots[RTSX_MS_CARD].card_event)
                pcr->slots[RTSX_MS_CARD].card_event(
                                pcr->slots[RTSX_MS_CARD].p_dev);
 }
index a06d66b929b1ea96743826435d18899464fb24b5..ecc092c7f7453e4cfb7146fc222546869239f8b0 100644 (file)
@@ -219,25 +219,18 @@ static void tc3589x_irq_unmap(struct irq_domain *d, unsigned int virq)
 }
 
 static struct irq_domain_ops tc3589x_irq_ops = {
-        .map    = tc3589x_irq_map,
+       .map    = tc3589x_irq_map,
        .unmap  = tc3589x_irq_unmap,
-        .xlate  = irq_domain_xlate_twocell,
+       .xlate  = irq_domain_xlate_twocell,
 };
 
 static int tc3589x_irq_init(struct tc3589x *tc3589x, struct device_node *np)
 {
        int base = tc3589x->irq_base;
 
-       if (base) {
-               tc3589x->domain = irq_domain_add_legacy(
-                       NULL, TC3589x_NR_INTERNAL_IRQS, base,
-                       0, &tc3589x_irq_ops, tc3589x);
-       }
-       else {
-               tc3589x->domain = irq_domain_add_linear(
-                       np, TC3589x_NR_INTERNAL_IRQS,
-                       &tc3589x_irq_ops, tc3589x);
-       }
+       tc3589x->domain = irq_domain_add_simple(
+               np, TC3589x_NR_INTERNAL_IRQS, base,
+               &tc3589x_irq_ops, tc3589x);
 
        if (!tc3589x->domain) {
                dev_err(tc3589x->dev, "Failed to create irqdomain\n");
index 4dae241e501734f66c9080283a0c43188729b0b5..dd362c1078e1438b3751ec69dc1c8b1ad3efa0bb 100644 (file)
@@ -159,7 +159,7 @@ out:
 static int twl4030_write_script(u8 address, struct twl4030_ins *script,
                                       int len)
 {
-       int err;
+       int err = -EINVAL;
 
        for (; len; len--, address++, script++) {
                if (len == 1) {
index fae15d880758cc197ed0bfe8e095daca74f01bd5..3c1723aa62250c28c61aab4b3f83442e28770dc8 100644 (file)
@@ -67,6 +67,7 @@ struct vexpress_config_bridge *vexpress_config_bridge_register(
 
        return bridge;
 }
+EXPORT_SYMBOL(vexpress_config_bridge_register);
 
 void vexpress_config_bridge_unregister(struct vexpress_config_bridge *bridge)
 {
@@ -83,6 +84,7 @@ void vexpress_config_bridge_unregister(struct vexpress_config_bridge *bridge)
        while (!list_empty(&__bridge.transactions))
                cpu_relax();
 }
+EXPORT_SYMBOL(vexpress_config_bridge_unregister);
 
 
 struct vexpress_config_func {
@@ -142,6 +144,7 @@ struct vexpress_config_func *__vexpress_config_func_get(struct device *dev,
 
        return func;
 }
+EXPORT_SYMBOL(__vexpress_config_func_get);
 
 void vexpress_config_func_put(struct vexpress_config_func *func)
 {
@@ -149,7 +152,7 @@ void vexpress_config_func_put(struct vexpress_config_func *func)
        of_node_put(func->bridge->node);
        kfree(func);
 }
-
+EXPORT_SYMBOL(vexpress_config_func_put);
 
 struct vexpress_config_trans {
        struct vexpress_config_func *func;
@@ -229,6 +232,7 @@ void vexpress_config_complete(struct vexpress_config_bridge *bridge,
 
        complete(&trans->completion);
 }
+EXPORT_SYMBOL(vexpress_config_complete);
 
 int vexpress_config_wait(struct vexpress_config_trans *trans)
 {
@@ -236,7 +240,7 @@ int vexpress_config_wait(struct vexpress_config_trans *trans)
 
        return trans->status;
 }
-
+EXPORT_SYMBOL(vexpress_config_wait);
 
 int vexpress_config_read(struct vexpress_config_func *func, int offset,
                u32 *data)
index 088872ab63389e49d04dd3f38fb02664fdc929ba..1133a64c2dc9388609ff125c480a82840d9285d1 100644 (file)
@@ -1882,7 +1882,7 @@ static bool wm5102_volatile_register(struct device *dev, unsigned int reg)
        }
 }
 
-#define WM5102_MAX_REGISTER 0x1a8fff
+#define WM5102_MAX_REGISTER 0x1a9800
 
 const struct regmap_config wm5102_spi_regmap = {
        .reg_bits = 32,
index 571915dfb218382f0d29ea72136b05669b9271ea..f74b5adca64232dd4a8ab7d4a397281b8f02c7a0 100644 (file)
@@ -1060,26 +1060,6 @@ static int sd_wait_voltage_stable_2(struct realtek_pci_sdmmc *host)
        return 0;
 }
 
-static int sd_change_bank_voltage(struct realtek_pci_sdmmc *host, u8 voltage)
-{
-       struct rtsx_pcr *pcr = host->pcr;
-       int err;
-
-       if (voltage == SD_IO_3V3) {
-               err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24);
-               if (err < 0)
-                       return err;
-       } else if (voltage == SD_IO_1V8) {
-               err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24);
-               if (err < 0)
-                       return err;
-       } else {
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
 static int sdmmc_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
 {
        struct realtek_pci_sdmmc *host = mmc_priv(mmc);
@@ -1098,11 +1078,11 @@ static int sdmmc_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
        rtsx_pci_start_run(pcr);
 
        if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330)
-               voltage = SD_IO_3V3;
+               voltage = OUTPUT_3V3;
        else
-               voltage = SD_IO_1V8;
+               voltage = OUTPUT_1V8;
 
-       if (voltage == SD_IO_1V8) {
+       if (voltage == OUTPUT_1V8) {
                err = rtsx_pci_write_register(pcr,
                                SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B);
                if (err < 0)
@@ -1113,11 +1093,11 @@ static int sdmmc_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
                        goto out;
        }
 
-       err = sd_change_bank_voltage(host, voltage);
+       err = rtsx_pci_switch_output_voltage(pcr, voltage);
        if (err < 0)
                goto out;
 
-       if (voltage == SD_IO_1V8) {
+       if (voltage == OUTPUT_1V8) {
                err = sd_wait_voltage_stable_2(host);
                if (err < 0)
                        goto out;
index 5233b8f58d773b6edb44f306f477674f05415084..58607f196c9ee5e5c3d214c70ca9abe0e2a5b6d0 100644 (file)
@@ -960,7 +960,7 @@ static int c_can_handle_bus_err(struct net_device *dev,
                break;
        case LEC_ACK_ERROR:
                netdev_dbg(dev, "ack error\n");
-               cf->data[2] |= (CAN_ERR_PROT_LOC_ACK |
+               cf->data[3] |= (CAN_ERR_PROT_LOC_ACK |
                                CAN_ERR_PROT_LOC_ACK_DEL);
                break;
        case LEC_BIT1_ERROR:
@@ -973,7 +973,7 @@ static int c_can_handle_bus_err(struct net_device *dev,
                break;
        case LEC_CRC_ERROR:
                netdev_dbg(dev, "CRC error\n");
-               cf->data[2] |= (CAN_ERR_PROT_LOC_CRC_SEQ |
+               cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ |
                                CAN_ERR_PROT_LOC_CRC_DEL);
                break;
        default:
index 7d1748575b1fffc45f38351ea3f071269545548a..5c314a961970b0041c7776da283979f00c4114f8 100644 (file)
@@ -560,7 +560,7 @@ static void pch_can_error(struct net_device *ndev, u32 status)
                stats->rx_errors++;
                break;
        case PCH_CRC_ERR:
-               cf->data[2] |= CAN_ERR_PROT_LOC_CRC_SEQ |
+               cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ |
                               CAN_ERR_PROT_LOC_CRC_DEL;
                priv->can.can_stats.bus_error++;
                stats->rx_errors++;
index f898c6363729b2a41be58c824f3f3bb145a95897..300581b24ff32860447e3646079024646e77a592 100644 (file)
@@ -746,12 +746,12 @@ static int ti_hecc_error(struct net_device *ndev, int int_status,
                }
                if (err_status & HECC_CANES_CRCE) {
                        hecc_set_bit(priv, HECC_CANES, HECC_CANES_CRCE);
-                       cf->data[2] |= CAN_ERR_PROT_LOC_CRC_SEQ |
+                       cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ |
                                        CAN_ERR_PROT_LOC_CRC_DEL;
                }
                if (err_status & HECC_CANES_ACKE) {
                        hecc_set_bit(priv, HECC_CANES, HECC_CANES_ACKE);
-                       cf->data[2] |= CAN_ERR_PROT_LOC_ACK |
+                       cf->data[3] |= CAN_ERR_PROT_LOC_ACK |
                                        CAN_ERR_PROT_LOC_ACK_DEL;
                }
        }
index 66df936380859b55ab0b8b15595319bfeb98c98a..ffd8de28a76ad2c69a96daab3c59dbe29127faa1 100644 (file)
@@ -432,7 +432,7 @@ static int tc574_config(struct pcmcia_device *link)
        netdev_info(dev, "%s at io %#3lx, irq %d, hw_addr %pM\n",
                    cardname, dev->base_addr, dev->irq, dev->dev_addr);
        netdev_info(dev, " %dK FIFO split %s Rx:Tx, %sMII interface.\n",
-                   8 << config & Ram_size,
+                   8 << (config & Ram_size),
                    ram_split[(config & Ram_split) >> Ram_split_shift],
                    config & Autoselect ? "autoselect " : "");
 
index 78ea90c40e1902af09272a80b09010da52ae6c6b..bdb086934cd95de72cd1aa02cf1cb4b6baaaafc3 100644 (file)
@@ -1283,14 +1283,26 @@ static int tg3_phy_auxctl_write(struct tg3 *tp, int reg, u32 set)
        return tg3_writephy(tp, MII_TG3_AUX_CTRL, set | reg);
 }
 
-#define TG3_PHY_AUXCTL_SMDSP_ENABLE(tp) \
-       tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL, \
-                            MII_TG3_AUXCTL_ACTL_SMDSP_ENA | \
-                            MII_TG3_AUXCTL_ACTL_TX_6DB)
+static int tg3_phy_toggle_auxctl_smdsp(struct tg3 *tp, bool enable)
+{
+       u32 val;
+       int err;
 
-#define TG3_PHY_AUXCTL_SMDSP_DISABLE(tp) \
-       tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL, \
-                            MII_TG3_AUXCTL_ACTL_TX_6DB);
+       err = tg3_phy_auxctl_read(tp, MII_TG3_AUXCTL_SHDWSEL_AUXCTL, &val);
+
+       if (err)
+               return err;
+       if (enable)
+
+               val |= MII_TG3_AUXCTL_ACTL_SMDSP_ENA;
+       else
+               val &= ~MII_TG3_AUXCTL_ACTL_SMDSP_ENA;
+
+       err = tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL,
+                                  val | MII_TG3_AUXCTL_ACTL_TX_6DB);
+
+       return err;
+}
 
 static int tg3_bmcr_reset(struct tg3 *tp)
 {
@@ -2223,7 +2235,7 @@ static void tg3_phy_apply_otp(struct tg3 *tp)
 
        otp = tp->phy_otp;
 
-       if (TG3_PHY_AUXCTL_SMDSP_ENABLE(tp))
+       if (tg3_phy_toggle_auxctl_smdsp(tp, true))
                return;
 
        phy = ((otp & TG3_OTP_AGCTGT_MASK) >> TG3_OTP_AGCTGT_SHIFT);
@@ -2248,7 +2260,7 @@ static void tg3_phy_apply_otp(struct tg3 *tp)
              ((otp & TG3_OTP_RCOFF_MASK) >> TG3_OTP_RCOFF_SHIFT);
        tg3_phydsp_write(tp, MII_TG3_DSP_EXP97, phy);
 
-       TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
+       tg3_phy_toggle_auxctl_smdsp(tp, false);
 }
 
 static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up)
@@ -2284,9 +2296,9 @@ static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up)
 
        if (!tp->setlpicnt) {
                if (current_link_up == 1 &&
-                  !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
+                  !tg3_phy_toggle_auxctl_smdsp(tp, true)) {
                        tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0000);
-                       TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
+                       tg3_phy_toggle_auxctl_smdsp(tp, false);
                }
 
                val = tr32(TG3_CPMU_EEE_MODE);
@@ -2302,11 +2314,11 @@ static void tg3_phy_eee_enable(struct tg3 *tp)
            (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
             GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
             tg3_flag(tp, 57765_CLASS)) &&
-           !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
+           !tg3_phy_toggle_auxctl_smdsp(tp, true)) {
                val = MII_TG3_DSP_TAP26_ALNOKO |
                      MII_TG3_DSP_TAP26_RMRXSTO;
                tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val);
-               TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
+               tg3_phy_toggle_auxctl_smdsp(tp, false);
        }
 
        val = tr32(TG3_CPMU_EEE_MODE);
@@ -2450,7 +2462,7 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
                tg3_writephy(tp, MII_CTRL1000,
                             CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER);
 
-               err = TG3_PHY_AUXCTL_SMDSP_ENABLE(tp);
+               err = tg3_phy_toggle_auxctl_smdsp(tp, true);
                if (err)
                        return err;
 
@@ -2471,7 +2483,7 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
        tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8200);
        tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0000);
 
-       TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
+       tg3_phy_toggle_auxctl_smdsp(tp, false);
 
        tg3_writephy(tp, MII_CTRL1000, phy9_orig);
 
@@ -2572,10 +2584,10 @@ static int tg3_phy_reset(struct tg3 *tp)
 
 out:
        if ((tp->phy_flags & TG3_PHYFLG_ADC_BUG) &&
-           !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
+           !tg3_phy_toggle_auxctl_smdsp(tp, true)) {
                tg3_phydsp_write(tp, 0x201f, 0x2aaa);
                tg3_phydsp_write(tp, 0x000a, 0x0323);
-               TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
+               tg3_phy_toggle_auxctl_smdsp(tp, false);
        }
 
        if (tp->phy_flags & TG3_PHYFLG_5704_A0_BUG) {
@@ -2584,14 +2596,14 @@ out:
        }
 
        if (tp->phy_flags & TG3_PHYFLG_BER_BUG) {
-               if (!TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
+               if (!tg3_phy_toggle_auxctl_smdsp(tp, true)) {
                        tg3_phydsp_write(tp, 0x000a, 0x310b);
                        tg3_phydsp_write(tp, 0x201f, 0x9506);
                        tg3_phydsp_write(tp, 0x401f, 0x14e2);
-                       TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
+                       tg3_phy_toggle_auxctl_smdsp(tp, false);
                }
        } else if (tp->phy_flags & TG3_PHYFLG_JITTER_BUG) {
-               if (!TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
+               if (!tg3_phy_toggle_auxctl_smdsp(tp, true)) {
                        tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a);
                        if (tp->phy_flags & TG3_PHYFLG_ADJUST_TRIM) {
                                tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x110b);
@@ -2600,7 +2612,7 @@ out:
                        } else
                                tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x010b);
 
-                       TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
+                       tg3_phy_toggle_auxctl_smdsp(tp, false);
                }
        }
 
@@ -4009,7 +4021,7 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl)
        tw32(TG3_CPMU_EEE_MODE,
             tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE);
 
-       err = TG3_PHY_AUXCTL_SMDSP_ENABLE(tp);
+       err = tg3_phy_toggle_auxctl_smdsp(tp, true);
        if (!err) {
                u32 err2;
 
@@ -4042,7 +4054,7 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl)
                                                 MII_TG3_DSP_CH34TP2_HIBW01);
                }
 
-               err2 = TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
+               err2 = tg3_phy_toggle_auxctl_smdsp(tp, false);
                if (!err)
                        err = err2;
        }
@@ -6950,6 +6962,9 @@ static void tg3_poll_controller(struct net_device *dev)
        int i;
        struct tg3 *tp = netdev_priv(dev);
 
+       if (tg3_irq_sync(tp))
+               return;
+
        for (i = 0; i < tp->irq_cnt; i++)
                tg3_interrupt(tp->napi[i].irq_vec, &tp->napi[i]);
 }
@@ -16367,6 +16382,7 @@ static int tg3_init_one(struct pci_dev *pdev,
        tp->pm_cap = pm_cap;
        tp->rx_mode = TG3_DEF_RX_MODE;
        tp->tx_mode = TG3_DEF_TX_MODE;
+       tp->irq_sync = 1;
 
        if (tg3_debug > 0)
                tp->msg_enable = tg3_debug;
index b407043ce9b0df3c1286fb3c0051f012cfa5e5b0..f7f02900f6508f0c8a7f8b6b41558aa85550e291 100644 (file)
@@ -548,6 +548,10 @@ static int desc_get_rx_status(struct xgmac_priv *priv, struct xgmac_dma_desc *p)
                return -1;
        }
 
+       /* All frames should fit into a single buffer */
+       if (!(status & RXDESC_FIRST_SEG) || !(status & RXDESC_LAST_SEG))
+               return -1;
+
        /* Check if packet has checksum already */
        if ((status & RXDESC_FRAME_TYPE) && (status & RXDESC_EXT_STATUS) &&
                !(ext_status & RXDESC_IP_PAYLOAD_MASK))
index f0718e1a83696b0e2ec0b8fad9121288ecda81bc..c306df7d45684ce1fcd2f25012e8100da98abdd2 100644 (file)
@@ -1994,9 +1994,20 @@ static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
 {
        const struct port_info *pi = netdev_priv(dev);
        struct adapter *adap = pi->adapter;
-
-       return set_rxq_intr_params(adap, &adap->sge.ethrxq[pi->first_qset].rspq,
-                       c->rx_coalesce_usecs, c->rx_max_coalesced_frames);
+       struct sge_rspq *q;
+       int i;
+       int r = 0;
+
+       for (i = pi->first_qset; i < pi->first_qset + pi->nqsets; i++) {
+               q = &adap->sge.ethrxq[i].rspq;
+               r = set_rxq_intr_params(adap, q, c->rx_coalesce_usecs,
+                       c->rx_max_coalesced_frames);
+               if (r) {
+                       dev_err(&dev->dev, "failed to set coalesce %d\n", r);
+                       break;
+               }
+       }
+       return r;
 }
 
 static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
index f3a632bf8d96f8bd76983e8990c80f1cefe984ac..687c83d1bdabb7589ac4492e9763b863ac5fcef0 100644 (file)
@@ -32,7 +32,7 @@
 
 obj-$(CONFIG_IXGBE) += ixgbe.o
 
-ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o ixgbe_debugfs.o\
+ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \
               ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \
               ixgbe_mbx.o ixgbe_x540.o ixgbe_lib.o ixgbe_ptp.o
 
@@ -40,4 +40,5 @@ ixgbe-$(CONFIG_IXGBE_DCB) +=  ixgbe_dcb.o ixgbe_dcb_82598.o \
                               ixgbe_dcb_82599.o ixgbe_dcb_nl.o
 
 ixgbe-$(CONFIG_IXGBE_HWMON) += ixgbe_sysfs.o
+ixgbe-$(CONFIG_DEBUG_FS) += ixgbe_debugfs.o
 ixgbe-$(CONFIG_FCOE:m=y) += ixgbe_fcoe.o
index 50aa546b8c7a589100be6bd88eac590adf314d98..3504686d3af515ed7f5e04924be29cd9098f2061 100644 (file)
@@ -24,9 +24,6 @@
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
-
-#ifdef CONFIG_DEBUG_FS
-
 #include <linux/debugfs.h>
 #include <linux/module.h>
 
@@ -277,5 +274,3 @@ void ixgbe_dbg_exit(void)
 {
        debugfs_remove_recursive(ixgbe_dbg_root);
 }
-
-#endif /* CONFIG_DEBUG_FS */
index 1a751c9d09c47f319e45d76a9c2bbad8573016d3..bb9256a1b0a9b467412ce127911ed3cfb53a7053 100644 (file)
@@ -660,11 +660,11 @@ int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter,
                break;
        case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
                tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1;
-               tsync_rx_mtrl = IXGBE_RXMTRL_V1_SYNC_MSG;
+               tsync_rx_mtrl |= IXGBE_RXMTRL_V1_SYNC_MSG;
                break;
        case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
                tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1;
-               tsync_rx_mtrl = IXGBE_RXMTRL_V1_DELAY_REQ_MSG;
+               tsync_rx_mtrl |= IXGBE_RXMTRL_V1_DELAY_REQ_MSG;
                break;
        case HWTSTAMP_FILTER_PTP_V2_EVENT:
        case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
index 2b799f4f1c37100f06eab93aef628d4124182230..6771b69f40d562bf58909a1f806bddd1ace9ea65 100644 (file)
@@ -630,10 +630,15 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
                ring->tx_csum++;
        }
 
-       /* Copy dst mac address to wqe */
-       ethh = (struct ethhdr *)skb->data;
-       tx_desc->ctrl.srcrb_flags16[0] = get_unaligned((__be16 *)ethh->h_dest);
-       tx_desc->ctrl.imm = get_unaligned((__be32 *)(ethh->h_dest + 2));
+       if (mlx4_is_mfunc(mdev->dev) || priv->validate_loopback) {
+               /* Copy dst mac address to wqe. This allows loopback in eSwitch,
+                * so that VFs and PF can communicate with each other
+                */
+               ethh = (struct ethhdr *)skb->data;
+               tx_desc->ctrl.srcrb_flags16[0] = get_unaligned((__be16 *)ethh->h_dest);
+               tx_desc->ctrl.imm = get_unaligned((__be32 *)(ethh->h_dest + 2));
+       }
+
        /* Handle LSO (TSO) packets */
        if (lso_header_size) {
                /* Mark opcode as LSO */
index e1bafffbc3b1d261f4cf0972dd3f95c942c5fc3d..a6542d75374cdce3f7a17c21f7022fadff109850 100644 (file)
@@ -1790,15 +1790,8 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev)
        int i;
 
        if (msi_x) {
-               /* In multifunction mode each function gets 2 msi-X vectors
-                * one for data path completions anf the other for asynch events
-                * or command completions */
-               if (mlx4_is_mfunc(dev)) {
-                       nreq = 2;
-               } else {
-                       nreq = min_t(int, dev->caps.num_eqs -
-                                    dev->caps.reserved_eqs, nreq);
-               }
+               nreq = min_t(int, dev->caps.num_eqs - dev->caps.reserved_eqs,
+                            nreq);
 
                entries = kcalloc(nreq, sizeof *entries, GFP_KERNEL);
                if (!entries)
index bc165f4d0f65cebb6cc82e3aa99590863963f767..695667d471a1bef8dc81dd8034a593a118993e07 100644 (file)
@@ -144,7 +144,7 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter)
                                         buffrag->length, PCI_DMA_TODEVICE);
                        buffrag->dma = 0ULL;
                }
-               for (j = 0; j < cmd_buf->frag_count; j++) {
+               for (j = 1; j < cmd_buf->frag_count; j++) {
                        buffrag++;
                        if (buffrag->dma) {
                                pci_unmap_page(adapter->pdev, buffrag->dma,
index 6098fd4adfeb89ef5ed9c15407799ddbdcf02e7a..69e321a650779c9d3bae975a273035b922fca08f 100644 (file)
@@ -1963,10 +1963,12 @@ unwind:
        while (--i >= 0) {
                nf = &pbuf->frag_array[i+1];
                pci_unmap_page(pdev, nf->dma, nf->length, PCI_DMA_TODEVICE);
+               nf->dma = 0ULL;
        }
 
        nf = &pbuf->frag_array[0];
        pci_unmap_single(pdev, nf->dma, skb_headlen(skb), PCI_DMA_TODEVICE);
+       nf->dma = 0ULL;
 
 out_err:
        return -ENOMEM;
index ed96f309bca8e030a0c098df8b8e728314f04bb0..11702324a071b87deff9ef13f919be57e99b024b 100644 (file)
@@ -1826,8 +1826,6 @@ static void rtl8169_rx_vlan_tag(struct RxDesc *desc, struct sk_buff *skb)
 
        if (opts2 & RxVlanTag)
                __vlan_hwaccel_put_tag(skb, swab16(opts2 & 0xffff));
-
-       desc->opts2 = 0;
 }
 
 static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
@@ -6064,8 +6062,6 @@ static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, u32 budget
                            !(status & (RxRWT | RxFOVF)) &&
                            (dev->features & NETIF_F_RXALL))
                                goto process_pkt;
-
-                       rtl8169_mark_to_asic(desc, rx_buf_sz);
                } else {
                        struct sk_buff *skb;
                        dma_addr_t addr;
@@ -6086,16 +6082,14 @@ process_pkt:
                        if (unlikely(rtl8169_fragmented_frame(status))) {
                                dev->stats.rx_dropped++;
                                dev->stats.rx_length_errors++;
-                               rtl8169_mark_to_asic(desc, rx_buf_sz);
-                               continue;
+                               goto release_descriptor;
                        }
 
                        skb = rtl8169_try_rx_copy(tp->Rx_databuff[entry],
                                                  tp, pkt_size, addr);
-                       rtl8169_mark_to_asic(desc, rx_buf_sz);
                        if (!skb) {
                                dev->stats.rx_dropped++;
-                               continue;
+                               goto release_descriptor;
                        }
 
                        rtl8169_rx_csum(skb, status);
@@ -6111,13 +6105,10 @@ process_pkt:
                        tp->rx_stats.bytes += pkt_size;
                        u64_stats_update_end(&tp->rx_stats.syncp);
                }
-
-               /* Work around for AMD plateform. */
-               if ((desc->opts2 & cpu_to_le32(0xfffe000)) &&
-                   (tp->mac_version == RTL_GIGA_MAC_VER_05)) {
-                       desc->opts2 = 0;
-                       cur_rx++;
-               }
+release_descriptor:
+               desc->opts2 = 0;
+               wmb();
+               rtl8169_mark_to_asic(desc, rx_buf_sz);
        }
 
        count = cur_rx - tp->cur_rx;
index 5fd6f4674326f0d3236ae8a97127b842ffffa008..e6fe0d80d6122fcd8dfcf7bb65fa71dac68c1e73 100644 (file)
@@ -84,7 +84,7 @@ struct hv_netvsc_packet {
 };
 
 struct netvsc_device_info {
-       unsigned char mac_adr[6];
+       unsigned char mac_adr[ETH_ALEN];
        bool link_state;        /* 0 - link up, 1 - link down */
        int  ring_size;
 };
index f825a629a699cfe5fac73803353da4b47ca18974..8264f0ef7692f5c832a12336a1188f9c7620190f 100644 (file)
@@ -349,7 +349,7 @@ static int netvsc_set_mac_addr(struct net_device *ndev, void *p)
        struct net_device_context *ndevctx = netdev_priv(ndev);
        struct hv_device *hdev =  ndevctx->device_ctx;
        struct sockaddr *addr = p;
-       char save_adr[14];
+       char save_adr[ETH_ALEN];
        unsigned char save_aatype;
        int err;
 
index 81f8f9e31db510892acae3cdb39a799de7e21be9..fcbf680c3e62f73af4933896641045de34f1f68c 100644 (file)
@@ -77,6 +77,11 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb,
 
        skb_orphan(skb);
 
+       /* Before queueing this packet to netif_rx(),
+        * make sure dst is refcounted.
+        */
+       skb_dst_force(skb);
+
        skb->protocol = eth_type_trans(skb, dev);
 
        /* it's OK to use per_cpu_ptr() because BHs are off */
index 68a43fe602e7a89ccffa54d1a5b82e2da4e5330c..d3fb97d97cbcb61f68deda7c3009a83393515656 100644 (file)
@@ -822,7 +822,10 @@ static int macvlan_changelink(struct net_device *dev,
 
 static size_t macvlan_get_size(const struct net_device *dev)
 {
-       return nla_total_size(4);
+       return (0
+               + nla_total_size(4) /* IFLA_MACVLAN_MODE */
+               + nla_total_size(2) /* IFLA_MACVLAN_FLAGS */
+               );
 }
 
 static int macvlan_fill_info(struct sk_buff *skb,
index d5199cb4caecd06c1774295765476d3a508e4a10..b5ddd5077a80dd9c6324c92e68a1ecd8a03314e7 100644 (file)
@@ -36,8 +36,9 @@ MODULE_LICENSE("GPL");
 
 /* IP101A/G - IP1001 */
 #define IP10XX_SPEC_CTRL_STATUS                16      /* Spec. Control Register */
+#define IP1001_RXPHASE_SEL             (1<<0)  /* Add delay on RX_CLK */
+#define IP1001_TXPHASE_SEL             (1<<1)  /* Add delay on TX_CLK */
 #define IP1001_SPEC_CTRL_STATUS_2      20      /* IP1001 Spec. Control Reg 2 */
-#define IP1001_PHASE_SEL_MASK          3       /* IP1001 RX/TXPHASE_SEL */
 #define IP1001_APS_ON                  11      /* IP1001 APS Mode  bit */
 #define IP101A_G_APS_ON                        2       /* IP101A/G APS Mode bit */
 #define IP101A_G_IRQ_CONF_STATUS       0x11    /* Conf Info IRQ & Status Reg */
@@ -138,19 +139,24 @@ static int ip1001_config_init(struct phy_device *phydev)
        if (c < 0)
                return c;
 
-       /* INTR pin used: speed/link/duplex will cause an interrupt */
-       c = phy_write(phydev, IP101A_G_IRQ_CONF_STATUS, IP101A_G_IRQ_DEFAULT);
-       if (c < 0)
-               return c;
+       if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
+           (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
+           (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
+           (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) {
 
-       if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
-               /* Additional delay (2ns) used to adjust RX clock phase
-                * at RGMII interface */
                c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);
                if (c < 0)
                        return c;
 
-               c |= IP1001_PHASE_SEL_MASK;
+               c &= ~(IP1001_RXPHASE_SEL | IP1001_TXPHASE_SEL);
+
+               if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
+                       c |= (IP1001_RXPHASE_SEL | IP1001_TXPHASE_SEL);
+               else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
+                       c |= IP1001_RXPHASE_SEL;
+               else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
+                       c |= IP1001_TXPHASE_SEL;
+
                c = phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c);
                if (c < 0)
                        return c;
@@ -167,6 +173,11 @@ static int ip101a_g_config_init(struct phy_device *phydev)
        if (c < 0)
                return c;
 
+       /* INTR pin used: speed/link/duplex will cause an interrupt */
+       c = phy_write(phydev, IP101A_G_IRQ_CONF_STATUS, IP101A_G_IRQ_DEFAULT);
+       if (c < 0)
+               return c;
+
        /* Enable Auto Power Saving mode */
        c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);
        c |= IP101A_G_APS_ON;
index 5d2a3f2158876bb39ffc02f2647a57676b1bb718..22dec9c7ef05d7480e87b575605e2240f4476a20 100644 (file)
@@ -353,15 +353,6 @@ static int m88e1111_config_init(struct phy_device *phydev)
        int err;
        int temp;
 
-       /* Enable Fiber/Copper auto selection */
-       temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
-       temp &= ~MII_M1111_HWCFG_FIBER_COPPER_AUTO;
-       phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
-
-       temp = phy_read(phydev, MII_BMCR);
-       temp |= BMCR_RESET;
-       phy_write(phydev, MII_BMCR, temp);
-
        if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
            (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
            (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
index af372d0957fe3c6c7bc47e12df7d2c1e827c7f20..cc09b67c23bcd30402d73a93594f7aef9cb100da 100644 (file)
@@ -109,11 +109,11 @@ struct tap_filter {
        unsigned char   addr[FLT_EXACT_COUNT][ETH_ALEN];
 };
 
-/* 1024 is probably a high enough limit: modern hypervisors seem to support on
- * the order of 100-200 CPUs so this leaves us some breathing space if we want
- * to match a queue per guest CPU.
- */
-#define MAX_TAP_QUEUES 1024
+/* DEFAULT_MAX_NUM_RSS_QUEUES were choosed to let the rx/tx queues allocated for
+ * the netdevice to be fit in one page. So we can make sure the success of
+ * memory allocation. TODO: increase the limit. */
+#define MAX_TAP_QUEUES DEFAULT_MAX_NUM_RSS_QUEUES
+#define MAX_TAP_FLOWS  4096
 
 #define TUN_FLOW_EXPIRE (3 * HZ)
 
@@ -185,6 +185,8 @@ struct tun_struct {
        unsigned long ageing_time;
        unsigned int numdisabled;
        struct list_head disabled;
+       void *security;
+       u32 flow_count;
 };
 
 static inline u32 tun_hashfn(u32 rxhash)
@@ -218,6 +220,7 @@ static struct tun_flow_entry *tun_flow_create(struct tun_struct *tun,
                e->queue_index = queue_index;
                e->tun = tun;
                hlist_add_head_rcu(&e->hash_link, head);
+               ++tun->flow_count;
        }
        return e;
 }
@@ -228,6 +231,7 @@ static void tun_flow_delete(struct tun_struct *tun, struct tun_flow_entry *e)
                  e->rxhash, e->queue_index);
        hlist_del_rcu(&e->hash_link);
        kfree_rcu(e, rcu);
+       --tun->flow_count;
 }
 
 static void tun_flow_flush(struct tun_struct *tun)
@@ -317,7 +321,8 @@ static void tun_flow_update(struct tun_struct *tun, u32 rxhash,
                e->updated = jiffies;
        } else {
                spin_lock_bh(&tun->lock);
-               if (!tun_flow_find(head, rxhash))
+               if (!tun_flow_find(head, rxhash) &&
+                   tun->flow_count < MAX_TAP_FLOWS)
                        tun_flow_create(tun, head, rxhash, queue_index);
 
                if (!timer_pending(&tun->flow_gc_timer))
@@ -490,6 +495,10 @@ static int tun_attach(struct tun_struct *tun, struct file *file)
        struct tun_file *tfile = file->private_data;
        int err;
 
+       err = security_tun_dev_attach(tfile->socket.sk, tun->security);
+       if (err < 0)
+               goto out;
+
        err = -EINVAL;
        if (rtnl_dereference(tfile->tun))
                goto out;
@@ -1373,6 +1382,7 @@ static void tun_free_netdev(struct net_device *dev)
 
        BUG_ON(!(list_empty(&tun->disabled)));
        tun_flow_uninit(tun);
+       security_tun_dev_free_security(tun->security);
        free_netdev(dev);
 }
 
@@ -1562,7 +1572,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 
                if (tun_not_capable(tun))
                        return -EPERM;
-               err = security_tun_dev_attach(tfile->socket.sk);
+               err = security_tun_dev_open(tun->security);
                if (err < 0)
                        return err;
 
@@ -1577,6 +1587,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
        else {
                char *name;
                unsigned long flags = 0;
+               int queues = ifr->ifr_flags & IFF_MULTI_QUEUE ?
+                            MAX_TAP_QUEUES : 1;
 
                if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
                        return -EPERM;
@@ -1600,8 +1612,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
                        name = ifr->ifr_name;
 
                dev = alloc_netdev_mqs(sizeof(struct tun_struct), name,
-                                      tun_setup,
-                                      MAX_TAP_QUEUES, MAX_TAP_QUEUES);
+                                      tun_setup, queues, queues);
+
                if (!dev)
                        return -ENOMEM;
 
@@ -1619,7 +1631,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 
                spin_lock_init(&tun->lock);
 
-               security_tun_dev_post_create(&tfile->sk);
+               err = security_tun_dev_alloc_security(&tun->security);
+               if (err < 0)
+                       goto err_free_dev;
 
                tun_net_init(dev);
 
@@ -1789,10 +1803,14 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr)
 
        if (ifr->ifr_flags & IFF_ATTACH_QUEUE) {
                tun = tfile->detached;
-               if (!tun)
+               if (!tun) {
                        ret = -EINVAL;
-               else
-                       ret = tun_attach(tun, file);
+                       goto unlock;
+               }
+               ret = security_tun_dev_attach_queue(tun->security);
+               if (ret < 0)
+                       goto unlock;
+               ret = tun_attach(tun, file);
        } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) {
                tun = rtnl_dereference(tfile->tun);
                if (!tun || !(tun->flags & TUN_TAP_MQ))
@@ -1802,6 +1820,7 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr)
        } else
                ret = -EINVAL;
 
+unlock:
        rtnl_unlock();
        return ret;
 }
index 42f51c71ec1fc7444c668153bdaa200a2b0f4315..248d2dc765a5c06c64ab3c27c47f38d36bf14c20 100644 (file)
@@ -374,6 +374,21 @@ static const struct driver_info cdc_mbim_info = {
        .tx_fixup = cdc_mbim_tx_fixup,
 };
 
+/* MBIM and NCM devices should not need a ZLP after NTBs with
+ * dwNtbOutMaxSize length. This driver_info is for the exceptional
+ * devices requiring it anyway, allowing them to be supported without
+ * forcing the performance penalty on all the sane devices.
+ */
+static const struct driver_info cdc_mbim_info_zlp = {
+       .description = "CDC MBIM",
+       .flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN | FLAG_SEND_ZLP,
+       .bind = cdc_mbim_bind,
+       .unbind = cdc_mbim_unbind,
+       .manage_power = cdc_mbim_manage_power,
+       .rx_fixup = cdc_mbim_rx_fixup,
+       .tx_fixup = cdc_mbim_tx_fixup,
+};
+
 static const struct usb_device_id mbim_devs[] = {
        /* This duplicate NCM entry is intentional. MBIM devices can
         * be disguised as NCM by default, and this is necessary to
@@ -385,6 +400,10 @@ static const struct usb_device_id mbim_devs[] = {
        { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
          .driver_info = (unsigned long)&cdc_mbim_info,
        },
+       /* Sierra Wireless MC7710 need ZLPs */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x68a2, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
+         .driver_info = (unsigned long)&cdc_mbim_info_zlp,
+       },
        { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
          .driver_info = (unsigned long)&cdc_mbim_info,
        },
index 71b6e92b8e9b687c70d0eda9416f1e235a788747..9197b2c72ca36dd9e62bbccafbea388d5fc99793 100644 (file)
@@ -435,6 +435,13 @@ advance:
                len -= temp;
        }
 
+       /* some buggy devices have an IAD but no CDC Union */
+       if (!ctx->union_desc && intf->intf_assoc && intf->intf_assoc->bInterfaceCount == 2) {
+               ctx->control = intf;
+               ctx->data = usb_ifnum_to_if(dev->udev, intf->cur_altsetting->desc.bInterfaceNumber + 1);
+               dev_dbg(&intf->dev, "CDC Union missing - got slave from IAD\n");
+       }
+
        /* check if we got everything */
        if ((ctx->control == NULL) || (ctx->data == NULL) ||
            ((!ctx->mbim_desc) && ((ctx->ether_desc == NULL) || (ctx->control != intf))))
@@ -497,7 +504,8 @@ advance:
 error2:
        usb_set_intfdata(ctx->control, NULL);
        usb_set_intfdata(ctx->data, NULL);
-       usb_driver_release_interface(driver, ctx->data);
+       if (ctx->data != ctx->control)
+               usb_driver_release_interface(driver, ctx->data);
 error:
        cdc_ncm_free((struct cdc_ncm_ctx *)dev->data[0]);
        dev->data[0] = 0;
@@ -1155,6 +1163,20 @@ static const struct driver_info wwan_info = {
        .tx_fixup = cdc_ncm_tx_fixup,
 };
 
+/* Same as wwan_info, but with FLAG_NOARP  */
+static const struct driver_info wwan_noarp_info = {
+       .description = "Mobile Broadband Network Device (NO ARP)",
+       .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET
+                       | FLAG_WWAN | FLAG_NOARP,
+       .bind = cdc_ncm_bind,
+       .unbind = cdc_ncm_unbind,
+       .check_connect = cdc_ncm_check_connect,
+       .manage_power = usbnet_manage_power,
+       .status = cdc_ncm_status,
+       .rx_fixup = cdc_ncm_rx_fixup,
+       .tx_fixup = cdc_ncm_tx_fixup,
+};
+
 static const struct usb_device_id cdc_devs[] = {
        /* Ericsson MBM devices like F5521gw */
        { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
@@ -1194,6 +1216,13 @@ static const struct usb_device_id cdc_devs[] = {
          .driver_info = (unsigned long)&wwan_info,
        },
 
+       /* Infineon(now Intel) HSPA Modem platform */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x1519, 0x0443,
+               USB_CLASS_COMM,
+               USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
+         .driver_info = (unsigned long)&wwan_noarp_info,
+       },
+
        /* Generic CDC-NCM devices */
        { USB_INTERFACE_INFO(USB_CLASS_COMM,
                USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE),
index 3f554c1149f36d2cf3221ee38e4f02507d566ba7..d7e99445518eb5981d064a7378d7fcf02e4bf5cd 100644 (file)
 #define DM_MCAST_ADDR  0x16    /* 8 bytes */
 #define DM_GPR_CTRL    0x1e
 #define DM_GPR_DATA    0x1f
+#define DM_CHIP_ID     0x2c
+#define DM_MODE_CTRL   0x91    /* only on dm9620 */
+
+/* chip id values */
+#define ID_DM9601      0
+#define ID_DM9620      1
 
 #define DM_MAX_MCAST   64
 #define DM_MCAST_SIZE  8
@@ -53,7 +59,6 @@
 #define DM_RX_OVERHEAD 7       /* 3 byte header + 4 byte crc tail */
 #define DM_TIMEOUT     1000
 
-
 static int dm_read(struct usbnet *dev, u8 reg, u16 length, void *data)
 {
        int err;
@@ -84,32 +89,23 @@ static int dm_write(struct usbnet *dev, u8 reg, u16 length, void *data)
 
 static int dm_write_reg(struct usbnet *dev, u8 reg, u8 value)
 {
-       return usbnet_write_cmd(dev, DM_WRITE_REGS,
+       return usbnet_write_cmd(dev, DM_WRITE_REG,
                                USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
                                value, reg, NULL, 0);
 }
 
-static void dm_write_async_helper(struct usbnet *dev, u8 reg, u8 value,
-                                 u16 length, void *data)
+static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data)
 {
        usbnet_write_cmd_async(dev, DM_WRITE_REGS,
                               USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-                              value, reg, data, length);
-}
-
-static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data)
-{
-       netdev_dbg(dev->net, "dm_write_async() reg=0x%02x length=%d\n", reg, length);
-
-       dm_write_async_helper(dev, reg, 0, length, data);
+                              0, reg, data, length);
 }
 
 static void dm_write_reg_async(struct usbnet *dev, u8 reg, u8 value)
 {
-       netdev_dbg(dev->net, "dm_write_reg_async() reg=0x%02x value=0x%02x\n",
-                  reg, value);
-
-       dm_write_async_helper(dev, reg, value, 0, NULL);
+       usbnet_write_cmd_async(dev, DM_WRITE_REG,
+                              USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                              value, reg, NULL, 0);
 }
 
 static int dm_read_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 *value)
@@ -358,7 +354,7 @@ static const struct net_device_ops dm9601_netdev_ops = {
 static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)
 {
        int ret;
-       u8 mac[ETH_ALEN];
+       u8 mac[ETH_ALEN], id;
 
        ret = usbnet_get_endpoints(dev, intf);
        if (ret)
@@ -399,6 +395,24 @@ static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)
                __dm9601_set_mac_address(dev);
        }
 
+       if (dm_read_reg(dev, DM_CHIP_ID, &id) < 0) {
+               netdev_err(dev->net, "Error reading chip ID\n");
+               ret = -ENODEV;
+               goto out;
+       }
+
+       /* put dm9620 devices in dm9601 mode */
+       if (id == ID_DM9620) {
+               u8 mode;
+
+               if (dm_read_reg(dev, DM_MODE_CTRL, &mode) < 0) {
+                       netdev_err(dev->net, "Error reading MODE_CTRL\n");
+                       ret = -ENODEV;
+                       goto out;
+               }
+               dm_write_reg(dev, DM_MODE_CTRL, mode & 0x7f);
+       }
+
        /* power up phy */
        dm_write_reg(dev, DM_GPR_CTRL, 1);
        dm_write_reg(dev, DM_GPR_DATA, 0);
@@ -581,6 +595,10 @@ static const struct usb_device_id products[] = {
         USB_DEVICE(0x0a46, 0x9000),    /* DM9000E */
         .driver_info = (unsigned long)&dm9601_info,
         },
+       {
+        USB_DEVICE(0x0a46, 0x9620),    /* DM9620 USB to Fast Ethernet Adapter */
+        .driver_info = (unsigned long)&dm9601_info,
+        },
        {},                     // END
 };
 
index 6a1ca500e61267e9ba8858d3ed7405990b28e43d..575a5839ee3458434d355677d785589d3472395d 100644 (file)
@@ -433,6 +433,7 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x19d2, 0x0199, 1)},    /* ZTE MF820S */
        {QMI_FIXED_INTF(0x19d2, 0x0200, 1)},
        {QMI_FIXED_INTF(0x19d2, 0x0257, 3)},    /* ZTE MF821 */
+       {QMI_FIXED_INTF(0x19d2, 0x0265, 4)},    /* ONDA MT8205 4G LTE */
        {QMI_FIXED_INTF(0x19d2, 0x0284, 4)},    /* ZTE MF880 */
        {QMI_FIXED_INTF(0x19d2, 0x0326, 4)},    /* ZTE MF821D */
        {QMI_FIXED_INTF(0x19d2, 0x1008, 4)},    /* ZTE (Vodafone) K3570-Z */
@@ -459,6 +460,7 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x1199, 0x68a2, 19)},   /* Sierra Wireless MC7710 in QMI mode */
        {QMI_FIXED_INTF(0x1199, 0x901c, 8)},    /* Sierra Wireless EM7700 */
        {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)},    /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
+       {QMI_FIXED_INTF(0x2357, 0x0201, 4)},    /* TP-LINK HSUPA Modem MA180 */
 
        /* 4. Gobi 1000 devices */
        {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)},    /* Acer Gobi Modem Device */
index 3d4bf01641b49f0f7c5d820a547885806378c4e2..f34b2ebee815ff6b832ef280e26ce7039ef6bfd6 100644 (file)
@@ -1448,6 +1448,10 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
                if ((dev->driver_info->flags & FLAG_WWAN) != 0)
                        strcpy(net->name, "wwan%d");
 
+               /* devices that cannot do ARP */
+               if ((dev->driver_info->flags & FLAG_NOARP) != 0)
+                       net->flags |= IFF_NOARP;
+
                /* maybe the remote can't receive an Ethernet MTU */
                if (net->mtu > (dev->hard_mtu - net->hard_header_len))
                        net->mtu = dev->hard_mtu - net->hard_header_len;
index a6fcf15adc4ff3d36d928f44cc0ac1f49d249820..35c00c5ea02adcbdf6f2855b7ee506544944843a 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/scatterlist.h>
 #include <linux/if_vlan.h>
 #include <linux/slab.h>
+#include <linux/cpu.h>
 
 static int napi_weight = 128;
 module_param(napi_weight, int, 0444);
@@ -123,6 +124,12 @@ struct virtnet_info {
 
        /* Does the affinity hint is set for virtqueues? */
        bool affinity_hint_set;
+
+       /* Per-cpu variable to show the mapping from CPU to virtqueue */
+       int __percpu *vq_index;
+
+       /* CPU hot plug notifier */
+       struct notifier_block nb;
 };
 
 struct skb_vnet_hdr {
@@ -1013,32 +1020,75 @@ static int virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid)
        return 0;
 }
 
-static void virtnet_set_affinity(struct virtnet_info *vi, bool set)
+static void virtnet_clean_affinity(struct virtnet_info *vi, long hcpu)
 {
        int i;
+       int cpu;
+
+       if (vi->affinity_hint_set) {
+               for (i = 0; i < vi->max_queue_pairs; i++) {
+                       virtqueue_set_affinity(vi->rq[i].vq, -1);
+                       virtqueue_set_affinity(vi->sq[i].vq, -1);
+               }
+
+               vi->affinity_hint_set = false;
+       }
+
+       i = 0;
+       for_each_online_cpu(cpu) {
+               if (cpu == hcpu) {
+                       *per_cpu_ptr(vi->vq_index, cpu) = -1;
+               } else {
+                       *per_cpu_ptr(vi->vq_index, cpu) =
+                               ++i % vi->curr_queue_pairs;
+               }
+       }
+}
+
+static void virtnet_set_affinity(struct virtnet_info *vi)
+{
+       int i;
+       int cpu;
 
        /* In multiqueue mode, when the number of cpu is equal to the number of
         * queue pairs, we let the queue pairs to be private to one cpu by
         * setting the affinity hint to eliminate the contention.
         */
-       if ((vi->curr_queue_pairs == 1 ||
-            vi->max_queue_pairs != num_online_cpus()) && set) {
-               if (vi->affinity_hint_set)
-                       set = false;
-               else
-                       return;
+       if (vi->curr_queue_pairs == 1 ||
+           vi->max_queue_pairs != num_online_cpus()) {
+               virtnet_clean_affinity(vi, -1);
+               return;
        }
 
-       for (i = 0; i < vi->max_queue_pairs; i++) {
-               int cpu = set ? i : -1;
+       i = 0;
+       for_each_online_cpu(cpu) {
                virtqueue_set_affinity(vi->rq[i].vq, cpu);
                virtqueue_set_affinity(vi->sq[i].vq, cpu);
+               *per_cpu_ptr(vi->vq_index, cpu) = i;
+               i++;
        }
 
-       if (set)
-               vi->affinity_hint_set = true;
-       else
-               vi->affinity_hint_set = false;
+       vi->affinity_hint_set = true;
+}
+
+static int virtnet_cpu_callback(struct notifier_block *nfb,
+                               unsigned long action, void *hcpu)
+{
+       struct virtnet_info *vi = container_of(nfb, struct virtnet_info, nb);
+
+       switch(action & ~CPU_TASKS_FROZEN) {
+       case CPU_ONLINE:
+       case CPU_DOWN_FAILED:
+       case CPU_DEAD:
+               virtnet_set_affinity(vi);
+               break;
+       case CPU_DOWN_PREPARE:
+               virtnet_clean_affinity(vi, (long)hcpu);
+               break;
+       default:
+               break;
+       }
+       return NOTIFY_OK;
 }
 
 static void virtnet_get_ringparam(struct net_device *dev,
@@ -1082,13 +1132,15 @@ static int virtnet_set_channels(struct net_device *dev,
        if (queue_pairs > vi->max_queue_pairs)
                return -EINVAL;
 
+       get_online_cpus();
        err = virtnet_set_queues(vi, queue_pairs);
        if (!err) {
                netif_set_real_num_tx_queues(dev, queue_pairs);
                netif_set_real_num_rx_queues(dev, queue_pairs);
 
-               virtnet_set_affinity(vi, true);
+               virtnet_set_affinity(vi);
        }
+       put_online_cpus();
 
        return err;
 }
@@ -1127,12 +1179,19 @@ static int virtnet_change_mtu(struct net_device *dev, int new_mtu)
 
 /* To avoid contending a lock hold by a vcpu who would exit to host, select the
  * txq based on the processor id.
- * TODO: handle cpu hotplug.
  */
 static u16 virtnet_select_queue(struct net_device *dev, struct sk_buff *skb)
 {
-       int txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) :
-                 smp_processor_id();
+       int txq;
+       struct virtnet_info *vi = netdev_priv(dev);
+
+       if (skb_rx_queue_recorded(skb)) {
+               txq = skb_get_rx_queue(skb);
+       } else {
+               txq = *__this_cpu_ptr(vi->vq_index);
+               if (txq == -1)
+                       txq = 0;
+       }
 
        while (unlikely(txq >= dev->real_num_tx_queues))
                txq -= dev->real_num_tx_queues;
@@ -1248,7 +1307,7 @@ static void virtnet_del_vqs(struct virtnet_info *vi)
 {
        struct virtio_device *vdev = vi->vdev;
 
-       virtnet_set_affinity(vi, false);
+       virtnet_clean_affinity(vi, -1);
 
        vdev->config->del_vqs(vdev);
 
@@ -1371,7 +1430,10 @@ static int init_vqs(struct virtnet_info *vi)
        if (ret)
                goto err_free;
 
-       virtnet_set_affinity(vi, true);
+       get_online_cpus();
+       virtnet_set_affinity(vi);
+       put_online_cpus();
+
        return 0;
 
 err_free:
@@ -1453,6 +1515,10 @@ static int virtnet_probe(struct virtio_device *vdev)
        if (vi->stats == NULL)
                goto free;
 
+       vi->vq_index = alloc_percpu(int);
+       if (vi->vq_index == NULL)
+               goto free_stats;
+
        mutex_init(&vi->config_lock);
        vi->config_enable = true;
        INIT_WORK(&vi->config_work, virtnet_config_changed_work);
@@ -1476,7 +1542,7 @@ static int virtnet_probe(struct virtio_device *vdev)
        /* Allocate/initialize the rx/tx queues, and invoke find_vqs */
        err = init_vqs(vi);
        if (err)
-               goto free_stats;
+               goto free_index;
 
        netif_set_real_num_tx_queues(dev, 1);
        netif_set_real_num_rx_queues(dev, 1);
@@ -1499,6 +1565,13 @@ static int virtnet_probe(struct virtio_device *vdev)
                }
        }
 
+       vi->nb.notifier_call = &virtnet_cpu_callback;
+       err = register_hotcpu_notifier(&vi->nb);
+       if (err) {
+               pr_debug("virtio_net: registering cpu notifier failed\n");
+               goto free_recv_bufs;
+       }
+
        /* Assume link up if device can't report link status,
           otherwise get link status from config. */
        if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
@@ -1520,6 +1593,8 @@ free_recv_bufs:
 free_vqs:
        cancel_delayed_work_sync(&vi->refill);
        virtnet_del_vqs(vi);
+free_index:
+       free_percpu(vi->vq_index);
 free_stats:
        free_percpu(vi->stats);
 free:
@@ -1543,6 +1618,8 @@ static void virtnet_remove(struct virtio_device *vdev)
 {
        struct virtnet_info *vi = vdev->priv;
 
+       unregister_hotcpu_notifier(&vi->nb);
+
        /* Prevent config work handler from accessing the device. */
        mutex_lock(&vi->config_lock);
        vi->config_enable = false;
@@ -1554,6 +1631,7 @@ static void virtnet_remove(struct virtio_device *vdev)
 
        flush_work(&vi->config_work);
 
+       free_percpu(vi->vq_index);
        free_percpu(vi->stats);
        free_netdev(vi->dev);
 }
index 8b0d8dcd76255239e7451b4a1258adca79ef8342..56317b0fb6b692f3f9ae20b8ba681ec18371788f 100644 (file)
@@ -976,6 +976,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
                                          AR_PHY_CL_TAB_1,
                                          AR_PHY_CL_TAB_2 };
 
+       ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
+
        if (rtt) {
                if (!ar9003_hw_rtt_restore(ah, chan))
                        run_rtt_cal = true;
index ce19c09fa8e84aec2877e2f14861b0284f4d958e..3afc24bde6d65d88a0d469abb0ef73d93856edcb 100644 (file)
@@ -586,32 +586,19 @@ static void ar9003_hw_init_bb(struct ath_hw *ah,
        ath9k_hw_synth_delay(ah, chan, synthDelay);
 }
 
-static void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
+void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
 {
-       switch (rx) {
-       case 0x5:
+       if (ah->caps.tx_chainmask == 5 || ah->caps.rx_chainmask == 5)
                REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
                            AR_PHY_SWAP_ALT_CHAIN);
-       case 0x3:
-       case 0x1:
-       case 0x2:
-       case 0x7:
-               REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx);
-               REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx);
-               break;
-       default:
-               break;
-       }
+
+       REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx);
+       REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx);
 
        if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7))
-               REG_WRITE(ah, AR_SELFGEN_MASK, 0x3);
-       else
-               REG_WRITE(ah, AR_SELFGEN_MASK, tx);
+               tx = 3;
 
-       if (tx == 0x5) {
-               REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
-                           AR_PHY_SWAP_ALT_CHAIN);
-       }
+       REG_WRITE(ah, AR_SELFGEN_MASK, tx);
 }
 
 /*
index 86e26a19efdac1923395543c1a50fb53a6cb8958..42794c546a4068ac91b47c1252153b9040362555 100644 (file)
@@ -317,7 +317,6 @@ struct ath_rx {
        u32 *rxlink;
        u32 num_pkts;
        unsigned int rxfilter;
-       spinlock_t rxbuflock;
        struct list_head rxbuf;
        struct ath_descdma rxdma;
        struct ath_buf *rx_bufptr;
@@ -328,7 +327,6 @@ struct ath_rx {
 
 int ath_startrecv(struct ath_softc *sc);
 bool ath_stoprecv(struct ath_softc *sc);
-void ath_flushrecv(struct ath_softc *sc);
 u32 ath_calcrxfilter(struct ath_softc *sc);
 int ath_rx_init(struct ath_softc *sc, int nbufs);
 void ath_rx_cleanup(struct ath_softc *sc);
@@ -646,7 +644,6 @@ void ath_ant_comb_update(struct ath_softc *sc);
 enum sc_op_flags {
        SC_OP_INVALID,
        SC_OP_BEACONS,
-       SC_OP_RXFLUSH,
        SC_OP_ANI_RUN,
        SC_OP_PRIM_STA_VIF,
        SC_OP_HW_RESET,
index 531fffd801a34eaa11b8d483aca51ac07e7a7fab..2ca355e94da65467e36595990423c80be1b897b6 100644 (file)
@@ -147,6 +147,7 @@ static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw,
                                 skb->len, DMA_TO_DEVICE);
                dev_kfree_skb_any(skb);
                bf->bf_buf_addr = 0;
+               bf->bf_mpdu = NULL;
        }
 
        skb = ieee80211_beacon_get(hw, vif);
@@ -359,7 +360,6 @@ void ath9k_beacon_tasklet(unsigned long data)
                return;
 
        bf = ath9k_beacon_generate(sc->hw, vif);
-       WARN_ON(!bf);
 
        if (sc->beacon.bmisscnt != 0) {
                ath_dbg(common, BSTUCK, "resume beacon xmit after %u misses\n",
index 13ff9edc24015e5e2126fc4f6c7fde8dcb003c90..e585fc827c50b2e9d5ff2fe08afb15cd49cedba6 100644 (file)
@@ -861,7 +861,6 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
        RXS_ERR("RX-LENGTH-ERR", rx_len_err);
        RXS_ERR("RX-OOM-ERR", rx_oom_err);
        RXS_ERR("RX-RATE-ERR", rx_rate_err);
-       RXS_ERR("RX-DROP-RXFLUSH", rx_drop_rxflush);
        RXS_ERR("RX-TOO-MANY-FRAGS", rx_too_many_frags_err);
 
        PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN);
index 375c3b46411eee6cd140dbc22e6e435fe0e32ad9..6df2ab62dcb706df5bef4a8afdf04593651f111a 100644 (file)
@@ -216,7 +216,6 @@ struct ath_tx_stats {
  * @rx_oom_err:  No. of frames dropped due to OOM issues.
  * @rx_rate_err:  No. of frames dropped due to rate errors.
  * @rx_too_many_frags_err:  Frames dropped due to too-many-frags received.
- * @rx_drop_rxflush: No. of frames dropped due to RX-FLUSH.
  * @rx_beacons:  No. of beacons received.
  * @rx_frags:  No. of rx-fragements received.
  */
@@ -235,7 +234,6 @@ struct ath_rx_stats {
        u32 rx_oom_err;
        u32 rx_rate_err;
        u32 rx_too_many_frags_err;
-       u32 rx_drop_rxflush;
        u32 rx_beacons;
        u32 rx_frags;
 };
index 4a9570dfba72605d2f492ddf51cde8e8e7db835b..aac4a406a5134727e49fef2999e563e39169d83f 100644 (file)
@@ -344,6 +344,8 @@ void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,
                        endpoint->ep_callbacks.tx(endpoint->ep_callbacks.priv,
                                                  skb, htc_hdr->endpoint_id,
                                                  txok);
+               } else {
+                       kfree_skb(skb);
                }
        }
 
index 7f1a8e91c908c2dea314a7171e1d1d59139e6c6a..9d26fc56ca56a6bf7d4e8ac0ed91366df0de50cd 100644 (file)
@@ -1066,6 +1066,7 @@ void ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain);
 int ar9003_paprd_init_table(struct ath_hw *ah);
 bool ar9003_paprd_is_done(struct ath_hw *ah);
 bool ar9003_is_paprd_enabled(struct ath_hw *ah);
+void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
 
 /* Hardware family op attach helpers */
 void ar5008_hw_attach_phy_ops(struct ath_hw *ah);
index be30a9af152884d8e073b7a3be5b79e6b3d5a8ee..dd91f8fdc01c3ea44c922bbbbd14bee2df4fd6db 100644 (file)
@@ -182,7 +182,7 @@ static void ath_restart_work(struct ath_softc *sc)
        ath_start_ani(sc);
 }
 
-static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush)
+static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx)
 {
        struct ath_hw *ah = sc->sc_ah;
        bool ret = true;
@@ -202,14 +202,6 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush)
        if (!ath_drain_all_txq(sc, retry_tx))
                ret = false;
 
-       if (!flush) {
-               if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
-                       ath_rx_tasklet(sc, 1, true);
-               ath_rx_tasklet(sc, 1, false);
-       } else {
-               ath_flushrecv(sc);
-       }
-
        return ret;
 }
 
@@ -262,11 +254,11 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath9k_hw_cal_data *caldata = NULL;
        bool fastcc = true;
-       bool flush = false;
        int r;
 
        __ath_cancel_work(sc);
 
+       tasklet_disable(&sc->intr_tq);
        spin_lock_bh(&sc->sc_pcu_lock);
 
        if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
@@ -276,11 +268,10 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,
 
        if (!hchan) {
                fastcc = false;
-               flush = true;
                hchan = ah->curchan;
        }
 
-       if (!ath_prepare_reset(sc, retry_tx, flush))
+       if (!ath_prepare_reset(sc, retry_tx))
                fastcc = false;
 
        ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n",
@@ -302,6 +293,8 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,
 
 out:
        spin_unlock_bh(&sc->sc_pcu_lock);
+       tasklet_enable(&sc->intr_tq);
+
        return r;
 }
 
@@ -804,7 +797,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
                ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
        }
 
-       ath_prepare_reset(sc, false, true);
+       ath_prepare_reset(sc, false);
 
        if (sc->rx.frag) {
                dev_kfree_skb_any(sc->rx.frag);
@@ -1833,6 +1826,9 @@ static u32 fill_chainmask(u32 cap, u32 new)
 
 static bool validate_antenna_mask(struct ath_hw *ah, u32 val)
 {
+       if (AR_SREV_9300_20_OR_LATER(ah))
+               return true;
+
        switch (val & 0x7) {
        case 0x1:
        case 0x3:
index d4df98a938bf4755d1af6238d41e5df0753970c6..90752f2469704bbbb2bf7cae86a1c2cb4029435a 100644 (file)
@@ -254,8 +254,6 @@ rx_init_fail:
 
 static void ath_edma_start_recv(struct ath_softc *sc)
 {
-       spin_lock_bh(&sc->rx.rxbuflock);
-
        ath9k_hw_rxena(sc->sc_ah);
 
        ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP,
@@ -267,8 +265,6 @@ static void ath_edma_start_recv(struct ath_softc *sc)
        ath_opmode_init(sc);
 
        ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));
-
-       spin_unlock_bh(&sc->rx.rxbuflock);
 }
 
 static void ath_edma_stop_recv(struct ath_softc *sc)
@@ -285,8 +281,6 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
        int error = 0;
 
        spin_lock_init(&sc->sc_pcu_lock);
-       spin_lock_init(&sc->rx.rxbuflock);
-       clear_bit(SC_OP_RXFLUSH, &sc->sc_flags);
 
        common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 +
                             sc->sc_ah->caps.rx_status_len;
@@ -447,7 +441,6 @@ int ath_startrecv(struct ath_softc *sc)
                return 0;
        }
 
-       spin_lock_bh(&sc->rx.rxbuflock);
        if (list_empty(&sc->rx.rxbuf))
                goto start_recv;
 
@@ -468,26 +461,31 @@ start_recv:
        ath_opmode_init(sc);
        ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));
 
-       spin_unlock_bh(&sc->rx.rxbuflock);
-
        return 0;
 }
 
+static void ath_flushrecv(struct ath_softc *sc)
+{
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
+               ath_rx_tasklet(sc, 1, true);
+       ath_rx_tasklet(sc, 1, false);
+}
+
 bool ath_stoprecv(struct ath_softc *sc)
 {
        struct ath_hw *ah = sc->sc_ah;
        bool stopped, reset = false;
 
-       spin_lock_bh(&sc->rx.rxbuflock);
        ath9k_hw_abortpcurecv(ah);
        ath9k_hw_setrxfilter(ah, 0);
        stopped = ath9k_hw_stopdmarecv(ah, &reset);
 
+       ath_flushrecv(sc);
+
        if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
                ath_edma_stop_recv(sc);
        else
                sc->rx.rxlink = NULL;
-       spin_unlock_bh(&sc->rx.rxbuflock);
 
        if (!(ah->ah_flags & AH_UNPLUGGED) &&
            unlikely(!stopped)) {
@@ -499,15 +497,6 @@ bool ath_stoprecv(struct ath_softc *sc)
        return stopped && !reset;
 }
 
-void ath_flushrecv(struct ath_softc *sc)
-{
-       set_bit(SC_OP_RXFLUSH, &sc->sc_flags);
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
-               ath_rx_tasklet(sc, 1, true);
-       ath_rx_tasklet(sc, 1, false);
-       clear_bit(SC_OP_RXFLUSH, &sc->sc_flags);
-}
-
 static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb)
 {
        /* Check whether the Beacon frame has DTIM indicating buffered bc/mc */
@@ -744,6 +733,7 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
                        return NULL;
        }
 
+       list_del(&bf->list);
        if (!bf->bf_mpdu)
                return bf;
 
@@ -1059,16 +1049,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
                dma_type = DMA_FROM_DEVICE;
 
        qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP;
-       spin_lock_bh(&sc->rx.rxbuflock);
 
        tsf = ath9k_hw_gettsf64(ah);
        tsf_lower = tsf & 0xffffffff;
 
        do {
                bool decrypt_error = false;
-               /* If handling rx interrupt and flush is in progress => exit */
-               if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags) && (flush == 0))
-                       break;
 
                memset(&rs, 0, sizeof(rs));
                if (edma)
@@ -1111,15 +1097,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
 
                ath_debug_stat_rx(sc, &rs);
 
-               /*
-                * If we're asked to flush receive queue, directly
-                * chain it back at the queue without processing it.
-                */
-               if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags)) {
-                       RX_STAT_INC(rx_drop_rxflush);
-                       goto requeue_drop_frag;
-               }
-
                memset(rxs, 0, sizeof(struct ieee80211_rx_status));
 
                rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
@@ -1254,19 +1231,18 @@ requeue_drop_frag:
                        sc->rx.frag = NULL;
                }
 requeue:
+               list_add_tail(&bf->list, &sc->rx.rxbuf);
+               if (flush)
+                       continue;
+
                if (edma) {
-                       list_add_tail(&bf->list, &sc->rx.rxbuf);
                        ath_rx_edma_buf_link(sc, qtype);
                } else {
-                       list_move_tail(&bf->list, &sc->rx.rxbuf);
                        ath_rx_buf_link(sc, bf);
-                       if (!flush)
-                               ath9k_hw_rxena(ah);
+                       ath9k_hw_rxena(ah);
                }
        } while (1);
 
-       spin_unlock_bh(&sc->rx.rxbuflock);
-
        if (!(ah->imask & ATH9K_INT_RXEOL)) {
                ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
                ath9k_hw_set_interrupts(ah);
index 1fbd8ecbe2ea293a28d6a65648fe011a2fff3fa6..0f71d1d4339dc38ccfdd89428fdc4a62bb5b7bd9 100644 (file)
@@ -1407,9 +1407,10 @@ void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic)
 #endif
        t->ms = ms;
        t->periodic = (bool) periodic;
-       t->set = true;
-
-       atomic_inc(&t->wl->callbacks);
+       if (!t->set) {
+               t->set = true;
+               atomic_inc(&t->wl->callbacks);
+       }
 
        ieee80211_queue_delayed_work(hw, &t->dly_wrk, msecs_to_jiffies(ms));
 }
index 7e16d10a7f140e4bc0a1414af1ec317f7284b9c6..90b8970eadf0fa7c296be194c2d18ef9266b1043 100644 (file)
@@ -3958,17 +3958,21 @@ il_connection_init_rx_config(struct il_priv *il)
 
        memset(&il->staging, 0, sizeof(il->staging));
 
-       if (!il->vif) {
+       switch (il->iw_mode) {
+       case NL80211_IFTYPE_UNSPECIFIED:
                il->staging.dev_type = RXON_DEV_TYPE_ESS;
-       } else if (il->vif->type == NL80211_IFTYPE_STATION) {
+               break;
+       case NL80211_IFTYPE_STATION:
                il->staging.dev_type = RXON_DEV_TYPE_ESS;
                il->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
-       } else if (il->vif->type == NL80211_IFTYPE_ADHOC) {
+               break;
+       case NL80211_IFTYPE_ADHOC:
                il->staging.dev_type = RXON_DEV_TYPE_IBSS;
                il->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
                il->staging.filter_flags =
                    RXON_FILTER_BCON_AWARE_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
-       } else {
+               break;
+       default:
                IL_ERR("Unsupported interface type %d\n", il->vif->type);
                return;
        }
@@ -4550,8 +4554,7 @@ out:
 EXPORT_SYMBOL(il_mac_add_interface);
 
 static void
-il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif,
-                     bool mode_change)
+il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif)
 {
        lockdep_assert_held(&il->mutex);
 
@@ -4560,9 +4563,7 @@ il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif,
                il_force_scan_end(il);
        }
 
-       if (!mode_change)
-               il_set_mode(il);
-
+       il_set_mode(il);
 }
 
 void
@@ -4575,8 +4576,8 @@ il_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 
        WARN_ON(il->vif != vif);
        il->vif = NULL;
-
-       il_teardown_interface(il, vif, false);
+       il->iw_mode = NL80211_IFTYPE_UNSPECIFIED;
+       il_teardown_interface(il, vif);
        memset(il->bssid, 0, ETH_ALEN);
 
        D_MAC80211("leave\n");
@@ -4685,18 +4686,10 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        }
 
        /* success */
-       il_teardown_interface(il, vif, true);
        vif->type = newtype;
        vif->p2p = false;
-       err = il_set_mode(il);
-       WARN_ON(err);
-       /*
-        * We've switched internally, but submitting to the
-        * device may have failed for some reason. Mask this
-        * error, because otherwise mac80211 will not switch
-        * (and set the interface type back) and we'll be
-        * out of sync with it.
-        */
+       il->iw_mode = newtype;
+       il_teardown_interface(il, vif);
        err = 0;
 
 out:
index a790599fe2c219b63526a833c3db63ac09d84e84..31534f7c05488ba38d4c65c7ce0209a43712fd51 100644 (file)
@@ -1079,6 +1079,8 @@ static void iwlagn_set_tx_status(struct iwl_priv *priv,
 {
        u16 status = le16_to_cpu(tx_resp->status.status);
 
+       info->flags &= ~IEEE80211_TX_CTL_AMPDU;
+
        info->status.rates[0].count = tx_resp->failure_frame + 1;
        info->flags |= iwl_tx_status_to_mac80211(status);
        iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags),
index efe525be27dd3607f63c76e49d089d5f7e34d0d5..cdb11b3964e27dd68de20ac68ab8442772a070a1 100644 (file)
@@ -1459,7 +1459,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
        struct cfg80211_ssid req_ssid;
        int ret, auth_type = 0;
        struct cfg80211_bss *bss = NULL;
-       u8 is_scanning_required = 0, config_bands = 0;
+       u8 is_scanning_required = 0;
 
        memset(&req_ssid, 0, sizeof(struct cfg80211_ssid));
 
@@ -1478,19 +1478,6 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
        /* disconnect before try to associate */
        mwifiex_deauthenticate(priv, NULL);
 
-       if (channel) {
-               if (mode == NL80211_IFTYPE_STATION) {
-                       if (channel->band == IEEE80211_BAND_2GHZ)
-                               config_bands = BAND_B | BAND_G | BAND_GN;
-                       else
-                               config_bands = BAND_A | BAND_AN;
-
-                       if (!((config_bands | priv->adapter->fw_bands) &
-                             ~priv->adapter->fw_bands))
-                               priv->adapter->config_bands = config_bands;
-               }
-       }
-
        /* As this is new association, clear locally stored
         * keys and security related flags */
        priv->sec_info.wpa_enabled = false;
@@ -1707,7 +1694,7 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
 
                if (cfg80211_get_chandef_type(&params->chandef) !=
                                                NL80211_CHAN_NO_HT)
-                       config_bands |= BAND_GN;
+                       config_bands |= BAND_G | BAND_GN;
        } else {
                if (cfg80211_get_chandef_type(&params->chandef) ==
                                                NL80211_CHAN_NO_HT)
index 13fbc4eb15952fe375be1e10c55518bb2b6b3836..b879e1338a54f5347a7a5f0b955b98a3f3566b66 100644 (file)
@@ -161,7 +161,7 @@ static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
 
        if (pdev) {
                card = (struct pcie_service_card *) pci_get_drvdata(pdev);
-               if (!card || card->adapter) {
+               if (!card || !card->adapter) {
                        pr_err("Card or adapter structure is not valid\n");
                        return 0;
                }
index 60e88b58039de129f060160f9e18baa49fde0a3d..f542bb8ccbc8d4ce6859e8fff1e45784183f8fbb 100644 (file)
@@ -283,6 +283,20 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
                if (ret)
                        goto done;
 
+               if (bss_desc) {
+                       u8 config_bands = 0;
+
+                       if (mwifiex_band_to_radio_type((u8) bss_desc->bss_band)
+                           == HostCmd_SCAN_RADIO_TYPE_BG)
+                               config_bands = BAND_B | BAND_G | BAND_GN;
+                       else
+                               config_bands = BAND_A | BAND_AN;
+
+                       if (!((config_bands | adapter->fw_bands) &
+                             ~adapter->fw_bands))
+                               adapter->config_bands = config_bands;
+               }
+
                ret = mwifiex_check_network_compatibility(priv, bss_desc);
                if (ret)
                        goto done;
index 21b1bbb93a7e41452720a6f9ede17cba3951393e..b80bc4612581857455c2e076de835f66ac5be710 100644 (file)
@@ -57,12 +57,12 @@ config RTL8192CU
 
 config RTLWIFI
        tristate
-       depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE
+       depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE || RTL8723AE
        default m
 
 config RTLWIFI_DEBUG
        bool "Additional debugging output"
-       depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE
+       depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE || RTL8723AE
        default y
 
 config RTL8192C_COMMON
index c31aeb01bb0002cc648b603c6c526ad83f9ab9a9..efaecefe3f8cc5fda8326c5dbd647e56076a4984 100644 (file)
@@ -181,7 +181,6 @@ config PINCTRL_COH901
 
 config PINCTRL_SAMSUNG
        bool
-       depends on OF && GPIOLIB
        select PINMUX
        select PINCONF
 
index 69aba3697287d02e749fc5c27155c026518601b7..428ea96a94d356a3caee8b971a1df51d8c9564c3 100644 (file)
@@ -588,7 +588,7 @@ static int dove_pinctrl_probe(struct platform_device *pdev)
 {
        const struct of_device_id *match =
                of_match_device(dove_pinctrl_of_match, &pdev->dev);
-       pdev->dev.platform_data = match->data;
+       pdev->dev.platform_data = (void *)match->data;
 
        /*
         * General MPP Configuration Register is part of pdma registers.
index f12084e180579afe19cb3914ff8d4e4db7573eed..cdd483df673eaf5d38d522ba3e8f5ef26f835c3c 100644 (file)
@@ -66,9 +66,9 @@ static struct mvebu_mpp_mode mv88f6xxx_mpp_modes[] = {
                MPP_VAR_FUNCTION(0x5, "sata0", "act",    V(0, 1, 1, 1, 1, 0)),
                MPP_VAR_FUNCTION(0xb, "lcd", "vsync",    V(0, 0, 0, 0, 1, 0))),
        MPP_MODE(6,
-               MPP_VAR_FUNCTION(0x0, "sysrst", "out",   V(1, 1, 1, 1, 1, 1)),
-               MPP_VAR_FUNCTION(0x1, "spi", "mosi",     V(1, 1, 1, 1, 1, 1)),
-               MPP_VAR_FUNCTION(0x2, "ptp", "trig",     V(1, 1, 1, 1, 0, 0))),
+               MPP_VAR_FUNCTION(0x1, "sysrst", "out",   V(1, 1, 1, 1, 1, 1)),
+               MPP_VAR_FUNCTION(0x2, "spi", "mosi",     V(1, 1, 1, 1, 1, 1)),
+               MPP_VAR_FUNCTION(0x3, "ptp", "trig",     V(1, 1, 1, 1, 0, 0))),
        MPP_MODE(7,
                MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(1, 1, 1, 1, 1, 1)),
                MPP_VAR_FUNCTION(0x1, "pex", "rsto",     V(1, 1, 1, 1, 0, 1)),
@@ -458,7 +458,7 @@ static int kirkwood_pinctrl_probe(struct platform_device *pdev)
 {
        const struct of_device_id *match =
                of_match_device(kirkwood_pinctrl_of_match, &pdev->dev);
-       pdev->dev.platform_data = match->data;
+       pdev->dev.platform_data = (void *)match->data;
        return mvebu_pinctrl_probe(pdev);
 }
 
index de05b64f0da695708f2c5ef201c5438c96946d88..142729914c347fc305e32449c11f637a44ad654f 100644 (file)
@@ -599,7 +599,7 @@ static int exynos5440_gpio_direction_output(struct gpio_chip *gc, unsigned offse
 }
 
 /* parse the pin numbers listed in the 'samsung,exynos5440-pins' property */
-static int __init exynos5440_pinctrl_parse_dt_pins(struct platform_device *pdev,
+static int exynos5440_pinctrl_parse_dt_pins(struct platform_device *pdev,
                        struct device_node *cfg_np, unsigned int **pin_list,
                        unsigned int *npins)
 {
@@ -630,7 +630,7 @@ static int __init exynos5440_pinctrl_parse_dt_pins(struct platform_device *pdev,
  * Parse the information about all the available pin groups and pin functions
  * from device node of the pin-controller.
  */
-static int __init exynos5440_pinctrl_parse_dt(struct platform_device *pdev,
+static int exynos5440_pinctrl_parse_dt(struct platform_device *pdev,
                                struct exynos5440_pinctrl_priv_data *priv)
 {
        struct device *dev = &pdev->dev;
@@ -723,7 +723,7 @@ static int __init exynos5440_pinctrl_parse_dt(struct platform_device *pdev,
 }
 
 /* register the pinctrl interface with the pinctrl subsystem */
-static int __init exynos5440_pinctrl_register(struct platform_device *pdev,
+static int exynos5440_pinctrl_register(struct platform_device *pdev,
                                struct exynos5440_pinctrl_priv_data *priv)
 {
        struct device *dev = &pdev->dev;
@@ -798,7 +798,7 @@ static int __init exynos5440_pinctrl_register(struct platform_device *pdev,
 }
 
 /* register the gpiolib interface with the gpiolib subsystem */
-static int __init exynos5440_gpiolib_register(struct platform_device *pdev,
+static int exynos5440_gpiolib_register(struct platform_device *pdev,
                                struct exynos5440_pinctrl_priv_data *priv)
 {
        struct gpio_chip *gc;
@@ -831,7 +831,7 @@ static int __init exynos5440_gpiolib_register(struct platform_device *pdev,
 }
 
 /* unregister the gpiolib interface with the gpiolib subsystem */
-static int __init exynos5440_gpiolib_unregister(struct platform_device *pdev,
+static int exynos5440_gpiolib_unregister(struct platform_device *pdev,
                                struct exynos5440_pinctrl_priv_data *priv)
 {
        int ret = gpiochip_remove(priv->gc);
index dd227d21dcf28563c1d0902d51fa8a3b8140aeed..23af9f1f9c35e6d9d7793075ad7ec2df92070043 100644 (file)
@@ -146,7 +146,7 @@ free:
 static void mxs_dt_free_map(struct pinctrl_dev *pctldev,
                            struct pinctrl_map *map, unsigned num_maps)
 {
-       int i;
+       u32 i;
 
        for (i = 0; i < num_maps; i++) {
                if (map[i].type == PIN_MAP_TYPE_MUX_GROUP)
@@ -203,7 +203,7 @@ static int mxs_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned selector,
        void __iomem *reg;
        u8 bank, shift;
        u16 pin;
-       int i;
+       u32 i;
 
        for (i = 0; i < g->npins; i++) {
                bank = PINID_TO_BANK(g->pins[i]);
@@ -256,7 +256,7 @@ static int mxs_pinconf_group_set(struct pinctrl_dev *pctldev,
        void __iomem *reg;
        u8 ma, vol, pull, bank, shift;
        u16 pin;
-       int i;
+       u32 i;
 
        ma = CONFIG_TO_MA(config);
        vol = CONFIG_TO_VOL(config);
@@ -345,8 +345,7 @@ static int mxs_pinctrl_parse_group(struct platform_device *pdev,
        const char *propname = "fsl,pinmux-ids";
        char *group;
        int length = strlen(np->name) + SUFFIX_LEN;
-       int i;
-       u32 val;
+       u32 val, i;
 
        group = devm_kzalloc(&pdev->dev, length, GFP_KERNEL);
        if (!group)
index 1bb16ffb4e41a9d0f252fc8a563188f97f343642..5767b18ebdff6d1639bd37c6007f9c93553a3f58 100644 (file)
@@ -676,7 +676,7 @@ int nmk_gpio_set_mode(int gpio, int gpio_mode)
 }
 EXPORT_SYMBOL(nmk_gpio_set_mode);
 
-static int nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio)
+static int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio)
 {
        int i;
        u16 reg;
index f6a360b86eb6465fef029e777147ccbd3bc95b66..5c32e880bcb24315b4b2db260294106765eb4240 100644 (file)
@@ -30,7 +30,6 @@
 #define PCS_MUX_BITS_NAME              "pinctrl-single,bits"
 #define PCS_REG_NAME_LEN               ((sizeof(unsigned long) * 2) + 1)
 #define PCS_OFF_DISABLED               ~0U
-#define PCS_MAX_GPIO_VALUES            2
 
 /**
  * struct pcs_pingroup - pingroups for a function
@@ -77,16 +76,6 @@ struct pcs_function {
        struct list_head node;
 };
 
-/**
- * struct pcs_gpio_range - pinctrl gpio range
- * @range:     subrange of the GPIO number space
- * @gpio_func: gpio function value in the pinmux register
- */
-struct pcs_gpio_range {
-       struct pinctrl_gpio_range range;
-       int gpio_func;
-};
-
 /**
  * struct pcs_data - wrapper for data needed by pinctrl framework
  * @pa:                pindesc array
@@ -414,26 +403,9 @@ static void pcs_disable(struct pinctrl_dev *pctldev, unsigned fselector,
 }
 
 static int pcs_request_gpio(struct pinctrl_dev *pctldev,
-                           struct pinctrl_gpio_range *range, unsigned pin)
+                       struct pinctrl_gpio_range *range, unsigned offset)
 {
-       struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
-       struct pcs_gpio_range *gpio = NULL;
-       int end, mux_bytes;
-       unsigned data;
-
-       gpio = container_of(range, struct pcs_gpio_range, range);
-       end = range->pin_base + range->npins - 1;
-       if (pin < range->pin_base || pin > end) {
-               dev_err(pctldev->dev,
-                       "pin %d isn't in the range of %d to %d\n",
-                       pin, range->pin_base, end);
-               return -EINVAL;
-       }
-       mux_bytes = pcs->width / BITS_PER_BYTE;
-       data = pcs->read(pcs->base + pin * mux_bytes) & ~pcs->fmask;
-       data |= gpio->gpio_func;
-       pcs->write(data, pcs->base + pin * mux_bytes);
-       return 0;
+       return -ENOTSUPP;
 }
 
 static struct pinmux_ops pcs_pinmux_ops = {
@@ -907,49 +879,6 @@ static void pcs_free_resources(struct pcs_device *pcs)
 
 static struct of_device_id pcs_of_match[];
 
-static int pcs_add_gpio_range(struct device_node *node, struct pcs_device *pcs)
-{
-       struct pcs_gpio_range *gpio;
-       struct device_node *child;
-       struct resource r;
-       const char name[] = "pinctrl-single";
-       u32 gpiores[PCS_MAX_GPIO_VALUES];
-       int ret, i = 0, mux_bytes = 0;
-
-       for_each_child_of_node(node, child) {
-               ret = of_address_to_resource(child, 0, &r);
-               if (ret < 0)
-                       continue;
-               memset(gpiores, 0, sizeof(u32) * PCS_MAX_GPIO_VALUES);
-               ret = of_property_read_u32_array(child, "pinctrl-single,gpio",
-                                                gpiores, PCS_MAX_GPIO_VALUES);
-               if (ret < 0)
-                       continue;
-               gpio = devm_kzalloc(pcs->dev, sizeof(*gpio), GFP_KERNEL);
-               if (!gpio) {
-                       dev_err(pcs->dev, "failed to allocate pcs gpio\n");
-                       return -ENOMEM;
-               }
-               gpio->range.name = devm_kzalloc(pcs->dev, sizeof(name),
-                                               GFP_KERNEL);
-               if (!gpio->range.name) {
-                       dev_err(pcs->dev, "failed to allocate range name\n");
-                       return -ENOMEM;
-               }
-               memcpy((char *)gpio->range.name, name, sizeof(name));
-
-               gpio->range.id = i++;
-               gpio->range.base = gpiores[0];
-               gpio->gpio_func = gpiores[1];
-               mux_bytes = pcs->width / BITS_PER_BYTE;
-               gpio->range.pin_base = (r.start - pcs->res->start) / mux_bytes;
-               gpio->range.npins = (r.end - r.start) / mux_bytes + 1;
-
-               pinctrl_add_gpio_range(pcs->pctl, &gpio->range);
-       }
-       return 0;
-}
-
 static int pcs_probe(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
@@ -1046,10 +975,6 @@ static int pcs_probe(struct platform_device *pdev)
                goto free;
        }
 
-       ret = pcs_add_gpio_range(np, pcs);
-       if (ret < 0)
-               goto free;
-
        dev_info(pcs->dev, "%i pins at pa %p size %u\n",
                 pcs->desc.npins, pcs->base, pcs->size);
 
index 7481146a5b473c1cab6745a7d6ac1ae76e66257e..97c2be195efc36eeb76bd848f2c1327be7f168c2 100644 (file)
@@ -244,7 +244,7 @@ static int __init ibm_rtl_init(void) {
        if (force)
                pr_warn("module loaded by force\n");
        /* first ensure that we are running on IBM HW */
-       else if (efi_enabled || !dmi_check_system(ibm_rtl_dmi_table))
+       else if (efi_enabled(EFI_BOOT) || !dmi_check_system(ibm_rtl_dmi_table))
                return -ENODEV;
 
        /* Get the address for the Extended BIOS Data Area */
index 71623a2ff3e87b0cffe3d5e85ae96480600a7e59..d1f0300531766f64ab741ccbd4d388db0644d427 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/seq_file.h>
 #include <linux/debugfs.h>
 #include <linux/ctype.h>
+#include <linux/efi.h>
 #include <acpi/video.h>
 
 /*
@@ -1544,6 +1545,9 @@ static int __init samsung_init(void)
        struct samsung_laptop *samsung;
        int ret;
 
+       if (efi_enabled(EFI_BOOT))
+               return -ENODEV;
+
        quirks = &samsung_unknown;
        if (!force && !dmi_check_system(samsung_dmi_table))
                return -ENODEV;
index 261f3d2299bc0a5d2d074824211172be7a6b8448..89bd2faaef8cf627cddcd9f1b7a03c9b4cab5fae 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include "dbx500-prcmu.h"
 
index b15d711bc8c66634c9792c26e15885e055aabe11..9019d0e7ecb6ad9868fa96e23fa0f77a1275fc75 100644 (file)
@@ -728,7 +728,7 @@ static int tps80031_regulator_probe(struct platform_device *pdev)
                        }
                }
                rdev = regulator_register(&ri->rinfo->desc, &config);
-               if (IS_ERR_OR_NULL(rdev)) {
+               if (IS_ERR(rdev)) {
                        dev_err(&pdev->dev,
                                "register regulator failed %s\n",
                                        ri->rinfo->desc.name);
index d73fdcfeb45a19e1695dc188b045e29c72e57557..2839baa82a5a458d0035d59e8a5666ac07690779 100644 (file)
@@ -633,7 +633,7 @@ static int isci_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                return -ENOMEM;
        pci_set_drvdata(pdev, pci_info);
 
-       if (efi_enabled)
+       if (efi_enabled(EFI_RUNTIME_SERVICES))
                orom = isci_get_efi_var(pdev);
 
        if (!orom)
index b906ed17a8391a99ffbc15d8ea62c6861be90689..9802de0f85e61fe061ea150d15177c39b4128ca3 100644 (file)
@@ -281,6 +281,7 @@ static void gdlm_put_lock(struct gfs2_glock *gl)
 {
        struct gfs2_sbd *sdp = gl->gl_sbd;
        struct lm_lockstruct *ls = &sdp->sd_lockstruct;
+       int lvb_needs_unlock = 0;
        int error;
 
        if (gl->gl_lksb.sb_lkid == 0) {
@@ -294,8 +295,12 @@ static void gdlm_put_lock(struct gfs2_glock *gl)
        gfs2_update_request_times(gl);
 
        /* don't want to skip dlm_unlock writing the lvb when lock is ex */
+
+       if (gl->gl_lksb.sb_lvbptr && (gl->gl_state == LM_ST_EXCLUSIVE))
+               lvb_needs_unlock = 1;
+
        if (test_bit(SDF_SKIP_DLM_UNLOCK, &sdp->sd_flags) &&
-           gl->gl_lksb.sb_lvbptr && (gl->gl_state != LM_ST_EXCLUSIVE)) {
+           !lvb_needs_unlock) {
                gfs2_glock_free(gl);
                return;
        }
index 4111a40ebe1a17dde31f89e5154c0d257c6e5d6c..5f707e5371717a331131f72f5babff24670d9bef 100644 (file)
@@ -86,11 +86,11 @@ xfs_destroy_ioend(
        }
 
        if (ioend->io_iocb) {
+               inode_dio_done(ioend->io_inode);
                if (ioend->io_isasync) {
                        aio_complete(ioend->io_iocb, ioend->io_error ?
                                        ioend->io_error : ioend->io_result, 0);
                }
-               inode_dio_done(ioend->io_inode);
        }
 
        mempool_free(ioend, xfs_ioend_pool);
index 0e92d12765d2670146b0325cd1215b449fb60dfe..cdb2d33485837bcd314f380f6d0c6737424626ec 100644 (file)
@@ -4680,9 +4680,6 @@ __xfs_bmapi_allocate(
                        return error;
        }
 
-       if (bma->flags & XFS_BMAPI_STACK_SWITCH)
-               bma->stack_switch = 1;
-
        error = xfs_bmap_alloc(bma);
        if (error)
                return error;
@@ -4956,6 +4953,9 @@ xfs_bmapi_write(
        bma.flist = flist;
        bma.firstblock = firstblock;
 
+       if (flags & XFS_BMAPI_STACK_SWITCH)
+               bma.stack_switch = 1;
+
        while (bno < end && n < *nmap) {
                inhole = eof || bma.got.br_startoff > bno;
                wasdelay = !inhole && isnullstartblock(bma.got.br_startblock);
index 56d1614760cfba8b58957f37146d417d120fc087..fbbb9eb92e32a7b38ec32c954313cffdb39a8508 100644 (file)
@@ -487,6 +487,7 @@ _xfs_buf_find(
        struct rb_node          *parent;
        xfs_buf_t               *bp;
        xfs_daddr_t             blkno = map[0].bm_bn;
+       xfs_daddr_t             eofs;
        int                     numblks = 0;
        int                     i;
 
@@ -498,6 +499,23 @@ _xfs_buf_find(
        ASSERT(!(numbytes < (1 << btp->bt_sshift)));
        ASSERT(!(BBTOB(blkno) & (xfs_off_t)btp->bt_smask));
 
+       /*
+        * Corrupted block numbers can get through to here, unfortunately, so we
+        * have to check that the buffer falls within the filesystem bounds.
+        */
+       eofs = XFS_FSB_TO_BB(btp->bt_mount, btp->bt_mount->m_sb.sb_dblocks);
+       if (blkno >= eofs) {
+               /*
+                * XXX (dgc): we should really be returning EFSCORRUPTED here,
+                * but none of the higher level infrastructure supports
+                * returning a specific error on buffer lookup failures.
+                */
+               xfs_alert(btp->bt_mount,
+                         "%s: Block out of range: block 0x%llx, EOFS 0x%llx ",
+                         __func__, blkno, eofs);
+               return NULL;
+       }
+
        /* get tree root */
        pag = xfs_perag_get(btp->bt_mount,
                                xfs_daddr_to_agno(btp->bt_mount, blkno));
@@ -1487,6 +1505,8 @@ restart:
        while (!list_empty(&btp->bt_lru)) {
                bp = list_first_entry(&btp->bt_lru, struct xfs_buf, b_lru);
                if (atomic_read(&bp->b_hold) > 1) {
+                       trace_xfs_buf_wait_buftarg(bp, _RET_IP_);
+                       list_move_tail(&bp->b_lru, &btp->bt_lru);
                        spin_unlock(&btp->bt_lru_lock);
                        delay(100);
                        goto restart;
index 77b09750e92c3e05964a2924507342205fc463b1..3f9949fee391b11cdfd73c12799cccba4ce1b56b 100644 (file)
@@ -652,7 +652,10 @@ xfs_buf_item_unlock(
 
        /*
         * If the buf item isn't tracking any data, free it, otherwise drop the
-        * reference we hold to it.
+        * reference we hold to it. If we are aborting the transaction, this may
+        * be the only reference to the buf item, so we free it anyway
+        * regardless of whether it is dirty or not. A dirty abort implies a
+        * shutdown, anyway.
         */
        clean = 1;
        for (i = 0; i < bip->bli_format_count; i++) {
@@ -664,7 +667,12 @@ xfs_buf_item_unlock(
        }
        if (clean)
                xfs_buf_item_relse(bp);
-       else
+       else if (aborted) {
+               if (atomic_dec_and_test(&bip->bli_refcount)) {
+                       ASSERT(XFS_FORCED_SHUTDOWN(lip->li_mountp));
+                       xfs_buf_item_relse(bp);
+               }
+       } else
                atomic_dec(&bip->bli_refcount);
 
        if (!hold)
index d0e9c74d3d96a75c18d40f175efd51eec85aab18..a8bd26b82ecb00dd14063da4c62c1a64011f0caa 100644 (file)
@@ -246,10 +246,10 @@ xfs_swap_extents(
                goto out_unlock;
        }
 
-       error = -filemap_write_and_wait(VFS_I(ip)->i_mapping);
+       error = -filemap_write_and_wait(VFS_I(tip)->i_mapping);
        if (error)
                goto out_unlock;
-       truncate_pagecache_range(VFS_I(ip), 0, -1);
+       truncate_pagecache_range(VFS_I(tip), 0, -1);
 
        /* Verify O_DIRECT for ftmp */
        if (VN_CACHED(VFS_I(tip)) != 0) {
index add06b4e9a635511afc3e2716836e210ff794c46..364818eef40e55720a6a4509afbde63a1b48cd05 100644 (file)
@@ -351,6 +351,15 @@ xfs_iomap_prealloc_size(
                }
                if (shift)
                        alloc_blocks >>= shift;
+
+               /*
+                * If we are still trying to allocate more space than is
+                * available, squash the prealloc hard. This can happen if we
+                * have a large file on a small filesystem and the above
+                * lowspace thresholds are smaller than MAXEXTLEN.
+                */
+               while (alloc_blocks >= freesp)
+                       alloc_blocks >>= 4;
        }
 
        if (alloc_blocks < mp->m_writeio_blocks)
index da508463ff1006b7b4b5371d5f2c19495cb5d44b..7d6df7c00c36fb22e8f864285c6d2352b44a7cdd 100644 (file)
@@ -658,7 +658,7 @@ xfs_sb_quiet_read_verify(
                return;
        }
        /* quietly fail */
-       xfs_buf_ioerror(bp, EFSCORRUPTED);
+       xfs_buf_ioerror(bp, EWRONGFS);
 }
 
 static void
index 2e137d4a85ae66bc3a9172a4d93f734ba7aabb99..16a812977eab3d8fcf001e0175e6cfd773dcfe67 100644 (file)
@@ -341,6 +341,7 @@ DEFINE_BUF_EVENT(xfs_buf_item_relse);
 DEFINE_BUF_EVENT(xfs_buf_item_iodone);
 DEFINE_BUF_EVENT(xfs_buf_item_iodone_async);
 DEFINE_BUF_EVENT(xfs_buf_error_relse);
+DEFINE_BUF_EVENT(xfs_buf_wait_buftarg);
 DEFINE_BUF_EVENT(xfs_trans_read_buf_io);
 DEFINE_BUF_EVENT(xfs_trans_read_buf_shut);
 
index 8b84916dc6719ce46430fa791aa27c0bf8b16835..7a9498ab3c2d10dedf8af5c5dae3b2fd56753684 100644 (file)
@@ -618,18 +618,30 @@ extern int __init efi_setup_pcdp_console(char *);
 #endif
 
 /*
- * We play games with efi_enabled so that the compiler will, if possible, remove
- * EFI-related code altogether.
+ * We play games with efi_enabled so that the compiler will, if
+ * possible, remove EFI-related code altogether.
  */
+#define EFI_BOOT               0       /* Were we booted from EFI? */
+#define EFI_SYSTEM_TABLES      1       /* Can we use EFI system tables? */
+#define EFI_CONFIG_TABLES      2       /* Can we use EFI config tables? */
+#define EFI_RUNTIME_SERVICES   3       /* Can we use runtime services? */
+#define EFI_MEMMAP             4       /* Can we use EFI memory map? */
+#define EFI_64BIT              5       /* Is the firmware 64-bit? */
+
 #ifdef CONFIG_EFI
 # ifdef CONFIG_X86
-   extern int efi_enabled;
-   extern bool efi_64bit;
+extern int efi_enabled(int facility);
 # else
-#  define efi_enabled 1
+static inline int efi_enabled(int facility)
+{
+       return 1;
+}
 # endif
 #else
-# define efi_enabled 0
+static inline int efi_enabled(int facility)
+{
+       return 0;
+}
 #endif
 
 /*
index 2138bd33021a629f59b868d5a3938aefa4f87449..e53dcfeaee69bb052181261f4843c9da57f04e05 100644 (file)
@@ -272,8 +272,6 @@ struct abx500_bm_data {
        const struct abx500_fg_parameters *fg_params;
 };
 
-extern struct abx500_bm_data ab8500_bm_data;
-
 enum {
        NTC_EXTERNAL = 0,
        NTC_INTERNAL,
index 44310c98ee6eb59f38ca3024622966e6b528bf1d..9bd037df97d95a673d80f771cb9b1eaf56bce1c1 100644 (file)
@@ -422,7 +422,10 @@ struct ab8500_chargalg_platform_data {
 struct ab8500_btemp;
 struct ab8500_gpadc;
 struct ab8500_fg;
+
 #ifdef CONFIG_AB8500_BM
+extern struct abx500_bm_data ab8500_bm_data;
+
 void ab8500_fg_reinit(void);
 void ab8500_charger_usb_state_changed(u8 bm_usb_state, u16 mA);
 struct ab8500_btemp *ab8500_btemp_get(void);
@@ -434,31 +437,7 @@ int ab8500_fg_inst_curr_finalize(struct ab8500_fg *di, int *res);
 int ab8500_fg_inst_curr_done(struct ab8500_fg *di);
 
 #else
-int ab8500_fg_inst_curr_done(struct ab8500_fg *di)
-{
-}
-static void ab8500_fg_reinit(void)
-{
-}
-static void ab8500_charger_usb_state_changed(u8 bm_usb_state, u16 mA)
-{
-}
-static struct ab8500_btemp *ab8500_btemp_get(void)
-{
-       return NULL;
-}
-static int ab8500_btemp_get_batctrl_temp(struct ab8500_btemp *btemp)
-{
-       return 0;
-}
-struct ab8500_fg *ab8500_fg_get(void)
-{
-       return NULL;
-}
-static int ab8500_fg_inst_curr_blocking(struct ab8500_fg *dev)
-{
-       return -ENODEV;
-}
+static struct abx500_bm_data ab8500_bm_data;
 
 static inline int ab8500_fg_inst_curr_start(struct ab8500_fg *di)
 {
index 86dd93de6ff2b70ac4c693e8a9a05083bea72503..786d02eb79d2210ef8c3dfe145e3c8d0e0123ef1 100644 (file)
@@ -99,6 +99,9 @@ struct da9052 {
        u8 chip_id;
 
        int chip_irq;
+
+       /* SOC I/O transfer related fixes for DA9052/53 */
+       int (*fix_io) (struct da9052 *da9052, unsigned char reg);
 };
 
 /* ADC API */
@@ -113,32 +116,87 @@ static inline int da9052_reg_read(struct da9052 *da9052, unsigned char reg)
        ret = regmap_read(da9052->regmap, reg, &val);
        if (ret < 0)
                return ret;
+
+       if (da9052->fix_io) {
+               ret = da9052->fix_io(da9052, reg);
+               if (ret < 0)
+                       return ret;
+       }
+
        return val;
 }
 
 static inline int da9052_reg_write(struct da9052 *da9052, unsigned char reg,
                                    unsigned char val)
 {
-       return regmap_write(da9052->regmap, reg, val);
+       int ret;
+
+       ret = regmap_write(da9052->regmap, reg, val);
+       if (ret < 0)
+               return ret;
+
+       if (da9052->fix_io) {
+               ret = da9052->fix_io(da9052, reg);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return ret;
 }
 
 static inline int da9052_group_read(struct da9052 *da9052, unsigned char reg,
                                     unsigned reg_cnt, unsigned char *val)
 {
-       return regmap_bulk_read(da9052->regmap, reg, val, reg_cnt);
+       int ret;
+
+       ret = regmap_bulk_read(da9052->regmap, reg, val, reg_cnt);
+       if (ret < 0)
+               return ret;
+
+       if (da9052->fix_io) {
+               ret = da9052->fix_io(da9052, reg);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return ret;
 }
 
 static inline int da9052_group_write(struct da9052 *da9052, unsigned char reg,
                                      unsigned reg_cnt, unsigned char *val)
 {
-       return regmap_raw_write(da9052->regmap, reg, val, reg_cnt);
+       int ret;
+
+       ret = regmap_raw_write(da9052->regmap, reg, val, reg_cnt);
+       if (ret < 0)
+               return ret;
+
+       if (da9052->fix_io) {
+               ret = da9052->fix_io(da9052, reg);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return ret;
 }
 
 static inline int da9052_reg_update(struct da9052 *da9052, unsigned char reg,
                                     unsigned char bit_mask,
                                     unsigned char reg_val)
 {
-       return regmap_update_bits(da9052->regmap, reg, bit_mask, reg_val);
+       int ret;
+
+       ret = regmap_update_bits(da9052->regmap, reg, bit_mask, reg_val);
+       if (ret < 0)
+               return ret;
+
+       if (da9052->fix_io) {
+               ret = da9052->fix_io(da9052, reg);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return ret;
 }
 
 int da9052_device_init(struct da9052 *da9052, u8 chip_id);
index b97f7309d7f69e7189d74aead8ac4281a8ed0881..c4dd3a8add21b94cc526843c117734c506cc5233 100644 (file)
@@ -34,6 +34,9 @@
 #define DA9052_STATUS_C_REG            3
 #define DA9052_STATUS_D_REG            4
 
+/* PARK REGISTER */
+#define DA9052_PARK_REGISTER           DA9052_STATUS_D_REG
+
 /* EVENT REGISTERS */
 #define DA9052_EVENT_A_REG             5
 #define DA9052_EVENT_B_REG             6
index a8d393e3066b74465f14994740b758f1a134850b..2b13970596f53732cda07a6fd3b270cc9e933e5b 100644 (file)
@@ -38,6 +38,9 @@
 #define RTSX_SD_CARD                   0
 #define RTSX_MS_CARD                   1
 
+#define CLK_TO_DIV_N                   0
+#define DIV_N_TO_CLK                   1
+
 struct platform_device;
 
 struct rtsx_slot {
index 060b721fcbfb93b690d51191daeb95da692eef8c..4b117a3f54d493f59393226c6351e1fa8c1e16ca 100644 (file)
 #define SG_TRANS_DATA          (0x02 << 4)
 #define SG_LINK_DESC           (0x03 << 4)
 
-/* SD bank voltage */
-#define SD_IO_3V3              0
-#define SD_IO_1V8              1
-
+/* Output voltage */
+#define OUTPUT_3V3             0
+#define OUTPUT_1V8             1
 
 /* Card Clock Enable Register */
 #define SD_CLK_EN                      0x04
 #define CHANGE_CLK                     0x01
 
 /* LDO_CTL */
+#define BPP_ASIC_1V7                   0x00
+#define BPP_ASIC_1V8                   0x01
+#define BPP_ASIC_1V9                   0x02
+#define BPP_ASIC_2V0                   0x03
+#define BPP_ASIC_2V7                   0x04
+#define BPP_ASIC_2V8                   0x05
+#define BPP_ASIC_3V2                   0x06
+#define BPP_ASIC_3V3                   0x07
+#define BPP_REG_TUNED18                        0x07
+#define BPP_TUNED18_SHIFT_8402         5
+#define BPP_TUNED18_SHIFT_8411         4
+#define BPP_PAD_MASK                   0x04
+#define BPP_PAD_3V3                    0x04
+#define BPP_PAD_1V8                    0x00
 #define BPP_LDO_POWB                   0x03
 #define BPP_LDO_ON                     0x00
 #define BPP_LDO_SUSPEND                        0x02
@@ -688,7 +701,10 @@ struct pcr_ops {
        int             (*disable_auto_blink)(struct rtsx_pcr *pcr);
        int             (*card_power_on)(struct rtsx_pcr *pcr, int card);
        int             (*card_power_off)(struct rtsx_pcr *pcr, int card);
+       int             (*switch_output_voltage)(struct rtsx_pcr *pcr,
+                                               u8 voltage);
        unsigned int    (*cd_deglitch)(struct rtsx_pcr *pcr);
+       int             (*conv_clk_and_div_n)(int clk, int dir);
 };
 
 enum PDEV_STAT  {PDEV_STAT_IDLE, PDEV_STAT_RUN};
@@ -783,6 +799,7 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
                u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk);
 int rtsx_pci_card_power_on(struct rtsx_pcr *pcr, int card);
 int rtsx_pci_card_power_off(struct rtsx_pcr *pcr, int card);
+int rtsx_pci_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage);
 unsigned int rtsx_pci_card_exist(struct rtsx_pcr *pcr);
 void rtsx_pci_complete_unfinished_transfer(struct rtsx_pcr *pcr);
 
index 0f6afc657f778f2e682e7fb108e97b6788a53973..eee7478cda701ddeabc00150f607f368a4239350 100644 (file)
@@ -989,17 +989,29 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
  *     tells the LSM to decrement the number of secmark labeling rules loaded
  * @req_classify_flow:
  *     Sets the flow's sid to the openreq sid.
+ * @tun_dev_alloc_security:
+ *     This hook allows a module to allocate a security structure for a TUN
+ *     device.
+ *     @security pointer to a security structure pointer.
+ *     Returns a zero on success, negative values on failure.
+ * @tun_dev_free_security:
+ *     This hook allows a module to free the security structure for a TUN
+ *     device.
+ *     @security pointer to the TUN device's security structure
  * @tun_dev_create:
  *     Check permissions prior to creating a new TUN device.
- * @tun_dev_post_create:
- *     This hook allows a module to update or allocate a per-socket security
- *     structure.
- *     @sk contains the newly created sock structure.
+ * @tun_dev_attach_queue:
+ *     Check permissions prior to attaching to a TUN device queue.
+ *     @security pointer to the TUN device's security structure.
  * @tun_dev_attach:
- *     Check permissions prior to attaching to a persistent TUN device.  This
- *     hook can also be used by the module to update any security state
+ *     This hook can be used by the module to update any security state
  *     associated with the TUN device's sock structure.
  *     @sk contains the existing sock structure.
+ *     @security pointer to the TUN device's security structure.
+ * @tun_dev_open:
+ *     This hook can be used by the module to update any security state
+ *     associated with the TUN device's security structure.
+ *     @security pointer to the TUN devices's security structure.
  *
  * Security hooks for XFRM operations.
  *
@@ -1620,9 +1632,12 @@ struct security_operations {
        void (*secmark_refcount_inc) (void);
        void (*secmark_refcount_dec) (void);
        void (*req_classify_flow) (const struct request_sock *req, struct flowi *fl);
-       int (*tun_dev_create)(void);
-       void (*tun_dev_post_create)(struct sock *sk);
-       int (*tun_dev_attach)(struct sock *sk);
+       int (*tun_dev_alloc_security) (void **security);
+       void (*tun_dev_free_security) (void *security);
+       int (*tun_dev_create) (void);
+       int (*tun_dev_attach_queue) (void *security);
+       int (*tun_dev_attach) (struct sock *sk, void *security);
+       int (*tun_dev_open) (void *security);
 #endif /* CONFIG_SECURITY_NETWORK */
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
@@ -2566,9 +2581,12 @@ void security_inet_conn_established(struct sock *sk,
 int security_secmark_relabel_packet(u32 secid);
 void security_secmark_refcount_inc(void);
 void security_secmark_refcount_dec(void);
+int security_tun_dev_alloc_security(void **security);
+void security_tun_dev_free_security(void *security);
 int security_tun_dev_create(void);
-void security_tun_dev_post_create(struct sock *sk);
-int security_tun_dev_attach(struct sock *sk);
+int security_tun_dev_attach_queue(void *security);
+int security_tun_dev_attach(struct sock *sk, void *security);
+int security_tun_dev_open(void *security);
 
 #else  /* CONFIG_SECURITY_NETWORK */
 static inline int security_unix_stream_connect(struct sock *sock,
@@ -2733,16 +2751,31 @@ static inline void security_secmark_refcount_dec(void)
 {
 }
 
+static inline int security_tun_dev_alloc_security(void **security)
+{
+       return 0;
+}
+
+static inline void security_tun_dev_free_security(void *security)
+{
+}
+
 static inline int security_tun_dev_create(void)
 {
        return 0;
 }
 
-static inline void security_tun_dev_post_create(struct sock *sk)
+static inline int security_tun_dev_attach_queue(void *security)
+{
+       return 0;
+}
+
+static inline int security_tun_dev_attach(struct sock *sk, void *security)
 {
+       return 0;
 }
 
-static inline int security_tun_dev_attach(struct sock *sk)
+static inline int security_tun_dev_open(void *security)
 {
        return 0;
 }
index bd45eb7bedc8f365ab70704c552e93041af4ac94..5de7a220e98680f9c9cfc7b36c1f5c2114d7144f 100644 (file)
@@ -100,6 +100,7 @@ struct driver_info {
 #define FLAG_LINK_INTR 0x0800          /* updates link (carrier) status */
 
 #define FLAG_POINTTOPOINT 0x1000       /* possibly use "usb%d" names */
+#define FLAG_NOARP     0x2000          /* device can't do ARP */
 
 /*
  * Indicates to usbnet, that USB driver accumulates multiple IP packets.
diff --git a/include/ne