Merge branch 'fixes' of git://git.linaro.org/people/rmk/linux-arm
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 22 Sep 2012 19:40:16 +0000 (12:40 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 22 Sep 2012 19:40:16 +0000 (12:40 -0700)
Pull ARM and clkdev fixes from Russell King:
 "Two patches for clkdev which resolve the long standing issue that the
  devm_* versions were dependent on clkdev, which they shouldn't have
  been.  Instead, they're dependent on HAVE_CLK instead, which implies
  that you're providing clk_get() and clk_put().

  A small fix to the ARM decompressor to ensure that the page tables are
  properly interpreted by the CPU, and reserve syscall 378 for kcmp (the
  checksyscalls.sh script is unfortunately currently broken so arch
  maintainers aren't getting notified of new syscalls...)

  Lastly, a larger fix for an issue between the common clk subsystem and
  smp_twd which causes warnings to be spat out."

* 'fixes' of git://git.linaro.org/people/rmk/linux-arm:
  ARM: reserve syscall 378 for kcmp
  ARM: 7535/1: Reprogram smp_twd based on new common clk framework notifiers
  ARM: 7537/1: clk: Fix release in devm_clk_put()
  ARM: 7532/1: decompressor: reset SCTLR.TRE for VMSA ARMv7 cores
  ARM: 7534/1: clk: Make the managed clk functions generically available

249 files changed:
MAINTAINERS
Makefile
arch/arm/boot/dts/at91sam9260.dtsi
arch/arm/boot/dts/at91sam9263.dtsi
arch/arm/boot/dts/at91sam9g45.dtsi
arch/arm/boot/dts/at91sam9n12.dtsi
arch/arm/boot/dts/at91sam9x5.dtsi
arch/arm/mach-imx/clk-imx25.c
arch/arm/mach-imx/mach-armadillo5x0.c
arch/arm/mach-shmobile/board-kzm9g.c
arch/arm/plat-mxc/include/mach/mx25.h
arch/arm/plat-samsung/clock.c
arch/s390/include/asm/hugetlb.h
arch/s390/include/asm/tlbflush.h
arch/s390/kernel/setup.c
arch/s390/lib/uaccess_pt.c
arch/sh/kernel/cpu/sh5/entry.S
arch/sh/kernel/entry-common.S
arch/sparc/kernel/module.c
arch/x86/Kconfig
arch/x86/include/asm/xen/page.h
arch/x86/kernel/cpu/perf_event.h
arch/x86/kernel/cpu/perf_event_amd_ibs.c
arch/x86/kernel/cpu/perf_event_intel.c
arch/x86/kernel/cpu/perf_event_intel_ds.c
arch/x86/kernel/cpu/perf_event_intel_uncore.c
arch/x86/mm/init.c
arch/x86/xen/enlighten.c
arch/x86/xen/p2m.c
block/blk-core.c
block/ioctl.c
drivers/acpi/bus.c
drivers/acpi/power.c
drivers/block/aoe/aoecmd.c
drivers/block/cciss_scsi.c
drivers/block/mtip32xx/mtip32xx.c
drivers/block/mtip32xx/mtip32xx.h
drivers/block/nbd.c
drivers/block/xen-blkback/blkback.c
drivers/cpufreq/powernow-k8.c
drivers/dma/at_hdmac.c
drivers/dma/pl330.c
drivers/extcon/extcon-max77693.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/nouveau/nv50_gpio.c
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/r100.c
drivers/hid/hid-lenovo-tpkbd.c
drivers/hid/hid-logitech-dj.c
drivers/hid/hid-logitech-dj.h
drivers/hwmon/ad7314.c
drivers/hwmon/ads7871.c
drivers/hwmon/applesmc.c
drivers/hwspinlock/hwspinlock_core.c
drivers/infiniband/hw/cxgb4/cm.c
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
drivers/infiniband/hw/qib/qib_mad.c
drivers/infiniband/ulp/ipoib/ipoib.h
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
drivers/input/keyboard/imx_keypad.c
drivers/input/misc/ab8500-ponkey.c
drivers/input/mouse/sentelic.c
drivers/input/serio/ambakmi.c
drivers/input/serio/i8042-x86ia64io.h
drivers/input/touchscreen/edt-ft5x06.c
drivers/input/touchscreen/usbtouchscreen.c
drivers/md/md.c
drivers/md/raid5.c
drivers/mfd/88pm800.c
drivers/mfd/88pm805.c
drivers/mfd/88pm860x-core.c
drivers/mfd/aat2870-core.c
drivers/mfd/ab3100-core.c
drivers/mfd/ab8500-core.c
drivers/mfd/arizona-core.c
drivers/mfd/asic3.c
drivers/mfd/cs5535-mfd.c
drivers/mfd/da9052-core.c
drivers/mfd/davinci_voicecodec.c
drivers/mfd/db8500-prcmu.c
drivers/mfd/htc-pasic3.c
drivers/mfd/intel_msic.c
drivers/mfd/janz-cmodio.c
drivers/mfd/jz4740-adc.c
drivers/mfd/lm3533-core.c
drivers/mfd/lpc_ich.c
drivers/mfd/lpc_sch.c
drivers/mfd/max77686.c
drivers/mfd/max77693-irq.c
drivers/mfd/max77693.c
drivers/mfd/max8925-core.c
drivers/mfd/max8997.c
drivers/mfd/max8998.c
drivers/mfd/mc13xxx-core.c
drivers/mfd/mfd-core.c
drivers/mfd/palmas.c
drivers/mfd/rc5t583.c
drivers/mfd/rdc321x-southbridge.c
drivers/mfd/sec-core.c
drivers/mfd/sta2x11-mfd.c
drivers/mfd/stmpe.c
drivers/mfd/t7l66xb.c
drivers/mfd/tc3589x.c
drivers/mfd/tc6387xb.c
drivers/mfd/tc6393xb.c
drivers/mfd/ti-ssp.c
drivers/mfd/timberdale.c
drivers/mfd/tps6105x.c
drivers/mfd/tps6507x.c
drivers/mfd/tps65090.c
drivers/mfd/tps65217.c
drivers/mfd/tps6586x.c
drivers/mfd/tps65910.c
drivers/mfd/tps65912-core.c
drivers/mfd/twl4030-audio.c
drivers/mfd/twl6040-core.c
drivers/mfd/vx855.c
drivers/mfd/wl1273-core.c
drivers/mfd/wm831x-core.c
drivers/mfd/wm8400-core.c
drivers/mfd/wm8994-core.c
drivers/net/can/janz-ican3.c
drivers/net/can/ti_hecc.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/cadence/at91_ether.c
drivers/net/ethernet/freescale/gianfar_ethtool.c
drivers/net/ethernet/freescale/gianfar_ptp.c
drivers/net/ethernet/intel/e1000/e1000_main.c
drivers/net/ethernet/mellanox/mlx4/icm.c
drivers/net/ethernet/mellanox/mlx4/icm.h
drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_timer.c
drivers/net/irda/sh_sir.c
drivers/net/usb/asix_devices.c
drivers/net/usb/qmi_wwan.c
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
drivers/net/wireless/ath/ath9k/debug.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/ath/ath9k/link.c
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
drivers/net/wireless/brcm80211/brcmsmac/channel.c
drivers/net/wireless/rtlwifi/rtl8192ce/def.h
drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
drivers/pwm/pwm-tiecap.c
drivers/pwm/pwm-tiehrpwm.c
drivers/regulator/tps65217-regulator.c
drivers/rpmsg/virtio_rpmsg_bus.c
drivers/rtc/rtc-twl.c
drivers/s390/block/dasd.c
drivers/s390/block/dasd_alias.c
drivers/s390/block/dasd_eckd.c
drivers/s390/cio/device.c
drivers/sh/intc/core.c
drivers/sh/pfc/pinctrl.c
drivers/staging/nvec/nvec.c
drivers/target/iscsi/iscsi_target_login.c
drivers/target/target_core_alua.c
drivers/target/target_core_device.c
drivers/target/target_core_iblock.c
drivers/target/target_core_pr.c
drivers/target/target_core_pscsi.c
drivers/target/target_core_spc.c
drivers/target/target_core_transport.c
drivers/watchdog/hpwdt.c
drivers/watchdog/watchdog_core.c
drivers/xen/gntdev.c
drivers/xen/grant-table.c
fs/btrfs/qgroup.c
fs/cifs/cifs_unicode.c
fs/dcache.c
fs/debugfs/file.c
fs/proc/proc_sysctl.c
fs/xfs/xfs_buf.c
fs/xfs/xfs_buf.h
fs/xfs/xfs_super.c
include/linux/atmel-ssc.h
include/linux/compiler-gcc4.h
include/linux/compiler.h
include/linux/dcache.h
include/linux/kernel.h
include/linux/memory.h
include/linux/mfd/core.h
include/linux/mfd/tps65217.h
include/linux/perf_event.h
include/linux/sched.h
include/linux/xfrm.h
include/net/ip6_fib.h
include/net/net_namespace.h
include/net/netns/ipv4.h
include/net/route.h
include/net/sock.h
include/target/target_core_backend.h
include/target/target_core_base.h
include/trace/events/kmem.h
include/xen/grant_table.h
kernel/pid_namespace.c
kernel/sched/core.c
kernel/sched/fair.c
kernel/time/timekeeping.c
kernel/workqueue.c
mm/memory_hotplug.c
mm/page_alloc.c
mm/slab.c
mm/slub.c
mm/vmscan.c
net/batman-adv/bitarray.h
net/bluetooth/bnep/sock.c
net/bluetooth/cmtp/sock.c
net/bluetooth/hci_sock.c
net/bluetooth/hidp/sock.c
net/core/dev.c
net/core/skbuff.c
net/ipv4/arp.c
net/ipv4/devinet.c
net/ipv4/fib_frontend.c
net/ipv4/fib_rules.c
net/ipv4/fib_trie.c
net/ipv4/route.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv6/inet6_connection_sock.c
net/ipv6/ip6_fib.c
net/ipv6/route.c
net/netrom/af_netrom.c
net/sched/sch_qfq.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_user.c
security/selinux/include/xfrm.h
sound/pci/hda/hda_intel.c
sound/soc/codecs/arizona.c
sound/soc/codecs/mc13783.c
sound/soc/codecs/wm8904.c
sound/soc/fsl/imx-sgtl5000.c
sound/soc/omap/am3517evm.c
sound/soc/samsung/dma.c
sound/soc/soc-dapm.c
sound/soc/spear/spear_pcm.c
sound/soc/tegra/tegra_alc5632.c
sound/soc/tegra/tegra_pcm.c
sound/soc/ux500/ux500_msp_i2s.c

index 53cc13c..b17587d 100644 (file)
@@ -3666,11 +3666,12 @@ F:      Documentation/networking/README.ipw2200
 F:     drivers/net/wireless/ipw2x00/
 
 INTEL(R) TRUSTED EXECUTION TECHNOLOGY (TXT)
-M:     Joseph Cihula <joseph.cihula@intel.com>
+M:     Richard L Maliszewski <richard.l.maliszewski@intel.com>
+M:     Gang Wei <gang.wei@intel.com>
 M:     Shane Wang <shane.wang@intel.com>
 L:     tboot-devel@lists.sourceforge.net
 W:     http://tboot.sourceforge.net
-T:     Mercurial http://www.bughost.org/repos.hg/tboot.hg
+T:     hg http://tboot.hg.sourceforge.net:8000/hgroot/tboot/tboot
 S:     Supported
 F:     Documentation/intel_txt.txt
 F:     include/linux/tboot.h
index 0f66f14..ae6928c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 6
 SUBLEVEL = 0
-EXTRAVERSION = -rc5
+EXTRAVERSION = -rc6
 NAME = Saber-toothed Squirrel
 
 # *DOCUMENTATION*
index 66389c1..7c95f76 100644 (file)
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioB: gpio@fffff600 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioC: gpio@fffff800 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        dbgu: serial@fffff200 {
index b460d6c..195019b 100644 (file)
@@ -95,6 +95,7 @@
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioB: gpio@fffff400 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioC: gpio@fffff600 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioD: gpio@fffff800 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioE: gpio@fffffa00 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        dbgu: serial@ffffee00 {
index bafa880..63751b1 100644 (file)
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioB: gpio@fffff400 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioC: gpio@fffff600 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioD: gpio@fffff800 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioE: gpio@fffffa00 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        dbgu: serial@ffffee00 {
index bfac0df..ef9336a 100644 (file)
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioB: gpio@fffff600 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioC: gpio@fffff800 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioD: gpio@fffffa00 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        dbgu: serial@fffff200 {
index 4a18c39..8a387a8 100644 (file)
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioB: gpio@fffff600 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioC: gpio@fffff800 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioD: gpio@fffffa00 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        dbgu: serial@fffff200 {
index 4431a62..d20d479 100644 (file)
@@ -241,6 +241,6 @@ int __init mx25_clocks_init(void)
        clk_register_clkdev(clk[sdma_ahb], "ahb", "imx35-sdma");
        clk_register_clkdev(clk[iim_ipg], "iim", NULL);
 
-       mxc_timer_init(MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
+       mxc_timer_init(MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), MX25_INT_GPT1);
        return 0;
 }
index 2c6ab32..5985ed1 100644 (file)
@@ -526,7 +526,8 @@ static void __init armadillo5x0_init(void)
        imx31_add_mxc_nand(&armadillo5x0_nand_board_info);
 
        /* set NAND page size to 2k if not configured via boot mode pins */
-       __raw_writel(__raw_readl(MXC_CCM_RCSR) | (1 << 30), MXC_CCM_RCSR);
+       __raw_writel(__raw_readl(mx3_ccm_base + MXC_CCM_RCSR) |
+                                       (1 << 30), mx3_ccm_base + MXC_CCM_RCSR);
 
        /* RTC */
        /* Get RTC IRQ and register the chip */
index 53b7ea9..3b8a017 100644 (file)
@@ -346,11 +346,11 @@ static struct resource sh_mmcif_resources[] = {
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
-               .start  = gic_spi(141),
+               .start  = gic_spi(140),
                .flags  = IORESOURCE_IRQ,
        },
        [2] = {
-               .start  = gic_spi(140),
+               .start  = gic_spi(141),
                .flags  = IORESOURCE_IRQ,
        },
 };
index 627d94f..ec46640 100644 (file)
@@ -98,6 +98,7 @@
 #define MX25_INT_UART1         (NR_IRQS_LEGACY + 45)
 #define MX25_INT_GPIO2         (NR_IRQS_LEGACY + 51)
 #define MX25_INT_GPIO1         (NR_IRQS_LEGACY + 52)
+#define MX25_INT_GPT1          (NR_IRQS_LEGACY + 54)
 #define MX25_INT_FEC           (NR_IRQS_LEGACY + 57)
 
 #define MX25_DMA_REQ_SSI2_RX1  22
index 65c5eca..d1116e2 100644 (file)
@@ -144,6 +144,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
 
 int clk_set_rate(struct clk *clk, unsigned long rate)
 {
+       unsigned long flags;
        int ret;
 
        if (IS_ERR(clk))
@@ -159,9 +160,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
        if (clk->ops == NULL || clk->ops->set_rate == NULL)
                return -EINVAL;
 
-       spin_lock(&clocks_lock);
+       spin_lock_irqsave(&clocks_lock, flags);
        ret = (clk->ops->set_rate)(clk, rate);
-       spin_unlock(&clocks_lock);
+       spin_unlock_irqrestore(&clocks_lock, flags);
 
        return ret;
 }
@@ -173,17 +174,18 @@ struct clk *clk_get_parent(struct clk *clk)
 
 int clk_set_parent(struct clk *clk, struct clk *parent)
 {
+       unsigned long flags;
        int ret = 0;
 
        if (IS_ERR(clk))
                return -EINVAL;
 
-       spin_lock(&clocks_lock);
+       spin_lock_irqsave(&clocks_lock, flags);
 
        if (clk->ops && clk->ops->set_parent)
                ret = (clk->ops->set_parent)(clk, parent);
 
-       spin_unlock(&clocks_lock);
+       spin_unlock_irqrestore(&clocks_lock, flags);
 
        return ret;
 }
index 799ed0f..2d6e6e3 100644 (file)
@@ -66,16 +66,6 @@ static inline pte_t huge_ptep_get(pte_t *ptep)
        return pte;
 }
 
-static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
-                                           unsigned long addr, pte_t *ptep)
-{
-       pte_t pte = huge_ptep_get(ptep);
-
-       mm->context.flush_mm = 1;
-       pmd_clear((pmd_t *) ptep);
-       return pte;
-}
-
 static inline void __pmd_csp(pmd_t *pmdp)
 {
        register unsigned long reg2 asm("2") = pmd_val(*pmdp);
@@ -117,6 +107,15 @@ static inline void huge_ptep_invalidate(struct mm_struct *mm,
                __pmd_csp(pmdp);
 }
 
+static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+                                           unsigned long addr, pte_t *ptep)
+{
+       pte_t pte = huge_ptep_get(ptep);
+
+       huge_ptep_invalidate(mm, addr, ptep);
+       return pte;
+}
+
 #define huge_ptep_set_access_flags(__vma, __addr, __ptep, __entry, __dirty) \
 ({                                                                         \
        int __changed = !pte_same(huge_ptep_get(__ptep), __entry);          \
@@ -131,10 +130,7 @@ static inline void huge_ptep_invalidate(struct mm_struct *mm,
 ({                                                                     \
        pte_t __pte = huge_ptep_get(__ptep);                            \
        if (pte_write(__pte)) {                                         \
-               (__mm)->context.flush_mm = 1;                           \
-               if (atomic_read(&(__mm)->context.attach_count) > 1 ||   \
-                   (__mm) != current->active_mm)                       \
-                       huge_ptep_invalidate(__mm, __addr, __ptep);     \
+               huge_ptep_invalidate(__mm, __addr, __ptep);             \
                set_huge_pte_at(__mm, __addr, __ptep,                   \
                                huge_pte_wrprotect(__pte));             \
        }                                                               \
index 9fde315..1d8fe2b 100644 (file)
@@ -90,12 +90,10 @@ static inline void __tlb_flush_mm(struct mm_struct * mm)
 
 static inline void __tlb_flush_mm_cond(struct mm_struct * mm)
 {
-       spin_lock(&mm->page_table_lock);
        if (mm->context.flush_mm) {
                __tlb_flush_mm(mm);
                mm->context.flush_mm = 0;
        }
-       spin_unlock(&mm->page_table_lock);
 }
 
 /*
index f86c81e..40b5769 100644 (file)
@@ -974,11 +974,13 @@ static void __init setup_hwcaps(void)
        if (MACHINE_HAS_HPAGE)
                elf_hwcap |= HWCAP_S390_HPAGE;
 
+#if defined(CONFIG_64BIT)
        /*
         * 64-bit register support for 31-bit processes
         * HWCAP_S390_HIGH_GPRS is bit 9.
         */
        elf_hwcap |= HWCAP_S390_HIGH_GPRS;
+#endif
 
        get_cpu_id(&cpu_id);
        switch (cpu_id.machine) {
index 60ee2b8..2d37bb8 100644 (file)
@@ -2,69 +2,82 @@
  *  User access functions based on page table walks for enhanced
  *  system layout without hardware support.
  *
- *    Copyright IBM Corp. 2006
+ *    Copyright IBM Corp. 2006, 2012
  *    Author(s): Gerald Schaefer (gerald.schaefer@de.ibm.com)
  */
 
 #include <linux/errno.h>
 #include <linux/hardirq.h>
 #include <linux/mm.h>
+#include <linux/hugetlb.h>
 #include <asm/uaccess.h>
 #include <asm/futex.h>
 #include "uaccess.h"
 
-static inline pte_t *follow_table(struct mm_struct *mm, unsigned long addr)
+
+/*
+ * Returns kernel address for user virtual address. If the returned address is
+ * >= -4095 (IS_ERR_VALUE(x) returns true), a fault has occured and the address
+ * contains the (negative) exception code.
+ */
+static __always_inline unsigned long follow_table(struct mm_struct *mm,
+                                                 unsigned long addr, int write)
 {
        pgd_t *pgd;
        pud_t *pud;
        pmd_t *pmd;
+       pte_t *ptep;
 
        pgd = pgd_offset(mm, addr);
        if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
-               return (pte_t *) 0x3a;
+               return -0x3aUL;
 
        pud = pud_offset(pgd, addr);
        if (pud_none(*pud) || unlikely(pud_bad(*pud)))
-               return (pte_t *) 0x3b;
+               return -0x3bUL;
 
        pmd = pmd_offset(pud, addr);
-       if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
-               return (pte_t *) 0x10;
+       if (pmd_none(*pmd))
+               return -0x10UL;
+       if (pmd_huge(*pmd)) {
+               if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO))
+                       return -0x04UL;
+               return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK);
+       }
+       if (unlikely(pmd_bad(*pmd)))
+               return -0x10UL;
+
+       ptep = pte_offset_map(pmd, addr);
+       if (!pte_present(*ptep))
+               return -0x11UL;
+       if (write && !pte_write(*ptep))
+               return -0x04UL;
 
-       return pte_offset_map(pmd, addr);
+       return (pte_val(*ptep) & PAGE_MASK) + (addr & ~PAGE_MASK);
 }
 
 static __always_inline size_t __user_copy_pt(unsigned long uaddr, void *kptr,
                                             size_t n, int write_user)
 {
        struct mm_struct *mm = current->mm;
-       unsigned long offset, pfn, done, size;
-       pte_t *pte;
+       unsigned long offset, done, size, kaddr;
        void *from, *to;
 
        done = 0;
 retry:
        spin_lock(&mm->page_table_lock);
        do {
-               pte = follow_table(mm, uaddr);
-               if ((unsigned long) pte < 0x1000)
+               kaddr = follow_table(mm, uaddr, write_user);
+               if (IS_ERR_VALUE(kaddr))
                        goto fault;
-               if (!pte_present(*pte)) {
-                       pte = (pte_t *) 0x11;
-                       goto fault;
-               } else if (write_user && !pte_write(*pte)) {
-                       pte = (pte_t *) 0x04;
-                       goto fault;
-               }
 
-               pfn = pte_pfn(*pte);
-               offset = uaddr & (PAGE_SIZE - 1);
+               offset = uaddr & ~PAGE_MASK;
                size = min(n - done, PAGE_SIZE - offset);
                if (write_user) {
-                       to = (void *)((pfn << PAGE_SHIFT) + offset);
+                       to = (void *) kaddr;
                        from = kptr + done;
                } else {
-                       from = (void *)((pfn << PAGE_SHIFT) + offset);
+                       from = (void *) kaddr;
                        to = kptr + done;
                }
                memcpy(to, from, size);
@@ -75,7 +88,7 @@ retry:
        return n - done;
 fault:
        spin_unlock(&mm->page_table_lock);
-       if (__handle_fault(uaddr, (unsigned long) pte, write_user))
+       if (__handle_fault(uaddr, -kaddr, write_user))
                return n - done;
        goto retry;
 }
@@ -84,27 +97,22 @@ fault:
  * Do DAT for user address by page table walk, return kernel address.
  * This function needs to be called with current->mm->page_table_lock held.
  */
-static __always_inline unsigned long __dat_user_addr(unsigned long uaddr)
+static __always_inline unsigned long __dat_user_addr(unsigned long uaddr,
+                                                    int write)
 {
        struct mm_struct *mm = current->mm;
-       unsigned long pfn;
-       pte_t *pte;
+       unsigned long kaddr;
        int rc;
 
 retry:
-       pte = follow_table(mm, uaddr);
-       if ((unsigned long) pte < 0x1000)
-               goto fault;
-       if (!pte_present(*pte)) {
-               pte = (pte_t *) 0x11;
+       kaddr = follow_table(mm, uaddr, write);
+       if (IS_ERR_VALUE(kaddr))
                goto fault;
-       }
 
-       pfn = pte_pfn(*pte);
-       return (pfn << PAGE_SHIFT) + (uaddr & (PAGE_SIZE - 1));
+       return kaddr;
 fault:
        spin_unlock(&mm->page_table_lock);
-       rc = __handle_fault(uaddr, (unsigned long) pte, 0);
+       rc = __handle_fault(uaddr, -kaddr, write);
        spin_lock(&mm->page_table_lock);
        if (!rc)
                goto retry;
@@ -159,11 +167,9 @@ static size_t clear_user_pt(size_t n, void __user *to)
 
 static size_t strnlen_user_pt(size_t count, const char __user *src)
 {
-       char *addr;
        unsigned long uaddr = (unsigned long) src;
        struct mm_struct *mm = current->mm;
-       unsigned long offset, pfn, done, len;
-       pte_t *pte;
+       unsigned long offset, done, len, kaddr;
        size_t len_str;
 
        if (segment_eq(get_fs(), KERNEL_DS))
@@ -172,19 +178,13 @@ static size_t strnlen_user_pt(size_t count, const char __user *src)
 retry:
        spin_lock(&mm->page_table_lock);
        do {
-               pte = follow_table(mm, uaddr);
-               if ((unsigned long) pte < 0x1000)
-                       goto fault;
-               if (!pte_present(*pte)) {
-                       pte = (pte_t *) 0x11;
+               kaddr = follow_table(mm, uaddr, 0);
+               if (IS_ERR_VALUE(kaddr))
                        goto fault;
-               }
 
-               pfn = pte_pfn(*pte);
-               offset = uaddr & (PAGE_SIZE-1);
-               addr = (char *)(pfn << PAGE_SHIFT) + offset;
+               offset = uaddr & ~PAGE_MASK;
                len = min(count - done, PAGE_SIZE - offset);
-               len_str = strnlen(addr, len);
+               len_str = strnlen((char *) kaddr, len);
                done += len_str;
                uaddr += len_str;
        } while ((len_str == len) && (done < count));
@@ -192,7 +192,7 @@ retry:
        return done + 1;
 fault:
        spin_unlock(&mm->page_table_lock);
-       if (__handle_fault(uaddr, (unsigned long) pte, 0))
+       if (__handle_fault(uaddr, -kaddr, 0))
                return 0;
        goto retry;
 }
@@ -225,11 +225,10 @@ static size_t copy_in_user_pt(size_t n, void __user *to,
                              const void __user *from)
 {
        struct mm_struct *mm = current->mm;
-       unsigned long offset_from, offset_to, offset_max, pfn_from, pfn_to,
-                     uaddr, done, size, error_code;
+       unsigned long offset_max, uaddr, done, size, error_code;
        unsigned long uaddr_from = (unsigned long) from;
        unsigned long uaddr_to = (unsigned long) to;
-       pte_t *pte_from, *pte_to;
+       unsigned long kaddr_to, kaddr_from;
        int write_user;
 
        if (segment_eq(get_fs(), KERNEL_DS)) {
@@ -242,38 +241,23 @@ retry:
        do {
                write_user = 0;
                uaddr = uaddr_from;
-               pte_from = follow_table(mm, uaddr_from);
-               error_code = (unsigned long) pte_from;
-               if (error_code < 0x1000)
-                       goto fault;
-               if (!pte_present(*pte_from)) {
-                       error_code = 0x11;
+               kaddr_from = follow_table(mm, uaddr_from, 0);
+               error_code = kaddr_from;
+               if (IS_ERR_VALUE(error_code))
                        goto fault;
-               }
 
                write_user = 1;
                uaddr = uaddr_to;
-               pte_to = follow_table(mm, uaddr_to);
-               error_code = (unsigned long) pte_to;
-               if (error_code < 0x1000)
-                       goto fault;
-               if (!pte_present(*pte_to)) {
-                       error_code = 0x11;
+               kaddr_to = follow_table(mm, uaddr_to, 1);
+               error_code = (unsigned long) kaddr_to;
+               if (IS_ERR_VALUE(error_code))
                        goto fault;
-               } else if (!pte_write(*pte_to)) {
-                       error_code = 0x04;
-                       goto fault;
-               }
 
-               pfn_from = pte_pfn(*pte_from);
-               pfn_to = pte_pfn(*pte_to);
-               offset_from = uaddr_from & (PAGE_SIZE-1);
-               offset_to = uaddr_from & (PAGE_SIZE-1);
-               offset_max = max(offset_from, offset_to);
+               offset_max = max(uaddr_from & ~PAGE_MASK,
+                                uaddr_to & ~PAGE_MASK);
                size = min(n - done, PAGE_SIZE - offset_max);
 
-               memcpy((void *)(pfn_to << PAGE_SHIFT) + offset_to,
-                      (void *)(pfn_from << PAGE_SHIFT) + offset_from, size);
+               memcpy((void *) kaddr_to, (void *) kaddr_from, size);
                done += size;
                uaddr_from += size;
                uaddr_to += size;
@@ -282,7 +266,7 @@ retry:
        return n - done;
 fault:
        spin_unlock(&mm->page_table_lock);
-       if (__handle_fault(uaddr, error_code, write_user))
+       if (__handle_fault(uaddr, -error_code, write_user))
                return n - done;
        goto retry;
 }
@@ -341,7 +325,7 @@ int futex_atomic_op_pt(int op, u32 __user *uaddr, int oparg, int *old)
                return __futex_atomic_op_pt(op, uaddr, oparg, old);
        spin_lock(&current->mm->page_table_lock);
        uaddr = (u32 __force __user *)
-               __dat_user_addr((__force unsigned long) uaddr);
+               __dat_user_addr((__force unsigned long) uaddr, 1);
        if (!uaddr) {
                spin_unlock(&current->mm->page_table_lock);
                return -EFAULT;
@@ -378,7 +362,7 @@ int futex_atomic_cmpxchg_pt(u32 *uval, u32 __user *uaddr,
                return __futex_atomic_cmpxchg_pt(uval, uaddr, oldval, newval);
        spin_lock(&current->mm->page_table_lock);
        uaddr = (u32 __force __user *)
-               __dat_user_addr((__force unsigned long) uaddr);
+               __dat_user_addr((__force unsigned long) uaddr, 1);
        if (!uaddr) {
                spin_unlock(&current->mm->page_table_lock);
                return -EFAULT;
index b7cf6a5..7e605b9 100644 (file)
@@ -933,7 +933,7 @@ ret_with_reschedule:
 
        pta     restore_all, tr1
 
-       movi    _TIF_SIGPENDING, r8
+       movi    (_TIF_SIGPENDING|_TIF_NOTIFY_RESUME), r8
        and     r8, r7, r8
        pta     work_notifysig, tr0
        bne     r8, ZERO, tr0
index f67601c..b96489d 100644 (file)
@@ -139,7 +139,7 @@ work_pending:
        ! r8: current_thread_info
        ! t:  result of "tst    #_TIF_NEED_RESCHED, r0"
        bf/s    work_resched
-        tst    #_TIF_SIGPENDING, r0
+        tst    #(_TIF_SIGPENDING | _TIF_NOTIFY_RESUME), r0
 work_notifysig:
        bt/s    __restore_all
         mov    r15, r4
index 15e0a16..f1ddc0d 100644 (file)
@@ -48,9 +48,7 @@ void *module_alloc(unsigned long size)
                return NULL;
 
        ret = module_map(size);
-       if (!ret)
-               ret = ERR_PTR(-ENOMEM);
-       else
+       if (ret)
                memset(ret, 0, size);
 
        return ret;
@@ -116,6 +114,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
                v = sym->st_value + rel[i].r_addend;
 
                switch (ELF_R_TYPE(rel[i].r_info) & 0xff) {
+               case R_SPARC_DISP32:
+                       v -= (Elf_Addr) location;
+                       *loc32 = v;
+                       break;
 #ifdef CONFIG_SPARC64
                case R_SPARC_64:
                        location[0] = v >> 56;
@@ -128,11 +130,6 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
                        location[7] = v >>  0;
                        break;
 
-               case R_SPARC_DISP32:
-                       v -= (Elf_Addr) location;
-                       *loc32 = v;
-                       break;
-
                case R_SPARC_WDISP19:
                        v -= (Elf_Addr) location;
                        *loc32 = (*loc32 & ~0x7ffff) |
index 8ec3a1a..50a1d1f 100644 (file)
@@ -746,10 +746,10 @@ config SWIOTLB
        def_bool y if X86_64
        ---help---
          Support for software bounce buffers used on x86-64 systems
-         which don't have a hardware IOMMU (e.g. the current generation
-         of Intel's x86-64 CPUs). Using this PCI devices which can only
-         access 32-bits of memory can be used on systems with more than
-         3 GB of memory. If unsure, say Y.
+         which don't have a hardware IOMMU. Using this PCI devices
+         which can only access 32-bits of memory can be used on systems
+         with more than 3 GB of memory.
+         If unsure, say Y.
 
 config IOMMU_HELPER
        def_bool (CALGARY_IOMMU || GART_IOMMU || SWIOTLB || AMD_IOMMU)
index 93971e8..472b9b7 100644 (file)
@@ -51,7 +51,8 @@ extern unsigned long set_phys_range_identity(unsigned long pfn_s,
 
 extern int m2p_add_override(unsigned long mfn, struct page *page,
                            struct gnttab_map_grant_ref *kmap_op);
-extern int m2p_remove_override(struct page *page, bool clear_pte);
+extern int m2p_remove_override(struct page *page,
+                               struct gnttab_map_grant_ref *kmap_op);
 extern struct page *m2p_find_override(unsigned long mfn);
 extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn);
 
index 6605a81..8b6defe 100644 (file)
@@ -586,6 +586,8 @@ extern struct event_constraint intel_westmere_pebs_event_constraints[];
 
 extern struct event_constraint intel_snb_pebs_event_constraints[];
 
+extern struct event_constraint intel_ivb_pebs_event_constraints[];
+
 struct event_constraint *intel_pebs_constraints(struct perf_event *event);
 
 void intel_pmu_pebs_enable(struct perf_event *event);
index 7bfb5be..eebd5ff 100644 (file)
@@ -209,6 +209,15 @@ static int perf_ibs_precise_event(struct perf_event *event, u64 *config)
        return -EOPNOTSUPP;
 }
 
+static const struct perf_event_attr ibs_notsupp = {
+       .exclude_user   = 1,
+       .exclude_kernel = 1,
+       .exclude_hv     = 1,
+       .exclude_idle   = 1,
+       .exclude_host   = 1,
+       .exclude_guest  = 1,
+};
+
 static int perf_ibs_init(struct perf_event *event)
 {
        struct hw_perf_event *hwc = &event->hw;
@@ -229,6 +238,9 @@ static int perf_ibs_init(struct perf_event *event)
        if (event->pmu != &perf_ibs->pmu)
                return -ENOENT;
 
+       if (perf_flags(&event->attr) & perf_flags(&ibs_notsupp))
+               return -EINVAL;
+
        if (config & ~perf_ibs->config_mask)
                return -EINVAL;
 
index 0d3d63a..6bca492 100644 (file)
@@ -2048,7 +2048,6 @@ __init int intel_pmu_init(void)
        case 42: /* SandyBridge */
        case 45: /* SandyBridge, "Romely-EP" */
                x86_add_quirk(intel_sandybridge_quirk);
-       case 58: /* IvyBridge */
                memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
                       sizeof(hw_cache_event_ids));
                memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
@@ -2073,6 +2072,29 @@ __init int intel_pmu_init(void)
 
                pr_cont("SandyBridge events, ");
                break;
+       case 58: /* IvyBridge */
+               memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
+                      sizeof(hw_cache_event_ids));
+               memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
+                      sizeof(hw_cache_extra_regs));
+
+               intel_pmu_lbr_init_snb();
+
+               x86_pmu.event_constraints = intel_snb_event_constraints;
+               x86_pmu.pebs_constraints = intel_ivb_pebs_event_constraints;
+               x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
+               x86_pmu.extra_regs = intel_snb_extra_regs;
+               /* all extra regs are per-cpu when HT is on */
+               x86_pmu.er_flags |= ERF_HAS_RSP_1;
+               x86_pmu.er_flags |= ERF_NO_HT_SHARING;
+
+               /* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */
+               intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
+                       X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1);
+
+               pr_cont("IvyBridge events, ");
+               break;
+
 
        default:
                switch (x86_pmu.version) {
index e38d97b..826054a 100644 (file)
@@ -407,6 +407,20 @@ struct event_constraint intel_snb_pebs_event_constraints[] = {
        EVENT_CONSTRAINT_END
 };
 
+struct event_constraint intel_ivb_pebs_event_constraints[] = {
+        INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
+        INTEL_UEVENT_CONSTRAINT(0x01c2, 0xf), /* UOPS_RETIRED.ALL */
+        INTEL_UEVENT_CONSTRAINT(0x02c2, 0xf), /* UOPS_RETIRED.RETIRE_SLOTS */
+        INTEL_EVENT_CONSTRAINT(0xc4, 0xf),    /* BR_INST_RETIRED.* */
+        INTEL_EVENT_CONSTRAINT(0xc5, 0xf),    /* BR_MISP_RETIRED.* */
+        INTEL_EVENT_CONSTRAINT(0xcd, 0x8),    /* MEM_TRANS_RETIRED.* */
+        INTEL_EVENT_CONSTRAINT(0xd0, 0xf),    /* MEM_UOP_RETIRED.* */
+        INTEL_EVENT_CONSTRAINT(0xd1, 0xf),    /* MEM_LOAD_UOPS_RETIRED.* */
+        INTEL_EVENT_CONSTRAINT(0xd2, 0xf),    /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
+        INTEL_EVENT_CONSTRAINT(0xd3, 0xf),    /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
+        EVENT_CONSTRAINT_END
+};
+
 struct event_constraint *intel_pebs_constraints(struct perf_event *event)
 {
        struct event_constraint *c;
index 0a55710..38e4894 100644 (file)
@@ -661,6 +661,11 @@ static void snb_uncore_msr_init_box(struct intel_uncore_box *box)
        }
 }
 
+static struct uncore_event_desc snb_uncore_events[] = {
+       INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"),
+       { /* end: all zeroes */ },
+};
+
 static struct attribute *snb_uncore_formats_attr[] = {
        &format_attr_event.attr,
        &format_attr_umask.attr,
@@ -704,6 +709,7 @@ static struct intel_uncore_type snb_uncore_cbox = {
        .constraints    = snb_uncore_cbox_constraints,
        .ops            = &snb_uncore_msr_ops,
        .format_group   = &snb_uncore_format_group,
+       .event_descs    = snb_uncore_events,
 };
 
 static struct intel_uncore_type *snb_msr_uncores[] = {
index e0e6990..ab1f6a9 100644 (file)
@@ -319,7 +319,7 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
  */
 int devmem_is_allowed(unsigned long pagenr)
 {
-       if (pagenr <= 256)
+       if (pagenr < 256)
                return 1;
        if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
                return 0;
index 9642d4a..1fbe75a 100644 (file)
@@ -1452,6 +1452,10 @@ asmlinkage void __init xen_start_kernel(void)
                pci_request_acs();
 
                xen_acpi_sleep_register();
+
+               /* Avoid searching for BIOS MP tables */
+               x86_init.mpparse.find_smp_config = x86_init_noop;
+               x86_init.mpparse.get_smp_config = x86_init_uint_noop;
        }
 #ifdef CONFIG_PCI
        /* PCI BIOS service won't work from a PV guest. */
index 76ba0e9..72213da 100644 (file)
@@ -828,9 +828,6 @@ int m2p_add_override(unsigned long mfn, struct page *page,
 
                        xen_mc_issue(PARAVIRT_LAZY_MMU);
                }
-               /* let's use dev_bus_addr to record the old mfn instead */
-               kmap_op->dev_bus_addr = page->index;
-               page->index = (unsigned long) kmap_op;
        }
        spin_lock_irqsave(&m2p_override_lock, flags);
        list_add(&page->lru,  &m2p_overrides[mfn_hash(mfn)]);
@@ -857,7 +854,8 @@ int m2p_add_override(unsigned long mfn, struct page *page,
        return 0;
 }
 EXPORT_SYMBOL_GPL(m2p_add_override);
-int m2p_remove_override(struct page *page, bool clear_pte)
+int m2p_remove_override(struct page *page,
+               struct gnttab_map_grant_ref *kmap_op)
 {
        unsigned long flags;
        unsigned long mfn;
@@ -887,10 +885,8 @@ int m2p_remove_override(struct page *page, bool clear_pte)
        WARN_ON(!PagePrivate(page));
        ClearPagePrivate(page);
 
-       if (clear_pte) {
-               struct gnttab_map_grant_ref *map_op =
-                       (struct gnttab_map_grant_ref *) page->index;
-               set_phys_to_machine(pfn, map_op->dev_bus_addr);
+       set_phys_to_machine(pfn, page->index);
+       if (kmap_op != NULL) {
                if (!PageHighMem(page)) {
                        struct multicall_space mcs;
                        struct gnttab_unmap_grant_ref *unmap_op;
@@ -902,13 +898,13 @@ int m2p_remove_override(struct page *page, bool clear_pte)
                         * issued. In this case handle is going to -1 because
                         * it hasn't been modified yet.
                         */
-                       if (map_op->handle == -1)
+                       if (kmap_op->handle == -1)
                                xen_mc_flush();
                        /*
-                        * Now if map_op->handle is negative it means that the
+                        * Now if kmap_op->handle is negative it means that the
                         * hypercall actually returned an error.
                         */
-                       if (map_op->handle == GNTST_general_error) {
+                       if (kmap_op->handle == GNTST_general_error) {
                                printk(KERN_WARNING "m2p_remove_override: "
                                                "pfn %lx mfn %lx, failed to modify kernel mappings",
                                                pfn, mfn);
@@ -918,8 +914,8 @@ int m2p_remove_override(struct page *page, bool clear_pte)
                        mcs = xen_mc_entry(
                                        sizeof(struct gnttab_unmap_grant_ref));
                        unmap_op = mcs.args;
-                       unmap_op->host_addr = map_op->host_addr;
-                       unmap_op->handle = map_op->handle;
+                       unmap_op->host_addr = kmap_op->host_addr;
+                       unmap_op->handle = kmap_op->handle;
                        unmap_op->dev_bus_addr = 0;
 
                        MULTI_grant_table_op(mcs.mc,
@@ -930,10 +926,9 @@ int m2p_remove_override(struct page *page, bool clear_pte)
                        set_pte_at(&init_mm, address, ptep,
                                        pfn_pte(pfn, PAGE_KERNEL));
                        __flush_tlb_single(address);
-                       map_op->host_addr = 0;
+                       kmap_op->host_addr = 0;
                }
-       } else
-               set_phys_to_machine(pfn, page->index);
+       }
 
        /* p2m(m2p(mfn)) == FOREIGN_FRAME(mfn): the mfn is already present
         * somewhere in this domain, even before being added to the
index 4b4dbdf..ee3cb3a 100644 (file)
@@ -2254,9 +2254,11 @@ bool blk_update_request(struct request *req, int error, unsigned int nr_bytes)
                        error_type = "I/O";
                        break;
                }
-               printk(KERN_ERR "end_request: %s error, dev %s, sector %llu\n",
-                      error_type, req->rq_disk ? req->rq_disk->disk_name : "?",
-                      (unsigned long long)blk_rq_pos(req));
+               printk_ratelimited(KERN_ERR "end_request: %s error, dev %s, sector %llu\n",
+                                  error_type, req->rq_disk ?
+                                  req->rq_disk->disk_name : "?",
+                                  (unsigned long long)blk_rq_pos(req));
+
        }
 
        blk_account_io_completion(req, nr_bytes);
index 4476e0e..4a85096 100644 (file)
@@ -41,7 +41,7 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user
                            sizeof(long long) > sizeof(long)) {
                                long pstart = start, plength = length;
                                if (pstart != start || plength != length
-                                   || pstart < 0 || plength < 0)
+                                   || pstart < 0 || plength < 0 || partno > 65535)
                                        return -EINVAL;
                        }
 
index 9628652..e059695 100644 (file)
@@ -237,6 +237,16 @@ static int __acpi_bus_get_power(struct acpi_device *device, int *state)
        } else if (result == ACPI_STATE_D3_HOT) {
                result = ACPI_STATE_D3;
        }
+
+       /*
+        * If we were unsure about the device parent's power state up to this
+        * point, the fact that the device is in D0 implies that the parent has
+        * to be in D0 too.
+        */
+       if (device->parent && device->parent->power.state == ACPI_STATE_UNKNOWN
+           && result == ACPI_STATE_D0)
+               device->parent->power.state = ACPI_STATE_D0;
+
        *state = result;
 
  out:
index fc18034..40e38a0 100644 (file)
@@ -107,6 +107,7 @@ struct acpi_power_resource {
 
        /* List of devices relying on this power resource */
        struct acpi_power_resource_device *devices;
+       struct mutex devices_lock;
 };
 
 static struct list_head acpi_power_resource_list;
@@ -225,7 +226,6 @@ static void acpi_power_on_device(struct acpi_power_managed_device *device)
 
 static int __acpi_power_on(struct acpi_power_resource *resource)
 {
-       struct acpi_power_resource_device *device_list = resource->devices;
        acpi_status status = AE_OK;
 
        status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL);
@@ -238,19 +238,15 @@ static int __acpi_power_on(struct acpi_power_resource *resource)
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n",
                          resource->name));
 
-       while (device_list) {
-               acpi_power_on_device(device_list->device);
-
-               device_list = device_list->next;
-       }
-
        return 0;
 }
 
 static int acpi_power_on(acpi_handle handle)
 {
        int result = 0;
+       bool resume_device = false;
        struct acpi_power_resource *resource = NULL;
+       struct acpi_power_resource_device *device_list;
 
        result = acpi_power_get_context(handle, &resource);
        if (result)
@@ -266,10 +262,25 @@ static int acpi_power_on(acpi_handle handle)
                result = __acpi_power_on(resource);
                if (result)
                        resource->ref_count--;
+               else
+                       resume_device = true;
        }
 
        mutex_unlock(&resource->resource_lock);
 
+       if (!resume_device)
+               return result;
+
+       mutex_lock(&resource->devices_lock);
+
+       device_list = resource->devices;
+       while (device_list) {
+               acpi_power_on_device(device_list->device);
+               device_list = device_list->next;
+       }
+
+       mutex_unlock(&resource->devices_lock);
+
        return result;
 }
 
@@ -355,7 +366,7 @@ static void __acpi_power_resource_unregister_device(struct device *dev,
        if (acpi_power_get_context(res_handle, &resource))
                return;
 
-       mutex_lock(&resource->resource_lock);
+       mutex_lock(&resource->devices_lock);
        prev = NULL;
        curr = resource->devices;
        while (curr) {
@@ -372,7 +383,7 @@ static void __acpi_power_resource_unregister_device(struct device *dev,
                prev = curr;
                curr = curr->next;
        }
-       mutex_unlock(&resource->resource_lock);
+       mutex_unlock(&resource->devices_lock);
 }
 
 /* Unlink dev from all power resources in _PR0 */
@@ -414,10 +425,10 @@ static int __acpi_power_resource_register_device(
 
        power_resource_device->device = powered_device;
 
-       mutex_lock(&resource->resource_lock);
+       mutex_lock(&resource->devices_lock);
        power_resource_device->next = resource->devices;
        resource->devices = power_resource_device;
-       mutex_unlock(&resource->resource_lock);
+       mutex_unlock(&resource->devices_lock);
 
        return 0;
 }
@@ -462,7 +473,7 @@ int acpi_power_resource_register_device(struct device *dev, acpi_handle handle)
        return ret;
 
 no_power_resource:
-       printk(KERN_WARNING PREFIX "Invalid Power Resource to register!");
+       printk(KERN_DEBUG PREFIX "Invalid Power Resource to register!");
        return -ENODEV;
 }
 EXPORT_SYMBOL_GPL(acpi_power_resource_register_device);
@@ -721,6 +732,7 @@ static int acpi_power_add(struct acpi_device *device)
 
        resource->device = device;
        mutex_init(&resource->resource_lock);
+       mutex_init(&resource->devices_lock);
        strcpy(resource->name, device->pnp.bus_id);
        strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_POWER_CLASS);
index de0435e..887f68f 100644 (file)
@@ -35,6 +35,7 @@ new_skb(ulong len)
                skb_reset_mac_header(skb);
                skb_reset_network_header(skb);
                skb->protocol = __constant_htons(ETH_P_AOE);
+               skb_checksum_none_assert(skb);
        }
        return skb;
 }
index 38aa6dd..da33111 100644 (file)
@@ -795,6 +795,7 @@ static void complete_scsi_command(CommandList_struct *c, int timeout,
                                }
                        break;
                        case CMD_PROTOCOL_ERR:
+                               cmd->result = DID_ERROR << 16;
                                dev_warn(&h->pdev->dev,
                                        "%p has protocol error\n", c);
                         break;
index a8fddeb..f946d31 100644 (file)
@@ -1148,11 +1148,15 @@ static bool mtip_pause_ncq(struct mtip_port *port,
        reply = port->rxfis + RX_FIS_D2H_REG;
        task_file_data = readl(port->mmio+PORT_TFDATA);
 
-       if ((task_file_data & 1) || (fis->command == ATA_CMD_SEC_ERASE_UNIT))
+       if (fis->command == ATA_CMD_SEC_ERASE_UNIT)
+               clear_bit(MTIP_DDF_SEC_LOCK_BIT, &port->dd->dd_flag);
+
+       if ((task_file_data & 1))
                return false;
 
        if (fis->command == ATA_CMD_SEC_ERASE_PREP) {
                set_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags);
+               set_bit(MTIP_DDF_SEC_LOCK_BIT, &port->dd->dd_flag);
                port->ic_pause_timer = jiffies;
                return true;
        } else if ((fis->command == ATA_CMD_DOWNLOAD_MICRO) &&
@@ -1900,7 +1904,7 @@ static int exec_drive_command(struct mtip_port *port, u8 *command,
        int rv = 0, xfer_sz = command[3];
 
        if (xfer_sz) {
-               if (user_buffer)
+               if (!user_buffer)
                        return -EFAULT;
 
                buf = dmam_alloc_coherent(&port->dd->pdev->dev,
@@ -2043,7 +2047,7 @@ static void mtip_set_timeout(struct host_to_dev_fis *fis, unsigned int *timeout)
                *timeout = 240000; /* 4 minutes */
                break;
        case ATA_CMD_STANDBYNOW1:
-               *timeout = 10000;  /* 10 seconds */
+               *timeout = 120000;  /* 2 minutes */
                break;
        case 0xF7:
        case 0xFA:
@@ -2588,9 +2592,6 @@ static ssize_t mtip_hw_read_registers(struct file *f, char __user *ubuf,
        if (!len || size)
                return 0;
 
-       if (size < 0)
-               return -EINVAL;
-
        size += sprintf(&buf[size], "H/ S ACTive      : [ 0x");
 
        for (n = dd->slot_groups-1; n >= 0; n--)
@@ -2660,9 +2661,6 @@ static ssize_t mtip_hw_read_flags(struct file *f, char __user *ubuf,
        if (!len || size)
                return 0;
 
-       if (size < 0)
-               return -EINVAL;
-
        size += sprintf(&buf[size], "Flag-port : [ %08lX ]\n",
                                                        dd->port->flags);
        size += sprintf(&buf[size], "Flag-dd   : [ %08lX ]\n",
@@ -3214,8 +3212,8 @@ static int mtip_hw_init(struct driver_data *dd)
                                "Unable to check write protect progress\n");
        else
                dev_info(&dd->pdev->dev,
-                               "Write protect progress: %d%% (%d blocks)\n",
-                               attr242.cur, attr242.data);
+                               "Write protect progress: %u%% (%u blocks)\n",
+                               attr242.cur, le32_to_cpu(attr242.data));
        return rv;
 
 out3:
@@ -3619,6 +3617,10 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
                        bio_endio(bio, -ENODATA);
                        return;
                }
+               if (unlikely(test_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag))) {
+                       bio_endio(bio, -ENODATA);
+                       return;
+               }
        }
 
        if (unlikely(!bio_has_data(bio))) {
@@ -4168,7 +4170,13 @@ static void mtip_pci_shutdown(struct pci_dev *pdev)
 
 /* Table of device ids supported by this driver. */
 static DEFINE_PCI_DEVICE_TABLE(mtip_pci_tbl) = {
-       {  PCI_DEVICE(PCI_VENDOR_ID_MICRON, P320_DEVICE_ID) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MICRON, P320H_DEVICE_ID) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MICRON, P320M_DEVICE_ID) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MICRON, P320S_DEVICE_ID) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MICRON, P325M_DEVICE_ID) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MICRON, P420H_DEVICE_ID) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MICRON, P420M_DEVICE_ID) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MICRON, P425M_DEVICE_ID) },
        { 0 }
 };
 
@@ -4199,12 +4207,12 @@ static int __init mtip_init(void)
 {
        int error;
 
-       printk(KERN_INFO MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n");
+       pr_info(MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n");
 
        /* Allocate a major block device number to use with this driver. */
        error = register_blkdev(0, MTIP_DRV_NAME);
        if (error <= 0) {
-               printk(KERN_ERR "Unable to register block device (%d)\n",
+               pr_err("Unable to register block device (%d)\n",
                error);
                return -EBUSY;
        }
@@ -4213,7 +4221,7 @@ static int __init mtip_init(void)
        if (!dfs_parent) {
                dfs_parent = debugfs_create_dir("rssd", NULL);
                if (IS_ERR_OR_NULL(dfs_parent)) {
-                       printk(KERN_WARNING "Error creating debugfs parent\n");
+                       pr_warn("Error creating debugfs parent\n");
                        dfs_parent = NULL;
                }
        }
index f51fc23..18627a1 100644 (file)
 
 /* Micron Vendor ID & P320x SSD Device ID */
 #define PCI_VENDOR_ID_MICRON    0x1344
-#define P320_DEVICE_ID         0x5150
+#define P320H_DEVICE_ID                0x5150
+#define P320M_DEVICE_ID                0x5151
+#define P320S_DEVICE_ID                0x5152
+#define P325M_DEVICE_ID                0x5153
+#define P420H_DEVICE_ID                0x5160
+#define P420M_DEVICE_ID                0x5161
+#define P425M_DEVICE_ID                0x5163
 
 /* Driver name and version strings */
 #define MTIP_DRV_NAME          "mtip32xx"
@@ -131,10 +137,12 @@ enum {
        MTIP_PF_SVC_THD_STOP_BIT    = 8,
 
        /* below are bit numbers in 'dd_flag' defined in driver_data */
+       MTIP_DDF_SEC_LOCK_BIT       = 0,
        MTIP_DDF_REMOVE_PENDING_BIT = 1,
        MTIP_DDF_OVER_TEMP_BIT      = 2,
        MTIP_DDF_WRITE_PROTECT_BIT  = 3,
        MTIP_DDF_STOP_IO      = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | \
+                               (1 << MTIP_DDF_SEC_LOCK_BIT) | \
                                (1 << MTIP_DDF_OVER_TEMP_BIT) | \
                                (1 << MTIP_DDF_WRITE_PROTECT_BIT)),
 
index d07c9f7..0c03411 100644 (file)
@@ -449,6 +449,14 @@ static void nbd_clear_que(struct nbd_device *nbd)
                req->errors++;
                nbd_end_request(req);
        }
+
+       while (!list_empty(&nbd->waiting_queue)) {
+               req = list_entry(nbd->waiting_queue.next, struct request,
+                                queuelist);
+               list_del_init(&req->queuelist);
+               req->errors++;
+               nbd_end_request(req);
+       }
 }
 
 
@@ -598,6 +606,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
                nbd->file = NULL;
                nbd_clear_que(nbd);
                BUG_ON(!list_empty(&nbd->queue_head));
+               BUG_ON(!list_empty(&nbd->waiting_queue));
                if (file)
                        fput(file);
                return 0;
index 73f196c..c6decb9 100644 (file)
@@ -337,7 +337,7 @@ static void xen_blkbk_unmap(struct pending_req *req)
                invcount++;
        }
 
-       ret = gnttab_unmap_refs(unmap, pages, invcount, false);
+       ret = gnttab_unmap_refs(unmap, NULL, pages, invcount);
        BUG_ON(ret);
 }
 
index c0e8164..1a40935 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/cpumask.h>
-#include <linux/sched.h>       /* for current / set_cpus_allowed() */
 #include <linux/io.h>
 #include <linux/delay.h>
 
@@ -1139,16 +1138,23 @@ static int transition_frequency_pstate(struct powernow_k8_data *data,
        return res;
 }
 
-/* Driver entry point to switch to the target frequency */
-static int powernowk8_target(struct cpufreq_policy *pol,
-               unsigned targfreq, unsigned relation)
+struct powernowk8_target_arg {
+       struct cpufreq_policy           *pol;
+       unsigned                        targfreq;
+       unsigned                        relation;
+};
+
+static long powernowk8_target_fn(void *arg)
 {
-       cpumask_var_t oldmask;
+       struct powernowk8_target_arg *pta = arg;
+       struct cpufreq_policy *pol = pta->pol;
+       unsigned targfreq = pta->targfreq;
+       unsigned relation = pta->relation;
        struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
        u32 checkfid;
        u32 checkvid;
        unsigned int newstate;
-       int ret = -EIO;
+       int ret;
 
        if (!data)
                return -EINVAL;
@@ -1156,29 +1162,16 @@ static int powernowk8_target(struct cpufreq_policy *pol,
        checkfid = data->currfid;
        checkvid = data->currvid;
 
-       /* only run on specific CPU from here on. */
-       /* This is poor form: use a workqueue or smp_call_function_single */
-       if (!alloc_cpumask_var(&oldmask, GFP_KERNEL))
-               return -ENOMEM;
-
-       cpumask_copy(oldmask, tsk_cpus_allowed(current));
-       set_cpus_allowed_ptr(current, cpumask_of(pol->cpu));
-
-       if (smp_processor_id() != pol->cpu) {
-               printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
-               goto err_out;
-       }
-
        if (pending_bit_stuck()) {
                printk(KERN_ERR PFX "failing targ, change pending bit set\n");
-               goto err_out;
+               return -EIO;
        }
 
        pr_debug("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n",
                pol->cpu, targfreq, pol->min, pol->max, relation);
 
        if (query_current_values_with_pending_wait(data))
-               goto err_out;
+               return -EIO;
 
        if (cpu_family != CPU_HW_PSTATE) {
                pr_debug("targ: curr fid 0x%x, vid 0x%x\n",
@@ -1196,7 +1189,7 @@ static int powernowk8_target(struct cpufreq_policy *pol,
 
        if (cpufreq_frequency_table_target(pol, data->powernow_table,
                                targfreq, relation, &newstate))
-               goto err_out;
+               return -EIO;
 
        mutex_lock(&fidvid_mutex);
 
@@ -1209,9 +1202,8 @@ static int powernowk8_target(struct cpufreq_policy *pol,
                ret = transition_frequency_fidvid(data, newstate);
        if (ret) {
                printk(KERN_ERR PFX "transition frequency failed\n");
-               ret = 1;
                mutex_unlock(&fidvid_mutex);
-               goto err_out;
+               return 1;
        }
        mutex_unlock(&fidvid_mutex);
 
@@ -1220,12 +1212,25 @@ static int powernowk8_target(struct cpufreq_policy *pol,
                                data->powernow_table[newstate].index);
        else
                pol->cur = find_khz_freq_from_fid(data->currfid);
-       ret = 0;
 
-err_out:
-       set_cpus_allowed_ptr(current, oldmask);
-       free_cpumask_var(oldmask);
-       return ret;
+       return 0;
+}
+
+/* Driver entry point to switch to the target frequency */
+static int powernowk8_target(struct cpufreq_policy *pol,
+               unsigned targfreq, unsigned relation)
+{
+       struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq,
+                                            .relation = relation };
+
+       /*
+        * Must run on @pol->cpu.  cpufreq core is responsible for ensuring
+        * that we're bound to the current CPU and pol->cpu stays online.
+        */
+       if (smp_processor_id() == pol->cpu)
+               return powernowk8_target_fn(&pta);
+       else
+               return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta);
 }
 
 /* Driver entry point to verify the policy and range of frequencies */
index 3934fcc..7ab6e26 100644 (file)
@@ -661,7 +661,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
                        flags);
 
        if (unlikely(!atslave || !sg_len)) {
-               dev_dbg(chan2dev(chan), "prep_dma_memcpy: length is zero!\n");
+               dev_dbg(chan2dev(chan), "prep_slave_sg: sg length is zero!\n");
                return NULL;
        }
 
@@ -689,6 +689,11 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 
                        mem = sg_dma_address(sg);
                        len = sg_dma_len(sg);
+                       if (unlikely(!len)) {
+                               dev_dbg(chan2dev(chan),
+                                       "prep_slave_sg: sg(%d) data length is zero\n", i);
+                               goto err;
+                       }
                        mem_width = 2;
                        if (unlikely(mem & 3 || len & 3))
                                mem_width = 0;
@@ -724,6 +729,11 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 
                        mem = sg_dma_address(sg);
                        len = sg_dma_len(sg);
+                       if (unlikely(!len)) {
+                               dev_dbg(chan2dev(chan),
+                                       "prep_slave_sg: sg(%d) data length is zero\n", i);
+                               goto err;
+                       }
                        mem_width = 2;
                        if (unlikely(mem & 3 || len & 3))
                                mem_width = 0;
@@ -757,6 +767,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 
 err_desc_get:
        dev_err(chan2dev(chan), "not enough descriptors available\n");
+err:
        atc_desc_put(atchan, first);
        return NULL;
 }
index e4feba6..f5843bc 100644 (file)
@@ -1567,17 +1567,19 @@ static int pl330_submit_req(void *ch_id, struct pl330_req *r)
                goto xfer_exit;
        }
 
-       /* Prefer Secure Channel */
-       if (!_manager_ns(thrd))
-               r->cfg->nonsecure = 0;
-       else
-               r->cfg->nonsecure = 1;
 
        /* Use last settings, if not provided */
-       if (r->cfg)
+       if (r->cfg) {
+               /* Prefer Secure Channel */
+               if (!_manager_ns(thrd))
+                       r->cfg->nonsecure = 0;
+               else
+                       r->cfg->nonsecure = 1;
+
                ccr = _prepare_ccr(r->cfg);
-       else
+       } else {
                ccr = readl(regs + CC(thrd->id));
+       }
 
        /* If this req doesn't have valid xfer settings */
        if (!_is_valid(ccr)) {
@@ -2928,6 +2930,11 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
                num_chan = max_t(int, pi->pcfg.num_peri, pi->pcfg.num_chan);
 
        pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL);
+       if (!pdmac->peripherals) {
+               ret = -ENOMEM;
+               dev_err(&adev->dev, "unable to allocate pdmac->peripherals\n");
+               goto probe_err5;
+       }
 
        for (i = 0; i < num_chan; i++) {
                pch = &pdmac->peripherals[i];
index 920a609..38f9e52 100644 (file)
@@ -669,13 +669,18 @@ static int __devinit max77693_muic_probe(struct platform_device *pdev)
        }
        info->dev = &pdev->dev;
        info->max77693 = max77693;
-       info->max77693->regmap_muic = regmap_init_i2c(info->max77693->muic,
-                                        &max77693_muic_regmap_config);
-       if (IS_ERR(info->max77693->regmap_muic)) {
-               ret = PTR_ERR(info->max77693->regmap_muic);
-               dev_err(max77693->dev,
-                       "failed to allocate register map: %d\n", ret);
-               goto err_regmap;
+       if (info->max77693->regmap_muic)
+               dev_dbg(&pdev->dev, "allocate register map\n");
+       else {
+               info->max77693->regmap_muic = devm_regmap_init_i2c(
+                                               info->max77693->muic,
+                                               &max77693_muic_regmap_config);
+               if (IS_ERR(info->max77693->regmap_muic)) {
+                       ret = PTR_ERR(info->max77693->regmap_muic);
+                       dev_err(max77693->dev,
+                               "failed to allocate register map: %d\n", ret);
+                       goto err_regmap;
+               }
        }
        platform_set_drvdata(pdev, info);
        mutex_init(&info->mutex);
index 489e2b1..274d25d 100644 (file)
@@ -3242,7 +3242,8 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj,
 {
        int ret;
 
-       BUG_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT);
+       if (WARN_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT))
+               return -EBUSY;
 
        if (obj->gtt_space != NULL) {
                if ((alignment && obj->gtt_offset & (alignment - 1)) ||
index bc2ad34..c040aee 100644 (file)
@@ -4191,12 +4191,6 @@ static void i8xx_update_pll(struct drm_crtc *crtc,
        POSTING_READ(DPLL(pipe));
        udelay(150);
 
-       I915_WRITE(DPLL(pipe), dpll);
-
-       /* Wait for the clocks to stabilize. */
-       POSTING_READ(DPLL(pipe));
-       udelay(150);
-
        /* The LVDS pin pair needs to be on before the DPLLs are enabled.
         * This is an exception to the general rule that mode_set doesn't turn
         * things on.
@@ -4204,6 +4198,12 @@ static void i8xx_update_pll(struct drm_crtc *crtc,
        if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
                intel_update_lvds(crtc, clock, adjusted_mode);
 
+       I915_WRITE(DPLL(pipe), dpll);
+
+       /* Wait for the clocks to stabilize. */
+       POSTING_READ(DPLL(pipe));
+       udelay(150);
+
        /* The pixel multiplier can only be updated once the
         * DPLL is enabled and the clocks are stable.
         *
index 98f6024..12dc330 100644 (file)
@@ -609,7 +609,7 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
        u32 temp;
        u32 enable_bits = SDVO_ENABLE;
 
-       if (intel_hdmi->has_audio)
+       if (intel_hdmi->has_audio || mode != DRM_MODE_DPMS_ON)
                enable_bits |= SDVO_AUDIO_ENABLE;
 
        temp = I915_READ(intel_hdmi->sdvox_reg);
index f034905..c399d51 100644 (file)
@@ -22,6 +22,7 @@
  * Authors: Ben Skeggs
  */
 
+#include <linux/dmi.h>
 #include "drmP.h"
 #include "nouveau_drv.h"
 #include "nouveau_hw.h"
@@ -110,13 +111,25 @@ nv50_gpio_isr(struct drm_device *dev)
                nv_wr32(dev, 0xe074, intr1);
 }
 
+static struct dmi_system_id gpio_reset_ids[] = {
+       {
+               .ident = "Apple Macbook 10,1",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro10,1"),
+               }
+       },
+       { }
+};
+
 int
 nv50_gpio_init(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
 
        /* initialise gpios and routing to vbios defaults */
-       nouveau_gpio_reset(dev);
+       if (dmi_check_system(gpio_reset_ids))
+               nouveau_gpio_reset(dev);
 
        /* disable, and ack any pending gpio interrupts */
        nv_wr32(dev, 0xe050, 0x00000000);
index e721e30..2817101 100644 (file)
@@ -1479,98 +1479,14 @@ static void radeon_legacy_atom_fixup(struct drm_crtc *crtc)
        }
 }
 
-/**
- * radeon_get_pll_use_mask - look up a mask of which pplls are in use
- *
- * @crtc: drm crtc
- *
- * Returns the mask of which PPLLs (Pixel PLLs) are in use.
- */
-static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc)
-{
-       struct drm_device *dev = crtc->dev;
-       struct drm_crtc *test_crtc;
-       struct radeon_crtc *radeon_test_crtc;
-       u32 pll_in_use = 0;
-
-       list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
-               if (crtc == test_crtc)
-                       continue;
-
-               radeon_test_crtc = to_radeon_crtc(test_crtc);
-               if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID)
-                       pll_in_use |= (1 << radeon_test_crtc->pll_id);
-       }
-       return pll_in_use;
-}
-
-/**
- * radeon_get_shared_dp_ppll - return the PPLL used by another crtc for DP
- *
- * @crtc: drm crtc
- *
- * Returns the PPLL (Pixel PLL) used by another crtc/encoder which is
- * also in DP mode.  For DP, a single PPLL can be used for all DP
- * crtcs/encoders.
- */
-static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc)
-{
-       struct drm_device *dev = crtc->dev;
-       struct drm_encoder *test_encoder;
-       struct radeon_crtc *radeon_test_crtc;
-
-       list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
-               if (test_encoder->crtc && (test_encoder->crtc != crtc)) {
-                       if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
-                               /* for DP use the same PLL for all */
-                               radeon_test_crtc = to_radeon_crtc(test_encoder->crtc);
-                               if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID)
-                                       return radeon_test_crtc->pll_id;
-                       }
-               }
-       }
-       return ATOM_PPLL_INVALID;
-}
-
-/**
- * radeon_atom_pick_pll - Allocate a PPLL for use by the crtc.
- *
- * @crtc: drm crtc
- *
- * Returns the PPLL (Pixel PLL) to be used by the crtc.  For DP monitors
- * a single PPLL can be used for all DP crtcs/encoders.  For non-DP
- * monitors a dedicated PPLL must be used.  If a particular board has
- * an external DP PLL, return ATOM_PPLL_INVALID to skip PLL programming
- * as there is no need to program the PLL itself.  If we are not able to
- * allocate a PLL, return ATOM_PPLL_INVALID to skip PLL programming to
- * avoid messing up an existing monitor.
- *
- * Asic specific PLL information
- *
- * DCE 6.1
- * - PPLL2 is only available to UNIPHYA (both DP and non-DP)
- * - PPLL0, PPLL1 are available for UNIPHYB/C/D/E/F (both DP and non-DP)
- *
- * DCE 6.0
- * - PPLL0 is available to all UNIPHY (DP only)
- * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
- *
- * DCE 5.0
- * - DCPLL is available to all UNIPHY (DP only)
- * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
- *
- * DCE 3.0/4.0/4.1
- * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
- *
- */
 static int radeon_atom_pick_pll(struct drm_crtc *crtc)
 {
        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
        struct drm_device *dev = crtc->dev;
        struct radeon_device *rdev = dev->dev_private;
        struct drm_encoder *test_encoder;
-       u32 pll_in_use;
-       int pll;
+       struct drm_crtc *test_crtc;
+       uint32_t pll_in_use = 0;
 
        if (ASIC_IS_DCE61(rdev)) {
                list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
@@ -1582,40 +1498,32 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
 
                                if ((test_radeon_encoder->encoder_id ==
                                     ENCODER_OBJECT_ID_INTERNAL_UNIPHY) &&
-                                   (dig->linkb == false))
-                                       /* UNIPHY A uses PPLL2 */
+                                   (dig->linkb == false)) /* UNIPHY A uses PPLL2 */
                                        return ATOM_PPLL2;
-                               else if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
-                                       /* UNIPHY B/C/D/E/F */
-                                       if (rdev->clock.dp_extclk)
-                                               /* skip PPLL programming if using ext clock */
-                                               return ATOM_PPLL_INVALID;
-                                       else {
-                                               /* use the same PPLL for all DP monitors */
-                                               pll = radeon_get_shared_dp_ppll(crtc);
-                                               if (pll != ATOM_PPLL_INVALID)
-                                                       return pll;
-                                       }
-                               }
-                               break;
                        }
                }
                /* UNIPHY B/C/D/E/F */
-               pll_in_use = radeon_get_pll_use_mask(crtc);
-               if (!(pll_in_use & (1 << ATOM_PPLL0)))
+               list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
+                       struct radeon_crtc *radeon_test_crtc;
+
+                       if (crtc == test_crtc)
+                               continue;
+
+                       radeon_test_crtc = to_radeon_crtc(test_crtc);
+                       if ((radeon_test_crtc->pll_id == ATOM_PPLL0) ||
+                           (radeon_test_crtc->pll_id == ATOM_PPLL1))
+                               pll_in_use |= (1 << radeon_test_crtc->pll_id);
+               }
+               if (!(pll_in_use & 4))
                        return ATOM_PPLL0;
-               if (!(pll_in_use & (1 << ATOM_PPLL1)))
-                       return ATOM_PPLL1;
-               DRM_ERROR("unable to allocate a PPLL\n");
-               return ATOM_PPLL_INVALID;
+               return ATOM_PPLL1;
        } else if (ASIC_IS_DCE4(rdev)) {
                list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
                        if (test_encoder->crtc && (test_encoder->crtc == crtc)) {
                                /* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock,
                                 * depending on the asic:
                                 * DCE4: PPLL or ext clock
-                                * DCE5: PPLL, DCPLL, or ext clock
-                                * DCE6: PPLL, PPLL0, or ext clock
+                                * DCE5: DCPLL or ext clock
                                 *
                                 * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip
                                 * PPLL/DCPLL programming and only program the DP DTO for the
@@ -1623,34 +1531,31 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
                                 */
                                if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
                                        if (rdev->clock.dp_extclk)
-                                               /* skip PPLL programming if using ext clock */
                                                return ATOM_PPLL_INVALID;
                                        else if (ASIC_IS_DCE6(rdev))
-                                               /* use PPLL0 for all DP */
                                                return ATOM_PPLL0;
                                        else if (ASIC_IS_DCE5(rdev))
-                                               /* use DCPLL for all DP */
                                                return ATOM_DCPLL;
-                                       else {
-                                               /* use the same PPLL for all DP monitors */
-                                               pll = radeon_get_shared_dp_ppll(crtc);
-                                               if (pll != ATOM_PPLL_INVALID)
-                                                       return pll;
-                                       }
                                }
-                               break;
                        }
                }
-               /* all other cases */
-               pll_in_use = radeon_get_pll_use_mask(crtc);
-               if (!(pll_in_use & (1 << ATOM_PPLL2)))
-                       return ATOM_PPLL2;
-               if (!(pll_in_use & (1 << ATOM_PPLL1)))
+
+               /* otherwise, pick one of the plls */
+               list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
+                       struct radeon_crtc *radeon_test_crtc;
+
+                       if (crtc == test_crtc)
+                               continue;
+
+                       radeon_test_crtc = to_radeon_crtc(test_crtc);
+                       if ((radeon_test_crtc->pll_id >= ATOM_PPLL1) &&
+                           (radeon_test_crtc->pll_id <= ATOM_PPLL2))
+                               pll_in_use |= (1 << radeon_test_crtc->pll_id);
+               }
+               if (!(pll_in_use & 1))
                        return ATOM_PPLL1;
-               DRM_ERROR("unable to allocate a PPLL\n");
-               return ATOM_PPLL_INVALID;
+               return ATOM_PPLL2;
        } else
-               /* use PPLL1 or PPLL2 */
                return radeon_crtc->crtc_id;
 
 }
@@ -1792,7 +1697,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
                break;
        }
 done:
-       radeon_crtc->pll_id = ATOM_PPLL_INVALID;
+       radeon_crtc->pll_id = -1;
 }
 
 static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
@@ -1841,6 +1746,6 @@ void radeon_atombios_init_crtc(struct drm_device *dev,
                else
                        radeon_crtc->crtc_offset = 0;
        }
-       radeon_crtc->pll_id = ATOM_PPLL_INVALID;
+       radeon_crtc->pll_id = -1;
        drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
 }
index 8acb34f..8d7e33a 100644 (file)
@@ -1182,7 +1182,8 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
        ring->ready = true;
        radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
 
