diff options
-rw-r--r-- | drivers/gpio/gpio-pca953x.c | 77 |
1 files changed, 28 insertions, 49 deletions
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 5e4d3f23156a..e6805b97d047 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -85,7 +85,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; @@ -446,13 +445,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; @@ -476,7 +475,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, chip->irq_stat &= chip->reg_direction; mutex_init(&chip->irq_lock); - chip->irq_base = irq_alloc_descs(-1, pdata->irq_base, chip->gpio_chip.ngpio, -1); + chip->irq_base = irq_alloc_descs(-1, irq_base, chip->gpio_chip.ngpio, -1); if (chip->irq_base < 0) goto out_failed; @@ -524,12 +523,12 @@ static void pca953x_irq_teardown(struct pca953x_chip *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; @@ -547,45 +546,35 @@ static void pca953x_irq_teardown(struct pca953x_chip *chip) /* * Translate OpenFirmware node properties into platform_data */ -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; + return; - pdata = kzalloc(sizeof(struct pca953x_platform_data), GFP_KERNEL); - if (pdata == NULL) { - dev_err(&client->dev, "Unable to allocate platform_data\n"); - return NULL; - } - - pdata->gpio_base = -1; + *gpio_base = -1; val = of_get_property(node, "linux,gpio-base", &size); 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); 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 @@ -647,6 +636,7 @@ static int __devinit pca953x_probe(struct i2c_client *client, { struct pca953x_platform_data *pdata; struct pca953x_chip *chip; + int irq_base=-1, invert=0; int ret = 0; chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); @@ -654,26 +644,17 @@ 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); } 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); @@ -684,13 +665,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; @@ -698,7 +679,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) @@ -711,7 +692,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; } @@ -722,7 +702,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) { @@ -740,7 +720,6 @@ static int pca953x_remove(struct i2c_client *client) } pca953x_irq_teardown(chip); - kfree(chip->dyn_pdata); kfree(chip); return 0; } |