Merge tag 'nfs-for-3.8-4' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 31 Jan 2013 21:43:52 +0000 (08:43 +1100)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 31 Jan 2013 21:43:52 +0000 (08:43 +1100)
Pull NFS client bugfixes from Trond Myklebust:

 - Error reporting in nfs_xdev_mount incorrectly maps all errors to
   ENOMEM

 - Fix an NFSv4 refcounting issue

 - Fix a mount failure when the server reboots during NFSv4 trunking
   discovery

 - NFSv4.1 mounts may need to run the lease recovery thread.

 - Don't silently fail setattr() requests on mountpoints

 - Fix a SUNRPC socket/transport livelock and priority queue issue

 - We must handle NFS4ERR_DELAY when resetting the NFSv4.1 session.

* tag 'nfs-for-3.8-4' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
  NFSv4.1: Handle NFS4ERR_DELAY when resetting the NFSv4.1 session
  SUNRPC: When changing the queue priority, ensure that we change the owner
  NFS: Don't silently fail setattr() requests on mountpoints
  NFSv4.1: Ensure that nfs41_walk_client_list() does start lease recovery
  NFSv4: Fix NFSv4 trunking discovery
  NFSv4: Fix NFSv4 reference counting for trunked sessions
  NFS: Fix error reporting in nfs_xdev_mount

238 files changed:
Documentation/device-mapper/dm-raid.txt
Documentation/x86/boot.txt
Documentation/x86/zero-page.txt
MAINTAINERS
arch/mips/bcm47xx/Kconfig
arch/mips/cavium-octeon/executive/cvmx-l2c.c
arch/mips/include/asm/break.h [deleted file]
arch/mips/include/asm/dsp.h
arch/mips/include/asm/inst.h
arch/mips/include/asm/mach-pnx833x/war.h
arch/mips/include/asm/pgtable-64.h
arch/mips/include/uapi/asm/Kbuild
arch/mips/include/uapi/asm/break.h [new file with mode: 0644]
arch/mips/kernel/ftrace.c
arch/mips/kernel/mcount.S
arch/mips/kernel/vpe.c
arch/mips/lantiq/irq.c
arch/mips/lib/delay.c
arch/mips/mm/ioremap.c
arch/mips/mm/mmap.c
arch/mips/netlogic/xlr/setup.c
arch/mips/pci/pci-ar71xx.c
arch/mips/pci/pci-ar724x.c
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/boot/Makefile
arch/x86/boot/compressed/eboot.c
arch/x86/boot/compressed/head_32.S
arch/x86/boot/compressed/head_64.S
arch/x86/boot/header.S
arch/x86/boot/setup.ld
arch/x86/boot/tools/build.c
arch/x86/include/asm/efi.h
arch/x86/include/asm/uv/uv.h
arch/x86/include/uapi/asm/bootparam.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/efi/efi_64.c
arch/x86/platform/uv/tlb_uv.c
arch/x86/tools/relocs.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 406d82d5d2bb1e08a8cb9e4c548ce937f448b376..3edb4c2887a1f816eaf0f53f7dbf800bf73bf42a 100644 (file)
@@ -57,6 +57,10 @@ Protocol 2.10:       (Kernel 2.6.31) Added a protocol for relaxed alignment
 Protocol 2.11: (Kernel 3.6) Added a field for offset of EFI handover
                protocol entry point.
 
+Protocol 2.12: (Kernel 3.9) Added the xloadflags field and extension fields
+               to struct boot_params for for loading bzImage and ramdisk
+               above 4G in 64bit.
+
 **** MEMORY LAYOUT
 
 The traditional memory map for the kernel loader, used for Image or
@@ -182,7 +186,7 @@ Offset      Proto   Name            Meaning
 0230/4 2.05+   kernel_alignment Physical addr alignment required for kernel
 0234/1 2.05+   relocatable_kernel Whether kernel is relocatable or not
 0235/1 2.10+   min_alignment   Minimum alignment, as a power of two
-0236/2 N/A     pad3            Unused
+0236/2 2.12+   xloadflags      Boot protocol option flags
 0238/4 2.06+   cmdline_size    Maximum size of the kernel command line
 023C/4 2.07+   hardware_subarch Hardware subarchitecture
 0240/8 2.07+   hardware_subarch_data Subarchitecture-specific data
@@ -582,6 +586,27 @@ Protocol:  2.10+
   misaligned kernel.  Therefore, a loader should typically try each
   power-of-two alignment from kernel_alignment down to this alignment.
 
+Field name:     xloadflags
+Type:           read
+Offset/size:    0x236/2
+Protocol:       2.12+
+
+  This field is a bitmask.
+
+  Bit 0 (read):        XLF_KERNEL_64
+       - If 1, this kernel has the legacy 64-bit entry point at 0x200.
+
+  Bit 1 (read): XLF_CAN_BE_LOADED_ABOVE_4G
+        - If 1, kernel/boot_params/cmdline/ramdisk can be above 4G.
+
+  Bit 2 (read):        XLF_EFI_HANDOVER_32
+       - If 1, the kernel supports the 32-bit EFI handoff entry point
+          given at handover_offset.
+
+  Bit 3 (read): XLF_EFI_HANDOVER_64
+       - If 1, the kernel supports the 64-bit EFI handoff entry point
+          given at handover_offset + 0x200.
+
 Field name:    cmdline_size
 Type:          read
 Offset/size:   0x238/4
index cf5437deda81a003864f9e8a5f4e533d276a189d..199f453cb4de10016030c2dd230fb9a3a3125cee 100644 (file)
@@ -19,6 +19,9 @@ Offset        Proto   Name            Meaning
 090/010        ALL     hd1_info        hd1 disk parameter, OBSOLETE!!
 0A0/010        ALL     sys_desc_table  System description table (struct sys_desc_table)
 0B0/010        ALL     olpc_ofw_header OLPC's OpenFirmware CIF and friends
