diff options
Diffstat (limited to 'arch/cris')
-rw-r--r-- | arch/cris/arch-v10/drivers/gpio.c | 3 | ||||
-rw-r--r-- | arch/cris/arch-v10/drivers/sync_serial.c | 34 | ||||
-rw-r--r-- | arch/cris/arch-v32/drivers/mach-a3/gpio.c | 4 | ||||
-rw-r--r-- | arch/cris/arch-v32/drivers/mach-fs/gpio.c | 5 | ||||
-rw-r--r-- | arch/cris/arch-v32/drivers/sync_serial.c | 33 |
5 files changed, 52 insertions, 27 deletions
diff --git a/arch/cris/arch-v10/drivers/gpio.c b/arch/cris/arch-v10/drivers/gpio.c index 68a998bd1069..86048e697eb5 100644 --- a/arch/cris/arch-v10/drivers/gpio.c +++ b/arch/cris/arch-v10/drivers/gpio.c @@ -16,6 +16,7 @@ #include <linux/errno.h> #include <linux/kernel.h> #include <linux/fs.h> +#include <linux/smp_lock.h> #include <linux/string.h> #include <linux/poll.h> #include <linux/init.h> @@ -323,6 +324,7 @@ gpio_open(struct inode *inode, struct file *filp) if (!priv) return -ENOMEM; + lock_kernel(); priv->minor = p; /* initialize the io/alarm struct */ @@ -357,6 +359,7 @@ gpio_open(struct inode *inode, struct file *filp) alarmlist = priv; spin_unlock_irqrestore(&gpio_lock, flags); + unlock_kernel(); return 0; } diff --git a/arch/cris/arch-v10/drivers/sync_serial.c b/arch/cris/arch-v10/drivers/sync_serial.c index 069546e342c5..91fea623c7c9 100644 --- a/arch/cris/arch-v10/drivers/sync_serial.c +++ b/arch/cris/arch-v10/drivers/sync_serial.c @@ -21,6 +21,7 @@ #include <linux/interrupt.h> #include <linux/poll.h> #include <linux/init.h> +#include <linux/smp_lock.h> #include <linux/timer.h> #include <asm/irq.h> #include <asm/dma.h> @@ -443,18 +444,21 @@ static int sync_serial_open(struct inode *inode, struct file *file) int dev = MINOR(inode->i_rdev); struct sync_port *port; int mode; + int err = -EBUSY; + lock_kernel(); DEBUG(printk(KERN_DEBUG "Open sync serial port %d\n", dev)); if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev)); - return -ENODEV; + err = -ENODEV; + goto out; } port = &ports[dev]; /* Allow open this device twice (assuming one reader and one writer) */ if (port->busy == 2) { DEBUG(printk(KERN_DEBUG "Device is busy.. \n")); - return -EBUSY; + goto out; } if (port->init_irqs) { if (port->use_dma) { @@ -465,14 +469,14 @@ static int sync_serial_open(struct inode *inode, struct file *file) &ports[0])) { printk(KERN_CRIT "Can't alloc " "sync serial port 1 IRQ"); - return -EBUSY; + goto out; } else if (request_irq(25, rx_interrupt, 0, "synchronous serial 1 dma rx", &ports[0])) { free_irq(24, &port[0]); printk(KERN_CRIT "Can't alloc " "sync serial port 1 IRQ"); - return -EBUSY; + goto out; } else if (cris_request_dma(8, "synchronous serial 1 dma tr", DMA_VERBOSE_ON_ERROR, @@ -482,7 +486,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) printk(KERN_CRIT "Can't alloc " "sync serial port 1 " "TX DMA channel"); - return -EBUSY; + goto out; } else if (cris_request_dma(9, "synchronous serial 1 dma rec", DMA_VERBOSE_ON_ERROR, @@ -493,7 +497,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) printk(KERN_CRIT "Can't alloc " "sync serial port 1 " "RX DMA channel"); - return -EBUSY; + goto out; } #endif RESET_DMA(8); WAIT_DMA(8); @@ -520,14 +524,14 @@ static int sync_serial_open(struct inode *inode, struct file *file) &ports[1])) { printk(KERN_CRIT "Can't alloc " "sync serial port 3 IRQ"); - return -EBUSY; + goto out; } else if (request_irq(21, rx_interrupt, 0, "synchronous serial 3 dma rx", &ports[1])) { free_irq(20, &ports[1]); printk(KERN_CRIT "Can't alloc " "sync serial port 3 IRQ"); - return -EBUSY; + goto out; } else if (cris_request_dma(4, "synchronous serial 3 dma tr", DMA_VERBOSE_ON_ERROR, @@ -537,7 +541,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) printk(KERN_CRIT "Can't alloc " "sync serial port 3 " "TX DMA channel"); - return -EBUSY; + goto out; } else if (cris_request_dma(5, "synchronous serial 3 dma rec", DMA_VERBOSE_ON_ERROR, @@ -548,7 +552,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) printk(KERN_CRIT "Can't alloc " "sync serial port 3 " "RX DMA channel"); - return -EBUSY; + goto out; } #endif RESET_DMA(4); WAIT_DMA(4); @@ -581,7 +585,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) &ports[0])) { printk(KERN_CRIT "Can't alloc " "sync serial manual irq"); - return -EBUSY; + goto out; } } else if (port == &ports[1]) { if (request_irq(8, @@ -591,7 +595,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) &ports[1])) { printk(KERN_CRIT "Can't alloc " "sync serial manual irq"); - return -EBUSY; + goto out; } } port->init_irqs = 0; @@ -620,7 +624,11 @@ static int sync_serial_open(struct inode *inode, struct file *file) *R_IRQ_MASK1_SET = 1 << port->data_avail_bit; DEBUG(printk(KERN_DEBUG "sser%d rec started\n", dev)); } - return 0; + ret = 0; + +out: + unlock_kernel(); + return ret; } static int sync_serial_release(struct inode *inode, struct file *file) diff --git a/arch/cris/arch-v32/drivers/mach-a3/gpio.c b/arch/cris/arch-v32/drivers/mach-a3/gpio.c index de107dad9f4f..ef98608e5067 100644 --- a/arch/cris/arch-v32/drivers/mach-a3/gpio.c +++ b/arch/cris/arch-v32/drivers/mach-a3/gpio.c @@ -23,6 +23,7 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/spinlock.h> +#include <linux/smp_lock.h> #include <asm/etraxgpio.h> #include <hwregs/reg_map.h> @@ -390,6 +391,8 @@ static int gpio_open(struct inode *inode, struct file *filp) if (!priv) return -ENOMEM; + + lock_kernel(); memset(priv, 0, sizeof(*priv)); priv->minor = p; @@ -412,6 +415,7 @@ static int gpio_open(struct inode *inode, struct file *filp) spin_unlock_irq(&gpio_lock); } + unlock_kernel(); return 0; } diff --git a/arch/cris/arch-v32/drivers/mach-fs/gpio.c b/arch/cris/arch-v32/drivers/mach-fs/gpio.c index 7863fd4efc2b..fe1fde893887 100644 --- a/arch/cris/arch-v32/drivers/mach-fs/gpio.c +++ b/arch/cris/arch-v32/drivers/mach-fs/gpio.c @@ -22,6 +22,7 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/spinlock.h> +#include <linux/smp_lock.h> #include <asm/etraxgpio.h> #include <hwregs/reg_map.h> @@ -426,9 +427,10 @@ gpio_open(struct inode *inode, struct file *filp) return -EINVAL; priv = kmalloc(sizeof(struct gpio_private), GFP_KERNEL); - if (!priv) return -ENOMEM; + + lock_kernel(); memset(priv, 0, sizeof(*priv)); priv->minor = p; @@ -449,6 +451,7 @@ gpio_open(struct inode *inode, struct file *filp) alarmlist = priv; spin_unlock_irq(&alarm_lock); + unlock_kernel(); return 0; } diff --git a/arch/cris/arch-v32/drivers/sync_serial.c b/arch/cris/arch-v32/drivers/sync_serial.c index 47c377df6fb3..d2a0fbf5341f 100644 --- a/arch/cris/arch-v32/drivers/sync_serial.c +++ b/arch/cris/arch-v32/drivers/sync_serial.c @@ -14,6 +14,7 @@ #include <linux/major.h> #include <linux/sched.h> #include <linux/slab.h> +#include <linux/smp_lock.h> #include <linux/interrupt.h> #include <linux/poll.h> #include <linux/init.h> @@ -429,23 +430,26 @@ static inline int sync_data_avail_to_end(struct sync_port *port) static int sync_serial_open(struct inode *inode, struct file *file) { int dev = iminor(inode); + int ret = -EBUSY; sync_port *port; reg_dma_rw_cfg cfg = {.en = regk_dma_yes}; reg_dma_rw_intr_mask intr_mask = {.data = regk_dma_yes}; + lock_kernel(); DEBUG(printk(KERN_DEBUG "Open sync serial port %d\n", dev)); if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled) { DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev)); - return -ENODEV; + ret = -ENODEV; + goto out; } port = &ports[dev]; /* Allow open this device twice (assuming one reader and one writer) */ if (port->busy == 2) { DEBUG(printk(KERN_DEBUG "Device is busy.. \n")); - return -EBUSY; + goto out; } @@ -459,7 +463,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) "synchronous serial 0 dma tr", &ports[0])) { printk(KERN_CRIT "Can't allocate sync serial port 0 IRQ"); - return -EBUSY; + goto out; } else if (request_irq(DMA_IN_INTR_VECT, rx_interrupt, 0, @@ -467,7 +471,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) &ports[0])) { free_irq(DMA_OUT_INTR_VECT, &port[0]); printk(KERN_CRIT "Can't allocate sync serial port 0 IRQ"); - return -EBUSY; + goto out; } else if (crisv32_request_dma(OUT_DMA_NBR, "synchronous serial 0 dma tr", DMA_VERBOSE_ON_ERROR, @@ -476,7 +480,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) free_irq(DMA_OUT_INTR_VECT, &port[0]); free_irq(DMA_IN_INTR_VECT, &port[0]); printk(KERN_CRIT "Can't allocate sync serial port 0 TX DMA channel"); - return -EBUSY; + goto out; } else if (crisv32_request_dma(IN_DMA_NBR, "synchronous serial 0 dma rec", DMA_VERBOSE_ON_ERROR, @@ -486,7 +490,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) free_irq(DMA_OUT_INTR_VECT, &port[0]); free_irq(DMA_IN_INTR_VECT, &port[0]); printk(KERN_CRIT "Can't allocate sync serial port 1 RX DMA channel"); - return -EBUSY; + goto out; } #endif } @@ -499,7 +503,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) "synchronous serial 1 dma tr", &ports[1])) { printk(KERN_CRIT "Can't allocate sync serial port 1 IRQ"); - return -EBUSY; + goto out; } else if (request_irq(DMA7_INTR_VECT, rx_interrupt, 0, @@ -507,7 +511,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) &ports[1])) { free_irq(DMA6_INTR_VECT, &ports[1]); printk(KERN_CRIT "Can't allocate sync serial port 3 IRQ"); - return -EBUSY; + goto out; } else if (crisv32_request_dma( SYNC_SER1_TX_DMA_NBR, "synchronous serial 1 dma tr", @@ -517,7 +521,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) free_irq(DMA6_INTR_VECT, &ports[1]); free_irq(DMA7_INTR_VECT, &ports[1]); printk(KERN_CRIT "Can't allocate sync serial port 3 TX DMA channel"); - return -EBUSY; + goto out; } else if (crisv32_request_dma( SYNC_SER1_RX_DMA_NBR, "synchronous serial 3 dma rec", @@ -528,7 +532,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) free_irq(DMA6_INTR_VECT, &ports[1]); free_irq(DMA7_INTR_VECT, &ports[1]); printk(KERN_CRIT "Can't allocate sync serial port 3 RX DMA channel"); - return -EBUSY; + goto out; } #endif } @@ -554,7 +558,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) "synchronous serial manual irq", &ports[0])) { printk("Can't allocate sync serial manual irq"); - return -EBUSY; + goto out; } } #ifdef CONFIG_ETRAXFS @@ -565,7 +569,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) "synchronous serial manual irq", &ports[1])) { printk(KERN_CRIT "Can't allocate sync serial manual irq"); - return -EBUSY; + goto out; } } #endif @@ -578,7 +582,10 @@ static int sync_serial_open(struct inode *inode, struct file *file) } /* port->init_irqs */ port->busy++; - return 0; + ret = 0; +out: + unlock_kernel(); + return ret; } static int sync_serial_release(struct inode *inode, struct file *file) |