Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 18 Dec 2012 20:46:37 +0000 (12:46 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 18 Dec 2012 20:46:37 +0000 (12:46 -0800)
Pull second round of input updates from Dmitry Torokhov:
 "As usual, there are a couple of new drivers, input core now supports
  managed input devices (devres), a slew of drivers now have device tree
  support and a bunch of fixes and cleanups."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (71 commits)
  Input: walkera0701 - fix crash on startup
  Input: matrix-keymap - provide a proper module license
  Input: gpio_keys_polled - switch to using gpio_request_one()
  Input: gpio_keys - switch to using gpio_request_one()
  Input: wacom - fix touch support for Bamboo Fun CTH-461
  Input: xpad - add a few new VID/PID combinations
  Input: xpad - minor formatting fixes
  Input: gpio-keys-polled - honor 'autorepeat' setting in platform data
  Input: tca8418-keypad - switch to using managed resources
  Input: tca8418_keypad - increase severity of failures in probe()
  Input: tca8418_keypad - move device ID tables closer to where they are used
  Input: tca8418_keypad - use dev_get_platdata() to retrieve platform data
  Input: tca8418_keypad - use a temporary variable for parent device
  Input: tca8418_keypad - add support for shared interrupt
  Input: tca8418_keypad - add support for device tree bindings
  Input: remove Compaq iPAQ H3600 (Bitsy) touchscreen driver
  Input: bu21013_ts - add support for Device Tree booting
  Input: bu21013_ts - move GPIO init and exit functions into the driver
  Input: bu21013_ts - request regulator that actually exists
  ARM: ux500: Strip out duplicate touch screen platform information
  ...

12 files changed:
1  2 
arch/arm/mach-omap1/board-nokia770.c
drivers/input/input-mt.c
drivers/input/keyboard/Kconfig
drivers/input/misc/Kconfig
drivers/input/misc/Makefile
drivers/input/misc/da9052_onkey.c
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/Makefile
drivers/input/touchscreen/atmel_tsadcc.c
drivers/input/touchscreen/da9052_tsi.c
drivers/input/touchscreen/ti_am335x_tsc.c
drivers/mfd/stmpe.c

index 3e8ead67e4598db020424fd4bb2003359a714ccf,be6490b5eb2353978781bcc75103b95dbaf6f046..24d2f2df11a067646216f9359afbca2502ccef04
  #include <asm/mach/map.h>
  
  #include <mach/mux.h>
 -#include <plat/mmc.h>
 -#include <plat/clock.h>
  
  #include <mach/hardware.h>
  #include <mach/usb.h>
  
  #include "common.h"
 +#include "clock.h"
 +#include "mmc.h"
  
  #define ADS7846_PENDOWN_GPIO  15
  
@@@ -112,17 -112,6 +112,6 @@@ static void __init mipid_dev_init(void
        omapfb_set_lcd_config(&nokia770_lcd_config);
  }
  
- static void __init ads7846_dev_init(void)
- {
-       if (gpio_request(ADS7846_PENDOWN_GPIO, "ADS7846 pendown") < 0)
-               printk(KERN_ERR "can't get ads7846 pen down GPIO\n");
- }
- static int ads7846_get_pendown_state(void)
- {
-       return !gpio_get_value(ADS7846_PENDOWN_GPIO);
- }
  static struct ads7846_platform_data nokia770_ads7846_platform_data __initdata = {
        .x_max          = 0x0fff,
        .y_max          = 0x0fff,
        .debounce_max   = 10,
        .debounce_tol   = 3,
        .debounce_rep   = 1,
-       .get_pendown_state      = ads7846_get_pendown_state,
+       .gpio_pendown   = ADS7846_PENDOWN_GPIO,
  };
  
  static struct spi_board_info nokia770_spi_board_info[] __initdata = {
@@@ -241,7 -230,6 +230,6 @@@ static void __init omap_nokia770_init(v
        omap_serial_init();
        omap_register_i2c_bus(1, 100, NULL, 0);
        hwa742_dev_init();
-       ads7846_dev_init();
        mipid_dev_init();
        omap1_usb_init(&nokia770_usb_config);
        nokia770_mmc_init();
@@@ -251,6 -239,7 +239,6 @@@ MACHINE_START(NOKIA770, "Nokia 770"
        .atag_offset    = 0x100,
        .map_io         = omap16xx_map_io,
        .init_early     = omap1_init_early,
 -      .reserve        = omap_reserve,
        .init_irq       = omap1_init_irq,
        .init_machine   = omap_nokia770_init,
        .init_late      = omap1_init_late,
diff --combined drivers/input/input-mt.c
index 8c4b50fd9a79b59fcb15ce254d6fa835aa9eb4d9,c2f436ce7f5bea722edb236d2e5bf46540599f04..47a6009dbf43f04ba6dcd883513127857591a70f
@@@ -194,7 -194,7 +194,7 @@@ void input_mt_report_pointer_emulation(
        if (!mt)
                return;
  
-       oldest = 0;
+       oldest = NULL;
        oldid = mt->trkid;
        count = 0;
  
@@@ -251,7 -251,7 +251,7 @@@ void input_mt_sync_frame(struct input_d
  
        if (mt->flags & INPUT_MT_DROP_UNUSED) {
                for (s = mt->slots; s != mt->slots + mt->num_slots; s++) {
 -                      if (s->frame == mt->frame)
 +                      if (input_mt_is_used(mt, s))
                                continue;
                        input_mt_slot(dev, s - mt->slots);
                        input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
index febead4bf8a5d3b3c6f51711f4954c7aff78dba7,48309641b1b2a496fef70b98979b4320c3e7c45b..5a240c60342d8a8e7c3381a576103c2949bdce1d
@@@ -134,7 -134,7 +134,7 @@@ config KEYBOARD_QT107
  
  config KEYBOARD_QT2160
        tristate "Atmel AT42QT2160 Touch Sensor Chip"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          If you say yes here you get support for Atmel AT42QT2160 Touch
          Sensor chip as a keyboard input.
@@@ -409,7 -409,7 +409,7 @@@ config KEYBOARD_NEWTO
  
  config KEYBOARD_NOMADIK
        tristate "ST-Ericsson Nomadik SKE keyboard"
 -      depends on PLAT_NOMADIK
 +      depends on (ARCH_NOMADIK || ARCH_U8500)
        select INPUT_MATRIXKMAP
        help
          Say Y here if you want to use a keypad provided on the SKE controller
@@@ -544,7 -544,6 +544,7 @@@ config KEYBOARD_OMA
  
  config KEYBOARD_OMAP4
        tristate "TI OMAP4+ keypad support"
 +      depends on ARCH_OMAP2PLUS
        select INPUT_MATRIXKMAP
        help
          Say Y here if you want to use the OMAP4+ keypad.
index 104a7c3153c0c4ce5fd695403bfb8a263da992d7,2a1647ef5610077b905e1f43d1d5a698b883c711..259ef31abb18c9eccec32189f6f8641c79d9819f
@@@ -72,16 -72,6 +72,16 @@@ config INPUT_AD714X_SP
          To compile this driver as a module, choose M here: the
          module will be called ad714x-spi.
  
 +config INPUT_ARIZONA_HAPTICS
 +      tristate "Arizona haptics support"
 +      depends on MFD_ARIZONA && SND_SOC
 +      select INPUT_FF_MEMLESS
 +      help
 +        Say Y to enable support for the haptics module in Arizona CODECs.
 +
 +        To compile this driver as a module, choose M here: the
 +        module will be called arizona-haptics.
 +
  config INPUT_BMA150
        tristate "BMA150/SMB380 acceleration sensor support"
        depends on I2C
@@@ -300,8 -290,7 +300,7 @@@ config INPUT_ATI_REMOTE
          called ati_remote2.
  
  config INPUT_KEYSPAN_REMOTE
-       tristate "Keyspan DMR USB remote control (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
+       tristate "Keyspan DMR USB remote control"
        depends on USB_ARCH_HAS_HCD
        select USB
        help
@@@ -350,7 -339,6 +349,6 @@@ config INPUT_POWERMAT
  
  config INPUT_YEALINK
        tristate "Yealink usb-p1k voip phone"
-       depends on EXPERIMENTAL
        depends on USB_ARCH_HAS_HCD
        select USB
        help
  
  config INPUT_CM109
        tristate "C-Media CM109 USB I/O Controller"
-       depends on EXPERIMENTAL
        depends on USB_ARCH_HAS_HCD
        select USB
        help
          To compile this driver as a module, choose M here: the module will be
          called cm109.
  
+ config INPUT_RETU_PWRBUTTON
+       tristate "Retu Power button Driver"
+       depends on MFD_RETU
+       help
+         Say Y here if you want to enable power key reporting via the
+         Retu chips found in Nokia Internet Tablets (770, N800, N810).
+         To compile this driver as a module, choose M here. The module will
+         be called retu-pwrbutton.
  config INPUT_TWL4030_PWRBUTTON
        tristate "TWL4030 Power button Driver"
        depends on TWL4030_CORE
@@@ -444,7 -441,7 +451,7 @@@ config INPUT_PCF50633_PM
  
  config INPUT_PCF8574
        tristate "PCF8574 Keypad input device"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          Say Y here if you want to support a keypad connected via I2C
          with a PCF8574.
  
  config INPUT_PWM_BEEPER
        tristate "PWM beeper support"
-       depends on HAVE_PWM
+       depends on HAVE_PWM || PWM
        help
          Say Y here to get support for PWM based beeper devices.
  
@@@ -496,6 -493,16 +503,16 @@@ config INPUT_DA9052_ONKE
          To compile this driver as a module, choose M here: the
          module will be called da9052_onkey.
  
+ config INPUT_DA9055_ONKEY
+       tristate "Dialog Semiconductor DA9055 ONKEY"
+       depends on MFD_DA9055
+       help
+         Support the ONKEY of DA9055 PMICs as an input device
+         reporting power button status.
+         To compile this driver as a module, choose M here: the module
+         will be called da9055_onkey.
  config INPUT_DM355EVM
        tristate "TI DaVinci DM355 EVM Keypad and IR Remote"
        depends on MFD_DM355EVM_MSP
index 5ea769eda999ff1fa35954bdc6bf467c22ebbf99,1f874afeea6aab279c11d37bee9940a8556a795b..1f1e1b109d9dd3dd739c12c01cdff6018469027e
@@@ -14,7 -14,6 +14,7 @@@ obj-$(CONFIG_INPUT_ADXL34X)           += adxl34x
  obj-$(CONFIG_INPUT_ADXL34X_I2C)               += adxl34x-i2c.o
  obj-$(CONFIG_INPUT_ADXL34X_SPI)               += adxl34x-spi.o
  obj-$(CONFIG_INPUT_APANEL)            += apanel.o
 +obj-$(CONFIG_INPUT_ARIZONA_HAPTICS)   += arizona-haptics.o
  obj-$(CONFIG_INPUT_ATI_REMOTE2)               += ati_remote2.o
  obj-$(CONFIG_INPUT_ATLAS_BTNS)                += atlas_btns.o
  obj-$(CONFIG_INPUT_BFIN_ROTARY)               += bfin_rotary.o
@@@ -24,6 -23,7 +24,7 @@@ obj-$(CONFIG_INPUT_CMA3000)           += cma3000
  obj-$(CONFIG_INPUT_CMA3000_I2C)               += cma3000_d0x_i2c.o
  obj-$(CONFIG_INPUT_COBALT_BTNS)               += cobalt_btns.o
  obj-$(CONFIG_INPUT_DA9052_ONKEY)      += da9052_onkey.o
+ obj-$(CONFIG_INPUT_DA9055_ONKEY)      += da9055_onkey.o
  obj-$(CONFIG_INPUT_DM355EVM)          += dm355evm_keys.o
  obj-$(CONFIG_INPUT_GP2A)              += gp2ap002a00f.o
  obj-$(CONFIG_INPUT_GPIO_TILT_POLLED)  += gpio_tilt_polled.o
@@@ -46,6 -46,7 +47,7 @@@ obj-$(CONFIG_INPUT_PMIC8XXX_PWRKEY)   += 
  obj-$(CONFIG_INPUT_POWERMATE)         += powermate.o
  obj-$(CONFIG_INPUT_PWM_BEEPER)                += pwm-beeper.o
  obj-$(CONFIG_INPUT_RB532_BUTTON)      += rb532_button.o
+ obj-$(CONFIG_INPUT_RETU_PWRBUTTON)    += retu-pwrbutton.o
  obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER)       += rotary_encoder.o
  obj-$(CONFIG_INPUT_SGI_BTNS)          += sgi_btns.o
  obj-$(CONFIG_INPUT_SPARCSPKR)         += sparcspkr.o
index 3be3acc3a6eb9e142c6585c8479274cd88332374,630c1ce4980a1486d6442303e6d47852587ce746..020569a499f20faa03a63fff95847ed8be42c273
@@@ -24,6 -24,7 +24,6 @@@ struct da9052_onkey 
        struct da9052 *da9052;
        struct input_dev *input;
        struct delayed_work work;
 -      unsigned int irq;
  };
  
  static void da9052_onkey_query(struct da9052_onkey *onkey)
@@@ -70,11 -71,12 +70,11 @@@ static irqreturn_t da9052_onkey_irq(in
        return IRQ_HANDLED;
  }
  
- static int __devinit da9052_onkey_probe(struct platform_device *pdev)
+ static int da9052_onkey_probe(struct platform_device *pdev)
  {
        struct da9052 *da9052 = dev_get_drvdata(pdev->dev.parent);
        struct da9052_onkey *onkey;
        struct input_dev *input_dev;
 -      int irq;
        int error;
  
        if (!da9052) {
                return -EINVAL;
        }
  
 -      irq = platform_get_irq_byname(pdev, "ONKEY");
 -      if (irq < 0) {
 -              dev_err(&pdev->dev,
 -                      "Failed to get an IRQ for input device, %d\n", irq);
 -              return -EINVAL;
 -      }
 -
        onkey = kzalloc(sizeof(*onkey), GFP_KERNEL);
        input_dev = input_allocate_device();
        if (!onkey || !input_dev) {
  
        onkey->input = input_dev;
        onkey->da9052 = da9052;
 -      onkey->irq = irq;
        INIT_DELAYED_WORK(&onkey->work, da9052_onkey_work);
  
        input_dev->name = "da9052-onkey";
        input_dev->evbit[0] = BIT_MASK(EV_KEY);
        __set_bit(KEY_POWER, input_dev->keybit);
  
 -      error = request_threaded_irq(onkey->irq, NULL, da9052_onkey_irq,
 -                                   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
 -                                   "ONKEY", onkey);
 +      error = da9052_request_irq(onkey->da9052, DA9052_IRQ_NONKEY, "ONKEY",
 +                          da9052_onkey_irq, onkey);
        if (error < 0) {
                dev_err(onkey->da9052->dev,
 -                      "Failed to register ONKEY IRQ %d, error = %d\n",
 -                      onkey->irq, error);
 +                      "Failed to register ONKEY IRQ: %d\n", error);
                goto err_free_mem;
        }
  
        return 0;
  
  err_free_irq:
 -      free_irq(onkey->irq, onkey);
 +      da9052_free_irq(onkey->da9052, DA9052_IRQ_NONKEY, onkey);
        cancel_delayed_work_sync(&onkey->work);
  err_free_mem:
        input_free_device(input_dev);
        return error;
  }
  
- static int __devexit da9052_onkey_remove(struct platform_device *pdev)
+ static int da9052_onkey_remove(struct platform_device *pdev)
  {
        struct da9052_onkey *onkey = platform_get_drvdata(pdev);
  
 -      free_irq(onkey->irq, onkey);
 +      da9052_free_irq(onkey->da9052, DA9052_IRQ_NONKEY, onkey);
        cancel_delayed_work_sync(&onkey->work);
  
        input_unregister_device(onkey->input);
  
  static struct platform_driver da9052_onkey_driver = {
        .probe  = da9052_onkey_probe,
-       .remove = __devexit_p(da9052_onkey_remove),
+       .remove = da9052_onkey_remove,
        .driver = {
                .name   = "da9052-onkey",
                .owner  = THIS_MODULE,
index 0c45caddd41c0b3d5d4ce18238508414a1819eed,b93b5988ace837348ffa39ec6e6543012fcaaee9..515cfe7905430fb621362231ac7dd468f42a3016
@@@ -111,18 -111,6 +111,6 @@@ config TOUCHSCREEN_AUO_PIXCI
          To compile this driver as a module, choose M here: the
          module will be called auo-pixcir-ts.
  
- config TOUCHSCREEN_BITSY
-       tristate "Compaq iPAQ H3600 (Bitsy) touchscreen"
-       depends on SA1100_BITSY
-       select SERIO
-       help
-         Say Y here if you have the h3600 (Bitsy) touchscreen.
-         If unsure, say N.
-         To compile this driver as a module, choose M here: the
-         module will be called h3600_ts_input.
  config TOUCHSCREEN_BU21013
        tristate "BU21013 based touch panel controllers"
        depends on I2C
@@@ -529,9 -517,9 +517,9 @@@ config TOUCHSCREEN_TOUCHWI
          To compile this driver as a module, choose M here: the
          module will be called touchwin.
  
 -config TOUCHSCREEN_TI_TSCADC
 +config TOUCHSCREEN_TI_AM335X_TSC
        tristate "TI Touchscreen Interface"
 -      depends on ARCH_OMAP2PLUS
 +      depends on MFD_TI_AM335X_TSCADC
        help
          Say Y here if you have 4/5/8 wire touchscreen controller
          to be connected to the ADC controller on your TI AM335x SoC.
          If unsure, say N.
  
          To compile this driver as a module, choose M here: the
 -        module will be called ti_tscadc.
 +        module will be called ti_am335x_tsc.
  
  config TOUCHSCREEN_ATMEL_TSADCC
        tristate "Atmel Touchscreen Interface"
index 7c4c78ebe49e877a86d5e9198226bd892d415da9,5f949c0bf82f54cc8677b5a7a2dda4e810bedbcf..6bfbeab67c9ffc93489283cb88d8ea773e291719
@@@ -15,7 -15,6 +15,6 @@@ obj-$(CONFIG_TOUCHSCREEN_ADS7846)     += ad
  obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT)   += atmel_mxt_ts.o
  obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC)        += atmel_tsadcc.o
  obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR)  += auo-pixcir-ts.o
- obj-$(CONFIG_TOUCHSCREEN_BITSY)               += h3600_ts_input.o
  obj-$(CONFIG_TOUCHSCREEN_BU21013)     += bu21013_ts.o
  obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110)  += cy8ctmg110_ts.o
  obj-$(CONFIG_TOUCHSCREEN_CYTTSP_CORE) += cyttsp_core.o
@@@ -52,7 -51,7 +51,7 @@@ obj-$(CONFIG_TOUCHSCREEN_PIXCIR)      += pix
  obj-$(CONFIG_TOUCHSCREEN_S3C2410)     += s3c2410_ts.o
  obj-$(CONFIG_TOUCHSCREEN_ST1232)      += st1232.o
  obj-$(CONFIG_TOUCHSCREEN_STMPE)               += stmpe-ts.o
 -obj-$(CONFIG_TOUCHSCREEN_TI_TSCADC)   += ti_tscadc.o
 +obj-$(CONFIG_TOUCHSCREEN_TI_AM335X_TSC)       += ti_am335x_tsc.o
  obj-$(CONFIG_TOUCHSCREEN_TNETV107X)   += tnetv107x-ts.o
  obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213)  += touchit213.o
  obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT)  += touchright.o
index ea392ee138ed2cf2b95293df751d778dc866741d,55092d1c5cb9baf7004e8c53e9289b3b996aade1..95f6785a94b02ecf6ef64be0d638a7ef7a82c063
@@@ -22,7 -22,7 +22,7 @@@
  #include <linux/clk.h>
  #include <linux/platform_device.h>
  #include <linux/io.h>
 -#include <mach/board.h>
 +#include <linux/platform_data/atmel.h>
  #include <mach/cpu.h>
  
  /* Register definitions based on AT91SAM9RL64 preliminary draft datasheet */
@@@ -177,7 -177,7 +177,7 @@@ static irqreturn_t atmel_tsadcc_interru
   * The functions for inserting/removing us as a module.
   */
  
- static int __devinit atmel_tsadcc_probe(struct platform_device *pdev)
+ static int atmel_tsadcc_probe(struct platform_device *pdev)
  {
        struct atmel_tsadcc     *ts_dev;
        struct input_dev        *input_dev;
@@@ -323,7 -323,7 +323,7 @@@ err_free_mem
        return err;
  }
  
- static int __devexit atmel_tsadcc_remove(struct platform_device *pdev)
+ static int atmel_tsadcc_remove(struct platform_device *pdev)
  {
        struct atmel_tsadcc *ts_dev = dev_get_drvdata(&pdev->dev);
        struct resource *res;
  
  static struct platform_driver atmel_tsadcc_driver = {
        .probe          = atmel_tsadcc_probe,
-       .remove         = __devexit_p(atmel_tsadcc_remove),
+       .remove         = atmel_tsadcc_remove,
        .driver         = {
                .name   = "atmel_tsadcc",
        },
index 53133efe041873e1f690a955e7d78732c1f48ab8,303966ffe1e8c6c344facdf72b99eebe50c51808..8f561e22bdd498dacb85375773cad52f50388f46
@@@ -27,6 -27,8 +27,6 @@@ struct da9052_tsi 
        struct input_dev *dev;
        struct delayed_work ts_pen_work;
        struct mutex mutex;
 -      unsigned int irq_pendwn;
 -      unsigned int irq_datardy;
        bool stopped;
        bool adc_on;
  };
@@@ -43,8 -45,8 +43,8 @@@ static irqreturn_t da9052_ts_pendwn_irq
  
        if (!tsi->stopped) {
                /* Mask PEN_DOWN event and unmask TSI_READY event */
 -              disable_irq_nosync(tsi->irq_pendwn);
 -              enable_irq(tsi->irq_datardy);
 +              da9052_disable_irq_nosync(tsi->da9052, DA9052_IRQ_PENDOWN);
 +              da9052_enable_irq(tsi->da9052, DA9052_IRQ_TSIREADY);
  
                da9052_ts_adc_toggle(tsi, true);
  
@@@ -135,13 -137,13 +135,13 @@@ static void da9052_ts_pen_work(struct w
                                return;
  
                        /* Mask TSI_READY event and unmask PEN_DOWN event */
 -                      disable_irq(tsi->irq_datardy);
 -                      enable_irq(tsi->irq_pendwn);
 +                      da9052_disable_irq(tsi->da9052, DA9052_IRQ_TSIREADY);
 +                      da9052_enable_irq(tsi->da9052, DA9052_IRQ_PENDOWN);
                }
        }
  }
  
- static int __devinit da9052_ts_configure_gpio(struct da9052 *da9052)
+ static int da9052_ts_configure_gpio(struct da9052 *da9052)
  {
        int error;
  
        return 0;
  }
  
- static int __devinit da9052_configure_tsi(struct da9052_tsi *tsi)
+ static int da9052_configure_tsi(struct da9052_tsi *tsi)
  {
        int error;
  
@@@ -195,7 -197,7 +195,7 @@@ static int da9052_ts_input_open(struct 
        mb();
  
        /* Unmask PEN_DOWN event */
 -      enable_irq(tsi->irq_pendwn);
 +      da9052_enable_irq(tsi->da9052, DA9052_IRQ_PENDOWN);
  
        /* Enable Pen Detect Circuit */
        return da9052_reg_update(tsi->da9052, DA9052_TSI_CONT_A_REG,
@@@ -208,11 -210,11 +208,11 @@@ static void da9052_ts_input_close(struc
  
        tsi->stopped = true;
        mb();
 -      disable_irq(tsi->irq_pendwn);
 +      da9052_disable_irq(tsi->da9052, DA9052_IRQ_PENDOWN);
        cancel_delayed_work_sync(&tsi->ts_pen_work);
  
        if (tsi->adc_on) {
 -              disable_irq(tsi->irq_datardy);
 +              da9052_disable_irq(tsi->da9052, DA9052_IRQ_TSIREADY);
                da9052_ts_adc_toggle(tsi, false);
  
                /*
                 * twice and we need to enable it to keep enable/disable
                 * counter balanced. IRQ is still off though.
                 */
 -              enable_irq(tsi->irq_pendwn);
 +              da9052_enable_irq(tsi->da9052, DA9052_IRQ_PENDOWN);
        }
  
        /* Disable Pen Detect Circuit */
        da9052_reg_update(tsi->da9052, DA9052_TSI_CONT_A_REG, 1 << 1, 0);
  }
  
- static int __devinit da9052_ts_probe(struct platform_device *pdev)
+ static int da9052_ts_probe(struct platform_device *pdev)
  {
        struct da9052 *da9052;
        struct da9052_tsi *tsi;
        struct input_dev *input_dev;
 -      int irq_pendwn;
 -      int irq_datardy;
        int error;
  
        da9052 = dev_get_drvdata(pdev->dev.parent);
        if (!da9052)
                return -EINVAL;
  
 -      irq_pendwn = platform_get_irq_byname(pdev, "PENDWN");
 -      irq_datardy = platform_get_irq_byname(pdev, "TSIRDY");
 -      if (irq_pendwn < 0 || irq_datardy < 0) {
 -              dev_err(da9052->dev, "Unable to determine device interrupts\n");
 -              return -ENXIO;
 -      }
 -
        tsi = kzalloc(sizeof(struct da9052_tsi), GFP_KERNEL);
        input_dev = input_allocate_device();
        if (!tsi || !input_dev) {
  
        tsi->da9052 = da9052;
        tsi->dev = input_dev;
 -      tsi->irq_pendwn = da9052->irq_base + irq_pendwn;
 -      tsi->irq_datardy = da9052->irq_base + irq_datardy;
        tsi->stopped = true;
        INIT_DELAYED_WORK(&tsi->ts_pen_work, da9052_ts_pen_work);
  
        /* Disable ADC */
        da9052_ts_adc_toggle(tsi, false);
  
 -      error = request_threaded_irq(tsi->irq_pendwn,
 -                                   NULL, da9052_ts_pendwn_irq,
 -                                   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
 -                                   "PENDWN", tsi);
 +      error = da9052_request_irq(tsi->da9052, DA9052_IRQ_PENDOWN,
 +                              "pendown-irq", da9052_ts_pendwn_irq, tsi);
        if (error) {
                dev_err(tsi->da9052->dev,
 -                      "Failed to register PENDWN IRQ %d, error = %d\n",
 -                      tsi->irq_pendwn, error);
 +                      "Failed to register PENDWN IRQ: %d\n", error);
                goto err_free_mem;
        }
  
 -      error = request_threaded_irq(tsi->irq_datardy,
 -                                   NULL, da9052_ts_datardy_irq,
 -                                   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
 -                                   "TSIRDY", tsi);
 +      error = da9052_request_irq(tsi->da9052, DA9052_IRQ_TSIREADY,
 +                              "tsiready-irq", da9052_ts_datardy_irq, tsi);
        if (error) {
                dev_err(tsi->da9052->dev,
 -                      "Failed to register TSIRDY IRQ %d, error = %d\n",
 -                      tsi->irq_datardy, error);
 +                      "Failed to register TSIRDY IRQ :%d\n", error);
                goto err_free_pendwn_irq;
        }
  
        /* Mask PEN_DOWN and TSI_READY events */
 -      disable_irq(tsi->irq_pendwn);
 -      disable_irq(tsi->irq_datardy);
 +      da9052_disable_irq(tsi->da9052, DA9052_IRQ_PENDOWN);
 +      da9052_disable_irq(tsi->da9052, DA9052_IRQ_TSIREADY);
  
        error = da9052_configure_tsi(tsi);
        if (error)
        return 0;
  
  err_free_datardy_irq:
 -      free_irq(tsi->irq_datardy, tsi);
 +      da9052_free_irq(tsi->da9052, DA9052_IRQ_TSIREADY, tsi);
  err_free_pendwn_irq:
 -      free_irq(tsi->irq_pendwn, tsi);
 +      da9052_free_irq(tsi->da9052, DA9052_IRQ_PENDOWN, tsi);
  err_free_mem:
        kfree(tsi);
        input_free_device(input_dev);
        return error;
  }
  
- static int  __devexit da9052_ts_remove(struct platform_device *pdev)
+ static int  da9052_ts_remove(struct platform_device *pdev)
  {
        struct da9052_tsi *tsi = platform_get_drvdata(pdev);
  
        da9052_reg_write(tsi->da9052, DA9052_LDO9_REG, 0x19);
  
 -      free_irq(tsi->irq_pendwn, tsi);
 -      free_irq(tsi->irq_datardy, tsi);
 +      da9052_free_irq(tsi->da9052, DA9052_IRQ_TSIREADY, tsi);
 +      da9052_free_irq(tsi->da9052, DA9052_IRQ_PENDOWN, tsi);
  
        input_unregister_device(tsi->dev);
        kfree(tsi);
  
  static struct platform_driver da9052_tsi_driver = {
        .probe  = da9052_ts_probe,
-       .remove = __devexit_p(da9052_ts_remove),
+       .remove = da9052_ts_remove,
        .driver = {
                .name   = "da9052-tsi",
                .owner  = THIS_MODULE,
index 7a18a8a15228683ccd8cba001f493f689040a936,0000000000000000000000000000000000000000..51e7b87827a45ff0bd1c5335d2dc7b7b0ce70d8a
mode 100644,000000..100644
--- /dev/null
@@@ -1,398 -1,0 +1,398 @@@
- static int __devinit titsc_probe(struct platform_device *pdev)
 +/*
 + * TI Touch Screen driver
 + *
 + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
 + *
 + * This program is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU General Public License as
 + * published by the Free Software Foundation version 2.
 + *
 + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
 + * kind, whether express or implied; without even the implied warranty
 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + * GNU General Public License for more details.
 + */
 +
 +
 +#include <linux/init.h>
 +#include <linux/kernel.h>
 +#include <linux/err.h>
 +#include <linux/module.h>
 +#include <linux/input.h>
 +#include <linux/slab.h>
 +#include <linux/interrupt.h>
 +#include <linux/clk.h>
 +#include <linux/platform_device.h>
 +#include <linux/io.h>
 +#include <linux/input/ti_am335x_tsc.h>
 +#include <linux/delay.h>
 +
 +#include <linux/mfd/ti_am335x_tscadc.h>
 +
 +#define ADCFSM_STEPID         0x10
 +#define SEQ_SETTLE            275
 +#define MAX_12BIT             ((1 << 12) - 1)
 +
 +struct titsc {
 +      struct input_dev        *input;
 +      struct ti_tscadc_dev    *mfd_tscadc;
 +      unsigned int            irq;
 +      unsigned int            wires;
 +      unsigned int            x_plate_resistance;
 +      bool                    pen_down;
 +      int                     steps_to_configure;
 +};
 +
 +static unsigned int titsc_readl(struct titsc *ts, unsigned int reg)
 +{
 +      return readl(ts->mfd_tscadc->tscadc_base + reg);
 +}
 +
 +static void titsc_writel(struct titsc *tsc, unsigned int reg,
 +                                      unsigned int val)
 +{
 +      writel(val, tsc->mfd_tscadc->tscadc_base + reg);
 +}
 +
 +static void titsc_step_config(struct titsc *ts_dev)
 +{
 +      unsigned int    config;
 +      int i, total_steps;
 +
 +      /* Configure the Step registers */
 +      total_steps = 2 * ts_dev->steps_to_configure;
 +
 +      config = STEPCONFIG_MODE_HWSYNC |
 +                      STEPCONFIG_AVG_16 | STEPCONFIG_XPP;
 +      switch (ts_dev->wires) {
 +      case 4:
 +              config |= STEPCONFIG_INP_AN2 | STEPCONFIG_XNN;
 +              break;
 +      case 5:
 +              config |= STEPCONFIG_YNN |
 +                              STEPCONFIG_INP_AN4 | STEPCONFIG_XNN |
 +                              STEPCONFIG_YPP;
 +              break;
 +      case 8:
 +              config |= STEPCONFIG_INP_AN2 | STEPCONFIG_XNN;
 +              break;
 +      }
 +
 +      for (i = 1; i <= ts_dev->steps_to_configure; i++) {
 +              titsc_writel(ts_dev, REG_STEPCONFIG(i), config);
 +              titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY);
 +      }
 +
 +      config = 0;
 +      config = STEPCONFIG_MODE_HWSYNC |
 +                      STEPCONFIG_AVG_16 | STEPCONFIG_YNN |
 +                      STEPCONFIG_INM_ADCREFM | STEPCONFIG_FIFO1;
 +      switch (ts_dev->wires) {
 +      case 4:
 +              config |= STEPCONFIG_YPP;
 +              break;
 +      case 5:
 +              config |= STEPCONFIG_XPP | STEPCONFIG_INP_AN4 |
 +                              STEPCONFIG_XNP | STEPCONFIG_YPN;
 +              break;
 +      case 8:
 +              config |= STEPCONFIG_YPP;
 +              break;
 +      }
 +
 +      for (i = (ts_dev->steps_to_configure + 1); i <= total_steps; i++) {
 +              titsc_writel(ts_dev, REG_STEPCONFIG(i), config);
 +              titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY);
 +      }
 +
 +      config = 0;
 +      /* Charge step configuration */
 +      config = STEPCONFIG_XPP | STEPCONFIG_YNN |
 +                      STEPCHARGE_RFP_XPUL | STEPCHARGE_RFM_XNUR |
 +                      STEPCHARGE_INM_AN1 | STEPCHARGE_INP_AN1;
 +
 +      titsc_writel(ts_dev, REG_CHARGECONFIG, config);
 +      titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY);
 +
 +      config = 0;
 +      /* Configure to calculate pressure */
 +      config = STEPCONFIG_MODE_HWSYNC |
 +                      STEPCONFIG_AVG_16 | STEPCONFIG_YPP |
 +                      STEPCONFIG_XNN | STEPCONFIG_INM_ADCREFM;
 +      titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 1), config);
 +      titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 1),
 +                      STEPCONFIG_OPENDLY);
 +
 +      config |= STEPCONFIG_INP_AN3 | STEPCONFIG_FIFO1;
 +      titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 2), config);
 +      titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 2),
 +                      STEPCONFIG_OPENDLY);
 +
 +      titsc_writel(ts_dev, REG_SE, STPENB_STEPENB_TC);
 +}
 +
 +static void titsc_read_coordinates(struct titsc *ts_dev,
 +                                  unsigned int *x, unsigned int *y)
 +{
 +      unsigned int fifocount = titsc_readl(ts_dev, REG_FIFO0CNT);
 +      unsigned int prev_val_x = ~0, prev_val_y = ~0;
 +      unsigned int prev_diff_x = ~0, prev_diff_y = ~0;
 +      unsigned int read, diff;
 +      unsigned int i, channel;
 +
 +      /*
 +       * Delta filter is used to remove large variations in sampled
 +       * values from ADC. The filter tries to predict where the next
 +       * coordinate could be. This is done by taking a previous
 +       * coordinate and subtracting it form current one. Further the
 +       * algorithm compares the difference with that of a present value,
 +       * if true the value is reported to the sub system.
 +       */
 +      for (i = 0; i < fifocount - 1; i++) {
 +              read = titsc_readl(ts_dev, REG_FIFO0);
 +              channel = read & 0xf0000;
 +              channel = channel >> 0x10;
 +              if ((channel >= 0) && (channel < ts_dev->steps_to_configure)) {
 +                      read &= 0xfff;
 +                      diff = abs(read - prev_val_x);
 +                      if (diff < prev_diff_x) {
 +                              prev_diff_x = diff;
 +                              *x = read;
 +                      }
 +                      prev_val_x = read;
 +              }
 +
 +              read = titsc_readl(ts_dev, REG_FIFO1);
 +              channel = read & 0xf0000;
 +              channel = channel >> 0x10;
 +              if ((channel >= ts_dev->steps_to_configure) &&
 +                      (channel < (2 * ts_dev->steps_to_configure - 1))) {
 +                      read &= 0xfff;
 +                      diff = abs(read - prev_val_y);
 +                      if (diff < prev_diff_y) {
 +                              prev_diff_y = diff;
 +                              *y = read;
 +                      }
 +                      prev_val_y = read;
 +              }
 +      }
 +}
 +
 +static irqreturn_t titsc_irq(int irq, void *dev)
 +{
 +      struct titsc *ts_dev = dev;
 +      struct input_dev *input_dev = ts_dev->input;
 +      unsigned int status, irqclr = 0;
 +      unsigned int x = 0, y = 0;
 +      unsigned int z1, z2, z;
 +      unsigned int fsm;
 +      unsigned int fifo1count, fifo0count;
 +      int i;
 +
 +      status = titsc_readl(ts_dev, REG_IRQSTATUS);
 +      if (status & IRQENB_FIFO0THRES) {
 +              titsc_read_coordinates(ts_dev, &x, &y);
 +
 +              z1 = titsc_readl(ts_dev, REG_FIFO0) & 0xfff;
 +              z2 = titsc_readl(ts_dev, REG_FIFO1) & 0xfff;
 +
 +              fifo1count = titsc_readl(ts_dev, REG_FIFO1CNT);
 +              for (i = 0; i < fifo1count; i++)
 +                      titsc_readl(ts_dev, REG_FIFO1);
 +
 +              fifo0count = titsc_readl(ts_dev, REG_FIFO0CNT);
 +              for (i = 0; i < fifo0count; i++)
 +                      titsc_readl(ts_dev, REG_FIFO0);
 +
 +              if (ts_dev->pen_down && z1 != 0 && z2 != 0) {
 +                      /*
 +                       * Calculate pressure using formula
 +                       * Resistance(touch) = x plate resistance *
 +                       * x postion/4096 * ((z2 / z1) - 1)
 +                       */
 +                      z = z2 - z1;
 +                      z *= x;
 +                      z *= ts_dev->x_plate_resistance;
 +                      z /= z1;
 +                      z = (z + 2047) >> 12;
 +
 +                      if (z <= MAX_12BIT) {
 +                              input_report_abs(input_dev, ABS_X, x);
 +                              input_report_abs(input_dev, ABS_Y, y);
 +                              input_report_abs(input_dev, ABS_PRESSURE, z);
 +                              input_report_key(input_dev, BTN_TOUCH, 1);
 +                              input_sync(input_dev);
 +                      }
 +              }
 +              irqclr |= IRQENB_FIFO0THRES;
 +      }
 +
 +      /*
 +       * Time for sequencer to settle, to read
 +       * correct state of the sequencer.
 +       */
 +      udelay(SEQ_SETTLE);
 +
 +      status = titsc_readl(ts_dev, REG_RAWIRQSTATUS);
 +      if (status & IRQENB_PENUP) {
 +              /* Pen up event */
 +              fsm = titsc_readl(ts_dev, REG_ADCFSM);
 +              if (fsm == ADCFSM_STEPID) {
 +                      ts_dev->pen_down = false;
 +                      input_report_key(input_dev, BTN_TOUCH, 0);
 +                      input_report_abs(input_dev, ABS_PRESSURE, 0);
 +                      input_sync(input_dev);
 +              } else {
 +                      ts_dev->pen_down = true;
 +              }
 +              irqclr |= IRQENB_PENUP;
 +      }
 +
 +      titsc_writel(ts_dev, REG_IRQSTATUS, irqclr);
 +
 +      titsc_writel(ts_dev, REG_SE, STPENB_STEPENB_TC);
 +      return IRQ_HANDLED;
 +}
 +
 +/*
 + * The functions for inserting/removing driver as a module.
 + */
 +
