Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 256715
b: refs/heads/master
c: c6dcf59
h: refs/heads/master
i:
  256713: e33d712
  256711: b502fbc
v: v3
  • Loading branch information
David Jander authored and Grant Likely committed Jun 16, 2011
1 parent 27a3483 commit 213800a
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 50 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c609c05db10dcb020f6869186e548a0596a78896
refs/heads/master: c6dcf592437e5919cb03af5dcfe369702e6a4a7c
77 changes: 28 additions & 49 deletions trunk/drivers/gpio/gpio-pca953x.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand All @@ -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;

Expand Down Expand Up @@ -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;
Expand All @@ -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

Expand Down Expand Up @@ -647,33 +636,25 @@ 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);
if (chip == NULL)
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);
Expand All @@ -684,21 +665,21 @@ 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;

ret = gpiochip_add(&chip->gpio_chip);
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)
Expand All @@ -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;
}
Expand All @@ -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) {
Expand All @@ -740,7 +720,6 @@ static int pca953x_remove(struct i2c_client *client)
}

pca953x_irq_teardown(chip);
kfree(chip->dyn_pdata);
kfree(chip);
return 0;
}
Expand Down

0 comments on commit 213800a

Please sign in to comment.