Intel Quark X1000 GPIO controller supports interrupt handling for
both core power well and resume power well. This patch is to enable
the IRQ support and provide IRQ handling for Intel Quark X1000
GPIO-SCH device driver.
static int sch_gpio_probe(struct platform_device *pdev)
{
struct sch_gpio *sch;
- struct resource *res;
+ struct resource *res, *irq;
+ int err;
sch = devm_kzalloc(&pdev->dev, sizeof(*sch), GFP_KERNEL);
if (!sch)
@@ -203,6 +376,17 @@ static int sch_gpio_probe(struct platform_device *pdev)
pdev->name))
return -EBUSY;
+ irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ sch->irq_support = !!irq;
+ if (sch->irq_support) {
+ sch->irq_num = irq->start;
+ if (sch->irq_num < 0) {
+ dev_warn(&pdev->dev,
+ "failed to obtain irq number for device\n");
+ sch->irq_support = false;
+ }
+ }
+
spin_lock_init(&sch->lock);
sch->iobase = res->start;
sch->chip = sch_gpio_chip;
@@ -251,15 +435,64 @@ static int sch_gpio_probe(struct platform_device *pdev)
return -ENODEV;
}
+ err = gpiochip_add(&sch->chip);
+ if (err < 0)
+ goto err_sch_gpio;
+
+ if (sch->irq_support) {
+ sch->irq_base = irq_alloc_descs(-1, 0, sch->chip.ngpio,
+ NUMA_NO_NODE);
+ if (sch->irq_base < 0) {
+ dev_err(&pdev->dev,
+ "failed to allocate GPIO IRQ descs\n");
+ goto err_sch_intr_chip;
+ }
+
+ /* disable interrupts */
+ sch_gpio_irq_disable_all(sch, sch->chip.ngpio);
+
+ err = request_irq(sch->irq_num, sch_gpio_irq_handler,
+ IRQF_SHARED, KBUILD_MODNAME, sch);
+ if (err) {
+ dev_err(&pdev->dev,
+ "%s failed to request IRQ\n", __func__);
+ goto err_sch_request_irq;
+ }
+
+ sch_gpio_irqs_init(sch, sch->chip.ngpio);
+ }
+
platform_set_drvdata(pdev, sch);
- return gpiochip_add(&sch->chip);
+ return 0;
+
+err_sch_request_irq:
+ irq_free_descs(sch->irq_base, sch->chip.ngpio);
+
+err_sch_intr_chip:
+ if (gpiochip_remove(&sch->chip))
+ dev_err(&pdev->dev,
+ "%s gpiochip_remove() failed\n", __func__);
+
+err_sch_gpio:
+ release_region(res->start, resource_size(res));
+
+ return err;
}