- static int __devexit titsc_remove(struct platform_device *pdev)
++static int titsc_probe(struct platform_device *pdev)
 +{
 +      struct titsc *ts_dev;
 +      struct input_dev *input_dev;
 +      struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data;
 +      struct mfd_tscadc_board *pdata;
 +      int err;
 +
 +      pdata = tscadc_dev->dev->platform_data;
 +
 +      if (!pdata) {
 +              dev_err(&pdev->dev, "Could not find platform data\n");
 +              return -EINVAL;
 +      }
 +
 +      /* Allocate memory for device */
 +      ts_dev = kzalloc(sizeof(struct titsc), GFP_KERNEL);
 +      input_dev = input_allocate_device();
 +      if (!ts_dev || !input_dev) {
 +              dev_err(&pdev->dev, "failed to allocate memory.\n");
 +              err = -ENOMEM;
 +              goto err_free_mem;
 +      }
 +
 +      tscadc_dev->tsc = ts_dev;
 +      ts_dev->mfd_tscadc = tscadc_dev;
 +      ts_dev->input = input_dev;
 +      ts_dev->irq = tscadc_dev->irq;
 +      ts_dev->wires = pdata->tsc_init->wires;
 +      ts_dev->x_plate_resistance = pdata->tsc_init->x_plate_resistance;
 +      ts_dev->steps_to_configure = pdata->tsc_init->steps_to_configure;
 +
 +      err = request_irq(ts_dev->irq, titsc_irq,
 +                        0, pdev->dev.driver->name, ts_dev);
 +      if (err) {
 +              dev_err(&pdev->dev, "failed to allocate irq.\n");
 +              goto err_free_mem;
 +      }
 +
 +      titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES);
 +      titsc_step_config(ts_dev);
 +      titsc_writel(ts_dev, REG_FIFO0THR, ts_dev->steps_to_configure);
 +
 +      input_dev->name = "ti-tsc";
 +      input_dev->dev.parent = &pdev->dev;
 +
 +      input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 +      input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 +
 +      input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0);
 +      input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0);
 +      input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0);
 +
 +      /* register to the input system */
 +      err = input_register_device(input_dev);
 +      if (err)
 +              goto err_free_irq;
 +
 +      platform_set_drvdata(pdev, ts_dev);
 +      return 0;
 +
 +err_free_irq:
 +      free_irq(ts_dev->irq, ts_dev);
 +err_free_mem:
 +      input_free_device(input_dev);
 +      kfree(ts_dev);
 +      return err;
 +}
 +
