aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/pca953x.c
diff options
context:
space:
mode:
authorAlek Du <alek.du@intel.com>2010-10-26 17:22:41 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-26 19:52:15 -0400
commit8a233f01b7d7dd587f85fa581274f168f1e88bb8 (patch)
treea3f48e7647dde5cd62d2931c3152a5ded590e6d5 /drivers/gpio/pca953x.c
parent2e85c4ddd3f32d3e1da51f4129473399e505ffa3 (diff)
pca953x: pca953x driver fixes for x86 mrst
Our Moorestown platform has two max7315 chips which is covered by pca953x i2c gpio driver. A while ago this driver got updated with nested irq thread support, and it broke the compatibity with "request_irq". For example, the gpio_keys.c driver can not work with this driver now. This patch fixes the issue by switching to generic_handle_irq. Also fix the irq_base issue: irq_base == 0 is valid, and a "-1" value should mean invalid. IRQ 0 is not a valid IRQ, irq_base of 0 is valid. Signed-off-by: Alek Du <alek.du@intel.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/gpio/pca953x.c')
-rw-r--r--drivers/gpio/pca953x.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c
index a2b12aa1f2b9..501866662e05 100644
--- a/drivers/gpio/pca953x.c
+++ b/drivers/gpio/pca953x.c
@@ -345,7 +345,7 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid)
345 345
346 do { 346 do {
347 level = __ffs(pending); 347 level = __ffs(pending);
348 handle_nested_irq(level + chip->irq_base); 348 generic_handle_irq(level + chip->irq_base);
349 349
350 pending &= ~(1 << level); 350 pending &= ~(1 << level);
351 } while (pending); 351 } while (pending);
@@ -360,7 +360,8 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
360 struct pca953x_platform_data *pdata = client->dev.platform_data; 360 struct pca953x_platform_data *pdata = client->dev.platform_data;
361 int ret; 361 int ret;
362 362
363 if (pdata->irq_base && (id->driver_data & PCA953X_INT)) { 363 if (pdata->irq_base != -1
364 && (id->driver_data & PCA953X_INT)) {
364 int lvl; 365 int lvl;
365 366
366 ret = pca953x_read_reg(chip, PCA953X_INPUT, 367 ret = pca953x_read_reg(chip, PCA953X_INPUT,
@@ -383,7 +384,6 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
383 set_irq_chip_data(irq, chip); 384 set_irq_chip_data(irq, chip);
384 set_irq_chip_and_handler(irq, &pca953x_irq_chip, 385 set_irq_chip_and_handler(irq, &pca953x_irq_chip,
385 handle_edge_irq); 386 handle_edge_irq);
386 set_irq_nested_thread(irq, 1);
387#ifdef CONFIG_ARM 387#ifdef CONFIG_ARM
388 set_irq_flags(irq, IRQF_VALID); 388 set_irq_flags(irq, IRQF_VALID);
389#else 389#else
@@ -394,6 +394,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
394 ret = request_threaded_irq(client->irq, 394 ret = request_threaded_irq(client->irq,
395 NULL, 395 NULL,
396 pca953x_irq_handler, 396 pca953x_irq_handler,
397 IRQF_TRIGGER_RISING |
397 IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 398 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
398 dev_name(&client->dev), chip); 399 dev_name(&client->dev), chip);
399 if (ret) { 400 if (ret) {
@@ -408,13 +409,13 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
408 return 0; 409 return 0;
409 410
410out_failed: 411out_failed:
411 chip->irq_base = 0; 412 chip->irq_base = -1;
412 return ret; 413 return ret;
413} 414}
414 415
415static void pca953x_irq_teardown(struct pca953x_chip *chip) 416static void pca953x_irq_teardown(struct pca953x_chip *chip)
416{ 417{
417 if (chip->irq_base) 418 if (chip->irq_base != -1)
418 free_irq(chip->client->irq, chip); 419 free_irq(chip->client->irq, chip);
419} 420}
420#else /* CONFIG_GPIO_PCA953X_IRQ */ 421#else /* CONFIG_GPIO_PCA953X_IRQ */
@@ -424,7 +425,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
424 struct i2c_client *client = chip->client; 425 struct i2c_client *client = chip->client;
425 struct pca953x_platform_data *pdata = client->dev.platform_data; 426 struct pca953x_platform_data *pdata = client->dev.platform_data;
426 427
427 if (pdata->irq_base && (id->driver_data & PCA953X_INT)) 428 if (pdata->irq_base != -1 && (id->driver_data & PCA953X_INT))
428 dev_warn(&client->dev, "interrupt support not compiled in\n"); 429 dev_warn(&client->dev, "interrupt support not compiled in\n");
429 430
430 return 0; 431 return 0;