diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/synclink_gt.c | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 1746d91205f7..11999784383e 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -2357,26 +2357,27 @@ static irqreturn_t slgt_interrupt(int dummy, void *dev_id) | |||
2357 | 2357 | ||
2358 | DBGISR(("slgt_interrupt irq=%d entry\n", info->irq_level)); | 2358 | DBGISR(("slgt_interrupt irq=%d entry\n", info->irq_level)); |
2359 | 2359 | ||
2360 | spin_lock(&info->lock); | ||
2361 | |||
2362 | while((gsr = rd_reg32(info, GSR) & 0xffffff00)) { | 2360 | while((gsr = rd_reg32(info, GSR) & 0xffffff00)) { |
2363 | DBGISR(("%s gsr=%08x\n", info->device_name, gsr)); | 2361 | DBGISR(("%s gsr=%08x\n", info->device_name, gsr)); |
2364 | info->irq_occurred = true; | 2362 | info->irq_occurred = true; |
2365 | for(i=0; i < info->port_count ; i++) { | 2363 | for(i=0; i < info->port_count ; i++) { |
2366 | if (info->port_array[i] == NULL) | 2364 | if (info->port_array[i] == NULL) |
2367 | continue; | 2365 | continue; |
2366 | spin_lock(&info->port_array[i]->lock); | ||
2368 | if (gsr & (BIT8 << i)) | 2367 | if (gsr & (BIT8 << i)) |
2369 | isr_serial(info->port_array[i]); | 2368 | isr_serial(info->port_array[i]); |
2370 | if (gsr & (BIT16 << (i*2))) | 2369 | if (gsr & (BIT16 << (i*2))) |
2371 | isr_rdma(info->port_array[i]); | 2370 | isr_rdma(info->port_array[i]); |
2372 | if (gsr & (BIT17 << (i*2))) | 2371 | if (gsr & (BIT17 << (i*2))) |
2373 | isr_tdma(info->port_array[i]); | 2372 | isr_tdma(info->port_array[i]); |
2373 | spin_unlock(&info->port_array[i]->lock); | ||
2374 | } | 2374 | } |
2375 | } | 2375 | } |
2376 | 2376 | ||
2377 | if (info->gpio_present) { | 2377 | if (info->gpio_present) { |
2378 | unsigned int state; | 2378 | unsigned int state; |
2379 | unsigned int changed; | 2379 | unsigned int changed; |
2380 | spin_lock(&info->lock); | ||
2380 | while ((changed = rd_reg32(info, IOSR)) != 0) { | 2381 | while ((changed = rd_reg32(info, IOSR)) != 0) { |
2381 | DBGISR(("%s iosr=%08x\n", info->device_name, changed)); | 2382 | DBGISR(("%s iosr=%08x\n", info->device_name, changed)); |
2382 | /* read latched state of GPIO signals */ | 2383 | /* read latched state of GPIO signals */ |
@@ -2388,22 +2389,24 @@ static irqreturn_t slgt_interrupt(int dummy, void *dev_id) | |||
2388 | isr_gpio(info->port_array[i], changed, state); | 2389 | isr_gpio(info->port_array[i], changed, state); |
2389 | } | 2390 | } |
2390 | } | 2391 | } |
2392 | spin_unlock(&info->lock); | ||
2391 | } | 2393 | } |
2392 | 2394 | ||
2393 | for(i=0; i < info->port_count ; i++) { | 2395 | for(i=0; i < info->port_count ; i++) { |
2394 | struct slgt_info *port = info->port_array[i]; | 2396 | struct slgt_info *port = info->port_array[i]; |
2395 | 2397 | if (port == NULL) | |
2396 | if (port && (port->port.count || port->netcount) && | 2398 | continue; |
2399 | spin_lock(&port->lock); | ||
2400 | if ((port->port.count || port->netcount) && | ||
2397 | port->pending_bh && !port->bh_running && | 2401 | port->pending_bh && !port->bh_running && |
2398 | !port->bh_requested) { | 2402 | !port->bh_requested) { |
2399 | DBGISR(("%s bh queued\n", port->device_name)); | 2403 | DBGISR(("%s bh queued\n", port->device_name)); |
2400 | schedule_work(&port->task); | 2404 | schedule_work(&port->task); |
2401 | port->bh_requested = true; | 2405 | port->bh_requested = true; |
2402 | } | 2406 | } |
2407 | spin_unlock(&port->lock); | ||
2403 | } | 2408 | } |
2404 | 2409 | ||
2405 | spin_unlock(&info->lock); | ||
2406 | |||
2407 | DBGISR(("slgt_interrupt irq=%d exit\n", info->irq_level)); | 2410 | DBGISR(("slgt_interrupt irq=%d exit\n", info->irq_level)); |
2408 | return IRQ_HANDLED; | 2411 | return IRQ_HANDLED; |
2409 | } | 2412 | } |
@@ -2906,7 +2909,7 @@ static int set_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio) | |||
2906 | info->device_name, gpio.state, gpio.smask, | 2909 | info->device_name, gpio.state, gpio.smask, |
2907 | gpio.dir, gpio.dmask)); | 2910 | gpio.dir, gpio.dmask)); |
2908 | 2911 | ||
2909 | spin_lock_irqsave(&info->lock,flags); | 2912 | spin_lock_irqsave(&info->port_array[0]->lock, flags); |
2910 | if (gpio.dmask) { | 2913 | if (gpio.dmask) { |
2911 | data = rd_reg32(info, IODR); | 2914 | data = rd_reg32(info, IODR); |
2912 | data |= gpio.dmask & gpio.dir; | 2915 | data |= gpio.dmask & gpio.dir; |
@@ -2919,7 +2922,7 @@ static int set_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio) | |||
2919 | data &= ~(gpio.smask & ~gpio.state); | 2922 | data &= ~(gpio.smask & ~gpio.state); |
2920 | wr_reg32(info, IOVR, data); | 2923 | wr_reg32(info, IOVR, data); |
2921 | } | 2924 | } |
2922 | spin_unlock_irqrestore(&info->lock,flags); | 2925 | spin_unlock_irqrestore(&info->port_array[0]->lock, flags); |
2923 | 2926 | ||
2924 | return 0; | 2927 | return 0; |
2925 | } | 2928 | } |
@@ -3020,7 +3023,7 @@ static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio) | |||
3020 | return -EINVAL; | 3023 | return -EINVAL; |
3021 | init_cond_wait(&wait, gpio.smask); | 3024 | init_cond_wait(&wait, gpio.smask); |
3022 | 3025 | ||
3023 | spin_lock_irqsave(&info->lock, flags); | 3026 | spin_lock_irqsave(&info->port_array[0]->lock, flags); |
3024 | /* enable interrupts for watched pins */ | 3027 | /* enable interrupts for watched pins */ |
3025 | wr_reg32(info, IOER, rd_reg32(info, IOER) | gpio.smask); | 3028 | wr_reg32(info, IOER, rd_reg32(info, IOER) | gpio.smask); |
3026 | /* get current pin states */ | 3029 | /* get current pin states */ |
@@ -3032,20 +3035,20 @@ static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio) | |||
3032 | } else { | 3035 | } else { |
3033 | /* wait for target state */ | 3036 | /* wait for target state */ |
3034 | add_cond_wait(&info->gpio_wait_q, &wait); | 3037 | add_cond_wait(&info->gpio_wait_q, &wait); |
3035 | spin_unlock_irqrestore(&info->lock, flags); | 3038 | spin_unlock_irqrestore(&info->port_array[0]->lock, flags); |
3036 | schedule(); | 3039 | schedule(); |
3037 | if (signal_pending(current)) | 3040 | if (signal_pending(current)) |
3038 | rc = -ERESTARTSYS; | 3041 | rc = -ERESTARTSYS; |
3039 | else | 3042 | else |
3040 | gpio.state = wait.data; | 3043 | gpio.state = wait.data; |
3041 | spin_lock_irqsave(&info->lock, flags); | 3044 | spin_lock_irqsave(&info->port_array[0]->lock, flags); |
3042 | remove_cond_wait(&info->gpio_wait_q, &wait); | 3045 | remove_cond_wait(&info->gpio_wait_q, &wait); |
3043 | } | 3046 | } |
3044 | 3047 | ||
3045 | /* disable all GPIO interrupts if no waiting processes */ | 3048 | /* disable all GPIO interrupts if no waiting processes */ |
3046 | if (info->gpio_wait_q == NULL) | 3049 | if (info->gpio_wait_q == NULL) |
3047 | wr_reg32(info, IOER, 0); | 3050 | wr_reg32(info, IOER, 0); |
3048 | spin_unlock_irqrestore(&info->lock,flags); | 3051 | spin_unlock_irqrestore(&info->port_array[0]->lock, flags); |
3049 | 3052 | ||
3050 | if ((rc == 0) && copy_to_user(user_gpio, &gpio, sizeof(gpio))) | 3053 | if ((rc == 0) && copy_to_user(user_gpio, &gpio, sizeof(gpio))) |
3051 | rc = -EFAULT; | 3054 | rc = -EFAULT; |
@@ -3578,7 +3581,6 @@ static void device_init(int adapter_num, struct pci_dev *pdev) | |||
3578 | 3581 | ||
3579 | /* copy resource information from first port to others */ | 3582 | /* copy resource information from first port to others */ |
3580 | for (i = 1; i < port_count; ++i) { | 3583 | for (i = 1; i < port_count; ++i) { |
3581 | port_array[i]->lock = port_array[0]->lock; | ||
3582 | port_array[i]->irq_level = port_array[0]->irq_level; | 3584 | port_array[i]->irq_level = port_array[0]->irq_level; |
3583 | port_array[i]->reg_addr = port_array[0]->reg_addr; | 3585 | port_array[i]->reg_addr = port_array[0]->reg_addr; |
3584 | alloc_dma_bufs(port_array[i]); | 3586 | alloc_dma_bufs(port_array[i]); |