+0C0/004        ALL     ext_ramdisk_image ramdisk_image high 32bits
+0C4/004        ALL     ext_ramdisk_size  ramdisk_size high 32bits
+0C8/004        ALL     ext_cmd_line_ptr  cmd_line_ptr high 32bits
 140/080        ALL     edid_info       Video mode setup (struct edid_info)
 1C0/020        ALL     efi_info        EFI 32 information (struct efi_info)
 1E0/004        ALL     alk_mem_k       Alternative mem check, in KB
@@ -27,6 +30,7 @@ Offset        Proto   Name            Meaning
 1E9/001        ALL     eddbuf_entries  Number of entries in eddbuf (below)
 1EA/001        ALL     edd_mbr_sig_buf_entries Number of entries in edd_mbr_sig_buffer
                                (below)
+1EF/001        ALL     sentinel        Used to detect broken bootloaders
 290/040        ALL     edd_mbr_sig_buffer EDD MBR signatures
 2D0/A00        ALL     e820_map        E820 memory map table
                                (array of struct e820entry)
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 d7af29f1fcf0079c7ccdcae5af9f0add4c8c2c80..ba611927749b9f81def164126a2b2b1d00bf42c5 100644 (file)
@@ -8,8 +8,10 @@ config BCM47XX_SSB
        select SSB_DRIVER_EXTIF
        select SSB_EMBEDDED
        select SSB_B43_PCI_BRIDGE if PCI
+       select SSB_DRIVER_PCICORE if PCI
        select SSB_PCICORE_HOSTMODE if PCI
        select SSB_DRIVER_GPIO
+       select GPIOLIB
        default y
        help
         Add support for old Broadcom BCM47xx boards with Sonics Silicon Backplane support.
@@ -25,6 +27,7 @@ config BCM47XX_BCMA
        select BCMA_HOST_PCI if PCI
        select BCMA_DRIVER_PCI_HOSTMODE if PCI
        select BCMA_DRIVER_GPIO
+       select GPIOLIB
        default y
        help
         Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus.
index 9f883bf769530d18c880416850060cd738bb0fa8..33b72144db3100625bd17991c1651ddd803ddf2b 100644 (file)
@@ -30,6 +30,7 @@
  * measurement, and debugging facilities.
  */
 
+#include <linux/compiler.h>
 #include <linux/irqflags.h>
 #include <asm/octeon/cvmx.h>
 #include <asm/octeon/cvmx-l2c.h>