-       if (radeon_ring_supports_scratch_reg(rdev, ring)) {
+       if (!ring->rptr_save_reg /* not resuming from suspend */
+           && radeon_ring_supports_scratch_reg(rdev, ring)) {
                r = radeon_scratch_get(rdev, &ring->rptr_save_reg);
                if (r) {
                        DRM_ERROR("failed to get scratch reg for rptr save (%d).\n", r);
index 77d2df0..60c4e1e 100644 (file)
@@ -519,6 +519,8 @@ static void tpkbd_remove_tp(struct hid_device *hdev)
        led_classdev_unregister(&data_pointer->led_mute);
 
        hid_set_drvdata(hdev, NULL);
+       kfree(data_pointer->led_micmute.name);
+       kfree(data_pointer->led_mute.name);
        kfree(data_pointer);
 }
 
index 4d524b5..9500f2f 100644 (file)
@@ -193,6 +193,7 @@ static struct hid_ll_driver logi_dj_ll_driver;
 static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf,
                                        size_t count,
                                        unsigned char report_type);
+static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev);
 
 static void logi_dj_recv_destroy_djhid_device(struct dj_receiver_dev *djrcv_dev,
                                                struct dj_report *dj_report)
@@ -233,6 +234,7 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
        if (dj_report->report_params[DEVICE_PAIRED_PARAM_SPFUNCTION] &
            SPFUNCTION_DEVICE_LIST_EMPTY) {
                dbg_hid("%s: device list is empty\n", __func__);
+               djrcv_dev->querying_devices = false;
                return;
        }
 
@@ -243,6 +245,12 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
                return;
        }
 
+       if (djrcv_dev->paired_dj_devices[dj_report->device_index]) {
+               /* The device is already known. No need to reallocate it. */
+               dbg_hid("%s: device is already known\n", __func__);
+               return;
+       }
+
        dj_hiddev = hid_allocate_device();
        if (IS_ERR(dj_hiddev)) {
                dev_err(&djrcv_hdev->dev, "%s: hid_allocate_device failed\n",
@@ -306,6 +314,7 @@ static void delayedwork_callback(struct work_struct *work)
        struct dj_report dj_report;
        unsigned long flags;
        int count;
+       int retval;
 
        dbg_hid("%s\n", __func__);
 
@@ -338,6 +347,25 @@ static void delayedwork_callback(struct work_struct *work)
                logi_dj_recv_destroy_djhid_device(djrcv_dev, &dj_report);
                break;
        default:
+       /* A normal report (i. e. not belonging to a pair/unpair notification)
+        * arriving here, means that the report arrived but we did not have a
+        * paired dj_device associated to the report's device_index, this
+        * means that the original "device paired" notification corresponding
+        * to this dj_device never arrived to this driver. The reason is that
+        * hid-core discards all packets coming from a device while probe() is
+        * executing. */
+       if (!djrcv_dev->paired_dj_devices[dj_report.device_index]) {
+               /* ok, we don't know the device, just re-ask the
+                * receiver for the list of connected devices. */
+               retval = logi_dj_recv_query_paired_devices(djrcv_dev);
+               if (!retval) {
+                       /* everything went fine, so just leave */
+                       break;
+               }
+               dev_err(&djrcv_dev->hdev->dev,
+                       "%s:logi_dj_recv_query_paired_devices "
+                       "error:%d\n", __func__, retval);
+               }
                dbg_hid("%s: unexpected report type\n", __func__);
        }
 }
@@ -368,6 +396,12 @@ static void logi_dj_recv_forward_null_report(struct dj_receiver_dev *djrcv_dev,
        if (!djdev) {
                dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]"
                        " is NULL, index %d\n", dj_report->device_index);
+               kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report));
+
+               if (schedule_work(&djrcv_dev->work) == 0) {
+                       dbg_hid("%s: did not schedule the work item, was already "
+                       "queued\n", __func__);
+               }
                return;
        }
 
@@ -398,6 +432,12 @@ static void logi_dj_recv_forward_report(struct dj_receiver_dev *djrcv_dev,
        if (dj_device == NULL) {
                dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]"
                        " is NULL, index %d\n", dj_report->device_index);
+               kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report));
+
+               if (schedule_work(&djrcv_dev->work) == 0) {
+                       dbg_hid("%s: did not schedule the work item, was already "
+                       "queued\n", __func__);
+               }
                return;
        }
 
@@ -439,6 +479,10 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
        struct dj_report *dj_report;
        int retval;
 
+       /* no need to protect djrcv_dev->querying_devices */
+       if (djrcv_dev->querying_devices)
+               return 0;
+
        dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL);
        if (!dj_report)
                return -ENOMEM;
@@ -450,6 +494,7 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
        return retval;
 }
 
+
 static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
                                          unsigned timeout)
 {
index fd28a5e..4a40003 100644 (file)
@@ -101,6 +101,7 @@ struct dj_receiver_dev {
        struct work_struct work;
        struct kfifo notif_fifo;
        spinlock_t lock;
+       bool querying_devices;
 };
 
 struct dj_device {
index cfec802..f915eb1 100644 (file)
@@ -87,10 +87,18 @@ static ssize_t ad7314_show_temperature(struct device *dev,
        }
 }
 
+static ssize_t ad7314_show_name(struct device *dev,
+                               struct device_attribute *devattr, char *buf)
+{
+       return sprintf(buf, "%s\n", to_spi_device(dev)->modalias);
+}
+
+static DEVICE_ATTR(name, S_IRUGO, ad7314_show_name, NULL);
 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
                          ad7314_show_temperature, NULL, 0);
 
 static struct attribute *ad7314_attributes[] = {
+       &dev_attr_name.attr,
        &sensor_dev_attr_temp1_input.dev_attr.attr,
        NULL,
 };
index e65c6e4..7bf4ce3 100644 (file)
@@ -139,6 +139,12 @@ static ssize_t show_voltage(struct device *dev,
        }
 }
 
+static ssize_t ads7871_show_name(struct device *dev,
+                                struct device_attribute *devattr, char *buf)
+{
+       return sprintf(buf, "%s\n", to_spi_device(dev)->modalias);
+}
+
 static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_voltage, NULL, 0);
 static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_voltage, NULL, 1);
 static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_voltage, NULL, 2);
@@ -148,6 +154,8 @@ static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_voltage, NULL, 5);
 static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_voltage, NULL, 6);
 static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_voltage, NULL, 7);
 
+static DEVICE_ATTR(name, S_IRUGO, ads7871_show_name, NULL);
+
 static struct attribute *ads7871_attributes[] = {
        &sensor_dev_attr_in0_input.dev_attr.attr,
        &sensor_dev_attr_in1_input.dev_attr.attr,
@@ -157,6 +165,7 @@ static struct attribute *ads7871_attributes[] = {
        &sensor_dev_attr_in5_input.dev_attr.attr,
        &sensor_dev_attr_in6_input.dev_attr.attr,
        &sensor_dev_attr_in7_input.dev_attr.attr,
+       &dev_attr_name.attr,
        NULL
 };
 
index 2827088..8f3f6f2 100644 (file)
 
 #define APPLESMC_MAX_DATA_LENGTH 32
 
-/* wait up to 32 ms for a status change. */
+/* wait up to 128 ms for a status change. */
 #define APPLESMC_MIN_WAIT      0x0010
 #define APPLESMC_RETRY_WAIT    0x0100
-#define APPLESMC_MAX_WAIT      0x8000
+#define APPLESMC_MAX_WAIT      0x20000
 
 #define APPLESMC_READ_CMD      0x10
 #define APPLESMC_WRITE_CMD     0x11
index 1201a15..db713c0 100644 (file)
@@ -552,7 +552,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_request_specific);
  */
 int hwspin_lock_free(struct hwspinlock *hwlock)
 {
-       struct device *dev = hwlock->bank->dev;
+       struct device *dev;
        struct hwspinlock *tmp;
        int ret;
 
@@ -561,6 +561,7 @@ int hwspin_lock_free(struct hwspinlock *hwlock)
                return -EINVAL;
        }
 
+       dev = hwlock->bank->dev;
        mutex_lock(&hwspinlock_tree_lock);
 
        /* make sure the hwspinlock is used */
index 51f4206..6cfd4d8 100644 (file)
@@ -1361,11 +1361,11 @@ static int abort_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
        struct tid_info *t = dev->rdev.lldi.tids;
 
        ep = lookup_tid(t, tid);
-       PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
        if (!ep) {
                printk(KERN_WARNING MOD "Abort rpl to freed endpoint\n");
                return 0;
        }
+       PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
        mutex_lock(&ep->com.mutex);
        switch (ep->com.state) {
        case ABORTING:
index cb5b7f7..b29a424 100644 (file)
@@ -2219,7 +2219,6 @@ static bool ocrdma_poll_success_scqe(struct ocrdma_qp *qp,
        u32 wqe_idx;
 
        if (!qp->wqe_wr_id_tbl[tail].signaled) {
-               expand = true;  /* CQE cannot be consumed yet */
                *polled = false;    /* WC cannot be consumed yet */
        } else {
                ibwc->status = IB_WC_SUCCESS;
@@ -2227,10 +2226,11 @@ static bool ocrdma_poll_success_scqe(struct ocrdma_qp *qp,
                ibwc->qp = &qp->ibqp;
                ocrdma_update_wc(qp, ibwc, tail);
                *polled = true;
-               wqe_idx = le32_to_cpu(cqe->wq.wqeidx) & OCRDMA_CQE_WQEIDX_MASK;
-               if (tail != wqe_idx)
-                       expand = true; /* Coalesced CQE can't be consumed yet */
        }
+       wqe_idx = le32_to_cpu(cqe->wq.wqeidx) & OCRDMA_CQE_WQEIDX_MASK;
+       if (tail != wqe_idx)
+               expand = true; /* Coalesced CQE can't be consumed yet */
+
        ocrdma_hwq_inc_tail(&qp->sq);
        return expand;
 }
index 19f1e6c..ccb1191 100644 (file)
@@ -471,9 +471,10 @@ static int subn_get_portinfo(struct ib_smp *smp, struct ib_device *ibdev,
                if (port_num != port) {
                        ibp = to_iport(ibdev, port_num);
                        ret = check_mkey(ibp, smp, 0);
-                       if (ret)
+                       if (ret) {
                                ret = IB_MAD_RESULT_FAILURE;
                                goto bail;
+                       }
                }
        }
 
index ca43901..0af216d 100644 (file)
@@ -262,7 +262,10 @@ struct ipoib_ethtool_st {
        u16     max_coalesced_frames;
 };
 
+struct ipoib_neigh_table;
+
 struct ipoib_neigh_hash {
+       struct ipoib_neigh_table       *ntbl;
        struct ipoib_neigh __rcu      **buckets;
        struct rcu_head                 rcu;
        u32                             mask;
@@ -271,9 +274,9 @@ struct ipoib_neigh_hash {
 
 struct ipoib_neigh_table {
        struct ipoib_neigh_hash __rcu  *htbl;
-       rwlock_t                        rwlock;
        atomic_t                        entries;
        struct completion               flushed;
+       struct completion               deleted;
 };
 
 /*
index 3e2085a..1e19b5a 100644 (file)
@@ -546,15 +546,15 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr,
        struct ipoib_neigh *neigh;
        unsigned long flags;
 
+       spin_lock_irqsave(&priv->lock, flags);
        neigh = ipoib_neigh_alloc(daddr, dev);
        if (!neigh) {
+               spin_unlock_irqrestore(&priv->lock, flags);
                ++dev->stats.tx_dropped;
                dev_kfree_skb_any(skb);
                return;
        }
 
-       spin_lock_irqsave(&priv->lock, flags);
-
        path = __path_find(dev, daddr + 4);
        if (!path) {
                path = path_rec_create(dev, daddr + 4);
@@ -863,10 +863,10 @@ static void __ipoib_reap_neigh(struct ipoib_dev_priv *priv)
        if (test_bit(IPOIB_STOP_NEIGH_GC, &priv->flags))
                return;
 
-       write_lock_bh(&ntbl->rwlock);
+       spin_lock_irqsave(&priv->lock, flags);
 
        htbl = rcu_dereference_protected(ntbl->htbl,
-                                        lockdep_is_held(&ntbl->rwlock));
+                                        lockdep_is_held(&priv->lock));
 
        if (!htbl)
                goto out_unlock;
@@ -883,16 +883,14 @@ static void __ipoib_reap_neigh(struct ipoib_dev_priv *priv)
                struct ipoib_neigh __rcu **np = &htbl->buckets[i];
 
                while ((neigh = rcu_dereference_protected(*np,
-                                                         lockdep_is_held(&ntbl->rwlock))) != NULL) {
+                                                         lockdep_is_held(&priv->lock))) != NULL) {
                        /* was the neigh idle for two GC periods */
                        if (time_after(neigh_obsolete, neigh->alive)) {
                                rcu_assign_pointer(*np,
                                                   rcu_dereference_protected(neigh->hnext,
-                                                                            lockdep_is_held(&ntbl->rwlock)));
+                                                                            lockdep_is_held(&priv->lock)));
                                /* remove from path/mc list */
-                               spin_lock_irqsave(&priv->lock, flags);
                                list_del(&neigh->list);
-                               spin_unlock_irqrestore(&priv->lock, flags);
                                call_rcu(&neigh->rcu, ipoib_neigh_reclaim);
                        } else {
                                np = &neigh->hnext;
@@ -902,7 +900,7 @@ static void __ipoib_reap_neigh(struct ipoib_dev_priv *priv)
        }
 
 out_unlock:
-       write_unlock_bh(&ntbl->rwlock);
+       spin_unlock_irqrestore(&priv->lock, flags);
 }
 
 static void ipoib_reap_neigh(struct work_struct *work)
@@ -947,10 +945,8 @@ struct ipoib_neigh *ipoib_neigh_alloc(u8 *daddr,
        struct ipoib_neigh *neigh;
        u32 hash_val;
 
-       write_lock_bh(&ntbl->rwlock);
-
        htbl = rcu_dereference_protected(ntbl->htbl,
-                                        lockdep_is_held(&ntbl->rwlock));
+                                        lockdep_is_held(&priv->lock));
        if (!htbl) {
                neigh = NULL;
                goto out_unlock;
@@ -961,10 +957,10 @@ struct ipoib_neigh *ipoib_neigh_alloc(u8 *daddr,
         */
        hash_val = ipoib_addr_hash(htbl, daddr);
        for (neigh = rcu_dereference_protected(htbl->buckets[hash_val],
-                                              lockdep_is_held(&ntbl->rwlock));
+                                              lockdep_is_held(&priv->lock));
             neigh != NULL;
             neigh = rcu_dereference_protected(neigh->hnext,
-                                              lockdep_is_held(&ntbl->rwlock))) {
+                                              lockdep_is_held(&priv->lock))) {
                if (memcmp(daddr, neigh->daddr, INFINIBAND_ALEN) == 0) {
                        /* found, take one ref on behalf of the caller */
                        if (!atomic_inc_not_zero(&neigh->refcnt)) {
@@ -987,12 +983,11 @@ struct ipoib_neigh *ipoib_neigh_alloc(u8 *daddr,
        /* put in hash */
        rcu_assign_pointer(neigh->hnext,
                           rcu_dereference_protected(htbl->buckets[hash_val],
-                                                    lockdep_is_held(&ntbl->rwlock)));
+                                                    lockdep_is_held(&priv->lock)));
        rcu_assign_pointer(htbl->buckets[hash_val], neigh);
        atomic_inc(&ntbl->entries);
 
 out_unlock:
-       write_unlock_bh(&ntbl->rwlock);
 
        return neigh;
 }
@@ -1040,35 +1035,29 @@ void ipoib_neigh_free(struct ipoib_neigh *neigh)
        struct ipoib_neigh *n;
        u32 hash_val;
 
-       write_lock_bh(&ntbl->rwlock);
-
        htbl = rcu_dereference_protected(ntbl->htbl,
-                                       lockdep_is_held(&ntbl->rwlock));
+                                       lockdep_is_held(&priv->lock));
        if (!htbl)
-               goto out_unlock;
+               return;
 
        hash_val = ipoib_addr_hash(htbl, neigh->daddr);
        np = &htbl->buckets[hash_val];
        for (n = rcu_dereference_protected(*np,
-                                           lockdep_is_held(&ntbl->rwlock));
+                                           lockdep_is_held(&priv->lock));
             n != NULL;
             n = rcu_dereference_protected(*np,
-                                       lockdep_is_held(&ntbl->rwlock))) {
+                                       lockdep_is_held(&priv->lock))) {
                if (n == neigh) {
                        /* found */
                        rcu_assign_pointer(*np,
                                           rcu_dereference_protected(neigh->hnext,
-                                                                    lockdep_is_held(&ntbl->rwlock)));
+                                                                    lockdep_is_held(&priv->lock)));
                        call_rcu(&neigh->rcu, ipoib_neigh_reclaim);
-                       goto out_unlock;
+                       return;
                } else {
                        np = &n->hnext;
                }
        }
-
-out_unlock:
-       write_unlock_bh(&ntbl->rwlock);
-
 }
 
 static int ipoib_neigh_hash_init(struct ipoib_dev_priv *priv)
@@ -1080,7 +1069,6 @@ static int ipoib_neigh_hash_init(struct ipoib_dev_priv *priv)
 
        clear_bit(IPOIB_NEIGH_TBL_FLUSH, &priv->flags);
        ntbl->htbl = NULL;
-       rwlock_init(&ntbl->rwlock);
        htbl = kzalloc(sizeof(*htbl), GFP_KERNEL);
        if (!htbl)
                return -ENOMEM;
@@ -1095,6 +1083,7 @@ static int ipoib_neigh_hash_init(struct ipoib_dev_priv *priv)
        htbl->mask = (size - 1);
        htbl->buckets = buckets;
        ntbl->htbl = htbl;
+       htbl->ntbl = ntbl;
        atomic_set(&ntbl->entries, 0);
 
        /* start garbage collection */
@@ -1111,9 +1100,11 @@ static void neigh_hash_free_rcu(struct rcu_head *head)
                                                    struct ipoib_neigh_hash,
                                                    rcu);
        struct ipoib_neigh __rcu **buckets = htbl->buckets;
+       struct ipoib_neigh_table *ntbl = htbl->ntbl;
 
        kfree(buckets);
        kfree(htbl);
+       complete(&ntbl->deleted);
 }
 
 void ipoib_del_neighs_by_gid(struct net_device *dev, u8 *gid)
@@ -1125,10 +1116,10 @@ void ipoib_del_neighs_by_gid(struct net_device *dev, u8 *gid)
        int i;
 
        /* remove all neigh connected to a given path or mcast */
-       write_lock_bh(&ntbl->rwlock);
+       spin_lock_irqsave(&priv->lock, flags);
 
        htbl = rcu_dereference_protected(ntbl->htbl,
-                                        lockdep_is_held(&ntbl->rwlock));
+                                        lockdep_is_held(&priv->lock));
 
        if (!htbl)
                goto out_unlock;
@@ -1138,16 +1129,14 @@ void ipoib_del_neighs_by_gid(struct net_device *dev, u8 *gid)
                struct ipoib_neigh __rcu **np = &htbl->buckets[i];
 
                while ((neigh = rcu_dereference_protected(*np,
-                                                         lockdep_is_held(&ntbl->rwlock))) != NULL) {
+                                                         lockdep_is_held(&priv->lock))) != NULL) {
                        /* delete neighs belong to this parent */
                        if (!memcmp(gid, neigh->daddr + 4, sizeof (union ib_gid))) {
                                rcu_assign_pointer(*np,
                                                   rcu_dereference_protected(neigh->hnext,
-                                                                            lockdep_is_held(&ntbl->rwlock)));
+                                                                            lockdep_is_held(&priv->lock)));
                                /* remove from parent list */
-                               spin_lock_irqsave(&priv->lock, flags);
                                list_del(&neigh->list);
-                               spin_unlock_irqrestore(&priv->lock, flags);
                                call_rcu(&neigh->rcu, ipoib_neigh_reclaim);
                        } else {
                                np = &neigh->hnext;
@@ -1156,7 +1145,7 @@ void ipoib_del_neighs_by_gid(struct net_device *dev, u8 *gid)
                }
        }
 out_unlock:
-       write_unlock_bh(&ntbl->rwlock);
+       spin_unlock_irqrestore(&priv->lock, flags);
 }
 
 static void ipoib_flush_neighs(struct ipoib_dev_priv *priv)
@@ -1164,37 +1153,44 @@ static void ipoib_flush_neighs(struct ipoib_dev_priv *priv)
        struct ipoib_neigh_table *ntbl = &priv->ntbl;
        struct ipoib_neigh_hash *htbl;
        unsigned long flags;
-       int i;
+       int i, wait_flushed = 0;
 
-       write_lock_bh(&ntbl->rwlock);
+       init_completion(&priv->ntbl.flushed);
+
+       spin_lock_irqsave(&priv->lock, flags);
 
        htbl = rcu_dereference_protected(ntbl->htbl,
-                                       lockdep_is_held(&ntbl->rwlock));
+                                       lockdep_is_held(&priv->lock));
        if (!htbl)
                goto out_unlock;
 
+       wait_flushed = atomic_read(&priv->ntbl.entries);
+       if (!wait_flushed)
+               goto free_htbl;
+
        for (i = 0; i < htbl->size; i++) {
                struct ipoib_neigh *neigh;
                struct ipoib_neigh __rcu **np = &htbl->buckets[i];
 
                while ((neigh = rcu_dereference_protected(*np,
-                                                         lockdep_is_held(&ntbl->rwlock))) != NULL) {
+                                      lockdep_is_held(&priv->lock))) != NULL) {
                        rcu_assign_pointer(*np,
                                           rcu_dereference_protected(neigh->hnext,
-                                                                    lockdep_is_held(&ntbl->rwlock)));
+                                                                    lockdep_is_held(&priv->lock)));
                        /* remove from path/mc list */
-                       spin_lock_irqsave(&priv->lock, flags);
                        list_del(&neigh->list);
-                       spin_unlock_irqrestore(&priv->lock, flags);
                        call_rcu(&neigh->rcu, ipoib_neigh_reclaim);
                }
        }
 
+free_htbl:
        rcu_assign_pointer(ntbl->htbl, NULL);
        call_rcu(&htbl->rcu, neigh_hash_free_rcu);
 
 out_unlock:
-       write_unlock_bh(&ntbl->rwlock);
+       spin_unlock_irqrestore(&priv->lock, flags);
+       if (wait_flushed)
+               wait_for_completion(&priv->ntbl.flushed);
 }
 
 static void ipoib_neigh_hash_uninit(struct net_device *dev)
@@ -1203,7 +1199,7 @@ static void ipoib_neigh_hash_uninit(struct net_device *dev)
        int stopped;
 
        ipoib_dbg(priv, "ipoib_neigh_hash_uninit\n");
-       init_completion(&priv->ntbl.flushed);
+       init_completion(&priv->ntbl.deleted);
        set_bit(IPOIB_NEIGH_TBL_FLUSH, &priv->flags);
 
        /* Stop GC if called at init fail need to cancel work */
@@ -1211,10 +1207,9 @@ static void ipoib_neigh_hash_uninit(struct net_device *dev)
        if (!stopped)
                cancel_delayed_work(&priv->neigh_reap_task);
 
-       if (atomic_read(&priv->ntbl.entries)) {
-               ipoib_flush_neighs(priv);
-               wait_for_completion(&priv->ntbl.flushed);
-       }
+       ipoib_flush_neighs(priv);
+
+       wait_for_completion(&priv->ntbl.deleted);
 }
 
 
index 13f4aa7..7536724 100644 (file)
@@ -707,9 +707,7 @@ out:
                neigh = ipoib_neigh_get(dev, daddr);
                spin_lock_irqsave(&priv->lock, flags);
                if (!neigh) {
-                       spin_unlock_irqrestore(&priv->lock, flags);
                        neigh = ipoib_neigh_alloc(daddr, dev);
-                       spin_lock_irqsave(&priv->lock, flags);
                        if (neigh) {
                                kref_get(&mcast->ah->ref);
                                neigh->ah       = mcast->ah;
index ce68e36..cdc2526 100644 (file)
@@ -516,9 +516,9 @@ static int __devinit imx_keypad_probe(struct platform_device *pdev)
        input_set_drvdata(input_dev, keypad);
 
        /* Ensure that the keypad will stay dormant until opened */
-       clk_enable(keypad->clk);
+       clk_prepare_enable(keypad->clk);
        imx_keypad_inhibit(keypad);
-       clk_disable(keypad->clk);
+       clk_disable_unprepare(keypad->clk);
 
        error = request_irq(irq, imx_keypad_irq_handler, 0,
                            pdev->name, keypad);
index f06231b..84ec691 100644 (file)
@@ -74,8 +74,8 @@ static int __devinit ab8500_ponkey_probe(struct platform_device *pdev)
 
        ponkey->idev = input;
        ponkey->ab8500 = ab8500;
-       ponkey->irq_dbf = ab8500_irq_get_virq(ab8500, irq_dbf);
-       ponkey->irq_dbr = ab8500_irq_get_virq(ab8500, irq_dbr);
+       ponkey->irq_dbf = irq_dbf;
+       ponkey->irq_dbr = irq_dbr;
 
        input->name = "AB8500 POn(PowerOn) Key";
        input->dev.parent = &pdev->dev;
index 3f5649f..a261d85 100644 (file)
@@ -721,6 +721,17 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
 
        switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) {
        case FSP_PKT_TYPE_ABS:
+
+               if ((packet[0] == 0x48 || packet[0] == 0x49) &&
+                   packet[1] == 0 && packet[2] == 0) {
+                       /*
+                        * Ignore coordinate noise when finger leaving the
+                        * surface, otherwise cursor may jump to upper-left
+                        * corner.
+                        */
+                       packet[3] &= 0xf0;
+               }
+
                abs_x = GET_ABS_X(packet);
                abs_y = GET_ABS_Y(packet);
 
index 2ffd110..2e77246 100644 (file)
@@ -72,7 +72,7 @@ static int amba_kmi_open(struct serio *io)
        unsigned int divisor;
        int ret;
 
-       ret = clk_enable(kmi->clk);
+       ret = clk_prepare_enable(kmi->clk);
        if (ret)
                goto out;
 
@@ -92,7 +92,7 @@ static int amba_kmi_open(struct serio *io)
        return 0;
 
  clk_disable:
-       clk_disable(kmi->clk);
+       clk_disable_unprepare(kmi->clk);
  out:
        return ret;
 }
@@ -104,7 +104,7 @@ static void amba_kmi_close(struct serio *io)
        writeb(0, KMICR);
 
        free_irq(kmi->irq, kmi);
-       clk_disable(kmi->clk);
+       clk_disable_unprepare(kmi->clk);
 }
 
 static int __devinit amba_kmi_probe(struct amba_device *dev,
index 6918773..d6cc77a 100644 (file)
@@ -333,6 +333,12 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"),
                },
        },
+       {
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE C850D"),
+               },
+       },
        {
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"),
index b06a5e3..6495777 100644 (file)
@@ -566,9 +566,12 @@ static ssize_t edt_ft5x06_debugfs_raw_data_read(struct file *file,
        }
 
        read = min_t(size_t, count, tsdata->raw_bufsize - *off);
-       error = copy_to_user(buf, tsdata->raw_buffer + *off, read);
-       if (!error)
-               *off += read;
+       if (copy_to_user(buf, tsdata->raw_buffer + *off, read)) {
+               error = -EFAULT;
+               goto out;
+       }
+
+       *off += read;
 out:
        mutex_unlock(&tsdata->mutex);
        return error ?: read;
index e32709e..721fdb3 100644 (file)
@@ -304,6 +304,45 @@ static int e2i_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
 #define EGALAX_PKT_TYPE_REPT           0x80
 #define EGALAX_PKT_TYPE_DIAG           0x0A
 
+static int egalax_init(struct usbtouch_usb *usbtouch)
+{
+       int ret, i;
+       unsigned char *buf;
+       struct usb_device *udev = interface_to_usbdev(usbtouch->interface);
+
+       /*
+        * An eGalax diagnostic packet kicks the device into using the right
+        * protocol.  We send a "check active" packet.  The response will be
+        * read later and ignored.
+        */
+
+       buf = kmalloc(3, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       buf[0] = EGALAX_PKT_TYPE_DIAG;
+       buf[1] = 1;     /* length */
+       buf[2] = 'A';   /* command - check active */
+
+       for (i = 0; i < 3; i++) {
+               ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+                                     0,
+                                     USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                                     0, 0, buf, 3,
+                                     USB_CTRL_SET_TIMEOUT);
+               if (ret >= 0) {
+                       ret = 0;
+                       break;
+               }
+               if (ret != -EPIPE)
+                       break;
+       }
+
+       kfree(buf);
+
+       return ret;
+}
+
 static int egalax_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
 {
        if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT)
@@ -1056,6 +1095,7 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
                .process_pkt    = usbtouch_process_multi,
                .get_pkt_len    = egalax_get_pkt_len,
                .read_data      = egalax_read_data,
+               .init           = egalax_init,
        },
 #endif
 
index 3f6203a..308e87b 100644 (file)
@@ -7619,6 +7619,8 @@ static int remove_and_add_spares(struct mddev *mddev)
                        }
                }
        }
+       if (removed)
+               set_bit(MD_CHANGE_DEVS, &mddev->flags);
        return spares;
 }
 
@@ -7632,9 +7634,11 @@ static void reap_sync_thread(struct mddev *mddev)
            !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
                /* success...*/
                /* activate any spares */
-               if (mddev->pers->spare_active(mddev))
+               if (mddev->pers->spare_active(mddev)) {
                        sysfs_notify(&mddev->kobj, NULL,
                                     "degraded");
+                       set_bit(MD_CHANGE_DEVS, &mddev->flags);
+               }
        }
        if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
            mddev->pers->finish_reshape)
index adda94d..7031b86 100644 (file)
@@ -393,6 +393,8 @@ static int calc_degraded(struct r5conf *conf)
        degraded = 0;
        for (i = 0; i < conf->previous_raid_disks; i++) {
                struct md_rdev *rdev = rcu_dereference(conf->disks[i].rdev);
+               if (rdev && test_bit(Faulty, &rdev->flags))
+                       rdev = rcu_dereference(conf->disks[i].replacement);
                if (!rdev || test_bit(Faulty, &rdev->flags))
                        degraded++;
                else if (test_bit(In_sync, &rdev->flags))
@@ -417,6 +419,8 @@ static int calc_degraded(struct r5conf *conf)
        degraded2 = 0;
        for (i = 0; i < conf->raid_disks; i++) {
                struct md_rdev *rdev = rcu_dereference(conf->disks[i].rdev);
+               if (rdev && test_bit(Faulty, &rdev->flags))
+                       rdev = rcu_dereference(conf->disks[i].replacement);
                if (!rdev || test_bit(Faulty, &rdev->flags))
                        degraded2++;
                else if (test_bit(In_sync, &rdev->flags))
@@ -4192,7 +4196,7 @@ static void make_request(struct mddev *mddev, struct bio * bi)
                        finish_wait(&conf->wait_for_overlap, &w);
                        set_bit(STRIPE_HANDLE, &sh->state);
                        clear_bit(STRIPE_DELAYED, &sh->state);
-                       if ((bi->bi_rw & REQ_NOIDLE) &&
+                       if ((bi->bi_rw & REQ_SYNC) &&
                            !test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state))
                                atomic_inc(&conf->preread_active_stripes);
                        release_stripe_plug(mddev, sh);
index b67a301..ce229ea 100644 (file)
@@ -470,7 +470,8 @@ static int __devinit device_800_init(struct pm80x_chip *chip,
 
        ret =
            mfd_add_devices(chip->dev, 0, &onkey_devs[0],
-                           ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0);
+                           ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0,
+                           NULL);
        if (ret < 0) {
                dev_err(chip->dev, "Failed to add onkey subdev\n");
                goto out_dev;
@@ -481,7 +482,7 @@ static int __devinit device_800_init(struct pm80x_chip *chip,
                rtc_devs[0].platform_data = pdata->rtc;
                rtc_devs[0].pdata_size = sizeof(struct pm80x_rtc_pdata);
                ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],
-                                     ARRAY_SIZE(rtc_devs), NULL, 0);
+                                     ARRAY_SIZE(rtc_devs), NULL, 0, NULL);
                if (ret < 0) {
                        dev_err(chip->dev, "Failed to add rtc subdev\n");
                        goto out_dev;
index 6146583..c20a311 100644 (file)
@@ -216,7 +216,8 @@ static int __devinit device_805_init(struct pm80x_chip *chip)
        }
 
        ret = mfd_add_devices(chip->dev, 0, &codec_devs[0],
-                             ARRAY_SIZE(codec_devs), &codec_resources[0], 0);
+                             ARRAY_SIZE(codec_devs), &codec_resources[0], 0,
+                             NULL);
        if (ret < 0) {
                dev_err(chip->dev, "Failed to add codec subdev\n");
                goto out_codec;
index d09918c..b73f033 100644 (file)
@@ -637,7 +637,7 @@ static void __devinit device_bk_init(struct pm860x_chip *chip,
                        bk_devs[i].resources = &bk_resources[j];
                        ret = mfd_add_devices(chip->dev, 0,
                                              &bk_devs[i], 1,
-                                             &bk_resources[j], 0);
+                                             &bk_resources[j], 0, NULL);
                        if (ret < 0) {
                                dev_err(chip->dev, "Failed to add "
                                        "backlight subdev\n");
@@ -672,7 +672,7 @@ static void __devinit device_led_init(struct pm860x_chip *chip,
                        led_devs[i].resources = &led_resources[j],
                        ret = mfd_add_devices(chip->dev, 0,
                                              &led_devs[i], 1,
-                                             &led_resources[j], 0);
+                                             &led_resources[j], 0, NULL);
                        if (ret < 0) {
                                dev_err(chip->dev, "Failed to add "
                                        "led subdev\n");
@@ -709,7 +709,7 @@ static void __devinit device_regulator_init(struct pm860x_chip *chip,
                regulator_devs[i].resources = &regulator_resources[seq];
 
                ret = mfd_add_devices(chip->dev, 0, &regulator_devs[i], 1,
-                                     &regulator_resources[seq], 0);
+                                     &regulator_resources[seq], 0, NULL);
                if (ret < 0) {
                        dev_err(chip->dev, "Failed to add regulator subdev\n");
                        goto out;
@@ -733,7 +733,7 @@ static void __devinit device_rtc_init(struct pm860x_chip *chip,
        rtc_devs[0].resources = &rtc_resources[0];
        ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],
                              ARRAY_SIZE(rtc_devs), &rtc_resources[0],
-                             chip->irq_base);
+                             chip->irq_base, NULL);
        if (ret < 0)
                dev_err(chip->dev, "Failed to add rtc subdev\n");
 }
@@ -752,7 +752,7 @@ static void __devinit device_touch_init(struct pm860x_chip *chip,
        touch_devs[0].resources = &touch_resources[0];
        ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],
                              ARRAY_SIZE(touch_devs), &touch_resources[0],
-                             chip->irq_base);
+                             chip->irq_base, NULL);
        if (ret < 0)
                dev_err(chip->dev, "Failed to add touch subdev\n");
 }
@@ -770,7 +770,7 @@ static void __devinit device_power_init(struct pm860x_chip *chip,
        power_devs[0].num_resources = ARRAY_SIZE(battery_resources);
        power_devs[0].resources = &battery_resources[0],
        ret = mfd_add_devices(chip->dev, 0, &power_devs[0], 1,
-                             &battery_resources[0], chip->irq_base);
+                             &battery_resources[0], chip->irq_base, NULL);
        if (ret < 0)
                dev_err(chip->dev, "Failed to add battery subdev\n");
 
@@ -779,7 +779,7 @@ static void __devinit device_power_init(struct pm860x_chip *chip,
        power_devs[1].num_resources = ARRAY_SIZE(charger_resources);
        power_devs[1].resources = &charger_resources[0],
        ret = mfd_add_devices(chip->dev, 0, &power_devs[1], 1,
-                             &charger_resources[0], chip->irq_base);
+                             &charger_resources[0], chip->irq_base, NULL);
        if (ret < 0)
                dev_err(chip->dev, "Failed to add charger subdev\n");
 
@@ -788,7 +788,7 @@ static void __devinit device_power_init(struct pm860x_chip *chip,
        power_devs[2].num_resources = ARRAY_SIZE(preg_resources);
        power_devs[2].resources = &preg_resources[0],
        ret = mfd_add_devices(chip->dev, 0, &power_devs[2], 1,
-                             &preg_resources[0], chip->irq_base);
+                             &preg_resources[0], chip->irq_base, NULL);
        if (ret < 0)
                dev_err(chip->dev, "Failed to add preg subdev\n");
 }
@@ -802,7 +802,7 @@ static void __devinit device_onkey_init(struct pm860x_chip *chip,
        onkey_devs[0].resources = &onkey_resources[0],
        ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0],
                              ARRAY_SIZE(onkey_devs), &onkey_resources[0],
-                             chip->irq_base);
+                             chip->irq_base, NULL);
        if (ret < 0)
                dev_err(chip->dev, "Failed to add onkey subdev\n");
 }
@@ -815,7 +815,8 @@ static void __devinit device_codec_init(struct pm860x_chip *chip,
        codec_devs[0].num_resources = ARRAY_SIZE(codec_resources);
        codec_devs[0].resources = &codec_resources[0],
        ret = mfd_add_devices(chip->dev, 0, &codec_devs[0],
-                             ARRAY_SIZE(codec_devs), &codec_resources[0], 0);
+                             ARRAY_SIZE(codec_devs), &codec_resources[0], 0,
+                             NULL);
        if (ret < 0)
                dev_err(chip->dev, "Failed to add codec subdev\n");
 }
index 44a3fdb..f1beb49 100644 (file)
@@ -424,7 +424,7 @@ static int aat2870_i2c_probe(struct i2c_client *client,
        }
 
        ret = mfd_add_devices(aat2870->dev, 0, aat2870_devs,
-                             ARRAY_SIZE(aat2870_devs), NULL, 0);
+                             ARRAY_SIZE(aat2870_devs), NULL, 0, NULL);
        if (ret != 0) {
                dev_err(aat2870->dev, "Failed to add subdev: %d\n", ret);
                goto out_disable;
index 78fca29..01781ae 100644 (file)
@@ -946,7 +946,7 @@ static int __devinit ab3100_probe(struct i2c_client *client,
        }
 
        err = mfd_add_devices(&client->dev, 0, ab3100_devs,
-               ARRAY_SIZE(ab3100_devs), NULL, 0);
+                             ARRAY_SIZE(ab3100_devs), NULL, 0, NULL);
 
        ab3100_setup_debugfs(ab3100);
 
index 626b4ec..47adf80 100644 (file)
@@ -1418,25 +1418,25 @@ static int __devinit ab8500_probe(struct platform_device *pdev)
 
        ret = mfd_add_devices(ab8500->dev, 0, abx500_common_devs,
                        ARRAY_SIZE(abx500_common_devs), NULL,
-                       ab8500->irq_base);
+                       ab8500->irq_base, ab8500->domain);
        if (ret)
                goto out_freeirq;
 
        if (is_ab9540(ab8500))
                ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs,
                                ARRAY_SIZE(ab9540_devs), NULL,
-                               ab8500->irq_base);
+                               ab8500->irq_base, ab8500->domain);
        else
                ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs,
                                ARRAY_SIZE(ab8500_devs), NULL,
-                               ab8500->irq_base);
+                               ab8500->irq_base, ab8500->domain);
        if (ret)
                goto out_freeirq;
 
        if (is_ab9540(ab8500) || is_ab8505(ab8500))
                ret = mfd_add_devices(ab8500->dev, 0, ab9540_ab8505_devs,
                                ARRAY_SIZE(ab9540_ab8505_devs), NULL,
-                               ab8500->irq_base);
+                               ab8500->irq_base, ab8500->domain);
        if (ret)
                goto out_freeirq;
 
@@ -1444,7 +1444,7 @@ static int __devinit ab8500_probe(struct platform_device *pdev)
                /* Add battery management devices */
                ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs,
                                      ARRAY_SIZE(ab8500_bm_devs), NULL,
-                                     ab8500->irq_base);
+                                     ab8500->irq_base, ab8500->domain);
                if (ret)
                        dev_err(ab8500->dev, "error adding bm devices\n");
        }
index c7983e8..1b48f20 100644 (file)
@@ -316,7 +316,7 @@ int __devinit arizona_dev_init(struct arizona *arizona)
        }
 
        ret = mfd_add_devices(arizona->dev, -1, early_devs,
-                             ARRAY_SIZE(early_devs), NULL, 0);
+                             ARRAY_SIZE(early_devs), NULL, 0, NULL);
        if (ret != 0) {
                dev_err(dev, "Failed to add early children: %d\n", ret);
                return ret;
@@ -516,11 +516,11 @@ int __devinit arizona_dev_init(struct arizona *arizona)
        switch (arizona->type) {
        case WM5102:
                ret = mfd_add_devices(arizona->dev, -1, wm5102_devs,
-                                     ARRAY_SIZE(wm5102_devs), NULL, 0);
+                                     ARRAY_SIZE(wm5102_devs), NULL, 0, NULL);
                break;
        case WM5110:
                ret = mfd_add_devices(arizona->dev, -1, wm5110_devs,
-                                     ARRAY_SIZE(wm5102_devs), NULL, 0);
+                                     ARRAY_SIZE(wm5102_devs), NULL, 0, NULL);
                break;
        }
 
index 683e18a..62f0883 100644 (file)
@@ -913,14 +913,14 @@ static int __init asic3_mfd_probe(struct platform_device *pdev,
        if (pdata->clock_rate) {
                ds1wm_pdata.clock_rate = pdata->clock_rate;
                ret = mfd_add_devices(&pdev->dev, pdev->id,
-                       &asic3_cell_ds1wm, 1, mem, asic->irq_base);
+                       &asic3_cell_ds1wm, 1, mem, asic->irq_base, NULL);
                if (ret < 0)
                        goto out;
        }
 
        if (mem_sdio && (irq >= 0)) {
                ret = mfd_add_devices(&pdev->dev, pdev->id,
-                       &asic3_cell_mmc, 1, mem_sdio, irq);
+                       &asic3_cell_mmc, 1, mem_sdio, irq, NULL);
                if (ret < 0)
                        goto out;
        }
@@ -934,7 +934,7 @@ static int __init asic3_mfd_probe(struct platform_device *pdev,
                        asic3_cell_leds[i].pdata_size = sizeof(pdata->leds[i]);
                }
                ret = mfd_add_devices(&pdev->dev, 0,
-                       asic3_cell_leds, ASIC3_NUM_LEDS, NULL, 0);
+                       asic3_cell_leds, ASIC3_NUM_LEDS, NULL, 0, NULL);
        }
 
  out:
index 3419e72..2b28213 100644 (file)
@@ -149,7 +149,7 @@ static int __devinit cs5535_mfd_probe(struct pci_dev *pdev,
        }
 
        err = mfd_add_devices(&pdev->dev, -1, cs5535_mfd_cells,
-                       ARRAY_SIZE(cs5535_mfd_cells), NULL, 0);
+                             ARRAY_SIZE(cs5535_mfd_cells), NULL, 0, NULL);
        if (err) {
                dev_err(&pdev->dev, "MFD add devices failed: %d\n", err);
                goto err_disable;
index 2544910..a0a62b2 100644 (file)
@@ -803,7 +803,7 @@ int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id)
                dev_err(da9052->dev, "DA9052 ADC IRQ failed ret=%d\n", ret);
 
        ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info,
-                             ARRAY_SIZE(da9052_subdev_info), NULL, 0);
+                             ARRAY_SIZE(da9052_subdev_info), NULL, 0, NULL);
        if (ret)
                goto err;
 
index 4e2af2c..45e83a6 100644 (file)
@@ -129,7 +129,7 @@ static int __init davinci_vc_probe(struct platform_device *pdev)
        cell->pdata_size = sizeof(*davinci_vc);
 
        ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells,
-                             DAVINCI_VC_CELLS, NULL, 0);
+                             DAVINCI_VC_CELLS, NULL, 0, NULL);
        if (ret != 0) {
                dev_err(&pdev->dev, "fail to register client devices\n");
                goto fail4;
index 7040a00..0e63cdd 100644 (file)
@@ -3010,7 +3010,7 @@ static int __devinit db8500_prcmu_probe(struct platform_device *pdev)
                prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET);
 
        err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs,
-                       ARRAY_SIZE(db8500_prcmu_devs), NULL, 0);
+                             ARRAY_SIZE(db8500_prcmu_devs), NULL, 0, NULL);
        if (err) {
                pr_err("prcmu: Failed to add subdevices\n");
                return err;
index 04c7093..9e5453d 100644 (file)
@@ -168,7 +168,7 @@ static int __init pasic3_probe(struct platform_device *pdev)
                /* the first 5 PASIC3 registers control the DS1WM */
                ds1wm_resources[0].end = (5 << asic->bus_shift) - 1;
                ret = mfd_add_devices(&pdev->dev, pdev->id,
-                               &ds1wm_cell, 1, r, irq);
+                                     &ds1wm_cell, 1, r, irq, NULL);
                if (ret < 0)
                        dev_warn(dev, "failed to register DS1WM\n");
        }
@@ -176,7 +176,8 @@ static int __init pasic3_probe(struct platform_device *pdev)
        if (pdata && pdata->led_pdata) {
                led_cell.platform_data = pdata->led_pdata;
                led_cell.pdata_size = sizeof(struct pasic3_leds_machinfo);
-               ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, 0);
+               ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r,
+                                     0, NULL);
                if (ret < 0)
                        dev_warn(dev, "failed to register LED device\n");
        }
index 59df558..266bdc5 100644 (file)
@@ -344,13 +344,13 @@ static int __devinit intel_msic_init_devices(struct intel_msic *msic)
                        continue;
 
                ret = mfd_add_devices(&pdev->dev, -1, &msic_devs[i], 1, NULL,
-                                     pdata->irq[i]);
+                                     pdata->irq[i], NULL);
                if (ret)
                        goto fail;
        }
 
        ret = mfd_add_devices(&pdev->dev, 0, msic_other_devs,
-                             ARRAY_SIZE(msic_other_devs), NULL, 0);
+                             ARRAY_SIZE(msic_other_devs), NULL, 0, NULL);
        if (ret)
                goto fail;
 
index 2ea9998..965c480 100644 (file)
@@ -147,7 +147,7 @@ static int __devinit cmodio_probe_submodules(struct cmodio_device *priv)
        }
 
        return mfd_add_devices(&pdev->dev, 0, priv->cells,
-                              num_probed, NULL, pdev->irq);
+                              num_probed, NULL, pdev->irq, NULL);
 }
 
 /*
index 87662a1..c6b6d7d 100644 (file)
@@ -287,7 +287,8 @@ static int __devinit jz4740_adc_probe(struct platform_device *pdev)
        writeb(0xff, adc->base + JZ_REG_ADC_CTRL);
 
        ret = mfd_add_devices(&pdev->dev, 0, jz4740_adc_cells,
-               ARRAY_SIZE(jz4740_adc_cells), mem_base, irq_base);
+                             ARRAY_SIZE(jz4740_adc_cells), mem_base,
+                             irq_base, NULL);
        if (ret < 0)
                goto err_clk_put;
 
index 0b2879b..24212f4 100644 (file)
@@ -393,7 +393,8 @@ static int __devinit lm3533_device_als_init(struct lm3533 *lm3533)
        lm3533_als_devs[0].platform_data = pdata->als;
        lm3533_als_devs[0].pdata_size = sizeof(*pdata->als);
 
-       ret = mfd_add_devices(lm3533->dev, 0, lm3533_als_devs, 1, NULL, 0);
+       ret = mfd_add_devices(lm3533->dev, 0, lm3533_als_devs, 1, NULL,
+                             0, NULL);
        if (ret) {
                dev_err(lm3533->dev, "failed to add ALS device\n");
                return ret;
@@ -422,7 +423,7 @@ static int __devinit lm3533_device_bl_init(struct lm3533 *lm3533)
        }
 
        ret = mfd_add_devices(lm3533->dev, 0, lm3533_bl_devs,
-                                       pdata->num_backlights, NULL, 0);
+                             pdata->num_backlights, NULL, 0, NULL);
        if (ret) {
                dev_err(lm3533->dev, "failed to add backlight devices\n");
                return ret;
@@ -451,7 +452,7 @@ static int __devinit lm3533_device_led_init(struct lm3533 *lm3533)
        }
 
        ret = mfd_add_devices(lm3533->dev, 0, lm3533_led_devs,
-                                               pdata->num_leds, NULL, 0);
+                             pdata->num_leds, NULL, 0, NULL);
        if (ret) {
                dev_err(lm3533->dev, "failed to add LED devices\n");
                return ret;
index 027cc8f..092ad4b 100644 (file)
@@ -750,7 +750,7 @@ gpe0_done:
 
        lpc_ich_finalize_cell(&lpc_ich_cells[LPC_GPIO], id);
        ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_GPIO],
-                               1, NULL, 0);
+                             1, NULL, 0, NULL);
 
 gpio_done:
        if (acpi_conflict)
@@ -765,7 +765,6 @@ static int __devinit lpc_ich_init_wdt(struct pci_dev *dev,
        u32 base_addr_cfg;
        u32 base_addr;
        int ret;
-       bool acpi_conflict = false;
        struct resource *res;
 
        /* Setup power management base register */
@@ -780,20 +779,11 @@ static int __devinit lpc_ich_init_wdt(struct pci_dev *dev,
        res = wdt_io_res(ICH_RES_IO_TCO);
        res->start = base_addr + ACPIBASE_TCO_OFF;
        res->end = base_addr + ACPIBASE_TCO_END;
-       ret = acpi_check_resource_conflict(res);
-       if (ret) {
-               acpi_conflict = true;
-               goto wdt_done;
-       }
 
        res = wdt_io_res(ICH_RES_IO_SMI);
        res->start = base_addr + ACPIBASE_SMI_OFF;
        res->end = base_addr + ACPIBASE_SMI_END;
-       ret = acpi_check_resource_conflict(res);
-       if (ret) {
-               acpi_conflict = true;
-               goto wdt_done;
-       }
+
        lpc_ich_enable_acpi_space(dev);
 
        /*
@@ -813,21 +803,13 @@ static int __devinit lpc_ich_init_wdt(struct pci_dev *dev,
                res = wdt_mem_res(ICH_RES_MEM_GCS);
                res->start = base_addr + ACPIBASE_GCS_OFF;
                res->end = base_addr + ACPIBASE_GCS_END;
-               ret = acpi_check_resource_conflict(res);
-               if (ret) {
-                       acpi_conflict = true;
-                       goto wdt_done;
-               }
        }
 
        lpc_ich_finalize_cell(&lpc_ich_cells[LPC_WDT], id);
        ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_WDT],
-                               1, NULL, 0);
+                             1, NULL, 0, NULL);
 
 wdt_done:
-       if (acpi_conflict)
-               pr_warn("Resource conflict(s) found affecting %s\n",
-                               lpc_ich_cells[LPC_WDT].name);
        return ret;
 }
 
index 9f20abc..f6b9c5c 100644 (file)
@@ -127,7 +127,8 @@ static int __devinit lpc_sch_probe(struct pci_dev *dev,
                lpc_sch_cells[i].id = id->device;
 
        ret = mfd_add_devices(&dev->dev, 0,
-                       lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, 0);
+                             lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL,
+                             0, NULL);
        if (ret)
                goto out_dev;
 
@@ -153,7 +154,8 @@ static int __devinit lpc_sch_probe(struct pci_dev *dev,
                        tunnelcreek_cells[i].id = id->device;
 
                ret = mfd_add_devices(&dev->dev, 0, tunnelcreek_cells,
-                       ARRAY_SIZE(tunnelcreek_cells), NULL, 0);
+                                     ARRAY_SIZE(tunnelcreek_cells), NULL,
+                                     0, NULL);
        }
 
        return ret;
index c03e12b..d9e24c8 100644 (file)
@@ -126,7 +126,7 @@ static int max77686_i2c_probe(struct i2c_client *i2c,
        max77686_irq_init(max77686);
 
        ret = mfd_add_devices(max77686->dev, -1, max77686_devs,
-                             ARRAY_SIZE(max77686_devs), NULL, 0);
+                             ARRAY_SIZE(max77686_devs), NULL, 0, NULL);
 
        if (ret < 0)
                goto err_mfd;
index 2b40356..1029d01 100644 (file)
@@ -137,6 +137,9 @@ static void max77693_irq_mask(struct irq_data *data)
        const struct max77693_irq_data *irq_data =
                                irq_to_max77693_irq(max77693, data->irq);
 
+       if (irq_data->group >= MAX77693_IRQ_GROUP_NR)
+               return;
+
        if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3)
                max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask;
        else
@@ -149,6 +152,9 @@ static void max77693_irq_unmask(struct irq_data *data)
        const struct max77693_irq_data *irq_data =
            irq_to_max77693_irq(max77693, data->irq);
 
+       if (irq_data->group >= MAX77693_IRQ_GROUP_NR)
+               return;
+
        if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3)
                max77693->irq_masks_cur[irq_data->group] |= irq_data->mask;
        else
@@ -200,7 +206,7 @@ static irqreturn_t max77693_irq_thread(int irq, void *data)
 
        if (irq_src & MAX77693_IRQSRC_MUIC)
                /* MUIC INT1 ~ INT3 */
-               max77693_bulk_read(max77693->regmap, MAX77693_MUIC_REG_INT1,
+               max77693_bulk_read(max77693->regmap_muic, MAX77693_MUIC_REG_INT1,
                        MAX77693_NUM_IRQ_MUIC_REGS, &irq_reg[MUIC_INT1]);
 
        /* Apply masking */
@@ -255,7 +261,8 @@ int max77693_irq_init(struct max77693_dev *max77693)
 {
        struct irq_domain *domain;
        int i;
-       int ret;
+       int ret = 0;
+       u8 intsrc_mask;
 
        mutex_init(&max77693->irqlock);
 
@@ -287,19 +294,38 @@ int max77693_irq_init(struct max77693_dev *max77693)
                                        &max77693_irq_domain_ops, max77693);
        if (!domain) {
                dev_err(max77693->dev, "could not create irq domain\n");
-               return -ENODEV;
+               ret = -ENODEV;
+               goto err_irq;
        }
        max77693->irq_domain = domain;
 
+       /* Unmask max77693 interrupt */
+       ret = max77693_read_reg(max77693->regmap,
+                       MAX77693_PMIC_REG_INTSRC_MASK, &intsrc_mask);
+       if (ret < 0) {
+               dev_err(max77693->dev, "fail to read PMIC register\n");
+               goto err_irq;
+       }
+
+       intsrc_mask &= ~(MAX77693_IRQSRC_CHG);
+       intsrc_mask &= ~(MAX77693_IRQSRC_FLASH);
+       intsrc_mask &= ~(MAX77693_IRQSRC_MUIC);
+       ret = max77693_write_reg(max77693->regmap,
+                       MAX77693_PMIC_REG_INTSRC_MASK, intsrc_mask);
+       if (ret < 0) {
+               dev_err(max77693->dev, "fail to write PMIC register\n");
+               goto err_irq;
+       }
+
        ret = request_threaded_irq(max77693->irq, NULL, max77693_irq_thread,
                                   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
                                   "max77693-irq", max77693);
-
        if (ret)
                dev_err(max77693->dev, "Failed to request IRQ %d: %d\n",
                        max77693->irq, ret);
 
-       return 0;
+err_irq:
+       return ret;
 }
 
 void max77693_irq_exit(struct max77693_dev *max77693)
index a1811cb..cc5155e 100644 (file)
@@ -152,6 +152,20 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
        max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC);
        i2c_set_clientdata(max77693->haptic, max77693);
 
+       /*
+        * Initialize register map for MUIC device because use regmap-muic
+        * instance of MUIC device when irq of max77693 is initialized
+        * before call max77693-muic probe() function.
+        */
+       max77693->regmap_muic = devm_regmap_init_i2c(max77693->muic,
+                                        &max77693_regmap_config);
+       if (IS_ERR(max77693->regmap_muic)) {
+               ret = PTR_ERR(max77693->regmap_muic);
+               dev_err(max77693->dev,
+                       "failed to allocate register map: %d\n", ret);
+               goto err_regmap;
+       }
+
        ret = max77693_irq_init(max77693);
        if (ret < 0)
                goto err_irq;
@@ -159,7 +173,7 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
        pm_runtime_set_active(max77693->dev);
 
        ret = mfd_add_devices(max77693->dev, -1, max77693_devs,
-                       ARRAY_SIZE(max77693_devs), NULL, 0);
+                             ARRAY_SIZE(max77693_devs), NULL, 0, NULL);
        if (ret < 0)
                goto err_mfd;
 
index 825a7f0..ee53757 100644 (file)
@@ -598,7 +598,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip,
 
        ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],
                              ARRAY_SIZE(rtc_devs),
-                             &rtc_resources[0], chip->irq_base);
+                             &rtc_resources[0], chip->irq_base, NULL);
        if (ret < 0) {
                dev_err(chip->dev, "Failed to add rtc subdev\n");
                goto out;
@@ -606,7 +606,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip,
 
        ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0],
                              ARRAY_SIZE(onkey_devs),
-                             &onkey_resources[0], 0);
+                             &onkey_resources[0], 0, NULL);
        if (ret < 0) {
                dev_err(chip->dev, "Failed to add onkey subdev\n");
                goto out_dev;
@@ -615,7 +615,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip,
        if (pdata) {
                ret = mfd_add_devices(chip->dev, 0, &regulator_devs[0],
                                      ARRAY_SIZE(regulator_devs),
-                                     &regulator_resources[0], 0);
+                                     &regulator_resources[0], 0, NULL);
                if (ret < 0) {
                        dev_err(chip->dev, "Failed to add regulator subdev\n");
                        goto out_dev;
@@ -625,7 +625,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip,
        if (pdata && pdata->backlight) {
                ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0],
                                      ARRAY_SIZE(backlight_devs),
-                                     &backlight_resources[0], 0);
+                                     &backlight_resources[0], 0, NULL);
                if (ret < 0) {
                        dev_err(chip->dev, "Failed to add backlight subdev\n");
                        goto out_dev;
@@ -635,7 +635,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip,
        if (pdata && pdata->power) {
                ret = mfd_add_devices(chip->dev, 0, &power_devs[0],
                                        ARRAY_SIZE(power_devs),
-                                       &power_supply_resources[0], 0);
+                                     &power_supply_resources[0], 0, NULL);
                if (ret < 0) {
                        dev_err(chip->dev, "Failed to add power supply "
                                "subdev\n");
@@ -646,7 +646,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip,
        if (pdata && pdata->touch) {
                ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],
                                      ARRAY_SIZE(touch_devs),
-                                     &touch_resources[0], 0);
+                                     &touch_resources[0], 0, NULL);
                if (ret < 0) {
                        dev_err(chip->dev, "Failed to add touch subdev\n");
                        goto out_dev;
index 10b629c..f123517 100644 (file)
@@ -160,7 +160,7 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
 
        mfd_add_devices(max8997->dev, -1, max8997_devs,
                        ARRAY_SIZE(max8997_devs),
-                       NULL, 0);
+                       NULL, 0, NULL);
 
        /*
         * TODO: enable others (flash, muic, rtc, battery, ...) and
index 6ef56d2..d7218cc 100644 (file)
@@ -161,13 +161,13 @@ static int max8998_i2c_probe(struct i2c_client *i2c,
        switch (id->driver_data) {
        case TYPE_LP3974:
                ret = mfd_add_devices(max8998->dev, -1,
-                               lp3974_devs, ARRAY_SIZE(lp3974_devs),
-                               NULL, 0);
+                                     lp3974_devs, ARRAY_SIZE(lp3974_devs),
+                                     NULL, 0, NULL);
                break;
        case TYPE_MAX8998:
                ret = mfd_add_devices(max8998->dev, -1,
-                               max8998_devs, ARRAY_SIZE(max8998_devs),
-                               NULL, 0);
+                                     max8998_devs, ARRAY_SIZE(max8998_devs),
+                                     NULL, 0, NULL);
                break;
        default:
                ret = -EINVAL;
index b801dc7..1ec79b5 100644 (file)
@@ -612,7 +612,7 @@ static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx,
        if (!cell.name)
                return -ENOMEM;
 
-       return mfd_add_devices(mc13xxx->dev, -1, &cell, 1, NULL, 0);
+       return mfd_add_devices(mc13xxx->dev, -1, &cell, 1, NULL, 0, NULL);
 }
 
 static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format)
index 0c3a01c..f8b7771 100644 (file)
@@ -74,12 +74,11 @@ static int mfd_platform_add_cell(struct platform_device *pdev,
 static int mfd_add_device(struct device *parent, int id,
                          const struct mfd_cell *cell,
                          struct resource *mem_base,
-                         int irq_base)
+                         int irq_base, struct irq_domain *domain)
 {
        struct resource *res;
        struct platform_device *pdev;
        struct device_node *np = NULL;
-       struct irq_domain *domain = NULL;
        int ret = -ENOMEM;
        int r;
 
@@ -97,7 +96,6 @@ static int mfd_add_device(struct device *parent, int id,
                for_each_child_of_node(parent->of_node, np) {
                        if (of_device_is_compatible(np, cell->of_compatible)) {
                                pdev->dev.of_node = np;
-                               domain = irq_find_host(parent->of_node);
                                break;
                        }
                }
@@ -177,7 +175,7 @@ fail_alloc:
 int mfd_add_devices(struct device *parent, int id,
                    struct mfd_cell *cells, int n_devs,
                    struct resource *mem_base,
-                   int irq_base)
+                   int irq_base, struct irq_domain *domain)
 {
        int i;
        int ret = 0;
@@ -191,7 +189,8 @@ int mfd_add_devices(struct device *parent, int id,
        for (i = 0; i < n_devs; i++) {
                atomic_set(&cnts[i], 0);
                cells[i].usage_count = &cnts[i];
-               ret = mfd_add_device(parent, id, cells + i, mem_base, irq_base);
+               ret = mfd_add_device(parent, id, cells + i, mem_base,
+                                    irq_base, domain);
                if (ret)
                        break;
        }
@@ -247,7 +246,8 @@ int mfd_clone_cell(const char *cell, const char **clones, size_t n_clones)
        for (i = 0; i < n_clones; i++) {
                cell_entry.name = clones[i];
                /* don't give up if a single call fails; just report error */
-               if (mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0))
+               if (mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0,
+                                  NULL))
                        dev_err(dev, "failed to create platform device '%s'\n",
                                        clones[i]);
        }
index c4a69f1..a345f9b 100644 (file)
@@ -453,7 +453,8 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
 
        ret = mfd_add_devices(palmas->dev, -1,
                              children, ARRAY_SIZE(palmas_children),
-                             NULL, regmap_irq_chip_get_base(palmas->irq_data));
+                             NULL, regmap_irq_chip_get_base(palmas->irq_data),
+                             NULL);
        kfree(children);
 
        if (ret < 0)
index cdc1df7..3a8fa88 100644 (file)
@@ -289,7 +289,7 @@ static int __devinit rc5t583_i2c_probe(struct i2c_client *i2c,
        }
 
        ret = mfd_add_devices(rc5t583->dev, -1, rc5t583_subdevs,
-                       ARRAY_SIZE(rc5t583_subdevs), NULL, 0);
+                             ARRAY_SIZE(rc5t583_subdevs), NULL, 0, NULL);
        if (ret) {
                dev_err(&i2c->dev, "add mfd devices failed: %d\n", ret);
                goto err_add_devs;
index 685d61e..0f70dce 100644 (file)
@@ -87,7 +87,8 @@ static int __devinit rdc321x_sb_probe(struct pci_dev *pdev,
        rdc321x_wdt_pdata.sb_pdev = pdev;
 
        return mfd_add_devices(&pdev->dev, -1,
-               rdc321x_sb_cells, ARRAY_SIZE(rdc321x_sb_cells), NULL, 0);
+                              rdc321x_sb_cells, ARRAY_SIZE(rdc321x_sb_cells),
+                              NULL, 0, NULL);
 }
 
 static void __devexit rdc321x_sb_remove(struct pci_dev *pdev)
index 2988efd..49d361a 100644 (file)
@@ -141,19 +141,19 @@ static int sec_pmic_probe(struct i2c_client *i2c,
        switch (sec_pmic->device_type) {
        case S5M8751X:
                ret = mfd_add_devices(sec_pmic->dev, -1, s5m8751_devs,
-                                       ARRAY_SIZE(s5m8751_devs), NULL, 0);
+                                     ARRAY_SIZE(s5m8751_devs), NULL, 0, NULL);
                break;
        case S5M8763X:
                ret = mfd_add_devices(sec_pmic->dev, -1, s5m8763_devs,
-                                       ARRAY_SIZE(s5m8763_devs), NULL, 0);
+                                     ARRAY_SIZE(s5m8763_devs), NULL, 0, NULL);
                break;
        case S5M8767X:
                ret = mfd_add_devices(sec_pmic->dev, -1, s5m8767_devs,
-                                       ARRAY_SIZE(s5m8767_devs), NULL, 0);
+                                     ARRAY_SIZE(s5m8767_devs), NULL, 0, NULL);
                break;
        case S2MPS11X:
                ret = mfd_add_devices(sec_pmic->dev, -1, s2mps11_devs,
-                                       ARRAY_SIZE(s2mps11_devs), NULL, 0);
+                                     ARRAY_SIZE(s2mps11_devs), NULL, 0, NULL);
                break;
        default:
                /* If this happens the probe function is problem */
index d31fed0..d35da68 100644 (file)
@@ -407,7 +407,7 @@ static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev,
                              sta2x11_mfd_bar0,
                              ARRAY_SIZE(sta2x11_mfd_bar0),
                              &pdev->resource[0],
-                             0);
+                             0, NULL);
        if (err) {
                dev_err(&pdev->dev, "mfd_add_devices[0] failed: %d\n", err);
                goto err_disable;
@@ -417,7 +417,7 @@ static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev,
                              sta2x11_mfd_bar1,
                              ARRAY_SIZE(sta2x11_mfd_bar1),
                              &pdev->resource[1],
-                             0);
+                             0, NULL);
        if (err) {
                dev_err(&pdev->dev, "mfd_add_devices[1] failed: %d\n", err);
                goto err_disable;
index 2dd8d49..c94f521 100644 (file)
@@ -962,7 +962,7 @@ static int __devinit stmpe_add_device(struct stmpe *stmpe,
                                      struct mfd_cell *cell, int irq)
 {
        return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1,
-                              NULL, stmpe->irq_base + irq);
+                              NULL, stmpe->irq_base + irq, NULL);
 }
 
 static int __devinit stmpe_devices_init(struct stmpe *stmpe)
index 2d9e879..b32940e 100644 (file)
@@ -388,7 +388,7 @@ static int t7l66xb_probe(struct platform_device *dev)
 
        ret = mfd_add_devices(&dev->dev, dev->id,
                              t7l66xb_cells, ARRAY_SIZE(t7l66xb_cells),
-                             iomem, t7l66xb->irq_base);
+                             iomem, t7l66xb->irq_base, NULL);
 
        if (!ret)
                return 0;
index 048bf05..b56ba6b 100644 (file)
@@ -262,8 +262,8 @@ static int __devinit tc3589x_device_init(struct tc3589x *tc3589x)
 
        if (blocks & TC3589x_BLOCK_GPIO) {
                ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_gpio,
-                               ARRAY_SIZE(tc3589x_dev_gpio), NULL,
-                               tc3589x->irq_base);
+                                     ARRAY_SIZE(tc3589x_dev_gpio), NULL,
+                                     tc3589x->irq_base, NULL);
                if (ret) {
                        dev_err(tc3589x->dev, "failed to add gpio child\n");
                        return ret;
@@ -273,8 +273,8 @@ static int __devinit tc3589x_device_init(struct tc3589x *tc3589x)
 
        if (blocks & TC3589x_BLOCK_KEYPAD) {
                ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_keypad,
-                               ARRAY_SIZE(tc3589x_dev_keypad), NULL,
-                               tc3589x->irq_base);
+                                     ARRAY_SIZE(tc3589x_dev_keypad), NULL,
+                                     tc3589x->irq_base, NULL);
                if (ret) {
                        dev_err(tc3589x->dev, "failed to keypad child\n");
                        return ret;
index d20a284..413c891 100644 (file)
@@ -192,7 +192,7 @@ static int __devinit tc6387xb_probe(struct platform_device *dev)
        printk(KERN_INFO "Toshiba tc6387xb initialised\n");
 
        ret = mfd_add_devices(&dev->dev, dev->id, tc6387xb_cells,
-                             ARRAY_SIZE(tc6387xb_cells), iomem, irq);
+                             ARRAY_SIZE(tc6387xb_cells), iomem, irq, NULL);
 
        if (!ret)
                return 0;
index 9612264..dcab026 100644 (file)
@@ -700,8 +700,8 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
        tc6393xb_cells[TC6393XB_CELL_FB].pdata_size = sizeof(*tcpd->fb_data);
 
        ret = mfd_add_devices(&dev->dev, dev->id,
-                       tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells),
-                       iomem, tcpd->irq_base);
+                             tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells),
+                             iomem, tcpd->irq_base, NULL);
 
        if (!ret)
                return 0;
index 4fb0e6c..7c3675a 100644 (file)
@@ -412,7 +412,7 @@ static int __devinit ti_ssp_probe(struct platform_device *pdev)
                cells[id].data_size     = data->pdata_size;
        }
 
-       error = mfd_add_devices(dev, 0, cells, 2, NULL, 0);
+       error = mfd_add_devices(dev, 0, cells, 2, NULL, 0, NULL);
        if (error < 0) {
                dev_err(dev, "cannot add mfd cells\n");
                goto error_enable;
index a447f4e..cccc626 100644 (file)
@@ -757,25 +757,25 @@ static int __devinit timb_probe(struct pci_dev *dev,
                err = mfd_add_devices(&dev->dev, -1,
                        timberdale_cells_bar0_cfg0,
                        ARRAY_SIZE(timberdale_cells_bar0_cfg0),
-                       &dev->resource[0], msix_entries[0].vector);
+                       &dev->resource[0], msix_entries[0].vector, NULL);
                break;
        case TIMB_HW_VER1:
                err = mfd_add_devices(&dev->dev, -1,
                        timberdale_cells_bar0_cfg1,
                        ARRAY_SIZE(timberdale_cells_bar0_cfg1),
-                       &dev->resource[0], msix_entries[0].vector);
+                       &dev->resource[0], msix_entries[0].vector, NULL);
                break;
        case TIMB_HW_VER2:
                err = mfd_add_devices(&dev->dev, -1,
                        timberdale_cells_bar0_cfg2,
                        ARRAY_SIZE(timberdale_cells_bar0_cfg2),
-                       &dev->resource[0], msix_entries[0].vector);
+                       &dev->resource[0], msix_entries[0].vector, NULL);
                break;
        case TIMB_HW_VER3:
                err = mfd_add_devices(&dev->dev, -1,
                        timberdale_cells_bar0_cfg3,
                        ARRAY_SIZE(timberdale_cells_bar0_cfg3),
-                       &dev->resource[0], msix_entries[0].vector);
+                       &dev->resource[0], msix_entries[0].vector, NULL);
                break;
        default:
                dev_err(&dev->dev, "Uknown IP setup: %d.%d.%d\n",
@@ -792,7 +792,7 @@ static int __devinit timb_probe(struct pci_dev *dev,
 
        err = mfd_add_devices(&dev->dev, 0,
                timberdale_cells_bar1, ARRAY_SIZE(timberdale_cells_bar1),
-               &dev->resource[1], msix_entries[0].vector);
+               &dev->resource[1], msix_entries[0].vector, NULL);
        if (err) {
                dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err);
                goto err_mfd2;
@@ -803,7 +803,7 @@ static int __devinit timb_probe(struct pci_dev *dev,
                ((priv->fw.config & TIMB_HW_VER_MASK) == TIMB_HW_VER3)) {
                err = mfd_add_devices(&dev->dev, 1, timberdale_cells_bar2,
                        ARRAY_SIZE(timberdale_cells_bar2),
-                       &dev->resource[2], msix_entries[0].vector);
+                       &dev->resource[2], msix_entries[0].vector, NULL);
                if (err) {
                        dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err);
                        goto err_mfd2;
index a293b97..14051bd 100644 (file)
@@ -188,7 +188,7 @@ static int __devinit tps6105x_probe(struct i2c_client *client,
        }
 
        ret = mfd_add_devices(&client->dev, 0, tps6105x_cells,
-               ARRAY_SIZE(tps6105x_cells), NULL, 0);
+                             ARRAY_SIZE(tps6105x_cells), NULL, 0, NULL);
        if (ret)
                goto fail;
 
index 33ba772..1b20349 100644 (file)
@@ -100,7 +100,7 @@ static int tps6507x_i2c_probe(struct i2c_client *i2c,
 
        ret = mfd_add_devices(tps6507x->dev, -1,
                              tps6507x_devs, ARRAY_SIZE(tps6507x_devs),
-                             NULL, 0);
+                             NULL, 0, NULL);
 
        if (ret < 0)
                goto err;
index 80e24f4..50fd87c 100644 (file)
@@ -292,7 +292,7 @@ static int __devinit tps65090_i2c_probe(struct i2c_client *client,
        }
 
        ret = mfd_add_devices(tps65090->dev, -1, tps65090s,
-               ARRAY_SIZE(tps65090s), NULL, 0);
+                             ARRAY_SIZE(tps65090s), NULL, 0, NULL);
        if (ret) {
                dev_err(&client->dev, "add mfd devices failed with err: %d\n",
                        ret);
index 61c097a..a95e942 100644 (file)
 #include <linux/slab.h>
 #include <linux/regmap.h>
 #include <linux/err.h>
-#include <linux/regulator/of_regulator.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <linux/mfd/core.h>
 #include <linux/mfd/tps65217.h>
 
+static struct mfd_cell tps65217s[] = {
+       {
+               .name = "tps65217-pmic",
+       },
+};
+
 /**
  * tps65217_reg_read: Read a single tps65217 register.
  *
@@ -133,83 +140,48 @@ int tps65217_clear_bits(struct tps65217 *tps, unsigned int reg,
 }
 EXPORT_SYMBOL_GPL(tps65217_clear_bits);
 
-#ifdef CONFIG_OF
-static struct of_regulator_match reg_matches[] = {
-       { .name = "dcdc1", .driver_data = (void *)TPS65217_DCDC_1 },
-       { .name = "dcdc2", .driver_data = (void *)TPS65217_DCDC_2 },
-       { .name = "dcdc3", .driver_data = (void *)TPS65217_DCDC_3 },
-       { .name = "ldo1", .driver_data = (void *)TPS65217_LDO_1 },
-       { .name = "ldo2", .driver_data = (void *)TPS65217_LDO_2 },
-       { .name = "ldo3", .driver_data = (void *)TPS65217_LDO_3 },
-       { .name = "ldo4", .driver_data = (void *)TPS65217_LDO_4 },
-};
-
-static struct tps65217_board *tps65217_parse_dt(struct i2c_client *client)
-{
-       struct device_node *node = client->dev.of_node;
-       struct tps65217_board *pdata;
-       struct device_node *regs;
-       int count = ARRAY_SIZE(reg_matches);
-       int ret, i;
-
-       regs = of_find_node_by_name(node, "regulators");
-       if (!regs)
-               return NULL;
-
-       ret = of_regulator_match(&client->dev, regs, reg_matches, count);
-       of_node_put(regs);
-       if ((ret < 0) || (ret > count))
-               return NULL;
-
-       count = ret;
-       pdata = devm_kzalloc(&client->dev, count * sizeof(*pdata), GFP_KERNEL);
-       if (!pdata)
-               return NULL;
-
-       for (i = 0; i < count; i++) {
-               if (!reg_matches[i].init_data || !reg_matches[i].of_node)
-                       continue;
-
-               pdata->tps65217_init_data[i] = reg_matches[i].init_data;
-               pdata->of_node[i] = reg_matches[i].of_node;
-       }
-
-       return pdata;
-}
-
-static struct of_device_id tps65217_of_match[] = {
-       { .compatible = "ti,tps65217", },
-       { },
-};
-#else
-static struct tps65217_board *tps65217_parse_dt(struct i2c_client *client)
-{
-       return NULL;
-}
-#endif
-
 static struct regmap_config tps65217_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
 };
 
+static const struct of_device_id tps65217_of_match[] = {
+       { .compatible = "ti,tps65217", .data = (void *)TPS65217 },
+       { /* sentinel */ },
+};
+
 static int __devinit tps65217_probe(struct i2c_client *client,
                                const struct i2c_device_id *ids)
 {
        struct tps65217 *tps;
-       struct regulator_init_data *reg_data;
-       struct tps65217_board *pdata = client->dev.platform_data;
-       int i, ret;
        unsigned int version;
+       unsigned int chip_id = ids->driver_data;
+       const struct of_device_id *match;
+       int ret;
 
-       if (!pdata && client->dev.of_node)
-               pdata = tps65217_parse_dt(client);
+       if (client->dev.of_node) {
+               match = of_match_device(tps65217_of_match, &client->dev);
+               if (!match) {
+                       dev_err(&client->dev,
+                               "Failed to find matching dt id\n");
+                       return -EINVAL;
+               }
+               chip_id = (unsigned int)match->data;
+       }
+
+       if (!chip_id) {
+               dev_err(&client->dev, "id is null.\n");
+               return -ENODEV;
+       }
 
        tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
        if (!tps)
                return -ENOMEM;
 
-       tps->pdata = pdata;
+       i2c_set_clientdata(client, tps);
+       tps->dev = &client->dev;
+       tps->id = chip_id;
+
        tps->regmap = devm_regmap_init_i2c(client, &tps65217_regmap_config);
        if (IS_ERR(tps->regmap)) {
                ret = PTR_ERR(tps->regmap);
@@ -218,8 +190,12 @@ static int __devinit tps65217_probe(struct i2c_client *client,
                return ret;
        }
 
-       i2c_set_clientdata(client, tps);
-       tps->dev = &client->dev;
+       ret = mfd_add_devices(tps->dev, -1, tps65217s,
+                             ARRAY_SIZE(tps65217s), NULL, 0, NULL);
+       if (ret < 0) {
+               dev_err(tps->dev, "mfd_add_devices failed: %d\n", ret);
+               return ret;
+       }
 
        ret = tps65217_reg_read(tps, TPS65217_REG_CHIPID, &version);
        if (ret < 0) {
@@ -232,41 +208,21 @@ static int __devinit tps65217_probe(struct i2c_client *client,
                        (version & TPS65217_CHIPID_CHIP_MASK) >> 4,
                        version & TPS65217_CHIPID_REV_MASK);
 
-       for (i = 0; i < TPS65217_NUM_REGULATOR; i++) {
-               struct platform_device *pdev;
-
-               pdev = platform_device_alloc("tps65217-pmic", i);
-               if (!pdev) {
-                       dev_err(tps->dev, "Cannot create regulator %d\n", i);
-                       continue;
-               }
-
-               pdev->dev.parent = tps->dev;
-               pdev->dev.of_node = pdata->of_node[i];
-               reg_data = pdata->tps65217_init_data[i];
-               platform_device_add_data(pdev, reg_data, sizeof(*reg_data));
-               tps->regulator_pdev[i] = pdev;
-
-               platform_device_add(pdev);
-       }
-
        return 0;
 }
 
 static int __devexit tps65217_remove(struct i2c_client *client)
 {
        struct tps65217 *tps = i2c_get_clientdata(client);
-       int i;
 
-       for (i = 0; i < TPS65217_NUM_REGULATOR; i++)
-               platform_device_unregister(tps->regulator_pdev[i]);
+       mfd_remove_devices(tps->dev);
 
        return 0;
 }
 
 static const struct i2c_device_id tps65217_id_table[] = {
-       {"tps65217", 0xF0},
-       {/* end of list */}
+       {"tps65217", TPS65217},
+       { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(i2c, tps65217_id_table);
 
index 353c348..5f58370 100644 (file)
@@ -493,7 +493,8 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client,
        }
 
        ret = mfd_add_devices(tps6586x->dev, -1,
-                       tps6586x_cell, ARRAY_SIZE(tps6586x_cell), NULL, 0);
+                             tps6586x_cell, ARRAY_SIZE(tps6586x_cell),
+                             NULL, 0, NULL);
        if (ret < 0) {
                dev_err(&client->dev, "mfd_add_devices failed: %d\n", ret);
                goto err_mfd_add;
index 1c56379..d3ce4d5 100644 (file)
@@ -254,7 +254,7 @@ static __devinit int tps65910_i2c_probe(struct i2c_client *i2c,
 
        ret = mfd_add_devices(tps65910->dev, -1,
                              tps65910s, ARRAY_SIZE(tps65910s),
-                             NULL, 0);
+                             NULL, 0, NULL);
        if (ret < 0) {
                dev_err(&i2c->dev, "mfd_add_devices failed: %d\n", ret);
                return ret;
index 74fd8cb..4658b5b 100644 (file)
@@ -146,7 +146,7 @@ int tps65912_device_init(struct tps65912 *tps65912)
 
        ret = mfd_add_devices(tps65912->dev, -1,
                              tps65912s, ARRAY_SIZE(tps65912s),
-                             NULL, 0);
+                             NULL, 0, NULL);
        if (ret < 0)
                goto err;
 
index 838ce4e..77c9acb 100644 (file)
@@ -223,7 +223,7 @@ static int __devinit twl4030_audio_probe(struct platform_device *pdev)
 
        if (childs)
                ret = mfd_add_devices(&pdev->dev, pdev->id, audio->cells,
-                                     childs, NULL, 0);
+                                     childs, NULL, 0, NULL);
        else {
                dev_err(&pdev->dev, "No platform data found for childs\n");
                ret = -ENODEV;
index b0fad0f..3dca5c1 100644 (file)
@@ -632,7 +632,7 @@ static int __devinit twl6040_probe(struct i2c_client *client,
        }
 
        ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children,
-                             NULL, 0);
+                             NULL, 0, NULL);
        if (ret)
                goto mfd_err;
 
index 872aff2..b9a636d 100644 (file)
@@ -102,7 +102,7 @@ static __devinit int vx855_probe(struct pci_dev *pdev,
        vx855_gpio_resources[1].end = vx855_gpio_resources[1].start + 3;
 
        ret = mfd_add_devices(&pdev->dev, -1, vx855_cells, ARRAY_SIZE(vx855_cells),
-                       NULL, 0);
+                       NULL, 0, NULL);
 
        /* we always return -ENODEV here in order to enable other
         * drivers like old, not-yet-platform_device ported i2c-viapro */
index f39b756..86e0e43 100644 (file)
@@ -241,7 +241,7 @@ static int __devinit wl1273_core_probe(struct i2c_client *client,
                __func__, children);
 
        r = mfd_add_devices(&client->dev, -1, core->cells,
-                           children, NULL, 0);
+                           children, NULL, 0, NULL);
        if (r)
                goto err;
 
index 946698f..3017310 100644 (file)
@@ -1813,27 +1813,27 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
        case WM8310:
                ret = mfd_add_devices(wm831x->dev, wm831x_num,
                                      wm8310_devs, ARRAY_SIZE(wm8310_devs),
-                                     NULL, 0);
+                                     NULL, 0, NULL);
                break;
 
        case WM8311:
                ret = mfd_add_devices(wm831x->dev, wm831x_num,
                                      wm8311_devs, ARRAY_SIZE(wm8311_devs),
-                                     NULL, 0);
+                                     NULL, 0, NULL);
                if (!pdata || !pdata->disable_touch)
                        mfd_add_devices(wm831x->dev, wm831x_num,
                                        touch_devs, ARRAY_SIZE(touch_devs),
-                                       NULL, 0);
+                                       NULL, 0, NULL);
                break;
 
        case WM8312:
                ret = mfd_add_devices(wm831x->dev, wm831x_num,
                                      wm8312_devs, ARRAY_SIZE(wm8312_devs),
-                                     NULL, 0);
+                                     NULL, 0, NULL);
                if (!pdata || !pdata->disable_touch)
                        mfd_add_devices(wm831x->dev, wm831x_num,
                                        touch_devs, ARRAY_SIZE(touch_devs),
-                                       NULL, 0);
+                                       NULL, 0, NULL);
                break;
 
        case WM8320:
@@ -1842,7 +1842,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
        case WM8326:
                ret = mfd_add_devices(wm831x->dev, wm831x_num,
                                      wm8320_devs, ARRAY_SIZE(wm8320_devs),
-                                     NULL, 0);
+                                     NULL, 0, NULL);
                break;
 
        default:
@@ -1867,7 +1867,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
        if (ret & WM831X_XTAL_ENA) {
                ret = mfd_add_devices(wm831x->dev, wm831x_num,
                                      rtc_devs, ARRAY_SIZE(rtc_devs),
-                                     NULL, 0);
+                                     NULL, 0, NULL);
                if (ret != 0) {
                        dev_err(wm831x->dev, "Failed to add RTC: %d\n", ret);
                        goto err_irq;
@@ -1880,7 +1880,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
                /* Treat errors as non-critical */
                ret = mfd_add_devices(wm831x->dev, wm831x_num, backlight_devs,
                                      ARRAY_SIZE(backlight_devs), NULL,
-                                     0);
+                                     0, NULL);
                if (ret < 0)
                        dev_err(wm831x->dev, "Failed to add backlight: %d\n",
                                ret);
index 4b7d378..639ca35 100644 (file)
@@ -70,7 +70,7 @@ static int wm8400_register_codec(struct wm8400 *wm8400)
                .pdata_size = sizeof(*wm8400),
        };
 
-       return mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0);
+       return mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0, NULL);
 }
 
 /*
index eec74aa..2febf88 100644 (file)
@@ -414,7 +414,7 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq)
        ret = mfd_add_devices(wm8994->dev, -1,
                              wm8994_regulator_devs,
                              ARRAY_SIZE(wm8994_regulator_devs),
-                             NULL, 0);
+                             NULL, 0, NULL);
        if (ret != 0) {
                dev_err(wm8994->dev, "Failed to add children: %d\n", ret);
                goto err;
@@ -648,7 +648,7 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq)
 
        ret = mfd_add_devices(wm8994->dev, -1,
                              wm8994_devs, ARRAY_SIZE(wm8994_devs),
-                             NULL, 0);
+                             NULL, 0, NULL);
        if (ret != 0) {
                dev_err(wm8994->dev, "Failed to add children: %d\n", ret);
                goto err_irq;
index 98ee438..7edadee 100644 (file)
@@ -1391,7 +1391,6 @@ static irqreturn_t ican3_irq(int irq, void *dev_id)
  */
 static int ican3_reset_module(struct ican3_dev *mod)
 {
-       u8 val = 1 << mod->num;
        unsigned long start;
        u8 runold, runnew;
 
@@ -1405,8 +1404,7 @@ static int ican3_reset_module(struct ican3_dev *mod)
        runold = ioread8(mod->dpm + TARGET_RUNNING);
 
        /* reset the module */
-       iowrite8(val, &mod->ctrl->reset_assert);
-       iowrite8(val, &mod->ctrl->reset_deassert);
+       iowrite8(0x00, &mod->dpmctrl->hwreset);
 
        /* wait until the module has finished resetting and is running */
        start = jiffies;
index 527dbcf..9ded21e 100644 (file)
@@ -984,12 +984,12 @@ static int __devexit ti_hecc_remove(struct platform_device *pdev)
        struct net_device *ndev = platform_get_drvdata(pdev);
        struct ti_hecc_priv *priv = netdev_priv(ndev);
 
+       unregister_candev(ndev);
        clk_disable(priv->clk);
        clk_put(priv->clk);
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        iounmap(priv->base);
        release_mem_region(res->start, resource_size(res));
-       unregister_candev(ndev);
        free_candev(ndev);
        platform_set_drvdata(pdev, NULL);
 
index af20c6e..e8e97a7 100644 (file)
@@ -662,14 +662,16 @@ void bnx2x_csum_validate(struct sk_buff *skb, union eth_rx_cqe *cqe,
                                 struct bnx2x_fastpath *fp,
                                 struct bnx2x_eth_q_stats *qstats)
 {
-       /* Do nothing if no IP/L4 csum validation was done */
-
+       /* Do nothing if no L4 csum validation was done.
+        * We do not check whether IP csum was validated. For IPv4 we assume
+        * that if the card got as far as validating the L4 csum, it also
+        * validated the IP csum. IPv6 has no IP csum.
+        */
        if (cqe->fast_path_cqe.status_flags &
-           (ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG |
-            ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG))
+           ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG)
                return;
 
-       /* If both IP/L4 validation were done, check if an error was found. */
+       /* If L4 validation was done, check if an error was found. */
 
        if (cqe->fast_path_cqe.type_error_flags &
            (ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG |
index 211753e..0875ecf 100644 (file)
@@ -9831,12 +9831,13 @@ static void __devinit bnx2x_get_igu_cam_info(struct bnx2x *bp)
        }
 
 #ifdef CONFIG_PCI_MSI
-       /*
-        * It's expected that number of CAM entries for this functions is equal
-        * to the number evaluated based on the MSI-X table size. We want a
-        * harsh warning if these values are different!
+       /* Due to new PF resource allocation by MFW T7.4 and above, it's
+        * optional that number of CAM entries will not be equal to the value
+        * advertised in PCI.
+        * Driver should use the minimal value of both as the actual status
+        * block count
         */
-       WARN_ON(bp->igu_sb_cnt != igu_sb_cnt);
+       bp->igu_sb_cnt = min_t(int, bp->igu_sb_cnt, igu_sb_cnt);
 #endif
 
        if (igu_sb_cnt == 0)
index 7788419..4e980a7 100644 (file)
@@ -1086,7 +1086,7 @@ static int __init at91ether_probe(struct platform_device *pdev)
        /* Clock */
        lp->ether_clk = clk_get(&pdev->dev, "ether_clk");
        if (IS_ERR(lp->ether_clk)) {
-               res = -ENODEV;
+               res = PTR_ERR(lp->ether_clk);
                goto err_ioumap;
        }
        clk_enable(lp->ether_clk);
index 8971921..ab6762c 100644 (file)
@@ -1773,6 +1773,7 @@ static int gfar_get_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
 }
 
 int gfar_phc_index = -1;
+EXPORT_SYMBOL(gfar_phc_index);
 
 static int gfar_get_ts_info(struct net_device *dev,
                            struct ethtool_ts_info *info)
index c08e5d4..0daa66b 100644 (file)
@@ -515,7 +515,7 @@ static int gianfar_ptp_probe(struct platform_device *dev)
                err = PTR_ERR(etsects->clock);
                goto no_clock;
        }
-       gfar_phc_clock = ptp_clock_index(etsects->clock);
+       gfar_phc_index = ptp_clock_index(etsects->clock);
 
        dev_set_drvdata(&dev->dev, etsects);
 
@@ -539,7 +539,7 @@ static int gianfar_ptp_remove(struct platform_device *dev)
        gfar_write(&etsects->regs->tmr_temask, 0);
        gfar_write(&etsects->regs->tmr_ctrl,   0);
 
-       gfar_phc_clock = -1;
+       gfar_phc_index = -1;
        ptp_clock_unregister(etsects->clock);
        iounmap(etsects->regs);
        release_resource(etsects->rsrc);
index 3bfbb8d..bde337e 100644 (file)
@@ -3149,6 +3149,17 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
                return NETDEV_TX_OK;
        }
 
+       /* On PCI/PCI-X HW, if packet size is less than ETH_ZLEN,
+        * packets may get corrupted during padding by HW.
+        * To WA this issue, pad all small packets manually.
+        */
+       if (skb->len < ETH_ZLEN) {
+               if (skb_pad(skb, ETH_ZLEN - skb->len))
+                       return NETDEV_TX_OK;
+               skb->len = ETH_ZLEN;
+               skb_set_tail_pointer(skb, ETH_ZLEN);
+       }
+
        mss = skb_shinfo(skb)->gso_size;
        /* The controller does a simple calculation to
         * make sure there is enough room in the FIFO before
index daf4179..31d0264 100644 (file)
@@ -227,9 +227,10 @@ int mlx4_UNMAP_ICM_AUX(struct mlx4_dev *dev)
                        MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
 }
 
-int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj)
+int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj)
 {
-       int i = (obj & (table->num_obj - 1)) / (MLX4_TABLE_CHUNK_SIZE / table->obj_size);
+       u32 i = (obj & (table->num_obj - 1)) /
+                       (MLX4_TABLE_CHUNK_SIZE / table->obj_size);
        int ret = 0;
 
        mutex_lock(&table->mutex);
@@ -262,16 +263,18 @@ out:
        return ret;
 }
 
-void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj)
+void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj)
 {
-       int i;
+       u32 i;
+       u64 offset;
 
        i = (obj & (table->num_obj - 1)) / (MLX4_TABLE_CHUNK_SIZE / table->obj_size);
 
        mutex_lock(&table->mutex);
 
        if (--table->icm[i]->refcount == 0) {
-               mlx4_UNMAP_ICM(dev, table->virt + i * MLX4_TABLE_CHUNK_SIZE,
+               offset = (u64) i * MLX4_TABLE_CHUNK_SIZE;
+               mlx4_UNMAP_ICM(dev, table->virt + offset,
                               MLX4_TABLE_CHUNK_SIZE / MLX4_ICM_PAGE_SIZE);
                mlx4_free_icm(dev, table->icm[i], table->coherent);
                table->icm[i] = NULL;
@@ -280,9 +283,11 @@ void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj)
        mutex_unlock(&table->mutex);
 }
 
-void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_handle)
+void *mlx4_table_find(struct mlx4_icm_table *table, u32 obj,
+                       dma_addr_t *dma_handle)
 {
-       int idx, offset, dma_offset, i;
+       int offset, dma_offset, i;
+       u64 idx;
        struct mlx4_icm_chunk *chunk;
        struct mlx4_icm *icm;
        struct page *page = NULL;
@@ -292,7 +297,7 @@ void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_han
 
        mutex_lock(&table->mutex);
 
-       idx = (obj & (table->num_obj - 1)) * table->obj_size;
+       idx = (u64) (obj & (table->num_obj - 1)) * table->obj_size;
        icm = table->icm[idx / MLX4_TABLE_CHUNK_SIZE];
        dma_offset = offset = idx % MLX4_TABLE_CHUNK_SIZE;
 
@@ -326,10 +331,11 @@ out:
 }
 
 int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
-                        int start, int end)
+                        u32 start, u32 end)
 {
        int inc = MLX4_TABLE_CHUNK_SIZE / table->obj_size;
-       int i, err;
+       int err;
+       u32 i;
 
        for (i = start; i <= end; i += inc) {
                err = mlx4_table_get(dev, table, i);
@@ -349,9 +355,9 @@ fail:
 }
 
 void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
-                         int start, int end)
+                         u32 start, u32 end)
 {
-       int i;
+       u32 i;
 
        for (i = start; i <= end; i += MLX4_TABLE_CHUNK_SIZE / table->obj_size)
                mlx4_table_put(dev, table, i);
index a67744f..dee67fa 100644 (file)
@@ -71,17 +71,17 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
                                gfp_t gfp_mask, int coherent);
 void mlx4_free_icm(struct mlx4_dev *dev, struct mlx4_icm *icm, int coherent);
 
-int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj);
-void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj);
+int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj);
+void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj);
 int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
-                        int start, int end);
+                        u32 start, u32 end);
 void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
-                         int start, int end);
+                         u32 start, u32 end);
 int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table,
                        u64 virt, int obj_size, u32 nobj, int reserved,
                        int use_lowmem, int use_coherent);
 void mlx4_cleanup_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table);
-void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_handle);
+void *mlx4_table_find(struct mlx4_icm_table *table, u32 obj, dma_addr_t *dma_handle);
 
 static inline void mlx4_icm_first(struct mlx4_icm *icm,
                                  struct mlx4_icm_iter *iter)
index 342b3a7..a77c558 100644 (file)
@@ -1378,6 +1378,10 @@ static void netxen_mask_aer_correctable(struct netxen_adapter *adapter)
        struct pci_dev *root = pdev->bus->self;
        u32 aer_pos;
 
+       /* root bus? */
+       if (!root)
+               return;
+
        if (adapter->ahw.board_type != NETXEN_BRDTYPE_P3_4_GB_MM &&
                adapter->ahw.board_type != NETXEN_BRDTYPE_P3_10G_TP)
                return;
index c136162..3be8833 100644 (file)
@@ -1066,7 +1066,7 @@ static int stmmac_open(struct net_device *dev)
        } else
                priv->tm->enable = 1;
 #endif
-       clk_enable(priv->stmmac_clk);
+       clk_prepare_enable(priv->stmmac_clk);
 
        stmmac_check_ether_addr(priv);
 
@@ -1188,7 +1188,7 @@ open_error:
        if (priv->phydev)
                phy_disconnect(priv->phydev);
 
-       clk_disable(priv->stmmac_clk);
+       clk_disable_unprepare(priv->stmmac_clk);
 
        return ret;
 }
@@ -1246,7 +1246,7 @@ static int stmmac_release(struct net_device *dev)
 #ifdef CONFIG_STMMAC_DEBUG_FS
        stmmac_exit_fs();
 #endif
-       clk_disable(priv->stmmac_clk);
+       clk_disable_unprepare(priv->stmmac_clk);
 
        return 0;
 }
@@ -2178,7 +2178,7 @@ int stmmac_suspend(struct net_device *ndev)
        else {
                stmmac_set_mac(priv->ioaddr, false);
                /* Disable clock in case of PWM is off */
-               clk_disable(priv->stmmac_clk);
+               clk_disable_unprepare(priv->stmmac_clk);
        }
        spin_unlock_irqrestore(&priv->lock, flags);
        return 0;
@@ -2203,7 +2203,7 @@ int stmmac_resume(struct net_device *ndev)
                priv->hw->mac->pmt(priv->ioaddr, 0);
        else
                /* enable the clk prevously disabled */
-               clk_enable(priv->stmmac_clk);
+               clk_prepare_enable(priv->stmmac_clk);
 
        netif_device_attach(ndev);
 
index 2a0e1ab..4ccd4e2 100644 (file)
@@ -97,19 +97,19 @@ static struct clk *timer_clock;
 static void stmmac_tmu_start(unsigned int new_freq)
 {
        clk_set_rate(timer_clock, new_freq);
-       clk_enable(timer_clock);
+       clk_prepare_enable(timer_clock);
 }
 
 static void stmmac_tmu_stop(void)
 {
-       clk_disable(timer_clock);
+       clk_disable_unprepare(timer_clock);
 }
 
 int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
 {
        timer_clock = clk_get(NULL, TMU_CHANNEL);
 
-       if (timer_clock == NULL)
+       if (IS_ERR(timer_clock))
                return -1;
 
        if (tmu2_register_user(stmmac_timer_handler, (void *)dev) < 0) {
@@ -126,7 +126,7 @@ int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
 
 int stmmac_close_ext_timer(void)
 {
-       clk_disable(timer_clock);
+       clk_disable_unprepare(timer_clock);
        tmu2_unregister_user();
        clk_put(timer_clock);
        return 0;
index 256eddf..7951094 100644 (file)
@@ -280,7 +280,7 @@ static int sh_sir_set_baudrate(struct sh_sir_self *self, u32 baudrate)
        }
 
        clk = clk_get(NULL, "irda_clk");
-       if (!clk) {
+       if (IS_ERR(clk)) {
                dev_err(dev, "can not get irda_clk\n");
                return -EIO;
        }
index 4fd48df..32e31c5 100644 (file)
@@ -961,6 +961,10 @@ static const struct usb_device_id  products [] = {
        // DLink DUB-E100 H/W Ver B1 Alternate
        USB_DEVICE (0x2001, 0x3c05),
        .driver_info = (unsigned long) &ax88772_info,
+}, {
+       // DLink DUB-E100 H/W Ver C1
+       USB_DEVICE (0x2001, 0x1a02),
+       .driver_info = (unsigned long) &ax88772_info,
 }, {
        // Linksys USB1000
        USB_DEVICE (0x1737, 0x0039),
index b1ba68f..3543c9e 100644 (file)
@@ -366,16 +366,20 @@ static const struct usb_device_id products[] = {
        },
 
        /* 2. Combined interface devices matching on class+protocol */
+       {       /* Huawei E367 and possibly others in "Windows mode" */
+               USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 7),
+               .driver_info        = (unsigned long)&qmi_wwan_info,
+       },
        {       /* Huawei E392, E398 and possibly others in "Windows mode" */
                USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 17),
                .driver_info        = (unsigned long)&qmi_wwan_shared,
        },
-       {       /* Pantech UML290 */
-               USB_DEVICE_AND_INTERFACE_INFO(0x106c, 0x3718, USB_CLASS_VENDOR_SPEC, 0xf0, 0xff),
+       {       /* Pantech UML290, P4200 and more */
+               USB_VENDOR_AND_INTERFACE_INFO(0x106c, USB_CLASS_VENDOR_SPEC, 0xf0, 0xff),
                .driver_info        = (unsigned long)&qmi_wwan_shared,
        },
        {       /* Pantech UML290 - newer firmware */
-               USB_DEVICE_AND_INTERFACE_INFO(0x106c, 0x3718, USB_CLASS_VENDOR_SPEC, 0xf1, 0xff),
+               USB_VENDOR_AND_INTERFACE_INFO(0x106c, USB_CLASS_VENDOR_SPEC, 0xf1, 0xff),
                .driver_info        = (unsigned long)&qmi_wwan_shared,
        },
 
@@ -383,6 +387,7 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x19d2, 0x0055, 1)},    /* ZTE (Vodafone) K3520-Z */
        {QMI_FIXED_INTF(0x19d2, 0x0063, 4)},    /* ZTE (Vodafone) K3565-Z */
        {QMI_FIXED_INTF(0x19d2, 0x0104, 4)},    /* ZTE (Vodafone) K4505-Z */
+       {QMI_FIXED_INTF(0x19d2, 0x0157, 5)},    /* ZTE MF683 */
        {QMI_FIXED_INTF(0x19d2, 0x0167, 4)},    /* ZTE MF820D */
        {QMI_FIXED_INTF(0x19d2, 0x0326, 4)},    /* ZTE MF821D */
        {QMI_FIXED_INTF(0x19d2, 0x1008, 4)},    /* ZTE (Vodafone) K3570-Z */
index 2588848..d066f25 100644 (file)
@@ -2982,6 +2982,10 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
        case EEP_RX_MASK:
                return pBase->txrxMask & 0xf;
        case EEP_PAPRD:
+               if (AR_SREV_9462(ah))
+                       return false;
+               if (!ah->config.enable_paprd);
+                       return false;
                return !!(pBase->featureEnable & BIT(5));
        case EEP_CHAIN_MASK_REDUCE:
                return (pBase->miscConfiguration >> 0x3) & 0x1;
index 68b643c..c8ef301 100644 (file)
@@ -1577,6 +1577,8 @@ int ath9k_init_debug(struct ath_hw *ah)
                            sc->debug.debugfs_phy, sc, &fops_tx_chainmask);
        debugfs_create_file("disable_ani", S_IRUSR | S_IWUSR,
                            sc->debug.debugfs_phy, sc, &fops_disable_ani);
+       debugfs_create_bool("paprd", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
+                           &sc->sc_ah->config.enable_paprd);
        debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
                            sc, &fops_regidx);
        debugfs_create_file("regval", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
index 48af401..4faf0a3 100644 (file)
@@ -2497,10 +2497,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
                pCap->rx_status_len = sizeof(struct ar9003_rxs);
                pCap->tx_desc_len = sizeof(struct ar9003_txc);
                pCap->txs_len = sizeof(struct ar9003_txs);
-               if (!ah->config.paprd_disable &&
-                   ah->eep_ops->get_eeprom(ah, EEP_PAPRD) &&
-                   !AR_SREV_9462(ah))
-                       pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;
        } else {
                pCap->tx_desc_len = sizeof(struct ath_desc);
                if (AR_SREV_9280_20(ah))
index 6599a75..de6968f 100644 (file)
@@ -236,7 +236,6 @@ enum ath9k_hw_caps {
        ATH9K_HW_CAP_LDPC                       = BIT(6),
        ATH9K_HW_CAP_FASTCLOCK                  = BIT(7),
        ATH9K_HW_CAP_SGI_20                     = BIT(8),
-       ATH9K_HW_CAP_PAPRD                      = BIT(9),
        ATH9K_HW_CAP_ANT_DIV_COMB               = BIT(10),
        ATH9K_HW_CAP_2GHZ                       = BIT(11),
        ATH9K_HW_CAP_5GHZ                       = BIT(12),
@@ -287,12 +286,12 @@ struct ath9k_ops_config {
        u8 pcie_clock_req;
        u32 pcie_waen;
        u8 analog_shiftreg;
-       u8 paprd_disable;
        u32 ofdm_trig_low;
        u32 ofdm_trig_high;
        u32 cck_trig_high;
        u32 cck_trig_low;
        u32 enable_ani;
+       u32 enable_paprd;
        int serialize_regmode;
        bool rx_intr_mitigation;
        bool tx_intr_mitigation;
index 825a29c..7b88b9c 100644 (file)
@@ -423,7 +423,7 @@ set_timer:
                cal_interval = min(cal_interval, (u32)short_cal_interval);
 
        mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
-       if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) {
+       if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD) && ah->caldata) {
                if (!ah->caldata->paprd_done)
                        ieee80211_queue_work(sc->hw, &sc->paprd_work);
                else if (!ah->paprd_table_write_done)
index 49765d3..7c4ee72 100644 (file)
@@ -638,6 +638,8 @@ static int brcmf_sdio_pd_probe(struct platform_device *pdev)
 
                oobirq_entry = kzalloc(sizeof(struct brcmf_sdio_oobirq),
                                       GFP_KERNEL);
+               if (!oobirq_entry)
+                       return -ENOMEM;
                oobirq_entry->irq = res->start;
                oobirq_entry->flags = res->flags & IRQF_TRIGGER_MASK;
                list_add_tail(&oobirq_entry->list, &oobirq_lh);
index 2621dd3..6f70953 100644 (file)
@@ -764,8 +764,11 @@ static void brcmf_c_arp_offload_set(struct brcmf_pub *drvr, int arp_mode)
 {
        char iovbuf[32];
        int retcode;
+       __le32 arp_mode_le;
 
-       brcmf_c_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf));
+       arp_mode_le = cpu_to_le32(arp_mode);
+       brcmf_c_mkiovar("arp_ol", (char *)&arp_mode_le, 4, iovbuf,
+                       sizeof(iovbuf));
        retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
                                   iovbuf, sizeof(iovbuf));
        retcode = retcode >= 0 ? 0 : retcode;
@@ -781,8 +784,11 @@ static void brcmf_c_arp_offload_enable(struct brcmf_pub *drvr, int arp_enable)
 {
        char iovbuf[32];
        int retcode;
+       __le32 arp_enable_le;
 
-       brcmf_c_mkiovar("arpoe", (char *)&arp_enable, 4,
+       arp_enable_le = cpu_to_le32(arp_enable);
+
+       brcmf_c_mkiovar("arpoe", (char *)&arp_enable_le, 4,
                        iovbuf, sizeof(iovbuf));
        retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
                                   iovbuf, sizeof(iovbuf));
@@ -800,10 +806,10 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
        char iovbuf[BRCMF_EVENTING_MASK_LEN + 12];      /*  Room for
                                 "event_msgs" + '\0' + bitvec  */
        char buf[128], *ptr;
-       u32 roaming = 1;
-       uint bcn_timeout = 3;
-       int scan_assoc_time = 40;
-       int scan_unassoc_time = 40;
+       __le32 roaming_le = cpu_to_le32(1);
+       __le32 bcn_timeout_le = cpu_to_le32(3);
+       __le32 scan_assoc_time_le = cpu_to_le32(40);
+       __le32 scan_unassoc_time_le = cpu_to_le32(40);
        int i;
        struct brcmf_bus_dcmd *cmdlst;
        struct list_head *cur, *q;
@@ -829,14 +835,14 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
 
        /* Setup timeout if Beacons are lost and roam is off to report
                 link down */
-       brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
+       brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout_le, 4, iovbuf,
                    sizeof(iovbuf));
        brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
                                  sizeof(iovbuf));
 
        /* Enable/Disable build-in roaming to allowed ext supplicant to take
                 of romaing */
-       brcmf_c_mkiovar("roam_off", (char *)&roaming, 4,
+       brcmf_c_mkiovar("roam_off", (char *)&roaming_le, 4,
                      iovbuf, sizeof(iovbuf));
        brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
                                  sizeof(iovbuf));
@@ -848,9 +854,9 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
                                  sizeof(iovbuf));
 
        brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_CHANNEL_TIME,
-                        (char *)&scan_assoc_time, sizeof(scan_assoc_time));
+                (char *)&scan_assoc_time_le, sizeof(scan_assoc_time_le));
        brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_UNASSOC_TIME,
-                        (char *)&scan_unassoc_time, sizeof(scan_unassoc_time));
+                (char *)&scan_unassoc_time_le, sizeof(scan_unassoc_time_le));
 
        /* Set and enable ARP offload feature */
        brcmf_c_arp_offload_set(drvr, BRCMF_ARPOL_MODE);
index c36e923..50b5553 100644 (file)
@@ -500,8 +500,10 @@ static void wl_iscan_prep(struct brcmf_scan_params_le *params_le,
        params_le->active_time = cpu_to_le32(-1);
        params_le->passive_time = cpu_to_le32(-1);
        params_le->home_time = cpu_to_le32(-1);
-       if (ssid && ssid->SSID_len)
-               memcpy(&params_le->ssid_le, ssid, sizeof(struct brcmf_ssid));
+       if (ssid && ssid->SSID_len) {
+               params_le->ssid_le.SSID_len = cpu_to_le32(ssid->SSID_len);
+               memcpy(&params_le->ssid_le.SSID, ssid->SSID, ssid->SSID_len);
+       }
 }
 
 static s32
index 7ed7d75..64a48f0 100644 (file)
@@ -77,7 +77,7 @@
                                         NL80211_RRF_NO_IBSS)
 
 static const struct ieee80211_regdomain brcms_regdom_x2 = {
-       .n_reg_rules = 7,
+       .n_reg_rules = 6,
        .alpha2 = "X2",
        .reg_rules = {
                BRCM_2GHZ_2412_2462,
index 04c3aef..2925094 100644 (file)
 
 #define CHIP_VER_B                     BIT(4)
 #define CHIP_92C_BITMASK               BIT(0)
+#define CHIP_UNKNOWN                   BIT(7)
 #define CHIP_92C_1T2R                  0x03
 #define CHIP_92C                       0x01
 #define CHIP_88C                       0x00
index bd0da7e..dd4bb09 100644 (file)
@@ -994,8 +994,16 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw)
                version = (value32 & TYPE_ID) ? VERSION_A_CHIP_92C :
                           VERSION_A_CHIP_88C;
        } else {
-               version = (value32 & TYPE_ID) ? VERSION_B_CHIP_92C :
-                          VERSION_B_CHIP_88C;
+               version = (enum version_8192c) (CHIP_VER_B |
+                               ((value32 & TYPE_ID) ? CHIP_92C_BITMASK : 0) |
+                               ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0));
+               if ((!IS_CHIP_VENDOR_UMC(version)) && (value32 &
+                    CHIP_VER_RTL_MASK)) {
+                       version = (enum version_8192c)(version |
+                                  ((((value32 & CHIP_VER_RTL_MASK) == BIT(12))
+                                  ? CHIP_VENDOR_UMC_B_CUT : CHIP_UNKNOWN) |
+                                  CHIP_VENDOR_UMC));
+               }
        }
 
        switch (version) {
index 3aa927f..7d8f964 100644 (file)
@@ -162,10 +162,12 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
 
        /* request fw */
        if (IS_VENDOR_UMC_A_CUT(rtlhal->version) &&
-           !IS_92C_SERIAL(rtlhal->version))
+           !IS_92C_SERIAL(rtlhal->version)) {
                rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU.bin";
-       else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version))
+       } else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) {
                rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU_B.bin";
+               pr_info("****** This B_CUT device may not work with kernels 3.6 and earlier\n");
+       }
 
        rtlpriv->max_fw_size = 0x4000;
        pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name);
index 0b66d0f..4b66889 100644 (file)
@@ -100,6 +100,13 @@ static int ecap_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
                writel(period_cycles, pc->mmio_base + CAP3);
        }
 
+       if (!test_bit(PWMF_ENABLED, &pwm->flags)) {
+               reg_val = readw(pc->mmio_base + ECCTL2);
+               /* Disable APWM mode to put APWM output Low */
+               reg_val &= ~ECCTL2_APWM_MODE;
+               writew(reg_val, pc->mmio_base + ECCTL2);
+       }
+
        pm_runtime_put_sync(pc->chip.dev);
        return 0;
 }
index c3756d1..b1996bc 100644 (file)
@@ -104,6 +104,7 @@ struct ehrpwm_pwm_chip {
        struct pwm_chip chip;
        unsigned int    clk_rate;
        void __iomem    *mmio_base;
+       unsigned long period_cycles[NUM_PWM_CHANNEL];
 };
 
 static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip)
