diff options
author | Hans J. Koch <hjk@linutronix.de> | 2008-05-23 07:50:14 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-07-22 00:54:55 -0400 |
commit | 328a14e70e7f46997cb50d4258dd93d5377f98c6 (patch) | |
tree | 7cc64b122fc45af454d4dde9f561b329d9f2b0c4 /drivers/uio/uio.c | |
parent | 934da4766e5f72797118f7c014efaef567a812fc (diff) |
UIO: Add write function to allow irq masking
Sometimes it is necessary to enable/disable the interrupt of a UIO device
from the userspace part of the driver. With this patch, the UIO kernel driver
can implement an "irqcontrol()" function that does this. Userspace can write
an s32 value to /dev/uioX (usually 0 or 1 to turn the irq off or on). The
UIO core will then call the driver's irqcontrol function.
Signed-off-by: Hans J. Koch <hjk@linutronix.de>
Acked-by: Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
Acked-by: Magnus Damm <damm@igel.co.jp>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/uio/uio.c')
-rw-r--r-- | drivers/uio/uio.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 5a7ca2e6094d..3a6934bf7131 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c | |||
@@ -427,6 +427,31 @@ static ssize_t uio_read(struct file *filep, char __user *buf, | |||
427 | return retval; | 427 | return retval; |
428 | } | 428 | } |
429 | 429 | ||
430 | static ssize_t uio_write(struct file *filep, const char __user *buf, | ||
431 | size_t count, loff_t *ppos) | ||
432 | { | ||
433 | struct uio_listener *listener = filep->private_data; | ||
434 | struct uio_device *idev = listener->dev; | ||
435 | ssize_t retval; | ||
436 | s32 irq_on; | ||
437 | |||
438 | if (idev->info->irq == UIO_IRQ_NONE) | ||
439 | return -EIO; | ||
440 | |||
441 | if (count != sizeof(s32)) | ||
442 | return -EINVAL; | ||
443 | |||
444 | if (!idev->info->irqcontrol) | ||
445 | return -ENOSYS; | ||
446 | |||
447 | if (copy_from_user(&irq_on, buf, count)) | ||
448 | return -EFAULT; | ||
449 | |||
450 | retval = idev->info->irqcontrol(idev->info, irq_on); | ||
451 | |||
452 | return retval ? retval : sizeof(s32); | ||
453 | } | ||
454 | |||
430 | static int uio_find_mem_index(struct vm_area_struct *vma) | 455 | static int uio_find_mem_index(struct vm_area_struct *vma) |
431 | { | 456 | { |
432 | int mi; | 457 | int mi; |
@@ -546,6 +571,7 @@ static const struct file_operations uio_fops = { | |||
546 | .open = uio_open, | 571 | .open = uio_open, |
547 | .release = uio_release, | 572 | .release = uio_release, |
548 | .read = uio_read, | 573 | .read = uio_read, |
574 | .write = uio_write, | ||
549 | .mmap = uio_mmap, | 575 | .mmap = uio_mmap, |
550 | .poll = uio_poll, | 576 | .poll = uio_poll, |
551 | .fasync = uio_fasync, | 577 | .fasync = uio_fasync, |