-       .remove = __devexit_p(titsc_remove),
++static int titsc_remove(struct platform_device *pdev)
 +{
 +      struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data;
 +      struct titsc *ts_dev = tscadc_dev->tsc;
 +
 +      free_irq(ts_dev->irq, ts_dev);
 +
 +      input_unregister_device(ts_dev->input);
 +
 +      platform_set_drvdata(pdev, NULL);
 +      kfree(ts_dev);
 +      return 0;
 +}
 +
 +#ifdef CONFIG_PM
 +static int titsc_suspend(struct device *dev)
 +{
 +      struct ti_tscadc_dev *tscadc_dev = dev->platform_data;
 +      struct titsc *ts_dev = tscadc_dev->tsc;
 +      unsigned int idle;
 +
 +      if (device_may_wakeup(tscadc_dev->dev)) {
 +              idle = titsc_readl(ts_dev, REG_IRQENABLE);
 +              titsc_writel(ts_dev, REG_IRQENABLE,
 +                              (idle | IRQENB_HW_PEN));
 +              titsc_writel(ts_dev, REG_IRQWAKEUP, IRQWKUP_ENB);
 +      }
 +      return 0;
 +}
 +
 +static int titsc_resume(struct device *dev)
 +{
 +      struct ti_tscadc_dev *tscadc_dev = dev->platform_data;
 +      struct titsc *ts_dev = tscadc_dev->tsc;
 +
 +      if (device_may_wakeup(tscadc_dev->dev)) {
 +              titsc_writel(ts_dev, REG_IRQWAKEUP,
 +                              0x00);
 +              titsc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN);
 +      }
 +      titsc_step_config(ts_dev);
 +      titsc_writel(ts_dev, REG_FIFO0THR,
 +                      ts_dev->steps_to_configure);
 +      return 0;
 +}
 +
 +static const struct dev_pm_ops titsc_pm_ops = {
 +      .suspend = titsc_suspend,
 +      .resume  = titsc_resume,
 +};
 +#define TITSC_PM_OPS (&titsc_pm_ops)
 +#else
 +#define TITSC_PM_OPS NULL
 +#endif
 +
 +static struct platform_driver ti_tsc_driver = {
 +      .probe  = titsc_probe,
++      .remove = titsc_remove,
 +      .driver = {
 +              .name   = "tsc",
 +              .owner  = THIS_MODULE,
 +              .pm     = TITSC_PM_OPS,
 +      },
 +};
 +module_platform_driver(ti_tsc_driver);
 +
 +MODULE_DESCRIPTION("TI touchscreen controller driver");
 +MODULE_AUTHOR("Rachna Patil <rachna@ti.com>");
 +MODULE_LICENSE("GPL");
