]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/kernel-video.git/commitdiff
Merge tag 'mfd-3.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 17 Dec 2012 02:55:20 +0000 (18:55 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 17 Dec 2012 02:55:20 +0000 (18:55 -0800)
Pull MFS update from Samuel Ortiz:
 "This is the MFD patch set for the 3.8 merge window.

  We have several new drivers, most of the time coming with their sub
  devices drivers:

   - Austria Microsystem's AS3711
   - Nano River's viperboard
   - TI's TPS80031, AM335x TS/ADC,
   - Realtek's MMC/memstick card reader
   - Nokia's retu

  We also got some notable cleanups and improvements:

   - tps6586x got converted to IRQ domains.
   - tps65910 and tps65090 moved to the regmap IRQ API.
   - STMPE is now Device Tree aware.
   - A general twl6040 and twl-core cleanup, with moves to the regmap
     I/O and IRQ APIs and a conversion to the recently added PWM
     framework.
   - sta2x11 gained regmap support.

  Then the rest is mostly tiny cleanups and fixes, among which we have
  Mark's wm5xxx and wm8xxx patchset."

Far amount of annoying but largely trivial conflicts.  Many due to
__devinit/exit removal, others due to one or two of the new drivers also
having come in through another tree.

* tag 'mfd-3.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6: (119 commits)
  mfd: tps6507x: Convert to devm_kzalloc
  mfd: stmpe: Update DT support for stmpe driver
  mfd: wm5102: Add readback of DSP status 3 register
  mfd: arizona: Log if we fail to create the primary IRQ domain
  mfd: tps80031: MFD_TPS80031 needs to select REGMAP_IRQ
  mfd: tps80031: Add terminating entry for tps80031_id_table
  mfd: sta2x11: Fix potential NULL pointer dereference in __sta2x11_mfd_mask()
  mfd: wm5102: Add tuning for revision B
  mfd: arizona: Defer patch initialistation until after first device boot
  mfd: tps65910: Fix wrong ack_base register
  mfd: tps65910: Remove unused data
  mfd: stmpe: Get rid of irq_invert_polarity
  mfd: ab8500-core: Fix invalid free of devm_ allocated data
  mfd: wm5102: Mark DSP memory regions as volatile
  mfd: wm5102: Correct default for LDO1_CONTROL_2
  mfd: arizona: Register haptics devices
  mfd: wm8994: Make current device behaviour the default
  mfd: tps65090: MFD_TPS65090 needs to select REGMAP_IRQ
  mfd: Fix stmpe.c build when OF is not enabled
  mfd: jz4740-adc: Use devm_kzalloc
  ...

37 files changed:
1  2 
drivers/gpio/Kconfig
drivers/gpio/Makefile
drivers/gpio/gpio-da9052.c
drivers/gpio/gpio-tps6586x.c
drivers/gpio/gpio-twl4030.c
drivers/iio/adc/Kconfig
drivers/iio/adc/Makefile
drivers/mfd/Kconfig
drivers/mfd/Makefile
drivers/mfd/ab8500-core.c
drivers/mfd/arizona-core.c
drivers/mfd/arizona-irq.c
drivers/mfd/da9052-core.c
drivers/mfd/db8500-prcmu.c
drivers/mfd/jz4740-adc.c
drivers/mfd/lpc_ich.c
drivers/mfd/mc13xxx-i2c.c
drivers/mfd/mc13xxx-spi.c
drivers/mfd/sta2x11-mfd.c
drivers/mfd/stmpe-i2c.c
drivers/mfd/stmpe.c
drivers/mfd/tps65090.c
drivers/mfd/tps65217.c
drivers/mfd/tps6586x.c
drivers/mfd/tps65910.c
drivers/mfd/twl-core.c
drivers/mfd/twl4030-irq.c
drivers/mfd/twl4030-madc.c
drivers/mfd/twl4030-power.c
drivers/mfd/wm5102-tables.c
drivers/mfd/wm8994-core.c
drivers/mmc/host/Makefile
drivers/power/da9052-battery.c
include/linux/mfd/arizona/registers.h
include/linux/mfd/da9055/pdata.h
include/linux/mfd/tps65090.h
include/linux/mfd/tps6586x.h

diff --combined drivers/gpio/Kconfig
index bf892bd68c1769fa35de808fcaf54e739fb142bc,c3bbd08bcdc376bd36a39940b0cde8e5140c71e2..8ae1f5b196690f557e9ac4f95de50fa125f9b4e3
@@@ -47,11 -47,7 +47,11 @@@ if GPIOLI
  
  config OF_GPIO
        def_bool y
 -      depends on OF && !SPARC
 +      depends on OF
 +
 +config GPIO_ACPI
 +      def_bool y
 +      depends on ACPI
  
  config DEBUG_GPIO
        bool "Debug GPIO calls"
@@@ -90,26 -86,11 +90,26 @@@ config GPIO_DA905
        help
          Say yes here to enable the GPIO driver for the DA9052 chip.
  
 +config GPIO_DA9055
 +      tristate "Dialog Semiconductor DA9055 GPIO"
 +      depends on MFD_DA9055
 +      help
 +        Say yes here to enable the GPIO driver for the DA9055 chip.
 +
 +        The Dialog DA9055 PMIC chip has 3 GPIO pins that can be
 +        be controller by this driver.
 +
 +        If driver is built as a module it will be called gpio-da9055.
 +
  config GPIO_MAX730X
        tristate
  
  comment "Memory mapped GPIO drivers:"
  
 +config GPIO_CLPS711X
 +      def_bool y
 +      depends on ARCH_CLPS711X
 +
  config GPIO_GENERIC_PLATFORM
        tristate "Generic memory-mapped GPIO controller support (MMIO platform device)"
        select GPIO_GENERIC
@@@ -171,7 -152,7 +171,7 @@@ config GPIO_MSM_V
  
  config GPIO_MVEBU
        def_bool y
 -      depends on ARCH_MVEBU
 +      depends on PLAT_ORION
        select GPIO_GENERIC
        select GENERIC_IRQ_CHIP
  
@@@ -189,7 -170,7 +189,7 @@@ config GPIO_MX
  
  config GPIO_PL061
        bool "PrimeCell PL061 GPIO support"
 -      depends on ARM_AMBA
 +      depends on ARM && ARM_AMBA
        select GENERIC_IRQ_CHIP
        help
          Say yes here to support the PrimeCell PL061 GPIO device
@@@ -200,13 -181,6 +200,13 @@@ config GPIO_PX
        help
          Say yes here to support the PXA GPIO device
  
 +config GPIO_SPEAR_SPICS
 +      bool "ST SPEAr13xx SPI Chip Select as GPIO support"
 +      depends on PLAT_SPEAR
 +      select GENERIC_IRQ_CHIP
 +      help
 +        Say yes here to support ST SPEAr SPI Chip Select as GPIO device
 +
  config GPIO_STA2X11
        bool "STA2x11/ConneXt GPIO support"
        depends on MFD_STA2X11
          Say yes here to support the STA2x11/ConneXt GPIO device.
          The GPIO module has 128 GPIO pins with alternate functions.
  
 +config GPIO_TS5500
 +      tristate "TS-5500 DIO blocks and compatibles"
 +      help
 +        This driver supports Digital I/O exposed by pin blocks found on some
 +        Technologic Systems platforms. It includes, but is not limited to, 3
 +        blocks of the TS-5500: DIO1, DIO2 and the LCD port, and the TS-5600
 +        LCD port.
 +
  config GPIO_VT8500
        bool "VIA/Wondermedia SoC GPIO Support"
        depends on ARCH_VT8500
@@@ -500,11 -466,11 +500,11 @@@ config GPIO_ADP5588_IR
  
  config GPIO_ADNP
        tristate "Avionic Design N-bit GPIO expander"
 -      depends on I2C && OF
 +      depends on I2C && OF_GPIO
        help
          This option enables support for N GPIOs found on Avionic Design
          I2C GPIO expanders. The register space will be extended by powers
 -        of two, so the controller will need to accomodate for that. For
 +        of two, so the controller will need to accommodate for that. For
          example: if a controller provides 48 pins, 6 registers will be
          enough to represent all pins, but the driver will assume a
          register layout for 64 pins (8 registers).
@@@ -683,4 -649,17 +683,17 @@@ config GPIO_MSI
          Enable support for GPIO on intel MSIC controllers found in
          intel MID devices
  
+ comment "USB GPIO expanders:"
+ config GPIO_VIPERBOARD
+       tristate "Viperboard GPIO a & b support"
+       depends on MFD_VIPERBOARD && USB
+       help
+         Say yes here to access the GPIO signals of Nano River
+         Technologies Viperboard. There are two GPIO chips on the
+         board: gpioa and gpiob.
+           See viperboard API specification and Nano
+           River Tech's viperboard.h for detailed meaning
+           of the module parameters.
  endif
diff --combined drivers/gpio/Makefile
index 76b344683251731f7b43323e43a5803cfd71e0a5,16a1385226e95c59a2fd7c4e93a2623674578898..c5aebd008dde4d3e5428fb90de3563f82ae159ac
@@@ -4,7 -4,6 +4,7 @@@ ccflags-$(CONFIG_DEBUG_GPIO)     += -DDEBU
  
  obj-$(CONFIG_GPIOLIB)         += gpiolib.o devres.o
  obj-$(CONFIG_OF_GPIO)         += gpiolib-of.o
 +obj-$(CONFIG_GPIO_ACPI)               += gpiolib-acpi.o
  
  # Device drivers. Generally keep list sorted alphabetically
  obj-$(CONFIG_GPIO_GENERIC)    += gpio-generic.o
@@@ -17,10 -16,8 +17,10 @@@ obj-$(CONFIG_GPIO_ADP5588)  += gpio-adp5
  obj-$(CONFIG_GPIO_AMD8111)    += gpio-amd8111.o
  obj-$(CONFIG_GPIO_ARIZONA)    += gpio-arizona.o
  obj-$(CONFIG_GPIO_BT8XX)      += gpio-bt8xx.o
 +obj-$(CONFIG_GPIO_CLPS711X)   += gpio-clps711x.o
  obj-$(CONFIG_GPIO_CS5535)     += gpio-cs5535.o
  obj-$(CONFIG_GPIO_DA9052)     += gpio-da9052.o
 +obj-$(CONFIG_GPIO_DA9055)     += gpio-da9055.o
  obj-$(CONFIG_ARCH_DAVINCI)    += gpio-davinci.o
  obj-$(CONFIG_GPIO_EM)         += gpio-em.o
  obj-$(CONFIG_GPIO_EP93XX)     += gpio-ep93xx.o
@@@ -60,7 -57,6 +60,7 @@@ obj-$(CONFIG_PLAT_SAMSUNG)    += gpio-sams
  obj-$(CONFIG_ARCH_SA1100)     += gpio-sa1100.o
  obj-$(CONFIG_GPIO_SCH)                += gpio-sch.o
  obj-$(CONFIG_GPIO_SODAVILLE)  += gpio-sodaville.o
 +obj-$(CONFIG_GPIO_SPEAR_SPICS)        += gpio-spear-spics.o
  obj-$(CONFIG_GPIO_STA2X11)    += gpio-sta2x11.o
  obj-$(CONFIG_GPIO_STMPE)      += gpio-stmpe.o
  obj-$(CONFIG_GPIO_STP_XWAY)   += gpio-stp-xway.o
@@@ -72,10 -68,10 +72,11 @@@ obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) +
  obj-$(CONFIG_GPIO_TPS6586X)   += gpio-tps6586x.o
  obj-$(CONFIG_GPIO_TPS65910)   += gpio-tps65910.o
  obj-$(CONFIG_GPIO_TPS65912)   += gpio-tps65912.o
 +obj-$(CONFIG_GPIO_TS5500)     += gpio-ts5500.o
  obj-$(CONFIG_GPIO_TWL4030)    += gpio-twl4030.o
  obj-$(CONFIG_GPIO_TWL6040)    += gpio-twl6040.o
  obj-$(CONFIG_GPIO_UCB1400)    += gpio-ucb1400.o
+ obj-$(CONFIG_GPIO_VIPERBOARD) += gpio-viperboard.o
  obj-$(CONFIG_GPIO_VR41XX)     += gpio-vr41xx.o
  obj-$(CONFIG_GPIO_VT8500)     += gpio-vt8500.o
  obj-$(CONFIG_GPIO_VX855)      += gpio-vx855.o
