summaryrefslogtreecommitdiff
path: root/drivers/gpio
diff options
context:
space:
mode:
authorSamuel Holland <samuel.holland@sifive.com>2023-07-25 03:40:41 +0300
committerBartosz Golaszewski <bartosz.golaszewski@linaro.org>2023-07-25 13:00:29 +0300
commit3b5560c8f074aee8839b66093b4d565702a6921d (patch)
tree54421dc114712533d11c7a49cc560abfd420ddec /drivers/gpio
parent1cd9cee75f99cfe31a6e339af518679649812838 (diff)
downloadlinux-3b5560c8f074aee8839b66093b4d565702a6921d.tar.xz
gpio: sifive: Get the parent IRQ's domain from its irq_data
Do not parse the devicetree again when the data is already available from the IRQ subsystem. This follows the example of the ThunderX and X-Gene GPIO drivers. The ngpio check is needed to avoid a possible out-of-bounds read. Signed-off-by: Samuel Holland <samuel.holland@sifive.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-sifive.c25
1 files changed, 10 insertions, 15 deletions
diff --git a/drivers/gpio/gpio-sifive.c b/drivers/gpio/gpio-sifive.c
index e292c333f8dd..8033bb8246c6 100644
--- a/drivers/gpio/gpio-sifive.c
+++ b/drivers/gpio/gpio-sifive.c
@@ -6,7 +6,6 @@
#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/errno.h>
-#include <linux/of_irq.h>
#include <linux/gpio/driver.h>
#include <linux/init.h>
#include <linux/platform_device.h>
@@ -182,8 +181,6 @@ static const struct regmap_config sifive_gpio_regmap_config = {
static int sifive_gpio_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct device_node *node = pdev->dev.of_node;
- struct device_node *irq_parent;
struct irq_domain *parent;
struct gpio_irq_chip *girq;
struct sifive_gpio *chip;
@@ -204,24 +201,22 @@ static int sifive_gpio_probe(struct platform_device *pdev)
if (IS_ERR(chip->regs))
return PTR_ERR(chip->regs);
- irq_parent = of_irq_find_parent(node);
- if (!irq_parent) {
- dev_err(dev, "no IRQ parent node\n");
- return -ENODEV;
- }
- parent = irq_find_host(irq_parent);
- of_node_put(irq_parent);
- if (!parent) {
- dev_err(dev, "no IRQ parent domain\n");
- return -ENODEV;
- }
-
for (ngpio = 0; ngpio < SIFIVE_GPIO_MAX; ngpio++) {
ret = platform_get_irq_optional(pdev, ngpio);
if (ret < 0)
break;
chip->irq_number[ngpio] = ret;
}
+ if (!ngpio) {
+ dev_err(dev, "no IRQ found\n");
+ return -ENODEV;
+ }
+
+ /*
+ * The check above ensures at least one parent IRQ is valid.
+ * Assume all parent IRQs belong to the same domain.
+ */
+ parent = irq_get_irq_data(chip->irq_number[0])->domain;
ret = bgpio_init(&chip->gc, dev, 4,
chip->base + SIFIVE_GPIO_INPUT_VAL,