From 8a233f01b7d7dd587f85fa581274f168f1e88bb8 Mon Sep 17 00:00:00 2001 From: Alek Du Date: Tue, 26 Oct 2010 14:22:41 -0700 Subject: [PATCH] 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 Signed-off-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpio/pca953x.c | 13 +++++++------ 1 file 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) do { level = __ffs(pending); - handle_nested_irq(level + chip->irq_base); + generic_handle_irq(level + chip->irq_base); pending &= ~(1 << level); } while (pending); @@ -360,7 +360,8 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, struct pca953x_platform_data *pdata = client->dev.platform_data; int ret; - if (pdata->irq_base && (id->driver_data & PCA953X_INT)) { + if (pdata->irq_base != -1 + && (id->driver_data & PCA953X_INT)) { int lvl; ret = pca953x_read_reg(chip, PCA953X_INPUT, @@ -383,7 +384,6 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, set_irq_chip_data(irq, chip); set_irq_chip_and_handler(irq, &pca953x_irq_chip, handle_edge_irq); - set_irq_nested_thread(irq, 1); #ifdef CONFIG_ARM set_irq_flags(irq, IRQF_VALID); #else @@ -394,6 +394,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, ret = request_threaded_irq(client->irq, NULL, pca953x_irq_handler, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, dev_name(&client->dev), chip); if (ret) { @@ -408,13 +409,13 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, return 0; out_failed: - chip->irq_base = 0; + chip->irq_base = -1; return ret; } static void pca953x_irq_teardown(struct pca953x_chip *chip) { - if (chip->irq_base) + if (chip->irq_base != -1) free_irq(chip->client->irq, chip); } #else /* CONFIG_GPIO_PCA953X_IRQ */ @@ -424,7 +425,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, struct i2c_client *client = chip->client; struct pca953x_platform_data *pdata = client->dev.platform_data; - if (pdata->irq_base && (id->driver_data & PCA953X_INT)) + if (pdata->irq_base != -1 && (id->driver_data & PCA953X_INT)) dev_warn(&client->dev, "interrupt support not compiled in\n"); return 0;