mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-03 18:20:25 +02:00 
			
		
		
		
	The equivalent of both of these are now done via macro magic when the relevant register calls are made. The actual structure elements will shortly go away. Note that stm32-timer-trigger has expanded rather beyond triggers (to include encoder input counting for example) and hence has an iio_info structure. Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Reviewed-by: Lars-Peter Clausen <lars@metafoo.de>
		
			
				
	
	
		
			118 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			118 lines
		
	
	
	
		
			2.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Industrial I/O - generic interrupt based trigger support
 | 
						|
 *
 | 
						|
 * Copyright (c) 2008-2013 Jonathan Cameron
 | 
						|
 *
 | 
						|
 * This program is free software; you can redistribute it and/or modify it
 | 
						|
 * under the terms of the GNU General Public License version 2 as published by
 | 
						|
 * the Free Software Foundation.
 | 
						|
 */
 | 
						|
 | 
						|
#include <linux/kernel.h>
 | 
						|
#include <linux/module.h>
 | 
						|
#include <linux/platform_device.h>
 | 
						|
#include <linux/interrupt.h>
 | 
						|
#include <linux/slab.h>
 | 
						|
 | 
						|
#include <linux/iio/iio.h>
 | 
						|
#include <linux/iio/trigger.h>
 | 
						|
 | 
						|
 | 
						|
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 const struct iio_trigger_ops iio_interrupt_trigger_ops = {
 | 
						|
};
 | 
						|
 | 
						|
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("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;
 | 
						|
	trig->ops = &iio_interrupt_trigger_ops;
 | 
						|
	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 <jic23@kernel.org>");
 | 
						|
MODULE_DESCRIPTION("Interrupt trigger for the iio subsystem");
 | 
						|
MODULE_LICENSE("GPL v2");
 |