index a05aacd2777aaa92564f520885896b6d3d6c2c99,63f9f5bbc75cd03464ceb46e104b38afb1c37846..29b11e9b6a78600b2d14d61a178d5e1de3fdc2bc
@@@ -185,10 -185,14 +185,14 @@@ static int da9052_gpio_to_irq(struct gp
        struct da9052_gpio *gpio = to_da9052_gpio(gc);
        struct da9052 *da9052 = gpio->da9052;
  
-       return da9052->irq_base + DA9052_IRQ_GPI0 + offset;
+       int irq;
+       irq = regmap_irq_get_virq(da9052->irq_data, DA9052_IRQ_GPI0 + offset);
+       return irq;
  }
  
 -static struct gpio_chip reference_gp __devinitdata = {
 +static struct gpio_chip reference_gp = {
        .label = "da9052-gpio",
        .owner = THIS_MODULE,
        .get = da9052_gpio_get,
        .base = -1,
  };
  
 -static int __devinit da9052_gpio_probe(struct platform_device *pdev)
 +static int da9052_gpio_probe(struct platform_device *pdev)
  {
        struct da9052_gpio *gpio;
        struct da9052_pdata *pdata;
        return 0;
  }
  
 -static int __devexit da9052_gpio_remove(struct platform_device *pdev)
 +static int da9052_gpio_remove(struct platform_device *pdev)
  {
        struct da9052_gpio *gpio = platform_get_drvdata(pdev);
  
  
  static struct platform_driver da9052_gpio_driver = {
        .probe = da9052_gpio_probe,
 -      .remove = __devexit_p(da9052_gpio_remove),
 +      .remove = da9052_gpio_remove,
        .driver = {
                .name   = "da9052-gpio",
                .owner  = THIS_MODULE,
index c1b82da56504b1676b1a730007cca934dacc68bf,62e9e1cb3bc12f0f131bc0f621428251e80183f0..29e8e750bd49580acd38f36f748187d8c60566f7
@@@ -80,7 -80,15 +80,15 @@@ static int tps6586x_gpio_output(struct 
                                val, mask);
  }
  
 -static int __devinit tps6586x_gpio_probe(struct platform_device *pdev)
+ static int tps6586x_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
+ {
+       struct tps6586x_gpio *tps6586x_gpio = to_tps6586x_gpio(gc);
+       return tps6586x_irq_get_virq(tps6586x_gpio->parent,
+                               TPS6586X_INT_PLDO_0 + offset);
+ }
 +static int tps6586x_gpio_probe(struct platform_device *pdev)
  {
        struct tps6586x_platform_data *pdata;
        struct tps6586x_gpio *tps6586x_gpio;
        tps6586x_gpio->gpio_chip.direction_output = tps6586x_gpio_output;
        tps6586x_gpio->gpio_chip.set    = tps6586x_gpio_set;
        tps6586x_gpio->gpio_chip.get    = tps6586x_gpio_get;
+       tps6586x_gpio->gpio_chip.to_irq = tps6586x_gpio_to_irq;
  
  #ifdef CONFIG_OF_GPIO
        tps6586x_gpio->gpio_chip.of_node = pdev->dev.parent->of_node;
        return ret;
  }
  
 -static int __devexit tps6586x_gpio_remove(struct platform_device *pdev)
 +static int tps6586x_gpio_remove(struct platform_device *pdev)
  {
        struct tps6586x_gpio *tps6586x_gpio = platform_get_drvdata(pdev);
  
@@@ -137,7 -146,7 +146,7 @@@ static struct platform_driver tps6586x_
        .driver.name    = "tps6586x-gpio",
        .driver.owner   = THIS_MODULE,
        .probe          = tps6586x_gpio_probe,
 -      .remove         = __devexit_p(tps6586x_gpio_remove),
 +      .remove         = tps6586x_gpio_remove,
  };
  
  static int __init tps6586x_gpio_init(void)
index 00329f2fc05beceedb7a4620a41a3a62f5e7267b,88829c3337bfe12f34afb3401c8ee66b9e15c8a1..9572aa137e6f48b49e3ecef578147308fc014159
@@@ -88,15 -88,11 +88,15 @@@ static inline int gpio_twl4030_write(u
  /*----------------------------------------------------------------------*/
  
  /*
 - * LED register offsets (use TWL4030_MODULE_{LED,PWMA,PWMB}))
 + * LED register offsets from TWL_MODULE_LED base
   * PWMs A and B are dedicated to LEDs A and B, respectively.
   */
  
 -#define TWL4030_LED_LEDEN     0x0
 +#define TWL4030_LED_LEDEN_REG 0x00
 +#define TWL4030_PWMAON_REG    0x01
 +#define TWL4030_PWMAOFF_REG   0x02
 +#define TWL4030_PWMBON_REG    0x03
 +#define TWL4030_PWMBOFF_REG   0x04
  
  /* LEDEN bits */
  #define LEDEN_LEDAON          BIT(0)
  #define LEDEN_PWM_LENGTHA     BIT(6)
  #define LEDEN_PWM_LENGTHB     BIT(7)
  
 -#define TWL4030_PWMx_PWMxON   0x0
 -#define TWL4030_PWMx_PWMxOFF  0x1
 -
  #define PWMxON_LENGTH         BIT(7)
  
  /*----------------------------------------------------------------------*/
@@@ -146,7 -145,7 +146,7 @@@ static void twl4030_led_set_value(int l
        else
                cached_leden |= mask;
        status = twl_i2c_write_u8(TWL4030_MODULE_LED, cached_leden,
 -                      TWL4030_LED_LEDEN);
 +                                TWL4030_LED_LEDEN_REG);
        mutex_unlock(&gpio_lock);
  }
  
@@@ -217,33 -216,33 +217,33 @@@ static int twl_request(struct gpio_chi
        if (offset >= TWL4030_GPIO_MAX) {
                u8      ledclr_mask = LEDEN_LEDAON | LEDEN_LEDAEXT
                                | LEDEN_LEDAPWM | LEDEN_PWM_LENGTHA;
 -              u8      module = TWL4030_MODULE_PWMA;
 +              u8      reg = TWL4030_PWMAON_REG;
  
                offset -= TWL4030_GPIO_MAX;
                if (offset) {
                        ledclr_mask <<= 1;
 -                      module = TWL4030_MODULE_PWMB;
 +                      reg = TWL4030_PWMBON_REG;
                }
  
                /* initialize PWM to always-drive */
 -              status = twl_i2c_write_u8(module, 0x7f,
 -                              TWL4030_PWMx_PWMxOFF);
 +              /* Configure PWM OFF register first */
 +              status = twl_i2c_write_u8(TWL4030_MODULE_LED, 0x7f, reg + 1);
                if (status < 0)
                        goto done;
 -              status = twl_i2c_write_u8(module, 0x7f,
 -                              TWL4030_PWMx_PWMxON);
 +
 +              /* Followed by PWM ON register */
 +              status = twl_i2c_write_u8(TWL4030_MODULE_LED, 0x7f, reg);
                if (status < 0)
                        goto done;
  
                /* init LED to not-driven (high) */
 -              module = TWL4030_MODULE_LED;
 -              status = twl_i2c_read_u8(module, &cached_leden,
 -                              TWL4030_LED_LEDEN);
 +              status = twl_i2c_read_u8(TWL4030_MODULE_LED, &cached_leden,
 +                                       TWL4030_LED_LEDEN_REG);
                if (status < 0)
                        goto done;
                cached_leden &= ~ledclr_mask;
 -              status = twl_i2c_write_u8(module, cached_leden,
 -                              TWL4030_LED_LEDEN);
 +              status = twl_i2c_write_u8(TWL4030_MODULE_LED, cached_leden,
 +                                        TWL4030_LED_LEDEN_REG);
                if (status < 0)
                        goto done;
  
@@@ -353,15 -352,15 +353,15 @@@ static struct gpio_chip twl_gpiochip = 
  
  /*----------------------------------------------------------------------*/
  
 -static int __devinit gpio_twl4030_pulls(u32 ups, u32 downs)
 +static int gpio_twl4030_pulls(u32 ups, u32 downs)
  {
-       u8              message[6];
+       u8              message[5];
        unsigned        i, gpio_bit;
  
        /* For most pins, a pulldown was enabled by default.
         * We should have data that's specific to this board.
         */
-       for (gpio_bit = 1, i = 1; i < 6; i++) {
+       for (gpio_bit = 1, i = 0; i < 5; i++) {
                u8              bit_mask;
                unsigned        j;
  
                                REG_GPIOPUPDCTR1, 5);
  }
  
 -static int __devinit gpio_twl4030_debounce(u32 debounce, u8 mmc_cd)
 +static int gpio_twl4030_debounce(u32 debounce, u8 mmc_cd)
  {
-       u8              message[4];
+       u8              message[3];
  
        /* 30 msec of debouncing is always used for MMC card detect,
         * and is optional for everything else.
         */
-       message[1] = (debounce & 0xff) | (mmc_cd & 0x03);
+       message[0] = (debounce & 0xff) | (mmc_cd & 0x03);
        debounce >>= 8;
-       message[2] = (debounce & 0xff);
+       message[1] = (debounce & 0xff);
        debounce >>= 8;
-       message[3] = (debounce & 0x03);
+       message[2] = (debounce & 0x03);
  
        return twl_i2c_write(TWL4030_MODULE_GPIO, message,
                                REG_GPIO_DEBEN1, 3);
@@@ -420,7 -419,7 +420,7 @@@ static struct twl4030_gpio_platform_dat
        return omap_twl_info;
  }
  
 -static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
 +static int gpio_twl4030_probe(struct platform_device *pdev)
  {
        struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
        struct device_node *node = pdev->dev.of_node;
@@@ -506,7 -505,7 +506,7 @@@ out
        return ret;
  }
  
 -/* Cannot use __devexit as gpio_twl4030_probe() calls us */
 +/* Cannot use as gpio_twl4030_probe() calls us */
  static int gpio_twl4030_remove(struct platform_device *pdev)
  {
        struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
diff --combined drivers/iio/adc/Kconfig
index 961b8d0a4bacbc3c986d9bdeeb2fc6347632fc22,bb3053739c806c41464a22cb782a36db460152fd..fe822a14d13073917f102a0d6bc82764e7e51d92
@@@ -18,18 -18,6 +18,18 @@@ config AD726
          Say yes here to build support for Analog Devices AD7265 and AD7266
          ADCs.
  
 +config AD7298
 +      tristate "Analog Devices AD7298 ADC driver"
 +      depends on SPI
 +      select IIO_BUFFER
 +      select IIO_TRIGGERED_BUFFER
 +      help
 +        Say yes here to build support for Analog Devices AD7298
 +        8 Channel ADC with temperature sensor.
 +
 +        To compile this driver as a module, choose M here: the
 +        module will be called ad7298.
 +
  config AD7791
        tristate "Analog Devices AD7791 ADC driver"
        depends on SPI
          To compile this driver as a module, choose M here: the module will be
          called ad7791.
  
 +config AD7793
 +      tristate "Analog Devices AD7793 and similar ADCs driver"
 +      depends on SPI
 +      select AD_SIGMA_DELTA
 +      help
 +        Say yes here to build support for Analog Devices AD7785, AD7792, AD7793,
 +        AD7794 and AD7795 SPI analog to digital converters (ADC).
 +        If unsure, say N (but it's safe to say "Y").
 +
 +        To compile this driver as a module, choose M here: the
 +        module will be called AD7793.
 +
  config AD7476
        tristate "Analog Devices AD7476 and similar 1-channel ADCs driver"
        depends on SPI
          To compile this driver as a module, choose M here: the
          module will be called ad7476.
  
 +config AD7887
 +      tristate "Analog Devices AD7887 ADC driver"
 +      depends on SPI
 +      select IIO_BUFFER
 +      select IIO_TRIGGERED_BUFFER
 +      help
 +        Say yes here to build support for Analog Devices
 +        AD7887 SPI analog to digital converter (ADC).
 +        If unsure, say N (but it's safe to say "Y").
 +
 +        To compile this driver as a module, choose M here: the
 +        module will be called ad7887.
 +
  config AT91_ADC
        tristate "Atmel AT91 ADC"
        depends on ARCH_AT91
@@@ -97,32 -60,18 +97,46 @@@ config LP8788_AD
        help
          Say yes here to build support for TI LP8788 ADC.
  
 +config MAX1363
 +      tristate "Maxim max1363 ADC driver"
 +      depends on I2C
 +      select IIO_TRIGGER
 +      select MAX1363_RING_BUFFER
 +      select IIO_BUFFER
 +      select IIO_KFIFO_BUF
 +      help
 +        Say yes here to build support for many Maxim i2c analog to digital
 +        converters (ADC). (max1361, max1362, max1363, max1364, max1036,
 +        max1037, max1038, max1039, max1136, max1136, max1137, max1138,
 +        max1139, max1236, max1237, max11238, max1239, max11600, max11601,
 +        max11602, max11603, max11604, max11605, max11606, max11607,
 +        max11608, max11609, max11610, max11611, max11612, max11613,
 +        max11614, max11615, max11616, max11617, max11644, max11645,
 +        max11646, max11647) Provides direct access via sysfs and buffered
 +        data via the iio dev interface.
 +
 +config TI_ADC081C
 +      tristate "Texas Instruments ADC081C021/027"
 +      depends on I2C
 +      help
 +        If you say yes here you get support for Texas Instruments ADC081C021
 +        and ADC081C027 ADC chips.
 +
 +        This driver can also be built as a module. If so, the module will be
 +        called ti-adc081c.
 +
+ config TI_AM335X_ADC
+       tristate "TI's ADC driver"
+       depends on MFD_TI_AM335X_TSCADC
+       help
+         Say yes here to build support for Texas Instruments ADC
+         driver which is also a MFD client.
+ config VIPERBOARD_ADC
+       tristate "Viperboard ADC support"
+       depends on MFD_VIPERBOARD && USB
+       help
+         Say yes here to access the ADC part of the Nano River
+         Technologies Viperboard.
  endmenu
diff --combined drivers/iio/adc/Makefile
index 472fd7cd24174c5e056bd7bcb6907825a923e7f7,4268fa987fe672f35b57bdb5ff30f08e87baab9d..2d5f10080d8d5ca6b4c86b14e85375e6ef0759f6
@@@ -4,13 -4,9 +4,14 @@@
  
  obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o
  obj-$(CONFIG_AD7266) += ad7266.o
 +obj-$(CONFIG_AD7298) += ad7298.o
  obj-$(CONFIG_AD7476) += ad7476.o
  obj-$(CONFIG_AD7791) += ad7791.o
 +obj-$(CONFIG_AD7793) += ad7793.o
 +obj-$(CONFIG_AD7887) += ad7887.o
  obj-$(CONFIG_AT91_ADC) += at91_adc.o
  obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
 +obj-$(CONFIG_MAX1363) += max1363.o
 +obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
 -obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
+ obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
++obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
diff --combined drivers/mfd/Kconfig
index b63987c6ed200ec3ed447df7be2a0cdd6895d51b,50bbe88d1664bbc8e091cff0b76ec987593feb1b..1c0abd4dfc43eeef01bb096bb33e5a1bdc08ef5e
@@@ -104,6 -104,17 +104,17 @@@ config MFD_TI_SS
          To compile this driver as a module, choose M here: the
          module will be called ti-ssp.
  
+ config MFD_TI_AM335X_TSCADC
+       tristate "TI ADC / Touch Screen chip support"
+       select MFD_CORE
+       select REGMAP
+       select REGMAP_MMIO
+       help
+         If you say yes here you get support for Texas Instruments series
+         of Touch Screen /ADC chips.
+         To compile this driver as a module, choose M here: the
+         module will be called ti_am335x_tscadc.
  config HTC_EGPIO
        bool "HTC EGPIO support"
        depends on GENERIC_HARDIRQS && GPIOLIB && ARM
@@@ -211,6 -222,7 +222,6 @@@ config MFD_TPS6586
        depends on I2C=y && GENERIC_HARDIRQS
        select MFD_CORE
        select REGMAP_I2C
 -      depends on REGULATOR
        help
          If you say yes here you get support for the TPS6586X series of
          Power Management chips.
@@@ -253,6 -265,20 +264,20 @@@ config MFD_TPS65912_SP
          If you say yes here you get support for the TPS65912 series of
          PM chips with SPI interface.
  
+ config MFD_TPS80031
+       bool "TI TPS80031/TPS80032 Power Management chips"
+       depends on I2C=y && GENERIC_HARDIRQS
+       select MFD_CORE
+       select REGMAP_I2C
+       select REGMAP_IRQ
+       help
+         If you say yes here you get support for the Texas Instruments
+         TPS80031/ TPS80032 Fully Integrated Power Management with Power
+         Path and Battery Charger. The device provides five configurable
+         step-down converters, 11 general purpose LDOs, USB OTG Module,
+         ADC, RTC, 2 PWM, System Voltage Regulator/Battery Charger with
+         Power Path from USB, 32K clock generator.
  config MENELAUS
        bool "Texas Instruments TWL92330/Menelaus PM chip"
        depends on I2C=y && ARCH_OMAP2
@@@ -309,10 -335,10 +334,10 @@@ config MFD_TWL4030_AUDI
  
  config TWL6040_CORE
        bool "Support for TWL6040 audio codec"
-       depends on I2C=y && GENERIC_HARDIRQS
+       depends on I2C=y
        select MFD_CORE
        select REGMAP_I2C
-       select IRQ_DOMAIN
+       select REGMAP_IRQ
        default n
        help
          Say yes here if you want support for Texas Instruments TWL6040 audio
@@@ -990,6 -1016,7 +1015,7 @@@ config MFD_TPS6509
        depends on I2C=y && GENERIC_HARDIRQS
        select MFD_CORE
        select REGMAP_I2C
+       select REGMAP_IRQ
        help
          If you say yes here you get support for the TPS65090 series of
          Power Management chips.
@@@ -1034,6 -1061,7 +1060,7 @@@ config MFD_STA2X1
        bool "STA2X11 multi function device support"
        depends on STA2X11
        select MFD_CORE
+       select REGMAP_MMIO
  
  config MFD_SYSCON
        bool "System Controller Register R/W Based on Regmap"
@@@ -1053,6 -1081,38 +1080,38 @@@ config MFD_PALMA
          If you say yes here you get support for the Palmas
          series of PMIC chips from Texas Instruments.
  
+ config MFD_VIPERBOARD
+         tristate "Support for Nano River Technologies Viperboard"
+       select MFD_CORE
+       depends on USB
+       default n
+       help
+         Say yes here if you want support for Nano River Technologies
+         Viperboard.
+         There are mfd cell drivers available for i2c master, adc and
+         both gpios found on the board. The spi part does not yet
+         have a driver.
+         You need to select the mfd cell drivers separately.
+         The drivers do not support all features the board exposes.
+ config MFD_RETU
+       tristate "Support for Retu multi-function device"
+       select MFD_CORE
+       depends on I2C
+       select REGMAP_IRQ
+       help
+         Retu is a multi-function device found on Nokia Internet Tablets
+         (770, N800 and N810).
+ config MFD_AS3711
+       bool "Support for AS3711"
+       select MFD_CORE
+       select REGMAP_I2C
+       select REGMAP_IRQ
+       depends on I2C=y
+       help
+         Support for the AS3711 PMIC from AMS
  endmenu
  endif
  
@@@ -1079,9 -1139,3 +1138,9 @@@ config MCP_UCB1200_T
        depends on MCP_UCB1200 && INPUT
  
  endmenu
 +
 +config VEXPRESS_CONFIG
 +      bool
 +      help
 +        Platform configuration infrastructure for the ARM Ltd.
 +        Versatile Express.
diff --combined drivers/mfd/Makefile
index 69f260ae022507c178a3e205b411b73602285429,f2216dfd963c677cc586aaf80b4bb0df0fa0aa40..8b977f8045ae8f52cbc283838fa1cbfe375809f9
@@@ -19,6 -19,7 +19,7 @@@ obj-$(CONFIG_HTC_I2CPLD)      += htc-i2cpld.
  obj-$(CONFIG_MFD_DAVINCI_VOICECODEC)  += davinci_voicecodec.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_STA2X11)     += sta2x11-mfd.o
  obj-$(CONFIG_MFD_STMPE)               += stmpe.o
@@@ -55,18 -56,19 +56,19 @@@ obj-$(CONFIG_TPS6105X)             += tps6105x.
  obj-$(CONFIG_TPS65010)                += tps65010.o
  obj-$(CONFIG_TPS6507X)                += tps6507x.o
  obj-$(CONFIG_MFD_TPS65217)    += tps65217.o
- obj-$(CONFIG_MFD_TPS65910)    += tps65910.o tps65910-irq.o
+ obj-$(CONFIG_MFD_TPS65910)    += tps65910.o
  tps65912-objs                   := tps65912-core.o tps65912-irq.o
  obj-$(CONFIG_MFD_TPS65912)    += tps65912.o
  obj-$(CONFIG_MFD_TPS65912_I2C)        += tps65912-i2c.o
  obj-$(CONFIG_MFD_TPS65912_SPI)  += tps65912-spi.o
+ obj-$(CONFIG_MFD_TPS80031)    += tps80031.o
  obj-$(CONFIG_MENELAUS)                += menelaus.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_MFD_TWL4030_AUDIO)       += twl4030-audio.o
- obj-$(CONFIG_TWL6040_CORE)    += twl6040-core.o twl6040-irq.o
+ obj-$(CONFIG_TWL6040_CORE)    += twl6040.o
  
  obj-$(CONFIG_MFD_MC13XXX)     += mc13xxx-core.o
  obj-$(CONFIG_MFD_MC13XXX_SPI) += mc13xxx-spi.o
@@@ -89,6 -91,7 +91,7 @@@ obj-$(CONFIG_UCB1400_CORE)    += ucb1400_c
  
  obj-$(CONFIG_PMIC_DA903X)     += da903x.o
  
+ obj-$(CONFIG_PMIC_DA9052)     += da9052-irq.o
  obj-$(CONFIG_PMIC_DA9052)     += da9052-core.o
  obj-$(CONFIG_MFD_DA9052_SPI)  += da9052-spi.o
  obj-$(CONFIG_MFD_DA9052_I2C)  += da9052-i2c.o
@@@ -137,8 -140,10 +140,11 @@@ obj-$(CONFIG_MFD_TPS65090)       += tps65090.
  obj-$(CONFIG_MFD_AAT2870_CORE)        += aat2870-core.o
  obj-$(CONFIG_MFD_INTEL_MSIC)  += intel_msic.o
  obj-$(CONFIG_MFD_PALMAS)      += palmas.o
+ obj-$(CONFIG_MFD_VIPERBOARD)    += viperboard.o
  obj-$(CONFIG_MFD_RC5T583)     += rc5t583.o rc5t583-irq.o
  obj-$(CONFIG_MFD_SEC_CORE)    += sec-core.o sec-irq.o
  obj-$(CONFIG_MFD_SYSCON)      += syscon.o
  obj-$(CONFIG_MFD_LM3533)      += lm3533-core.o lm3533-ctrlbank.o
 +obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o vexpress-sysreg.o
+ obj-$(CONFIG_MFD_RETU)                += retu-mfd.o
+ obj-$(CONFIG_MFD_AS3711)      += as3711.o
index 59da1650fb814ea5c688f2c83051734d6bc2e8a7,660a09bf456401cf7f748e5c25c236ad022284bf..e1650badd106da6e3992b219e77fdc35e20ad1c8
@@@ -565,10 -565,15 +565,10 @@@ static int ab8500_irq_init(struct ab850
        else
                num_irqs = AB8500_NR_IRQS;
  
 -      if (ab8500->irq_base) {
 -              ab8500->domain = irq_domain_add_legacy(
 -                      NULL, num_irqs, ab8500->irq_base,
 -                      0, &ab8500_irq_ops, ab8500);
 -      }
 -      else {
 -              ab8500->domain = irq_domain_add_linear(
 -                      np, num_irqs, &ab8500_irq_ops, ab8500);
 -      }
 +      /* If ->irq_base is zero this will give a linear mapping */
 +      ab8500->domain = irq_domain_add_simple(NULL,
 +                      num_irqs, ab8500->irq_base,
 +                      &ab8500_irq_ops, ab8500);
  
        if (!ab8500->domain) {
                dev_err(ab8500->dev, "Failed to create irqdomain\n");
@@@ -586,39 -591,7 +586,7 @@@ int ab8500_suspend(struct ab8500 *ab850
                return 0;
  }
  
- /* AB8500 GPIO Resources */
- static struct resource __devinitdata ab8500_gpio_resources[] = {
-       {
-               .name   = "GPIO_INT6",
-               .start  = AB8500_INT_GPIO6R,
-               .end    = AB8500_INT_GPIO41F,
-               .flags  = IORESOURCE_IRQ,
-       }
- };
- /* AB9540 GPIO Resources */
- static struct resource __devinitdata ab9540_gpio_resources[] = {
-       {
-               .name   = "GPIO_INT6",
-               .start  = AB8500_INT_GPIO6R,
-               .end    = AB8500_INT_GPIO41F,
-               .flags  = IORESOURCE_IRQ,
-       },
-       {
-               .name   = "GPIO_INT14",
-               .start  = AB9540_INT_GPIO50R,
-               .end    = AB9540_INT_GPIO54R,
-               .flags  = IORESOURCE_IRQ,
-       },
-       {
-               .name   = "GPIO_INT15",
-               .start  = AB9540_INT_GPIO50F,
-               .end    = AB9540_INT_GPIO54F,
-               .flags  = IORESOURCE_IRQ,
-       }
- };
 -static struct resource __devinitdata ab8500_gpadc_resources[] = {
 +static struct resource ab8500_gpadc_resources[] = {
        {
                .name   = "HW_CONV_END",
                .start  = AB8500_INT_GP_HW_ADC_CONV_END,
        },
  };
  
 -static struct resource __devinitdata ab8500_rtc_resources[] = {
 +static struct resource ab8500_rtc_resources[] = {
        {
                .name   = "60S",
                .start  = AB8500_INT_RTC_60S,
        },
  };
  
 -static struct resource __devinitdata ab8500_poweronkey_db_resources[] = {
 +static struct resource ab8500_poweronkey_db_resources[] = {
        {
                .name   = "ONKEY_DBF",
                .start  = AB8500_INT_PON_KEY1DB_F,
        },
  };
  
 -static struct resource __devinitdata ab8500_av_acc_detect_resources[] = {
 +static struct resource ab8500_av_acc_detect_resources[] = {
        {
               .name = "ACC_DETECT_1DB_F",
               .start = AB8500_INT_ACC_DETECT_1DB_F,
        },
  };
  
 -static struct resource __devinitdata ab8500_charger_resources[] = {
 +static struct resource ab8500_charger_resources[] = {
        {
                .name = "MAIN_CH_UNPLUG_DET",
                .start = AB8500_INT_MAIN_CH_UNPLUG_DET,
        },
  };
  
 -static struct resource __devinitdata ab8500_btemp_resources[] = {
 +static struct resource ab8500_btemp_resources[] = {
        {
                .name = "BAT_CTRL_INDB",
                .start = AB8500_INT_BAT_CTRL_INDB,
        },
  };
  
 -static struct resource __devinitdata ab8500_fg_resources[] = {
 +static struct resource ab8500_fg_resources[] = {
        {
                .name = "NCONV_ACCU",
                .start = AB8500_INT_CCN_CONV_ACC,
        },
  };
  
 -static struct resource __devinitdata ab8500_chargalg_resources[] = {};
 +static struct resource ab8500_chargalg_resources[] = {};
  
  #ifdef CONFIG_DEBUG_FS
 -static struct resource __devinitdata ab8500_debug_resources[] = {
 +static struct resource ab8500_debug_resources[] = {
        {
                .name   = "IRQ_FIRST",
                .start  = AB8500_INT_MAIN_EXT_CH_NOT_OK,
  };
  #endif
  
 -static struct resource __devinitdata ab8500_usb_resources[] = {
 +static struct resource ab8500_usb_resources[] = {
        {
                .name = "ID_WAKEUP_R",
                .start = AB8500_INT_ID_WAKEUP_R,
        },
  };
  
 -static struct resource __devinitdata ab8505_iddet_resources[] = {
 +static struct resource ab8505_iddet_resources[] = {
        {
                .name  = "KeyDeglitch",
                .start = AB8505_INT_KEYDEGLITCH,
        },
  };
  
 -static struct resource __devinitdata ab8500_temp_resources[] = {
 +static struct resource ab8500_temp_resources[] = {
        {
                .name  = "AB8500_TEMP_WARM",
                .start = AB8500_INT_TEMP_WARM,
        },
  };
  
 -static struct mfd_cell __devinitdata abx500_common_devs[] = {
 +static struct mfd_cell abx500_common_devs[] = {
  #ifdef CONFIG_DEBUG_FS
        {
                .name = "ab8500-debug",
                .name = "ab8500-regulator",
                .of_compatible = "stericsson,ab8500-regulator",
        },
+       {
+               .name = "abx500-clk",
+               .of_compatible = "stericsson,abx500-clk",
+       },
        {
                .name = "ab8500-gpadc",
                .of_compatible = "stericsson,ab8500-gpadc",
        },
  };
  
 -static struct mfd_cell __devinitdata ab8500_bm_devs[] = {
 +static struct mfd_cell ab8500_bm_devs[] = {
        {
                .name = "ab8500-charger",
 +              .of_compatible = "stericsson,ab8500-charger",
                .num_resources = ARRAY_SIZE(ab8500_charger_resources),
                .resources = ab8500_charger_resources,
 +#ifndef CONFIG_OF
 +              .platform_data = &ab8500_bm_data,
 +              .pdata_size = sizeof(ab8500_bm_data),
 +#endif
        },
        {
                .name = "ab8500-btemp",
 +              .of_compatible = "stericsson,ab8500-btemp",
                .num_resources = ARRAY_SIZE(ab8500_btemp_resources),
                .resources = ab8500_btemp_resources,
 +#ifndef CONFIG_OF
 +              .platform_data = &ab8500_bm_data,
 +              .pdata_size = sizeof(ab8500_bm_data),
 +#endif
        },
        {
                .name = "ab8500-fg",
 +              .of_compatible = "stericsson,ab8500-fg",
                .num_resources = ARRAY_SIZE(ab8500_fg_resources),
                .resources = ab8500_fg_resources,
 +#ifndef CONFIG_OF
 +              .platform_data = &ab8500_bm_data,
 +              .pdata_size = sizeof(ab8500_bm_data),
 +#endif
        },
        {
                .name = "ab8500-chargalg",
 +              .of_compatible = "stericsson,ab8500-chargalg",
                .num_resources = ARRAY_SIZE(ab8500_chargalg_resources),
                .resources = ab8500_chargalg_resources,
 +#ifndef CONFIG_OF
 +              .platform_data = &ab8500_bm_data,
 +              .pdata_size = sizeof(ab8500_bm_data),
 +#endif
        },
  };
  
 -static struct mfd_cell __devinitdata ab8500_devs[] = {
 +static struct mfd_cell ab8500_devs[] = {
        {
                .name = "ab8500-gpio",
                .of_compatible = "stericsson,ab8500-gpio",
-               .num_resources = ARRAY_SIZE(ab8500_gpio_resources),
-               .resources = ab8500_gpio_resources,
        },
        {
                .name = "ab8500-usb",
        },
  };
  
 -static struct mfd_cell __devinitdata ab9540_devs[] = {
 +static struct mfd_cell ab9540_devs[] = {
        {
                .name = "ab8500-gpio",
-               .num_resources = ARRAY_SIZE(ab9540_gpio_resources),
-               .resources = ab9540_gpio_resources,
        },
        {
                .name = "ab9540-usb",
  };
  
  /* Device list common to ab9540 and ab8505 */
 -static struct mfd_cell __devinitdata ab9540_ab8505_devs[] = {
 +static struct mfd_cell ab9540_ab8505_devs[] = {
        {
                .name = "ab-iddet",
                .num_resources = ARRAY_SIZE(ab8505_iddet_resources),
@@@ -1263,7 -1216,7 +1231,7 @@@ static struct attribute_group ab9540_at
        .attrs  = ab9540_sysfs_entries,
  };
  
 -static int __devinit ab8500_probe(struct platform_device *pdev)
 +static int ab8500_probe(struct platform_device *pdev)
  {
        static char *switch_off_status[] = {
                "Swoff bit programming",
        int i;
        u8 value;
  
-       ab8500 = kzalloc(sizeof *ab8500, GFP_KERNEL);
+       ab8500 = devm_kzalloc(&pdev->dev, sizeof *ab8500, GFP_KERNEL);
        if (!ab8500)
                return -ENOMEM;
  
        ab8500->dev = &pdev->dev;
  
        resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       if (!resource) {
-               ret = -ENODEV;
-               goto out_free_ab8500;
-       }
+       if (!resource)
+               return -ENODEV;
  
        ab8500->irq = resource->start;
  
                ret = get_register_interruptible(ab8500, AB8500_MISC,
                        AB8500_IC_NAME_REG, &value);
                if (ret < 0)
-                       goto out_free_ab8500;
+                       return ret;
  
                ab8500->version = value;
        }
        ret = get_register_interruptible(ab8500, AB8500_MISC,
                AB8500_REV_REG, &value);
        if (ret < 0)
-               goto out_free_ab8500;
+               return ret;
  
        ab8500->chip_id = value;
  
                ab8500->mask_size = AB8500_NUM_IRQ_REGS;
                ab8500->irq_reg_offset = ab8500_irq_regoffset;
        }
-       ab8500->mask = kzalloc(ab8500->mask_size, GFP_KERNEL);
+       ab8500->mask = devm_kzalloc(&pdev->dev, ab8500->mask_size, GFP_KERNEL);
        if (!ab8500->mask)
                return -ENOMEM;
-       ab8500->oldmask = kzalloc(ab8500->mask_size, GFP_KERNEL);
-       if (!ab8500->oldmask) {
-               ret = -ENOMEM;
-               goto out_freemask;
-       }
+       ab8500->oldmask = devm_kzalloc(&pdev->dev, ab8500->mask_size, GFP_KERNEL);
+       if (!ab8500->oldmask)
+               return -ENOMEM;
        /*
         * ab8500 has switched off due to (SWITCH_OFF_STATUS):
         * 0x01 Swoff bit programming
  
        ret = abx500_register_ops(ab8500->dev, &ab8500_ops);
        if (ret)
-               goto out_freeoldmask;
+               return ret;
  
        for (i = 0; i < ab8500->mask_size; i++)
                ab8500->mask[i] = ab8500->oldmask[i] = 0xff;
  
        ret = ab8500_irq_init(ab8500, np);
        if (ret)
-               goto out_freeoldmask;
+               return ret;
  
        /*  Activate this feature only in ab9540 */
        /*  till tests are done on ab8500 1p2 or later*/
        if (is_ab9540(ab8500)) {
-               ret = request_threaded_irq(ab8500->irq, NULL,
-                                       ab8500_hierarchical_irq,
-                                       IRQF_ONESHOT | IRQF_NO_SUSPEND,
-                                       "ab8500", ab8500);
+               ret = devm_request_threaded_irq(&pdev->dev, ab8500->irq, NULL,
+                                               ab8500_hierarchical_irq,
+                                               IRQF_ONESHOT | IRQF_NO_SUSPEND,
+                                               "ab8500", ab8500);
        }
        else {
-               ret = request_threaded_irq(ab8500->irq, NULL,
-                                       ab8500_irq,
-                                       IRQF_ONESHOT | IRQF_NO_SUSPEND,
-                                       "ab8500", ab8500);
+               ret = devm_request_threaded_irq(&pdev->dev, ab8500->irq, NULL,
+                                               ab8500_irq,
+                                               IRQF_ONESHOT | IRQF_NO_SUSPEND,
+                                               "ab8500", ab8500);
                if (ret)
-                       goto out_freeoldmask;
+                       return ret;
        }
  
        ret = mfd_add_devices(ab8500->dev, 0, abx500_common_devs,
                        ARRAY_SIZE(abx500_common_devs), NULL,
                        ab8500->irq_base, ab8500->domain);
        if (ret)
-               goto out_freeirq;
+               return ret;
  
        if (is_ab9540(ab8500))
                ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs,
                                ARRAY_SIZE(ab8500_devs), NULL,
                                ab8500->irq_base, ab8500->domain);
        if (ret)
-               goto out_freeirq;
+               return ret;
  
        if (is_ab9540(ab8500) || is_ab8505(ab8500))
                ret = mfd_add_devices(ab8500->dev, 0, ab9540_ab8505_devs,
                                ARRAY_SIZE(ab9540_ab8505_devs), NULL,
                                ab8500->irq_base, ab8500->domain);
        if (ret)
-               goto out_freeirq;
+               return ret;
  
        if (!no_bm) {
                /* Add battery management devices */
                dev_err(ab8500->dev, "error creating sysfs entries\n");
  
        return ret;
- out_freeirq:
-       free_irq(ab8500->irq, ab8500);
- out_freeoldmask:
-       kfree(ab8500->oldmask);
- out_freemask:
-       kfree(ab8500->mask);
- out_free_ab8500:
-       kfree(ab8500);
-       return ret;
  }
  
 -static int __devexit ab8500_remove(struct platform_device *pdev)
 +static int ab8500_remove(struct platform_device *pdev)
  {
        struct ab8500 *ab8500 = platform_get_drvdata(pdev);
  
                sysfs_remove_group(&ab8500->dev->kobj, &ab8500_attr_group);
  
        mfd_remove_devices(ab8500->dev);
-       free_irq(ab8500->irq, ab8500);
-       kfree(ab8500->oldmask);
-       kfree(ab8500->mask);
-       kfree(ab8500);
  
        return 0;
  }
@@@ -1521,7 -1455,7 +1470,7 @@@ static struct platform_driver ab8500_co
                .owner = THIS_MODULE,
        },
        .probe  = ab8500_probe,
 -      .remove = __devexit_p(ab8500_remove),
 +      .remove = ab8500_remove,
        .id_table = ab8500_id,
  };
  
index c784f4602a746c8d4eec1d8c4383ed4cae0a8df6,f59773da8adfee7292de01e61d007b14e39ee226..bc8a3edb6bbf2b2fdc9c3f15a425eafb0bcb23af
@@@ -96,11 -96,11 +96,11 @@@ static irqreturn_t arizona_underclocked
                return IRQ_NONE;
        }
  
 -      if (val & ARIZONA_AIF3_UNDERCLOCKED_STS)
 -              dev_err(arizona->dev, "AIF3 underclocked\n");
        if (val & ARIZONA_AIF3_UNDERCLOCKED_STS)
                dev_err(arizona->dev, "AIF3 underclocked\n");
        if (val & ARIZONA_AIF2_UNDERCLOCKED_STS)
 +              dev_err(arizona->dev, "AIF2 underclocked\n");
 +      if (val & ARIZONA_AIF1_UNDERCLOCKED_STS)
                dev_err(arizona->dev, "AIF1 underclocked\n");
        if (val & ARIZONA_ISRC2_UNDERCLOCKED_STS)
                dev_err(arizona->dev, "ISRC2 underclocked\n");
@@@ -287,11 -287,12 +287,12 @@@ static struct mfd_cell wm5110_devs[] = 
        { .name = "wm5110-codec" },
  };
  
 -int __devinit arizona_dev_init(struct arizona *arizona)
 +int arizona_dev_init(struct arizona *arizona)
  {
        struct device *dev = arizona->dev;
        const char *type_name;
        unsigned int reg, val;
+       int (*apply_patch)(struct arizona *) = NULL;
        int ret, i;
  
        dev_set_drvdata(arizona->dev, arizona);
                                arizona->type);
                        arizona->type = WM5102;
                }
-               ret = wm5102_patch(arizona);
+               apply_patch = wm5102_patch;
                break;
  #endif
  #ifdef CONFIG_MFD_WM5110
                                arizona->type);
                        arizona->type = WM5110;
                }
-               ret = wm5110_patch(arizona);
+               apply_patch = wm5110_patch;
                break;
  #endif
        default:
  
        dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A');
  
-       if (ret != 0)
-               dev_err(arizona->dev, "Failed to apply patch: %d\n", ret);
        /* If we have a /RESET GPIO we'll already be reset */
        if (!arizona->pdata.reset) {
 +              regcache_mark_dirty(arizona->regmap);
 +
                ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0);
                if (ret != 0) {
                        dev_err(dev, "Failed to reset device: %d\n", ret);
                        goto err_reset;
                }
 +
 +              ret = regcache_sync(arizona->regmap);
 +              if (ret != 0) {
 +                      dev_err(dev, "Failed to sync device: %d\n", ret);
 +                      goto err_reset;
 +              }
        }
  
        ret = arizona_wait_for_boot(arizona);
                goto err_reset;
        }
  
+       if (apply_patch) {
+               ret = apply_patch(arizona);
+               if (ret != 0) {
+                       dev_err(arizona->dev, "Failed to apply patch: %d\n",
+                               ret);
+                       goto err_reset;
+               }
+       }
        for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
                if (!arizona->pdata.gpio_defaults[i])
                        continue;
                break;
        case WM5110:
                ret = mfd_add_devices(arizona->dev, -1, wm5110_devs,
 -                                    ARRAY_SIZE(wm5102_devs), NULL, 0, NULL);
 +                                    ARRAY_SIZE(wm5110_devs), NULL, 0, NULL);
                break;
        }
  
@@@ -563,7 -562,7 +570,7 @@@ err_early
  }
  EXPORT_SYMBOL_GPL(arizona_dev_init);
  
 -int __devexit arizona_dev_exit(struct arizona *arizona)
 +int arizona_dev_exit(struct arizona *arizona)
  {
        mfd_remove_devices(arizona->dev);
        arizona_free_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, arizona);
index b1b0091774055213c6b0a573f4075b8ebb7af5d9,7db56ab475941d658917216966ad6b07b2c1b977..74713bf5371fa42361dbb2342407c0dfe9c039b6
@@@ -178,7 -178,6 +178,7 @@@ int arizona_irq_init(struct arizona *ar
  
                switch (arizona->rev) {
                case 0:
 +              case 1:
                        ctrlif_error = false;
                        break;
                default:
        arizona->virq = irq_domain_add_linear(NULL, 2, &arizona_domain_ops,
                                              arizona);
        if (!arizona->virq) {
+               dev_err(arizona->dev, "Failed to add core IRQ domain\n");
                ret = -EINVAL;
                goto err;
        }
index 689b747416af7cd92933e4fe261e7f20a398d5db,2153f9bba9ef43177f830c4d6152f490a7b328de..a3c9613f91664e87ae03f4496c3360df74c755ef
@@@ -15,7 -15,6 +15,6 @@@
  #include <linux/delay.h>
  #include <linux/input.h>
  #include <linux/interrupt.h>
- #include <linux/irq.h>
  #include <linux/mfd/core.h>
  #include <linux/slab.h>
  #include <linux/module.h>
  #include <linux/mfd/da9052/pdata.h>
  #include <linux/mfd/da9052/reg.h>
  
- #define DA9052_NUM_IRQ_REGS           4
- #define DA9052_IRQ_MASK_POS_1         0x01
- #define DA9052_IRQ_MASK_POS_2         0x02
- #define DA9052_IRQ_MASK_POS_3         0x04
- #define DA9052_IRQ_MASK_POS_4         0x08
- #define DA9052_IRQ_MASK_POS_5         0x10
- #define DA9052_IRQ_MASK_POS_6         0x20
- #define DA9052_IRQ_MASK_POS_7         0x40
- #define DA9052_IRQ_MASK_POS_8         0x80
  static bool da9052_reg_readable(struct device *dev, unsigned int reg)
  {
        switch (reg) {
@@@ -425,15 -414,6 +414,6 @@@ err
  }
  EXPORT_SYMBOL_GPL(da9052_adc_manual_read);
  
- static irqreturn_t da9052_auxadc_irq(int irq, void *irq_data)
- {
-       struct da9052 *da9052 = irq_data;
-       complete(&da9052->done);
-       return IRQ_HANDLED;
- }
  int da9052_adc_read_temp(struct da9052 *da9052)
  {
        int tbat;
  }
  EXPORT_SYMBOL_GPL(da9052_adc_read_temp);
  
- static struct resource da9052_rtc_resource = {
-       .name = "ALM",
-       .start = DA9052_IRQ_ALARM,
-       .end   = DA9052_IRQ_ALARM,
-       .flags = IORESOURCE_IRQ,
- };
- static struct resource da9052_onkey_resource = {
-       .name = "ONKEY",
-       .start = DA9052_IRQ_NONKEY,
-       .end   = DA9052_IRQ_NONKEY,
-       .flags = IORESOURCE_IRQ,
- };
- static struct resource da9052_bat_resources[] = {
-       {
-               .name = "BATT TEMP",
-               .start = DA9052_IRQ_TBAT,
-               .end   = DA9052_IRQ_TBAT,
-               .flags = IORESOURCE_IRQ,
-       },
-       {
-               .name = "DCIN DET",
-               .start = DA9052_IRQ_DCIN,
-               .end   = DA9052_IRQ_DCIN,
-               .flags = IORESOURCE_IRQ,
-       },
-       {
-               .name = "DCIN REM",
-               .start = DA9052_IRQ_DCINREM,
-               .end   = DA9052_IRQ_DCINREM,
-               .flags = IORESOURCE_IRQ,
-       },
-       {
-               .name = "VBUS DET",
-               .start = DA9052_IRQ_VBUS,
-               .end   = DA9052_IRQ_VBUS,
-               .flags = IORESOURCE_IRQ,
-       },
-       {
-               .name = "VBUS REM",
-               .start = DA9052_IRQ_VBUSREM,
-               .end   = DA9052_IRQ_VBUSREM,
-               .flags = IORESOURCE_IRQ,
-       },
-       {
-               .name = "CHG END",
-               .start = DA9052_IRQ_CHGEND,
-               .end   = DA9052_IRQ_CHGEND,
-               .flags = IORESOURCE_IRQ,
-       },
- };
- static struct resource da9052_tsi_resources[] = {
-       {
-               .name = "PENDWN",
-               .start = DA9052_IRQ_PENDOWN,
-               .end   = DA9052_IRQ_PENDOWN,
-               .flags = IORESOURCE_IRQ,
-       },
-       {
-               .name = "TSIRDY",
-               .start = DA9052_IRQ_TSIREADY,
-               .end   = DA9052_IRQ_TSIREADY,
-               .flags = IORESOURCE_IRQ,
-       },
- };
 -static struct mfd_cell __devinitdata da9052_subdev_info[] = {
 +static struct mfd_cell da9052_subdev_info[] = {
        {
                .name = "da9052-regulator",
                .id = 1,
        },
        {
                .name = "da9052-onkey",
-               .resources = &da9052_onkey_resource,
-               .num_resources = 1,
        },
        {
                .name = "da9052-rtc",
-               .resources = &da9052_rtc_resource,
-               .num_resources = 1,
        },
        {
                .name = "da9052-gpio",
        },
        {
                .name = "da9052-tsi",
-               .resources = da9052_tsi_resources,
-               .num_resources = ARRAY_SIZE(da9052_tsi_resources),
        },
        {
                .name = "da9052-bat",
-               .resources = da9052_bat_resources,
-               .num_resources = ARRAY_SIZE(da9052_bat_resources),
        },
        {
                .name = "da9052-watchdog",
        },
  };
  
- static struct regmap_irq da9052_irqs[] = {
-       [DA9052_IRQ_DCIN] = {
-               .reg_offset = 0,
-               .mask = DA9052_IRQ_MASK_POS_1,
-       },
-       [DA9052_IRQ_VBUS] = {
-               .reg_offset = 0,
-               .mask = DA9052_IRQ_MASK_POS_2,
-       },
-       [DA9052_IRQ_DCINREM] = {
-               .reg_offset = 0,
-               .mask = DA9052_IRQ_MASK_POS_3,
-       },
-       [DA9052_IRQ_VBUSREM] = {
-               .reg_offset = 0,
-               .mask = DA9052_IRQ_MASK_POS_4,
-       },
-       [DA9052_IRQ_VDDLOW] = {
-               .reg_offset = 0,
-               .mask = DA9052_IRQ_MASK_POS_5,
-       },
-       [DA9052_IRQ_ALARM] = {
-               .reg_offset = 0,
-               .mask = DA9052_IRQ_MASK_POS_6,
-       },
-       [DA9052_IRQ_SEQRDY] = {
-               .reg_offset = 0,
-               .mask = DA9052_IRQ_MASK_POS_7,
-       },
-       [DA9052_IRQ_COMP1V2] = {
-               .reg_offset = 0,
-               .mask = DA9052_IRQ_MASK_POS_8,
-       },
-       [DA9052_IRQ_NONKEY] = {
-               .reg_offset = 1,
-               .mask = DA9052_IRQ_MASK_POS_1,
-       },
-       [DA9052_IRQ_IDFLOAT] = {
-               .reg_offset = 1,
-               .mask = DA9052_IRQ_MASK_POS_2,
-       },
-       [DA9052_IRQ_IDGND] = {
-               .reg_offset = 1,
-               .mask = DA9052_IRQ_MASK_POS_3,
-       },
-       [DA9052_IRQ_CHGEND] = {
-               .reg_offset = 1,
-               .mask = DA9052_IRQ_MASK_POS_4,
-       },
-       [DA9052_IRQ_TBAT] = {
-               .reg_offset = 1,
-               .mask = DA9052_IRQ_MASK_POS_5,
-       },
-       [DA9052_IRQ_ADC_EOM] = {
-               .reg_offset = 1,
-               .mask = DA9052_IRQ_MASK_POS_6,
-       },
-       [DA9052_IRQ_PENDOWN] = {
-               .reg_offset = 1,
-               .mask = DA9052_IRQ_MASK_POS_7,
-       },
-       [DA9052_IRQ_TSIREADY] = {
-               .reg_offset = 1,
-               .mask = DA9052_IRQ_MASK_POS_8,
-       },
-       [DA9052_IRQ_GPI0] = {
-               .reg_offset = 2,
-               .mask = DA9052_IRQ_MASK_POS_1,
-       },
-       [DA9052_IRQ_GPI1] = {
-               .reg_offset = 2,
-               .mask = DA9052_IRQ_MASK_POS_2,
-       },
-       [DA9052_IRQ_GPI2] = {
-               .reg_offset = 2,
-               .mask = DA9052_IRQ_MASK_POS_3,
-       },
-       [DA9052_IRQ_GPI3] = {
-               .reg_offset = 2,
-               .mask = DA9052_IRQ_MASK_POS_4,
-       },
-       [DA9052_IRQ_GPI4] = {
-               .reg_offset = 2,
-               .mask = DA9052_IRQ_MASK_POS_5,
-       },
-       [DA9052_IRQ_GPI5] = {
-               .reg_offset = 2,
-               .mask = DA9052_IRQ_MASK_POS_6,
-       },
-       [DA9052_IRQ_GPI6] = {
-               .reg_offset = 2,
-               .mask = DA9052_IRQ_MASK_POS_7,
-       },
-       [DA9052_IRQ_GPI7] = {
-               .reg_offset = 2,
-               .mask = DA9052_IRQ_MASK_POS_8,
-       },
-       [DA9052_IRQ_GPI8] = {
-               .reg_offset = 3,
-               .mask = DA9052_IRQ_MASK_POS_1,
-       },
-       [DA9052_IRQ_GPI9] = {
-               .reg_offset = 3,
-               .mask = DA9052_IRQ_MASK_POS_2,
-       },
-       [DA9052_IRQ_GPI10] = {
-               .reg_offset = 3,
-               .mask = DA9052_IRQ_MASK_POS_3,
-       },
-       [DA9052_IRQ_GPI11] = {
-               .reg_offset = 3,
-               .mask = DA9052_IRQ_MASK_POS_4,
-       },
-       [DA9052_IRQ_GPI12] = {
-               .reg_offset = 3,
-               .mask = DA9052_IRQ_MASK_POS_5,
-       },
-       [DA9052_IRQ_GPI13] = {
-               .reg_offset = 3,
-               .mask = DA9052_IRQ_MASK_POS_6,
-       },
-       [DA9052_IRQ_GPI14] = {
-               .reg_offset = 3,
-               .mask = DA9052_IRQ_MASK_POS_7,
-       },
-       [DA9052_IRQ_GPI15] = {
-               .reg_offset = 3,
-               .mask = DA9052_IRQ_MASK_POS_8,
-       },
- };
- static struct regmap_irq_chip da9052_regmap_irq_chip = {
-       .name = "da9052_irq",
-       .status_base = DA9052_EVENT_A_REG,
-       .mask_base = DA9052_IRQ_MASK_A_REG,
-       .ack_base = DA9052_EVENT_A_REG,
-       .num_regs = DA9052_NUM_IRQ_REGS,
-       .irqs = da9052_irqs,
-       .num_irqs = ARRAY_SIZE(da9052_irqs),
- };
  struct regmap_config da9052_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
  };
  EXPORT_SYMBOL_GPL(da9052_regmap_config);
  
 -int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id)
 +int da9052_device_init(struct da9052 *da9052, u8 chip_id)
  {
        struct da9052_pdata *pdata = da9052->dev->platform_data;
        int ret;
  
        da9052->chip_id = chip_id;
  
-       if (!pdata || !pdata->irq_base)
-               da9052->irq_base = -1;
-       else
-               da9052->irq_base = pdata->irq_base;
-       ret = regmap_add_irq_chip(da9052->regmap, da9052->chip_irq,
-                                 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
-                                 da9052->irq_base, &da9052_regmap_irq_chip,
-                                 &da9052->irq_data);
-       if (ret < 0)
-               goto regmap_err;
-       da9052->irq_base = regmap_irq_chip_get_base(da9052->irq_data);
-       ret = request_threaded_irq(DA9052_IRQ_ADC_EOM, NULL, da9052_auxadc_irq,
-                                  IRQF_TRIGGER_LOW | IRQF_ONESHOT,
-                                  "adc irq", da9052);
-       if (ret != 0)
-               dev_err(da9052->dev, "DA9052 ADC IRQ failed ret=%d\n", ret);
+       ret = da9052_irq_init(da9052);
+       if (ret != 0) {
+               dev_err(da9052->dev, "da9052_irq_init failed: %d\n", ret);
+               return ret;
+       }
  
        ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info,
                              ARRAY_SIZE(da9052_subdev_info), NULL, 0, NULL);
-       if (ret)
+       if (ret) {
+               dev_err(da9052->dev, "mfd_add_devices failed: %d\n", ret);
                goto err;
+       }
  
        return 0;
  
  err:
-       free_irq(DA9052_IRQ_ADC_EOM, da9052);
-       mfd_remove_devices(da9052->dev);
- regmap_err:
+       da9052_irq_exit(da9052);
        return ret;
  }
  
  void da9052_device_exit(struct da9052 *da9052)
  {
-       free_irq(DA9052_IRQ_ADC_EOM, da9052);
-       regmap_del_irq_chip(da9052->chip_irq, da9052->irq_data);
        mfd_remove_devices(da9052->dev);
+       da9052_irq_exit(da9052);
  }
  
  MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
index 29710565a08fca94ce90ac4f3f2feaba843276f1,c56ceddf85810fecb7e37987bdee286f60019fce..dc8826d8d69da0d1ee8c29911dc6c95ade7f1da2
@@@ -31,7 -31,6 +31,7 @@@
  #include <linux/mfd/abx500/ab8500.h>
  #include <linux/regulator/db8500-prcmu.h>
  #include <linux/regulator/machine.h>
 +#include <linux/cpufreq.h>
  #include <asm/hardware/gic.h>
  #include <mach/hardware.h>
  #include <mach/irqs.h>
@@@ -421,6 -420,9 +421,6 @@@ static struct 
  
  static atomic_t ac_wake_req_state = ATOMIC_INIT(0);
  
 -/* Functions definition */
 -static void compute_armss_rate(void);
 -
  /* Spinlocks */
  static DEFINE_SPINLOCK(prcmu_lock);
  static DEFINE_SPINLOCK(clkout_lock);
@@@ -1017,6 -1019,7 +1017,6 @@@ int db8500_prcmu_set_arm_opp(u8 opp
                (mb1_transfer.ack.arm_opp != opp))
                r = -EIO;
  
 -      compute_armss_rate();
        mutex_unlock(&mb1_transfer.lock);
  
        return r;
@@@ -1166,12 -1169,12 +1166,12 @@@ int db8500_prcmu_get_ape_opp(void
  }
  
  /**
 - * prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage
 + * db8500_prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage
   * @enable: true to request the higher voltage, false to drop a request.
   *
   * Calls to this function to enable and disable requests must be balanced.
   */
 -int prcmu_request_ape_opp_100_voltage(bool enable)
 +int db8500_prcmu_request_ape_opp_100_voltage(bool enable)
  {
        int r = 0;
        u8 header;
@@@ -1666,8 -1669,13 +1666,8 @@@ static unsigned long clock_rate(u8 cloc
        else
                return 0;
  }
 -static unsigned long latest_armss_rate;
 -static unsigned long armss_rate(void)
 -{
 -      return latest_armss_rate;
 -}
  
 -static void compute_armss_rate(void)
 +static unsigned long armss_rate(void)
  {
        u32 r;
        unsigned long rate;
                rate = pll_rate(PRCM_PLLARM_FREQ, ROOT_CLOCK_RATE, PLL_DIV);
        }
  
 -      latest_armss_rate = rate;
 +      return rate;
  }
  
  static unsigned long dsiclk_rate(u8 n)
@@@ -1812,35 -1820,6 +1812,35 @@@ static long round_clock_rate(u8 clock, 
        return rounded_rate;
  }
  
 +/* CPU FREQ table, may be changed due to if MAX_OPP is supported. */
 +static struct cpufreq_frequency_table db8500_cpufreq_table[] = {
 +      { .frequency = 200000, .index = ARM_EXTCLK,},
 +      { .frequency = 400000, .index = ARM_50_OPP,},
 +      { .frequency = 800000, .index = ARM_100_OPP,},
 +      { .frequency = CPUFREQ_TABLE_END,}, /* To be used for MAX_OPP. */
 +      { .frequency = CPUFREQ_TABLE_END,},
 +};
 +
 +static long round_armss_rate(unsigned long rate)
 +{
 +      long freq = 0;
 +      int i = 0;
 +
 +      /* cpufreq table frequencies is in KHz. */
 +      rate = rate / 1000;
 +
 +      /* Find the corresponding arm opp from the cpufreq table. */
 +      while (db8500_cpufreq_table[i].frequency != CPUFREQ_TABLE_END) {
 +              freq = db8500_cpufreq_table[i].frequency;
 +              if (freq == rate)
 +                      break;
 +              i++;
 +      }
 +
 +      /* Return the last valid value, even if a match was not found. */
 +      return freq * 1000;
 +}
 +
  #define MIN_PLL_VCO_RATE 600000000ULL
  #define MAX_PLL_VCO_RATE 1680640000ULL
  
@@@ -1912,8 -1891,6 +1912,8 @@@ long prcmu_round_clock_rate(u8 clock, u
  {
        if (clock < PRCMU_NUM_REG_CLOCKS)
                return round_clock_rate(clock, rate);
 +      else if (clock == PRCMU_ARMSS)
 +              return round_armss_rate(rate);
        else if (clock == PRCMU_PLLDSI)
                return round_plldsi_rate(rate);
        else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK))
@@@ -1973,27 -1950,6 +1973,27 @@@ static void set_clock_rate(u8 clock, un
        spin_unlock_irqrestore(&clk_mgt_lock, flags);
  }
  
 +static int set_armss_rate(unsigned long rate)
 +{
 +      int i = 0;
 +
 +      /* cpufreq table frequencies is in KHz. */
 +      rate = rate / 1000;
 +
 +      /* Find the corresponding arm opp from the cpufreq table. */
 +      while (db8500_cpufreq_table[i].frequency != CPUFREQ_TABLE_END) {
 +              if (db8500_cpufreq_table[i].frequency == rate)
 +                      break;
 +              i++;
 +      }
 +
 +      if (db8500_cpufreq_table[i].frequency != rate)
 +              return -EINVAL;
 +
 +      /* Set the new arm opp. */
 +      return db8500_prcmu_set_arm_opp(db8500_cpufreq_table[i].index);
 +}
 +
  static int set_plldsi_rate(unsigned long rate)
  {
        unsigned long src_rate;
@@@ -2074,8 -2030,6 +2074,8 @@@ int prcmu_set_clock_rate(u8 clock, unsi
  {
        if (clock < PRCMU_NUM_REG_CLOCKS)
                set_clock_rate(clock, rate);
 +      else if (clock == PRCMU_ARMSS)
 +              return set_armss_rate(rate);
        else if (clock == PRCMU_PLLDSI)
                return set_plldsi_rate(rate);
        else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK))
@@@ -2743,15 -2697,9 +2743,15 @@@ static struct irq_domain_ops db8500_irq
  
  static int db8500_irq_init(struct device_node *np)
  {
 -      db8500_irq_domain = irq_domain_add_legacy(
 -              np, NUM_PRCMU_WAKEUPS, IRQ_PRCMU_BASE,
 -              0, &db8500_irq_ops, NULL);
 +      int irq_base = -1;
 +
 +      /* In the device tree case, just take some IRQs */
 +      if (!np)
 +              irq_base = IRQ_PRCMU_BASE;
 +
 +      db8500_irq_domain = irq_domain_add_simple(
 +              np, NUM_PRCMU_WAKEUPS, irq_base,
 +              &db8500_irq_ops, NULL);
  
        if (!db8500_irq_domain) {
                pr_err("Failed to create irqdomain\n");
  
  void __init db8500_prcmu_early_init(void)
  {
-       if (cpu_is_u8500v2()) {
+       if (cpu_is_u8500v2() || cpu_is_u9540()) {
                void *tcpm_base = ioremap_nocache(U8500_PRCMU_TCPM_BASE, SZ_4K);
  
                if (tcpm_base != NULL) {
                        iounmap(tcpm_base);
                }
  
-               tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE);
+               if (cpu_is_u9540())
+                       tcdm_base = ioremap_nocache(U8500_PRCMU_TCDM_BASE,
+                                               SZ_4K + SZ_8K) + SZ_8K;
+               else
+                       tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE);
        } else {
                pr_err("prcmu: Unsupported chip version\n");
                BUG();
        init_completion(&mb5_transfer.work);
  
        INIT_WORK(&mb0_transfer.mask_work, prcmu_mask_work);
 -
 -      compute_armss_rate();
  }
  
  static void __init init_prcm_registers(void)
@@@ -3070,8 -3024,6 +3074,8 @@@ static struct mfd_cell db8500_prcmu_dev
        {
                .name = "cpufreq-u8500",
                .of_compatible = "stericsson,cpufreq-u8500",
 +              .platform_data = &db8500_cpufreq_table,
 +              .pdata_size = sizeof(db8500_cpufreq_table),
        },
        {
                .name = "ab8500-core",
        },
  };
  
 +static void db8500_prcmu_update_cpufreq(void)
 +{
 +      if (prcmu_has_arm_maxopp()) {
 +              db8500_cpufreq_table[3].frequency = 1000000;
 +              db8500_cpufreq_table[3].index = ARM_MAX_OPP;
 +      }
 +}
 +
  /**
   * prcmu_fw_init - arch init call for the Linux PRCMU fw init logic
   *
   */
 -static int __devinit db8500_prcmu_probe(struct platform_device *pdev)
 +static int db8500_prcmu_probe(struct platform_device *pdev)
  {
        struct ab8500_platform_data *ab8500_platdata = pdev->dev.platform_data;
        struct device_node *np = pdev->dev.of_node;
        if (cpu_is_u8500v20_or_later())
                prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET);
  
 +      db8500_prcmu_update_cpufreq();
 +
        err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs,
                              ARRAY_SIZE(db8500_prcmu_devs), NULL, 0, NULL);
        if (err) {
diff --combined drivers/mfd/jz4740-adc.c
index 0b8b55bb9b11303cbcc71c0b2d3de62e84d19d85,8619508f34816e566e7d12efe547fd82025af56b..e80587f1a792ab72beb464b7904063d4296c3d3a
@@@ -202,7 -202,7 +202,7 @@@ static struct mfd_cell jz4740_adc_cells
        },
  };
  
 -static int __devinit jz4740_adc_probe(struct platform_device *pdev)
 +static int jz4740_adc_probe(struct platform_device *pdev)
  {
        struct irq_chip_generic *gc;
        struct irq_chip_type *ct;
        int ret;
        int irq_base;
  
-       adc = kmalloc(sizeof(*adc), GFP_KERNEL);
+       adc = devm_kzalloc(&pdev->dev, sizeof(*adc), GFP_KERNEL);
        if (!adc) {
                dev_err(&pdev->dev, "Failed to allocate driver structure\n");
                return -ENOMEM;
        if (adc->irq < 0) {
                ret = adc->irq;
                dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret);
-               goto err_free;
+               return ret;
        }
  
        irq_base = platform_get_irq(pdev, 1);
        if (irq_base < 0) {
-               ret = irq_base;
-               dev_err(&pdev->dev, "Failed to get irq base: %d\n", ret);
-               goto err_free;
+               dev_err(&pdev->dev, "Failed to get irq base: %d\n", irq_base);
+               return irq_base;
        }
  
        mem_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!mem_base) {
-               ret = -ENOENT;
                dev_err(&pdev->dev, "Failed to get platform mmio resource\n");
-               goto err_free;
+               return -ENOENT;
        }
  
        /* Only request the shared registers for the MFD driver */
        adc->mem = request_mem_region(mem_base->start, JZ_REG_ADC_STATUS,
                                        pdev->name);
        if (!adc->mem) {
-               ret = -EBUSY;
                dev_err(&pdev->dev, "Failed to request mmio memory region\n");
-               goto err_free;
+               return -EBUSY;
        }
  
        adc->base = ioremap_nocache(adc->mem->start, resource_size(adc->mem));
@@@ -301,13 -298,10 +298,10 @@@ err_iounmap
        iounmap(adc->base);
  err_release_mem_region:
        release_mem_region(adc->mem->start, resource_size(adc->mem));
- err_free:
-       kfree(adc);
        return ret;
  }
  
 -static int __devexit jz4740_adc_remove(struct platform_device *pdev)
 +static int jz4740_adc_remove(struct platform_device *pdev)
  {
        struct jz4740_adc *adc = platform_get_drvdata(pdev);
  
  
        platform_set_drvdata(pdev, NULL);
  
-       kfree(adc);
        return 0;
  }
  
  static struct platform_driver jz4740_adc_driver = {
        .probe  = jz4740_adc_probe,
 -      .remove = __devexit_p(jz4740_adc_remove),
 +      .remove = jz4740_adc_remove,
        .driver = {
                .name = "jz4740-adc",
                .owner = THIS_MODULE,
diff --combined drivers/mfd/lpc_ich.c
index 2ad24caa07dbfba6e8857031d0085a1c52cbac98,b6dd4993c66b5f4a47c104992bc7eca920b62a3a..d9d930302e98123c756e47477ca95cac0acebc59
@@@ -196,7 -196,7 +196,7 @@@ enum lpc_chipsets 
        LPC_LPT_LP,     /* Lynx Point-LP */
  };
  
 -struct lpc_ich_info lpc_chipset_info[] __devinitdata = {
 +struct lpc_ich_info lpc_chipset_info[] = {
        [LPC_ICH] = {
                .name = "ICH",
                .iTCO_version = 1,
@@@ -672,7 -672,7 +672,7 @@@ static void lpc_ich_restore_config_spac
        }
  }
  
 -static void __devinit lpc_ich_enable_acpi_space(struct pci_dev *dev)
 +static void lpc_ich_enable_acpi_space(struct pci_dev *dev)
  {
        u8 reg_save;
  
        lpc_ich_acpi_save = reg_save;
  }
  
 -static void __devinit lpc_ich_enable_gpio_space(struct pci_dev *dev)
 +static void lpc_ich_enable_gpio_space(struct pci_dev *dev)
  {
        u8 reg_save;
  
        lpc_ich_gpio_save = reg_save;
  }
  
 -static void __devinit lpc_ich_finalize_cell(struct mfd_cell *cell,
 +static void lpc_ich_finalize_cell(struct mfd_cell *cell,
                                        const struct pci_device_id *id)
  {
        cell->platform_data = &lpc_chipset_info[id->driver_data];
   * GPIO groups and it's enough to have access to one of these to instantiate
   * the device.
   */
 -static int __devinit lpc_ich_check_conflict_gpio(struct resource *res)
 +static int lpc_ich_check_conflict_gpio(struct resource *res)
  {
        int ret;
        u8 use_gpio = 0;
        return use_gpio ? use_gpio : ret;
  }
  
 -static int __devinit lpc_ich_init_gpio(struct pci_dev *dev,
 +static int lpc_ich_init_gpio(struct pci_dev *dev,
                                const struct pci_device_id *id)
  {
        u32 base_addr_cfg;
        pci_read_config_dword(dev, ACPIBASE, &base_addr_cfg);
        base_addr = base_addr_cfg & 0x0000ff80;
        if (!base_addr) {
-               dev_err(&dev->dev, "I/O space for ACPI uninitialized\n");
+               dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n");
                lpc_ich_cells[LPC_GPIO].num_resources--;
                goto gpe0_done;
        }
@@@ -760,7 -760,7 +760,7 @@@ gpe0_done
        pci_read_config_dword(dev, GPIOBASE, &base_addr_cfg);
        base_addr = base_addr_cfg & 0x0000ff80;
        if (!base_addr) {
-               dev_err(&dev->dev, "I/O space for GPIO uninitialized\n");
+               dev_notice(&dev->dev, "I/O space for GPIO uninitialized\n");
                ret = -ENODEV;
                goto gpio_done;
        }
@@@ -798,7 -798,7 +798,7 @@@ gpio_done
        return ret;
  }
  
 -static int __devinit lpc_ich_init_wdt(struct pci_dev *dev,
 +static int lpc_ich_init_wdt(struct pci_dev *dev,
                                const struct pci_device_id *id)
  {
        u32 base_addr_cfg;
        pci_read_config_dword(dev, ACPIBASE, &base_addr_cfg);
        base_addr = base_addr_cfg & 0x0000ff80;
        if (!base_addr) {
-               dev_err(&dev->dev, "I/O space for ACPI uninitialized\n");
+               dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n");
                ret = -ENODEV;
                goto wdt_done;
        }
         * we have to read RCBA from PCI Config space 0xf0 and use
         * it as base. GCS = RCBA + ICH6_GCS(0x3410).
         */
-       if (lpc_chipset_info[id->driver_data].iTCO_version == 2) {
+       if (lpc_chipset_info[id->driver_data].iTCO_version == 1) {
+               /* Don't register iomem for TCO ver 1 */
+               lpc_ich_cells[LPC_WDT].num_resources--;
+       } else {
                pci_read_config_dword(dev, RCBABASE, &base_addr_cfg);
                base_addr = base_addr_cfg & 0xffffc000;
                if (!(base_addr_cfg & 1)) {
-                       pr_err("RCBA is disabled by hardware/BIOS, "
-                                       "device disabled\n");
+                       dev_notice(&dev->dev, "RCBA is disabled by "
+                                       "hardware/BIOS, device disabled\n");
                        ret = -ENODEV;
                        goto wdt_done;
                }
@@@ -852,7 -855,7 +855,7 @@@ wdt_done
        return ret;
  }
  
 -static int __devinit lpc_ich_probe(struct pci_dev *dev,
 +static int lpc_ich_probe(struct pci_dev *dev,
                                const struct pci_device_id *id)
  {
        int ret;
         * successfully.
         */
        if (!cell_added) {
+               dev_warn(&dev->dev, "No MFD cells added\n");
                lpc_ich_restore_config_space(dev);
                return -ENODEV;
        }
        return 0;
  }
  
 -static void __devexit lpc_ich_remove(struct pci_dev *dev)
 +static void lpc_ich_remove(struct pci_dev *dev)
  {
        mfd_remove_devices(&dev->dev);
        lpc_ich_restore_config_space(dev);
@@@ -888,7 -892,7 +892,7 @@@ static struct pci_driver lpc_ich_drive
        .name           = "lpc_ich",
        .id_table       = lpc_ich_ids,
        .probe          = lpc_ich_probe,
 -      .remove         = __devexit_p(lpc_ich_remove),
 +      .remove         = lpc_ich_remove,
  };
  
  static int __init lpc_ich_init(void)
index 7957999f30bbe99c17e562f39bfa97f06bc3885c,bfc1284537ea46ae67ed84720ffb9b24e190975d..f745e27ee874a469e734cebd2757542388a0d10d
  static const struct i2c_device_id mc13xxx_i2c_device_id[] = {
        {
                .name = "mc13892",
-               .driver_data = MC13XXX_ID_MC13892,
+               .driver_data = (kernel_ulong_t)&mc13xxx_variant_mc13892,
+       }, {
+               .name = "mc34708",
+               .driver_data = (kernel_ulong_t)&mc13xxx_variant_mc34708,
        }, {
                /* sentinel */
        }
@@@ -34,7 -37,10 +37,10 @@@ MODULE_DEVICE_TABLE(i2c, mc13xxx_i2c_de
  static const struct of_device_id mc13xxx_dt_ids[] = {
        {
                .compatible = "fsl,mc13892",
-               .data = (void *) &mc13xxx_i2c_device_id[0],
+               .data = &mc13xxx_variant_mc13892,
+       }, {
+               .compatible = "fsl,mc34708",
+               .data = &mc13xxx_variant_mc34708,
        }, {
                /* sentinel */
        }
@@@ -76,16 -82,20 +82,20 @@@ static int mc13xxx_i2c_probe(struct i2c
                return ret;
        }
  
-       ret = mc13xxx_common_init(mc13xxx, pdata, client->irq);
+       if (client->dev.of_node) {
+               const struct of_device_id *of_id =
+                       of_match_device(mc13xxx_dt_ids, &client->dev);
+               mc13xxx->variant = of_id->data;
+       } else {
+               mc13xxx->variant = (void *)id->driver_data;
+       }
  
-       if (ret == 0 && (id->driver_data != mc13xxx->ictype))
-               dev_warn(mc13xxx->dev,
-                               "device id doesn't match auto detection!\n");
+       ret = mc13xxx_common_init(mc13xxx, pdata, client->irq);
  
        return ret;
  }
  
 -static int __devexit mc13xxx_i2c_remove(struct i2c_client *client)
 +static int mc13xxx_i2c_remove(struct i2c_client *client)
  {
        struct mc13xxx *mc13xxx = dev_get_drvdata(&client->dev);
  
@@@ -102,7 -112,7 +112,7 @@@ static struct i2c_driver mc13xxx_i2c_dr
                .of_match_table = mc13xxx_dt_ids,
        },
        .probe = mc13xxx_i2c_probe,
 -      .remove = __devexit_p(mc13xxx_i2c_remove),
 +      .remove = mc13xxx_i2c_remove,
  };
  
  static int __init mc13xxx_i2c_init(void)
index cb32f69d80ba46cb6decc7b72ed506d1f8eba224,afca4f92f0cfd547c439736822f5d95369c24ddb..3032bae20b62ce4460413194d140956ec38be587
  static const struct spi_device_id mc13xxx_device_id[] = {
        {
                .name = "mc13783",
-               .driver_data = MC13XXX_ID_MC13783,
+               .driver_data = (kernel_ulong_t)&mc13xxx_variant_mc13783,
        }, {
                .name = "mc13892",
-               .driver_data = MC13XXX_ID_MC13892,
+               .driver_data = (kernel_ulong_t)&mc13xxx_variant_mc13892,
+       }, {
+               .name = "mc34708",
+               .driver_data = (kernel_ulong_t)&mc13xxx_variant_mc34708,
        }, {
                /* sentinel */
        }
@@@ -39,8 -42,9 +42,9 @@@
  MODULE_DEVICE_TABLE(spi, mc13xxx_device_id);
  
  static const struct of_device_id mc13xxx_dt_ids[] = {
-       { .compatible = "fsl,mc13783", .data = (void *) MC13XXX_ID_MC13783, },
-       { .compatible = "fsl,mc13892", .data = (void *) MC13XXX_ID_MC13892, },
+       { .compatible = "fsl,mc13783", .data = &mc13xxx_variant_mc13783, },
+       { .compatible = "fsl,mc13892", .data = &mc13xxx_variant_mc13892, },
+       { .compatible = "fsl,mc34708", .data = &mc13xxx_variant_mc34708, },
        { /* sentinel */ }
  };
  MODULE_DEVICE_TABLE(of, mc13xxx_dt_ids);
@@@ -144,22 -148,21 +148,21 @@@ static int mc13xxx_spi_probe(struct spi
                return ret;
        }
  
-       ret = mc13xxx_common_init(mc13xxx, pdata, spi->irq);
+       if (spi->dev.of_node) {
+               const struct of_device_id *of_id =
+                       of_match_device(mc13xxx_dt_ids, &spi->dev);
  
-       if (ret) {
-               dev_set_drvdata(&spi->dev, NULL);
+               mc13xxx->variant = of_id->data;
        } else {
-               const struct spi_device_id *devid =
-                       spi_get_device_id(spi);
-               if (!devid || devid->driver_data != mc13xxx->ictype)
-                       dev_warn(mc13xxx->dev,
-                               "device id doesn't match auto detection!\n");
+               const struct spi_device_id *id_entry = spi_get_device_id(spi);
+               mc13xxx->variant = (void *)id_entry->driver_data;
        }
  
-       return ret;
+       return mc13xxx_common_init(mc13xxx, pdata, spi->irq);
  }
  
 -static int __devexit mc13xxx_spi_remove(struct spi_device *spi)
 +static int mc13xxx_spi_remove(struct spi_device *spi)
  {
        struct mc13xxx *mc13xxx = dev_get_drvdata(&spi->dev);
  
@@@ -176,7 -179,7 +179,7 @@@ static struct spi_driver mc13xxx_spi_dr
                .of_match_table = mc13xxx_dt_ids,
        },
        .probe = mc13xxx_spi_probe,
 -      .remove = __devexit_p(mc13xxx_spi_remove),
 +      .remove = mc13xxx_spi_remove,
  };
  
  static int __init mc13xxx_init(void)
index d6284cacd27a30e2174bc21ff77e7bef7592423b,009b4b7721eb87ff13125c4205ae4fc476ef20c2..1225dcbcfcfcc6fa9db396e1ea47c43b6a9a85b0
@@@ -1,6 -1,6 +1,6 @@@
  /*
   * Copyright (c) 2009-2011 Wind River Systems, Inc.
-  * Copyright (c) 2011 ST Microelectronics (Alessandro Rubini)
+  * Copyright (c) 2011 ST Microelectronics (Alessandro Rubini, Davide Ciminaghi)
   *
   * 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
  #include <linux/io.h>
  #include <linux/ioport.h>
  #include <linux/pci.h>
- #include <linux/debugfs.h>
  #include <linux/seq_file.h>
  #include <linux/platform_device.h>
  #include <linux/mfd/core.h>
  #include <linux/mfd/sta2x11-mfd.h>
+ #include <linux/regmap.h>
  
  #include <asm/sta2x11.h>
  
+ static inline int __reg_within_range(unsigned int r,
+                                    unsigned int start,
+                                    unsigned int end)
+ {
+       return ((r >= start) && (r <= end));
+ }
  /* This describes STA2X11 MFD chip for us, we may have several */
  struct sta2x11_mfd {
        struct sta2x11_instance *instance;
-       spinlock_t lock;
+       struct regmap *regmap[sta2x11_n_mfd_plat_devs];
+       spinlock_t lock[sta2x11_n_mfd_plat_devs];
        struct list_head list;
-       void __iomem *sctl_regs;
-       void __iomem *apbreg_regs;
+       void __iomem *regs[sta2x11_n_mfd_plat_devs];
  };
  
  static LIST_HEAD(sta2x11_mfd_list);
@@@ -69,8 -76,9 +76,9 @@@ static struct sta2x11_mfd *sta2x11_mfd_
        return NULL;
  }
  
 -static int __devinit sta2x11_mfd_add(struct pci_dev *pdev, gfp_t flags)
 +static int sta2x11_mfd_add(struct pci_dev *pdev, gfp_t flags)
  {
+       int i;
        struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev);
        struct sta2x11_instance *instance;
  
        if (!mfd)
                return -ENOMEM;
        INIT_LIST_HEAD(&mfd->list);
-       spin_lock_init(&mfd->lock);
+       for (i = 0; i < ARRAY_SIZE(mfd->lock); i++)
+               spin_lock_init(&mfd->lock[i]);
        mfd->instance = instance;
        list_add(&mfd->list, &sta2x11_mfd_list);
        return 0;
  }
  
 -static int __devexit mfd_remove(struct pci_dev *pdev)
 +static int mfd_remove(struct pci_dev *pdev)
  {
        struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev);
  
        return 0;
  }
  
- /* These two functions are exported and are not expected to fail */
- u32 sta2x11_sctl_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val)
+ /* This function is exported and is not expected to fail */
+ u32 __sta2x11_mfd_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val,
+                      enum sta2x11_mfd_plat_dev index)
  {
        struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev);
        u32 r;
        unsigned long flags;
+       void __iomem *regs;
  
        if (!mfd) {
                dev_warn(&pdev->dev, ": can't access sctl regs\n");
                return 0;
        }
-       if (!mfd->sctl_regs) {
+       regs = mfd->regs[index];
+       if (!regs) {
                dev_warn(&pdev->dev, ": system ctl not initialized\n");
                return 0;
        }
-       spin_lock_irqsave(&mfd->lock, flags);
-       r = readl(mfd->sctl_regs + reg);
+       spin_lock_irqsave(&mfd->lock[index], flags);
+       r = readl(regs + reg);
        r &= ~mask;
        r |= val;
        if (mask)
-               writel(r, mfd->sctl_regs + reg);
-       spin_unlock_irqrestore(&mfd->lock, flags);
+               writel(r, regs + reg);
+       spin_unlock_irqrestore(&mfd->lock[index], flags);
        return r;
  }
- EXPORT_SYMBOL(sta2x11_sctl_mask);
+ EXPORT_SYMBOL(__sta2x11_mfd_mask);
  
- u32 sta2x11_apbreg_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val)
+ int sta2x11_mfd_get_regs_data(struct platform_device *dev,
+                             enum sta2x11_mfd_plat_dev index,
+                             void __iomem **regs,
+                             spinlock_t **lock)
  {
-       struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev);
-       u32 r;
-       unsigned long flags;
+       struct pci_dev *pdev = *(struct pci_dev **)(dev->dev.platform_data);
+       struct sta2x11_mfd *mfd;
  
-       if (!mfd) {
-               dev_warn(&pdev->dev, ": can't access apb regs\n");
-               return 0;
-       }
-       if (!mfd->apbreg_regs) {
-               dev_warn(&pdev->dev, ": apb bridge not initialized\n");
-               return 0;
-       }
-       spin_lock_irqsave(&mfd->lock, flags);
-       r = readl(mfd->apbreg_regs + reg);
-       r &= ~mask;
-       r |= val;
-       if (mask)
-               writel(r, mfd->apbreg_regs + reg);
-       spin_unlock_irqrestore(&mfd->lock, flags);
-       return r;
+       if (!pdev)
+               return -ENODEV;
+       mfd = sta2x11_mfd_find(pdev);
+       if (!mfd)
+               return -ENODEV;
+       if (index >= sta2x11_n_mfd_plat_devs)
+               return -ENODEV;
+       *regs = mfd->regs[index];
+       *lock = &mfd->lock[index];
+       pr_debug("%s %d *regs = %p\n", __func__, __LINE__, *regs);
+       return *regs ? 0 : -ENODEV;
  }
- EXPORT_SYMBOL(sta2x11_apbreg_mask);
- /* Two debugfs files, for our registers (FIXME: one instance only) */
- #define REG(regname) {.name = #regname, .offset = SCTL_ ## regname}
- static struct debugfs_reg32 sta2x11_sctl_regs[] = {
-       REG(SCCTL), REG(ARMCFG), REG(SCPLLCTL), REG(SCPLLFCTRL),
-       REG(SCRESFRACT), REG(SCRESCTRL1), REG(SCRESXTRL2), REG(SCPEREN0),
-       REG(SCPEREN1), REG(SCPEREN2), REG(SCGRST), REG(SCPCIPMCR1),
-       REG(SCPCIPMCR2), REG(SCPCIPMSR1), REG(SCPCIPMSR2), REG(SCPCIPMSR3),
-       REG(SCINTREN), REG(SCRISR), REG(SCCLKSTAT0), REG(SCCLKSTAT1),
-       REG(SCCLKSTAT2), REG(SCRSTSTA),
- };
- #undef REG
+ EXPORT_SYMBOL(sta2x11_mfd_get_regs_data);
  
- static struct debugfs_regset32 sctl_regset = {
-       .regs = sta2x11_sctl_regs,
-       .nregs = ARRAY_SIZE(sta2x11_sctl_regs),
- };
+ /*
+  * Special sta2x11-mfd regmap lock/unlock functions
+  */
+ static void sta2x11_regmap_lock(void *__lock)
+ {
+       spinlock_t *lock = __lock;
+       spin_lock(lock);
+ }
  
- #define REG(regname) {.name = #regname, .offset = regname}
- static struct debugfs_reg32 sta2x11_apbreg_regs[] = {
-       REG(APBREG_BSR), REG(APBREG_PAER), REG(APBREG_PWAC), REG(APBREG_PRAC),
-       REG(APBREG_PCG), REG(APBREG_PUR), REG(APBREG_EMU_PCG),
+ static void sta2x11_regmap_unlock(void *__lock)
+ {
+       spinlock_t *lock = __lock;
+       spin_unlock(lock);
+ }
+ /* OTP (one time programmable registers do not require locking */
+ static void sta2x11_regmap_nolock(void *__lock)
+ {
+ }
+ static const char *sta2x11_mfd_names[sta2x11_n_mfd_plat_devs] = {
+       [sta2x11_sctl] = STA2X11_MFD_SCTL_NAME,
+       [sta2x11_apbreg] = STA2X11_MFD_APBREG_NAME,
+       [sta2x11_apb_soc_regs] = STA2X11_MFD_APB_SOC_REGS_NAME,
+       [sta2x11_scr] = STA2X11_MFD_SCR_NAME,
  };
- #undef REG
  
- static struct debugfs_regset32 apbreg_regset = {
-       .regs = sta2x11_apbreg_regs,
-       .nregs = ARRAY_SIZE(sta2x11_apbreg_regs),
+ static bool sta2x11_sctl_writeable_reg(struct device *dev, unsigned int reg)
+ {
+       return !__reg_within_range(reg, SCTL_SCPCIECSBRST, SCTL_SCRSTSTA);
+ }
+ static struct regmap_config sta2x11_sctl_regmap_config = {
+       .reg_bits = 32,
+       .reg_stride = 4,
+       .val_bits = 32,
+       .lock = sta2x11_regmap_lock,
+       .unlock = sta2x11_regmap_unlock,
+       .max_register = SCTL_SCRSTSTA,
+       .writeable_reg = sta2x11_sctl_writeable_reg,
  };
  
- static struct dentry *sta2x11_sctl_debugfs;
- static struct dentry *sta2x11_apbreg_debugfs;
+ static bool sta2x11_scr_readable_reg(struct device *dev, unsigned int reg)
+ {
+       return (reg == STA2X11_SECR_CR) ||
+               __reg_within_range(reg, STA2X11_SECR_FVR0, STA2X11_SECR_FVR1);
+ }
  
- /* Probe for the two platform devices */
- static int sta2x11_sctl_probe(struct platform_device *dev)
+ static bool sta2x11_scr_writeable_reg(struct device *dev, unsigned int reg)
  {
-       struct pci_dev **pdev;
-       struct sta2x11_mfd *mfd;
-       struct resource *res;
+       return false;
+ }
  
-       pdev = dev->dev.platform_data;
-       mfd = sta2x11_mfd_find(*pdev);
-       if (!mfd)
-               return -ENODEV;
+ static struct regmap_config sta2x11_scr_regmap_config = {
+       .reg_bits = 32,
+       .reg_stride = 4,
+       .val_bits = 32,
+       .lock = sta2x11_regmap_nolock,
+       .unlock = sta2x11_regmap_nolock,
+       .max_register = STA2X11_SECR_FVR1,
+       .readable_reg = sta2x11_scr_readable_reg,
+       .writeable_reg = sta2x11_scr_writeable_reg,
+ };
  
-       res = platform_get_resource(dev, IORESOURCE_MEM, 0);
-       if (!res)
-               return -ENOMEM;
+ static bool sta2x11_apbreg_readable_reg(struct device *dev, unsigned int reg)
+ {
+       /* Two blocks (CAN and MLB, SARAC) 0x100 bytes apart */
+       if (reg >= APBREG_BSR_SARAC)
+               reg -= APBREG_BSR_SARAC;
+       switch (reg) {
+       case APBREG_BSR:
+       case APBREG_PAER:
+       case APBREG_PWAC:
+       case APBREG_PRAC:
+       case APBREG_PCG:
+       case APBREG_PUR:
+       case APBREG_EMU_PCG:
+               return true;
+       default:
+               return false;
+       }
+ }
  
-       if (!request_mem_region(res->start, resource_size(res),
-                               "sta2x11-sctl"))
-               return -EBUSY;
+ static bool sta2x11_apbreg_writeable_reg(struct device *dev, unsigned int reg)
+ {
+       if (reg >= APBREG_BSR_SARAC)
+               reg -= APBREG_BSR_SARAC;
+       if (!sta2x11_apbreg_readable_reg(dev, reg))
+               return false;
+       return reg != APBREG_PAER;
+ }
  
-       mfd->sctl_regs = ioremap(res->start, resource_size(res));
-       if (!mfd->sctl_regs) {
-               release_mem_region(res->start, resource_size(res));
-               return -ENOMEM;
+ static struct regmap_config sta2x11_apbreg_regmap_config = {
+       .reg_bits = 32,
+       .reg_stride = 4,
+       .val_bits = 32,
+       .lock = sta2x11_regmap_lock,
+       .unlock = sta2x11_regmap_unlock,
+       .max_register = APBREG_EMU_PCG_SARAC,
+       .readable_reg = sta2x11_apbreg_readable_reg,
+       .writeable_reg = sta2x11_apbreg_writeable_reg,
+ };
+ static bool sta2x11_apb_soc_regs_readable_reg(struct device *dev,
+                                             unsigned int reg)
+ {
+       return reg <= PCIE_SoC_INT_ROUTER_STATUS3_REG ||
+               __reg_within_range(reg, DMA_IP_CTRL_REG, SPARE3_RESERVED) ||
+               __reg_within_range(reg, MASTER_LOCK_REG,
+                                  SYSTEM_CONFIG_STATUS_REG) ||
+               reg == MSP_CLK_CTRL_REG ||
+               __reg_within_range(reg, COMPENSATION_REG1, TEST_CTL_REG);
+ }
+ static bool sta2x11_apb_soc_regs_writeable_reg(struct device *dev,
+                                              unsigned int reg)
+ {
+       if (!sta2x11_apb_soc_regs_readable_reg(dev, reg))
+               return false;
+       switch (reg) {
+       case PCIE_COMMON_CLOCK_CONFIG_0_4_0:
+       case SYSTEM_CONFIG_STATUS_REG:
+       case COMPENSATION_REG1:
+       case PCIE_SoC_INT_ROUTER_STATUS0_REG...PCIE_SoC_INT_ROUTER_STATUS3_REG:
+       case PCIE_PM_STATUS_0_PORT_0_4...PCIE_PM_STATUS_7_0_EP4:
+               return false;
+       default:
+               return true;
        }
-       sctl_regset.base = mfd->sctl_regs;
-       sta2x11_sctl_debugfs = debugfs_create_regset32("sta2x11-sctl",
-                                                 S_IFREG | S_IRUGO,
-                                                 NULL, &sctl_regset);
-       return 0;
  }
  
- static int sta2x11_apbreg_probe(struct platform_device *dev)
+ static struct regmap_config sta2x11_apb_soc_regs_regmap_config = {
+       .reg_bits = 32,
+       .reg_stride = 4,
+       .val_bits = 32,
+       .lock = sta2x11_regmap_lock,
+       .unlock = sta2x11_regmap_unlock,
+       .max_register = TEST_CTL_REG,
+       .readable_reg = sta2x11_apb_soc_regs_readable_reg,
+       .writeable_reg = sta2x11_apb_soc_regs_writeable_reg,
+ };
+ static struct regmap_config *
+ sta2x11_mfd_regmap_configs[sta2x11_n_mfd_plat_devs] = {
+       [sta2x11_sctl] = &sta2x11_sctl_regmap_config,
+       [sta2x11_apbreg] = &sta2x11_apbreg_regmap_config,
+       [sta2x11_apb_soc_regs] = &sta2x11_apb_soc_regs_regmap_config,
+       [sta2x11_scr] = &sta2x11_scr_regmap_config,
+ };
+ /* Probe for the four platform devices */
+ static int sta2x11_mfd_platform_probe(struct platform_device *dev,
+                                     enum sta2x11_mfd_plat_dev index)
  {
        struct pci_dev **pdev;
        struct sta2x11_mfd *mfd;
        struct resource *res;
+       const char *name = sta2x11_mfd_names[index];
+       struct regmap_config *regmap_config = sta2x11_mfd_regmap_configs[index];
  
        pdev = dev->dev.platform_data;
-       dev_dbg(&dev->dev, "%s: pdata is %p\n", __func__, pdev);
-       dev_dbg(&dev->dev, "%s: *pdata is %p\n", __func__, *pdev);
        mfd = sta2x11_mfd_find(*pdev);
        if (!mfd)
                return -ENODEV;
+       if (!regmap_config)
+               return -ENODEV;
  
        res = platform_get_resource(dev, IORESOURCE_MEM, 0);
        if (!res)
                return -ENOMEM;
  
-       if (!request_mem_region(res->start, resource_size(res),
-                               "sta2x11-apbreg"))
+       if (!request_mem_region(res->start, resource_size(res), name))
                return -EBUSY;
  
-       mfd->apbreg_regs = ioremap(res->start, resource_size(res));
-       if (!mfd->apbreg_regs) {
+       mfd->regs[index] = ioremap(res->start, resource_size(res));
+       if (!mfd->regs[index]) {
                release_mem_region(res->start, resource_size(res));
                return -ENOMEM;
        }
-       dev_dbg(&dev->dev, "%s: regbase %p\n", __func__, mfd->apbreg_regs);
+       regmap_config->lock_arg = &mfd->lock;
+       /*
+          No caching, registers could be reached both via regmap and via
+          void __iomem *
+       */
+       regmap_config->cache_type = REGCACHE_NONE;
+       mfd->regmap[index] = devm_regmap_init_mmio(&dev->dev, mfd->regs[index],
+                                                  regmap_config);
+       WARN_ON(!mfd->regmap[index]);
  
-       apbreg_regset.base = mfd->apbreg_regs;
-       sta2x11_apbreg_debugfs = debugfs_create_regset32("sta2x11-apbreg",
-                                                 S_IFREG | S_IRUGO,
-                                                 NULL, &apbreg_regset);
        return 0;
  }
  
- /* The two platform drivers */
+ static int sta2x11_sctl_probe(struct platform_device *dev)
+ {
+       return sta2x11_mfd_platform_probe(dev, sta2x11_sctl);
+ }
+ static int sta2x11_apbreg_probe(struct platform_device *dev)
+ {
+       return sta2x11_mfd_platform_probe(dev, sta2x11_apbreg);
+ }
+ static int sta2x11_apb_soc_regs_probe(struct platform_device *dev)
+ {
+       return sta2x11_mfd_platform_probe(dev, sta2x11_apb_soc_regs);
+ }
+ static int sta2x11_scr_probe(struct platform_device *dev)
+ {
+       return sta2x11_mfd_platform_probe(dev, sta2x11_scr);
+ }
+ /* The three platform drivers */
  static struct platform_driver sta2x11_sctl_platform_driver = {
        .driver = {
-               .name   = "sta2x11-sctl",
+               .name   = STA2X11_MFD_SCTL_NAME,
                .owner  = THIS_MODULE,
        },
        .probe          = sta2x11_sctl_probe,
@@@ -268,7 -392,7 +392,7 @@@ static int __init sta2x11_sctl_init(voi
  
  static struct platform_driver sta2x11_platform_driver = {
        .driver = {
-               .name   = "sta2x11-apbreg",
+               .name   = STA2X11_MFD_APBREG_NAME,
                .owner  = THIS_MODULE,
        },
        .probe          = sta2x11_apbreg_probe,
@@@ -280,13 -404,44 +404,44 @@@ static int __init sta2x11_apbreg_init(v
        return platform_driver_register(&sta2x11_platform_driver);
  }
  
+ static struct platform_driver sta2x11_apb_soc_regs_platform_driver = {
+       .driver = {
+               .name   = STA2X11_MFD_APB_SOC_REGS_NAME,
+               .owner  = THIS_MODULE,
+       },
+       .probe          = sta2x11_apb_soc_regs_probe,
+ };
+ static int __init sta2x11_apb_soc_regs_init(void)
+ {
+       pr_info("%s\n", __func__);
+       return platform_driver_register(&sta2x11_apb_soc_regs_platform_driver);
+ }
+ static struct platform_driver sta2x11_scr_platform_driver = {
+       .driver = {
+               .name = STA2X11_MFD_SCR_NAME,
+               .owner = THIS_MODULE,
+       },
+       .probe = sta2x11_scr_probe,
+ };
+ static int __init sta2x11_scr_init(void)
+ {
+       pr_info("%s\n", __func__);
+       return platform_driver_register(&sta2x11_scr_platform_driver);
+ }
  /*
-  * What follows is the PCI device that hosts the above two pdevs.
+  * What follows are the PCI devices that host the above pdevs.
   * Each logic block is 4kB and they are all consecutive: we use this info.
   */
  
- /* Bar 0 */
- enum bar0_cells {
+ /* Mfd 0 device */
+ /* Mfd 0, Bar 0 */
+ enum mfd0_bar0_cells {
        STA2X11_GPIO_0 = 0,
        STA2X11_GPIO_1,
        STA2X11_GPIO_2,
        STA2X11_SCR,
        STA2X11_TIME,
  };
- /* Bar 1 */
- enum bar1_cells {
+ /* Mfd 0 , Bar 1 */
+ enum mfd0_bar1_cells {
        STA2X11_APBREG = 0,
  };
  #define CELL_4K(_name, _cell) { \
                .flags = IORESOURCE_MEM, \
                }
  
 -static const __devinitconst struct resource gpio_resources[] = {
 +static const struct resource gpio_resources[] = {
        {
-               .name = "sta2x11_gpio", /* 4 consecutive cells, 1 driver */
+               /* 4 consecutive cells, 1 driver */
+               .name = STA2X11_MFD_GPIO_NAME,
                .start = 0,
                .end = (4 * 4096) - 1,
                .flags = IORESOURCE_MEM,
        }
  };
 -static const __devinitconst struct resource sctl_resources[] = {
 +static const struct resource sctl_resources[] = {
-       CELL_4K("sta2x11-sctl", STA2X11_SCTL),
+       CELL_4K(STA2X11_MFD_SCTL_NAME, STA2X11_SCTL),
  };
 -static const __devinitconst struct resource scr_resources[] = {
 +static const struct resource scr_resources[] = {
-       CELL_4K("sta2x11-scr", STA2X11_SCR),
+       CELL_4K(STA2X11_MFD_SCR_NAME, STA2X11_SCR),
  };
 -static const __devinitconst struct resource time_resources[] = {
 +static const struct resource time_resources[] = {
-       CELL_4K("sta2x11-time", STA2X11_TIME),
+       CELL_4K(STA2X11_MFD_TIME_NAME, STA2X11_TIME),
  };
  
 -static const __devinitconst struct resource apbreg_resources[] = {
 +static const struct resource apbreg_resources[] = {
-       CELL_4K("sta2x11-apbreg", STA2X11_APBREG),
+       CELL_4K(STA2X11_MFD_APBREG_NAME, STA2X11_APBREG),
  };
  
  #define DEV(_name, _r) \
        { .name = _name, .num_resources = ARRAY_SIZE(_r), .resources = _r, }
  
- static struct mfd_cell sta2x11_mfd_bar0[] = {
-       DEV("sta2x11-gpio", gpio_resources), /* offset 0: we add pdata later */
-       DEV("sta2x11-sctl", sctl_resources),
-       DEV("sta2x11-scr", scr_resources),
-       DEV("sta2x11-time", time_resources),
 -static __devinitdata struct mfd_cell sta2x11_mfd0_bar0[] = {
++static struct mfd_cell sta2x11_mfd0_bar0[] = {
+       /* offset 0: we add pdata later */
+       DEV(STA2X11_MFD_GPIO_NAME, gpio_resources),
+       DEV(STA2X11_MFD_SCTL_NAME, sctl_resources),
+       DEV(STA2X11_MFD_SCR_NAME,  scr_resources),
+       DEV(STA2X11_MFD_TIME_NAME, time_resources),
  };
  
- static struct mfd_cell sta2x11_mfd_bar1[] = {
-       DEV("sta2x11-apbreg", apbreg_resources),
 -static __devinitdata struct mfd_cell sta2x11_mfd0_bar1[] = {
++static struct mfd_cell sta2x11_mfd0_bar1[] = {
+       DEV(STA2X11_MFD_APBREG_NAME, apbreg_resources),
  };
  
+ /* Mfd 1 devices */
+ /* Mfd 1, Bar 0 */
+ enum mfd1_bar0_cells {
+       STA2X11_VIC = 0,
+ };
+ /* Mfd 1, Bar 1 */
+ enum mfd1_bar1_cells {
+       STA2X11_APB_SOC_REGS = 0,
+ };
+ static const __devinitconst struct resource vic_resources[] = {
+       CELL_4K(STA2X11_MFD_VIC_NAME, STA2X11_VIC),
+ };
+ static const __devinitconst struct resource apb_soc_regs_resources[] = {
+       CELL_4K(STA2X11_MFD_APB_SOC_REGS_NAME, STA2X11_APB_SOC_REGS),
+ };
+ static __devinitdata struct mfd_cell sta2x11_mfd1_bar0[] = {
+       DEV(STA2X11_MFD_VIC_NAME, vic_resources),
+ };
+ static __devinitdata struct mfd_cell sta2x11_mfd1_bar1[] = {
+       DEV(STA2X11_MFD_APB_SOC_REGS_NAME, apb_soc_regs_resources),
+ };
  static int sta2x11_mfd_suspend(struct pci_dev *pdev, pm_message_t state)
  {
        pci_save_state(pdev);
@@@ -363,11 -549,63 +549,63 @@@ static int sta2x11_mfd_resume(struct pc
        return 0;
  }
  
 -static void __devinit sta2x11_mfd_setup(struct pci_dev *pdev,
 -                                      struct sta2x11_mfd_setup_data *sd)
+ struct sta2x11_mfd_bar_setup_data {
+       struct mfd_cell *cells;
+       int ncells;
+ };
+ struct sta2x11_mfd_setup_data {
+       struct sta2x11_mfd_bar_setup_data bars[2];
+ };
+ #define STA2X11_MFD0 0
+ #define STA2X11_MFD1 1
+ static struct sta2x11_mfd_setup_data mfd_setup_data[] = {
+       /* Mfd 0: gpio, sctl, scr, timers / apbregs */
+       [STA2X11_MFD0] = {
+               .bars = {
+                       [0] = {
+                               .cells = sta2x11_mfd0_bar0,
+                               .ncells = ARRAY_SIZE(sta2x11_mfd0_bar0),
+                       },
+                       [1] = {
+                               .cells = sta2x11_mfd0_bar1,
+                               .ncells = ARRAY_SIZE(sta2x11_mfd0_bar1),
+                       },
+               },
+       },
+       /* Mfd 1: vic / apb-soc-regs */
+       [STA2X11_MFD1] = {
+               .bars = {
+                       [0] = {
+                               .cells = sta2x11_mfd1_bar0,
+                               .ncells = ARRAY_SIZE(sta2x11_mfd1_bar0),
+                       },
+                       [1] = {
+                               .cells = sta2x11_mfd1_bar1,
+                               .ncells = ARRAY_SIZE(sta2x11_mfd1_bar1),
+                       },
+               },
+       },
+ };
 -static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev,
 -                                     const struct pci_device_id *pci_id)
++static void sta2x11_mfd_setup(struct pci_dev *pdev,
++                            struct sta2x11_mfd_setup_data *sd)
+ {
+       int i, j;
+       for (i = 0; i < ARRAY_SIZE(sd->bars); i++)
+               for (j = 0; j < sd->bars[i].ncells; j++) {
+                       sd->bars[i].cells[j].pdata_size = sizeof(pdev);
+                       sd->bars[i].cells[j].platform_data = &pdev;
+               }
+ }
-                                      const struct pci_device_id *pci_id)
 +static int sta2x11_mfd_probe(struct pci_dev *pdev,
++                           const struct pci_device_id *pci_id)
  {
        int err, i;
-       struct sta2x11_gpio_pdata *gpio_data;
+       struct sta2x11_mfd_setup_data *setup_data;
  
        dev_info(&pdev->dev, "%s\n", __func__);
  
        if (err)
                dev_info(&pdev->dev, "Enable msi failed\n");
  
-       /* Read gpio config data as pci device's platform data */
-       gpio_data = dev_get_platdata(&pdev->dev);
-       if (!gpio_data)
-               dev_warn(&pdev->dev, "no gpio configuration\n");
-       dev_dbg(&pdev->dev, "%s, gpio_data = %p (%p)\n", __func__,
-               gpio_data, &gpio_data);
-       dev_dbg(&pdev->dev, "%s, pdev = %p (%p)\n", __func__,
-               pdev, &pdev);
+       setup_data = pci_id->device == PCI_DEVICE_ID_STMICRO_GPIO ?
+               &mfd_setup_data[STA2X11_MFD0] :
+               &mfd_setup_data[STA2X11_MFD1];
  
        /* platform data is the pci device for all of them */
-       for (i = 0; i < ARRAY_SIZE(sta2x11_mfd_bar0); i++) {
-               sta2x11_mfd_bar0[i].pdata_size = sizeof(pdev);
-               sta2x11_mfd_bar0[i].platform_data = &pdev;
-       }
-       sta2x11_mfd_bar1[0].pdata_size = sizeof(pdev);
-       sta2x11_mfd_bar1[0].platform_data = &pdev;
+       sta2x11_mfd_setup(pdev, setup_data);
  
        /* Record this pdev before mfd_add_devices: their probe looks for it */
-       sta2x11_mfd_add(pdev, GFP_ATOMIC);
-       err = mfd_add_devices(&pdev->dev, -1,
-                             sta2x11_mfd_bar0,
-                             ARRAY_SIZE(sta2x11_mfd_bar0),
-                             &pdev->resource[0],
-                             0, NULL);
-       if (err) {
-               dev_err(&pdev->dev, "mfd_add_devices[0] failed: %d\n", err);
-               goto err_disable;
-       }
-       err = mfd_add_devices(&pdev->dev, -1,
-                             sta2x11_mfd_bar1,
-                             ARRAY_SIZE(sta2x11_mfd_bar1),
-                             &pdev->resource[1],
-                             0, NULL);
-       if (err) {
-               dev_err(&pdev->dev, "mfd_add_devices[1] failed: %d\n", err);
-               goto err_disable;
+       if (!sta2x11_mfd_find(pdev))
+               sta2x11_mfd_add(pdev, GFP_ATOMIC);
+       /* Just 2 bars for all mfd's at present */
+       for (i = 0; i < 2; i++) {
+               err = mfd_add_devices(&pdev->dev, -1,
+                                     setup_data->bars[i].cells,
+                                     setup_data->bars[i].ncells,
+                                     &pdev->resource[i],
+                                     0, NULL);
+               if (err) {
+                       dev_err(&pdev->dev,
+                               "mfd_add_devices[%d] failed: %d\n", i, err);
+                       goto err_disable;
+               }
        }
  
        return 0;
@@@ -434,6 -655,7 +655,7 @@@ err_disable
  
  static DEFINE_PCI_DEVICE_TABLE(sta2x11_mfd_tbl) = {
        {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_GPIO)},
+       {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_VIC)},
        {0,},
  };
  
@@@ -459,6 -681,8 +681,8 @@@ static int __init sta2x11_mfd_init(void
   */
  subsys_initcall(sta2x11_apbreg_init);
  subsys_initcall(sta2x11_sctl_init);
+ subsys_initcall(sta2x11_apb_soc_regs_init);
+ subsys_initcall(sta2x11_scr_init);
  rootfs_initcall(sta2x11_mfd_init);
  
  MODULE_LICENSE("GPL v2");
diff --combined drivers/mfd/stmpe-i2c.c
index 36df187780294191469a486019f0a1178469d3f8,c734dc33fbfd160536a041d79a5ef99b52108a73..fd5fcb63068548d57c44ed3cd0d777228fdbcaec
@@@ -52,7 -52,7 +52,7 @@@ static struct stmpe_client_info i2c_ci 
        .write_block = i2c_block_write,
  };
  
 -static int __devinit
 +static int
  stmpe_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
  {
        i2c_ci.data = (void *)id;
@@@ -63,7 -63,7 +63,7 @@@
        return stmpe_probe(&i2c_ci, id->driver_data);
  }
  
 -static int __devexit stmpe_i2c_remove(struct i2c_client *i2c)
 +static int stmpe_i2c_remove(struct i2c_client *i2c)
  {
        struct stmpe *stmpe = dev_get_drvdata(&i2c->dev);
  
@@@ -82,13 -82,15 +82,15 @@@ static const struct i2c_device_id stmpe
  MODULE_DEVICE_TABLE(i2c, stmpe_id);
  
  static struct i2c_driver stmpe_i2c_driver = {
-       .driver.name    = "stmpe-i2c",
-       .driver.owner   = THIS_MODULE,
+       .driver = {
+               .name = "stmpe-i2c",
+               .owner = THIS_MODULE,
  #ifdef CONFIG_PM
-       .driver.pm      = &stmpe_dev_pm_ops,
+               .pm = &stmpe_dev_pm_ops,
  #endif
+       },
        .probe          = stmpe_i2c_probe,
 -      .remove         = __devexit_p(stmpe_i2c_remove),
 +      .remove         = stmpe_i2c_remove,
        .id_table       = stmpe_i2c_id,
  };
  
diff --combined drivers/mfd/stmpe.c
index 79e88d1fd99aa92f3028820b17abbf2005c2b709,b18cc1a1b162a3304be70083bc8c975127579d70..19636199d7a57066cfd5c1069414c2d8c74643b3
@@@ -7,11 -7,15 +7,15 @@@
   * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
   */
  
+ #include <linux/err.h>
  #include <linux/gpio.h>
  #include <linux/export.h>
  #include <linux/kernel.h>
  #include <linux/interrupt.h>
  #include <linux/irq.h>
+ #include <linux/irqdomain.h>
+ #include <linux/of.h>
+ #include <linux/of_gpio.h>
  #include <linux/pm.h>
  #include <linux/slab.h>
  #include <linux/mfd/core.h>
@@@ -294,14 -298,12 +298,14 @@@ static struct resource stmpe_gpio_resou
  
  static struct mfd_cell stmpe_gpio_cell = {
        .name           = "stmpe-gpio",
 +      .of_compatible  = "st,stmpe-gpio",
        .resources      = stmpe_gpio_resources,
        .num_resources  = ARRAY_SIZE(stmpe_gpio_resources),
  };
  
  static struct mfd_cell stmpe_gpio_cell_noirq = {
        .name           = "stmpe-gpio",
 +      .of_compatible  = "st,stmpe-gpio",
        /* gpio cell resources consist of an irq only so no resources here */
  };
  
  static struct resource stmpe_keypad_resources[] = {
        {
                .name   = "KEYPAD",
-               .start  = 0,
-               .end    = 0,
                .flags  = IORESOURCE_IRQ,
        },
        {
                .name   = "KEYPAD_OVER",
-               .start  = 1,
-               .end    = 1,
                .flags  = IORESOURCE_IRQ,
        },
  };
@@@ -399,14 -397,10 +399,10 @@@ static struct stmpe_variant_info stmpe8
  static struct resource stmpe_ts_resources[] = {
        {
                .name   = "TOUCH_DET",
-               .start  = 0,
-               .end    = 0,
                .flags  = IORESOURCE_IRQ,
        },
        {
                .name   = "FIFO_TH",
-               .start  = 1,
-               .end    = 1,
                .flags  = IORESOURCE_IRQ,
        },
  };
@@@ -528,12 -522,12 +524,12 @@@ static const u8 stmpe1601_regs[] = 
  static struct stmpe_variant_block stmpe1601_blocks[] = {
        {
                .cell   = &stmpe_gpio_cell,
-               .irq    = STMPE24XX_IRQ_GPIOC,
+               .irq    = STMPE1601_IRQ_GPIOC,
                .block  = STMPE_BLOCK_GPIO,
        },
        {
                .cell   = &stmpe_keypad_cell,
-               .irq    = STMPE24XX_IRQ_KEYPAD,
+               .irq    = STMPE1601_IRQ_KEYPAD,
                .block  = STMPE_BLOCK_KEYPAD,
        },
  };
@@@ -767,7 -761,9 +763,9 @@@ static irqreturn_t stmpe_irq(int irq, v
        int i;
  
        if (variant->id_val == STMPE801_ID) {
-               handle_nested_irq(stmpe->irq_base);
+               int base = irq_create_mapping(stmpe->domain, 0);
+               handle_nested_irq(base);
                return IRQ_HANDLED;
        }
  
                while (status) {
                        int bit = __ffs(status);
                        int line = bank * 8 + bit;
+                       int nestedirq = irq_create_mapping(stmpe->domain, line);
  
-                       handle_nested_irq(stmpe->irq_base + line);
+                       handle_nested_irq(nestedirq);
                        status &= ~(1 << bit);
                }
  
@@@ -830,7 -827,7 +829,7 @@@ static void stmpe_irq_sync_unlock(struc
  static void stmpe_irq_mask(struct irq_data *data)
  {
        struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
-       int offset = data->irq - stmpe->irq_base;
+       int offset = data->hwirq;
        int regoffset = offset / 8;
        int mask = 1 << (offset % 8);
  
  static void stmpe_irq_unmask(struct irq_data *data)
  {
        struct stmpe *stmpe = irq_data_get_irq_chip_data(data);
-       int offset = data->irq - stmpe->irq_base;
+       int offset = data->hwirq;
        int regoffset = offset / 8;
        int mask = 1 << (offset % 8);
  
@@@ -855,43 -852,59 +854,59 @@@ static struct irq_chip stmpe_irq_chip 
        .irq_unmask             = stmpe_irq_unmask,
  };
  
- static int __devinit stmpe_irq_init(struct stmpe *stmpe)
+ static int stmpe_irq_map(struct irq_domain *d, unsigned int virq,
+                                 irq_hw_number_t hwirq)
  {
+       struct stmpe *stmpe = d->host_data;
        struct irq_chip *chip = NULL;
-       int num_irqs = stmpe->variant->num_irqs;
-       int base = stmpe->irq_base;
-       int irq;
  
        if (stmpe->variant->id_val != STMPE801_ID)
                chip = &stmpe_irq_chip;
  
-       for (irq = base; irq < base + num_irqs; irq++) {
-               irq_set_chip_data(irq, stmpe);
-               irq_set_chip_and_handler(irq, chip, handle_edge_irq);
-               irq_set_nested_thread(irq, 1);
+       irq_set_chip_data(virq, stmpe);
+       irq_set_chip_and_handler(virq, chip, handle_edge_irq);
+       irq_set_nested_thread(virq, 1);
  #ifdef CONFIG_ARM
-               set_irq_flags(irq, IRQF_VALID);
+       set_irq_flags(virq, IRQF_VALID);
  #else
-               irq_set_noprobe(irq);
+       irq_set_noprobe(virq);
  #endif
-       }
  
        return 0;
  }
  
- static void stmpe_irq_remove(struct stmpe *stmpe)
+ static void stmpe_irq_unmap(struct irq_domain *d, unsigned int virq)
  {
-       int num_irqs = stmpe->variant->num_irqs;
-       int base = stmpe->irq_base;
-       int irq;
-       for (irq = base; irq < base + num_irqs; irq++) {
  #ifdef CONFIG_ARM
-               set_irq_flags(irq, 0);
+               set_irq_flags(virq, 0);
  #endif
-               irq_set_chip_and_handler(irq, NULL, NULL);
-               irq_set_chip_data(irq, NULL);
+               irq_set_chip_and_handler(virq, NULL, NULL);
+               irq_set_chip_data(virq, NULL);
+ }
+ static struct irq_domain_ops stmpe_irq_ops = {
+         .map    = stmpe_irq_map,
+         .unmap  = stmpe_irq_unmap,
+         .xlate  = irq_domain_xlate_twocell,
+ };
+ static int __devinit stmpe_irq_init(struct stmpe *stmpe,
+                               struct device_node *np)
+ {
+       int base = 0;
+       int num_irqs = stmpe->variant->num_irqs;
+       if (!np)
+               base = stmpe->irq_base;
+       stmpe->domain = irq_domain_add_simple(np, num_irqs, base,
+                                             &stmpe_irq_ops, stmpe);
+       if (!stmpe->domain) {
+               dev_err(stmpe->dev, "Failed to create irqdomain\n");
+               return -ENOSYS;
        }
+       return 0;
  }
  
  static int __devinit stmpe_chip_init(struct stmpe *stmpe)
                        else
                                icr |= STMPE_ICR_LSB_HIGH;
                }
-               if (stmpe->pdata->irq_invert_polarity) {
-                       if (id == STMPE801_ID)
-                               icr ^= STMPE801_REG_SYS_CTRL_INT_HI;
-                       else
-                               icr ^= STMPE_ICR_LSB_HIGH;
-               }
        }
  
        if (stmpe->pdata->autosleep) {
  }
  
  static int __devinit stmpe_add_device(struct stmpe *stmpe,
-                                     struct mfd_cell *cell, int irq)
+                                     struct mfd_cell *cell)
  {
        return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1,
-                              NULL, stmpe->irq_base + irq, NULL);
+                              NULL, stmpe->irq_base, stmpe->domain);
  }
  
  static int __devinit stmpe_devices_init(struct stmpe *stmpe)
        struct stmpe_variant_info *variant = stmpe->variant;
        unsigned int platform_blocks = stmpe->pdata->blocks;
        int ret = -EINVAL;
-       int i;
+       int i, j;
  
        for (i = 0; i < variant->num_blocks; i++) {
                struct stmpe_variant_block *block = &variant->blocks[i];
                if (!(platform_blocks & block->block))
                        continue;
  
+               for (j = 0; j < block->cell->num_resources; j++) {
+                       struct resource *res =
+                               (struct resource *) &block->cell->resources[j];
+                       /* Dynamically fill in a variant's IRQ. */
+                       if (res->flags & IORESOURCE_IRQ)
+                               res->start = res->end = block->irq + j;
+               }
                platform_blocks &= ~block->block;
-               ret = stmpe_add_device(stmpe, block->cell, block->irq);
+               ret = stmpe_add_device(stmpe, block->cell);
                if (ret)
                        return ret;
        }
        return ret;
  }
  
+ void __devinit stmpe_of_probe(struct stmpe_platform_data *pdata,
+                       struct device_node *np)
+ {
+       struct device_node *child;
+       pdata->id = -1;
+       pdata->irq_trigger = IRQF_TRIGGER_NONE;
+       of_property_read_u32(np, "st,autosleep-timeout",
+                       &pdata->autosleep_timeout);
+       pdata->autosleep = (pdata->autosleep_timeout) ? true : false;
+       for_each_child_of_node(np, child) {
+               if (!strcmp(child->name, "stmpe_gpio")) {
+                       pdata->blocks |= STMPE_BLOCK_GPIO;
+               } else if (!strcmp(child->name, "stmpe_keypad")) {
+                       pdata->blocks |= STMPE_BLOCK_KEYPAD;
+               } else if (!strcmp(child->name, "stmpe_touchscreen")) {
+                       pdata->blocks |= STMPE_BLOCK_TOUCHSCREEN;
+               } else if (!strcmp(child->name, "stmpe_adc")) {
+                       pdata->blocks |= STMPE_BLOCK_ADC;
+               } else if (!strcmp(child->name, "stmpe_pwm")) {
+                       pdata->blocks |= STMPE_BLOCK_PWM;
+               } else if (!strcmp(child->name, "stmpe_rotator")) {
+                       pdata->blocks |= STMPE_BLOCK_ROTATOR;
+               }
+       }
+ }
  /* Called from client specific probe routines */
  int __devinit stmpe_probe(struct stmpe_client_info *ci, int partnum)
  {
        struct stmpe_platform_data *pdata = dev_get_platdata(ci->dev);
+       struct device_node *np = ci->dev->of_node;
        struct stmpe *stmpe;
        int ret;
  
-       if (!pdata)
-               return -EINVAL;
+       if (!pdata) {
+               if (!np)
+                       return -EINVAL;
+               pdata = devm_kzalloc(ci->dev, sizeof(*pdata), GFP_KERNEL);
+               if (!pdata)
+                       return -ENOMEM;
+               stmpe_of_probe(pdata, np);
+       }
  
-       stmpe = kzalloc(sizeof(struct stmpe), GFP_KERNEL);
+       stmpe = devm_kzalloc(ci->dev, sizeof(struct stmpe), GFP_KERNEL);
        if (!stmpe)
                return -ENOMEM;
  
                ci->init(stmpe);
  
        if (pdata->irq_over_gpio) {
-               ret = gpio_request_one(pdata->irq_gpio, GPIOF_DIR_IN, "stmpe");
+               ret = devm_gpio_request_one(ci->dev, pdata->irq_gpio,
+                               GPIOF_DIR_IN, "stmpe");
                if (ret) {
                        dev_err(stmpe->dev, "failed to request IRQ GPIO: %d\n",
                                        ret);
-                       goto out_free;
+                       return ret;
                }
  
                stmpe->irq = gpio_to_irq(pdata->irq_gpio);
                        dev_err(stmpe->dev,
                                "%s does not support no-irq mode!\n",
                                stmpe->variant->name);
-                       ret = -ENODEV;
-                       goto free_gpio;
+                       return -ENODEV;
                }
                stmpe->variant = stmpe_noirq_variant_info[stmpe->partnum];
+       } else if (pdata->irq_trigger == IRQF_TRIGGER_NONE) {
+               pdata->irq_trigger =
+                       irqd_get_trigger_type(irq_get_irq_data(stmpe->irq));
        }
  
        ret = stmpe_chip_init(stmpe);
        if (ret)
-               goto free_gpio;
+               return ret;
  
        if (stmpe->irq >= 0) {
-               ret = stmpe_irq_init(stmpe);
+               ret = stmpe_irq_init(stmpe, np);
                if (ret)
-                       goto free_gpio;
+                       return ret;
  
-               ret = request_threaded_irq(stmpe->irq, NULL, stmpe_irq,
-                               pdata->irq_trigger | IRQF_ONESHOT,
+               ret = devm_request_threaded_irq(ci->dev, stmpe->irq, NULL,
+                               stmpe_irq, pdata->irq_trigger | IRQF_ONESHOT,
                                "stmpe", stmpe);
                if (ret) {
                        dev_err(stmpe->dev, "failed to request IRQ: %d\n",
                                        ret);
-                       goto out_removeirq;
+                       return ret;
                }
        }
  
        ret = stmpe_devices_init(stmpe);
-       if (ret) {
-               dev_err(stmpe->dev, "failed to add children\n");
-               goto out_removedevs;
-       }
-       return 0;
+       if (!ret)
+               return 0;
  
- out_removedevs:
+       dev_err(stmpe->dev, "failed to add children\n");
        mfd_remove_devices(stmpe->dev);
-       if (stmpe->irq >= 0)
-               free_irq(stmpe->irq, stmpe);
- out_removeirq:
-       if (stmpe->irq >= 0)
-               stmpe_irq_remove(stmpe);
- free_gpio:
-       if (pdata->irq_over_gpio)
-               gpio_free(pdata->irq_gpio);
- out_free:
-       kfree(stmpe);
        return ret;
  }
  
@@@ -1099,16 -1143,6 +1145,6 @@@ int stmpe_remove(struct stmpe *stmpe
  {
        mfd_remove_devices(stmpe->dev);
  
-       if (stmpe->irq >= 0) {
-               free_irq(stmpe->irq, stmpe);
-               stmpe_irq_remove(stmpe);
-       }
-       if (stmpe->pdata->irq_over_gpio)
-               gpio_free(stmpe->pdata->irq_gpio);
-       kfree(stmpe);
        return 0;
  }
  
diff --combined drivers/mfd/tps65090.c
index 382a857b0dde56b1438358fad9d52550f65449c8,2eaae52cb5b8f91ff17eb2d2bc79fe335cf66139..8d12a8e00d9c97ecfbfb477bd73515749ca5e663
@@@ -25,7 -25,6 +25,6 @@@
  #include <linux/i2c.h>
  #include <linux/mfd/core.h>
  #include <linux/mfd/tps65090.h>
- #include <linux/regmap.h>
  #include <linux/err.h>
  
  #define NUM_INT_REG 2
  #define TPS65090_INT_MSK      0x2
  #define TPS65090_INT_MSK2     0x3
  
- struct tps65090_irq_data {
-       u8              mask_reg;
-       u8              mask_pos;
- };
- #define TPS65090_IRQ(_reg, _mask_pos)         \
-       {                                       \
-               .mask_reg       = (_reg),       \
-               .mask_pos       = (_mask_pos),  \
-       }
- static const struct tps65090_irq_data tps65090_irqs[] = {
-       [0]             = TPS65090_IRQ(0, 0),
-       [1]             = TPS65090_IRQ(0, 1),
-       [2]             = TPS65090_IRQ(0, 2),
-       [3]             = TPS65090_IRQ(0, 3),
-       [4]             = TPS65090_IRQ(0, 4),
-       [5]             = TPS65090_IRQ(0, 5),
-       [6]             = TPS65090_IRQ(0, 6),
-       [7]             = TPS65090_IRQ(0, 7),
-       [8]             = TPS65090_IRQ(1, 0),
-       [9]             = TPS65090_IRQ(1, 1),
-       [10]            = TPS65090_IRQ(1, 2),
-       [11]            = TPS65090_IRQ(1, 3),
-       [12]            = TPS65090_IRQ(1, 4),
-       [13]            = TPS65090_IRQ(1, 5),
-       [14]            = TPS65090_IRQ(1, 6),
-       [15]            = TPS65090_IRQ(1, 7),
- };
+ #define TPS65090_INT1_MASK_VAC_STATUS_CHANGE          1
+ #define TPS65090_INT1_MASK_VSYS_STATUS_CHANGE         2
+ #define TPS65090_INT1_MASK_BAT_STATUS_CHANGE          3
+ #define TPS65090_INT1_MASK_CHARGING_STATUS_CHANGE     4
+ #define TPS65090_INT1_MASK_CHARGING_COMPLETE          5
+ #define TPS65090_INT1_MASK_OVERLOAD_DCDC1             6
+ #define TPS65090_INT1_MASK_OVERLOAD_DCDC2             7
+ #define TPS65090_INT2_MASK_OVERLOAD_DCDC3             0
+ #define TPS65090_INT2_MASK_OVERLOAD_FET1              1
+ #define TPS65090_INT2_MASK_OVERLOAD_FET2              2
+ #define TPS65090_INT2_MASK_OVERLOAD_FET3              3
+ #define TPS65090_INT2_MASK_OVERLOAD_FET4              4
+ #define TPS65090_INT2_MASK_OVERLOAD_FET5              5
+ #define TPS65090_INT2_MASK_OVERLOAD_FET6              6
+ #define TPS65090_INT2_MASK_OVERLOAD_FET7              7
  
  static struct mfd_cell tps65090s[] = {
        {
                .name = "tps65090-pmic",
        },
        {
-               .name = "tps65090-regulator",
+               .name = "tps65090-charger",
        },
  };
  
- int tps65090_write(struct device *dev, int reg, uint8_t val)
- {
-       struct tps65090 *tps = dev_get_drvdata(dev);
-       return regmap_write(tps->rmap, reg, val);
- }
- EXPORT_SYMBOL_GPL(tps65090_write);
- int tps65090_read(struct device *dev, int reg, uint8_t *val)
- {
-       struct tps65090 *tps = dev_get_drvdata(dev);
-       unsigned int temp_val;
-       int ret;
-       ret = regmap_read(tps->rmap, reg, &temp_val);
-       if (!ret)
-               *val = temp_val;
-       return ret;
- }
- EXPORT_SYMBOL_GPL(tps65090_read);
- int tps65090_set_bits(struct device *dev, int reg, uint8_t bit_num)
- {
-       struct tps65090 *tps = dev_get_drvdata(dev);
-       return regmap_update_bits(tps->rmap, reg, BIT(bit_num), ~0u);
- }
- EXPORT_SYMBOL_GPL(tps65090_set_bits);
- int tps65090_clr_bits(struct device *dev, int reg, uint8_t bit_num)
- {
-       struct tps65090 *tps = dev_get_drvdata(dev);
-       return regmap_update_bits(tps->rmap, reg, BIT(bit_num), 0u);
- }
- EXPORT_SYMBOL_GPL(tps65090_clr_bits);
- static void tps65090_irq_lock(struct irq_data *data)
- {
-       struct tps65090 *tps65090 = irq_data_get_irq_chip_data(data);
-       mutex_lock(&tps65090->irq_lock);
- }
- static void tps65090_irq_mask(struct irq_data *irq_data)
- {
-       struct tps65090 *tps65090 = irq_data_get_irq_chip_data(irq_data);
-       unsigned int __irq = irq_data->hwirq;
-       const struct tps65090_irq_data *data = &tps65090_irqs[__irq];
-       tps65090_set_bits(tps65090->dev, (TPS65090_INT_MSK + data->mask_reg),
-               data->mask_pos);
- }
- static void tps65090_irq_unmask(struct irq_data *irq_data)
- {
-       struct tps65090 *tps65090 = irq_data_get_irq_chip_data(irq_data);
-       unsigned int __irq = irq_data->irq - tps65090->irq_base;
-       const struct tps65090_irq_data *data = &tps65090_irqs[__irq];
-       tps65090_clr_bits(tps65090->dev, (TPS65090_INT_MSK + data->mask_reg),
-               data->mask_pos);
- }
- static void tps65090_irq_sync_unlock(struct irq_data *data)
- {
-       struct tps65090 *tps65090 = irq_data_get_irq_chip_data(data);
-       mutex_unlock(&tps65090->irq_lock);
- }
- static irqreturn_t tps65090_irq(int irq, void *data)
- {
-       struct tps65090 *tps65090 = data;
-       int ret = 0;
-       u8 status, mask;
-       unsigned long int acks = 0;
-       int i;
-       for (i = 0; i < NUM_INT_REG; i++) {
-               ret = tps65090_read(tps65090->dev, TPS65090_INT_MSK + i, &mask);
-               if (ret < 0) {
-                       dev_err(tps65090->dev,
-                               "failed to read mask reg [addr:%d]\n",
-                               TPS65090_INT_MSK + i);
-                       return IRQ_NONE;
-               }
-               ret = tps65090_read(tps65090->dev, TPS65090_INT_STS + i,
-                       &status);
-               if (ret < 0) {
-                       dev_err(tps65090->dev,
-                               "failed to read status reg [addr:%d]\n",
-                                TPS65090_INT_STS + i);
-                       return IRQ_NONE;
-               }
-               if (status) {
-                       /* Ack only those interrupts which are not masked */
-                       status &= (~mask);
-                       ret = tps65090_write(tps65090->dev,
-                                       TPS65090_INT_STS + i, status);
-                       if (ret < 0) {
-                               dev_err(tps65090->dev,
-                                       "failed to write interrupt status\n");
-                               return IRQ_NONE;
-                       }
-                       acks |= (status << (i * 8));
-               }
-       }
-       for_each_set_bit(i, &acks, ARRAY_SIZE(tps65090_irqs))
-               handle_nested_irq(tps65090->irq_base + i);
-       return acks ? IRQ_HANDLED : IRQ_NONE;
- }
- static int tps65090_irq_init(struct tps65090 *tps65090, int irq,
-       int irq_base)
- {
-       int i, ret;
-       if (!irq_base) {
-               dev_err(tps65090->dev, "IRQ base not set\n");
-               return -EINVAL;
-       }
-       mutex_init(&tps65090->irq_lock);
-       for (i = 0; i < NUM_INT_REG; i++)
-               tps65090_write(tps65090->dev, TPS65090_INT_MSK + i, 0xFF);
-       for (i = 0; i < NUM_INT_REG; i++)
-               tps65090_write(tps65090->dev, TPS65090_INT_STS + i, 0xff);
-       tps65090->irq_base = irq_base;
-       tps65090->irq_chip.name = "tps65090";
-       tps65090->irq_chip.irq_mask = tps65090_irq_mask;
-       tps65090->irq_chip.irq_unmask = tps65090_irq_unmask;
-       tps65090->irq_chip.irq_bus_lock = tps65090_irq_lock;
-       tps65090->irq_chip.irq_bus_sync_unlock = tps65090_irq_sync_unlock;
-       for (i = 0; i < ARRAY_SIZE(tps65090_irqs); i++) {
-               int __irq = i + tps65090->irq_base;
-               irq_set_chip_data(__irq, tps65090);
-               irq_set_chip_and_handler(__irq, &tps65090->irq_chip,
-                                        handle_simple_irq);
-               irq_set_nested_thread(__irq, 1);
- #ifdef CONFIG_ARM
-               set_irq_flags(__irq, IRQF_VALID);
- #endif
-       }
-       ret = request_threaded_irq(irq, NULL, tps65090_irq, IRQF_ONESHOT,
-                               "tps65090", tps65090);
-       if (!ret) {
-               device_init_wakeup(tps65090->dev, 1);
-               enable_irq_wake(irq);
-       }
+ static const struct regmap_irq tps65090_irqs[] = {
+       /* INT1 IRQs*/
+       [TPS65090_IRQ_VAC_STATUS_CHANGE] = {
+                       .mask = TPS65090_INT1_MASK_VAC_STATUS_CHANGE,
+       },
+       [TPS65090_IRQ_VSYS_STATUS_CHANGE] = {
+                       .mask = TPS65090_INT1_MASK_VSYS_STATUS_CHANGE,
+       },
+       [TPS65090_IRQ_BAT_STATUS_CHANGE] = {
+                       .mask = TPS65090_INT1_MASK_BAT_STATUS_CHANGE,
+       },
+       [TPS65090_IRQ_CHARGING_STATUS_CHANGE] = {
+                       .mask = TPS65090_INT1_MASK_CHARGING_STATUS_CHANGE,
+       },
+       [TPS65090_IRQ_CHARGING_COMPLETE] = {
+                       .mask = TPS65090_INT1_MASK_CHARGING_COMPLETE,
+       },
+       [TPS65090_IRQ_OVERLOAD_DCDC1] = {
+                       .mask = TPS65090_INT1_MASK_OVERLOAD_DCDC1,
+       },
+       [TPS65090_IRQ_OVERLOAD_DCDC2] = {
+                       .mask = TPS65090_INT1_MASK_OVERLOAD_DCDC2,
+       },
+       /* INT2 IRQs*/
+       [TPS65090_IRQ_OVERLOAD_DCDC3] = {
+                       .reg_offset = 1,
+                       .mask = TPS65090_INT2_MASK_OVERLOAD_DCDC3,
+       },
+       [TPS65090_IRQ_OVERLOAD_FET1] = {
+                       .reg_offset = 1,
+                       .mask = TPS65090_INT2_MASK_OVERLOAD_FET1,
+       },
+       [TPS65090_IRQ_OVERLOAD_FET2] = {
+                       .reg_offset = 1,
+                       .mask = TPS65090_INT2_MASK_OVERLOAD_FET2,
+       },
+       [TPS65090_IRQ_OVERLOAD_FET3] = {
+                       .reg_offset = 1,
+                       .mask = TPS65090_INT2_MASK_OVERLOAD_FET3,
+       },
+       [TPS65090_IRQ_OVERLOAD_FET4] = {
+                       .reg_offset = 1,
+                       .mask = TPS65090_INT2_MASK_OVERLOAD_FET4,
+       },
+       [TPS65090_IRQ_OVERLOAD_FET5] = {
+                       .reg_offset = 1,
+                       .mask = TPS65090_INT2_MASK_OVERLOAD_FET5,
+       },
+       [TPS65090_IRQ_OVERLOAD_FET6] = {
+                       .reg_offset = 1,
+                       .mask = TPS65090_INT2_MASK_OVERLOAD_FET6,
+       },
+       [TPS65090_IRQ_OVERLOAD_FET7] = {
+                       .reg_offset = 1,
+                       .mask = TPS65090_INT2_MASK_OVERLOAD_FET7,
+       },
+ };
  
-       return ret;
- }
+ static struct regmap_irq_chip tps65090_irq_chip = {
+       .name = "tps65090",
+       .irqs = tps65090_irqs,
+       .num_irqs = ARRAY_SIZE(tps65090_irqs),
+       .num_regs = NUM_INT_REG,
+       .status_base = TPS65090_INT_STS,
+       .mask_base = TPS65090_INT_MSK,
+       .mask_invert = true,
+ };
  
  static bool is_volatile_reg(struct device *dev, unsigned int reg)
  {
-       if (reg == TPS65090_INT_STS)
+       if ((reg == TPS65090_INT_STS) || (reg == TPS65090_INT_STS2))
                return true;
        else
                return false;
@@@ -251,7 -148,7 +148,7 @@@ static const struct regmap_config tps65
        .volatile_reg = is_volatile_reg,
  };
  
 -static int __devinit tps65090_i2c_probe(struct i2c_client *client,
 +static int tps65090_i2c_probe(struct i2c_client *client,
                                        const struct i2c_device_id *id)
  {
        struct tps65090_platform_data *pdata = client->dev.platform_data;
                return -EINVAL;
        }
  
-       tps65090 = devm_kzalloc(&client->dev, sizeof(struct tps65090),
-               GFP_KERNEL);
-       if (tps65090 == NULL)
+       tps65090 = devm_kzalloc(&client->dev, sizeof(*tps65090), GFP_KERNEL);
+       if (!tps65090) {
+               dev_err(&client->dev, "mem alloc for tps65090 failed\n");
                return -ENOMEM;
+       }
  
-       tps65090->client = client;
        tps65090->dev = &client->dev;
        i2c_set_clientdata(client, tps65090);
  
-       mutex_init(&tps65090->lock);
-       if (client->irq) {
-               ret = tps65090_irq_init(tps65090, client->irq, pdata->irq_base);
-               if (ret) {
-                       dev_err(&client->dev, "IRQ init failed with err: %d\n",
-                               ret);
-                       goto err_exit;
-               }
-       }
-       tps65090->rmap = devm_regmap_init_i2c(tps65090->client,
-                                             &tps65090_regmap_config);
+       tps65090->rmap = devm_regmap_init_i2c(client, &tps65090_regmap_config);
        if (IS_ERR(tps65090->rmap)) {
                ret = PTR_ERR(tps65090->rmap);
                dev_err(&client->dev, "regmap_init failed with err: %d\n", ret);
-               goto err_irq_exit;
+               return ret;
+       }
+       if (client->irq) {
+               ret = regmap_add_irq_chip(tps65090->rmap, client->irq,
+                       IRQF_ONESHOT | IRQF_TRIGGER_LOW, pdata->irq_base,
+                       &tps65090_irq_chip, &tps65090->irq_data);
+                       if (ret) {
+                               dev_err(&client->dev,
+                                       "IRQ init failed with err: %d\n", ret);
+                       return ret;
+               }
        }
  
        ret = mfd_add_devices(tps65090->dev, -1, tps65090s,
-                             ARRAY_SIZE(tps65090s), NULL, 0, NULL);
+               ARRAY_SIZE(tps65090s), NULL,
+               regmap_irq_chip_get_base(tps65090->irq_data), NULL);
        if (ret) {
                dev_err(&client->dev, "add mfd devices failed with err: %d\n",
                        ret);
  
  err_irq_exit:
        if (client->irq)
-               free_irq(client->irq, tps65090);
- err_exit:
+               regmap_del_irq_chip(client->irq, tps65090->irq_data);
        return ret;
  }
  
 -static int __devexit tps65090_i2c_remove(struct i2c_client *client)
 +static int tps65090_i2c_remove(struct i2c_client *client)
  {
        struct tps65090 *tps65090 = i2c_get_clientdata(client);
  
        mfd_remove_devices(tps65090->dev);
        if (client->irq)
-               free_irq(client->irq, tps65090);
+               regmap_del_irq_chip(client->irq, tps65090->irq_data);
  
        return 0;
  }
@@@ -354,7 -250,7 +250,7 @@@ static struct i2c_driver tps65090_drive
                .pm     = &tps65090_pm_ops,
        },
        .probe          = tps65090_i2c_probe,
 -      .remove         = __devexit_p(tps65090_i2c_remove),
 +      .remove         = tps65090_i2c_remove,
        .id_table       = tps65090_id_table,
  };
  
diff --combined drivers/mfd/tps65217.c
index e14e252e3473fc7081a06475f1b1b390662ee86b,c7f17d86db78dac5a68601b9b132a7e3a6b09754..b8f48647661e7db4a58612208bb51ed8957d3fab
@@@ -153,13 -153,14 +153,14 @@@ static const struct of_device_id tps652
        { /* sentinel */ },
  };
  
 -static int __devinit tps65217_probe(struct i2c_client *client,
 +static int tps65217_probe(struct i2c_client *client,
                                const struct i2c_device_id *ids)
  {
        struct tps65217 *tps;
        unsigned int version;
        unsigned int chip_id = ids->driver_data;
        const struct of_device_id *match;
+       bool status_off = false;
        int ret;
  
        if (client->dev.of_node) {
                        return -EINVAL;
                }
                chip_id = (unsigned int)match->data;
+               status_off = of_property_read_bool(client->dev.of_node,
+                                       "ti,pmic-shutdown-controller");
        }
  
        if (!chip_id) {
                return ret;
        }
  
+       /* Set the PMIC to shutdown on PWR_EN toggle */
+       if (status_off) {
+               ret = tps65217_set_bits(tps, TPS65217_REG_STATUS,
+                               TPS65217_STATUS_OFF, TPS65217_STATUS_OFF,
+                               TPS65217_PROTECT_NONE);
+               if (ret)
+                       dev_warn(tps->dev, "unable to set the status OFF\n");
+       }
        dev_info(tps->dev, "TPS65217 ID %#x version 1.%d\n",
                        (version & TPS65217_CHIPID_CHIP_MASK) >> 4,
                        version & TPS65217_CHIPID_REV_MASK);
        return 0;
  }
  
 -static int __devexit tps65217_remove(struct i2c_client *client)
 +static int tps65217_remove(struct i2c_client *client)
  {
        struct tps65217 *tps = i2c_get_clientdata(client);
  
@@@ -237,7 -249,7 +249,7 @@@ static struct i2c_driver tps65217_drive
        },
        .id_table       = tps65217_id_table,
        .probe          = tps65217_probe,
 -      .remove         = __devexit_p(tps65217_remove),
 +      .remove         = tps65217_remove,
  };
  
  static int __init tps65217_init(void)
diff --combined drivers/mfd/tps6586x.c
index 87ba7ada3bbc8a72392745cdc3400fb541e8056c,c11539a80fc589736a02539d5ab9d468e6a1d513..721b9186a5d1cdeb3679bbd34ba786d5d9e996e8
  
  #include <linux/interrupt.h>
  #include <linux/irq.h>
+ #include <linux/irqdomain.h>
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/mutex.h>
  #include <linux/slab.h>
  #include <linux/err.h>
  #include <linux/i2c.h>
+ #include <linux/platform_device.h>
  #include <linux/regmap.h>
 -#include <linux/regulator/of_regulator.h>
 -#include <linux/regulator/machine.h>
  
  #include <linux/mfd/core.h>
  #include <linux/mfd/tps6586x.h>
@@@ -92,15 -96,22 +94,25 @@@ static const struct tps6586x_irq_data t
        [TPS6586X_INT_RTC_ALM2] = TPS6586X_IRQ(TPS6586X_INT_MASK4, 1 << 1),
  };
  
+ static struct resource tps6586x_rtc_resources[] = {
+       {
+               .start  = TPS6586X_INT_RTC_ALM1,
+               .end    = TPS6586X_INT_RTC_ALM1,
+               .flags  = IORESOURCE_IRQ,
+       },
+ };
  static struct mfd_cell tps6586x_cell[] = {
        {
                .name = "tps6586x-gpio",
        },
 +      {
 +              .name = "tps6586x-pmic",
 +      },
        {
                .name = "tps6586x-rtc",
+               .num_resources = ARRAY_SIZE(tps6586x_rtc_resources),
+               .resources = &tps6586x_rtc_resources[0],
        },
        {
                .name = "tps6586x-onkey",
@@@ -117,6 -128,7 +129,7 @@@ struct tps6586x 
        int                     irq_base;
        u32                     irq_en;
        u8                      mask_reg[5];
+       struct irq_domain       *irq_domain;
  };
  
  static inline struct tps6586x *dev_to_tps6586x(struct device *dev)
@@@ -185,6 -197,14 +198,14 @@@ int tps6586x_update(struct device *dev
  }
  EXPORT_SYMBOL_GPL(tps6586x_update);
  
+ int tps6586x_irq_get_virq(struct device *dev, int irq)
+ {
+       struct tps6586x *tps6586x = dev_to_tps6586x(dev);
+       return irq_create_mapping(tps6586x->irq_domain, irq);
+ }
+ EXPORT_SYMBOL_GPL(tps6586x_irq_get_virq);
  static int __remove_subdev(struct device *dev, void *unused)
  {
        platform_device_unregister(to_platform_device(dev));
@@@ -206,7 -226,7 +227,7 @@@ static void tps6586x_irq_lock(struct ir
  static void tps6586x_irq_enable(struct irq_data *irq_data)
  {
        struct tps6586x *tps6586x = irq_data_get_irq_chip_data(irq_data);
-       unsigned int __irq = irq_data->irq - tps6586x->irq_base;
+       unsigned int __irq = irq_data->hwirq;
        const struct tps6586x_irq_data *data = &tps6586x_irqs[__irq];
  
        tps6586x->mask_reg[data->mask_reg] &= ~data->mask_mask;
@@@ -217,7 -237,7 +238,7 @@@ static void tps6586x_irq_disable(struc
  {
        struct tps6586x *tps6586x = irq_data_get_irq_chip_data(irq_data);
  
-       unsigned int __irq = irq_data->irq - tps6586x->irq_base;
+       unsigned int __irq = irq_data->hwirq;
        const struct tps6586x_irq_data *data = &tps6586x_irqs[__irq];
  
        tps6586x->mask_reg[data->mask_reg] |= data->mask_mask;
@@@ -240,6 -260,39 +261,39 @@@ static void tps6586x_irq_sync_unlock(st
        mutex_unlock(&tps6586x->irq_lock);
  }
  
+ static struct irq_chip tps6586x_irq_chip = {
+       .name = "tps6586x",
+       .irq_bus_lock = tps6586x_irq_lock,
+       .irq_bus_sync_unlock = tps6586x_irq_sync_unlock,
+       .irq_disable = tps6586x_irq_disable,
+       .irq_enable = tps6586x_irq_enable,
+ };
+ static int tps6586x_irq_map(struct irq_domain *h, unsigned int virq,
+                               irq_hw_number_t hw)
+ {
+       struct tps6586x *tps6586x = h->host_data;
+       irq_set_chip_data(virq, tps6586x);
+       irq_set_chip_and_handler(virq, &tps6586x_irq_chip, handle_simple_irq);
+       irq_set_nested_thread(virq, 1);
+       /* ARM needs us to explicitly flag the IRQ as valid
+        * and will set them noprobe when we do so. */
+ #ifdef CONFIG_ARM
+       set_irq_flags(virq, IRQF_VALID);
+ #else
+       irq_set_noprobe(virq);
+ #endif
+       return 0;
+ }
+ static struct irq_domain_ops tps6586x_domain_ops = {
+       .map    = tps6586x_irq_map,
+       .xlate  = irq_domain_xlate_twocell,
+ };
  static irqreturn_t tps6586x_irq(int irq, void *data)
  {
        struct tps6586x *tps6586x = data;
                int i = __ffs(acks);
  
                if (tps6586x->irq_en & (1 << i))
-                       handle_nested_irq(tps6586x->irq_base + i);
+                       handle_nested_irq(
+                               irq_find_mapping(tps6586x->irq_domain, i));
  
                acks &= ~(1 << i);
        }
        return IRQ_HANDLED;
  }
  
 -static int __devinit tps6586x_irq_init(struct tps6586x *tps6586x, int irq,
 +static int tps6586x_irq_init(struct tps6586x *tps6586x, int irq,
                                       int irq_base)
  {
        int i, ret;
        u8 tmp[4];
-       if (!irq_base) {
-               dev_warn(tps6586x->dev, "No interrupt support on IRQ base\n");
-               return -EINVAL;
-       }
+       int new_irq_base;
+       int irq_num = ARRAY_SIZE(tps6586x_irqs);
  
        mutex_init(&tps6586x->irq_lock);
        for (i = 0; i < 5; i++) {
  
        tps6586x_reads(tps6586x->dev, TPS6586X_INT_ACK1, sizeof(tmp), tmp);
  
-       tps6586x->irq_base = irq_base;
-       tps6586x->irq_chip.name = "tps6586x";
-       tps6586x->irq_chip.irq_enable = tps6586x_irq_enable;
-       tps6586x->irq_chip.irq_disable = tps6586x_irq_disable;
-       tps6586x->irq_chip.irq_bus_lock = tps6586x_irq_lock;
-       tps6586x->irq_chip.irq_bus_sync_unlock = tps6586x_irq_sync_unlock;
-       for (i = 0; i < ARRAY_SIZE(tps6586x_irqs); i++) {
-               int __irq = i + tps6586x->irq_base;
-               irq_set_chip_data(__irq, tps6586x);
-               irq_set_chip_and_handler(__irq, &tps6586x->irq_chip,
-                                        handle_simple_irq);
-               irq_set_nested_thread(__irq, 1);
- #ifdef CONFIG_ARM
-               set_irq_flags(__irq, IRQF_VALID);
- #endif
+       if  (irq_base > 0) {
+               new_irq_base = irq_alloc_descs(irq_base, 0, irq_num, -1);
+               if (new_irq_base < 0) {
+                       dev_err(tps6586x->dev,
+                               "Failed to alloc IRQs: %d\n", new_irq_base);
+                       return new_irq_base;
+               }
+       } else {
+               new_irq_base = 0;
        }
  
+       tps6586x->irq_domain = irq_domain_add_simple(tps6586x->dev->of_node,
+                               irq_num, new_irq_base, &tps6586x_domain_ops,
+                               tps6586x);
+       if (!tps6586x->irq_domain) {
+               dev_err(tps6586x->dev, "Failed to create IRQ domain\n");
+               return -ENOMEM;
+       }
        ret = request_threaded_irq(irq, NULL, tps6586x_irq, IRQF_ONESHOT,
                                   "tps6586x", tps6586x);
  
        return ret;
  }
  
 -static int __devinit tps6586x_add_subdevs(struct tps6586x *tps6586x,
 +static int tps6586x_add_subdevs(struct tps6586x *tps6586x,
                                          struct tps6586x_platform_data *pdata)
  {
        struct tps6586x_subdev_info *subdev;
@@@ -351,19 -401,80 +402,19 @@@ failed
  }
  
  #ifdef CONFIG_OF
 -static struct of_regulator_match tps6586x_matches[] = {
 -      { .name = "sys",     .driver_data = (void *)TPS6586X_ID_SYS     },
 -      { .name = "sm0",     .driver_data = (void *)TPS6586X_ID_SM_0    },
 -      { .name = "sm1",     .driver_data = (void *)TPS6586X_ID_SM_1    },
 -      { .name = "sm2",     .driver_data = (void *)TPS6586X_ID_SM_2    },
 -      { .name = "ldo0",    .driver_data = (void *)TPS6586X_ID_LDO_0   },
 -      { .name = "ldo1",    .driver_data = (void *)TPS6586X_ID_LDO_1   },
 -      { .name = "ldo2",    .driver_data = (void *)TPS6586X_ID_LDO_2   },
 -      { .name = "ldo3",    .driver_data = (void *)TPS6586X_ID_LDO_3   },
 -      { .name = "ldo4",    .driver_data = (void *)TPS6586X_ID_LDO_4   },
 -      { .name = "ldo5",    .driver_data = (void *)TPS6586X_ID_LDO_5   },
 -      { .name = "ldo6",    .driver_data = (void *)TPS6586X_ID_LDO_6   },
 -      { .name = "ldo7",    .driver_data = (void *)TPS6586X_ID_LDO_7   },
 -      { .name = "ldo8",    .driver_data = (void *)TPS6586X_ID_LDO_8   },
 -      { .name = "ldo9",    .driver_data = (void *)TPS6586X_ID_LDO_9   },
 -      { .name = "ldo_rtc", .driver_data = (void *)TPS6586X_ID_LDO_RTC },
 -};
 -
  static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *client)
  {
 -      const unsigned int num = ARRAY_SIZE(tps6586x_matches);
        struct device_node *np = client->dev.of_node;
        struct tps6586x_platform_data *pdata;
 -      struct tps6586x_subdev_info *devs;
 -      struct device_node *regs;
 -      const char *sys_rail_name = NULL;
 -      unsigned int count;
 -      unsigned int i, j;
 -      int err;
 -
 -      regs = of_find_node_by_name(np, "regulators");
 -      if (!regs)
 -              return NULL;
 -
 -      err = of_regulator_match(&client->dev, regs, tps6586x_matches, num);
 -      if (err < 0) {
 -              of_node_put(regs);
 -              return NULL;
 -      }
 -
 -      of_node_put(regs);
 -      count = err;
 -
 -      devs = devm_kzalloc(&client->dev, count * sizeof(*devs), GFP_KERNEL);
 -      if (!devs)
 -              return NULL;
 -
 -      for (i = 0, j = 0; i < num && j < count; i++) {
 -              struct regulator_init_data *reg_idata;
 -
 -              if (!tps6586x_matches[i].init_data)
 -                      continue;
 -
 -              reg_idata  = tps6586x_matches[i].init_data;
 -              devs[j].name = "tps6586x-regulator";
 -              devs[j].platform_data = tps6586x_matches[i].init_data;
 -              devs[j].id = (int)tps6586x_matches[i].driver_data;
 -              if (devs[j].id == TPS6586X_ID_SYS)
 -                      sys_rail_name = reg_idata->constraints.name;
 -
 -              if ((devs[j].id == TPS6586X_ID_LDO_5) ||
 -                      (devs[j].id == TPS6586X_ID_LDO_RTC))
 -                      reg_idata->supply_regulator = sys_rail_name;
 -
 -              devs[j].of_node = tps6586x_matches[i].of_node;
 -              j++;
 -      }
  
        pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
 -      if (!pdata)
 +      if (!pdata) {
 +              dev_err(&client->dev, "Memory allocation failed\n");
                return NULL;
 +      }
  
 -      pdata->num_subdevs = count;
 -      pdata->subdevs = devs;
 +      pdata->num_subdevs = 0;
 +      pdata->subdevs = NULL;
        pdata->gpio_base = -1;
        pdata->irq_base = -1;
        pdata->pm_off = of_property_read_bool(np, "ti,system-power-controller");
@@@ -408,7 -519,7 +459,7 @@@ static void tps6586x_power_off(void
        tps6586x_set_bits(tps6586x_dev, TPS6586X_SUPPLYENE, SLEEP_MODE_BIT);
  }
  
 -static int __devinit tps6586x_i2c_probe(struct i2c_client *client,
 +static int tps6586x_i2c_probe(struct i2c_client *client,
                                        const struct i2c_device_id *id)
  {
        struct tps6586x_platform_data *pdata = client->dev.platform_data;
  
        ret = mfd_add_devices(tps6586x->dev, -1,
                              tps6586x_cell, ARRAY_SIZE(tps6586x_cell),
-                             NULL, 0, NULL);
+                             NULL, 0, tps6586x->irq_domain);
        if (ret < 0) {
                dev_err(&client->dev, "mfd_add_devices failed: %d\n", ret);
                goto err_mfd_add;
@@@ -488,7 -599,7 +539,7 @@@ err_mfd_add
        return ret;
  }
  
 -static int __devexit tps6586x_i2c_remove(struct i2c_client *client)
 +static int tps6586x_i2c_remove(struct i2c_client *client)
  {
        struct tps6586x *tps6586x = i2c_get_clientdata(client);
  
@@@ -512,7 -623,7 +563,7 @@@ static struct i2c_driver tps6586x_drive
                .of_match_table = of_match_ptr(tps6586x_of_match),
        },
        .probe          = tps6586x_i2c_probe,
 -      .remove         = __devexit_p(tps6586x_i2c_remove),
 +      .remove         = tps6586x_i2c_remove,
        .id_table       = tps6586x_id_table,
  };
  
diff --combined drivers/mfd/tps65910.c
index ce054654f5bbdd0e03b41063e4c2c1a4f193a2f1,d5ef3a5b16b1c30be7d8181f203e29174aeb3ac2..d792772048358dbc9857cd3090d693a951d48713
@@@ -19,6 -19,9 +19,9 @@@
  #include <linux/err.h>
  #include <linux/slab.h>
  #include <linux/i2c.h>
+ #include <linux/interrupt.h>
+ #include <linux/irq.h>
+ #include <linux/irqdomain.h>
  #include <linux/mfd/core.h>
  #include <linux/regmap.h>
  #include <linux/mfd/tps65910.h>
@@@ -50,6 -53,219 +53,219 @@@ static struct mfd_cell tps65910s[] = 
  };
  
  
+ static const struct regmap_irq tps65911_irqs[] = {
+       /* INT_STS */
+       [TPS65911_IRQ_PWRHOLD_F] = {
+               .mask = INT_MSK_PWRHOLD_F_IT_MSK_MASK,
+               .reg_offset = 0,
+       },
+       [TPS65911_IRQ_VBAT_VMHI] = {
+               .mask = INT_MSK_VMBHI_IT_MSK_MASK,
+               .reg_offset = 0,
+       },
+       [TPS65911_IRQ_PWRON] = {
+               .mask = INT_MSK_PWRON_IT_MSK_MASK,
+               .reg_offset = 0,
+       },
+       [TPS65911_IRQ_PWRON_LP] = {
+               .mask = INT_MSK_PWRON_LP_IT_MSK_MASK,
+               .reg_offset = 0,
+       },
+       [TPS65911_IRQ_PWRHOLD_R] = {
+               .mask = INT_MSK_PWRHOLD_R_IT_MSK_MASK,
+               .reg_offset = 0,
+       },
+       [TPS65911_IRQ_HOTDIE] = {
+               .mask = INT_MSK_HOTDIE_IT_MSK_MASK,
+               .reg_offset = 0,
+       },
+       [TPS65911_IRQ_RTC_ALARM] = {
+               .mask = INT_MSK_RTC_ALARM_IT_MSK_MASK,
+               .reg_offset = 0,
+       },
+       [TPS65911_IRQ_RTC_PERIOD] = {
+               .mask = INT_MSK_RTC_PERIOD_IT_MSK_MASK,
+               .reg_offset = 0,
+       },
+       /* INT_STS2 */
+       [TPS65911_IRQ_GPIO0_R] = {
+               .mask = INT_MSK2_GPIO0_R_IT_MSK_MASK,
+               .reg_offset = 1,
+       },
+       [TPS65911_IRQ_GPIO0_F] = {
+               .mask = INT_MSK2_GPIO0_F_IT_MSK_MASK,
+               .reg_offset = 1,
+       },
+       [TPS65911_IRQ_GPIO1_R] = {
+               .mask = INT_MSK2_GPIO1_R_IT_MSK_MASK,
+               .reg_offset = 1,
+       },
+       [TPS65911_IRQ_GPIO1_F] = {
+               .mask = INT_MSK2_GPIO1_F_IT_MSK_MASK,
+               .reg_offset = 1,
+       },
+       [TPS65911_IRQ_GPIO2_R] = {
+               .mask = INT_MSK2_GPIO2_R_IT_MSK_MASK,
+               .reg_offset = 1,
+       },
+       [TPS65911_IRQ_GPIO2_F] = {
+               .mask = INT_MSK2_GPIO2_F_IT_MSK_MASK,
+               .reg_offset = 1,
+       },
+       [TPS65911_IRQ_GPIO3_R] = {
+               .mask = INT_MSK2_GPIO3_R_IT_MSK_MASK,
+               .reg_offset = 1,
+       },
+       [TPS65911_IRQ_GPIO3_F] = {
+               .mask = INT_MSK2_GPIO3_F_IT_MSK_MASK,
+               .reg_offset = 1,
+       },
+       /* INT_STS2 */
+       [TPS65911_IRQ_GPIO4_R] = {
+               .mask = INT_MSK3_GPIO4_R_IT_MSK_MASK,
+               .reg_offset = 2,
+       },
+       [TPS65911_IRQ_GPIO4_F] = {
+               .mask = INT_MSK3_GPIO4_F_IT_MSK_MASK,
+               .reg_offset = 2,
+       },
+       [TPS65911_IRQ_GPIO5_R] = {
+               .mask = INT_MSK3_GPIO5_R_IT_MSK_MASK,
+               .reg_offset = 2,
+       },
+       [TPS65911_IRQ_GPIO5_F] = {
+               .mask = INT_MSK3_GPIO5_F_IT_MSK_MASK,
+               .reg_offset = 2,
+       },
+       [TPS65911_IRQ_WTCHDG] = {
+               .mask = INT_MSK3_WTCHDG_IT_MSK_MASK,
+               .reg_offset = 2,
+       },
+       [TPS65911_IRQ_VMBCH2_H] = {
+               .mask = INT_MSK3_VMBCH2_H_IT_MSK_MASK,
+               .reg_offset = 2,
+       },
+       [TPS65911_IRQ_VMBCH2_L] = {
+               .mask = INT_MSK3_VMBCH2_L_IT_MSK_MASK,
+               .reg_offset = 2,
+       },
+       [TPS65911_IRQ_PWRDN] = {
+               .mask = INT_MSK3_PWRDN_IT_MSK_MASK,
+               .reg_offset = 2,
+       },
+ };
+ static const struct regmap_irq tps65910_irqs[] = {
+       /* INT_STS */
+       [TPS65910_IRQ_VBAT_VMBDCH] = {
+               .mask = TPS65910_INT_MSK_VMBDCH_IT_MSK_MASK,
+               .reg_offset = 0,
+       },
+       [TPS65910_IRQ_VBAT_VMHI] = {
+               .mask = TPS65910_INT_MSK_VMBHI_IT_MSK_MASK,
+               .reg_offset = 0,
+       },
+       [TPS65910_IRQ_PWRON] = {
+               .mask = TPS65910_INT_MSK_PWRON_IT_MSK_MASK,
+               .reg_offset = 0,
+       },
+       [TPS65910_IRQ_PWRON_LP] = {
+               .mask = TPS65910_INT_MSK_PWRON_LP_IT_MSK_MASK,
+               .reg_offset = 0,
+       },
+       [TPS65910_IRQ_PWRHOLD] = {
+               .mask = TPS65910_INT_MSK_PWRHOLD_IT_MSK_MASK,
+               .reg_offset = 0,
+       },
+       [TPS65910_IRQ_HOTDIE] = {
+               .mask = TPS65910_INT_MSK_HOTDIE_IT_MSK_MASK,
+               .reg_offset = 0,
+       },
+       [TPS65910_IRQ_RTC_ALARM] = {
+               .mask = TPS65910_INT_MSK_RTC_ALARM_IT_MSK_MASK,
+               .reg_offset = 0,
+       },
+       [TPS65910_IRQ_RTC_PERIOD] = {
+               .mask = TPS65910_INT_MSK_RTC_PERIOD_IT_MSK_MASK,
+               .reg_offset = 0,
+       },
+       /* INT_STS2 */
+       [TPS65910_IRQ_GPIO_R] = {
+               .mask = TPS65910_INT_MSK2_GPIO0_F_IT_MSK_MASK,
+               .reg_offset = 1,
+       },
+       [TPS65910_IRQ_GPIO_F] = {
+               .mask = TPS65910_INT_MSK2_GPIO0_R_IT_MSK_MASK,
+               .reg_offset = 1,
+       },
+ };
+ static struct regmap_irq_chip tps65911_irq_chip = {
+       .name = "tps65910",
+       .irqs = tps65911_irqs,
+       .num_irqs = ARRAY_SIZE(tps65911_irqs),
+       .num_regs = 3,
+       .irq_reg_stride = 2,
+       .status_base = TPS65910_INT_STS,
+       .mask_base = TPS65910_INT_MSK,
+       .ack_base = TPS65910_INT_STS,
+ };
+ static struct regmap_irq_chip tps65910_irq_chip = {
+       .name = "tps65910",
+       .irqs = tps65910_irqs,
+       .num_irqs = ARRAY_SIZE(tps65910_irqs),
+       .num_regs = 2,
+       .irq_reg_stride = 2,
+       .status_base = TPS65910_INT_STS,
+       .mask_base = TPS65910_INT_MSK,
+       .ack_base = TPS65910_INT_STS,
+ };
+ static int tps65910_irq_init(struct tps65910 *tps65910, int irq,
+                   struct tps65910_platform_data *pdata)
+ {
+       int ret = 0;
+       static struct regmap_irq_chip *tps6591x_irqs_chip;
+       if (!irq) {
+               dev_warn(tps65910->dev, "No interrupt support, no core IRQ\n");
+               return -EINVAL;
+       }
+       if (!pdata) {
+               dev_warn(tps65910->dev, "No interrupt support, no pdata\n");
+               return -EINVAL;
+       }
+       switch (tps65910_chip_id(tps65910)) {
+       case TPS65910:
+               tps6591x_irqs_chip = &tps65910_irq_chip;
+               break;
+       case TPS65911:
+               tps6591x_irqs_chip = &tps65911_irq_chip;
+               break;
+       }
+       tps65910->chip_irq = irq;
+       ret = regmap_add_irq_chip(tps65910->regmap, tps65910->chip_irq,
+               IRQF_ONESHOT, pdata->irq_base,
+               tps6591x_irqs_chip, &tps65910->irq_data);
+       if (ret < 0)
+               dev_warn(tps65910->dev, "Failed to add irq_chip %d\n", ret);
+       return ret;
+ }
+ static int tps65910_irq_exit(struct tps65910 *tps65910)
+ {
+       if (tps65910->chip_irq > 0)
+               regmap_del_irq_chip(tps65910->chip_irq, tps65910->irq_data);
+       return 0;
+ }
  static bool is_volatile_reg(struct device *dev, unsigned int reg)
  {
        struct tps65910 *tps65910 = dev_get_drvdata(dev);
@@@ -78,7 -294,7 +294,7 @@@ static const struct regmap_config tps65
        .cache_type = REGCACHE_RBTREE,
  };
  
 -static int __devinit tps65910_ck32k_init(struct tps65910 *tps65910,
 +static int tps65910_ck32k_init(struct tps65910 *tps65910,
                                        struct tps65910_board *pmic_pdata)
  {
        int ret;
        return 0;
  }
  
 -static int __devinit tps65910_sleepinit(struct tps65910 *tps65910,
 +static int tps65910_sleepinit(struct tps65910 *tps65910,
                struct tps65910_board *pmic_pdata)
  {
        struct device *dev = NULL;
@@@ -237,7 -453,7 +453,7 @@@ static void tps65910_power_off(void
                        DEVCTRL_DEV_ON_MASK);
  }
  
 -static __devinit int tps65910_i2c_probe(struct i2c_client *i2c,
 +static int tps65910_i2c_probe(struct i2c_client *i2c,
                                        const struct i2c_device_id *id)
  {
        struct tps65910 *tps65910;
        tps65910->dev = &i2c->dev;
        tps65910->i2c_client = i2c;
        tps65910->id = chip_id;
-       mutex_init(&tps65910->io_mutex);
  
        tps65910->regmap = devm_regmap_init_i2c(i2c, &tps65910_regmap_config);
        if (IS_ERR(tps65910->regmap)) {
                return ret;
        }
  
-       ret = mfd_add_devices(tps65910->dev, -1,
-                             tps65910s, ARRAY_SIZE(tps65910s),
-                             NULL, 0, NULL);
-       if (ret < 0) {
-               dev_err(&i2c->dev, "mfd_add_devices failed: %d\n", ret);
-               return ret;
-       }
        init_data->irq = pmic_plat_data->irq;
        init_data->irq_base = pmic_plat_data->irq_base;
  
                pm_power_off = tps65910_power_off;
        }
  
+       ret = mfd_add_devices(tps65910->dev, -1,
+                             tps65910s, ARRAY_SIZE(tps65910s),
+                             NULL, 0,
+                             regmap_irq_get_domain(tps65910->irq_data));
+       if (ret < 0) {
+               dev_err(&i2c->dev, "mfd_add_devices failed: %d\n", ret);
+               return ret;
+       }
        return ret;
  }
  
 -static __devexit int tps65910_i2c_remove(struct i2c_client *i2c)
 +static int tps65910_i2c_remove(struct i2c_client *i2c)
  {
        struct tps65910 *tps65910 = i2c_get_clientdata(i2c);
  
@@@ -327,7 -543,7 +543,7 @@@ static struct i2c_driver tps65910_i2c_d
                   .of_match_table = of_match_ptr(tps65910_of_match),
        },
        .probe = tps65910_i2c_probe,
 -      .remove = __devexit_p(tps65910_i2c_remove),
 +      .remove = tps65910_i2c_remove,
        .id_table = tps65910_i2c_id,
  };
  
diff --combined drivers/mfd/twl-core.c
index 11b76c0109f55c451bd3e52fb966d62099b136e1,43c7b4c92940f01fb8032b7aba0aec33bb5e76aa..4f3baadd0038e04f44d0a88856218edee23e5646
@@@ -32,6 -32,7 +32,7 @@@
  #include <linux/mutex.h>
  #include <linux/module.h>
  #include <linux/platform_device.h>
+ #include <linux/regmap.h>
  #include <linux/clk.h>
  #include <linux/err.h>
  #include <linux/device.h>
@@@ -65,9 -66,6 +66,6 @@@
  
  /* Triton Core internal information (BEGIN) */
  
- /* Last - for index max*/
- #define TWL4030_MODULE_LAST           TWL4030_MODULE_SECURED_REG
  #define TWL_NUM_SLAVES                4
  
  #define SUB_CHIP_ID0 0
@@@ -171,13 -169,7 +169,7 @@@ EXPORT_SYMBOL(twl_rev)
  /* Structure for each TWL4030/TWL6030 Slave */
  struct twl_client {
        struct i2c_client *client;
-       u8 address;
-       /* max numb of i2c_msg required is for read =2 */
-       struct i2c_msg xfer_msg[2];
-       /* To lock access to xfer_msg */
-       struct mutex xfer_lock;
+       struct regmap *regmap;
  };
  
  static struct twl_client twl_modules[TWL_NUM_SLAVES];
@@@ -189,7 -181,7 +181,7 @@@ struct twl_mapping 
  };
  static struct twl_mapping *twl_map;
  
- static struct twl_mapping twl4030_map[TWL4030_MODULE_LAST + 1] = {
+ static struct twl_mapping twl4030_map[] = {
        /*
         * NOTE:  don't change this table without updating the
         * <linux/i2c/twl.h> defines for TWL4030_MODULE_*
         */
  
        { 0, TWL4030_BASEADD_USB },
        { 1, TWL4030_BASEADD_AUDIO_VOICE },
        { 1, TWL4030_BASEADD_GPIO },
        { 1, TWL4030_BASEADD_INTBR },
        { 1, TWL4030_BASEADD_PIH },
-       { 1, TWL4030_BASEADD_TEST },
  
+       { 1, TWL4030_BASEADD_TEST },
        { 2, TWL4030_BASEADD_KEYPAD },
        { 2, TWL4030_BASEADD_MADC },
        { 2, TWL4030_BASEADD_INTERRUPTS },
        { 2, TWL4030_BASEADD_LED },
        { 2, TWL4030_BASEADD_MAIN_CHARGE },
        { 2, TWL4030_BASEADD_PRECHARGE },
        { 2, TWL4030_BASEADD_PWM0 },
        { 2, TWL4030_BASEADD_PWM1 },
        { 2, TWL4030_BASEADD_PWMA },
        { 2, TWL4030_BASEADD_PWMB },
        { 2, TWL5031_BASEADD_ACCESSORY },
        { 2, TWL5031_BASEADD_INTERRUPTS },
        { 3, TWL4030_BASEADD_BACKUP },
        { 3, TWL4030_BASEADD_INT },
        { 3, TWL4030_BASEADD_PM_MASTER },
        { 3, TWL4030_BASEADD_PM_RECEIVER },
        { 3, TWL4030_BASEADD_RTC },
        { 3, TWL4030_BASEADD_SECURED_REG },
  };
  
+ static struct regmap_config twl4030_regmap_config[4] = {
+       {
+               /* Address 0x48 */
+               .reg_bits = 8,
+               .val_bits = 8,
+               .max_register = 0xff,
+       },
+       {
+               /* Address 0x49 */
+               .reg_bits = 8,
+               .val_bits = 8,
+               .max_register = 0xff,
+       },
+       {
+               /* Address 0x4a */
+               .reg_bits = 8,
+               .val_bits = 8,
+               .max_register = 0xff,
+       },
+       {
+               /* Address 0x4b */
+               .reg_bits = 8,
+               .val_bits = 8,
+               .max_register = 0xff,
+       },
+ };
  static struct twl_mapping twl6030_map[] = {
        /*
         * NOTE:  don't change this table without updating the
        { SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
        { SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
        { SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
        { SUB_CHIP_ID0, TWL6030_BASEADD_PM_MASTER },
        { SUB_CHIP_ID0, TWL6030_BASEADD_PM_SLAVE_MISC },
        { SUB_CHIP_ID0, TWL6030_BASEADD_RTC },
        { SUB_CHIP_ID0, TWL6030_BASEADD_MEM },
        { SUB_CHIP_ID1, TWL6025_BASEADD_CHARGER },
  };
  
+ static struct regmap_config twl6030_regmap_config[3] = {
+       {
+               /* Address 0x48 */
+               .reg_bits = 8,
+               .val_bits = 8,
+               .max_register = 0xff,
+       },
+       {
+               /* Address 0x49 */
+               .reg_bits = 8,
+               .val_bits = 8,
+               .max_register = 0xff,
+       },
+       {
+               /* Address 0x4a */
+               .reg_bits = 8,
+               .val_bits = 8,
+               .max_register = 0xff,
+       },
+ };
  /*----------------------------------------------------------------------*/
  
  /* Exported Functions */
@@@ -283,9 -324,8 +324,8 @@@ int twl_i2c_write(u8 mod_no, u8 *value
        int ret;
        int sid;
        struct twl_client *twl;
-       struct i2c_msg *msg;
  
-       if (unlikely(mod_no > TWL_MODULE_LAST)) {
+       if (unlikely(mod_no >= TWL_MODULE_LAST)) {
                pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
                return -EPERM;
        }
        }
        twl = &twl_modules[sid];
  
-       mutex_lock(&twl->xfer_lock);
-       /*
-        * [MSG1]: fill the register address data
-        * fill the data Tx buffer
-        */
-       msg = &twl->xfer_msg[0];
-       msg->addr = twl->address;
-       msg->len = num_bytes + 1;
-       msg->flags = 0;
-       msg->buf = value;
-       /* over write the first byte of buffer with the register address */
-       *value = twl_map[mod_no].base + reg;
-       ret = i2c_transfer(twl->client->adapter, twl->xfer_msg, 1);
-       mutex_unlock(&twl->xfer_lock);
-       /* i2c_transfer returns number of messages transferred */
-       if (ret != 1) {
-               pr_err("%s: i2c_write failed to transfer all messages\n",
-                       DRIVER_NAME);
-               if (ret < 0)
-                       return ret;
-               else
-                       return -EIO;
-       } else {
-               return 0;
-       }
+       ret = regmap_bulk_write(twl->regmap, twl_map[mod_no].base + reg,
+                               value, num_bytes);
+       if (ret)
+               pr_err("%s: Write failed (mod %d, reg 0x%02x count %d)\n",
+                      DRIVER_NAME, mod_no, reg, num_bytes);
+       return ret;
  }
  EXPORT_SYMBOL(twl_i2c_write);
  
  int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
  {
        int ret;
-       u8 val;
        int sid;
        struct twl_client *twl;
-       struct i2c_msg *msg;
  
-       if (unlikely(mod_no > TWL_MODULE_LAST)) {
+       if (unlikely(mod_no >= TWL_MODULE_LAST)) {
                pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
                return -EPERM;
        }
        }
        twl = &twl_modules[sid];
  
-       mutex_lock(&twl->xfer_lock);
-       /* [MSG1] fill the register address data */
-       msg = &twl->xfer_msg[0];
-       msg->addr = twl->address;
-       msg->len = 1;
-       msg->flags = 0; /* Read the register value */
-       val = twl_map[mod_no].base + reg;
-       msg->buf = &val;
-       /* [MSG2] fill the data rx buffer */
-       msg = &twl->xfer_msg[1];
-       msg->addr = twl->address;
-       msg->flags = I2C_M_RD;  /* Read the register value */
-       msg->len = num_bytes;   /* only n bytes */
-       msg->buf = value;
-       ret = i2c_transfer(twl->client->adapter, twl->xfer_msg, 2);
-       mutex_unlock(&twl->xfer_lock);
-       /* i2c_transfer returns number of messages transferred */
-       if (ret != 2) {
-               pr_err("%s: i2c_read failed to transfer all messages\n",
-                       DRIVER_NAME);
-               if (ret < 0)
-                       return ret;
-               else
-                       return -EIO;
-       } else {
-               return 0;
-       }
+       ret = regmap_bulk_read(twl->regmap, twl_map[mod_no].base + reg,
+                              value, num_bytes);
+       if (ret)
+               pr_err("%s: Read failed (mod %d, reg 0x%02x count %d)\n",
+                      DRIVER_NAME, mod_no, reg, num_bytes);
+       return ret;
  }
  EXPORT_SYMBOL(twl_i2c_read);
  
   */
  int twl_i2c_write_u8(u8 mod_no, u8 value, u8 reg)
  {
-       /* 2 bytes offset 1 contains the data offset 0 is used by i2c_write */
-       u8 temp_buffer[2] = { 0 };
-       /* offset 1 contains the data */
-       temp_buffer[1] = value;
-       return twl_i2c_write(mod_no, temp_buffer, reg, 1);
+       return twl_i2c_write(mod_no, &value, reg, 1);
  }
  EXPORT_SYMBOL(twl_i2c_write_u8);
  
@@@ -646,8 -641,9 +641,9 @@@ add_children(struct twl4030_platform_da
                        return PTR_ERR(child);
        }
  
-       if (IS_ENABLED(CONFIG_TWL4030_MADC) && pdata->madc) {
-               child = add_child(2, "twl4030_madc",
+       if (IS_ENABLED(CONFIG_TWL4030_MADC) && pdata->madc &&
+           twl_class_is_4030()) {
+               child = add_child(SUB_CHIP_ID2, "twl4030_madc",
                                pdata->madc, sizeof(*pdata->madc),
                                true, irq_base + MADC_INTR_OFFSET, 0);
                if (IS_ERR(child))
                 * HW security concerns, and "least privilege".
                 */
                sub_chip_id = twl_map[TWL_MODULE_RTC].sid;
-               child = add_child(sub_chip_id, "twl_rtc",
-                               NULL, 0,
+               child = add_child(sub_chip_id, "twl_rtc", NULL, 0,
                                true, irq_base + RTC_INTR_OFFSET, 0);
                if (IS_ERR(child))
                        return PTR_ERR(child);
        }
  
-       if (IS_ENABLED(CONFIG_PWM_TWL6030) && twl_class_is_6030()) {
-               child = add_child(SUB_CHIP_ID1, "twl6030-pwm", NULL, 0,
+       if (IS_ENABLED(CONFIG_PWM_TWL)) {
+               child = add_child(SUB_CHIP_ID1, "twl-pwm", NULL, 0,
+                                 false, 0, 0);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+       }
+       if (IS_ENABLED(CONFIG_PWM_TWL_LED)) {
+               child = add_child(SUB_CHIP_ID1, "twl-pwmled", NULL, 0,
                                  false, 0, 0);
                if (IS_ERR(child))
                        return PTR_ERR(child);
  
                }
  
-               child = add_child(0, "twl4030_usb",
-                               pdata->usb, sizeof(*pdata->usb),
-                               true,
+               child = add_child(SUB_CHIP_ID0, "twl4030_usb",
+                               pdata->usb, sizeof(*pdata->usb), true,
                                /* irq0 = USB_PRES, irq1 = USB */
                                irq_base + USB_PRES_INTR_OFFSET,
                                irq_base + USB_INTR_OFFSET);
  
                pdata->usb->features = features;
  
-               child = add_child(0, "twl6030_usb",
-                       pdata->usb, sizeof(*pdata->usb),
-                       true,
+               child = add_child(SUB_CHIP_ID0, "twl6030_usb",
+                       pdata->usb, sizeof(*pdata->usb), true,
                        /* irq1 = VBUS_PRES, irq0 = USB ID */
                        irq_base + USBOTG_INTR_OFFSET,
                        irq_base + USB_PRES_INTR_OFFSET);
        }
  
        if (IS_ENABLED(CONFIG_TWL4030_WATCHDOG) && twl_class_is_4030()) {
-               child = add_child(0, "twl4030_wdt", NULL, 0, false, 0, 0);
+               child = add_child(SUB_CHIP_ID3, "twl4030_wdt", NULL, 0,
+                                 false, 0, 0);
                if (IS_ERR(child))
                        return PTR_ERR(child);
        }
  
        if (IS_ENABLED(CONFIG_INPUT_TWL4030_PWRBUTTON) && twl_class_is_4030()) {
-               child = add_child(1, "twl4030_pwrbutton",
-                               NULL, 0, true, irq_base + 8 + 0, 0);
+               child = add_child(SUB_CHIP_ID3, "twl4030_pwrbutton", NULL, 0,
+                                 true, irq_base + 8 + 0, 0);
                if (IS_ERR(child))
                        return PTR_ERR(child);
        }
  
        if (IS_ENABLED(CONFIG_MFD_TWL4030_AUDIO) && pdata->audio &&
            twl_class_is_4030()) {
-               sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid;
-               child = add_child(sub_chip_id, "twl4030-audio",
+               child = add_child(SUB_CHIP_ID1, "twl4030-audio",
                                pdata->audio, sizeof(*pdata->audio),
                                false, 0, 0);
                if (IS_ERR(child))
  
        if (IS_ENABLED(CONFIG_CHARGER_TWL4030) && pdata->bci &&
                        !(features & (TPS_SUBSET | TWL5031))) {
-               child = add_child(3, "twl4030_bci",
+               child = add_child(SUB_CHIP_ID3, "twl4030_bci",
                                pdata->bci, sizeof(*pdata->bci), false,
                                /* irq0 = CHG_PRES, irq1 = BCI */
                                irq_base + BCI_PRES_INTR_OFFSET,
@@@ -1077,8 -1077,8 +1077,8 @@@ static inline int __init protect_pm_mas
  {
        int e = 0;
  
-       e = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0,
-                       TWL4030_PM_MASTER_PROTECT_KEY);
+       e = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
+                            TWL4030_PM_MASTER_PROTECT_KEY);
        return e;
  }
  
@@@ -1086,12 -1086,10 +1086,10 @@@ static inline int __init unprotect_pm_m
  {
        int e = 0;
  
-       e |= twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
-                       TWL4030_PM_MASTER_KEY_CFG1,
-                       TWL4030_PM_MASTER_PROTECT_KEY);
-       e |= twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
-                       TWL4030_PM_MASTER_KEY_CFG2,
-                       TWL4030_PM_MASTER_PROTECT_KEY);
+       e |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
+                             TWL4030_PM_MASTER_PROTECT_KEY);
+       e |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2,
+                             TWL4030_PM_MASTER_PROTECT_KEY);
  
        return e;
  }
@@@ -1170,12 -1168,13 +1168,13 @@@ static int twl_remove(struct i2c_clien
  }
  
  /* NOTE: This driver only handles a single twl4030/tps659x0 chip */
 -static int __devinit
 +static int
  twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
  {
        struct twl4030_platform_data    *pdata = client->dev.platform_data;
        struct device_node              *node = client->dev.of_node;
        struct platform_device          *pdev;
+       struct regmap_config            *twl_regmap_config;
        int                             irq_base = 0;
        int                             status;
        unsigned                        i, num_slaves;
        if ((id->driver_data) & TWL6030_CLASS) {
                twl_id = TWL6030_CLASS_ID;
                twl_map = &twl6030_map[0];
+               twl_regmap_config = twl6030_regmap_config;
                num_slaves = TWL_NUM_SLAVES - 1;
        } else {
                twl_id = TWL4030_CLASS_ID;
                twl_map = &twl4030_map[0];
+               twl_regmap_config = twl4030_regmap_config;
                num_slaves = TWL_NUM_SLAVES;
        }
  
        for (i = 0; i < num_slaves; i++) {
                struct twl_client *twl = &twl_modules[i];
  
-               twl->address = client->addr + i;
                if (i == 0) {
                        twl->client = client;
                } else {
                        twl->client = i2c_new_dummy(client->adapter,
-                                       twl->address);
+                                                   client->addr + i);
                        if (!twl->client) {
                                dev_err(&client->dev,
                                        "can't attach client %d\n", i);
                                goto fail;
                        }
                }
-               mutex_init(&twl->xfer_lock);
+               twl->regmap = devm_regmap_init_i2c(twl->client,
+                                                  &twl_regmap_config[i]);
+               if (IS_ERR(twl->regmap)) {
+                       status = PTR_ERR(twl->regmap);
+                       dev_err(&client->dev,
+                               "Failed to allocate regmap %d, err: %d\n", i,
+                               status);
+                       goto fail;
+               }
        }
  
        inuse = true;
index cdd1173ed4e9641b0290bffbac7a860563f6c581,518da0c739075892d762e1b6f6e00311f9da7a88..a5f9888aa19c9679856143d8a231aed02bfa51ab
@@@ -295,8 -295,8 +295,8 @@@ static irqreturn_t handle_twl4030_pih(i
        irqreturn_t     ret;
        u8              pih_isr;
  
-       ret = twl_i2c_read_u8(TWL4030_MODULE_PIH, &pih_isr,
-                       REG_PIH_ISR_P1);
+       ret = twl_i2c_read_u8(TWL_MODULE_PIH, &pih_isr,
+                             REG_PIH_ISR_P1);
        if (ret) {
                pr_warning("twl4030: I2C error %d reading PIH ISR\n", ret);
                return IRQ_NONE;
@@@ -501,7 -501,7 +501,7 @@@ static void twl4030_sih_bus_sync_unlock
                } imr;
  
                /* byte[0] gets overwritten as we write ... */
-               imr.word = cpu_to_le32(agent->imr << 8);
+               imr.word = cpu_to_le32(agent->imr);
                agent->imr_change_pending = false;
  
                /* write the whole mask ... simpler than subsetting it */
                 * any processor on the other IRQ line, EDR registers are
                 * shared.
                 */
-               status = twl_i2c_read(sih->module, bytes + 1,
+               status = twl_i2c_read(sih->module, bytes,
                                sih->edr_offset, sih->bytes_edr);
                if (status) {
                        pr_err("twl4030: %s, %s --> %d\n", __func__,
                while (edge_change) {
                        int             i = fls(edge_change) - 1;
                        struct irq_data *idata;
-                       int             byte = 1 + (i >> 2);
+                       int             byte = i >> 2;
                        int             off = (i & 0x3) * 2;
                        unsigned int    type;
  
@@@ -672,8 -672,7 +672,8 @@@ int twl4030_sih_setup(struct device *de
        irq = sih_mod + twl4030_irq_base;
        irq_set_handler_data(irq, agent);
        agent->irq_name = kasprintf(GFP_KERNEL, "twl4030_%s", sih->name);
 -      status = request_threaded_irq(irq, NULL, handle_twl4030_sih, 0,
 +      status = request_threaded_irq(irq, NULL, handle_twl4030_sih,
 +                                    IRQF_EARLY_RESUME,
                                      agent->irq_name ?: sih->name, NULL);
  
        dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", sih->name,
index a39dcf3e21335a5b636aff0306bdf897ddb30c99,2baabaa14244ea1ba6e956d4b9c0fde59fba6aff..88ff9dc83305e2d2a644c6c049abb35439c2b5ad
@@@ -173,7 -173,7 +173,7 @@@ static int twl4030battery_temperature(i
  
        volt = (raw_volt * TEMP_STEP_SIZE) / TEMP_PSR_R;
        /* Getting and calculating the supply current in micro ampers */
-       ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &val,
+       ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, &val,
                REG_BCICTL2);
        if (ret < 0)
                return ret;
@@@ -196,7 -196,7 +196,7 @@@ static int twl4030battery_current(int r
        int ret;
        u8 val;
  
-       ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &val,
+       ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, &val,
                TWL4030_BCI_BCICTL1);
        if (ret)
                return ret;
@@@ -635,7 -635,7 +635,7 @@@ static int twl4030_madc_set_current_gen
        int ret;
        u8 regval;
  
-       ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
+       ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE,
                              &regval, TWL4030_BCI_BCICTL1);
        if (ret) {
                dev_err(madc->dev, "unable to read BCICTL1 reg 0x%X",
                regval |= chan ? TWL4030_BCI_ITHEN : TWL4030_BCI_TYPEN;
        else
                regval &= chan ? ~TWL4030_BCI_ITHEN : ~TWL4030_BCI_TYPEN;
-       ret = twl_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE,
+       ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE,
                               regval, TWL4030_BCI_BCICTL1);
        if (ret) {
                dev_err(madc->dev, "unable to write BCICTL1 reg 0x%X\n",
@@@ -668,7 -668,7 +668,7 @@@ static int twl4030_madc_set_power(struc
        u8 regval;
        int ret;
  
-       ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
+       ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE,
                              &regval, TWL4030_MADC_CTRL1);
        if (ret) {
                dev_err(madc->dev, "unable to read madc ctrl1 reg 0x%X\n",
  /*
   * Initialize MADC and request for threaded irq
   */
 -static int __devinit twl4030_madc_probe(struct platform_device *pdev)
 +static int twl4030_madc_probe(struct platform_device *pdev)
  {
        struct twl4030_madc_data *madc;
        struct twl4030_madc_platform_data *pdata = pdev->dev.platform_data;
        if (ret < 0)
                goto err_current_generator;
  
-       ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
+       ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE,
                              &regval, TWL4030_BCI_BCICTL1);
        if (ret) {
                dev_err(&pdev->dev, "unable to read reg BCI CTL1 0x%X\n",
                goto err_i2c;
        }
        regval |= TWL4030_BCI_MESBAT;
-       ret = twl_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE,
+       ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE,
                               regval, TWL4030_BCI_BCICTL1);
        if (ret) {
                dev_err(&pdev->dev, "unable to write reg BCI Ctl1 0x%X\n",
@@@ -785,7 -785,7 +785,7 @@@ err_power
        return ret;
  }
  
 -static int __devexit 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);
  
index a5332063183a26fb70f84f12c858fd1102226b7c,4fda77c7455244f0efd4f298a187f48fc64d4739..4dae241e501734f66c9080283a0c43188729b0b5
@@@ -124,21 -124,19 +124,19 @@@ static u8 res_config_addrs[] = 
        [RES_MAIN_REF]  = 0x94,
  };
  
 -static int __devinit twl4030_write_script_byte(u8 address, u8 byte)
 +static int twl4030_write_script_byte(u8 address, u8 byte)
  {
        int err;
  
-       err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address,
-                               R_MEMORY_ADDRESS);
+       err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_MEMORY_ADDRESS);
        if (err)
                goto out;
-       err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, byte,
-                               R_MEMORY_DATA);
+       err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, byte, R_MEMORY_DATA);
  out:
        return err;
  }
  
 -static int __devinit twl4030_write_script_ins(u8 address, u16 pmb_message,
 +static int twl4030_write_script_ins(u8 address, u16 pmb_message,
                                           u8 delay, u8 next)
  {
        int err;
@@@ -158,7 -156,7 +156,7 @@@ out
        return err;
  }
  
 -static int __devinit twl4030_write_script(u8 address, struct twl4030_ins *script,
 +static int twl4030_write_script(u8 address, struct twl4030_ins *script,
                                       int len)
  {
        int err;
        return err;
  }
  
 -static int __devinit twl4030_config_wakeup3_sequence(u8 address)
 +static int twl4030_config_wakeup3_sequence(u8 address)
  {
        int err;
        u8 data;
  
        /* Set SLEEP to ACTIVE SEQ address for P3 */
-       err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address,
-                               R_SEQ_ADD_S2A3);
+       err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_S2A3);
        if (err)
                goto out;
  
        /* P3 LVL_WAKEUP should be on LEVEL */
-       err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &data,
-                               R_P3_SW_EVENTS);
+       err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P3_SW_EVENTS);
        if (err)
                goto out;
        data |= LVL_WAKEUP;
-       err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, data,
-                               R_P3_SW_EVENTS);
+       err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P3_SW_EVENTS);
  out:
        if (err)
                pr_err("TWL4030 wakeup sequence for P3 config error\n");
        return err;
  }
  
 -static int __devinit twl4030_config_wakeup12_sequence(u8 address)
 +static int twl4030_config_wakeup12_sequence(u8 address)
  {
        int err = 0;
        u8 data;
  
        /* Set SLEEP to ACTIVE SEQ address for P1 and P2 */
-       err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address,
-                               R_SEQ_ADD_S2A12);
+       err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_S2A12);
        if (err)
                goto out;
  
        /* P1/P2 LVL_WAKEUP should be on LEVEL */
-       err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &data,
-                               R_P1_SW_EVENTS);
+       err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P1_SW_EVENTS);
        if (err)
                goto out;
  
        data |= LVL_WAKEUP;
-       err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, data,
-                               R_P1_SW_EVENTS);
+       err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P1_SW_EVENTS);
        if (err)
                goto out;
  
-       err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &data,
-                               R_P2_SW_EVENTS);
+       err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P2_SW_EVENTS);
        if (err)
                goto out;
  
        data |= LVL_WAKEUP;
-       err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, data,
-                               R_P2_SW_EVENTS);
+       err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P2_SW_EVENTS);
        if (err)
                goto out;
  
        if (machine_is_omap_3430sdp() || machine_is_omap_ldp()) {
                /* Disabling AC charger effect on sleep-active transitions */
-               err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &data,
-                                       R_CFG_P1_TRANSITION);
+               err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data,
+                                     R_CFG_P1_TRANSITION);
                if (err)
                        goto out;
                data &= ~(1<<1);
-               err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, data ,
-                                       R_CFG_P1_TRANSITION);
+               err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data,
+                                      R_CFG_P1_TRANSITION);
                if (err)
                        goto out;
        }
@@@ -262,13 -252,12 +252,12 @@@ out
        return err;
  }
  
 -static int __devinit twl4030_config_sleep_sequence(u8 address)
 +static int twl4030_config_sleep_sequence(u8 address)
  {
        int err;
  
        /* Set ACTIVE to SLEEP SEQ address in T2 memory*/
-       err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address,
-                               R_SEQ_ADD_A2S);
+       err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_A2S);
  
        if (err)
                pr_err("TWL4030 sleep sequence config error\n");
        return err;
  }
  
 -static int __devinit twl4030_config_warmreset_sequence(u8 address)
 +static int twl4030_config_warmreset_sequence(u8 address)
  {
        int err;
        u8 rd_data;
  
        /* Set WARM RESET SEQ address for P1 */
-       err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address,
-                               R_SEQ_ADD_WARM);
+       err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_WARM);
        if (err)
                goto out;
  
        /* P1/P2/P3 enable WARMRESET */
-       err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &rd_data,
-                               R_P1_SW_EVENTS);
+       err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P1_SW_EVENTS);
        if (err)
                goto out;
  
        rd_data |= ENABLE_WARMRESET;
-       err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, rd_data,
-                               R_P1_SW_EVENTS);
+       err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P1_SW_EVENTS);
        if (err)
                goto out;
  
-       err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &rd_data,
-                               R_P2_SW_EVENTS);
+       err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P2_SW_EVENTS);
        if (err)
                goto out;
  
        rd_data |= ENABLE_WARMRESET;
-       err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, rd_data,
-                               R_P2_SW_EVENTS);
+       err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P2_SW_EVENTS);
        if (err)
                goto out;
  
-       err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &rd_data,
-                               R_P3_SW_EVENTS);
+       err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P3_SW_EVENTS);
        if (err)
                goto out;
  
        rd_data |= ENABLE_WARMRESET;
-       err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, rd_data,
-                               R_P3_SW_EVENTS);
+       err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P3_SW_EVENTS);
  out:
        if (err)
                pr_err("TWL4030 warmreset seq config error\n");
        return err;
  }
  
 -static int __devinit twl4030_configure_resource(struct twl4030_resconfig *rconfig)
 +static int twl4030_configure_resource(struct twl4030_resconfig *rconfig)
  {
        int rconfig_addr;
        int err;
        rconfig_addr = res_config_addrs[rconfig->resource];
  
        /* Set resource group */
-       err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &grp,
+       err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &grp,
                              rconfig_addr + DEV_GRP_OFFSET);
        if (err) {
                pr_err("TWL4030 Resource %d group could not be read\n",
        if (rconfig->devgroup != TWL4030_RESCONFIG_UNDEF) {
                grp &= ~DEV_GRP_MASK;
                grp |= rconfig->devgroup << DEV_GRP_SHIFT;
-               err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+               err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
                                       grp, rconfig_addr + DEV_GRP_OFFSET);
                if (err < 0) {
                        pr_err("TWL4030 failed to program devgroup\n");
        }
  
        /* Set resource types */
-       err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &type,
+       err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &type,
                                rconfig_addr + TYPE_OFFSET);
        if (err < 0) {
                pr_err("TWL4030 Resource %d type could not be read\n",
                type |= rconfig->type2 << TYPE2_SHIFT;
        }
  
-       err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+       err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
                                type, rconfig_addr + TYPE_OFFSET);
        if (err < 0) {
                pr_err("TWL4030 failed to program resource type\n");
        }
  
        /* Set remap states */
-       err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &remap,
+       err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &remap,
                              rconfig_addr + REMAP_OFFSET);
        if (err < 0) {
                pr_err("TWL4030 Resource %d remap could not be read\n",
                remap |= rconfig->remap_sleep << SLEEP_STATE_SHIFT;
        }
  
-       err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+       err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
                               remap,
                               rconfig_addr + REMAP_OFFSET);
        if (err < 0) {
        return 0;
  }
  
 -static int __devinit load_twl4030_script(struct twl4030_script *tscript,
 +static int load_twl4030_script(struct twl4030_script *tscript,
               u8 address)
  {
        int err;
@@@ -463,49 -445,47 +445,47 @@@ int twl4030_remove_script(u8 flags
  {
        int err = 0;
  
-       err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
-                       TWL4030_PM_MASTER_KEY_CFG1,
-                       TWL4030_PM_MASTER_PROTECT_KEY);
+       err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
+                              TWL4030_PM_MASTER_PROTECT_KEY);
        if (err) {
                pr_err("twl4030: unable to unlock PROTECT_KEY\n");
                return err;
        }
  
-       err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
-                       TWL4030_PM_MASTER_KEY_CFG2,
-                       TWL4030_PM_MASTER_PROTECT_KEY);
+       err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2,
+                              TWL4030_PM_MASTER_PROTECT_KEY);
        if (err) {
                pr_err("twl4030: unable to unlock PROTECT_KEY\n");
                return err;
        }
  
        if (flags & TWL4030_WRST_SCRIPT) {
-               err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT,
-                               R_SEQ_ADD_WARM);
+               err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
+                                      R_SEQ_ADD_WARM);
                if (err)
                        return err;
        }
        if (flags & TWL4030_WAKEUP12_SCRIPT) {
-               err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT,
-                               R_SEQ_ADD_S2A12);
+               err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
+                                      R_SEQ_ADD_S2A12);
                if (err)
                        return err;
        }
        if (flags & TWL4030_WAKEUP3_SCRIPT) {
-               err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT,
-                               R_SEQ_ADD_S2A3);
+               err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
+                                      R_SEQ_ADD_S2A3);
                if (err)
                        return err;
        }
        if (flags & TWL4030_SLEEP_SCRIPT) {
-               err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT,
-                               R_SEQ_ADD_A2S);
+               err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
+                                      R_SEQ_ADD_A2S);
                if (err)
                        return err;
        }
  
-       err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0,
-                       TWL4030_PM_MASTER_PROTECT_KEY);
+       err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
+                              TWL4030_PM_MASTER_PROTECT_KEY);
        if (err)
                pr_err("TWL4030 Unable to relock registers\n");
  
@@@ -521,28 -501,26 +501,26 @@@ void twl4030_power_off(void
  {
        int err;
  
-       err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, PWR_DEVOFF,
+       err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, PWR_DEVOFF,
                               TWL4030_PM_MASTER_P1_SW_EVENTS);
        if (err)
                pr_err("TWL4030 Unable to power off\n");
  }
  
 -void __devinit twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
 +void twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
  {
        int err = 0;
        int i;
        struct twl4030_resconfig *resconfig;
        u8 val, address = twl4030_start_script_address;
  
-       err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
-                       TWL4030_PM_MASTER_KEY_CFG1,
-                       TWL4030_PM_MASTER_PROTECT_KEY);
+       err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
+                              TWL4030_PM_MASTER_PROTECT_KEY);
        if (err)
                goto unlock;
  
-       err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
-                       TWL4030_PM_MASTER_KEY_CFG2,
-                       TWL4030_PM_MASTER_PROTECT_KEY);
+       err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2,
+                              TWL4030_PM_MASTER_PROTECT_KEY);
        if (err)
                goto unlock;
  
        /* Board has to be wired properly to use this feature */
        if (twl4030_scripts->use_poweroff && !pm_power_off) {
                /* Default for SEQ_OFFSYNC is set, lets ensure this */
-               err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &val,
+               err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &val,
                                      TWL4030_PM_MASTER_CFG_P123_TRANSITION);
                if (err) {
                        pr_warning("TWL4030 Unable to read registers\n");
  
                } else if (!(val & SEQ_OFFSYNC)) {
                        val |= SEQ_OFFSYNC;
-                       err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, val,
+                       err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, val,
                                        TWL4030_PM_MASTER_CFG_P123_TRANSITION);
                        if (err) {
                                pr_err("TWL4030 Unable to setup SEQ_OFFSYNC\n");
        }
  
  relock:
-       err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0,
-                       TWL4030_PM_MASTER_PROTECT_KEY);
+       err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
+                              TWL4030_PM_MASTER_PROTECT_KEY);
        if (err)
                pr_err("TWL4030 Unable to relock registers\n");
        return;