diff --combined drivers/mfd/stmpe.c
index 19636199d7a57066cfd5c1069414c2d8c74643b3,bf1ba93f43a05c78924d213caf03ea05303232ba..5e8e6927cfcd8a78db34c3e7a6efb9858aa9551b
@@@ -7,15 -7,11 +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>
@@@ -298,14 -294,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,
        },
  };
  
  static struct mfd_cell stmpe_keypad_cell = {
        .name           = "stmpe-keypad",
+       .of_compatible  = "st,stmpe-keypad",
        .resources      = stmpe_keypad_resources,
        .num_resources  = ARRAY_SIZE(stmpe_keypad_resources),
  };
@@@ -399,16 -398,21 +400,17 @@@ 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,
        },
  };
  
  static struct mfd_cell stmpe_ts_cell = {
        .name           = "stmpe-ts",
+       .of_compatible  = "st,stmpe-ts",
        .resources      = stmpe_ts_resources,
        .num_resources  = ARRAY_SIZE(stmpe_ts_resources),
  };
@@@ -524,12 -528,12 +526,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,
        },
  };
@@@ -763,9 -767,7 +765,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);
                }
  
@@@ -829,7 -830,7 +831,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);
  
@@@ -854,59 -855,43 +856,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;
  }
  
@@@ -1145,6 -1099,16 +1147,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;
  }