@@ -285,22 +286,22 @@ uint64_t cvmx_l2c_read_perf(uint32_t counter)
  */
 static void fault_in(uint64_t addr, int len)
 {
-       volatile char *ptr;
-       volatile char dummy;
+       char *ptr;
+
        /*
         * Adjust addr and length so we get all cache lines even for
         * small ranges spanning two cache lines.
         */
        len += addr & CVMX_CACHE_LINE_MASK;
        addr &= ~CVMX_CACHE_LINE_MASK;
-       ptr = (volatile char *)cvmx_phys_to_ptr(addr);
+       ptr = cvmx_phys_to_ptr(addr);
        /*
         * Invalidate L1 cache to make sure all loads result in data
         * being in L2.
         */
        CVMX_DCACHE_INVALIDATE;
        while (len > 0) {
-               dummy += *ptr;
+               ACCESS_ONCE(*ptr);
                len -= CVMX_CACHE_LINE_SIZE;
                ptr += CVMX_CACHE_LINE_SIZE;
        }
diff --git a/arch/mips/include/asm/break.h b/arch/mips/include/asm/break.h
deleted file mode 100644 (file)
index 9161e68..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1995, 2003 by Ralf Baechle
- * Copyright (C) 1999 Silicon Graphics, Inc.
- */
-#ifndef __ASM_BREAK_H
-#define __ASM_BREAK_H
-
-/*
- * The following break codes are or were in use for specific purposes in
- * other MIPS operating systems.  Linux/MIPS doesn't use all of them.  The
- * unused ones are here as placeholders; we might encounter them in
- * non-Linux/MIPS object files or make use of them in the future.
- */
-#define BRK_USERBP     0       /* User bp (used by debuggers) */
-#define BRK_KERNELBP   1       /* Break in the kernel */
-#define BRK_ABORT      2       /* Sometimes used by abort(3) to SIGIOT */
-#define BRK_BD_TAKEN   3       /* For bd slot emulation - not implemented */
-#define BRK_BD_NOTTAKEN        4       /* For bd slot emulation - not implemented */
-#define BRK_SSTEPBP    5       /* User bp (used by debuggers) */
-#define BRK_OVERFLOW   6       /* Overflow check */
-#define BRK_DIVZERO    7       /* Divide by zero check */
-#define BRK_RANGE      8       /* Range error check */
-#define BRK_STACKOVERFLOW 9    /* For Ada stackchecking */
-#define BRK_NORLD      10      /* No rld found - not used by Linux/MIPS */
-#define _BRK_THREADBP  11      /* For threads, user bp (used by debuggers) */
-#define BRK_BUG                512     /* Used by BUG() */
-#define BRK_KDB                513     /* Used in KDB_ENTER() */
-#define BRK_MEMU       514     /* Used by FPU emulator */
-#define BRK_KPROBE_BP  515     /* Kprobe break */
-#define BRK_KPROBE_SSTEPBP 516 /* Kprobe single step software implementation */
-#define BRK_MULOVF     1023    /* Multiply overflow */
-
-#endif /* __ASM_BREAK_H */
index e9bfc0813c72e99a46b29dadb1c3556843fc31a1..7bfad0520e25731c548c949ccecc045e91bba002 100644 (file)
@@ -16,7 +16,7 @@
 #include <asm/mipsregs.h>
 
 #define DSP_DEFAULT    0x00000000
-#define DSP_MASK       0x3ff
+#define DSP_MASK       0x3f
 
 #define __enable_dsp_hazard()                                          \
 do {                                                                   \
index ab84064283db2c50d847d888b32e42a4d316dd7d..33c34adbecfa19ae457699d449d8242ed5a0f43c 100644 (file)
@@ -353,6 +353,7 @@ union mips_instruction {
        struct u_format u_format;
        struct c_format c_format;
        struct r_format r_format;
+       struct p_format p_format;
        struct f_format f_format;
        struct ma_format ma_format;
        struct b_format b_format;
index edaa06d9d492171090e10ee08ad370fae79bebe9..e410df4e1b3a650d99d8981c7b63c04d4218daf4 100644 (file)
@@ -21,4 +21,4 @@
 #define R10000_LLSC_WAR                        0
 #define MIPS34K_MISSED_ITLB_WAR                0
 
-#endif /* __ASM_MIPS_MACH_PNX8550_WAR_H */
+#endif /* __ASM_MIPS_MACH_PNX833X_WAR_H */
index c63191055e695c5a49812f3f32ed0c913d941a0a..013d5f781263e20cf3d9e93cf14b6552c4386cc8 100644 (file)
@@ -230,6 +230,7 @@ static inline void pud_clear(pud_t *pudp)
 #else
 #define pte_pfn(x)             ((unsigned long)((x).pte >> _PFN_SHIFT))
 #define pfn_pte(pfn, prot)     __pte(((pfn) << _PFN_SHIFT) | pgprot_val(prot))
+#define pfn_pmd(pfn, prot)     __pmd(((pfn) << _PFN_SHIFT) | pgprot_val(prot))
 #endif
 
 #define __pgd_offset(address)  pgd_index(address)
index a1a0452ac1853333b07dac4dc7495c9bdd2514a5..77d4fb33f75ad1dd765ba69f697ed771312b3e9a 100644 (file)
@@ -3,6 +3,7 @@ include include/uapi/asm-generic/Kbuild.asm
 
 header-y += auxvec.h
 header-y += bitsperlong.h
+header-y += break.h
 header-y += byteorder.h
 header-y += cachectl.h
 header-y += errno.h
diff --git a/arch/mips/include/uapi/asm/break.h b/arch/mips/include/uapi/asm/break.h
new file mode 100644 (file)
index 0000000..9161e68
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 2003 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef __ASM_BREAK_H
+#define __ASM_BREAK_H
+
+/*
+ * The following break codes are or were in use for specific purposes in
+ * other MIPS operating systems.  Linux/MIPS doesn't use all of them.  The
+ * unused ones are here as placeholders; we might encounter them in
+ * non-Linux/MIPS object files or make use of them in the future.
+ */
+#define BRK_USERBP     0       /* User bp (used by debuggers) */
+#define BRK_KERNELBP   1       /* Break in the kernel */
+#define BRK_ABORT      2       /* Sometimes used by abort(3) to SIGIOT */
+#define BRK_BD_TAKEN   3       /* For bd slot emulation - not implemented */
+#define BRK_BD_NOTTAKEN        4       /* For bd slot emulation - not implemented */
+#define BRK_SSTEPBP    5       /* User bp (used by debuggers) */
+#define BRK_OVERFLOW   6       /* Overflow check */
+#define BRK_DIVZERO    7       /* Divide by zero check */
+#define BRK_RANGE      8       /* Range error check */
+#define BRK_STACKOVERFLOW 9    /* For Ada stackchecking */
+#define BRK_NORLD      10      /* No rld found - not used by Linux/MIPS */
+#define _BRK_THREADBP  11      /* For threads, user bp (used by debuggers) */
+#define BRK_BUG                512     /* Used by BUG() */
+#define BRK_KDB                513     /* Used in KDB_ENTER() */
+#define BRK_MEMU       514     /* Used by FPU emulator */
+#define BRK_KPROBE_BP  515     /* Kprobe break */
+#define BRK_KPROBE_SSTEPBP 516 /* Kprobe single step software implementation */
+#define BRK_MULOVF     1023    /* Multiply overflow */
+
+#endif /* __ASM_BREAK_H */
index 6a2d758dd8e9ed0b4a0afb043d2972869620834c..83fa1460e294e02cf602cd5d611af6d02abbba39 100644 (file)
 #define MCOUNT_OFFSET_INSNS 4
 #endif
 
+/* Arch override because MIPS doesn't need to run this from stop_machine() */
+void arch_ftrace_update_code(int command)
+{
+       ftrace_modify_all_code(command);
+}
+
 /*
  * Check if the address is in kernel space
  *
@@ -89,6 +95,24 @@ static int ftrace_modify_code(unsigned long ip, unsigned int new_code)
        return 0;
 }
 
+#ifndef CONFIG_64BIT
+static int ftrace_modify_code_2(unsigned long ip, unsigned int new_code1,
+                               unsigned int new_code2)
+{
+       int faulted;
+
+       safe_store_code(new_code1, ip, faulted);
+       if (unlikely(faulted))
+               return -EFAULT;
+       ip += 4;
+       safe_store_code(new_code2, ip, faulted);
+       if (unlikely(faulted))
+               return -EFAULT;
+       flush_icache_range(ip, ip + 8); /* original ip + 12 */
+       return 0;
+}
+#endif
+
 /*
  * The details about the calling site of mcount on MIPS
  *
@@ -131,8 +155,18 @@ int ftrace_make_nop(struct module *mod,
         * needed.
         */
        new = in_kernel_space(ip) ? INSN_NOP : INSN_B_1F;
-
+#ifdef CONFIG_64BIT
        return ftrace_modify_code(ip, new);
+#else
+       /*
+        * On 32 bit MIPS platforms, gcc adds a stack adjust
+        * instruction in the delay slot after the branch to
+        * mcount and expects mcount to restore the sp on return.
+        * This is based on a legacy API and does nothing but
+        * waste instructions so it's being removed at runtime.
+        */
+       return ftrace_modify_code_2(ip, new, INSN_NOP);
+#endif
 }
 
 int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
index 4c968e7efb747d997ec20ba8ceeb500f4c12807d..1658676733576e74867347f0f7d122df0c5a023e 100644 (file)
@@ -46,9 +46,8 @@
        PTR_L   a5, PT_R9(sp)
        PTR_L   a6, PT_R10(sp)
        PTR_L   a7, PT_R11(sp)
-       PTR_ADDIU       sp, PT_SIZE
 #else
-       PTR_ADDIU       sp, (PT_SIZE + 8)
+       PTR_ADDIU       sp, PT_SIZE
 #endif
 .endm
 
@@ -69,7 +68,9 @@ NESTED(ftrace_caller, PT_SIZE, ra)
        .globl _mcount
 _mcount:
        b       ftrace_stub
-        nop
+       addiu sp,sp,8
+
+       /* When tracing is activated, it calls ftrace_caller+8 (aka here) */
        lw      t1, function_trace_stop
        bnez    t1, ftrace_stub
         nop
index eec690af6581616957089993e2decfd91f13b4fd..147cec19621d7a433429e66433fdd993c2abd62e 100644 (file)
@@ -705,7 +705,7 @@ static int vpe_run(struct vpe * v)
 
                        printk(KERN_WARNING
                               "VPE loader: TC %d is already in use.\n",
-                               t->index);
+                              v->tc->index);
                        return -ENOEXEC;
                }
        } else {
index f36acd1b38086d341458d927c4c4db99d3a40e0f..a7935bf0fecbf789299a2547abb7b0b2e8677e2b 100644 (file)
@@ -408,7 +408,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
 #endif
 
        /* tell oprofile which irq to use */
-       cp0_perfcount_irq = LTQ_PERF_IRQ;
+       cp0_perfcount_irq = irq_create_mapping(ltq_domain, LTQ_PERF_IRQ);
 
        /*
         * if the timer irq is not one of the mips irqs we need to
index dc81ca8dc0dd4b0ccd81ae2edc78b059aa8fd016..288f7954988d06ef61cc94bbf29dfeab322796b8 100644 (file)
@@ -21,7 +21,7 @@ void __delay(unsigned long loops)
        "       .set    noreorder                               \n"
        "       .align  3                                       \n"
        "1:     bnez    %0, 1b                                  \n"
-#if __SIZEOF_LONG__ == 4
+#if BITS_PER_LONG == 32
        "       subu    %0, 1                                   \n"
 #else
        "       dsubu   %0, 1                                   \n"
index 7657fd21cd3fb35779ad6a37ff65c73547cedc88..cacfd31e8ec9d1121c86e81feb35fac4344a9a3b 100644 (file)
@@ -190,9 +190,3 @@ void __iounmap(const volatile void __iomem *addr)
 
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(__iounmap);
-
-int __virt_addr_valid(const volatile void *kaddr)
-{
-       return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
-}
-EXPORT_SYMBOL_GPL(__virt_addr_valid);
index d9be7540a6be7979a265a3ce32acbbe241b2b91c..7e5fe2790d8a212a8d0163989280918d26a46a3c 100644 (file)
@@ -192,3 +192,9 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
 
        return ret;
 }
+
+int __virt_addr_valid(const volatile void *kaddr)
+{
+       return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
+}
+EXPORT_SYMBOL_GPL(__virt_addr_valid);
index 4e7f49d3d5a8105c45dd09a6b86999ed0506a7d7..c5ce6992ac4c7086aea4167a7460723a5d0cb7be 100644 (file)
@@ -193,8 +193,11 @@ static void nlm_init_node(void)
 
 void __init prom_init(void)
 {
-       int i, *argv, *envp;            /* passed as 32 bit ptrs */
+       int *argv, *envp;               /* passed as 32 bit ptrs */
        struct psb_info *prom_infop;
+#ifdef CONFIG_SMP
+       int i;
+#endif
 
        /* truncate to 32 bit and sign extend all args */
        argv = (int *)(long)(int)fw_arg1;
index 1552522b8718bffb86762229ef5279b93094df16..6eaa4f2d0e38cb8c85e31734c7e090ec9a491cb3 100644 (file)
@@ -24,7 +24,7 @@
 #include <asm/mach-ath79/pci.h>
 
 #define AR71XX_PCI_MEM_BASE    0x10000000
-#define AR71XX_PCI_MEM_SIZE    0x08000000
+#define AR71XX_PCI_MEM_SIZE    0x07000000
 
 #define AR71XX_PCI_WIN0_OFFS           0x10000000
 #define AR71XX_PCI_WIN1_OFFS           0x11000000
index 86d77a666458bae80c60f94c9fc405dca5f8459c..c11c75be2d7e06ab0b1232c35926a8ec3c5ba574 100644 (file)
@@ -21,7 +21,7 @@
 #define AR724X_PCI_CTRL_SIZE   0x100
 
 #define AR724X_PCI_MEM_BASE    0x10000000
-#define AR724X_PCI_MEM_SIZE    0x08000000
+#define AR724X_PCI_MEM_SIZE    0x04000000
 
 #define AR724X_PCI_REG_RESET           0x18
 #define AR724X_PCI_REG_INT_STATUS      0x4c
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 ccce0ed67dde703a80c78309252abbef17828291..379814bc41e3a956dc037a5f1d4ca23709854fbc 100644 (file)
@@ -71,7 +71,7 @@ GCOV_PROFILE := n
 $(obj)/bzImage: asflags-y  := $(SVGA_MODE)
 
 quiet_cmd_image = BUILD   $@
-cmd_image = $(obj)/tools/build $(obj)/setup.bin $(obj)/vmlinux.bin > $@
+cmd_image = $(obj)/tools/build $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/zoffset.h > $@
 
 $(obj)/bzImage: $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/tools/build FORCE
        $(call if_changed,image)
@@ -92,7 +92,7 @@ targets += voffset.h
 $(obj)/voffset.h: vmlinux FORCE
        $(call if_changed,voffset)
 
-sed-zoffset := -e 's/^\([0-9a-fA-F]*\) . \(startup_32\|input_data\|_end\|z_.*\)$$/\#define ZO_\2 0x\1/p'
+sed-zoffset := -e 's/^\([0-9a-fA-F]*\) . \(startup_32\|startup_64\|efi_pe_entry\|efi_stub_entry\|input_data\|_end\|z_.*\)$$/\#define ZO_\2 0x\1/p'
 
 quiet_cmd_zoffset = ZOFFSET $@
       cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@
index 18e329ca108e5f720adf1974fa1e90c8b2626991..f8fa41190c3526f61ec7bb6e1dc5b0ebf08b3c4d 100644 (file)
@@ -256,10 +256,10 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
        int i;
        struct setup_data *data;
 
-       data = (struct setup_data *)params->hdr.setup_data;
+       data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
 
        while (data && data->next)
-               data = (struct setup_data *)data->next;
+               data = (struct setup_data *)(unsigned long)data->next;
 
        status = efi_call_phys5(sys_table->boottime->locate_handle,
                                EFI_LOCATE_BY_PROTOCOL, &pci_proto,
@@ -295,16 +295,18 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
                if (!pci)
                        continue;
 
+#ifdef CONFIG_X86_64
                status = efi_call_phys4(pci->attributes, pci,
                                        EfiPciIoAttributeOperationGet, 0,
                                        &attributes);
-
+#else
+               status = efi_call_phys5(pci->attributes, pci,
+                                       EfiPciIoAttributeOperationGet, 0, 0,
+                                       &attributes);
+#endif
                if (status != EFI_SUCCESS)
                        continue;
 
-               if (!(attributes & EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM))
-                       continue;
-
                if (!pci->romimage || !pci->romsize)
                        continue;
 
@@ -345,9 +347,9 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
                memcpy(rom->romdata, pci->romimage, pci->romsize);
 
                if (data)
-                       data->next = (uint64_t)rom;
+                       data->next = (unsigned long)rom;
                else
-                       params->hdr.setup_data = (uint64_t)rom;
+                       params->hdr.setup_data = (unsigned long)rom;
 
                data = (struct setup_data *)rom;
 
@@ -432,10 +434,9 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
                         * Once we've found a GOP supporting ConOut,
                         * don't bother looking any further.
                         */
+                       first_gop = gop;
                        if (conout_found)
                                break;
-
-                       first_gop = gop;
                }
        }
 
