diff options
Diffstat (limited to 'arch/cris/arch-v10/drivers/sync_serial.c')
-rw-r--r-- | arch/cris/arch-v10/drivers/sync_serial.c | 34 |
1 files changed, 21 insertions, 13 deletions
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 @@ | |||
21 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
22 | #include <linux/poll.h> | 22 | #include <linux/poll.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/smp_lock.h> | ||
24 | #include <linux/timer.h> | 25 | #include <linux/timer.h> |
25 | #include <asm/irq.h> | 26 | #include <asm/irq.h> |
26 | #include <asm/dma.h> | 27 | #include <asm/dma.h> |
@@ -443,18 +444,21 @@ static int sync_serial_open(struct inode *inode, struct file *file) | |||
443 | int dev = MINOR(inode->i_rdev); | 444 | int dev = MINOR(inode->i_rdev); |
444 | struct sync_port *port; | 445 | struct sync_port *port; |
445 | int mode; | 446 | int mode; |
447 | int err = -EBUSY; | ||
446 | 448 | ||
449 | lock_kernel(); | ||
447 | DEBUG(printk(KERN_DEBUG "Open sync serial port %d\n", dev)); | 450 | DEBUG(printk(KERN_DEBUG "Open sync serial port %d\n", dev)); |
448 | 451 | ||
449 | if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { | 452 | if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { |
450 | DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev)); | 453 | DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev)); |
451 | return -ENODEV; | 454 | err = -ENODEV; |
455 | goto out; | ||
452 | } | 456 | } |
453 | port = &ports[dev]; | 457 | port = &ports[dev]; |
454 | /* Allow open this device twice (assuming one reader and one writer) */ | 458 | /* Allow open this device twice (assuming one reader and one writer) */ |
455 | if (port->busy == 2) { | 459 | if (port->busy == 2) { |
456 | DEBUG(printk(KERN_DEBUG "Device is busy.. \n")); | 460 | DEBUG(printk(KERN_DEBUG "Device is busy.. \n")); |
457 | return -EBUSY; | 461 | goto out; |
458 | } | 462 | } |
459 | if (port->init_irqs) { | 463 | if (port->init_irqs) { |
460 | if (port->use_dma) { | 464 | if (port->use_dma) { |
@@ -465,14 +469,14 @@ static int sync_serial_open(struct inode *inode, struct file *file) | |||
465 | &ports[0])) { | 469 | &ports[0])) { |
466 | printk(KERN_CRIT "Can't alloc " | 470 | printk(KERN_CRIT "Can't alloc " |
467 | "sync serial port 1 IRQ"); | 471 | "sync serial port 1 IRQ"); |
468 | return -EBUSY; | 472 | goto out; |
469 | } else if (request_irq(25, rx_interrupt, 0, | 473 | } else if (request_irq(25, rx_interrupt, 0, |
470 | "synchronous serial 1 dma rx", | 474 | "synchronous serial 1 dma rx", |
471 | &ports[0])) { | 475 | &ports[0])) { |
472 | free_irq(24, &port[0]); | 476 | free_irq(24, &port[0]); |
473 | printk(KERN_CRIT "Can't alloc " | 477 | printk(KERN_CRIT "Can't alloc " |
474 | "sync serial port 1 IRQ"); | 478 | "sync serial port 1 IRQ"); |
475 | return -EBUSY; | 479 | goto out; |
476 | } else if (cris_request_dma(8, | 480 | } else if (cris_request_dma(8, |
477 | "synchronous serial 1 dma tr", | 481 | "synchronous serial 1 dma tr", |
478 | DMA_VERBOSE_ON_ERROR, | 482 | DMA_VERBOSE_ON_ERROR, |
@@ -482,7 +486,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) | |||
482 | printk(KERN_CRIT "Can't alloc " | 486 | printk(KERN_CRIT "Can't alloc " |
483 | "sync serial port 1 " | 487 | "sync serial port 1 " |
484 | "TX DMA channel"); | 488 | "TX DMA channel"); |
485 | return -EBUSY; | 489 | goto out; |
486 | } else if (cris_request_dma(9, | 490 | } else if (cris_request_dma(9, |
487 | "synchronous serial 1 dma rec", | 491 | "synchronous serial 1 dma rec", |
488 | DMA_VERBOSE_ON_ERROR, | 492 | DMA_VERBOSE_ON_ERROR, |
@@ -493,7 +497,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) | |||
493 | printk(KERN_CRIT "Can't alloc " | 497 | printk(KERN_CRIT "Can't alloc " |
494 | "sync serial port 1 " | 498 | "sync serial port 1 " |
495 | "RX DMA channel"); | 499 | "RX DMA channel"); |
496 | return -EBUSY; | 500 | goto out; |
497 | } | 501 | } |
498 | #endif | 502 | #endif |
499 | RESET_DMA(8); WAIT_DMA(8); | 503 | RESET_DMA(8); WAIT_DMA(8); |
@@ -520,14 +524,14 @@ static int sync_serial_open(struct inode *inode, struct file *file) | |||
520 | &ports[1])) { | 524 | &ports[1])) { |
521 | printk(KERN_CRIT "Can't alloc " | 525 | printk(KERN_CRIT "Can't alloc " |
522 | "sync serial port 3 IRQ"); | 526 | "sync serial port 3 IRQ"); |
523 | return -EBUSY; | 527 | goto out; |
524 | } else if (request_irq(21, rx_interrupt, 0, | 528 | } else if (request_irq(21, rx_interrupt, 0, |
525 | "synchronous serial 3 dma rx", | 529 | "synchronous serial 3 dma rx", |
526 | &ports[1])) { | 530 | &ports[1])) { |
527 | free_irq(20, &ports[1]); | 531 | free_irq(20, &ports[1]); |
528 | printk(KERN_CRIT "Can't alloc " | 532 | printk(KERN_CRIT "Can't alloc " |
529 | "sync serial port 3 IRQ"); | 533 | "sync serial port 3 IRQ"); |
530 | return -EBUSY; | 534 | goto out; |
531 | } else if (cris_request_dma(4, | 535 | } else if (cris_request_dma(4, |
532 | "synchronous serial 3 dma tr", | 536 | "synchronous serial 3 dma tr", |
533 | DMA_VERBOSE_ON_ERROR, | 537 | DMA_VERBOSE_ON_ERROR, |
@@ -537,7 +541,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) | |||
537 | printk(KERN_CRIT "Can't alloc " | 541 | printk(KERN_CRIT "Can't alloc " |
538 | "sync serial port 3 " | 542 | "sync serial port 3 " |
539 | "TX DMA channel"); | 543 | "TX DMA channel"); |
540 | return -EBUSY; | 544 | goto out; |
541 | } else if (cris_request_dma(5, | 545 | } else if (cris_request_dma(5, |
542 | "synchronous serial 3 dma rec", | 546 | "synchronous serial 3 dma rec", |
543 | DMA_VERBOSE_ON_ERROR, | 547 | DMA_VERBOSE_ON_ERROR, |
@@ -548,7 +552,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) | |||
548 | printk(KERN_CRIT "Can't alloc " | 552 | printk(KERN_CRIT "Can't alloc " |
549 | "sync serial port 3 " | 553 | "sync serial port 3 " |
550 | "RX DMA channel"); | 554 | "RX DMA channel"); |
551 | return -EBUSY; | 555 | goto out; |
552 | } | 556 | } |
553 | #endif | 557 | #endif |
554 | RESET_DMA(4); WAIT_DMA(4); | 558 | RESET_DMA(4); WAIT_DMA(4); |
@@ -581,7 +585,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) | |||
581 | &ports[0])) { | 585 | &ports[0])) { |
582 | printk(KERN_CRIT "Can't alloc " | 586 | printk(KERN_CRIT "Can't alloc " |
583 | "sync serial manual irq"); | 587 | "sync serial manual irq"); |
584 | return -EBUSY; | 588 | goto out; |
585 | } | 589 | } |
586 | } else if (port == &ports[1]) { | 590 | } else if (port == &ports[1]) { |
587 | if (request_irq(8, | 591 | if (request_irq(8, |
@@ -591,7 +595,7 @@ static int sync_serial_open(struct inode *inode, struct file *file) | |||
591 | &ports[1])) { | 595 | &ports[1])) { |
592 | printk(KERN_CRIT "Can't alloc " | 596 | printk(KERN_CRIT "Can't alloc " |
593 | "sync serial manual irq"); | 597 | "sync serial manual irq"); |
594 | return -EBUSY; | 598 | goto out; |
595 | } | 599 | } |
596 | } | 600 | } |
597 | port->init_irqs = 0; | 601 | port->init_irqs = 0; |
@@ -620,7 +624,11 @@ static int sync_serial_open(struct inode *inode, struct file *file) | |||
620 | *R_IRQ_MASK1_SET = 1 << port->data_avail_bit; | 624 | *R_IRQ_MASK1_SET = 1 << port->data_avail_bit; |
621 | DEBUG(printk(KERN_DEBUG "sser%d rec started\n", dev)); | 625 | DEBUG(printk(KERN_DEBUG "sser%d rec started\n", dev)); |
622 | } | 626 | } |
623 | return 0; | 627 | ret = 0; |
628 | |||
629 | out: | ||
630 | unlock_kernel(); | ||
631 | return ret; | ||
624 | } | 632 | } |
625 | 633 | ||
626 | static int sync_serial_release(struct inode *inode, struct file *file) | 634 | static int sync_serial_release(struct inode *inode, struct file *file) |