ia64/linux-2.6.18-xen.hg

annotate drivers/char/nsc_gpio.c @ 893:f994bfe9b93b

linux/blktap2: reduce TLB flush scope

c/s 885 added very coarse TLB flushing. Since these flushes always
follow single page updates, single page flushes (when available) are
sufficient.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jun 04 10:32:57 2009 +0100 (2009-06-04)
parents 831230e53067
children
rev   line source
ian@0 1 /* linux/drivers/char/nsc_gpio.c
ian@0 2
ian@0 3 National Semiconductor common GPIO device-file/VFS methods.
ian@0 4 Allows a user space process to control the GPIO pins.
ian@0 5
ian@0 6 Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
ian@0 7 Copyright (c) 2005 Jim Cromie <jim.cromie@gmail.com>
ian@0 8 */
ian@0 9
ian@0 10 #include <linux/config.h>
ian@0 11 #include <linux/fs.h>
ian@0 12 #include <linux/module.h>
ian@0 13 #include <linux/errno.h>
ian@0 14 #include <linux/kernel.h>
ian@0 15 #include <linux/init.h>
ian@0 16 #include <linux/nsc_gpio.h>
ian@0 17 #include <linux/platform_device.h>
ian@0 18 #include <asm/uaccess.h>
ian@0 19 #include <asm/io.h>
ian@0 20
ian@0 21 #define NAME "nsc_gpio"
ian@0 22
ian@0 23 void nsc_gpio_dump(struct nsc_gpio_ops *amp, unsigned index)
ian@0 24 {
ian@0 25 /* retrieve current config w/o changing it */
ian@0 26 u32 config = amp->gpio_config(index, ~0, 0);
ian@0 27
ian@0 28 /* user requested via 'v' command, so its INFO */
ian@0 29 dev_info(amp->dev, "io%02u: 0x%04x %s %s %s %s %s %s %s\tio:%d/%d\n",
ian@0 30 index, config,
ian@0 31 (config & 1) ? "OE" : "TS", /* output-enabled/tristate */
ian@0 32 (config & 2) ? "PP" : "OD", /* push pull / open drain */
ian@0 33 (config & 4) ? "PUE" : "PUD", /* pull up enabled/disabled */
ian@0 34 (config & 8) ? "LOCKED" : "", /* locked / unlocked */
ian@0 35 (config & 16) ? "LEVEL" : "EDGE",/* level/edge input */
ian@0 36 (config & 32) ? "HI" : "LO", /* trigger on rise/fall edge */
ian@0 37 (config & 64) ? "DEBOUNCE" : "", /* debounce */
ian@0 38
ian@0 39 amp->gpio_get(index), amp->gpio_current(index));
ian@0 40 }
ian@0 41
ian@0 42 ssize_t nsc_gpio_write(struct file *file, const char __user *data,
ian@0 43 size_t len, loff_t *ppos)
ian@0 44 {
ian@0 45 unsigned m = iminor(file->f_dentry->d_inode);
ian@0 46 struct nsc_gpio_ops *amp = file->private_data;
ian@0 47 struct device *dev = amp->dev;
ian@0 48 size_t i;
ian@0 49 int err = 0;
ian@0 50
ian@0 51 for (i = 0; i < len; ++i) {
ian@0 52 char c;
ian@0 53 if (get_user(c, data + i))
ian@0 54 return -EFAULT;
ian@0 55 switch (c) {
ian@0 56 case '0':
ian@0 57 amp->gpio_set(m, 0);
ian@0 58 break;
ian@0 59 case '1':
ian@0 60 amp->gpio_set(m, 1);
ian@0 61 break;
ian@0 62 case 'O':
ian@0 63 dev_dbg(dev, "GPIO%d output enabled\n", m);
ian@0 64 amp->gpio_config(m, ~1, 1);
ian@0 65 break;
ian@0 66 case 'o':
ian@0 67 dev_dbg(dev, "GPIO%d output disabled\n", m);
ian@0 68 amp->gpio_config(m, ~1, 0);
ian@0 69 break;
ian@0 70 case 'T':
ian@0 71 dev_dbg(dev, "GPIO%d output is push pull\n", m);
ian@0 72 amp->gpio_config(m, ~2, 2);
ian@0 73 break;
ian@0 74 case 't':
ian@0 75 dev_dbg(dev, "GPIO%d output is open drain\n", m);
ian@0 76 amp->gpio_config(m, ~2, 0);
ian@0 77 break;
ian@0 78 case 'P':
ian@0 79 dev_dbg(dev, "GPIO%d pull up enabled\n", m);
ian@0 80 amp->gpio_config(m, ~4, 4);
ian@0 81 break;
ian@0 82 case 'p':
ian@0 83 dev_dbg(dev, "GPIO%d pull up disabled\n", m);
ian@0 84 amp->gpio_config(m, ~4, 0);
ian@0 85 break;
ian@0 86 case 'v':
ian@0 87 /* View Current pin settings */
ian@0 88 amp->gpio_dump(amp, m);
ian@0 89 break;
ian@0 90 case '\n':
ian@0 91 /* end of settings string, do nothing */
ian@0 92 break;
ian@0 93 default:
ian@0 94 dev_err(dev, "io%2d bad setting: chr<0x%2x>\n",
ian@0 95 m, (int)c);
ian@0 96 err++;
ian@0 97 }
ian@0 98 }
ian@0 99 if (err)
ian@0 100 return -EINVAL; /* full string handled, report error */
ian@0 101
ian@0 102 return len;
ian@0 103 }
ian@0 104
ian@0 105 ssize_t nsc_gpio_read(struct file *file, char __user * buf,
ian@0 106 size_t len, loff_t * ppos)
ian@0 107 {
ian@0 108 unsigned m = iminor(file->f_dentry->d_inode);
ian@0 109 int value;
ian@0 110 struct nsc_gpio_ops *amp = file->private_data;
ian@0 111
ian@0 112 value = amp->gpio_get(m);
ian@0 113 if (put_user(value ? '1' : '0', buf))
ian@0 114 return -EFAULT;
ian@0 115
ian@0 116 return 1;
ian@0 117 }
ian@0 118
ian@0 119 /* common file-ops routines for both scx200_gpio and pc87360_gpio */
ian@0 120 EXPORT_SYMBOL(nsc_gpio_write);
ian@0 121 EXPORT_SYMBOL(nsc_gpio_read);
ian@0 122 EXPORT_SYMBOL(nsc_gpio_dump);
ian@0 123
ian@0 124 static int __init nsc_gpio_init(void)
ian@0 125 {
ian@0 126 printk(KERN_DEBUG NAME " initializing\n");
ian@0 127 return 0;
ian@0 128 }
ian@0 129
ian@0 130 static void __exit nsc_gpio_cleanup(void)
ian@0 131 {
ian@0 132 printk(KERN_DEBUG NAME " cleanup\n");
ian@0 133 }
ian@0 134
ian@0 135 module_init(nsc_gpio_init);
ian@0 136 module_exit(nsc_gpio_cleanup);
ian@0 137
ian@0 138 MODULE_AUTHOR("Jim Cromie <jim.cromie@gmail.com>");
ian@0 139 MODULE_DESCRIPTION("NatSemi GPIO Common Methods");
ian@0 140 MODULE_LICENSE("GPL");