index aa4aaf1b23803e8ef0e180e3cbeedc7a4db6c556..1e3184f6072f913250b3b18371978a4fd1b3f63d 100644 (file)
@@ -35,11 +35,11 @@ ENTRY(startup_32)
 #ifdef CONFIG_EFI_STUB
        jmp     preferred_addr
 
-       .balign 0x10
        /*
         * We don't need the return address, so set up the stack so
-        * efi_main() can find its arugments.
+        * efi_main() can find its arguments.
         */
+ENTRY(efi_pe_entry)
        add     $0x4, %esp
 
        call    make_boot_params
@@ -50,8 +50,10 @@ ENTRY(startup_32)
        pushl   %eax
        pushl   %esi
        pushl   %ecx
+       sub     $0x4, %esp
 
-       .org 0x30,0x90
+ENTRY(efi_stub_entry)
+       add     $0x4, %esp
        call    efi_main
        cmpl    $0, %eax
        movl    %eax, %esi
index 2c4b171eec337619e8f2dab2b3c3b2048e622e51..f5d1aaa0dec87ce844317f2a343a90739408ac22 100644 (file)
@@ -201,12 +201,12 @@ ENTRY(startup_64)
         */
 #ifdef CONFIG_EFI_STUB
        /*
-        * The entry point for the PE/COFF executable is 0x210, so only
-        * legacy boot loaders will execute this jmp.
+        * The entry point for the PE/COFF executable is efi_pe_entry, so
+        * only legacy boot loaders will execute this jmp.
         */
        jmp     preferred_addr
 
