~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/cris/arch-v10/drivers/gpio.c

Version: ~ [ linux-5.14-rc1 ] ~ [ linux-5.13.1 ] ~ [ linux-5.12.16 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.49 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.131 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.197 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.239 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.275 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.275 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Etrax general port I/O device
  3  *
  4  * Copyright (c) 1999-2007 Axis Communications AB
  5  *
  6  * Authors:    Bjorn Wesen      (initial version)
  7  *             Ola Knutsson     (LED handling)
  8  *             Johan Adolfsson  (read/set directions, write, port G)
  9  */
 10 
 11 
 12 #include <linux/module.h>
 13 #include <linux/sched.h>
 14 #include <linux/slab.h>
 15 #include <linux/ioport.h>
 16 #include <linux/errno.h>
 17 #include <linux/kernel.h>
 18 #include <linux/fs.h>
 19 #include <linux/string.h>
 20 #include <linux/poll.h>
 21 #include <linux/init.h>
 22 #include <linux/interrupt.h>
 23 
 24 #include <asm/etraxgpio.h>
 25 #include <arch/svinto.h>
 26 #include <asm/io.h>
 27 #include <asm/irq.h>
 28 #include <arch/io_interface_mux.h>
 29 
 30 #define GPIO_MAJOR 120  /* experimental MAJOR number */
 31 
 32 #define D(x)
 33 
 34 #if 0
 35 static int dp_cnt;
 36 #define DP(x) do { dp_cnt++; if (dp_cnt % 1000 == 0) x; }while(0)
 37 #else
 38 #define DP(x)
 39 #endif
 40 
 41 static char gpio_name[] = "etrax gpio";
 42 
 43 #if 0
 44 static wait_queue_head_t *gpio_wq;
 45 #endif
 46 
 47 static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 48 static ssize_t gpio_write(struct file *file, const char __user *buf,
 49         size_t count, loff_t *off);
 50 static int gpio_open(struct inode *inode, struct file *filp);
 51 static int gpio_release(struct inode *inode, struct file *filp);
 52 static unsigned int gpio_poll(struct file *filp, struct poll_table_struct *wait);
 53 
 54 /* private data per open() of this driver */
 55 
 56 struct gpio_private {
 57         struct gpio_private *next;
 58         /* These fields are for PA and PB only */
 59         volatile unsigned char *port, *shadow;
 60         volatile unsigned char *dir, *dir_shadow;
 61         unsigned char changeable_dir;
 62         unsigned char changeable_bits;
 63         unsigned char clk_mask;
 64         unsigned char data_mask;
 65         unsigned char write_msb;
 66         unsigned char pad1, pad2, pad3;
 67         /* These fields are generic */
 68         unsigned long highalarm, lowalarm;
 69         wait_queue_head_t alarm_wq;
 70         int minor;
 71 };
 72 
 73 /* linked list of alarms to check for */
 74 
 75 static struct gpio_private *alarmlist;
 76 
 77 static int gpio_some_alarms; /* Set if someone uses alarm */
 78 static unsigned long gpio_pa_irq_enabled_mask;
 79 
 80 static DEFINE_SPINLOCK(gpio_lock); /* Protect directions etc */
 81 
 82 /* Port A and B use 8 bit access, but Port G is 32 bit */
 83 #define NUM_PORTS (GPIO_MINOR_B+1)
 84 
 85 static volatile unsigned char *ports[NUM_PORTS] = {
 86         R_PORT_PA_DATA,
 87         R_PORT_PB_DATA,
 88 };
 89 static volatile unsigned char *shads[NUM_PORTS] = {
 90         &port_pa_data_shadow,
 91         &port_pb_data_shadow
 92 };
 93 
 94 /* What direction bits that are user changeable 1=changeable*/
 95 #ifndef CONFIG_ETRAX_PA_CHANGEABLE_DIR
 96 #define CONFIG_ETRAX_PA_CHANGEABLE_DIR 0x00
 97 #endif
 98 #ifndef CONFIG_ETRAX_PB_CHANGEABLE_DIR
 99 #define CONFIG_ETRAX_PB_CHANGEABLE_DIR 0x00
100 #endif
101 
102 #ifndef CONFIG_ETRAX_PA_CHANGEABLE_BITS
103 #define CONFIG_ETRAX_PA_CHANGEABLE_BITS 0xFF
104 #endif
105 #ifndef CONFIG_ETRAX_PB_CHANGEABLE_BITS
106 #define CONFIG_ETRAX_PB_CHANGEABLE_BITS 0xFF
107 #endif
108 
109 
110 static unsigned char changeable_dir[NUM_PORTS] = {
111         CONFIG_ETRAX_PA_CHANGEABLE_DIR,
112         CONFIG_ETRAX_PB_CHANGEABLE_DIR
113 };
114 static unsigned char changeable_bits[NUM_PORTS] = {
115         CONFIG_ETRAX_PA_CHANGEABLE_BITS,
116         CONFIG_ETRAX_PB_CHANGEABLE_BITS
117 };
118 
119 static volatile unsigned char *dir[NUM_PORTS] = {
120         R_PORT_PA_DIR,
121         R_PORT_PB_DIR
122 };
123 
124 static volatile unsigned char *dir_shadow[NUM_PORTS] = {
125         &port_pa_dir_shadow,
126         &port_pb_dir_shadow
127 };
128 
129 /* All bits in port g that can change dir. */
130 static const unsigned long int changeable_dir_g_mask = 0x01FFFF01;
131 
132 /* Port G is 32 bit, handle it special, some bits are both inputs
133    and outputs at the same time, only some of the bits can change direction
134    and some of them in groups of 8 bit. */
135 static unsigned long changeable_dir_g;
136 static unsigned long dir_g_in_bits;
137 static unsigned long dir_g_out_bits;
138 static unsigned long dir_g_shadow; /* 1=output */
139 
140 #define USE_PORTS(priv) ((priv)->minor <= GPIO_MINOR_B)
141 
142 
143 static unsigned int gpio_poll(struct file *file, poll_table *wait)
144 {
145         unsigned int mask = 0;
146         struct gpio_private *priv = file->private_data;
147         unsigned long data;
148         unsigned long flags;
149 
150         spin_lock_irqsave(&gpio_lock, flags);
151 
152         poll_wait(file, &priv->alarm_wq, wait);
153         if (priv->minor == GPIO_MINOR_A) {
154                 unsigned long tmp;
155                 data = *R_PORT_PA_DATA;
156                 /* PA has support for high level interrupt -
157                  * lets activate for those low and with highalarm set
158                  */
159                 tmp = ~data & priv->highalarm & 0xFF;
160                 tmp = (tmp << R_IRQ_MASK1_SET__pa0__BITNR);
161 
162                 gpio_pa_irq_enabled_mask |= tmp;
163                 *R_IRQ_MASK1_SET = tmp;
164         } else if (priv->minor == GPIO_MINOR_B)
165                 data = *R_PORT_PB_DATA;
166         else if (priv->minor == GPIO_MINOR_G)
167                 data = *R_PORT_G_DATA;
168         else {
169                 mask = 0;
170                 goto out;
171         }
172 
173         if ((data & priv->highalarm) ||
174             (~data & priv->lowalarm)) {
175                 mask = POLLIN|POLLRDNORM;
176         }
177 
178 out:
179         spin_unlock_irqrestore(&gpio_lock, flags);
180         DP(printk("gpio_poll ready: mask 0x%08X\n", mask));
181 
182         return mask;
183 }
184 
185 int etrax_gpio_wake_up_check(void)
186 {
187         struct gpio_private *priv;
188         unsigned long data = 0;
189         int ret = 0;
190         unsigned long flags;
191 
192         spin_lock_irqsave(&gpio_lock, flags);
193         priv = alarmlist;
194         while (priv) {
195                 if (USE_PORTS(priv))
196                         data = *priv->port;
197                 else if (priv->minor == GPIO_MINOR_G)
198                         data = *R_PORT_G_DATA;
199 
200                 if ((data & priv->highalarm) ||
201                     (~data & priv->lowalarm)) {
202                         DP(printk("etrax_gpio_wake_up_check %i\n",priv->minor));
203                         wake_up_interruptible(&priv->alarm_wq);
204                         ret = 1;
205                 }
206                 priv = priv->next;
207         }
208         spin_unlock_irqrestore(&gpio_lock, flags);
209         return ret;
210 }
211 
212 static irqreturn_t
213 gpio_poll_timer_interrupt(int irq, void *dev_id)
214 {
215         if (gpio_some_alarms) {
216                 etrax_gpio_wake_up_check();
217                 return IRQ_HANDLED;
218         }
219         return IRQ_NONE;
220 }
221 
222 static irqreturn_t
223 gpio_interrupt(int irq, void *dev_id)
224 {
225         unsigned long tmp;
226         unsigned long flags;
227 
228         spin_lock_irqsave(&gpio_lock, flags);
229 
230         /* Find what PA interrupts are active */
231         tmp = (*R_IRQ_READ1);
232 
233         /* Find those that we have enabled */
234         tmp &= gpio_pa_irq_enabled_mask;
235 
236         /* Clear them.. */
237         *R_IRQ_MASK1_CLR = tmp;
238         gpio_pa_irq_enabled_mask &= ~tmp;
239 
240         spin_unlock_irqrestore(&gpio_lock, flags);
241 
242         if (gpio_some_alarms)
243                 return IRQ_RETVAL(etrax_gpio_wake_up_check());
244 
245         return IRQ_NONE;
246 }
247 
248 static void gpio_write_bit(struct gpio_private *priv,
249         unsigned char data, int bit)
250 {
251         *priv->port = *priv->shadow &= ~(priv->clk_mask);
252         if (data & 1 << bit)
253                 *priv->port = *priv->shadow |= priv->data_mask;
254         else
255                 *priv->port = *priv->shadow &= ~(priv->data_mask);
256 
257         /* For FPGA: min 5.0ns (DCC) before CCLK high */
258         *priv->port = *priv->shadow |= priv->clk_mask;
259 }
260 
261 static void gpio_write_byte(struct gpio_private *priv, unsigned char data)
262 {
263         int i;
264 
265         if (priv->write_msb)
266                 for (i = 7; i >= 0; i--)
267                         gpio_write_bit(priv, data, i);
268         else
269                 for (i = 0; i <= 7; i++)
270                         gpio_write_bit(priv, data, i);
271 }
272 
273 static ssize_t gpio_write(struct file *file, const char __user *buf,
274         size_t count, loff_t *off)
275 {
276         struct gpio_private *priv = file->private_data;
277         unsigned long flags;
278         ssize_t retval = count;
279 
280         if (priv->minor != GPIO_MINOR_A && priv->minor != GPIO_MINOR_B)
281                 return -EFAULT;
282 
283         if (!access_ok(VERIFY_READ, buf, count))
284                 return -EFAULT;
285 
286         spin_lock_irqsave(&gpio_lock, flags);
287 
288         /* It must have been configured using the IO_CFG_WRITE_MODE */
289         /* Perhaps a better error code? */
290         if (priv->clk_mask == 0 || priv->data_mask == 0) {
291                 retval = -EPERM;
292                 goto out;
293         }
294 
295         D(printk(KERN_DEBUG "gpio_write: %02X to data 0x%02X "
296                 "clk 0x%02X msb: %i\n",
297                 count, priv->data_mask, priv->clk_mask, priv->write_msb));
298 
299         while (count--)
300                 gpio_write_byte(priv, *buf++);
301 
302 out:
303         spin_unlock_irqrestore(&gpio_lock, flags);
304         return retval;
305 }
306 
307 
308 
309 static int
310 gpio_open(struct inode *inode, struct file *filp)
311 {
312         struct gpio_private *priv;
313         int p = iminor(inode);
314         unsigned long flags;
315 
316         if (p > GPIO_MINOR_LAST)
317                 return -EINVAL;
318 
319         priv = kzalloc(sizeof(struct gpio_private), GFP_KERNEL);
320 
321         if (!priv)
322                 return -ENOMEM;
323 
324         priv->minor = p;
325 
326         /* initialize the io/alarm struct */
327 
328         if (USE_PORTS(priv)) { /* A and B */
329                 priv->port = ports[p];
330                 priv->shadow = shads[p];
331                 priv->dir = dir[p];
332                 priv->dir_shadow = dir_shadow[p];
333                 priv->changeable_dir = changeable_dir[p];
334                 priv->changeable_bits = changeable_bits[p];
335         } else {
336                 priv->port = NULL;
337                 priv->shadow = NULL;
338                 priv->dir = NULL;
339                 priv->dir_shadow = NULL;
340                 priv->changeable_dir = 0;
341                 priv->changeable_bits = 0;
342         }
343 
344         priv->highalarm = 0;
345         priv->lowalarm = 0;
346         priv->clk_mask = 0;
347         priv->data_mask = 0;
348         init_waitqueue_head(&priv->alarm_wq);
349 
350         filp->private_data = priv;
351 
352         /* link it into our alarmlist */
353         spin_lock_irqsave(&gpio_lock, flags);
354         priv->next = alarmlist;
355         alarmlist = priv;
356         spin_unlock_irqrestore(&gpio_lock, flags);
357 
358         return 0;
359 }
360 
361 static int
362 gpio_release(struct inode *inode, struct file *filp)
363 {
364         struct gpio_private *p;
365         struct gpio_private *todel;
366         unsigned long flags;
367 
368         spin_lock_irqsave(&gpio_lock, flags);
369 
370         p = alarmlist;
371         todel = filp->private_data;
372 
373         /* unlink from alarmlist and free the private structure */
374 
375         if (p == todel) {
376                 alarmlist = todel->next;
377         } else {
378                 while (p->next != todel)
379                         p = p->next;
380                 p->next = todel->next;
381         }
382 
383         kfree(todel);
384         /* Check if there are still any alarms set */
385         p = alarmlist;
386         while (p) {
387                 if (p->highalarm | p->lowalarm) {
388                         gpio_some_alarms = 1;
389                         goto out;
390                 }
391                 p = p->next;
392         }
393         gpio_some_alarms = 0;
394 out:
395         spin_unlock_irqrestore(&gpio_lock, flags);
396         return 0;
397 }
398 
399 /* Main device API. ioctl's to read/set/clear bits, as well as to
400  * set alarms to wait for using a subsequent select().
401  */
402 unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
403 {
404         /* Set direction 0=unchanged 1=input,
405          * return mask with 1=input */
406         if (USE_PORTS(priv)) {
407                 *priv->dir = *priv->dir_shadow &=
408                 ~((unsigned char)arg & priv->changeable_dir);
409                 return ~(*priv->dir_shadow) & 0xFF; /* Only 8 bits */
410         }
411 
412         if (priv->minor != GPIO_MINOR_G)
413                 return 0;
414 
415         /* We must fiddle with R_GEN_CONFIG to change dir */
416         if (((arg & dir_g_in_bits) != arg) &&
417             (arg & changeable_dir_g)) {
418                 arg &= changeable_dir_g;
419                 /* Clear bits in genconfig to set to input */
420                 if (arg & (1<<0)) {
421                         genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g0dir);
422                         dir_g_in_bits |= (1<<0);
423                         dir_g_out_bits &= ~(1<<0);
424                 }
425                 if ((arg & 0x0000FF00) == 0x0000FF00) {
426                         genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g8_15dir);
427                         dir_g_in_bits |= 0x0000FF00;
428                         dir_g_out_bits &= ~0x0000FF00;
429                 }
430                 if ((arg & 0x00FF0000) == 0x00FF0000) {
431                         genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g16_23dir);
432                         dir_g_in_bits |= 0x00FF0000;
433                         dir_g_out_bits &= ~0x00FF0000;
434                 }
435                 if (arg & (1<<24)) {
436                         genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, g24dir);
437                         dir_g_in_bits |= (1<<24);
438                         dir_g_out_bits &= ~(1<<24);
439                 }
440                 D(printk(KERN_DEBUG "gpio: SETINPUT on port G set "
441                          "genconfig to 0x%08lX "
442                          "in_bits: 0x%08lX "
443                          "out_bits: 0x%08lX\n",
444                          (unsigned long)genconfig_shadow,
445                          dir_g_in_bits, dir_g_out_bits));
446                 *R_GEN_CONFIG = genconfig_shadow;
447                 /* Must be a >120 ns delay before writing this again */
448 
449         }
450         return dir_g_in_bits;
451 } /* setget_input */
452 
453 unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg)
454 {
455         if (USE_PORTS(priv)) {
456                 *priv->dir = *priv->dir_shadow |=
457                         ((unsigned char)arg & priv->changeable_dir);
458                 return *priv->dir_shadow;
459         }
460         if (priv->minor != GPIO_MINOR_G)
461                 return 0;
462 
463         /* We must fiddle with R_GEN_CONFIG to change dir */
464         if (((arg & dir_g_out_bits) != arg) &&
465             (arg & changeable_dir_g)) {
466                 /* Set bits in genconfig to set to output */
467                 if (arg & (1<<0)) {
468                         genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g0dir);
469                         dir_g_out_bits |= (1<<0);
470                         dir_g_in_bits &= ~(1<<0);
471                 }
472                 if ((arg & 0x0000FF00) == 0x0000FF00) {
473                         genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g8_15dir);
474                         dir_g_out_bits |= 0x0000FF00;
475                         dir_g_in_bits &= ~0x0000FF00;
476                 }
477                 if ((arg & 0x00FF0000) == 0x00FF0000) {
478                         genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g16_23dir);
479                         dir_g_out_bits |= 0x00FF0000;
480                         dir_g_in_bits &= ~0x00FF0000;
481                 }
482                 if (arg & (1<<24)) {
483                         genconfig_shadow |= IO_MASK(R_GEN_CONFIG, g24dir);
484                         dir_g_out_bits |= (1<<24);
485                         dir_g_in_bits &= ~(1<<24);
486                 }
487                 D(printk(KERN_INFO "gpio: SETOUTPUT on port G set "
488                          "genconfig to 0x%08lX "
489                          "in_bits: 0x%08lX "
490                          "out_bits: 0x%08lX\n",
491                          (unsigned long)genconfig_shadow,
492                          dir_g_in_bits, dir_g_out_bits));
493                 *R_GEN_CONFIG = genconfig_shadow;
494                 /* Must be a >120 ns delay before writing this again */
495         }
496         return dir_g_out_bits & 0x7FFFFFFF;
497 } /* setget_output */
498 
499 static int
500 gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
501 
502 static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
503 {
504         unsigned long flags;
505         unsigned long val;
506         int ret = 0;
507 
508         struct gpio_private *priv = file->private_data;
509         if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE)
510                 return -EINVAL;
511 
512         switch (_IOC_NR(cmd)) {
513         case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
514                 // read the port
515                 spin_lock_irqsave(&gpio_lock, flags);
516                 if (USE_PORTS(priv)) {
517                         ret =  *priv->port;
518                 } else if (priv->minor == GPIO_MINOR_G) {
519                         ret =  (*R_PORT_G_DATA) & 0x7FFFFFFF;
520                 }
521                 spin_unlock_irqrestore(&gpio_lock, flags);
522 
523                 break;
524         case IO_SETBITS:
525                 // set changeable bits with a 1 in arg
526                 spin_lock_irqsave(&gpio_lock, flags);
527 
528                 if (USE_PORTS(priv)) {
529                         *priv->port = *priv->shadow |=
530                           ((unsigned char)arg & priv->changeable_bits);
531                 } else if (priv->minor == GPIO_MINOR_G) {
532                         *R_PORT_G_DATA = port_g_data_shadow |= (arg & dir_g_out_bits);
533                 }
534                 spin_unlock_irqrestore(&gpio_lock, flags);
535 
536                 break;
537         case IO_CLRBITS:
538                 // clear changeable bits with a 1 in arg
539                 spin_lock_irqsave(&gpio_lock, flags);
540                 if (USE_PORTS(priv)) {
541                         *priv->port = *priv->shadow &=
542                          ~((unsigned char)arg & priv->changeable_bits);
543                 } else if (priv->minor == GPIO_MINOR_G) {
544                         *R_PORT_G_DATA = port_g_data_shadow &= ~((unsigned long)arg & dir_g_out_bits);
545                 }
546                 spin_unlock_irqrestore(&gpio_lock, flags);
547                 break;
548         case IO_HIGHALARM:
549                 // set alarm when bits with 1 in arg go high
550                 spin_lock_irqsave(&gpio_lock, flags);
551                 priv->highalarm |= arg;
552                 gpio_some_alarms = 1;
553                 spin_unlock_irqrestore(&gpio_lock, flags);
554                 break;
555         case IO_LOWALARM:
556                 // set alarm when bits with 1 in arg go low
557                 spin_lock_irqsave(&gpio_lock, flags);
558                 priv->lowalarm |= arg;
559                 gpio_some_alarms = 1;
560                 spin_unlock_irqrestore(&gpio_lock, flags);
561                 break;
562         case IO_CLRALARM:
563                 /* clear alarm for bits with 1 in arg */
564                 spin_lock_irqsave(&gpio_lock, flags);
565                 priv->highalarm &= ~arg;
566                 priv->lowalarm  &= ~arg;
567                 {
568                         /* Must update gpio_some_alarms */
569                         struct gpio_private *p = alarmlist;
570                         int some_alarms;
571                         p = alarmlist;
572                         some_alarms = 0;
573                         while (p) {
574                                 if (p->highalarm | p->lowalarm) {
575                                         some_alarms = 1;
576                                         break;
577                                 }
578                                 p = p->next;
579                         }
580                         gpio_some_alarms = some_alarms;
581                 }
582                 spin_unlock_irqrestore(&gpio_lock, flags);
583                 break;
584         case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
585                 /* Read direction 0=input 1=output */
586                 spin_lock_irqsave(&gpio_lock, flags);
587                 if (USE_PORTS(priv)) {
588                         ret = *priv->dir_shadow;
589                 } else if (priv->minor == GPIO_MINOR_G) {
590                         /* Note: Some bits are both in and out,
591                          * Those that are dual is set here as well.
592                          */
593                         ret = (dir_g_shadow | dir_g_out_bits) & 0x7FFFFFFF;
594                 }
595                 spin_unlock_irqrestore(&gpio_lock, flags);
596                 break;
597         case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */
598                 /* Set direction 0=unchanged 1=input,
599                  * return mask with 1=input
600                  */
601                 spin_lock_irqsave(&gpio_lock, flags);
602                 ret = setget_input(priv, arg) & 0x7FFFFFFF;
603                 spin_unlock_irqrestore(&gpio_lock, flags);
604                 break;
605         case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */
606                 /* Set direction 0=unchanged 1=output,
607                  * return mask with 1=output
608                  */
609                 spin_lock_irqsave(&gpio_lock, flags);
610                 ret =  setget_output(priv, arg) & 0x7FFFFFFF;
611                 spin_unlock_irqrestore(&gpio_lock, flags);
612                 break;
613         case IO_SHUTDOWN:
614                 spin_lock_irqsave(&gpio_lock, flags);
615                 SOFT_SHUTDOWN();
616                 spin_unlock_irqrestore(&gpio_lock, flags);
617                 break;
618         case IO_GET_PWR_BT:
619                 spin_lock_irqsave(&gpio_lock, flags);
620 #if defined (CONFIG_ETRAX_SOFT_SHUTDOWN)
621                 ret = (*R_PORT_G_DATA & ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT));
622 #else
623                 ret = 0;
624 #endif
625                 spin_unlock_irqrestore(&gpio_lock, flags);
626                 break;
627         case IO_CFG_WRITE_MODE:
628                 spin_lock_irqsave(&gpio_lock, flags);
629                 priv->clk_mask = arg & 0xFF;
630                 priv->data_mask = (arg >> 8) & 0xFF;
631                 priv->write_msb = (arg >> 16) & 0x01;
632                 /* Check if we're allowed to change the bits and
633                  * the direction is correct
634                  */
635                 if (!((priv->clk_mask & priv->changeable_bits) &&
636                       (priv->data_mask & priv->changeable_bits) &&
637                       (priv->clk_mask & *priv->dir_shadow) &&
638                       (priv->data_mask & *priv->dir_shadow)))
639                 {
640                         priv->clk_mask = 0;
641                         priv->data_mask = 0;
642                         ret = -EPERM;
643                 }
644                 spin_unlock_irqrestore(&gpio_lock, flags);
645                 break;
646         case IO_READ_INBITS:
647                 /* *arg is result of reading the input pins */
648                 spin_lock_irqsave(&gpio_lock, flags);
649                 if (USE_PORTS(priv)) {
650                         val = *priv->port;
651                 } else if (priv->minor == GPIO_MINOR_G) {
652                         val = *R_PORT_G_DATA;
653                 }
654                 spin_unlock_irqrestore(&gpio_lock, flags);
655                 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
656                         ret = -EFAULT;
657                 break;
658         case IO_READ_OUTBITS:
659                  /* *arg is result of reading the output shadow */
660                 spin_lock_irqsave(&gpio_lock, flags);
661                 if (USE_PORTS(priv)) {
662                         val = *priv->shadow;
663                 } else if (priv->minor == GPIO_MINOR_G) {
664                         val = port_g_data_shadow;
665                 }
666                 spin_unlock_irqrestore(&gpio_lock, flags);
667                 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
668                         ret = -EFAULT;
669                 break;
670         case IO_SETGET_INPUT:
671                 /* bits set in *arg is set to input,
672                  * *arg updated with current input pins.
673                  */
674                 if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
675                 {
676                         ret = -EFAULT;
677                         break;
678                 }
679                 spin_lock_irqsave(&gpio_lock, flags);
680                 val = setget_input(priv, val);
681                 spin_unlock_irqrestore(&gpio_lock, flags);
682                 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
683                         ret = -EFAULT;
684                 break;
685         case IO_SETGET_OUTPUT:
686                 /* bits set in *arg is set to output,
687                  * *arg updated with current output pins.
688                  */
689                 if (copy_from_user(&val, (void __user *)arg, sizeof(val))) {
690                         ret = -EFAULT;
691                         break;
692                 }
693                 spin_lock_irqsave(&gpio_lock, flags);
694                 val = setget_output(priv, val);
695                 spin_unlock_irqrestore(&gpio_lock, flags);
696                 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
697                         ret = -EFAULT;
698                 break;
699         default:
700                 spin_lock_irqsave(&gpio_lock, flags);
701                 if (priv->minor == GPIO_MINOR_LEDS)
702                         ret = gpio_leds_ioctl(cmd, arg);
703                 else
704                         ret = -EINVAL;
705                 spin_unlock_irqrestore(&gpio_lock, flags);
706         } /* switch */
707 
708         return ret;
709 }
710 
711 static int
712 gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
713 {
714         unsigned char green;
715         unsigned char red;
716 
717         switch (_IOC_NR(cmd)) {
718         case IO_LEDACTIVE_SET:
719                 green = ((unsigned char)arg) & 1;
720                 red   = (((unsigned char)arg) >> 1) & 1;
721                 CRIS_LED_ACTIVE_SET_G(green);
722                 CRIS_LED_ACTIVE_SET_R(red);
723                 break;
724 
725         case IO_LED_SETBIT:
726                 CRIS_LED_BIT_SET(arg);
727                 break;
728 
729         case IO_LED_CLRBIT:
730                 CRIS_LED_BIT_CLR(arg);
731                 break;
732 
733         default:
734                 return -EINVAL;
735         } /* switch */
736 
737         return 0;
738 }
739 
740 static const struct file_operations gpio_fops = {
741         .owner          = THIS_MODULE,
742         .poll           = gpio_poll,
743         .unlocked_ioctl = gpio_ioctl,
744         .write          = gpio_write,
745         .open           = gpio_open,
746         .release        = gpio_release,
747         .llseek         = noop_llseek,
748 };
749 
750 static void ioif_watcher(const unsigned int gpio_in_available,
751         const unsigned int gpio_out_available,
752         const unsigned char pa_available,
753         const unsigned char pb_available)
754 {
755         unsigned long int flags;
756 
757         D(printk(KERN_DEBUG "gpio.c: ioif_watcher called\n"));
758         D(printk(KERN_DEBUG "gpio.c: G in: 0x%08x G out: 0x%08x "
759                 "PA: 0x%02x PB: 0x%02x\n",
760                 gpio_in_available, gpio_out_available,
761                 pa_available, pb_available));
762 
763         spin_lock_irqsave(&gpio_lock, flags);
764 
765         dir_g_in_bits = gpio_in_available;
766         dir_g_out_bits = gpio_out_available;
767 
768         /* Initialise the dir_g_shadow etc. depending on genconfig */
769         /* 0=input 1=output */
770         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g0dir, out))
771                 dir_g_shadow |= (1 << 0);
772         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g8_15dir, out))
773                 dir_g_shadow |= 0x0000FF00;
774         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g16_23dir, out))
775                 dir_g_shadow |= 0x00FF0000;
776         if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g24dir, out))
777                 dir_g_shadow |= (1 << 24);
778 
779         changeable_dir_g = changeable_dir_g_mask;
780         changeable_dir_g &= dir_g_out_bits;
781         changeable_dir_g &= dir_g_in_bits;
782 
783         /* Correct the bits that can change direction */
784         dir_g_out_bits &= ~changeable_dir_g;
785         dir_g_out_bits |= dir_g_shadow;
786         dir_g_in_bits &= ~changeable_dir_g;
787         dir_g_in_bits |= (~dir_g_shadow & changeable_dir_g);
788 
789         spin_unlock_irqrestore(&gpio_lock, flags);
790 
791         printk(KERN_INFO "GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX "
792                 "val: %08lX\n",
793                dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA);
794         printk(KERN_INFO "GPIO port G: dir: %08lX changeable: %08lX\n",
795                dir_g_shadow, changeable_dir_g);
796 }
797 
798 /* main driver initialization routine, called from mem.c */
799 
800 static int __init gpio_init(void)
801 {
802         int res;
803 #if defined (CONFIG_ETRAX_CSP0_LEDS)
804         int i;
805 #endif
806 
807         res = register_chrdev(GPIO_MAJOR, gpio_name, &gpio_fops);
808         if (res < 0) {
809                 printk(KERN_ERR "gpio: couldn't get a major number.\n");
810                 return res;
811         }
812 
813         /* Clear all leds */
814 #if defined (CONFIG_ETRAX_CSP0_LEDS) ||  defined (CONFIG_ETRAX_PA_LEDS) || defined (CONFIG_ETRAX_PB_LEDS)
815         CRIS_LED_NETWORK_SET(0);
816         CRIS_LED_ACTIVE_SET(0);
817         CRIS_LED_DISK_READ(0);
818         CRIS_LED_DISK_WRITE(0);
819 
820 #if defined (CONFIG_ETRAX_CSP0_LEDS)
821         for (i = 0; i < 32; i++)
822                 CRIS_LED_BIT_SET(i);
823 #endif
824 
825 #endif
826         /* The I/O interface allocation watcher will be called when
827          * registering it. */
828         if (cris_io_interface_register_watcher(ioif_watcher)){
829                 printk(KERN_WARNING "gpio_init: Failed to install IO "
830                         "if allocator watcher\n");
831         }
832 
833         printk(KERN_INFO "ETRAX 100LX GPIO driver v2.5, (c) 2001-2008 "
834                 "Axis Communications AB\n");
835         /* We call etrax_gpio_wake_up_check() from timer interrupt and
836          * from default_idle() in kernel/process.c
837          * The check in default_idle() reduces latency from ~15 ms to ~6 ms
838          * in some tests.
839          */
840         res = request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt,
841                 IRQF_SHARED, "gpio poll", gpio_name);
842         if (res) {
843                 printk(KERN_CRIT "err: timer0 irq for gpio\n");
844                 return res;
845         }
846         res = request_irq(PA_IRQ_NBR, gpio_interrupt,
847                 IRQF_SHARED, "gpio PA", gpio_name);
848         if (res)
849                 printk(KERN_CRIT "err: PA irq for gpio\n");
850 
851         return res;
852 }
853 
854 /* this makes sure that gpio_init is called during kernel boot */
855 module_init(gpio_init);
856 
857 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp