Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Linus Torvalds [Mon, 1 Oct 2012 16:13:10 +0000 (09:13 -0700)]
Pull HID updates from Jiri Kosina:

 1) Patchset from Henrik Rydberg which substantially reduces irqsoff
    latency for all input devices.  In addition to that, Henrik reworked
    multitouch handling in order to reduce runtime memory consumption.

    This patchset touches code in Input subsystem as well.  All the
    changes have been Acked by Dmitry, and we agreed to do it this way
    due to inter-dependencies between the patchset and subsequent
    changes in HID subsystem.

 2) Rework, clenaups and a lot of fixes to picolcd driver by Bruno
    Prémont.

 3) Core report descriptor handling fix which fixes resume issue on some
    devices, by Kevin Daughtridge

 4) hidraw fixes by Alexey Khoroshilov and Ratan Nalumasu

 5) wiimote driver now supports balance board, by David Herrmann.

 6) Other smaller fixes and new device id additions all over the place.

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (79 commits)
  HID: hidraw: don't deallocate memory when it is in use
  HID: picoLCD: optimize for inactive debugfs
  HID: multitouch: add support for GeneralTouch multi-touchscreen
  HID: Add support for Sony PS3 BD Remote Control
  HID: keep dev_rdesc unmodified and use it for comparisons
  HID: lg4ff: Minor coding style fixes in lg4ff and hid-lg
  HID: hid-lg4ff: Set absolute axes parametes on DFP
  HID: hid-lg4ff: Adjust X axis input value accordingly to selected range.
  HID: hid-lg4ff: Minor code cleanup to improve readability
  HID: ntrig: change default value of logical/physical width/height to 1
  HID: picoLCD: bounds check in dump_buff_as_hex()
  Input: bcm5974 - Convert to MT-B
  Input: bcm5974 - Drop the logical dimensions
  Input: bcm5974 - Preparatory renames
  Input: bcm5974 - only setup button urb for TYPE1 devices
  HID: hid-multitouch: Add Flatfrog support
  HID: hid-multitouch: Fix contact count on 3M panels
  HID: hid-multitouch: Remove the redundant touch state
  HID: hid-multitouch: Simplify setup and frame synchronization
  HID: Allow more fields in the hid report
  ...

261 files changed:
Documentation/ABI/testing/sysfs-class-regulator
Documentation/accounting/getdelays.c
Documentation/devicetree/bindings/regulator/regulator.txt
Documentation/devicetree/bindings/regulator/tps65217.txt
Documentation/devicetree/bindings/regulator/tps6586x.txt
Documentation/dontdiff
Documentation/ia64/aliasing-test.c
Documentation/power/swsusp.txt
Documentation/trace/kprobetrace.txt
Documentation/vfio.txt
MAINTAINERS
Makefile
arch/arm/boot/compressed/head.S
arch/arm/include/asm/unistd.h
arch/arm/kernel/calls.S
arch/arm/kernel/smp_twd.c
arch/arm/mach-mxs/mach-mxs.c
arch/arm/mach-orion5x/common.c
arch/arm/mach-tegra/board-harmony-power.c
arch/arm/mm/dma-mapping.c
arch/c6x/include/asm/Kbuild
arch/c6x/include/asm/barrier.h [deleted file]
arch/m68k/platform/coldfire/clk.c
arch/mips/kernel/smp-cmp.c
arch/mips/mm/gup.c
arch/mips/mti-malta/malta-int.c
arch/mips/mti-malta/malta-platform.c
arch/powerpc/boot/.gitignore
arch/tile/include/gxio/iorpc_trio.h
arch/um/include/asm/processor-generic.h
arch/um/include/shared/common-offsets.h
arch/um/include/shared/user.h
arch/um/kernel/exec.c
arch/um/kernel/process.c
arch/um/kernel/signal.c
arch/um/kernel/syscall.c
arch/um/scripts/Makefile.rules
arch/x86/Makefile
arch/x86/include/asm/hpet.h
arch/x86/um/Kconfig
arch/x86/um/shared/sysdep/kernel-offsets.h
arch/x86/um/shared/sysdep/syscalls.h
arch/x86/um/signal.c
arch/x86/um/sys_call_table_32.c
arch/x86/um/syscalls_32.c
arch/x86/um/syscalls_64.c
arch/x86/xen/setup.c
drivers/base/regmap/regmap-irq.c
drivers/base/regmap/regmap.c
drivers/block/nvme.c
drivers/block/rbd.c
drivers/clk/Makefile
drivers/clk/clk-devres.c [new file with mode: 0644]
drivers/clk/clkdev.c
drivers/dma/at_hdmac.c
drivers/dma/ep93xx_dma.c
drivers/dma/fsldma.c
drivers/dma/imx-dma.c
drivers/dma/intel_mid_dma.c
drivers/dma/intel_mid_dma_regs.h
drivers/dma/ioat/hw.h
drivers/dma/pl330.c
drivers/dma/ppc4xx/adma.c
drivers/dma/ste_dma40_ll.h
drivers/edac/edac_mc.c
drivers/edac/i3200_edac.c
drivers/edac/i5000_edac.c
drivers/edac/sb_edac.c
drivers/extcon/extcon-arizona.c
drivers/gpio/gpio-lpc32xx.c
drivers/gpu/drm/nouveau/nouveau_abi16.c
drivers/gpu/drm/nouveau/nvc0_fb.c
drivers/gpu/drm/nouveau/nvc0_fifo.c
drivers/gpu/drm/nouveau/nve0_fifo.c
drivers/gpu/drm/udl/udl_connector.c
drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
drivers/hwmon/coretemp.c
drivers/hwmon/fam15h_power.c
drivers/hwmon/via-cputemp.c
drivers/iommu/amd_iommu.c
drivers/md/dm-mpath.c
drivers/md/dm-table.c
drivers/md/dm-thin.c
drivers/md/dm-verity.c
drivers/md/dm.c
drivers/md/dm.h
drivers/md/raid10.c
drivers/md/raid5.c
drivers/mfd/ab8500-gpadc.c
drivers/mfd/rc5t583.c
drivers/mfd/rdc321x-southbridge.c
drivers/mfd/tps6586x.c
drivers/mfd/tps65911-comparator.c
drivers/mfd/wm8994-irq.c
drivers/mmc/core/sdio.c
drivers/mmc/host/at91_mci.c
drivers/mmc/host/atmel-mci.c
drivers/mmc/host/omap_hsmmc.c
drivers/mmc/host/sdhci-esdhc-imx.c
drivers/mmc/host/vub300.c
drivers/mtd/mtdchar.c
drivers/net/ethernet/3com/typhoon.c
drivers/net/ethernet/broadcom/bnx2.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
drivers/net/ethernet/octeon/octeon_mgmt.c
drivers/net/ethernet/pasemi/pasemi_mac.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
drivers/net/phy/bcm87xx.c
drivers/net/phy/micrel.c
drivers/net/phy/smsc.c
drivers/net/ppp/pppoe.c
drivers/net/team/team.c
drivers/net/usb/smsc75xx.c
drivers/net/wireless/b43/Kconfig
drivers/net/wireless/iwlwifi/pcie/trans.c
drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
drivers/net/wireless/rtlwifi/rtl8192de/fw.c
drivers/pci/.gitignore [deleted file]
drivers/regulator/Kconfig
drivers/regulator/Makefile
drivers/regulator/aat2870-regulator.c
drivers/regulator/ab3100.c
drivers/regulator/ab8500.c
drivers/regulator/arizona-ldo1.c
drivers/regulator/arizona-micsupp.c
drivers/regulator/core.c
drivers/regulator/da9052-regulator.c
drivers/regulator/dummy.c
drivers/regulator/fan53555.c [new file with mode: 0644]
drivers/regulator/isl6271a-regulator.c
drivers/regulator/lp872x.c
drivers/regulator/lp8788-buck.c
drivers/regulator/lp8788-ldo.c
drivers/regulator/max77686.c
drivers/regulator/max8907-regulator.c [new file with mode: 0644]
drivers/regulator/mc13783-regulator.c
drivers/regulator/mc13892-regulator.c
drivers/regulator/mc13xxx-regulator-core.c
drivers/regulator/mc13xxx.h
drivers/regulator/of_regulator.c
drivers/regulator/palmas-regulator.c
drivers/regulator/s2mps11.c
drivers/regulator/tps6524x-regulator.c
drivers/regulator/tps6586x-regulator.c
drivers/regulator/twl-regulator.c
drivers/regulator/wm831x-dcdc.c
drivers/regulator/wm831x-ldo.c
drivers/regulator/wm8400-regulator.c
drivers/scsi/aic7xxx/aic79xx_core.c
drivers/scsi/bfa/bfa_ioc.c
drivers/scsi/bfa/bfa_ioc.h
drivers/scsi/bnx2fc/bnx2fc_fcoe.c
drivers/scsi/bnx2i/bnx2i_hwi.c
drivers/scsi/gdth.h
drivers/scsi/hpsa.c
drivers/scsi/ipr.c
drivers/scsi/isci/host.c
drivers/scsi/isci/init.c
drivers/scsi/isci/port.c
drivers/scsi/isci/request.c
drivers/scsi/isci/task.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/megaraid.c
drivers/scsi/megaraid.h
drivers/scsi/mpt2sas/mpt2sas_base.c
drivers/scsi/mvumi.c
drivers/scsi/qla4xxx/ql4_os.c
drivers/scsi/virtio_scsi.c
drivers/scsi/vmw_pvscsi.c
drivers/sh/pfc/pinctrl.c
drivers/spi/spi-au1550.c
drivers/spi/spi-bfin-sport.c
drivers/spi/spi-oc-tiny.c
drivers/spi/spi-ppc4xx.c
drivers/spi/spi-topcliff-pch.c
drivers/target/iscsi/iscsi_target_parameters.c
drivers/usb/core/devices.c
drivers/usb/core/hcd.c
drivers/usb/host/ohci-at91.c
drivers/vfio/pci/vfio_pci_intrs.c
drivers/video/backlight/88pm860x_bl.c
drivers/video/exynos/exynos_mipi_dsi.c
drivers/video/tmiofb.c
drivers/w1/masters/ds1wm.c
fs/btrfs/ctree.h
fs/btrfs/delayed-ref.h
fs/btrfs/inode.c
fs/dcache.c
fs/ext2/balloc.c
fs/ext3/balloc.c
fs/ext3/inode.c
fs/ext4/inode.c
fs/ext4/mballoc.c
fs/fs-writeback.c
fs/gfs2/aops.c
fs/gfs2/bmap.c
fs/gfs2/file.c
fs/gfs2/glock.c
fs/gfs2/glops.c
fs/gfs2/incore.h
fs/gfs2/inode.c
fs/gfs2/ops_fstype.c
fs/gfs2/quota.c
fs/gfs2/rgrp.c
fs/gfs2/rgrp.h
fs/gfs2/super.c
fs/gfs2/trace_gfs2.h
fs/gfs2/trans.h
fs/gfs2/xattr.c
fs/libfs.c
fs/lockd/svclock.c
fs/namespace.c
fs/nfs/super.c
include/asm-generic/unistd.h
include/linux/iommu.h
include/linux/irqdesc.h
include/linux/mfd/max77686.h
include/linux/mfd/max8998.h
include/linux/mfd/tps6586x.h
include/linux/micrel_phy.h
include/linux/nvme.h
include/linux/regmap.h
include/linux/regulator/consumer.h
include/linux/regulator/driver.h
include/linux/regulator/fan53555.h [new file with mode: 0644]
include/linux/regulator/machine.h
include/linux/security.h
include/trace/define_trace.h
lib/flex_proportions.c
mm/bootmem.c
mm/huge_memory.c
net/8021q/vlanproc.c
net/batman-adv/bat_iv_ogm.c
net/batman-adv/soft-interface.c
net/bluetooth/hci_core.c
net/bluetooth/l2cap_core.c
net/bluetooth/mgmt.c
net/ceph/messenger.c
net/core/sock.c
net/ipv4/inetpeer.c
net/ipv4/raw.c
net/ipv6/mip6.c
net/ipv6/raw.c
net/l2tp/l2tp_netlink.c
net/netfilter/xt_limit.c
net/wireless/reg.c
scripts/Makefile.fwinst
scripts/checksyscalls.sh
scripts/coccinelle/api/memdup_user.cocci
security/apparmor/.gitignore
sound/oss/.gitignore
sound/soc/codecs/wm2000.c
sound/usb/endpoint.c
tools/perf/util/callchain.h
tools/perf/util/parse-events-test.c
tools/perf/util/python-ext-sources
tools/testing/ktest/examples/include/defaults.conf
tools/testing/ktest/examples/include/tests.conf
tools/testing/selftests/vm/run_vmtests

index e091fa8..bc578bc 100644 (file)
@@ -349,3 +349,24 @@ Description:
 
                This will be one of the same strings reported by
                the "state" attribute.
+
+What:          /sys/class/regulator/.../bypass
+Date:          September 2012
+KernelVersion: 3.7
+Contact:       Mark Brown <broonie@opensource.wolfsonmicro.com>
+Description:
+               Some regulator directories will contain a field called
+               bypass.  This indicates if the device is in bypass mode.
+
+               This will be one of the following strings:
+
+               'enabled'
+               'disabled'
+               'unknown'
+
+               'enabled' means the regulator is in bypass mode.
+
+               'disabled' means that the regulator is regulating.
+
+               'unknown' means software cannot determine the state, or
+               the reported state is invalid.
index f6318f6..6f706ac 100644 (file)
@@ -98,10 +98,9 @@ static int create_nl_socket(int protocol)
        if (rcvbufsz)
                if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF,
                                &rcvbufsz, sizeof(rcvbufsz)) < 0) {
-                       fprintf(stderr, "Unable to set socket rcv buf size "
-                                       "to %d\n",
+                       fprintf(stderr, "Unable to set socket rcv buf size to %d\n",
                                rcvbufsz);
-                       return -1;
+                       goto error;
                }
 
        memset(&local, 0, sizeof(local));
index 66ece3f..ecfc6cc 100644 (file)
@@ -11,10 +11,13 @@ Optional properties:
 - regulator-boot-on: bootloader/firmware enabled regulator
 - <name>-supply: phandle to the parent supply/regulator node
 - regulator-ramp-delay: ramp delay for regulator(in uV/uS)
+
+Deprecated properties:
 - regulator-compatible: If a regulator chip contains multiple
   regulators, and if the chip's binding contains a child node that
   describes each regulator, then this property indicates which regulator
-  this child node is intended to configure.
+  this child node is intended to configure. If this property is missing,
+  the node's name will be used instead.
 
 Example:
 
index 0487e96..d316fb8 100644 (file)
@@ -22,66 +22,49 @@ Example:
                compatible = "ti,tps65217";
 
                regulators {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       dcdc1_reg: regulator@0 {
-                               reg = <0>;
-                               regulator-compatible = "dcdc1";
+                       dcdc1_reg: dcdc1 {
                                regulator-min-microvolt = <900000>;
                                regulator-max-microvolt = <1800000>;
                                regulator-boot-on;
                                regulator-always-on;
                        };
 
-                       dcdc2_reg: regulator@1 {
-                               reg = <1>;
-                               regulator-compatible = "dcdc2";
+                       dcdc2_reg: dcdc2 {
                                regulator-min-microvolt = <900000>;
                                regulator-max-microvolt = <3300000>;
                                regulator-boot-on;
                                regulator-always-on;
                        };
 
-                       dcdc3_reg: regulator@2 {
-                               reg = <2>;
-                               regulator-compatible = "dcdc3";
+                       dcdc3_reg: dcc3 {
                                regulator-min-microvolt = <900000>;
                                regulator-max-microvolt = <1500000>;
                                regulator-boot-on;
                                regulator-always-on;
                        };
 
-                       ldo1_reg: regulator@3 {
-                               reg = <3>;
-                               regulator-compatible = "ldo1";
+                       ldo1_reg: ldo1 {
                                regulator-min-microvolt = <1000000>;
                                regulator-max-microvolt = <3300000>;
                                regulator-boot-on;
                                regulator-always-on;
                        };
 
-                       ldo2_reg: regulator@4 {
-                               reg = <4>;
-                               regulator-compatible = "ldo2";
+                       ldo2_reg: ldo2 {
                                regulator-min-microvolt = <900000>;
                                regulator-max-microvolt = <3300000>;
                                regulator-boot-on;
                                regulator-always-on;
                        };
 
-                       ldo3_reg: regulator@5 {
-                               reg = <5>;
-                               regulator-compatible = "ldo3";
+                       ldo3_reg: ldo3 {
                                regulator-min-microvolt = <1800000>;
                                regulator-max-microvolt = <3300000>;
                                regulator-boot-on;
                                regulator-always-on;
                        };
 
-                       ldo4_reg: regulator@6 {
-                               reg = <6>;
-                               regulator-compatible = "ldo4";
+                       ldo4_reg: ldo4 {
                                regulator-min-microvolt = <1800000>;
                                regulator-max-microvolt = <3300000>;
                                regulator-boot-on;
index da80c2a..07b9ef6 100644 (file)
@@ -6,9 +6,13 @@ Required properties:
 - interrupts: the interrupt outputs of the controller
 - #gpio-cells: number of cells to describe a GPIO
 - gpio-controller: mark the device as a GPIO controller
-- regulators: list of regulators provided by this controller, must have
-  property "regulator-compatible" to match their hardware counterparts:
-  sm[0-2], ldo[0-9] and ldo_rtc
+- regulators: A node that houses a sub-node for each regulator within the
+  device. Each sub-node is identified using the node's name (or the deprecated
+  regulator-compatible property if present), with valid values listed below.
+  The content of each sub-node is defined by the standard binding for
+  regulators; see regulator.txt.
+  sys, sm[0-2], ldo[0-9] and ldo_rtc
+- sys-supply: The input supply for SYS.
 - vin-sm0-supply: The input supply for the SM0.
 - vin-sm1-supply: The input supply for the SM1.
 - vin-sm2-supply: The input supply for the SM2.
@@ -20,6 +24,9 @@ Required properties:
 
 Each regulator is defined using the standard binding for regulators.
 
+Note: LDO5 and LDO_RTC is supplied by SYS regulator internally and driver
+      take care of making proper parent child relationship.
+
 Example:
 
        pmu: tps6586x@34 {
@@ -30,6 +37,7 @@ Example:
                #gpio-cells = <2>;
                gpio-controller;
 
+               sys-supply = <&some_reg>;
                vin-sm0-supply = <&some_reg>;
                vin-sm1-supply = <&some_reg>;
                vin-sm2-supply = <&some_reg>;
@@ -40,103 +48,80 @@ Example:
                vinldo9-supply = <...>;
 
                regulators {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
+                       sys_reg: sys {
+                               regulator-name = "vdd_sys";
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
 
-                       sm0_reg: regulator@0 {
-                               reg = <0>;
-                               regulator-compatible = "sm0";
+                       sm0_reg: sm0 {
                                regulator-min-microvolt = < 725000>;
                                regulator-max-microvolt = <1500000>;
                                regulator-boot-on;
                                regulator-always-on;
                        };
 
-                       sm1_reg: regulator@1 {
-                               reg = <1>;
-                               regulator-compatible = "sm1";
+                       sm1_reg: sm1 {
                                regulator-min-microvolt = < 725000>;
                                regulator-max-microvolt = <1500000>;
                                regulator-boot-on;
                                regulator-always-on;
                        };
 
-                       sm2_reg: regulator@2 {
-                               reg = <2>;
-                               regulator-compatible = "sm2";
+                       sm2_reg: sm2 {
                                regulator-min-microvolt = <3000000>;
                                regulator-max-microvolt = <4550000>;
                                regulator-boot-on;
                                regulator-always-on;
                        };
 
-                       ldo0_reg: regulator@3 {
-                               reg = <3>;
-                               regulator-compatible = "ldo0";
+                       ldo0_reg: ldo0 {
                                regulator-name = "PCIE CLK";
                                regulator-min-microvolt = <3300000>;
                                regulator-max-microvolt = <3300000>;
                        };
 
-                       ldo1_reg: regulator@4 {
-                               reg = <4>;
-                               regulator-compatible = "ldo1";
+                       ldo1_reg: ldo1 {
                                regulator-min-microvolt = < 725000>;
                                regulator-max-microvolt = <1500000>;
                        };
 
-                       ldo2_reg: regulator@5 {
-                               reg = <5>;
-                               regulator-compatible = "ldo2";
+                       ldo2_reg: ldo2 {
                                regulator-min-microvolt = < 725000>;
                                regulator-max-microvolt = <1500000>;
                        };
 
-                       ldo3_reg: regulator@6 {
-                               reg = <6>;
-                               regulator-compatible = "ldo3";
+                       ldo3_reg: ldo3 {
                                regulator-min-microvolt = <1250000>;
                                regulator-max-microvolt = <3300000>;
                        };
 
-                       ldo4_reg: regulator@7 {
-                               reg = <7>;
-                               regulator-compatible = "ldo4";
+                       ldo4_reg: ldo4 {
                                regulator-min-microvolt = <1700000>;
                                regulator-max-microvolt = <2475000>;
                        };
 
-                       ldo5_reg: regulator@8 {
-                               reg = <8>;
-                               regulator-compatible = "ldo5";
+                       ldo5_reg: ldo5 {
                                regulator-min-microvolt = <1250000>;
                                regulator-max-microvolt = <3300000>;
                        };
 
-                       ldo6_reg: regulator@9 {
-                               reg = <9>;
-                               regulator-compatible = "ldo6";
+                       ldo6_reg: ldo6 {
                                regulator-min-microvolt = <1250000>;
                                regulator-max-microvolt = <3300000>;
                        };
 
-                       ldo7_reg: regulator@10 {
-                               reg = <10>;
-                               regulator-compatible = "ldo7";
+                       ldo7_reg: ldo7 {
                                regulator-min-microvolt = <1250000>;
                                regulator-max-microvolt = <3300000>;
                        };
 
-                       ldo8_reg: regulator@11 {
-                               reg = <11>;
-                               regulator-compatible = "ldo8";
+                       ldo8_reg: ldo8 {
                                regulator-min-microvolt = <1250000>;
                                regulator-max-microvolt = <3300000>;
                        };
 
-                       ldo9_reg: regulator@12 {
-                               reg = <12>;
-                               regulator-compatible = "ldo9";
+                       ldo9_reg: ldo9 {
                                regulator-min-microvolt = <1250000>;
                                regulator-max-microvolt = <3300000>;
                        };
index 39462cf..74c25c8 100644 (file)
@@ -162,7 +162,6 @@ mach-types.h
 machtypes.h
 map
 map_hugetlb
-maui_boot.h
 media
 mconf
 miboot*
index 5caa2af..62a190d 100644 (file)
@@ -132,6 +132,7 @@ static int read_rom(char *path)
 
        rc = write(fd, "1", 2);
        if (rc <= 0) {
+               close(fd);
                perror("write");
                return -1;
        }
index 92341b8..0b4b63e 100644 (file)
@@ -53,7 +53,7 @@ before suspend (it is limited to 500 MB by default).
 
 Article about goals and implementation of Software Suspend for Linux
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Author: G\202ábor Kuti
+Author: Gábor Kuti
 Last revised: 2003-10-20 by Pavel Machek
 
 Idea and goals to achieve
index d0d0bb9..d68ea5f 100644 (file)
@@ -12,7 +12,7 @@ kprobes can probe (this means, all functions body except for __kprobes
 functions). Unlike the Tracepoint based event, this can be added and removed
 dynamically, on the fly.
 
-To enable this feature, build your kernel with CONFIG_KPROBE_TRACING=y.
+To enable this feature, build your kernel with CONFIG_KPROBE_EVENT=y.
 
 Similar to the events tracer, this doesn't need to be activated via
 current_tracer. Instead of that, add probe points via
index 0cb6685..8eda363 100644 (file)
@@ -133,7 +133,7 @@ character devices for this group:
 $ lspci -n -s 0000:06:0d.0
 06:0d.0 0401: 1102:0002 (rev 08)
 # echo 0000:06:0d.0 > /sys/bus/pci/devices/0000:06:0d.0/driver/unbind
-# echo 1102 0002 > /sys/bus/pci/drivers/vfio/new_id
+# echo 1102 0002 > /sys/bus/pci/drivers/vfio-pci/new_id
 
 Now we need to look at what other devices are in the group to free
 it for use by VFIO:
index 553a863..9362f54 100644 (file)
@@ -3552,11 +3552,12 @@ K:      \b(ABS|SYN)_MT_
 
 INTEL C600 SERIES SAS CONTROLLER DRIVER
 M:     Intel SCU Linux support <intel-linux-scu@intel.com>
+M:     Lukasz Dorau <lukasz.dorau@intel.com>
+M:     Maciej Patelczyk <maciej.patelczyk@intel.com>
 M:     Dave Jiang <dave.jiang@intel.com>
-M:     Ed Nadolski <edmund.nadolski@intel.com>
 L:     linux-scsi@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/djbw/isci.git
-S:     Maintained
+T:     git git://git.code.sf.net/p/intel-sas/isci
+S:     Supported
 F:     drivers/scsi/isci/
 F:     firmware/isci/
 
@@ -5550,6 +5551,8 @@ F:        Documentation/devicetree/bindings/pwm/
 F:     include/linux/pwm.h
 F:     include/linux/of_pwm.h
 F:     drivers/pwm/
+F:     drivers/video/backlight/pwm_bl.c
+F:     include/linux/pwm_backlight.h
 
 PXA2xx/PXA3xx SUPPORT
 M:     Eric Miao <eric.y.miao@gmail.com>
index ae6928c..bb9fff2 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 VERSION = 3
 PATCHLEVEL = 6
 SUBLEVEL = 0
-EXTRAVERSION = -rc6
-NAME = Saber-toothed Squirrel
+EXTRAVERSION =
+NAME = Terrified Chipmunk
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
index 81769c1..bc67cbf 100644 (file)
@@ -653,6 +653,7 @@ __armv7_mmu_cache_on:
                mcrne   p15, 0, r0, c8, c7, 0   @ flush I,D TLBs
 #endif
                mrc     p15, 0, r0, c1, c0, 0   @ read control reg
+               bic     r0, r0, #1 << 28        @ clear SCTLR.TRE
                orr     r0, r0, #0x5000         @ I-cache enable, RR cache replacement
                orr     r0, r0, #0x003c         @ write buffer
 #ifdef CONFIG_MMU
index 0cab47d..2fde5fd 100644 (file)
 #define __NR_setns                     (__NR_SYSCALL_BASE+375)
 #define __NR_process_vm_readv          (__NR_SYSCALL_BASE+376)
 #define __NR_process_vm_writev         (__NR_SYSCALL_BASE+377)
+                                       /* 378 for kcmp */
 
 /*
  * The following SWIs are ARM private.
  */
 #define __IGNORE_fadvise64_64
 #define __IGNORE_migrate_pages
+#define __IGNORE_kcmp
 
 #endif /* __KERNEL__ */
 #endif /* __ASM_ARM_UNISTD_H */
index 463ff4a..e337879 100644 (file)
 /* 375 */      CALL(sys_setns)
                CALL(sys_process_vm_readv)
                CALL(sys_process_vm_writev)
+               CALL(sys_ni_syscall)    /* reserved for sys_kcmp */
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 #define syscalls_counted
index fef42b2..e1f9069 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/clk.h>
-#include <linux/cpufreq.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/err.h>
@@ -96,7 +95,52 @@ static void twd_timer_stop(struct clock_event_device *clk)
        disable_percpu_irq(clk->irq);
 }
 
-#ifdef CONFIG_CPU_FREQ
+#ifdef CONFIG_COMMON_CLK
+
+/*
+ * Updates clockevent frequency when the cpu frequency changes.
+ * Called on the cpu that is changing frequency with interrupts disabled.
+ */
+static void twd_update_frequency(void *new_rate)
+{
+       twd_timer_rate = *((unsigned long *) new_rate);
+
+       clockevents_update_freq(*__this_cpu_ptr(twd_evt), twd_timer_rate);
+}
+
+static int twd_rate_change(struct notifier_block *nb,
+       unsigned long flags, void *data)
+{
+       struct clk_notifier_data *cnd = data;
+
+       /*
+        * The twd clock events must be reprogrammed to account for the new
+        * frequency.  The timer is local to a cpu, so cross-call to the
+        * changing cpu.
+        */
+       if (flags == POST_RATE_CHANGE)
+               smp_call_function(twd_update_frequency,
+                                 (void *)&cnd->new_rate, 1);
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block twd_clk_nb = {
+       .notifier_call = twd_rate_change,
+};
+
+static int twd_clk_init(void)
+{
+       if (twd_evt && *__this_cpu_ptr(twd_evt) && !IS_ERR(twd_clk))
+               return clk_notifier_register(twd_clk, &twd_clk_nb);
+
+       return 0;
+}
+core_initcall(twd_clk_init);
+
+#elif defined (CONFIG_CPU_FREQ)
+
+#include <linux/cpufreq.h>
 
 /*
  * Updates clockevent frequency when the cpu frequency changes.
index 8dabfe8..ff886e0 100644 (file)
@@ -261,7 +261,7 @@ static void __init apx4devkit_init(void)
        enable_clk_enet_out();
 
        if (IS_BUILTIN(CONFIG_PHYLIB))
-               phy_register_fixup_for_uid(PHY_ID_KS8051, MICREL_PHY_ID_MASK,
+               phy_register_fixup_for_uid(PHY_ID_KSZ8051, MICREL_PHY_ID_MASK,
                                           apx4devkit_phy_fixup);
 
        mxsfb_pdata.mode_list = apx4devkit_video_modes;
index 410291c..a6cd14a 100644 (file)
@@ -204,6 +204,13 @@ void __init orion5x_wdt_init(void)
 void __init orion5x_init_early(void)
 {
        orion_time_set_base(TIMER_VIRT_BASE);
+
+       /*
+        * Some Orion5x devices allocate their coherent buffers from atomic
+        * context. Increase size of atomic coherent pool to make sure such
+        * the allocations won't fail.
+        */
+       init_dma_coherent_pool_size(SZ_1M);
 }
 
 int orion5x_tclk;
index b7344be..94486e7 100644 (file)
@@ -67,6 +67,13 @@ static struct regulator_init_data ldo0_data = {
                },                                                      \
        }
 
+static struct regulator_init_data sys_data = {
+       .supply_regulator = "vdd_5v0",
+       .constraints = {
+               .name = "vdd_sys",
+       },
+};
+
 HARMONY_REGULATOR_INIT(sm0,  "vdd_sm0",  "vdd_sys", 725, 1500, 1);
 HARMONY_REGULATOR_INIT(sm1,  "vdd_sm1",  "vdd_sys", 725, 1500, 1);
 HARMONY_REGULATOR_INIT(sm2,  "vdd_sm2",  "vdd_sys", 3000, 4550, 1);
@@ -74,7 +81,7 @@ HARMONY_REGULATOR_INIT(ldo1, "vdd_ldo1", "vdd_sm2", 725, 1500, 1);
 HARMONY_REGULATOR_INIT(ldo2, "vdd_ldo2", "vdd_sm2", 725, 1500, 0);
 HARMONY_REGULATOR_INIT(ldo3, "vdd_ldo3", "vdd_sm2", 1250, 3300, 1);
 HARMONY_REGULATOR_INIT(ldo4, "vdd_ldo4", "vdd_sm2", 1700, 2475, 1);
-HARMONY_REGULATOR_INIT(ldo5, "vdd_ldo5", NULL,     1250, 3300, 1);
+HARMONY_REGULATOR_INIT(ldo5, "vdd_ldo5", "vdd_sys", 1250, 3300, 1);
 HARMONY_REGULATOR_INIT(ldo6, "vdd_ldo6", "vdd_sm2", 1250, 3300, 0);
 HARMONY_REGULATOR_INIT(ldo7, "vdd_ldo7", "vdd_sm2", 1250, 3300, 0);
 HARMONY_REGULATOR_INIT(ldo8, "vdd_ldo8", "vdd_sm2", 1250, 3300, 0);
@@ -88,6 +95,7 @@ HARMONY_REGULATOR_INIT(ldo9, "vdd_ldo9", "vdd_sm2", 1250, 3300, 1);
        }
 
 static struct tps6586x_subdev_info tps_devs[] = {
+       TPS_REG(SYS, &sys_data),
        TPS_REG(SM_0, &sm0_data),
        TPS_REG(SM_1, &sm1_data),
        TPS_REG(SM_2, &sm2_data),
@@ -120,7 +128,7 @@ static struct i2c_board_info __initdata harmony_regulators[] = {
 
 int __init harmony_regulator_init(void)
 {
-       regulator_register_always_on(0, "vdd_sys",
+       regulator_register_always_on(0, "vdd_5v0",
                NULL, 0, 5000000);
 
        if (machine_is_harmony()) {
index e59c4ab..13f555d 100644 (file)
@@ -346,6 +346,8 @@ static int __init atomic_pool_init(void)
                       (unsigned)pool->size / 1024);
                return 0;
        }
+
+       kfree(pages);
 no_pages:
        kfree(bitmap);
 no_bitmap:
index 3af601e..f08e891 100644 (file)
@@ -2,6 +2,7 @@ include include/asm-generic/Kbuild.asm
 
 generic-y += atomic.h
 generic-y += auxvec.h
+generic-y += barrier.h
 generic-y += bitsperlong.h
 generic-y += bugs.h
 generic-y += cputime.h
diff --git a/arch/c6x/include/asm/barrier.h b/arch/c6x/include/asm/barrier.h
deleted file mode 100644 (file)
index 538240e..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *  Port on Texas Instruments TMS320C6x architecture
- *
- *  Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
- *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- */
-#ifndef _ASM_C6X_BARRIER_H
-#define _ASM_C6X_BARRIER_H
-
-#define nop()                    asm("NOP\n");
-
-#define mb()                     barrier()
-#define rmb()                    barrier()
-#define wmb()                    barrier()
-#define set_mb(var, value)       do { var = value;  mb(); } while (0)
-#define set_wmb(var, value)      do { var = value; wmb(); } while (0)
-
-#define smp_mb()                barrier()
-#define smp_rmb()               barrier()
-#define smp_wmb()               barrier()
-#define smp_read_barrier_depends()     do { } while (0)
-
-#endif /* _ASM_C6X_BARRIER_H */
index 75f9ee9..9cd13b4 100644 (file)
@@ -146,9 +146,3 @@ struct clk_ops clk_ops1 = {
 };
 #endif /* MCFPM_PPMCR1 */
 #endif /* MCFPM_PPMCR0 */
-
-struct clk *devm_clk_get(struct device *dev, const char *id)
-{
-       return NULL;
-}
-EXPORT_SYMBOL(devm_clk_get);
index e7e03ec..afc379c 100644 (file)
@@ -102,7 +102,7 @@ static void cmp_init_secondary(void)
        c->vpe_id = (read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE;
 #endif
 #ifdef CONFIG_MIPS_MT_SMTC
-       c->tc_id  = (read_c0_tcbind() >> TCBIND_CURTC_SHIFT) & TCBIND_CURTC;
+       c->tc_id  = (read_c0_tcbind() & TCBIND_CURTC) >> TCBIND_CURTC_SHIFT;
 #endif
 }
 
index 33aadbc..dcfd573 100644 (file)
@@ -152,6 +152,8 @@ static int gup_huge_pud(pud_t pud, unsigned long addr, unsigned long end,
        do {
                VM_BUG_ON(compound_head(page) != head);
                pages[*nr] = page;
+               if (PageTail(page))
+                       get_huge_page_tail(page);
                (*nr)++;
                page++;
                refs++;
index 7b13a4c..fea823f 100644 (file)
@@ -273,16 +273,19 @@ asmlinkage void plat_irq_dispatch(void)
        unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
        int irq;
 
+       if (unlikely(!pending)) {
+               spurious_interrupt();
+               return;
+       }
+
        irq = irq_ffs(pending);
 
        if (irq == MIPSCPU_INT_I8259A)
                malta_hw0_irqdispatch();
        else if (gic_present && ((1 << irq) & ipi_map[smp_processor_id()]))
                malta_ipi_irqdispatch();
-       else if (irq >= 0)
-               do_IRQ(MIPS_CPU_IRQ_BASE + irq);
        else
-               spurious_interrupt();
+               do_IRQ(MIPS_CPU_IRQ_BASE + irq);
 }
 
 #ifdef CONFIG_MIPS_MT_SMP
index 4c35301..80562b8 100644 (file)
@@ -138,11 +138,6 @@ static int __init malta_add_devices(void)
        if (err)
                return err;
 
-       /*
-        * Set RTC to BCD mode to support current alarm code.
-        */
-       CMOS_WRITE(CMOS_READ(RTC_CONTROL) & ~RTC_DM_BINARY, RTC_CONTROL);
-
        return 0;
 }
 
index 1c1aadc..c32ae5c 100644 (file)
@@ -1,10 +1,6 @@
 addnote
 empty.c
 hack-coff
-infblock.c
-infblock.h
-infcodes.c
-infcodes.h
 inffast.c
 inffast.h
 inffixed.h
index 15fb779..58105c3 100644 (file)
 #include <linux/module.h>
 #include <asm/pgtable.h>
 
-#define GXIO_TRIO_OP_ALLOC_ASIDS       IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1400)
+#define GXIO_TRIO_OP_DEALLOC_ASID      IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1400)
+#define GXIO_TRIO_OP_ALLOC_ASIDS       IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1401)
 
-#define GXIO_TRIO_OP_ALLOC_MEMORY_MAPS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1402)
+#define GXIO_TRIO_OP_ALLOC_MEMORY_MAPS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1404)
 
-#define GXIO_TRIO_OP_ALLOC_PIO_REGIONS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x140e)
-#define GXIO_TRIO_OP_INIT_PIO_REGION_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x140f)
+#define GXIO_TRIO_OP_ALLOC_PIO_REGIONS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1412)
 
-#define GXIO_TRIO_OP_INIT_MEMORY_MAP_MMU_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1417)
-#define GXIO_TRIO_OP_GET_PORT_PROPERTY IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1418)
-#define GXIO_TRIO_OP_CONFIG_LEGACY_INTR IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x1419)
-#define GXIO_TRIO_OP_CONFIG_MSI_INTR   IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x141a)
+#define GXIO_TRIO_OP_INIT_PIO_REGION_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1414)
 
-#define GXIO_TRIO_OP_SET_MPS_MRS       IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141c)
-#define GXIO_TRIO_OP_FORCE_RC_LINK_UP  IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141d)
-#define GXIO_TRIO_OP_FORCE_EP_LINK_UP  IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141e)
+#define GXIO_TRIO_OP_INIT_MEMORY_MAP_MMU_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141e)
+#define GXIO_TRIO_OP_GET_PORT_PROPERTY IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141f)
+#define GXIO_TRIO_OP_CONFIG_LEGACY_INTR IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x1420)
+#define GXIO_TRIO_OP_CONFIG_MSI_INTR   IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x1421)
+
+#define GXIO_TRIO_OP_SET_MPS_MRS       IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1423)
+#define GXIO_TRIO_OP_FORCE_RC_LINK_UP  IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1424)
+#define GXIO_TRIO_OP_FORCE_EP_LINK_UP  IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1425)
 #define GXIO_TRIO_OP_GET_MMIO_BASE     IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)
 #define GXIO_TRIO_OP_CHECK_MMIO_OFFSET IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8001)
 
index 69f1c57..33a6a24 100644 (file)
@@ -20,14 +20,6 @@ struct mm_struct;
 
 struct thread_struct {
        struct task_struct *saved_task;
-       /*
-        * This flag is set to 1 before calling do_fork (and analyzed in
-        * copy_thread) to mark that we are begin called from userspace (fork /
-        * vfork / clone), and reset to 0 after. It is left to 0 when called
-        * from kernelspace (i.e. kernel_thread() or fork_idle(),
-        * as of 2.6.11).
-        */
-       int forking;
        struct pt_regs regs;
        int singlestep_syscall;
        void *fault_addr;
@@ -58,7 +50,6 @@ struct thread_struct {
 
 #define INIT_THREAD \
 { \
-       .forking                = 0, \
        .regs                   = EMPTY_REGS,   \
        .fault_addr             = NULL, \
        .prev_sched             = NULL, \
index 40db8f7..2df313b 100644 (file)
@@ -7,16 +7,6 @@ DEFINE(UM_KERN_PAGE_MASK, PAGE_MASK);
 DEFINE(UM_KERN_PAGE_SHIFT, PAGE_SHIFT);
 DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
 
-DEFINE_STR(UM_KERN_EMERG, KERN_EMERG);
-DEFINE_STR(UM_KERN_ALERT, KERN_ALERT);
-DEFINE_STR(UM_KERN_CRIT, KERN_CRIT);
-DEFINE_STR(UM_KERN_ERR, KERN_ERR);
-DEFINE_STR(UM_KERN_WARNING, KERN_WARNING);
-DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE);
-DEFINE_STR(UM_KERN_INFO, KERN_INFO);
-DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG);
-DEFINE_STR(UM_KERN_CONT, KERN_CONT);
-
 DEFINE(UM_ELF_CLASS, ELF_CLASS);
 DEFINE(UM_ELFCLASS32, ELFCLASS32);
 DEFINE(UM_ELFCLASS64, ELFCLASS64);
index 4fa82c0..cef0685 100644 (file)
 extern void panic(const char *fmt, ...)
        __attribute__ ((format (printf, 1, 2)));
 
+/* Requires preincluding include/linux/kern_levels.h */
+#define UM_KERN_EMERG  KERN_EMERG
+#define UM_KERN_ALERT  KERN_ALERT
+#define UM_KERN_CRIT   KERN_CRIT
+#define UM_KERN_ERR    KERN_ERR
+#define UM_KERN_WARNING        KERN_WARNING
+#define UM_KERN_NOTICE KERN_NOTICE
+#define UM_KERN_INFO   KERN_INFO
+#define UM_KERN_DEBUG  KERN_DEBUG
+#define UM_KERN_CONT   KERN_CONT
+
 #ifdef UML_CONFIG_PRINTK
 extern int printk(const char *fmt, ...)
        __attribute__ ((format (printf, 1, 2)));
index 6cade93..8c82786 100644 (file)
@@ -39,34 +39,21 @@ void flush_thread(void)
 
 void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
 {
+       get_safe_registers(regs->regs.gp, regs->regs.fp);
        PT_REGS_IP(regs) = eip;
        PT_REGS_SP(regs) = esp;
-}
-EXPORT_SYMBOL(start_thread);
-
-static long execve1(const char *file,
-                   const char __user *const __user *argv,
-                   const char __user *const __user *env)
-{
-       long error;
-
-       error = do_execve(file, argv, env, &current->thread.regs);
-       if (error == 0) {
-               task_lock(current);
-               current->ptrace &= ~PT_DTRACE;
+       current->ptrace &= ~PT_DTRACE;
 #ifdef SUBARCH_EXECVE1
-               SUBARCH_EXECVE1(&current->thread.regs.regs);
+       SUBARCH_EXECVE1(regs->regs);
 #endif
-               task_unlock(current);
-       }
-       return error;
 }
+EXPORT_SYMBOL(start_thread);
 
 long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env)
 {
        long err;
 
-       err = execve1(file, argv, env);
+       err = do_execve(file, argv, env, &current->thread.regs);
        if (!err)
                UML_LONGJMP(current->thread.exec_buf, 1);
        return err;
@@ -81,7 +68,7 @@ long sys_execve(const char __user *file, const char __user *const __user *argv,
        filename = getname(file);
        error = PTR_ERR(filename);
        if (IS_ERR(filename)) goto out;
-       error = execve1(filename, argv, env);
+       error = do_execve(filename, argv, env, &current->thread.regs);
        putname(filename);
  out:
        return error;
index 57fc702..c5f5afa 100644 (file)
@@ -181,11 +181,12 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
                struct pt_regs *regs)
 {
        void (*handler)(void);
+       int kthread = current->flags & PF_KTHREAD;
        int ret = 0;
 
        p->thread = (struct thread_struct) INIT_THREAD;
 
-       if (current->thread.forking) {
+       if (!kthread) {
                memcpy(&p->thread.regs.regs, &regs->regs,
                       sizeof(p->thread.regs.regs));
                PT_REGS_SET_SYSCALL_RETURN(&p->thread.regs, 0);
@@ -195,8 +196,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
                handler = fork_handler;
 
                arch_copy_thread(&current->thread.arch, &p->thread.arch);
-       }
-       else {
+       } else {
                get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp);
                p->thread.request.u.thread = current->thread.request.u.thread;
                handler = new_thread_handler;
@@ -204,7 +204,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
 
        new_thread(task_stack_page(p), &p->thread.switch_buf, handler);
 
-       if (current->thread.forking) {
+       if (!kthread) {
                clear_flushed_tls(p);
 
                /*
index 7362d58..cc9c235 100644 (file)
@@ -22,9 +22,13 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr,
                         struct k_sigaction *ka, siginfo_t *info)
 {
        sigset_t *oldset = sigmask_to_save();
+       int singlestep = 0;
        unsigned long sp;
        int err;
 
+       if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
+               singlestep = 1;
+
        /* Did we come from a system call? */
        if (PT_REGS_SYSCALL_NR(regs) >= 0) {
                /* If so, check system call restarting.. */
@@ -61,7 +65,7 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr,
        if (err)
                force_sigsegv(signr, current);
        else
-               signal_delivered(signr, info, ka, regs, 0);
+               signal_delivered(signr, info, ka, regs, singlestep);
 }
 
 static int kern_do_signal(struct pt_regs *regs)
index f958cb8..a4c6d8e 100644 (file)
 
 long sys_fork(void)
 {
-       long ret;
-
-       current->thread.forking = 1;
-       ret = do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs),
+       return do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs),
                      &current->thread.regs, 0, NULL, NULL);
-       current->thread.forking = 0;
-       return ret;
 }
 
 long sys_vfork(void)
 {
-       long ret;
-
-       current->thread.forking = 1;
-       ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
+       return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
                      UPT_SP(&current->thread.regs.regs),
                      &current->thread.regs, 0, NULL, NULL);
-       current->thread.forking = 0;
-       return ret;
+}
+
+long sys_clone(unsigned long clone_flags, unsigned long newsp,
+              void __user *parent_tid, void __user *child_tid)
+{
+       if (!newsp)
+               newsp = UPT_SP(&current->thread.regs.regs);
+
+       return do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
+                     child_tid);
 }
 
 long old_mmap(unsigned long addr, unsigned long len,
index d50270d..15889df 100644 (file)
@@ -8,7 +8,7 @@ USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m)  $(USER_SINGLE_OBJS))
 USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
 
 $(USER_OBJS:.o=.%): \
-       c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) -include user.h $(CFLAGS_$(basetarget).o)
+       c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) -include $(srctree)/include/linux/kern_levels.h -include user.h $(CFLAGS_$(basetarget).o)
 
 # These are like USER_OBJS but filter USER_CFLAGS through unprofile instead of
 # using it directly.
index 682e9c2..474ca35 100644 (file)
@@ -142,7 +142,7 @@ KBUILD_CFLAGS += $(call cc-option,-mno-avx,)
 KBUILD_CFLAGS += $(mflags-y)
 KBUILD_AFLAGS += $(mflags-y)
 
-archscripts:
+archscripts: scripts_basic
        $(Q)$(MAKE) $(build)=arch/x86/tools relocs
 
 ###
index 2c392d6..434e210 100644 (file)
@@ -35,8 +35,6 @@
 #define        HPET_ID_NUMBER_SHIFT    8
 #define HPET_ID_VENDOR_SHIFT   16
 
-#define HPET_ID_VENDOR_8086    0x8086
-
 #define HPET_CFG_ENABLE                0x001
 #define HPET_CFG_LEGACY                0x002
 #define        HPET_LEGACY_8254        2
index 9926e11..aeaff8b 100644 (file)
@@ -21,6 +21,7 @@ config 64BIT
 config X86_32
        def_bool !64BIT
        select HAVE_AOUT
+       select ARCH_WANT_IPC_PARSE_VERSION
 
 config X86_64
        def_bool 64BIT
index 5868526..46a9df9 100644 (file)
@@ -7,9 +7,6 @@
 #define DEFINE(sym, val) \
        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
 
-#define STR(x) #x
-#define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " STR(val) " " #val: : )
-
 #define BLANK() asm volatile("\n->" : : )
 
 #define OFFSET(sym, str, mem) \
index bd9a89b..ca255a8 100644 (file)
@@ -1,3 +1,5 @@
+extern long sys_clone(unsigned long clone_flags, unsigned long newsp,
+              void __user *parent_tid, void __user *child_tid);
 #ifdef __i386__
 #include "syscalls_32.h"
 #else
index a508cea..ba7363e 100644 (file)
@@ -416,9 +416,6 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
        PT_REGS_AX(regs) = (unsigned long) sig;
        PT_REGS_DX(regs) = (unsigned long) 0;
        PT_REGS_CX(regs) = (unsigned long) 0;
-
-       if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
-               ptrace_notify(SIGTRAP);
        return 0;
 }
 
@@ -466,9 +463,6 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
        PT_REGS_AX(regs) = (unsigned long) sig;
        PT_REGS_DX(regs) = (unsigned long) &frame->info;
        PT_REGS_CX(regs) = (unsigned long) &frame->uc;
-
-       if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
-               ptrace_notify(SIGTRAP);
        return 0;
 }
 
index 68d1dc9..b5408ce 100644 (file)
@@ -28,7 +28,7 @@
 #define ptregs_execve sys_execve
 #define ptregs_iopl sys_iopl
 #define ptregs_vm86old sys_vm86old
-#define ptregs_clone sys_clone
+#define ptregs_clone i386_clone
 #define ptregs_vm86 sys_vm86
 #define ptregs_sigaltstack sys_sigaltstack
 #define ptregs_vfork sys_vfork
index b853e86..db444c7 100644 (file)
@@ -3,37 +3,24 @@
  * Licensed under the GPL
  */
 
-#include "linux/sched.h"
-#include "linux/shm.h"
-#include "linux/ipc.h"
-#include "linux/syscalls.h"
-#include "asm/mman.h"
-#include "asm/uaccess.h"
-#include "asm/unistd.h"
+#include <linux/syscalls.h>
+#include <sysdep/syscalls.h>
 
 /*
  * The prototype on i386 is:
  *
- *     int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls, int * child_tidptr)
+ *     int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls
  *
  * and the "newtls" arg. on i386 is read by copy_thread directly from the
  * register saved on the stack.
  */
-long sys_clone(unsigned long clone_flags, unsigned long newsp,
-              int __user *parent_tid, void *newtls, int __user *child_tid)
+long i386_clone(unsigned long clone_flags, unsigned long newsp,
+               int __user *parent_tid, void *newtls, int __user *child_tid)
 {
-       long ret;
-
-       if (!newsp)
-               newsp = UPT_SP(&current->thread.regs.regs);
-
-       current->thread.forking = 1;
-       ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
-                     child_tid);
-       current->thread.forking = 0;
-       return ret;
+       return sys_clone(clone_flags, newsp, parent_tid, child_tid);
 }
 
+
 long sys_sigaction(int sig, const struct old_sigaction __user *act,
                         struct old_sigaction __user *oact)
 {
index f3d82bb..adb08eb 100644 (file)
@@ -5,12 +5,9 @@
  * Licensed under the GPL
  */
 
-#include "linux/linkage.h"
-#include "linux/personality.h"
-#include "linux/utsname.h"
-#include "asm/prctl.h" /* XXX This should get the constants from libc */
-#include "asm/uaccess.h"
-#include "os.h"
+#include <linux/sched.h>
+#include <asm/prctl.h> /* XXX This should get the constants from libc */
+#include <os.h>
 
 long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
 {
@@ -79,20 +76,6 @@ long sys_arch_prctl(int code, unsigned long addr)
        return arch_prctl(current, code, (unsigned long __user *) addr);
 }
 
-long sys_clone(unsigned long clone_flags, unsigned long newsp,
-              void __user *parent_tid, void __user *child_tid)
-{
-       long ret;
-
-       if (!newsp)
-               newsp = UPT_SP(&current->thread.regs.regs);
-       current->thread.forking = 1;
-       ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
-                     child_tid);
-       current->thread.forking = 0;
-       return ret;
-}
-
 void arch_switch_to(struct task_struct *to)
 {
        if ((to->thread.arch.fs == 0) || (to->mm == NULL))
index d11ca11..e2d62d6 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/e820.h>
 #include <asm/setup.h>
 #include <asm/acpi.h>
+#include <asm/numa.h>
 #include <asm/xen/hypervisor.h>
 #include <asm/xen/hypercall.h>
 
@@ -544,4 +545,7 @@ void __init xen_arch_setup(void)
        disable_cpufreq();
        WARN_ON(set_pm_idle_to_default());
        fiddle_vdso();
+#ifdef CONFIG_NUMA
+       numa_off = 1;
+#endif
 }
index a897346..5b6b1d8 100644 (file)
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/irqdomain.h>
+#include <linux/pm_runtime.h>
 #include <linux/slab.h>
 
 #include "internal.h"
 
 struct regmap_irq_chip_data {
        struct mutex lock;
+       struct irq_chip irq_chip;
 
        struct regmap *map;
        const struct regmap_irq_chip *chip;
@@ -59,6 +61,14 @@ static void regmap_irq_sync_unlock(struct irq_data *data)
        struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data);
        struct regmap *map = d->map;
        int i, ret;
+       u32 reg;
+
+       if (d->chip->runtime_pm) {
+               ret = pm_runtime_get_sync(map->dev);
+               if (ret < 0)
+                       dev_err(map->dev, "IRQ sync failed to resume: %d\n",
+                               ret);
+       }
 
        /*
         * If there's been a change in the mask write it back to the
@@ -66,15 +76,22 @@ static void regmap_irq_sync_unlock(struct irq_data *data)
         * suppress pointless writes.
         */
        for (i = 0; i < d->chip->num_regs; i++) {
-               ret = regmap_update_bits(d->map, d->chip->mask_base +
-                                               (i * map->reg_stride *
-                                               d->irq_reg_stride),
+               reg = d->chip->mask_base +
+                       (i * map->reg_stride * d->irq_reg_stride);
+               if (d->chip->mask_invert)
+                       ret = regmap_update_bits(d->map, reg,
+                                        d->mask_buf_def[i], ~d->mask_buf[i]);
+               else
+                       ret = regmap_update_bits(d->map, reg,
                                         d->mask_buf_def[i], d->mask_buf[i]);
                if (ret != 0)
                        dev_err(d->map->dev, "Failed to sync masks in %x\n",
-                               d->chip->mask_base + (i * map->reg_stride));
+                               reg);
        }
 
+       if (d->chip->runtime_pm)
+               pm_runtime_put(map->dev);
+
        /* If we've changed our wakeup count propagate it to the parent */
        if (d->wake_count < 0)
                for (i = d->wake_count; i < 0; i++)
@@ -128,8 +145,7 @@ static int regmap_irq_set_wake(struct irq_data *data, unsigned int on)
        return 0;
 }
 
-static struct irq_chip regmap_irq_chip = {
-       .name                   = "regmap",
+static const struct irq_chip regmap_irq_chip = {
        .irq_bus_lock           = regmap_irq_lock,
        .irq_bus_sync_unlock    = regmap_irq_sync_unlock,
        .irq_disable            = regmap_irq_disable,
@@ -144,6 +160,16 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
        struct regmap *map = data->map;
        int ret, i;
        bool handled = false;
+       u32 reg;
+
+       if (chip->runtime_pm) {
+               ret = pm_runtime_get_sync(map->dev);
+               if (ret < 0) {
+                       dev_err(map->dev, "IRQ thread failed to resume: %d\n",
+                               ret);
+                       return IRQ_NONE;
+               }
+       }
 
        /*
         * Ignore masked IRQs and ack if we need to; we ack early so
@@ -160,20 +186,20 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
                if (ret != 0) {
                        dev_err(map->dev, "Failed to read IRQ status: %d\n",
                                        ret);
+                       if (chip->runtime_pm)
+                               pm_runtime_put(map->dev);
                        return IRQ_NONE;
                }
 
                data->status_buf[i] &= ~data->mask_buf[i];
 
                if (data->status_buf[i] && chip->ack_base) {
-                       ret = regmap_write(map, chip->ack_base +
-                                               (i * map->reg_stride *
-                                               data->irq_reg_stride),
-                                          data->status_buf[i]);
+                       reg = chip->ack_base +
+                               (i * map->reg_stride * data->irq_reg_stride);
+                       ret = regmap_write(map, reg, data->status_buf[i]);
                        if (ret != 0)
                                dev_err(map->dev, "Failed to ack 0x%x: %d\n",
-                                       chip->ack_base + (i * map->reg_stride),
-                                       ret);
+                                       reg, ret);
                }
        }
 
@@ -185,6 +211,9 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
                }
        }
 
+       if (chip->runtime_pm)
+               pm_runtime_put(map->dev);
+
        if (handled)
                return IRQ_HANDLED;
        else
@@ -197,7 +226,7 @@ static int regmap_irq_map(struct irq_domain *h, unsigned int virq,
        struct regmap_irq_chip_data *data = h->host_data;
 
        irq_set_chip_data(virq, data);
-       irq_set_chip_and_handler(virq, &regmap_irq_chip, handle_edge_irq);
+       irq_set_chip(virq, &data->irq_chip);
        irq_set_nested_thread(virq, 1);
 
        /* ARM needs us to explicitly flag the IRQ as valid
@@ -238,6 +267,7 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
        struct regmap_irq_chip_data *d;
        int i;
        int ret = -ENOMEM;
+       u32 reg;
 
        for (i = 0; i < chip->num_irqs; i++) {
                if (chip->irqs[i].reg_offset % map->reg_stride)
@@ -284,6 +314,13 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
                        goto err_alloc;
        }
 
+       d->irq_chip = regmap_irq_chip;
+       d->irq_chip.name = chip->name;
+       if (!chip->wake_base) {
+               d->irq_chip.irq_set_wake = NULL;
+               d->irq_chip.flags |= IRQCHIP_MASK_ON_SUSPEND |
+                                    IRQCHIP_SKIP_SET_WAKE;
+       }
        d->irq = irq;
        d->map = map;
        d->chip = chip;
@@ -303,16 +340,37 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
        /* Mask all the interrupts by default */
        for (i = 0; i < chip->num_regs; i++) {
                d->mask_buf[i] = d->mask_buf_def[i];
-               ret = regmap_write(map, chip->mask_base + (i * map->reg_stride
-                                  * d->irq_reg_stride),
-                                  d->mask_buf[i]);
+               reg = chip->mask_base +
+                       (i * map->reg_stride * d->irq_reg_stride);
+               if (chip->mask_invert)
+                       ret = regmap_update_bits(map, reg,
+                                        d->mask_buf[i], ~d->mask_buf[i]);
+               else
+                       ret = regmap_update_bits(map, reg,
+                                        d->mask_buf[i], d->mask_buf[i]);
                if (ret != 0) {
                        dev_err(map->dev, "Failed to set masks in 0x%x: %d\n",
-                               chip->mask_base + (i * map->reg_stride), ret);
+                               reg, ret);
                        goto err_alloc;
                }
        }
 
+       /* Wake is disabled by default */
+       if (d->wake_buf) {
+               for (i = 0; i < chip->num_regs; i++) {
+                       d->wake_buf[i] = d->mask_buf_def[i];
+                       reg = chip->wake_base +
+                               (i * map->reg_stride * d->irq_reg_stride);
+                       ret = regmap_update_bits(map, reg, d->wake_buf[i],
+                                                d->wake_buf[i]);
+                       if (ret != 0) {
+                               dev_err(map->dev, "Failed to set masks in 0x%x: %d\n",
+                                       reg, ret);
+                               goto err_alloc;
+                       }
+               }
+       }
+
        if (irq_base)
                d->domain = irq_domain_add_legacy(map->dev->of_node,
                                                  chip->num_irqs, irq_base, 0,
index c241ae2..52069d2 100644 (file)
@@ -659,13 +659,12 @@ EXPORT_SYMBOL_GPL(devm_regmap_init);
  * new cache.  This can be used to restore the cache to defaults or to
  * update the cache configuration to reflect runtime discovery of the
  * hardware.
+ *
+ * No explicit locking is done here, the user needs to ensure that
+ * this function will not race with other calls to regmap.
  */
 int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
 {
-       int ret;
-
-       map->lock(map);
-
        regcache_exit(map);
        regmap_debugfs_exit(map);
 
@@ -681,11 +680,7 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
        map->cache_bypass = false;
        map->cache_only = false;
 
-       ret = regcache_init(map, config);
-
-       map->unlock(map);
-
-       return ret;
+       return regcache_init(map, config);
 }
 EXPORT_SYMBOL_GPL(regmap_reinit_cache);
 
index 38a2d06..ad16c68 100644 (file)
@@ -79,6 +79,7 @@ struct nvme_dev {
        char serial[20];
        char model[40];
        char firmware_rev[8];
+       u32 max_hw_sectors;
 };
 
 /*
@@ -835,15 +836,15 @@ static int nvme_identify(struct nvme_dev *dev, unsigned nsid, unsigned cns,
 }
 
 static int nvme_get_features(struct nvme_dev *dev, unsigned fid,
-                               unsigned dword11, dma_addr_t dma_addr)
+                               unsigned nsid, dma_addr_t dma_addr)
 {
        struct nvme_command c;
 
        memset(&c, 0, sizeof(c));
        c.features.opcode = nvme_admin_get_features;
+       c.features.nsid = cpu_to_le32(nsid);
        c.features.prp1 = cpu_to_le64(dma_addr);
        c.features.fid = cpu_to_le32(fid);
-       c.features.dword11 = cpu_to_le32(dword11);
 
        return nvme_submit_admin_cmd(dev, &c, NULL);
 }
@@ -862,11 +863,51 @@ static int nvme_set_features(struct nvme_dev *dev, unsigned fid,
        return nvme_submit_admin_cmd(dev, &c, result);
 }
 
+/**
+ * nvme_cancel_ios - Cancel outstanding I/Os
+ * @queue: The queue to cancel I/Os on
+ * @timeout: True to only cancel I/Os which have timed out
+ */
+static void nvme_cancel_ios(struct nvme_queue *nvmeq, bool timeout)
+{
+       int depth = nvmeq->q_depth - 1;
+       struct nvme_cmd_info *info = nvme_cmd_info(nvmeq);
+       unsigned long now = jiffies;
+       int cmdid;
+
+       for_each_set_bit(cmdid, nvmeq->cmdid_data, depth) {
+               void *ctx;
+               nvme_completion_fn fn;
+               static struct nvme_completion cqe = {
+                       .status = cpu_to_le16(NVME_SC_ABORT_REQ) << 1,
+               };
+
+               if (timeout && !time_after(now, info[cmdid].timeout))
+                       continue;
+               dev_warn(nvmeq->q_dmadev, "Cancelling I/O %d\n", cmdid);
+               ctx = cancel_cmdid(nvmeq, cmdid, &fn);
+               fn(nvmeq->dev, ctx, &cqe);
+       }
+}
+
+static void nvme_free_queue_mem(struct nvme_queue *nvmeq)
+{
+       dma_free_coherent(nvmeq->q_dmadev, CQ_SIZE(nvmeq->q_depth),
+                               (void *)nvmeq->cqes, nvmeq->cq_dma_addr);
+       dma_free_coherent(nvmeq->q_dmadev, SQ_SIZE(nvmeq->q_depth),
+                                       nvmeq->sq_cmds, nvmeq->sq_dma_addr);
+       kfree(nvmeq);
+}
+
 static void nvme_free_queue(struct nvme_dev *dev, int qid)
 {
        struct nvme_queue *nvmeq = dev->queues[qid];
        int vector = dev->entry[nvmeq->cq_vector].vector;
 
+       spin_lock_irq(&nvmeq->q_lock);
+       nvme_cancel_ios(nvmeq, false);
+       spin_unlock_irq(&nvmeq->q_lock);
+
        irq_set_affinity_hint(vector, NULL);
        free_irq(vector, nvmeq);
 
@@ -876,18 +917,15 @@ static void nvme_free_queue(struct nvme_dev *dev, int qid)
                adapter_delete_cq(dev, qid);
        }
 
-       dma_free_coherent(nvmeq->q_dmadev, CQ_SIZE(nvmeq->q_depth),
-                               (void *)nvmeq->cqes, nvmeq->cq_dma_addr);
-       dma_free_coherent(nvmeq->q_dmadev, SQ_SIZE(nvmeq->q_depth),
-                                       nvmeq->sq_cmds, nvmeq->sq_dma_addr);
-       kfree(nvmeq);
+       nvme_free_queue_mem(nvmeq);
 }
 
 static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid,
                                                        int depth, int vector)
 {
        struct device *dmadev = &dev->pci_dev->dev;
-       unsigned extra = (depth / 8) + (depth * sizeof(struct nvme_cmd_info));
+       unsigned extra = DIV_ROUND_UP(depth, 8) + (depth *
+                                               sizeof(struct nvme_cmd_info));
        struct nvme_queue *nvmeq = kzalloc(sizeof(*nvmeq) + extra, GFP_KERNEL);
        if (!nvmeq)
                return NULL;
@@ -975,7 +1013,7 @@ static __devinit struct nvme_queue *nvme_create_queue(struct nvme_dev *dev,
 
 static int __devinit nvme_configure_admin_queue(struct nvme_dev *dev)
 {
-       int result;
+       int result = 0;
        u32 aqa;
        u64 cap;
        unsigned long timeout;
@@ -1005,17 +1043,22 @@ static int __devinit nvme_configure_admin_queue(struct nvme_dev *dev)
        timeout = ((NVME_CAP_TIMEOUT(cap) + 1) * HZ / 2) + jiffies;
        dev->db_stride = NVME_CAP_STRIDE(cap);
 
-       while (!(readl(&dev->bar->csts) & NVME_CSTS_RDY)) {
+       while (!result && !(readl(&dev->bar->csts) & NVME_CSTS_RDY)) {
                msleep(100);
                if (fatal_signal_pending(current))
-                       return -EINTR;
+                       result = -EINTR;
                if (time_after(jiffies, timeout)) {
                        dev_err(&dev->pci_dev->dev,
                                "Device not ready; aborting initialisation\n");
-                       return -ENODEV;
+                       result = -ENODEV;
                }
        }
 
+       if (result) {
+               nvme_free_queue_mem(nvmeq);
+               return result;
+       }
+
        result = queue_request_irq(dev, nvmeq, "nvme admin");
        dev->queues[0] = nvmeq;
        return result;
@@ -1037,6 +1080,8 @@ static struct nvme_iod *nvme_map_user_pages(struct nvme_dev *dev, int write,
        offset = offset_in_page(addr);
        count = DIV_ROUND_UP(offset + length, PAGE_SIZE);
        pages = kcalloc(count, sizeof(*pages), GFP_KERNEL);
+       if (!pages)
+               return ERR_PTR(-ENOMEM);
 
        err = get_user_pages_fast(addr, count, 1, pages);
        if (err < count) {
@@ -1146,14 +1191,13 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
        return status;
 }
 
-static int nvme_user_admin_cmd(struct nvme_ns *ns,
+static int nvme_user_admin_cmd(struct nvme_dev *dev,
                                        struct nvme_admin_cmd __user *ucmd)
 {
-       struct nvme_dev *dev = ns->dev;
        struct nvme_admin_cmd cmd;
        struct nvme_command c;
        int status, length;
-       struct nvme_iod *iod;
+       struct nvme_iod *uninitialized_var(iod);
 
        if (!capable(CAP_SYS_ADMIN))
                return -EACCES;
@@ -1204,7 +1248,7 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
        case NVME_IOCTL_ID:
                return ns->ns_id;
        case NVME_IOCTL_ADMIN_CMD:
-               return nvme_user_admin_cmd(ns, (void __user *)arg);
+               return nvme_user_admin_cmd(ns->dev, (void __user *)arg);
        case NVME_IOCTL_SUBMIT_IO:
                return nvme_submit_io(ns, (void __user *)arg);
        default:
@@ -1218,26 +1262,6 @@ static const struct block_device_operations nvme_fops = {
        .compat_ioctl   = nvme_ioctl,
 };
 
-static void nvme_timeout_ios(struct nvme_queue *nvmeq)
-{
-       int depth = nvmeq->q_depth - 1;
-       struct nvme_cmd_info *info = nvme_cmd_info(nvmeq);
-       unsigned long now = jiffies;
-       int cmdid;
-
-       for_each_set_bit(cmdid, nvmeq->cmdid_data, depth) {
-               void *ctx;
-               nvme_completion_fn fn;
-               static struct nvme_completion cqe = { .status = cpu_to_le16(NVME_SC_ABORT_REQ) << 1, };
-
-               if (!time_after(now, info[cmdid].timeout))
-                       continue;
-               dev_warn(nvmeq->q_dmadev, "Timing out I/O %d\n", cmdid);
-               ctx = cancel_cmdid(nvmeq, cmdid, &fn);
-               fn(nvmeq->dev, ctx, &cqe);
-       }
-}
-
 static void nvme_resubmit_bios(struct nvme_queue *nvmeq)
 {
        while (bio_list_peek(&nvmeq->sq_cong)) {
@@ -1269,7 +1293,7 @@ static int nvme_kthread(void *data)
                                spin_lock_irq(&nvmeq->q_lock);
                                if (nvme_process_cq(nvmeq))
                                        printk("process_cq did something\n");
-                               nvme_timeout_ios(nvmeq);
+                               nvme_cancel_ios(nvmeq, true);
                                nvme_resubmit_bios(nvmeq);
                                spin_unlock_irq(&nvmeq->q_lock);
                        }
@@ -1339,6 +1363,9 @@ static struct nvme_ns *nvme_alloc_ns(struct nvme_dev *dev, int nsid,
        ns->disk = disk;
        lbaf = id->flbas & 0xf;
        ns->lba_shift = id->lbaf[lbaf].ds;
+       blk_queue_logical_block_size(ns->queue, 1 << ns->lba_shift);
+       if (dev->max_hw_sectors)
+               blk_queue_max_hw_sectors(ns->queue, dev->max_hw_sectors);
 
        disk->major = nvme_major;
        disk->minors = NVME_MINORS;
@@ -1383,7 +1410,7 @@ static int set_queue_count(struct nvme_dev *dev, int count)
 
 static int __devinit nvme_setup_io_queues(struct nvme_dev *dev)
 {
-       int result, cpu, i, nr_io_queues, db_bar_size;
+       int result, cpu, i, nr_io_queues, db_bar_size, q_depth;
 
        nr_io_queues = num_online_cpus();
        result = set_queue_count(dev, nr_io_queues);
@@ -1429,9 +1456,10 @@ static int __devinit nvme_setup_io_queues(struct nvme_dev *dev)
                cpu = cpumask_next(cpu, cpu_online_mask);
        }
 
+       q_depth = min_t(int, NVME_CAP_MQES(readq(&dev->bar->cap)) + 1,
+                                                               NVME_Q_DEPTH);
        for (i = 0; i < nr_io_queues; i++) {
-               dev->queues[i + 1] = nvme_create_queue(dev, i + 1,
-                                                       NVME_Q_DEPTH, i);
+               dev->queues[i + 1] = nvme_create_queue(dev, i + 1, q_depth, i);
                if (IS_ERR(dev->queues[i + 1]))
                        return PTR_ERR(dev->queues[i + 1]);
                dev->queue_count++;
@@ -1480,6 +1508,10 @@ static int __devinit nvme_dev_add(struct nvme_dev *dev)
        memcpy(dev->serial, ctrl->sn, sizeof(ctrl->sn));
        memcpy(dev->model, ctrl->mn, sizeof(ctrl->mn));
        memcpy(dev->firmware_rev, ctrl->fr, sizeof(ctrl->fr));
+       if (ctrl->mdts) {
+               int shift = NVME_CAP_MPSMIN(readq(&dev->bar->cap)) + 12;
+               dev->max_hw_sectors = 1 << (ctrl->mdts + shift - 9);
+       }
 
        id_ns = mem;
        for (i = 1; i <= nn; i++) {
@@ -1523,8 +1555,6 @@ static int nvme_dev_remove(struct nvme_dev *dev)
        list_del(&dev->node);
        spin_unlock(&dev_list_lock);
 
-       /* TODO: wait all I/O finished or cancel them */
-
        list_for_each_entry_safe(ns, next, &dev->namespaces, list) {
                list_del(&ns->list);
                del_gendisk(ns->disk);
@@ -1560,15 +1590,33 @@ static void nvme_release_prp_pools(struct nvme_dev *dev)
        dma_pool_destroy(dev->prp_small_pool);
 }
 
-/* XXX: Use an ida or something to let remove / add work correctly */
-static void nvme_set_instance(struct nvme_dev *dev)
+static DEFINE_IDA(nvme_instance_ida);
+
+static int nvme_set_instance(struct nvme_dev *dev)
 {
-       static int instance;
-       dev->instance = instance++;
+       int instance, error;
+
+       do {
+               if (!ida_pre_get(&nvme_instance_ida, GFP_KERNEL))
+                       return -ENODEV;
+
+               spin_lock(&dev_list_lock);
+               error = ida_get_new(&nvme_instance_ida, &instance);
+               spin_unlock(&dev_list_lock);
+       } while (error == -EAGAIN);
+
+       if (error)
+               return -ENODEV;
+
+       dev->instance = instance;
+       return 0;
 }
 
 static void nvme_release_instance(struct nvme_dev *dev)
 {
+       spin_lock(&dev_list_lock);
+       ida_remove(&nvme_instance_ida, dev->instance);
+       spin_unlock(&dev_list_lock);
 }
 
 static int __devinit nvme_probe(struct pci_dev *pdev,
@@ -1601,7 +1649,10 @@ static int __devinit nvme_probe(struct pci_dev *pdev,
        pci_set_drvdata(pdev, dev);
        dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
        dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
-       nvme_set_instance(dev);
+       result = nvme_set_instance(dev);
+       if (result)
+               goto disable;
+
        dev->entry[0].vector = pdev->irq;
 
        result = nvme_setup_prp_pools(dev);
@@ -1704,15 +1755,17 @@ static struct pci_driver nvme_driver = {
 
 static int __init nvme_init(void)
 {
-       int result = -EBUSY;
+       int result;
 
        nvme_thread = kthread_run(nvme_kthread, NULL, "nvme");
        if (IS_ERR(nvme_thread))
                return PTR_ERR(nvme_thread);
 
-       nvme_major = register_blkdev(nvme_major, "nvme");
-       if (nvme_major <= 0)
+       result = register_blkdev(nvme_major, "nvme");
+       if (result < 0)
                goto kill_kthread;
+       else if (result > 0)
+               nvme_major = result;
 
        result = pci_register_driver(&nvme_driver);
        if (result)
index 9917943..54a55f0 100644 (file)
@@ -246,13 +246,12 @@ static int rbd_open(struct block_device *bdev, fmode_t mode)
 {
        struct rbd_device *rbd_dev = bdev->bd_disk->private_data;
 
-       rbd_get_dev(rbd_dev);
-
-       set_device_ro(bdev, rbd_dev->read_only);
-
        if ((mode & FMODE_WRITE) && rbd_dev->read_only)
                return -EROFS;
 
+       rbd_get_dev(rbd_dev);
+       set_device_ro(bdev, rbd_dev->read_only);
+
        return 0;
 }
 
index 5869ea3..72ce247 100644 (file)
@@ -1,4 +1,5 @@
 # common clock types
+obj-$(CONFIG_HAVE_CLK)         += clk-devres.o
 obj-$(CONFIG_CLKDEV_LOOKUP)    += clkdev.o
 obj-$(CONFIG_COMMON_CLK)       += clk.o clk-fixed-rate.o clk-gate.o \
                                   clk-mux.o clk-divider.o clk-fixed-factor.o
diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
new file mode 100644 (file)
index 0000000..8f57154
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/gfp.h>
+
+static void devm_clk_release(struct device *dev, void *res)
+{
+       clk_put(*(struct clk **)res);
+}
+
+struct clk *devm_clk_get(struct device *dev, const char *id)
+{
+       struct clk **ptr, *clk;
+
+       ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
+       if (!ptr)
+               return ERR_PTR(-ENOMEM);
+
+       clk = clk_get(dev, id);
+       if (!IS_ERR(clk)) {
+               *ptr = clk;
+               devres_add(dev, ptr);
+       } else {
+               devres_free(ptr);
+       }
+
+       return clk;
+}
+EXPORT_SYMBOL(devm_clk_get);
+
+static int devm_clk_match(struct device *dev, void *res, void *data)
+{
+       struct clk **c = res;
+       if (!c || !*c) {
+               WARN_ON(!c || !*c);
+               return 0;
+       }
+       return *c == data;
+}
+
+void devm_clk_put(struct device *dev, struct clk *clk)
+{
+       int ret;
+
+       ret = devres_release(dev, devm_clk_release, devm_clk_match, clk);
+
+       WARN_ON(ret);
+}
+EXPORT_SYMBOL(devm_clk_put);
index d423c9b..442a313 100644 (file)
@@ -171,51 +171,6 @@ void clk_put(struct clk *clk)
 }
 EXPORT_SYMBOL(clk_put);
 
-static void devm_clk_release(struct device *dev, void *res)
-{
-       clk_put(*(struct clk **)res);
-}
-
-struct clk *devm_clk_get(struct device *dev, const char *id)
-{
-       struct clk **ptr, *clk;
-
-       ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
-       if (!ptr)
-               return ERR_PTR(-ENOMEM);
-
-       clk = clk_get(dev, id);
-       if (!IS_ERR(clk)) {
-               *ptr = clk;
-               devres_add(dev, ptr);
-       } else {
-               devres_free(ptr);
-       }
-
-       return clk;
-}
-EXPORT_SYMBOL(devm_clk_get);
-
-static int devm_clk_match(struct device *dev, void *res, void *data)
-{
-       struct clk **c = res;
-       if (!c || !*c) {
-               WARN_ON(!c || !*c);
-               return 0;
-       }
-       return *c == data;
-}
-
-void devm_clk_put(struct device *dev, struct clk *clk)
-{
-       int ret;
-
-       ret = devres_destroy(dev, devm_clk_release, devm_clk_match, clk);
-
-       WARN_ON(ret);
-}
-EXPORT_SYMBOL(devm_clk_put);
-
 void clkdev_add(struct clk_lookup *cl)
 {
        mutex_lock(&clocks_mutex);
index 7ab6e26..17d6958 100644 (file)
@@ -168,9 +168,9 @@ static void atc_desc_put(struct at_dma_chan *atchan, struct at_desc *desc)
 }
 
 /**
- * atc_desc_chain - build chain adding a descripor
- * @first: address of first descripor of the chain
- * @prev: address of previous descripor of the chain
+ * atc_desc_chain - build chain adding a descriptor
+ * @first: address of first descriptor of the chain
+ * @prev: address of previous descriptor of the chain
  * @desc: descriptor to queue
  *
  * Called from prep_* functions
@@ -796,7 +796,7 @@ err_out:
 }
 
 /**
- * atc_dma_cyclic_fill_desc - Fill one period decriptor
+ * atc_dma_cyclic_fill_desc - Fill one period descriptor
  */
 static int
 atc_dma_cyclic_fill_desc(struct dma_chan *chan, struct at_desc *desc,
index c64917e..bb02fd9 100644 (file)
@@ -1118,7 +1118,7 @@ fail:
  * @chan: channel
  * @dma_addr: DMA mapped address of the buffer
  * @buf_len: length of the buffer (in bytes)
- * @period_len: lenght of a single period
+ * @period_len: length of a single period
  * @dir: direction of the operation
  * @context: operation context (ignored)
  *
index 8f84761..094437b 100644 (file)
@@ -1015,7 +1015,7 @@ static irqreturn_t fsldma_chan_irq(int irq, void *data)
        /*
         * Programming Error
         * The DMA_INTERRUPT async_tx is a NULL transfer, which will
-        * triger a PE interrupt.
+        * trigger a PE interrupt.
         */
        if (stat & FSL_DMA_SR_PE) {
                chan_dbg(chan, "irq: Programming Error INT\n");
index 5084975..54f580b 100644 (file)
@@ -572,8 +572,8 @@ static void imxdma_tasklet(unsigned long data)
        if (desc->desc.callback)
                desc->desc.callback(desc->desc.callback_param);
 
-       /* If we are dealing with a cyclic descriptor keep it on ld_active
-        * and dont mark the descripor as complete.
+       /* If we are dealing with a cyclic descriptor, keep it on ld_active
+        * and dont mark the descriptor as complete.
         * Only in non-cyclic cases it would be marked as complete
         */
        if (imxdma_chan_is_doing_cyclic(imxdmac))
index 222e907..02b21d7 100644 (file)
@@ -427,7 +427,7 @@ DMA engine callback Functions*/
  * intel_mid_dma_tx_submit -   callback to submit DMA transaction
  * @tx: dma engine descriptor
  *
- * Submit the DMA trasaction for this descriptor, start if ch idle
+ * Submit the DMA transaction for this descriptor, start if ch idle
  */
 static dma_cookie_t intel_mid_dma_tx_submit(struct dma_async_tx_descriptor *tx)
 {
index 1bfa926..17b4219 100644 (file)
@@ -168,9 +168,9 @@ union intel_mid_dma_cfg_hi {
  * @active_list: current active descriptors
  * @queue: current queued up descriptors
  * @free_list: current free descriptors
- * @slave: dma slave struture
- * @descs_allocated: total number of decsiptors allocated
- * @dma: dma device struture pointer
+ * @slave: dma slave structure
+ * @descs_allocated: total number of descriptors allocated
+ * @dma: dma device structure pointer
  * @busy: bool representing if ch is busy (active txn) or not
  * @in_use: bool representing if ch is in use or not
  * @raw_tfr: raw trf interrupt received
index 60e6754..d2ff3fd 100644 (file)
@@ -22,7 +22,6 @@
 #define _IOAT_HW_H_
 
 /* PCI Configuration Space Values */
-#define IOAT_PCI_VID            0x8086
 #define IOAT_MMIO_BAR          0
 
 /* CB device ID's */
@@ -31,9 +30,6 @@
 #define IOAT_PCI_DID_SCNB       0x65FF
 #define IOAT_PCI_DID_SNB        0x402F
 
-#define IOAT_PCI_RID            0x00
-#define IOAT_PCI_SVID           0x8086
-#define IOAT_PCI_SID            0x8086
 #define IOAT_VER_1_2            0x12    /* Version 1.2 */
 #define IOAT_VER_2_0            0x20    /* Version 2.0 */
 #define IOAT_VER_3_0            0x30    /* Version 3.0 */
index f5843bc..5d3bbcd 100644 (file)
@@ -522,7 +522,7 @@ enum desc_status {
        /* In the DMAC pool */
        FREE,
        /*
-        * Allocted to some channel during prep_xxx
+        * Allocated to some channel during prep_xxx
         * Also may be sitting on the work_list.
         */
        PREP,
index ced9882..f72348d 100644 (file)
@@ -4446,7 +4446,7 @@ static int __devinit ppc440spe_adma_probe(struct platform_device *ofdev)
                ret = -ENOMEM;
                goto err_dma_alloc;
        }
-       dev_dbg(&ofdev->dev, "allocted descriptor pool virt 0x%p phys 0x%llx\n",
+       dev_dbg(&ofdev->dev, "allocated descriptor pool virt 0x%p phys 0x%llx\n",
                adev->dma_desc_pool_virt, (u64)adev->dma_desc_pool);
 
        regs = ioremap(res.start, resource_size(&res));
index 51e8e53..6d47373 100644 (file)
 /* LLI related structures */
 
 /**
- * struct d40_phy_lli - The basic configration register for each physical
+ * struct d40_phy_lli - The basic configuration register for each physical
  * channel.
  *
  * @reg_cfg: The configuration register.
index 616d90b..d5dc9da 100644 (file)
@@ -199,6 +199,36 @@ void *edac_align_ptr(void **p, unsigned size, int n_elems)
        return (void *)(((unsigned long)ptr) + align - r);
 }
 
+static void _edac_mc_free(struct mem_ctl_info *mci)
+{
+       int i, chn, row;
+       struct csrow_info *csr;
+       const unsigned int tot_dimms = mci->tot_dimms;
+       const unsigned int tot_channels = mci->num_cschannel;
+       const unsigned int tot_csrows = mci->nr_csrows;
+
+       if (mci->dimms) {
+               for (i = 0; i < tot_dimms; i++)
+                       kfree(mci->dimms[i]);
+               kfree(mci->dimms);
+       }
+       if (mci->csrows) {
+               for (row = 0; row < tot_csrows; row++) {
+                       csr = mci->csrows[row];
+                       if (csr) {
+                               if (csr->channels) {
+                                       for (chn = 0; chn < tot_channels; chn++)
+                                               kfree(csr->channels[chn]);
+                                       kfree(csr->channels);
+                               }
+                               kfree(csr);
+                       }
+               }
+               kfree(mci->csrows);
+       }
+       kfree(mci);
+}
+
 /**
  * edac_mc_alloc: Allocate and partially fill a struct mem_ctl_info structure
  * @mc_num:            Memory controller number
@@ -413,24 +443,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
        return mci;
 
 error:
-       if (mci->dimms) {
-               for (i = 0; i < tot_dimms; i++)
-                       kfree(mci->dimms[i]);
-               kfree(mci->dimms);
-       }
-       if (mci->csrows) {
-               for (chn = 0; chn < tot_channels; chn++) {
-                       csr = mci->csrows[chn];
-                       if (csr) {
-                               for (chn = 0; chn < tot_channels; chn++)
-                                       kfree(csr->channels[chn]);
-                               kfree(csr);
-                       }
-                       kfree(mci->csrows[i]);
-               }
-               kfree(mci->csrows);
-       }
-       kfree(mci);
+       _edac_mc_free(mci);
 
        return NULL;
 }
@@ -445,6 +458,14 @@ void edac_mc_free(struct mem_ctl_info *mci)
 {
        edac_dbg(1, "\n");
 
+       /* If we're not yet registered with sysfs free only what was allocated
+        * in edac_mc_alloc().
+        */
+       if (!device_is_registered(&mci->dev)) {
+               _edac_mc_free(mci);
+               return;
+       }
+
        /* the mci instance is freed here, when the sysfs object is dropped */
        edac_unregister_sysfs(mci);
 }
index 47180a0..b6653a6 100644 (file)
@@ -391,7 +391,7 @@ static int i3200_probe1(struct pci_dev *pdev, int dev_idx)
                for (j = 0; j < nr_channels; j++) {
                        struct dimm_info *dimm = csrow->channels[j]->dimm;
 
-                       dimm->nr_pages = nr_pages / nr_channels;
+                       dimm->nr_pages = nr_pages;
                        dimm->grain = nr_pages << PAGE_SHIFT;
                        dimm->mtype = MEM_DDR2;
                        dimm->dtype = DEV_UNKNOWN;
index 39c6375..6a49dd0 100644 (file)
@@ -1012,6 +1012,10 @@ static void handle_channel(struct i5000_pvt *pvt, int slot, int channel,
                        /* add the number of COLUMN bits */
                        addrBits += MTR_DIMM_COLS_ADDR_BITS(mtr);
 
+                       /* Dual-rank memories have twice the size */
+                       if (dinfo->dual_rank)
+                               addrBits++;
+
                        addrBits += 6;  /* add 64 bits per DIMM */
                        addrBits -= 20; /* divide by 2^^20 */
                        addrBits -= 3;  /* 8 bits per bytes */
index f3b1f9f..5715b7c 100644 (file)
@@ -513,7 +513,8 @@ static int get_dimm_config(struct mem_ctl_info *mci)
 {
        struct sbridge_pvt *pvt = mci->pvt_info;
        struct dimm_info *dimm;
-       int i, j, banks, ranks, rows, cols, size, npages;
+       unsigned i, j, banks, ranks, rows, cols, npages;
+       u64 size;
        u32 reg;
        enum edac_type mode;
        enum mem_type mtype;
@@ -585,10 +586,10 @@ static int get_dimm_config(struct mem_ctl_info *mci)
                                cols = numcol(mtr);
 
                                /* DDR3 has 8 I/O banks */
-                               size = (rows * cols * banks * ranks) >> (20 - 3);
+                               size = ((u64)rows * cols * banks * ranks) >> (20 - 3);
                                npages = MiB_TO_PAGES(size);
 
-                               edac_dbg(0, "mc#%d: channel %d, dimm %d, %d Mb (%d pages) bank: %d, rank: %d, row: %#x, col: %#x\n",
+                               edac_dbg(0, "mc#%d: channel %d, dimm %d, %Ld Mb (%d pages) bank: %d, rank: %d, row: %#x, col: %#x\n",
                                         pvt->sbridge_dev->mc, i, j,
                                         size, npages,
                                         banks, ranks, rows, cols);
index 427a289..6c19833 100644 (file)
@@ -434,6 +434,11 @@ static int __devinit arizona_extcon_probe(struct platform_device *pdev)
        regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
                           ARIZONA_JD1_ENA, ARIZONA_JD1_ENA);
 
+       ret = regulator_allow_bypass(info->micvdd, true);
+       if (ret != 0)
+               dev_warn(arizona->dev, "Failed to set MICVDD to bypass: %d\n",
+                        ret);
+
        pm_runtime_put(&pdev->dev);
 
        return 0;
index 8a420f1..ed94b4e 100644 (file)
@@ -308,6 +308,7 @@ static int lpc32xx_gpio_dir_output_p012(struct gpio_chip *chip, unsigned pin,
 {
        struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
 
+       __set_gpio_level_p012(group, pin, value);
        __set_gpio_dir_p012(group, pin, 0);
 
        return 0;
@@ -318,6 +319,7 @@ static int lpc32xx_gpio_dir_output_p3(struct gpio_chip *chip, unsigned pin,
 {
        struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
 
+       __set_gpio_level_p3(group, pin, value);
        __set_gpio_dir_p3(group, pin, 0);
 
        return 0;
@@ -326,6 +328,9 @@ static int lpc32xx_gpio_dir_output_p3(struct gpio_chip *chip, unsigned pin,
 static int lpc32xx_gpio_dir_out_always(struct gpio_chip *chip, unsigned pin,
        int value)
 {
+       struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
+
+       __set_gpo_level_p3(group, pin, value);
        return 0;
 }
 
index ff23d88..3ca240b 100644 (file)
@@ -179,7 +179,7 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
                        return 0;
        } else
        if (init->class == 0x906e) {
-               NV_ERROR(dev, "906e not supported yet\n");
+               NV_DEBUG(dev, "906e not supported yet\n");
                return -EINVAL;
        }
 
index f704e94..f376c39 100644 (file)
@@ -124,6 +124,7 @@ nvc0_fb_init(struct drm_device *dev)
        priv = dev_priv->engine.fb.priv;
 
        nv_wr32(dev, 0x100c10, priv->r100c10 >> 8);
+       nv_mask(dev, 0x17e820, 0x00100000, 0x00000000); /* NV_PLTCG_INTR_EN */
        return 0;
 }
 
index 7d85553..cd39eb9 100644 (file)
@@ -373,7 +373,8 @@ nvc0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit)
 static void
 nvc0_fifo_isr(struct drm_device *dev)
 {
-       u32 stat = nv_rd32(dev, 0x002100);
+       u32 mask = nv_rd32(dev, 0x002140);
+       u32 stat = nv_rd32(dev, 0x002100) & mask;
 
        if (stat & 0x00000100) {
                NV_INFO(dev, "PFIFO: unknown status 0x00000100\n");
index e98d144..281bece 100644 (file)
@@ -345,7 +345,8 @@ nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit)
 static void
 nve0_fifo_isr(struct drm_device *dev)
 {
-       u32 stat = nv_rd32(dev, 0x002100);
+       u32 mask = nv_rd32(dev, 0x002140);
+       u32 stat = nv_rd32(dev, 0x002100) & mask;
 
        if (stat & 0x00000100) {
                NV_INFO(dev, "PFIFO: unknown status 0x00000100\n");
index ba055e9..8d9dc44 100644 (file)
@@ -69,6 +69,13 @@ static int udl_get_modes(struct drm_connector *connector)
 static int udl_mode_valid(struct drm_connector *connector,
                          struct drm_display_mode *mode)
 {
+       struct udl_device *udl = connector->dev->dev_private;
+       if (!udl->sku_pixel_limit)
+               return 0;
+
+       if (mode->vdisplay * mode->hdisplay > udl->sku_pixel_limit)
+               return MODE_VIRTUAL_Y;
+
        return 0;
 }
 
index f2fb8f1..7e07433 100644 (file)
@@ -1018,7 +1018,7 @@ int vmw_event_fence_action_create(struct drm_file *file_priv,
        }
 
 
-       event = kzalloc(sizeof(event->event), GFP_KERNEL);
+       event = kzalloc(sizeof(*event), GFP_KERNEL);
        if (unlikely(event == NULL)) {
                DRM_ERROR("Failed to allocate an event.\n");
                ret = -ENOMEM;
index 0fa356f..984a3f1 100644 (file)
@@ -815,17 +815,20 @@ static int __init coretemp_init(void)
        if (err)
                goto exit;
 
+       get_online_cpus();
        for_each_online_cpu(i)
                get_core_online(i);
 
 #ifndef CONFIG_HOTPLUG_CPU
        if (list_empty(&pdev_list)) {
+               put_online_cpus();
                err = -ENODEV;
                goto exit_driver_unreg;
        }
 #endif
 
        register_hotcpu_notifier(&coretemp_cpu_notifier);
+       put_online_cpus();
        return 0;
 
 #ifndef CONFIG_HOTPLUG_CPU
@@ -840,6 +843,7 @@ static void __exit coretemp_exit(void)
 {
        struct pdev_entry *p, *n;
 
+       get_online_cpus();
        unregister_hotcpu_notifier(&coretemp_cpu_notifier);
        mutex_lock(&pdev_list_mutex);
        list_for_each_entry_safe(p, n, &pdev_list, list) {
@@ -848,6 +852,7 @@ static void __exit coretemp_exit(void)
                kfree(p);
        }
        mutex_unlock(&pdev_list_mutex);
+       put_online_cpus();
        platform_driver_unregister(&coretemp_driver);
 }
 
index 2764b78..af69073 100644 (file)
@@ -129,12 +129,12 @@ static bool __devinit fam15h_power_is_internal_node0(struct pci_dev *f4)
  * counter saturations resulting in bogus power readings.
  * We correct this value ourselves to cope with older BIOSes.
  */
-static DEFINE_PCI_DEVICE_TABLE(affected_device) = {
+static const struct pci_device_id affected_device[] = {
        { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) },
        { 0 }
 };
 
-static void __devinit tweak_runavg_range(struct pci_dev *pdev)
+static void tweak_runavg_range(struct pci_dev *pdev)
 {
        u32 val;
 
@@ -158,6 +158,16 @@ static void __devinit tweak_runavg_range(struct pci_dev *pdev)
                REG_TDP_RUNNING_AVERAGE, val);
 }
 
+#ifdef CONFIG_PM
+static int fam15h_power_resume(struct pci_dev *pdev)
+{
+       tweak_runavg_range(pdev);
+       return 0;
+}
+#else
+#define fam15h_power_resume NULL
+#endif
+
 static void __devinit fam15h_power_init_data(struct pci_dev *f4,
                                             struct fam15h_power_data *data)
 {
@@ -256,6 +266,7 @@ static struct pci_driver fam15h_power_driver = {
        .id_table = fam15h_power_id_table,
        .probe = fam15h_power_probe,
        .remove = __devexit_p(fam15h_power_remove),
+       .resume = fam15h_power_resume,
 };
 
 module_pci_driver(fam15h_power_driver);
index ee4ebc1..2e56c6c 100644 (file)
@@ -328,6 +328,7 @@ static int __init via_cputemp_init(void)
        if (err)
                goto exit;
 
+       get_online_cpus();
        for_each_online_cpu(i) {
                struct cpuinfo_x86 *c = &cpu_data(i);
 
@@ -347,12 +348,14 @@ static int __init via_cputemp_init(void)
 
 #ifndef CONFIG_HOTPLUG_CPU
        if (list_empty(&pdev_list)) {
+               put_online_cpus();
                err = -ENODEV;
                goto exit_driver_unreg;
        }
 #endif
 
        register_hotcpu_notifier(&via_cputemp_cpu_notifier);
+       put_online_cpus();
        return 0;
 
 #ifndef CONFIG_HOTPLUG_CPU
@@ -367,6 +370,7 @@ static void __exit via_cputemp_exit(void)
 {
        struct pdev_entry *p, *n;
 
+       get_online_cpus();
        unregister_hotcpu_notifier(&via_cputemp_cpu_notifier);
        mutex_lock(&pdev_list_mutex);
        list_for_each_entry_safe(p, n, &pdev_list, list) {
@@ -375,6 +379,7 @@ static void __exit via_cputemp_exit(void)
                kfree(p);
        }
        mutex_unlock(&pdev_list_mutex);
+       put_online_cpus();
        platform_driver_unregister(&via_cputemp_driver);
 }
 
index b64502d..e89daf1 100644 (file)
@@ -266,7 +266,7 @@ static void swap_pci_ref(struct pci_dev **from, struct pci_dev *to)
 
 static int iommu_init_device(struct device *dev)
 {
-       struct pci_dev *dma_pdev, *pdev = to_pci_dev(dev);
+       struct pci_dev *dma_pdev = NULL, *pdev = to_pci_dev(dev);
        struct iommu_dev_data *dev_data;
        struct iommu_group *group;
        u16 alias;
@@ -293,7 +293,9 @@ static int iommu_init_device(struct device *dev)
                dev_data->alias_data = alias_data;
 
                dma_pdev = pci_get_bus_and_slot(alias >> 8, alias & 0xff);
-       } else
+       }
+
+       if (dma_pdev == NULL)
                dma_pdev = pci_dev_get(pdev);
 
        /* Account for quirked devices */
index d8abb90..034233e 100644 (file)
@@ -1555,6 +1555,7 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd,
                           unsigned long arg)
 {
        struct multipath *m = ti->private;
+       struct pgpath *pgpath;
        struct block_device *bdev;
        fmode_t mode;
        unsigned long flags;
@@ -1570,12 +1571,14 @@ again:
        if (!m->current_pgpath)
                __choose_pgpath(m, 0);
 
-       if (m->current_pgpath) {
-               bdev = m->current_pgpath->path.dev->bdev;
-               mode = m->current_pgpath->path.dev->mode;
+       pgpath = m->current_pgpath;
+
+       if (pgpath) {
+               bdev = pgpath->path.dev->bdev;
+               mode = pgpath->path.dev->mode;
        }
 
-       if (m->queue_io)
+       if ((pgpath && m->queue_io) || (!pgpath && m->queue_if_no_path))
                r = -EAGAIN;
        else if (!bdev)
                r = -EIO;
index f900690..100368e 100644 (file)
@@ -1212,6 +1212,41 @@ struct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector)
        return &t->targets[(KEYS_PER_NODE * n) + k];
 }
 
+static int count_device(struct dm_target *ti, struct dm_dev *dev,
+                       sector_t start, sector_t len, void *data)
+{
+       unsigned *num_devices = data;
+
+       (*num_devices)++;
+
+       return 0;
+}
+
+/*
+ * Check whether a table has no data devices attached using each
+ * target's iterate_devices method.
+ * Returns false if the result is unknown because a target doesn't
+ * support iterate_devices.
+ */
+bool dm_table_has_no_data_devices(struct dm_table *table)
+{
+       struct dm_target *uninitialized_var(ti);
+       unsigned i = 0, num_devices = 0;
+
+       while (i < dm_table_get_num_targets(table)) {
+               ti = dm_table_get_target(table, i++);
+
+               if (!ti->type->iterate_devices)
+                       return false;
+
+               ti->type->iterate_devices(ti, count_device, &num_devices);
+               if (num_devices)
+                       return false;
+       }
+
+       return true;
+}
+
 /*
  * Establish the new table's queue_limits and validate them.
  */
@@ -1354,17 +1389,25 @@ static int device_is_nonrot(struct dm_target *ti, struct dm_dev *dev,
        return q && blk_queue_nonrot(q);
 }
 
-static bool dm_table_is_nonrot(struct dm_table *t)
+static int device_is_not_random(struct dm_target *ti, struct dm_dev *dev,
+                            sector_t start, sector_t len, void *data)
+{
+       struct request_queue *q = bdev_get_queue(dev->bdev);
+
+       return q && !blk_queue_add_random(q);
+}
+
+static bool dm_table_all_devices_attribute(struct dm_table *t,
+                                          iterate_devices_callout_fn func)
 {
        struct dm_target *ti;
        unsigned i = 0;
 
-       /* Ensure that all underlying device are non-rotational. */
        while (i < dm_table_get_num_targets(t)) {
                ti = dm_table_get_target(t, i++);
 
                if (!ti->type->iterate_devices ||
-                   !ti->type->iterate_devices(ti, device_is_nonrot, NULL))
+                   !ti->type->iterate_devices(ti, func, NULL))
                        return 0;
        }
 
@@ -1396,7 +1439,8 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
        if (!dm_table_discard_zeroes_data(t))
                q->limits.discard_zeroes_data = 0;
 
-       if (dm_table_is_nonrot(t))
+       /* Ensure that all underlying devices are non-rotational. */
+       if (dm_table_all_devices_attribute(t, device_is_nonrot))
                queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q);
        else
                queue_flag_clear_unlocked(QUEUE_FLAG_NONROT, q);
@@ -1404,6 +1448,15 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
        dm_table_set_integrity(t);
 
        /*
+        * Determine whether or not this queue's I/O timings contribute
+        * to the entropy pool, Only request-based targets use this.
+        * Clear QUEUE_FLAG_ADD_RANDOM if any underlying device does not
+        * have it set.
+        */
+       if (blk_queue_add_random(q) && dm_table_all_devices_attribute(t, device_is_not_random))
+               queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, q);
+
+       /*
         * QUEUE_FLAG_STACKABLE must be set after all queue settings are
         * visible to other CPUs because, once the flag is set, incoming bios
         * are processed by request-based dm, which refers to the queue
index af1fc3b..c29410a 100644 (file)
@@ -509,9 +509,9 @@ enum pool_mode {
 struct pool_features {
        enum pool_mode mode;
 
-       unsigned zero_new_blocks:1;
-       unsigned discard_enabled:1;
-       unsigned discard_passdown:1;
+       bool zero_new_blocks:1;
+       bool discard_enabled:1;
+       bool discard_passdown:1;
 };
 
 struct thin_c;
@@ -580,7 +580,8 @@ struct pool_c {
        struct dm_target_callbacks callbacks;
 
        dm_block_t low_water_blocks;
-       struct pool_features pf;
+       struct pool_features requested_pf; /* Features requested during table load */
+       struct pool_features adjusted_pf;  /* Features used after adjusting for constituent devices */
 };
 
 /*
@@ -1839,6 +1840,47 @@ static void __requeue_bios(struct pool *pool)
 /*----------------------------------------------------------------
  * Binding of control targets to a pool object
  *--------------------------------------------------------------*/
+static bool data_dev_supports_discard(struct pool_c *pt)
+{
+       struct request_queue *q = bdev_get_queue(pt->data_dev->bdev);
+
+       return q && blk_queue_discard(q);
+}
+
+/*
+ * If discard_passdown was enabled verify that the data device
+ * supports discards.  Disable discard_passdown if not.
+ */
+static void disable_passdown_if_not_supported(struct pool_c *pt)
+{
+       struct pool *pool = pt->pool;
+       struct block_device *data_bdev = pt->data_dev->bdev;
+       struct queue_limits *data_limits = &bdev_get_queue(data_bdev)->limits;
+       sector_t block_size = pool->sectors_per_block << SECTOR_SHIFT;
+       const char *reason = NULL;
+       char buf[BDEVNAME_SIZE];
+
+       if (!pt->adjusted_pf.discard_passdown)
+               return;
+
+       if (!data_dev_supports_discard(pt))
+               reason = "discard unsupported";
+
+       else if (data_limits->max_discard_sectors < pool->sectors_per_block)
+               reason = "max discard sectors smaller than a block";
+
+       else if (data_limits->discard_granularity > block_size)
+               reason = "discard granularity larger than a block";
+
+       else if (block_size & (data_limits->discard_granularity - 1))
+               reason = "discard granularity not a factor of block size";
+
+       if (reason) {
+               DMWARN("Data device (%s) %s: Disabling discard passdown.", bdevname(data_bdev, buf), reason);
+               pt->adjusted_pf.discard_passdown = false;
+       }
+}
+
 static int bind_control_target(struct pool *pool, struct dm_target *ti)
 {
        struct pool_c *pt = ti->private;
@@ -1847,31 +1889,16 @@ static int bind_control_target(struct pool *pool, struct dm_target *ti)
         * We want to make sure that degraded pools are never upgraded.
         */
        enum pool_mode old_mode = pool->pf.mode;
-       enum pool_mode new_mode = pt->pf.mode;
+       enum pool_mode new_mode = pt->adjusted_pf.mode;
 
        if (old_mode > new_mode)
                new_mode = old_mode;
 
        pool->ti = ti;
        pool->low_water_blocks = pt->low_water_blocks;
-       pool->pf = pt->pf;
-       set_pool_mode(pool, new_mode);
+       pool->pf = pt->adjusted_pf;
 
-       /*
-        * If discard_passdown was enabled verify that the data device
-        * supports discards.  Disable discard_passdown if not; otherwise
-        * -EOPNOTSUPP will be returned.
-        */
-       /* FIXME: pull this out into a sep fn. */
-       if (pt->pf.discard_passdown) {
-               struct request_queue *q = bdev_get_queue(pt->data_dev->bdev);
-               if (!q || !blk_queue_discard(q)) {
-                       char buf[BDEVNAME_SIZE];
-                       DMWARN("Discard unsupported by data device (%s): Disabling discard passdown.",
-                              bdevname(pt->data_dev->bdev, buf));
-                       pool->pf.discard_passdown = 0;
-               }
-       }
+       set_pool_mode(pool, new_mode);
 
        return 0;
 }
@@ -1889,9 +1916,9 @@ static void unbind_control_target(struct pool *pool, struct dm_target *ti)
 static void pool_features_init(struct pool_features *pf)
 {
        pf->mode = PM_WRITE;
-       pf->zero_new_blocks = 1;
-       pf->discard_enabled = 1;
-       pf->discard_passdown = 1;
+       pf->zero_new_blocks = true;
+       pf->discard_enabled = true;
+       pf->discard_passdown = true;
 }
 
 static void __pool_destroy(struct pool *pool)
@@ -2119,13 +2146,13 @@ static int parse_pool_features(struct dm_arg_set *as, struct pool_features *pf,
                argc--;
 
                if (!strcasecmp(arg_name, "skip_block_zeroing"))
-                       pf->zero_new_blocks = 0;
+                       pf->zero_new_blocks = false;
 
                else if (!strcasecmp(arg_name, "ignore_discard"))
-                       pf->discard_enabled = 0;
+                       pf->discard_enabled = false;
 
                else if (!strcasecmp(arg_name, "no_discard_passdown"))
-                       pf->discard_passdown = 0;
+                       pf->discard_passdown = false;
 
                else if (!strcasecmp(arg_name, "read_only"))
                        pf->mode = PM_READ_ONLY;
@@ -2259,8 +2286,9 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
        pt->metadata_dev = metadata_dev;
        pt->data_dev = data_dev;
        pt->low_water_blocks = low_water_blocks;
-       pt->pf = pf;
+       pt->adjusted_pf = pt->requested_pf = pf;
        ti->num_flush_requests = 1;
+
        /*
         * Only need to enable discards if the pool should pass
         * them down to the data device.  The thin device's discard
@@ -2268,12 +2296,14 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
         */
        if (pf.discard_enabled && pf.discard_passdown) {
                ti->num_discard_requests = 1;
+
                /*
                 * Setting 'discards_supported' circumvents the normal
                 * stacking of discard limits (this keeps the pool and
                 * thin devices' discard limits consistent).
                 */
                ti->discards_supported = true;
+               ti->discard_zeroes_data_unsupported = true;
        }
        ti->private = pt;
 
@@ -2703,7 +2733,7 @@ static int pool_status(struct dm_target *ti, status_type_t type,
                       format_dev_t(buf2, pt->data_dev->bdev->bd_dev),
                       (unsigned long)pool->sectors_per_block,
                       (unsigned long long)pt->low_water_blocks);
-               emit_flags(&pt->pf, result, sz, maxlen);
+               emit_flags(&pt->requested_pf, result, sz, maxlen);
                break;
        }
 
@@ -2732,20 +2762,21 @@ static int pool_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
        return min(max_size, q->merge_bvec_fn(q, bvm, biovec));
 }
 
-static void set_discard_limits(struct pool *pool, struct queue_limits *limits)
+static void set_discard_limits(struct pool_c *pt, struct queue_limits *limits)
 {
-       /*
-        * FIXME: these limits may be incompatible with the pool's data device
-        */
+       struct pool *pool = pt->pool;
+       struct queue_limits *data_limits;
+
        limits->max_discard_sectors = pool->sectors_per_block;
 
        /*
-        * This is just a hint, and not enforced.  We have to cope with
-        * bios that cover a block partially.  A discard that spans a block
-        * boundary is not sent to this target.
+        * discard_granularity is just a hint, and not enforced.
         */
-       limits->discard_granularity = pool->sectors_per_block << SECTOR_SHIFT;
-       limits->discard_zeroes_data = pool->pf.zero_new_blocks;
+       if (pt->adjusted_pf.discard_passdown) {
+               data_limits = &bdev_get_queue(pt->data_dev->bdev)->limits;
+               limits->discard_granularity = data_limits->discard_granularity;
+       } else
+               limits->discard_granularity = pool->sectors_per_block << SECTOR_SHIFT;
 }
 
 static void pool_io_hints(struct dm_target *ti, struct queue_limits *limits)
@@ -2755,15 +2786,25 @@ static void pool_io_hints(struct dm_target *ti, struct queue_limits *limits)
 
        blk_limits_io_min(limits, 0);
        blk_limits_io_opt(limits, pool->sectors_per_block << SECTOR_SHIFT);
-       if (pool->pf.discard_enabled)
-               set_discard_limits(pool, limits);
+
+       /*
+        * pt->adjusted_pf is a staging area for the actual features to use.
+        * They get transferred to the live pool in bind_control_target()
+        * called from pool_preresume().
+        */
+       if (!pt->adjusted_pf.discard_enabled)
+               return;
+
+       disable_passdown_if_not_supported(pt);
+
+       set_discard_limits(pt, limits);
 }
 
 static struct target_type pool_target = {
        .name = "thin-pool",
        .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE |
                    DM_TARGET_IMMUTABLE,
-       .version = {1, 3, 0},
+       .version = {1, 4, 0},
        .module = THIS_MODULE,
        .ctr = pool_ctr,
        .dtr = pool_dtr,
@@ -3042,19 +3083,19 @@ static int thin_iterate_devices(struct dm_target *ti,
        return 0;
 }
 
+/*
+ * A thin device always inherits its queue limits from its pool.
+ */
 static void thin_io_hints(struct dm_target *ti, struct queue_limits *limits)
 {
        struct thin_c *tc = ti->private;
-       struct pool *pool = tc->pool;
 
-       blk_limits_io_min(limits, 0);
-       blk_limits_io_opt(limits, pool->sectors_per_block << SECTOR_SHIFT);
-       set_discard_limits(pool, limits);
+       *limits = bdev_get_queue(tc->pool_dev->bdev)->limits;
 }
 
 static struct target_type thin_target = {
        .name = "thin",
-       .version = {1, 3, 0},
+       .version = {1, 4, 0},
        .module = THIS_MODULE,
        .ctr = thin_ctr,
        .dtr = thin_dtr,
index 254d192..892ae27 100644 (file)
@@ -718,8 +718,8 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
        v->hash_dev_block_bits = ffs(num) - 1;
 
        if (sscanf(argv[5], "%llu%c", &num_ll, &dummy) != 1 ||
-           num_ll << (v->data_dev_block_bits - SECTOR_SHIFT) !=
-           (sector_t)num_ll << (v->data_dev_block_bits - SECTOR_SHIFT)) {
+           (sector_t)(num_ll << (v->data_dev_block_bits - SECTOR_SHIFT))
+           >> (v->data_dev_block_bits - SECTOR_SHIFT) != num_ll) {
                ti->error = "Invalid data blocks";
                r = -EINVAL;
                goto bad;
@@ -733,8 +733,8 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
        }
 
        if (sscanf(argv[6], "%llu%c", &num_ll, &dummy) != 1 ||
-           num_ll << (v->hash_dev_block_bits - SECTOR_SHIFT) !=
-           (sector_t)num_ll << (v->hash_dev_block_bits - SECTOR_SHIFT)) {
+           (sector_t)(num_ll << (v->hash_dev_block_bits - SECTOR_SHIFT))
+           >> (v->hash_dev_block_bits - SECTOR_SHIFT) != num_ll) {
                ti->error = "Invalid hash start";
                r = -EINVAL;
                goto bad;
index 4e09b6f..67ffa39 100644 (file)
@@ -865,10 +865,14 @@ static void dm_done(struct request *clone, int error, bool mapped)
 {
        int r = error;
        struct dm_rq_target_io *tio = clone->end_io_data;
-       dm_request_endio_fn rq_end_io = tio->ti->type->rq_end_io;
+       dm_request_endio_fn rq_end_io = NULL;
 
-       if (mapped && rq_end_io)
-               r = rq_end_io(tio->ti, clone, error, &tio->info);
+       if (tio->ti) {
+               rq_end_io = tio->ti->type->rq_end_io;
+
+               if (mapped && rq_end_io)
+                       r = rq_end_io(tio->ti, clone, error, &tio->info);
+       }
 
        if (r <= 0)
                /* The target wants to complete the I/O */
@@ -1588,15 +1592,6 @@ static int map_request(struct dm_target *ti, struct request *clone,
        int r, requeued = 0;
        struct dm_rq_target_io *tio = clone->end_io_data;
 
-       /*
-        * Hold the md reference here for the in-flight I/O.
-        * We can't rely on the reference count by device opener,
-        * because the device may be closed during the request completion
-        * when all bios are completed.
-        * See the comment in rq_completed() too.
-        */
-       dm_get(md);
-
        tio->ti = ti;
        r = ti->type->map_rq(ti, clone, &tio->info);
        switch (r) {
@@ -1628,6 +1623,26 @@ static int map_request(struct dm_target *ti, struct request *clone,
        return requeued;
 }
 
+static struct request *dm_start_request(struct mapped_device *md, struct request *orig)
+{
+       struct request *clone;
+
+       blk_start_request(orig);
+       clone = orig->special;
+       atomic_inc(&md->pending[rq_data_dir(clone)]);
+
+       /*
+        * Hold the md reference here for the in-flight I/O.
+        * We can't rely on the reference count by device opener,
+        * because the device may be closed during the request completion
+        * when all bios are completed.
+        * See the comment in rq_completed() too.
+        */
+       dm_get(md);
+
+       return clone;
+}
+
 /*
  * q->request_fn for request-based dm.
  * Called with the queue lock held.
@@ -1657,14 +1672,21 @@ static void dm_request_fn(struct request_queue *q)
                        pos = blk_rq_pos(rq);
 
                ti = dm_table_find_target(map, pos);
-               BUG_ON(!dm_target_is_valid(ti));
+               if (!dm_target_is_valid(ti)) {
+                       /*
+                        * Must perform setup, that dm_done() requires,
+                        * before calling dm_kill_unmapped_request
+                        */
+                       DMERR_LIMIT("request attempted access beyond the end of device");
+                       clone = dm_start_request(md, rq);
+                       dm_kill_unmapped_request(clone, -EIO);
+                       continue;
+               }
 
                if (ti->type->busy && ti->type->busy(ti))
                        goto delay_and_out;
 
-               blk_start_request(rq);
-               clone = rq->special;
-               atomic_inc(&md->pending[rq_data_dir(clone)]);
+               clone = dm_start_request(md, rq);
 
                spin_unlock(q->queue_lock);
                if (map_request(ti, clone, md))
@@ -1684,8 +1706,6 @@ delay_and_out:
        blk_delay_queue(q, HZ / 10);
 out:
        dm_table_put(map);
-
-       return;
 }
 
 int dm_underlying_device_busy(struct request_queue *q)
@@ -2409,7 +2429,7 @@ static void dm_queue_flush(struct mapped_device *md)
  */
 struct dm_table *dm_swap_table(struct mapped_device *md, struct dm_table *table)
 {
-       struct dm_table *map = ERR_PTR(-EINVAL);
+       struct dm_table *live_map, *map = ERR_PTR(-EINVAL);
        struct queue_limits limits;
        int r;
 
@@ -2419,6 +2439,19 @@ struct dm_table *dm_swap_table(struct mapped_device *md, struct dm_table *table)
        if (!dm_suspended_md(md))
                goto out;
 
+       /*
+        * If the new table has no data devices, retain the existing limits.
+        * This helps multipath with queue_if_no_path if all paths disappear,
+        * then new I/O is queued based on these limits, and then some paths
+        * reappear.
+        */
+       if (dm_table_has_no_data_devices(table)) {
+               live_map = dm_get_live_table(md);
+               if (live_map)
+                       limits = md->queue->limits;
+               dm_table_put(live_map);
+       }
+
        r = dm_calculate_queue_limits(table, &limits);
        if (r) {
                map = ERR_PTR(r);
index 52eef49..6a99fef 100644 (file)
@@ -54,6 +54,7 @@ void dm_table_event_callback(struct dm_table *t,
                             void (*fn)(void *), void *context);
 struct dm_target *dm_table_get_target(struct dm_table *t, unsigned int index);
 struct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector);
+bool dm_table_has_no_data_devices(struct dm_table *table);
 int dm_calculate_queue_limits(struct dm_table *table,
                              struct queue_limits *limits);
 void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
index 1c2eb38..0138a72 100644 (file)
@@ -1512,14 +1512,16 @@ static int _enough(struct r10conf *conf, struct geom *geo, int ignore)
        do {
                int n = conf->copies;
                int cnt = 0;
+               int this = first;
                while (n--) {
-                       if (conf->mirrors[first].rdev &&
-                           first != ignore)
+                       if (conf->mirrors[this].rdev &&
+                           this != ignore)
                                cnt++;
-                       first = (first+1) % geo->raid_disks;
+                       this = (this+1) % geo->raid_disks;
                }
                if (cnt == 0)
                        return 0;
+               first = (first + geo->near_copies) % geo->raid_disks;
        } while (first != 0);
        return 1;
 }
index 7031b86..0689173 100644 (file)
@@ -1591,6 +1591,7 @@ static int resize_stripes(struct r5conf *conf, int newsize)
                #ifdef CONFIG_MULTICORE_RAID456
                init_waitqueue_head(&nsh->ops.wait_for_ops);
                #endif
+               spin_lock_init(&nsh->stripe_lock);
 
                list_add(&nsh->lru, &newstripes);
        }
index 866f959..29d72a2 100644 (file)
@@ -342,7 +342,7 @@ int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel)
 
                 /*
                  * Delay might be needed for ABB8500 cut 3.0, if not, remove
-                 * when hardware will be availible
+                 * when hardware will be available
                  */
                        msleep(1);
                        break;
index 3a8fa88..ff61efc 100644 (file)
@@ -281,7 +281,7 @@ static int __devinit rc5t583_i2c_probe(struct i2c_client *i2c,
 
        if (i2c->irq) {
                ret = rc5t583_irq_init(rc5t583, i2c->irq, pdata->irq_base);
-               /* Still continue with waring if irq init fails */
+               /* Still continue with warning, if irq init fails */
                if (ret)
                        dev_warn(&i2c->dev, "IRQ init failed: %d\n", ret);
                else
index 0f70dce..fbabc3c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * RDC321x MFD southbrige driver
+ * RDC321x MFD southbridge driver
  *
  * Copyright (C) 2007-2010 Florian Fainelli <florian@openwrt.org>
  * Copyright (C) 2010 Bernhard Loos <bernhardloos@googlemail.com>
index 5f58370..345960c 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/i2c.h>
 #include <linux/regmap.h>
 #include <linux/regulator/of_regulator.h>
+#include <linux/regulator/machine.h>
 
 #include <linux/mfd/core.h>
 #include <linux/mfd/tps6586x.h>
@@ -346,6 +347,7 @@ failed:
 
 #ifdef CONFIG_OF
 static struct of_regulator_match tps6586x_matches[] = {
+       { .name = "sys",     .driver_data = (void *)TPS6586X_ID_SYS     },
        { .name = "sm0",     .driver_data = (void *)TPS6586X_ID_SM_0    },
        { .name = "sm1",     .driver_data = (void *)TPS6586X_ID_SM_1    },
        { .name = "sm2",     .driver_data = (void *)TPS6586X_ID_SM_2    },
@@ -369,6 +371,7 @@ static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *clien
        struct tps6586x_platform_data *pdata;
        struct tps6586x_subdev_info *devs;
        struct device_node *regs;
+       const char *sys_rail_name = NULL;
        unsigned int count;
        unsigned int i, j;
        int err;
@@ -391,12 +394,22 @@ static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *clien
                return NULL;
 
        for (i = 0, j = 0; i < num && j < count; i++) {
+               struct regulator_init_data *reg_idata;
+
                if (!tps6586x_matches[i].init_data)
                        continue;
 
+               reg_idata  = tps6586x_matches[i].init_data;
                devs[j].name = "tps6586x-regulator";
                devs[j].platform_data = tps6586x_matches[i].init_data;
                devs[j].id = (int)tps6586x_matches[i].driver_data;
+               if (devs[j].id == TPS6586X_ID_SYS)
+                       sys_rail_name = reg_idata->constraints.name;
+
+               if ((devs[j].id == TPS6586X_ID_LDO_5) ||
+                       (devs[j].id == TPS6586X_ID_LDO_RTC))
+                       reg_idata->supply_regulator = sys_rail_name;
+
                devs[j].of_node = tps6586x_matches[i].of_node;
                j++;
        }
index 5a62e6b..0b6e361 100644 (file)
@@ -136,7 +136,7 @@ static __devinit int tps65911_comparator_probe(struct platform_device *pdev)
 
        ret = comp_threshold_set(tps65910, COMP2, pdata->vmbch2_threshold);
        if (ret < 0) {
-               dev_err(&pdev->dev, "cannot set COMP2 theshold\n");
+               dev_err(&pdev->dev, "cannot set COMP2 threshold\n");
                return ret;
        }
 
index 0aac4af..a050e56 100644 (file)
@@ -135,6 +135,7 @@ static struct regmap_irq_chip wm8994_irq_chip = {
        .status_base = WM8994_INTERRUPT_STATUS_1,
        .mask_base = WM8994_INTERRUPT_STATUS_1_MASK,
        .ack_base = WM8994_INTERRUPT_STATUS_1,
+       .runtime_pm = true,
 };
 
 int wm8994_irq_init(struct wm8994 *wm8994)
index d4619e2..2273ce6 100644 (file)
@@ -641,7 +641,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
        /*
         * If the host and card support UHS-I mode request the card
         * to switch to 1.8V signaling level.  No 1.8v signalling if
-        * UHS mode is not enabled to maintain compatibilty and some
+        * UHS mode is not enabled to maintain compatibility and some
         * systems that claim 1.8v signalling in fact do not support
         * it.
         */
index efdb81d..74bed0f 100644 (file)
@@ -356,7 +356,7 @@ static void at91_mci_handle_transmitted(struct at91mci_host *host)
 }
 
 /*
- * Update bytes tranfered count during a write operation
+ * Update bytes transfered count during a write operation
  */
 static void at91_mci_update_bytes_xfered(struct at91mci_host *host)
 {
index a53c7c4..852d5fb 100644 (file)
@@ -1022,7 +1022,7 @@ static void atmci_stop_transfer(struct atmel_mci *host)
 }
 
 /*
- * Stop data transfer because error(s) occured.
+ * Stop data transfer because error(s) occurred.
  */
 static void atmci_stop_transfer_pdc(struct atmel_mci *host)
 {
index 3a09f93..686e256 100644 (file)
@@ -447,7 +447,7 @@ static void omap_hsmmc_stop_clock(struct omap_hsmmc_host *host)
        OMAP_HSMMC_WRITE(host->base, SYSCTL,
                OMAP_HSMMC_READ(host->base, SYSCTL) & ~CEN);
        if ((OMAP_HSMMC_READ(host->base, SYSCTL) & CEN) != 0x0)
-               dev_dbg(mmc_dev(host->mmc), "MMC Clock is not stoped\n");
+               dev_dbg(mmc_dev(host->mmc), "MMC Clock is not stopped\n");
 }
 
 static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host,
index e23f813..32f4a07 100644 (file)
@@ -315,7 +315,7 @@ static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg)
                new_val = val & (SDHCI_CTRL_LED | \
                                SDHCI_CTRL_4BITBUS | \
                                SDHCI_CTRL_D3CD);
-               /* ensure the endianess */
+               /* ensure the endianness */
                new_val |= ESDHC_HOST_CONTROL_LE;
                /* bits 8&9 are reserved on mx25 */
                if (!is_imx25_esdhc(imx_data)) {
index 3135a1a..58eab9a 100644 (file)
@@ -806,7 +806,7 @@ static void command_res_completed(struct urb *urb)
                 * we suspect a buggy USB host controller
                 */
        } else if (!vub300->data) {
-               /* this means that the command (typically CMD52) suceeded */
+               /* this means that the command (typically CMD52) succeeded */
        } else if (vub300->resp.common.header_type != 0x02) {
                /*
                 * this is an error response from the VUB300 chip
index f2f482b..a6e7451 100644 (file)
@@ -1123,6 +1123,33 @@ static unsigned long mtdchar_get_unmapped_area(struct file *file,
 }
 #endif
 
+static inline unsigned long get_vm_size(struct vm_area_struct *vma)
+{
+       return vma->vm_end - vma->vm_start;
+}
+
+static inline resource_size_t get_vm_offset(struct vm_area_struct *vma)
+{
+       return (resource_size_t) vma->vm_pgoff << PAGE_SHIFT;
+}
+
+/*
+ * Set a new vm offset.
+ *
+ * Verify that the incoming offset really works as a page offset,
+ * and that the offset and size fit in a resource_size_t.
+ */
+static inline int set_vm_offset(struct vm_area_struct *vma, resource_size_t off)
+{
+       pgoff_t pgoff = off >> PAGE_SHIFT;
+       if (off != (resource_size_t) pgoff << PAGE_SHIFT)
+               return -EINVAL;
+       if (off + get_vm_size(vma) - 1 < off)
+               return -EINVAL;
+       vma->vm_pgoff = pgoff;
+       return 0;
+}
+
 /*
  * set up a mapping for shared memory segments
  */
@@ -1132,20 +1159,29 @@ static int mtdchar_mmap(struct file *file, struct vm_area_struct *vma)
        struct mtd_file_info *mfi = file->private_data;
        struct mtd_info *mtd = mfi->mtd;
        struct map_info *map = mtd->priv;
-       unsigned long start;
-       unsigned long off;
-       u32 len;
+       resource_size_t start, off;
+       unsigned long len, vma_len;
 
        if (mtd->type == MTD_RAM || mtd->type == MTD_ROM) {
-               off = vma->vm_pgoff << PAGE_SHIFT;
+               off = get_vm_offset(vma);
                start = map->phys;
                len = PAGE_ALIGN((start & ~PAGE_MASK) + map->size);
                start &= PAGE_MASK;
-               if ((vma->vm_end - vma->vm_start + off) > len)
+               vma_len = get_vm_size(vma);
+
+               /* Overflow in off+len? */
+               if (vma_len + off < off)
+                       return -EINVAL;
+               /* Does it fit in the mapping? */
+               if (vma_len + off > len)
                        return -EINVAL;
 
                off += start;
-               vma->vm_pgoff = off >> PAGE_SHIFT;
+               /* Did that overflow? */
+               if (off < start)
+                       return -EINVAL;
+               if (set_vm_offset(vma, off) < 0)
+                       return -EINVAL;
                vma->vm_flags |= VM_IO | VM_RESERVED;
 
 #ifdef pgprot_noncached
index b153666..bb9670f 100644 (file)
@@ -364,7 +364,7 @@ typhoon_inc_rxfree_index(u32 *index, const int count)
 static inline void
 typhoon_inc_tx_index(u32 *index, const int count)
 {
-       /* if we start using the Hi Tx ring, this needs updateing */
+       /* if we start using the Hi Tx ring, this needs updating */
        typhoon_inc_index(index, count, TXLO_ENTRIES);
 }
 
index 79cebd8..e48312f 100644 (file)
@@ -8564,7 +8564,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        return 0;
 
 error:
-       iounmap(bp->regview);
+       pci_iounmap(pdev, bp->regview);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
        pci_set_drvdata(pdev, NULL);
index 6d1a24a..eac2523 100644 (file)
@@ -1458,7 +1458,7 @@ struct bnx2x {
        int                             fw_stats_req_sz;
 
        /*
-        * FW statistics data shortcut (points at the begining of
+        * FW statistics data shortcut (points at the beginning of
         * fw_stats buffer + fw_stats_req_sz).
         */
        struct bnx2x_fw_stats_data      *fw_stats_data;
index f83e033..acf2fe4 100644 (file)
@@ -1321,7 +1321,7 @@ void bnx2x_init_mcast_obj(struct bnx2x *bp,
  * the current command will be enqueued to the tail of the
  * pending commands list.
  *
- * Return: 0 is operation was sucessfull and there are no pending completions,
+ * Return: 0 is operation was successfull and there are no pending completions,
  *         negative if there were errors, positive if there are pending
  *         completions.
  */
index c42bbb1..a688a2d 100644 (file)
@@ -722,10 +722,8 @@ static int octeon_mgmt_init_phy(struct net_device *netdev)
                                   octeon_mgmt_adjust_link, 0,
                                   PHY_INTERFACE_MODE_MII);
 
-       if (IS_ERR(p->phydev)) {
-               p->phydev = NULL;
+       if (!p->phydev)
                return -1;
-       }
 
        phy_start_aneg(p->phydev);
 
index e559dfa..6fa74d5 100644 (file)
@@ -1101,9 +1101,9 @@ static int pasemi_mac_phy_init(struct net_device *dev)
        phydev = of_phy_connect(dev, phy_dn, &pasemi_adjust_link, 0,
                                PHY_INTERFACE_MODE_SGMII);
 
-       if (IS_ERR(phydev)) {
+       if (!phydev) {
                printk(KERN_ERR "%s: Could not attach to phy\n", dev->name);
-               return PTR_ERR(phydev);
+               return -ENODEV;
        }
 
        mac->phydev = phydev;
index b8ead69..2a179d0 100644 (file)
@@ -15,7 +15,7 @@ qlcnic_poll_rsp(struct qlcnic_adapter *adapter)
 
        do {
                /* give atleast 1ms for firmware to respond */
-               msleep(1);
+               mdelay(1);
 
                if (++timeout > QLCNIC_OS_CRB_RETRY_COUNT)
                        return QLCNIC_CDRP_RSP_TIMEOUT;
@@ -601,7 +601,7 @@ void qlcnic_fw_destroy_ctx(struct qlcnic_adapter *adapter)
                qlcnic_fw_cmd_destroy_tx_ctx(adapter);
 
                /* Allow dma queues to drain after context reset */
-               msleep(20);
+               mdelay(20);
        }
 }
 
index 2346b38..7997895 100644 (file)
@@ -229,3 +229,5 @@ static void __exit bcm87xx_exit(void)
                ARRAY_SIZE(bcm87xx_driver));
 }
 module_exit(bcm87xx_exit);
+
+MODULE_LICENSE("GPL");
index cf287e0..2165d5f 100644 (file)
 #include <linux/phy.h>
 #include <linux/micrel_phy.h>
 
+/* Operation Mode Strap Override */
+#define MII_KSZPHY_OMSO                                0x16
+#define KSZPHY_OMSO_B_CAST_OFF                 (1 << 9)
+#define KSZPHY_OMSO_RMII_OVERRIDE              (1 << 1)
+#define KSZPHY_OMSO_MII_OVERRIDE               (1 << 0)
+
 /* general Interrupt control/status reg in vendor specific block. */
 #define MII_KSZPHY_INTCS                       0x1B
 #define        KSZPHY_INTCS_JABBER                     (1 << 15)
@@ -101,6 +107,13 @@ static int kszphy_config_init(struct phy_device *phydev)
        return 0;
 }
 
+static int ksz8021_config_init(struct phy_device *phydev)
+{
+       const u16 val = KSZPHY_OMSO_B_CAST_OFF | KSZPHY_OMSO_RMII_OVERRIDE;
+       phy_write(phydev, MII_KSZPHY_OMSO, val);
+       return 0;
+}
+
 static int ks8051_config_init(struct phy_device *phydev)
 {
        int regval;
@@ -128,9 +141,22 @@ static struct phy_driver ksphy_driver[] = {
        .config_intr    = ks8737_config_intr,
        .driver         = { .owner = THIS_MODULE,},
 }, {
-       .phy_id         = PHY_ID_KS8041,
+       .phy_id         = PHY_ID_KSZ8021,
+       .phy_id_mask    = 0x00ffffff,
+       .name           = "Micrel KSZ8021",
+       .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause |
+                          SUPPORTED_Asym_Pause),
+       .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
+       .config_init    = ksz8021_config_init,
+       .config_aneg    = genphy_config_aneg,
+       .read_status    = genphy_read_status,
+       .ack_interrupt  = kszphy_ack_interrupt,
+       .config_intr    = kszphy_config_intr,
+       .driver         = { .owner = THIS_MODULE,},
+}, {
+       .phy_id         = PHY_ID_KSZ8041,
        .phy_id_mask    = 0x00fffff0,
-       .name           = "Micrel KS8041",
+       .name           = "Micrel KSZ8041",
        .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause
                                | SUPPORTED_Asym_Pause),
        .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
@@ -141,9 +167,9 @@ static struct phy_driver ksphy_driver[] = {
        .config_intr    = kszphy_config_intr,
        .driver         = { .owner = THIS_MODULE,},
 }, {
-       .phy_id         = PHY_ID_KS8051,
+       .phy_id         = PHY_ID_KSZ8051,
        .phy_id_mask    = 0x00fffff0,
-       .name           = "Micrel KS8051",
+       .name           = "Micrel KSZ8051",
        .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause
                                | SUPPORTED_Asym_Pause),
        .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
@@ -154,8 +180,8 @@ static struct phy_driver ksphy_driver[] = {
        .config_intr    = kszphy_config_intr,
        .driver         = { .owner = THIS_MODULE,},
 }, {
-       .phy_id         = PHY_ID_KS8001,
-       .name           = "Micrel KS8001 or KS8721",
+       .phy_id         = PHY_ID_KSZ8001,
+       .name           = "Micrel KSZ8001 or KS8721",
        .phy_id_mask    = 0x00ffffff,
        .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
        .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
@@ -201,10 +227,11 @@ MODULE_LICENSE("GPL");
 
 static struct mdio_device_id __maybe_unused micrel_tbl[] = {
        { PHY_ID_KSZ9021, 0x000ffffe },
-       { PHY_ID_KS8001, 0x00ffffff },
+       { PHY_ID_KSZ8001, 0x00ffffff },
        { PHY_ID_KS8737, 0x00fffff0 },
-       { PHY_ID_KS8041, 0x00fffff0 },
-       { PHY_ID_KS8051, 0x00fffff0 },
+       { PHY_ID_KSZ8021, 0x00ffffff },
+       { PHY_ID_KSZ8041, 0x00fffff0 },
+       { PHY_ID_KSZ8051, 0x00fffff0 },
        { }
 };
 
index 6d61923..88e3991 100644 (file)
@@ -56,6 +56,32 @@ static int smsc_phy_config_init(struct phy_device *phydev)
        return smsc_phy_ack_interrupt (phydev);
 }
 
+static int lan87xx_config_init(struct phy_device *phydev)
+{
+       /*
+        * Make sure the EDPWRDOWN bit is NOT set. Setting this bit on
+        * LAN8710/LAN8720 PHY causes the PHY to misbehave, likely due
+        * to a bug on the chip.
+        *
+        * When the system is powered on with the network cable being
+        * disconnected all the way until after ifconfig ethX up is
+        * issued for the LAN port with this PHY, connecting the cable
+        * afterwards does not cause LINK change detection, while the
+        * expected behavior is the Link UP being detected.
+        */
+       int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
+       if (rc < 0)
+               return rc;
+
+       rc &= ~MII_LAN83C185_EDPWRDOWN;
+
+       rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS, rc);
+       if (rc < 0)
+               return rc;
+
+       return smsc_phy_ack_interrupt(phydev);
+}
+
 static int lan911x_config_init(struct phy_device *phydev)
 {
        return smsc_phy_ack_interrupt(phydev);
@@ -162,7 +188,7 @@ static struct phy_driver smsc_phy_driver[] = {
        /* basic functions */
        .config_aneg    = genphy_config_aneg,
        .read_status    = genphy_read_status,
-       .config_init    = smsc_phy_config_init,
+       .config_init    = lan87xx_config_init,
 
        /* IRQ related */
        .ack_interrupt  = smsc_phy_ack_interrupt,
index cbf7047..20f31d0 100644 (file)
@@ -570,7 +570,7 @@ static int pppoe_release(struct socket *sock)
 
        po = pppox_sk(sk);
 
-       if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
+       if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND | PPPOX_ZOMBIE)) {
                dev_put(po->pppoe_dev);
                po->pppoe_dev = NULL;
        }
index 341b65d..f8cd61f 100644 (file)
@@ -848,7 +848,7 @@ static struct netpoll_info *team_netpoll_info(struct team *team)
 }
 #endif
 
-static void __team_port_change_check(struct team_port *port, bool linkup);
+static void __team_port_change_port_added(struct team_port *port, bool linkup);
 
 static int team_port_add(struct team *team, struct net_device *port_dev)
 {
@@ -948,7 +948,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
        team_port_enable(team, port);
        list_add_tail_rcu(&port->list, &team->port_list);
        __team_compute_features(team);
-       __team_port_change_check(port, !!netif_carrier_ok(port_dev));
+       __team_port_change_port_added(port, !!netif_carrier_ok(port_dev));
        __team_options_change_check(team);
 
        netdev_info(dev, "Port device %s added\n", portname);
@@ -983,6 +983,8 @@ err_set_mtu:
        return err;
 }
 
+static void __team_port_change_port_removed(struct team_port *port);
+
 static int team_port_del(struct team *team, struct net_device *port_dev)
 {
        struct net_device *dev = team->dev;
@@ -999,8 +1001,7 @@ static int team_port_del(struct team *team, struct net_device *port_dev)
        __team_option_inst_mark_removed_port(team, port);
        __team_options_change_check(team);
        __team_option_inst_del_port(team, port);
-       port->removed = true;
-       __team_port_change_check(port, false);
+       __team_port_change_port_removed(port);
        team_port_disable(team, port);
        list_del_rcu(&port->list);
        netdev_rx_handler_unregister(port_dev);
@@ -1652,8 +1653,8 @@ static int team_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info)
 
        hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq,
                          &team_nl_family, 0, TEAM_CMD_NOOP);
-       if (IS_ERR(hdr)) {
-               err = PTR_ERR(hdr);
+       if (!hdr) {
+               err = -EMSGSIZE;
                goto err_msg_put;
        }
 
@@ -1847,8 +1848,8 @@ start_again:
 
        hdr = genlmsg_put(skb, pid, seq, &team_nl_family, flags | NLM_F_MULTI,
                          TEAM_CMD_OPTIONS_GET);
-       if (IS_ERR(hdr))
-               return PTR_ERR(hdr);
+       if (!hdr)
+               return -EMSGSIZE;
 
        if (nla_put_u32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex))
                goto nla_put_failure;
@@ -2067,8 +2068,8 @@ static int team_nl_fill_port_list_get(struct sk_buff *skb,
 
        hdr = genlmsg_put(skb, pid, seq, &team_nl_family, flags,
                          TEAM_CMD_PORT_LIST_GET);
-       if (IS_ERR(hdr))
-               return PTR_ERR(hdr);
+       if (!hdr)
+               return -EMSGSIZE;
 
        if (nla_put_u32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex))
                goto nla_put_failure;
@@ -2251,13 +2252,11 @@ static void __team_options_change_check(struct team *team)
 }
 
 /* rtnl lock is held */
-static void __team_port_change_check(struct team_port *port, bool linkup)
+
+static void __team_port_change_send(struct team_port *port, bool linkup)
 {
        int err;
 
-       if (!port->removed && port->state.linkup == linkup)
-               return;
-
        port->changed = true;
        port->state.linkup = linkup;
        team_refresh_port_linkup(port);
@@ -2282,6 +2281,23 @@ send_event:
 
 }
 
+static void __team_port_change_check(struct team_port *port, bool linkup)
+{
+       if (port->state.linkup != linkup)
+               __team_port_change_send(port, linkup);
+}
+
+static void __team_port_change_port_added(struct team_port *port, bool linkup)
+{
+       __team_port_change_send(port, linkup);
+}
+
+static void __team_port_change_port_removed(struct team_port *port)
+{
+       port->removed = true;
+       __team_port_change_send(port, false);
+}
+
 static void team_port_change_check(struct team_port *port, bool linkup)
 {
        struct team *team = port->team;
index f5ab6e6..376143e 100644 (file)
@@ -1253,6 +1253,7 @@ static struct usb_driver smsc75xx_driver = {
        .probe          = usbnet_probe,
        .suspend        = usbnet_suspend,
        .resume         = usbnet_resume,
+       .reset_resume   = usbnet_resume,
        .disconnect     = usbnet_disconnect,
        .disable_hub_initiated_lpm = 1,
 };
index 3876c7e..7a28d21 100644 (file)
@@ -34,8 +34,8 @@ config B43_BCMA
 config B43_BCMA_EXTRA
        bool "Hardware support that overlaps with the brcmsmac driver"
        depends on B43_BCMA
-       default n if BRCMSMAC || BRCMSMAC_MODULE
-       default y
+       default n if BRCMSMAC
+       default y
 
 config B43_SSB
        bool
index 1e86ea2..dbeebef 100644 (file)
@@ -1442,6 +1442,7 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
        return err;
 
 err_free_irq:
+       trans_pcie->irq_requested = false;
        free_irq(trans_pcie->irq, trans);
 error:
        iwl_free_isr_ict(trans);
index 44febfd..8a7b864 100644 (file)
@@ -315,7 +315,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
        u16 box_reg = 0, box_extreg = 0;
        u8 u1b_tmp;
        bool isfw_read = false;
-       bool bwrite_sucess = false;
+       bool bwrite_success = false;
        u8 wait_h2c_limmit = 100;
        u8 wait_writeh2c_limmit = 100;
        u8 boxcontent[4], boxextcontent[2];
@@ -354,7 +354,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
                }
        }
 
-       while (!bwrite_sucess) {
+       while (!bwrite_success) {
                wait_writeh2c_limmit--;
                if (wait_writeh2c_limmit == 0) {
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
@@ -491,7 +491,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
                        break;
                }
 
-               bwrite_sucess = true;
+               bwrite_success = true;
 
                rtlhal->last_hmeboxnum = boxnum + 1;
                if (rtlhal->last_hmeboxnum == 4)
index 895ae6c..eb22dcc 100644 (file)
@@ -365,7 +365,7 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
        u8 u1b_tmp;
        bool isfw_read = false;
        u8 buf_index = 0;
-       bool bwrite_sucess = false;
+       bool bwrite_success = false;
        u8 wait_h2c_limmit = 100;
        u8 wait_writeh2c_limmit = 100;
        u8 boxcontent[4], boxextcontent[2];
@@ -408,7 +408,7 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
                        break;
                }
        }
-       while (!bwrite_sucess) {
+       while (!bwrite_success) {
                wait_writeh2c_limmit--;
                if (wait_writeh2c_limmit == 0) {
                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
@@ -515,7 +515,7 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
                                 "switch case not processed\n");
                        break;
                }
-               bwrite_sucess = true;
+               bwrite_success = true;
                rtlhal->last_hmeboxnum = boxnum + 1;
                if (rtlhal->last_hmeboxnum == 4)
                        rtlhal->last_hmeboxnum = 0;
diff --git a/drivers/pci/.gitignore b/drivers/pci/.gitignore
deleted file mode 100644 (file)
index f297ca8..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-classlist.h
-devlist.h
-gen-devlist
-
index 4e932cc..e98a5e7 100644 (file)
@@ -33,9 +33,8 @@ config REGULATOR_DUMMY
        help
          If this option is enabled then when a regulator lookup fails
          and the board has not specified that it has provided full
-         constraints then the regulator core will provide an always
-         enabled dummy regulator will be provided, allowing consumer
-         drivers to continue.
+         constraints the regulator core will provide an always
+         enabled dummy regulator, allowing consumer drivers to continue.
 
          A warning will be generated when this substitution is done.
 
@@ -50,11 +49,11 @@ config REGULATOR_VIRTUAL_CONSUMER
        tristate "Virtual regulator consumer support"
        help
          This driver provides a virtual consumer for the voltage and
-          current regulator API which provides sysfs controls for
-          configuring the supplies requested.  This is mainly useful
-          for test purposes.
+         current regulator API which provides sysfs controls for
+         configuring the supplies requested.  This is mainly useful
+         for test purposes.
 
-          If unsure, say no.
+         If unsure, say no.
 
 config REGULATOR_USERSPACE_CONSUMER
        tristate "Userspace regulator consumer support"
@@ -63,7 +62,7 @@ config REGULATOR_USERSPACE_CONSUMER
          from user space. Userspace consumer driver provides ability to
          control power supplies for such devices.
 
-          If unsure, say no.
+         If unsure, say no.
 
 config REGULATOR_GPIO
        tristate "GPIO regulator support"
@@ -110,6 +109,17 @@ config REGULATOR_DA9052
          This driver supports the voltage regulators of DA9052-BC and
          DA9053-AA/Bx PMIC.
 
+config REGULATOR_FAN53555
+       tristate "Fairchild FAN53555 Regulator"
+       depends on I2C
+       select REGMAP_I2C
+       help
+         This driver supports Fairchild FAN53555 Digitally Programmable
+         TinyBuck Regulator. The FAN53555 is a step-down switching voltage
+         regulator that delivers a digitally programmable output from an
+         input voltage supply of 2.5V to 5.5V. The output voltage is
+         programmed through an I2C interface.
+
 config REGULATOR_ANATOP
        tristate "Freescale i.MX on-chip ANATOP LDO regulators"
        depends on MFD_ANATOP
@@ -172,6 +182,14 @@ config REGULATOR_MAX8660
          This driver controls a Maxim 8660/8661 voltage output
          regulator via I2C bus.
 
+config REGULATOR_MAX8907
+       tristate "Maxim 8907 voltage regulator"
+       depends on MFD_MAX8907
+       help
+         This driver controls a Maxim 8907 voltage output regulator
+         via I2C bus. The provided regulator is suitable for Tegra
+         chip to control Step-Down DC-DC and LDOs.
+
 config REGULATOR_MAX8925
        tristate "Maxim MAX8925 Power Management IC"
        depends on MFD_MAX8925
@@ -247,7 +265,7 @@ config REGULATOR_LP8788
 
 config REGULATOR_PCF50633
        tristate "NXP PCF50633 regulator driver"
-        depends on MFD_PCF50633
+       depends on MFD_PCF50633
        help
         Say Y here to support the voltage regulators and convertors
         on PCF50633
@@ -416,7 +434,7 @@ config REGULATOR_WM8350
        depends on MFD_WM8350
        help
          This driver provides support for the voltage and current regulators
-          of the WM8350 AudioPlus PMIC.
+         of the WM8350 AudioPlus PMIC.
 
 config REGULATOR_WM8400
        tristate "Wolfson Microelectronics WM8400 AudioPlus PMIC"
index 3342615..e431eed 100644 (file)
@@ -20,6 +20,7 @@ obj-$(CONFIG_REGULATOR_DA903X)        += da903x.o
 obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o
 obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o
 obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o
+obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o
 obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o
 obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o
 obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
@@ -30,6 +31,7 @@ obj-$(CONFIG_REGULATOR_LP8788) += lp8788-ldo.o
 obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
 obj-$(CONFIG_REGULATOR_MAX8649)        += max8649.o
 obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o
+obj-$(CONFIG_REGULATOR_MAX8907) += max8907-regulator.o
 obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o
 obj-$(CONFIG_REGULATOR_MAX8952) += max8952.o
 obj-$(CONFIG_REGULATOR_MAX8997) += max8997.o
index 6f45bfd..167c93f 100644 (file)
@@ -162,7 +162,7 @@ static struct aat2870_regulator *aat2870_get_regulator(int id)
 static int aat2870_regulator_probe(struct platform_device *pdev)
 {
        struct aat2870_regulator *ri;
-       struct regulator_config config = { 0 };
+       struct regulator_config config = { };
        struct regulator_dev *rdev;
 
        ri = aat2870_get_regulator(pdev->id);
index c151fd5..65ad2b3 100644 (file)
@@ -347,17 +347,11 @@ static int ab3100_get_voltage_regulator_external(struct regulator_dev *reg)
        return abreg->plfdata->external_voltage;
 }
 
-static int ab3100_get_fixed_voltage_regulator(struct regulator_dev *reg)
-{
-       return reg->desc->min_uV;
-}
-
 static struct regulator_ops regulator_ops_fixed = {
        .list_voltage = regulator_list_voltage_linear,
        .enable      = ab3100_enable_regulator,
        .disable     = ab3100_disable_regulator,
        .is_enabled  = ab3100_is_enabled_regulator,
-       .get_voltage = ab3100_get_fixed_voltage_regulator,
 };
 
 static struct regulator_ops regulator_ops_variable = {
index 10f2f4d..e3d1d06 100644 (file)
@@ -37,6 +37,7 @@
  * @voltage_bank: bank to control regulator voltage
  * @voltage_reg: register to control regulator voltage
  * @voltage_mask: mask to control regulator voltage
+ * @voltage_shift: shift to control regulator voltage
  * @delay: startup/set voltage delay in us
  */
 struct ab8500_regulator_info {
@@ -50,6 +51,7 @@ struct ab8500_regulator_info {
        u8 voltage_bank;
        u8 voltage_reg;
        u8 voltage_mask;
+       u8 voltage_shift;
        unsigned int delay;
 };
 
@@ -195,17 +197,14 @@ static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev)
        }
 
        dev_vdbg(rdev_get_dev(rdev),
-               "%s-get_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
-               " 0x%x\n",
-               info->desc.name, info->voltage_bank, info->voltage_reg,
-               info->voltage_mask, regval);
+               "%s-get_voltage (bank, reg, mask, shift, value): "
+               "0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
+               info->desc.name, info->voltage_bank,
+               info->voltage_reg, info->voltage_mask,
+               info->voltage_shift, regval);
 
-       /* vintcore has a different layout */
        val = regval & info->voltage_mask;
-       if (info->desc.id == AB8500_LDO_INTCORE)
-               return val >> 0x3;
-       else
-               return val;
+       return val >> info->voltage_shift;
 }
 
 static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
@@ -221,7 +220,7 @@ static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
        }
 
        /* set the registers for the request */
-       regval = (u8)selector;
+       regval = (u8)selector << info->voltage_shift;
        ret = abx500_mask_and_set_register_interruptible(info->dev,
                        info->voltage_bank, info->voltage_reg,
                        info->voltage_mask, regval);
@@ -238,13 +237,6 @@ static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
        return ret;
 }
 
-static int ab8500_regulator_enable_time(struct regulator_dev *rdev)
-{
-       struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
-
-       return info->delay;
-}
-
 static int ab8500_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
                                             unsigned int old_sel,
                                             unsigned int new_sel)
@@ -261,22 +253,14 @@ static struct regulator_ops ab8500_regulator_ops = {
        .get_voltage_sel = ab8500_regulator_get_voltage_sel,
        .set_voltage_sel = ab8500_regulator_set_voltage_sel,
        .list_voltage   = regulator_list_voltage_table,
-       .enable_time    = ab8500_regulator_enable_time,
        .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
 };
 
-static int ab8500_fixed_get_voltage(struct regulator_dev *rdev)
-{
-       return rdev->desc->min_uV;
-}
-
 static struct regulator_ops ab8500_regulator_fixed_ops = {
        .enable         = ab8500_regulator_enable,
        .disable        = ab8500_regulator_disable,
        .is_enabled     = ab8500_regulator_is_enabled,
-       .get_voltage    = ab8500_fixed_get_voltage,
        .list_voltage   = regulator_list_voltage_linear,
-       .enable_time    = ab8500_regulator_enable_time,
 };
 
 static struct ab8500_regulator_info
@@ -358,6 +342,7 @@ static struct ab8500_regulator_info
                .voltage_bank           = 0x03,
                .voltage_reg            = 0x80,
                .voltage_mask           = 0x38,
+               .voltage_shift          = 3,
        },
 
        /*
@@ -374,6 +359,7 @@ static struct ab8500_regulator_info
                        .owner          = THIS_MODULE,
                        .n_voltages     = 1,
                        .min_uV         = 2000000,
+                       .enable_time    = 10000,
                },
                .delay                  = 10000,
                .update_bank            = 0x03,
index c8f95c0..d184aa3 100644 (file)
@@ -39,6 +39,8 @@ static struct regulator_ops arizona_ldo1_ops = {
        .map_voltage = regulator_map_voltage_linear,
        .get_voltage_sel = regulator_get_voltage_sel_regmap,
        .set_voltage_sel = regulator_set_voltage_sel_regmap,
+       .get_bypass = regulator_get_bypass_regmap,
+       .set_bypass = regulator_set_bypass_regmap,
 };
 
 static const struct regulator_desc arizona_ldo1 = {
@@ -49,9 +51,11 @@ static const struct regulator_desc arizona_ldo1 = {
 
        .vsel_reg = ARIZONA_LDO1_CONTROL_1,
        .vsel_mask = ARIZONA_LDO1_VSEL_MASK,
+       .bypass_reg = ARIZONA_LDO1_CONTROL_1,
+       .bypass_mask = ARIZONA_LDO1_BYPASS,
        .min_uV = 900000,
        .uV_step = 50000,
-       .n_voltages = 7,
+       .n_voltages = 6,
 
        .owner = THIS_MODULE,
 };
index 450a069..d9b1f82 100644 (file)
@@ -82,6 +82,9 @@ static struct regulator_ops arizona_micsupp_ops = {
 
        .get_voltage_sel = regulator_get_voltage_sel_regmap,
        .set_voltage_sel = regulator_set_voltage_sel_regmap,
+
+       .get_bypass = regulator_get_bypass_regmap,
+       .set_bypass = regulator_set_bypass_regmap,
 };
 
 static const struct regulator_desc arizona_micsupp = {
@@ -95,6 +98,8 @@ static const struct regulator_desc arizona_micsupp = {
        .vsel_mask = ARIZONA_LDO2_VSEL_MASK,
        .enable_reg = ARIZONA_MIC_CHARGE_PUMP_1,
        .enable_mask = ARIZONA_CPMIC_ENA,
+       .bypass_reg = ARIZONA_MIC_CHARGE_PUMP_1,
+       .bypass_mask = ARIZONA_CPMIC_BYPASS,
 
        .owner = THIS_MODULE,
 };
index 4838531..2e0352d 100644 (file)
@@ -77,6 +77,7 @@ struct regulator {
        struct device *dev;
        struct list_head list;
        unsigned int always_on:1;
+       unsigned int bypass:1;
        int uA_load;
        int min_uV;
        int max_uV;
@@ -394,6 +395,9 @@ static ssize_t regulator_status_show(struct device *dev,
        case REGULATOR_STATUS_STANDBY:
                label = "standby";
                break;
+       case REGULATOR_STATUS_BYPASS:
+               label = "bypass";
+               break;
        case REGULATOR_STATUS_UNDEFINED:
                label = "undefined";
                break;
@@ -585,6 +589,27 @@ static ssize_t regulator_suspend_standby_state_show(struct device *dev,
 static DEVICE_ATTR(suspend_standby_state, 0444,
                regulator_suspend_standby_state_show, NULL);
 
+static ssize_t regulator_bypass_show(struct device *dev,
+                                    struct device_attribute *attr, char *buf)
+{
+       struct regulator_dev *rdev = dev_get_drvdata(dev);
+       const char *report;
+       bool bypass;
+       int ret;
+
+       ret = rdev->desc->ops->get_bypass(rdev, &bypass);
+
+       if (ret != 0)
+               report = "unknown";
+       else if (bypass)
+               report = "enabled";
+       else
+               report = "disabled";
+
+       return sprintf(buf, "%s\n", report);
+}
+static DEVICE_ATTR(bypass, 0444,
+                  regulator_bypass_show, NULL);
 
 /*
  * These are the only attributes are present for all regulators.
@@ -778,6 +803,9 @@ static void print_constraints(struct regulator_dev *rdev)
        if (constraints->valid_modes_mask & REGULATOR_MODE_STANDBY)
                count += sprintf(buf + count, "standby");
 
+       if (!count)
+               sprintf(buf, "no parameters");
+
        rdev_info(rdev, "%s\n", buf);
 
        if ((constraints->min_uV != constraints->max_uV) &&
@@ -974,6 +1002,7 @@ static int set_supply(struct regulator_dev *rdev,
                err = -ENOMEM;
                return err;
        }
+       supply_rdev->open_count++;
 
        return 0;
 }
@@ -1720,6 +1749,9 @@ int regulator_disable_deferred(struct regulator *regulator, int ms)
        if (regulator->always_on)
                return 0;
 
+       if (!ms)
+               return regulator_disable(regulator);
+
        mutex_lock(&rdev->mutex);
        rdev->deferred_disables++;
        mutex_unlock(&rdev->mutex);
@@ -2178,9 +2210,12 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
                }
        }
 
-       if (ret == 0 && best_val >= 0)
+       if (ret == 0 && best_val >= 0) {
+               unsigned long data = best_val;
+
                _notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE,
-                                    (void *)best_val);
+                                    (void *)data);
+       }
 
        trace_regulator_set_voltage_complete(rdev_get_name(rdev), best_val);
 
@@ -2291,8 +2326,8 @@ int regulator_set_voltage_time(struct regulator *regulator,
 EXPORT_SYMBOL_GPL(regulator_set_voltage_time);
 
 /**
- *regulator_set_voltage_time_sel - get raise/fall time
- * @regulator: regulator source
+ * regulator_set_voltage_time_sel - get raise/fall time
+ * @rdev: regulator source device
  * @old_selector: selector for starting voltage
  * @new_selector: selector for target voltage
  *
@@ -2388,6 +2423,8 @@ static int _regulator_get_voltage(struct regulator_dev *rdev)
                ret = rdev->desc->ops->list_voltage(rdev, sel);
        } else if (rdev->desc->ops->get_voltage) {
                ret = rdev->desc->ops->get_voltage(rdev);
+       } else if (rdev->desc->ops->list_voltage) {
+               ret = rdev->desc->ops->list_voltage(rdev, 0);
        } else {
                return -EINVAL;
        }
@@ -2674,6 +2711,100 @@ out:
 EXPORT_SYMBOL_GPL(regulator_set_optimum_mode);
 
 /**
+ * regulator_set_bypass_regmap - Default set_bypass() using regmap
+ *
+ * @rdev: device to operate on.
+ * @enable: state to set.
+ */
+int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable)
+{
+       unsigned int val;
+
+       if (enable)
+               val = rdev->desc->bypass_mask;
+       else
+               val = 0;
+
+       return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg,
+                                 rdev->desc->bypass_mask, val);
+}
+EXPORT_SYMBOL_GPL(regulator_set_bypass_regmap);
+
+/**
+ * regulator_get_bypass_regmap - Default get_bypass() using regmap
+ *
+ * @rdev: device to operate on.
+ * @enable: current state.
+ */
+int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable)
+{
+       unsigned int val;
+       int ret;
+
+       ret = regmap_read(rdev->regmap, rdev->desc->bypass_reg, &val);
+       if (ret != 0)
+               return ret;
+
+       *enable = val & rdev->desc->bypass_mask;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap);
+
+/**
+ * regulator_allow_bypass - allow the regulator to go into bypass mode
+ *
+ * @regulator: Regulator to configure
+ * @allow: enable or disable bypass mode
+ *
+ * Allow the regulator to go into bypass mode if all other consumers
+ * for the regulator also enable bypass mode and the machine
+ * constraints allow this.  Bypass mode means that the regulator is
+ * simply passing the input directly to the output with no regulation.
+ */
+int regulator_allow_bypass(struct regulator *regulator, bool enable)
+{
+       struct regulator_dev *rdev = regulator->rdev;
+       int ret = 0;
+
+       if (!rdev->desc->ops->set_bypass)
+               return 0;
+
+       if (rdev->constraints &&
+           !(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_BYPASS))
+               return 0;
+
+       mutex_lock(&rdev->mutex);
+
+       if (enable && !regulator->bypass) {
+               rdev->bypass_count++;
+
+               if (rdev->bypass_count == rdev->open_count) {
+                       ret = rdev->desc->ops->set_bypass(rdev, enable);
+                       if (ret != 0)
+                               rdev->bypass_count--;
+               }
+
+       } else if (!enable && regulator->bypass) {
+               rdev->bypass_count--;
+
+               if (rdev->bypass_count != rdev->open_count) {
+                       ret = rdev->desc->ops->set_bypass(rdev, enable);
+                       if (ret != 0)
+                               rdev->bypass_count++;
+               }
+       }
+
+       if (ret == 0)
+               regulator->bypass = enable;
+
+       mutex_unlock(&rdev->mutex);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(regulator_allow_bypass);
+
+/**
  * regulator_register_notifier - register regulator event notifier
  * @regulator: regulator source
  * @nb: notifier block
@@ -3011,7 +3142,8 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
 
        /* some attributes need specific methods to be displayed */
        if ((ops->get_voltage && ops->get_voltage(rdev) >= 0) ||
-           (ops->get_voltage_sel && ops->get_voltage_sel(rdev) >= 0)) {
+           (ops->get_voltage_sel && ops->get_voltage_sel(rdev) >= 0) ||
+           (ops->list_voltage && ops->list_voltage(rdev, 0) >= 0)) {
                status = device_create_file(dev, &dev_attr_microvolts);
                if (status < 0)
                        return status;
@@ -3036,6 +3168,11 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
                if (status < 0)
                        return status;
        }
+       if (ops->get_bypass) {
+               status = device_create_file(dev, &dev_attr_bypass);
+               if (status < 0)
+                       return status;
+       }
 
        /* some attributes are type-specific */
        if (rdev->desc->type == REGULATOR_CURRENT) {
@@ -3124,6 +3261,8 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)
                           &rdev->use_count);
        debugfs_create_u32("open_count", 0444, rdev->debugfs,
                           &rdev->open_count);
+       debugfs_create_u32("bypass_count", 0444, rdev->debugfs,
+                          &rdev->bypass_count);
 }
 
 /**
@@ -3189,8 +3328,10 @@ regulator_register(const struct regulator_desc *regulator_desc,
        rdev->desc = regulator_desc;
        if (config->regmap)
                rdev->regmap = config->regmap;
-       else
+       else if (dev_get_regmap(dev, NULL))
                rdev->regmap = dev_get_regmap(dev, NULL);
+       else if (dev->parent)
+               rdev->regmap = dev_get_regmap(dev->parent, NULL);
        INIT_LIST_HEAD(&rdev->consumer_list);
        INIT_LIST_HEAD(&rdev->list);
        BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier);
index 903299c..27355b1 100644 (file)
@@ -133,8 +133,8 @@ static int da9052_dcdc_set_current_limit(struct regulator_dev *rdev, int min_uA,
            max_uA < da9052_current_limits[row][DA9052_MIN_UA])
                return -EINVAL;
 
-       for (i = 0; i < DA9052_CURRENT_RANGE; i++) {
-               if (min_uA <= da9052_current_limits[row][i]) {
+       for (i = DA9052_CURRENT_RANGE - 1; i >= 0; i--) {
+               if (da9052_current_limits[row][i] <= max_uA) {
                        reg_val = i;
                        break;
                }
index 86f655c..03a1d7c 100644 (file)
@@ -30,7 +30,7 @@ static struct regulator_init_data dummy_initdata;
 static struct regulator_ops dummy_ops;
 
 static struct regulator_desc dummy_desc = {
-       .name = "dummy",
+       .name = "regulator-dummy",
        .id = -1,
        .type = REGULATOR_VOLTAGE,
        .owner = THIS_MODULE,
diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c
new file mode 100644 (file)
index 0000000..339f4d7
--- /dev/null
@@ -0,0 +1,322 @@
+/*
+ * FAN53555 Fairchild Digitally Programmable TinyBuck Regulator Driver.
+ *
+ * Supported Part Numbers:
+ * FAN53555UC00X/01X/03X/04X/05X
+ *
+ * Copyright (c) 2012 Marvell Technology Ltd.
+ * Yunfan Zhang <yfzhang@marvell.com>
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/module.h>
+#include <linux/param.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/regmap.h>
+#include <linux/regulator/fan53555.h>
+
+/* Voltage setting */
+#define FAN53555_VSEL0         0x00
+#define FAN53555_VSEL1         0x01
+/* Control register */
+#define FAN53555_CONTROL       0x02
+/* IC Type */
+#define FAN53555_ID1           0x03
+/* IC mask version */
+#define FAN53555_ID2           0x04
+/* Monitor register */
+#define FAN53555_MONITOR       0x05
+
+/* VSEL bit definitions */
+#define VSEL_BUCK_EN   (1 << 7)
+#define VSEL_MODE              (1 << 6)
+#define VSEL_NSEL_MASK 0x3F
+/* Chip ID and Verison */
+#define DIE_ID         0x0F    /* ID1 */
+#define DIE_REV                0x0F    /* ID2 */
+/* Control bit definitions */
+#define CTL_OUTPUT_DISCHG      (1 << 7)
+#define CTL_SLEW_MASK          (0x7 << 4)
+#define CTL_SLEW_SHIFT         4
+#define CTL_RESET                      (1 << 2)
+
+#define FAN53555_NVOLTAGES     64      /* Numbers of voltages */
+
+/* IC Type */
+enum {
+       FAN53555_CHIP_ID_00 = 0,
+       FAN53555_CHIP_ID_01,
+       FAN53555_CHIP_ID_02,
+       FAN53555_CHIP_ID_03,
+       FAN53555_CHIP_ID_04,
+       FAN53555_CHIP_ID_05,
+};
+
+struct fan53555_device_info {
+       struct regmap *regmap;
+       struct device *dev;
+       struct regulator_desc desc;
+       struct regulator_dev *rdev;
+       struct regulator_init_data *regulator;
+       /* IC Type and Rev */
+       int chip_id;
+       int chip_rev;
+       /* Voltage setting register */
+       unsigned int vol_reg;
+       unsigned int sleep_reg;
+       /* Voltage range and step(linear) */
+       unsigned int vsel_min;
+       unsigned int vsel_step;
+       /* Voltage slew rate limiting */
+       unsigned int slew_rate;
+       /* Sleep voltage cache */
+       unsigned int sleep_vol_cache;
+};
+
+static int fan53555_set_suspend_voltage(struct regulator_dev *rdev, int uV)
+{
+       struct fan53555_device_info *di = rdev_get_drvdata(rdev);
+       int ret;
+
+       if (di->sleep_vol_cache == uV)
+               return 0;
+       ret = regulator_map_voltage_linear(rdev, uV, uV);
+       if (ret < 0)
+               return -EINVAL;
+       ret = regmap_update_bits(di->regmap, di->sleep_reg,
+                                       VSEL_NSEL_MASK, ret);
+       if (ret < 0)
+               return -EINVAL;
+       /* Cache the sleep voltage setting.
+        * Might not be the real voltage which is rounded */
+       di->sleep_vol_cache = uV;
+
+       return 0;
+}
+
+static int fan53555_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+       struct fan53555_device_info *di = rdev_get_drvdata(rdev);
+
+       switch (mode) {
+       case REGULATOR_MODE_FAST:
+               regmap_update_bits(di->regmap, di->vol_reg,
+                               VSEL_MODE, VSEL_MODE);
+               break;
+       case REGULATOR_MODE_NORMAL:
+               regmap_update_bits(di->regmap, di->vol_reg, VSEL_MODE, 0);
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static unsigned int fan53555_get_mode(struct regulator_dev *rdev)
+{
+       struct fan53555_device_info *di = rdev_get_drvdata(rdev);
+       unsigned int val;
+       int ret = 0;
+
+       ret = regmap_read(di->regmap, di->vol_reg, &val);
+       if (ret < 0)
+               return ret;
+       if (val & VSEL_MODE)
+               return REGULATOR_MODE_FAST;
+       else
+               return REGULATOR_MODE_NORMAL;
+}
+
+static struct regulator_ops fan53555_regulator_ops = {
+       .set_voltage_sel = regulator_set_voltage_sel_regmap,
+       .get_voltage_sel = regulator_get_voltage_sel_regmap,
+       .map_voltage = regulator_map_voltage_linear,
+       .list_voltage = regulator_list_voltage_linear,
+       .set_suspend_voltage = fan53555_set_suspend_voltage,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
+       .is_enabled = regulator_is_enabled_regmap,
+       .set_mode = fan53555_set_mode,
+       .get_mode = fan53555_get_mode,
+};
+
+/* For 00,01,03,05 options:
+ * VOUT = 0.60V + NSELx * 10mV, from 0.60 to 1.23V.
+ * For 04 option:
+ * VOUT = 0.603V + NSELx * 12.826mV, from 0.603 to 1.411V.
+ * */
+static int fan53555_device_setup(struct fan53555_device_info *di,
+                               struct fan53555_platform_data *pdata)
+{
+       unsigned int reg, data, mask;
+
+       /* Setup voltage control register */
+       switch (pdata->sleep_vsel_id) {
+       case FAN53555_VSEL_ID_0:
+               di->sleep_reg = FAN53555_VSEL0;
+               di->vol_reg = FAN53555_VSEL1;
+               break;
+       case FAN53555_VSEL_ID_1:
+               di->sleep_reg = FAN53555_VSEL1;
+               di->vol_reg = FAN53555_VSEL0;
+               break;
+       default:
+               dev_err(di->dev, "Invalid VSEL ID!\n");
+               return -EINVAL;
+       }
+       /* Init voltage range and step */
+       switch (di->chip_id) {
+       case FAN53555_CHIP_ID_00:
+       case FAN53555_CHIP_ID_01:
+       case FAN53555_CHIP_ID_03:
+       case FAN53555_CHIP_ID_05:
+               di->vsel_min = 600000;
+               di->vsel_step = 10000;
+               break;
+       case FAN53555_CHIP_ID_04:
+               di->vsel_min = 603000;
+               di->vsel_step = 12826;
+               break;
+       default:
+               dev_err(di->dev,
+                       "Chip ID[%d]\n not supported!\n", di->chip_id);
+               return -EINVAL;
+       }
+       /* Init slew rate */
+       if (pdata->slew_rate & 0x7)
+               di->slew_rate = pdata->slew_rate;
+       else
+               di->slew_rate = FAN53555_SLEW_RATE_64MV;
+       reg = FAN53555_CONTROL;
+       data = di->slew_rate << CTL_SLEW_SHIFT;
+       mask = CTL_SLEW_MASK;
+       return regmap_update_bits(di->regmap, reg, mask, data);
+}
+
+static int fan53555_regulator_register(struct fan53555_device_info *di,
+                       struct regulator_config *config)
+{
+       struct regulator_desc *rdesc = &di->desc;
+
+       rdesc->name = "fan53555-reg";
+       rdesc->ops = &fan53555_regulator_ops;
+       rdesc->type = REGULATOR_VOLTAGE;
+       rdesc->n_voltages = FAN53555_NVOLTAGES;
+       rdesc->enable_reg = di->vol_reg;
+       rdesc->enable_mask = VSEL_BUCK_EN;
+       rdesc->min_uV = di->vsel_min;
+       rdesc->uV_step = di->vsel_step;
+       rdesc->vsel_reg = di->vol_reg;
+       rdesc->vsel_mask = VSEL_NSEL_MASK;
+       rdesc->owner = THIS_MODULE;
+
+       di->rdev = regulator_register(&di->desc, config);
+       if (IS_ERR(di->rdev))
+               return PTR_ERR(di->rdev);
+       return 0;
+
+}
+
+static struct regmap_config fan53555_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+};
+
+static int __devinit fan53555_regulator_probe(struct i2c_client *client,
+                               const struct i2c_device_id *id)
+{
+       struct fan53555_device_info *di;
+       struct fan53555_platform_data *pdata;
+       struct regulator_config config = { };
+       unsigned int val;
+       int ret;
+
+       pdata = client->dev.platform_data;
+       if (!pdata || !pdata->regulator) {
+               dev_err(&client->dev, "Platform data not found!\n");
+               return -ENODEV;
+       }
+
+       di = devm_kzalloc(&client->dev, sizeof(struct fan53555_device_info),
+                                       GFP_KERNEL);
+       if (!di) {
+               dev_err(&client->dev, "Failed to allocate device info data!\n");
+               return -ENOMEM;
+       }
+       di->regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config);
+       if (IS_ERR(di->regmap)) {
+               dev_err(&client->dev, "Failed to allocate regmap!\n");
+               return PTR_ERR(di->regmap);
+       }
+       di->dev = &client->dev;
+       di->regulator = pdata->regulator;
+       i2c_set_clientdata(client, di);
+       /* Get chip ID */
+       ret = regmap_read(di->regmap, FAN53555_ID1, &val);
+       if (ret < 0) {
+               dev_err(&client->dev, "Failed to get chip ID!\n");
+               return -ENODEV;
+       }
+       di->chip_id = val & DIE_ID;
+       /* Get chip revision */
+       ret = regmap_read(di->regmap, FAN53555_ID2, &val);
+       if (ret < 0) {
+               dev_err(&client->dev, "Failed to get chip Rev!\n");
+               return -ENODEV;
+       }
+       di->chip_rev = val & DIE_REV;
+       dev_info(&client->dev, "FAN53555 Option[%d] Rev[%d] Detected!\n",
+                               di->chip_id, di->chip_rev);
+       /* Device init */
+       ret = fan53555_device_setup(di, pdata);
+       if (ret < 0) {
+               dev_err(&client->dev, "Failed to setup device!\n");
+               return ret;
+       }
+       /* Register regulator */
+       config.dev = di->dev;
+       config.init_data = di->regulator;
+       config.regmap = di->regmap;
+       config.driver_data = di;
+       ret = fan53555_regulator_register(di, &config);
+       if (ret < 0)
+               dev_err(&client->dev, "Failed to register regulator!\n");
+       return ret;
+
+}
+
+static int __devexit fan53555_regulator_remove(struct i2c_client *client)
+{
+       struct fan53555_device_info *di = i2c_get_clientdata(client);
+
+       regulator_unregister(di->rdev);
+       return 0;
+}
+
+static const struct i2c_device_id fan53555_id[] = {
+       {"fan53555", -1},
+       { },
+};
+
+static struct i2c_driver fan53555_regulator_driver = {
+       .driver = {
+               .name = "fan53555-regulator",
+       },
+       .probe = fan53555_regulator_probe,
+       .remove = __devexit_p(fan53555_regulator_remove),
+       .id_table = fan53555_id,
+};
+
+module_i2c_driver(fan53555_regulator_driver);
+
+MODULE_AUTHOR("Yunfan Zhang <yfzhang@marvell.com>");
+MODULE_DESCRIPTION("FAN53555 regulator driver");
+MODULE_LICENSE("GPL v2");
index 1d145a0..d8ecf49 100644 (file)
@@ -73,13 +73,7 @@ static struct regulator_ops isl_core_ops = {
        .map_voltage    = regulator_map_voltage_linear,
 };
 
-static int isl6271a_get_fixed_voltage(struct regulator_dev *dev)
-{
-       return dev->desc->min_uV;
-}
-
 static struct regulator_ops isl_fixed_ops = {
-       .get_voltage    = isl6271a_get_fixed_voltage,
        .list_voltage   = regulator_list_voltage_linear,
 };
 
index 212c38e..708f4b6 100644 (file)
 #define EXTERN_DVS_USED                        0
 #define MAX_DELAY                      6
 
+/* Default DVS Mode */
+#define LP8720_DEFAULT_DVS             0
+#define LP8725_DEFAULT_DVS             BIT(2)
+
 /* dump registers in regmap-debugfs */
 #define MAX_REGISTERS                  0x0F
 
@@ -269,9 +273,9 @@ static int lp872x_regulator_enable_time(struct regulator_dev *rdev)
        return val > MAX_DELAY ? 0 : val * time_step_us;
 }
 
-static void lp872x_set_dvs(struct lp872x *lp, int gpio)
+static void lp872x_set_dvs(struct lp872x *lp, enum lp872x_dvs_sel dvs_sel,
+                       int gpio)
 {
-       enum lp872x_dvs_sel dvs_sel = lp->pdata->dvs->vsel;
        enum lp872x_dvs_state state;
 
        state = dvs_sel == SEL_V1 ? DVS_HIGH : DVS_LOW;
@@ -339,10 +343,10 @@ static int lp872x_buck_set_voltage_sel(struct regulator_dev *rdev,
        struct lp872x *lp = rdev_get_drvdata(rdev);
        enum lp872x_regulator_id buck = rdev_get_id(rdev);
        u8 addr, mask = LP872X_VOUT_M;
-       struct lp872x_dvs *dvs = lp->pdata->dvs;
+       struct lp872x_dvs *dvs = lp->pdata ? lp->pdata->dvs : NULL;
 
        if (dvs && gpio_is_valid(dvs->gpio))
-               lp872x_set_dvs(lp, dvs->gpio);
+               lp872x_set_dvs(lp, dvs->vsel, dvs->gpio);
 
        addr = lp872x_select_buck_vout_addr(lp, buck);
        if (!lp872x_is_valid_buck_addr(addr))
@@ -374,8 +378,8 @@ static int lp8725_buck_set_current_limit(struct regulator_dev *rdev,
 {
        struct lp872x *lp = rdev_get_drvdata(rdev);
        enum lp872x_regulator_id buck = rdev_get_id(rdev);
-       int i, max = ARRAY_SIZE(lp8725_buck_uA);
-       u8 addr, val;
+       int i;
+       u8 addr;
 
        switch (buck) {
        case LP8725_ID_BUCK1:
@@ -388,17 +392,15 @@ static int lp8725_buck_set_current_limit(struct regulator_dev *rdev,
                return -EINVAL;
        }
 
-       for (i = 0 ; i < max ; i++)
+       for (i = ARRAY_SIZE(lp8725_buck_uA) - 1 ; i >= 0; i--) {
                if (lp8725_buck_uA[i] >= min_uA &&
                        lp8725_buck_uA[i] <= max_uA)
-                       break;
-
-       if (i == max)
-               return -EINVAL;
-
-       val = i << LP8725_BUCK_CL_S;
+                       return lp872x_update_bits(lp, addr,
+                                                 LP8725_BUCK_CL_M,
+                                                 i << LP8725_BUCK_CL_S);
+       }
 
-       return lp872x_update_bits(lp, addr, LP8725_BUCK_CL_M, val);
+       return -EINVAL;
 }
 
 static int lp8725_buck_get_current_limit(struct regulator_dev *rdev)
@@ -727,39 +729,16 @@ static struct regulator_desc lp8725_regulator_desc[] = {
        },
 };
 
-static int lp872x_check_dvs_validity(struct lp872x *lp)
-{
-       struct lp872x_dvs *dvs = lp->pdata->dvs;
-       u8 val = 0;
-       int ret;
-
-       ret = lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val);
-       if (ret)
-               return ret;
-
-       ret = 0;
-       if (lp->chipid == LP8720) {
-               if (val & LP8720_EXT_DVS_M)
-                       ret = dvs ? 0 : -EINVAL;
-       } else {
-               if ((val & LP8725_DVS1_M) == EXTERN_DVS_USED)
-                       ret = dvs ? 0 : -EINVAL;
-       }
-
-       return ret;
-}
-
 static int lp872x_init_dvs(struct lp872x *lp)
 {
        int ret, gpio;
-       struct lp872x_dvs *dvs = lp->pdata->dvs;
+       struct lp872x_dvs *dvs = lp->pdata ? lp->pdata->dvs : NULL;
        enum lp872x_dvs_state pinstate;
+       u8 mask[] = { LP8720_EXT_DVS_M, LP8725_DVS1_M | LP8725_DVS2_M };
+       u8 default_dvs_mode[] = { LP8720_DEFAULT_DVS, LP8725_DEFAULT_DVS };
 
-       ret = lp872x_check_dvs_validity(lp);
-       if (ret) {
-               dev_warn(lp->dev, "invalid dvs data: %d\n", ret);
-               return ret;
-       }
+       if (!dvs)
+               goto set_default_dvs_mode;
 
        gpio = dvs->gpio;
        if (!gpio_is_valid(gpio)) {
@@ -778,6 +757,10 @@ static int lp872x_init_dvs(struct lp872x *lp)
        lp->dvs_gpio = gpio;
 
        return 0;
+
+set_default_dvs_mode:
+       return lp872x_update_bits(lp, LP872X_GENERAL_CFG, mask[lp->chipid],
+                               default_dvs_mode[lp->chipid]);
 }
 
 static int lp872x_config(struct lp872x *lp)
@@ -785,24 +768,29 @@ static int lp872x_config(struct lp872x *lp)
        struct lp872x_platform_data *pdata = lp->pdata;
        int ret;
 
-       if (!pdata->update_config)
-               return 0;
+       if (!pdata || !pdata->update_config)
+               goto init_dvs;
 
        ret = lp872x_write_byte(lp, LP872X_GENERAL_CFG, pdata->general_config);
        if (ret)
                return ret;
 
+init_dvs:
        return lp872x_init_dvs(lp);
 }
 
 static struct regulator_init_data
 *lp872x_find_regulator_init_data(int id, struct lp872x *lp)
 {
+       struct lp872x_platform_data *pdata = lp->pdata;
        int i;
 
+       if (!pdata)
+               return NULL;
+
        for (i = 0; i < lp->num_regulators; i++) {
-               if (lp->pdata->regulator_data[i].id == id)
-                       return lp->pdata->regulator_data[i].init_data;
+               if (pdata->regulator_data[i].id == id)
+                       return pdata->regulator_data[i].init_data;
        }
 
        return NULL;
@@ -863,18 +851,12 @@ static const struct regmap_config lp872x_regmap_config = {
 static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
 {
        struct lp872x *lp;
-       struct lp872x_platform_data *pdata = cl->dev.platform_data;
        int ret, size, num_regulators;
        const int lp872x_num_regulators[] = {
                [LP8720] = LP8720_NUM_REGULATORS,
                [LP8725] = LP8725_NUM_REGULATORS,
        };
 
-       if (!pdata) {
-               dev_err(&cl->dev, "no platform data\n");
-               return -EINVAL;
-       }
-
        lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL);
        if (!lp)
                goto err_mem;
@@ -894,7 +876,7 @@ static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
        }
 
        lp->dev = &cl->dev;
-       lp->pdata = pdata;
+       lp->pdata = cl->dev.platform_data;
        lp->chipid = id->driver_data;
        lp->num_regulators = num_regulators;
        i2c_set_clientdata(cl, lp);
index 6356e82..ba3e0aa 100644 (file)
@@ -69,6 +69,9 @@
 #define PIN_HIGH                       1
 #define ENABLE_TIME_USEC               32
 
+#define BUCK_FPWM_MASK(x)              (1 << (x))
+#define BUCK_FPWM_SHIFT(x)             (x)
+
 enum lp8788_dvs_state {
        DVS_LOW  = GPIOF_OUT_INIT_LOW,
        DVS_HIGH = GPIOF_OUT_INIT_HIGH,
@@ -86,15 +89,9 @@ enum lp8788_buck_id {
        BUCK4,
 };
 
-struct lp8788_pwm_map {
-       u8 mask;
-       u8 shift;
-};
-
 struct lp8788_buck {
        struct lp8788 *lp;
        struct regulator_dev *regulator;
-       struct lp8788_pwm_map *pmap;
        void *dvs;
 };
 
@@ -106,29 +103,6 @@ static const int lp8788_buck_vtbl[] = {
        1950000, 2000000,
 };
 
-/* buck pwm mode selection : used for set/get_mode in regulator ops
- * @forced pwm : fast mode
- * @auto pwm   : normal mode
- */
-static struct lp8788_pwm_map buck_pmap[] = {
-       [BUCK1] = {
-               .mask = LP8788_FPWM_BUCK1_M,
-               .shift = LP8788_FPWM_BUCK1_S,
-       },
-       [BUCK2] = {
-               .mask = LP8788_FPWM_BUCK2_M,
-               .shift = LP8788_FPWM_BUCK2_S,
-       },
-       [BUCK3] = {
-               .mask = LP8788_FPWM_BUCK3_M,
-               .shift = LP8788_FPWM_BUCK3_S,
-       },
-       [BUCK4] = {
-               .mask = LP8788_FPWM_BUCK4_M,
-               .shift = LP8788_FPWM_BUCK4_S,
-       },
-};
-
 static const u8 buck1_vout_addr[] = {
        LP8788_BUCK1_VOUT0, LP8788_BUCK1_VOUT1,
        LP8788_BUCK1_VOUT2, LP8788_BUCK1_VOUT3,
@@ -347,41 +321,37 @@ static int lp8788_buck_enable_time(struct regulator_dev *rdev)
 static int lp8788_buck_set_mode(struct regulator_dev *rdev, unsigned int mode)
 {
        struct lp8788_buck *buck = rdev_get_drvdata(rdev);
-       struct lp8788_pwm_map *pmap = buck->pmap;
-       u8 val;
-
-       if (!pmap)
-               return -EINVAL;
+       enum lp8788_buck_id id = rdev_get_id(rdev);
+       u8 mask, val;
 
+       mask = BUCK_FPWM_MASK(id);
        switch (mode) {
        case REGULATOR_MODE_FAST:
-               val = LP8788_FORCE_PWM << pmap->shift;
+               val = LP8788_FORCE_PWM << BUCK_FPWM_SHIFT(id);
                break;
        case REGULATOR_MODE_NORMAL:
-               val = LP8788_AUTO_PWM << pmap->shift;
+               val = LP8788_AUTO_PWM << BUCK_FPWM_SHIFT(id);
                break;
        default:
                return -EINVAL;
        }
 
-       return lp8788_update_bits(buck->lp, LP8788_BUCK_PWM, pmap->mask, val);
+       return lp8788_update_bits(buck->lp, LP8788_BUCK_PWM, mask, val);
 }
 
 static unsigned int lp8788_buck_get_mode(struct regulator_dev *rdev)
 {
        struct lp8788_buck *buck = rdev_get_drvdata(rdev);
-       struct lp8788_pwm_map *pmap = buck->pmap;
+       enum lp8788_buck_id id = rdev_get_id(rdev);
        u8 val;
        int ret;
 
-       if (!pmap)
-               return -EINVAL;
-
        ret = lp8788_read_byte(buck->lp, LP8788_BUCK_PWM, &val);
        if (ret)
                return ret;
 
-       return val & pmap->mask ? REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
+       return val & BUCK_FPWM_MASK(id) ?
+                               REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
 }
 
 static struct regulator_ops lp8788_buck12_ops = {
@@ -459,27 +429,6 @@ static struct regulator_desc lp8788_buck_desc[] = {
        },
 };
 
-static int lp8788_set_default_dvs_ctrl_mode(struct lp8788 *lp,
-                                       enum lp8788_buck_id id)
-{
-       u8 mask, val;
-
-       switch (id) {
-       case BUCK1:
-               mask = LP8788_BUCK1_DVS_SEL_M;
-               val  = LP8788_BUCK1_DVS_I2C;
-               break;
-       case BUCK2:
-               mask = LP8788_BUCK2_DVS_SEL_M;
-               val  = LP8788_BUCK2_DVS_I2C;
-               break;
-       default:
-               return 0;
-       }
-
-       return lp8788_update_bits(lp, LP8788_BUCK_DVS_SEL, mask, val);
-}
-
 static int _gpio_request(struct lp8788_buck *buck, int gpio, char *name)
 {
        struct device *dev = buck->lp->dev;
@@ -530,6 +479,7 @@ static int lp8788_init_dvs(struct lp8788_buck *buck, enum lp8788_buck_id id)
        struct lp8788_platform_data *pdata = buck->lp->pdata;
        u8 mask[] = { LP8788_BUCK1_DVS_SEL_M, LP8788_BUCK2_DVS_SEL_M };
        u8 val[]  = { LP8788_BUCK1_DVS_PIN, LP8788_BUCK2_DVS_PIN };
+       u8 default_dvs_mode[] = { LP8788_BUCK1_DVS_I2C, LP8788_BUCK2_DVS_I2C };
 
        /* no dvs for buck3, 4 */
        if (id == BUCK3 || id == BUCK4)
@@ -550,7 +500,8 @@ static int lp8788_init_dvs(struct lp8788_buck *buck, enum lp8788_buck_id id)
                                val[id]);
 
 set_default_dvs_mode:
-       return lp8788_set_default_dvs_ctrl_mode(buck->lp, id);
+       return lp8788_update_bits(buck->lp, LP8788_BUCK_DVS_SEL, mask[id],
+                                 default_dvs_mode[id]);
 }
 
 static __devinit int lp8788_buck_probe(struct platform_device *pdev)
@@ -567,7 +518,6 @@ static __devinit int lp8788_buck_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        buck->lp = lp;
-       buck->pmap = &buck_pmap[id];
 
        ret = lp8788_init_dvs(buck, id);
        if (ret)
index d2122e4..6796eeb 100644 (file)
@@ -496,6 +496,7 @@ static struct regulator_desc lp8788_dldo_desc[] = {
                .name = "dldo12",
                .id = DLDO12,
                .ops = &lp8788_ldo_voltage_fixed_ops,
+               .n_voltages = 1,
                .type = REGULATOR_VOLTAGE,
                .owner = THIS_MODULE,
                .enable_reg = LP8788_EN_LDO_B,
@@ -521,6 +522,7 @@ static struct regulator_desc lp8788_aldo_desc[] = {
                .name = "aldo2",
                .id = ALDO2,
                .ops = &lp8788_ldo_voltage_fixed_ops,
+               .n_voltages = 1,
                .type = REGULATOR_VOLTAGE,
                .owner = THIS_MODULE,
                .enable_reg = LP8788_EN_LDO_B,
@@ -530,6 +532,7 @@ static struct regulator_desc lp8788_aldo_desc[] = {
                .name = "aldo3",
                .id = ALDO3,
                .ops = &lp8788_ldo_voltage_fixed_ops,
+               .n_voltages = 1,
                .type = REGULATOR_VOLTAGE,
                .owner = THIS_MODULE,
                .enable_reg = LP8788_EN_LDO_B,
@@ -539,6 +542,7 @@ static struct regulator_desc lp8788_aldo_desc[] = {
                .name = "aldo4",
                .id = ALDO4,
                .ops = &lp8788_ldo_voltage_fixed_ops,
+               .n_voltages = 1,
                .type = REGULATOR_VOLTAGE,
                .owner = THIS_MODULE,
                .enable_reg = LP8788_EN_LDO_B,
@@ -548,6 +552,7 @@ static struct regulator_desc lp8788_aldo_desc[] = {
                .name = "aldo5",
                .id = ALDO5,
                .ops = &lp8788_ldo_voltage_fixed_ops,
+               .n_voltages = 1,
                .type = REGULATOR_VOLTAGE,
                .owner = THIS_MODULE,
                .enable_reg = LP8788_EN_LDO_C,
@@ -583,6 +588,7 @@ static struct regulator_desc lp8788_aldo_desc[] = {
                .name = "aldo8",
                .id = ALDO8,
                .ops = &lp8788_ldo_voltage_fixed_ops,
+               .n_voltages = 1,
                .type = REGULATOR_VOLTAGE,
                .owner = THIS_MODULE,
                .enable_reg = LP8788_EN_LDO_C,
@@ -592,6 +598,7 @@ static struct regulator_desc lp8788_aldo_desc[] = {
                .name = "aldo9",
                .id = ALDO9,
                .ops = &lp8788_ldo_voltage_fixed_ops,
+               .n_voltages = 1,
                .type = REGULATOR_VOLTAGE,
                .owner = THIS_MODULE,
                .enable_reg = LP8788_EN_LDO_C,
@@ -601,6 +608,7 @@ static struct regulator_desc lp8788_aldo_desc[] = {
                .name = "aldo10",
                .id = ALDO10,
                .ops = &lp8788_ldo_voltage_fixed_ops,
+               .n_voltages = 1,
                .type = REGULATOR_VOLTAGE,
                .owner = THIS_MODULE,
                .enable_reg = LP8788_EN_LDO_C,
index c564af6..2a67d08 100644 (file)
@@ -66,7 +66,7 @@ enum max77686_ramp_rate {
 };
 
 struct max77686_data {
-       struct regulator_dev **rdev;
+       struct regulator_dev *rdev[MAX77686_REGULATORS];
 };
 
 static int max77686_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
@@ -265,6 +265,7 @@ static int max77686_pmic_dt_parse_pdata(struct max77686_dev *iodev,
                rmatch.of_node = NULL;
                of_regulator_match(iodev->dev, regulators_np, &rmatch, 1);
                rdata[i].initdata = rmatch.init_data;
+               rdata[i].of_node = rmatch.of_node;
        }
 
        pdata->regulators = rdata;
@@ -283,10 +284,8 @@ static __devinit int max77686_pmic_probe(struct platform_device *pdev)
 {
        struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent);
        struct max77686_platform_data *pdata = dev_get_platdata(iodev->dev);
-       struct regulator_dev **rdev;
        struct max77686_data *max77686;
-       int i,  size;
-       int ret = 0;
+       int i, ret = 0;
        struct regulator_config config = { };
 
        dev_dbg(&pdev->dev, "%s\n", __func__);
@@ -313,45 +312,38 @@ static __devinit int max77686_pmic_probe(struct platform_device *pdev)
        if (!max77686)
                return -ENOMEM;
 
-       size = sizeof(struct regulator_dev *) * MAX77686_REGULATORS;
-       max77686->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
-       if (!max77686->rdev)
-               return -ENOMEM;
-
-       rdev = max77686->rdev;
        config.dev = &pdev->dev;
        config.regmap = iodev->regmap;
        platform_set_drvdata(pdev, max77686);
 
        for (i = 0; i < MAX77686_REGULATORS; i++) {
                config.init_data = pdata->regulators[i].initdata;
+               config.of_node = pdata->regulators[i].of_node;
 
-               rdev[i] = regulator_register(&regulators[i], &config);
-               if (IS_ERR(rdev[i])) {
-                       ret = PTR_ERR(rdev[i]);
+               max77686->rdev[i] = regulator_register(&regulators[i], &config);
+               if (IS_ERR(max77686->rdev[i])) {
+                       ret = PTR_ERR(max77686->rdev[i]);
                        dev_err(&pdev->dev,
                                "regulator init failed for %d\n", i);
-                               rdev[i] = NULL;
-                               goto err;
+                       max77686->rdev[i] = NULL;
+                       goto err;
                }
        }
 
        return 0;
 err:
        while (--i >= 0)
-               regulator_unregister(rdev[i]);
+               regulator_unregister(max77686->rdev[i]);
        return ret;
 }
 
 static int __devexit max77686_pmic_remove(struct platform_device *pdev)
 {
        struct max77686_data *max77686 = platform_get_drvdata(pdev);
-       struct regulator_dev **rdev = max77686->rdev;
        int i;
 
        for (i = 0; i < MAX77686_REGULATORS; i++)
-               if (rdev[i])
-                       regulator_unregister(rdev[i]);
+               regulator_unregister(max77686->rdev[i]);
 
        return 0;
 }
diff --git a/drivers/regulator/max8907-regulator.c b/drivers/regulator/max8907-regulator.c
new file mode 100644 (file)
index 0000000..af76075
--- /dev/null
@@ -0,0 +1,408 @@
+/*
+ * max8907-regulator.c -- support regulators in max8907
+ *
+ * Copyright (C) 2010 Gyungoh Yoo <jack.yoo@maxim-ic.com>
+ * Copyright (C) 2010-2012, NVIDIA CORPORATION. All rights reserved.
+ *
+ * Portions based on drivers/regulator/tps65910-regulator.c,
+ *     Copyright 2010 Texas Instruments Inc.
+ *     Author: Graeme Gregory <gg@slimlogic.co.uk>
+ *     Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/max8907.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#define MAX8907_II2RR_VERSION_MASK     0xF0
+#define MAX8907_II2RR_VERSION_REV_A    0x00
+#define MAX8907_II2RR_VERSION_REV_B    0x10
+#define MAX8907_II2RR_VERSION_REV_C    0x30
+
+struct max8907_regulator {
+       struct regulator_desc desc[MAX8907_NUM_REGULATORS];
+       struct regulator_dev *rdev[MAX8907_NUM_REGULATORS];
+};
+
+#define REG_MBATT() \
+       [MAX8907_MBATT] = { \
+               .name = "MBATT", \
+               .supply_name = "mbatt", \
+               .id = MAX8907_MBATT, \
+               .ops = &max8907_mbatt_ops, \
+               .type = REGULATOR_VOLTAGE, \
+               .owner = THIS_MODULE, \
+       }
+
+#define REG_LDO(ids, supply, base, min, max, step) \
+       [MAX8907_##ids] = { \
+               .name = #ids, \
+               .supply_name = supply, \
+               .id = MAX8907_##ids, \
+               .n_voltages = ((max) - (min)) / (step) + 1, \
+  &nbs