-       .org 0x210
+ENTRY(efi_pe_entry)
        mov     %rcx, %rdi
        mov     %rdx, %rsi
        pushq   %rdi
@@ -218,7 +218,7 @@ ENTRY(startup_64)
        popq    %rsi
        popq    %rdi
 
-       .org 0x230,0x90
+ENTRY(efi_stub_entry)
        call    efi_main
        movq    %rax,%rsi
        cmpq    $0,%rax
index 8c132a625b94991c179def21973bb8ad3c3a56d5..944ce595f767621f07a47d6c89cdea9415627663 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/e820.h>
 #include <asm/page_types.h>
 #include <asm/setup.h>
+#include <asm/bootparam.h>
 #include "boot.h"
 #include "voffset.h"
 #include "zoffset.h"
@@ -255,6 +256,9 @@ section_table:
        # header, from the old boot sector.
 
        .section ".header", "a"
+       .globl  sentinel
+sentinel:      .byte 0xff, 0xff        /* Used to detect broken loaders */
+
        .globl  hdr
 hdr:
 setup_sects:   .byte 0                 /* Filled in by build.c */
@@ -279,7 +283,7 @@ _start:
        # Part 2 of the header, from the old setup.S
 
                .ascii  "HdrS"          # header signature
-               .word   0x020b          # header version number (>= 0x0105)
+               .word   0x020c          # header version number (>= 0x0105)
                                        # or else old loadlin-1.5 will fail)
                .globl realmode_swtch
 realmode_swtch:        .word   0, 0            # default_switch, SETUPSEG
