git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
vserver 1.9.5.x5
[linux-2.6.git]
/
arch
/
cris
/
arch-v10
/
drivers
/
gpio.c
diff --git
a/arch/cris/arch-v10/drivers/gpio.c
b/arch/cris/arch-v10/drivers/gpio.c
index
f3a5716
..
50548a2
100644
(file)
--- a/
arch/cris/arch-v10/drivers/gpio.c
+++ b/
arch/cris/arch-v10/drivers/gpio.c
@@
-1,4
+1,4
@@
-/* $Id: gpio.c,v 1.
8 2003/07/04 08:27:37
starvik Exp $
+/* $Id: gpio.c,v 1.
12 2004/08/24 07:19:59
starvik Exp $
*
* Etrax general port I/O device
*
*
* Etrax general port I/O device
*
@@
-9,6
+9,15
@@
* Johan Adolfsson (read/set directions, write, port G)
*
* $Log: gpio.c,v $
* Johan Adolfsson (read/set directions, write, port G)
*
* $Log: gpio.c,v $
+ * Revision 1.12 2004/08/24 07:19:59 starvik
+ * Whitespace cleanup
+ *
+ * Revision 1.11 2004/05/14 07:58:03 starvik
+ * Merge of changes from 2.4
+ *
+ * Revision 1.9 2003/09/11 07:29:48 starvik
+ * Merge of Linux 2.6.0-test5
+ *
* Revision 1.8 2003/07/04 08:27:37 starvik
* Merge of Linux 2.5.74
*
* Revision 1.8 2003/07/04 08:27:37 starvik
* Merge of Linux 2.5.74
*
@@
-183,6
+192,7
@@
struct gpio_private {
static struct gpio_private *alarmlist = 0;
static int gpio_some_alarms = 0; /* Set if someone uses alarm */
static struct gpio_private *alarmlist = 0;
static int gpio_some_alarms = 0; /* Set if someone uses alarm */
+static unsigned long gpio_pa_irq_enabled_mask = 0;
/* Port A and B use 8 bit access, but Port G is 32 bit */
#define NUM_PORTS (GPIO_MINOR_B+1)
/* Port A and B use 8 bit access, but Port G is 32 bit */
#define NUM_PORTS (GPIO_MINOR_B+1)
@@
-252,13
+262,19
@@
gpio_poll(struct file *file,
unsigned long data;
poll_wait(file, &priv->alarm_wq, wait);
if (priv->minor == GPIO_MINOR_A) {
unsigned long data;
poll_wait(file, &priv->alarm_wq, wait);
if (priv->minor == GPIO_MINOR_A) {
+ unsigned long flags;
unsigned long tmp;
data = *R_PORT_PA_DATA;
/* PA has support for high level interrupt -
* lets activate for those low and with highalarm set
*/
tmp = ~data & priv->highalarm & 0xFF;
unsigned long tmp;
data = *R_PORT_PA_DATA;
/* PA has support for high level interrupt -
* lets activate for those low and with highalarm set
*/
tmp = ~data & priv->highalarm & 0xFF;
- *R_IRQ_MASK1_SET = (tmp << R_IRQ_MASK1_SET__pa0__BITNR);
+ tmp = (tmp << R_IRQ_MASK1_SET__pa0__BITNR);
+ save_flags(flags); cli();
+ gpio_pa_irq_enabled_mask |= tmp;
+ *R_IRQ_MASK1_SET = tmp;
+ restore_flags(flags);
+
} else if (priv->minor == GPIO_MINOR_B)
data = *R_PORT_PB_DATA;
else if (priv->minor == GPIO_MINOR_G)
} else if (priv->minor == GPIO_MINOR_B)
data = *R_PORT_PB_DATA;
else if (priv->minor == GPIO_MINOR_G)
@@
-312,12
+328,15
@@
gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned long tmp;
/* Find what PA interrupts are active */
{
unsigned long tmp;
/* Find what PA interrupts are active */
- tmp = (*R_IRQ_READ1 >> R_IRQ_READ1__pa0__BITNR) & 0xFF;
+ tmp = (*R_IRQ_READ1);
+
+ /* Find those that we have enabled */
+ tmp &= gpio_pa_irq_enabled_mask;
+
/* Clear them.. */
/* Clear them.. */
- /* NOTE: Maybe we need to be more careful here if some other
- * driver uses PA interrupt as well?
- */
- *R_IRQ_MASK1_CLR = (tmp << R_IRQ_MASK1_CLR__pa0__BITNR);
+ *R_IRQ_MASK1_CLR = tmp;
+ gpio_pa_irq_enabled_mask &= ~tmp;
+
if (gpio_some_alarms) {
return IRQ_RETVAL(etrax_gpio_wake_up_check());
}
if (gpio_some_alarms) {
return IRQ_RETVAL(etrax_gpio_wake_up_check());
}
@@
-386,7
+405,7
@@
static int
gpio_open(struct inode *inode, struct file *filp)
{
struct gpio_private *priv;
gpio_open(struct inode *inode, struct file *filp)
{
struct gpio_private *priv;
- int p =
iminor(inode
);
+ int p =
MINOR(inode->i_rdev
);
if (p > GPIO_MINOR_LAST)
return -EINVAL;
if (p > GPIO_MINOR_LAST)
return -EINVAL;
@@
-479,6
+498,7
@@
unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
return ~(*priv->dir_shadow) & 0xFF; /* Only 8 bits */
} else if (priv->minor == GPIO_MINOR_G) {
/* We must fiddle with R_GEN_CONFIG to change dir */
return ~(*priv->dir_shadow) & 0xFF; /* Only 8 bits */
} else if (priv->minor == GPIO_MINOR_G) {
/* We must fiddle with R_GEN_CONFIG to change dir */
+ save_flags(flags); cli();
if (((arg & dir_g_in_bits) != arg) &&
(arg & changeable_dir_g)) {
arg &= changeable_dir_g;
if (((arg & dir_g_in_bits) != arg) &&
(arg & changeable_dir_g)) {
arg &= changeable_dir_g;
@@
-503,16
+523,17
@@
unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
dir_g_in_bits |= (1<<24);
dir_g_out_bits &= ~(1<<24);
}
dir_g_in_bits |= (1<<24);
dir_g_out_bits &= ~(1<<24);
}
-
printk(
"gpio: SETINPUT on port G set "
- "genconfig to 0x%08lX "
- "in_bits: 0x%08lX "
- "out_bits: 0x%08lX\n",
- (unsigned long)genconfig_shadow,
-
dir_g_in_bits, dir_g_out_bits
);
+
D(printk(KERN_INFO
"gpio: SETINPUT on port G set "
+
"genconfig to 0x%08lX "
+
"in_bits: 0x%08lX "
+ "out_bits: 0x%08lX\n",
+ (unsigned long)genconfig_shadow,
+
dir_g_in_bits, dir_g_out_bits)
);
*R_GEN_CONFIG = genconfig_shadow;
/* Must be a >120 ns delay before writing this again */
}
*R_GEN_CONFIG = genconfig_shadow;
/* Must be a >120 ns delay before writing this again */
}
+ restore_flags(flags);
return dir_g_in_bits;
}
return 0;
return dir_g_in_bits;
}
return 0;
@@
-529,6
+550,7
@@
unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg)
return *priv->dir_shadow;
} else if (priv->minor == GPIO_MINOR_G) {
/* We must fiddle with R_GEN_CONFIG to change dir */
return *priv->dir_shadow;
} else if (priv->minor == GPIO_MINOR_G) {
/* We must fiddle with R_GEN_CONFIG to change dir */
+ save_flags(flags); cli();
if (((arg & dir_g_out_bits) != arg) &&
(arg & changeable_dir_g)) {
/* Set bits in genconfig to set to output */
if (((arg & dir_g_out_bits) != arg) &&
(arg & changeable_dir_g)) {
/* Set bits in genconfig to set to output */
@@
-552,15
+574,16
@@
unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg)
dir_g_out_bits |= (1<<24);
dir_g_in_bits &= ~(1<<24);
}
dir_g_out_bits |= (1<<24);
dir_g_in_bits &= ~(1<<24);
}
-
printk(
"gpio: SETOUTPUT on port G set "
- "genconfig to 0x%08lX "
- "in_bits: 0x%08lX "
- "out_bits: 0x%08lX\n",
- (unsigned long)genconfig_shadow,
-
dir_g_in_bits, dir_g_out_bits
);
+
D(printk(KERN_INFO
"gpio: SETOUTPUT on port G set "
+
"genconfig to 0x%08lX "
+
"in_bits: 0x%08lX "
+ "out_bits: 0x%08lX\n",
+ (unsigned long)genconfig_shadow,
+
dir_g_in_bits, dir_g_out_bits)
);
*R_GEN_CONFIG = genconfig_shadow;
/* Must be a >120 ns delay before writing this again */
}
*R_GEN_CONFIG = genconfig_shadow;
/* Must be a >120 ns delay before writing this again */
}
+ restore_flags(flags);
return dir_g_out_bits & 0x7FFFFFFF;
}
return 0;
return dir_g_out_bits & 0x7FFFFFFF;
}
return 0;
@@
-625,6
+648,20
@@
gpio_ioctl(struct inode *inode, struct file *file,
// clear alarm for bits with 1 in arg
priv->highalarm &= ~arg;
priv->lowalarm &= ~arg;
// clear alarm for bits with 1 in arg
priv->highalarm &= ~arg;
priv->lowalarm &= ~arg;
+ {
+ /* Must update gpio_some_alarms */
+ struct gpio_private *p = alarmlist;
+ int some_alarms;
+ some_alarms = 0;
+ while (p) {
+ if (p->highalarm | p->lowalarm) {
+ some_alarms = 1;
+ break;
+ }
+ p = p->next;
+ }
+ gpio_some_alarms = some_alarms;
+ }
break;
case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
/* Read direction 0=input 1=output */
break;
case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
/* Read direction 0=input 1=output */
@@
-844,9
+881,9
@@
static void __init gpio_init_port_g(void)
dir_g_in_bits |= (~dir_g_shadow & changeable_dir_g);
dir_g_in_bits |= (~dir_g_shadow & changeable_dir_g);
- printk("GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX val: %08lX\n",
+ printk(
KERN_INFO
"GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX val: %08lX\n",
dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA);
dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA);
- printk(
"GPIO port G: dir: %08lX changeable: %08lX\n",
+ printk(
KERN_INFO "GPIO port G: dir: %08lX changeable: %08lX\n",
dir_g_shadow, changeable_dir_g);
}
dir_g_shadow, changeable_dir_g);
}
@@
-883,7
+920,7
@@
gpio_init(void)
#endif
gpio_init_port_g();
#endif
gpio_init_port_g();
- printk("ETRAX 100LX GPIO driver v2.5, (c) 2001, 2002 Axis Communications AB\n");
+ printk(
KERN_INFO
"ETRAX 100LX GPIO driver v2.5, (c) 2001, 2002 Axis Communications AB\n");
/* We call etrax_gpio_wake_up_check() from timer interrupt and
* from cpu_idle() in kernel/process.c
* The check in cpu_idle() reduces latency from ~15 ms to ~6 ms
/* We call etrax_gpio_wake_up_check() from timer interrupt and
* from cpu_idle() in kernel/process.c
* The check in cpu_idle() reduces latency from ~15 ms to ~6 ms
@@
-891,11
+928,11
@@
gpio_init(void)
*/
if (request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt,
SA_SHIRQ | SA_INTERRUPT,"gpio poll", NULL)) {
*/
if (request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt,
SA_SHIRQ | SA_INTERRUPT,"gpio poll", NULL)) {
- printk("err: timer0 irq for gpio\n");
+ printk(
KERN_CRIT
"err: timer0 irq for gpio\n");
}
if (request_irq(PA_IRQ_NBR, gpio_pa_interrupt,
SA_SHIRQ | SA_INTERRUPT,"gpio PA", NULL)) {
}
if (request_irq(PA_IRQ_NBR, gpio_pa_interrupt,
SA_SHIRQ | SA_INTERRUPT,"gpio PA", NULL)) {
- printk("err: PA irq for gpio\n");
+ printk(
KERN_CRIT
"err: PA irq for gpio\n");
}
}