Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.16 118 lines 2.7 kB view raw
1/* 2 * Industrial I/O - generic interrupt based trigger support 3 * 4 * Copyright (c) 2008-2013 Jonathan Cameron 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 as published by 8 * the Free Software Foundation. 9 */ 10 11#include <linux/kernel.h> 12#include <linux/module.h> 13#include <linux/platform_device.h> 14#include <linux/interrupt.h> 15#include <linux/slab.h> 16 17#include <linux/iio/iio.h> 18#include <linux/iio/trigger.h> 19 20 21struct iio_interrupt_trigger_info { 22 unsigned int irq; 23}; 24 25static irqreturn_t iio_interrupt_trigger_poll(int irq, void *private) 26{ 27 iio_trigger_poll(private); 28 return IRQ_HANDLED; 29} 30 31static const struct iio_trigger_ops iio_interrupt_trigger_ops = { 32}; 33 34static int iio_interrupt_trigger_probe(struct platform_device *pdev) 35{ 36 struct iio_interrupt_trigger_info *trig_info; 37 struct iio_trigger *trig; 38 unsigned long irqflags; 39 struct resource *irq_res; 40 int irq, ret = 0; 41 42 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 43 44 if (irq_res == NULL) 45 return -ENODEV; 46 47 irqflags = (irq_res->flags & IRQF_TRIGGER_MASK) | IRQF_SHARED; 48 49 irq = irq_res->start; 50 51 trig = iio_trigger_alloc("irqtrig%d", irq); 52 if (!trig) { 53 ret = -ENOMEM; 54 goto error_ret; 55 } 56 57 trig_info = kzalloc(sizeof(*trig_info), GFP_KERNEL); 58 if (!trig_info) { 59 ret = -ENOMEM; 60 goto error_free_trigger; 61 } 62 iio_trigger_set_drvdata(trig, trig_info); 63 trig_info->irq = irq; 64 trig->ops = &iio_interrupt_trigger_ops; 65 ret = request_irq(irq, iio_interrupt_trigger_poll, 66 irqflags, trig->name, trig); 67 if (ret) { 68 dev_err(&pdev->dev, 69 "request IRQ-%d failed", irq); 70 goto error_free_trig_info; 71 } 72 73 ret = iio_trigger_register(trig); 74 if (ret) 75 goto error_release_irq; 76 platform_set_drvdata(pdev, trig); 77 78 return 0; 79 80/* First clean up the partly allocated trigger */ 81error_release_irq: 82 free_irq(irq, trig); 83error_free_trig_info: 84 kfree(trig_info); 85error_free_trigger: 86 iio_trigger_free(trig); 87error_ret: 88 return ret; 89} 90 91static int iio_interrupt_trigger_remove(struct platform_device *pdev) 92{ 93 struct iio_trigger *trig; 94 struct iio_interrupt_trigger_info *trig_info; 95 96 trig = platform_get_drvdata(pdev); 97 trig_info = iio_trigger_get_drvdata(trig); 98 iio_trigger_unregister(trig); 99 free_irq(trig_info->irq, trig); 100 kfree(trig_info); 101 iio_trigger_free(trig); 102 103 return 0; 104} 105 106static struct platform_driver iio_interrupt_trigger_driver = { 107 .probe = iio_interrupt_trigger_probe, 108 .remove = iio_interrupt_trigger_remove, 109 .driver = { 110 .name = "iio_interrupt_trigger", 111 }, 112}; 113 114module_platform_driver(iio_interrupt_trigger_driver); 115 116MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>"); 117MODULE_DESCRIPTION("Interrupt trigger for the iio subsystem"); 118MODULE_LICENSE("GPL v2");