// SPDX-License-Identifier: GPL-2.0-only /* * Industrial I/O - generic interrupt based trigger support * * Copyright (c) 2008-2013 Jonathan Cameron */ #include #include #include #include #include #include #include struct iio_interrupt_trigger_info { unsigned int irq; }; static irqreturn_t iio_interrupt_trigger_poll(int irq, void *private) { iio_trigger_poll(private); return IRQ_HANDLED; } static int iio_interrupt_trigger_probe(struct platform_device *pdev) { struct iio_interrupt_trigger_info *trig_info; struct iio_trigger *trig; unsigned long irqflags; struct resource *irq_res; int irq, ret = 0; irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (irq_res == NULL) return -ENODEV; irqflags = (irq_res->flags & IRQF_TRIGGER_MASK) | IRQF_SHARED; irq = irq_res->start; trig = iio_trigger_alloc(NULL, "irqtrig%d", irq); if (!trig) { ret = -ENOMEM; goto error_ret; } trig_info = kzalloc(sizeof(*trig_info), GFP_KERNEL); if (!trig_info) { ret = -ENOMEM; goto error_free_trigger; } iio_trigger_set_drvdata(trig, trig_info); trig_info->irq = irq; ret = request_irq(irq, iio_interrupt_trigger_poll, irqflags, trig->name, trig); if (ret) { dev_err(&pdev->dev, "request IRQ-%d failed", irq); goto error_free_trig_info; } ret = iio_trigger_register(trig); if (ret) goto error_release_irq; platform_set_drvdata(pdev, trig); return 0; /* First clean up the partly allocated trigger */ error_release_irq: free_irq(irq, trig); error_free_trig_info: kfree(trig_info); error_free_trigger: iio_trigger_free(trig); error_ret: return ret; } static int iio_interrupt_trigger_remove(struct platform_device *pdev) { struct iio_trigger *trig; struct iio_interrupt_trigger_info *trig_info; trig = platform_get_drvdata(pdev); trig_info = iio_trigger_get_drvdata(trig); iio_trigger_unregister(trig); free_irq(trig_info->irq, trig); kfree(trig_info); iio_trigger_free(trig); return 0; } static struct platform_driver iio_interrupt_trigger_driver = { .probe = iio_interrupt_trigger_probe, .remove = iio_interrupt_trigger_remove, .driver = { .name = "iio_interrupt_trigger", }, }; module_platform_driver(iio_interrupt_trigger_driver); MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("Interrupt trigger for the iio subsystem"); MODULE_LICENSE("GPL v2");