Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[pandora-kernel.git] / drivers / gpio / gpio-pca953x.c
index a610864..c43b8ff 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/slab.h>
 #ifdef CONFIG_OF_GPIO
 #include <linux/of_platform.h>
-#include <linux/of_gpio.h>
 #endif
 
 #define PCA953X_INPUT          0
@@ -85,7 +84,6 @@ struct pca953x_chip {
 #endif
 
        struct i2c_client *client;
-       struct pca953x_platform_data *dyn_pdata;
        struct gpio_chip gpio_chip;
        const char *const *names;
        int     chip_type;
@@ -437,7 +435,7 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid)
 
        do {
                level = __ffs(pending);
-               generic_handle_irq(level + chip->irq_base);
+               handle_nested_irq(level + chip->irq_base);
 
                pending &= ~(1 << level);
        } while (pending);
@@ -446,13 +444,13 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid)
 }
 
 static int pca953x_irq_setup(struct pca953x_chip *chip,
-                            const struct i2c_device_id *id)
+                            const struct i2c_device_id *id,
+                            int irq_base)
 {
        struct i2c_client *client = chip->client;
-       struct pca953x_platform_data *pdata = client->dev.platform_data;
        int ret, offset = 0;
 
-       if (pdata->irq_base != -1
+       if (irq_base != -1
                        && (id->driver_data & PCA_INT)) {
                int lvl;
 
@@ -474,15 +472,19 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
                 * this purpose.
                 */
                chip->irq_stat &= chip->reg_direction;
-               chip->irq_base = pdata->irq_base;
                mutex_init(&chip->irq_lock);
 
+               chip->irq_base = irq_alloc_descs(-1, irq_base, chip->gpio_chip.ngpio, -1);
+               if (chip->irq_base < 0)
+                       goto out_failed;
+
                for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) {
                        int irq = lvl + chip->irq_base;
 
+                       irq_clear_status_flags(irq, IRQ_NOREQUEST);
                        irq_set_chip_data(irq, chip);
-                       irq_set_chip_and_handler(irq, &pca953x_irq_chip,
-                                                handle_simple_irq);
+                       irq_set_chip(irq, &pca953x_irq_chip);
+                       irq_set_nested_thread(irq, true);
 #ifdef CONFIG_ARM
                        set_irq_flags(irq, IRQF_VALID);
 #else
@@ -493,7 +495,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
                ret = request_threaded_irq(client->irq,
                                           NULL,
                                           pca953x_irq_handler,
-                                          IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+                                          IRQF_TRIGGER_LOW | IRQF_ONESHOT,
                                           dev_name(&client->dev), chip);
                if (ret) {
                        dev_err(&client->dev, "failed to request irq %d\n",
@@ -513,17 +515,19 @@ out_failed:
 
 static void pca953x_irq_teardown(struct pca953x_chip *chip)
 {
-       if (chip->irq_base != -1)
+       if (chip->irq_base != -1) {
+               irq_free_descs(chip->irq_base, chip->gpio_chip.ngpio);
                free_irq(chip->client->irq, chip);
+       }
 }
 #else /* CONFIG_GPIO_PCA953X_IRQ */
 static int pca953x_irq_setup(struct pca953x_chip *chip,
-                            const struct i2c_device_id *id)
+                            const struct i2c_device_id *id,
+                            int irq_base)
 {
        struct i2c_client *client = chip->client;
-       struct pca953x_platform_data *pdata = client->dev.platform_data;
 
-       if (pdata->irq_base != -1 && (id->driver_data & PCA_INT))
+       if (irq_base != -1 && (id->driver_data & PCA_INT))
                dev_warn(&client->dev, "interrupt support not compiled in\n");
 
        return 0;
@@ -540,46 +544,39 @@ static void pca953x_irq_teardown(struct pca953x_chip *chip)
 #ifdef CONFIG_OF_GPIO
 /*
  * Translate OpenFirmware node properties into platform_data
+ * WARNING: This is DEPRECATED and will be removed eventually!
  */
-static struct pca953x_platform_data *
-pca953x_get_alt_pdata(struct i2c_client *client)
+void
+pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert)
 {
-       struct pca953x_platform_data *pdata;
        struct device_node *node;
        const __be32 *val;
        int size;
 
        node = client->dev.of_node;
        if (node == NULL)
-               return NULL;
-
-       pdata = kzalloc(sizeof(struct pca953x_platform_data), GFP_KERNEL);
-       if (pdata == NULL) {
-               dev_err(&client->dev, "Unable to allocate platform_data\n");
-               return NULL;
-       }
+               return;
 
-       pdata->gpio_base = -1;
+       *gpio_base = -1;
        val = of_get_property(node, "linux,gpio-base", &size);
+       WARN(val, "%s: device-tree property 'linux,gpio-base' is deprecated!", __func__);
        if (val) {
                if (size != sizeof(*val))
                        dev_warn(&client->dev, "%s: wrong linux,gpio-base\n",
                                 node->full_name);
                else
-                       pdata->gpio_base = be32_to_cpup(val);
+                       *gpio_base = be32_to_cpup(val);
        }
 
        val = of_get_property(node, "polarity", NULL);
+       WARN(val, "%s: device-tree property 'polarity' is deprecated!", __func__);
        if (val)
-               pdata->invert = *val;
-
-       return pdata;
+               *invert = *val;
 }
 #else
-static struct pca953x_platform_data *
-pca953x_get_alt_pdata(struct i2c_client *client)
+void
+pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert)
 {
-       return NULL;
 }
 #endif
 
@@ -641,6 +638,7 @@ static int __devinit pca953x_probe(struct i2c_client *client,
 {
        struct pca953x_platform_data *pdata;
        struct pca953x_chip *chip;
+       int irq_base=0, invert=0;
        int ret = 0;
 
        chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL);
@@ -648,26 +646,22 @@ static int __devinit pca953x_probe(struct i2c_client *client,
                return -ENOMEM;
 
        pdata = client->dev.platform_data;
-       if (pdata == NULL) {
-               pdata = pca953x_get_alt_pdata(client);
-               /*
-                * Unlike normal platform_data, this is allocated
-                * dynamically and must be freed in the driver
-                */
-               chip->dyn_pdata = pdata;
-       }
-
-       if (pdata == NULL) {
-               dev_dbg(&client->dev, "no platform data\n");
-               ret = -EINVAL;
-               goto out_failed;
+       if (pdata) {
+               irq_base = pdata->irq_base;
+               chip->gpio_start = pdata->gpio_base;
+               invert = pdata->invert;
+               chip->names = pdata->names;
+       } else {
+               pca953x_get_alt_pdata(client, &chip->gpio_start, &invert);
+#ifdef CONFIG_OF_GPIO
+               /* If I2C node has no interrupts property, disable GPIO interrupts */
+               if (of_find_property(client->dev.of_node, "interrupts", NULL) == NULL)
+                       irq_base = -1;
+#endif
        }
 
        chip->client = client;
 
-       chip->gpio_start = pdata->gpio_base;
-
-       chip->names = pdata->names;
        chip->chip_type = id->driver_data & (PCA953X_TYPE | PCA957X_TYPE);
 
        mutex_init(&chip->i2c_lock);
@@ -678,13 +672,13 @@ static int __devinit pca953x_probe(struct i2c_client *client,
        pca953x_setup_gpio(chip, id->driver_data & PCA_GPIO_MASK);
 
        if (chip->chip_type == PCA953X_TYPE)
-               device_pca953x_init(chip, pdata->invert);
+               device_pca953x_init(chip, invert);
        else if (chip->chip_type == PCA957X_TYPE)
-               device_pca957x_init(chip, pdata->invert);
+               device_pca957x_init(chip, invert);
        else
                goto out_failed;
 
-       ret = pca953x_irq_setup(chip, id);
+       ret = pca953x_irq_setup(chip, id, irq_base);
        if (ret)
                goto out_failed;
 
@@ -692,7 +686,7 @@ static int __devinit pca953x_probe(struct i2c_client *client,
        if (ret)
                goto out_failed_irq;
 
-       if (pdata->setup) {
+       if (pdata && pdata->setup) {
                ret = pdata->setup(client, chip->gpio_chip.base,
                                chip->gpio_chip.ngpio, pdata->context);
                if (ret < 0)
@@ -705,7 +699,6 @@ static int __devinit pca953x_probe(struct i2c_client *client,
 out_failed_irq:
        pca953x_irq_teardown(chip);
 out_failed:
-       kfree(chip->dyn_pdata);
        kfree(chip);
        return ret;
 }
@@ -716,7 +709,7 @@ static int pca953x_remove(struct i2c_client *client)
        struct pca953x_chip *chip = i2c_get_clientdata(client);
        int ret = 0;
 
-       if (pdata->teardown) {
+       if (pdata && pdata->teardown) {
                ret = pdata->teardown(client, chip->gpio_chip.base,
                                chip->gpio_chip.ngpio, pdata->context);
                if (ret < 0) {
@@ -734,7 +727,6 @@ static int pca953x_remove(struct i2c_client *client)
        }
 
        pca953x_irq_teardown(chip);
-       kfree(chip->dyn_pdata);
        kfree(chip);
        return 0;
 }