diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2016-12-07 15:24:12 +0100 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2016-12-07 15:24:12 +0100 |
commit | acf1fcf77247efa01d7213f53082451f6c9c8f3b (patch) | |
tree | 7f4acc733d5384e0f342240a82c6156f5619e80c /drivers/gpio | |
parent | eb485c7d9e6d71e4f621edb83573cb85c1d22975 (diff) | |
parent | 35ca3f61617db77364e40c1977952c5ee0a776cb (diff) |
Merge branch 'thread-irq-simpler' into devel
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpio-adnp.c | 12 | ||||
-rw-r--r-- | drivers/gpio/gpio-crystalcove.c | 6 | ||||
-rw-r--r-- | drivers/gpio/gpio-dln2.c | 1 | ||||
-rw-r--r-- | drivers/gpio/gpio-max732x.c | 17 | ||||
-rw-r--r-- | drivers/gpio/gpio-mcp23s08.c | 17 | ||||
-rw-r--r-- | drivers/gpio/gpio-pca953x.c | 16 | ||||
-rw-r--r-- | drivers/gpio/gpio-pcf857x.c | 11 | ||||
-rw-r--r-- | drivers/gpio/gpio-stmpe.c | 17 | ||||
-rw-r--r-- | drivers/gpio/gpio-tc3589x.c | 17 | ||||
-rw-r--r-- | drivers/gpio/gpio-wcove.c | 6 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.c | 69 |
11 files changed, 117 insertions, 72 deletions
diff --git a/drivers/gpio/gpio-adnp.c b/drivers/gpio/gpio-adnp.c index 8ff7b0d3eac6..89863ea25de1 100644 --- a/drivers/gpio/gpio-adnp.c +++ b/drivers/gpio/gpio-adnp.c @@ -468,17 +468,19 @@ static int adnp_irq_setup(struct adnp *adnp) return err; } - err = gpiochip_irqchip_add(chip, - &adnp_irq_chip, - 0, - handle_simple_irq, - IRQ_TYPE_NONE); + err = gpiochip_irqchip_add_nested(chip, + &adnp_irq_chip, + 0, + handle_simple_irq, + IRQ_TYPE_NONE); if (err) { dev_err(chip->parent, "could not connect irqchip to gpiochip\n"); return err; } + gpiochip_set_nested_irqchip(chip, &adnp_irq_chip, adnp->client->irq); + return 0; } diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c index 7c446d118cd6..2197368cc899 100644 --- a/drivers/gpio/gpio-crystalcove.c +++ b/drivers/gpio/gpio-crystalcove.c @@ -351,8 +351,8 @@ static int crystalcove_gpio_probe(struct platform_device *pdev) return retval; } - gpiochip_irqchip_add(&cg->chip, &crystalcove_irqchip, 0, - handle_simple_irq, IRQ_TYPE_NONE); + gpiochip_irqchip_add_nested(&cg->chip, &crystalcove_irqchip, 0, + handle_simple_irq, IRQ_TYPE_NONE); retval = request_threaded_irq(irq, NULL, crystalcove_gpio_irq_handler, IRQF_ONESHOT, KBUILD_MODNAME, cg); @@ -362,6 +362,8 @@ static int crystalcove_gpio_probe(struct platform_device *pdev) return retval; } + gpiochip_set_nested_irqchip(&cg->chip, &crystalcove_irqchip, irq); + return 0; } diff --git a/drivers/gpio/gpio-dln2.c b/drivers/gpio/gpio-dln2.c index f7a60a441e95..5d38b08d1ee2 100644 --- a/drivers/gpio/gpio-dln2.c +++ b/drivers/gpio/gpio-dln2.c @@ -467,7 +467,6 @@ static int dln2_gpio_probe(struct platform_device *pdev) dln2->gpio.base = -1; dln2->gpio.ngpio = pins; dln2->gpio.can_sleep = true; - dln2->gpio.irq_not_threaded = true; dln2->gpio.set = dln2_gpio_set; dln2->gpio.get = dln2_gpio_get; dln2->gpio.request = dln2_gpio_request; diff --git a/drivers/gpio/gpio-max732x.c b/drivers/gpio/gpio-max732x.c index a9aaf9d822b4..4ea4c6a1313b 100644 --- a/drivers/gpio/gpio-max732x.c +++ b/drivers/gpio/gpio-max732x.c @@ -520,20 +520,19 @@ static int max732x_irq_setup(struct max732x_chip *chip, client->irq); return ret; } - ret = gpiochip_irqchip_add(&chip->gpio_chip, - &max732x_irq_chip, - irq_base, - handle_simple_irq, - IRQ_TYPE_NONE); + ret = gpiochip_irqchip_add_nested(&chip->gpio_chip, + &max732x_irq_chip, + irq_base, + handle_simple_irq, + IRQ_TYPE_NONE); if (ret) { dev_err(&client->dev, "could not connect irqchip to gpiochip\n"); return ret; } - gpiochip_set_chained_irqchip(&chip->gpio_chip, - &max732x_irq_chip, - client->irq, - NULL); + gpiochip_set_nested_irqchip(&chip->gpio_chip, + &max732x_irq_chip, + client->irq); } return 0; diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index 99d37b56c258..504550665091 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c @@ -473,21 +473,20 @@ static int mcp23s08_irq_setup(struct mcp23s08 *mcp) return err; } - err = gpiochip_irqchip_add(chip, - &mcp23s08_irq_chip, - 0, - handle_simple_irq, - IRQ_TYPE_NONE); + err = gpiochip_irqchip_add_nested(chip, + &mcp23s08_irq_chip, + 0, + handle_simple_irq, + IRQ_TYPE_NONE); if (err) { dev_err(chip->parent, "could not connect irqchip to gpiochip: %d\n", err); return err; } - gpiochip_set_chained_irqchip(chip, - &mcp23s08_irq_chip, - mcp->irq, - NULL); + gpiochip_set_nested_irqchip(chip, + &mcp23s08_irq_chip, + mcp->irq); return 0; } diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 601c4550ee27..9733678f0219 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -636,20 +636,20 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, return ret; } - ret = gpiochip_irqchip_add(&chip->gpio_chip, - &pca953x_irq_chip, - irq_base, - handle_simple_irq, - IRQ_TYPE_NONE); + ret = gpiochip_irqchip_add_nested(&chip->gpio_chip, + &pca953x_irq_chip, + irq_base, + handle_simple_irq, + IRQ_TYPE_NONE); if (ret) { dev_err(&client->dev, "could not connect irqchip to gpiochip\n"); return ret; } - gpiochip_set_chained_irqchip(&chip->gpio_chip, - &pca953x_irq_chip, - client->irq, NULL); + gpiochip_set_nested_irqchip(&chip->gpio_chip, + &pca953x_irq_chip, + client->irq); } return 0; diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c index d168410e2338..895af42a4513 100644 --- a/drivers/gpio/gpio-pcf857x.c +++ b/drivers/gpio/gpio-pcf857x.c @@ -378,9 +378,10 @@ static int pcf857x_probe(struct i2c_client *client, /* Enable irqchip if we have an interrupt */ if (client->irq) { - status = gpiochip_irqchip_add(&gpio->chip, &pcf857x_irq_chip, - 0, handle_level_irq, - IRQ_TYPE_NONE); + status = gpiochip_irqchip_add_nested(&gpio->chip, + &pcf857x_irq_chip, + 0, handle_level_irq, + IRQ_TYPE_NONE); if (status) { dev_err(&client->dev, "cannot add irqchip\n"); goto fail; @@ -393,8 +394,8 @@ static int pcf857x_probe(struct i2c_client *client, if (status) goto fail; - gpiochip_set_chained_irqchip(&gpio->chip, &pcf857x_irq_chip, - client->irq, NULL); + gpiochip_set_nested_irqchip(&gpio->chip, &pcf857x_irq_chip, + client->irq); gpio->irq_parent = client->irq; } diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index e2e1b16a42db..21364e95065d 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c @@ -484,21 +484,20 @@ static int stmpe_gpio_probe(struct platform_device *pdev) if (stmpe_gpio->norequest_mask & BIT(i)) clear_bit(i, stmpe_gpio->chip.irq_valid_mask); } - ret = gpiochip_irqchip_add(&stmpe_gpio->chip, - &stmpe_gpio_irq_chip, - 0, - handle_simple_irq, - IRQ_TYPE_NONE); + ret = gpiochip_irqchip_add_nested(&stmpe_gpio->chip, + &stmpe_gpio_irq_chip, + 0, + handle_simple_irq, + IRQ_TYPE_NONE); if (ret) { dev_err(&pdev->dev, "could not connect irqchip to gpiochip\n"); goto out_disable; } - gpiochip_set_chained_irqchip(&stmpe_gpio->chip, - &stmpe_gpio_irq_chip, - irq, - NULL); + gpiochip_set_nested_irqchip(&stmpe_gpio->chip, + &stmpe_gpio_irq_chip, + irq); } platform_set_drvdata(pdev, stmpe_gpio); diff --git a/drivers/gpio/gpio-tc3589x.c b/drivers/gpio/gpio-tc3589x.c index 5a5a6cb00eea..f041965f1b03 100644 --- a/drivers/gpio/gpio-tc3589x.c +++ b/drivers/gpio/gpio-tc3589x.c @@ -337,21 +337,20 @@ static int tc3589x_gpio_probe(struct platform_device *pdev) return ret; } - ret = gpiochip_irqchip_add(&tc3589x_gpio->chip, - &tc3589x_gpio_irq_chip, - 0, - handle_simple_irq, - IRQ_TYPE_NONE); + ret = gpiochip_irqchip_add_nested(&tc3589x_gpio->chip, + &tc3589x_gpio_irq_chip, + 0, + handle_simple_irq, + IRQ_TYPE_NONE); if (ret) { dev_err(&pdev->dev, "could not connect irqchip to gpiochip\n"); return ret; } - gpiochip_set_chained_irqchip(&tc3589x_gpio->chip, - &tc3589x_gpio_irq_chip, - irq, - NULL); + gpiochip_set_nested_irqchip(&tc3589x_gpio->chip, + &tc3589x_gpio_irq_chip, + irq); platform_set_drvdata(pdev, tc3589x_gpio); diff --git a/drivers/gpio/gpio-wcove.c b/drivers/gpio/gpio-wcove.c index d0ddba7a9d08..34baee5b1dd6 100644 --- a/drivers/gpio/gpio-wcove.c +++ b/drivers/gpio/gpio-wcove.c @@ -426,8 +426,8 @@ static int wcove_gpio_probe(struct platform_device *pdev) return ret; } - ret = gpiochip_irqchip_add(&wg->chip, &wcove_irqchip, 0, - handle_simple_irq, IRQ_TYPE_NONE); + ret = gpiochip_irqchip_add_nested(&wg->chip, &wcove_irqchip, 0, + handle_simple_irq, IRQ_TYPE_NONE); if (ret) { dev_err(dev, "Failed to add irqchip: %d\n", ret); return ret; @@ -446,6 +446,8 @@ static int wcove_gpio_probe(struct platform_device *pdev) return ret; } + gpiochip_set_nested_irqchip(&wg->chip, &wcove_irqchip, virq); + return 0; } diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 0e29cb745648..acdff62f2ee2 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1440,7 +1440,7 @@ static bool gpiochip_irqchip_irq_valid(const struct gpio_chip *gpiochip, } /** - * gpiochip_set_chained_irqchip() - sets a chained irqchip to a gpiochip + * gpiochip_set_cascaded_irqchip() - connects a cascaded irqchip to a gpiochip * @gpiochip: the gpiochip to set the irqchip chain to * @irqchip: the irqchip to chain to the gpiochip * @parent_irq: the irq number corresponding to the parent IRQ for this @@ -1449,10 +1449,10 @@ static bool gpiochip_irqchip_irq_valid(const struct gpio_chip *gpiochip, * coming out of the gpiochip. If the interrupt is nested rather than * cascaded, pass NULL in this handler argument */ -void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip, - struct irq_chip *irqchip, - int parent_irq, - irq_flow_handler_t parent_handler) +static void gpiochip_set_cascaded_irqchip(struct gpio_chip *gpiochip, + struct irq_chip *irqchip, + int parent_irq, + irq_flow_handler_t parent_handler) { unsigned int offset; @@ -1476,7 +1476,7 @@ void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip, irq_set_chained_handler_and_data(parent_irq, parent_handler, gpiochip); - gpiochip->irq_parent = parent_irq; + gpiochip->irq_chained_parent = parent_irq; } /* Set the parent IRQ for all affected IRQs */ @@ -1487,9 +1487,48 @@ void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip, parent_irq); } } + +/** + * gpiochip_set_chained_irqchip() - connects a chained irqchip to a gpiochip + * @gpiochip: the gpiochip to set the irqchip chain to + * @irqchip: the irqchip to chain to the gpiochip + * @parent_irq: the irq number corresponding to the parent IRQ for this + * chained irqchip + * @parent_handler: the parent interrupt handler for the accumulated IRQ + * coming out of the gpiochip. If the interrupt is nested rather than + * cascaded, pass NULL in this handler argument + */ +void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip, + struct irq_chip *irqchip, + int parent_irq, + irq_flow_handler_t parent_handler) +{ + gpiochip_set_cascaded_irqchip(gpiochip, irqchip, parent_irq, + parent_handler); +} EXPORT_SYMBOL_GPL(gpiochip_set_chained_irqchip); /** + * gpiochip_set_nested_irqchip() - connects a nested irqchip to a gpiochip + * @gpiochip: the gpiochip to set the irqchip nested handler to + * @irqchip: the irqchip to nest to the gpiochip + * @parent_irq: the irq number corresponding to the parent IRQ for this + * nested irqchip + */ +void gpiochip_set_nested_irqchip(struct gpio_chip *gpiochip, + struct irq_chip *irqchip, + int parent_irq) +{ + if (!gpiochip->irq_nested) { + chip_err(gpiochip, "tried to nest a chained gpiochip\n"); + return; + } + gpiochip_set_cascaded_irqchip(gpiochip, irqchip, parent_irq, + NULL); +} +EXPORT_SYMBOL_GPL(gpiochip_set_nested_irqchip); + +/** * gpiochip_irq_map() - maps an IRQ into a GPIO irqchip * @d: the irqdomain used by this irqchip * @irq: the global irq number used by this GPIO irqchip irq @@ -1511,8 +1550,8 @@ static int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, */ irq_set_lockdep_class(irq, chip->lock_key); irq_set_chip_and_handler(irq, chip->irqchip, chip->irq_handler); - /* Chips that can sleep need nested thread handlers */ - if (chip->can_sleep && !chip->irq_not_threaded) + /* Chips that use nested thread handlers have them marked */ + if (chip->irq_nested) irq_set_nested_thread(irq, 1); irq_set_noprobe(irq); @@ -1530,7 +1569,7 @@ static void gpiochip_irq_unmap(struct irq_domain *d, unsigned int irq) { struct gpio_chip *chip = d->host_data; - if (chip->can_sleep) + if (chip->irq_nested) irq_set_nested_thread(irq, 0); irq_set_chip_and_handler(irq, NULL, NULL); irq_set_chip_data(irq, NULL); @@ -1585,9 +1624,9 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) acpi_gpiochip_free_interrupts(gpiochip); - if (gpiochip->irq_parent) { - irq_set_chained_handler(gpiochip->irq_parent, NULL); - irq_set_handler_data(gpiochip->irq_parent, NULL); + if (gpiochip->irq_chained_parent) { + irq_set_chained_handler(gpiochip->irq_chained_parent, NULL); + irq_set_handler_data(gpiochip->irq_chained_parent, NULL); } /* Remove all IRQ mappings and delete the domain */ @@ -1611,7 +1650,7 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) } /** - * gpiochip_irqchip_add() - adds an irqchip to a gpiochip + * _gpiochip_irqchip_add() - adds an irqchip to a gpiochip * @gpiochip: the gpiochip to add the irqchip to * @irqchip: the irqchip to add to the gpiochip * @first_irq: if not dynamically assigned, the base (first) IRQ to @@ -1619,6 +1658,8 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) * @handler: the irq handler to use (often a predefined irq core function) * @type: the default type for IRQs on this irqchip, pass IRQ_TYPE_NONE * to have the core avoid setting up any default type in the hardware. + * @nested: whether this is a nested irqchip calling handle_nested_irq() + * in its IRQ handler * @lock_key: lockdep class * * This function closely associates a certain irqchip with a certain @@ -1640,6 +1681,7 @@ int _gpiochip_irqchip_add(struct gpio_chip *gpiochip, unsigned int first_irq, irq_flow_handler_t handler, unsigned int type, + bool nested, struct lock_class_key *lock_key) { struct device_node *of_node; @@ -1654,6 +1696,7 @@ int _gpiochip_irqchip_add(struct gpio_chip *gpiochip, pr_err("missing gpiochip .dev parent pointer\n"); return -EINVAL; } + gpiochip->irq_nested = nested; of_node = gpiochip->parent->of_node; #ifdef CONFIG_OF_GPIO /* |