浏览代码

Merge tag 'mfd-for-linus-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd

Pull MFD updates from Lee Jones:
 "Changes to existing drivers:
   - Use of managed resources - omap, twl4030, ti_am335x_tscadc
   - Advanced error handling - omap
   - Rework clk management - omap
   - Device Tree (re-)work - tc3589x, pm8921, da9055, sec
   - IRC management overhaul and !BROKEN - pm8921
   - Convert to regmap - ssbi, pm8921
   - Use simple power-management ops - ucb1x00
   - Include file clean-up - adp5520, cs5535, janz, lpc_ich,
      - lpc_sch, max14577, mcp-sa11x0, pcf50633-adc, rc5t583,
      	rdc321x-southbridge, retu, smsc-ece1099, ti-ssp, ti_am335x_tscadc,
	tps65912, vexpress-config, wm8350, ywm8350
   - Various bug fixes across the subsystem
      - NULL/invalid pointer dereference prevention
      - Resource leak mitigation,
      - Variable used initialised
      - Staticise various containers
      - Enforce return value checks

  New drivers/supported devices:
   - Add support for s2mps14 and s2mpa01 to sec
   - Add support for da9063 (v5) to da9063
   - Add support for atom-c2000 to gpio-ich
   - Add support for come-{mbt10,cbt6,chl6} to kempld
   - Add support for da9053 to da9052
   - Add support for itco-wdt (v3) and baytrail to lpc_ich
   - Add new drivers for tps65218, rtsx_usb, bcm590xx

  (Re-)moved drivers:
   - twl4030 ==> drivers/iio
   - ti-ssp  ==> /dev/null"

* tag 'mfd-for-linus-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (103 commits)
  mfd: wm5110: Correct default for HEADPHONE_DETECT_1
  mfd: arizona: Correct small errors in the DT binding documentation
  mfd: arizona: Mark DSP clocking register as volatile
  mfd: devicetree: bindings: Add pm8xxx RTC description
  mfd: kempld-core: Fix potential hang-up during boot
  mfd: sec-core: Fix uninitialized 'regmap_rtc' on S2MPA01
  mfd: tps65910: Fix regmap_irq_chip_data leak on mfd_add_devices fail
  mfd: tps65910: Fix possible invalid pointer dereference on regmap_add_irq_chip fail
  mfd: sec-core: Fix I2C dummy device resource leak on probe failure
  mfd: sec-core: Add of_compatible strings for clock MFD cells
  mfd: Remove obsolete ti-ssp driver
  Documentation: mfd: s2mps11: Describe S5M8767 and S2MPS14 clocks
  mfd: bcm590xx: Fix type argument for module device table
  mfd: lpc_ich: Add support for Intel Bay Trail SoC
  mfd: lpc_ich: Add support for NM10 GPIO
  mfd: lpc_ich: Change Avoton to iTCO v3
  watchdog: iTCO_wdt: Add support for v3 silicon
  mfd: lpc_ich: Add support for iTCO v3
  mfd: lpc_ich: Remove lpc_ich_cfg struct use
  mfd: lpc_ich: Only configure watchdog or GPIO when present
  ...
Linus Torvalds 11 年之前
父节点
当前提交
e5744abb2f
共有 92 个文件被更改,包括 3958 次插入1588 次删除
  1. 24 0
      Documentation/devicetree/bindings/iio/adc/twl4030-madc.txt
  2. 13 10
      Documentation/devicetree/bindings/mfd/arizona.txt
  3. 37 0
      Documentation/devicetree/bindings/mfd/bcm590xx.txt
  4. 72 0
      Documentation/devicetree/bindings/mfd/da9055.txt
  5. 23 0
      Documentation/devicetree/bindings/mfd/omap-usb-host.txt
  6. 10 0
      Documentation/devicetree/bindings/mfd/omap-usb-tll.txt
  7. 96 0
      Documentation/devicetree/bindings/mfd/qcom,pm8xxx.txt
  8. 15 9
      Documentation/devicetree/bindings/mfd/s2mps11.txt
  9. 6 0
      arch/arm/boot/dts/omap4.dtsi
  10. 6 0
      arch/arm/boot/dts/omap5.dtsi
  11. 0 4
      arch/arm/mach-omap2/cclock3xxx_data.c
  12. 0 6
      arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
  13. 0 4
      drivers/clk/ti/clk-3xxx.c
  14. 25 1
      drivers/gpio/gpio-ich.c
  15. 10 0
      drivers/iio/adc/Kconfig
  16. 1 0
      drivers/iio/adc/Makefile
  17. 199 122
      drivers/iio/adc/twl4030-madc.c
  18. 1 2
      drivers/mfd/88pm800.c
  19. 6 0
      drivers/mfd/88pm860x-core.c
  20. 54 44
      drivers/mfd/Kconfig
  21. 3 3
      drivers/mfd/Makefile
  22. 0 1
      drivers/mfd/adp5520.c
  23. 1 0
      drivers/mfd/as3722.c
  24. 93 0
      drivers/mfd/bcm590xx.c
  25. 0 1
      drivers/mfd/cs5535-mfd.c
  26. 3 0
      drivers/mfd/da9052-core.c
  27. 4 1
      drivers/mfd/da9052-i2c.c
  28. 1 0
      drivers/mfd/da9052-spi.c
  29. 8 0
      drivers/mfd/da9055-i2c.c
  30. 14 11
      drivers/mfd/da9063-core.c
  31. 0 1
      drivers/mfd/janz-cmodio.c
  32. 29 2
      drivers/mfd/kempld-core.c
  33. 108 43
      drivers/mfd/lpc_ich.c
  34. 0 1
      drivers/mfd/lpc_sch.c
  35. 5 1
      drivers/mfd/max14577.c
  36. 4 0
      drivers/mfd/max77686.c
  37. 11 1
      drivers/mfd/max77693.c
  38. 9 0
      drivers/mfd/max8925-i2c.c
  39. 18 0
      drivers/mfd/max8997.c
  40. 4 0
      drivers/mfd/max8998.c
  41. 5 0
      drivers/mfd/mc13xxx-spi.c
  42. 0 1
      drivers/mfd/mcp-sa11x0.c
  43. 90 99
      drivers/mfd/omap-usb-host.c
  44. 1 1
      drivers/mfd/omap-usb-tll.c
  45. 0 1
      drivers/mfd/pcf50633-adc.c
  46. 365 54
      drivers/mfd/pm8921-core.c
  47. 0 371
      drivers/mfd/pm8xxx-irq.c
  48. 0 1
      drivers/mfd/rc5t583-irq.c
  49. 0 1
      drivers/mfd/rdc321x-southbridge.c
  50. 0 1
      drivers/mfd/retu-mfd.c
  51. 760 0
      drivers/mfd/rtsx_usb.c
  52. 14 3
      drivers/mfd/sec-core.c
  53. 0 1
      drivers/mfd/smsc-ece1099.c
  54. 1 1
      drivers/mfd/stmpe.c
  55. 7 1
      drivers/mfd/stw481x.c
  56. 1 8
      drivers/mfd/syscon.c
  57. 59 25
      drivers/mfd/tc3589x.c
  58. 0 465
      drivers/mfd/ti-ssp.c
  59. 4 20
      drivers/mfd/ti_am335x_tscadc.c
  60. 1 1
      drivers/mfd/timberdale.c
  61. 282 0
      drivers/mfd/tps65218.c
  62. 4 1
      drivers/mfd/tps65910.c
  63. 0 1
      drivers/mfd/tps65912-core.c
  64. 0 1
      drivers/mfd/tps65912-irq.c
  65. 5 5
      drivers/mfd/twl-core.c
  66. 0 1
      drivers/mfd/twl4030-irq.c
  67. 0 1
      drivers/mfd/twl6030-irq.c
  68. 5 1
      drivers/mfd/twl6040.c
  69. 1 3
      drivers/mfd/ucb1x00-core.c
  70. 1 2
      drivers/mfd/vexpress-config.c
  71. 1 1
      drivers/mfd/vexpress-sysreg.c
  72. 36 0
      drivers/mfd/wm5102-tables.c
  73. 173 1
      drivers/mfd/wm5110-tables.c
  74. 0 1
      drivers/mfd/wm8350-core.c
  75. 0 1
      drivers/mfd/wm8350-irq.c
  76. 5 17
      drivers/mfd/wm8400-core.c
  77. 82 55
      drivers/watchdog/iTCO_wdt.c
  78. 12 0
      include/linux/i2c/twl.h
  79. 1 1
      include/linux/i2c/twl4030-madc.h
  80. 84 0
      include/linux/mfd/arizona/registers.h
  81. 31 0
      include/linux/mfd/bcm590xx.h
  82. 1 0
      include/linux/mfd/da9052/da9052.h
  83. 5 1
      include/linux/mfd/da9063/core.h
  84. 62 58
      include/linux/mfd/da9063/registers.h
  85. 14 11
      include/linux/mfd/lpc_ich.h
  86. 0 8
      include/linux/mfd/max14577-private.h
  87. 0 5
      include/linux/mfd/max14577.h
  88. 0 59
      include/linux/mfd/pm8xxx/irq.h
  89. 0 30
      include/linux/mfd/pm8xxx/pm8921.h
  90. 628 0
      include/linux/mfd/rtsx_usb.h
  91. 284 0
      include/linux/mfd/tps65218.h
  92. 20 0
      include/linux/ssbi.h

+ 24 - 0
Documentation/devicetree/bindings/iio/adc/twl4030-madc.txt

@@ -0,0 +1,24 @@
+* TWL4030 Monitoring Analog to Digital Converter (MADC)
+
+The MADC subsystem in the TWL4030 consists of a 10-bit ADC
+combined with a 16-input analog multiplexer.
+
+Required properties:
+  - compatible: Should contain "ti,twl4030-madc".
+  - interrupts: IRQ line for the MADC submodule.
+  - #io-channel-cells: Should be set to <1>.
+
+Optional properties:
+  - ti,system-uses-second-madc-irq: boolean, set if the second madc irq register
+				    should be used, which is intended to be used
+				    by Co-Processors (e.g. a modem).
+
+Example:
+
+&twl {
+	madc {
+		compatible = "ti,twl4030-madc";
+		interrupts = <3>;
+		#io-channel-cells = <1>;
+	};
+};

+ 13 - 10
Documentation/devicetree/bindings/mfd/arizona.txt

@@ -5,9 +5,10 @@ of analogue I/O.
 
 
 Required properties:
 Required properties:
 
 
-  - compatible : one of the following chip-specific strings:
-	"wlf,wm5102"
-	"wlf,wm5110"
+  - compatible : One of the following chip-specific strings:
+        "wlf,wm5102"
+        "wlf,wm5110"
+        "wlf,wm8997"
   - reg : I2C slave address when connected using I2C, chip select number when
   - reg : I2C slave address when connected using I2C, chip select number when
     using SPI.
     using SPI.
 
 
@@ -25,8 +26,9 @@ Required properties:
   - #gpio-cells : Must be 2. The first cell is the pin number and the
   - #gpio-cells : Must be 2. The first cell is the pin number and the
     second cell is used to specify optional parameters (currently unused).
     second cell is used to specify optional parameters (currently unused).
 
 
-  - AVDD1-supply, DBVDD1-supply, DBVDD2-supply, DBVDD3-supply, CPVDD-supply,
-    SPKVDDL-supply, SPKVDDR-supply : power supplies for the device, as covered
+  - AVDD-supply, DBVDD1-supply, DBVDD2-supply, DBVDD3-supply (wm5102, wm5110),
+    CPVDD-supply, SPKVDDL-supply (wm5102, wm5110), SPKVDDR-supply (wm5102,
+    wm5110), SPKVDD-supply (wm8997) : Power supplies for the device, as covered
     in Documentation/devicetree/bindings/regulator/regulator.txt
     in Documentation/devicetree/bindings/regulator/regulator.txt
 
 
 Optional properties:
 Optional properties:
@@ -46,6 +48,7 @@ codec: wm5102@1a {
 	compatible = "wlf,wm5102";
 	compatible = "wlf,wm5102";
 	reg = <0x1a>;
 	reg = <0x1a>;
 	interrupts = <347>;
 	interrupts = <347>;
+	interrupt-controller;
 	#interrupt-cells = <2>;
 	#interrupt-cells = <2>;
         interrupt-parent = <&gic>;
         interrupt-parent = <&gic>;
 
 
@@ -53,10 +56,10 @@ codec: wm5102@1a {
 	#gpio-cells = <2>;
 	#gpio-cells = <2>;
 
 
 	wlf,gpio-defaults = <
 	wlf,gpio-defaults = <
-		0x00000000, /* AIF1TXLRCLK */
-		0xffffffff,
-		0xffffffff,
-		0xffffffff,
-		0xffffffff,
+		0x00000000 /* AIF1TXLRCLK */
+		0xffffffff
+		0xffffffff
+		0xffffffff
+		0xffffffff
 	>;
 	>;
 };
 };

+ 37 - 0
Documentation/devicetree/bindings/mfd/bcm590xx.txt

@@ -0,0 +1,37 @@
+-------------------------------
+BCM590xx Power Management Units
+-------------------------------
+
+Required properties:
+- compatible: "brcm,bcm59056"
+- reg: I2C slave address
+- interrupts: interrupt for the PMU. Generic interrupt client node bindings
+  are described in interrupt-controller/interrupts.txt
+
+------------------
+Voltage Regulators
+------------------
+
+Optional child nodes:
+- regulators: container node for regulators following the generic
+  regulator binding in regulator/regulator.txt
+
+  The valid regulator node names for BCM59056 are:
+  	rfldo, camldo1, camldo2, simldo1, simldo2, sdldo, sdxldo,
+	mmcldo1, mmcldo2, audldo, micldo, usbldo, vibldo,
+	csr, iosr1, iosr2, msr, sdsr1, sdsr2, vsr
+
+Example:
+	pmu: bcm59056@8 {
+		compatible = "brcm,bcm59056";
+		reg = <0x08>;
+		interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
+		regulators {
+			rfldo_reg: rfldo {
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <3300000>;
+			};
+
+			...
+		};
+	};

+ 72 - 0
Documentation/devicetree/bindings/mfd/da9055.txt

@@ -0,0 +1,72 @@
+* Dialog DA9055 Power Management Integrated Circuit (PMIC)
+
+DA9055 consists of a large and varied group of sub-devices (I2C Only):
+
+Device			 Supply Names	 Description
+------			 ------------	 -----------
+da9055-gpio		:		: GPIOs
+da9055-regulator	:		: Regulators
+da9055-onkey		:		: On key
+da9055-rtc		:		: RTC
+da9055-hwmon		:		: ADC
+da9055-watchdog		:		: Watchdog
+
+The CODEC device in DA9055 has a separate, configurable I2C address and so
+is instantiated separately from the PMIC.
+
+For details on accompanying CODEC I2C device, see the following:
+Documentation/devicetree/bindings/sound/da9055.txt
+
+======
+
+Required properties:
+- compatible : Should be "dlg,da9055-pmic"
+- reg: Specifies the I2C slave address (defaults to 0x5a but can be modified)
+- interrupt-parent: Specifies the phandle of the interrupt controller to which
+  the IRQs from da9055 are delivered to.
+- interrupts: IRQ line info for da9055 chip.
+- interrupt-controller: da9055 has internal IRQs (has own IRQ domain).
+- #interrupt-cells: Should be 1, is the local IRQ number for da9055.
+
+Sub-nodes:
+- regulators : Contain the regulator nodes. The DA9055 regulators are
+  bound using their names as listed below:
+
+    buck1     : regulator BUCK1
+    buck2     : regulator BUCK2
+    ldo1      : regulator LDO1
+    ldo2      : regulator LDO2
+    ldo3      : regulator LDO3
+    ldo4      : regulator LDO4
+    ldo5      : regulator LDO5
+    ldo6      : regulator LDO6
+
+  The bindings details of individual regulator device can be found in:
+  Documentation/devicetree/bindings/regulator/regulator.txt
+
+
+Example:
+
+	pmic: da9055-pmic@5a {
+		compatible = "dlg,da9055-pmic";
+		reg = <0x5a>;
+		interrupt-parent = <&intc>;
+		interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-controller;
+		#interrupt-cells = <1>;
+
+		regulators {
+			buck1: BUCK1 {
+				regulator-min-microvolt = <725000>;
+				regulator-max-microvolt = <2075000>;
+			};
+			buck2: BUCK2 {
+				regulator-min-microvolt = <925000>;
+				regulator-max-microvolt = <2500000>;
+			};
+			ldo1: LDO1 {
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <3300000>;
+			};
+		};
+	};

+ 23 - 0
Documentation/devicetree/bindings/mfd/omap-usb-host.txt

@@ -32,6 +32,29 @@ Optional properties:
 - single-ulpi-bypass: Must be present if the controller contains a single
 - single-ulpi-bypass: Must be present if the controller contains a single
   ULPI bypass control bit. e.g. OMAP3 silicon <= ES2.1
   ULPI bypass control bit. e.g. OMAP3 silicon <= ES2.1
 
 
+- clocks: a list of phandles and clock-specifier pairs, one for each entry in
+  clock-names.
+
+- clock-names: should include:
+  For OMAP3
+  * "usbhost_120m_fck" - 120MHz Functional clock.
+
+  For OMAP4+
+  * "refclk_60m_int" - 60MHz internal reference clock for UTMI clock mux
+  * "refclk_60m_ext_p1" - 60MHz external ref. clock for Port 1's UTMI clock mux.
+  * "refclk_60m_ext_p2" - 60MHz external ref. clock for Port 2's UTMI clock mux
+  * "utmi_p1_gfclk" - Port 1 UTMI clock mux.
+  * "utmi_p2_gfclk" - Port 2 UTMI clock mux.
+  * "usb_host_hs_utmi_p1_clk" - Port 1 UTMI clock gate.
+  * "usb_host_hs_utmi_p2_clk" - Port 2 UTMI clock gate.
+  * "usb_host_hs_utmi_p3_clk" - Port 3 UTMI clock gate.
+  * "usb_host_hs_hsic480m_p1_clk" - Port 1 480MHz HSIC clock gate.
+  * "usb_host_hs_hsic480m_p2_clk" - Port 2 480MHz HSIC clock gate.
+  * "usb_host_hs_hsic480m_p3_clk" - Port 3 480MHz HSIC clock gate.
+  * "usb_host_hs_hsic60m_p1_clk" - Port 1 60MHz HSIC clock gate.
+  * "usb_host_hs_hsic60m_p2_clk" - Port 2 60MHz HSIC clock gate.
+  * "usb_host_hs_hsic60m_p3_clk" - Port 3 60MHz HSIC clock gate.
+
 Required properties if child node exists:
 Required properties if child node exists:
 
 
 - #address-cells: Must be 1
 - #address-cells: Must be 1

+ 10 - 0
Documentation/devicetree/bindings/mfd/omap-usb-tll.txt

@@ -7,6 +7,16 @@ Required properties:
 - interrupts : should contain the TLL module's interrupt
 - interrupts : should contain the TLL module's interrupt
 - ti,hwmod : must contain "usb_tll_hs"
 - ti,hwmod : must contain "usb_tll_hs"
 
 
+Optional properties:
+
+- clocks: a list of phandles and clock-specifier pairs, one for each entry in
+  clock-names.
+
+- clock-names: should include:
+  * "usb_tll_hs_usb_ch0_clk" - USB TLL channel 0 clock
+  * "usb_tll_hs_usb_ch1_clk" - USB TLL channel 1 clock
+  * "usb_tll_hs_usb_ch2_clk" - USB TLL channel 2 clock
+
 Example:
 Example:
 
 
 	usbhstll: usbhstll@4a062000 {
 	usbhstll: usbhstll@4a062000 {

+ 96 - 0
Documentation/devicetree/bindings/mfd/qcom,pm8xxx.txt

@@ -0,0 +1,96 @@
+Qualcomm PM8xxx PMIC multi-function devices
+
+The PM8xxx family of Power Management ICs are used to provide regulated
+voltages and other various functionality to Qualcomm SoCs.
+
+= PROPERTIES
+
+- compatible:
+	Usage: required
+	Value type: <string>
+	Definition: must be one of:
+		    "qcom,pm8058"
+		    "qcom,pm8921"
+
+- #address-cells:
+	Usage: required
+	Value type: <u32>
+	Definition: must be 1
+
+- #size-cells:
+	Usage: required
+	Value type: <u32>
+	Definition: must be 0
+
+- interrupts:
+	Usage: required
+	Value type: <prop-encoded-array>
+	Definition: specifies the interrupt that indicates a subdevice
+		    has generated an interrupt (summary interrupt). The
+		    format of the specifier is defined by the binding document
+		    describing the node's interrupt parent.
+
+- #interrupt-cells:
+	Usage: required
+	Value type : <u32>
+	Definition: must be 2. Specifies the number of cells needed to encode
+		    an interrupt source. The 1st cell contains the interrupt
+		    number. The 2nd cell is the trigger type and level flags
+		    encoded as follows:
+
+			1 = low-to-high edge triggered
+			2 = high-to-low edge triggered
+			4 = active high level-sensitive
+			8 = active low level-sensitive
+
+- interrupt-controller:
+	Usage: required
+	Value type: <empty>
+	Definition: identifies this node as an interrupt controller
+
+= SUBCOMPONENTS
+
+The PMIC contains multiple independent functions, each described in a subnode.
+The below bindings specify the set of valid subnodes.
+
+== Real-Time Clock
+
+- compatible:
+	Usage: required
+	Value type: <string>
+	Definition: must be one of:
+		    "qcom,pm8058-rtc"
+		    "qcom,pm8921-rtc"
+
+- reg:
+	Usage: required
+	Value type: <prop-encoded-array>
+	Definition: single entry specifying the base address of the RTC registers
+
+- interrupts:
+	Usage: required
+	Value type: <prop-encoded-array>
+	Definition: single entry specifying the RTC's alarm interrupt
+
+- allow-set-time:
+	Usage: optional
+	Value type: <empty>
+	Definition: indicates that the setting of RTC time is allowed by
+		    the host CPU
+
+= EXAMPLE
+
+	pmicintc: pmic@0 {
+		compatible = "qcom,pm8921";
+		interrupts = <104 8>;
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		rtc@11d {
+			compatible = "qcom,pm8921-rtc";
+			reg = <0x11d>;
+			interrupts = <0x27 0>;
+		};
+	};

+ 15 - 9
Documentation/devicetree/bindings/mfd/s2mps11.txt

@@ -16,20 +16,25 @@ Optional properties:
 - interrupts: Interrupt specifiers for interrupt sources.
 - interrupts: Interrupt specifiers for interrupt sources.
 
 
 Optional nodes:
 Optional nodes:
-- clocks: s2mps11 provides three(AP/CP/BT) buffered 32.768 KHz outputs, so to
-  register these as clocks with common clock framework instantiate a sub-node
-  named "clocks". It uses the common clock binding documented in :
+- clocks: s2mps11 and s5m8767 provide three(AP/CP/BT) buffered 32.768 KHz
+  outputs, so to register these as clocks with common clock framework
+  instantiate a sub-node named "clocks". It uses the common clock binding
+  documented in :
   [Documentation/devicetree/bindings/clock/clock-bindings.txt]
   [Documentation/devicetree/bindings/clock/clock-bindings.txt]
+  The s2mps14 provides two (AP/BT) buffered 32.768 KHz outputs.
   - #clock-cells: should be 1.
   - #clock-cells: should be 1.
 
 
   - The following is the list of clocks generated by the controller. Each clock
   - The following is the list of clocks generated by the controller. Each clock
     is assigned an identifier and client nodes use this identifier to specify
     is assigned an identifier and client nodes use this identifier to specify
     the clock which they consume.
     the clock which they consume.
-    Clock               ID
-    ----------------------
-    32KhzAP		0
-    32KhzCP		1
-    32KhzBT		2
+    Clock               ID           Devices
+    ----------------------------------------------------------
+    32KhzAP		0            S2MPS11, S2MPS14, S5M8767
+    32KhzCP		1            S2MPS11, S5M8767
+    32KhzBT		2            S2MPS11, S2MPS14, S5M8767
+
+  - compatible: Should be one of: "samsung,s2mps11-clk", "samsung,s2mps14-clk",
+		"samsung,s5m8767-clk"
 
 
 - regulators: The regulators of s2mps11 that have to be instantiated should be
 - regulators: The regulators of s2mps11 that have to be instantiated should be
 included in a sub-node named 'regulators'. Regulator nodes included in this
 included in a sub-node named 'regulators'. Regulator nodes included in this
@@ -75,7 +80,8 @@ Example:
 		compatible = "samsung,s2mps11-pmic";
 		compatible = "samsung,s2mps11-pmic";
 		reg = <0x66>;
 		reg = <0x66>;
 
 
-		s2m_osc: clocks{
+		s2m_osc: clocks {
+			compatible = "samsung,s2mps11-clk";
 			#clock-cells = 1;
 			#clock-cells = 1;
 			clock-output-names = "xx", "yy", "zz";
 			clock-output-names = "xx", "yy", "zz";
 		};
 		};

+ 6 - 0
arch/arm/boot/dts/omap4.dtsi

@@ -733,6 +733,12 @@
 			#address-cells = <1>;
 			#address-cells = <1>;
 			#size-cells = <1>;
 			#size-cells = <1>;
 			ranges;
 			ranges;
+			clocks = <&init_60m_fclk>,
+				 <&xclk60mhsp1_ck>,
+				 <&xclk60mhsp2_ck>;
+			clock-names = "refclk_60m_int",
+				      "refclk_60m_ext_p1",
+				      "refclk_60m_ext_p2";
 
 
 			usbhsohci: ohci@4a064800 {
 			usbhsohci: ohci@4a064800 {
 				compatible = "ti,ohci-omap3";
 				compatible = "ti,ohci-omap3";

+ 6 - 0
arch/arm/boot/dts/omap5.dtsi

@@ -814,6 +814,12 @@
 			#address-cells = <1>;
 			#address-cells = <1>;
 			#size-cells = <1>;
 			#size-cells = <1>;
 			ranges;
 			ranges;
+			clocks = <&l3init_60m_fclk>,
+				 <&xclk60mhsp1_ck>,
+				 <&xclk60mhsp2_ck>;
+			clock-names = "refclk_60m_int",
+				      "refclk_60m_ext_p1",
+				      "refclk_60m_ext_p2";
 
 
 			usbhsohci: ohci@4a064800 {
 			usbhsohci: ohci@4a064800 {
 				compatible = "ti,ohci-omap3";
 				compatible = "ti,ohci-omap3";

+ 0 - 4
arch/arm/mach-omap2/cclock3xxx_data.c

@@ -3497,10 +3497,6 @@ static struct omap_clk omap3xxx_clks[] = {
 	CLK(NULL,	"dss_tv_fck",	&dss_tv_fck),
 	CLK(NULL,	"dss_tv_fck",	&dss_tv_fck),
 	CLK(NULL,	"dss_96m_fck",	&dss_96m_fck),
 	CLK(NULL,	"dss_96m_fck",	&dss_96m_fck),
 	CLK(NULL,	"dss2_alwon_fck",	&dss2_alwon_fck),
 	CLK(NULL,	"dss2_alwon_fck",	&dss2_alwon_fck),
-	CLK(NULL,	"utmi_p1_gfclk",	&dummy_ck),
-	CLK(NULL,	"utmi_p2_gfclk",	&dummy_ck),
-	CLK(NULL,	"xclk60mhsp1_ck",	&dummy_ck),
-	CLK(NULL,	"xclk60mhsp2_ck",	&dummy_ck),
 	CLK(NULL,	"init_60m_fclk",	&dummy_ck),
 	CLK(NULL,	"init_60m_fclk",	&dummy_ck),
 	CLK(NULL,	"gpt1_fck",	&gpt1_fck),
 	CLK(NULL,	"gpt1_fck",	&gpt1_fck),
 	CLK(NULL,	"aes2_ick",	&aes2_ick),
 	CLK(NULL,	"aes2_ick",	&aes2_ick),

+ 0 - 6
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c

@@ -1955,10 +1955,6 @@ static struct omap_hwmod_class omap3xxx_usb_host_hs_hwmod_class = {
 	.sysc = &omap3xxx_usb_host_hs_sysc,
 	.sysc = &omap3xxx_usb_host_hs_sysc,
 };
 };
 
 
-static struct omap_hwmod_opt_clk omap3xxx_usb_host_hs_opt_clks[] = {
-	  { .role = "ehci_logic_fck", .clk = "usbhost_120m_fck", },
-};
-
 static struct omap_hwmod_irq_info omap3xxx_usb_host_hs_irqs[] = {
 static struct omap_hwmod_irq_info omap3xxx_usb_host_hs_irqs[] = {
 	{ .name = "ohci-irq", .irq = 76 + OMAP_INTC_START, },
 	{ .name = "ohci-irq", .irq = 76 + OMAP_INTC_START, },
 	{ .name = "ehci-irq", .irq = 77 + OMAP_INTC_START, },
 	{ .name = "ehci-irq", .irq = 77 + OMAP_INTC_START, },
@@ -1981,8 +1977,6 @@ static struct omap_hwmod omap3xxx_usb_host_hs_hwmod = {
 			.idlest_stdby_bit = OMAP3430ES2_ST_USBHOST_STDBY_SHIFT,
 			.idlest_stdby_bit = OMAP3430ES2_ST_USBHOST_STDBY_SHIFT,
 		},
 		},
 	},
 	},
-	.opt_clks	= omap3xxx_usb_host_hs_opt_clks,
-	.opt_clks_cnt	= ARRAY_SIZE(omap3xxx_usb_host_hs_opt_clks),
 
 
 	/*
 	/*
 	 * Errata: USBHOST Configured In Smart-Idle Can Lead To a Deadlock
 	 * Errata: USBHOST Configured In Smart-Idle Can Lead To a Deadlock

+ 0 - 4
drivers/clk/ti/clk-3xxx.c

@@ -130,10 +130,6 @@ static struct ti_dt_clk omap3xxx_clks[] = {
 	DT_CLK(NULL, "dss_tv_fck", "dss_tv_fck"),
 	DT_CLK(NULL, "dss_tv_fck", "dss_tv_fck"),
 	DT_CLK(NULL, "dss_96m_fck", "dss_96m_fck"),
 	DT_CLK(NULL, "dss_96m_fck", "dss_96m_fck"),
 	DT_CLK(NULL, "dss2_alwon_fck", "dss2_alwon_fck"),
 	DT_CLK(NULL, "dss2_alwon_fck", "dss2_alwon_fck"),
-	DT_CLK(NULL, "utmi_p1_gfclk", "dummy_ck"),
-	DT_CLK(NULL, "utmi_p2_gfclk", "dummy_ck"),
-	DT_CLK(NULL, "xclk60mhsp1_ck", "dummy_ck"),
-	DT_CLK(NULL, "xclk60mhsp2_ck", "dummy_ck"),
 	DT_CLK(NULL, "init_60m_fclk", "dummy_ck"),
 	DT_CLK(NULL, "init_60m_fclk", "dummy_ck"),
 	DT_CLK(NULL, "gpt1_fck", "gpt1_fck"),
 	DT_CLK(NULL, "gpt1_fck", "gpt1_fck"),
 	DT_CLK(NULL, "aes2_ick", "aes2_ick"),
 	DT_CLK(NULL, "aes2_ick", "aes2_ick"),

+ 25 - 1
drivers/gpio/gpio-ich.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Intel ICH6-10, Series 5 and 6 GPIO driver
+ * Intel ICH6-10, Series 5 and 6, Atom C2000 (Avoton/Rangeley) GPIO driver
  *
  *
  * Copyright (C) 2010 Extreme Engineering Solutions.
  * Copyright (C) 2010 Extreme Engineering Solutions.
  *
  *
@@ -55,6 +55,16 @@ static const u8 ichx_reglen[3] = {
 	0x30, 0x10, 0x10,
 	0x30, 0x10, 0x10,
 };
 };
 
 
+static const u8 avoton_regs[4][3] = {
+	{0x00, 0x80, 0x00},
+	{0x04, 0x84, 0x00},
+	{0x08, 0x88, 0x00},
+};
+
+static const u8 avoton_reglen[3] = {
+	0x10, 0x10, 0x00,
+};
+
 #define ICHX_WRITE(val, reg, base_res)	outl(val, (reg) + (base_res)->start)
 #define ICHX_WRITE(val, reg, base_res)	outl(val, (reg) + (base_res)->start)
 #define ICHX_READ(reg, base_res)	inl((reg) + (base_res)->start)
 #define ICHX_READ(reg, base_res)	inl((reg) + (base_res)->start)
 
 
@@ -353,6 +363,17 @@ static struct ichx_desc intel5_desc = {
 	.reglen = ichx_reglen,
 	.reglen = ichx_reglen,
 };
 };
 
 
+/* Avoton */
+static struct ichx_desc avoton_desc = {
+	/* Avoton has only 59 GPIOs, but we assume the first set of register
+	 * (Core) has 32 instead of 31 to keep gpio-ich compliance
+	 */
+	.ngpio = 60,
+	.regs = avoton_regs,
+	.reglen = avoton_reglen,
+	.use_outlvl_cache = true,
+};
+
 static int ichx_gpio_request_regions(struct resource *res_base,
 static int ichx_gpio_request_regions(struct resource *res_base,
 						const char *name, u8 use_gpio)
 						const char *name, u8 use_gpio)
 {
 {
@@ -427,6 +448,9 @@ static int ichx_gpio_probe(struct platform_device *pdev)
 	case ICH_V10CONS_GPIO:
 	case ICH_V10CONS_GPIO:
 		ichx_priv.desc = &ich10_cons_desc;
 		ichx_priv.desc = &ich10_cons_desc;
 		break;
 		break;
+	case AVOTON_GPIO:
+		ichx_priv.desc = &avoton_desc;
+		break;
 	default:
 	default:
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}

+ 10 - 0
drivers/iio/adc/Kconfig

@@ -193,6 +193,16 @@ config TI_AM335X_ADC
 	  Say yes here to build support for Texas Instruments ADC
 	  Say yes here to build support for Texas Instruments ADC
 	  driver which is also a MFD client.
 	  driver which is also a MFD client.
 
 
+config TWL4030_MADC
+	tristate "TWL4030 MADC (Monitoring A/D Converter)"
+	depends on TWL4030_CORE
+	help
+	This driver provides support for Triton TWL4030-MADC. The
+	driver supports both RT and SW conversion methods.
+
+	This driver can also be built as a module. If so, the module will be
+	called twl4030-madc.
+
 config TWL6030_GPADC
 config TWL6030_GPADC
 	tristate "TWL6030 GPADC (General Purpose A/D Converter) Support"
 	tristate "TWL6030 GPADC (General Purpose A/D Converter) Support"
 	depends on TWL4030_CORE
 	depends on TWL4030_CORE

+ 1 - 0
drivers/iio/adc/Makefile

@@ -21,6 +21,7 @@ obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
 obj-$(CONFIG_NAU7802) += nau7802.o
 obj-$(CONFIG_NAU7802) += nau7802.o
 obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
 obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
 obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
 obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
+obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o
 obj-$(CONFIG_TWL6030_GPADC) += twl6030-gpadc.o
 obj-$(CONFIG_TWL6030_GPADC) += twl6030-gpadc.o
 obj-$(CONFIG_VF610_ADC) += vf610_adc.o
 obj-$(CONFIG_VF610_ADC) += vf610_adc.o
 obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
 obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o

+ 199 - 122
drivers/mfd/twl4030-madc.c → drivers/iio/adc/twl4030-madc.c

@@ -29,7 +29,6 @@
  *
  *
  */
  */
 
 
-#include <linux/init.h>
 #include <linux/device.h>
 #include <linux/device.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
@@ -47,20 +46,84 @@
 #include <linux/gfp.h>
 #include <linux/gfp.h>
 #include <linux/err.h>
 #include <linux/err.h>
 
 
-/*
+#include <linux/iio/iio.h>
+
+/**
  * struct twl4030_madc_data - a container for madc info
  * struct twl4030_madc_data - a container for madc info
- * @dev - pointer to device structure for madc
- * @lock - mutex protecting this data structure
- * @requests - Array of request struct corresponding to SW1, SW2 and RT
- * @imr - Interrupt mask register of MADC
- * @isr - Interrupt status register of MADC
+ * @dev:		Pointer to device structure for madc
+ * @lock:		Mutex protecting this data structure
+ * @requests:		Array of request struct corresponding to SW1, SW2 and RT
+ * @use_second_irq:	IRQ selection (main or co-processor)
+ * @imr:		Interrupt mask register of MADC
+ * @isr:		Interrupt status register of MADC
  */
  */
 struct twl4030_madc_data {
 struct twl4030_madc_data {
 	struct device *dev;
 	struct device *dev;
 	struct mutex lock;	/* mutex protecting this data structure */
 	struct mutex lock;	/* mutex protecting this data structure */
 	struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS];
 	struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS];
-	int imr;
-	int isr;
+	bool use_second_irq;
+	u8 imr;
+	u8 isr;
+};
+
+static int twl4030_madc_read(struct iio_dev *iio_dev,
+			     const struct iio_chan_spec *chan,
+			     int *val, int *val2, long mask)
+{
+	struct twl4030_madc_data *madc = iio_priv(iio_dev);
+	struct twl4030_madc_request req;
+	int ret;
+
+	req.method = madc->use_second_irq ? TWL4030_MADC_SW2 : TWL4030_MADC_SW1;
+
+	req.channels = BIT(chan->channel);
+	req.active = false;
+	req.func_cb = NULL;
+	req.type = TWL4030_MADC_WAIT;
+	req.raw = !(mask == IIO_CHAN_INFO_PROCESSED);
+	req.do_avg = (mask == IIO_CHAN_INFO_AVERAGE_RAW);
+
+	ret = twl4030_madc_conversion(&req);
+	if (ret < 0)
+		return ret;
+
+	*val = req.rbuf[chan->channel];
+
+	return IIO_VAL_INT;
+}
+
+static const struct iio_info twl4030_madc_iio_info = {
+	.read_raw = &twl4030_madc_read,
+	.driver_module = THIS_MODULE,
+};
+
+#define TWL4030_ADC_CHANNEL(_channel, _type, _name) {	\
+	.type = _type,					\
+	.channel = _channel,				\
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
+			      BIT(IIO_CHAN_INFO_AVERAGE_RAW) | \
+			      BIT(IIO_CHAN_INFO_PROCESSED), \
+	.datasheet_name = _name,			\
+	.indexed = 1,					\
+}
+
+static const struct iio_chan_spec twl4030_madc_iio_channels[] = {
+	TWL4030_ADC_CHANNEL(0, IIO_VOLTAGE, "ADCIN0"),
+	TWL4030_ADC_CHANNEL(1, IIO_TEMP, "ADCIN1"),
+	TWL4030_ADC_CHANNEL(2, IIO_VOLTAGE, "ADCIN2"),
+	TWL4030_ADC_CHANNEL(3, IIO_VOLTAGE, "ADCIN3"),
+	TWL4030_ADC_CHANNEL(4, IIO_VOLTAGE, "ADCIN4"),
+	TWL4030_ADC_CHANNEL(5, IIO_VOLTAGE, "ADCIN5"),
+	TWL4030_ADC_CHANNEL(6, IIO_VOLTAGE, "ADCIN6"),
+	TWL4030_ADC_CHANNEL(7, IIO_VOLTAGE, "ADCIN7"),
+	TWL4030_ADC_CHANNEL(8, IIO_VOLTAGE, "ADCIN8"),
+	TWL4030_ADC_CHANNEL(9, IIO_VOLTAGE, "ADCIN9"),
+	TWL4030_ADC_CHANNEL(10, IIO_CURRENT, "ADCIN10"),
+	TWL4030_ADC_CHANNEL(11, IIO_VOLTAGE, "ADCIN11"),
+	TWL4030_ADC_CHANNEL(12, IIO_VOLTAGE, "ADCIN12"),
+	TWL4030_ADC_CHANNEL(13, IIO_VOLTAGE, "ADCIN13"),
+	TWL4030_ADC_CHANNEL(14, IIO_VOLTAGE, "ADCIN14"),
+	TWL4030_ADC_CHANNEL(15, IIO_VOLTAGE, "ADCIN15"),
 };
 };
 
 
 static struct twl4030_madc_data *twl4030_madc;
 static struct twl4030_madc_data *twl4030_madc;
@@ -91,17 +154,16 @@ twl4030_divider_ratios[16] = {
 };
 };
 
 
 
 
-/*
- * Conversion table from -3 to 55 degree Celcius
- */
-static int therm_tbl[] = {
-30800,	29500,	28300,	27100,
-26000,	24900,	23900,	22900,	22000,	21100,	20300,	19400,	18700,	17900,
-17200,	16500,	15900,	15300,	14700,	14100,	13600,	13100,	12600,	12100,
-11600,	11200,	10800,	10400,	10000,	9630,	9280,	8950,	8620,	8310,
-8020,	7730,	7460,	7200,	6950,	6710,	6470,	6250,	6040,	5830,
-5640,	5450,	5260,	5090,	4920,	4760,	4600,	4450,	4310,	4170,
-4040,	3910,	3790,	3670,	3550
+/* Conversion table from -3 to 55 degrees Celcius */
+static int twl4030_therm_tbl[] = {
+	30800,	29500,	28300,	27100,
+	26000,	24900,	23900,	22900,	22000,	21100,	20300,	19400,	18700,
+	17900,	17200,	16500,	15900,	15300,	14700,	14100,	13600,	13100,
+	12600,	12100,	11600,	11200,	10800,	10400,	10000,	9630,	9280,
+	8950,	8620,	8310,	8020,	7730,	7460,	7200,	6950,	6710,
+	6470,	6250,	6040,	5830,	5640,	5450,	5260,	5090,	4920,
+	4760,	4600,	4450,	4310,	4170,	4040,	3910,	3790,	3670,
+	3550
 };
 };
 
 
 /*
 /*
@@ -133,37 +195,32 @@ const struct twl4030_madc_conversion_method twl4030_conversion_methods[] = {
 			      },
 			      },
 };
 };
 
 
-/*
- * Function to read a particular channel value.
- * @madc - pointer to struct twl4030_madc_data
- * @reg - lsb of ADC Channel
- * If the i2c read fails it returns an error else returns 0.
+/**
+ * twl4030_madc_channel_raw_read() - Function to read a particular channel value
+ * @madc:	pointer to struct twl4030_madc_data
+ * @reg:	lsb of ADC Channel
+ *
+ * Return: 0 on success, an error code otherwise.
  */
  */
 static int twl4030_madc_channel_raw_read(struct twl4030_madc_data *madc, u8 reg)
 static int twl4030_madc_channel_raw_read(struct twl4030_madc_data *madc, u8 reg)
 {
 {
-	u8 msb, lsb;
+	u16 val;
 	int ret;
 	int ret;
 	/*
 	/*
 	 * For each ADC channel, we have MSB and LSB register pair. MSB address
 	 * For each ADC channel, we have MSB and LSB register pair. MSB address
 	 * is always LSB address+1. reg parameter is the address of LSB register
 	 * is always LSB address+1. reg parameter is the address of LSB register
 	 */
 	 */
-	ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &msb, reg + 1);
+	ret = twl_i2c_read_u16(TWL4030_MODULE_MADC, &val, reg);
 	if (ret) {
 	if (ret) {
-		dev_err(madc->dev, "unable to read MSB register 0x%X\n",
-			reg + 1);
-		return ret;
-	}
-	ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &lsb, reg);
-	if (ret) {
-		dev_err(madc->dev, "unable to read LSB register 0x%X\n", reg);
+		dev_err(madc->dev, "unable to read register 0x%X\n", reg);
 		return ret;
 		return ret;
 	}
 	}
 
 
-	return (int)(((msb << 8) | lsb) >> 6);
+	return (int)(val >> 6);
 }
 }
 
 
 /*
 /*
- * Return battery temperature
+ * Return battery temperature in degrees Celsius
  * Or < 0 on failure.
  * Or < 0 on failure.
  */
  */
 static int twl4030battery_temperature(int raw_volt)
 static int twl4030battery_temperature(int raw_volt)
@@ -172,18 +229,18 @@ static int twl4030battery_temperature(int raw_volt)
 	int temp, curr, volt, res, ret;
 	int temp, curr, volt, res, ret;
 
 
 	volt = (raw_volt * TEMP_STEP_SIZE) / TEMP_PSR_R;
 	volt = (raw_volt * TEMP_STEP_SIZE) / TEMP_PSR_R;
-	/* Getting and calculating the supply current in micro ampers */
+	/* Getting and calculating the supply current in micro amperes */
 	ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, &val,
 	ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, &val,
 		REG_BCICTL2);
 		REG_BCICTL2);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
+
 	curr = ((val & TWL4030_BCI_ITHEN) + 1) * 10;
 	curr = ((val & TWL4030_BCI_ITHEN) + 1) * 10;
 	/* Getting and calculating the thermistor resistance in ohms */
 	/* Getting and calculating the thermistor resistance in ohms */
 	res = volt * 1000 / curr;
 	res = volt * 1000 / curr;
 	/* calculating temperature */
 	/* calculating temperature */
 	for (temp = 58; temp >= 0; temp--) {
 	for (temp = 58; temp >= 0; temp--) {
-		int actual = therm_tbl[temp];
-
+		int actual = twl4030_therm_tbl[temp];
 		if ((actual - res) >= 0)
 		if ((actual - res) >= 0)
 			break;
 			break;
 	}
 	}
@@ -205,11 +262,12 @@ static int twl4030battery_current(int raw_volt)
 	else /* slope of 0.88 mV/mA */
 	else /* slope of 0.88 mV/mA */
 		return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R2;
 		return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R2;
 }
 }
+
 /*
 /*
  * Function to read channel values
  * Function to read channel values
  * @madc - pointer to twl4030_madc_data struct
  * @madc - pointer to twl4030_madc_data struct
  * @reg_base - Base address of the first channel
  * @reg_base - Base address of the first channel
- * @Channels - 16 bit bitmap. If the bit is set, channel value is read
+ * @Channels - 16 bit bitmap. If the bit is set, channel's value is read
  * @buf - The channel values are stored here. if read fails error
  * @buf - The channel values are stored here. if read fails error
  * @raw - Return raw values without conversion
  * @raw - Return raw values without conversion
  * value is stored
  * value is stored
@@ -220,17 +278,17 @@ static int twl4030_madc_read_channels(struct twl4030_madc_data *madc,
 				      long channels, int *buf,
 				      long channels, int *buf,
 				      bool raw)
 				      bool raw)
 {
 {
-	int count = 0, count_req = 0, i;
+	int count = 0;
+	int i;
 	u8 reg;
 	u8 reg;
 
 
 	for_each_set_bit(i, &channels, TWL4030_MADC_MAX_CHANNELS) {
 	for_each_set_bit(i, &channels, TWL4030_MADC_MAX_CHANNELS) {
-		reg = reg_base + 2 * i;
+		reg = reg_base + (2 * i);
 		buf[i] = twl4030_madc_channel_raw_read(madc, reg);
 		buf[i] = twl4030_madc_channel_raw_read(madc, reg);
 		if (buf[i] < 0) {
 		if (buf[i] < 0) {
-			dev_err(madc->dev,
-				"Unable to read register 0x%X\n", reg);
-			count_req++;
-			continue;
+			dev_err(madc->dev, "Unable to read register 0x%X\n",
+				reg);
+			return buf[i];
 		}
 		}
 		if (raw) {
 		if (raw) {
 			count++;
 			count++;
@@ -241,7 +299,7 @@ static int twl4030_madc_read_channels(struct twl4030_madc_data *madc,
 			buf[i] = twl4030battery_current(buf[i]);
 			buf[i] = twl4030battery_current(buf[i]);
 			if (buf[i] < 0) {
 			if (buf[i] < 0) {
 				dev_err(madc->dev, "err reading current\n");
 				dev_err(madc->dev, "err reading current\n");
-				count_req++;
+				return buf[i];
 			} else {
 			} else {
 				count++;
 				count++;
 				buf[i] = buf[i] - 750;
 				buf[i] = buf[i] - 750;
@@ -251,7 +309,7 @@ static int twl4030_madc_read_channels(struct twl4030_madc_data *madc,
 			buf[i] = twl4030battery_temperature(buf[i]);
 			buf[i] = twl4030battery_temperature(buf[i]);
 			if (buf[i] < 0) {
 			if (buf[i] < 0) {
 				dev_err(madc->dev, "err reading temperature\n");
 				dev_err(madc->dev, "err reading temperature\n");
-				count_req++;
+				return buf[i];
 			} else {
 			} else {
 				buf[i] -= 3;
 				buf[i] -= 3;
 				count++;
 				count++;
@@ -272,8 +330,6 @@ static int twl4030_madc_read_channels(struct twl4030_madc_data *madc,
 				twl4030_divider_ratios[i].numerator);
 				twl4030_divider_ratios[i].numerator);
 		}
 		}
 	}
 	}
-	if (count_req)
-		dev_err(madc->dev, "%d channel conversion failed\n", count_req);
 
 
 	return count;
 	return count;
 }
 }
@@ -297,13 +353,13 @@ static int twl4030_madc_enable_irq(struct twl4030_madc_data *madc, u8 id)
 			madc->imr);
 			madc->imr);
 		return ret;
 		return ret;
 	}
 	}
+
 	val &= ~(1 << id);
 	val &= ~(1 << id);
 	ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr);
 	ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr);
 	if (ret) {
 	if (ret) {
 		dev_err(madc->dev,
 		dev_err(madc->dev,
 			"unable to write imr register 0x%X\n", madc->imr);
 			"unable to write imr register 0x%X\n", madc->imr);
 		return ret;
 		return ret;
-
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -366,7 +422,7 @@ static irqreturn_t twl4030_madc_threaded_irq_handler(int irq, void *_madc)
 			continue;
 			continue;
 		ret = twl4030_madc_disable_irq(madc, i);
 		ret = twl4030_madc_disable_irq(madc, i);
 		if (ret < 0)
 		if (ret < 0)
-			dev_dbg(madc->dev, "Disable interrupt failed%d\n", i);
+			dev_dbg(madc->dev, "Disable interrupt failed %d\n", i);
 		madc->requests[i].result_pending = 1;
 		madc->requests[i].result_pending = 1;
 	}
 	}
 	for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
 	for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
@@ -448,21 +504,17 @@ static int twl4030_madc_start_conversion(struct twl4030_madc_data *madc,
 {
 {
 	const struct twl4030_madc_conversion_method *method;
 	const struct twl4030_madc_conversion_method *method;
 	int ret = 0;
 	int ret = 0;
+
+	if (conv_method != TWL4030_MADC_SW1 && conv_method != TWL4030_MADC_SW2)
+		return -ENOTSUPP;
+
 	method = &twl4030_conversion_methods[conv_method];
 	method = &twl4030_conversion_methods[conv_method];
-	switch (conv_method) {
-	case TWL4030_MADC_SW1:
-	case TWL4030_MADC_SW2:
-		ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
-				       TWL4030_MADC_SW_START, method->ctrl);
-		if (ret) {
-			dev_err(madc->dev,
-				"unable to write ctrl register 0x%X\n",
-				method->ctrl);
-			return ret;
-		}
-		break;
-	default:
-		break;
+	ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, TWL4030_MADC_SW_START,
+			       method->ctrl);
+	if (ret) {
+		dev_err(madc->dev, "unable to write ctrl register 0x%X\n",
+			method->ctrl);
+		return ret;
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -513,7 +565,6 @@ static int twl4030_madc_wait_conversion_ready(struct twl4030_madc_data *madc,
 int twl4030_madc_conversion(struct twl4030_madc_request *req)
 int twl4030_madc_conversion(struct twl4030_madc_request *req)
 {
 {
 	const struct twl4030_madc_conversion_method *method;
 	const struct twl4030_madc_conversion_method *method;
-	u8 ch_msb, ch_lsb;
 	int ret;
 	int ret;
 
 
 	if (!req || !twl4030_madc)
 	if (!req || !twl4030_madc)
@@ -529,38 +580,22 @@ int twl4030_madc_conversion(struct twl4030_madc_request *req)
 		ret = -EBUSY;
 		ret = -EBUSY;
 		goto out;
 		goto out;
 	}
 	}
-	ch_msb = (req->channels >> 8) & 0xff;
-	ch_lsb = req->channels & 0xff;
 	method = &twl4030_conversion_methods[req->method];
 	method = &twl4030_conversion_methods[req->method];
 	/* Select channels to be converted */
 	/* Select channels to be converted */
-	ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, ch_msb, method->sel + 1);
-	if (ret) {
-		dev_err(twl4030_madc->dev,
-			"unable to write sel register 0x%X\n", method->sel + 1);
-		goto out;
-	}
-	ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, ch_lsb, method->sel);
+	ret = twl_i2c_write_u16(TWL4030_MODULE_MADC, req->channels, method->sel);
 	if (ret) {
 	if (ret) {
 		dev_err(twl4030_madc->dev,
 		dev_err(twl4030_madc->dev,
-			"unable to write sel register 0x%X\n", method->sel + 1);
+			"unable to write sel register 0x%X\n", method->sel);
 		goto out;
 		goto out;
 	}
 	}
 	/* Select averaging for all channels if do_avg is set */
 	/* Select averaging for all channels if do_avg is set */
 	if (req->do_avg) {
 	if (req->do_avg) {
-		ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
-				       ch_msb, method->avg + 1);
+		ret = twl_i2c_write_u16(TWL4030_MODULE_MADC, req->channels,
+				       method->avg);
 		if (ret) {
 		if (ret) {
 			dev_err(twl4030_madc->dev,
 			dev_err(twl4030_madc->dev,
 				"unable to write avg register 0x%X\n",
 				"unable to write avg register 0x%X\n",
-				method->avg + 1);
-			goto out;
-		}
-		ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
-				       ch_lsb, method->avg);
-		if (ret) {
-			dev_err(twl4030_madc->dev,
-				"unable to write sel reg 0x%X\n",
-				method->sel + 1);
+				method->avg);
 			goto out;
 			goto out;
 		}
 		}
 	}
 	}
@@ -601,10 +636,6 @@ out:
 }
 }
 EXPORT_SYMBOL_GPL(twl4030_madc_conversion);
 EXPORT_SYMBOL_GPL(twl4030_madc_conversion);
 
 
-/*
- * Return channel value
- * Or < 0 on failure.
- */
 int twl4030_get_madc_conversion(int channel_no)
 int twl4030_get_madc_conversion(int channel_no)
 {
 {
 	struct twl4030_madc_request req;
 	struct twl4030_madc_request req;
@@ -625,20 +656,25 @@ int twl4030_get_madc_conversion(int channel_no)
 }
 }
 EXPORT_SYMBOL_GPL(twl4030_get_madc_conversion);
 EXPORT_SYMBOL_GPL(twl4030_get_madc_conversion);
 
 
-/*
+/**
+ * twl4030_madc_set_current_generator() - setup bias current
+ *
+ * @madc:	pointer to twl4030_madc_data struct
+ * @chan:	can be one of the two values:
+ *		TWL4030_BCI_ITHEN
+ *		Enables bias current for main battery type reading
+ *		TWL4030_BCI_TYPEN
+ *		Enables bias current for main battery temperature sensing
+ * @on:		enable or disable chan.
+ *
  * Function to enable or disable bias current for
  * Function to enable or disable bias current for
  * main battery type reading or temperature sensing
  * main battery type reading or temperature sensing
- * @madc - pointer to twl4030_madc_data struct
- * @chan - can be one of the two values
- * TWL4030_BCI_ITHEN - Enables bias current for main battery type reading
- * TWL4030_BCI_TYPEN - Enables bias current for main battery temperature
- * sensing
- * @on - enable or disable chan.
  */
  */
 static int twl4030_madc_set_current_generator(struct twl4030_madc_data *madc,
 static int twl4030_madc_set_current_generator(struct twl4030_madc_data *madc,
 					      int chan, int on)
 					      int chan, int on)
 {
 {
 	int ret;
 	int ret;
+	int regmask;
 	u8 regval;
 	u8 regval;
 
 
 	ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE,
 	ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE,
@@ -648,10 +684,13 @@ static int twl4030_madc_set_current_generator(struct twl4030_madc_data *madc,
 			TWL4030_BCI_BCICTL1);
 			TWL4030_BCI_BCICTL1);
 		return ret;
 		return ret;
 	}
 	}
+
+	regmask = chan ? TWL4030_BCI_ITHEN : TWL4030_BCI_TYPEN;
 	if (on)
 	if (on)
-		regval |= chan ? TWL4030_BCI_ITHEN : TWL4030_BCI_TYPEN;
+		regval |= regmask;
 	else
 	else
-		regval &= chan ? ~TWL4030_BCI_ITHEN : ~TWL4030_BCI_TYPEN;
+		regval &= ~regmask;
+
 	ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE,
 	ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE,
 			       regval, TWL4030_BCI_BCICTL1);
 			       regval, TWL4030_BCI_BCICTL1);
 	if (ret) {
 	if (ret) {
@@ -666,7 +705,7 @@ static int twl4030_madc_set_current_generator(struct twl4030_madc_data *madc,
 /*
 /*
  * Function that sets MADC software power on bit to enable MADC
  * Function that sets MADC software power on bit to enable MADC
  * @madc - pointer to twl4030_madc_data struct
  * @madc - pointer to twl4030_madc_data struct
- * @on - Enable or disable MADC software powen on bit.
+ * @on - Enable or disable MADC software power on bit.
  * returns error if i2c read/write fails else 0
  * returns error if i2c read/write fails else 0
  */
  */
 static int twl4030_madc_set_power(struct twl4030_madc_data *madc, int on)
 static int twl4030_madc_set_power(struct twl4030_madc_data *madc, int on)
@@ -702,31 +741,52 @@ static int twl4030_madc_probe(struct platform_device *pdev)
 {
 {
 	struct twl4030_madc_data *madc;
 	struct twl4030_madc_data *madc;
 	struct twl4030_madc_platform_data *pdata = dev_get_platdata(&pdev->dev);
 	struct twl4030_madc_platform_data *pdata = dev_get_platdata(&pdev->dev);
-	int ret;
+	struct device_node *np = pdev->dev.of_node;
+	int irq, ret;
 	u8 regval;
 	u8 regval;
+	struct iio_dev *iio_dev = NULL;
 
 
-	if (!pdata) {
-		dev_err(&pdev->dev, "platform_data not available\n");
+	if (!pdata && !np) {
+		dev_err(&pdev->dev, "neither platform data nor Device Tree node available\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
-	madc = kzalloc(sizeof(*madc), GFP_KERNEL);
-	if (!madc)
+
+	iio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*madc));
+	if (!iio_dev) {
+		dev_err(&pdev->dev, "failed allocating iio device\n");
 		return -ENOMEM;
 		return -ENOMEM;
+	}
 
 
+	madc = iio_priv(iio_dev);
 	madc->dev = &pdev->dev;
 	madc->dev = &pdev->dev;
 
 
+	iio_dev->name = dev_name(&pdev->dev);
+	iio_dev->dev.parent = &pdev->dev;
+	iio_dev->dev.of_node = pdev->dev.of_node;
+	iio_dev->info = &twl4030_madc_iio_info;
+	iio_dev->modes = INDIO_DIRECT_MODE;
+	iio_dev->channels = twl4030_madc_iio_channels;
+	iio_dev->num_channels = ARRAY_SIZE(twl4030_madc_iio_channels);
+
 	/*
 	/*
 	 * Phoenix provides 2 interrupt lines. The first one is connected to
 	 * Phoenix provides 2 interrupt lines. The first one is connected to
 	 * the OMAP. The other one can be connected to the other processor such
 	 * the OMAP. The other one can be connected to the other processor such
 	 * as modem. Hence two separate ISR and IMR registers.
 	 * as modem. Hence two separate ISR and IMR registers.
 	 */
 	 */
-	madc->imr = (pdata->irq_line == 1) ?
-	    TWL4030_MADC_IMR1 : TWL4030_MADC_IMR2;
-	madc->isr = (pdata->irq_line == 1) ?
-	    TWL4030_MADC_ISR1 : TWL4030_MADC_ISR2;
+	if (pdata)
+		madc->use_second_irq = (pdata->irq_line != 1);
+	else
+		madc->use_second_irq = of_property_read_bool(np,
+				       "ti,system-uses-second-madc-irq");
+
+	madc->imr = madc->use_second_irq ? TWL4030_MADC_IMR2 :
+					   TWL4030_MADC_IMR1;
+	madc->isr = madc->use_second_irq ? TWL4030_MADC_ISR2 :
+					   TWL4030_MADC_ISR1;
+
 	ret = twl4030_madc_set_power(madc, 1);
 	ret = twl4030_madc_set_power(madc, 1);
 	if (ret < 0)
 	if (ret < 0)
-		goto err_power;
+		return ret;
 	ret = twl4030_madc_set_current_generator(madc, 0, 1);
 	ret = twl4030_madc_set_current_generator(madc, 0, 1);
 	if (ret < 0)
 	if (ret < 0)
 		goto err_current_generator;
 		goto err_current_generator;
@@ -768,46 +828,63 @@ static int twl4030_madc_probe(struct platform_device *pdev)
 		}
 		}
 	}
 	}
 
 
-	platform_set_drvdata(pdev, madc);
+	platform_set_drvdata(pdev, iio_dev);
 	mutex_init(&madc->lock);
 	mutex_init(&madc->lock);
-	ret = request_threaded_irq(platform_get_irq(pdev, 0), NULL,
+
+	irq = platform_get_irq(pdev, 0);
+	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
 				   twl4030_madc_threaded_irq_handler,
 				   twl4030_madc_threaded_irq_handler,
 				   IRQF_TRIGGER_RISING, "twl4030_madc", madc);
 				   IRQF_TRIGGER_RISING, "twl4030_madc", madc);
 	if (ret) {
 	if (ret) {
-		dev_dbg(&pdev->dev, "could not request irq\n");
+		dev_err(&pdev->dev, "could not request irq\n");
 		goto err_i2c;
 		goto err_i2c;
 	}
 	}
 	twl4030_madc = madc;
 	twl4030_madc = madc;
+
+	ret = iio_device_register(iio_dev);
+	if (ret) {
+		dev_err(&pdev->dev, "could not register iio device\n");
+		goto err_i2c;
+	}
+
 	return 0;
 	return 0;
+
 err_i2c:
 err_i2c:
 	twl4030_madc_set_current_generator(madc, 0, 0);
 	twl4030_madc_set_current_generator(madc, 0, 0);
 err_current_generator:
 err_current_generator:
 	twl4030_madc_set_power(madc, 0);
 	twl4030_madc_set_power(madc, 0);
-err_power:
-	kfree(madc);
-
 	return ret;
 	return ret;
 }
 }
 
 
 static int twl4030_madc_remove(struct platform_device *pdev)
 static int twl4030_madc_remove(struct platform_device *pdev)
 {
 {
-	struct twl4030_madc_data *madc = platform_get_drvdata(pdev);
+	struct iio_dev *iio_dev = platform_get_drvdata(pdev);
+	struct twl4030_madc_data *madc = iio_priv(iio_dev);
+
+	iio_device_unregister(iio_dev);
 
 
-	free_irq(platform_get_irq(pdev, 0), madc);
 	twl4030_madc_set_current_generator(madc, 0, 0);
 	twl4030_madc_set_current_generator(madc, 0, 0);
 	twl4030_madc_set_power(madc, 0);
 	twl4030_madc_set_power(madc, 0);
-	kfree(madc);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
+#ifdef CONFIG_OF
+static const struct of_device_id twl_madc_of_match[] = {
+	{ .compatible = "ti,twl4030-madc", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, twl_madc_of_match);
+#endif
+
 static struct platform_driver twl4030_madc_driver = {
 static struct platform_driver twl4030_madc_driver = {
 	.probe = twl4030_madc_probe,
 	.probe = twl4030_madc_probe,
 	.remove = twl4030_madc_remove,
 	.remove = twl4030_madc_remove,
 	.driver = {
 	.driver = {
 		   .name = "twl4030_madc",
 		   .name = "twl4030_madc",
 		   .owner = THIS_MODULE,
 		   .owner = THIS_MODULE,
-		   },
+		   .of_match_table = of_match_ptr(twl_madc_of_match),
+	},
 };
 };
 
 
 module_platform_driver(twl4030_madc_driver);
 module_platform_driver(twl4030_madc_driver);

+ 1 - 2
drivers/mfd/88pm800.c

@@ -571,7 +571,7 @@ static int pm800_probe(struct i2c_client *client,
 	ret = pm800_pages_init(chip);
 	ret = pm800_pages_init(chip);
 	if (ret) {
 	if (ret) {
 		dev_err(&client->dev, "pm800_pages_init failed!\n");
 		dev_err(&client->dev, "pm800_pages_init failed!\n");
-		goto err_page_init;
+		goto err_device_init;
 	}
 	}
 
 
 	ret = device_800_init(chip, pdata);
 	ret = device_800_init(chip, pdata);
@@ -587,7 +587,6 @@ static int pm800_probe(struct i2c_client *client,
 
 
 err_device_init:
 err_device_init:
 	pm800_pages_exit(chip);
 	pm800_pages_exit(chip);
-err_page_init:
 err_subchip_alloc:
 err_subchip_alloc:
 	pm80x_deinit();
 	pm80x_deinit();
 out_init:
 out_init:

+ 6 - 0
drivers/mfd/88pm860x-core.c

@@ -1179,12 +1179,18 @@ static int pm860x_probe(struct i2c_client *client,
 		chip->companion_addr = pdata->companion_addr;
 		chip->companion_addr = pdata->companion_addr;
 		chip->companion = i2c_new_dummy(chip->client->adapter,
 		chip->companion = i2c_new_dummy(chip->client->adapter,
 						chip->companion_addr);
 						chip->companion_addr);
+		if (!chip->companion) {
+			dev_err(&client->dev,
+				"Failed to allocate I2C companion device\n");
+			return -ENODEV;
+		}
 		chip->regmap_companion = regmap_init_i2c(chip->companion,
 		chip->regmap_companion = regmap_init_i2c(chip->companion,
 							&pm860x_regmap_config);
 							&pm860x_regmap_config);
 		if (IS_ERR(chip->regmap_companion)) {
 		if (IS_ERR(chip->regmap_companion)) {
 			ret = PTR_ERR(chip->regmap_companion);
 			ret = PTR_ERR(chip->regmap_companion);
 			dev_err(&chip->companion->dev,
 			dev_err(&chip->companion->dev,
 				"Failed to allocate register map: %d\n", ret);
 				"Failed to allocate register map: %d\n", ret);
+			i2c_unregister_device(chip->companion);
 			return ret;
 			return ret;
 		}
 		}
 		i2c_set_clientdata(chip->companion, chip);
 		i2c_set_clientdata(chip->companion, chip);

+ 54 - 44
drivers/mfd/Kconfig

@@ -59,6 +59,14 @@ config MFD_AAT2870_CORE
 	  additional drivers must be enabled in order to use the
 	  additional drivers must be enabled in order to use the
 	  functionality of the device.
 	  functionality of the device.
 
 
+config MFD_BCM590XX
+	tristate "Broadcom BCM590xx PMUs"
+	select MFD_CORE
+	select REGMAP_I2C
+	depends on I2C
+	help
+	  Support for the BCM590xx PMUs from Broadcom
+
 config MFD_CROS_EC
 config MFD_CROS_EC
 	tristate "ChromeOS Embedded Controller"
 	tristate "ChromeOS Embedded Controller"
 	select MFD_CORE
 	select MFD_CORE
@@ -100,7 +108,7 @@ config PMIC_DA903X
 	bool "Dialog Semiconductor DA9030/DA9034 PMIC Support"
 	bool "Dialog Semiconductor DA9030/DA9034 PMIC Support"
 	depends on I2C=y
 	depends on I2C=y
 	help
 	help
-	  Say yes here to support for Dialog Semiconductor DA9030 (a.k.a
+	  Say yes here to add support for Dialog Semiconductor DA9030 (a.k.a
 	  ARAVA) and DA9034 (a.k.a MICCO), these are Power Management IC
 	  ARAVA) and DA9034 (a.k.a MICCO), these are Power Management IC
 	  usually found on PXA processors-based platforms. This includes
 	  usually found on PXA processors-based platforms. This includes
 	  the I2C driver and the core APIs _only_, you have to select
 	  the I2C driver and the core APIs _only_, you have to select
@@ -270,13 +278,18 @@ config MFD_KEMPLD
 	  device may provide functions like watchdog, GPIO, UART and I2C bus.
 	  device may provide functions like watchdog, GPIO, UART and I2C bus.
 
 
 	  The following modules are supported:
 	  The following modules are supported:
+		* COMe-bHL6
 		* COMe-bIP#
 		* COMe-bIP#
 		* COMe-bPC2 (ETXexpress-PC)
 		* COMe-bPC2 (ETXexpress-PC)
 		* COMe-bSC# (ETXexpress-SC T#)
 		* COMe-bSC# (ETXexpress-SC T#)
+		* COMe-cBT6
 		* COMe-cCT6
 		* COMe-cCT6
 		* COMe-cDC2 (microETXexpress-DC)
 		* COMe-cDC2 (microETXexpress-DC)
+		* COMe-cHL6
 		* COMe-cPC2 (microETXexpress-PC)
 		* COMe-cPC2 (microETXexpress-PC)
+		* COMe-mBT10
 		* COMe-mCT10
 		* COMe-mCT10
+		* COMe-mTT10 (nanoETXexpress-TT)
 		* ETX-OH
 		* ETX-OH
 
 
 	  This driver can also be built as a module. If so, the module
 	  This driver can also be built as a module. If so, the module
@@ -322,9 +335,10 @@ config MFD_MAX14577
 	depends on I2C=y
 	depends on I2C=y
 	select MFD_CORE
 	select MFD_CORE
 	select REGMAP_I2C
 	select REGMAP_I2C
+	select REGMAP_IRQ
 	select IRQ_DOMAIN
 	select IRQ_DOMAIN
 	help
 	help
-	  Say yes here to support for Maxim Semiconductor MAX14577.
+	  Say yes here to add support for Maxim Semiconductor MAX14577.
 	  This is a Micro-USB IC with Charger controls on chip.
 	  This is a Micro-USB IC with Charger controls on chip.
 	  This driver provides common support for accessing the device;
 	  This driver provides common support for accessing the device;
 	  additional drivers must be enabled in order to use the functionality
 	  additional drivers must be enabled in order to use the functionality
@@ -337,7 +351,7 @@ config MFD_MAX77686
 	select REGMAP_I2C
 	select REGMAP_I2C
 	select IRQ_DOMAIN
 	select IRQ_DOMAIN
 	help
 	help
-	  Say yes here to support for Maxim Semiconductor MAX77686.
+	  Say yes here to add support for Maxim Semiconductor MAX77686.
 	  This is a Power Management IC with RTC on chip.
 	  This is a Power Management IC with RTC on chip.
 	  This driver provides common support for accessing the device;
 	  This driver provides common support for accessing the device;
 	  additional drivers must be enabled in order to use the functionality
 	  additional drivers must be enabled in order to use the functionality
@@ -349,7 +363,7 @@ config MFD_MAX77693
 	select MFD_CORE
 	select MFD_CORE
 	select REGMAP_I2C
 	select REGMAP_I2C
 	help
 	help
-	  Say yes here to support for Maxim Semiconductor MAX77693.
+	  Say yes here to add support for Maxim Semiconductor MAX77693.
 	  This is a companion Power Management IC with Flash, Haptic, Charger,
 	  This is a companion Power Management IC with Flash, Haptic, Charger,
 	  and MUIC(Micro USB Interface Controller) controls on chip.
 	  and MUIC(Micro USB Interface Controller) controls on chip.
 	  This driver provides common support for accessing the device;
 	  This driver provides common support for accessing the device;
@@ -363,7 +377,7 @@ config MFD_MAX8907
 	select REGMAP_I2C
 	select REGMAP_I2C
 	select REGMAP_IRQ
 	select REGMAP_IRQ
 	help
 	help
-	  Say yes here to support for Maxim Semiconductor MAX8907. This is
+	  Say yes here to add support for Maxim Semiconductor MAX8907. This is
 	  a Power Management IC. This driver provides common support for
 	  a Power Management IC. This driver provides common support for
 	  accessing the device; additional drivers must be enabled in order
 	  accessing the device; additional drivers must be enabled in order
 	  to use the functionality of the device.
 	  to use the functionality of the device.
@@ -373,7 +387,7 @@ config MFD_MAX8925
 	depends on I2C=y
 	depends on I2C=y
 	select MFD_CORE
 	select MFD_CORE
 	help
 	help
-	  Say yes here to support for Maxim Semiconductor MAX8925. This is
+	  Say yes here to add support for Maxim Semiconductor MAX8925. This is
 	  a Power Management IC. This driver provides common support for
 	  a Power Management IC. This driver provides common support for
 	  accessing the device, additional drivers must be enabled in order
 	  accessing the device, additional drivers must be enabled in order
 	  to use the functionality of the device.
 	  to use the functionality of the device.
@@ -384,7 +398,7 @@ config MFD_MAX8997
 	select MFD_CORE
 	select MFD_CORE
 	select IRQ_DOMAIN
 	select IRQ_DOMAIN
 	help
 	help
-	  Say yes here to support for Maxim Semiconductor MAX8997/8966.
+	  Say yes here to add support for Maxim Semiconductor MAX8997/8966.
 	  This is a Power Management IC with RTC, Flash, Fuel Gauge, Haptic,
 	  This is a Power Management IC with RTC, Flash, Fuel Gauge, Haptic,
 	  MUIC controls on chip.
 	  MUIC controls on chip.
 	  This driver provides common support for accessing the device;
 	  This driver provides common support for accessing the device;
@@ -397,7 +411,7 @@ config MFD_MAX8998
 	select MFD_CORE
 	select MFD_CORE
 	select IRQ_DOMAIN
 	select IRQ_DOMAIN
 	help
 	help
-	  Say yes here to support for Maxim Semiconductor MAX8998 and
+	  Say yes here to add support for Maxim Semiconductor MAX8998 and
 	  National Semiconductor LP3974. This is a Power Management IC.
 	  National Semiconductor LP3974. This is a Power Management IC.
 	  This driver provides common support for accessing the device,
 	  This driver provides common support for accessing the device,
 	  additional drivers must be enabled in order to use the functionality
 	  additional drivers must be enabled in order to use the functionality
@@ -473,10 +487,11 @@ config MFD_PM8XXX
 
 
 config MFD_PM8921_CORE
 config MFD_PM8921_CORE
 	tristate "Qualcomm PM8921 PMIC chip"
 	tristate "Qualcomm PM8921 PMIC chip"
-	depends on (ARCH_MSM || HEXAGON)
-	depends on BROKEN
+	depends on (ARM || HEXAGON)
+	select IRQ_DOMAIN
 	select MFD_CORE
 	select MFD_CORE
 	select MFD_PM8XXX
 	select MFD_PM8XXX
+	select REGMAP
 	help
 	help
 	  If you say yes to this option, support will be included for the
 	  If you say yes to this option, support will be included for the
 	  built-in PM8921 PMIC chip.
 	  built-in PM8921 PMIC chip.
@@ -487,16 +502,6 @@ config MFD_PM8921_CORE
 	  Say M here if you want to include support for PM8921 chip as a module.
 	  Say M here if you want to include support for PM8921 chip as a module.
 	  This will build a module called "pm8921-core".
 	  This will build a module called "pm8921-core".
 
 
-config MFD_PM8XXX_IRQ
-	bool "Qualcomm PM8xxx IRQ features"
-	depends on MFD_PM8XXX
-	default y if MFD_PM8XXX
-	help
-	  This is the IRQ driver for Qualcomm PM 8xxx PMIC chips.
-
-	  This is required to use certain other PM 8xxx features, such as GPIO
-	  and MPP.
-
 config MFD_RDC321X
 config MFD_RDC321X
 	tristate "RDC R-321x southbridge"
 	tristate "RDC R-321x southbridge"
 	select MFD_CORE
 	select MFD_CORE
@@ -516,6 +521,16 @@ config MFD_RTSX_PCI
 	  types of memory cards, such as Memory Stick, Memory Stick Pro,
 	  types of memory cards, such as Memory Stick, Memory Stick Pro,
 	  Secure Digital and MultiMediaCard.
 	  Secure Digital and MultiMediaCard.
 
 
+config MFD_RTSX_USB
+	tristate "Realtek USB card reader"
+	depends on USB
+	select MFD_CORE
+	help
+	  Select this option to get support for Realtek USB 2.0 card readers
+	  including RTS5129, RTS5139, RTS5179 and RTS5170.
+	  Realtek card reader supports access to many types of memory cards,
+	  such as Memory Stick Pro, Secure Digital and MultiMediaCard.
+
 config MFD_RC5T583
 config MFD_RC5T583
 	bool "Ricoh RC5T583 Power Management system device"
 	bool "Ricoh RC5T583 Power Management system device"
 	depends on I2C=y
 	depends on I2C=y
@@ -774,17 +789,6 @@ config MFD_PALMAS
 	  If you say yes here you get support for the Palmas
 	  If you say yes here you get support for the Palmas
 	  series of PMIC chips from Texas Instruments.
 	  series of PMIC chips from Texas Instruments.
 
 
-config MFD_TI_SSP
-	tristate "TI Sequencer Serial Port support"
-	depends on ARCH_DAVINCI_TNETV107X
-	select MFD_CORE
-	---help---
-	  Say Y here if you want support for the Sequencer Serial Port
-	  in a Texas Instruments TNETV107X SoC.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called ti-ssp.
-
 config TPS6105X
 config TPS6105X
 	tristate "TI TPS61050/61052 Boost Converters"
 	tristate "TI TPS61050/61052 Boost Converters"
 	depends on I2C
 	depends on I2C
@@ -853,6 +857,22 @@ config MFD_TPS65217
 	  This driver can also be built as a module.  If so, the module
 	  This driver can also be built as a module.  If so, the module
 	  will be called tps65217.
 	  will be called tps65217.
 
 
+config MFD_TPS65218
+	tristate "TI TPS65218 Power Management chips"
+	depends on I2C
+	select MFD_CORE
+	select REGMAP_I2C
+	select REGMAP_IRQ
+	help
+	  If you say yes here you get support for the TPS65218 series of
+	  Power Management chips.
+	  These include voltage regulators, gpio and other features
+	  that are often used in portable devices. Only regulator
+	  component is currently supported.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called tps65218.
+
 config MFD_TPS6586X
 config MFD_TPS6586X
 	bool "TI TPS6586x Power Management chips"
 	bool "TI TPS6586x Power Management chips"
 	depends on I2C=y
 	depends on I2C=y
@@ -935,16 +955,6 @@ config TWL4030_CORE
 	  high speed USB OTG transceiver, an audio codec (on most
 	  high speed USB OTG transceiver, an audio codec (on most
 	  versions) and many other features.
 	  versions) and many other features.
 
 
-config TWL4030_MADC
-	tristate "TI TWL4030 MADC"
-	depends on TWL4030_CORE
-	help
-	This driver provides support for triton TWL4030-MADC. The
-	driver supports both RT and SW conversion methods.
-
-	This driver can be built as a module. If so it will be
-	named twl4030-madc
-
 config TWL4030_POWER
 config TWL4030_POWER
 	bool "TI TWL4030 power resources"
 	bool "TI TWL4030 power resources"
 	depends on TWL4030_CORE && ARM
 	depends on TWL4030_CORE && ARM
@@ -1193,9 +1203,6 @@ config MFD_STW481X
 	  in various ST Microelectronics and ST-Ericsson embedded
 	  in various ST Microelectronics and ST-Ericsson embedded
 	  Nomadik series.
 	  Nomadik series.
 
 
-endmenu
-endif
-
 menu "Multimedia Capabilities Port drivers"
 menu "Multimedia Capabilities Port drivers"
 	depends on ARCH_SA1100
 	depends on ARCH_SA1100
 
 
@@ -1226,3 +1233,6 @@ config VEXPRESS_CONFIG
 	help
 	help
 	  Platform configuration infrastructure for the ARM Ltd.
 	  Platform configuration infrastructure for the ARM Ltd.
 	  Versatile Express.
 	  Versatile Express.
+
+endmenu
+endif

+ 3 - 3
drivers/mfd/Makefile

@@ -8,12 +8,14 @@ obj-$(CONFIG_MFD_88PM800)	+= 88pm800.o 88pm80x.o
 obj-$(CONFIG_MFD_88PM805)	+= 88pm805.o 88pm80x.o
 obj-$(CONFIG_MFD_88PM805)	+= 88pm805.o 88pm80x.o
 obj-$(CONFIG_MFD_SM501)		+= sm501.o
 obj-$(CONFIG_MFD_SM501)		+= sm501.o
 obj-$(CONFIG_MFD_ASIC3)		+= asic3.o tmio_core.o
 obj-$(CONFIG_MFD_ASIC3)		+= asic3.o tmio_core.o
+obj-$(CONFIG_MFD_BCM590XX)	+= bcm590xx.o
 obj-$(CONFIG_MFD_CROS_EC)	+= cros_ec.o
 obj-$(CONFIG_MFD_CROS_EC)	+= cros_ec.o
 obj-$(CONFIG_MFD_CROS_EC_I2C)	+= cros_ec_i2c.o
 obj-$(CONFIG_MFD_CROS_EC_I2C)	+= cros_ec_i2c.o
 obj-$(CONFIG_MFD_CROS_EC_SPI)	+= cros_ec_spi.o
 obj-$(CONFIG_MFD_CROS_EC_SPI)	+= cros_ec_spi.o
 
 
 rtsx_pci-objs			:= rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5249.o
 rtsx_pci-objs			:= rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5249.o
 obj-$(CONFIG_MFD_RTSX_PCI)	+= rtsx_pci.o
 obj-$(CONFIG_MFD_RTSX_PCI)	+= rtsx_pci.o
+obj-$(CONFIG_MFD_RTSX_USB)	+= rtsx_usb.o
 
 
 obj-$(CONFIG_HTC_EGPIO)		+= htc-egpio.o
 obj-$(CONFIG_HTC_EGPIO)		+= htc-egpio.o
 obj-$(CONFIG_HTC_PASIC3)	+= htc-pasic3.o
 obj-$(CONFIG_HTC_PASIC3)	+= htc-pasic3.o
@@ -21,7 +23,6 @@ obj-$(CONFIG_HTC_I2CPLD)	+= htc-i2cpld.o
 
 
 obj-$(CONFIG_MFD_DAVINCI_VOICECODEC)	+= davinci_voicecodec.o
 obj-$(CONFIG_MFD_DAVINCI_VOICECODEC)	+= davinci_voicecodec.o
 obj-$(CONFIG_MFD_DM355EVM_MSP)	+= dm355evm_msp.o
 obj-$(CONFIG_MFD_DM355EVM_MSP)	+= dm355evm_msp.o
-obj-$(CONFIG_MFD_TI_SSP)	+= ti-ssp.o
 obj-$(CONFIG_MFD_TI_AM335X_TSCADC)	+= ti_am335x_tscadc.o
 obj-$(CONFIG_MFD_TI_AM335X_TSCADC)	+= ti_am335x_tscadc.o
 
 
 obj-$(CONFIG_MFD_STA2X11)	+= sta2x11-mfd.o
 obj-$(CONFIG_MFD_STA2X11)	+= sta2x11-mfd.o
@@ -62,6 +63,7 @@ obj-$(CONFIG_TPS6105X)		+= tps6105x.o
 obj-$(CONFIG_TPS65010)		+= tps65010.o
 obj-$(CONFIG_TPS65010)		+= tps65010.o
 obj-$(CONFIG_TPS6507X)		+= tps6507x.o
 obj-$(CONFIG_TPS6507X)		+= tps6507x.o
 obj-$(CONFIG_MFD_TPS65217)	+= tps65217.o
 obj-$(CONFIG_MFD_TPS65217)	+= tps65217.o
+obj-$(CONFIG_MFD_TPS65218)	+= tps65218.o
 obj-$(CONFIG_MFD_TPS65910)	+= tps65910.o
 obj-$(CONFIG_MFD_TPS65910)	+= tps65910.o
 tps65912-objs                   := tps65912-core.o tps65912-irq.o
 tps65912-objs                   := tps65912-core.o tps65912-irq.o
 obj-$(CONFIG_MFD_TPS65912)	+= tps65912.o
 obj-$(CONFIG_MFD_TPS65912)	+= tps65912.o
@@ -71,7 +73,6 @@ obj-$(CONFIG_MFD_TPS80031)	+= tps80031.o
 obj-$(CONFIG_MENELAUS)		+= menelaus.o
 obj-$(CONFIG_MENELAUS)		+= menelaus.o
 
 
 obj-$(CONFIG_TWL4030_CORE)	+= twl-core.o twl4030-irq.o twl6030-irq.o
 obj-$(CONFIG_TWL4030_CORE)	+= twl-core.o twl4030-irq.o twl6030-irq.o
-obj-$(CONFIG_TWL4030_MADC)      += twl4030-madc.o
 obj-$(CONFIG_TWL4030_POWER)    += twl4030-power.o
 obj-$(CONFIG_TWL4030_POWER)    += twl4030-power.o
 obj-$(CONFIG_MFD_TWL4030_AUDIO)	+= twl4030-audio.o
 obj-$(CONFIG_MFD_TWL4030_AUDIO)	+= twl4030-audio.o
 obj-$(CONFIG_TWL6040_CORE)	+= twl6040.o
 obj-$(CONFIG_TWL6040_CORE)	+= twl6040.o
@@ -150,7 +151,6 @@ obj-$(CONFIG_MFD_SI476X_CORE)	+= si476x-core.o
 obj-$(CONFIG_MFD_CS5535)	+= cs5535-mfd.o
 obj-$(CONFIG_MFD_CS5535)	+= cs5535-mfd.o
 obj-$(CONFIG_MFD_OMAP_USB_HOST)	+= omap-usb-host.o omap-usb-tll.o
 obj-$(CONFIG_MFD_OMAP_USB_HOST)	+= omap-usb-host.o omap-usb-tll.o
 obj-$(CONFIG_MFD_PM8921_CORE) 	+= pm8921-core.o ssbi.o
 obj-$(CONFIG_MFD_PM8921_CORE) 	+= pm8921-core.o ssbi.o
-obj-$(CONFIG_MFD_PM8XXX_IRQ) 	+= pm8xxx-irq.o
 obj-$(CONFIG_TPS65911_COMPARATOR)	+= tps65911-comparator.o
 obj-$(CONFIG_TPS65911_COMPARATOR)	+= tps65911-comparator.o
 obj-$(CONFIG_MFD_TPS65090)	+= tps65090.o
 obj-$(CONFIG_MFD_TPS65090)	+= tps65090.o
 obj-$(CONFIG_MFD_AAT2870_CORE)	+= aat2870-core.o
 obj-$(CONFIG_MFD_AAT2870_CORE)	+= aat2870-core.o

+ 0 - 1
drivers/mfd/adp5520.c

@@ -20,7 +20,6 @@
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
-#include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/irq.h>

+ 1 - 0
drivers/mfd/as3722.c

@@ -277,6 +277,7 @@ static const struct regmap_range as3722_readable_ranges[] = {
 	regmap_reg_range(AS3722_ADC0_CONTROL_REG, AS3722_ADC_CONFIGURATION_REG),
 	regmap_reg_range(AS3722_ADC0_CONTROL_REG, AS3722_ADC_CONFIGURATION_REG),
 	regmap_reg_range(AS3722_ASIC_ID1_REG, AS3722_ASIC_ID2_REG),
 	regmap_reg_range(AS3722_ASIC_ID1_REG, AS3722_ASIC_ID2_REG),
 	regmap_reg_range(AS3722_LOCK_REG, AS3722_LOCK_REG),
 	regmap_reg_range(AS3722_LOCK_REG, AS3722_LOCK_REG),
+	regmap_reg_range(AS3722_FUSE7_REG, AS3722_FUSE7_REG),
 };
 };
 
 
 static const struct regmap_access_table as3722_readable_table = {
 static const struct regmap_access_table as3722_readable_table = {

+ 93 - 0
drivers/mfd/bcm590xx.c

@@ -0,0 +1,93 @@
+/*
+ * Broadcom BCM590xx PMU
+ *
+ * Copyright 2014 Linaro Limited
+ * Author: Matt Porter <mporter@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under  the terms of the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/mfd/bcm590xx.h>
+#include <linux/mfd/core.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+static const struct mfd_cell bcm590xx_devs[] = {
+	{
+		.name = "bcm590xx-vregs",
+	},
+};
+
+static const struct regmap_config bcm590xx_regmap_config = {
+	.reg_bits	= 8,
+	.val_bits	= 8,
+	.max_register	= BCM590XX_MAX_REGISTER,
+	.cache_type	= REGCACHE_RBTREE,
+};
+
+static int bcm590xx_i2c_probe(struct i2c_client *i2c,
+			      const struct i2c_device_id *id)
+{
+	struct bcm590xx *bcm590xx;
+	int ret;
+
+	bcm590xx = devm_kzalloc(&i2c->dev, sizeof(*bcm590xx), GFP_KERNEL);
+	if (!bcm590xx)
+		return -ENOMEM;
+
+	i2c_set_clientdata(i2c, bcm590xx);
+	bcm590xx->dev = &i2c->dev;
+	bcm590xx->i2c_client = i2c;
+
+	bcm590xx->regmap = devm_regmap_init_i2c(i2c, &bcm590xx_regmap_config);
+	if (IS_ERR(bcm590xx->regmap)) {
+		ret = PTR_ERR(bcm590xx->regmap);
+		dev_err(&i2c->dev, "regmap initialization failed: %d\n", ret);
+		return ret;
+	}
+
+	ret = mfd_add_devices(&i2c->dev, -1, bcm590xx_devs,
+			      ARRAY_SIZE(bcm590xx_devs), NULL, 0, NULL);
+	if (ret < 0)
+		dev_err(&i2c->dev, "failed to add sub-devices: %d\n", ret);
+
+	return ret;
+}
+
+static const struct of_device_id bcm590xx_of_match[] = {
+	{ .compatible = "brcm,bcm59056" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, bcm590xx_of_match);
+
+static const struct i2c_device_id bcm590xx_i2c_id[] = {
+	{ "bcm59056" },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, bcm590xx_i2c_id);
+
+static struct i2c_driver bcm590xx_i2c_driver = {
+	.driver = {
+		   .name = "bcm590xx",
+		   .owner = THIS_MODULE,
+		   .of_match_table = of_match_ptr(bcm590xx_of_match),
+	},
+	.probe = bcm590xx_i2c_probe,
+	.id_table = bcm590xx_i2c_id,
+};
+module_i2c_driver(bcm590xx_i2c_driver);
+
+MODULE_AUTHOR("Matt Porter <mporter@linaro.org>");
+MODULE_DESCRIPTION("BCM590xx multi-function driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:bcm590xx");

+ 0 - 1
drivers/mfd/cs5535-mfd.c

@@ -23,7 +23,6 @@
  */
  */
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
-#include <linux/init.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/core.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/pci.h>

+ 3 - 0
drivers/mfd/da9052-core.c

@@ -279,6 +279,9 @@ static bool da9052_reg_volatile(struct device *dev, unsigned int reg)
 	case DA9052_EVENT_B_REG:
 	case DA9052_EVENT_B_REG:
 	case DA9052_EVENT_C_REG:
 	case DA9052_EVENT_C_REG:
 	case DA9052_EVENT_D_REG:
 	case DA9052_EVENT_D_REG:
+	case DA9052_CONTROL_B_REG:
+	case DA9052_CONTROL_D_REG:
+	case DA9052_SUPPLY_REG:
 	case DA9052_FAULTLOG_REG:
 	case DA9052_FAULTLOG_REG:
 	case DA9052_CHG_TIME_REG:
 	case DA9052_CHG_TIME_REG:
 	case DA9052_ADC_RES_L_REG:
 	case DA9052_ADC_RES_L_REG:

+ 4 - 1
drivers/mfd/da9052-i2c.c

@@ -75,6 +75,7 @@ static int da9052_i2c_fix(struct da9052 *da9052, unsigned char reg)
 					   DA9052_PARK_REGISTER,
 					   DA9052_PARK_REGISTER,
 					   &val);
 					   &val);
 		break;
 		break;
+	case DA9053_BC:
 	default:
 	default:
 		/*
 		/*
 		 * For other chips parking of I2C register
 		 * For other chips parking of I2C register
@@ -114,6 +115,7 @@ static const struct i2c_device_id da9052_i2c_id[] = {
 	{"da9053-aa", DA9053_AA},
 	{"da9053-aa", DA9053_AA},
 	{"da9053-ba", DA9053_BA},
 	{"da9053-ba", DA9053_BA},
 	{"da9053-bb", DA9053_BB},
 	{"da9053-bb", DA9053_BB},
+	{"da9053-bc", DA9053_BC},
 	{}
 	{}
 };
 };
 
 
@@ -121,8 +123,9 @@ static const struct i2c_device_id da9052_i2c_id[] = {
 static const struct of_device_id dialog_dt_ids[] = {
 static const struct of_device_id dialog_dt_ids[] = {
 	{ .compatible = "dlg,da9052", .data = &da9052_i2c_id[0] },
 	{ .compatible = "dlg,da9052", .data = &da9052_i2c_id[0] },
 	{ .compatible = "dlg,da9053-aa", .data = &da9052_i2c_id[1] },
 	{ .compatible = "dlg,da9053-aa", .data = &da9052_i2c_id[1] },
-	{ .compatible = "dlg,da9053-ab", .data = &da9052_i2c_id[2] },
+	{ .compatible = "dlg,da9053-ba", .data = &da9052_i2c_id[2] },
 	{ .compatible = "dlg,da9053-bb", .data = &da9052_i2c_id[3] },
 	{ .compatible = "dlg,da9053-bb", .data = &da9052_i2c_id[3] },
+	{ .compatible = "dlg,da9053-bc", .data = &da9052_i2c_id[4] },
 	{ /* sentinel */ }
 	{ /* sentinel */ }
 };
 };
 #endif
 #endif

+ 1 - 0
drivers/mfd/da9052-spi.c

@@ -71,6 +71,7 @@ static struct spi_device_id da9052_spi_id[] = {
 	{"da9053-aa", DA9053_AA},
 	{"da9053-aa", DA9053_AA},
 	{"da9053-ba", DA9053_BA},
 	{"da9053-ba", DA9053_BA},
 	{"da9053-bb", DA9053_BB},
 	{"da9053-bb", DA9053_BB},
+	{"da9053-bc", DA9053_BC},
 	{}
 	{}
 };
 };
 
 

+ 8 - 0
drivers/mfd/da9055-i2c.c

@@ -15,6 +15,8 @@
 #include <linux/device.h>
 #include <linux/device.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
 #include <linux/err.h>
 #include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 
 #include <linux/mfd/da9055/core.h>
 #include <linux/mfd/da9055/core.h>
 
 
@@ -66,6 +68,11 @@ static struct i2c_device_id da9055_i2c_id[] = {
 };
 };
 MODULE_DEVICE_TABLE(i2c, da9055_i2c_id);
 MODULE_DEVICE_TABLE(i2c, da9055_i2c_id);
 
 
+static const struct of_device_id da9055_of_match[] = {
+	{ .compatible = "dlg,da9055-pmic", },
+	{ }
+};
+
 static struct i2c_driver da9055_i2c_driver = {
 static struct i2c_driver da9055_i2c_driver = {
 	.probe = da9055_i2c_probe,
 	.probe = da9055_i2c_probe,
 	.remove = da9055_i2c_remove,
 	.remove = da9055_i2c_remove,
@@ -73,6 +80,7 @@ static struct i2c_driver da9055_i2c_driver = {
 	.driver = {
 	.driver = {
 		.name = "da9055-pmic",
 		.name = "da9055-pmic",
 		.owner = THIS_MODULE,
 		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(da9055_of_match),
 	},
 	},
 };
 };
 
 

+ 14 - 11
drivers/mfd/da9063-core.c

@@ -110,7 +110,7 @@ static const struct mfd_cell da9063_devs[] = {
 int da9063_device_init(struct da9063 *da9063, unsigned int irq)
 int da9063_device_init(struct da9063 *da9063, unsigned int irq)
 {
 {
 	struct da9063_pdata *pdata = da9063->dev->platform_data;
 	struct da9063_pdata *pdata = da9063->dev->platform_data;
-	int model, revision;
+	int model, variant_id, variant_code;
 	int ret;
 	int ret;
 
 
 	if (pdata) {
 	if (pdata) {
@@ -141,23 +141,26 @@ int da9063_device_init(struct da9063 *da9063, unsigned int irq)
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
 
 
-	ret = regmap_read(da9063->regmap, DA9063_REG_CHIP_VARIANT, &revision);
+	ret = regmap_read(da9063->regmap, DA9063_REG_CHIP_VARIANT, &variant_id);
 	if (ret < 0) {
 	if (ret < 0) {
-		dev_err(da9063->dev, "Cannot read chip revision id.\n");
+		dev_err(da9063->dev, "Cannot read chip variant id.\n");
 		return -EIO;
 		return -EIO;
 	}
 	}
-	revision >>= DA9063_CHIP_VARIANT_SHIFT;
-	if (revision != 3) {
-		dev_err(da9063->dev, "Unknown chip revision: %d\n", revision);
+
+	variant_code = variant_id >> DA9063_CHIP_VARIANT_SHIFT;
+
+	dev_info(da9063->dev,
+		 "Device detected (chip-ID: 0x%02X, var-ID: 0x%02X)\n",
+		 model, variant_id);
+
+	if (variant_code != PMIC_DA9063_BB) {
+		dev_err(da9063->dev, "Unknown chip variant code: 0x%02X\n",
+				variant_code);
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
 
 
 	da9063->model = model;
 	da9063->model = model;
-	da9063->revision = revision;
-
-	dev_info(da9063->dev,
-		 "Device detected (model-ID: 0x%02X  rev-ID: 0x%02X)\n",
-		 model, revision);
+	da9063->variant_code = variant_code;
 
 
 	ret = da9063_irq_init(da9063);
 	ret = da9063_irq_init(da9063);
 	if (ret) {
 	if (ret) {

+ 0 - 1
drivers/mfd/janz-cmodio.c

@@ -13,7 +13,6 @@
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/delay.h>

+ 29 - 2
drivers/mfd/kempld-core.c

@@ -322,9 +322,12 @@ static int kempld_detect_device(struct kempld_device_data *pld)
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
 
 
-	/* Release hardware mutex if aquired */
-	if (!(index_reg & KEMPLD_MUTEX_KEY))
+	/* Release hardware mutex if acquired */
+	if (!(index_reg & KEMPLD_MUTEX_KEY)) {
 		iowrite8(KEMPLD_MUTEX_KEY, pld->io_index);
 		iowrite8(KEMPLD_MUTEX_KEY, pld->io_index);
+		/* PXT and COMe-cPC2 boards may require a second release */
+		iowrite8(KEMPLD_MUTEX_KEY, pld->io_index);
+	}
 
 
 	mutex_unlock(&pld->lock);
 	mutex_unlock(&pld->lock);
 
 
@@ -437,6 +440,14 @@ static struct dmi_system_id __initdata kempld_dmi_table[] = {
 		},
 		},
 		.driver_data = (void *)&kempld_platform_data_generic,
 		.driver_data = (void *)&kempld_platform_data_generic,
 		.callback = kempld_create_platform_device,
 		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "CHL6",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "COMe-cHL6"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
 	}, {
 	}, {
 		.ident = "CHR2",
 		.ident = "CHR2",
 		.matches = {
 		.matches = {
@@ -509,6 +520,14 @@ static struct dmi_system_id __initdata kempld_dmi_table[] = {
 		},
 		},
 		.driver_data = (void *)&kempld_platform_data_generic,
 		.driver_data = (void *)&kempld_platform_data_generic,
 		.callback = kempld_create_platform_device,
 		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "CVV6",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "COMe-cBT"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
 	}, {
 	}, {
 		.ident = "FRI2",
 		.ident = "FRI2",
 		.matches = {
 		.matches = {
@@ -532,6 +551,14 @@ static struct dmi_system_id __initdata kempld_dmi_table[] = {
 		},
 		},
 		.driver_data = (void *)&kempld_platform_data_generic,
 		.driver_data = (void *)&kempld_platform_data_generic,
 		.callback = kempld_create_platform_device,
 		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "MVV1",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "COMe-mBT"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
 	}, {
 	}, {
 		.ident = "NTC1",
 		.ident = "NTC1",
 		.matches = {
 		.matches = {

+ 108 - 43
drivers/mfd/lpc_ich.c

@@ -58,7 +58,6 @@
 
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/errno.h>
@@ -72,9 +71,11 @@
 #define ACPIBASE_GPE_END	0x2f
 #define ACPIBASE_GPE_END	0x2f
 #define ACPIBASE_SMI_OFF	0x30
 #define ACPIBASE_SMI_OFF	0x30
 #define ACPIBASE_SMI_END	0x33
 #define ACPIBASE_SMI_END	0x33
+#define ACPIBASE_PMC_OFF	0x08
+#define ACPIBASE_PMC_END	0x0c
 #define ACPIBASE_TCO_OFF	0x60
 #define ACPIBASE_TCO_OFF	0x60
 #define ACPIBASE_TCO_END	0x7f
 #define ACPIBASE_TCO_END	0x7f
-#define ACPICTRL		0x44
+#define ACPICTRL_PMCBASE	0x44
 
 
 #define ACPIBASE_GCS_OFF	0x3410
 #define ACPIBASE_GCS_OFF	0x3410
 #define ACPIBASE_GCS_END	0x3414
 #define ACPIBASE_GCS_END	0x3414
@@ -90,16 +91,17 @@
 #define wdt_mem_res(i) wdt_res(ICH_RES_MEM_OFF, i)
 #define wdt_mem_res(i) wdt_res(ICH_RES_MEM_OFF, i)
 #define wdt_res(b, i) (&wdt_ich_res[(b) + (i)])
 #define wdt_res(b, i) (&wdt_ich_res[(b) + (i)])
 
 
-struct lpc_ich_cfg {
-	int base;
-	int ctrl;
-	int save;
-};
-
 struct lpc_ich_priv {
 struct lpc_ich_priv {
 	int chipset;
 	int chipset;
-	struct lpc_ich_cfg acpi;
-	struct lpc_ich_cfg gpio;
+
+	int abase;		/* ACPI base */
+	int actrl_pbase;	/* ACPI control or PMC base */
+	int gbase;		/* GPIO base */
+	int gctrl;		/* GPIO control */
+
+	int abase_save;		/* Cached ACPI base value */
+	int actrl_pbase_save;		/* Cached ACPI control or PMC base value */
+	int gctrl_save;		/* Cached GPIO control value */
 };
 };
 
 
 static struct resource wdt_ich_res[] = {
 static struct resource wdt_ich_res[] = {
@@ -111,7 +113,7 @@ static struct resource wdt_ich_res[] = {
 	{
 	{
 		.flags = IORESOURCE_IO,
 		.flags = IORESOURCE_IO,
 	},
 	},
-	/* GCS */
+	/* GCS or PMC */
 	{
 	{
 		.flags = IORESOURCE_MEM,
 		.flags = IORESOURCE_MEM,
 	},
 	},
@@ -211,6 +213,7 @@ enum lpc_chipsets {
 	LPC_LPT_LP,	/* Lynx Point-LP */
 	LPC_LPT_LP,	/* Lynx Point-LP */
 	LPC_WBG,	/* Wellsburg */
 	LPC_WBG,	/* Wellsburg */
 	LPC_AVN,	/* Avoton SoC */
 	LPC_AVN,	/* Avoton SoC */
+	LPC_BAYTRAIL,   /* Bay Trail SoC */
 	LPC_COLETO,	/* Coleto Creek */
 	LPC_COLETO,	/* Coleto Creek */
 	LPC_WPT_LP,	/* Wildcat Point-LP */
 	LPC_WPT_LP,	/* Wildcat Point-LP */
 };
 };
@@ -303,6 +306,7 @@ static struct lpc_ich_info lpc_chipset_info[] = {
 	[LPC_NM10] = {
 	[LPC_NM10] = {
 		.name = "NM10",
 		.name = "NM10",
 		.iTCO_version = 2,
 		.iTCO_version = 2,
+		.gpio_version = ICH_V7_GPIO,
 	},
 	},
 	[LPC_ICH8] = {
 	[LPC_ICH8] = {
 		.name = "ICH8 or ICH8R",
 		.name = "ICH8 or ICH8R",
@@ -499,7 +503,12 @@ static struct lpc_ich_info lpc_chipset_info[] = {
 	},
 	},
 	[LPC_AVN] = {
 	[LPC_AVN] = {
 		.name = "Avoton SoC",
 		.name = "Avoton SoC",
-		.iTCO_version = 1,
+		.iTCO_version = 3,
+		.gpio_version = AVOTON_GPIO,
+	},
+	[LPC_BAYTRAIL] = {
+		.name = "Bay Trail SoC",
+		.iTCO_version = 3,
 	},
 	},
 	[LPC_COLETO] = {
 	[LPC_COLETO] = {
 		.name = "Coleto Creek",
 		.name = "Coleto Creek",
@@ -726,6 +735,7 @@ static const struct pci_device_id lpc_ich_ids[] = {
 	{ PCI_VDEVICE(INTEL, 0x1f39), LPC_AVN},
 	{ PCI_VDEVICE(INTEL, 0x1f39), LPC_AVN},
 	{ PCI_VDEVICE(INTEL, 0x1f3a), LPC_AVN},
 	{ PCI_VDEVICE(INTEL, 0x1f3a), LPC_AVN},
 	{ PCI_VDEVICE(INTEL, 0x1f3b), LPC_AVN},
 	{ PCI_VDEVICE(INTEL, 0x1f3b), LPC_AVN},
+	{ PCI_VDEVICE(INTEL, 0x0f1c), LPC_BAYTRAIL},
 	{ PCI_VDEVICE(INTEL, 0x2390), LPC_COLETO},
 	{ PCI_VDEVICE(INTEL, 0x2390), LPC_COLETO},
 	{ PCI_VDEVICE(INTEL, 0x9cc1), LPC_WPT_LP},
 	{ PCI_VDEVICE(INTEL, 0x9cc1), LPC_WPT_LP},
 	{ PCI_VDEVICE(INTEL, 0x9cc2), LPC_WPT_LP},
 	{ PCI_VDEVICE(INTEL, 0x9cc2), LPC_WPT_LP},
@@ -742,14 +752,20 @@ static void lpc_ich_restore_config_space(struct pci_dev *dev)
 {
 {
 	struct lpc_ich_priv *priv = pci_get_drvdata(dev);
 	struct lpc_ich_priv *priv = pci_get_drvdata(dev);
 
 
-	if (priv->acpi.save >= 0) {
-		pci_write_config_byte(dev, priv->acpi.ctrl, priv->acpi.save);
-		priv->acpi.save = -1;
+	if (priv->abase_save >= 0) {
+		pci_write_config_byte(dev, priv->abase, priv->abase_save);
+		priv->abase_save = -1;
+	}
+
+	if (priv->actrl_pbase_save >= 0) {
+		pci_write_config_byte(dev, priv->actrl_pbase,
+			priv->actrl_pbase_save);
+		priv->actrl_pbase_save = -1;
 	}
 	}
 
 
-	if (priv->gpio.save >= 0) {
-		pci_write_config_byte(dev, priv->gpio.ctrl, priv->gpio.save);
-		priv->gpio.save = -1;
+	if (priv->gctrl_save >= 0) {
+		pci_write_config_byte(dev, priv->gctrl, priv->gctrl_save);
+		priv->gctrl_save = -1;
 	}
 	}
 }
 }
 
 
@@ -758,9 +774,26 @@ static void lpc_ich_enable_acpi_space(struct pci_dev *dev)
 	struct lpc_ich_priv *priv = pci_get_drvdata(dev);
 	struct lpc_ich_priv *priv = pci_get_drvdata(dev);
 	u8 reg_save;
 	u8 reg_save;
 
 
-	pci_read_config_byte(dev, priv->acpi.ctrl, &reg_save);
-	pci_write_config_byte(dev, priv->acpi.ctrl, reg_save | 0x10);
-	priv->acpi.save = reg_save;
+	switch (lpc_chipset_info[priv->chipset].iTCO_version) {
+	case 3:
+		/*
+		 * Some chipsets (eg Avoton) enable the ACPI space in the
+		 * ACPI BASE register.
+		 */
+		pci_read_config_byte(dev, priv->abase, &reg_save);
+		pci_write_config_byte(dev, priv->abase, reg_save | 0x2);
+		priv->abase_save = reg_save;
+		break;
+	default:
+		/*
+		 * Most chipsets enable the ACPI space in the ACPI control
+		 * register.
+		 */
+		pci_read_config_byte(dev, priv->actrl_pbase, &reg_save);
+		pci_write_config_byte(dev, priv->actrl_pbase, reg_save | 0x80);
+		priv->actrl_pbase_save = reg_save;
+		break;
+	}
 }
 }
 
 
 static void lpc_ich_enable_gpio_space(struct pci_dev *dev)
 static void lpc_ich_enable_gpio_space(struct pci_dev *dev)
@@ -768,9 +801,20 @@ static void lpc_ich_enable_gpio_space(struct pci_dev *dev)
 	struct lpc_ich_priv *priv = pci_get_drvdata(dev);
 	struct lpc_ich_priv *priv = pci_get_drvdata(dev);
 	u8 reg_save;
 	u8 reg_save;
 
 
-	pci_read_config_byte(dev, priv->gpio.ctrl, &reg_save);
-	pci_write_config_byte(dev, priv->gpio.ctrl, reg_save | 0x10);
-	priv->gpio.save = reg_save;
+	pci_read_config_byte(dev, priv->gctrl, &reg_save);
+	pci_write_config_byte(dev, priv->gctrl, reg_save | 0x10);
+	priv->gctrl_save = reg_save;
+}
+
+static void lpc_ich_enable_pmc_space(struct pci_dev *dev)
+{
+	struct lpc_ich_priv *priv = pci_get_drvdata(dev);
+	u8 reg_save;
+
+	pci_read_config_byte(dev, priv->actrl_pbase, &reg_save);
+	pci_write_config_byte(dev, priv->actrl_pbase, reg_save | 0x2);
+
+	priv->actrl_pbase_save = reg_save;
 }
 }
 
 
 static void lpc_ich_finalize_cell(struct pci_dev *dev, struct mfd_cell *cell)
 static void lpc_ich_finalize_cell(struct pci_dev *dev, struct mfd_cell *cell)
@@ -815,7 +859,7 @@ static int lpc_ich_init_gpio(struct pci_dev *dev)
 	struct resource *res;
 	struct resource *res;
 
 
 	/* Setup power management base register */
 	/* Setup power management base register */
-	pci_read_config_dword(dev, priv->acpi.base, &base_addr_cfg);
+	pci_read_config_dword(dev, priv->abase, &base_addr_cfg);
 	base_addr = base_addr_cfg & 0x0000ff80;
 	base_addr = base_addr_cfg & 0x0000ff80;
 	if (!base_addr) {
 	if (!base_addr) {
 		dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n");
 		dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n");
@@ -841,7 +885,7 @@ static int lpc_ich_init_gpio(struct pci_dev *dev)
 
 
 gpe0_done:
 gpe0_done:
 	/* Setup GPIO base register */
 	/* Setup GPIO base register */
-	pci_read_config_dword(dev, priv->gpio.base, &base_addr_cfg);
+	pci_read_config_dword(dev, priv->gbase, &base_addr_cfg);
 	base_addr = base_addr_cfg & 0x0000ff80;
 	base_addr = base_addr_cfg & 0x0000ff80;
 	if (!base_addr) {
 	if (!base_addr) {
 		dev_notice(&dev->dev, "I/O space for GPIO uninitialized\n");
 		dev_notice(&dev->dev, "I/O space for GPIO uninitialized\n");
@@ -891,7 +935,7 @@ static int lpc_ich_init_wdt(struct pci_dev *dev)
 	struct resource *res;
 	struct resource *res;
 
 
 	/* Setup power management base register */
 	/* Setup power management base register */
-	pci_read_config_dword(dev, priv->acpi.base, &base_addr_cfg);
+	pci_read_config_dword(dev, priv->abase, &base_addr_cfg);
 	base_addr = base_addr_cfg & 0x0000ff80;
 	base_addr = base_addr_cfg & 0x0000ff80;
 	if (!base_addr) {
 	if (!base_addr) {
 		dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n");
 		dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n");
@@ -910,14 +954,20 @@ static int lpc_ich_init_wdt(struct pci_dev *dev)
 	lpc_ich_enable_acpi_space(dev);
 	lpc_ich_enable_acpi_space(dev);
 
 
 	/*
 	/*
+	 * iTCO v2:
 	 * Get the Memory-Mapped GCS register. To get access to it
 	 * Get the Memory-Mapped GCS register. To get access to it
 	 * we have to read RCBA from PCI Config space 0xf0 and use
 	 * we have to read RCBA from PCI Config space 0xf0 and use
 	 * it as base. GCS = RCBA + ICH6_GCS(0x3410).
 	 * it as base. GCS = RCBA + ICH6_GCS(0x3410).
+	 *
+	 * iTCO v3:
+	 * Get the Power Management Configuration register.  To get access
+	 * to it we have to read the PMC BASE from config space and address
+	 * the register at offset 0x8.
 	 */
 	 */
 	if (lpc_chipset_info[priv->chipset].iTCO_version == 1) {
 	if (lpc_chipset_info[priv->chipset].iTCO_version == 1) {
 		/* Don't register iomem for TCO ver 1 */
 		/* Don't register iomem for TCO ver 1 */
 		lpc_ich_cells[LPC_WDT].num_resources--;
 		lpc_ich_cells[LPC_WDT].num_resources--;
-	} else {
+	} else if (lpc_chipset_info[priv->chipset].iTCO_version == 2) {
 		pci_read_config_dword(dev, RCBABASE, &base_addr_cfg);
 		pci_read_config_dword(dev, RCBABASE, &base_addr_cfg);
 		base_addr = base_addr_cfg & 0xffffc000;
 		base_addr = base_addr_cfg & 0xffffc000;
 		if (!(base_addr_cfg & 1)) {
 		if (!(base_addr_cfg & 1)) {
@@ -926,9 +976,17 @@ static int lpc_ich_init_wdt(struct pci_dev *dev)
 			ret = -ENODEV;
 			ret = -ENODEV;
 			goto wdt_done;
 			goto wdt_done;
 		}
 		}
-		res = wdt_mem_res(ICH_RES_MEM_GCS);
+		res = wdt_mem_res(ICH_RES_MEM_GCS_PMC);
 		res->start = base_addr + ACPIBASE_GCS_OFF;
 		res->start = base_addr + ACPIBASE_GCS_OFF;
 		res->end = base_addr + ACPIBASE_GCS_END;
 		res->end = base_addr + ACPIBASE_GCS_END;
+	} else if (lpc_chipset_info[priv->chipset].iTCO_version == 3) {
+		lpc_ich_enable_pmc_space(dev);
+		pci_read_config_dword(dev, ACPICTRL_PMCBASE, &base_addr_cfg);
+		base_addr = base_addr_cfg & 0xfffffe00;
+
+		res = wdt_mem_res(ICH_RES_MEM_GCS_PMC);
+		res->start = base_addr + ACPIBASE_PMC_OFF;
+		res->end = base_addr + ACPIBASE_PMC_END;
 	}
 	}
 
 
 	lpc_ich_finalize_cell(dev, &lpc_ich_cells[LPC_WDT]);
 	lpc_ich_finalize_cell(dev, &lpc_ich_cells[LPC_WDT]);
@@ -952,28 +1010,35 @@ static int lpc_ich_probe(struct pci_dev *dev,
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	priv->chipset = id->driver_data;
 	priv->chipset = id->driver_data;
-	priv->acpi.save = -1;
-	priv->acpi.base = ACPIBASE;
-	priv->acpi.ctrl = ACPICTRL;
 
 
-	priv->gpio.save = -1;
+	priv->actrl_pbase_save = -1;
+	priv->abase_save = -1;
+
+	priv->abase = ACPIBASE;
+	priv->actrl_pbase = ACPICTRL_PMCBASE;
+
+	priv->gctrl_save = -1;
 	if (priv->chipset <= LPC_ICH5) {
 	if (priv->chipset <= LPC_ICH5) {
-		priv->gpio.base = GPIOBASE_ICH0;
-		priv->gpio.ctrl = GPIOCTRL_ICH0;
+		priv->gbase = GPIOBASE_ICH0;
+		priv->gctrl = GPIOCTRL_ICH0;
 	} else {
 	} else {
-		priv->gpio.base = GPIOBASE_ICH6;
-		priv->gpio.ctrl = GPIOCTRL_ICH6;
+		priv->gbase = GPIOBASE_ICH6;
+		priv->gctrl = GPIOCTRL_ICH6;
 	}
 	}
 
 
 	pci_set_drvdata(dev, priv);
 	pci_set_drvdata(dev, priv);
 
 
-	ret = lpc_ich_init_wdt(dev);
-	if (!ret)
-		cell_added = true;
+	if (lpc_chipset_info[priv->chipset].iTCO_version) {
+		ret = lpc_ich_init_wdt(dev);
+		if (!ret)
+			cell_added = true;
+	}
 
 
-	ret = lpc_ich_init_gpio(dev);
-	if (!ret)
-		cell_added = true;
+	if (lpc_chipset_info[priv->chipset].gpio_version) {
+		ret = lpc_ich_init_gpio(dev);
+		if (!ret)
+			cell_added = true;
+	}
 
 
 	/*
 	/*
 	 * We only care if at least one or none of the cells registered
 	 * We only care if at least one or none of the cells registered

+ 0 - 1
drivers/mfd/lpc_sch.c

@@ -23,7 +23,6 @@
  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  */
  */
 
 
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/errno.h>

+ 5 - 1
drivers/mfd/max14577.c

@@ -18,6 +18,7 @@
  * This driver is based on max8997.c
  * This driver is based on max8997.c
  */
  */
 
 
+#include <linux/err.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/core.h>
@@ -25,7 +26,10 @@
 #include <linux/mfd/max14577-private.h>
 #include <linux/mfd/max14577-private.h>
 
 
 static struct mfd_cell max14577_devs[] = {
 static struct mfd_cell max14577_devs[] = {
-	{ .name = "max14577-muic", },
+	{
+		.name = "max14577-muic",
+		.of_compatible = "maxim,max14577-muic",
+	},
 	{
 	{
 		.name = "max14577-regulator",
 		.name = "max14577-regulator",
 		.of_compatible = "maxim,max14577-regulator",
 		.of_compatible = "maxim,max14577-regulator",

+ 4 - 0
drivers/mfd/max77686.c

@@ -121,6 +121,10 @@ static int max77686_i2c_probe(struct i2c_client *i2c,
 		dev_info(max77686->dev, "device found\n");
 		dev_info(max77686->dev, "device found\n");
 
 
 	max77686->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC);
 	max77686->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC);
+	if (!max77686->rtc) {
+		dev_err(max77686->dev, "Failed to allocate I2C device for RTC\n");
+		return -ENODEV;
+	}
 	i2c_set_clientdata(max77686->rtc, max77686);
 	i2c_set_clientdata(max77686->rtc, max77686);
 
 
 	max77686_irq_init(max77686);
 	max77686_irq_init(max77686);

+ 11 - 1
drivers/mfd/max77693.c

@@ -148,9 +148,18 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
 		dev_info(max77693->dev, "device ID: 0x%x\n", reg_data);
 		dev_info(max77693->dev, "device ID: 0x%x\n", reg_data);
 
 
 	max77693->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC);
 	max77693->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC);
+	if (!max77693->muic) {
+		dev_err(max77693->dev, "Failed to allocate I2C device for MUIC\n");
+		return -ENODEV;
+	}
 	i2c_set_clientdata(max77693->muic, max77693);
 	i2c_set_clientdata(max77693->muic, max77693);
 
 
 	max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC);
 	max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC);
+	if (!max77693->haptic) {
+		dev_err(max77693->dev, "Failed to allocate I2C device for Haptic\n");
+		ret = -ENODEV;
+		goto err_i2c_haptic;
+	}
 	i2c_set_clientdata(max77693->haptic, max77693);
 	i2c_set_clientdata(max77693->haptic, max77693);
 
 
 	/*
 	/*
@@ -184,8 +193,9 @@ err_mfd:
 	max77693_irq_exit(max77693);
 	max77693_irq_exit(max77693);
 err_irq:
 err_irq:
 err_regmap_muic:
 err_regmap_muic:
-	i2c_unregister_device(max77693->muic);
 	i2c_unregister_device(max77693->haptic);
 	i2c_unregister_device(max77693->haptic);
+err_i2c_haptic:
+	i2c_unregister_device(max77693->muic);
 	return ret;
 	return ret;
 }
 }
 
 

+ 9 - 0
drivers/mfd/max8925-i2c.c

@@ -181,9 +181,18 @@ static int max8925_probe(struct i2c_client *client,
 	mutex_init(&chip->io_lock);
 	mutex_init(&chip->io_lock);
 
 
 	chip->rtc = i2c_new_dummy(chip->i2c->adapter, RTC_I2C_ADDR);
 	chip->rtc = i2c_new_dummy(chip->i2c->adapter, RTC_I2C_ADDR);
+	if (!chip->rtc) {
+		dev_err(chip->dev, "Failed to allocate I2C device for RTC\n");
+		return -ENODEV;
+	}
 	i2c_set_clientdata(chip->rtc, chip);
 	i2c_set_clientdata(chip->rtc, chip);
 
 
 	chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR);
 	chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR);
+	if (!chip->adc) {
+		dev_err(chip->dev, "Failed to allocate I2C device for ADC\n");
+		i2c_unregister_device(chip->rtc);
+		return -ENODEV;
+	}
 	i2c_set_clientdata(chip->adc, chip);
 	i2c_set_clientdata(chip->adc, chip);
 
 
 	device_init_wakeup(&client->dev, 1);
 	device_init_wakeup(&client->dev, 1);

+ 18 - 0
drivers/mfd/max8997.c

@@ -208,10 +208,26 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
 	mutex_init(&max8997->iolock);
 	mutex_init(&max8997->iolock);
 
 
 	max8997->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC);
 	max8997->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC);
+	if (!max8997->rtc) {
+		dev_err(max8997->dev, "Failed to allocate I2C device for RTC\n");
+		return -ENODEV;
+	}
 	i2c_set_clientdata(max8997->rtc, max8997);
 	i2c_set_clientdata(max8997->rtc, max8997);
+
 	max8997->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC);
 	max8997->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC);
+	if (!max8997->haptic) {
+		dev_err(max8997->dev, "Failed to allocate I2C device for Haptic\n");
+		ret = -ENODEV;
+		goto err_i2c_haptic;
+	}
 	i2c_set_clientdata(max8997->haptic, max8997);
 	i2c_set_clientdata(max8997->haptic, max8997);
+
 	max8997->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC);
 	max8997->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC);
+	if (!max8997->muic) {
+		dev_err(max8997->dev, "Failed to allocate I2C device for MUIC\n");
+		ret = -ENODEV;
+		goto err_i2c_muic;
+	}
 	i2c_set_clientdata(max8997->muic, max8997);
 	i2c_set_clientdata(max8997->muic, max8997);
 
 
 	pm_runtime_set_active(max8997->dev);
 	pm_runtime_set_active(max8997->dev);
@@ -239,7 +255,9 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
 err_mfd:
 err_mfd:
 	mfd_remove_devices(max8997->dev);
 	mfd_remove_devices(max8997->dev);
 	i2c_unregister_device(max8997->muic);
 	i2c_unregister_device(max8997->muic);
+err_i2c_muic:
 	i2c_unregister_device(max8997->haptic);
 	i2c_unregister_device(max8997->haptic);
+err_i2c_haptic:
 	i2c_unregister_device(max8997->rtc);
 	i2c_unregister_device(max8997->rtc);
 	return ret;
 	return ret;
 }
 }

+ 4 - 0
drivers/mfd/max8998.c

@@ -215,6 +215,10 @@ static int max8998_i2c_probe(struct i2c_client *i2c,
 	mutex_init(&max8998->iolock);
 	mutex_init(&max8998->iolock);
 
 
 	max8998->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR);
 	max8998->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR);
+	if (!max8998->rtc) {
+		dev_err(&i2c->dev, "Failed to allocate I2C device for RTC\n");
+		return -ENODEV;
+	}
 	i2c_set_clientdata(max8998->rtc, max8998);
 	i2c_set_clientdata(max8998->rtc, max8998);
 
 
 	max8998_irq_init(max8998);
 	max8998_irq_init(max8998);

+ 5 - 0
drivers/mfd/mc13xxx-spi.c

@@ -140,6 +140,11 @@ static int mc13xxx_spi_probe(struct spi_device *spi)
 
 
 	mc13xxx->irq = spi->irq;
 	mc13xxx->irq = spi->irq;
 
 
+	spi->max_speed_hz = spi->max_speed_hz ? : 26000000;
+	ret = spi_setup(spi);
+	if (ret)
+		return ret;
+
 	mc13xxx->regmap = devm_regmap_init(&spi->dev, &regmap_mc13xxx_bus,
 	mc13xxx->regmap = devm_regmap_init(&spi->dev, &regmap_mc13xxx_bus,
 					   &spi->dev,
 					   &spi->dev,
 					   &mc13xxx_regmap_spi_config);
 					   &mc13xxx_regmap_spi_config);

+ 0 - 1
drivers/mfd/mcp-sa11x0.c

@@ -12,7 +12,6 @@
  *  MCP read/write timeouts from Jordi Colomer, rehacked by rmk.
  *  MCP read/write timeouts from Jordi Colomer, rehacked by rmk.
  */
  */
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/errno.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>

+ 90 - 99
drivers/mfd/omap-usb-host.c

@@ -665,55 +665,78 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 		goto err_mem;
 		goto err_mem;
 	}
 	}
 
 
-	need_logic_fck = false;
+	/* Set all clocks as invalid to begin with */
+	omap->ehci_logic_fck = ERR_PTR(-ENODEV);
+	omap->init_60m_fclk = ERR_PTR(-ENODEV);
+	omap->utmi_p1_gfclk = ERR_PTR(-ENODEV);
+	omap->utmi_p2_gfclk = ERR_PTR(-ENODEV);
+	omap->xclk60mhsp1_ck = ERR_PTR(-ENODEV);
+	omap->xclk60mhsp2_ck = ERR_PTR(-ENODEV);
+
 	for (i = 0; i < omap->nports; i++) {
 	for (i = 0; i < omap->nports; i++) {
-		if (is_ehci_phy_mode(i) || is_ehci_tll_mode(i) ||
-			is_ehci_hsic_mode(i))
-				need_logic_fck |= true;
+		omap->utmi_clk[i] = ERR_PTR(-ENODEV);
+		omap->hsic480m_clk[i] = ERR_PTR(-ENODEV);
+		omap->hsic60m_clk[i] = ERR_PTR(-ENODEV);
 	}
 	}
 
 
-	omap->ehci_logic_fck = ERR_PTR(-EINVAL);
-	if (need_logic_fck) {
-		omap->ehci_logic_fck = clk_get(dev, "ehci_logic_fck");
-		if (IS_ERR(omap->ehci_logic_fck)) {
-			ret = PTR_ERR(omap->ehci_logic_fck);
-			dev_dbg(dev, "ehci_logic_fck failed:%d\n", ret);
+	/* for OMAP3 i.e. USBHS REV1 */
+	if (omap->usbhs_rev == OMAP_USBHS_REV1) {
+		need_logic_fck = false;
+		for (i = 0; i < omap->nports; i++) {
+			if (is_ehci_phy_mode(pdata->port_mode[i]) ||
+			    is_ehci_tll_mode(pdata->port_mode[i]) ||
+			    is_ehci_hsic_mode(pdata->port_mode[i]))
+
+				need_logic_fck |= true;
 		}
 		}
+
+		if (need_logic_fck) {
+			omap->ehci_logic_fck = devm_clk_get(dev,
+							    "usbhost_120m_fck");
+			if (IS_ERR(omap->ehci_logic_fck)) {
+				ret = PTR_ERR(omap->ehci_logic_fck);
+				dev_err(dev, "usbhost_120m_fck failed:%d\n",
+					ret);
+				goto err_mem;
+			}
+		}
+		goto initialize;
 	}
 	}
 
 
-	omap->utmi_p1_gfclk = clk_get(dev, "utmi_p1_gfclk");
+	/* for OMAP4+ i.e. USBHS REV2+ */
+	omap->utmi_p1_gfclk = devm_clk_get(dev, "utmi_p1_gfclk");
 	if (IS_ERR(omap->utmi_p1_gfclk)) {
 	if (IS_ERR(omap->utmi_p1_gfclk)) {
 		ret = PTR_ERR(omap->utmi_p1_gfclk);
 		ret = PTR_ERR(omap->utmi_p1_gfclk);
 		dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret);
 		dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret);
-		goto err_p1_gfclk;
+		goto err_mem;
 	}
 	}
 
 
-	omap->utmi_p2_gfclk = clk_get(dev, "utmi_p2_gfclk");
+	omap->utmi_p2_gfclk = devm_clk_get(dev, "utmi_p2_gfclk");
 	if (IS_ERR(omap->utmi_p2_gfclk)) {
 	if (IS_ERR(omap->utmi_p2_gfclk)) {
 		ret = PTR_ERR(omap->utmi_p2_gfclk);
 		ret = PTR_ERR(omap->utmi_p2_gfclk);
 		dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
 		dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
-		goto err_p2_gfclk;
+		goto err_mem;
 	}
 	}
 
 
-	omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
+	omap->xclk60mhsp1_ck = devm_clk_get(dev, "refclk_60m_ext_p1");
 	if (IS_ERR(omap->xclk60mhsp1_ck)) {
 	if (IS_ERR(omap->xclk60mhsp1_ck)) {
 		ret = PTR_ERR(omap->xclk60mhsp1_ck);
 		ret = PTR_ERR(omap->xclk60mhsp1_ck);
-		dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret);
-		goto err_xclk60mhsp1;
+		dev_err(dev, "refclk_60m_ext_p1 failed error:%d\n", ret);
+		goto err_mem;
 	}
 	}
 
 
-	omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck");
+	omap->xclk60mhsp2_ck = devm_clk_get(dev, "refclk_60m_ext_p2");
 	if (IS_ERR(omap->xclk60mhsp2_ck)) {
 	if (IS_ERR(omap->xclk60mhsp2_ck)) {
 		ret = PTR_ERR(omap->xclk60mhsp2_ck);
 		ret = PTR_ERR(omap->xclk60mhsp2_ck);
-		dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret);
-		goto err_xclk60mhsp2;
+		dev_err(dev, "refclk_60m_ext_p2 failed error:%d\n", ret);
+		goto err_mem;
 	}
 	}
 
 
-	omap->init_60m_fclk = clk_get(dev, "init_60m_fclk");
+	omap->init_60m_fclk = devm_clk_get(dev, "refclk_60m_int");
 	if (IS_ERR(omap->init_60m_fclk)) {
 	if (IS_ERR(omap->init_60m_fclk)) {
 		ret = PTR_ERR(omap->init_60m_fclk);
 		ret = PTR_ERR(omap->init_60m_fclk);
-		dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
-		goto err_init60m;
+		dev_err(dev, "refclk_60m_int failed error:%d\n", ret);
+		goto err_mem;
 	}
 	}
 
 
 	for (i = 0; i < omap->nports; i++) {
 	for (i = 0; i < omap->nports; i++) {
@@ -727,55 +750,72 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 		 * platforms have all clocks and we can function without
 		 * platforms have all clocks and we can function without
 		 * them
 		 * them
 		 */
 		 */
-		omap->utmi_clk[i] = clk_get(dev, clkname);
-		if (IS_ERR(omap->utmi_clk[i]))
-			dev_dbg(dev, "Failed to get clock : %s : %ld\n",
-				clkname, PTR_ERR(omap->utmi_clk[i]));
+		omap->utmi_clk[i] = devm_clk_get(dev, clkname);
+		if (IS_ERR(omap->utmi_clk[i])) {
+			ret = PTR_ERR(omap->utmi_clk[i]);
+			dev_err(dev, "Failed to get clock : %s : %d\n",
+				clkname, ret);
+			goto err_mem;
+		}
 
 
 		snprintf(clkname, sizeof(clkname),
 		snprintf(clkname, sizeof(clkname),
 				"usb_host_hs_hsic480m_p%d_clk", i + 1);
 				"usb_host_hs_hsic480m_p%d_clk", i + 1);
-		omap->hsic480m_clk[i] = clk_get(dev, clkname);
-		if (IS_ERR(omap->hsic480m_clk[i]))
-			dev_dbg(dev, "Failed to get clock : %s : %ld\n",
-				clkname, PTR_ERR(omap->hsic480m_clk[i]));
+		omap->hsic480m_clk[i] = devm_clk_get(dev, clkname);
+		if (IS_ERR(omap->hsic480m_clk[i])) {
+			ret = PTR_ERR(omap->hsic480m_clk[i]);
+			dev_err(dev, "Failed to get clock : %s : %d\n",
+				clkname, ret);
+			goto err_mem;
+		}
 
 
 		snprintf(clkname, sizeof(clkname),
 		snprintf(clkname, sizeof(clkname),
 				"usb_host_hs_hsic60m_p%d_clk", i + 1);
 				"usb_host_hs_hsic60m_p%d_clk", i + 1);
-		omap->hsic60m_clk[i] = clk_get(dev, clkname);
-		if (IS_ERR(omap->hsic60m_clk[i]))
-			dev_dbg(dev, "Failed to get clock : %s : %ld\n",
-				clkname, PTR_ERR(omap->hsic60m_clk[i]));
+		omap->hsic60m_clk[i] = devm_clk_get(dev, clkname);
+		if (IS_ERR(omap->hsic60m_clk[i])) {
+			ret = PTR_ERR(omap->hsic60m_clk[i]);
+			dev_err(dev, "Failed to get clock : %s : %d\n",
+				clkname, ret);
+			goto err_mem;
+		}
 	}
 	}
 
 
 	if (is_ehci_phy_mode(pdata->port_mode[0])) {
 	if (is_ehci_phy_mode(pdata->port_mode[0])) {
-		/* for OMAP3, clk_set_parent fails */
 		ret = clk_set_parent(omap->utmi_p1_gfclk,
 		ret = clk_set_parent(omap->utmi_p1_gfclk,
 					omap->xclk60mhsp1_ck);
 					omap->xclk60mhsp1_ck);
-		if (ret != 0)
-			dev_dbg(dev, "xclk60mhsp1_ck set parent failed: %d\n",
-					ret);
+		if (ret != 0) {
+			dev_err(dev, "xclk60mhsp1_ck set parent failed: %d\n",
+				ret);
+			goto err_mem;
+		}
 	} else if (is_ehci_tll_mode(pdata->port_mode[0])) {
 	} else if (is_ehci_tll_mode(pdata->port_mode[0])) {
 		ret = clk_set_parent(omap->utmi_p1_gfclk,
 		ret = clk_set_parent(omap->utmi_p1_gfclk,
 					omap->init_60m_fclk);
 					omap->init_60m_fclk);
-		if (ret != 0)
-			dev_dbg(dev, "P0 init_60m_fclk set parent failed: %d\n",
-					ret);
+		if (ret != 0) {
+			dev_err(dev, "P0 init_60m_fclk set parent failed: %d\n",
+				ret);
+			goto err_mem;
+		}
 	}
 	}
 
 
 	if (is_ehci_phy_mode(pdata->port_mode[1])) {
 	if (is_ehci_phy_mode(pdata->port_mode[1])) {
 		ret = clk_set_parent(omap->utmi_p2_gfclk,
 		ret = clk_set_parent(omap->utmi_p2_gfclk,
 					omap->xclk60mhsp2_ck);
 					omap->xclk60mhsp2_ck);
-		if (ret != 0)
-			dev_dbg(dev, "xclk60mhsp2_ck set parent failed: %d\n",
-					ret);
+		if (ret != 0) {
+			dev_err(dev, "xclk60mhsp2_ck set parent failed: %d\n",
+				ret);
+			goto err_mem;
+		}
 	} else if (is_ehci_tll_mode(pdata->port_mode[1])) {
 	} else if (is_ehci_tll_mode(pdata->port_mode[1])) {
 		ret = clk_set_parent(omap->utmi_p2_gfclk,
 		ret = clk_set_parent(omap->utmi_p2_gfclk,
 						omap->init_60m_fclk);
 						omap->init_60m_fclk);
-		if (ret != 0)
-			dev_dbg(dev, "P1 init_60m_fclk set parent failed: %d\n",
-					ret);
+		if (ret != 0) {
+			dev_err(dev, "P1 init_60m_fclk set parent failed: %d\n",
+				ret);
+			goto err_mem;
+		}
 	}
 	}
 
 
+initialize:
 	omap_usbhs_init(dev);
 	omap_usbhs_init(dev);
 
 
 	if (dev->of_node) {
 	if (dev->of_node) {
@@ -784,7 +824,7 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 
 
 		if (ret) {
 		if (ret) {
 			dev_err(dev, "Failed to create DT children: %d\n", ret);
 			dev_err(dev, "Failed to create DT children: %d\n", ret);
-			goto err_alloc;
+			goto err_mem;
 		}
 		}
 
 
 	} else {
 	} else {
@@ -792,40 +832,12 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 		if (ret) {
 		if (ret) {
 			dev_err(dev, "omap_usbhs_alloc_children failed: %d\n",
 			dev_err(dev, "omap_usbhs_alloc_children failed: %d\n",
 						ret);
 						ret);
-			goto err_alloc;
+			goto err_mem;
 		}
 		}
 	}
 	}
 
 
 	return 0;
 	return 0;
 
 
-err_alloc:
-	for (i = 0; i < omap->nports; i++) {
-		if (!IS_ERR(omap->utmi_clk[i]))
-			clk_put(omap->utmi_clk[i]);
-		if (!IS_ERR(omap->hsic60m_clk[i]))
-			clk_put(omap->hsic60m_clk[i]);
-		if (!IS_ERR(omap->hsic480m_clk[i]))
-			clk_put(omap->hsic480m_clk[i]);
-	}
-
-	clk_put(omap->init_60m_fclk);
-
-err_init60m:
-	clk_put(omap->xclk60mhsp2_ck);
-
-err_xclk60mhsp2:
-	clk_put(omap->xclk60mhsp1_ck);
-
-err_xclk60mhsp1:
-	clk_put(omap->utmi_p2_gfclk);
-
-err_p2_gfclk:
-	clk_put(omap->utmi_p1_gfclk);
-
-err_p1_gfclk:
-	if (!IS_ERR(omap->ehci_logic_fck))
-		clk_put(omap->ehci_logic_fck);
-
 err_mem:
 err_mem:
 	pm_runtime_disable(dev);
 	pm_runtime_disable(dev);
 
 
@@ -847,27 +859,6 @@ static int usbhs_omap_remove_child(struct device *dev, void *data)
  */
  */
 static int usbhs_omap_remove(struct platform_device *pdev)
 static int usbhs_omap_remove(struct platform_device *pdev)
 {
 {
-	struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
-	int i;
-
-	for (i = 0; i < omap->nports; i++) {
-		if (!IS_ERR(omap->utmi_clk[i]))
-			clk_put(omap->utmi_clk[i]);
-		if (!IS_ERR(omap->hsic60m_clk[i]))
-			clk_put(omap->hsic60m_clk[i]);
-		if (!IS_ERR(omap->hsic480m_clk[i]))
-			clk_put(omap->hsic480m_clk[i]);
-	}
-
-	clk_put(omap->init_60m_fclk);
-	clk_put(omap->utmi_p1_gfclk);
-	clk_put(omap->utmi_p2_gfclk);
-	clk_put(omap->xclk60mhsp2_ck);
-	clk_put(omap->xclk60mhsp1_ck);
-
-	if (!IS_ERR(omap->ehci_logic_fck))
-		clk_put(omap->ehci_logic_fck);
-
 	pm_runtime_disable(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
 
 	/* remove children */
 	/* remove children */

+ 1 - 1
drivers/mfd/omap-usb-tll.c

@@ -252,7 +252,7 @@ static int usbtll_omap_probe(struct platform_device *pdev)
 		break;
 		break;
 	}
 	}
 
 
-	tll->ch_clk = devm_kzalloc(dev, sizeof(struct clk * [tll->nch]),
+	tll->ch_clk = devm_kzalloc(dev, sizeof(struct clk *) * tll->nch,
 						GFP_KERNEL);
 						GFP_KERNEL);
 	if (!tll->ch_clk) {
 	if (!tll->ch_clk) {
 		ret = -ENOMEM;
 		ret = -ENOMEM;

+ 0 - 1
drivers/mfd/pcf50633-adc.c

@@ -19,7 +19,6 @@
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/device.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/completion.h>
 #include <linux/completion.h>

+ 365 - 54
drivers/mfd/pm8921-core.c

@@ -14,23 +14,316 @@
 #define pr_fmt(fmt) "%s: " fmt, __func__
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/err.h>
 #include <linux/ssbi.h>
 #include <linux/ssbi.h>
+#include <linux/regmap.h>
+#include <linux/of_platform.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/core.h>
-#include <linux/mfd/pm8xxx/pm8921.h>
 #include <linux/mfd/pm8xxx/core.h>
 #include <linux/mfd/pm8xxx/core.h>
 
 
+#define	SSBI_REG_ADDR_IRQ_BASE		0x1BB
+
+#define	SSBI_REG_ADDR_IRQ_ROOT		(SSBI_REG_ADDR_IRQ_BASE + 0)
+#define	SSBI_REG_ADDR_IRQ_M_STATUS1	(SSBI_REG_ADDR_IRQ_BASE + 1)
+#define	SSBI_REG_ADDR_IRQ_M_STATUS2	(SSBI_REG_ADDR_IRQ_BASE + 2)
+#define	SSBI_REG_ADDR_IRQ_M_STATUS3	(SSBI_REG_ADDR_IRQ_BASE + 3)
+#define	SSBI_REG_ADDR_IRQ_M_STATUS4	(SSBI_REG_ADDR_IRQ_BASE + 4)
+#define	SSBI_REG_ADDR_IRQ_BLK_SEL	(SSBI_REG_ADDR_IRQ_BASE + 5)
+#define	SSBI_REG_ADDR_IRQ_IT_STATUS	(SSBI_REG_ADDR_IRQ_BASE + 6)
+#define	SSBI_REG_ADDR_IRQ_CONFIG	(SSBI_REG_ADDR_IRQ_BASE + 7)
+#define	SSBI_REG_ADDR_IRQ_RT_STATUS	(SSBI_REG_ADDR_IRQ_BASE + 8)
+
+#define	PM_IRQF_LVL_SEL			0x01	/* level select */
+#define	PM_IRQF_MASK_FE			0x02	/* mask falling edge */
+#define	PM_IRQF_MASK_RE			0x04	/* mask rising edge */
+#define	PM_IRQF_CLR			0x08	/* clear interrupt */
+#define	PM_IRQF_BITS_MASK		0x70
+#define	PM_IRQF_BITS_SHIFT		4
+#define	PM_IRQF_WRITE			0x80
+
+#define	PM_IRQF_MASK_ALL		(PM_IRQF_MASK_FE | \
+					PM_IRQF_MASK_RE)
+
 #define REG_HWREV		0x002  /* PMIC4 revision */
 #define REG_HWREV		0x002  /* PMIC4 revision */
 #define REG_HWREV_2		0x0E8  /* PMIC4 revision 2 */
 #define REG_HWREV_2		0x0E8  /* PMIC4 revision 2 */
 
 
+#define PM8921_NR_IRQS		256
+
+struct pm_irq_chip {
+	struct device		*dev;
+	struct regmap		*regmap;
+	spinlock_t		pm_irq_lock;
+	struct irq_domain	*irqdomain;
+	unsigned int		num_irqs;
+	unsigned int		num_blocks;
+	unsigned int		num_masters;
+	u8			config[0];
+};
+
 struct pm8921 {
 struct pm8921 {
 	struct device			*dev;
 	struct device			*dev;
 	struct pm_irq_chip		*irq_chip;
 	struct pm_irq_chip		*irq_chip;
 };
 };
 
 
+static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, unsigned int bp,
+				 unsigned int *ip)
+{
+	int	rc;
+
+	spin_lock(&chip->pm_irq_lock);
+	rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, bp);
+	if (rc) {
+		pr_err("Failed Selecting Block %d rc=%d\n", bp, rc);
+		goto bail;
+	}
+
+	rc = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_IT_STATUS, ip);
+	if (rc)
+		pr_err("Failed Reading Status rc=%d\n", rc);
+bail:
+	spin_unlock(&chip->pm_irq_lock);
+	return rc;
+}
+
+static int
+pm8xxx_config_irq(struct pm_irq_chip *chip, unsigned int bp, unsigned int cp)
+{
+	int	rc;
+
+	spin_lock(&chip->pm_irq_lock);
+	rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, bp);
+	if (rc) {
+		pr_err("Failed Selecting Block %d rc=%d\n", bp, rc);
+		goto bail;
+	}
+
+	cp |= PM_IRQF_WRITE;
+	rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_CONFIG, cp);
+	if (rc)
+		pr_err("Failed Configuring IRQ rc=%d\n", rc);
+bail:
+	spin_unlock(&chip->pm_irq_lock);
+	return rc;
+}
+
+static int pm8xxx_irq_block_handler(struct pm_irq_chip *chip, int block)
+{
+	int pmirq, irq, i, ret = 0;
+	unsigned int bits;
+
+	ret = pm8xxx_read_block_irq(chip, block, &bits);
+	if (ret) {
+		pr_err("Failed reading %d block ret=%d", block, ret);
+		return ret;
+	}
+	if (!bits) {
+		pr_err("block bit set in master but no irqs: %d", block);
+		return 0;
+	}
+
+	/* Check IRQ bits */
+	for (i = 0; i < 8; i++) {
+		if (bits & (1 << i)) {
+			pmirq = block * 8 + i;
+			irq = irq_find_mapping(chip->irqdomain, pmirq);
+			generic_handle_irq(irq);
+		}
+	}
+	return 0;
+}
+
+static int pm8xxx_irq_master_handler(struct pm_irq_chip *chip, int master)
+{
+	unsigned int blockbits;
+	int block_number, i, ret = 0;
+
+	ret = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_M_STATUS1 + master,
+			  &blockbits);
+	if (ret) {
+		pr_err("Failed to read master %d ret=%d\n", master, ret);
+		return ret;
+	}
+	if (!blockbits) {
+		pr_err("master bit set in root but no blocks: %d", master);
+		return 0;
+	}
+
+	for (i = 0; i < 8; i++)
+		if (blockbits & (1 << i)) {
+			block_number = master * 8 + i;	/* block # */
+			ret |= pm8xxx_irq_block_handler(chip, block_number);
+		}
+	return ret;
+}
+
+static void pm8xxx_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	struct pm_irq_chip *chip = irq_desc_get_handler_data(desc);
+	struct irq_chip *irq_chip = irq_desc_get_chip(desc);
+	unsigned int root;
+	int	i, ret, masters = 0;
+
+	chained_irq_enter(irq_chip, desc);
+
+	ret = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_ROOT, &root);
+	if (ret) {
+		pr_err("Can't read root status ret=%d\n", ret);
+		return;
+	}
+
+	/* on pm8xxx series masters start from bit 1 of the root */
+	masters = root >> 1;
+
+	/* Read allowed masters for blocks. */
+	for (i = 0; i < chip->num_masters; i++)
+		if (masters & (1 << i))
+			pm8xxx_irq_master_handler(chip, i);
+
+	chained_irq_exit(irq_chip, desc);
+}
+
+static void pm8xxx_irq_mask_ack(struct irq_data *d)
+{
+	struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
+	unsigned int pmirq = irqd_to_hwirq(d);
+	int	irq_bit;
+	u8	block, config;
+
+	block = pmirq / 8;
+	irq_bit = pmirq % 8;
+
+	config = chip->config[pmirq] | PM_IRQF_MASK_ALL | PM_IRQF_CLR;
+	pm8xxx_config_irq(chip, block, config);
+}
+
+static void pm8xxx_irq_unmask(struct irq_data *d)
+{
+	struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
+	unsigned int pmirq = irqd_to_hwirq(d);
+	int	irq_bit;
+	u8	block, config;
+
+	block = pmirq / 8;
+	irq_bit = pmirq % 8;
+
+	config = chip->config[pmirq];
+	pm8xxx_config_irq(chip, block, config);
+}
+
+static int pm8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
+{
+	struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
+	unsigned int pmirq = irqd_to_hwirq(d);
+	int irq_bit;
+	u8 block, config;
+
+	block = pmirq / 8;
+	irq_bit  = pmirq % 8;
+
+	chip->config[pmirq] = (irq_bit << PM_IRQF_BITS_SHIFT)
+							| PM_IRQF_MASK_ALL;
+	if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
+		if (flow_type & IRQF_TRIGGER_RISING)
+			chip->config[pmirq] &= ~PM_IRQF_MASK_RE;
+		if (flow_type & IRQF_TRIGGER_FALLING)
+			chip->config[pmirq] &= ~PM_IRQF_MASK_FE;
+	} else {
+		chip->config[pmirq] |= PM_IRQF_LVL_SEL;
+
+		if (flow_type & IRQF_TRIGGER_HIGH)
+			chip->config[pmirq] &= ~PM_IRQF_MASK_RE;
+		else
+			chip->config[pmirq] &= ~PM_IRQF_MASK_FE;
+	}
+
+	config = chip->config[pmirq] | PM_IRQF_CLR;
+	return pm8xxx_config_irq(chip, block, config);
+}
+
+static struct irq_chip pm8xxx_irq_chip = {
+	.name		= "pm8xxx",
+	.irq_mask_ack	= pm8xxx_irq_mask_ack,
+	.irq_unmask	= pm8xxx_irq_unmask,
+	.irq_set_type	= pm8xxx_irq_set_type,
+	.flags		= IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
+};
+
+/**
+ * pm8xxx_get_irq_stat - get the status of the irq line
+ * @chip: pointer to identify a pmic irq controller
+ * @irq: the irq number
+ *
+ * The pm8xxx gpio and mpp rely on the interrupt block to read
+ * the values on their pins. This function is to facilitate reading
+ * the status of a gpio or an mpp line. The caller has to convert the
+ * gpio number to irq number.
+ *
+ * RETURNS:
+ * an int indicating the value read on that line
+ */
+static int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq)
+{
+	int pmirq, rc;
+	unsigned int  block, bits, bit;
+	unsigned long flags;
+	struct irq_data *irq_data = irq_get_irq_data(irq);
+
+	pmirq = irq_data->hwirq;
+
+	block = pmirq / 8;
+	bit = pmirq % 8;
+
+	spin_lock_irqsave(&chip->pm_irq_lock, flags);
+
+	rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, block);
+	if (rc) {
+		pr_err("Failed Selecting block irq=%d pmirq=%d blk=%d rc=%d\n",
+			irq, pmirq, block, rc);
+		goto bail_out;
+	}
+
+	rc = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits);
+	if (rc) {
+		pr_err("Failed Configuring irq=%d pmirq=%d blk=%d rc=%d\n",
+			irq, pmirq, block, rc);
+		goto bail_out;
+	}
+
+	rc = (bits & (1 << bit)) ? 1 : 0;
+
+bail_out:
+	spin_unlock_irqrestore(&chip->pm_irq_lock, flags);
+
+	return rc;
+}
+
+static int pm8xxx_irq_domain_map(struct irq_domain *d, unsigned int irq,
+				   irq_hw_number_t hwirq)
+{
+	struct pm_irq_chip *chip = d->host_data;
+
+	irq_set_chip_and_handler(irq, &pm8xxx_irq_chip, handle_level_irq);
+	irq_set_chip_data(irq, chip);
+#ifdef CONFIG_ARM
+	set_irq_flags(irq, IRQF_VALID);
+#else
+	irq_set_noprobe(irq);
+#endif
+	return 0;
+}
+
+static const struct irq_domain_ops pm8xxx_irq_domain_ops = {
+	.xlate = irq_domain_xlate_twocell,
+	.map = pm8xxx_irq_domain_map,
+};
+
 static int pm8921_readb(const struct device *dev, u16 addr, u8 *val)
 static int pm8921_readb(const struct device *dev, u16 addr, u8 *val)
 {
 {
 	const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
 	const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
@@ -81,42 +374,35 @@ static struct pm8xxx_drvdata pm8921_drvdata = {
 	.pmic_read_irq_stat	= pm8921_read_irq_stat,
 	.pmic_read_irq_stat	= pm8921_read_irq_stat,
 };
 };
 
 
-static int pm8921_add_subdevices(const struct pm8921_platform_data
-					   *pdata,
-					   struct pm8921 *pmic,
-					   u32 rev)
-{
-	int ret = 0, irq_base = 0;
-	struct pm_irq_chip *irq_chip;
-
-	if (pdata->irq_pdata) {
-		pdata->irq_pdata->irq_cdata.nirqs = PM8921_NR_IRQS;
-		pdata->irq_pdata->irq_cdata.rev = rev;
-		irq_base = pdata->irq_pdata->irq_base;
-		irq_chip = pm8xxx_irq_init(pmic->dev, pdata->irq_pdata);
+static const struct regmap_config ssbi_regmap_config = {
+	.reg_bits = 16,
+	.val_bits = 8,
+	.max_register = 0x3ff,
+	.fast_io = true,
+	.reg_read = ssbi_reg_read,
+	.reg_write = ssbi_reg_write
+};
 
 
-		if (IS_ERR(irq_chip)) {
-			pr_err("Failed to init interrupts ret=%ld\n",
-					PTR_ERR(irq_chip));
-			return PTR_ERR(irq_chip);
-		}
-		pmic->irq_chip = irq_chip;
-	}
-	return ret;
-}
+static const struct of_device_id pm8921_id_table[] = {
+	{ .compatible = "qcom,pm8058", },
+	{ .compatible = "qcom,pm8921", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, pm8921_id_table);
 
 
 static int pm8921_probe(struct platform_device *pdev)
 static int pm8921_probe(struct platform_device *pdev)
 {
 {
-	const struct pm8921_platform_data *pdata = dev_get_platdata(&pdev->dev);
 	struct pm8921 *pmic;
 	struct pm8921 *pmic;
-	int rc;
-	u8 val;
+	struct regmap *regmap;
+	int irq, rc;
+	unsigned int val;
 	u32 rev;
 	u32 rev;
+	struct pm_irq_chip *chip;
+	unsigned int nirqs = PM8921_NR_IRQS;
 
 
-	if (!pdata) {
-		pr_err("missing platform data\n");
-		return -EINVAL;
-	}
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
 
 
 	pmic = devm_kzalloc(&pdev->dev, sizeof(struct pm8921), GFP_KERNEL);
 	pmic = devm_kzalloc(&pdev->dev, sizeof(struct pm8921), GFP_KERNEL);
 	if (!pmic) {
 	if (!pmic) {
@@ -124,8 +410,13 @@ static int pm8921_probe(struct platform_device *pdev)
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 
 
+	regmap = devm_regmap_init(&pdev->dev, NULL, pdev->dev.parent,
+				  &ssbi_regmap_config);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
 	/* Read PMIC chip revision */
 	/* Read PMIC chip revision */
-	rc = ssbi_read(pdev->dev.parent, REG_HWREV, &val, sizeof(val));
+	rc = regmap_read(regmap, REG_HWREV, &val);
 	if (rc) {
 	if (rc) {
 		pr_err("Failed to read hw rev reg %d:rc=%d\n", REG_HWREV, rc);
 		pr_err("Failed to read hw rev reg %d:rc=%d\n", REG_HWREV, rc);
 		return rc;
 		return rc;
@@ -134,7 +425,7 @@ static int pm8921_probe(struct platform_device *pdev)
 	rev = val;
 	rev = val;
 
 
 	/* Read PMIC chip revision 2 */
 	/* Read PMIC chip revision 2 */
-	rc = ssbi_read(pdev->dev.parent, REG_HWREV_2, &val, sizeof(val));
+	rc = regmap_read(regmap, REG_HWREV_2, &val);
 	if (rc) {
 	if (rc) {
 		pr_err("Failed to read hw rev 2 reg %d:rc=%d\n",
 		pr_err("Failed to read hw rev 2 reg %d:rc=%d\n",
 			REG_HWREV_2, rc);
 			REG_HWREV_2, rc);
@@ -147,37 +438,56 @@ static int pm8921_probe(struct platform_device *pdev)
 	pm8921_drvdata.pm_chip_data = pmic;
 	pm8921_drvdata.pm_chip_data = pmic;
 	platform_set_drvdata(pdev, &pm8921_drvdata);
 	platform_set_drvdata(pdev, &pm8921_drvdata);
 
 
-	rc = pm8921_add_subdevices(pdata, pmic, rev);
+	chip = devm_kzalloc(&pdev->dev, sizeof(*chip) +
+					sizeof(chip->config[0]) * nirqs,
+					GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	pmic->irq_chip = chip;
+	chip->dev = &pdev->dev;
+	chip->regmap = regmap;
+	chip->num_irqs = nirqs;
+	chip->num_blocks = DIV_ROUND_UP(chip->num_irqs, 8);
+	chip->num_masters = DIV_ROUND_UP(chip->num_blocks, 8);
+	spin_lock_init(&chip->pm_irq_lock);
+
+	chip->irqdomain = irq_domain_add_linear(pdev->dev.of_node, nirqs,
+						&pm8xxx_irq_domain_ops,
+						chip);
+	if (!chip->irqdomain)
+		return -ENODEV;
+
+	irq_set_handler_data(irq, chip);
+	irq_set_chained_handler(irq, pm8xxx_irq_handler);
+	irq_set_irq_wake(irq, 1);
+
+	rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
 	if (rc) {
 	if (rc) {
-		pr_err("Cannot add subdevices rc=%d\n", rc);
-		goto err;
+		irq_set_chained_handler(irq, NULL);
+		irq_set_handler_data(irq, NULL);
+		irq_domain_remove(chip->irqdomain);
 	}
 	}
 
 
-	/* gpio might not work if no irq device is found */
-	WARN_ON(pmic->irq_chip == NULL);
+	return rc;
+}
 
 
+static int pm8921_remove_child(struct device *dev, void *unused)
+{
+	platform_device_unregister(to_platform_device(dev));
 	return 0;
 	return 0;
-
-err:
-	mfd_remove_devices(pmic->dev);
-	return rc;
 }
 }
 
 
 static int pm8921_remove(struct platform_device *pdev)
 static int pm8921_remove(struct platform_device *pdev)
 {
 {
-	struct pm8xxx_drvdata *drvdata;
-	struct pm8921 *pmic = NULL;
-
-	drvdata = platform_get_drvdata(pdev);
-	if (drvdata)
-		pmic = drvdata->pm_chip_data;
-	if (pmic) {
-		mfd_remove_devices(pmic->dev);
-		if (pmic->irq_chip) {
-			pm8xxx_irq_exit(pmic->irq_chip);
-			pmic->irq_chip = NULL;
-		}
-	}
+	int irq = platform_get_irq(pdev, 0);
+	struct pm8921 *pmic = pm8921_drvdata.pm_chip_data;
+	struct pm_irq_chip *chip = pmic->irq_chip;
+
+	device_for_each_child(&pdev->dev, NULL, pm8921_remove_child);
+	irq_set_chained_handler(irq, NULL);
+	irq_set_handler_data(irq, NULL);
+	irq_domain_remove(chip->irqdomain);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -188,6 +498,7 @@ static struct platform_driver pm8921_driver = {
 	.driver		= {
 	.driver		= {
 		.name	= "pm8921-core",
 		.name	= "pm8921-core",
 		.owner	= THIS_MODULE,
 		.owner	= THIS_MODULE,
+		.of_match_table = pm8921_id_table,
 	},
 	},
 };
 };
 
 

+ 0 - 371
drivers/mfd/pm8xxx-irq.c

@@ -1,371 +0,0 @@
-/*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#define pr_fmt(fmt)	"%s: " fmt, __func__
-
-#include <linux/err.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/mfd/pm8xxx/core.h>
-#include <linux/mfd/pm8xxx/irq.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-/* PMIC8xxx IRQ */
-
-#define	SSBI_REG_ADDR_IRQ_BASE		0x1BB
-
-#define	SSBI_REG_ADDR_IRQ_ROOT		(SSBI_REG_ADDR_IRQ_BASE + 0)
-#define	SSBI_REG_ADDR_IRQ_M_STATUS1	(SSBI_REG_ADDR_IRQ_BASE + 1)
-#define	SSBI_REG_ADDR_IRQ_M_STATUS2	(SSBI_REG_ADDR_IRQ_BASE + 2)
-#define	SSBI_REG_ADDR_IRQ_M_STATUS3	(SSBI_REG_ADDR_IRQ_BASE + 3)
-#define	SSBI_REG_ADDR_IRQ_M_STATUS4	(SSBI_REG_ADDR_IRQ_BASE + 4)
-#define	SSBI_REG_ADDR_IRQ_BLK_SEL	(SSBI_REG_ADDR_IRQ_BASE + 5)
-#define	SSBI_REG_ADDR_IRQ_IT_STATUS	(SSBI_REG_ADDR_IRQ_BASE + 6)
-#define	SSBI_REG_ADDR_IRQ_CONFIG	(SSBI_REG_ADDR_IRQ_BASE + 7)
-#define	SSBI_REG_ADDR_IRQ_RT_STATUS	(SSBI_REG_ADDR_IRQ_BASE + 8)
-
-#define	PM_IRQF_LVL_SEL			0x01	/* level select */
-#define	PM_IRQF_MASK_FE			0x02	/* mask falling edge */
-#define	PM_IRQF_MASK_RE			0x04	/* mask rising edge */
-#define	PM_IRQF_CLR			0x08	/* clear interrupt */
-#define	PM_IRQF_BITS_MASK		0x70
-#define	PM_IRQF_BITS_SHIFT		4
-#define	PM_IRQF_WRITE			0x80
-
-#define	PM_IRQF_MASK_ALL		(PM_IRQF_MASK_FE | \
-					PM_IRQF_MASK_RE)
-
-struct pm_irq_chip {
-	struct device		*dev;
-	spinlock_t		pm_irq_lock;
-	unsigned int		devirq;
-	unsigned int		irq_base;
-	unsigned int		num_irqs;
-	unsigned int		num_blocks;
-	unsigned int		num_masters;
-	u8			config[0];
-};
-
-static int pm8xxx_read_root_irq(const struct pm_irq_chip *chip, u8 *rp)
-{
-	return pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_ROOT, rp);
-}
-
-static int pm8xxx_read_master_irq(const struct pm_irq_chip *chip, u8 m, u8 *bp)
-{
-	return pm8xxx_readb(chip->dev,
-			SSBI_REG_ADDR_IRQ_M_STATUS1 + m, bp);
-}
-
-static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, u8 bp, u8 *ip)
-{
-	int	rc;
-
-	spin_lock(&chip->pm_irq_lock);
-	rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp);
-	if (rc) {
-		pr_err("Failed Selecting Block %d rc=%d\n", bp, rc);
-		goto bail;
-	}
-
-	rc = pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_IT_STATUS, ip);
-	if (rc)
-		pr_err("Failed Reading Status rc=%d\n", rc);
-bail:
-	spin_unlock(&chip->pm_irq_lock);
-	return rc;
-}
-
-static int pm8xxx_config_irq(struct pm_irq_chip *chip, u8 bp, u8 cp)
-{
-	int	rc;
-
-	spin_lock(&chip->pm_irq_lock);
-	rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp);
-	if (rc) {
-		pr_err("Failed Selecting Block %d rc=%d\n", bp, rc);
-		goto bail;
-	}
-
-	cp |= PM_IRQF_WRITE;
-	rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_CONFIG, cp);
-	if (rc)
-		pr_err("Failed Configuring IRQ rc=%d\n", rc);
-bail:
-	spin_unlock(&chip->pm_irq_lock);
-	return rc;
-}
-
-static int pm8xxx_irq_block_handler(struct pm_irq_chip *chip, int block)
-{
-	int pmirq, irq, i, ret = 0;
-	u8 bits;
-
-	ret = pm8xxx_read_block_irq(chip, block, &bits);
-	if (ret) {
-		pr_err("Failed reading %d block ret=%d", block, ret);
-		return ret;
-	}
-	if (!bits) {
-		pr_err("block bit set in master but no irqs: %d", block);
-		return 0;
-	}
-
-	/* Check IRQ bits */
-	for (i = 0; i < 8; i++) {
-		if (bits & (1 << i)) {
-			pmirq = block * 8 + i;
-			irq = pmirq + chip->irq_base;
-			generic_handle_irq(irq);
-		}
-	}
-	return 0;
-}
-
-static int pm8xxx_irq_master_handler(struct pm_irq_chip *chip, int master)
-{
-	u8 blockbits;
-	int block_number, i, ret = 0;
-
-	ret = pm8xxx_read_master_irq(chip, master, &blockbits);
-	if (ret) {
-		pr_err("Failed to read master %d ret=%d\n", master, ret);
-		return ret;
-	}
-	if (!blockbits) {
-		pr_err("master bit set in root but no blocks: %d", master);
-		return 0;
-	}
-
-	for (i = 0; i < 8; i++)
-		if (blockbits & (1 << i)) {
-			block_number = master * 8 + i;	/* block # */
-			ret |= pm8xxx_irq_block_handler(chip, block_number);
-		}
-	return ret;
-}
-
-static void pm8xxx_irq_handler(unsigned int irq, struct irq_desc *desc)
-{
-	struct pm_irq_chip *chip = irq_desc_get_handler_data(desc);
-	struct irq_chip *irq_chip = irq_desc_get_chip(desc);
-	u8	root;
-	int	i, ret, masters = 0;
-
-	ret = pm8xxx_read_root_irq(chip, &root);
-	if (ret) {
-		pr_err("Can't read root status ret=%d\n", ret);
-		return;
-	}
-
-	/* on pm8xxx series masters start from bit 1 of the root */
-	masters = root >> 1;
-
-	/* Read allowed masters for blocks. */
-	for (i = 0; i < chip->num_masters; i++)
-		if (masters & (1 << i))
-			pm8xxx_irq_master_handler(chip, i);
-
-	irq_chip->irq_ack(&desc->irq_data);
-}
-
-static void pm8xxx_irq_mask_ack(struct irq_data *d)
-{
-	struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
-	unsigned int pmirq = d->irq - chip->irq_base;
-	int	master, irq_bit;
-	u8	block, config;
-
-	block = pmirq / 8;
-	master = block / 8;
-	irq_bit = pmirq % 8;
-
-	config = chip->config[pmirq] | PM_IRQF_MASK_ALL | PM_IRQF_CLR;
-	pm8xxx_config_irq(chip, block, config);
-}
-
-static void pm8xxx_irq_unmask(struct irq_data *d)
-{
-	struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
-	unsigned int pmirq = d->irq - chip->irq_base;
-	int	master, irq_bit;
-	u8	block, config;
-
-	block = pmirq / 8;
-	master = block / 8;
-	irq_bit = pmirq % 8;
-
-	config = chip->config[pmirq];
-	pm8xxx_config_irq(chip, block, config);
-}
-
-static int pm8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
-{
-	struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
-	unsigned int pmirq = d->irq - chip->irq_base;
-	int master, irq_bit;
-	u8 block, config;
-
-	block = pmirq / 8;
-	master = block / 8;
-	irq_bit  = pmirq % 8;
-
-	chip->config[pmirq] = (irq_bit << PM_IRQF_BITS_SHIFT)
-							| PM_IRQF_MASK_ALL;
-	if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
-		if (flow_type & IRQF_TRIGGER_RISING)
-			chip->config[pmirq] &= ~PM_IRQF_MASK_RE;
-		if (flow_type & IRQF_TRIGGER_FALLING)
-			chip->config[pmirq] &= ~PM_IRQF_MASK_FE;
-	} else {
-		chip->config[pmirq] |= PM_IRQF_LVL_SEL;
-
-		if (flow_type & IRQF_TRIGGER_HIGH)
-			chip->config[pmirq] &= ~PM_IRQF_MASK_RE;
-		else
-			chip->config[pmirq] &= ~PM_IRQF_MASK_FE;
-	}
-
-	config = chip->config[pmirq] | PM_IRQF_CLR;
-	return pm8xxx_config_irq(chip, block, config);
-}
-
-static int pm8xxx_irq_set_wake(struct irq_data *d, unsigned int on)
-{
-	return 0;
-}
-
-static struct irq_chip pm8xxx_irq_chip = {
-	.name		= "pm8xxx",
-	.irq_mask_ack	= pm8xxx_irq_mask_ack,
-	.irq_unmask	= pm8xxx_irq_unmask,
-	.irq_set_type	= pm8xxx_irq_set_type,
-	.irq_set_wake	= pm8xxx_irq_set_wake,
-	.flags		= IRQCHIP_MASK_ON_SUSPEND,
-};
-
-/**
- * pm8xxx_get_irq_stat - get the status of the irq line
- * @chip: pointer to identify a pmic irq controller
- * @irq: the irq number
- *
- * The pm8xxx gpio and mpp rely on the interrupt block to read
- * the values on their pins. This function is to facilitate reading
- * the status of a gpio or an mpp line. The caller has to convert the
- * gpio number to irq number.
- *
- * RETURNS:
- * an int indicating the value read on that line
- */
-int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq)
-{
-	int pmirq, rc;
-	u8  block, bits, bit;
-	unsigned long flags;
-
-	if (chip == NULL || irq < chip->irq_base ||
-			irq >= chip->irq_base + chip->num_irqs)
-		return -EINVAL;
-
-	pmirq = irq - chip->irq_base;
-
-	block = pmirq / 8;
-	bit = pmirq % 8;
-
-	spin_lock_irqsave(&chip->pm_irq_lock, flags);
-
-	rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, block);
-	if (rc) {
-		pr_err("Failed Selecting block irq=%d pmirq=%d blk=%d rc=%d\n",
-			irq, pmirq, block, rc);
-		goto bail_out;
-	}
-
-	rc = pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits);
-	if (rc) {
-		pr_err("Failed Configuring irq=%d pmirq=%d blk=%d rc=%d\n",
-			irq, pmirq, block, rc);
-		goto bail_out;
-	}
-
-	rc = (bits & (1 << bit)) ? 1 : 0;
-
-bail_out:
-	spin_unlock_irqrestore(&chip->pm_irq_lock, flags);
-
-	return rc;
-}
-EXPORT_SYMBOL_GPL(pm8xxx_get_irq_stat);
-
-struct pm_irq_chip *  pm8xxx_irq_init(struct device *dev,
-				const struct pm8xxx_irq_platform_data *pdata)
-{
-	struct pm_irq_chip  *chip;
-	int devirq, rc;
-	unsigned int pmirq;
-
-	if (!pdata) {
-		pr_err("No platform data\n");
-		return ERR_PTR(-EINVAL);
-	}
-
-	devirq = pdata->devirq;
-	if (devirq < 0) {
-		pr_err("missing devirq\n");
-		rc = devirq;
-		return ERR_PTR(-EINVAL);
-	}
-
-	chip = kzalloc(sizeof(struct pm_irq_chip)
-			+ sizeof(u8) * pdata->irq_cdata.nirqs, GFP_KERNEL);
-	if (!chip) {
-		pr_err("Cannot alloc pm_irq_chip struct\n");
-		return ERR_PTR(-EINVAL);
-	}
-
-	chip->dev = dev;
-	chip->devirq = devirq;
-	chip->irq_base = pdata->irq_base;
-	chip->num_irqs = pdata->irq_cdata.nirqs;
-	chip->num_blocks = DIV_ROUND_UP(chip->num_irqs, 8);
-	chip->num_masters = DIV_ROUND_UP(chip->num_blocks, 8);
-	spin_lock_init(&chip->pm_irq_lock);
-
-	for (pmirq = 0; pmirq < chip->num_irqs; pmirq++) {
-		irq_set_chip_and_handler(chip->irq_base + pmirq,
-				&pm8xxx_irq_chip,
-				handle_level_irq);
-		irq_set_chip_data(chip->irq_base + pmirq, chip);
-#ifdef CONFIG_ARM
-		set_irq_flags(chip->irq_base + pmirq, IRQF_VALID);
-#else
-		irq_set_noprobe(chip->irq_base + pmirq);
-#endif
-	}
-
-	irq_set_irq_type(devirq, pdata->irq_trigger_flag);
-	irq_set_handler_data(devirq, chip);
-	irq_set_chained_handler(devirq, pm8xxx_irq_handler);
-	set_irq_wake(devirq, 1);
-
-	return chip;
-}
-
-int pm8xxx_irq_exit(struct pm_irq_chip *chip)
-{
-	irq_set_chained_handler(chip->devirq, NULL);
-	kfree(chip);
-	return 0;
-}

+ 0 - 1
drivers/mfd/rc5t583-irq.c

@@ -22,7 +22,6 @@
  */
  */
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/irq.h>
-#include <linux/init.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
 #include <linux/mfd/rc5t583.h>
 #include <linux/mfd/rc5t583.h>
 
 

+ 0 - 1
drivers/mfd/rdc321x-southbridge.c

@@ -19,7 +19,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  *
  */
  */
-#include <linux/init.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>

+ 0 - 1
drivers/mfd/retu-mfd.c

@@ -19,7 +19,6 @@
 #include <linux/err.h>
 #include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
 #include <linux/irq.h>
 #include <linux/irq.h>
-#include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/mutex.h>
 #include <linux/module.h>
 #include <linux/module.h>

+ 760 - 0
drivers/mfd/rtsx_usb.c

@@ -0,0 +1,760 @@
+/* Driver for Realtek USB card reader
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Roger Tseng <rogerable@realtek.com>
+ */
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/usb.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/rtsx_usb.h>
+
+static int polling_pipe = 1;
+module_param(polling_pipe, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(polling_pipe, "polling pipe (0: ctl, 1: bulk)");
+
+static struct mfd_cell rtsx_usb_cells[] = {
+	[RTSX_USB_SD_CARD] = {
+		.name = "rtsx_usb_sdmmc",
+		.pdata_size = 0,
+	},
+	[RTSX_USB_MS_CARD] = {
+		.name = "rtsx_usb_ms",
+		.pdata_size = 0,
+	},
+};
+
+static void rtsx_usb_sg_timed_out(unsigned long data)
+{
+	struct rtsx_ucr *ucr = (struct rtsx_ucr *)data;
+
+	dev_dbg(&ucr->pusb_intf->dev, "%s: sg transfer timed out", __func__);
+	usb_sg_cancel(&ucr->current_sg);
+
+	/* we know the cancellation is caused by time-out */
+	ucr->current_sg.status = -ETIMEDOUT;
+}
+
+static int rtsx_usb_bulk_transfer_sglist(struct rtsx_ucr *ucr,
+		unsigned int pipe, struct scatterlist *sg, int num_sg,
+		unsigned int length, unsigned int *act_len, int timeout)
+{
+	int ret;
+
+	dev_dbg(&ucr->pusb_intf->dev, "%s: xfer %u bytes, %d entries\n",
+			__func__, length, num_sg);
+	ret = usb_sg_init(&ucr->current_sg, ucr->pusb_dev, pipe, 0,
+			sg, num_sg, length, GFP_NOIO);
+	if (ret)
+		return ret;
+
+	ucr->sg_timer.expires = jiffies + msecs_to_jiffies(timeout);
+	add_timer(&ucr->sg_timer);
+	usb_sg_wait(&ucr->current_sg);
+	del_timer(&ucr->sg_timer);
+
+	if (act_len)
+		*act_len = ucr->current_sg.bytes;
+
+	return ucr->current_sg.status;
+}
+
+int rtsx_usb_transfer_data(struct rtsx_ucr *ucr, unsigned int pipe,
+			      void *buf, unsigned int len, int num_sg,
+			      unsigned int *act_len, int timeout)
+{
+	if (timeout < 600)
+		timeout = 600;
+
+	if (num_sg)
+		return rtsx_usb_bulk_transfer_sglist(ucr, pipe,
+				(struct scatterlist *)buf, num_sg, len, act_len,
+				timeout);
+	else
+		return usb_bulk_msg(ucr->pusb_dev, pipe, buf, len, act_len,
+				timeout);
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_transfer_data);
+
+static inline void rtsx_usb_seq_cmd_hdr(struct rtsx_ucr *ucr,
+		u16 addr, u16 len, u8 seq_type)
+{
+	rtsx_usb_cmd_hdr_tag(ucr);
+
+	ucr->cmd_buf[PACKET_TYPE] = seq_type;
+	ucr->cmd_buf[5] = (u8)(len >> 8);
+	ucr->cmd_buf[6] = (u8)len;
+	ucr->cmd_buf[8] = (u8)(addr >> 8);
+	ucr->cmd_buf[9] = (u8)addr;
+
+	if (seq_type == SEQ_WRITE)
+		ucr->cmd_buf[STAGE_FLAG] = 0;
+	else
+		ucr->cmd_buf[STAGE_FLAG] = STAGE_R;
+}
+
+static int rtsx_usb_seq_write_register(struct rtsx_ucr *ucr,
+		u16 addr, u16 len, u8 *data)
+{
+	u16 cmd_len = ALIGN(SEQ_WRITE_DATA_OFFSET + len, 4);
+
+	if (!data)
+		return -EINVAL;
+
+	if (cmd_len > IOBUF_SIZE)
+		return -EINVAL;
+
+	rtsx_usb_seq_cmd_hdr(ucr, addr, len, SEQ_WRITE);
+	memcpy(ucr->cmd_buf + SEQ_WRITE_DATA_OFFSET, data, len);
+
+	return rtsx_usb_transfer_data(ucr,
+			usb_sndbulkpipe(ucr->pusb_dev, EP_BULK_OUT),
+			ucr->cmd_buf, cmd_len, 0, NULL, 100);
+}
+
+static int rtsx_usb_seq_read_register(struct rtsx_ucr *ucr,
+		u16 addr, u16 len, u8 *data)
+{
+	int i, ret;
+	u16 rsp_len = round_down(len, 4);
+	u16 res_len = len - rsp_len;
+
+	if (!data)
+		return -EINVAL;
+
+	/* 4-byte aligned part */
+	if (rsp_len) {
+		rtsx_usb_seq_cmd_hdr(ucr, addr, len, SEQ_READ);
+		ret = rtsx_usb_transfer_data(ucr,
+				usb_sndbulkpipe(ucr->pusb_dev, EP_BULK_OUT),
+				ucr->cmd_buf, 12, 0, NULL, 100);
+		if (ret)
+			return ret;
+
+		ret = rtsx_usb_transfer_data(ucr,
+				usb_rcvbulkpipe(ucr->pusb_dev, EP_BULK_IN),
+				data, rsp_len, 0, NULL, 100);
+		if (ret)
+			return ret;
+	}
+
+	/* unaligned part */
+	for (i = 0; i < res_len; i++) {
+		ret = rtsx_usb_read_register(ucr, addr + rsp_len + i,
+				data + rsp_len + i);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+int rtsx_usb_read_ppbuf(struct rtsx_ucr *ucr, u8 *buf, int buf_len)
+{
+	return rtsx_usb_seq_read_register(ucr, PPBUF_BASE2, (u16)buf_len, buf);
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_read_ppbuf);
+
+int rtsx_usb_write_ppbuf(struct rtsx_ucr *ucr, u8 *buf, int buf_len)
+{
+	return rtsx_usb_seq_write_register(ucr, PPBUF_BASE2, (u16)buf_len, buf);
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_write_ppbuf);
+
+int rtsx_usb_ep0_write_register(struct rtsx_ucr *ucr, u16 addr,
+		u8 mask, u8 data)
+{
+	u16 value, index;
+
+	addr |= EP0_WRITE_REG_CMD << EP0_OP_SHIFT;
+	value = swab16(addr);
+	index = mask | data << 8;
+
+	return usb_control_msg(ucr->pusb_dev,
+			usb_sndctrlpipe(ucr->pusb_dev, 0), RTSX_USB_REQ_REG_OP,
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			value, index, NULL, 0, 100);
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_ep0_write_register);
+
+int rtsx_usb_ep0_read_register(struct rtsx_ucr *ucr, u16 addr, u8 *data)
+{
+	u16 value;
+
+	if (!data)
+		return -EINVAL;
+	*data = 0;
+
+	addr |= EP0_READ_REG_CMD << EP0_OP_SHIFT;
+	value = swab16(addr);
+
+	return usb_control_msg(ucr->pusb_dev,
+			usb_rcvctrlpipe(ucr->pusb_dev, 0), RTSX_USB_REQ_REG_OP,
+			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			value, 0, data, 1, 100);
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_ep0_read_register);
+
+void rtsx_usb_add_cmd(struct rtsx_ucr *ucr, u8 cmd_type, u16 reg_addr,
+		u8 mask, u8 data)
+{
+	int i;
+
+	if (ucr->cmd_idx < (IOBUF_SIZE - CMD_OFFSET) / 4) {
+		i = CMD_OFFSET + ucr->cmd_idx * 4;
+
+		ucr->cmd_buf[i++] = ((cmd_type & 0x03) << 6) |
+			(u8)((reg_addr >> 8) & 0x3F);
+		ucr->cmd_buf[i++] = (u8)reg_addr;
+		ucr->cmd_buf[i++] = mask;
+		ucr->cmd_buf[i++] = data;
+
+		ucr->cmd_idx++;
+	}
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_add_cmd);
+
+int rtsx_usb_send_cmd(struct rtsx_ucr *ucr, u8 flag, int timeout)
+{
+	int ret;
+
+	ucr->cmd_buf[CNT_H] = (u8)(ucr->cmd_idx >> 8);
+	ucr->cmd_buf[CNT_L] = (u8)(ucr->cmd_idx);
+	ucr->cmd_buf[STAGE_FLAG] = flag;
+
+	ret = rtsx_usb_transfer_data(ucr,
+			usb_sndbulkpipe(ucr->pusb_dev, EP_BULK_OUT),
+			ucr->cmd_buf, ucr->cmd_idx * 4 + CMD_OFFSET,
+			0, NULL, timeout);
+	if (ret) {
+		rtsx_usb_clear_fsm_err(ucr);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_send_cmd);
+
+int rtsx_usb_get_rsp(struct rtsx_ucr *ucr, int rsp_len, int timeout)
+{
+	if (rsp_len <= 0)
+		return -EINVAL;
+
+	rsp_len = ALIGN(rsp_len, 4);
+
+	return rtsx_usb_transfer_data(ucr,
+			usb_rcvbulkpipe(ucr->pusb_dev, EP_BULK_IN),
+			ucr->rsp_buf, rsp_len, 0, NULL, timeout);
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_get_rsp);
+
+static int rtsx_usb_get_status_with_bulk(struct rtsx_ucr *ucr, u16 *status)
+{
+	int ret;
+
+	rtsx_usb_init_cmd(ucr);
+	rtsx_usb_add_cmd(ucr, READ_REG_CMD, CARD_EXIST, 0x00, 0x00);
+	rtsx_usb_add_cmd(ucr, READ_REG_CMD, OCPSTAT, 0x00, 0x00);
+	ret = rtsx_usb_send_cmd(ucr, MODE_CR, 100);
+	if (ret)
+		return ret;
+
+	ret = rtsx_usb_get_rsp(ucr, 2, 100);
+	if (ret)
+		return ret;
+
+	*status = ((ucr->rsp_buf[0] >> 2) & 0x0f) |
+		  ((ucr->rsp_buf[1] & 0x03) << 4);
+
+	return 0;
+}
+
+int rtsx_usb_get_card_status(struct rtsx_ucr *ucr, u16 *status)
+{
+	int ret;
+
+	if (!status)
+		return -EINVAL;
+
+	if (polling_pipe == 0)
+		ret = usb_control_msg(ucr->pusb_dev,
+				usb_rcvctrlpipe(ucr->pusb_dev, 0),
+				RTSX_USB_REQ_POLL,
+				USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+				0, 0, status, 2, 100);
+	else
+		ret = rtsx_usb_get_status_with_bulk(ucr, status);
+
+	/* usb_control_msg may return positive when success */
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_get_card_status);
+
+static int rtsx_usb_write_phy_register(struct rtsx_ucr *ucr, u8 addr, u8 val)
+{
+	dev_dbg(&ucr->pusb_intf->dev, "Write 0x%x to phy register 0x%x\n",
+			val, addr);
+
+	rtsx_usb_init_cmd(ucr);
+
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VSTAIN, 0xFF, val);
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VCONTROL, 0xFF, addr & 0x0F);
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00);
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00);
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x01);
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VCONTROL,
+			0xFF, (addr >> 4) & 0x0F);
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00);
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00);
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x01);
+
+	return rtsx_usb_send_cmd(ucr, MODE_C, 100);
+}
+
+int rtsx_usb_write_register(struct rtsx_ucr *ucr, u16 addr, u8 mask, u8 data)
+{
+	rtsx_usb_init_cmd(ucr);
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, addr, mask, data);
+	return rtsx_usb_send_cmd(ucr, MODE_C, 100);
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_write_register);
+
+int rtsx_usb_read_register(struct rtsx_ucr *ucr, u16 addr, u8 *data)
+{
+	int ret;
+
+	if (data != NULL)
+		*data = 0;
+
+	rtsx_usb_init_cmd(ucr);
+	rtsx_usb_add_cmd(ucr, READ_REG_CMD, addr, 0, 0);
+	ret = rtsx_usb_send_cmd(ucr, MODE_CR, 100);
+	if (ret)
+		return ret;
+
+	ret = rtsx_usb_get_rsp(ucr, 1, 100);
+	if (ret)
+		return ret;
+
+	if (data != NULL)
+		*data = ucr->rsp_buf[0];
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_read_register);
+
+static inline u8 double_ssc_depth(u8 depth)
+{
+	return (depth > 1) ? (depth - 1) : depth;
+}
+
+static u8 revise_ssc_depth(u8 ssc_depth, u8 div)
+{
+	if (div > CLK_DIV_1) {
+		if (ssc_depth > div - 1)
+			ssc_depth -= (div - 1);
+		else
+			ssc_depth = SSC_DEPTH_2M;
+	}
+
+	return ssc_depth;
+}
+
+int rtsx_usb_switch_clock(struct rtsx_ucr *ucr, unsigned int card_clock,
+		u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk)
+{
+	int ret;
+	u8 n, clk_divider, mcu_cnt, div;
+
+	if (!card_clock) {
+		ucr->cur_clk = 0;
+		return 0;
+	}
+
+	if (initial_mode) {
+		/* We use 250k(around) here, in initial stage */
+		clk_divider = SD_CLK_DIVIDE_128;
+		card_clock = 30000000;
+	} else {
+		clk_divider = SD_CLK_DIVIDE_0;
+	}
+
+	ret = rtsx_usb_write_register(ucr, SD_CFG1,
+			SD_CLK_DIVIDE_MASK, clk_divider);
+	if (ret < 0)
+		return ret;
+
+	card_clock /= 1000000;
+	dev_dbg(&ucr->pusb_intf->dev,
+			"Switch card clock to %dMHz\n", card_clock);
+
+	if (!initial_mode && double_clk)
+		card_clock *= 2;
+	dev_dbg(&ucr->pusb_intf->dev,
+			"Internal SSC clock: %dMHz (cur_clk = %d)\n",
+			card_clock, ucr->cur_clk);
+
+	if (card_clock == ucr->cur_clk)
+		return 0;
+
+	/* Converting clock value into internal settings: n and div */
+	n = card_clock - 2;
+	if ((card_clock <= 2) || (n > MAX_DIV_N))
+		return -EINVAL;
+
+	mcu_cnt = 60/card_clock + 3;
+	if (mcu_cnt > 15)
+		mcu_cnt = 15;
+
+	/* Make sure that the SSC clock div_n is not less than MIN_DIV_N */
+
+	div = CLK_DIV_1;
+	while (n < MIN_DIV_N && div < CLK_DIV_4) {
+		n = (n + 2) * 2 - 2;
+		div++;
+	}
+	dev_dbg(&ucr->pusb_intf->dev, "n = %d, div = %d\n", n, div);
+
+	if (double_clk)
+		ssc_depth = double_ssc_depth(ssc_depth);
+
+	ssc_depth = revise_ssc_depth(ssc_depth, div);
+	dev_dbg(&ucr->pusb_intf->dev, "ssc_depth = %d\n", ssc_depth);
+
+	rtsx_usb_init_cmd(ucr);
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CLK_DIV, CLK_CHANGE, CLK_CHANGE);
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CLK_DIV,
+			0x3F, (div << 4) | mcu_cnt);
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0);
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SSC_CTL2,
+			SSC_DEPTH_MASK, ssc_depth);
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, n);
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB);
+	if (vpclk) {
+		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_VPCLK0_CTL,
+				PHASE_NOT_RESET, 0);
+		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_VPCLK0_CTL,
+				PHASE_NOT_RESET, PHASE_NOT_RESET);
+	}
+
+	ret = rtsx_usb_send_cmd(ucr, MODE_C, 2000);
+	if (ret < 0)
+		return ret;
+
+	ret = rtsx_usb_write_register(ucr, SSC_CTL1, 0xff,
+			SSC_RSTB | SSC_8X_EN | SSC_SEL_4M);
+	if (ret < 0)
+		return ret;
+
+	/* Wait SSC clock stable */
+	usleep_range(100, 1000);
+
+	ret = rtsx_usb_write_register(ucr, CLK_DIV, CLK_CHANGE, 0);
+	if (ret < 0)
+		return ret;
+
+	ucr->cur_clk = card_clock;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_switch_clock);
+
+int rtsx_usb_card_exclusive_check(struct rtsx_ucr *ucr, int card)
+{
+	int ret;
+	u16 val;
+	u16 cd_mask[] = {
+		[RTSX_USB_SD_CARD] = (CD_MASK & ~SD_CD),
+		[RTSX_USB_MS_CARD] = (CD_MASK & ~MS_CD)
+	};
+
+	ret = rtsx_usb_get_card_status(ucr, &val);
+	/*
+	 * If get status fails, return 0 (ok) for the exclusive check
+	 * and let the flow fail at somewhere else.
+	 */
+	if (ret)
+		return 0;
+
+	if (val & cd_mask[card])
+		return -EIO;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_usb_card_exclusive_check);
+
+static int rtsx_usb_reset_chip(struct rtsx_ucr *ucr)
+{
+	int ret;
+	u8 val;
+
+	rtsx_usb_init_cmd(ucr);
+
+	if (CHECK_PKG(ucr, LQFP48)) {
+		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PWR_CTL,
+				LDO3318_PWR_MASK, LDO_SUSPEND);
+		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PWR_CTL,
+				FORCE_LDO_POWERB, FORCE_LDO_POWERB);
+		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL1,
+				0x30, 0x10);
+		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL5,
+				0x03, 0x01);
+		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL6,
+				0x0C, 0x04);
+	}
+
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SYS_DUMMY0, NYET_MSAK, NYET_EN);
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CD_DEGLITCH_WIDTH, 0xFF, 0x08);
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
+			CD_DEGLITCH_EN, XD_CD_DEGLITCH_EN, 0x0);
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD30_DRIVE_SEL,
+			SD30_DRIVE_MASK, DRIVER_TYPE_D);
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
+			CARD_DRIVE_SEL, SD20_DRIVE_MASK, 0x0);
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, LDO_POWER_CFG, 0xE0, 0x0);
+
+	if (ucr->is_rts5179)
+		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
+				CARD_PULL_CTL5, 0x03, 0x01);
+
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_DMA1_CTL,
+		       EXTEND_DMA1_ASYNC_SIGNAL, EXTEND_DMA1_ASYNC_SIGNAL);
+	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_INT_PEND,
+			XD_INT | MS_INT | SD_INT,
+			XD_INT | MS_INT | SD_INT);
+
+	ret = rtsx_usb_send_cmd(ucr, MODE_C, 100);
+	if (ret)
+		return ret;
+
+	/* config non-crystal mode */
+	rtsx_usb_read_register(ucr, CFG_MODE, &val);
+	if ((val & XTAL_FREE) || ((val & CLK_MODE_MASK) == CLK_MODE_NON_XTAL)) {
+		ret = rtsx_usb_write_phy_register(ucr, 0xC2, 0x7C);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int rtsx_usb_init_chip(struct rtsx_ucr *ucr)
+{
+	int ret;
+	u8 val;
+
+	rtsx_usb_clear_fsm_err(ucr);
+
+	/* power on SSC */
+	ret = rtsx_usb_write_register(ucr,
+			FPDCTL, SSC_POWER_MASK, SSC_POWER_ON);
+	if (ret)
+		return ret;
+
+	usleep_range(100, 1000);
+	ret = rtsx_usb_write_register(ucr, CLK_DIV, CLK_CHANGE, 0x00);
+	if (ret)
+		return ret;
+
+	/* determine IC version */
+	ret = rtsx_usb_read_register(ucr, HW_VERSION, &val);
+	if (ret)
+		return ret;
+
+	ucr->ic_version = val & HW_VER_MASK;
+
+	/* determine package */
+	ret = rtsx_usb_read_register(ucr, CARD_SHARE_MODE, &val);
+	if (ret)
+		return ret;
+
+	if (val & CARD_SHARE_LQFP_SEL) {
+		ucr->package = LQFP48;
+		dev_dbg(&ucr->pusb_intf->dev, "Package: LQFP48\n");
+	} else {
+		ucr->package = QFN24;
+		dev_dbg(&ucr->pusb_intf->dev, "Package: QFN24\n");
+	}
+
+	/* determine IC variations */
+	rtsx_usb_read_register(ucr, CFG_MODE_1, &val);
+	if (val & RTS5179) {
+		ucr->is_rts5179 = true;
+		dev_dbg(&ucr->pusb_intf->dev, "Device is rts5179\n");
+	} else {
+		ucr->is_rts5179 = false;
+	}
+
+	return rtsx_usb_reset_chip(ucr);
+}
+
+static int rtsx_usb_probe(struct usb_interface *intf,
+			 const struct usb_device_id *id)
+{
+	struct usb_device *usb_dev = interface_to_usbdev(intf);
+	struct rtsx_ucr *ucr;
+	int ret;
+
+	dev_dbg(&intf->dev,
+		": Realtek USB Card Reader found at bus %03d address %03d\n",
+		 usb_dev->bus->busnum, usb_dev->devnum);
+
+	ucr = devm_kzalloc(&intf->dev, sizeof(*ucr), GFP_KERNEL);
+	if (!ucr)
+		return -ENOMEM;
+
+	ucr->pusb_dev = usb_dev;
+
+	ucr->iobuf = usb_alloc_coherent(ucr->pusb_dev, IOBUF_SIZE,
+			GFP_KERNEL, &ucr->iobuf_dma);
+	if (!ucr->iobuf)
+		return -ENOMEM;
+
+	usb_set_intfdata(intf, ucr);
+
+	ucr->vendor_id = id->idVendor;
+	ucr->product_id = id->idProduct;
+	ucr->cmd_buf = ucr->rsp_buf = ucr->iobuf;
+
+	mutex_init(&ucr->dev_mutex);
+
+	ucr->pusb_intf = intf;
+
+	/* initialize */
+	ret = rtsx_usb_init_chip(ucr);
+	if (ret)
+		goto out_init_fail;
+
+	ret = mfd_add_devices(&intf->dev, usb_dev->devnum, rtsx_usb_cells,
+			ARRAY_SIZE(rtsx_usb_cells), NULL, 0, NULL);
+	if (ret)
+		goto out_init_fail;
+
+	/* initialize USB SG transfer timer */
+	init_timer(&ucr->sg_timer);
+	setup_timer(&ucr->sg_timer, rtsx_usb_sg_timed_out, (unsigned long) ucr);
+#ifdef CONFIG_PM
+	intf->needs_remote_wakeup = 1;
+	usb_enable_autosuspend(usb_dev);
+#endif
+
+	return 0;
+
+out_init_fail:
+	usb_free_coherent(ucr->pusb_dev, IOBUF_SIZE, ucr->iobuf,
+			ucr->iobuf_dma);
+	return ret;
+}
+
+static void rtsx_usb_disconnect(struct usb_interface *intf)
+{
+	struct rtsx_ucr *ucr = (struct rtsx_ucr *)usb_get_intfdata(intf);
+
+	dev_dbg(&intf->dev, "%s called\n", __func__);
+
+	mfd_remove_devices(&intf->dev);
+
+	usb_set_intfdata(ucr->pusb_intf, NULL);
+	usb_free_coherent(ucr->pusb_dev, IOBUF_SIZE, ucr->iobuf,
+			ucr->iobuf_dma);
+}
+
+#ifdef CONFIG_PM
+static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message)
+{
+	struct rtsx_ucr *ucr =
+		(struct rtsx_ucr *)usb_get_intfdata(intf);
+
+	dev_dbg(&intf->dev, "%s called with pm message 0x%04u\n",
+			__func__, message.event);
+
+	mutex_lock(&ucr->dev_mutex);
+	rtsx_usb_turn_off_led(ucr);
+	mutex_unlock(&ucr->dev_mutex);
+	return 0;
+}
+
+static int rtsx_usb_resume(struct usb_interface *intf)
+{
+	return 0;
+}
+
+static int rtsx_usb_reset_resume(struct usb_interface *intf)
+{
+	struct rtsx_ucr *ucr =
+		(struct rtsx_ucr *)usb_get_intfdata(intf);
+
+	rtsx_usb_reset_chip(ucr);
+	return 0;
+}
+
+#else /* CONFIG_PM */
+
+#define rtsx_usb_suspend NULL
+#define rtsx_usb_resume NULL
+#define rtsx_usb_reset_resume NULL
+
+#endif /* CONFIG_PM */
+
+
+static int rtsx_usb_pre_reset(struct usb_interface *intf)
+{
+	struct rtsx_ucr *ucr = (struct rtsx_ucr *)usb_get_intfdata(intf);
+
+	mutex_lock(&ucr->dev_mutex);
+	return 0;
+}
+
+static int rtsx_usb_post_reset(struct usb_interface *intf)
+{
+	struct rtsx_ucr *ucr = (struct rtsx_ucr *)usb_get_intfdata(intf);
+
+	mutex_unlock(&ucr->dev_mutex);
+	return 0;
+}
+
+static struct usb_device_id rtsx_usb_usb_ids[] = {
+	{ USB_DEVICE(0x0BDA, 0x0129) },
+	{ USB_DEVICE(0x0BDA, 0x0139) },
+	{ USB_DEVICE(0x0BDA, 0x0140) },
+	{ }
+};
+
+static struct usb_driver rtsx_usb_driver = {
+	.name			= "rtsx_usb",
+	.probe			= rtsx_usb_probe,
+	.disconnect		= rtsx_usb_disconnect,
+	.suspend		= rtsx_usb_suspend,
+	.resume			= rtsx_usb_resume,
+	.reset_resume		= rtsx_usb_reset_resume,
+	.pre_reset		= rtsx_usb_pre_reset,
+	.post_reset		= rtsx_usb_post_reset,
+	.id_table		= rtsx_usb_usb_ids,
+	.supports_autosuspend	= 1,
+	.soft_unbind		= 1,
+};
+
+module_usb_driver(rtsx_usb_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Roger Tseng <rogerable@realtek.com>");
+MODULE_DESCRIPTION("Realtek USB Card Reader Driver");

+ 14 - 3
drivers/mfd/sec-core.c

@@ -60,6 +60,7 @@ static const struct mfd_cell s5m8767_devs[] = {
 		.name = "s5m-rtc",
 		.name = "s5m-rtc",
 	}, {
 	}, {
 		.name = "s5m8767-clk",
 		.name = "s5m8767-clk",
+		.of_compatible = "samsung,s5m8767-clk",
 	}
 	}
 };
 };
 
 
@@ -68,6 +69,7 @@ static const struct mfd_cell s2mps11_devs[] = {
 		.name = "s2mps11-pmic",
 		.name = "s2mps11-pmic",
 	}, {
 	}, {
 		.name = "s2mps11-clk",
 		.name = "s2mps11-clk",
+		.of_compatible = "samsung,s2mps11-clk",
 	}
 	}
 };
 };
 
 
@@ -78,6 +80,7 @@ static const struct mfd_cell s2mps14_devs[] = {
 		.name = "s2mps14-rtc",
 		.name = "s2mps14-rtc",
 	}, {
 	}, {
 		.name = "s2mps14-clk",
 		.name = "s2mps14-clk",
+		.of_compatible = "samsung,s2mps14-clk",
 	}
 	}
 };
 };
 
 
@@ -295,6 +298,13 @@ static int sec_pmic_probe(struct i2c_client *i2c,
 	switch (sec_pmic->device_type) {
 	switch (sec_pmic->device_type) {
 	case S2MPA01:
 	case S2MPA01:
 		regmap = &s2mpa01_regmap_config;
 		regmap = &s2mpa01_regmap_config;
+		/*
+		 * The rtc-s5m driver does not support S2MPA01 and there
+		 * is no mfd_cell for S2MPA01 RTC device.
+		 * However we must pass something to devm_regmap_init_i2c()
+		 * so use S5M-like regmap config even though it wouldn't work.
+		 */
+		regmap_rtc = &s5m_rtc_regmap_config;
 		break;
 		break;
 	case S2MPS11X:
 	case S2MPS11X:
 		regmap = &s2mps11_regmap_config;
 		regmap = &s2mps11_regmap_config;
@@ -344,7 +354,7 @@ static int sec_pmic_probe(struct i2c_client *i2c,
 		ret = PTR_ERR(sec_pmic->regmap_rtc);
 		ret = PTR_ERR(sec_pmic->regmap_rtc);
 		dev_err(&i2c->dev, "Failed to allocate RTC register map: %d\n",
 		dev_err(&i2c->dev, "Failed to allocate RTC register map: %d\n",
 			ret);
 			ret);
-		return ret;
+		goto err_regmap_rtc;
 	}
 	}
 
 
 	if (pdata && pdata->cfg_pmic_irq)
 	if (pdata && pdata->cfg_pmic_irq)
@@ -385,14 +395,15 @@ static int sec_pmic_probe(struct i2c_client *i2c,
 	}
 	}
 
 
 	if (ret)
 	if (ret)
-		goto err;
+		goto err_mfd;
 
 
 	device_init_wakeup(sec_pmic->dev, sec_pmic->wakeup);
 	device_init_wakeup(sec_pmic->dev, sec_pmic->wakeup);
 
 
 	return ret;
 	return ret;
 
 
-err:
+err_mfd:
 	sec_irq_exit(sec_pmic);
 	sec_irq_exit(sec_pmic);
+err_regmap_rtc:
 	i2c_unregister_device(sec_pmic->rtc);
 	i2c_unregister_device(sec_pmic->rtc);
 	return ret;
 	return ret;
 }
 }

+ 0 - 1
drivers/mfd/smsc-ece1099.c

@@ -13,7 +13,6 @@
 
 
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/moduleparam.h>
-#include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
 #include <linux/gpio.h>
 #include <linux/gpio.h>

+ 1 - 1
drivers/mfd/stmpe.c

@@ -706,7 +706,7 @@ static int stmpe1801_reset(struct stmpe *stmpe)
 		if (!(ret & STMPE1801_MSK_SYS_CTRL_RESET))
 		if (!(ret & STMPE1801_MSK_SYS_CTRL_RESET))
 			return 0;
 			return 0;
 		usleep_range(100, 200);
 		usleep_range(100, 200);
-	};
+	}
 	return -EIO;
 	return -EIO;
 }
 }
 
 

+ 7 - 1
drivers/mfd/stw481x.c

@@ -167,7 +167,7 @@ static struct mfd_cell stw481x_cells[] = {
 	},
 	},
 };
 };
 
 
-const struct regmap_config stw481x_regmap_config = {
+static const struct regmap_config stw481x_regmap_config = {
 	.reg_bits = 8,
 	.reg_bits = 8,
 	.val_bits = 8,
 	.val_bits = 8,
 };
 };
@@ -186,6 +186,12 @@ static int stw481x_probe(struct i2c_client *client,
 	i2c_set_clientdata(client, stw481x);
 	i2c_set_clientdata(client, stw481x);
 	stw481x->client = client;
 	stw481x->client = client;
 	stw481x->map = devm_regmap_init_i2c(client, &stw481x_regmap_config);
 	stw481x->map = devm_regmap_init_i2c(client, &stw481x_regmap_config);
+	if (IS_ERR(stw481x->map)) {
+		ret = PTR_ERR(stw481x->map);
+		dev_err(&client->dev, "Failed to allocate register map: %d\n",
+			ret);
+		return ret;
+	}
 
 
 	ret = stw481x_startup(stw481x);
 	ret = stw481x_startup(stw481x);
 	if (ret) {
 	if (ret) {

+ 1 - 8
drivers/mfd/syscon.c

@@ -69,13 +69,6 @@ EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_compatible);
 
 
 static int syscon_match_pdevname(struct device *dev, void *data)
 static int syscon_match_pdevname(struct device *dev, void *data)
 {
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	const struct platform_device_id *id = platform_get_device_id(pdev);
-
-	if (id)
-		if (!strcmp(id->name, (const char *)data))
-			return 1;
-
 	return !strcmp(dev_name(dev), (const char *)data);
 	return !strcmp(dev_name(dev), (const char *)data);
 }
 }
 
 
@@ -152,7 +145,7 @@ static int syscon_probe(struct platform_device *pdev)
 
 
 	platform_set_drvdata(pdev, syscon);
 	platform_set_drvdata(pdev, syscon);
 
 
-	dev_info(dev, "regmap %pR registered\n", res);
+	dev_dbg(dev, "regmap %pR registered\n", res);
 
 
 	return 0;
 	return 0;
 }
 }

+ 59 - 25
drivers/mfd/tc3589x.c

@@ -13,8 +13,10 @@
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
 #include <linux/of.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/tc3589x.h>
 #include <linux/mfd/tc3589x.h>
+#include <linux/err.h>
 
 
 /**
 /**
  * enum tc3589x_version - indicates the TC3589x version
  * enum tc3589x_version - indicates the TC3589x version
@@ -160,7 +162,7 @@ static const struct mfd_cell tc3589x_dev_gpio[] = {
 		.name		= "tc3589x-gpio",
 		.name		= "tc3589x-gpio",
 		.num_resources	= ARRAY_SIZE(gpio_resources),
 		.num_resources	= ARRAY_SIZE(gpio_resources),
 		.resources	= &gpio_resources[0],
 		.resources	= &gpio_resources[0],
-		.of_compatible	= "tc3589x-gpio",
+		.of_compatible	= "toshiba,tc3589x-gpio",
 	},
 	},
 };
 };
 
 
@@ -169,7 +171,7 @@ static const struct mfd_cell tc3589x_dev_keypad[] = {
 		.name           = "tc3589x-keypad",
 		.name           = "tc3589x-keypad",
 		.num_resources  = ARRAY_SIZE(keypad_resources),
 		.num_resources  = ARRAY_SIZE(keypad_resources),
 		.resources      = &keypad_resources[0],
 		.resources      = &keypad_resources[0],
-		.of_compatible	= "tc3589x-keypad",
+		.of_compatible	= "toshiba,tc3589x-keypad",
 	},
 	},
 };
 };
 
 
@@ -318,45 +320,74 @@ static int tc3589x_device_init(struct tc3589x *tc3589x)
 	return ret;
 	return ret;
 }
 }
 
 
-static int tc3589x_of_probe(struct device_node *np,
-			struct tc3589x_platform_data *pdata)
+#ifdef CONFIG_OF
+static const struct of_device_id tc3589x_match[] = {
+	/* Legacy compatible string */
+	{ .compatible = "tc3589x", .data = (void *) TC3589X_UNKNOWN },
+	{ .compatible = "toshiba,tc35890", .data = (void *) TC3589X_TC35890 },
+	{ .compatible = "toshiba,tc35892", .data = (void *) TC3589X_TC35892 },
+	{ .compatible = "toshiba,tc35893", .data = (void *) TC3589X_TC35893 },
+	{ .compatible = "toshiba,tc35894", .data = (void *) TC3589X_TC35894 },
+	{ .compatible = "toshiba,tc35895", .data = (void *) TC3589X_TC35895 },
+	{ .compatible = "toshiba,tc35896", .data = (void *) TC3589X_TC35896 },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(of, tc3589x_match);
+
+static struct tc3589x_platform_data *
+tc3589x_of_probe(struct device *dev, enum tc3589x_version *version)
 {
 {
+	struct device_node *np = dev->of_node;
+	struct tc3589x_platform_data *pdata;
 	struct device_node *child;
 	struct device_node *child;
+	const struct of_device_id *of_id;
+
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return ERR_PTR(-ENOMEM);
+
+	of_id = of_match_device(tc3589x_match, dev);
+	if (!of_id)
+		return ERR_PTR(-ENODEV);
+	*version = (enum tc3589x_version) of_id->data;
 
 
 	for_each_child_of_node(np, child) {
 	for_each_child_of_node(np, child) {
-		if (!strcmp(child->name, "tc3589x_gpio")) {
+		if (of_device_is_compatible(child, "toshiba,tc3589x-gpio"))
 			pdata->block |= TC3589x_BLOCK_GPIO;
 			pdata->block |= TC3589x_BLOCK_GPIO;
-		}
-		if (!strcmp(child->name, "tc3589x_keypad")) {
+		if (of_device_is_compatible(child, "toshiba,tc3589x-keypad"))
 			pdata->block |= TC3589x_BLOCK_KEYPAD;
 			pdata->block |= TC3589x_BLOCK_KEYPAD;
-		}
 	}
 	}
 
 
-	return 0;
+	return pdata;
 }
 }
+#else
+static inline struct tc3589x_platform_data *
+tc3589x_of_probe(struct device *dev, enum tc3589x_version *version)
+{
+	dev_err(dev, "no device tree support\n");
+	return ERR_PTR(-ENODEV);
+}
+#endif
 
 
 static int tc3589x_probe(struct i2c_client *i2c,
 static int tc3589x_probe(struct i2c_client *i2c,
 				   const struct i2c_device_id *id)
 				   const struct i2c_device_id *id)
 {
 {
-	struct tc3589x_platform_data *pdata = dev_get_platdata(&i2c->dev);
 	struct device_node *np = i2c->dev.of_node;
 	struct device_node *np = i2c->dev.of_node;
+	struct tc3589x_platform_data *pdata = dev_get_platdata(&i2c->dev);
 	struct tc3589x *tc3589x;
 	struct tc3589x *tc3589x;
+	enum tc3589x_version version;
 	int ret;
 	int ret;
 
 
 	if (!pdata) {
 	if (!pdata) {
-		if (np) {
-			pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL);
-			if (!pdata)
-				return -ENOMEM;
-
-			ret = tc3589x_of_probe(np, pdata);
-			if (ret)
-				return ret;
-		}
-		else {
+		pdata = tc3589x_of_probe(&i2c->dev, &version);
+		if (IS_ERR(pdata)) {
 			dev_err(&i2c->dev, "No platform data or DT found\n");
 			dev_err(&i2c->dev, "No platform data or DT found\n");
-			return -EINVAL;
+			return PTR_ERR(pdata);
 		}
 		}
+	} else {
+		/* When not probing from device tree we have this ID */
+		version = id->driver_data;
 	}
 	}
 
 
 	if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA
 	if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA
@@ -375,7 +406,7 @@ static int tc3589x_probe(struct i2c_client *i2c,
 	tc3589x->pdata = pdata;
 	tc3589x->pdata = pdata;
 	tc3589x->irq_base = pdata->irq_base;
 	tc3589x->irq_base = pdata->irq_base;
 
 
-	switch (id->driver_data) {
+	switch (version) {
 	case TC3589X_TC35893:
 	case TC3589X_TC35893:
 	case TC3589X_TC35895:
 	case TC3589X_TC35895:
 	case TC3589X_TC35896:
 	case TC3589X_TC35896:
@@ -471,9 +502,12 @@ static const struct i2c_device_id tc3589x_id[] = {
 MODULE_DEVICE_TABLE(i2c, tc3589x_id);
 MODULE_DEVICE_TABLE(i2c, tc3589x_id);
 
 
 static struct i2c_driver tc3589x_driver = {
 static struct i2c_driver tc3589x_driver = {
-	.driver.name	= "tc3589x",
-	.driver.owner	= THIS_MODULE,
-	.driver.pm	= &tc3589x_dev_pm_ops,
+	.driver = {
+		.name	= "tc3589x",
+		.owner	= THIS_MODULE,
+		.pm	= &tc3589x_dev_pm_ops,
+		.of_match_table = of_match_ptr(tc3589x_match),
+	},
 	.probe		= tc3589x_probe,
 	.probe		= tc3589x_probe,
 	.remove		= tc3589x_remove,
 	.remove		= tc3589x_remove,
 	.id_table	= tc3589x_id,
 	.id_table	= tc3589x_id,

+ 0 - 465
drivers/mfd/ti-ssp.c

@@ -1,465 +0,0 @@
-/*
- * Sequencer Serial Port (SSP) driver for Texas Instruments' SoCs
- *
- * Copyright (C) 2010 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/init.h>
-#include <linux/wait.h>
-#include <linux/clk.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/spinlock.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/sched.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/ti_ssp.h>
-
-/* Register Offsets */
-#define REG_REV		0x00
-#define REG_IOSEL_1	0x04
-#define REG_IOSEL_2	0x08
-#define REG_PREDIV	0x0c
-#define REG_INTR_ST	0x10
-#define REG_INTR_EN	0x14
-#define REG_TEST_CTRL	0x18
-
-/* Per port registers */
-#define PORT_CFG_2	0x00
-#define PORT_ADDR	0x04
-#define PORT_DATA	0x08
-#define PORT_CFG_1	0x0c
-#define PORT_STATE	0x10
-
-#define SSP_PORT_CONFIG_MASK	(SSP_EARLY_DIN | SSP_DELAY_DOUT)
-#define SSP_PORT_CLKRATE_MASK	0x0f
-
-#define SSP_SEQRAM_WR_EN	BIT(4)
-#define SSP_SEQRAM_RD_EN	BIT(5)
-#define SSP_START		BIT(15)
-#define SSP_BUSY		BIT(10)
-#define SSP_PORT_ASL		BIT(7)
-#define SSP_PORT_CFO1		BIT(6)
-
-#define SSP_PORT_SEQRAM_SIZE	32
-
-static const int ssp_port_base[]   = {0x040, 0x080};
-static const int ssp_port_seqram[] = {0x100, 0x180};
-
-struct ti_ssp {
-	struct resource		*res;
-	struct device		*dev;
-	void __iomem		*regs;
-	spinlock_t		lock;
-	struct clk		*clk;
-	int			irq;
-	wait_queue_head_t	wqh;
-
-	/*
-	 * Some of the iosel2 register bits always read-back as 0, we need to
-	 * remember these values so that we don't clobber previously set
-	 * values.
-	 */
-	u32			iosel2;
-};
-
-static inline struct ti_ssp *dev_to_ssp(struct device *dev)
-{
-	return dev_get_drvdata(dev->parent);
-}
-
-static inline int dev_to_port(struct device *dev)
-{
-	return to_platform_device(dev)->id;
-}
-
-/* Register Access Helpers, rmw() functions need to run locked */
-static inline u32 ssp_read(struct ti_ssp *ssp, int reg)
-{
-	return __raw_readl(ssp->regs + reg);
-}
-
-static inline void ssp_write(struct ti_ssp *ssp, int reg, u32 val)
-{
-	__raw_writel(val, ssp->regs + reg);
-}
-
-static inline void ssp_rmw(struct ti_ssp *ssp, int reg, u32 mask, u32 bits)
-{
-	ssp_write(ssp, reg, (ssp_read(ssp, reg) & ~mask) | bits);
-}
-
-static inline u32 ssp_port_read(struct ti_ssp *ssp, int port, int reg)
-{
-	return ssp_read(ssp, ssp_port_base[port] + reg);
-}
-
-static inline void ssp_port_write(struct ti_ssp *ssp, int port, int reg,
-				  u32 val)
-{
-	ssp_write(ssp, ssp_port_base[port] + reg, val);
-}
-
-static inline void ssp_port_rmw(struct ti_ssp *ssp, int port, int reg,
-				u32 mask, u32 bits)
-{
-	ssp_rmw(ssp, ssp_port_base[port] + reg, mask, bits);
-}
-
-static inline void ssp_port_clr_bits(struct ti_ssp *ssp, int port, int reg,
-				     u32 bits)
-{
-	ssp_port_rmw(ssp, port, reg, bits, 0);
-}
-
-static inline void ssp_port_set_bits(struct ti_ssp *ssp, int port, int reg,
-				     u32 bits)
-{
-	ssp_port_rmw(ssp, port, reg, 0, bits);
-}
-
-/* Called to setup port clock mode, caller must hold ssp->lock */
-static int __set_mode(struct ti_ssp *ssp, int port, int mode)
-{
-	mode &= SSP_PORT_CONFIG_MASK;
-	ssp_port_rmw(ssp, port, PORT_CFG_1, SSP_PORT_CONFIG_MASK, mode);
-
-	return 0;
-}
-
-int ti_ssp_set_mode(struct device *dev, int mode)
-{
-	struct ti_ssp *ssp = dev_to_ssp(dev);
-	int port = dev_to_port(dev);
-	int ret;
-
-	spin_lock(&ssp->lock);
-	ret = __set_mode(ssp, port, mode);
-	spin_unlock(&ssp->lock);
-
-	return ret;
-}
-EXPORT_SYMBOL(ti_ssp_set_mode);
-
-/* Called to setup iosel2, caller must hold ssp->lock */
-static void __set_iosel2(struct ti_ssp *ssp, u32 mask, u32 val)
-{
-	ssp->iosel2 = (ssp->iosel2 & ~mask) | val;
-	ssp_write(ssp, REG_IOSEL_2, ssp->iosel2);
-}
-
-/* Called to setup port iosel, caller must hold ssp->lock */
-static void __set_iosel(struct ti_ssp *ssp, int port, u32 iosel)
-{
-	unsigned val, shift = port ? 16 : 0;
-
-	/* IOSEL1 gets the least significant 16 bits */
-	val = ssp_read(ssp, REG_IOSEL_1);
-	val &= 0xffff << (port ? 0 : 16);
-	val |= (iosel & 0xffff) << (port ? 16 : 0);
-	ssp_write(ssp, REG_IOSEL_1, val);
-
-	/* IOSEL2 gets the most significant 16 bits */
-	val = (iosel >> 16) & 0x7;
-	__set_iosel2(ssp, 0x7 << shift, val << shift);
-}
-
-int ti_ssp_set_iosel(struct device *dev, u32 iosel)
-{
-	struct ti_ssp *ssp = dev_to_ssp(dev);
-	int port = dev_to_port(dev);
-
-	spin_lock(&ssp->lock);
-	__set_iosel(ssp, port, iosel);
-	spin_unlock(&ssp->lock);
-
-	return 0;
-}
-EXPORT_SYMBOL(ti_ssp_set_iosel);
-
-int ti_ssp_load(struct device *dev, int offs, u32* prog, int len)
-{
-	struct ti_ssp *ssp = dev_to_ssp(dev);
-	int port = dev_to_port(dev);
-	int i;
-
-	if (len > SSP_PORT_SEQRAM_SIZE)
-		return -ENOSPC;
-
-	spin_lock(&ssp->lock);
-
-	/* Enable SeqRAM access */
-	ssp_port_set_bits(ssp, port, PORT_CFG_2, SSP_SEQRAM_WR_EN);
-
-	/* Copy code */
-	for (i = 0; i < len; i++) {
-		__raw_writel(prog[i], ssp->regs + offs + 4*i +
-			     ssp_port_seqram[port]);
-	}
-
-	/* Disable SeqRAM access */
-	ssp_port_clr_bits(ssp, port, PORT_CFG_2, SSP_SEQRAM_WR_EN);
-
-	spin_unlock(&ssp->lock);
-
-	return 0;
-}
-EXPORT_SYMBOL(ti_ssp_load);
-
-int ti_ssp_raw_read(struct device *dev)
-{
-	struct ti_ssp *ssp = dev_to_ssp(dev);
-	int port = dev_to_port(dev);
-	int shift = port ? 27 : 11;
-
-	return (ssp_read(ssp, REG_IOSEL_2) >> shift) & 0xf;
-}
-EXPORT_SYMBOL(ti_ssp_raw_read);
-
-int ti_ssp_raw_write(struct device *dev, u32 val)
-{
-	struct ti_ssp *ssp = dev_to_ssp(dev);
-	int port = dev_to_port(dev), shift;
-
-	spin_lock(&ssp->lock);
-
-	shift = port ? 22 : 6;
-	val &= 0xf;
-	__set_iosel2(ssp, 0xf << shift, val << shift);
-
-	spin_unlock(&ssp->lock);
-
-	return 0;
-}
-EXPORT_SYMBOL(ti_ssp_raw_write);
-
-static inline int __xfer_done(struct ti_ssp *ssp, int port)
-{
-	return !(ssp_port_read(ssp, port, PORT_CFG_1) & SSP_BUSY);
-}
-
-int ti_ssp_run(struct device *dev, u32 pc, u32 input, u32 *output)
-{
-	struct ti_ssp *ssp = dev_to_ssp(dev);
-	int port = dev_to_port(dev);
-	int ret;
-
-	if (pc & ~(0x3f))
-		return -EINVAL;
-
-	/* Grab ssp->lock to serialize rmw on ssp registers */
-	spin_lock(&ssp->lock);
-
-	ssp_port_write(ssp, port, PORT_ADDR, input >> 16);
-	ssp_port_write(ssp, port, PORT_DATA, input & 0xffff);
-	ssp_port_rmw(ssp, port, PORT_CFG_1, 0x3f, pc);
-
-	/* grab wait queue head lock to avoid race with the isr */
-	spin_lock_irq(&ssp->wqh.lock);
-
-	/* kick off sequence execution in hardware */
-	ssp_port_set_bits(ssp, port, PORT_CFG_1, SSP_START);
-
-	/* drop ssp lock; no register writes beyond this */
-	spin_unlock(&ssp->lock);
-
-	ret = wait_event_interruptible_locked_irq(ssp->wqh,
-						  __xfer_done(ssp, port));
-	spin_unlock_irq(&ssp->wqh.lock);
-
-	if (ret < 0)
-		return ret;
-
-	if (output) {
-		*output = (ssp_port_read(ssp, port, PORT_ADDR) << 16) |
-			  (ssp_port_read(ssp, port, PORT_DATA) &  0xffff);
-	}
-
-	ret = ssp_port_read(ssp, port, PORT_STATE) & 0x3f; /* stop address */
-
-	return ret;
-}
-EXPORT_SYMBOL(ti_ssp_run);
-
-static irqreturn_t ti_ssp_interrupt(int irq, void *dev_data)
-{
-	struct ti_ssp *ssp = dev_data;
-
-	spin_lock(&ssp->wqh.lock);
-
-	ssp_write(ssp, REG_INTR_ST, 0x3);
-	wake_up_locked(&ssp->wqh);
-
-	spin_unlock(&ssp->wqh.lock);
-
-	return IRQ_HANDLED;
-}
-
-static int ti_ssp_probe(struct platform_device *pdev)
-{
-	static struct ti_ssp *ssp;
-	const struct ti_ssp_data *pdata = dev_get_platdata(&pdev->dev);
-	int error = 0, prediv = 0xff, id;
-	unsigned long sysclk;
-	struct device *dev = &pdev->dev;
-	struct mfd_cell cells[2];
-
-	ssp = kzalloc(sizeof(*ssp), GFP_KERNEL);
-	if (!ssp) {
-		dev_err(dev, "cannot allocate device info\n");
-		return -ENOMEM;
-	}
-
-	ssp->dev = dev;
-	dev_set_drvdata(dev, ssp);
-
-	ssp->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!ssp->res) {
-		error = -ENODEV;
-		dev_err(dev, "cannot determine register area\n");
-		goto error_res;
-	}
-
-	if (!request_mem_region(ssp->res->start, resource_size(ssp->res),
-				pdev->name)) {
-		error = -ENOMEM;
-		dev_err(dev, "cannot claim register memory\n");
-		goto error_res;
-	}
-
-	ssp->regs = ioremap(ssp->res->start, resource_size(ssp->res));
-	if (!ssp->regs) {
-		error = -ENOMEM;
-		dev_err(dev, "cannot map register memory\n");
-		goto error_map;
-	}
-
-	ssp->clk = clk_get(dev, NULL);
-	if (IS_ERR(ssp->clk)) {
-		error = PTR_ERR(ssp->clk);
-		dev_err(dev, "cannot claim device clock\n");
-		goto error_clk;
-	}
-
-	ssp->irq = platform_get_irq(pdev, 0);
-	if (ssp->irq < 0) {
-		error = -ENODEV;
-		dev_err(dev, "unknown irq\n");
-		goto error_irq;
-	}
-
-	error = request_threaded_irq(ssp->irq, NULL, ti_ssp_interrupt, 0,
-				     dev_name(dev), ssp);
-	if (error < 0) {
-		dev_err(dev, "cannot acquire irq\n");
-		goto error_irq;
-	}
-
-	spin_lock_init(&ssp->lock);
-	init_waitqueue_head(&ssp->wqh);
-
-	/* Power on and initialize SSP */
-	error = clk_enable(ssp->clk);
-	if (error) {
-		dev_err(dev, "cannot enable device clock\n");
-		goto error_enable;
-	}
-
-	/* Reset registers to a sensible known state */
-	ssp_write(ssp, REG_IOSEL_1, 0);
-	ssp_write(ssp, REG_IOSEL_2, 0);
-	ssp_write(ssp, REG_INTR_EN, 0x3);
-	ssp_write(ssp, REG_INTR_ST, 0x3);
-	ssp_write(ssp, REG_TEST_CTRL, 0);
-	ssp_port_write(ssp, 0, PORT_CFG_1, SSP_PORT_ASL);
-	ssp_port_write(ssp, 1, PORT_CFG_1, SSP_PORT_ASL);
-	ssp_port_write(ssp, 0, PORT_CFG_2, SSP_PORT_CFO1);
-	ssp_port_write(ssp, 1, PORT_CFG_2, SSP_PORT_CFO1);
-
-	sysclk = clk_get_rate(ssp->clk);
-	if (pdata && pdata->out_clock)
-		prediv = (sysclk / pdata->out_clock) - 1;
-	prediv = clamp(prediv, 0, 0xff);
-	ssp_rmw(ssp, REG_PREDIV, 0xff, prediv);
-
-	memset(cells, 0, sizeof(cells));
-	for (id = 0; id < 2; id++) {
-		const struct ti_ssp_dev_data *data = &pdata->dev_data[id];
-
-		cells[id].id		= id;
-		cells[id].name		= data->dev_name;
-		cells[id].platform_data	= data->pdata;
-	}
-
-	error = mfd_add_devices(dev, 0, cells, 2, NULL, 0, NULL);
-	if (error < 0) {
-		dev_err(dev, "cannot add mfd cells\n");
-		goto error_enable;
-	}
-
-	return 0;
-
-error_enable:
-	free_irq(ssp->irq, ssp);
-error_irq:
-	clk_put(ssp->clk);
-error_clk:
-	iounmap(ssp->regs);
-error_map:
-	release_mem_region(ssp->res->start, resource_size(ssp->res));
-error_res:
-	kfree(ssp);
-	return error;
-}
-
-static int ti_ssp_remove(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct ti_ssp *ssp = dev_get_drvdata(dev);
-
-	mfd_remove_devices(dev);
-	clk_disable(ssp->clk);
-	free_irq(ssp->irq, ssp);
-	clk_put(ssp->clk);
-	iounmap(ssp->regs);
-	release_mem_region(ssp->res->start, resource_size(ssp->res));
-	kfree(ssp);
-	return 0;
-}
-
-static struct platform_driver ti_ssp_driver = {
-	.probe		= ti_ssp_probe,
-	.remove		= ti_ssp_remove,
-	.driver		= {
-		.name	= "ti-ssp",
-		.owner	= THIS_MODULE,
-	}
-};
-
-module_platform_driver(ti_ssp_driver);
-
-MODULE_DESCRIPTION("Sequencer Serial Port (SSP) Driver");
-MODULE_AUTHOR("Cyril Chemparathy");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:ti-ssp");

+ 4 - 20
drivers/mfd/ti_am335x_tscadc.c

@@ -14,7 +14,6 @@
  */
  */
 
 
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/io.h>
@@ -184,12 +183,6 @@ static	int ti_tscadc_probe(struct platform_device *pdev)
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dev_err(&pdev->dev, "no memory resource defined.\n");
-		return -EINVAL;
-	}
-
 	/* Allocate memory for device */
 	/* Allocate memory for device */
 	tscadc = devm_kzalloc(&pdev->dev,
 	tscadc = devm_kzalloc(&pdev->dev,
 			sizeof(struct ti_tscadc_dev), GFP_KERNEL);
 			sizeof(struct ti_tscadc_dev), GFP_KERNEL);
@@ -206,19 +199,10 @@ static	int ti_tscadc_probe(struct platform_device *pdev)
 	} else
 	} else
 		tscadc->irq = err;
 		tscadc->irq = err;
 
 
-	res = devm_request_mem_region(&pdev->dev,
-			res->start, resource_size(res), pdev->name);
-	if (!res) {
-		dev_err(&pdev->dev, "failed to reserve registers.\n");
-		return -EBUSY;
-	}
-
-	tscadc->tscadc_base = devm_ioremap(&pdev->dev,
-			res->start, resource_size(res));
-	if (!tscadc->tscadc_base) {
-		dev_err(&pdev->dev, "failed to map registers.\n");
-		return -ENOMEM;
-	}
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	tscadc->tscadc_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(tscadc->tscadc_base))
+		return PTR_ERR(tscadc->tscadc_base);
 
 
 	tscadc->regmap_tscadc = devm_regmap_init_mmio(&pdev->dev,
 	tscadc->regmap_tscadc = devm_regmap_init_mmio(&pdev->dev,
 			tscadc->tscadc_base, &tscadc_regmap_config);
 			tscadc->tscadc_base, &tscadc_regmap_config);

+ 1 - 1
drivers/mfd/timberdale.c

@@ -715,7 +715,7 @@ static int timb_probe(struct pci_dev *dev,
 	for (i = 0; i < TIMBERDALE_NR_IRQS; i++)
 	for (i = 0; i < TIMBERDALE_NR_IRQS; i++)
 		msix_entries[i].entry = i;
 		msix_entries[i].entry = i;
 
 
-	err = pci_enable_msix(dev, msix_entries, TIMBERDALE_NR_IRQS);
+	err = pci_enable_msix_exact(dev, msix_entries, TIMBERDALE_NR_IRQS);
 	if (err) {
 	if (err) {
 		dev_err(&dev->dev,
 		dev_err(&dev->dev,
 			"MSI-X init failed: %d, expected entries: %d\n",
 			"MSI-X init failed: %d, expected entries: %d\n",

+ 282 - 0
drivers/mfd/tps65218.c

@@ -0,0 +1,282 @@
+/*
+ * Driver for TPS65218 Integrated power management chipsets
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.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.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether expressed or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License version 2 for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/regmap.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/mutex.h>
+
+#include <linux/mfd/core.h>
+#include <linux/mfd/tps65218.h>
+
+#define TPS65218_PASSWORD_REGS_UNLOCK   0x7D
+
+/**
+ * tps65218_reg_read: Read a single tps65218 register.
+ *
+ * @tps: Device to read from.
+ * @reg: Register to read.
+ * @val: Contians the value
+ */
+int tps65218_reg_read(struct tps65218 *tps, unsigned int reg,
+			unsigned int *val)
+{
+	return regmap_read(tps->regmap, reg, val);
+}
+EXPORT_SYMBOL_GPL(tps65218_reg_read);
+
+/**
+ * tps65218_reg_write: Write a single tps65218 register.
+ *
+ * @tps65218: Device to write to.
+ * @reg: Register to write to.
+ * @val: Value to write.
+ * @level: Password protected level
+ */
+int tps65218_reg_write(struct tps65218 *tps, unsigned int reg,
+			unsigned int val, unsigned int level)
+{
+	int ret;
+	unsigned int xor_reg_val;
+
+	switch (level) {
+	case TPS65218_PROTECT_NONE:
+		return regmap_write(tps->regmap, reg, val);
+	case TPS65218_PROTECT_L1:
+		xor_reg_val = reg ^ TPS65218_PASSWORD_REGS_UNLOCK;
+		ret = regmap_write(tps->regmap, TPS65218_REG_PASSWORD,
+							xor_reg_val);
+		if (ret < 0)
+			return ret;
+
+		return regmap_write(tps->regmap, reg, val);
+	default:
+		return -EINVAL;
+	}
+}
+EXPORT_SYMBOL_GPL(tps65218_reg_write);
+
+/**
+ * tps65218_update_bits: Modify bits w.r.t mask, val and level.
+ *
+ * @tps65218: Device to write to.
+ * @reg: Register to read-write to.
+ * @mask: Mask.
+ * @val: Value to write.
+ * @level: Password protected level
+ */
+static int tps65218_update_bits(struct tps65218 *tps, unsigned int reg,
+		unsigned int mask, unsigned int val, unsigned int level)
+{
+	int ret;
+	unsigned int data;
+
+	ret = tps65218_reg_read(tps, reg, &data);
+	if (ret) {
+		dev_err(tps->dev, "Read from reg 0x%x failed\n", reg);
+		return ret;
+	}
+
+	data &= ~mask;
+	data |= val & mask;
+
+	mutex_lock(&tps->tps_lock);
+	ret = tps65218_reg_write(tps, reg, data, level);
+	if (ret)
+		dev_err(tps->dev, "Write for reg 0x%x failed\n", reg);
+	mutex_unlock(&tps->tps_lock);
+
+	return ret;
+}
+
+int tps65218_set_bits(struct tps65218 *tps, unsigned int reg,
+		unsigned int mask, unsigned int val, unsigned int level)
+{
+	return tps65218_update_bits(tps, reg, mask, val, level);
+}
+EXPORT_SYMBOL_GPL(tps65218_set_bits);
+
+int tps65218_clear_bits(struct tps65218 *tps, unsigned int reg,
+		unsigned int mask, unsigned int level)
+{
+	return tps65218_update_bits(tps, reg, mask, 0, level);
+}
+EXPORT_SYMBOL_GPL(tps65218_clear_bits);
+
+static struct regmap_config tps65218_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.cache_type = REGCACHE_RBTREE,
+};
+
+static const struct regmap_irq tps65218_irqs[] = {
+	/* INT1 IRQs */
+	[TPS65218_PRGC_IRQ] = {
+		.mask = TPS65218_INT1_PRGC,
+	},
+	[TPS65218_CC_AQC_IRQ] = {
+		.mask = TPS65218_INT1_CC_AQC,
+	},
+	[TPS65218_HOT_IRQ] = {
+		.mask = TPS65218_INT1_HOT,
+	},
+	[TPS65218_PB_IRQ] = {
+		.mask = TPS65218_INT1_PB,
+	},
+	[TPS65218_AC_IRQ] = {
+		.mask = TPS65218_INT1_AC,
+	},
+	[TPS65218_VPRG_IRQ] = {
+		.mask = TPS65218_INT1_VPRG,
+	},
+	[TPS65218_INVALID1_IRQ] = {
+	},
+	[TPS65218_INVALID2_IRQ] = {
+	},
+	/* INT2 IRQs*/
+	[TPS65218_LS1_I_IRQ] = {
+		.mask = TPS65218_INT2_LS1_I,
+		.reg_offset = 1,
+	},
+	[TPS65218_LS2_I_IRQ] = {
+		.mask = TPS65218_INT2_LS2_I,
+		.reg_offset = 1,
+	},
+	[TPS65218_LS3_I_IRQ] = {
+		.mask = TPS65218_INT2_LS3_I,
+		.reg_offset = 1,
+	},
+	[TPS65218_LS1_F_IRQ] = {
+		.mask = TPS65218_INT2_LS1_F,
+		.reg_offset = 1,
+	},
+	[TPS65218_LS2_F_IRQ] = {
+		.mask = TPS65218_INT2_LS2_F,
+		.reg_offset = 1,
+	},
+	[TPS65218_LS3_F_IRQ] = {
+		.mask = TPS65218_INT2_LS3_F,
+		.reg_offset = 1,
+	},
+	[TPS65218_INVALID3_IRQ] = {
+	},
+	[TPS65218_INVALID4_IRQ] = {
+	},
+};
+
+static struct regmap_irq_chip tps65218_irq_chip = {
+	.name = "tps65218",
+	.irqs = tps65218_irqs,
+	.num_irqs = ARRAY_SIZE(tps65218_irqs),
+
+	.num_regs = 2,
+	.mask_base = TPS65218_REG_INT_MASK1,
+};
+
+static const struct of_device_id of_tps65218_match_table[] = {
+	{ .compatible = "ti,tps65218", },
+};
+
+static int tps65218_probe(struct i2c_client *client,
+				const struct i2c_device_id *ids)
+{
+	struct tps65218 *tps;
+	const struct of_device_id *match;
+	int ret;
+
+	match = of_match_device(of_tps65218_match_table, &client->dev);
+	if (!match) {
+		dev_err(&client->dev,
+			"Failed to find matching dt id\n");
+		return -EINVAL;
+	}
+
+	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
+	if (!tps)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, tps);
+	tps->dev = &client->dev;
+	tps->irq = client->irq;
+	tps->regmap = devm_regmap_init_i2c(client, &tps65218_regmap_config);
+	if (IS_ERR(tps->regmap)) {
+		ret = PTR_ERR(tps->regmap);
+		dev_err(tps->dev, "Failed to allocate register map: %d\n",
+			ret);
+		return ret;
+	}
+
+	mutex_init(&tps->tps_lock);
+
+	ret = regmap_add_irq_chip(tps->regmap, tps->irq,
+			IRQF_ONESHOT, 0, &tps65218_irq_chip,
+			&tps->irq_data);
+	if (ret < 0)
+		return ret;
+
+	ret = of_platform_populate(client->dev.of_node, NULL, NULL,
+				   &client->dev);
+	if (ret < 0)
+		goto err_irq;
+
+	return 0;
+
+err_irq:
+	regmap_del_irq_chip(tps->irq, tps->irq_data);
+
+	return ret;
+}
+
+static int tps65218_remove(struct i2c_client *client)
+{
+	struct tps65218 *tps = i2c_get_clientdata(client);
+
+	regmap_del_irq_chip(tps->irq, tps->irq_data);
+
+	return 0;
+}
+
+static const struct i2c_device_id tps65218_id_table[] = {
+	{ "tps65218", TPS65218 },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, tps65218_id_table);
+
+static struct i2c_driver tps65218_driver = {
+	.driver		= {
+		.name	= "tps65218",
+		.owner	= THIS_MODULE,
+		.of_match_table = of_tps65218_match_table,
+	},
+	.probe		= tps65218_probe,
+	.remove		= tps65218_remove,
+	.id_table       = tps65218_id_table,
+};
+
+module_i2c_driver(tps65218_driver);
+
+MODULE_AUTHOR("J Keerthy <j-keerthy@ti.com>");
+MODULE_DESCRIPTION("TPS65218 chip family multi-function driver");
+MODULE_LICENSE("GPL v2");

+ 4 - 1
drivers/mfd/tps65910.c

@@ -255,8 +255,10 @@ static int tps65910_irq_init(struct tps65910 *tps65910, int irq,
 	ret = regmap_add_irq_chip(tps65910->regmap, tps65910->chip_irq,
 	ret = regmap_add_irq_chip(tps65910->regmap, tps65910->chip_irq,
 		IRQF_ONESHOT, pdata->irq_base,
 		IRQF_ONESHOT, pdata->irq_base,
 		tps6591x_irqs_chip, &tps65910->irq_data);
 		tps6591x_irqs_chip, &tps65910->irq_data);
-	if (ret < 0)
+	if (ret < 0) {
 		dev_warn(tps65910->dev, "Failed to add irq_chip %d\n", ret);
 		dev_warn(tps65910->dev, "Failed to add irq_chip %d\n", ret);
+		tps65910->chip_irq = 0;
+	}
 	return ret;
 	return ret;
 }
 }
 
 
@@ -509,6 +511,7 @@ static int tps65910_i2c_probe(struct i2c_client *i2c,
 			      regmap_irq_get_domain(tps65910->irq_data));
 			      regmap_irq_get_domain(tps65910->irq_data));
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&i2c->dev, "mfd_add_devices failed: %d\n", ret);
 		dev_err(&i2c->dev, "mfd_add_devices failed: %d\n", ret);
+		tps65910_irq_exit(tps65910);
 		return ret;
 		return ret;
 	}
 	}
 
 

+ 0 - 1
drivers/mfd/tps65912-core.c

@@ -15,7 +15,6 @@
 
 
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/moduleparam.h>
-#include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/gpio.h>
 #include <linux/gpio.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/core.h>

+ 0 - 1
drivers/mfd/tps65912-irq.c

@@ -15,7 +15,6 @@
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/bug.h>
 #include <linux/bug.h>
 #include <linux/device.h>
 #include <linux/device.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>

+ 5 - 5
drivers/mfd/twl-core.c

@@ -282,11 +282,11 @@ static struct reg_default twl4030_49_defaults[] = {
 static bool twl4030_49_nop_reg(struct device *dev, unsigned int reg)
 static bool twl4030_49_nop_reg(struct device *dev, unsigned int reg)
 {
 {
 	switch (reg) {
 	switch (reg) {
-	case 0:
-	case 3:
-	case 40:
-	case 41:
-	case 42:
+	case 0x00:
+	case 0x03:
+	case 0x40:
+	case 0x41:
+	case 0x42:
 		return false;
 		return false;
 	default:
 	default:
 		return true;
 		return true;

+ 0 - 1
drivers/mfd/twl4030-irq.c

@@ -27,7 +27,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
  */
 
 
-#include <linux/init.h>
 #include <linux/export.h>
 #include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/irq.h>

+ 0 - 1
drivers/mfd/twl6030-irq.c

@@ -31,7 +31,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
  */
 
 
-#include <linux/init.h>
 #include <linux/export.h>
 #include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/irq.h>

+ 5 - 1
drivers/mfd/twl6040.c

@@ -661,6 +661,11 @@ static int twl6040_probe(struct i2c_client *client,
 	init_completion(&twl6040->ready);
 	init_completion(&twl6040->ready);
 
 
 	twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV);
 	twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV);
+	if (twl6040->rev < 0) {
+		dev_err(&client->dev, "Failed to read revision register: %d\n",
+			twl6040->rev);
+		goto gpio_err;
+	}
 
 
 	/* ERRATA: Automatic power-up is not possible in ES1.0 */
 	/* ERRATA: Automatic power-up is not possible in ES1.0 */
 	if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0)
 	if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0)
@@ -703,7 +708,6 @@ static int twl6040_probe(struct i2c_client *client,
 	}
 	}
 
 
 	/* dual-access registers controlled by I2C only */
 	/* dual-access registers controlled by I2C only */
-	twl6040_set_bits(twl6040, TWL6040_REG_ACCCTL, TWL6040_I2CSEL);
 	regmap_register_patch(twl6040->regmap, twl6040_patch,
 	regmap_register_patch(twl6040->regmap, twl6040_patch,
 			      ARRAY_SIZE(twl6040_patch));
 			      ARRAY_SIZE(twl6040_patch));
 
 

+ 1 - 3
drivers/mfd/ucb1x00-core.c

@@ -742,9 +742,7 @@ static int ucb1x00_resume(struct device *dev)
 }
 }
 #endif
 #endif
 
 
-static const struct dev_pm_ops ucb1x00_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(ucb1x00_suspend, ucb1x00_resume)
-};
+static SIMPLE_DEV_PM_OPS(ucb1x00_pm_ops, ucb1x00_suspend, ucb1x00_resume);
 
 
 static struct mcp_driver ucb1x00_driver = {
 static struct mcp_driver ucb1x00_driver = {
 	.drv		= {
 	.drv		= {

+ 1 - 2
drivers/mfd/vexpress-config.c

@@ -16,7 +16,6 @@
 #include <linux/bitops.h>
 #include <linux/bitops.h>
 #include <linux/completion.h>
 #include <linux/completion.h>
 #include <linux/export.h>
 #include <linux/export.h>
-#include <linux/init.h>
 #include <linux/list.h>
 #include <linux/list.h>
 #include <linux/of.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_device.h>
@@ -27,7 +26,7 @@
 
 
 #define VEXPRESS_CONFIG_MAX_BRIDGES 2
 #define VEXPRESS_CONFIG_MAX_BRIDGES 2
 
 
-struct vexpress_config_bridge {
+static struct vexpress_config_bridge {
 	struct device_node *node;
 	struct device_node *node;
 	struct vexpress_config_bridge_info *info;
 	struct vexpress_config_bridge_info *info;
 	struct list_head transactions;
 	struct list_head transactions;

+ 1 - 1
drivers/mfd/vexpress-sysreg.c

@@ -168,7 +168,7 @@ static void *vexpress_sysreg_config_func_get(struct device *dev,
 		struct device_node *node)
 		struct device_node *node)
 {
 {
 	struct vexpress_sysreg_config_func *config_func;
 	struct vexpress_sysreg_config_func *config_func;
-	u32 site;
+	u32 site = 0;
 	u32 position = 0;
 	u32 position = 0;
 	u32 dcc = 0;
 	u32 dcc = 0;
 	u32 func_device[2];
 	u32 func_device[2];

+ 36 - 0
drivers/mfd/wm5102-tables.c

@@ -73,6 +73,7 @@ static const struct reg_default wm5102_revb_patch[] = {
 	{ 0x171, 0x0000 },
 	{ 0x171, 0x0000 },
 	{ 0x35E, 0x000C },
 	{ 0x35E, 0x000C },
 	{ 0x2D4, 0x0000 },
 	{ 0x2D4, 0x0000 },
+	{ 0x4DC, 0x0900 },
 	{ 0x80, 0x0000 },
 	{ 0x80, 0x0000 },
 };
 };
 
 
@@ -1839,6 +1840,23 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg)
 	case ARIZONA_DSP1_STATUS_1:
 	case ARIZONA_DSP1_STATUS_1:
 	case ARIZONA_DSP1_STATUS_2:
 	case ARIZONA_DSP1_STATUS_2:
 	case ARIZONA_DSP1_STATUS_3:
 	case ARIZONA_DSP1_STATUS_3:
+	case ARIZONA_DSP1_WDMA_BUFFER_1:
+	case ARIZONA_DSP1_WDMA_BUFFER_2:
+	case ARIZONA_DSP1_WDMA_BUFFER_3:
+	case ARIZONA_DSP1_WDMA_BUFFER_4:
+	case ARIZONA_DSP1_WDMA_BUFFER_5:
+	case ARIZONA_DSP1_WDMA_BUFFER_6:
+	case ARIZONA_DSP1_WDMA_BUFFER_7:
+	case ARIZONA_DSP1_WDMA_BUFFER_8:
+	case ARIZONA_DSP1_RDMA_BUFFER_1:
+	case ARIZONA_DSP1_RDMA_BUFFER_2:
+	case ARIZONA_DSP1_RDMA_BUFFER_3:
+	case ARIZONA_DSP1_RDMA_BUFFER_4:
+	case ARIZONA_DSP1_RDMA_BUFFER_5:
+	case ARIZONA_DSP1_RDMA_BUFFER_6:
+	case ARIZONA_DSP1_WDMA_CONFIG_1:
+	case ARIZONA_DSP1_WDMA_CONFIG_2:
+	case ARIZONA_DSP1_RDMA_CONFIG_1:
 	case ARIZONA_DSP1_SCRATCH_0:
 	case ARIZONA_DSP1_SCRATCH_0:
 	case ARIZONA_DSP1_SCRATCH_1:
 	case ARIZONA_DSP1_SCRATCH_1:
 	case ARIZONA_DSP1_SCRATCH_2:
 	case ARIZONA_DSP1_SCRATCH_2:
@@ -1894,9 +1912,27 @@ static bool wm5102_volatile_register(struct device *dev, unsigned int reg)
 	case ARIZONA_AOD_IRQ1:
 	case ARIZONA_AOD_IRQ1:
 	case ARIZONA_AOD_IRQ2:
 	case ARIZONA_AOD_IRQ2:
 	case ARIZONA_AOD_IRQ_RAW_STATUS:
 	case ARIZONA_AOD_IRQ_RAW_STATUS:
+	case ARIZONA_DSP1_CLOCKING_1:
 	case ARIZONA_DSP1_STATUS_1:
 	case ARIZONA_DSP1_STATUS_1:
 	case ARIZONA_DSP1_STATUS_2:
 	case ARIZONA_DSP1_STATUS_2:
 	case ARIZONA_DSP1_STATUS_3:
 	case ARIZONA_DSP1_STATUS_3:
+	case ARIZONA_DSP1_WDMA_BUFFER_1:
+	case ARIZONA_DSP1_WDMA_BUFFER_2:
+	case ARIZONA_DSP1_WDMA_BUFFER_3:
+	case ARIZONA_DSP1_WDMA_BUFFER_4:
+	case ARIZONA_DSP1_WDMA_BUFFER_5:
+	case ARIZONA_DSP1_WDMA_BUFFER_6:
+	case ARIZONA_DSP1_WDMA_BUFFER_7:
+	case ARIZONA_DSP1_WDMA_BUFFER_8:
+	case ARIZONA_DSP1_RDMA_BUFFER_1:
+	case ARIZONA_DSP1_RDMA_BUFFER_2:
+	case ARIZONA_DSP1_RDMA_BUFFER_3:
+	case ARIZONA_DSP1_RDMA_BUFFER_4:
+	case ARIZONA_DSP1_RDMA_BUFFER_5:
+	case ARIZONA_DSP1_RDMA_BUFFER_6:
+	case ARIZONA_DSP1_WDMA_CONFIG_1:
+	case ARIZONA_DSP1_WDMA_CONFIG_2:
+	case ARIZONA_DSP1_RDMA_CONFIG_1:
 	case ARIZONA_DSP1_SCRATCH_0:
 	case ARIZONA_DSP1_SCRATCH_0:
 	case ARIZONA_DSP1_SCRATCH_1:
 	case ARIZONA_DSP1_SCRATCH_1:
 	case ARIZONA_DSP1_SCRATCH_2:
 	case ARIZONA_DSP1_SCRATCH_2:

+ 173 - 1
drivers/mfd/wm5110-tables.c

@@ -538,7 +538,7 @@ static const struct reg_default wm5110_reg_default[] = {
 	{ 0x00000219, 0x01A6 },    /* R537   - Mic Bias Ctrl 2 */
 	{ 0x00000219, 0x01A6 },    /* R537   - Mic Bias Ctrl 2 */
 	{ 0x0000021A, 0x01A6 },    /* R538   - Mic Bias Ctrl 3 */
 	{ 0x0000021A, 0x01A6 },    /* R538   - Mic Bias Ctrl 3 */
 	{ 0x00000293, 0x0000 },    /* R659   - Accessory Detect Mode 1 */
 	{ 0x00000293, 0x0000 },    /* R659   - Accessory Detect Mode 1 */
-	{ 0x0000029B, 0x0020 },    /* R667   - Headphone Detect 1 */
+	{ 0x0000029B, 0x0028 },    /* R667   - Headphone Detect 1 */
 	{ 0x0000029C, 0x0000 },    /* R668   - Headphone Detect 2 */
 	{ 0x0000029C, 0x0000 },    /* R668   - Headphone Detect 2 */
 	{ 0x000002A2, 0x0000 },    /* R674   - Micd clamp control */
 	{ 0x000002A2, 0x0000 },    /* R674   - Micd clamp control */
 	{ 0x000002A3, 0x1102 },    /* R675   - Mic Detect 1 */
 	{ 0x000002A3, 0x1102 },    /* R675   - Mic Detect 1 */
@@ -2461,6 +2461,27 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
 	case ARIZONA_DSP1_STATUS_1:
 	case ARIZONA_DSP1_STATUS_1:
 	case ARIZONA_DSP1_STATUS_2:
 	case ARIZONA_DSP1_STATUS_2:
 	case ARIZONA_DSP1_STATUS_3:
 	case ARIZONA_DSP1_STATUS_3:
+	case ARIZONA_DSP1_STATUS_4:
+	case ARIZONA_DSP1_WDMA_BUFFER_1:
+	case ARIZONA_DSP1_WDMA_BUFFER_2:
+	case ARIZONA_DSP1_WDMA_BUFFER_3:
+	case ARIZONA_DSP1_WDMA_BUFFER_4:
+	case ARIZONA_DSP1_WDMA_BUFFER_5:
+	case ARIZONA_DSP1_WDMA_BUFFER_6:
+	case ARIZONA_DSP1_WDMA_BUFFER_7:
+	case ARIZONA_DSP1_WDMA_BUFFER_8:
+	case ARIZONA_DSP1_RDMA_BUFFER_1:
+	case ARIZONA_DSP1_RDMA_BUFFER_2:
+	case ARIZONA_DSP1_RDMA_BUFFER_3:
+	case ARIZONA_DSP1_RDMA_BUFFER_4:
+	case ARIZONA_DSP1_RDMA_BUFFER_5:
+	case ARIZONA_DSP1_RDMA_BUFFER_6:
+	case ARIZONA_DSP1_WDMA_CONFIG_1:
+	case ARIZONA_DSP1_WDMA_CONFIG_2:
+	case ARIZONA_DSP1_WDMA_OFFSET_1:
+	case ARIZONA_DSP1_RDMA_CONFIG_1:
+	case ARIZONA_DSP1_RDMA_OFFSET_1:
+	case ARIZONA_DSP1_EXTERNAL_START_SELECT_1:
 	case ARIZONA_DSP1_SCRATCH_0:
 	case ARIZONA_DSP1_SCRATCH_0:
 	case ARIZONA_DSP1_SCRATCH_1:
 	case ARIZONA_DSP1_SCRATCH_1:
 	case ARIZONA_DSP1_SCRATCH_2:
 	case ARIZONA_DSP1_SCRATCH_2:
@@ -2470,6 +2491,27 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
 	case ARIZONA_DSP2_STATUS_1:
 	case ARIZONA_DSP2_STATUS_1:
 	case ARIZONA_DSP2_STATUS_2:
 	case ARIZONA_DSP2_STATUS_2:
 	case ARIZONA_DSP2_STATUS_3:
 	case ARIZONA_DSP2_STATUS_3:
+	case ARIZONA_DSP2_STATUS_4:
+	case ARIZONA_DSP2_WDMA_BUFFER_1:
+	case ARIZONA_DSP2_WDMA_BUFFER_2:
+	case ARIZONA_DSP2_WDMA_BUFFER_3:
+	case ARIZONA_DSP2_WDMA_BUFFER_4:
+	case ARIZONA_DSP2_WDMA_BUFFER_5:
+	case ARIZONA_DSP2_WDMA_BUFFER_6:
+	case ARIZONA_DSP2_WDMA_BUFFER_7:
+	case ARIZONA_DSP2_WDMA_BUFFER_8:
+	case ARIZONA_DSP2_RDMA_BUFFER_1:
+	case ARIZONA_DSP2_RDMA_BUFFER_2:
+	case ARIZONA_DSP2_RDMA_BUFFER_3:
+	case ARIZONA_DSP2_RDMA_BUFFER_4:
+	case ARIZONA_DSP2_RDMA_BUFFER_5:
+	case ARIZONA_DSP2_RDMA_BUFFER_6:
+	case ARIZONA_DSP2_WDMA_CONFIG_1:
+	case ARIZONA_DSP2_WDMA_CONFIG_2:
+	case ARIZONA_DSP2_WDMA_OFFSET_1:
+	case ARIZONA_DSP2_RDMA_CONFIG_1:
+	case ARIZONA_DSP2_RDMA_OFFSET_1:
+	case ARIZONA_DSP2_EXTERNAL_START_SELECT_1:
 	case ARIZONA_DSP2_SCRATCH_0:
 	case ARIZONA_DSP2_SCRATCH_0:
 	case ARIZONA_DSP2_SCRATCH_1:
 	case ARIZONA_DSP2_SCRATCH_1:
 	case ARIZONA_DSP2_SCRATCH_2:
 	case ARIZONA_DSP2_SCRATCH_2:
@@ -2479,6 +2521,27 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
 	case ARIZONA_DSP3_STATUS_1:
 	case ARIZONA_DSP3_STATUS_1:
 	case ARIZONA_DSP3_STATUS_2:
 	case ARIZONA_DSP3_STATUS_2:
 	case ARIZONA_DSP3_STATUS_3:
 	case ARIZONA_DSP3_STATUS_3:
+	case ARIZONA_DSP3_STATUS_4:
+	case ARIZONA_DSP3_WDMA_BUFFER_1:
+	case ARIZONA_DSP3_WDMA_BUFFER_2:
+	case ARIZONA_DSP3_WDMA_BUFFER_3:
+	case ARIZONA_DSP3_WDMA_BUFFER_4:
+	case ARIZONA_DSP3_WDMA_BUFFER_5:
+	case ARIZONA_DSP3_WDMA_BUFFER_6:
+	case ARIZONA_DSP3_WDMA_BUFFER_7:
+	case ARIZONA_DSP3_WDMA_BUFFER_8:
+	case ARIZONA_DSP3_RDMA_BUFFER_1:
+	case ARIZONA_DSP3_RDMA_BUFFER_2:
+	case ARIZONA_DSP3_RDMA_BUFFER_3:
+	case ARIZONA_DSP3_RDMA_BUFFER_4:
+	case ARIZONA_DSP3_RDMA_BUFFER_5:
+	case ARIZONA_DSP3_RDMA_BUFFER_6:
+	case ARIZONA_DSP3_WDMA_CONFIG_1:
+	case ARIZONA_DSP3_WDMA_CONFIG_2:
+	case ARIZONA_DSP3_WDMA_OFFSET_1:
+	case ARIZONA_DSP3_RDMA_CONFIG_1:
+	case ARIZONA_DSP3_RDMA_OFFSET_1:
+	case ARIZONA_DSP3_EXTERNAL_START_SELECT_1:
 	case ARIZONA_DSP3_SCRATCH_0:
 	case ARIZONA_DSP3_SCRATCH_0:
 	case ARIZONA_DSP3_SCRATCH_1:
 	case ARIZONA_DSP3_SCRATCH_1:
 	case ARIZONA_DSP3_SCRATCH_2:
 	case ARIZONA_DSP3_SCRATCH_2:
@@ -2488,6 +2551,27 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
 	case ARIZONA_DSP4_STATUS_1:
 	case ARIZONA_DSP4_STATUS_1:
 	case ARIZONA_DSP4_STATUS_2:
 	case ARIZONA_DSP4_STATUS_2:
 	case ARIZONA_DSP4_STATUS_3:
 	case ARIZONA_DSP4_STATUS_3:
+	case ARIZONA_DSP4_STATUS_4:
+	case ARIZONA_DSP4_WDMA_BUFFER_1:
+	case ARIZONA_DSP4_WDMA_BUFFER_2:
+	case ARIZONA_DSP4_WDMA_BUFFER_3:
+	case ARIZONA_DSP4_WDMA_BUFFER_4:
+	case ARIZONA_DSP4_WDMA_BUFFER_5:
+	case ARIZONA_DSP4_WDMA_BUFFER_6:
+	case ARIZONA_DSP4_WDMA_BUFFER_7:
+	case ARIZONA_DSP4_WDMA_BUFFER_8:
+	case ARIZONA_DSP4_RDMA_BUFFER_1:
+	case ARIZONA_DSP4_RDMA_BUFFER_2:
+	case ARIZONA_DSP4_RDMA_BUFFER_3:
+	case ARIZONA_DSP4_RDMA_BUFFER_4:
+	case ARIZONA_DSP4_RDMA_BUFFER_5:
+	case ARIZONA_DSP4_RDMA_BUFFER_6:
+	case ARIZONA_DSP4_WDMA_CONFIG_1:
+	case ARIZONA_DSP4_WDMA_CONFIG_2:
+	case ARIZONA_DSP4_WDMA_OFFSET_1:
+	case ARIZONA_DSP4_RDMA_CONFIG_1:
+	case ARIZONA_DSP4_RDMA_OFFSET_1:
+	case ARIZONA_DSP4_EXTERNAL_START_SELECT_1:
 	case ARIZONA_DSP4_SCRATCH_0:
 	case ARIZONA_DSP4_SCRATCH_0:
 	case ARIZONA_DSP4_SCRATCH_1:
 	case ARIZONA_DSP4_SCRATCH_1:
 	case ARIZONA_DSP4_SCRATCH_2:
 	case ARIZONA_DSP4_SCRATCH_2:
@@ -2543,31 +2627,119 @@ static bool wm5110_volatile_register(struct device *dev, unsigned int reg)
 	case ARIZONA_DSP1_STATUS_1:
 	case ARIZONA_DSP1_STATUS_1:
 	case ARIZONA_DSP1_STATUS_2:
 	case ARIZONA_DSP1_STATUS_2:
 	case ARIZONA_DSP1_STATUS_3:
 	case ARIZONA_DSP1_STATUS_3:
+	case ARIZONA_DSP1_STATUS_4:
+	case ARIZONA_DSP1_WDMA_BUFFER_1:
+	case ARIZONA_DSP1_WDMA_BUFFER_2:
+	case ARIZONA_DSP1_WDMA_BUFFER_3:
+	case ARIZONA_DSP1_WDMA_BUFFER_4:
+	case ARIZONA_DSP1_WDMA_BUFFER_5:
+	case ARIZONA_DSP1_WDMA_BUFFER_6:
+	case ARIZONA_DSP1_WDMA_BUFFER_7:
+	case ARIZONA_DSP1_WDMA_BUFFER_8:
+	case ARIZONA_DSP1_RDMA_BUFFER_1:
+	case ARIZONA_DSP1_RDMA_BUFFER_2:
+	case ARIZONA_DSP1_RDMA_BUFFER_3:
+	case ARIZONA_DSP1_RDMA_BUFFER_4:
+	case ARIZONA_DSP1_RDMA_BUFFER_5:
+	case ARIZONA_DSP1_RDMA_BUFFER_6:
+	case ARIZONA_DSP1_WDMA_CONFIG_1:
+	case ARIZONA_DSP1_WDMA_CONFIG_2:
+	case ARIZONA_DSP1_WDMA_OFFSET_1:
+	case ARIZONA_DSP1_RDMA_CONFIG_1:
+	case ARIZONA_DSP1_RDMA_OFFSET_1:
+	case ARIZONA_DSP1_EXTERNAL_START_SELECT_1:
 	case ARIZONA_DSP1_SCRATCH_0:
 	case ARIZONA_DSP1_SCRATCH_0:
 	case ARIZONA_DSP1_SCRATCH_1:
 	case ARIZONA_DSP1_SCRATCH_1:
 	case ARIZONA_DSP1_SCRATCH_2:
 	case ARIZONA_DSP1_SCRATCH_2:
 	case ARIZONA_DSP1_SCRATCH_3:
 	case ARIZONA_DSP1_SCRATCH_3:
+	case ARIZONA_DSP1_CLOCKING_1:
 	case ARIZONA_DSP2_STATUS_1:
 	case ARIZONA_DSP2_STATUS_1:
 	case ARIZONA_DSP2_STATUS_2:
 	case ARIZONA_DSP2_STATUS_2:
 	case ARIZONA_DSP2_STATUS_3:
 	case ARIZONA_DSP2_STATUS_3:
+	case ARIZONA_DSP2_STATUS_4:
+	case ARIZONA_DSP2_WDMA_BUFFER_1:
+	case ARIZONA_DSP2_WDMA_BUFFER_2:
+	case ARIZONA_DSP2_WDMA_BUFFER_3:
+	case ARIZONA_DSP2_WDMA_BUFFER_4:
+	case ARIZONA_DSP2_WDMA_BUFFER_5:
+	case ARIZONA_DSP2_WDMA_BUFFER_6:
+	case ARIZONA_DSP2_WDMA_BUFFER_7:
+	case ARIZONA_DSP2_WDMA_BUFFER_8:
+	case ARIZONA_DSP2_RDMA_BUFFER_1:
+	case ARIZONA_DSP2_RDMA_BUFFER_2:
+	case ARIZONA_DSP2_RDMA_BUFFER_3:
+	case ARIZONA_DSP2_RDMA_BUFFER_4:
+	case ARIZONA_DSP2_RDMA_BUFFER_5:
+	case ARIZONA_DSP2_RDMA_BUFFER_6:
+	case ARIZONA_DSP2_WDMA_CONFIG_1:
+	case ARIZONA_DSP2_WDMA_CONFIG_2:
+	case ARIZONA_DSP2_WDMA_OFFSET_1:
+	case ARIZONA_DSP2_RDMA_CONFIG_1:
+	case ARIZONA_DSP2_RDMA_OFFSET_1:
+	case ARIZONA_DSP2_EXTERNAL_START_SELECT_1:
 	case ARIZONA_DSP2_SCRATCH_0:
 	case ARIZONA_DSP2_SCRATCH_0:
 	case ARIZONA_DSP2_SCRATCH_1:
 	case ARIZONA_DSP2_SCRATCH_1:
 	case ARIZONA_DSP2_SCRATCH_2:
 	case ARIZONA_DSP2_SCRATCH_2:
 	case ARIZONA_DSP2_SCRATCH_3:
 	case ARIZONA_DSP2_SCRATCH_3:
+	case ARIZONA_DSP2_CLOCKING_1:
 	case ARIZONA_DSP3_STATUS_1:
 	case ARIZONA_DSP3_STATUS_1:
 	case ARIZONA_DSP3_STATUS_2:
 	case ARIZONA_DSP3_STATUS_2:
 	case ARIZONA_DSP3_STATUS_3:
 	case ARIZONA_DSP3_STATUS_3:
+	case ARIZONA_DSP3_STATUS_4:
+	case ARIZONA_DSP3_WDMA_BUFFER_1:
+	case ARIZONA_DSP3_WDMA_BUFFER_2:
+	case ARIZONA_DSP3_WDMA_BUFFER_3:
+	case ARIZONA_DSP3_WDMA_BUFFER_4:
+	case ARIZONA_DSP3_WDMA_BUFFER_5:
+	case ARIZONA_DSP3_WDMA_BUFFER_6:
+	case ARIZONA_DSP3_WDMA_BUFFER_7:
+	case ARIZONA_DSP3_WDMA_BUFFER_8:
+	case ARIZONA_DSP3_RDMA_BUFFER_1:
+	case ARIZONA_DSP3_RDMA_BUFFER_2:
+	case ARIZONA_DSP3_RDMA_BUFFER_3:
+	case ARIZONA_DSP3_RDMA_BUFFER_4:
+	case ARIZONA_DSP3_RDMA_BUFFER_5:
+	case ARIZONA_DSP3_RDMA_BUFFER_6:
+	case ARIZONA_DSP3_WDMA_CONFIG_1:
+	case ARIZONA_DSP3_WDMA_CONFIG_2:
+	case ARIZONA_DSP3_WDMA_OFFSET_1:
+	case ARIZONA_DSP3_RDMA_CONFIG_1:
+	case ARIZONA_DSP3_RDMA_OFFSET_1:
+	case ARIZONA_DSP3_EXTERNAL_START_SELECT_1:
 	case ARIZONA_DSP3_SCRATCH_0:
 	case ARIZONA_DSP3_SCRATCH_0:
 	case ARIZONA_DSP3_SCRATCH_1:
 	case ARIZONA_DSP3_SCRATCH_1:
 	case ARIZONA_DSP3_SCRATCH_2:
 	case ARIZONA_DSP3_SCRATCH_2:
 	case ARIZONA_DSP3_SCRATCH_3:
 	case ARIZONA_DSP3_SCRATCH_3:
+	case ARIZONA_DSP3_CLOCKING_1:
 	case ARIZONA_DSP4_STATUS_1:
 	case ARIZONA_DSP4_STATUS_1:
 	case ARIZONA_DSP4_STATUS_2:
 	case ARIZONA_DSP4_STATUS_2:
 	case ARIZONA_DSP4_STATUS_3:
 	case ARIZONA_DSP4_STATUS_3:
+	case ARIZONA_DSP4_STATUS_4:
+	case ARIZONA_DSP4_WDMA_BUFFER_1:
+	case ARIZONA_DSP4_WDMA_BUFFER_2:
+	case ARIZONA_DSP4_WDMA_BUFFER_3:
+	case ARIZONA_DSP4_WDMA_BUFFER_4:
+	case ARIZONA_DSP4_WDMA_BUFFER_5:
+	case ARIZONA_DSP4_WDMA_BUFFER_6:
+	case ARIZONA_DSP4_WDMA_BUFFER_7:
+	case ARIZONA_DSP4_WDMA_BUFFER_8:
+	case ARIZONA_DSP4_RDMA_BUFFER_1:
+	case ARIZONA_DSP4_RDMA_BUFFER_2:
+	case ARIZONA_DSP4_RDMA_BUFFER_3:
+	case ARIZONA_DSP4_RDMA_BUFFER_4:
+	case ARIZONA_DSP4_RDMA_BUFFER_5:
+	case ARIZONA_DSP4_RDMA_BUFFER_6:
+	case ARIZONA_DSP4_WDMA_CONFIG_1:
+	case ARIZONA_DSP4_WDMA_CONFIG_2:
+	case ARIZONA_DSP4_WDMA_OFFSET_1:
+	case ARIZONA_DSP4_RDMA_CONFIG_1:
+	case ARIZONA_DSP4_RDMA_OFFSET_1:
+	case ARIZONA_DSP4_EXTERNAL_START_SELECT_1:
 	case ARIZONA_DSP4_SCRATCH_0:
 	case ARIZONA_DSP4_SCRATCH_0:
 	case ARIZONA_DSP4_SCRATCH_1:
 	case ARIZONA_DSP4_SCRATCH_1:
 	case ARIZONA_DSP4_SCRATCH_2:
 	case ARIZONA_DSP4_SCRATCH_2:
 	case ARIZONA_DSP4_SCRATCH_3:
 	case ARIZONA_DSP4_SCRATCH_3:
+	case ARIZONA_DSP4_CLOCKING_1:
 		return true;
 		return true;
 	default:
 	default:
 		return wm5110_is_adsp_memory(dev, reg);
 		return wm5110_is_adsp_memory(dev, reg);

+ 0 - 1
drivers/mfd/wm8350-core.c

@@ -14,7 +14,6 @@
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/bug.h>
 #include <linux/bug.h>
 #include <linux/device.h>
 #include <linux/device.h>

+ 0 - 1
drivers/mfd/wm8350-irq.c

@@ -14,7 +14,6 @@
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/bug.h>
 #include <linux/bug.h>
 #include <linux/device.h>
 #include <linux/device.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>

+ 5 - 17
drivers/mfd/wm8400-core.c

@@ -161,31 +161,19 @@ static int wm8400_i2c_probe(struct i2c_client *i2c,
 			    const struct i2c_device_id *id)
 			    const struct i2c_device_id *id)
 {
 {
 	struct wm8400 *wm8400;
 	struct wm8400 *wm8400;
-	int ret;
 
 
 	wm8400 = devm_kzalloc(&i2c->dev, sizeof(struct wm8400), GFP_KERNEL);
 	wm8400 = devm_kzalloc(&i2c->dev, sizeof(struct wm8400), GFP_KERNEL);
-	if (wm8400 == NULL) {
-		ret = -ENOMEM;
-		goto err;
-	}
+	if (!wm8400)
+		return -ENOMEM;
 
 
 	wm8400->regmap = devm_regmap_init_i2c(i2c, &wm8400_regmap_config);
 	wm8400->regmap = devm_regmap_init_i2c(i2c, &wm8400_regmap_config);
-	if (IS_ERR(wm8400->regmap)) {
-		ret = PTR_ERR(wm8400->regmap);
-		goto err;
-	}
+	if (IS_ERR(wm8400->regmap))
+		return PTR_ERR(wm8400->regmap);
 
 
 	wm8400->dev = &i2c->dev;
 	wm8400->dev = &i2c->dev;
 	i2c_set_clientdata(i2c, wm8400);
 	i2c_set_clientdata(i2c, wm8400);
 
 
-	ret = wm8400_init(wm8400, dev_get_platdata(&i2c->dev));
-	if (ret != 0)
-		goto err;
-
-	return 0;
-
-err:
-	return ret;
+	return wm8400_init(wm8400, dev_get_platdata(&i2c->dev));
 }
 }
 
 
 static int wm8400_i2c_remove(struct i2c_client *i2c)
 static int wm8400_i2c_remove(struct i2c_client *i2c)

+ 82 - 55
drivers/watchdog/iTCO_wdt.c

@@ -48,7 +48,7 @@
 
 
 /* Module and version information */
 /* Module and version information */
 #define DRV_NAME	"iTCO_wdt"
 #define DRV_NAME	"iTCO_wdt"
-#define DRV_VERSION	"1.10"
+#define DRV_VERSION	"1.11"
 
 
 /* Includes */
 /* Includes */
 #include <linux/module.h>		/* For module specific items */
 #include <linux/module.h>		/* For module specific items */
@@ -92,9 +92,12 @@ static struct {		/* this is private data for the iTCO_wdt device */
 	unsigned int iTCO_version;
 	unsigned int iTCO_version;
 	struct resource *tco_res;
 	struct resource *tco_res;
 	struct resource *smi_res;
 	struct resource *smi_res;
-	struct resource *gcs_res;
-	/* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2)*/
-	unsigned long __iomem *gcs;
+	/*
+	 * NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2),
+	 * or memory-mapped PMC register bit 4 (TCO version 3).
+	 */
+	struct resource *gcs_pmc_res;
+	unsigned long __iomem *gcs_pmc;
 	/* the lock for io operations */
 	/* the lock for io operations */
 	spinlock_t io_lock;
 	spinlock_t io_lock;
 	struct platform_device *dev;
 	struct platform_device *dev;
@@ -125,11 +128,19 @@ MODULE_PARM_DESC(turn_SMI_watchdog_clear_off,
  * Some TCO specific functions
  * Some TCO specific functions
  */
  */
 
 
-static inline unsigned int seconds_to_ticks(int seconds)
+/*
+ * The iTCO v1 and v2's internal timer is stored as ticks which decrement
+ * every 0.6 seconds.  v3's internal timer is stored as seconds (some
+ * datasheets incorrectly state 0.6 seconds).
+ */
+static inline unsigned int seconds_to_ticks(int secs)
 {
 {
-	/* the internal timer is stored as ticks which decrement
-	 * every 0.6 seconds */
-	return (seconds * 10) / 6;
+	return iTCO_wdt_private.iTCO_version == 3 ? secs : (secs * 10) / 6;
+}
+
+static inline unsigned int ticks_to_seconds(int ticks)
+{
+	return iTCO_wdt_private.iTCO_version == 3 ? ticks : (ticks * 6) / 10;
 }
 }
 
 
 static void iTCO_wdt_set_NO_REBOOT_bit(void)
 static void iTCO_wdt_set_NO_REBOOT_bit(void)
@@ -137,10 +148,14 @@ static void iTCO_wdt_set_NO_REBOOT_bit(void)
 	u32 val32;
 	u32 val32;
 
 
 	/* Set the NO_REBOOT bit: this disables reboots */
 	/* Set the NO_REBOOT bit: this disables reboots */
-	if (iTCO_wdt_private.iTCO_version == 2) {
-		val32 = readl(iTCO_wdt_private.gcs);
+	if (iTCO_wdt_private.iTCO_version == 3) {
+		val32 = readl(iTCO_wdt_private.gcs_pmc);
+		val32 |= 0x00000010;
+		writel(val32, iTCO_wdt_private.gcs_pmc);
+	} else if (iTCO_wdt_private.iTCO_version == 2) {
+		val32 = readl(iTCO_wdt_private.gcs_pmc);
 		val32 |= 0x00000020;
 		val32 |= 0x00000020;
-		writel(val32, iTCO_wdt_private.gcs);
+		writel(val32, iTCO_wdt_private.gcs_pmc);
 	} else if (iTCO_wdt_private.iTCO_version == 1) {
 	} else if (iTCO_wdt_private.iTCO_version == 1) {
 		pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32);
 		pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32);
 		val32 |= 0x00000002;
 		val32 |= 0x00000002;
@@ -154,12 +169,20 @@ static int iTCO_wdt_unset_NO_REBOOT_bit(void)
 	u32 val32;
 	u32 val32;
 
 
 	/* Unset the NO_REBOOT bit: this enables reboots */
 	/* Unset the NO_REBOOT bit: this enables reboots */
-	if (iTCO_wdt_private.iTCO_version == 2) {
-		val32 = readl(iTCO_wdt_private.gcs);
+	if (iTCO_wdt_private.iTCO_version == 3) {
+		val32 = readl(iTCO_wdt_private.gcs_pmc);
+		val32 &= 0xffffffef;
+		writel(val32, iTCO_wdt_private.gcs_pmc);
+
+		val32 = readl(iTCO_wdt_private.gcs_pmc);
+		if (val32 & 0x00000010)
+			ret = -EIO;
+	} else if (iTCO_wdt_private.iTCO_version == 2) {
+		val32 = readl(iTCO_wdt_private.gcs_pmc);
 		val32 &= 0xffffffdf;
 		val32 &= 0xffffffdf;
-		writel(val32, iTCO_wdt_private.gcs);
+		writel(val32, iTCO_wdt_private.gcs_pmc);
 
 
-		val32 = readl(iTCO_wdt_private.gcs);
+		val32 = readl(iTCO_wdt_private.gcs_pmc);
 		if (val32 & 0x00000020)
 		if (val32 & 0x00000020)
 			ret = -EIO;
 			ret = -EIO;
 	} else if (iTCO_wdt_private.iTCO_version == 1) {
 	} else if (iTCO_wdt_private.iTCO_version == 1) {
@@ -192,7 +215,7 @@ static int iTCO_wdt_start(struct watchdog_device *wd_dev)
 
 
 	/* Force the timer to its reload value by writing to the TCO_RLD
 	/* Force the timer to its reload value by writing to the TCO_RLD
 	   register */
 	   register */
-	if (iTCO_wdt_private.iTCO_version == 2)
+	if (iTCO_wdt_private.iTCO_version >= 2)
 		outw(0x01, TCO_RLD);
 		outw(0x01, TCO_RLD);
 	else if (iTCO_wdt_private.iTCO_version == 1)
 	else if (iTCO_wdt_private.iTCO_version == 1)
 		outb(0x01, TCO_RLD);
 		outb(0x01, TCO_RLD);
@@ -240,9 +263,9 @@ static int iTCO_wdt_ping(struct watchdog_device *wd_dev)
 	iTCO_vendor_pre_keepalive(iTCO_wdt_private.smi_res, wd_dev->timeout);
 	iTCO_vendor_pre_keepalive(iTCO_wdt_private.smi_res, wd_dev->timeout);
 
 
 	/* Reload the timer by writing to the TCO Timer Counter register */
 	/* Reload the timer by writing to the TCO Timer Counter register */
-	if (iTCO_wdt_private.iTCO_version == 2)
+	if (iTCO_wdt_private.iTCO_version >= 2) {
 		outw(0x01, TCO_RLD);
 		outw(0x01, TCO_RLD);
-	else if (iTCO_wdt_private.iTCO_version == 1) {
+	} else if (iTCO_wdt_private.iTCO_version == 1) {
 		/* Reset the timeout status bit so that the timer
 		/* Reset the timeout status bit so that the timer
 		 * needs to count down twice again before rebooting */
 		 * needs to count down twice again before rebooting */
 		outw(0x0008, TCO1_STS);	/* write 1 to clear bit */
 		outw(0x0008, TCO1_STS);	/* write 1 to clear bit */
@@ -270,14 +293,14 @@ static int iTCO_wdt_set_timeout(struct watchdog_device *wd_dev, unsigned int t)
 	/* "Values of 0h-3h are ignored and should not be attempted" */
 	/* "Values of 0h-3h are ignored and should not be attempted" */
 	if (tmrval < 0x04)
 	if (tmrval < 0x04)
 		return -EINVAL;
 		return -EINVAL;
-	if (((iTCO_wdt_private.iTCO_version == 2) && (tmrval > 0x3ff)) ||
+	if (((iTCO_wdt_private.iTCO_version >= 2) && (tmrval > 0x3ff)) ||
 	    ((iTCO_wdt_private.iTCO_version == 1) && (tmrval > 0x03f)))
 	    ((iTCO_wdt_private.iTCO_version == 1) && (tmrval > 0x03f)))
 		return -EINVAL;
 		return -EINVAL;
 
 
 	iTCO_vendor_pre_set_heartbeat(tmrval);
 	iTCO_vendor_pre_set_heartbeat(tmrval);
 
 
 	/* Write new heartbeat to watchdog */
 	/* Write new heartbeat to watchdog */
-	if (iTCO_wdt_private.iTCO_version == 2) {
+	if (iTCO_wdt_private.iTCO_version >= 2) {
 		spin_lock(&iTCO_wdt_private.io_lock);
 		spin_lock(&iTCO_wdt_private.io_lock);
 		val16 = inw(TCOv2_TMR);
 		val16 = inw(TCOv2_TMR);
 		val16 &= 0xfc00;
 		val16 &= 0xfc00;
@@ -312,13 +335,13 @@ static unsigned int iTCO_wdt_get_timeleft(struct watchdog_device *wd_dev)
 	unsigned int time_left = 0;
 	unsigned int time_left = 0;
 
 
 	/* read the TCO Timer */
 	/* read the TCO Timer */
-	if (iTCO_wdt_private.iTCO_version == 2) {
+	if (iTCO_wdt_private.iTCO_version >= 2) {
 		spin_lock(&iTCO_wdt_private.io_lock);
 		spin_lock(&iTCO_wdt_private.io_lock);
 		val16 = inw(TCO_RLD);
 		val16 = inw(TCO_RLD);
 		val16 &= 0x3ff;
 		val16 &= 0x3ff;
 		spin_unlock(&iTCO_wdt_private.io_lock);
 		spin_unlock(&iTCO_wdt_private.io_lock);
 
 
-		time_left = (val16 * 6) / 10;
+		time_left = ticks_to_seconds(val16);
 	} else if (iTCO_wdt_private.iTCO_version == 1) {
 	} else if (iTCO_wdt_private.iTCO_version == 1) {
 		spin_lock(&iTCO_wdt_private.io_lock);
 		spin_lock(&iTCO_wdt_private.io_lock);
 		val8 = inb(TCO_RLD);
 		val8 = inb(TCO_RLD);
@@ -327,7 +350,7 @@ static unsigned int iTCO_wdt_get_timeleft(struct watchdog_device *wd_dev)
 			val8 += (inb(TCOv1_TMR) & 0x3f);
 			val8 += (inb(TCOv1_TMR) & 0x3f);
 		spin_unlock(&iTCO_wdt_private.io_lock);
 		spin_unlock(&iTCO_wdt_private.io_lock);
 
 
-		time_left = (val8 * 6) / 10;
+		time_left = ticks_to_seconds(val8);
 	}
 	}
 	return time_left;
 	return time_left;
 }
 }
@@ -376,16 +399,16 @@ static void iTCO_wdt_cleanup(void)
 			resource_size(iTCO_wdt_private.tco_res));
 			resource_size(iTCO_wdt_private.tco_res));
 	release_region(iTCO_wdt_private.smi_res->start,
 	release_region(iTCO_wdt_private.smi_res->start,
 			resource_size(iTCO_wdt_private.smi_res));
 			resource_size(iTCO_wdt_private.smi_res));
-	if (iTCO_wdt_private.iTCO_version == 2) {
-		iounmap(iTCO_wdt_private.gcs);
-		release_mem_region(iTCO_wdt_private.gcs_res->start,
-				resource_size(iTCO_wdt_private.gcs_res));
+	if (iTCO_wdt_private.iTCO_version >= 2) {
+		iounmap(iTCO_wdt_private.gcs_pmc);
+		release_mem_region(iTCO_wdt_private.gcs_pmc_res->start,
+				resource_size(iTCO_wdt_private.gcs_pmc_res));
 	}
 	}
 
 
 	iTCO_wdt_private.tco_res = NULL;
 	iTCO_wdt_private.tco_res = NULL;
 	iTCO_wdt_private.smi_res = NULL;
 	iTCO_wdt_private.smi_res = NULL;
-	iTCO_wdt_private.gcs_res = NULL;
-	iTCO_wdt_private.gcs = NULL;
+	iTCO_wdt_private.gcs_pmc_res = NULL;
+	iTCO_wdt_private.gcs_pmc = NULL;
 }
 }
 
 
 static int iTCO_wdt_probe(struct platform_device *dev)
 static int iTCO_wdt_probe(struct platform_device *dev)
@@ -414,27 +437,27 @@ static int iTCO_wdt_probe(struct platform_device *dev)
 	iTCO_wdt_private.pdev = to_pci_dev(dev->dev.parent);
 	iTCO_wdt_private.pdev = to_pci_dev(dev->dev.parent);
 
 
 	/*
 	/*
-	 * Get the Memory-Mapped GCS register, we need it for the
-	 * NO_REBOOT flag (TCO v2).
+	 * Get the Memory-Mapped GCS or PMC register, we need it for the
+	 * NO_REBOOT flag (TCO v2 and v3).
 	 */
 	 */
-	if (iTCO_wdt_private.iTCO_version == 2) {
-		iTCO_wdt_private.gcs_res = platform_get_resource(dev,
+	if (iTCO_wdt_private.iTCO_version >= 2) {
+		iTCO_wdt_private.gcs_pmc_res = platform_get_resource(dev,
 							IORESOURCE_MEM,
 							IORESOURCE_MEM,
-							ICH_RES_MEM_GCS);
+							ICH_RES_MEM_GCS_PMC);
 
 
-		if (!iTCO_wdt_private.gcs_res)
+		if (!iTCO_wdt_private.gcs_pmc_res)
 			goto out;
 			goto out;
 
 
-		if (!request_mem_region(iTCO_wdt_private.gcs_res->start,
-			resource_size(iTCO_wdt_private.gcs_res), dev->name)) {
+		if (!request_mem_region(iTCO_wdt_private.gcs_pmc_res->start,
+			resource_size(iTCO_wdt_private.gcs_pmc_res), dev->name)) {
 			ret = -EBUSY;
 			ret = -EBUSY;
 			goto out;
 			goto out;
 		}
 		}
-		iTCO_wdt_private.gcs = ioremap(iTCO_wdt_private.gcs_res->start,
-			resource_size(iTCO_wdt_private.gcs_res));
-		if (!iTCO_wdt_private.gcs) {
+		iTCO_wdt_private.gcs_pmc = ioremap(iTCO_wdt_private.gcs_pmc_res->start,
+			resource_size(iTCO_wdt_private.gcs_pmc_res));
+		if (!iTCO_wdt_private.gcs_pmc) {
 			ret = -EIO;
 			ret = -EIO;
-			goto unreg_gcs;
+			goto unreg_gcs_pmc;
 		}
 		}
 	}
 	}
 
 
@@ -442,7 +465,7 @@ static int iTCO_wdt_probe(struct platform_device *dev)
 	if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) {
 	if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) {
 		pr_info("unable to reset NO_REBOOT flag, device disabled by hardware/BIOS\n");
 		pr_info("unable to reset NO_REBOOT flag, device disabled by hardware/BIOS\n");
 		ret = -ENODEV;	/* Cannot reset NO_REBOOT bit */
 		ret = -ENODEV;	/* Cannot reset NO_REBOOT bit */
-		goto unmap_gcs;
+		goto unmap_gcs_pmc;
 	}
 	}
 
 
 	/* Set the NO_REBOOT bit to prevent later reboots, just for sure */
 	/* Set the NO_REBOOT bit to prevent later reboots, just for sure */
@@ -454,7 +477,7 @@ static int iTCO_wdt_probe(struct platform_device *dev)
 		pr_err("I/O address 0x%04llx already in use, device disabled\n",
 		pr_err("I/O address 0x%04llx already in use, device disabled\n",
 		       (u64)SMI_EN);
 		       (u64)SMI_EN);
 		ret = -EBUSY;
 		ret = -EBUSY;
-		goto unmap_gcs;
+		goto unmap_gcs_pmc;
 	}
 	}
 	if (turn_SMI_watchdog_clear_off >= iTCO_wdt_private.iTCO_version) {
 	if (turn_SMI_watchdog_clear_off >= iTCO_wdt_private.iTCO_version) {
 		/*
 		/*
@@ -478,9 +501,13 @@ static int iTCO_wdt_probe(struct platform_device *dev)
 		ich_info->name, ich_info->iTCO_version, (u64)TCOBASE);
 		ich_info->name, ich_info->iTCO_version, (u64)TCOBASE);
 
 
 	/* Clear out the (probably old) status */
 	/* Clear out the (probably old) status */
-	outw(0x0008, TCO1_STS);	/* Clear the Time Out Status bit */
-	outw(0x0002, TCO2_STS);	/* Clear SECOND_TO_STS bit */
-	outw(0x0004, TCO2_STS);	/* Clear BOOT_STS bit */
+	if (iTCO_wdt_private.iTCO_version == 3) {
+		outl(0x20008, TCO1_STS);
+	} else {
+		outw(0x0008, TCO1_STS);	/* Clear the Time Out Status bit */
+		outw(0x0002, TCO2_STS);	/* Clear SECOND_TO_STS bit */
+		outw(0x0004, TCO2_STS);	/* Clear BOOT_STS bit */
+	}
 
 
 	iTCO_wdt_watchdog_dev.bootstatus = 0;
 	iTCO_wdt_watchdog_dev.bootstatus = 0;
 	iTCO_wdt_watchdog_dev.timeout = WATCHDOG_TIMEOUT;
 	iTCO_wdt_watchdog_dev.timeout = WATCHDOG_TIMEOUT;
@@ -515,18 +542,18 @@ unreg_tco:
 unreg_smi:
 unreg_smi:
 	release_region(iTCO_wdt_private.smi_res->start,
 	release_region(iTCO_wdt_private.smi_res->start,
 			resource_size(iTCO_wdt_private.smi_res));
 			resource_size(iTCO_wdt_private.smi_res));
-unmap_gcs:
-	if (iTCO_wdt_private.iTCO_version == 2)
-		iounmap(iTCO_wdt_private.gcs);
-unreg_gcs:
-	if (iTCO_wdt_private.iTCO_version == 2)
-		release_mem_region(iTCO_wdt_private.gcs_res->start,
-				resource_size(iTCO_wdt_private.gcs_res));
+unmap_gcs_pmc:
+	if (iTCO_wdt_private.iTCO_version >= 2)
+		iounmap(iTCO_wdt_private.gcs_pmc);
+unreg_gcs_pmc:
+	if (iTCO_wdt_private.iTCO_version >= 2)
+		release_mem_region(iTCO_wdt_private.gcs_pmc_res->start,
+				resource_size(iTCO_wdt_private.gcs_pmc_res));
 out:
 out:
 	iTCO_wdt_private.tco_res = NULL;
 	iTCO_wdt_private.tco_res = NULL;
 	iTCO_wdt_private.smi_res = NULL;
 	iTCO_wdt_private.smi_res = NULL;
-	iTCO_wdt_private.gcs_res = NULL;
-	iTCO_wdt_private.gcs = NULL;
+	iTCO_wdt_private.gcs_pmc_res = NULL;
+	iTCO_wdt_private.gcs_pmc = NULL;
 
 
 	return ret;
 	return ret;
 }
 }

+ 12 - 0
include/linux/i2c/twl.h

@@ -195,6 +195,18 @@ static inline int twl_i2c_read_u8(u8 mod_no, u8 *val, u8 reg) {
 	return twl_i2c_read(mod_no, val, reg, 1);
 	return twl_i2c_read(mod_no, val, reg, 1);
 }
 }
 
 
+static inline int twl_i2c_write_u16(u8 mod_no, u16 val, u8 reg) {
+	val = cpu_to_le16(val);
+	return twl_i2c_write(mod_no, (u8*) &val, reg, 2);
+}
+
+static inline int twl_i2c_read_u16(u8 mod_no, u16 *val, u8 reg) {
+	int ret;
+	ret = twl_i2c_read(mod_no, (u8*) val, reg, 2);
+	*val = le16_to_cpu(*val);
+	return ret;
+}
+
 int twl_get_type(void);
 int twl_get_type(void);
 int twl_get_version(void);
 int twl_get_version(void);
 int twl_get_hfclk_rate(void);
 int twl_get_hfclk_rate(void);

+ 1 - 1
include/linux/i2c/twl4030-madc.h

@@ -44,7 +44,7 @@ struct twl4030_madc_conversion_method {
 
 
 struct twl4030_madc_request {
 struct twl4030_madc_request {
 	unsigned long channels;
 	unsigned long channels;
-	u16 do_avg;
+	bool do_avg;
 	u16 method;
 	u16 method;
 	u16 type;
 	u16 type;
 	bool active;
 	bool active;

+ 84 - 0
include/linux/mfd/arizona/registers.h

@@ -1034,6 +1034,27 @@
 #define ARIZONA_DSP1_STATUS_1                    0x1104
 #define ARIZONA_DSP1_STATUS_1                    0x1104
 #define ARIZONA_DSP1_STATUS_2                    0x1105
 #define ARIZONA_DSP1_STATUS_2                    0x1105
 #define ARIZONA_DSP1_STATUS_3                    0x1106
 #define ARIZONA_DSP1_STATUS_3                    0x1106
+#define ARIZONA_DSP1_STATUS_4                    0x1107
+#define ARIZONA_DSP1_WDMA_BUFFER_1               0x1110
+#define ARIZONA_DSP1_WDMA_BUFFER_2               0x1111
+#define ARIZONA_DSP1_WDMA_BUFFER_3               0x1112
+#define ARIZONA_DSP1_WDMA_BUFFER_4               0x1113
+#define ARIZONA_DSP1_WDMA_BUFFER_5               0x1114
+#define ARIZONA_DSP1_WDMA_BUFFER_6               0x1115
+#define ARIZONA_DSP1_WDMA_BUFFER_7               0x1116
+#define ARIZONA_DSP1_WDMA_BUFFER_8               0x1117
+#define ARIZONA_DSP1_RDMA_BUFFER_1               0x1120
+#define ARIZONA_DSP1_RDMA_BUFFER_2               0x1121
+#define ARIZONA_DSP1_RDMA_BUFFER_3               0x1122
+#define ARIZONA_DSP1_RDMA_BUFFER_4               0x1123
+#define ARIZONA_DSP1_RDMA_BUFFER_5               0x1124
+#define ARIZONA_DSP1_RDMA_BUFFER_6               0x1125
+#define ARIZONA_DSP1_WDMA_CONFIG_1               0x1130
+#define ARIZONA_DSP1_WDMA_CONFIG_2               0x1131
+#define ARIZONA_DSP1_WDMA_OFFSET_1               0x1132
+#define ARIZONA_DSP1_RDMA_CONFIG_1               0x1134
+#define ARIZONA_DSP1_RDMA_OFFSET_1               0x1135
+#define ARIZONA_DSP1_EXTERNAL_START_SELECT_1     0x1138
 #define ARIZONA_DSP1_SCRATCH_0                   0x1140
 #define ARIZONA_DSP1_SCRATCH_0                   0x1140
 #define ARIZONA_DSP1_SCRATCH_1                   0x1141
 #define ARIZONA_DSP1_SCRATCH_1                   0x1141
 #define ARIZONA_DSP1_SCRATCH_2                   0x1142
 #define ARIZONA_DSP1_SCRATCH_2                   0x1142
@@ -1043,6 +1064,27 @@
 #define ARIZONA_DSP2_STATUS_1                    0x1204
 #define ARIZONA_DSP2_STATUS_1                    0x1204
 #define ARIZONA_DSP2_STATUS_2                    0x1205
 #define ARIZONA_DSP2_STATUS_2                    0x1205
 #define ARIZONA_DSP2_STATUS_3                    0x1206
 #define ARIZONA_DSP2_STATUS_3                    0x1206
+#define ARIZONA_DSP2_STATUS_4                    0x1207
+#define ARIZONA_DSP2_WDMA_BUFFER_1               0x1210
+#define ARIZONA_DSP2_WDMA_BUFFER_2               0x1211
+#define ARIZONA_DSP2_WDMA_BUFFER_3               0x1212
+#define ARIZONA_DSP2_WDMA_BUFFER_4               0x1213
+#define ARIZONA_DSP2_WDMA_BUFFER_5               0x1214
+#define ARIZONA_DSP2_WDMA_BUFFER_6               0x1215
+#define ARIZONA_DSP2_WDMA_BUFFER_7               0x1216
+#define ARIZONA_DSP2_WDMA_BUFFER_8               0x1217
+#define ARIZONA_DSP2_RDMA_BUFFER_1               0x1220
+#define ARIZONA_DSP2_RDMA_BUFFER_2               0x1221
+#define ARIZONA_DSP2_RDMA_BUFFER_3               0x1222
+#define ARIZONA_DSP2_RDMA_BUFFER_4               0x1223
+#define ARIZONA_DSP2_RDMA_BUFFER_5               0x1224
+#define ARIZONA_DSP2_RDMA_BUFFER_6               0x1225
+#define ARIZONA_DSP2_WDMA_CONFIG_1               0x1230
+#define ARIZONA_DSP2_WDMA_CONFIG_2               0x1231
+#define ARIZONA_DSP2_WDMA_OFFSET_1               0x1232
+#define ARIZONA_DSP2_RDMA_CONFIG_1               0x1234
+#define ARIZONA_DSP2_RDMA_OFFSET_1               0x1235
+#define ARIZONA_DSP2_EXTERNAL_START_SELECT_1     0x1238
 #define ARIZONA_DSP2_SCRATCH_0                   0x1240
 #define ARIZONA_DSP2_SCRATCH_0                   0x1240
 #define ARIZONA_DSP2_SCRATCH_1                   0x1241
 #define ARIZONA_DSP2_SCRATCH_1                   0x1241
 #define ARIZONA_DSP2_SCRATCH_2                   0x1242
 #define ARIZONA_DSP2_SCRATCH_2                   0x1242
@@ -1052,6 +1094,27 @@
 #define ARIZONA_DSP3_STATUS_1                    0x1304
 #define ARIZONA_DSP3_STATUS_1                    0x1304
 #define ARIZONA_DSP3_STATUS_2                    0x1305
 #define ARIZONA_DSP3_STATUS_2                    0x1305
 #define ARIZONA_DSP3_STATUS_3                    0x1306
 #define ARIZONA_DSP3_STATUS_3                    0x1306
+#define ARIZONA_DSP3_STATUS_4                    0x1307
+#define ARIZONA_DSP3_WDMA_BUFFER_1               0x1310
+#define ARIZONA_DSP3_WDMA_BUFFER_2               0x1311
+#define ARIZONA_DSP3_WDMA_BUFFER_3               0x1312
+#define ARIZONA_DSP3_WDMA_BUFFER_4               0x1313
+#define ARIZONA_DSP3_WDMA_BUFFER_5               0x1314
+#define ARIZONA_DSP3_WDMA_BUFFER_6               0x1315
+#define ARIZONA_DSP3_WDMA_BUFFER_7               0x1316
+#define ARIZONA_DSP3_WDMA_BUFFER_8               0x1317
+#define ARIZONA_DSP3_RDMA_BUFFER_1               0x1320
+#define ARIZONA_DSP3_RDMA_BUFFER_2               0x1321
+#define ARIZONA_DSP3_RDMA_BUFFER_3               0x1322
+#define ARIZONA_DSP3_RDMA_BUFFER_4               0x1323
+#define ARIZONA_DSP3_RDMA_BUFFER_5               0x1324
+#define ARIZONA_DSP3_RDMA_BUFFER_6               0x1325
+#define ARIZONA_DSP3_WDMA_CONFIG_1               0x1330
+#define ARIZONA_DSP3_WDMA_CONFIG_2               0x1331
+#define ARIZONA_DSP3_WDMA_OFFSET_1               0x1332
+#define ARIZONA_DSP3_RDMA_CONFIG_1               0x1334
+#define ARIZONA_DSP3_RDMA_OFFSET_1               0x1335
+#define ARIZONA_DSP3_EXTERNAL_START_SELECT_1     0x1338
 #define ARIZONA_DSP3_SCRATCH_0                   0x1340
 #define ARIZONA_DSP3_SCRATCH_0                   0x1340
 #define ARIZONA_DSP3_SCRATCH_1                   0x1341
 #define ARIZONA_DSP3_SCRATCH_1                   0x1341
 #define ARIZONA_DSP3_SCRATCH_2                   0x1342
 #define ARIZONA_DSP3_SCRATCH_2                   0x1342
@@ -1061,6 +1124,27 @@
 #define ARIZONA_DSP4_STATUS_1                    0x1404
 #define ARIZONA_DSP4_STATUS_1                    0x1404
 #define ARIZONA_DSP4_STATUS_2                    0x1405
 #define ARIZONA_DSP4_STATUS_2                    0x1405
 #define ARIZONA_DSP4_STATUS_3                    0x1406
 #define ARIZONA_DSP4_STATUS_3                    0x1406
+#define ARIZONA_DSP4_STATUS_4                    0x1407
+#define ARIZONA_DSP4_WDMA_BUFFER_1               0x1410
+#define ARIZONA_DSP4_WDMA_BUFFER_2               0x1411
+#define ARIZONA_DSP4_WDMA_BUFFER_3               0x1412
+#define ARIZONA_DSP4_WDMA_BUFFER_4               0x1413
+#define ARIZONA_DSP4_WDMA_BUFFER_5               0x1414
+#define ARIZONA_DSP4_WDMA_BUFFER_6               0x1415
+#define ARIZONA_DSP4_WDMA_BUFFER_7               0x1416
+#define ARIZONA_DSP4_WDMA_BUFFER_8               0x1417
+#define ARIZONA_DSP4_RDMA_BUFFER_1               0x1420
+#define ARIZONA_DSP4_RDMA_BUFFER_2               0x1421
+#define ARIZONA_DSP4_RDMA_BUFFER_3               0x1422
+#define ARIZONA_DSP4_RDMA_BUFFER_4               0x1423
+#define ARIZONA_DSP4_RDMA_BUFFER_5               0x1424
+#define ARIZONA_DSP4_RDMA_BUFFER_6               0x1425
+#define ARIZONA_DSP4_WDMA_CONFIG_1               0x1430
+#define ARIZONA_DSP4_WDMA_CONFIG_2               0x1431
+#define ARIZONA_DSP4_WDMA_OFFSET_1               0x1432
+#define ARIZONA_DSP4_RDMA_CONFIG_1               0x1434
+#define ARIZONA_DSP4_RDMA_OFFSET_1               0x1435
+#define ARIZONA_DSP4_EXTERNAL_START_SELECT_1     0x1438
 #define ARIZONA_DSP4_SCRATCH_0                   0x1440
 #define ARIZONA_DSP4_SCRATCH_0                   0x1440
 #define ARIZONA_DSP4_SCRATCH_1                   0x1441
 #define ARIZONA_DSP4_SCRATCH_1                   0x1441
 #define ARIZONA_DSP4_SCRATCH_2                   0x1442
 #define ARIZONA_DSP4_SCRATCH_2                   0x1442

+ 31 - 0
include/linux/mfd/bcm590xx.h

@@ -0,0 +1,31 @@
+/*
+ * Broadcom BCM590xx PMU
+ *
+ * Copyright 2014 Linaro Limited
+ * Author: Matt Porter <mporter@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under  the terms of the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef __LINUX_MFD_BCM590XX_H
+#define __LINUX_MFD_BCM590XX_H
+
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+
+/* max register address */
+#define BCM590XX_MAX_REGISTER	0xe7
+
+struct bcm590xx {
+	struct device *dev;
+	struct i2c_client *i2c_client;
+	struct regmap *regmap;
+	unsigned int id;
+};
+
+#endif /*  __LINUX_MFD_BCM590XX_H */

+ 1 - 0
include/linux/mfd/da9052/da9052.h

@@ -83,6 +83,7 @@ enum da9052_chip_id {
 	DA9053_AA,
 	DA9053_AA,
 	DA9053_BA,
 	DA9053_BA,
 	DA9053_BB,
 	DA9053_BB,
+	DA9053_BC,
 };
 };
 
 
 struct da9052_pdata;
 struct da9052_pdata;

+ 5 - 1
include/linux/mfd/da9063/core.h

@@ -33,6 +33,10 @@ enum da9063_models {
 	PMIC_DA9063 = 0x61,
 	PMIC_DA9063 = 0x61,
 };
 };
 
 
+enum da9063_variant_codes {
+	PMIC_DA9063_BB = 0x5
+};
+
 /* Interrupts */
 /* Interrupts */
 enum da9063_irqs {
 enum da9063_irqs {
 	DA9063_IRQ_ONKEY = 0,
 	DA9063_IRQ_ONKEY = 0,
@@ -72,7 +76,7 @@ struct da9063 {
 	/* Device */
 	/* Device */
 	struct device	*dev;
 	struct device	*dev;
 	unsigned short	model;
 	unsigned short	model;
-	unsigned short	revision;
+	unsigned char	variant_code;
 	unsigned int	flags;
 	unsigned int	flags;
 
 
 	/* Control interface */
 	/* Control interface */

+ 62 - 58
include/linux/mfd/da9063/registers.h

@@ -17,11 +17,7 @@
 #define	_DA9063_REG_H
 #define	_DA9063_REG_H
 
 
 #define DA9063_I2C_PAGE_SEL_SHIFT	1
 #define DA9063_I2C_PAGE_SEL_SHIFT	1
-
 #define	DA9063_EVENT_REG_NUM		4
 #define	DA9063_EVENT_REG_NUM		4
-#define	DA9210_EVENT_REG_NUM		2
-#define	DA9063_EXT_EVENT_REG_NUM	(DA9063_EVENT_REG_NUM + \
-						DA9210_EVENT_REG_NUM)
 
 
 /* Page selection I2C or SPI always in the begining of any page. */
 /* Page selection I2C or SPI always in the begining of any page. */
 /* Page 0 : I2C access 0x000 - 0x0FF	SPI access 0x000 - 0x07F */
 /* Page 0 : I2C access 0x000 - 0x0FF	SPI access 0x000 - 0x07F */
@@ -61,9 +57,9 @@
 #define	DA9063_REG_GPIO_10_11		0x1A
 #define	DA9063_REG_GPIO_10_11		0x1A
 #define	DA9063_REG_GPIO_12_13		0x1B
 #define	DA9063_REG_GPIO_12_13		0x1B
 #define	DA9063_REG_GPIO_14_15		0x1C
 #define	DA9063_REG_GPIO_14_15		0x1C
-#define	DA9063_REG_GPIO_MODE_0_7	0x1D
-#define	DA9063_REG_GPIO_MODE_8_15	0x1E
-#define	DA9063_REG_GPIO_SWITCH_CONT	0x1F
+#define	DA9063_REG_GPIO_MODE0_7		0x1D
+#define	DA9063_REG_GPIO_MODE8_15	0x1E
+#define	DA9063_REG_SWITCH_CONT		0x1F
 
 
 /* Regulator Control Registers */
 /* Regulator Control Registers */
 #define	DA9063_REG_BCORE2_CONT		0x20
 #define	DA9063_REG_BCORE2_CONT		0x20
@@ -83,7 +79,7 @@
 #define	DA9063_REG_LDO9_CONT		0x2E
 #define	DA9063_REG_LDO9_CONT		0x2E
 #define	DA9063_REG_LDO10_CONT		0x2F
 #define	DA9063_REG_LDO10_CONT		0x2F
 #define	DA9063_REG_LDO11_CONT		0x30
 #define	DA9063_REG_LDO11_CONT		0x30
-#define	DA9063_REG_VIB			0x31
+#define	DA9063_REG_SUPPLIES		0x31
 #define	DA9063_REG_DVC_1		0x32
 #define	DA9063_REG_DVC_1		0x32
 #define	DA9063_REG_DVC_2		0x33
 #define	DA9063_REG_DVC_2		0x33
 
 
@@ -97,9 +93,9 @@
 #define	DA9063_REG_ADCIN1_RES		0x3A
 #define	DA9063_REG_ADCIN1_RES		0x3A
 #define	DA9063_REG_ADCIN2_RES		0x3B
 #define	DA9063_REG_ADCIN2_RES		0x3B
 #define	DA9063_REG_ADCIN3_RES		0x3C
 #define	DA9063_REG_ADCIN3_RES		0x3C
-#define	DA9063_REG_MON1_RES		0x3D
-#define	DA9063_REG_MON2_RES		0x3E
-#define	DA9063_REG_MON3_RES		0x3F
+#define	DA9063_REG_MON_A8_RES		0x3D
+#define	DA9063_REG_MON_A9_RES		0x3E
+#define	DA9063_REG_MON_A10_RES		0x3F
 
 
 /* RTC Calendar and Alarm Registers */
 /* RTC Calendar and Alarm Registers */
 #define	DA9063_REG_COUNT_S		0x40
 #define	DA9063_REG_COUNT_S		0x40
@@ -108,15 +104,16 @@
 #define	DA9063_REG_COUNT_D		0x43
 #define	DA9063_REG_COUNT_D		0x43
 #define	DA9063_REG_COUNT_MO		0x44
 #define	DA9063_REG_COUNT_MO		0x44
 #define	DA9063_REG_COUNT_Y		0x45
 #define	DA9063_REG_COUNT_Y		0x45
-#define	DA9063_REG_ALARM_MI		0x46
-#define	DA9063_REG_ALARM_H		0x47
-#define	DA9063_REG_ALARM_D		0x48
-#define	DA9063_REG_ALARM_MO		0x49
-#define	DA9063_REG_ALARM_Y		0x4A
-#define	DA9063_REG_SECOND_A		0x4B
-#define	DA9063_REG_SECOND_B		0x4C
-#define	DA9063_REG_SECOND_C		0x4D
-#define	DA9063_REG_SECOND_D		0x4E
+#define	DA9063_REG_ALARM_S		0x46
+#define	DA9063_REG_ALARM_MI		0x47
+#define	DA9063_REG_ALARM_H		0x48
+#define	DA9063_REG_ALARM_D		0x49
+#define	DA9063_REG_ALARM_MO		0x4A
+#define	DA9063_REG_ALARM_Y		0x4B
+#define	DA9063_REG_SECOND_A		0x4C
+#define	DA9063_REG_SECOND_B		0x4D
+#define	DA9063_REG_SECOND_C		0x4E
+#define	DA9063_REG_SECOND_D		0x4F
 
 
 /* Sequencer Control Registers */
 /* Sequencer Control Registers */
 #define	DA9063_REG_SEQ			0x81
 #define	DA9063_REG_SEQ			0x81
@@ -226,35 +223,37 @@
 #define	DA9063_REG_CONFIG_J		0x10F
 #define	DA9063_REG_CONFIG_J		0x10F
 #define	DA9063_REG_CONFIG_K		0x110
 #define	DA9063_REG_CONFIG_K		0x110
 #define	DA9063_REG_CONFIG_L		0x111
 #define	DA9063_REG_CONFIG_L		0x111
-#define	DA9063_REG_MON_REG_1		0x112
-#define	DA9063_REG_MON_REG_2		0x113
-#define	DA9063_REG_MON_REG_3		0x114
-#define	DA9063_REG_MON_REG_4		0x115
-#define	DA9063_REG_MON_REG_5		0x116
-#define	DA9063_REG_MON_REG_6		0x117
-#define	DA9063_REG_TRIM_CLDR		0x118
-
+#define	DA9063_REG_CONFIG_M		0x112
+#define	DA9063_REG_CONFIG_N		0x113
+
+#define	DA9063_REG_MON_REG_1		0x114
+#define	DA9063_REG_MON_REG_2		0x115
+#define	DA9063_REG_MON_REG_3		0x116
+#define	DA9063_REG_MON_REG_4		0x117
+#define	DA9063_REG_MON_REG_5		0x11E
+#define	DA9063_REG_MON_REG_6		0x11F
+#define	DA9063_REG_TRIM_CLDR		0x120
 /* General Purpose Registers */
 /* General Purpose Registers */
-#define	DA9063_REG_GP_ID_0		0x119
-#define	DA9063_REG_GP_ID_1		0x11A
-#define	DA9063_REG_GP_ID_2		0x11B
-#define	DA9063_REG_GP_ID_3		0x11C
-#define	DA9063_REG_GP_ID_4		0x11D
-#define	DA9063_REG_GP_ID_5		0x11E
-#define	DA9063_REG_GP_ID_6		0x11F
-#define	DA9063_REG_GP_ID_7		0x120
-#define	DA9063_REG_GP_ID_8		0x121
-#define	DA9063_REG_GP_ID_9		0x122
-#define	DA9063_REG_GP_ID_10		0x123
-#define	DA9063_REG_GP_ID_11		0x124
-#define	DA9063_REG_GP_ID_12		0x125
-#define	DA9063_REG_GP_ID_13		0x126
-#define	DA9063_REG_GP_ID_14		0x127
-#define	DA9063_REG_GP_ID_15		0x128
-#define	DA9063_REG_GP_ID_16		0x129
-#define	DA9063_REG_GP_ID_17		0x12A
-#define	DA9063_REG_GP_ID_18		0x12B
-#define	DA9063_REG_GP_ID_19		0x12C
+#define	DA9063_REG_GP_ID_0		0x121
+#define	DA9063_REG_GP_ID_1		0x122
+#define	DA9063_REG_GP_ID_2		0x123
+#define	DA9063_REG_GP_ID_3		0x124
+#define	DA9063_REG_GP_ID_4		0x125
+#define	DA9063_REG_GP_ID_5		0x126
+#define	DA9063_REG_GP_ID_6		0x127
+#define	DA9063_REG_GP_ID_7		0x128
+#define	DA9063_REG_GP_ID_8		0x129
+#define	DA9063_REG_GP_ID_9		0x12A
+#define	DA9063_REG_GP_ID_10		0x12B
+#define	DA9063_REG_GP_ID_11		0x12C
+#define	DA9063_REG_GP_ID_12		0x12D
+#define	DA9063_REG_GP_ID_13		0x12E
+#define	DA9063_REG_GP_ID_14		0x12F
+#define	DA9063_REG_GP_ID_15		0x130
+#define	DA9063_REG_GP_ID_16		0x131
+#define	DA9063_REG_GP_ID_17		0x132
+#define	DA9063_REG_GP_ID_18		0x133
+#define	DA9063_REG_GP_ID_19		0x134
 
 
 /* Chip ID and variant */
 /* Chip ID and variant */
 #define	DA9063_REG_CHIP_ID		0x181
 #define	DA9063_REG_CHIP_ID		0x181
@@ -405,8 +404,10 @@
 /* DA9063_REG_CONTROL_B (addr=0x0F) */
 /* DA9063_REG_CONTROL_B (addr=0x0F) */
 #define	DA9063_CHG_SEL				0x01
 #define	DA9063_CHG_SEL				0x01
 #define	DA9063_WATCHDOG_PD			0x02
 #define	DA9063_WATCHDOG_PD			0x02
+#define	DA9063_RESET_BLINKING			0x04
 #define	DA9063_NRES_MODE			0x08
 #define	DA9063_NRES_MODE			0x08
 #define	DA9063_NONKEY_LOCK			0x10
 #define	DA9063_NONKEY_LOCK			0x10
+#define	DA9063_BUCK_SLOWSTART			0x80
 
 
 /* DA9063_REG_CONTROL_C (addr=0x10) */
 /* DA9063_REG_CONTROL_C (addr=0x10) */
 #define	DA9063_DEBOUNCING_MASK			0x07
 #define	DA9063_DEBOUNCING_MASK			0x07
@@ -466,6 +467,7 @@
 #define	DA9063_GPADC_PAUSE			0x02
 #define	DA9063_GPADC_PAUSE			0x02
 #define	DA9063_PMIF_DIS				0x04
 #define	DA9063_PMIF_DIS				0x04
 #define	DA9063_HS2WIRE_DIS			0x08
 #define	DA9063_HS2WIRE_DIS			0x08
+#define	DA9063_CLDR_PAUSE			0x10
 #define	DA9063_BBAT_DIS				0x20
 #define	DA9063_BBAT_DIS				0x20
 #define	DA9063_OUT_32K_PAUSE			0x40
 #define	DA9063_OUT_32K_PAUSE			0x40
 #define	DA9063_PMCONT_DIS			0x80
 #define	DA9063_PMCONT_DIS			0x80
@@ -660,7 +662,7 @@
 #define		DA9063_GPIO15_TYPE_GPO		0x04
 #define		DA9063_GPIO15_TYPE_GPO		0x04
 #define	DA9063_GPIO15_NO_WAKEUP			0x80
 #define	DA9063_GPIO15_NO_WAKEUP			0x80
 
 
-/* DA9063_REG_GPIO_MODE_0_7 (addr=0x1D) */
+/* DA9063_REG_GPIO_MODE0_7 (addr=0x1D) */
 #define	DA9063_GPIO0_MODE			0x01
 #define	DA9063_GPIO0_MODE			0x01
 #define	DA9063_GPIO1_MODE			0x02
 #define	DA9063_GPIO1_MODE			0x02
 #define	DA9063_GPIO2_MODE			0x04
 #define	DA9063_GPIO2_MODE			0x04
@@ -670,7 +672,7 @@
 #define	DA9063_GPIO6_MODE			0x40
 #define	DA9063_GPIO6_MODE			0x40
 #define	DA9063_GPIO7_MODE			0x80
 #define	DA9063_GPIO7_MODE			0x80
 
 
-/* DA9063_REG_GPIO_MODE_8_15 (addr=0x1E) */
+/* DA9063_REG_GPIO_MODE8_15 (addr=0x1E) */
 #define	DA9063_GPIO8_MODE			0x01
 #define	DA9063_GPIO8_MODE			0x01
 #define	DA9063_GPIO9_MODE			0x02
 #define	DA9063_GPIO9_MODE			0x02
 #define	DA9063_GPIO10_MODE			0x04
 #define	DA9063_GPIO10_MODE			0x04
@@ -702,12 +704,12 @@
 #define		DA9063_SWITCH_SR_5MV		0x10
 #define		DA9063_SWITCH_SR_5MV		0x10
 #define		DA9063_SWITCH_SR_10MV		0x20
 #define		DA9063_SWITCH_SR_10MV		0x20
 #define		DA9063_SWITCH_SR_50MV		0x30
 #define		DA9063_SWITCH_SR_50MV		0x30
-#define	DA9063_SWITCH_SR_DIS			0x40
+#define	DA9063_CORE_SW_INTERNAL			0x40
 #define	DA9063_CP_EN_MODE			0x80
 #define	DA9063_CP_EN_MODE			0x80
 
 
 /* DA9063_REGL_Bxxxx_CONT common bits (addr=0x20-0x25) */
 /* DA9063_REGL_Bxxxx_CONT common bits (addr=0x20-0x25) */
 #define	DA9063_BUCK_EN				0x01
 #define	DA9063_BUCK_EN				0x01
-#define DA9063_BUCK_GPI_MASK			0x06
+#define	DA9063_BUCK_GPI_MASK			0x06
 #define		DA9063_BUCK_GPI_OFF		0x00
 #define		DA9063_BUCK_GPI_OFF		0x00
 #define		DA9063_BUCK_GPI_GPIO1		0x02
 #define		DA9063_BUCK_GPI_GPIO1		0x02
 #define		DA9063_BUCK_GPI_GPIO2		0x04
 #define		DA9063_BUCK_GPI_GPIO2		0x04
@@ -841,25 +843,27 @@
 #define DA9063_COUNT_YEAR_MASK			0x3F
 #define DA9063_COUNT_YEAR_MASK			0x3F
 #define DA9063_MONITOR				0x40
 #define DA9063_MONITOR				0x40
 
 
-/* DA9063_REG_ALARM_MI (addr=0x46) */
+/* DA9063_REG_ALARM_S (addr=0x46) */
+#define DA9063_ALARM_S_MASK			0x3F
 #define DA9063_ALARM_STATUS_ALARM		0x80
 #define DA9063_ALARM_STATUS_ALARM		0x80
 #define DA9063_ALARM_STATUS_TICK		0x40
 #define DA9063_ALARM_STATUS_TICK		0x40
+/* DA9063_REG_ALARM_MI (addr=0x47) */
 #define DA9063_ALARM_MIN_MASK			0x3F
 #define DA9063_ALARM_MIN_MASK			0x3F
 
 
-/* DA9063_REG_ALARM_H (addr=0x47) */
+/* DA9063_REG_ALARM_H (addr=0x48) */
 #define DA9063_ALARM_HOUR_MASK			0x1F
 #define DA9063_ALARM_HOUR_MASK			0x1F
 
 
-/* DA9063_REG_ALARM_D (addr=0x48) */
+/* DA9063_REG_ALARM_D (addr=0x49) */
 #define DA9063_ALARM_DAY_MASK			0x1F
 #define DA9063_ALARM_DAY_MASK			0x1F
 
 
-/* DA9063_REG_ALARM_MO (addr=0x49) */
+/* DA9063_REG_ALARM_MO (addr=0x4A) */
 #define DA9063_TICK_WAKE			0x20
 #define DA9063_TICK_WAKE			0x20
 #define DA9063_TICK_TYPE			0x10
 #define DA9063_TICK_TYPE			0x10
 #define		DA9063_TICK_TYPE_SEC		0x00
 #define		DA9063_TICK_TYPE_SEC		0x00
 #define		DA9063_TICK_TYPE_MIN		0x10
 #define		DA9063_TICK_TYPE_MIN		0x10
 #define DA9063_ALARM_MONTH_MASK			0x0F
 #define DA9063_ALARM_MONTH_MASK			0x0F
 
 
-/* DA9063_REG_ALARM_Y (addr=0x4A) */
+/* DA9063_REG_ALARM_Y (addr=0x4B) */
 #define DA9063_TICK_ON				0x80
 #define DA9063_TICK_ON				0x80
 #define DA9063_ALARM_ON				0x40
 #define DA9063_ALARM_ON				0x40
 #define DA9063_ALARM_YEAR_MASK			0x3F
 #define DA9063_ALARM_YEAR_MASK			0x3F
@@ -906,7 +910,7 @@
 
 
 /* DA9063_REG_Bxxxx_CFG common bits (addr=0x9D-0xA2) */
 /* DA9063_REG_Bxxxx_CFG common bits (addr=0x9D-0xA2) */
 #define DA9063_BUCK_FB_MASK			0x07
 #define DA9063_BUCK_FB_MASK			0x07
-#define DA9063_BUCK_PD_DIS_SHIFT		5
+#define DA9063_BUCK_PD_DIS_MASK		0x20
 #define DA9063_BUCK_MODE_MASK			0xC0
 #define DA9063_BUCK_MODE_MASK			0xC0
 #define		DA9063_BUCK_MODE_MANUAL		0x00
 #define		DA9063_BUCK_MODE_MANUAL		0x00
 #define		DA9063_BUCK_MODE_SLEEP		0x40
 #define		DA9063_BUCK_MODE_SLEEP		0x40

+ 14 - 11
include/linux/mfd/lpc_ich.h

@@ -21,23 +21,26 @@
 #define LPC_ICH_H
 #define LPC_ICH_H
 
 
 /* Watchdog resources */
 /* Watchdog resources */
-#define ICH_RES_IO_TCO	0
-#define ICH_RES_IO_SMI	1
-#define ICH_RES_MEM_OFF	2
-#define ICH_RES_MEM_GCS	0
+#define ICH_RES_IO_TCO		0
+#define ICH_RES_IO_SMI		1
+#define ICH_RES_MEM_OFF		2
+#define ICH_RES_MEM_GCS_PMC	0
 
 
 /* GPIO resources */
 /* GPIO resources */
 #define ICH_RES_GPIO	0
 #define ICH_RES_GPIO	0
 #define ICH_RES_GPE0	1
 #define ICH_RES_GPE0	1
 
 
 /* GPIO compatibility */
 /* GPIO compatibility */
-#define ICH_I3100_GPIO		0x401
-#define ICH_V5_GPIO		0x501
-#define ICH_V6_GPIO		0x601
-#define ICH_V7_GPIO		0x701
-#define ICH_V9_GPIO		0x801
-#define ICH_V10CORP_GPIO	0xa01
-#define ICH_V10CONS_GPIO	0xa11
+enum {
+	ICH_I3100_GPIO,
+	ICH_V5_GPIO,
+	ICH_V6_GPIO,
+	ICH_V7_GPIO,
+	ICH_V9_GPIO,
+	ICH_V10CORP_GPIO,
+	ICH_V10CONS_GPIO,
+	AVOTON_GPIO,
+};
 
 
 struct lpc_ich_info {
 struct lpc_ich_info {
 	char name[32];
 	char name[32];

+ 0 - 8
include/linux/mfd/max14577-private.h

@@ -248,14 +248,6 @@ enum max14577_charger_reg {
 /* MAX14577 regulator SFOUT LDO voltage, fixed, uV */
 /* MAX14577 regulator SFOUT LDO voltage, fixed, uV */
 #define MAX14577_REGULATOR_SAFEOUT_VOLTAGE		4900000
 #define MAX14577_REGULATOR_SAFEOUT_VOLTAGE		4900000
 
 
-enum max14577_irq_source {
-	MAX14577_IRQ_INT1 = 0,
-	MAX14577_IRQ_INT2,
-	MAX14577_IRQ_INT3,
-
-	MAX14577_IRQ_REGS_NUM,
-};
-
 enum max14577_irq {
 enum max14577_irq {
 	/* INT1 */
 	/* INT1 */
 	MAX14577_IRQ_INT1_ADC,
 	MAX14577_IRQ_INT1_ADC,

+ 0 - 5
include/linux/mfd/max14577.h

@@ -25,13 +25,8 @@
 #ifndef __MAX14577_H__
 #ifndef __MAX14577_H__
 #define __MAX14577_H__
 #define __MAX14577_H__
 
 
-#include <linux/mfd/max14577-private.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/consumer.h>
 
 
-/*
- * MAX14577 Regulator
- */
-
 /* MAX14577 regulator IDs */
 /* MAX14577 regulator IDs */
 enum max14577_regulators {
 enum max14577_regulators {
 	MAX14577_SAFEOUT = 0,
 	MAX14577_SAFEOUT = 0,

+ 0 - 59
include/linux/mfd/pm8xxx/irq.h

@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-/*
- * Qualcomm PMIC irq 8xxx driver header file
- *
- */
-
-#ifndef __MFD_PM8XXX_IRQ_H
-#define __MFD_PM8XXX_IRQ_H
-
-#include <linux/errno.h>
-#include <linux/err.h>
-
-struct pm8xxx_irq_core_data {
-	u32		rev;
-	int		nirqs;
-};
-
-struct pm8xxx_irq_platform_data {
-	int				irq_base;
-	struct pm8xxx_irq_core_data	irq_cdata;
-	int				devirq;
-	int				irq_trigger_flag;
-};
-
-struct pm_irq_chip;
-
-#ifdef CONFIG_MFD_PM8XXX_IRQ
-int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq);
-struct pm_irq_chip *pm8xxx_irq_init(struct device *dev,
-				const struct pm8xxx_irq_platform_data *pdata);
-int pm8xxx_irq_exit(struct pm_irq_chip *chip);
-#else
-static inline int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq)
-{
-	return -ENXIO;
-}
-static inline struct pm_irq_chip *pm8xxx_irq_init(
-				const struct device *dev,
-				const struct pm8xxx_irq_platform_data *pdata)
-{
-	return ERR_PTR(-ENXIO);
-}
-static inline int pm8xxx_irq_exit(struct pm_irq_chip *chip)
-{
-	return -ENXIO;
-}
-#endif /* CONFIG_MFD_PM8XXX_IRQ */
-#endif /* __MFD_PM8XXX_IRQ_H */

+ 0 - 30
include/linux/mfd/pm8xxx/pm8921.h

@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-/*
- * Qualcomm PMIC 8921 driver header file
- *
- */
-
-#ifndef __MFD_PM8921_H
-#define __MFD_PM8921_H
-
-#include <linux/mfd/pm8xxx/irq.h>
-
-#define PM8921_NR_IRQS		256
-
-struct pm8921_platform_data {
-	int					irq_base;
-	struct pm8xxx_irq_platform_data		*irq_pdata;
-};
-
-#endif

+ 628 - 0
include/linux/mfd/rtsx_usb.h

@@ -0,0 +1,628 @@
+/* Driver for Realtek RTS5139 USB card reader
+ *
+ * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ *   Roger Tseng <rogerable@realtek.com>
+ */
+
+#ifndef __RTSX_USB_H
+#define __RTSX_USB_H
+
+#include <linux/usb.h>
+
+/* related module names */
+#define RTSX_USB_SD_CARD	0
+#define RTSX_USB_MS_CARD	1
+
+/* endpoint numbers */
+#define EP_BULK_OUT		1
+#define EP_BULK_IN		2
+#define EP_INTR_IN		3
+
+/* USB vendor requests */
+#define RTSX_USB_REQ_REG_OP	0x00
+#define RTSX_USB_REQ_POLL	0x02
+
+/* miscellaneous parameters */
+#define MIN_DIV_N		60
+#define MAX_DIV_N		120
+
+#define MAX_PHASE		15
+#define RX_TUNING_CNT		3
+
+#define QFN24			0
+#define LQFP48			1
+#define CHECK_PKG(ucr, pkg)	((ucr)->package == (pkg))
+
+/* data structures */
+struct rtsx_ucr {
+	u16			vendor_id;
+	u16			product_id;
+
+	int			package;
+	u8			ic_version;
+	bool			is_rts5179;
+
+	unsigned int		cur_clk;
+
+	u8			*cmd_buf;
+	unsigned int		cmd_idx;
+	u8			*rsp_buf;
+
+	struct usb_device	*pusb_dev;
+	struct usb_interface	*pusb_intf;
+	struct usb_sg_request	current_sg;
+	unsigned char		*iobuf;
+	dma_addr_t		iobuf_dma;
+
+	struct timer_list	sg_timer;
+	struct mutex		dev_mutex;
+};
+
+/* buffer size */
+#define IOBUF_SIZE		1024
+
+/* prototypes of exported functions */
+extern int rtsx_usb_get_card_status(struct rtsx_ucr *ucr, u16 *status);
+
+extern int rtsx_usb_read_register(struct rtsx_ucr *ucr, u16 addr, u8 *data);
+extern int rtsx_usb_write_register(struct rtsx_ucr *ucr, u16 addr, u8 mask,
+		u8 data);
+
+extern int rtsx_usb_ep0_write_register(struct rtsx_ucr *ucr, u16 addr, u8 mask,
+		u8 data);
+extern int rtsx_usb_ep0_read_register(struct rtsx_ucr *ucr, u16 addr,
+		u8 *data);
+
+extern void rtsx_usb_add_cmd(struct rtsx_ucr *ucr, u8 cmd_type,
+		u16 reg_addr, u8 mask, u8 data);
+extern int rtsx_usb_send_cmd(struct rtsx_ucr *ucr, u8 flag, int timeout);
+extern int rtsx_usb_get_rsp(struct rtsx_ucr *ucr, int rsp_len, int timeout);
+extern int rtsx_usb_transfer_data(struct rtsx_ucr *ucr, unsigned int pipe,
+			      void *buf, unsigned int len, int use_sg,
+			      unsigned int *act_len, int timeout);
+
+extern int rtsx_usb_read_ppbuf(struct rtsx_ucr *ucr, u8 *buf, int buf_len);
+extern int rtsx_usb_write_ppbuf(struct rtsx_ucr *ucr, u8 *buf, int buf_len);
+extern int rtsx_usb_switch_clock(struct rtsx_ucr *ucr, unsigned int card_clock,
+		u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk);
+extern int rtsx_usb_card_exclusive_check(struct rtsx_ucr *ucr, int card);
+
+/* card status */
+#define SD_CD		0x01
+#define MS_CD		0x02
+#define XD_CD		0x04
+#define CD_MASK		(SD_CD | MS_CD | XD_CD)
+#define SD_WP		0x08
+
+/* reader command field offset & parameters */
+#define READ_REG_CMD		0
+#define WRITE_REG_CMD		1
+#define CHECK_REG_CMD		2
+
+#define PACKET_TYPE		4
+#define CNT_H			5
+#define CNT_L			6
+#define STAGE_FLAG		7
+#define CMD_OFFSET		8
+#define SEQ_WRITE_DATA_OFFSET	12
+
+#define BATCH_CMD		0
+#define SEQ_READ		1
+#define SEQ_WRITE		2
+
+#define STAGE_R			0x01
+#define STAGE_DI		0x02
+#define STAGE_DO		0x04
+#define STAGE_MS_STATUS		0x08
+#define STAGE_XD_STATUS		0x10
+#define MODE_C			0x00
+#define MODE_CR			(STAGE_R)
+#define MODE_CDIR		(STAGE_R | STAGE_DI)
+#define MODE_CDOR		(STAGE_R | STAGE_DO)
+
+#define EP0_OP_SHIFT		14
+#define EP0_READ_REG_CMD	2
+#define EP0_WRITE_REG_CMD	3
+
+#define rtsx_usb_cmd_hdr_tag(ucr)		\
+	do {					\
+		ucr->cmd_buf[0] = 'R';		\
+		ucr->cmd_buf[1] = 'T';		\
+		ucr->cmd_buf[2] = 'C';		\
+		ucr->cmd_buf[3] = 'R';		\
+	} while (0)
+
+static inline void rtsx_usb_init_cmd(struct rtsx_ucr *ucr)
+{
+	rtsx_usb_cmd_hdr_tag(ucr);
+	ucr->cmd_idx = 0;
+	ucr->cmd_buf[PACKET_TYPE] = BATCH_CMD;
+}
+
+/* internal register address */
+#define FPDCTL				0xFC00
+#define SSC_DIV_N_0			0xFC07
+#define SSC_CTL1			0xFC09
+#define SSC_CTL2			0xFC0A
+#define CFG_MODE			0xFC0E
+#define CFG_MODE_1			0xFC0F
+#define RCCTL				0xFC14
+#define SOF_WDOG			0xFC28
+#define SYS_DUMMY0			0xFC30
+
+#define MS_BLKEND			0xFD30
+#define MS_READ_START			0xFD31
+#define MS_READ_COUNT			0xFD32
+#define MS_WRITE_START			0xFD33
+#define MS_WRITE_COUNT			0xFD34
+#define MS_COMMAND			0xFD35
+#define MS_OLD_BLOCK_0			0xFD36
+#define MS_OLD_BLOCK_1			0xFD37
+#define MS_NEW_BLOCK_0			0xFD38
+#define MS_NEW_BLOCK_1			0xFD39
+#define MS_LOG_BLOCK_0			0xFD3A
+#define MS_LOG_BLOCK_1			0xFD3B
+#define MS_BUS_WIDTH			0xFD3C
+#define MS_PAGE_START			0xFD3D
+#define MS_PAGE_LENGTH			0xFD3E
+#define MS_CFG				0xFD40
+#define MS_TPC				0xFD41
+#define MS_TRANS_CFG			0xFD42
+#define MS_TRANSFER			0xFD43
+#define MS_INT_REG			0xFD44
+#define MS_BYTE_CNT			0xFD45
+#define MS_SECTOR_CNT_L			0xFD46
+#define MS_SECTOR_CNT_H			0xFD47
+#define MS_DBUS_H			0xFD48
+
+#define CARD_DMA1_CTL			0xFD5C
+#define CARD_PULL_CTL1			0xFD60
+#define CARD_PULL_CTL2			0xFD61
+#define CARD_PULL_CTL3			0xFD62
+#define CARD_PULL_CTL4			0xFD63
+#define CARD_PULL_CTL5			0xFD64
+#define CARD_PULL_CTL6			0xFD65
+#define CARD_EXIST			0xFD6F
+#define CARD_INT_PEND			0xFD71
+
+#define LDO_POWER_CFG			0xFD7B
+
+#define SD_CFG1				0xFDA0
+#define SD_CFG2				0xFDA1
+#define SD_CFG3				0xFDA2
+#define SD_STAT1			0xFDA3
+#define SD_STAT2			0xFDA4
+#define SD_BUS_STAT			0xFDA5
+#define SD_PAD_CTL			0xFDA6
+#define SD_SAMPLE_POINT_CTL		0xFDA7
+#define SD_PUSH_POINT_CTL		0xFDA8
+#define SD_CMD0				0xFDA9
+#define SD_CMD1				0xFDAA
+#define SD_CMD2				0xFDAB
+#define SD_CMD3				0xFDAC
+#define SD_CMD4				0xFDAD
+#define SD_CMD5				0xFDAE
+#define SD_BYTE_CNT_L			0xFDAF
+#define SD_BYTE_CNT_H			0xFDB0
+#define SD_BLOCK_CNT_L			0xFDB1
+#define SD_BLOCK_CNT_H			0xFDB2
+#define SD_TRANSFER			0xFDB3
+#define SD_CMD_STATE			0xFDB5
+#define SD_DATA_STATE			0xFDB6
+#define SD_VPCLK0_CTL			0xFC2A
+#define SD_VPCLK1_CTL			0xFC2B
+#define SD_DCMPS0_CTL			0xFC2C
+#define SD_DCMPS1_CTL			0xFC2D
+
+#define CARD_DMA1_CTL			0xFD5C
+
+#define HW_VERSION			0xFC01
+
+#define SSC_CLK_FPGA_SEL		0xFC02
+#define CLK_DIV				0xFC03
+#define SFSM_ED				0xFC04
+
+#define CD_DEGLITCH_WIDTH		0xFC20
+#define CD_DEGLITCH_EN			0xFC21
+#define AUTO_DELINK_EN			0xFC23
+
+#define FPGA_PULL_CTL			0xFC1D
+#define CARD_CLK_SOURCE			0xFC2E
+
+#define CARD_SHARE_MODE			0xFD51
+#define CARD_DRIVE_SEL			0xFD52
+#define CARD_STOP			0xFD53
+#define CARD_OE				0xFD54
+#define CARD_AUTO_BLINK			0xFD55
+#define CARD_GPIO			0xFD56
+#define SD30_DRIVE_SEL			0xFD57
+
+#define CARD_DATA_SOURCE		0xFD5D
+#define CARD_SELECT			0xFD5E
+
+#define CARD_CLK_EN			0xFD79
+#define CARD_PWR_CTL			0xFD7A
+
+#define OCPCTL				0xFD80
+#define OCPPARA1			0xFD81
+#define OCPPARA2			0xFD82
+#define OCPSTAT				0xFD83
+
+#define HS_USB_STAT			0xFE01
+#define HS_VCONTROL			0xFE26
+#define HS_VSTAIN			0xFE27
+#define HS_VLOADM			0xFE28
+#define HS_VSTAOUT			0xFE29
+
+#define MC_IRQ				0xFF00
+#define MC_IRQEN			0xFF01
+#define MC_FIFO_CTL			0xFF02
+#define MC_FIFO_BC0			0xFF03
+#define MC_FIFO_BC1			0xFF04
+#define MC_FIFO_STAT			0xFF05
+#define MC_FIFO_MODE			0xFF06
+#define MC_FIFO_RD_PTR0			0xFF07
+#define MC_FIFO_RD_PTR1			0xFF08
+#define MC_DMA_CTL			0xFF10
+#define MC_DMA_TC0			0xFF11
+#define MC_DMA_TC1			0xFF12
+#define MC_DMA_TC2			0xFF13
+#define MC_DMA_TC3			0xFF14
+#define MC_DMA_RST			0xFF15
+
+#define RBUF_SIZE_MASK			0xFBFF
+#define RBUF_BASE			0xF000
+#define PPBUF_BASE1			0xF800
+#define PPBUF_BASE2			0xFA00
+
+/* internal register value macros */
+#define POWER_OFF			0x03
+#define PARTIAL_POWER_ON		0x02
+#define POWER_ON			0x00
+#define POWER_MASK			0x03
+#define LDO3318_PWR_MASK		0x0C
+#define LDO_ON				0x00
+#define LDO_SUSPEND			0x08
+#define LDO_OFF				0x0C
+#define DV3318_AUTO_PWR_OFF		0x10
+#define FORCE_LDO_POWERB		0x60
+
+/* LDO_POWER_CFG */
+#define TUNE_SD18_MASK			0x1C
+#define TUNE_SD18_1V7			0x00
+#define TUNE_SD18_1V8			(0x01 << 2)
+#define TUNE_SD18_1V9			(0x02 << 2)
+#define TUNE_SD18_2V0			(0x03 << 2)
+#define TUNE_SD18_2V7			(0x04 << 2)
+#define TUNE_SD18_2V8			(0x05 << 2)
+#define TUNE_SD18_2V9			(0x06 << 2)
+#define TUNE_SD18_3V3			(0x07 << 2)
+
+/* CLK_DIV */
+#define CLK_CHANGE			0x80
+#define CLK_DIV_1			0x00
+#define CLK_DIV_2			0x01
+#define CLK_DIV_4			0x02
+#define CLK_DIV_8			0x03
+
+#define SSC_POWER_MASK			0x01
+#define SSC_POWER_DOWN			0x01
+#define SSC_POWER_ON			0x00
+
+#define FPGA_VER			0x80
+#define HW_VER_MASK			0x0F
+
+#define EXTEND_DMA1_ASYNC_SIGNAL	0x02
+
+/* CFG_MODE*/
+#define XTAL_FREE			0x80
+#define CLK_MODE_MASK			0x03
+#define CLK_MODE_12M_XTAL		0x00
+#define CLK_MODE_NON_XTAL		0x01
+#define CLK_MODE_24M_OSC		0x02
+#define CLK_MODE_48M_OSC		0x03
+
+/* CFG_MODE_1*/
+#define RTS5179				0x02
+
+#define NYET_EN				0x01
+#define NYET_MSAK			0x01
+
+#define SD30_DRIVE_MASK			0x07
+#define SD20_DRIVE_MASK			0x03
+
+#define DISABLE_SD_CD			0x08
+#define DISABLE_MS_CD			0x10
+#define DISABLE_XD_CD			0x20
+#define SD_CD_DEGLITCH_EN		0x01
+#define MS_CD_DEGLITCH_EN		0x02
+#define XD_CD_DEGLITCH_EN		0x04
+
+#define	CARD_SHARE_LQFP48		0x04
+#define	CARD_SHARE_QFN24		0x00
+#define CARD_SHARE_LQFP_SEL		0x04
+#define	CARD_SHARE_XD			0x00
+#define	CARD_SHARE_SD			0x01
+#define	CARD_SHARE_MS			0x02
+#define CARD_SHARE_MASK			0x03
+
+
+/* SD30_DRIVE_SEL */
+#define DRIVER_TYPE_A			0x05
+#define DRIVER_TYPE_B			0x03
+#define DRIVER_TYPE_C			0x02
+#define DRIVER_TYPE_D			0x01
+
+/* SD_BUS_STAT */
+#define	SD_CLK_TOGGLE_EN		0x80
+#define	SD_CLK_FORCE_STOP	        0x40
+#define	SD_DAT3_STATUS		        0x10
+#define	SD_DAT2_STATUS		        0x08
+#define	SD_DAT1_STATUS		        0x04
+#define	SD_DAT0_STATUS		        0x02
+#define	SD_CMD_STATUS			0x01
+
+/* SD_PAD_CTL */
+#define	SD_IO_USING_1V8		        0x80
+#define	SD_IO_USING_3V3		        0x7F
+#define	TYPE_A_DRIVING		        0x00
+#define	TYPE_B_DRIVING			0x01
+#define	TYPE_C_DRIVING			0x02
+#define	TYPE_D_DRIVING		        0x03
+
+/* CARD_CLK_EN */
+#define SD_CLK_EN			0x04
+#define MS_CLK_EN			0x08
+
+/* CARD_SELECT */
+#define SD_MOD_SEL			2
+#define MS_MOD_SEL			3
+
+/* CARD_SHARE_MODE */
+#define	CARD_SHARE_LQFP48		0x04
+#define	CARD_SHARE_QFN24		0x00
+#define CARD_SHARE_LQFP_SEL		0x04
+#define	CARD_SHARE_XD			0x00
+#define	CARD_SHARE_SD			0x01
+#define	CARD_SHARE_MS			0x02
+#define CARD_SHARE_MASK			0x03
+
+/* SSC_CTL1 */
+#define SSC_RSTB			0x80
+#define SSC_8X_EN			0x40
+#define SSC_FIX_FRAC			0x20
+#define SSC_SEL_1M			0x00
+#define SSC_SEL_2M			0x08
+#define SSC_SEL_4M			0x10
+#define SSC_SEL_8M			0x18
+
+/* SSC_CTL2 */
+#define SSC_DEPTH_MASK			0x03
+#define SSC_DEPTH_DISALBE		0x00
+#define SSC_DEPTH_2M			0x01
+#define SSC_DEPTH_1M			0x02
+#define SSC_DEPTH_512K			0x03
+
+/* SD_VPCLK0_CTL */
+#define PHASE_CHANGE			0x80
+#define PHASE_NOT_RESET			0x40
+
+/* SD_TRANSFER */
+#define	SD_TRANSFER_START		0x80
+#define	SD_TRANSFER_END			0x40
+#define SD_STAT_IDLE			0x20
+#define	SD_TRANSFER_ERR			0x10
+#define	SD_TM_NORMAL_WRITE		0x00
+#define	SD_TM_AUTO_WRITE_3		0x01
+#define	SD_TM_AUTO_WRITE_4		0x02
+#define	SD_TM_AUTO_READ_3		0x05
+#define	SD_TM_AUTO_READ_4		0x06
+#define	SD_TM_CMD_RSP			0x08
+#define	SD_TM_AUTO_WRITE_1		0x09
+#define	SD_TM_AUTO_WRITE_2		0x0A
+#define	SD_TM_NORMAL_READ		0x0C
+#define	SD_TM_AUTO_READ_1		0x0D
+#define	SD_TM_AUTO_READ_2		0x0E
+#define	SD_TM_AUTO_TUNING		0x0F
+
+/* SD_CFG1 */
+#define SD_CLK_DIVIDE_0			0x00
+#define	SD_CLK_DIVIDE_256		0xC0
+#define	SD_CLK_DIVIDE_128		0x80
+#define SD_CLK_DIVIDE_MASK		0xC0
+#define	SD_BUS_WIDTH_1BIT		0x00
+#define	SD_BUS_WIDTH_4BIT		0x01
+#define	SD_BUS_WIDTH_8BIT		0x02
+#define	SD_ASYNC_FIFO_RST		0x10
+#define	SD_20_MODE			0x00
+#define	SD_DDR_MODE			0x04
+#define	SD_30_MODE			0x08
+
+/* SD_CFG2 */
+#define	SD_CALCULATE_CRC7		0x00
+#define	SD_NO_CALCULATE_CRC7		0x80
+#define	SD_CHECK_CRC16			0x00
+#define	SD_NO_CHECK_CRC16		0x40
+#define SD_WAIT_CRC_TO_EN		0x20
+#define	SD_WAIT_BUSY_END		0x08
+#define	SD_NO_WAIT_BUSY_END		0x00
+#define	SD_CHECK_CRC7			0x00
+#define	SD_NO_CHECK_CRC7		0x04
+#define	SD_RSP_LEN_0			0x00
+#define	SD_RSP_LEN_6			0x01
+#define	SD_RSP_LEN_17			0x02
+#define	SD_RSP_TYPE_R0			0x04
+#define	SD_RSP_TYPE_R1			0x01
+#define	SD_RSP_TYPE_R1b			0x09
+#define	SD_RSP_TYPE_R2			0x02
+#define	SD_RSP_TYPE_R3			0x05
+#define	SD_RSP_TYPE_R4			0x05
+#define	SD_RSP_TYPE_R5			0x01
+#define	SD_RSP_TYPE_R6			0x01
+#define	SD_RSP_TYPE_R7			0x01
+
+/* SD_STAT1 */
+#define	SD_CRC7_ERR			0x80
+#define	SD_CRC16_ERR			0x40
+#define	SD_CRC_WRITE_ERR		0x20
+#define	SD_CRC_WRITE_ERR_MASK		0x1C
+#define	GET_CRC_TIME_OUT		0x02
+#define	SD_TUNING_COMPARE_ERR		0x01
+
+/* SD_DATA_STATE */
+#define SD_DATA_IDLE			0x80
+
+/* CARD_DATA_SOURCE */
+#define PINGPONG_BUFFER			0x01
+#define RING_BUFFER			0x00
+
+/* CARD_OE */
+#define SD_OUTPUT_EN			0x04
+#define MS_OUTPUT_EN			0x08
+
+/* CARD_STOP */
+#define SD_STOP				0x04
+#define MS_STOP				0x08
+#define SD_CLR_ERR			0x40
+#define MS_CLR_ERR			0x80
+
+/* CARD_CLK_SOURCE */
+#define CRC_FIX_CLK			(0x00 << 0)
+#define CRC_VAR_CLK0			(0x01 << 0)
+#define CRC_VAR_CLK1			(0x02 << 0)
+#define SD30_FIX_CLK			(0x00 << 2)
+#define SD30_VAR_CLK0			(0x01 << 2)
+#define SD30_VAR_CLK1			(0x02 << 2)
+#define SAMPLE_FIX_CLK			(0x00 << 4)
+#define SAMPLE_VAR_CLK0			(0x01 << 4)
+#define SAMPLE_VAR_CLK1			(0x02 << 4)
+
+/* SD_SAMPLE_POINT_CTL */
+#define	DDR_FIX_RX_DAT			0x00
+#define	DDR_VAR_RX_DAT			0x80
+#define	DDR_FIX_RX_DAT_EDGE		0x00
+#define	DDR_FIX_RX_DAT_14_DELAY		0x40
+#define	DDR_FIX_RX_CMD			0x00
+#define	DDR_VAR_RX_CMD			0x20
+#define	DDR_FIX_RX_CMD_POS_EDGE		0x00
+#define	DDR_FIX_RX_CMD_14_DELAY		0x10
+#define	SD20_RX_POS_EDGE		0x00
+#define	SD20_RX_14_DELAY		0x08
+#define SD20_RX_SEL_MASK		0x08
+
+/* SD_PUSH_POINT_CTL */
+#define	DDR_FIX_TX_CMD_DAT		0x00
+#define	DDR_VAR_TX_CMD_DAT		0x80
+#define	DDR_FIX_TX_DAT_14_TSU		0x00
+#define	DDR_FIX_TX_DAT_12_TSU		0x40
+#define	DDR_FIX_TX_CMD_NEG_EDGE		0x00
+#define	DDR_FIX_TX_CMD_14_AHEAD		0x20
+#define	SD20_TX_NEG_EDGE		0x00
+#define	SD20_TX_14_AHEAD		0x10
+#define SD20_TX_SEL_MASK		0x10
+#define	DDR_VAR_SDCLK_POL_SWAP		0x01
+
+/* MS_CFG */
+#define	SAMPLE_TIME_RISING		0x00
+#define	SAMPLE_TIME_FALLING		0x80
+#define	PUSH_TIME_DEFAULT		0x00
+#define	PUSH_TIME_ODD			0x40
+#define	NO_EXTEND_TOGGLE		0x00
+#define	EXTEND_TOGGLE_CHK		0x20
+#define	MS_BUS_WIDTH_1			0x00
+#define	MS_BUS_WIDTH_4			0x10
+#define	MS_BUS_WIDTH_8			0x18
+#define	MS_2K_SECTOR_MODE		0x04
+#define	MS_512_SECTOR_MODE		0x00
+#define	MS_TOGGLE_TIMEOUT_EN		0x00
+#define	MS_TOGGLE_TIMEOUT_DISEN		0x01
+#define MS_NO_CHECK_INT			0x02
+
+/* MS_TRANS_CFG */
+#define	WAIT_INT			0x80
+#define	NO_WAIT_INT			0x00
+#define	NO_AUTO_READ_INT_REG		0x00
+#define	AUTO_READ_INT_REG		0x40
+#define	MS_CRC16_ERR			0x20
+#define	MS_RDY_TIMEOUT			0x10
+#define	MS_INT_CMDNK			0x08
+#define	MS_INT_BREQ			0x04
+#define	MS_INT_ERR			0x02
+#define	MS_INT_CED			0x01
+
+/* MS_TRANSFER */
+#define	MS_TRANSFER_START		0x80
+#define	MS_TRANSFER_END			0x40
+#define	MS_TRANSFER_ERR			0x20
+#define	MS_BS_STATE			0x10
+#define	MS_TM_READ_BYTES		0x00
+#define	MS_TM_NORMAL_READ		0x01
+#define	MS_TM_WRITE_BYTES		0x04
+#define	MS_TM_NORMAL_WRITE		0x05
+#define	MS_TM_AUTO_READ			0x08
+#define	MS_TM_AUTO_WRITE		0x0C
+#define MS_TM_SET_CMD			0x06
+#define MS_TM_COPY_PAGE			0x07
+#define MS_TM_MULTI_READ		0x02
+#define MS_TM_MULTI_WRITE		0x03
+
+/* MC_FIFO_CTL */
+#define FIFO_FLUSH			0x01
+
+/* MC_DMA_RST */
+#define DMA_RESET  0x01
+
+/* MC_DMA_CTL */
+#define DMA_TC_EQ_0			0x80
+#define DMA_DIR_TO_CARD			0x00
+#define DMA_DIR_FROM_CARD		0x02
+#define DMA_EN				0x01
+#define DMA_128				(0 << 2)
+#define DMA_256				(1 << 2)
+#define DMA_512				(2 << 2)
+#define DMA_1024			(3 << 2)
+#define DMA_PACK_SIZE_MASK		0x0C
+
+/* CARD_INT_PEND */
+#define XD_INT				0x10
+#define MS_INT				0x08
+#define SD_INT				0x04
+
+/* LED operations*/
+static inline int rtsx_usb_turn_on_led(struct rtsx_ucr *ucr)
+{
+	return  rtsx_usb_ep0_write_register(ucr, CARD_GPIO, 0x03, 0x02);
+}
+
+static inline int rtsx_usb_turn_off_led(struct rtsx_ucr *ucr)
+{
+	return rtsx_usb_ep0_write_register(ucr, CARD_GPIO, 0x03, 0x03);
+}
+
+/* HW error clearing */
+static inline void rtsx_usb_clear_fsm_err(struct rtsx_ucr *ucr)
+{
+	rtsx_usb_ep0_write_register(ucr, SFSM_ED, 0xf8, 0xf8);
+}
+
+static inline void rtsx_usb_clear_dma_err(struct rtsx_ucr *ucr)
+{
+	rtsx_usb_ep0_write_register(ucr, MC_FIFO_CTL,
+			FIFO_FLUSH, FIFO_FLUSH);
+	rtsx_usb_ep0_write_register(ucr, MC_DMA_RST, DMA_RESET, DMA_RESET);
+}
+#endif /* __RTS51139_H */

+ 284 - 0
include/linux/mfd/tps65218.h

@@ -0,0 +1,284 @@
+/*
+ * linux/mfd/tps65218.h
+ *
+ * Functions to access TPS65219 power management chip.
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.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.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether expressed or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License version 2 for more details.
+ */
+
+#ifndef __LINUX_MFD_TPS65218_H
+#define __LINUX_MFD_TPS65218_H
+
+#include <linux/i2c.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/bitops.h>
+
+/* TPS chip id list */
+#define TPS65218			0xF0
+
+/* I2C ID for TPS65218 part */
+#define TPS65218_I2C_ID			0x24
+
+/* All register addresses */
+#define TPS65218_REG_CHIPID		0x00
+#define TPS65218_REG_INT1		0x01
+#define TPS65218_REG_INT2		0x02
+#define TPS65218_REG_INT_MASK1		0x03
+#define TPS65218_REG_INT_MASK2		0x04
+#define TPS65218_REG_STATUS		0x05
+#define TPS65218_REG_CONTROL		0x06
+#define TPS65218_REG_FLAG		0x07
+
+#define TPS65218_REG_PASSWORD		0x10
+#define TPS65218_REG_ENABLE1		0x11
+#define TPS65218_REG_ENABLE2		0x12
+#define TPS65218_REG_CONFIG1		0x13
+#define TPS65218_REG_CONFIG2		0x14
+#define TPS65218_REG_CONFIG3		0x15
+#define TPS65218_REG_CONTROL_DCDC1	0x16
+#define TPS65218_REG_CONTROL_DCDC2	0x17
+#define TPS65218_REG_CONTROL_DCDC3	0x18
+#define TPS65218_REG_CONTROL_DCDC4	0x19
+#define TPS65218_REG_CONTRL_SLEW_RATE	0x1A
+#define TPS65218_REG_CONTROL_LDO1	0x1B
+#define TPS65218_REG_SEQ1		0x20
+#define TPS65218_REG_SEQ2		0x21
+#define TPS65218_REG_SEQ3		0x22
+#define TPS65218_REG_SEQ4		0x23
+#define TPS65218_REG_SEQ5		0x24
+#define TPS65218_REG_SEQ6		0x25
+#define TPS65218_REG_SEQ7		0x26
+
+/* Register field definitions */
+#define TPS65218_CHIPID_CHIP_MASK	0xF8
+#define TPS65218_CHIPID_REV_MASK	0x07
+
+#define TPS65218_INT1_VPRG		BIT(5)
+#define TPS65218_INT1_AC		BIT(4)
+#define TPS65218_INT1_PB		BIT(3)
+#define TPS65218_INT1_HOT		BIT(2)
+#define TPS65218_INT1_CC_AQC		BIT(1)
+#define TPS65218_INT1_PRGC		BIT(0)
+
+#define TPS65218_INT2_LS3_F		BIT(5)
+#define TPS65218_INT2_LS2_F		BIT(4)
+#define TPS65218_INT2_LS1_F		BIT(3)
+#define TPS65218_INT2_LS3_I		BIT(2)
+#define TPS65218_INT2_LS2_I		BIT(1)
+#define TPS65218_INT2_LS1_I		BIT(0)
+
+#define TPS65218_INT_MASK1_VPRG		BIT(5)
+#define TPS65218_INT_MASK1_AC		BIT(4)
+#define TPS65218_INT_MASK1_PB		BIT(3)
+#define TPS65218_INT_MASK1_HOT		BIT(2)
+#define TPS65218_INT_MASK1_CC_AQC	BIT(1)
+#define TPS65218_INT_MASK1_PRGC		BIT(0)
+
+#define TPS65218_INT_MASK2_LS3_F	BIT(5)
+#define TPS65218_INT_MASK2_LS2_F	BIT(4)
+#define TPS65218_INT_MASK2_LS1_F	BIT(3)
+#define TPS65218_INT_MASK2_LS3_I	BIT(2)
+#define TPS65218_INT_MASK2_LS2_I	BIT(1)
+#define TPS65218_INT_MASK2_LS1_I	BIT(0)
+
+#define TPS65218_STATUS_FSEAL		BIT(7)
+#define TPS65218_STATUS_EE		BIT(6)
+#define TPS65218_STATUS_AC_STATE	BIT(5)
+#define TPS65218_STATUS_PB_STATE	BIT(4)
+#define TPS65218_STATUS_STATE_MASK	0xC
+#define TPS65218_STATUS_CC_STAT		0x3
+
+#define TPS65218_CONTROL_OFFNPFO	BIT(1)
+#define TPS65218_CONTROL_CC_AQ	BIT(0)
+
+#define TPS65218_FLAG_GPO3_FLG		BIT(7)
+#define TPS65218_FLAG_GPO2_FLG		BIT(6)
+#define TPS65218_FLAG_GPO1_FLG		BIT(5)
+#define TPS65218_FLAG_LDO1_FLG		BIT(4)
+#define TPS65218_FLAG_DC4_FLG		BIT(3)
+#define TPS65218_FLAG_DC3_FLG		BIT(2)
+#define TPS65218_FLAG_DC2_FLG		BIT(1)
+#define TPS65218_FLAG_DC1_FLG		BIT(0)
+
+#define TPS65218_ENABLE1_DC6_EN		BIT(5)
+#define TPS65218_ENABLE1_DC5_EN		BIT(4)
+#define TPS65218_ENABLE1_DC4_EN		BIT(3)
+#define TPS65218_ENABLE1_DC3_EN		BIT(2)
+#define TPS65218_ENABLE1_DC2_EN		BIT(1)
+#define TPS65218_ENABLE1_DC1_EN		BIT(0)
+
+#define TPS65218_ENABLE2_GPIO3		BIT(6)
+#define TPS65218_ENABLE2_GPIO2		BIT(5)
+#define TPS65218_ENABLE2_GPIO1		BIT(4)
+#define TPS65218_ENABLE2_LS3_EN		BIT(3)
+#define TPS65218_ENABLE2_LS2_EN		BIT(2)
+#define TPS65218_ENABLE2_LS1_EN		BIT(1)
+#define TPS65218_ENABLE2_LDO1_EN	BIT(0)
+
+
+#define TPS65218_CONFIG1_TRST		BIT(7)
+#define TPS65218_CONFIG1_GPO2_BUF	BIT(6)
+#define TPS65218_CONFIG1_IO1_SEL	BIT(5)
+#define TPS65218_CONFIG1_PGDLY_MASK	0x18
+#define TPS65218_CONFIG1_STRICT		BIT(2)
+#define TPS65218_CONFIG1_UVLO_MASK	0x3
+
+#define TPS65218_CONFIG2_DC12_RST	BIT(7)
+#define TPS65218_CONFIG2_UVLOHYS	BIT(6)
+#define TPS65218_CONFIG2_LS3ILIM_MASK	0xC
+#define TPS65218_CONFIG2_LS2ILIM_MASK	0x3
+
+#define TPS65218_CONFIG3_LS3NPFO	BIT(5)
+#define TPS65218_CONFIG3_LS2NPFO	BIT(4)
+#define TPS65218_CONFIG3_LS1NPFO	BIT(3)
+#define TPS65218_CONFIG3_LS3DCHRG	BIT(2)
+#define TPS65218_CONFIG3_LS2DCHRG	BIT(1)
+#define TPS65218_CONFIG3_LS1DCHRG	BIT(0)
+
+#define TPS65218_CONTROL_DCDC1_PFM	BIT(7)
+#define TPS65218_CONTROL_DCDC1_MASK	0x7F
+
+#define TPS65218_CONTROL_DCDC2_PFM	BIT(7)
+#define TPS65218_CONTROL_DCDC2_MASK	0x3F
+
+#define TPS65218_CONTROL_DCDC3_PFM	BIT(7)
+#define TPS65218_CONTROL_DCDC3_MASK	0x3F
+
+#define TPS65218_CONTROL_DCDC4_PFM	BIT(7)
+#define TPS65218_CONTROL_DCDC4_MASK	0x3F
+
+#define TPS65218_SLEW_RATE_GO		BIT(7)
+#define TPS65218_SLEW_RATE_GODSBL	BIT(6)
+#define TPS65218_SLEW_RATE_SLEW_MASK	0x7
+
+#define TPS65218_CONTROL_LDO1_MASK	0x3F
+
+#define TPS65218_SEQ1_DLY8		BIT(7)
+#define TPS65218_SEQ1_DLY7		BIT(6)
+#define TPS65218_SEQ1_DLY6		BIT(5)
+#define TPS65218_SEQ1_DLY5		BIT(4)
+#define TPS65218_SEQ1_DLY4		BIT(3)
+#define TPS65218_SEQ1_DLY3		BIT(2)
+#define TPS65218_SEQ1_DLY2		BIT(1)
+#define TPS65218_SEQ1_DLY1		BIT(0)
+
+#define TPS65218_SEQ2_DLYFCTR		BIT(7)
+#define TPS65218_SEQ2_DLY9		BIT(0)
+
+#define TPS65218_SEQ3_DC2_SEQ_MASK	0xF0
+#define TPS65218_SEQ3_DC1_SEQ_MASK	0xF
+
+#define TPS65218_SEQ4_DC4_SEQ_MASK	0xF0
+#define TPS65218_SEQ4_DC3_SEQ_MASK	0xF
+
+#define TPS65218_SEQ5_DC6_SEQ_MASK	0xF0
+#define TPS65218_SEQ5_DC5_SEQ_MASK	0xF
+
+#define TPS65218_SEQ6_LS1_SEQ_MASK	0xF0
+#define TPS65218_SEQ6_LDO1_SEQ_MASK	0xF
+
+#define TPS65218_SEQ7_GPO3_SEQ_MASK	0xF0
+#define TPS65218_SEQ7_GPO1_SEQ_MASK	0xF
+#define TPS65218_PROTECT_NONE		0
+#define TPS65218_PROTECT_L1		1
+
+enum tps65218_regulator_id {
+	/* DCDC's */
+	TPS65218_DCDC_1,
+	TPS65218_DCDC_2,
+	TPS65218_DCDC_3,
+	TPS65218_DCDC_4,
+	TPS65218_DCDC_5,
+	TPS65218_DCDC_6,
+	/* LDOs */
+	TPS65218_LDO_1,
+};
+
+#define TPS65218_MAX_REG_ID		TPS65218_LDO_1
+
+/* Number of step-down converters available */
+#define TPS65218_NUM_DCDC		6
+/* Number of LDO voltage regulators available */
+#define TPS65218_NUM_LDO		1
+/* Number of total regulators available */
+#define TPS65218_NUM_REGULATOR		(TPS65218_NUM_DCDC + TPS65218_NUM_LDO)
+
+/* Define the TPS65218 IRQ numbers */
+enum tps65218_irqs {
+	/* INT1 registers */
+	TPS65218_PRGC_IRQ,
+	TPS65218_CC_AQC_IRQ,
+	TPS65218_HOT_IRQ,
+	TPS65218_PB_IRQ,
+	TPS65218_AC_IRQ,
+	TPS65218_VPRG_IRQ,
+	TPS65218_INVALID1_IRQ,
+	TPS65218_INVALID2_IRQ,
+	/* INT2 registers */
+	TPS65218_LS1_I_IRQ,
+	TPS65218_LS2_I_IRQ,
+	TPS65218_LS3_I_IRQ,
+	TPS65218_LS1_F_IRQ,
+	TPS65218_LS2_F_IRQ,
+	TPS65218_LS3_F_IRQ,
+	TPS65218_INVALID3_IRQ,
+	TPS65218_INVALID4_IRQ,
+};
+
+/**
+ * struct tps_info - packages regulator constraints
+ * @id:			Id of the regulator
+ * @name:		Voltage regulator name
+ * @min_uV:		minimum micro volts
+ * @max_uV:		minimum micro volts
+ *
+ * This data is used to check the regualtor voltage limits while setting.
+ */
+struct tps_info {
+	int id;
+	const char *name;
+	int min_uV;
+	int max_uV;
+};
+
+/**
+ * struct tps65218 - tps65218 sub-driver chip access routines
+ *
+ * Device data may be used to access the TPS65218 chip
+ */
+
+struct tps65218 {
+	struct device *dev;
+	unsigned int id;
+
+	struct mutex tps_lock;		/* lock guarding the data structure */
+	/* IRQ Data */
+	int irq;
+	u32 irq_mask;
+	struct regmap_irq_chip_data *irq_data;
+	struct regulator_desc desc[TPS65218_NUM_REGULATOR];
+	struct regulator_dev *rdev[TPS65218_NUM_REGULATOR];
+	struct tps_info *info[TPS65218_NUM_REGULATOR];
+	struct regmap *regmap;
+};
+
+int tps65218_reg_read(struct tps65218 *tps, unsigned int reg,
+					unsigned int *val);
+int tps65218_reg_write(struct tps65218 *tps, unsigned int reg,
+			unsigned int val, unsigned int level);
+int tps65218_set_bits(struct tps65218 *tps, unsigned int reg,
+		unsigned int mask, unsigned int val, unsigned int level);
+int tps65218_clear_bits(struct tps65218 *tps, unsigned int reg,
+		unsigned int mask, unsigned int level);
+
+#endif /*  __LINUX_MFD_TPS65218_H */

+ 20 - 0
include/linux/ssbi.h

@@ -20,4 +20,24 @@
 int ssbi_write(struct device *dev, u16 addr, const u8 *buf, int len);
 int ssbi_write(struct device *dev, u16 addr, const u8 *buf, int len);
 int ssbi_read(struct device *dev, u16 addr, u8 *buf, int len);
 int ssbi_read(struct device *dev, u16 addr, u8 *buf, int len);
 
 
+static inline int
+ssbi_reg_read(void *context, unsigned int reg, unsigned int *val)
+{
+	int ret;
+	u8 v;
+
+	ret = ssbi_read(context, reg, &v, 1);
+	if (!ret)
+		*val = v;
+
+	return ret;
+}
+
+static inline int
+ssbi_reg_write(void *context, unsigned int reg, unsigned int val)
+{
+	u8 v = val;
+	return ssbi_write(context, reg, &v, 1);
+}
+
 #endif
 #endif