index 3141c4a173a7c8e9285931be1f330f420f0ce69e,8844b2f9de87a87293738513f72688ca7e662420..088872ab63389e49d04dd3f38fb02664fdc929ba
@@@ -43,7 -43,6 +43,7 @@@ static const struct reg_default wm5102_
        { 0x479, 0x0A30 },
        { 0x47B, 0x0810 },
        { 0x47D, 0x0510 },
 +      { 0x4D1, 0x017F },
        { 0x500, 0x000D },
        { 0x507, 0x1820 },
        { 0x508, 0x1820 },
        { 0x580, 0x000D },
        { 0x587, 0x1820 },
        { 0x588, 0x1820 },
 -      { 0x101, 0x8140 },
 -      { 0x3000, 0x2225 },
 -      { 0x3001, 0x3a03 },
 -      { 0x3002, 0x0225 },
 -      { 0x3003, 0x0801 },
 -      { 0x3004, 0x6249 },
 -      { 0x3005, 0x0c04 },
 -      { 0x3006, 0x0225 },
 -      { 0x3007, 0x5901 },
 -      { 0x3008, 0xe249 },
 -      { 0x3009, 0x030d },
 -      { 0x300a, 0x0249 },
 -      { 0x300b, 0x2c01 },
 -      { 0x300c, 0xe249 },
 -      { 0x300d, 0x4342 },
 -      { 0x300e, 0xe249 },
 -      { 0x300f, 0x73c0 },
 -      { 0x3010, 0x4249 },
 -      { 0x3011, 0x0c00 },
 -      { 0x3012, 0x0225 },
 -      { 0x3013, 0x1f01 },
 -      { 0x3014, 0x0225 },
 -      { 0x3015, 0x1e01 },
 -      { 0x3016, 0x0225 },
 -      { 0x3017, 0xfa00 },
 -      { 0x3018, 0x0000 },
 -      { 0x3019, 0xf000 },
 -      { 0x301a, 0x0000 },
 -      { 0x301b, 0xf000 },
 -      { 0x301c, 0x0000 },
 -      { 0x301d, 0xf000 },
 -      { 0x301e, 0x0000 },
 -      { 0x301f, 0xf000 },
 -      { 0x3020, 0x0000 },
 -      { 0x3021, 0xf000 },
 -      { 0x3022, 0x0000 },
 -      { 0x3023, 0xf000 },
 -      { 0x3024, 0x0000 },
 -      { 0x3025, 0xf000 },
 -      { 0x3026, 0x0000 },
 -      { 0x3027, 0xf000 },
 -      { 0x3028, 0x0000 },
 -      { 0x3029, 0xf000 },
 -      { 0x302a, 0x0000 },
 -      { 0x302b, 0xf000 },
 -      { 0x302c, 0x0000 },
 -      { 0x302d, 0xf000 },
 -      { 0x302e, 0x0000 },
 -      { 0x302f, 0xf000 },
 -      { 0x3030, 0x0225 },
 -      { 0x3031, 0x1a01 },
 -      { 0x3032, 0x0225 },
 -      { 0x3033, 0x1e00 },
 -      { 0x3034, 0x0225 },
 -      { 0x3035, 0x1f00 },
 -      { 0x3036, 0x6225 },
 -      { 0x3037, 0xf800 },
 -      { 0x3038, 0x0000 },
 -      { 0x3039, 0xf000 },
 -      { 0x303a, 0x0000 },
 -      { 0x303b, 0xf000 },
 -      { 0x303c, 0x0000 },
 -      { 0x303d, 0xf000 },
 -      { 0x303e, 0x0000 },
 -      { 0x303f, 0xf000 },
 -      { 0x3040, 0x2226 },
 -      { 0x3041, 0x3a03 },
 -      { 0x3042, 0x0226 },
 -      { 0x3043, 0x0801 },
 -      { 0x3044, 0x6249 },
 -      { 0x3045, 0x0c06 },
 -      { 0x3046, 0x0226 },
 -      { 0x3047, 0x5901 },
 -      { 0x3048, 0xe249 },
 -      { 0x3049, 0x030d },
 -      { 0x304a, 0x0249 },
 -      { 0x304b, 0x2c01 },
 -      { 0x304c, 0xe249 },
 -      { 0x304d, 0x4342 },
 -      { 0x304e, 0xe249 },
 -      { 0x304f, 0x73c0 },
 -      { 0x3050, 0x4249 },
 -      { 0x3051, 0x0c00 },
 -      { 0x3052, 0x0226 },
 -      { 0x3053, 0x1f01 },
 -      { 0x3054, 0x0226 },
 -      { 0x3055, 0x1e01 },
 -      { 0x3056, 0x0226 },
 -      { 0x3057, 0xfa00 },
 -      { 0x3058, 0x0000 },
 -      { 0x3059, 0xf000 },
 -      { 0x305a, 0x0000 },
 -      { 0x305b, 0xf000 },
 -      { 0x305c, 0x0000 },
 -      { 0x305d, 0xf000 },
 -      { 0x305e, 0x0000 },
 -      { 0x305f, 0xf000 },
 -      { 0x3060, 0x0000 },
 -      { 0x3061, 0xf000 },
 -      { 0x3062, 0x0000 },
 -      { 0x3063, 0xf000 },
 -      { 0x3064, 0x0000 },
 -      { 0x3065, 0xf000 },
 -      { 0x3066, 0x0000 },
 -      { 0x3067, 0xf000 },
 -      { 0x3068, 0x0000 },
 -      { 0x3069, 0xf000 },
 -      { 0x306a, 0x0000 },
 -      { 0x306b, 0xf000 },
 -      { 0x306c, 0x0000 },
 -      { 0x306d, 0xf000 },
 -      { 0x306e, 0x0000 },
 -      { 0x306f, 0xf000 },
 -      { 0x3070, 0x0226 },
 -      { 0x3071, 0x1a01 },
 -      { 0x3072, 0x0226 },
 -      { 0x3073, 0x1e00 },
 -      { 0x3074, 0x0226 },
 -      { 0x3075, 0x1f00 },
 -      { 0x3076, 0x6226 },
 -      { 0x3077, 0xf800 },
 -      { 0x3078, 0x0000 },
 -      { 0x3079, 0xf000 },
 -      { 0x307a, 0x0000 },
 -      { 0x307b, 0xf000 },
 -      { 0x307c, 0x0000 },
 -      { 0x307d, 0xf000 },
 -      { 0x307e, 0x0000 },
 -      { 0x307f, 0xf000 },
 -      { 0x3080, 0x2227 },
 -      { 0x3081, 0x3a03 },
 -      { 0x3082, 0x0227 },
 -      { 0x3083, 0x0801 },
 -      { 0x3084, 0x6255 },
 -      { 0x3085, 0x0c04 },
 -      { 0x3086, 0x0227 },
 -      { 0x3087, 0x5901 },
 -      { 0x3088, 0xe255 },
 -      { 0x3089, 0x030d },
 -      { 0x308a, 0x0255 },
 -      { 0x308b, 0x2c01 },
 -      { 0x308c, 0xe255 },
 -      { 0x308d, 0x4342 },
 -      { 0x308e, 0xe255 },
 -      { 0x308f, 0x73c0 },
 -      { 0x3090, 0x4255 },
 -      { 0x3091, 0x0c00 },
 -      { 0x3092, 0x0227 },
 -      { 0x3093, 0x1f01 },
 -      { 0x3094, 0x0227 },
 -      { 0x3095, 0x1e01 },
 -      { 0x3096, 0x0227 },
 -      { 0x3097, 0xfa00 },
 -      { 0x3098, 0x0000 },
 -      { 0x3099, 0xf000 },
 -      { 0x309a, 0x0000 },
 -      { 0x309b, 0xf000 },
 -      { 0x309c, 0x0000 },
 -      { 0x309d, 0xf000 },
 -      { 0x309e, 0x0000 },
 -      { 0x309f, 0xf000 },
 -      { 0x30a0, 0x0000 },
 -      { 0x30a1, 0xf000 },
 -      { 0x30a2, 0x0000 },
 -      { 0x30a3, 0xf000 },
 -      { 0x30a4, 0x0000 },
 -      { 0x30a5, 0xf000 },
 -      { 0x30a6, 0x0000 },
 -      { 0x30a7, 0xf000 },
 -      { 0x30a8, 0x0000 },
 -      { 0x30a9, 0xf000 },
 -      { 0x30aa, 0x0000 },
 -      { 0x30ab, 0xf000 },
 -      { 0x30ac, 0x0000 },
 -      { 0x30ad, 0xf000 },
 -      { 0x30ae, 0x0000 },
 -      { 0x30af, 0xf000 },
 -      { 0x30b0, 0x0227 },
 -      { 0x30b1, 0x1a01 },
 -      { 0x30b2, 0x0227 },
 -      { 0x30b3, 0x1e00 },
 -      { 0x30b4, 0x0227 },
 -      { 0x30b5, 0x1f00 },
 -      { 0x30b6, 0x6227 },
 -      { 0x30b7, 0xf800 },
 -      { 0x30b8, 0x0000 },
 -      { 0x30b9, 0xf000 },
 -      { 0x30ba, 0x0000 },
 -      { 0x30bb, 0xf000 },
 -      { 0x30bc, 0x0000 },
 -      { 0x30bd, 0xf000 },
 -      { 0x30be, 0x0000 },
 -      { 0x30bf, 0xf000 },
 -      { 0x30c0, 0x2228 },
 -      { 0x30c1, 0x3a03 },
 -      { 0x30c2, 0x0228 },
 -      { 0x30c3, 0x0801 },
 -      { 0x30c4, 0x6255 },
 -      { 0x30c5, 0x0c06 },
 -      { 0x30c6, 0x0228 },
 -      { 0x30c7, 0x5901 },
 -      { 0x30c8, 0xe255 },
 -      { 0x30c9, 0x030d },
 -      { 0x30ca, 0x0255 },
 -      { 0x30cb, 0x2c01 },
 -      { 0x30cc, 0xe255 },
 -      { 0x30cd, 0x4342 },
 -      { 0x30ce, 0xe255 },
 -      { 0x30cf, 0x73c0 },
 -      { 0x30d0, 0x4255 },
 -      { 0x30d1, 0x0c00 },
 -      { 0x30d2, 0x0228 },
 -      { 0x30d3, 0x1f01 },
 -      { 0x30d4, 0x0228 },
 -      { 0x30d5, 0x1e01 },
 -      { 0x30d6, 0x0228 },
 -      { 0x30d7, 0xfa00 },
 -      { 0x30d8, 0x0000 },
 -      { 0x30d9, 0xf000 },
 -      { 0x30da, 0x0000 },
 -      { 0x30db, 0xf000 },
 -      { 0x30dc, 0x0000 },
 -      { 0x30dd, 0xf000 },
 -      { 0x30de, 0x0000 },
 -      { 0x30df, 0xf000 },
 -      { 0x30e0, 0x0000 },
 -      { 0x30e1, 0xf000 },
 -      { 0x30e2, 0x0000 },
 -      { 0x30e3, 0xf000 },
 -      { 0x30e4, 0x0000 },
 -      { 0x30e5, 0xf000 },
 -      { 0x30e6, 0x0000 },
 -      { 0x30e7, 0xf000 },
 -      { 0x30e8, 0x0000 },
 -      { 0x30e9, 0xf000 },
 -      { 0x30ea, 0x0000 },
 -      { 0x30eb, 0xf000 },
 -      { 0x30ec, 0x0000 },
 -      { 0x30ed, 0xf000 },
 -      { 0x30ee, 0x0000 },
 -      { 0x30ef, 0xf000 },
 -      { 0x30f0, 0x0228 },
 -      { 0x30f1, 0x1a01 },
 -      { 0x30f2, 0x0228 },
 -      { 0x30f3, 0x1e00 },
 -      { 0x30f4, 0x0228 },
 -      { 0x30f5, 0x1f00 },
 -      { 0x30f6, 0x6228 },
 -      { 0x30f7, 0xf800 },
 -      { 0x30f8, 0x0000 },
 -      { 0x30f9, 0xf000 },
 -      { 0x30fa, 0x0000 },
 -      { 0x30fb, 0xf000 },
 -      { 0x30fc, 0x0000 },
 -      { 0x30fd, 0xf000 },
 -      { 0x30fe, 0x0000 },
 -      { 0x30ff, 0xf000 },
 -      { 0x3100, 0x222b },
 -      { 0x3101, 0x3a03 },
 -      { 0x3102, 0x222b },
 -      { 0x3103, 0x5803 },
 -      { 0x3104, 0xe26f },
 -      { 0x3105, 0x030d },
 -      { 0x3106, 0x626f },
 -      { 0x3107, 0x2c01 },
 -      { 0x3108, 0xe26f },
 -      { 0x3109, 0x4342 },
 -      { 0x310a, 0xe26f },
 -      { 0x310b, 0x73c0 },
 -      { 0x310c, 0x026f },
 -      { 0x310d, 0x0c00 },
 -      { 0x310e, 0x022b },
 -      { 0x310f, 0x1f01 },
 -      { 0x3110, 0x022b },
 -      { 0x3111, 0x1e01 },
 -      { 0x3112, 0x022b },
 -      { 0x3113, 0xfa00 },
 -      { 0x3114, 0x0000 },
 -      { 0x3115, 0xf000 },
 -      { 0x3116, 0x0000 },
 -      { 0x3117, 0xf000 },
 -      { 0x3118, 0x0000 },
 -      { 0x3119, 0xf000 },
 -      { 0x311a, 0x0000 },
 -      { 0x311b, 0xf000 },
 -      { 0x311c, 0x0000 },
 -      { 0x311d, 0xf000 },
 -      { 0x311e, 0x0000 },
 -      { 0x311f, 0xf000 },
 -      { 0x3120, 0x022b },
 -      { 0x3121, 0x0a01 },
 -      { 0x3122, 0x022b },
 -      { 0x3123, 0x1e00 },
 -      { 0x3124, 0x022b },
 -      { 0x3125, 0x1f00 },
 -      { 0x3126, 0x622b },
 -      { 0x3127, 0xf800 },
 -      { 0x3128, 0x0000 },
 -      { 0x3129, 0xf000 },
 -      { 0x312a, 0x0000 },
 -      { 0x312b, 0xf000 },
 -      { 0x312c, 0x0000 },
 -      { 0x312d, 0xf000 },
 -      { 0x312e, 0x0000 },
 -      { 0x312f, 0xf000 },
 -      { 0x3130, 0x0000 },
 -      { 0x3131, 0xf000 },
 -      { 0x3132, 0x0000 },
 -      { 0x3133, 0xf000 },
 -      { 0x3134, 0x0000 },
 -      { 0x3135, 0xf000 },
 -      { 0x3136, 0x0000 },
 -      { 0x3137, 0xf000 },
 -      { 0x3138, 0x0000 },
 -      { 0x3139, 0xf000 },
 -      { 0x313a, 0x0000 },
 -      { 0x313b, 0xf000 },
 -      { 0x313c, 0x0000 },
 -      { 0x313d, 0xf000 },
 -      { 0x313e, 0x0000 },
 -      { 0x313f, 0xf000 },
 -      { 0x3140, 0x0000 },
 -      { 0x3141, 0xf000 },
 -      { 0x3142, 0x0000 },
 -      { 0x3143, 0xf000 },
 -      { 0x3144, 0x0000 },
 -      { 0x3145, 0xf000 },
 -      { 0x3146, 0x0000 },
 -      { 0x3147, 0xf000 },
 -      { 0x3148, 0x0000 },
 -      { 0x3149, 0xf000 },
 -      { 0x314a, 0x0000 },
 -      { 0x314b, 0xf000 },
 -      { 0x314c, 0x0000 },
 -      { 0x314d, 0xf000 },
 -      { 0x314e, 0x0000 },
 -      { 0x314f, 0xf000 },
 -      { 0x3150, 0x0000 },
 -      { 0x3151, 0xf000 },
 -      { 0x3152, 0x0000 },
 -      { 0x3153, 0xf000 },
 -      { 0x3154, 0x0000 },
 -      { 0x3155, 0xf000 },
 -      { 0x3156, 0x0000 },
 -      { 0x3157, 0xf000 },
 -      { 0x3158, 0x0000 },
 -      { 0x3159, 0xf000 },
 -      { 0x315a, 0x0000 },
 -      { 0x315b, 0xf000 },
 -      { 0x315c, 0x0000 },
 -      { 0x315d, 0xf000 },
 -      { 0x315e, 0x0000 },
 -      { 0x315f, 0xf000 },
 -      { 0x3160, 0x0000 },
 -      { 0x3161, 0xf000 },
 -      { 0x3162, 0x0000 },
 -      { 0x3163, 0xf000 },
 -      { 0x3164, 0x0000 },
 -      { 0x3165, 0xf000 },
 -      { 0x3166, 0x0000 },
 -      { 0x3167, 0xf000 },
 -      { 0x3168, 0x0000 },
 -      { 0x3169, 0xf000 },
 -      { 0x316a, 0x0000 },
 -      { 0x316b, 0xf000 },
 -      { 0x316c, 0x0000 },
 -      { 0x316d, 0xf000 },
 -      { 0x316e, 0x0000 },
 -      { 0x316f, 0xf000 },
 -      { 0x3170, 0x0000 },
 -      { 0x3171, 0xf000 },
 -      { 0x3172, 0x0000 },
 -      { 0x3173, 0xf000 },
 -      { 0x3174, 0x0000 },
 -      { 0x3175, 0xf000 },
 -      { 0x3176, 0x0000 },
 -      { 0x3177, 0xf000 },
 -      { 0x3178, 0x0000 },
 -      { 0x3179, 0xf000 },
 -      { 0x317a, 0x0000 },
 -      { 0x317b, 0xf000 },
 -      { 0x317c, 0x0000 },
 -      { 0x317d, 0xf000 },
 -      { 0x317e, 0x0000 },
 -      { 0x317f, 0xf000 },
 -      { 0x3180, 0x2001 },
 -      { 0x3181, 0xf101 },
 -      { 0x3182, 0x0000 },
 -      { 0x3183, 0xf000 },
 -      { 0x3184, 0x0000 },
 -      { 0x3185, 0xf000 },
 -      { 0x3186, 0x0000 },
 -      { 0x3187, 0xf000 },
 -      { 0x3188, 0x0000 },
 -      { 0x3189, 0xf000 },
 -      { 0x318a, 0x0000 },
 -      { 0x318b, 0xf000 },
 -      { 0x318c, 0x0000 },
 -      { 0x318d, 0xf000 },
 -      { 0x318e, 0x0000 },
 -      { 0x318f, 0xf000 },
 -      { 0x3190, 0x0000 },
 -      { 0x3191, 0xf000 },
 -      { 0x3192, 0x0000 },
 -      { 0x3193, 0xf000 },
 -      { 0x3194, 0x0000 },
 -      { 0x3195, 0xf000 },
 -      { 0x3196, 0x0000 },
 -      { 0x3197, 0xf000 },
 -      { 0x3198, 0x0000 },
 -      { 0x3199, 0xf000 },
 -      { 0x319a, 0x0000 },
 -      { 0x319b, 0xf000 },
 -      { 0x319c, 0x0000 },
 -      { 0x319d, 0xf000 },
 -      { 0x319e, 0x0000 },
 -      { 0x319f, 0xf000 },
 -      { 0x31a0, 0x0000 },
 -      { 0x31a1, 0xf000 },
 -      { 0x31a2, 0x0000 },
 -      { 0x31a3, 0xf000 },
 -      { 0x31a4, 0x0000 },
 -      { 0x31a5, 0xf000 },
 -      { 0x31a6, 0x0000 },
 -      { 0x31a7, 0xf000 },
 -      { 0x31a8, 0x0000 },
 -      { 0x31a9, 0xf000 },
 -      { 0x31aa, 0x0000 },
 -      { 0x31ab, 0xf000 },
 -      { 0x31ac, 0x0000 },
 -      { 0x31ad, 0xf000 },
 -      { 0x31ae, 0x0000 },
 -      { 0x31af, 0xf000 },
 -      { 0x31b0, 0x0000 },
 -      { 0x31b1, 0xf000 },
 -      { 0x31b2, 0x0000 },
 -      { 0x31b3, 0xf000 },
 -      { 0x31b4, 0x0000 },
 -      { 0x31b5, 0xf000 },
 -      { 0x31b6, 0x0000 },
 -      { 0x31b7, 0xf000 },
 -      { 0x31b8, 0x0000 },
 -      { 0x31b9, 0xf000 },
 -      { 0x31ba, 0x0000 },
 -      { 0x31bb, 0xf000 },
 -      { 0x31bc, 0x0000 },
 -      { 0x31bd, 0xf000 },
 -      { 0x31be, 0x0000 },
 -      { 0x31bf, 0xf000 },
 -      { 0x31c0, 0x0000 },
 -      { 0x31c1, 0xf000 },
 -      { 0x31c2, 0x0000 },
 -      { 0x31c3, 0xf000 },
 -      { 0x31c4, 0x0000 },
 -      { 0x31c5, 0xf000 },
 -      { 0x31c6, 0x0000 },
 -      { 0x31c7, 0xf000 },
 -      { 0x31c8, 0x0000 },
 -      { 0x31c9, 0xf000 },
 -      { 0x31ca, 0x0000 },
 -      { 0x31cb, 0xf000 },
 -      { 0x31cc, 0x0000 },
 -      { 0x31cd, 0xf000 },
 -      { 0x31ce, 0x0000 },
 -      { 0x31cf, 0xf000 },
 -      { 0x31d0, 0x0000 },
 -      { 0x31d1, 0xf000 },
 -      { 0x31d2, 0x0000 },
 -      { 0x31d3, 0xf000 },
 -      { 0x31d4, 0x0000 },
 -      { 0x31d5, 0xf000 },
 -      { 0x31d6, 0x0000 },
 -      { 0x31d7, 0xf000 },
 -      { 0x31d8, 0x0000 },
 -      { 0x31d9, 0xf000 },
 -      { 0x31da, 0x0000 },
 -      { 0x31db, 0xf000 },
 -      { 0x31dc, 0x0000 },
 -      { 0x31dd, 0xf000 },
 -      { 0x31de, 0x0000 },
 -      { 0x31df, 0xf000 },
 -      { 0x31e0, 0x0000 },
 -      { 0x31e1, 0xf000 },
 -      { 0x31e2, 0x0000 },
 -      { 0x31e3, 0xf000 },
 -      { 0x31e4, 0x0000 },
 -      { 0x31e5, 0xf000 },
 -      { 0x31e6, 0x0000 },
 -      { 0x31e7, 0xf000 },
 -      { 0x31e8, 0x0000 },
 -      { 0x31e9, 0xf000 },
 -      { 0x31ea, 0x0000 },
 -      { 0x31eb, 0xf000 },
 -      { 0x31ec, 0x0000 },
 -      { 0x31ed, 0xf000 },
 -      { 0x31ee, 0x0000 },
 -      { 0x31ef, 0xf000 },
 -      { 0x31f0, 0x0000 },
 -      { 0x31f1, 0xf000 },
 -      { 0x31f2, 0x0000 },
 -      { 0x31f3, 0xf000 },
 -      { 0x31f4, 0x0000 },
 -      { 0x31f5, 0xf000 },
 -      { 0x31f6, 0x0000 },
 -      { 0x31f7, 0xf000 },
 -      { 0x31f8, 0x0000 },
 -      { 0x31f9, 0xf000 },
 -      { 0x31fa, 0x0000 },
 -      { 0x31fb, 0xf000 },
 -      { 0x31fc, 0x0000 },
 -      { 0x31fd, 0xf000 },
 -      { 0x31fe, 0x0000 },
 -      { 0x31ff, 0xf000 },
 -      { 0x024d, 0xff50 },
 -      { 0x0252, 0xff50 },
 -      { 0x0259, 0x0112 },
 -      { 0x025e, 0x0112 },
 -      { 0x101, 0x0304 },
        { 0x80, 0x0000 },
  };
  
+ static const struct reg_default wm5102_revb_patch[] = {
+       { 0x80, 0x0003 },
+       { 0x081, 0xE022 },
+       { 0x410, 0x6080 },
+       { 0x418, 0x6080 },
+       { 0x420, 0x6080 },
+       { 0x428, 0xC000 },
+       { 0x441, 0x8014 },
+       { 0x458, 0x000b },
+       { 0x80, 0x0000 },
+ };
  /* We use a function so we can use ARRAY_SIZE() */
  int wm5102_patch(struct arizona *arizona)
  {
                                             wm5102_reva_patch,
                                             ARRAY_SIZE(wm5102_reva_patch));
        default:
-               return 0;
+               return regmap_register_patch(arizona->regmap,
+                                            wm5102_revb_patch,
+                                            ARRAY_SIZE(wm5102_revb_patch));
        }
  }
  
@@@ -258,7 -789,6 +272,7 @@@ static const struct reg_default wm5102_
        { 0x00000154, 0x0000 },   /* R340   - Rate Estimator 3 */ 
        { 0x00000155, 0x0000 },   /* R341   - Rate Estimator 4 */ 
        { 0x00000156, 0x0000 },   /* R342   - Rate Estimator 5 */ 
 +      { 0x00000161, 0x0000 },   /* R353   - Dynamic Frequency Scaling 1 */ 
        { 0x00000171, 0x0000 },   /* R369   - FLL1 Control 1 */ 
        { 0x00000172, 0x0008 },   /* R370   - FLL1 Control 2 */ 
        { 0x00000173, 0x0018 },   /* R371   - FLL1 Control 3 */ 
        { 0x000001AA, 0x0004 },   /* R426   - FLL2 GPIO Clock */ 
        { 0x00000200, 0x0006 },   /* R512   - Mic Charge Pump 1 */ 
        { 0x00000210, 0x00D4 },   /* R528   - LDO1 Control 1 */ 
+       { 0x00000212, 0x0001 },   /* R530   - LDO1 Control 2 */
        { 0x00000213, 0x0344 },   /* R531   - LDO2 Control 1 */ 
        { 0x00000218, 0x01A6 },   /* R536   - Mic Bias Ctrl 1 */ 
        { 0x00000219, 0x01A6 },   /* R537   - Mic Bias Ctrl 2 */ 
@@@ -1048,7 -1579,6 +1063,7 @@@ static bool wm5102_readable_register(st
        case ARIZONA_RATE_ESTIMATOR_3:
        case ARIZONA_RATE_ESTIMATOR_4:
        case ARIZONA_RATE_ESTIMATOR_5:
 +      case ARIZONA_DYNAMIC_FREQUENCY_SCALING_1:
        case ARIZONA_FLL1_CONTROL_1:
        case ARIZONA_FLL1_CONTROL_2:
        case ARIZONA_FLL1_CONTROL_3:
        case ARIZONA_FLL1_CONTROL_5:
        case ARIZONA_FLL1_CONTROL_6:
        case ARIZONA_FLL1_LOOP_FILTER_TEST_1:
+       case ARIZONA_FLL1_NCO_TEST_0:
        case ARIZONA_FLL1_SYNCHRONISER_1:
        case ARIZONA_FLL1_SYNCHRONISER_2:
        case ARIZONA_FLL1_SYNCHRONISER_3:
        case ARIZONA_FLL2_CONTROL_5:
        case ARIZONA_FLL2_CONTROL_6:
        case ARIZONA_FLL2_LOOP_FILTER_TEST_1:
+       case ARIZONA_FLL2_NCO_TEST_0:
        case ARIZONA_FLL2_SYNCHRONISER_1:
        case ARIZONA_FLL2_SYNCHRONISER_2:
        case ARIZONA_FLL2_SYNCHRONISER_3:
        case ARIZONA_FLL2_GPIO_CLOCK:
        case ARIZONA_MIC_CHARGE_PUMP_1:
        case ARIZONA_LDO1_CONTROL_1:
 +      case ARIZONA_LDO1_CONTROL_2:
        case ARIZONA_LDO2_CONTROL_1:
        case ARIZONA_MIC_BIAS_CTRL_1:
        case ARIZONA_MIC_BIAS_CTRL_2:
        case ARIZONA_DSP1_CLOCKING_1:
        case ARIZONA_DSP1_STATUS_1:
        case ARIZONA_DSP1_STATUS_2:
+       case ARIZONA_DSP1_STATUS_3:
                return true;
        default:
                return false;
  
  static bool wm5102_volatile_register(struct device *dev, unsigned int reg)
  {
+       if (reg > 0xffff)
+               return true;
        switch (reg) {
        case ARIZONA_SOFTWARE_RESET:
        case ARIZONA_DEVICE_REVISION:
        case ARIZONA_OUTPUT_STATUS_1:
+       case ARIZONA_RAW_OUTPUT_STATUS_1:
+       case ARIZONA_SLIMBUS_RX_PORT_STATUS:
+       case ARIZONA_SLIMBUS_TX_PORT_STATUS:
        case ARIZONA_SAMPLE_RATE_1_STATUS:
        case ARIZONA_SAMPLE_RATE_2_STATUS:
        case ARIZONA_SAMPLE_RATE_3_STATUS:
        case ARIZONA_HAPTICS_STATUS:
        case ARIZONA_ASYNC_SAMPLE_RATE_1_STATUS:
+       case ARIZONA_FLL1_NCO_TEST_0:
+       case ARIZONA_FLL2_NCO_TEST_0:
        case ARIZONA_FX_CTRL2:
        case ARIZONA_INTERRUPT_STATUS_1:
        case ARIZONA_INTERRUPT_STATUS_2:
        case ARIZONA_AOD_IRQ_RAW_STATUS:
        case ARIZONA_DSP1_STATUS_1:
        case ARIZONA_DSP1_STATUS_2:
+       case ARIZONA_DSP1_STATUS_3:
        case ARIZONA_HEADPHONE_DETECT_2:
        case ARIZONA_MIC_DETECT_3:
                return true;
        }
  }
  
+ #define WM5102_MAX_REGISTER 0x1a8fff
  const struct regmap_config wm5102_spi_regmap = {
        .reg_bits = 32,
        .pad_bits = 16,
        .val_bits = 16,
  
-       .max_register = ARIZONA_DSP1_STATUS_2,
+       .max_register = WM5102_MAX_REGISTER,
        .readable_reg = wm5102_readable_register,
        .volatile_reg = wm5102_volatile_register,
  
@@@ -1874,7 -2417,7 +1903,7 @@@ const struct regmap_config wm5102_i2c_r
        .reg_bits = 32,
        .val_bits = 16,
  
-       .max_register = ARIZONA_DSP1_STATUS_2,
+       .max_register = WM5102_MAX_REGISTER,
        .readable_reg = wm5102_readable_register,
        .volatile_reg = wm5102_volatile_register,
  
index bcb226ff9d2b7415bc567d2e855bf18ebfcc487f,be1a424cbdeb512e8bb07b7d109253721fb22ea7..57c488d42d3e9b21e1ddd1dc68db4069e704aa44
@@@ -374,21 -374,21 +374,21 @@@ static int wm8994_ldo_in_use(struct wm8
  }
  #endif
  
 -static const __devinitconst struct reg_default wm8994_revc_patch[] = {
 +static const struct reg_default wm8994_revc_patch[] = {
        { 0x102, 0x3 },
        { 0x56, 0x3 },
        { 0x817, 0x0 },
        { 0x102, 0x0 },
  };
  
 -static const __devinitconst struct reg_default wm8958_reva_patch[] = {
 +static const struct reg_default wm8958_reva_patch[] = {
        { 0x102, 0x3 },
        { 0xcb, 0x81 },
        { 0x817, 0x0 },
        { 0x102, 0x0 },
  };
  
 -static const __devinitconst struct reg_default wm1811_reva_patch[] = {
 +static const struct reg_default wm1811_reva_patch[] = {
        { 0x102, 0x3 },
        { 0x56, 0xc07 },
        { 0x5d, 0x7e },
  /*
   * Instantiate the generic non-control parts of the device.
   */
 -static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq)
 +static int wm8994_device_init(struct wm8994 *wm8994, int irq)
  {
 -      struct wm8994_pdata *pdata = wm8994->dev->platform_data;
 +      struct wm8994_pdata *pdata;
        struct regmap_config *regmap_config;
        const struct reg_default *regmap_patch = NULL;
        const char *devname;
        int ret, i, patch_regs;
        int pulls = 0;
  
 +      if (dev_get_platdata(wm8994->dev)) {
 +              pdata = dev_get_platdata(wm8994->dev);
 +              wm8994->pdata = *pdata;
 +      }
 +      pdata = &wm8994->pdata;
 +
        dev_set_drvdata(wm8994->dev, wm8994);
  
        /* Add the on-chip regulators first for bootstrapping */
                        break;
                case 2:
                case 3:
+               default:
                        regmap_patch = wm8994_revc_patch;
                        patch_regs = ARRAY_SIZE(wm8994_revc_patch);
                        break;
-               default:
-                       break;
                }
                break;
  
                /* Revision C did not change the relevant layer */
                if (wm8994->revision > 1)
                        wm8994->revision++;
-               switch (wm8994->revision) {
-               case 0:
-               case 1:
-               case 2:
-               case 3:
-                       regmap_patch = wm1811_reva_patch;
-                       patch_regs = ARRAY_SIZE(wm1811_reva_patch);
-                       break;
-               default:
-                       break;
-               }
+               regmap_patch = wm1811_reva_patch;
+               patch_regs = ARRAY_SIZE(wm1811_reva_patch);
                break;
  
        default:
                }
        }
  
 -      if (pdata) {
 -              wm8994->irq_base = pdata->irq_base;
 -              wm8994->gpio_base = pdata->gpio_base;
 -
 -              /* GPIO configuration is only applied if it's non-zero */
 -              for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
 -                      if (pdata->gpio_defaults[i]) {
 -                              wm8994_set_bits(wm8994, WM8994_GPIO_1 + i,
 -                                              0xffff,
 -                                              pdata->gpio_defaults[i]);
 -                      }
 +      wm8994->irq_base = pdata->irq_base;
 +      wm8994->gpio_base = pdata->gpio_base;
 +
 +      /* GPIO configuration is only applied if it's non-zero */
 +      for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
 +              if (pdata->gpio_defaults[i]) {
 +                      wm8994_set_bits(wm8994, WM8994_GPIO_1 + i,
 +                                      0xffff, pdata->gpio_defaults[i]);
                }
 +      }
  
 -              wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven;
 +      wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven;
  
 -              if (pdata->spkmode_pu)
 -                      pulls |= WM8994_SPKMODE_PU;
 -      }
 +      if (pdata->spkmode_pu)
 +              pulls |= WM8994_SPKMODE_PU;
  
        /* Disable unneeded pulls */
        wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
@@@ -674,7 -662,7 +665,7 @@@ err
        return ret;
  }
  
 -static __devexit void wm8994_device_exit(struct wm8994 *wm8994)
 +static void wm8994_device_exit(struct wm8994 *wm8994)
  {
        pm_runtime_disable(wm8994->dev);
        mfd_remove_devices(wm8994->dev);
@@@ -692,7 -680,7 +683,7 @@@ static const struct of_device_id wm8994
  };
  MODULE_DEVICE_TABLE(of, wm8994_of_match);
  
 -static __devinit int wm8994_i2c_probe(struct i2c_client *i2c,
 +static int wm8994_i2c_probe(struct i2c_client *i2c,
                                      const struct i2c_device_id *id)
  {
        struct wm8994 *wm8994;
        return wm8994_device_init(wm8994, i2c->irq);
  }
  
 -static __devexit int wm8994_i2c_remove(struct i2c_client *i2c)
 +static int wm8994_i2c_remove(struct i2c_client *i2c)
  {
        struct wm8994 *wm8994 = i2c_get_clientdata(i2c);
  
@@@ -747,7 -735,7 +738,7 @@@ static struct i2c_driver wm8994_i2c_dri
                .of_match_table = wm8994_of_match,
        },
        .probe = wm8994_i2c_probe,
 -      .remove = __devexit_p(wm8994_i2c_remove),
 +      .remove = wm8994_i2c_remove,
        .id_table = wm8994_i2c_id,
  };
  
index b648058d718234e7b69dbceabd57df6bf90489fd,8aa592d14c4eac95e18ef61729ca949ad4a02799..e4e218c930bda626b6d9b62a30bcb5792817c458
@@@ -9,7 -9,6 +9,7 @@@ obj-$(CONFIG_MMC_MXS)            += mxs-mmc.
  obj-$(CONFIG_MMC_SDHCI)               += sdhci.o
  obj-$(CONFIG_MMC_SDHCI_PCI)   += sdhci-pci.o
  obj-$(subst m,y,$(CONFIG_MMC_SDHCI_PCI))      += sdhci-pci-data.o
 +obj-$(CONFIG_MMC_SDHCI_ACPI)  += sdhci-acpi.o
  obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o
  obj-$(CONFIG_MMC_SDHCI_PXAV2) += sdhci-pxav2.o
  obj-$(CONFIG_MMC_SDHCI_S3C)   += sdhci-s3c.o
@@@ -18,6 -17,7 +18,6 @@@ obj-$(CONFIG_MMC_WBSD)                += wbsd.
  obj-$(CONFIG_MMC_AU1X)                += au1xmmc.o
  obj-$(CONFIG_MMC_OMAP)                += omap.o
  obj-$(CONFIG_MMC_OMAP_HS)     += omap_hsmmc.o
 -obj-$(CONFIG_MMC_AT91)                += at91_mci.o
  obj-$(CONFIG_MMC_ATMELMCI)    += atmel-mci.o
  obj-$(CONFIG_MMC_TIFM_SD)     += tifm_sd.o
  obj-$(CONFIG_MMC_MSM)         += msm_sdcc.o
@@@ -45,10 -45,9 +45,12 @@@ obj-$(CONFIG_MMC_SH_MMCIF)  += sh_mmcif.
  obj-$(CONFIG_MMC_JZ4740)      += jz4740_mmc.o
  obj-$(CONFIG_MMC_VUB300)      += vub300.o
  obj-$(CONFIG_MMC_USHC)                += ushc.o
 +obj-$(CONFIG_MMC_WMT)         += wmt-sdmmc.o
 +
 +obj-$(CONFIG_MMC_REALTEK_PCI) += rtsx_pci_sdmmc.o
  
+ obj-$(CONFIG_MMC_REALTEK_PCI) += rtsx_pci_sdmmc.o
  obj-$(CONFIG_MMC_SDHCI_PLTFM)         += sdhci-pltfm.o
  obj-$(CONFIG_MMC_SDHCI_CNS3XXX)               += sdhci-cns3xxx.o
  obj-$(CONFIG_MMC_SDHCI_ESDHC_IMX)     += sdhci-esdhc-imx.o
index bb0df8917adcc92b70ec40c77700f141e737ba2a,3972dc0fc879b9bda3c66a812352d26d1cba8c4c..3c5c2e459d73c73b5f41493da8d383c74d606b3a
@@@ -440,8 -440,10 +440,10 @@@ static int da9052_bat_check_health(stru
  static irqreturn_t da9052_bat_irq(int irq, void *data)
  {
        struct da9052_battery *bat = data;
+       int virq;
  
-       irq -= bat->da9052->irq_base;
+       virq = regmap_irq_get_virq(bat->da9052->irq_data, irq);
+       irq -= virq;
  
        if (irq == DA9052_IRQ_CHGEND)
                bat->status = POWER_SUPPLY_STATUS_FULL;
@@@ -567,7 -569,7 +569,7 @@@ static struct power_supply template_bat
        .get_property   = da9052_bat_get_property,
  };
  
- static const char *const da9052_bat_irqs[] = {
+ static char *da9052_bat_irqs[] = {
        "BATT TEMP",
        "DCIN DET",
        "DCIN REM",
        "CHG END",
  };
  
 -static s32 __devinit da9052_bat_probe(struct platform_device *pdev)
+ static int da9052_bat_irq_bits[] = {
+       DA9052_IRQ_TBAT,
+       DA9052_IRQ_DCIN,
+       DA9052_IRQ_DCINREM,
+       DA9052_IRQ_VBUS,
+       DA9052_IRQ_VBUSREM,
+       DA9052_IRQ_CHGEND,
+ };
 +static s32 da9052_bat_probe(struct platform_device *pdev)
  {
        struct da9052_pdata *pdata;
        struct da9052_battery *bat;
        int ret;
-       int irq;
        int i;
  
        bat = kzalloc(sizeof(struct da9052_battery), GFP_KERNEL);
                bat->psy.use_for_apm = 1;
  
        for (i = 0; i < ARRAY_SIZE(da9052_bat_irqs); i++) {
-               irq = platform_get_irq_byname(pdev, da9052_bat_irqs[i]);
-               ret = request_threaded_irq(bat->da9052->irq_base + irq,
-                                          NULL, da9052_bat_irq,
-                                          IRQF_TRIGGER_LOW | IRQF_ONESHOT,
-                                          da9052_bat_irqs[i], bat);
+               ret = da9052_request_irq(bat->da9052,
+                               da9052_bat_irq_bits[i], da9052_bat_irqs[i],
+                               da9052_bat_irq, bat);
                if (ret != 0) {
                        dev_err(bat->da9052->dev,
-                               "DA9052 failed to request %s IRQ %d: %d\n",
-                               da9052_bat_irqs[i], irq, ret);
+                               "DA9052 failed to request %s IRQ: %d\n",
+                               da9052_bat_irqs[i], ret);
                        goto err;
                }
        }
        return 0;
  
  err:
-       while (--i >= 0) {
-               irq = platform_get_irq_byname(pdev, da9052_bat_irqs[i]);
-               free_irq(bat->da9052->irq_base + irq, bat);
-       }
+       while (--i >= 0)
+               da9052_free_irq(bat->da9052, da9052_bat_irq_bits[i], bat);
        kfree(bat);
        return ret;
  }
 -static int __devexit da9052_bat_remove(struct platform_device *pdev)
 +static int da9052_bat_remove(struct platform_device *pdev)
  {
        int i;
-       int irq;
        struct da9052_battery *bat = platform_get_drvdata(pdev);
  
-       for (i = 0; i < ARRAY_SIZE(da9052_bat_irqs); i++) {
-               irq = platform_get_irq_byname(pdev, da9052_bat_irqs[i]);
-               free_irq(bat->da9052->irq_base + irq, bat);
-       }
+       for (i = 0; i < ARRAY_SIZE(da9052_bat_irqs); i++)
+               da9052_free_irq(bat->da9052, da9052_bat_irq_bits[i], bat);
        power_supply_unregister(&bat->psy);
        kfree(bat);
  
  
  static struct platform_driver da9052_bat_driver = {
        .probe = da9052_bat_probe,
 -      .remove = __devexit_p(da9052_bat_remove),
 +      .remove = da9052_bat_remove,
        .driver = {
                .name = "da9052-bat",
                .owner = THIS_MODULE,
index ba26e99c388d0a7f6105ce9181cdc0f94e42736a,81bca23c9a922c9f6153aef73a0276b5356177ca..1f6fe31a4d5cdbfe0354e9eff4835ac5e87a145b
@@@ -76,7 -76,6 +76,7 @@@
  #define ARIZONA_RATE_ESTIMATOR_3                 0x154
  #define ARIZONA_RATE_ESTIMATOR_4                 0x155
  #define ARIZONA_RATE_ESTIMATOR_5                 0x156
 +#define ARIZONA_DYNAMIC_FREQUENCY_SCALING_1      0x161
  #define ARIZONA_FLL1_CONTROL_1                   0x171
  #define ARIZONA_FLL1_CONTROL_2                   0x172
  #define ARIZONA_FLL1_CONTROL_3                   0x173
  #define ARIZONA_FLL2_GPIO_CLOCK                  0x1AA
  #define ARIZONA_MIC_CHARGE_PUMP_1                0x200
  #define ARIZONA_LDO1_CONTROL_1                   0x210
 +#define ARIZONA_LDO1_CONTROL_2                   0x212
  #define ARIZONA_LDO2_CONTROL_1                   0x213
  #define ARIZONA_MIC_BIAS_CTRL_1                  0x218
  #define ARIZONA_MIC_BIAS_CTRL_2                  0x219
  #define ARIZONA_DSP1_CLOCKING_1                  0x1101
  #define ARIZONA_DSP1_STATUS_1                    0x1104
  #define ARIZONA_DSP1_STATUS_2                    0x1105
+ #define ARIZONA_DSP1_STATUS_3                    0x1106
  #define ARIZONA_DSP2_CONTROL_1                   0x1200
  #define ARIZONA_DSP2_CLOCKING_1                  0x1201
  #define ARIZONA_DSP2_STATUS_1                    0x1204
  #define ARIZONA_SAMPLE_RATE_DETECT_D_SHIFT            0  /* SAMPLE_RATE_DETECT_D - [4:0] */
  #define ARIZONA_SAMPLE_RATE_DETECT_D_WIDTH            5  /* SAMPLE_RATE_DETECT_D - [4:0] */
  
 +/*
 + * R353 (0x161) - Dynamic Frequency Scaling 1
 + */
 +#define ARIZONA_SUBSYS_MAX_FREQ                  0x0001  /* SUBSYS_MAX_FREQ */
 +#define ARIZONA_SUBSYS_MAX_FREQ_SHIFT                 0  /* SUBSYS_MAX_FREQ */
 +#define ARIZONA_SUBSYS_MAX_FREQ_WIDTH                 1  /* SUBSYS_MAX_FREQ */
 +
  /*
   * R369 (0x171) - FLL1 Control 1
   */
  #define ARIZONA_LDO1_ENA_SHIFT                        0  /* LDO1_ENA */
  #define ARIZONA_LDO1_ENA_WIDTH                        1  /* LDO1_ENA */
  
 +/*
 + * R530 (0x212) - LDO1 Control 2
 + */
 +#define ARIZONA_LDO1_HI_PWR                      0x0001  /* LDO1_HI_PWR */
 +#define ARIZONA_LDO1_HI_PWR_SHIFT                     0  /* LDO1_HI_PWR */
 +#define ARIZONA_LDO1_HI_PWR_WIDTH                     1  /* LDO1_HI_PWR */
 +
  /*
   * R531 (0x213) - LDO2 Control 1
   */
index f87a6c172a917f860976e90a62ddd8c790e4266e,b9b204edb4e99596273fafcd17f1aa720f6b4a18..04e092be4b0779b02a9c1dc4d426d5bf59dbebc3
@@@ -1,4 -1,4 +1,4 @@@
/* Copyright (C) 2012 Dialog Semiconductor Ltd.
+ /* Copyright (C) 2012 Dialog Semiconductor Ltd.
   *
   *  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
@@@ -25,29 -25,8 +25,29 @@@ struct da9055_pdata 
        int gpio_base;
  
        struct regulator_init_data *regulators[DA9055_MAX_REGULATORS];
 -      bool reset_enable;              /* Enable RTC in RESET Mode */
 -      enum gpio_select *gpio_rsel;    /* Select regulator set thru GPIO 1/2 */
 -      enum gpio_select *gpio_ren;     /* Enable regulator thru GPIO 1/2 */
 +      /* Enable RTC in RESET Mode */
 +      bool reset_enable;
 +      /*
 +       * GPI muxed pin to control
 +       * regulator state A/B, 0 if not available.
 +       */
 +      int *gpio_ren;
 +      /*
 +       * GPI muxed pin to control
 +       * regulator set, 0 if not available.
 +       */
 +      int *gpio_rsel;
 +      /*
 +       * Regulator mode control bits value (GPI offset) that
 +       * that controls the regulator state, 0 if not available.
 +       */
 +      enum gpio_select *reg_ren;
 +      /*
 +       * Regulator mode control bits value (GPI offset) that
 +       * controls the regulator set A/B, 0 if  not available.
 +       */
 +      enum gpio_select *reg_rsel;
 +      /* GPIOs to enable regulator, 0 if not available */
 +      int *ena_gpio;
  };
  #endif /* __DA9055_PDATA_H */
index 804e280c1e1d9a2a18157b377bfef9f622834cc7,4bbbb1350b91f8fd0f84e775a38a75c5b2328cf9..6694cf43e8b8998d1dce53712472c0eeba5b24b0
  #define __LINUX_MFD_TPS65090_H
  
  #include <linux/irq.h>
+ #include <linux/regmap.h>
+ /* TPS65090 IRQs */
+ enum {
+       TPS65090_IRQ_VAC_STATUS_CHANGE,
+       TPS65090_IRQ_VSYS_STATUS_CHANGE,
+       TPS65090_IRQ_BAT_STATUS_CHANGE,
+       TPS65090_IRQ_CHARGING_STATUS_CHANGE,
+       TPS65090_IRQ_CHARGING_COMPLETE,
+       TPS65090_IRQ_OVERLOAD_DCDC1,
+       TPS65090_IRQ_OVERLOAD_DCDC2,
+       TPS65090_IRQ_OVERLOAD_DCDC3,
+       TPS65090_IRQ_OVERLOAD_FET1,
+       TPS65090_IRQ_OVERLOAD_FET2,
+       TPS65090_IRQ_OVERLOAD_FET3,
+       TPS65090_IRQ_OVERLOAD_FET4,
+       TPS65090_IRQ_OVERLOAD_FET5,
+       TPS65090_IRQ_OVERLOAD_FET6,
+       TPS65090_IRQ_OVERLOAD_FET7,
+ };
  
 +/* TPS65090 Regulator ID */
 +enum {
 +      TPS65090_REGULATOR_DCDC1,
 +      TPS65090_REGULATOR_DCDC2,
 +      TPS65090_REGULATOR_DCDC3,
 +      TPS65090_REGULATOR_FET1,
 +      TPS65090_REGULATOR_FET2,
 +      TPS65090_REGULATOR_FET3,
 +      TPS65090_REGULATOR_FET4,
 +      TPS65090_REGULATOR_FET5,
 +      TPS65090_REGULATOR_FET6,
 +      TPS65090_REGULATOR_FET7,
 +      TPS65090_REGULATOR_LDO1,
 +      TPS65090_REGULATOR_LDO2,
 +
 +      /* Last entry for maximum ID */
 +      TPS65090_REGULATOR_MAX,
 +};
 +
  struct tps65090 {
-       struct mutex            lock;
        struct device           *dev;
-       struct i2c_client       *client;
        struct regmap           *rmap;
-       struct irq_chip         irq_chip;
-       struct mutex            irq_lock;
-       int                     irq_base;
-       unsigned int            id;
- };
- struct tps65090_subdev_info {
-       int             id;
-       const char      *name;
-       void            *platform_data;
+       struct regmap_irq_chip_data *irq_data;
  };
  
 +/*
 + * struct tps65090_regulator_plat_data
 + *
 + * @reg_init_data: The regulator init data.
 + * @enable_ext_control: Enable extrenal control or not. Only available for
 + *     DCDC1, DCDC2 and DCDC3.
 + * @gpio: Gpio number if external control is enabled and controlled through
 + *     gpio.
 + */
 +struct tps65090_regulator_plat_data {
 +      struct regulator_init_data *reg_init_data;
 +      bool enable_ext_control;
 +      int gpio;
 +};
 +
  struct tps65090_platform_data {
        int irq_base;
-       int num_subdevs;
-       struct tps65090_subdev_info *subdevs;
 +      struct tps65090_regulator_plat_data *reg_pdata[TPS65090_REGULATOR_MAX];
  };
  
  /*
   * NOTE: the functions below are not intended for use outside
   * of the TPS65090 sub-device drivers
   */
- extern int tps65090_write(struct device *dev, int reg, uint8_t val);
- extern int tps65090_read(struct device *dev, int reg, uint8_t *val);
- extern int tps65090_set_bits(struct device *dev, int reg, uint8_t bit_num);
- extern int tps65090_clr_bits(struct device *dev, int reg, uint8_t bit_num);
+ static inline int tps65090_write(struct device *dev, int reg, uint8_t val)
+ {
+       struct tps65090 *tps = dev_get_drvdata(dev);
+       return regmap_write(tps->rmap, reg, val);
+ }
+ static inline int tps65090_read(struct device *dev, int reg, uint8_t *val)
+ {
+       struct tps65090 *tps = dev_get_drvdata(dev);
+       unsigned int temp_val;
+       int ret;
+       ret = regmap_read(tps->rmap, reg, &temp_val);
+       if (!ret)
+               *val = temp_val;
+       return ret;
+ }
+ static inline int tps65090_set_bits(struct device *dev, int reg,
+               uint8_t bit_num)
+ {
+       struct tps65090 *tps = dev_get_drvdata(dev);
+       return regmap_update_bits(tps->rmap, reg, BIT(bit_num), ~0u);
+ }
+ static inline int tps65090_clr_bits(struct device *dev, int reg,
+               uint8_t bit_num)
+ {
+       struct tps65090 *tps = dev_get_drvdata(dev);
+       return regmap_update_bits(tps->rmap, reg, BIT(bit_num), 0u);
+ }
  
  #endif /*__LINUX_MFD_TPS65090_H */
index f8da0e152567059e0d0928c844e70dda7a94cc4a,ebd8b08a386bb26897dd8c38c408d9189e2b776f..87994542573ba713580b4e6e518a76b39243b78b
@@@ -29,7 -29,6 +29,7 @@@ enum 
        TPS6586X_ID_LDO_8,
        TPS6586X_ID_LDO_9,
        TPS6586X_ID_LDO_RTC,
 +      TPS6586X_ID_MAX_REGULATOR,
  };
  
  enum {
@@@ -80,8 -79,6 +80,8 @@@ struct tps6586x_platform_data 
        int gpio_base;
        int irq_base;
        bool pm_off;
 +
 +      struct regulator_init_data *reg_init_data[TPS6586X_ID_MAX_REGULATOR];
  };
  
  /*
@@@ -96,5 -93,6 +96,6 @@@ extern int tps6586x_set_bits(struct dev
  extern int tps6586x_clr_bits(struct device *dev, int reg, uint8_t bit_mask);
  extern int tps6586x_update(struct device *dev, int reg, uint8_t val,
                           uint8_t mask);
+ extern int tps6586x_irq_get_virq(struct device *dev, int irq);
  
  #endif /*__LINUX_MFD_TPS6586X_H */