diff options
Diffstat (limited to 'drivers/gpio/gpio-sifive.c')
-rw-r--r-- | drivers/gpio/gpio-sifive.c | 48 |
1 files changed, 21 insertions, 27 deletions
diff --git a/drivers/gpio/gpio-sifive.c b/drivers/gpio/gpio-sifive.c index 745e5f67254e..8decd9b5d229 100644 --- a/drivers/gpio/gpio-sifive.c +++ b/drivers/gpio/gpio-sifive.c @@ -6,10 +6,10 @@ #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> +#include <linux/property.h> #include <linux/slab.h> #include <linux/spinlock.h> #include <linux/regmap.h> @@ -150,6 +150,7 @@ static const struct irq_chip sifive_gpio_irqchip = { .irq_disable = sifive_gpio_irq_disable, .irq_eoi = sifive_gpio_irq_eoi, .irq_set_affinity = sifive_gpio_irq_set_affinity, + .irq_set_wake = irq_chip_set_wake_parent, .flags = IRQCHIP_IMMUTABLE, GPIOCHIP_IRQ_RESOURCE_HELPERS, }; @@ -180,12 +181,10 @@ 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; - int ret, ngpio, i; + int ret, ngpio; chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); if (!chip) @@ -202,31 +201,22 @@ static int sifive_gpio_probe(struct platform_device *pdev) if (IS_ERR(chip->regs)) return PTR_ERR(chip->regs); - ngpio = of_irq_count(node); - if (ngpio > SIFIVE_GPIO_MAX) { - dev_err(dev, "Too many GPIO interrupts (max=%d)\n", - SIFIVE_GPIO_MAX); - return -ENXIO; - } - - irq_parent = of_irq_find_parent(node); - if (!irq_parent) { - dev_err(dev, "no IRQ parent node\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; } - parent = irq_find_host(irq_parent); - of_node_put(irq_parent); - if (!parent) { - dev_err(dev, "no IRQ parent domain\n"); + if (!ngpio) { + dev_err(dev, "no IRQ found\n"); return -ENODEV; } - for (i = 0; i < ngpio; i++) { - ret = platform_get_irq(pdev, i); - if (ret < 0) - return ret; - chip->irq_number[i] = ret; - } + /* + * 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, @@ -254,7 +244,7 @@ static int sifive_gpio_probe(struct platform_device *pdev) chip->gc.owner = THIS_MODULE; girq = &chip->gc.irq; gpio_irq_chip_set_chip(girq, &sifive_gpio_irqchip); - girq->fwnode = of_node_to_fwnode(node); + girq->fwnode = dev_fwnode(dev); girq->parent_domain = parent; girq->child_to_parent_hwirq = sifive_gpio_child_to_parent_hwirq; girq->handler = handle_bad_irq; @@ -277,4 +267,8 @@ static struct platform_driver sifive_gpio_driver = { .of_match_table = sifive_gpio_match, }, }; -builtin_platform_driver(sifive_gpio_driver) +module_platform_driver(sifive_gpio_driver) + +MODULE_AUTHOR("Yash Shah <yash.shah@sifive.com>"); +MODULE_DESCRIPTION("SiFive GPIO driver"); +MODULE_LICENSE("GPL"); |