@@ -297,13 +301,7 @@ type_of_loader:    .byte   0               # 0 means ancient bootloader, newer
 
 # flags, unused bits must be zero (RFU) bit within loadflags
 loadflags:
-LOADED_HIGH    = 1                     # If set, the kernel is loaded high
-CAN_USE_HEAP   = 0x80                  # If set, the loader also has set
-                                       # heap_end_ptr to tell how much
-                                       # space behind setup.S can be used for
-                                       # heap purposes.
-                                       # Only the loader knows what is free
-               .byte   LOADED_HIGH
+               .byte   LOADED_HIGH     # The kernel is to be loaded high
 
 setup_move_size: .word  0x8000         # size to move, when setup is not
                                        # loaded at 0x90000. We will move setup
@@ -369,7 +367,23 @@ relocatable_kernel:    .byte 1
 relocatable_kernel:    .byte 0
 #endif
 min_alignment:         .byte MIN_KERNEL_ALIGN_LG2      # minimum alignment
-pad3:                  .word 0
+
+xloadflags:
+#ifdef CONFIG_X86_64
+# define XLF0 XLF_KERNEL_64                    /* 64-bit kernel */
+#else
+# define XLF0 0
+#endif
+#ifdef CONFIG_EFI_STUB
+# ifdef CONFIG_X86_64
+#  define XLF23 XLF_EFI_HANDOVER_64            /* 64-bit EFI handover ok */
+# else
+#  define XLF23 XLF_EFI_HANDOVER_32            /* 32-bit EFI handover ok */
+# endif
+#else
+# define XLF23 0
+#endif
+                       .word XLF0 | XLF23
 
 cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
                                                 #added with boot protocol
@@ -397,8 +411,13 @@ pref_address:              .quad LOAD_PHYSICAL_ADDR        # preferred load addr
 #define INIT_SIZE VO_INIT_SIZE
 #endif
 init_size:             .long INIT_SIZE         # kernel initialization size
-handover_offset:       .long 0x30              # offset to the handover
+handover_offset:
+#ifdef CONFIG_EFI_STUB
+                       .long 0x30              # offset to the handover
                                                # protocol entry point
+#else
+                       .long 0
+#endif
 
 # End of setup header #####################################################
 
index 03c0683636b6fbf859a8795262f249631e6157f9..96a6c7563538364d2dee7e307846815156c11c33 100644 (file)
@@ -13,7 +13,7 @@ SECTIONS
        .bstext         : { *(.bstext) }
        .bsdata         : { *(.bsdata) }
 
-       . = 497;
+       . = 495;
        .header         : { *(.header) }
        .entrytext      : { *(.entrytext) }
        .inittext       : { *(.inittext) }
index 4b8e165ee5723643dcd89619a341c7559eafe2bd..94c54465002003e34af8f6fb3d14a1be839fdeba 100644 (file)
@@ -52,6 +52,10 @@ int is_big_kernel;
 
 #define PECOFF_RELOC_RESERVE 0x20
 
+unsigned long efi_stub_entry;
+unsigned long efi_pe_entry;
+unsigned long startup_64;
+
 /*----------------------------------------------------------------------*/
 
 static const u32 crctab32[] = {
@@ -132,7 +136,7 @@ static void die(const char * str, ...)
 
 static void usage(void)
 {
-       die("Usage: build setup system [> image]");
+       die("Usage: build setup system [zoffset.h] [> image]");
 }
 
 #ifdef CONFIG_EFI_STUB
@@ -206,30 +210,54 @@ static void update_pecoff_text(unsigned int text_start, unsigned int file_sz)
         */
        put_unaligned_le32(file_sz - 512, &buf[pe_header + 0x1c]);
 
-#ifdef CONFIG_X86_32
        /*
-        * Address of entry point.
-        *
-        * The EFI stub entry point is +16 bytes from the start of
-        * the .text section.
+        * Address of entry point for PE/COFF executable
         */
-       put_unaligned_le32(text_start + 16, &buf[pe_header + 0x28]);
-#else
-       /*
-        * Address of entry point. startup_32 is at the beginning and
-        * the 64-bit entry point (startup_64) is always 512 bytes
-        * after. The EFI stub entry point is 16 bytes after that, as
-        * the first instruction allows legacy loaders to jump over
-        * the EFI stub initialisation
-        */
-       put_unaligned_le32(text_start + 528, &buf[pe_header + 0x28]);
-#endif /* CONFIG_X86_32 */
+       put_unaligned_le32(text_start + efi_pe_entry, &buf[pe_header + 0x28]);
 
        update_pecoff_section_header(".text", text_start, text_sz);
 }
 
 #endif /* CONFIG_EFI_STUB */
 
+
+/*
+ * Parse zoffset.h and find the entry points. We could just #include zoffset.h
+ * but that would mean tools/build would have to be rebuilt every time. It's
+ * not as if parsing it is hard...
+ */
+#define PARSE_ZOFS(p, sym) do { \
+       if (!strncmp(p, "#define ZO_" #sym " ", 11+sizeof(#sym)))       \
+               sym = strtoul(p + 11 + sizeof(#sym), NULL, 16);         \
+} while (0)
+
+static void parse_zoffset(char *fname)
+{
+       FILE *file;
+       char *p;
+       int c;
+
+       file = fopen(fname, "r");
+       if (!file)
+               die("Unable to open `%s': %m", fname);
+       c = fread(buf, 1, sizeof(buf) - 1, file);
+       if (ferror(file))
+               die("read-error on `zoffset.h'");
+       buf[c] = 0;
+
+       p = (char *)buf;
+
+       while (p && *p) {
+               PARSE_ZOFS(p, efi_stub_entry);
+               PARSE_ZOFS(p, efi_pe_entry);
+               PARSE_ZOFS(p, startup_64);
+
+               p = strchr(p, '\n');
+               while (p && (*p == '\r' || *p == '\n'))
+                       p++;
+       }
+}
+
 int main(int argc, char ** argv)
 {
        unsigned int i, sz, setup_sectors;
@@ -241,7 +269,19 @@ int main(int argc, char ** argv)
        void *kernel;
        u32 crc = 0xffffffffUL;
 
-       if (argc != 3)
+       /* Defaults for old kernel */
+#ifdef CONFIG_X86_32
+       efi_pe_entry = 0x10;
+       efi_stub_entry = 0x30;
+#else
+       efi_pe_entry = 0x210;
+       efi_stub_entry = 0x230;
+       startup_64 = 0x200;
+#endif
+
+       if (argc == 4)
+               parse_zoffset(argv[3]);
+       else if (argc != 3)
                usage();
 
        /* Copy the setup code */
@@ -299,6 +339,11 @@ int main(int argc, char ** argv)
 
 #ifdef CONFIG_EFI_STUB
        update_pecoff_text(setup_sectors * 512, sz + i + ((sys_size * 16) - sz));
+
+#ifdef CONFIG_X86_64 /* Yes, this is really how we defined it :( */
+       efi_stub_entry -= 0x200;
+#endif
+       put_unaligned_le32(efi_stub_entry, &buf[0x264]);
 #endif
 
        crc = partial_crc32(buf, i, crc);
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 92862cd902012b9fb174d03e6e2cd687787136cf..c15ddaf907107134d6cd2f8d86f554e510a6f848 100644 (file)
@@ -1,6 +1,31 @@
 #ifndef _ASM_X86_BOOTPARAM_H
 #define _ASM_X86_BOOTPARAM_H
 
+/* setup_data types */
+#define SETUP_NONE                     0
+#define SETUP_E820_EXT                 1
+#define SETUP_DTB                      2
+#define SETUP_PCI                      3
+
+/* ram_size flags */
+#define RAMDISK_IMAGE_START_MASK       0x07FF
+#define RAMDISK_PROMPT_FLAG            0x8000
+#define RAMDISK_LOAD_FLAG              0x4000
+
+/* loadflags */
+#define LOADED_HIGH    (1<<0)
+#define QUIET_FLAG     (1<<5)
+#define KEEP_SEGMENTS  (1<<6)
+#define CAN_USE_HEAP   (1<<7)
+
+/* xloadflags */
+#define XLF_KERNEL_64                  (1<<0)
+#define XLF_CAN_BE_LOADED_ABOVE_4G     (1<<1)
+#define XLF_EFI_HANDOVER_32            (1<<2)
+#define XLF_EFI_HANDOVER_64            (1<<3)
+
+#ifndef __ASSEMBLY__
+
 #include <linux/types.h>
 #include <linux/screen_info.h>
 #include <linux/apm_bios.h>
@@ -9,12 +34,6 @@
 #include <asm/ist.h>
 #include <video/edid.h>
 
-/* setup data types */
-#define SETUP_NONE                     0
-#define SETUP_E820_EXT                 1
-#define SETUP_DTB                      2
-#define SETUP_PCI                      3
-
 /* extensible setup data list node */
 struct setup_data {
        __u64 next;
@@ -28,9 +47,6 @@ struct setup_header {
        __u16   root_flags;
        __u32   syssize;
        __u16   ram_size;
-#define RAMDISK_IMAGE_START_MASK       0x07FF
-#define RAMDISK_PROMPT_FLAG            0x8000
-#define RAMDISK_LOAD_FLAG              0x4000
        __u16   vid_mode;
        __u16   root_dev;
        __u16   boot_flag;
@@ -42,10 +58,6 @@ struct setup_header {
        __u16   kernel_version;
        __u8    type_of_loader;
        __u8    loadflags;
-#define LOADED_HIGH    (1<<0)
-#define QUIET_FLAG     (1<<5)
-#define KEEP_SEGMENTS  (1<<6)
-#define CAN_USE_HEAP   (1<<7)
        __u16   setup_move_size;
        __u32   code32_start;
        __u32   ramdisk_image;
@@ -58,7 +70,8 @@ struct setup_header {
        __u32   initrd_addr_max;
        __u32   kernel_alignment;
        __u8    relocatable_kernel;
-       __u8    _pad2[3];
+       __u8    min_alignment;
+       __u16   xloadflags;
        __u32   cmdline_size;
        __u32   hardware_subarch;
        __u64   hardware_subarch_data;
@@ -106,7 +119,10 @@ struct boot_params {
        __u8  hd1_info[16];     /* obsolete! */         /* 0x090 */
        struct sys_desc_table sys_desc_table;           /* 0x0a0 */
        struct olpc_ofw_header olpc_ofw_header;         /* 0x0b0 */
-       __u8  _pad4[128];                               /* 0x0c0 */
+       __u32 ext_ramdisk_image;                        /* 0x0c0 */
+       __u32 ext_ramdisk_size;                         /* 0x0c4 */
+       __u32 ext_cmd_line_ptr;                         /* 0x0c8 */
+       __u8  _pad4[116];                               /* 0x0cc */
        struct edid_info edid_info;                     /* 0x140 */
        struct efi_info efi_info;                       /* 0x1c0 */
        __u32 alt_mem_k;                                /* 0x1e0 */
@@ -115,7 +131,20 @@ struct boot_params {
        __u8  eddbuf_entries;                           /* 0x1e9 */
        __u8  edd_mbr_sig_buf_entries;                  /* 0x1ea */
        __u8  kbd_status;                               /* 0x1eb */
-       __u8  _pad6[5];                                 /* 0x1ec */
+       __u8  _pad5[3];                                 /* 0x1ec */
+       /*
+        * The sentinel is set to a nonzero value (0xff) in header.S.
+        *
+        * A bootloader is supposed to only take setup_header and put
+        * it into a clean boot_params buffer. If it turns out that
+        * it is clumsy or too generous with the buffer, it most
+        * probably will pick up the sentinel variable too. The fact
+        * that this variable then is still 0xff will let kernel
+        * know that some variables in boot_params are invalid and
+        * kernel should zero out certain portions of boot_params.
+        */
+       __u8  sentinel;                                 /* 0x1ef */
+       __u8  _pad6[1];                                 /* 0x1f0 */
        struct setup_header hdr;    /* setup header */  /* 0x1f1 */
        __u8  _pad7[0x290-0x1f1-sizeof(struct setup_header)];
        __u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX];      /* 0x290 */
@@ -134,6 +163,6 @@ enum {
        X86_NR_SUBARCHS,
 };
 
-
+#endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_X86_BOOTPARAM_H */
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 ad4439145f858314dfe518cf7cd9336c5fe9c96d..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;
@@ -941,7 +949,7 @@ void __init efi_enter_virtual_mode(void)
         *
         * Call EFI services through wrapper functions.
         */
-       efi.runtime_version = efi_systab.fw_revision;
+       efi.runtime_version = efi_systab.hdr.revision;
        efi.get_time = virt_efi_get_time;
        efi.set_time = virt_efi_set_time;
        efi.get_wakeup_time = virt_efi_get_wakeup_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 95fd505dfeb6e43dd37b0c41954f0b0db6535d1c..2b2003860615fbc5e24ef12e1c1fa3d855a1f09d 100644 (file)
@@ -38,7 +38,7 @@
 #include <asm/cacheflush.h>
 #include <asm/fixmap.h>
 
-static pgd_t save_pgd __initdata;
+static pgd_t *save_pgd __initdata;
 static unsigned long efi_flags __initdata;
 
 static void __init early_code_mapping_set_exec(int executable)
@@ -61,12 +61,20 @@ static void __init early_code_mapping_set_exec(int executable)
 void __init efi_call_phys_prelog(void)
 {
        unsigned long vaddress;
+       int pgd;
+       int n_pgds;
 
        early_code_mapping_set_exec(1);
        local_irq_save(efi_flags);
-       vaddress = (unsigned long)__va(0x0UL);
-       save_pgd = *pgd_offset_k(0x0UL);
-       set_pgd(pgd_offset_k(0x0UL), *pgd_offset_k(vaddress));
+
+       n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT), PGDIR_SIZE);
+       save_pgd = kmalloc(n_pgds * sizeof(pgd_t), GFP_KERNEL);
+
+       for (pgd = 0; pgd < n_pgds; pgd++) {
+               save_pgd[pgd] = *pgd_offset_k(pgd * PGDIR_SIZE);
+               vaddress = (unsigned long)__va(pgd * PGDIR_SIZE);
+               set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), *pgd_offset_k(vaddress));
+       }
        __flush_tlb_all();
 }
 
@@ -75,7 +83,11 @@ void __init efi_call_phys_epilog(void)
        /*
         * After the lock is released, the original page table is restored.
         */
-       set_pgd(pgd_offset_k(0x0UL), save_pgd);
+       int pgd;
+       int n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT) , PGDIR_SIZE);
+       for (pgd = 0; pgd < n_pgds; pgd++)
+               set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), save_pgd[pgd]);
+       kfree(save_pgd);
        __flush_tlb_all();
        local_irq_restore(efi_flags);
        early_code_mapping_set_exec(0);
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 5a1847d619306e5f0ed5ed5570c53c69a8ce2315..79d67bd507fa6c5bd779defa312943b1d99a47f6 100644 (file)
@@ -814,12 +814,14 @@ int main(int argc, char **argv)
        read_relocs(fp);
        if (show_absolute_syms) {
                print_absolute_symbols();
-               return 0;
+               goto out;
        }
        if (show_absolute_relocs) {
                print_absolute_relocs();
-               return 0;
+               goto out;
        }
        emit_relocs(as_text, use_real_mode);
+out:
+       fclose(fp);
        return 0;
 }
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 7b1c37497c9a2683569f8a1ac9c959e8d5bc7636..f5596db0cf583dc16226bc629a42977de0f9fa05 100644 (file)
@@ -674,7 +674,7 @@ static int efi_status_to_err(efi_status_t status)
                err = -EACCES;
                break;
        case EFI_NOT_FOUND:
-               err = -ENOENT;
+               err = -EIO;
                break;
        default:
                err = -EINVAL;
@@ -793,6 +793,7 @@ static ssize_t efivarfs_file_write(struct file *file,
                spin_unlock(&efivars->lock);
                efivar_unregister(var);
                drop_nlink(inode);
+               d_delete(file->f_dentry);
                dput(file->f_dentry);
 
        } else {
@@ -994,7 +995,7 @@ static int efivarfs_unlink(struct inode *dir, struct dentry *dentry)
                list_del(&var->list);
                spin_unlock(&efivars->lock);
                efivar_unregister(var);
-               drop_nlink(dir);
+               drop_nlink(dentry->d_inode);
                dput(dentry);
                return 0;
        }
@@ -1782,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 */
@@ -1822,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