@@ -210,6 +211,7 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
        unsigned long long c;
        unsigned long period_cycles, duty_cycles;
        unsigned short ps_divval, tb_divval;
+       int i;
 
        if (period_ns < 0 || duty_ns < 0 || period_ns > NSEC_PER_SEC)
                return -ERANGE;
@@ -229,6 +231,28 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
                duty_cycles = (unsigned long)c;
        }
 
+       /*
+        * Period values should be same for multiple PWM channels as IP uses
+        * same period register for multiple channels.
+        */
+       for (i = 0; i < NUM_PWM_CHANNEL; i++) {
+               if (pc->period_cycles[i] &&
+                               (pc->period_cycles[i] != period_cycles)) {
+                       /*
+                        * Allow channel to reconfigure period if no other
+                        * channels being configured.
+                        */
+                       if (i == pwm->hwpwm)
+                               continue;
+
+                       dev_err(chip->dev, "Period value conflicts with channel %d\n",
+                                       i);
+                       return -EINVAL;
+               }
+       }
+
+       pc->period_cycles[pwm->hwpwm] = period_cycles;
+
        /* Configure clock prescaler to support Low frequency PWM wave */
        if (set_prescale_div(period_cycles/PERIOD_MAX, &ps_divval,
                                &tb_divval)) {
@@ -320,10 +344,15 @@ static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 
 static void ehrpwm_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
 {
+       struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip);
+
        if (test_bit(PWMF_ENABLED, &pwm->flags)) {
                dev_warn(chip->dev, "Removing PWM device without disabling\n");
                pm_runtime_put_sync(chip->dev);
        }
+
+       /* set period value to zero on free */
+       pc->period_cycles[pwm->hwpwm] = 0;
 }
 
 static const struct pwm_ops ehrpwm_pwm_ops = {
index 6caa222..ab00cab 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/err.h>
 #include <linux/platform_device.h>
 
+#include <linux/regulator/of_regulator.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/mfd/tps65217.h>
@@ -281,37 +282,130 @@ static const struct regulator_desc regulators[] = {
                           NULL),
 };
 
+#ifdef CONFIG_OF
+static struct of_regulator_match reg_matches[] = {
+       { .name = "dcdc1", .driver_data = (void *)TPS65217_DCDC_1 },
+       { .name = "dcdc2", .driver_data = (void *)TPS65217_DCDC_2 },
+       { .name = "dcdc3", .driver_data = (void *)TPS65217_DCDC_3 },
+       { .name = "ldo1", .driver_data = (void *)TPS65217_LDO_1 },
+       { .name = "ldo2", .driver_data = (void *)TPS65217_LDO_2 },
+       { .name = "ldo3", .driver_data = (void *)TPS65217_LDO_3 },
+       { .name = "ldo4", .driver_data = (void *)TPS65217_LDO_4 },
+};
+
+static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev)
+{
+       struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent);
+       struct device_node *node = tps->dev->of_node;
+       struct tps65217_board *pdata;
+       struct device_node *regs;
+       int i, count;
+
+       regs = of_find_node_by_name(node, "regulators");
+       if (!regs)
+               return NULL;
+
+       count = of_regulator_match(pdev->dev.parent, regs,
+                               reg_matches, TPS65217_NUM_REGULATOR);
+       of_node_put(regs);
+       if ((count < 0) || (count > TPS65217_NUM_REGULATOR))
+               return NULL;
+
+       pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata)
+               return NULL;
+
+       for (i = 0; i < count; i++) {
+               if (!reg_matches[i].init_data || !reg_matches[i].of_node)
+                       continue;
+
+               pdata->tps65217_init_data[i] = reg_matches[i].init_data;
+               pdata->of_node[i] = reg_matches[i].of_node;
+       }
+
+       return pdata;
+}
+#else
+static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev)
+{
+       return NULL;
+}
+#endif
+
 static int __devinit tps65217_regulator_probe(struct platform_device *pdev)
 {
+       struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent);
+       struct tps65217_board *pdata = dev_get_platdata(tps->dev);
+       struct regulator_init_data *reg_data;
        struct regulator_dev *rdev;
-       struct tps65217 *tps;
-       struct tps_info *info = &tps65217_pmic_regs[pdev->id];
        struct regulator_config config = { };
+       int i, ret;
 
-       /* Already set by core driver */
-       tps = dev_to_tps65217(pdev->dev.parent);
-       tps->info[pdev->id] = info;
+       if (tps->dev->of_node)
+               pdata = tps65217_parse_dt(pdev);
 
-       config.dev = &pdev->dev;
-       config.of_node = pdev->dev.of_node;
-       config.init_data = pdev->dev.platform_data;
-       config.driver_data = tps;
+       if (!pdata) {
+               dev_err(&pdev->dev, "Platform data not found\n");
+               return -EINVAL;
+       }
 
-       rdev = regulator_register(&regulators[pdev->id], &config);
-       if (IS_ERR(rdev))
-               return PTR_ERR(rdev);
+       if (tps65217_chip_id(tps) != TPS65217) {
+               dev_err(&pdev->dev, "Invalid tps chip version\n");
+               return -ENODEV;
+       }
 
-       platform_set_drvdata(pdev, rdev);
+       platform_set_drvdata(pdev, tps);
 
+       for (i = 0; i < TPS65217_NUM_REGULATOR; i++) {
+
+               reg_data = pdata->tps65217_init_data[i];
+
+               /*
+                * Regulator API handles empty constraints but not NULL
+                * constraints
+                */
+               if (!reg_data)
+                       continue;
+
+               /* Register the regulators */
+               tps->info[i] = &tps65217_pmic_regs[i];
+
+               config.dev = tps->dev;
+               config.init_data = reg_data;
+               config.driver_data = tps;
+               config.regmap = tps->regmap;
+               if (tps->dev->of_node)
+                       config.of_node = pdata->of_node[i];
+
+               rdev = regulator_register(&regulators[i], &config);
+               if (IS_ERR(rdev)) {
+                       dev_err(tps->dev, "failed to register %s regulator\n",
+                               pdev->name);
+                       ret = PTR_ERR(rdev);
+                       goto err_unregister_regulator;
+               }
+
+               /* Save regulator for cleanup */
+               tps->rdev[i] = rdev;
+       }
        return 0;
+
+err_unregister_regulator:
+       while (--i >= 0)
+               regulator_unregister(tps->rdev[i]);
+
+       return ret;
 }
 
 static int __devexit tps65217_regulator_remove(struct platform_device *pdev)
 {
-       struct regulator_dev *rdev = platform_get_drvdata(pdev);
+       struct tps65217 *tps = platform_get_drvdata(pdev);
+       unsigned int i;
+
+       for (i = 0; i < TPS65217_NUM_REGULATOR; i++)
+               regulator_unregister(tps->rdev[i]);
 
        platform_set_drvdata(pdev, NULL);
-       regulator_unregister(rdev);
 
        return 0;
 }
index 590cfaf..1859f71 100644 (file)
@@ -1008,8 +1008,8 @@ static int rpmsg_probe(struct virtio_device *vdev)
        return 0;
 
 free_coherent:
-       dma_free_coherent(vdev->dev.parent, RPMSG_TOTAL_BUF_SPACE, bufs_va,
-                                       vrp->bufs_dma);
+       dma_free_coherent(vdev->dev.parent->parent, RPMSG_TOTAL_BUF_SPACE,
+                                       bufs_va, vrp->bufs_dma);
 vqs_del:
        vdev->config->del_vqs(vrp->vdev);
 free_vrp:
@@ -1043,7 +1043,7 @@ static void __devexit rpmsg_remove(struct virtio_device *vdev)
 
        vdev->config->del_vqs(vrp->vdev);
 
-       dma_free_coherent(vdev->dev.parent, RPMSG_TOTAL_BUF_SPACE,
+       dma_free_coherent(vdev->dev.parent->parent, RPMSG_TOTAL_BUF_SPACE,
                                        vrp->rbufs, vrp->bufs_dma);
 
        kfree(vrp);
index c5d06fe..9277d94 100644 (file)
@@ -495,6 +495,11 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev)
        if (ret < 0)
                goto out1;
 
+       /* ensure interrupts are disabled, bootloaders can be strange */
+       ret = twl_rtc_write_u8(0, REG_RTC_INTERRUPTS_REG);
+       if (ret < 0)
+               dev_warn(&pdev->dev, "unable to disable interrupt\n");
+
        /* init cached IRQ enable bits */
        ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG);
        if (ret < 0)
index 15370a2..0595c76 100644 (file)
@@ -534,11 +534,11 @@ static void dasd_change_state(struct dasd_device *device)
        if (rc)
                device->target = device->state;
 
-       if (device->state == device->target)
-               wake_up(&dasd_init_waitq);
-
        /* let user-space know that the device status changed */
        kobject_uevent(&device->cdev->dev.kobj, KOBJ_CHANGE);
+
+       if (device->state == device->target)
+               wake_up(&dasd_init_waitq);
 }
 
 /*
@@ -2157,6 +2157,7 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible)
                    test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) &&
                    (!dasd_eer_enabled(device))) {
                        cqr->status = DASD_CQR_FAILED;
+                       cqr->intrc = -EAGAIN;
                        continue;
                }
                /* Don't try to start requests if device is stopped */
@@ -3270,6 +3271,16 @@ void dasd_generic_path_event(struct ccw_device *cdev, int *path_event)
                        dasd_schedule_device_bh(device);
                }
                if (path_event[chp] & PE_PATHGROUP_ESTABLISHED) {
+                       if (!(device->path_data.opm & eventlpm) &&
+                           !(device->path_data.tbvpm & eventlpm)) {
+                               /*
+                                * we can not establish a pathgroup on an
+                                * unavailable path, so trigger a path
+                                * verification first
+                                */
+                               device->path_data.tbvpm |= eventlpm;
+                               dasd_schedule_device_bh(device);
+                       }
                        DBF_DEV_EVENT(DBF_WARNING, device, "%s",
                                      "Pathgroup re-established\n");
                        if (device->discipline->kick_validate)
index 157defe..6b55699 100644 (file)
@@ -384,6 +384,29 @@ static void _remove_device_from_lcu(struct alias_lcu *lcu,
                group->next = NULL;
 };
 
+static int
+suborder_not_supported(struct dasd_ccw_req *cqr)
+{
+       char *sense;
+       char reason;
+       char msg_format;
+       char msg_no;
+
+       sense = dasd_get_sense(&cqr->irb);
+       if (!sense)
+               return 0;
+
+       reason = sense[0];
+       msg_format = (sense[7] & 0xF0);
+       msg_no = (sense[7] & 0x0F);
+
+       /* command reject, Format 0 MSG 4 - invalid parameter */
+       if ((reason == 0x80) && (msg_format == 0x00) && (msg_no == 0x04))
+               return 1;
+
+       return 0;
+}
+
 static int read_unit_address_configuration(struct dasd_device *device,
                                           struct alias_lcu *lcu)
 {
@@ -435,6 +458,8 @@ static int read_unit_address_configuration(struct dasd_device *device,
 
        do {
                rc = dasd_sleep_on(cqr);
+               if (rc && suborder_not_supported(cqr))
+                       return -EOPNOTSUPP;
        } while (rc && (cqr->retries > 0));
        if (rc) {
                spin_lock_irqsave(&lcu->lock, flags);
@@ -521,7 +546,7 @@ static void lcu_update_work(struct work_struct *work)
         * processing the data
         */
        spin_lock_irqsave(&lcu->lock, flags);
-       if (rc || (lcu->flags & NEED_UAC_UPDATE)) {
+       if ((rc && (rc != -EOPNOTSUPP)) || (lcu->flags & NEED_UAC_UPDATE)) {
                DBF_DEV_EVENT(DBF_WARNING, device, "could not update"
                            " alias data in lcu (rc = %d), retry later", rc);
                schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ);
index 2fb2b9e..c48c72a 100644 (file)
@@ -1507,7 +1507,8 @@ static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device,
  * call might change behaviour of DASD devices.
  */
 static int
-dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav)
+dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav,
+                 unsigned long flags)
 {
        struct dasd_ccw_req *cqr;
        int rc;
@@ -1516,10 +1517,19 @@ dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav)
        if (IS_ERR(cqr))
                return PTR_ERR(cqr);
 
+       /*
+        * set flags e.g. turn on failfast, to prevent blocking
+        * the calling function should handle failed requests
+        */
+       cqr->flags |= flags;
+
        rc = dasd_sleep_on(cqr);
        if (!rc)
                /* trigger CIO to reprobe devices */
                css_schedule_reprobe();
+       else if (cqr->intrc == -EAGAIN)
+               rc = -EAGAIN;
+
        dasd_sfree_request(cqr, cqr->memdev);
        return rc;
 }
@@ -1527,7 +1537,8 @@ dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav)
 /*
  * Valide storage server of current device.
  */
-static void dasd_eckd_validate_server(struct dasd_device *device)
+static int dasd_eckd_validate_server(struct dasd_device *device,
+                                    unsigned long flags)
 {
        int rc;
        struct dasd_eckd_private *private;
@@ -1536,17 +1547,18 @@ static void dasd_eckd_validate_server(struct dasd_device *device)
        private = (struct dasd_eckd_private *) device->private;
        if (private->uid.type == UA_BASE_PAV_ALIAS ||
            private->uid.type == UA_HYPER_PAV_ALIAS)
-               return;
+               return 0;
        if (dasd_nopav || MACHINE_IS_VM)
                enable_pav = 0;
        else
                enable_pav = 1;
-       rc = dasd_eckd_psf_ssc(device, enable_pav);
+       rc = dasd_eckd_psf_ssc(device, enable_pav, flags);
 
        /* may be requested feature is not available on server,
         * therefore just report error and go ahead */
        DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "PSF-SSC for SSID %04x "
                        "returned rc=%d", private->uid.ssid, rc);
+       return rc;
 }
 
 /*
@@ -1556,7 +1568,13 @@ static void dasd_eckd_do_validate_server(struct work_struct *work)
 {
        struct dasd_device *device = container_of(work, struct dasd_device,
                                                  kick_validate);
-       dasd_eckd_validate_server(device);
+       if (dasd_eckd_validate_server(device, DASD_CQR_FLAGS_FAILFAST)
+           == -EAGAIN) {
+               /* schedule worker again if failed */
+               schedule_work(&device->kick_validate);
+               return;
+       }
+
        dasd_put_device(device);
 }
 
@@ -1685,7 +1703,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
        if (rc)
                goto out_err2;
 
-       dasd_eckd_validate_server(device);
+       dasd_eckd_validate_server(device, 0);
 
        /* device may report different configuration data after LCU setup */
        rc = dasd_eckd_read_conf(device);
@@ -4153,7 +4171,7 @@ static int dasd_eckd_restore_device(struct dasd_device *device)
        rc = dasd_alias_make_device_known_to_lcu(device);
        if (rc)
                return rc;
-       dasd_eckd_validate_server(device);
+       dasd_eckd_validate_server(device, DASD_CQR_FLAGS_FAILFAST);
 
        /* RE-Read Configuration Data */
        rc = dasd_eckd_read_conf(device);
index ed25c87..fc916f5 100644 (file)
@@ -1426,6 +1426,8 @@ static enum io_sch_action sch_get_action(struct subchannel *sch)
                return IO_SCH_REPROBE;
        if (cdev->online)
                return IO_SCH_VERIFY;
+       if (cdev->private->state == DEV_STATE_NOT_OPER)
+               return IO_SCH_UNREG_ATTACH;
        return IO_SCH_NOP;
 }
 
@@ -1519,11 +1521,14 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process)
                        goto out;
                break;
        case IO_SCH_UNREG_ATTACH:
+               spin_lock_irqsave(sch->lock, flags);
                if (cdev->private->flags.resuming) {
                        /* Device will be handled later. */
                        rc = 0;
-                       goto out;
+                       goto out_unlock;
                }
+               sch_set_cdev(sch, NULL);
+               spin_unlock_irqrestore(sch->lock, flags);
                /* Unregister ccw device. */
                ccw_device_unregister(cdev);
                break;
index 32c26d7..8f32a13 100644 (file)
@@ -355,7 +355,7 @@ int __init register_intc_controller(struct intc_desc *desc)
                        if (unlikely(res)) {
                                if (res == -EEXIST) {
                                        res = irq_domain_associate(d->domain,
-                                                                  irq, irq);
+                                                                  irq2, irq2);
                                        if (unlikely(res)) {
                                                pr_err("domain association "
                                                       "failure\n");
index 2804eaa..a3ac39b 100644 (file)
@@ -211,7 +211,8 @@ static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev,
                break;
        default:
                pr_err("Unsupported mux type (%d), bailing...\n", pinmux_type);
-               return -ENOTSUPP;
+               ret = -ENOTSUPP;
+               goto err;
        }
 
        ret = 0;
index 695ea35..d0a7e40 100644 (file)
@@ -837,7 +837,7 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev)
        }
 
        ret = mfd_add_devices(nvec->dev, -1, nvec_devices,
-                             ARRAY_SIZE(nvec_devices), base, 0);
+                             ARRAY_SIZE(nvec_devices), base, 0, NULL);
        if (ret)
                dev_err(nvec->dev, "error adding subdevices\n");
 
index 0694d9b..6aba439 100644 (file)
@@ -221,6 +221,7 @@ static int iscsi_login_zero_tsih_s1(
 {
        struct iscsi_session *sess = NULL;
        struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf;
+       int ret;
 
        sess = kzalloc(sizeof(struct iscsi_session), GFP_KERNEL);
        if (!sess) {
@@ -257,9 +258,17 @@ static int iscsi_login_zero_tsih_s1(
                return -ENOMEM;
        }
        spin_lock(&sess_idr_lock);
-       idr_get_new(&sess_idr, NULL, &sess->session_index);
+       ret = idr_get_new(&sess_idr, NULL, &sess->session_index);
        spin_unlock(&sess_idr_lock);
 
+       if (ret < 0) {
+               pr_err("idr_get_new() for sess_idr failed\n");
+               iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
+                               ISCSI_LOGIN_STATUS_NO_RESOURCES);
+               kfree(sess);
+               return -ENOMEM;
+       }
+
        sess->creation_time = get_jiffies_64();
        spin_lock_init(&sess->session_stats_lock);
        /*
index 9179997..41641ba 100644 (file)
@@ -218,6 +218,13 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd)
                cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
                return -EINVAL;
        }
+       if (cmd->data_length < 4) {
+               pr_warn("SET TARGET PORT GROUPS parameter list length %u too"
+                       " small\n", cmd->data_length);
+               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+               return -EINVAL;
+       }
+
        buf = transport_kmap_data_sg(cmd);
 
        /*
index cf2c66f..9fc9a60 100644 (file)
@@ -669,6 +669,13 @@ int target_report_luns(struct se_cmd *se_cmd)
        unsigned char *buf;
        u32 lun_count = 0, offset = 8, i;
 
+       if (se_cmd->data_length < 16) {
+               pr_warn("REPORT LUNS allocation length %u too small\n",
+                       se_cmd->data_length);
+               se_cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
+               return -EINVAL;
+       }
+
        buf = transport_kmap_data_sg(se_cmd);
        if (!buf)
                return -ENOMEM;
index 76db75e..9ba4954 100644 (file)
@@ -325,17 +325,30 @@ static int iblock_execute_unmap(struct se_cmd *cmd)
        struct iblock_dev *ibd = dev->dev_ptr;
        unsigned char *buf, *ptr = NULL;
        sector_t lba;
-       int size = cmd->data_length;
+       int size;
        u32 range;
        int ret = 0;
        int dl, bd_dl;
 
+       if (cmd->data_length < 8) {
+               pr_warn("UNMAP parameter list length %u too small\n",
+                       cmd->data_length);
+               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+               return -EINVAL;
+       }
+
        buf = transport_kmap_data_sg(cmd);
 
        dl = get_unaligned_be16(&buf[0]);
        bd_dl = get_unaligned_be16(&buf[2]);
 
-       size = min(size - 8, bd_dl);
+       size = cmd->data_length - 8;
+       if (bd_dl > size)
+               pr_warn("UNMAP parameter list length %u too small, ignoring bd_dl %u\n",
+                       cmd->data_length, bd_dl);
+       else
+               size = bd_dl;
+
        if (size / 16 > dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) {
                cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
                ret = -EINVAL;
index 1e94650..956c84c 100644 (file)
@@ -1540,6 +1540,14 @@ static int core_scsi3_decode_spec_i_port(
        tidh_new->dest_local_nexus = 1;
        list_add_tail(&tidh_new->dest_list, &tid_dest_list);
 
+       if (cmd->data_length < 28) {
+               pr_warn("SPC-PR: Received PR OUT parameter list"
+                       " length too small: %u\n", cmd->data_length);
+               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+               ret = -EINVAL;
+               goto out;
+       }
+
        buf = transport_kmap_data_sg(cmd);
        /*
         * For a PERSISTENT RESERVE OUT specify initiator ports payload,
index 5552fa7..9d7ce3d 100644 (file)
@@ -667,7 +667,8 @@ static void pscsi_free_device(void *p)
        kfree(pdv);
 }
 
-static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg)
+static void pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg,
+                                    unsigned char *sense_buffer)
 {
        struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr;
        struct scsi_device *sd = pdv->pdv_sd;
@@ -679,7 +680,7 @@ static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg)
         * not been allocated because TCM is handling the emulation directly.
         */
        if (!pt)
-               return 0;
+               return;
 
        cdb = &pt->pscsi_cdb[0];
        result = pt->pscsi_result;
@@ -687,11 +688,11 @@ static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg)
         * Hack to make sure that Write-Protect modepage is set if R/O mode is
         * forced.
         */
+       if (!cmd->se_deve || !cmd->data_length)
+               goto after_mode_sense;
+
        if (((cdb[0] == MODE_SENSE) || (cdb[0] == MODE_SENSE_10)) &&
             (status_byte(result) << 1) == SAM_STAT_GOOD) {
-               if (!cmd->se_deve)
-                       goto after_mode_sense;
-
                if (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) {
                        unsigned char *buf = transport_kmap_data_sg(cmd);
 
@@ -708,7 +709,7 @@ static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg)
        }
 after_mode_sense:
 
-       if (sd->type != TYPE_TAPE)
+       if (sd->type != TYPE_TAPE || !cmd->data_length)
                goto after_mode_select;
 
        /*
@@ -750,10 +751,10 @@ after_mode_sense:
        }
 after_mode_select:
 
-       if (status_byte(result) & CHECK_CONDITION)
-               return 1;
-
-       return 0;
+       if (sense_buffer && (status_byte(result) & CHECK_CONDITION)) {
+               memcpy(sense_buffer, pt->pscsi_sense, TRANSPORT_SENSE_BUFFER);
+               cmd->se_cmd_flags |= SCF_TRANSPORT_TASK_SENSE;
+       }
 }
 
 enum {
@@ -1184,13 +1185,6 @@ fail:
        return -ENOMEM;
 }
 
-static unsigned char *pscsi_get_sense_buffer(struct se_cmd *cmd)
-{
-       struct pscsi_plugin_task *pt = cmd->priv;
-
-       return pt->pscsi_sense;
-}
-
 /*     pscsi_get_device_rev():
  *
  *
@@ -1273,7 +1267,6 @@ static struct se_subsystem_api pscsi_template = {
        .check_configfs_dev_params = pscsi_check_configfs_dev_params,
        .set_configfs_dev_params = pscsi_set_configfs_dev_params,
        .show_configfs_dev_params = pscsi_show_configfs_dev_params,
-       .get_sense_buffer       = pscsi_get_sense_buffer,
        .get_device_rev         = pscsi_get_device_rev,
        .get_device_type        = pscsi_get_device_type,
        .get_blocks             = pscsi_get_blocks,
index 4c861de..388a922 100644 (file)
@@ -877,9 +877,11 @@ static int spc_emulate_modesense(struct se_cmd *cmd)
 static int spc_emulate_request_sense(struct se_cmd *cmd)
 {
        unsigned char *cdb = cmd->t_task_cdb;
-       unsigned char *buf;
+       unsigned char *rbuf;
        u8 ua_asc = 0, ua_ascq = 0;
-       int err = 0;
+       unsigned char buf[SE_SENSE_BUF];
+
+       memset(buf, 0, SE_SENSE_BUF);
 
        if (cdb[1] & 0x01) {
                pr_err("REQUEST_SENSE description emulation not"
@@ -888,20 +890,21 @@ static int spc_emulate_request_sense(struct se_cmd *cmd)
                return -ENOSYS;
        }
 
-       buf = transport_kmap_data_sg(cmd);
-
-       if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) {
+       rbuf = transport_kmap_data_sg(cmd);
+       if (cmd->scsi_sense_reason != 0) {
+               /*
+                * Out of memory.  We will fail with CHECK CONDITION, so
+                * we must not clear the unit attention condition.
+                */
+               target_complete_cmd(cmd, CHECK_CONDITION);
+               return 0;
+       } else if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) {
                /*
                 * CURRENT ERROR, UNIT ATTENTION
                 */
                buf[0] = 0x70;
                buf[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION;
 
-               if (cmd->data_length < 18) {
-                       buf[7] = 0x00;
-                       err = -EINVAL;
-                       goto end;
-               }
                /*
                 * The Additional Sense Code (ASC) from the UNIT ATTENTION
                 */
@@ -915,11 +918,6 @@ static int spc_emulate_request_sense(struct se_cmd *cmd)
                buf[0] = 0x70;
                buf[SPC_SENSE_KEY_OFFSET] = NO_SENSE;
 
-               if (cmd->data_length < 18) {
-                       buf[7] = 0x00;
-                       err = -EINVAL;
-                       goto end;
-               }
                /*
                 * NO ADDITIONAL SENSE INFORMATION
                 */
@@ -927,8 +925,11 @@ static int spc_emulate_request_sense(struct se_cmd *cmd)
                buf[7] = 0x0A;
        }
 
-end:
-       transport_kunmap_data_sg(cmd);
+       if (rbuf) {
+               memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
+               transport_kunmap_data_sg(cmd);
+       }
+
        target_complete_cmd(cmd, GOOD);
        return 0;
 }
index 4de3186..269f544 100644 (file)
@@ -567,6 +567,34 @@ static void target_complete_failure_work(struct work_struct *work)
        transport_generic_request_failure(cmd);
 }
 
+/*
+ * Used when asking transport to copy Sense Data from the underlying
+ * Linux/SCSI struct scsi_cmnd
+ */
+static unsigned char *transport_get_sense_buffer(struct se_cmd *cmd)
+{
+       unsigned char *buffer = cmd->sense_buffer;
+       struct se_device *dev = cmd->se_dev;
+       u32 offset = 0;
+
+       WARN_ON(!cmd->se_lun);
+
+       if (!dev)
+               return NULL;
+
+       if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION)
+               return NULL;
+
+       offset = cmd->se_tfo->set_fabric_sense_len(cmd, TRANSPORT_SENSE_BUFFER);
+
+       /* Automatically padded */
+       cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset;
+
+       pr_debug("HBA_[%u]_PLUG[%s]: Requesting sense for SAM STATUS: 0x%02x\n",
+               dev->se_hba->hba_id, dev->transport->name, cmd->scsi_status);
+       return &buffer[offset];
+}
+
 void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)
 {
        struct se_device *dev = cmd->se_dev;
@@ -580,11 +608,11 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)
        cmd->transport_state &= ~CMD_T_BUSY;
 
        if (dev && dev->transport->transport_complete) {
-               if (dev->transport->transport_complete(cmd,
-                               cmd->t_data_sg) != 0) {
-                       cmd->se_cmd_flags |= SCF_TRANSPORT_TASK_SENSE;
+               dev->transport->transport_complete(cmd,
+                               cmd->t_data_sg,
+                               transport_get_sense_buffer(cmd));
+               if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE)
                        success = 1;
-               }
        }
 
        /*
@@ -1181,15 +1209,20 @@ int target_cmd_size_check(struct se_cmd *cmd, unsigned int size)
                        /* Returns CHECK_CONDITION + INVALID_CDB_FIELD */
                        goto out_invalid_cdb_field;
                }
-
+               /*
+                * For the overflow case keep the existing fabric provided
+                * ->data_length.  Otherwise for the underflow case, reset
+                * ->data_length to the smaller SCSI expected data transfer
+                * length.
+                */
                if (size > cmd->data_length) {
                        cmd->se_cmd_flags |= SCF_OVERFLOW_BIT;
                        cmd->residual_count = (size - cmd->data_length);
                } else {
                        cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT;
                        cmd->residual_count = (cmd->data_length - size);
+                       cmd->data_length = size;
                }
-               cmd->data_length = size;
        }
 
        return 0;
@@ -1815,61 +1848,6 @@ execute:
 }
 EXPORT_SYMBOL(target_execute_cmd);
 
-/*
- * Used to obtain Sense Data from underlying Linux/SCSI struct scsi_cmnd
- */
-static int transport_get_sense_data(struct se_cmd *cmd)
-{
-       unsigned char *buffer = cmd->sense_buffer, *sense_buffer = NULL;
-       struct se_device *dev = cmd->se_dev;
-       unsigned long flags;
-       u32 offset = 0;
-
-       WARN_ON(!cmd->se_lun);
-
-       if (!dev)
-               return 0;
-
-       spin_lock_irqsave(&cmd->t_state_lock, flags);
-       if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) {
-               spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-               return 0;
-       }
-
-       if (!(cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE))
-               goto out;
-
-       if (!dev->transport->get_sense_buffer) {
-               pr_err("dev->transport->get_sense_buffer is NULL\n");
-               goto out;
-       }
-
-       sense_buffer = dev->transport->get_sense_buffer(cmd);
-       if (!sense_buffer) {
-               pr_err("ITT 0x%08x cmd %p: Unable to locate"
-                       " sense buffer for task with sense\n",
-                       cmd->se_tfo->get_task_tag(cmd), cmd);
-               goto out;
-       }
-
-       spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-
-       offset = cmd->se_tfo->set_fabric_sense_len(cmd, TRANSPORT_SENSE_BUFFER);
-
-       memcpy(&buffer[offset], sense_buffer, TRANSPORT_SENSE_BUFFER);
-
-       /* Automatically padded */
-       cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset;
-
-       pr_debug("HBA_[%u]_PLUG[%s]: Set SAM STATUS: 0x%02x and sense\n",
-               dev->se_hba->hba_id, dev->transport->name, cmd->scsi_status);
-       return 0;
-
-out:
-       spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-       return -1;
-}
-
 /*
  * Process all commands up to the last received ORDERED task attribute which
  * requires another blocking boundary
@@ -1985,7 +1963,7 @@ static void transport_handle_queue_full(
 static void target_complete_ok_work(struct work_struct *work)
 {
        struct se_cmd *cmd = container_of(work, struct se_cmd, work);
-       int reason = 0, ret;
+       int ret;
 
        /*
         * Check if we need to move delayed/dormant tasks from cmds on the
@@ -2002,23 +1980,19 @@ static void target_complete_ok_work(struct work_struct *work)
                schedule_work(&cmd->se_dev->qf_work_queue);
 
        /*
-        * Check if we need to retrieve a sense buffer from
+        * Check if we need to send a sense buffer from
         * the struct se_cmd in question.
         */
        if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) {
-               if (transport_get_sense_data(cmd) < 0)
-                       reason = TCM_NON_EXISTENT_LUN;
-
-               if (cmd->scsi_status) {
-                       ret = transport_send_check_condition_and_sense(
-                                       cmd, reason, 1);
-                       if (ret == -EAGAIN || ret == -ENOMEM)
-                               goto queue_full;
+               WARN_ON(!cmd->scsi_status);
+               ret = transport_send_check_condition_and_sense(
+                                       cmd, 0, 1);
+               if (ret == -EAGAIN || ret == -ENOMEM)
+                       goto queue_full;
 
-                       transport_lun_remove_cmd(cmd);
-                       transport_cmd_check_stop_to_fabric(cmd);
-                       return;
-               }
+               transport_lun_remove_cmd(cmd);
+               transport_cmd_check_stop_to_fabric(cmd);
+               return;
        }
        /*
         * Check for a callback, used by amongst other things
@@ -2216,7 +2190,6 @@ void *transport_kmap_data_sg(struct se_cmd *cmd)
        struct page **pages;
        int i;
 
-       BUG_ON(!sg);
        /*
         * We need to take into account a possible offset here for fabrics like
         * tcm_loop who may be using a contig buffer from the SCSI midlayer for
@@ -2224,13 +2197,17 @@ void *transport_kmap_data_sg(struct se_cmd *cmd)
         */
        if (!cmd->t_data_nents)
                return NULL;
-       else if (cmd->t_data_nents == 1)
+
+       BUG_ON(!sg);
+       if (cmd->t_data_nents == 1)
                return kmap(sg_page(sg)) + sg->offset;
 
        /* >1 page. use vmap */
        pages = kmalloc(sizeof(*pages) * cmd->t_data_nents, GFP_KERNEL);
-       if (!pages)
+       if (!pages) {
+               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
                return NULL;
+       }
 
        /* convert sg[] to pages[] */
        for_each_sg(cmd->t_data_sg, sg, cmd->t_data_nents, i) {
@@ -2239,8 +2216,10 @@ void *transport_kmap_data_sg(struct se_cmd *cmd)
 
        cmd->t_data_vmap = vmap(pages, cmd->t_data_nents,  VM_MAP, PAGE_KERNEL);
        kfree(pages);
-       if (!cmd->t_data_vmap)
+       if (!cmd->t_data_vmap) {
+               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
                return NULL;
+       }
 
        return cmd->t_data_vmap + cmd->t_data_sg[0].offset;
 }
@@ -2326,19 +2305,14 @@ int transport_generic_new_cmd(struct se_cmd *cmd)
         * into the fabric for data transfers, go ahead and complete it right
         * away.
         */
-       if (!cmd->data_length) {
+       if (!cmd->data_length &&
+           cmd->t_task_cdb[0] != REQUEST_SENSE &&
+           cmd->se_dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV) {
                spin_lock_irq(&cmd->t_state_lock);
                cmd->t_state = TRANSPORT_COMPLETE;
                cmd->transport_state |= CMD_T_ACTIVE;
                spin_unlock_irq(&cmd->t_state_lock);
 
-               if (cmd->t_task_cdb[0] == REQUEST_SENSE) {
-                       u8 ua_asc = 0, ua_ascq = 0;
-
-                       core_scsi3_ua_clear_for_request_sense(cmd,
-                                       &ua_asc, &ua_ascq);
-               }
-
                INIT_WORK(&cmd->work, target_complete_ok_work);
                queue_work(target_completion_wq, &cmd->work);
                return 0;
index 1eff743..ae60406 100644 (file)
@@ -814,6 +814,9 @@ static int __devinit hpwdt_init_one(struct pci_dev *dev,
        hpwdt_timer_reg = pci_mem_addr + 0x70;
        hpwdt_timer_con = pci_mem_addr + 0x72;
 
+       /* Make sure that timer is disabled until /dev/watchdog is opened */
+       hpwdt_stop();
+
        /* Make sure that we have a valid soft_margin */
        if (hpwdt_change_timer(soft_margin))
                hpwdt_change_timer(DEFAULT_MARGIN);
index 6aa46a9..3796434 100644 (file)
@@ -128,11 +128,12 @@ EXPORT_SYMBOL_GPL(watchdog_register_device);
 void watchdog_unregister_device(struct watchdog_device *wdd)
 {
        int ret;
-       int devno = wdd->cdev.dev;
+       int devno;
 
        if (wdd == NULL)
                return;
 
+       devno = wdd->cdev.dev;
        ret = watchdog_dev_unregister(wdd);
        if (ret)
                pr_err("error unregistering /dev/watchdog (err=%d)\n", ret);
index 1ffd03b..7f12416 100644 (file)
@@ -314,8 +314,9 @@ static int __unmap_grant_pages(struct grant_map *map, int offset, int pages)
                }
        }
 
-       err = gnttab_unmap_refs(map->unmap_ops + offset, map->pages + offset,
-                               pages, true);
+       err = gnttab_unmap_refs(map->unmap_ops + offset,
+                       use_ptemod ? map->kmap_ops + offset : NULL, map->pages + offset,
+                       pages);
        if (err)
                return err;
 
index 0bfc1ef..0067266 100644 (file)
@@ -870,7 +870,8 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
 EXPORT_SYMBOL_GPL(gnttab_map_refs);
 
 int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
-                     struct page **pages, unsigned int count, bool clear_pte)
+                     struct gnttab_map_grant_ref *kmap_ops,
+                     struct page **pages, unsigned int count)
 {
        int i, ret;
        bool lazy = false;
@@ -888,7 +889,8 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
        }
 
        for (i = 0; i < count; i++) {
-               ret = m2p_remove_override(pages[i], clear_pte);
+               ret = m2p_remove_override(pages[i], kmap_ops ?
+                                      &kmap_ops[i] : NULL);
                if (ret)
                        return ret;
        }
index 38b42e7..b650155 100644 (file)
@@ -1371,10 +1371,8 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
 
        if (srcid) {
                srcgroup = find_qgroup_rb(fs_info, srcid);
-               if (!srcgroup) {
-                       ret = -EINVAL;
+               if (!srcgroup)
                        goto unlock;
-               }
                dstgroup->rfer = srcgroup->rfer - level_size;
                dstgroup->rfer_cmpr = srcgroup->rfer_cmpr - level_size;
                srcgroup->excl = level_size;
@@ -1383,10 +1381,8 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
                qgroup_dirty(fs_info, srcgroup);
        }
 
-       if (!inherit) {
-               ret = -EINVAL;
+       if (!inherit)
                goto unlock;
-       }
 
        i_qgroups = (u64 *)(inherit + 1);
        for (i = 0; i < inherit->num_qgroups; ++i) {
index 7dab9c0..53cf2aa 100644 (file)
@@ -328,7 +328,7 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
        }
 
 ctoUTF16_out:
-       return i;
+       return j;
 }
 
 #ifdef CONFIG_CIFS_SMB2
index 8086636..16521a9 100644 (file)
@@ -389,7 +389,7 @@ static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent)
         * Inform try_to_ascend() that we are no longer attached to the
         * dentry tree
         */
-       dentry->d_flags |= DCACHE_DISCONNECTED;
+       dentry->d_flags |= DCACHE_DENTRY_KILLED;
        if (parent)
                spin_unlock(&parent->d_lock);
        dentry_iput(dentry);
@@ -1048,7 +1048,7 @@ static struct dentry *try_to_ascend(struct dentry *old, int locked, unsigned seq
         * or deletion
         */
        if (new != old->d_parent ||
-                (old->d_flags & DCACHE_DISCONNECTED) ||
+                (old->d_flags & DCACHE_DENTRY_KILLED) ||
                 (!locked && read_seqretry(&rename_lock, seq))) {
                spin_unlock(&new->d_lock);
                new = NULL;
index 2340f69..c5ca6ae 100644 (file)
@@ -526,73 +526,51 @@ struct array_data {
        u32 elements;
 };
 
-static int u32_array_open(struct inode *inode, struct file *file)
-{
-       file->private_data = NULL;
-       return nonseekable_open(inode, file);
-}
-
-static size_t format_array(char *buf, size_t bufsize, const char *fmt,
-                          u32 *array, u32 array_size)
+static size_t u32_format_array(char *buf, size_t bufsize,
+                              u32 *array, int array_size)
 {
        size_t ret = 0;
-       u32 i;
 
-       for (i = 0; i < array_size; i++) {
+       while (--array_size >= 0) {
                size_t len;
+               char term = array_size ? ' ' : '\n';
 
-               len = snprintf(buf, bufsize, fmt, array[i]);
-               len++;  /* ' ' or '\n' */
+               len = snprintf(buf, bufsize, "%u%c", *array++, term);
                ret += len;
 
-               if (buf) {
-                       buf += len;
-                       bufsize -= len;
-                       buf[-1] = (i == array_size-1) ? '\n' : ' ';
-               }
+               buf += len;
+               bufsize -= len;
        }
-
-       ret++;          /* \0 */
-       if (buf)
-               *buf = '\0';
-
        return ret;
 }
 
-static char *format_array_alloc(const char *fmt, u32 *array,
-                                               u32 array_size)
+static int u32_array_open(struct inode *inode, struct file *file)
 {
-       size_t len = format_array(NULL, 0, fmt, array, array_size);
-       char *ret;
-
-       ret = kmalloc(len, GFP_KERNEL);
-       if (ret == NULL)
-               return NULL;
+       struct array_data *data = inode->i_private;
+       int size, elements = data->elements;
+       char *buf;
+
+       /*
+        * Max size:
+        *  - 10 digits + ' '/'\n' = 11 bytes per number
+        *  - terminating NUL character
+        */
+       size = elements*11;
+       buf = kmalloc(size+1, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+       buf[size] = 0;
+
+       file->private_data = buf;
+       u32_format_array(buf, size, data->array, data->elements);
 
-       format_array(ret, len, fmt, array, array_size);
-       return ret;
+       return nonseekable_open(inode, file);
 }
 
 static ssize_t u32_array_read(struct file *file, char __user *buf, size_t len,
                              loff_t *ppos)
 {
-       struct inode *inode = file->f_path.dentry->d_inode;
-       struct array_data *data = inode->i_private;
-       size_t size;
-
-       if (*ppos == 0) {
-               if (file->private_data) {
-                       kfree(file->private_data);
-                       file->private_data = NULL;
-               }
-
-               file->private_data = format_array_alloc("%u", data->array,
-                                                             data->elements);
-       }
-
-       size = 0;
-       if (file->private_data)
-               size = strlen(file->private_data);
+       size_t size = strlen(file->private_data);
 
        return simple_read_from_buffer(buf, len, ppos,
                                        file->private_data, size);
index dfafeb2..eb7cc91 100644 (file)
@@ -462,9 +462,6 @@ static struct dentry *proc_sys_lookup(struct inode *dir, struct dentry *dentry,
 
        err = ERR_PTR(-ENOMEM);
        inode = proc_sys_make_inode(dir->i_sb, h ? h : head, p);
-       if (h)
-               sysctl_head_finish(h);
-
        if (!inode)
                goto out;
 
@@ -473,6 +470,8 @@ static struct dentry *proc_sys_lookup(struct inode *dir, struct dentry *dentry,
        d_add(dentry, inode);
 
 out:
+       if (h)
+               sysctl_head_finish(h);
        sysctl_head_finish(head);
        return err;
 }
index d7a9dd7..933b793 100644 (file)
@@ -96,6 +96,7 @@ xfs_buf_lru_add(
                atomic_inc(&bp->b_hold);
                list_add_tail(&bp->b_lru, &btp->bt_lru);
                btp->bt_lru_nr++;
+               bp->b_lru_flags &= ~_XBF_LRU_DISPOSE;
        }
        spin_unlock(&btp->bt_lru_lock);
 }
@@ -154,7 +155,8 @@ xfs_buf_stale(
                struct xfs_buftarg *btp = bp->b_target;
 
                spin_lock(&btp->bt_lru_lock);
-               if (!list_empty(&bp->b_lru)) {
+               if (!list_empty(&bp->b_lru) &&
+                   !(bp->b_lru_flags & _XBF_LRU_DISPOSE)) {
                        list_del_init(&bp->b_lru);
                        btp->bt_lru_nr--;
                        atomic_dec(&bp->b_hold);
@@ -1501,6 +1503,7 @@ xfs_buftarg_shrink(
                 */
                list_move(&bp->b_lru, &dispose);
                btp->bt_lru_nr--;
+               bp->b_lru_flags |= _XBF_LRU_DISPOSE;
        }
        spin_unlock(&btp->bt_lru_lock);
 
index d03b73b..7c0b6a0 100644 (file)
@@ -38,27 +38,28 @@ typedef enum {
        XBRW_ZERO = 3,                  /* Zero target memory */
 } xfs_buf_rw_t;
 
-#define XBF_READ       (1 << 0) /* buffer intended for reading from device */
-#define XBF_WRITE      (1 << 1) /* buffer intended for writing to device */
-#define XBF_READ_AHEAD (1 << 2) /* asynchronous read-ahead */
-#define XBF_ASYNC      (1 << 4) /* initiator will not wait for completion */
-#define XBF_DONE       (1 << 5) /* all pages in the buffer uptodate */
-#define XBF_STALE      (1 << 6) /* buffer has been staled, do not find it */
+#define XBF_READ        (1 << 0) /* buffer intended for reading from device */
+#define XBF_WRITE       (1 << 1) /* buffer intended for writing to device */
+#define XBF_READ_AHEAD  (1 << 2) /* asynchronous read-ahead */
+#define XBF_ASYNC       (1 << 4) /* initiator will not wait for completion */
+#define XBF_DONE        (1 << 5) /* all pages in the buffer uptodate */
+#define XBF_STALE       (1 << 6) /* buffer has been staled, do not find it */
 
 /* I/O hints for the BIO layer */
-#define XBF_SYNCIO     (1 << 10)/* treat this buffer as synchronous I/O */
-#define XBF_FUA                (1 << 11)/* force cache write through mode */
-#define XBF_FLUSH      (1 << 12)/* flush the disk cache before a write */
+#define XBF_SYNCIO      (1 << 10)/* treat this buffer as synchronous I/O */
+#define XBF_FUA                 (1 << 11)/* force cache write through mode */
+#define XBF_FLUSH       (1 << 12)/* flush the disk cache before a write */
 
 /* flags used only as arguments to access routines */
-#define XBF_TRYLOCK    (1 << 16)/* lock requested, but do not wait */
-#define XBF_UNMAPPED   (1 << 17)/* do not map the buffer */
+#define XBF_TRYLOCK     (1 << 16)/* lock requested, but do not wait */
+#define XBF_UNMAPPED    (1 << 17)/* do not map the buffer */
 
 /* flags used only internally */
-#define _XBF_PAGES     (1 << 20)/* backed by refcounted pages */
-#define _XBF_KMEM      (1 << 21)/* backed by heap memory */
-#define _XBF_DELWRI_Q  (1 << 22)/* buffer on a delwri queue */
-#define _XBF_COMPOUND  (1 << 23)/* compound buffer */
+#define _XBF_PAGES      (1 << 20)/* backed by refcounted pages */
+#define _XBF_KMEM       (1 << 21)/* backed by heap memory */
+#define _XBF_DELWRI_Q   (1 << 22)/* buffer on a delwri queue */
+#define _XBF_COMPOUND   (1 << 23)/* compound buffer */
+#define _XBF_LRU_DISPOSE (1 << 24)/* buffer being discarded */
 
 typedef unsigned int xfs_buf_flags_t;
 
@@ -72,12 +73,13 @@ typedef unsigned int xfs_buf_flags_t;
        { XBF_SYNCIO,           "SYNCIO" }, \
        { XBF_FUA,              "FUA" }, \
        { XBF_FLUSH,            "FLUSH" }, \
-       { XBF_TRYLOCK,          "TRYLOCK" },    /* should never be set */\
+       { XBF_TRYLOCK,          "TRYLOCK" },    /* should never be set */\
        { XBF_UNMAPPED,         "UNMAPPED" },   /* ditto */\
        { _XBF_PAGES,           "PAGES" }, \
        { _XBF_KMEM,            "KMEM" }, \
        { _XBF_DELWRI_Q,        "DELWRI_Q" }, \
-       { _XBF_COMPOUND,        "COMPOUND" }
+       { _XBF_COMPOUND,        "COMPOUND" }, \
+       { _XBF_LRU_DISPOSE,     "LRU_DISPOSE" }
 
 typedef struct xfs_buftarg {
        dev_t                   bt_dev;
@@ -124,7 +126,12 @@ typedef struct xfs_buf {
        xfs_buf_flags_t         b_flags;        /* status flags */
        struct semaphore        b_sema;         /* semaphore for lockables */
 
+       /*
+        * concurrent access to b_lru and b_lru_flags are protected by
+        * bt_lru_lock and not by b_sema
+        */
        struct list_head        b_lru;          /* lru list */
+       xfs_buf_flags_t         b_lru_flags;    /* internal lru status flags */
        wait_queue_head_t       b_waiters;      /* unpin waiters */
        struct list_head        b_list;
        struct xfs_perag        *b_pag;         /* contains rbtree root */
index bdaf4cb..19e2380 100644 (file)
@@ -919,6 +919,7 @@ xfs_fs_put_super(
        struct xfs_mount        *mp = XFS_M(sb);
 
        xfs_filestream_unmount(mp);
+       cancel_delayed_work_sync(&mp->m_sync_work);
        xfs_unmountfs(mp);
        xfs_syncd_stop(mp);
        xfs_freesb(mp);
index 0602339..4eb3175 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <linux/platform_device.h>
 #include <linux/list.h>
+#include <linux/io.h>
 
 struct ssc_device {
        struct list_head        list;
index 2f40791..934bc34 100644 (file)
 #endif
 #endif
 
+#if __GNUC_MINOR__ >= 6
+/*
+ * Tell the optimizer that something else uses this function or variable.
+ */
+#define __visible __attribute__((externally_visible))
+#endif
+
 #if __GNUC_MINOR__ > 0
 #define __compiletime_object_size(obj) __builtin_object_size(obj, 0)
 #endif
index 923d093..f430e41 100644 (file)
@@ -278,6 +278,10 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
 # define __section(S) __attribute__ ((__section__(#S)))
 #endif
 
+#ifndef __visible
+#define __visible
+#endif
+
 /* Are two types/vars the same type (ignoring qualifiers)? */
 #ifndef __same_type
 # define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
index caa34e5..5920079 100644 (file)
@@ -206,6 +206,8 @@ struct dentry_operations {
 #define DCACHE_MANAGED_DENTRY \
        (DCACHE_MOUNTED|DCACHE_NEED_AUTOMOUNT|DCACHE_MANAGE_TRANSIT)
 
+#define DCACHE_DENTRY_KILLED   0x100000
+
 extern seqlock_t rename_lock;
 
 static inline int dname_external(struct dentry *dentry)
index 594b419..2451f1f 100644 (file)
@@ -91,7 +91,7 @@
 {                                                      \
        typeof(x) __x = x;                              \
        typeof(divisor) __d = divisor;                  \
-       (((typeof(x))-1) >= 0 || (__x) >= 0) ?          \
+       (((typeof(x))-1) > 0 || (__x) > 0) ?            \
                (((__x) + ((__d) / 2)) / (__d)) :       \
                (((__x) - ((__d) / 2)) / (__d));        \
 }                                                      \
index 1ac7f6e..ff9a9f8 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/compiler.h>
 #include <linux/mutex.h>
 
-#define MIN_MEMORY_BLOCK_SIZE     (1 << SECTION_SIZE_BITS)
+#define MIN_MEMORY_BLOCK_SIZE     (1UL << SECTION_SIZE_BITS)
 
 struct memory_block {
        unsigned long start_section_nr;
index 3a8435a..cebe97e 100644 (file)
@@ -16,6 +16,8 @@
 
 #include <linux/platform_device.h>
 
+struct irq_domain;
+
 /*
  * This struct describes the MFD part ("cell").
  * After registration the copy of this structure will become the platform data
@@ -98,7 +100,7 @@ static inline const struct mfd_cell *mfd_get_cell(struct platform_device *pdev)
 extern int mfd_add_devices(struct device *parent, int id,
                           struct mfd_cell *cells, int n_devs,
                           struct resource *mem_base,
-                          int irq_base);
+                          int irq_base, struct irq_domain *irq_domain);
 
 extern void mfd_remove_devices(struct device *parent);
 
index 12c0687..7cd83d8 100644 (file)
@@ -22,6 +22,9 @@
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 
+/* TPS chip id list */
+#define TPS65217                       0xF0
+
 /* I2C ID for TPS65217 part */
 #define TPS65217_I2C_ID                        0x24
 
@@ -248,13 +251,11 @@ struct tps_info {
 struct tps65217 {
        struct device *dev;
        struct tps65217_board *pdata;
+       unsigned int id;
        struct regulator_desc desc[TPS65217_NUM_REGULATOR];
        struct regulator_dev *rdev[TPS65217_NUM_REGULATOR];
        struct tps_info *info[TPS65217_NUM_REGULATOR];
        struct regmap *regmap;
-
-       /* Client devices */
-       struct platform_device *regulator_pdev[TPS65217_NUM_REGULATOR];
 };
 
 static inline struct tps65217 *dev_to_tps65217(struct device *dev)
@@ -262,6 +263,11 @@ static inline struct tps65217 *dev_to_tps65217(struct device *dev)
        return dev_get_drvdata(dev);
 }
 
+static inline int tps65217_chip_id(struct tps65217 *tps65217)
+{
+       return tps65217->id;
+}
+
 int tps65217_reg_read(struct tps65217 *tps, unsigned int reg,
                                        unsigned int *val);
 int tps65217_reg_write(struct tps65217 *tps, unsigned int reg,
index 33ed9d6..bdb4161 100644 (file)
@@ -274,6 +274,8 @@ struct perf_event_attr {
        __u64   branch_sample_type; /* enum branch_sample_type */
 };
 
+#define perf_flags(attr)       (*(&(attr)->read_format + 1))
+
 /*
  * Ioctls that can be done on a perf event fd:
  */
index b8c8664..23bddac 100644 (file)
@@ -954,7 +954,6 @@ struct sched_domain {
        unsigned int smt_gain;
        int flags;                      /* See SD_* */
        int level;
-       int idle_buddy;                 /* cpu assigned to select_idle_sibling() */
 
        /* Runtime fields. */
        unsigned long last_balance;     /* init to jiffies. units in jiffies */
index 22e61fd..28e493b 100644 (file)
@@ -84,6 +84,8 @@ struct xfrm_replay_state {
        __u32   bitmap;
 };
 
+#define XFRMA_REPLAY_ESN_MAX   4096
+
 struct xfrm_replay_state_esn {
        unsigned int    bmp_len;
        __u32           oseq;
index 0fedbd8..9fc7114 100644 (file)
@@ -111,9 +111,8 @@ struct rt6_info {
        struct inet6_dev                *rt6i_idev;
        unsigned long                   _rt6i_peer;
 
-#ifdef CONFIG_XFRM
-       u32                             rt6i_flow_cache_genid;
-#endif
+       u32                             rt6i_genid;
+
        /* more non-fragment space at head required */
        unsigned short                  rt6i_nfheader_len;
 
index ae1cd6c..fd87963 100644 (file)
@@ -102,6 +102,7 @@ struct net {
 #endif
        struct netns_ipvs       *ipvs;
        struct sock             *diag_nlsk;
+       atomic_t                rt_genid;
 };
 
 
@@ -300,5 +301,14 @@ static inline void unregister_net_sysctl_table(struct ctl_table_header *header)
 }
 #endif
 
+static inline int rt_genid(struct net *net)
+{
+       return atomic_read(&net->rt_genid);
+}
+
+static inline void rt_genid_bump(struct net *net)
+{
+       atomic_inc(&net->rt_genid);
+}
 
 #endif /* __NET_NET_NAMESPACE_H */
index 1474dd6..eb24dbc 100644 (file)
@@ -65,7 +65,6 @@ struct netns_ipv4 {
        unsigned int sysctl_ping_group_range[2];
        long sysctl_tcp_mem[3];
 
-       atomic_t rt_genid;
        atomic_t dev_addr_genid;
 
 #ifdef CONFIG_IP_MROUTE
index 776a27f..da22243 100644 (file)
@@ -108,7 +108,7 @@ extern struct ip_rt_acct __percpu *ip_rt_acct;
 
 struct in_device;
 extern int             ip_rt_init(void);
-extern void            rt_cache_flush(struct net *net, int how);
+extern void            rt_cache_flush(struct net *net);
 extern void            rt_flush_dev(struct net_device *dev);
 extern struct rtable *__ip_route_output_key(struct net *, struct flowi4 *flp);
 extern struct rtable *ip_route_output_flow(struct net *, struct flowi4 *flp,
index 72132ae..adb7da2 100644 (file)
@@ -1332,7 +1332,7 @@ static inline bool sk_wmem_schedule(struct sock *sk, int size)
 }
 
 static inline bool
-sk_rmem_schedule(struct sock *sk, struct sk_buff *skb, unsigned int size)
+sk_rmem_schedule(struct sock *sk, struct sk_buff *skb, int size)
 {
        if (!sk_has_account(sk))
                return true;
index f1405d3..941c84b 100644 (file)
@@ -23,7 +23,9 @@ struct se_subsystem_api {
        struct se_device *(*create_virtdevice)(struct se_hba *,
                                struct se_subsystem_dev *, void *);
        void (*free_device)(void *);
-       int (*transport_complete)(struct se_cmd *cmd, struct scatterlist *);
+       void (*transport_complete)(struct se_cmd *cmd,
+                                  struct scatterlist *,
+                                  unsigned char *);
 
        int (*parse_cdb)(struct se_cmd *cmd);
        ssize_t (*check_configfs_dev_params)(struct se_hba *,
index 015cea0..5be8937 100644 (file)
 
 #define SE_INQUIRY_BUF                         512
 #define SE_MODE_PAGE_BUF                       512
+#define SE_SENSE_BUF                           96
 
 /* struct se_hba->hba_flags */
 enum hba_flags_table {
index 5f889f1..08fa272 100644 (file)
@@ -214,7 +214,7 @@ TRACE_EVENT(mm_page_alloc,
 
        TP_printk("page=%p pfn=%lu order=%d migratetype=%d gfp_flags=%s",
                __entry->page,
-               page_to_pfn(__entry->page),
+               __entry->page ? page_to_pfn(__entry->page) : 0,
                __entry->order,
                __entry->migratetype,
                show_gfp_flags(__entry->gfp_flags))
@@ -240,7 +240,7 @@ DECLARE_EVENT_CLASS(mm_page,
 
        TP_printk("page=%p pfn=%lu order=%u migratetype=%d percpu_refill=%d",
                __entry->page,
-               page_to_pfn(__entry->page),
+               __entry->page ? page_to_pfn(__entry->page) : 0,
                __entry->order,
                __entry->migratetype,
                __entry->order == 0)
index 11e27c3..f19fff8 100644 (file)
@@ -187,6 +187,7 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
                    struct gnttab_map_grant_ref *kmap_ops,
                    struct page **pages, unsigned int count);
 int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
-                     struct page **pages, unsigned int count, bool clear_pte);
+                     struct gnttab_map_grant_ref *kunmap_ops,
+                     struct page **pages, unsigned int count);
 
 #endif /* __ASM_GNTTAB_H__ */
index b3c7fd5..6144bab 100644 (file)
@@ -232,15 +232,19 @@ static int pid_ns_ctl_handler(struct ctl_table *table, int write,
         */
 
        tmp.data = &current->nsproxy->pid_ns->last_pid;
-       return proc_dointvec(&tmp, write, buffer, lenp, ppos);
+       return proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
 }
 
+extern int pid_max;
+static int zero = 0;
 static struct ctl_table pid_ns_ctl_table[] = {
        {
                .procname = "ns_last_pid",
                .maxlen = sizeof(int),
                .mode = 0666, /* permissions are checked in the handler */
                .proc_handler = pid_ns_ctl_handler,
+               .extra1 = &zero,
+               .extra2 = &pid_max,
        },
        { }
 };
index a4ea245..649c9f8 100644 (file)
@@ -6014,11 +6014,6 @@ static void destroy_sched_domains(struct sched_domain *sd, int cpu)
  * SD_SHARE_PKG_RESOURCE set (Last Level Cache Domain) for this
  * allows us to avoid some pointer chasing select_idle_sibling().
  *
- * Iterate domains and sched_groups downward, assigning CPUs to be
- * select_idle_sibling() hw buddy.  Cross-wiring hw makes bouncing
- * due to random perturbation self canceling, ie sw buddies pull
- * their counterpart to their CPU's hw counterpart.
- *
  * Also keep a unique ID per domain (we use the first cpu number in
  * the cpumask of the domain), this allows us to quickly tell if
  * two cpus are in the same cache domain, see cpus_share_cache().
@@ -6032,40 +6027,8 @@ static void update_top_cache_domain(int cpu)
        int id = cpu;
 
        sd = highest_flag_domain(cpu, SD_SHARE_PKG_RESOURCES);
-       if (sd) {
-               struct sched_domain *tmp = sd;
-               struct sched_group *sg, *prev;
-               bool right;
-
-               /*
-                * Traverse to first CPU in group, and count hops
-                * to cpu from there, switching direction on each
-                * hop, never ever pointing the last CPU rightward.
-                */
-               do {
-                       id = cpumask_first(sched_domain_span(tmp));
-                       prev = sg = tmp->groups;
-                       right = 1;
-
-                       while (cpumask_first(sched_group_cpus(sg)) != id)
-                               sg = sg->next;
-
-                       while (!cpumask_test_cpu(cpu, sched_group_cpus(sg))) {
-                               prev = sg;
-                               sg = sg->next;
-                               right = !right;
-                       }
-
-                       /* A CPU went down, never point back to domain start. */
-                       if (right && cpumask_first(sched_group_cpus(sg->next)) == id)
-                               right = false;
-
-                       sg = right ? sg->next : prev;
-                       tmp->idle_buddy = cpumask_first(sched_group_cpus(sg));
-               } while ((tmp = tmp->child));
-
+       if (sd)
                id = cpumask_first(sched_domain_span(sd));
-       }
 
        rcu_assign_pointer(per_cpu(sd_llc, cpu), sd);
        per_cpu(sd_llc_id, cpu) = id;
index 42d9df6..96e2b18 100644 (file)
@@ -2637,6 +2637,8 @@ static int select_idle_sibling(struct task_struct *p, int target)
        int cpu = smp_processor_id();
        int prev_cpu = task_cpu(p);
        struct sched_domain *sd;
+       struct sched_group *sg;
+       int i;
 
        /*
         * If the task is going to be woken-up on this cpu and if it is
@@ -2653,17 +2655,29 @@ static int select_idle_sibling(struct task_struct *p, int target)
                return prev_cpu;
 
        /*
-        * Otherwise, check assigned siblings to find an elegible idle cpu.
+        * Otherwise, iterate the domains and find an elegible idle cpu.
         */
        sd = rcu_dereference(per_cpu(sd_llc, target));
-
        for_each_lower_domain(sd) {
-               if (!cpumask_test_cpu(sd->idle_buddy, tsk_cpus_allowed(p)))
-                       continue;
-               if (idle_cpu(sd->idle_buddy))
-                       return sd->idle_buddy;
-       }
+               sg = sd->groups;
+               do {
+                       if (!cpumask_intersects(sched_group_cpus(sg),
+                                               tsk_cpus_allowed(p)))
+                               goto next;
 
+                       for_each_cpu(i, sched_group_cpus(sg)) {
+                               if (!idle_cpu(i))
+                                       goto next;
+                       }
+
+                       target = cpumask_first_and(sched_group_cpus(sg),
+                                       tsk_cpus_allowed(p));
+                       goto done;
+next:
+                       sg = sg->next;
+               } while (sg != sd->groups);
+       }
+done:
        return target;
 }
 
index 34e5eac..d3b91e7 100644 (file)
@@ -303,10 +303,11 @@ void getnstimeofday(struct timespec *ts)
                seq = read_seqbegin(&tk->lock);
 
                ts->tv_sec = tk->xtime_sec;
-               ts->tv_nsec = timekeeping_get_ns(tk);
+               nsecs = timekeeping_get_ns(tk);
 
        } while (read_seqretry(&tk->lock, seq));
 
+       ts->tv_nsec = 0;
        timespec_add_ns(ts, nsecs);
 }
 EXPORT_SYMBOL(getnstimeofday);
@@ -345,6 +346,7 @@ void ktime_get_ts(struct timespec *ts)
 {
        struct timekeeper *tk = &timekeeper;
        struct timespec tomono;
+       s64 nsec;
        unsigned int seq;
 
        WARN_ON(timekeeping_suspended);
@@ -352,13 +354,14 @@ void ktime_get_ts(struct timespec *ts)
        do {
                seq = read_seqbegin(&tk->lock);
                ts->tv_sec = tk->xtime_sec;
-               ts->tv_nsec = timekeeping_get_ns(tk);
+               nsec = timekeeping_get_ns(tk);
                tomono = tk->wall_to_monotonic;
 
        } while (read_seqretry(&tk->lock, seq));
 
-       set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec,
-                               ts->tv_nsec + tomono.tv_nsec);
+       ts->tv_sec += tomono.tv_sec;
+       ts->tv_nsec = 0;
+       timespec_add_ns(ts, nsec + tomono.tv_nsec);
 }
 EXPORT_SYMBOL_GPL(ktime_get_ts);
 
@@ -1244,6 +1247,7 @@ void get_monotonic_boottime(struct timespec *ts)
 {
        struct timekeeper *tk = &timekeeper;
        struct timespec tomono, sleep;
+       s64 nsec;
        unsigned int seq;
 
        WARN_ON(timekeeping_suspended);
@@ -1251,14 +1255,15 @@ void get_monotonic_boottime(struct timespec *ts)
        do {
                seq = read_seqbegin(&tk->lock);
                ts->tv_sec = tk->xtime_sec;
-               ts->tv_nsec = timekeeping_get_ns(tk);
+               nsec = timekeeping_get_ns(tk);
                tomono = tk->wall_to_monotonic;
                sleep = tk->total_sleep_time;
 
        } while (read_seqretry(&tk->lock, seq));
 
-       set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec + sleep.tv_sec,
-                       ts->tv_nsec + tomono.tv_nsec + sleep.tv_nsec);
+       ts->tv_sec += tomono.tv_sec + sleep.tv_sec;
+       ts->tv_nsec = 0;
+       timespec_add_ns(ts, nsec + tomono.tv_nsec + sleep.tv_nsec);
 }
 EXPORT_SYMBOL_GPL(get_monotonic_boottime);
 
index 1e1373b..3c5a79e 100644 (file)
@@ -1349,8 +1349,16 @@ static void busy_worker_rebind_fn(struct work_struct *work)
        struct worker *worker = container_of(work, struct worker, rebind_work);
        struct global_cwq *gcwq = worker->pool->gcwq;
 
-       if (worker_maybe_bind_and_lock(worker))
-               worker_clr_flags(worker, WORKER_REBIND);
+       worker_maybe_bind_and_lock(worker);
+
+       /*
+        * %WORKER_REBIND must be cleared even if the above binding failed;
+        * otherwise, we may confuse the next CPU_UP cycle or oops / get
+        * stuck by calling idle_worker_rebind() prematurely.  If CPU went
+        * down again inbetween, %WORKER_UNBOUND would be set, so clearing
+        * %WORKER_REBIND is always safe.
+        */
+       worker_clr_flags(worker, WORKER_REBIND);
 
        spin_unlock_irq(&gcwq->lock);
 }
@@ -3568,18 +3576,17 @@ static int __devinit workqueue_cpu_down_callback(struct notifier_block *nfb,
 #ifdef CONFIG_SMP
 
 struct work_for_cpu {
-       struct completion completion;
+       struct work_struct work;
        long (*fn)(void *);
        void *arg;
        long ret;
 };
 
-static int do_work_for_cpu(void *_wfc)
+static void work_for_cpu_fn(struct work_struct *work)
 {
-       struct work_for_cpu *wfc = _wfc;
+       struct work_for_cpu *wfc = container_of(work, struct work_for_cpu, work);
+
        wfc->ret = wfc->fn(wfc->arg);
-       complete(&wfc->completion);
-       return 0;
 }
 
 /**
@@ -3594,19 +3601,11 @@ static int do_work_for_cpu(void *_wfc)
  */
 long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg)
 {
-       struct task_struct *sub_thread;
-       struct work_for_cpu wfc = {
-               .completion = COMPLETION_INITIALIZER_ONSTACK(wfc.completion),
-               .fn = fn,
-               .arg = arg,
-       };
+       struct work_for_cpu wfc = { .fn = fn, .arg = arg };
 
-       sub_thread = kthread_create(do_work_for_cpu, &wfc, "work_for_cpu");
-       if (IS_ERR(sub_thread))
-               return PTR_ERR(sub_thread);
-       kthread_bind(sub_thread, cpu);
-       wake_up_process(sub_thread);
-       wait_for_completion(&wfc.completion);
+       INIT_WORK_ONSTACK(&wfc.work, work_for_cpu_fn);
+       schedule_work_on(cpu, &wfc.work);
+       flush_work(&wfc.work);
        return wfc.ret;
 }
 EXPORT_SYMBOL_GPL(work_on_cpu);
index 3ad25f9..6a5b90d 100644 (file)
@@ -126,9 +126,6 @@ static void register_page_bootmem_info_section(unsigned long start_pfn)
        struct mem_section *ms;
        struct page *page, *memmap;
 
-       if (!pfn_valid(start_pfn))
-               return;
-
        section_nr = pfn_to_section_nr(start_pfn);
        ms = __nr_to_section(section_nr);
 
@@ -187,9 +184,16 @@ void register_page_bootmem_info_node(struct pglist_data *pgdat)
        end_pfn = pfn + pgdat->node_spanned_pages;
 
        /* register_section info */
-       for (; pfn < end_pfn; pfn += PAGES_PER_SECTION)
-               register_page_bootmem_info_section(pfn);
-
+       for (; pfn < end_pfn; pfn += PAGES_PER_SECTION) {
+               /*
+                * Some platforms can assign the same pfn to multiple nodes - on
+                * node0 as well as nodeN.  To avoid registering a pfn against
+                * multiple nodes we check that this pfn does not already
+                * reside in some other node.
+                */
+               if (pfn_valid(pfn) && (pfn_to_nid(pfn) == node))
+                       register_page_bootmem_info_section(pfn);
+       }
 }
 #endif /* !CONFIG_SPARSEMEM_VMEMMAP */
 
index c66fb87..c13ea75 100644 (file)
@@ -584,7 +584,7 @@ static inline void __free_one_page(struct page *page,
                combined_idx = buddy_idx & page_idx;
                higher_page = page + (combined_idx - page_idx);
                buddy_idx = __find_buddy_index(combined_idx, order + 1);
-               higher_buddy = page + (buddy_idx - combined_idx);
+               higher_buddy = higher_page + (buddy_idx - combined_idx);
                if (page_is_buddy(higher_page, higher_buddy, order + 1)) {
                        list_add_tail(&page->lru,
                                &zone->free_area[order].free_list[migratetype]);
index 811af03..c685475 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -983,7 +983,7 @@ static void *__ac_get_obj(struct kmem_cache *cachep, struct array_cache *ac,
                }
 
                /* The caller cannot use PFMEMALLOC objects, find another one */
-               for (i = 1; i < ac->avail; i++) {
+               for (i = 0; i < ac->avail; i++) {
                        /* If a !PFMEMALLOC object is found, swap them */
                        if (!is_obj_pfmemalloc(ac->entry[i])) {
                                objp = ac->entry[i];
@@ -1000,7 +1000,7 @@ static void *__ac_get_obj(struct kmem_cache *cachep, struct array_cache *ac,
                l3 = cachep->nodelists[numa_mem_id()];
                if (!list_empty(&l3->slabs_free) && force_refill) {
                        struct slab *slabp = virt_to_slab(objp);
-                       ClearPageSlabPfmemalloc(virt_to_page(slabp->s_mem));
+                       ClearPageSlabPfmemalloc(virt_to_head_page(slabp->s_mem));
                        clear_obj_pfmemalloc(&objp);
                        recheck_pfmemalloc_active(cachep, ac);
                        return objp;
@@ -1032,7 +1032,7 @@ static void *__ac_put_obj(struct kmem_cache *cachep, struct array_cache *ac,
 {
        if (unlikely(pfmemalloc_active)) {
                /* Some pfmemalloc slabs exist, check if this is one */
-               struct page *page = virt_to_page(objp);
+               struct page *page = virt_to_head_page(objp);
                if (PageSlabPfmemalloc(page))
                        set_obj_pfmemalloc(&objp);
        }
index 8f78e25..2fdd96f 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1524,12 +1524,13 @@ static inline void *acquire_slab(struct kmem_cache *s,
 }
 
 static int put_cpu_partial(struct kmem_cache *s, struct page *page, int drain);
+static inline bool pfmemalloc_match(struct page *page, gfp_t gfpflags);
 
 /*
  * Try to allocate a partial slab from a specific node.
  */
-static void *get_partial_node(struct kmem_cache *s,
-               struct kmem_cache_node *n, struct kmem_cache_cpu *c)
+static void *get_partial_node(struct kmem_cache *s, struct kmem_cache_node *n,
+                               struct kmem_cache_cpu *c, gfp_t flags)
 {
        struct page *page, *page2;
        void *object = NULL;
@@ -1545,9 +1546,13 @@ static void *get_partial_node(struct kmem_cache *s,
 
        spin_lock(&n->list_lock);
        list_for_each_entry_safe(page, page2, &n->partial, lru) {
-               void *t = acquire_slab(s, n, page, object == NULL);
+               void *t;
                int available;
 
+               if (!pfmemalloc_match(page, flags))
+                       continue;
+
+               t = acquire_slab(s, n, page, object == NULL);
                if (!t)
                        break;
 
@@ -1614,7 +1619,7 @@ static void *get_any_partial(struct kmem_cache *s, gfp_t flags,
 
                        if (n && cpuset_zone_allowed_hardwall(zone, flags) &&
                                        n->nr_partial > s->min_partial) {
-                               object = get_partial_node(s, n, c);
+                               object = get_partial_node(s, n, c, flags);
                                if (object) {
                                        /*
                                         * Return the object even if
@@ -1643,7 +1648,7 @@ static void *get_partial(struct kmem_cache *s, gfp_t flags, int node,
        void *object;
        int searchnode = (node == NUMA_NO_NODE) ? numa_node_id() : node;
 
-       object = get_partial_node(s, get_node(s, searchnode), c);
+       object = get_partial_node(s, get_node(s, searchnode), c, flags);
        if (object || node != NUMA_NO_NODE)
                return object;
 
index 8d01243..99b434b 100644 (file)
@@ -3102,6 +3102,7 @@ int kswapd_run(int nid)
                /* failure at boot is fatal */
                BUG_ON(system_state == SYSTEM_BOOTING);
                printk("Failed to start kswapd on node %d\n",nid);
+               pgdat->kswapd = NULL;
                ret = -1;
        }
        return ret;
index a081ce1..cebaae7 100644 (file)
@@ -20,8 +20,8 @@
 #ifndef _NET_BATMAN_ADV_BITARRAY_H_
 #define _NET_BATMAN_ADV_BITARRAY_H_
 
-/* returns true if the corresponding bit in the given seq_bits indicates true
- * and curr_seqno is within range of last_seqno
+/* Returns 1 if the corresponding bit in the given seq_bits indicates true
+ * and curr_seqno is within range of last_seqno. Otherwise returns 0.
  */
 static inline int batadv_test_bit(const unsigned long *seq_bits,
                                  uint32_t last_seqno, uint32_t curr_seqno)
@@ -32,7 +32,7 @@ static inline int batadv_test_bit(const unsigned long *seq_bits,
        if (diff < 0 || diff >= BATADV_TQ_LOCAL_WINDOW_SIZE)
                return 0;
        else
-               return  test_bit(diff, seq_bits);
+               return test_bit(diff, seq_bits) != 0;
 }
 
 /* turn corresponding bit on, so we can remember that we got the packet */
index 5e5f5b4..1eaacf1 100644 (file)
@@ -58,7 +58,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
        switch (cmd) {
        case BNEPCONNADD:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
 
                if (copy_from_user(&ca, argp, sizeof(ca)))
                        return -EFAULT;
@@ -84,7 +84,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
 
        case BNEPCONNDEL:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
 
                if (copy_from_user(&cd, argp, sizeof(cd)))
                        return -EFAULT;
index 311668d..32dc83d 100644 (file)
@@ -72,7 +72,7 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
        switch (cmd) {
        case CMTPCONNADD:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
 
                if (copy_from_user(&ca, argp, sizeof(ca)))
                        return -EFAULT;
@@ -97,7 +97,7 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
 
        case CMTPCONNDEL:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
 
                if (copy_from_user(&cd, argp, sizeof(cd)))
                        return -EFAULT;
index 19fdac7..d5ace1e 100644 (file)
@@ -490,7 +490,7 @@ static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd,
        switch (cmd) {
        case HCISETRAW:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
 
                if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
                        return -EPERM;
@@ -510,12 +510,12 @@ static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd,
 
        case HCIBLOCKADDR:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
                return hci_sock_blacklist_add(hdev, (void __user *) arg);
 
        case HCIUNBLOCKADDR:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
                return hci_sock_blacklist_del(hdev, (void __user *) arg);
 
        default:
@@ -546,22 +546,22 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd,
 
        case HCIDEVUP:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
                return hci_dev_open(arg);
 
        case HCIDEVDOWN:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
                return hci_dev_close(arg);
 
        case HCIDEVRESET:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
                return hci_dev_reset(arg);
 
        case HCIDEVRESTAT:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
                return hci_dev_reset_stat(arg);
 
        case HCISETSCAN:
@@ -573,7 +573,7 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd,
        case HCISETACLMTU:
        case HCISETSCOMTU:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
                return hci_dev_cmd(cmd, argp);
 
        case HCIINQUIRY:
index 18b3f68..b24fb3b 100644 (file)
@@ -56,7 +56,7 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
        switch (cmd) {
        case HIDPCONNADD:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
 
                if (copy_from_user(&ca, argp, sizeof(ca)))
                        return -EFAULT;
@@ -91,7 +91,7 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
 
        case HIDPCONNDEL:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
 
                if (copy_from_user(&cd, argp, sizeof(cd)))
                        return -EFAULT;
index d7fe32c..89e33a5 100644 (file)
@@ -2134,7 +2134,8 @@ static bool can_checksum_protocol(netdev_features_t features, __be16 protocol)
 static netdev_features_t harmonize_features(struct sk_buff *skb,
        __be16 protocol, netdev_features_t features)
 {
-       if (!can_checksum_protocol(features, protocol)) {
+       if (skb->ip_summed != CHECKSUM_NONE &&
+           !can_checksum_protocol(features, protocol)) {
                features &= ~NETIF_F_ALL_CSUM;
                features &= ~NETIF_F_SG;
        } else if (illegal_highdma(skb->dev, skb)) {
@@ -3322,7 +3323,7 @@ ncls:
 
        if (pt_prev) {
                if (unlikely(skb_orphan_frags(skb, GFP_ATOMIC)))
-                       ret = -ENOMEM;
+                       goto drop;
                else
                        ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
        } else {
index fe00d12..e33ebae 100644 (file)
@@ -3502,7 +3502,9 @@ bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from,
        if (!skb_cloned(from))
                skb_shinfo(from)->nr_frags = 0;
 
-       /* if the skb is cloned this does nothing since we set nr_frags to 0 */
+       /* if the skb is not cloned this does nothing
+        * since we set nr_frags to 0.
+        */
        for (i = 0; i < skb_shinfo(from)->nr_frags; i++)
                skb_frag_ref(from, i);
 
index 77e87af..4780045 100644 (file)
@@ -1225,7 +1225,7 @@ static int arp_netdev_event(struct notifier_block *this, unsigned long event,
        switch (event) {
        case NETDEV_CHANGEADDR:
                neigh_changeaddr(&arp_tbl, dev);
-               rt_cache_flush(dev_net(dev), 0);
+               rt_cache_flush(dev_net(dev));
                break;
        default:
                break;
index 44bf82e..e12fad7 100644 (file)
@@ -725,7 +725,7 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
                break;
 
        case SIOCSIFFLAGS:
-               ret = -EACCES;
+               ret = -EPERM;
                if (!capable(CAP_NET_ADMIN))
                        goto out;
                break;
@@ -733,7 +733,7 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
        case SIOCSIFBRDADDR:    /* Set the broadcast address */
        case SIOCSIFDSTADDR:    /* Set the destination address */
        case SIOCSIFNETMASK:    /* Set the netmask for the interface */
-               ret = -EACCES;
+               ret = -EPERM;
                if (!capable(CAP_NET_ADMIN))
                        goto out;
                ret = -EINVAL;
@@ -1503,7 +1503,7 @@ static int devinet_conf_proc(ctl_table *ctl, int write,
                if (i == IPV4_DEVCONF_ACCEPT_LOCAL - 1 ||
                    i == IPV4_DEVCONF_ROUTE_LOCALNET - 1)
                        if ((new_value == 0) && (old_value != 0))
-                               rt_cache_flush(net, 0);
+                               rt_cache_flush(net);
        }
 
        return ret;
@@ -1537,7 +1537,7 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write,
                                dev_disable_lro(idev->dev);
                        }
                        rtnl_unlock();
-                       rt_cache_flush(net, 0);
+                       rt_cache_flush(net);
                }
        }
 
@@ -1554,7 +1554,7 @@ static int ipv4_doint_and_flush(ctl_table *ctl, int write,
        struct net *net = ctl->extra2;
 
        if (write && *valp != val)
-               rt_cache_flush(net, 0);
+               rt_cache_flush(net);
 
        return ret;
 }
index c43ae3f..8e2b475 100644 (file)
@@ -148,7 +148,7 @@ static void fib_flush(struct net *net)
        }
 
        if (flushed)
-               rt_cache_flush(net, -1);
+               rt_cache_flush(net);
 }
 
 /*
@@ -999,11 +999,11 @@ static void nl_fib_lookup_exit(struct net *net)
        net->ipv4.fibnl = NULL;
 }
 
-static void fib_disable_ip(struct net_device *dev, int force, int delay)
+static void fib_disable_ip(struct net_device *dev, int force)
 {
        if (fib_sync_down_dev(dev, force))
                fib_flush(dev_net(dev));
-       rt_cache_flush(dev_net(dev), delay);
+       rt_cache_flush(dev_net(dev));
        arp_ifdown(dev);
 }
 
@@ -1020,7 +1020,7 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
                fib_sync_up(dev);
 #endif
                atomic_inc(&net->ipv4.dev_addr_genid);
-               rt_cache_flush(dev_net(dev), -1);
+               rt_cache_flush(dev_net(dev));
                break;
        case NETDEV_DOWN:
                fib_del_ifaddr(ifa, NULL);
@@ -1029,9 +1029,9 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
                        /* Last address was deleted from this interface.
                         * Disable IP.
                         */
-                       fib_disable_ip(dev, 1, 0);
+                       fib_disable_ip(dev, 1);
                } else {
-                       rt_cache_flush(dev_net(dev), -1);
+                       rt_cache_flush(dev_net(dev));
                }
                break;
        }
@@ -1045,7 +1045,7 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
        struct net *net = dev_net(dev);
 
        if (event == NETDEV_UNREGISTER) {
-               fib_disable_ip(dev, 2, -1);
+               fib_disable_ip(dev, 2);
                rt_flush_dev(dev);
                return NOTIFY_DONE;
        }
@@ -1062,14 +1062,14 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
                fib_sync_up(dev);
 #endif
                atomic_inc(&net->ipv4.dev_addr_genid);
-               rt_cache_flush(dev_net(dev), -1);
+               rt_cache_flush(dev_net(dev));
                break;
        case NETDEV_DOWN:
-               fib_disable_ip(dev, 0, 0);
+               fib_disable_ip(dev, 0);
                break;
        case NETDEV_CHANGEMTU:
        case NETDEV_CHANGE:
-               rt_cache_flush(dev_net(dev), 0);
+               rt_cache_flush(dev_net(dev));
                break;
        case NETDEV_UNREGISTER_BATCH:
                break;
index a83d74e..274309d 100644 (file)
@@ -259,7 +259,7 @@ static size_t fib4_rule_nlmsg_payload(struct fib_rule *rule)
 
 static void fib4_rule_flush_cache(struct fib_rules_ops *ops)
 {
-       rt_cache_flush(ops->fro_net, -1);
+       rt_cache_flush(ops->fro_net);
 }
 
 static const struct fib_rules_ops __net_initdata fib4_rules_ops_template = {
index 57bd978..d1b9359 100644 (file)
@@ -1286,7 +1286,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
 
                        fib_release_info(fi_drop);
                        if (state & FA_S_ACCESSED)
-                               rt_cache_flush(cfg->fc_nlinfo.nl_net, -1);
+                               rt_cache_flush(cfg->fc_nlinfo.nl_net);
                        rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen,
                                tb->tb_id, &cfg->fc_nlinfo, NLM_F_REPLACE);
 
@@ -1333,7 +1333,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
        list_add_tail_rcu(&new_fa->fa_list,
                          (fa ? &fa->fa_list : fa_head));
 
-       rt_cache_flush(cfg->fc_nlinfo.nl_net, -1);
+       rt_cache_flush(cfg->fc_nlinfo.nl_net);
        rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id,
                  &cfg->fc_nlinfo, 0);
 succeeded:
@@ -1708,7 +1708,7 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg)
                trie_leaf_remove(t, l);
 
        if (fa->fa_state & FA_S_ACCESSED)
-               rt_cache_flush(cfg->fc_nlinfo.nl_net, -1);
+               rt_cache_flush(cfg->fc_nlinfo.nl_net);
 
        fib_release_info(fa->fa_info);
        alias_free_mem_rcu(fa);
index 82cf2a7..fd9af60 100644 (file)
@@ -202,11 +202,6 @@ EXPORT_SYMBOL(ip_tos2prio);
 static DEFINE_PER_CPU(struct rt_cache_stat, rt_cache_stat);
 #define RT_CACHE_STAT_INC(field) __this_cpu_inc(rt_cache_stat.field)
 
-static inline int rt_genid(struct net *net)
-{
-       return atomic_read(&net->ipv4.rt_genid);
-}
-
 #ifdef CONFIG_PROC_FS
 static void *rt_cache_seq_start(struct seq_file *seq, loff_t *pos)
 {
@@ -447,27 +442,9 @@ static inline bool rt_is_expired(const struct rtable *rth)
        return rth->rt_genid != rt_genid(dev_net(rth->dst.dev));
 }
 
-/*
- * Perturbation of rt_genid by a small quantity [1..256]
- * Using 8 bits of shuffling ensure we can call rt_cache_invalidate()
- * many times (2^24) without giving recent rt_genid.
- * Jenkins hash is strong enough that litle changes of rt_genid are OK.
- */
-static void rt_cache_invalidate(struct net *net)
+void rt_cache_flush(struct net *net)
 {
-       unsigned char shuffle;
-
-       get_random_bytes(&shuffle, sizeof(shuffle));
-       atomic_add(shuffle + 1U, &net->ipv4.rt_genid);
-}
-
-/*
- * delay < 0  : invalidate cache (fast : entries will be deleted later)
- * delay >= 0 : invalidate & flush cache (can be long)
- */
-void rt_cache_flush(struct net *net, int delay)
-{
-       rt_cache_invalidate(net);
+       rt_genid_bump(net);
 }
 
 static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst,
@@ -2345,7 +2322,7 @@ int ip_rt_dump(struct sk_buff *skb,  struct netlink_callback *cb)
 
 void ip_rt_multicast_event(struct in_device *in_dev)
 {
-       rt_cache_flush(dev_net(in_dev->dev), 0);
+       rt_cache_flush(dev_net(in_dev->dev));
 }
 
 #ifdef CONFIG_SYSCTL
@@ -2354,16 +2331,7 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write,
                                        size_t *lenp, loff_t *ppos)
 {
        if (write) {
-               int flush_delay;
-               ctl_table ctl;
-               struct net *net;
-
-               memcpy(&ctl, __ctl, sizeof(ctl));
-               ctl.data = &flush_delay;
-               proc_dointvec(&ctl, write, buffer, lenp, ppos);
-
-               net = (struct net *)__ctl->extra1;
-               rt_cache_flush(net, flush_delay);
+               rt_cache_flush((struct net *)__ctl->extra1);
                return 0;
        }
 
@@ -2533,8 +2501,7 @@ static __net_initdata struct pernet_operations sysctl_route_ops = {
 
 static __net_init int rt_genid_init(struct net *net)
 {
-       get_random_bytes(&net->ipv4.rt_genid,
-                        sizeof(net->ipv4.rt_genid));
+       atomic_set(&net->rt_genid, 0);
        get_random_bytes(&net->ipv4.dev_addr_genid,
                         sizeof(net->ipv4.dev_addr_genid));
        return 0;
index 2109ff4..5f64193 100644 (file)
@@ -1762,8 +1762,14 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                }
 
 #ifdef CONFIG_NET_DMA
-               if (tp->ucopy.dma_chan)
-                       dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
+               if (tp->ucopy.dma_chan) {
+                       if (tp->rcv_wnd == 0 &&
+                           !skb_queue_empty(&sk->sk_async_wait_queue)) {
+                               tcp_service_net_dma(sk, true);
+                               tcp_cleanup_rbuf(sk, copied);
+                       } else
+                               dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
+               }
 #endif
                if (copied >= target) {
                        /* Do not sleep, just process backlog. */
@@ -2325,10 +2331,17 @@ static int tcp_repair_options_est(struct tcp_sock *tp,
                        tp->rx_opt.mss_clamp = opt.opt_val;
                        break;
                case TCPOPT_WINDOW:
-                       if (opt.opt_val > 14)
-                               return -EFBIG;
+                       {
+                               u16 snd_wscale = opt.opt_val & 0xFFFF;
+                               u16 rcv_wscale = opt.opt_val >> 16;
+
+                               if (snd_wscale > 14 || rcv_wscale > 14)
+                                       return -EFBIG;
 
-                       tp->rx_opt.snd_wscale = opt.opt_val;
+                               tp->rx_opt.snd_wscale = snd_wscale;
+                               tp->rx_opt.rcv_wscale = rcv_wscale;
+                               tp->rx_opt.wscale_ok = 1;
+                       }
                        break;
                case TCPOPT_SACK_PERM:
                        if (opt.opt_val != 0)
index 6e38c6c..d377f48 100644 (file)
@@ -4661,7 +4661,7 @@ queue_and_out:
 
                if (eaten > 0)
                        kfree_skb_partial(skb, fragstolen);
-               else if (!sock_flag(sk, SOCK_DEAD))
+               if (!sock_flag(sk, SOCK_DEAD))
                        sk->sk_data_ready(sk, 0);
                return;
        }
@@ -5556,8 +5556,7 @@ no_ack:
 #endif
                        if (eaten)
                                kfree_skb_partial(skb, fragstolen);
-                       else
-                               sk->sk_data_ready(sk, 0);
+                       sk->sk_data_ready(sk, 0);
                        return 0;
                }
        }
index 0251a60..c4f9341 100644 (file)
@@ -175,33 +175,12 @@ void __inet6_csk_dst_store(struct sock *sk, struct dst_entry *dst,
                           const struct in6_addr *saddr)
 {
        __ip6_dst_store(sk, dst, daddr, saddr);
-
-#ifdef CONFIG_XFRM
-       {
-               struct rt6_info *rt = (struct rt6_info  *)dst;
-               rt->rt6i_flow_cache_genid = atomic_read(&flow_cache_genid);
-       }
-#endif
 }
 
 static inline
 struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie)
 {
-       struct dst_entry *dst;
-
-       dst = __sk_dst_check(sk, cookie);
-
-#ifdef CONFIG_XFRM
-       if (dst) {
-               struct rt6_info *rt = (struct rt6_info *)dst;
-               if (rt->rt6i_flow_cache_genid != atomic_read(&flow_cache_genid)) {
-                       __sk_dst_reset(sk);
-                       dst = NULL;
-               }
-       }
-#endif
-
-       return dst;
+       return __sk_dst_check(sk, cookie);
 }
 
 static struct dst_entry *inet6_csk_route_socket(struct sock *sk,
index 13690d6..286acfc 100644 (file)
@@ -819,6 +819,10 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info)
                                        offsetof(struct rt6_info, rt6i_src),
                                        allow_create, replace_required);
 
+                       if (IS_ERR(sn)) {
+                               err = PTR_ERR(sn);
+                               sn = NULL;
+                       }
                        if (!sn) {
                                /* If it is failed, discard just allocated
                                   root, and then (in st_failure) stale node
index 8e80fd2..854e401 100644 (file)
@@ -226,7 +226,7 @@ static struct rt6_info ip6_null_entry_template = {
        .dst = {
                .__refcnt       = ATOMIC_INIT(1),
                .__use          = 1,
-               .obsolete       = -1,
+               .obsolete       = DST_OBSOLETE_FORCE_CHK,
                .error          = -ENETUNREACH,
                .input          = ip6_pkt_discard,
                .output         = ip6_pkt_discard_out,
@@ -246,7 +246,7 @@ static struct rt6_info ip6_prohibit_entry_template = {
        .dst = {
                .__refcnt       = ATOMIC_INIT(1),
                .__use          = 1,
-               .obsolete       = -1,
+               .obsolete       = DST_OBSOLETE_FORCE_CHK,
                .error          = -EACCES,
                .input          = ip6_pkt_prohibit,
                .output         = ip6_pkt_prohibit_out,
@@ -261,7 +261,7 @@ static struct rt6_info ip6_blk_hole_entry_template = {
        .dst = {
                .__refcnt       = ATOMIC_INIT(1),
                .__use          = 1,
-               .obsolete       = -1,
+               .obsolete       = DST_OBSOLETE_FORCE_CHK,
                .error          = -EINVAL,
                .input          = dst_discard,
                .output         = dst_discard,
@@ -281,13 +281,14 @@ static inline struct rt6_info *ip6_dst_alloc(struct net *net,
                                             struct fib6_table *table)
 {
        struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev,
-                                       0, DST_OBSOLETE_NONE, flags);
+                                       0, DST_OBSOLETE_FORCE_CHK, flags);
 
        if (rt) {
                struct dst_entry *dst = &rt->dst;
 
                memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
                rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers);
+               rt->rt6i_genid = rt_genid(net);
        }
        return rt;
 }
@@ -1031,6 +1032,13 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
 
        rt = (struct rt6_info *) dst;
 
+       /* All IPV6 dsts are created with ->obsolete set to the value
+        * DST_OBSOLETE_FORCE_CHK which forces validation calls down
+        * into this function always.
+        */
+       if (rt->rt6i_genid != rt_genid(dev_net(rt->dst.dev)))
+               return NULL;
+
        if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) {
                if (rt->rt6i_peer_genid != rt6_peer_genid()) {
                        if (!rt6_has_peer(rt))
@@ -1397,8 +1405,6 @@ int ip6_route_add(struct fib6_config *cfg)
                goto out;
        }
 
-       rt->dst.obsolete = -1;
-
        if (cfg->fc_flags & RTF_EXPIRES)
                rt6_set_expires(rt, jiffies +
                                clock_t_to_jiffies(cfg->fc_expires));
@@ -2080,7 +2086,6 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
        rt->dst.input = ip6_input;
        rt->dst.output = ip6_output;
        rt->rt6i_idev = idev;
-       rt->dst.obsolete = -1;
 
        rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP;
        if (anycast)
index 1b9024e..7261eb8 100644 (file)
@@ -601,7 +601,7 @@ static int nr_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
                if (!capable(CAP_NET_BIND_SERVICE)) {
                        dev_put(dev);
                        release_sock(sk);
-                       return -EACCES;
+                       return -EPERM;
                }
                nr->user_addr   = addr->fsa_digipeater[0];
                nr->source_addr = addr->fsa_ax25.sax25_call;
index e4723d3..211a212 100644 (file)
@@ -865,7 +865,10 @@ static void qfq_update_start(struct qfq_sched *q, struct qfq_class *cl)
                if (mask) {
                        struct qfq_group *next = qfq_ffs(q, mask);
                        if (qfq_gt(roundedF, next->F)) {
-                               cl->S = next->F;
+                               if (qfq_gt(limit, next->F))
+                                       cl->S = next->F;
+                               else /* preserve timestamp correctness */
+                                       cl->S = limit;
                                return;
                        }
                }
index 5a2aa17..387848e 100644 (file)
@@ -585,6 +585,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
        xfrm_pol_hold(policy);
        net->xfrm.policy_count[dir]++;
        atomic_inc(&flow_cache_genid);
+       rt_genid_bump(net);
        if (delpol)
                __xfrm_policy_unlink(delpol, dir);
        policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir);
@@ -1763,7 +1764,7 @@ static struct dst_entry *make_blackhole(struct net *net, u16 family,
 
        if (!afinfo) {
                dst_release(dst_orig);
-               ret = ERR_PTR(-EINVAL);
+               return ERR_PTR(-EINVAL);
        } else {
                ret = afinfo->blackhole_route(net, dst_orig);
        }
index e75d8e4..289f4bf 100644 (file)
@@ -123,9 +123,21 @@ static inline int verify_replay(struct xfrm_usersa_info *p,
                                struct nlattr **attrs)
 {
        struct nlattr *rt = attrs[XFRMA_REPLAY_ESN_VAL];
+       struct xfrm_replay_state_esn *rs;
 
-       if ((p->flags & XFRM_STATE_ESN) && !rt)
-               return -EINVAL;
+       if (p->flags & XFRM_STATE_ESN) {
+               if (!rt)
+                       return -EINVAL;
+
+               rs = nla_data(rt);
+
+               if (rs->bmp_len > XFRMA_REPLAY_ESN_MAX / sizeof(rs->bmp[0]) / 8)
+                       return -EINVAL;
+
+               if (nla_len(rt) < xfrm_replay_state_esn_len(rs) &&
+                   nla_len(rt) != sizeof(*rs))
+                       return -EINVAL;
+       }
 
        if (!rt)
                return 0;
@@ -370,14 +382,15 @@ static inline int xfrm_replay_verify_len(struct xfrm_replay_state_esn *replay_es
                                         struct nlattr *rp)
 {
        struct xfrm_replay_state_esn *up;
+       int ulen;
 
        if (!replay_esn || !rp)
                return 0;
 
        up = nla_data(rp);
+       ulen = xfrm_replay_state_esn_len(up);
 
-       if (xfrm_replay_state_esn_len(replay_esn) !=
-                       xfrm_replay_state_esn_len(up))
+       if (nla_len(rp) < ulen || xfrm_replay_state_esn_len(replay_esn) != ulen)
                return -EINVAL;
 
        return 0;
@@ -388,22 +401,28 @@ static int xfrm_alloc_replay_state_esn(struct xfrm_replay_state_esn **replay_esn
                                       struct nlattr *rta)
 {
        struct xfrm_replay_state_esn *p, *pp, *up;
+       int klen, ulen;
 
        if (!rta)
                return 0;
 
        up = nla_data(rta);
+       klen = xfrm_replay_state_esn_len(up);
+       ulen = nla_len(rta) >= klen ? klen : sizeof(*up);
 
-       p = kmemdup(up, xfrm_replay_state_esn_len(up), GFP_KERNEL);
+       p = kzalloc(klen, GFP_KERNEL);
        if (!p)
                return -ENOMEM;
 
-       pp = kmemdup(up, xfrm_replay_state_esn_len(up), GFP_KERNEL);
+       pp = kzalloc(klen, GFP_KERNEL);
        if (!pp) {
                kfree(p);
                return -ENOMEM;
        }
 
+       memcpy(p, up, ulen);
+       memcpy(pp, up, ulen);
+
        *replay_esn = p;
        *preplay_esn = pp;
 
@@ -442,10 +461,11 @@ static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *
  * somehow made shareable and move it to xfrm_state.c - JHS
  *
 */
-static void xfrm_update_ae_params(struct xfrm_state *x, struct nlattr **attrs)
+static void xfrm_update_ae_params(struct xfrm_state *x, struct nlattr **attrs,
+                                 int update_esn)
 {
        struct nlattr *rp = attrs[XFRMA_REPLAY_VAL];
-       struct nlattr *re = attrs[XFRMA_REPLAY_ESN_VAL];
+       struct nlattr *re = update_esn ? attrs[XFRMA_REPLAY_ESN_VAL] : NULL;
        struct nlattr *lt = attrs[XFRMA_LTIME_VAL];
        struct nlattr *et = attrs[XFRMA_ETIMER_THRESH];
        struct nlattr *rt = attrs[XFRMA_REPLAY_THRESH];
@@ -555,7 +575,7 @@ static struct xfrm_state *xfrm_state_construct(struct net *net,
                goto error;
 
        /* override default values from above */
-       xfrm_update_ae_params(x, attrs);
+       xfrm_update_ae_params(x, attrs, 0);
 
        return x;
 
@@ -689,6 +709,7 @@ out:
 
 static void copy_to_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p)
 {
+       memset(p, 0, sizeof(*p));
        memcpy(&p->id, &x->id, sizeof(p->id));
        memcpy(&p->sel, &x->sel, sizeof(p->sel));
        memcpy(&p->lft, &x->lft, sizeof(p->lft));
@@ -742,7 +763,7 @@ static int copy_to_user_auth(struct xfrm_algo_auth *auth, struct sk_buff *skb)
                return -EMSGSIZE;
 
        algo = nla_data(nla);
-       strcpy(algo->alg_name, auth->alg_name);
+       strncpy(algo->alg_name, auth->alg_name, sizeof(algo->alg_name));
        memcpy(algo->alg_key, auth->alg_key, (auth->alg_key_len + 7) / 8);
        algo->alg_key_len = auth->alg_key_len;
 
@@ -878,6 +899,7 @@ static struct sk_buff *xfrm_state_netlink(struct sk_buff *in_skb,
 {
        struct xfrm_dump_info info;
        struct sk_buff *skb;
+       int err;
 
        skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
        if (!skb)
@@ -888,9 +910,10 @@ static struct sk_buff *xfrm_state_netlink(struct sk_buff *in_skb,
        info.nlmsg_seq = seq;
        info.nlmsg_flags = 0;
 
-       if (dump_one_state(x, 0, &info)) {
+       err = dump_one_state(x, 0, &info);
+       if (err) {
                kfree_skb(skb);
-               return NULL;
+               return ERR_PTR(err);
        }
 
        return skb;
@@ -1317,6 +1340,7 @@ static void copy_from_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy
 
 static void copy_to_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy_info *p, int dir)
 {
+       memset(p, 0, sizeof(*p));
        memcpy(&p->sel, &xp->selector, sizeof(p->sel));
        memcpy(&p->lft, &xp->lft, sizeof(p->lft));
        memcpy(&p->curlft, &xp->curlft, sizeof(p->curlft));
@@ -1421,6 +1445,7 @@ static int copy_to_user_tmpl(struct xfrm_policy *xp, struct sk_buff *skb)
                struct xfrm_user_tmpl *up = &vec[i];
                struct xfrm_tmpl *kp = &xp->xfrm_vec[i];
 
+               memset(up, 0, sizeof(*up));
                memcpy(&up->id, &kp->id, sizeof(up->id));
                up->family = kp->encap_family;
                memcpy(&up->saddr, &kp->saddr, sizeof(up->saddr));
@@ -1546,6 +1571,7 @@ static struct sk_buff *xfrm_policy_netlink(struct sk_buff *in_skb,
 {
        struct xfrm_dump_info info;
        struct sk_buff *skb;
+       int err;
 
        skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!skb)
@@ -1556,9 +1582,10 @@ static struct sk_buff *xfrm_policy_netlink(struct sk_buff *in_skb,
        info.nlmsg_seq = seq;
        info.nlmsg_flags = 0;
 
-       if (dump_one_policy(xp, dir, 0, &info) < 0) {
+       err = dump_one_policy(xp, dir, 0, &info);
+       if (err) {
                kfree_skb(skb);
-               return NULL;
+               return ERR_PTR(err);
        }
 
        return skb;
@@ -1822,7 +1849,7 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
                goto out;
 
        spin_lock_bh(&x->lock);
-       xfrm_update_ae_params(x, attrs);
+       xfrm_update_ae_params(x, attrs, 1);
        spin_unlock_bh(&x->lock);
 
        c.event = nlh->nlmsg_type;
index c220f31..65f67cb 100644 (file)
@@ -51,6 +51,7 @@ int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall);
 static inline void selinux_xfrm_notify_policyload(void)
 {
        atomic_inc(&flow_cache_genid);
+       rt_genid_bump(&init_net);
 }
 #else
 static inline int selinux_xfrm_enabled(void)
index 228cdf9..c4763c5 100644 (file)
@@ -2701,6 +2701,7 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = {
        SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB),
+       SND_PCI_QUIRK(0x1043, 0x1ac3, "ASUS X53S", POS_FIX_POSBUF),
        SND_PCI_QUIRK(0x1043, 0x1b43, "ASUS K53E", POS_FIX_POSBUF),
        SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x10de, 0xcb89, "Macbook Pro 7,1", POS_FIX_LPIB),
index 5c9caca..1cf7a32 100644 (file)
@@ -426,7 +426,7 @@ static const int arizona_44k1_bclk_rates[] = {
        940800,
        1411200,
        1881600,
-       2882400,
+       2822400,
        3763200,
        5644800,
        7526400,
index 8f726c0..115a403 100644 (file)
@@ -659,7 +659,7 @@ static struct snd_soc_dai_driver mc13783_dai_async[] = {
                .id = MC13783_ID_STEREO_DAC,
                .playback = {
                        .stream_name = "Playback",
-                       .channels_min = 1,
+                       .channels_min = 2,
                        .channels_max = 2,
                        .rates = SNDRV_PCM_RATE_8000_96000,
                        .formats = MC13783_FORMATS,
@@ -670,7 +670,7 @@ static struct snd_soc_dai_driver mc13783_dai_async[] = {
                .id = MC13783_ID_STEREO_CODEC,
                .capture = {
                        .stream_name = "Capture",
-                       .channels_min = 1,
+                       .channels_min = 2,
                        .channels_max = 2,
                        .rates = MC13783_RATES_RECORD,
                        .formats = MC13783_FORMATS,
@@ -692,14 +692,14 @@ static struct snd_soc_dai_driver mc13783_dai_sync[] = {
                .id = MC13783_ID_SYNC,
                .playback = {
                        .stream_name = "Playback",
-                       .channels_min = 1,
+                       .channels_min = 2,
                        .channels_max = 2,
                        .rates = SNDRV_PCM_RATE_8000_96000,
                        .formats = MC13783_FORMATS,
                },
                .capture = {
                        .stream_name = "Capture",
-                       .channels_min = 1,
+                       .channels_min = 2,
                        .channels_max = 2,
                        .rates = MC13783_RATES_RECORD,
                        .formats = MC13783_FORMATS,
index 0013afe..dc4262e 100644 (file)
@@ -100,7 +100,7 @@ static const struct reg_default wm8904_reg_defaults[] = {
        { 14,  0x0000 },     /* R14  - Power Management 2 */
        { 15,  0x0000 },     /* R15  - Power Management 3 */
        { 18,  0x0000 },     /* R18  - Power Management 6 */
-       { 19,  0x945E },     /* R20  - Clock Rates 0 */
+       { 20,  0x945E },     /* R20  - Clock Rates 0 */
        { 21,  0x0C05 },     /* R21  - Clock Rates 1 */
        { 22,  0x0006 },     /* R22  - Clock Rates 2 */
        { 24,  0x0050 },     /* R24  - Audio Interface 0 */
index fb21b17..199408e 100644 (file)
@@ -94,7 +94,7 @@ static int __devinit imx_sgtl5000_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "audmux internal port setup failed\n");
                return ret;
        }
-       imx_audmux_v2_configure_port(ext_port,
+       ret = imx_audmux_v2_configure_port(ext_port,
                        IMX_AUDMUX_V2_PTCR_SYN,
                        IMX_AUDMUX_V2_PDCR_RXDSEL(int_port));
        if (ret) {
index 009533a..df65f98 100644 (file)
@@ -59,7 +59,7 @@ static int am3517evm_hw_params(struct snd_pcm_substream *substream,
                return ret;
        }
 
-       snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_FSR_SRC_FSX, 0,
+       ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_FSR_SRC_FSX, 0,
                                SND_SOC_CLOCK_IN);
        if (ret < 0) {
                printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_FSR_SRC_FSX\n");
index f3ebc38..b70964e 100644 (file)
@@ -34,9 +34,7 @@ static const struct snd_pcm_hardware dma_hardware = {
        .info                   = SNDRV_PCM_INFO_INTERLEAVED |
                                    SNDRV_PCM_INFO_BLOCK_TRANSFER |
                                    SNDRV_PCM_INFO_MMAP |
-                                   SNDRV_PCM_INFO_MMAP_VALID |
-                                   SNDRV_PCM_INFO_PAUSE |
-                                   SNDRV_PCM_INFO_RESUME,
+                                   SNDRV_PCM_INFO_MMAP_VALID,
        .formats                = SNDRV_PCM_FMTBIT_S16_LE |
                                    SNDRV_PCM_FMTBIT_U16_LE |
                                    SNDRV_PCM_FMTBIT_U8 |
@@ -248,15 +246,11 @@ static int dma_trigger(struct snd_pcm_substream *substream, int cmd)
 
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
-       case SNDRV_PCM_TRIGGER_RESUME:
-       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
                prtd->state |= ST_RUNNING;
                prtd->params->ops->trigger(prtd->params->ch);
                break;
 
        case SNDRV_PCM_TRIGGER_STOP:
-       case SNDRV_PCM_TRIGGER_SUSPEND:
-       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
                prtd->state &= ~ST_RUNNING;
                prtd->params->ops->stop(prtd->params->ch);
                break;
index dd7c49f..f90139b 100644 (file)
@@ -291,8 +291,11 @@ static int snd_soc_dapm_set_bias_level(struct snd_soc_dapm_context *dapm,
                if (dapm->codec->driver->set_bias_level)
                        ret = dapm->codec->driver->set_bias_level(dapm->codec,
                                                                  level);
-       } else
+               else
+                       dapm->bias_level = level;
+       } else if (!card || dapm != &card->dapm) {
                dapm->bias_level = level;
+       }
 
        if (ret != 0)
                goto out;
index 97c2cac..8c7f237 100644 (file)
@@ -138,7 +138,7 @@ static void spear_pcm_free(struct snd_pcm *pcm)
                        continue;
 
                buf = &substream->dma_buffer;
-               if (!buf && !buf->area)
+               if (!buf || !buf->area)
                        continue;
 
                dma_free_writecombine(pcm->card->dev, buf->bytes,
index e463529..76cb1b3 100644 (file)
@@ -89,7 +89,6 @@ static struct snd_soc_jack_gpio tegra_alc5632_hp_jack_gpio = {
        .name = "Headset detection",
        .report = SND_JACK_HEADSET,
        .debounce_time = 150,
-       .invert = 1,
 };
 
 static const struct snd_soc_dapm_widget tegra_alc5632_dapm_widgets[] = {
index 5658bce..8d6900c 100644 (file)
@@ -334,11 +334,11 @@ static int tegra_pcm_hw_params(struct snd_pcm_substream *substream,
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
                slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
                slave_config.dst_addr = dmap->addr;
-               slave_config.src_maxburst = 0;
+               slave_config.dst_maxburst = 4;
        } else {
                slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
                slave_config.src_addr = dmap->addr;
-               slave_config.dst_maxburst = 0;
+               slave_config.src_maxburst = 4;
        }
        slave_config.slave_id = dmap->req_sel;
 
index 5c472f3..eb85113 100644 (file)
@@ -663,7 +663,6 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
                        struct ux500_msp **msp_p,
                        struct msp_i2s_platform_data *platform_data)
 {
-       int ret = 0;
        struct resource *res = NULL;
        struct i2s_controller *i2s_cont;
        struct ux500_msp *msp;
@@ -685,15 +684,14 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
        if (res == NULL) {
                dev_err(&pdev->dev, "%s: ERROR: Unable to get resource!\n",
                        __func__);
-               ret = -ENOMEM;
-               goto err_res;
+               return -ENOMEM;
        }
 
-       msp->registers = ioremap(res->start, (res->end - res->start + 1));
+       msp->registers = devm_ioremap(&pdev->dev, res->start,
+                                     resource_size(res));
        if (msp->registers == NULL) {
                dev_err(&pdev->dev, "%s: ERROR: ioremap failed!\n", __func__);
-               ret = -ENOMEM;
-               goto err_res;
+               return -ENOMEM;
        }
 
        msp->msp_state = MSP_STATE_IDLE;
@@ -705,7 +703,7 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
                dev_err(&pdev->dev,
                        "%s: ERROR: Failed to allocate I2S-controller!\n",
                        __func__);
-               goto err_i2s_cont;
+               return -ENOMEM;
        }
        i2s_cont->dev.parent = &pdev->dev;
        i2s_cont->data = (void *)msp;
@@ -716,14 +714,6 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
        msp->i2s_cont = i2s_cont;
 
        return 0;
-
-err_i2s_cont:
-       iounmap(msp->registers);
-
-err_res:
-       devm_kfree(&pdev->dev, msp);
-
-       return ret;
 }
 
 void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev,
@@ -732,11 +722,6 @@ void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev,
        dev_dbg(msp->dev, "%s: Enter (id = %d).\n", __func__, msp->id);
 
        device_unregister(&msp->i2s_cont->dev);
-       devm_kfree(&pdev->dev, msp->i2s_cont);
-
-       iounmap(msp->registers);
-
-       devm_kfree(&pdev->dev, msp);
 }
 
 MODULE_LICENSE("GPL v2");