diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/hotplug/cpci_hotplug_core.c | 66 |
1 files changed, 21 insertions, 45 deletions
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index 684551559d44..ed4d44e3332c 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/smp_lock.h> | 35 | #include <linux/smp_lock.h> |
36 | #include <asm/atomic.h> | 36 | #include <asm/atomic.h> |
37 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
38 | #include <linux/kthread.h> | ||
38 | #include "cpci_hotplug.h" | 39 | #include "cpci_hotplug.h" |
39 | 40 | ||
40 | #define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>" | 41 | #define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>" |
@@ -59,9 +60,8 @@ static int slots; | |||
59 | static atomic_t extracting; | 60 | static atomic_t extracting; |
60 | int cpci_debug; | 61 | int cpci_debug; |
61 | static struct cpci_hp_controller *controller; | 62 | static struct cpci_hp_controller *controller; |
62 | static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ | 63 | static struct task_struct *cpci_thread; |
63 | static struct semaphore thread_exit; /* guard ensure thread has exited before calling it quits */ | 64 | static int thread_finished; |
64 | static int thread_finished = 1; | ||
65 | 65 | ||
66 | static int enable_slot(struct hotplug_slot *slot); | 66 | static int enable_slot(struct hotplug_slot *slot); |
67 | static int disable_slot(struct hotplug_slot *slot); | 67 | static int disable_slot(struct hotplug_slot *slot); |
@@ -357,9 +357,7 @@ cpci_hp_intr(int irq, void *data) | |||
357 | controller->ops->disable_irq(); | 357 | controller->ops->disable_irq(); |
358 | 358 | ||
359 | /* Trigger processing by the event thread */ | 359 | /* Trigger processing by the event thread */ |
360 | dbg("Signal event_semaphore"); | 360 | wake_up_process(cpci_thread); |
361 | up(&event_semaphore); | ||
362 | dbg("exited cpci_hp_intr"); | ||
363 | return IRQ_HANDLED; | 361 | return IRQ_HANDLED; |
364 | } | 362 | } |
365 | 363 | ||
@@ -521,17 +519,12 @@ event_thread(void *data) | |||
521 | { | 519 | { |
522 | int rc; | 520 | int rc; |
523 | 521 | ||
524 | lock_kernel(); | ||
525 | daemonize("cpci_hp_eventd"); | ||
526 | unlock_kernel(); | ||
527 | |||
528 | dbg("%s - event thread started", __FUNCTION__); | 522 | dbg("%s - event thread started", __FUNCTION__); |
529 | while (1) { | 523 | while (1) { |
530 | dbg("event thread sleeping"); | 524 | dbg("event thread sleeping"); |
531 | down_interruptible(&event_semaphore); | 525 | set_current_state(TASK_INTERRUPTIBLE); |
532 | dbg("event thread woken, thread_finished = %d", | 526 | schedule(); |
533 | thread_finished); | 527 | if (kthread_should_stop()) |
534 | if (thread_finished || signal_pending(current)) | ||
535 | break; | 528 | break; |
536 | do { | 529 | do { |
537 | rc = check_slots(); | 530 | rc = check_slots(); |
@@ -541,18 +534,17 @@ event_thread(void *data) | |||
541 | } else if (rc < 0) { | 534 | } else if (rc < 0) { |
542 | dbg("%s - error checking slots", __FUNCTION__); | 535 | dbg("%s - error checking slots", __FUNCTION__); |
543 | thread_finished = 1; | 536 | thread_finished = 1; |
544 | break; | 537 | goto out; |
545 | } | 538 | } |
546 | } while (atomic_read(&extracting) && !thread_finished); | 539 | } while (atomic_read(&extracting) && !kthread_should_stop()); |
547 | if (thread_finished) | 540 | if (kthread_should_stop()) |
548 | break; | 541 | break; |
549 | 542 | ||
550 | /* Re-enable ENUM# interrupt */ | 543 | /* Re-enable ENUM# interrupt */ |
551 | dbg("%s - re-enabling irq", __FUNCTION__); | 544 | dbg("%s - re-enabling irq", __FUNCTION__); |
552 | controller->ops->enable_irq(); | 545 | controller->ops->enable_irq(); |
553 | } | 546 | } |
554 | dbg("%s - event thread signals exit", __FUNCTION__); | 547 | out: |
555 | up(&thread_exit); | ||
556 | return 0; | 548 | return 0; |
557 | } | 549 | } |
558 | 550 | ||
@@ -562,12 +554,8 @@ poll_thread(void *data) | |||
562 | { | 554 | { |
563 | int rc; | 555 | int rc; |
564 | 556 | ||
565 | lock_kernel(); | ||
566 | daemonize("cpci_hp_polld"); | ||
567 | unlock_kernel(); | ||
568 | |||
569 | while (1) { | 557 | while (1) { |
570 | if (thread_finished || signal_pending(current)) | 558 | if (kthread_should_stop() || signal_pending(current)) |
571 | break; | 559 | break; |
572 | if (controller->ops->query_enum()) { | 560 | if (controller->ops->query_enum()) { |
573 | do { | 561 | do { |
@@ -578,48 +566,36 @@ poll_thread(void *data) | |||
578 | } else if (rc < 0) { | 566 | } else if (rc < 0) { |
579 | dbg("%s - error checking slots", __FUNCTION__); | 567 | dbg("%s - error checking slots", __FUNCTION__); |
580 | thread_finished = 1; | 568 | thread_finished = 1; |
581 | break; | 569 | goto out; |
582 | } | 570 | } |
583 | } while (atomic_read(&extracting) && !thread_finished); | 571 | } while (atomic_read(&extracting) && !kthread_should_stop()); |
584 | } | 572 | } |
585 | msleep(100); | 573 | msleep(100); |
586 | } | 574 | } |
587 | dbg("poll thread signals exit"); | 575 | out: |
588 | up(&thread_exit); | ||
589 | return 0; | 576 | return 0; |
590 | } | 577 | } |
591 | 578 | ||
592 | static int | 579 | static int |
593 | cpci_start_thread(void) | 580 | cpci_start_thread(void) |
594 | { | 581 | { |
595 | int pid; | ||
596 | |||
597 | /* initialize our semaphores */ | ||
598 | init_MUTEX_LOCKED(&event_semaphore); | ||
599 | init_MUTEX_LOCKED(&thread_exit); | ||
600 | thread_finished = 0; | ||
601 | |||
602 | if (controller->irq) | 582 | if (controller->irq) |
603 | pid = kernel_thread(event_thread, NULL, 0); | 583 | cpci_thread = kthread_run(event_thread, NULL, "cpci_hp_eventd"); |
604 | else | 584 | else |
605 | pid = kernel_thread(poll_thread, NULL, 0); | 585 | cpci_thread = kthread_run(poll_thread, NULL, "cpci_hp_polld"); |
606 | if (pid < 0) { | 586 | if (IS_ERR(cpci_thread)) { |
607 | err("Can't start up our thread"); | 587 | err("Can't start up our thread"); |
608 | return -1; | 588 | return PTR_ERR(cpci_thread); |
609 | } | 589 | } |
610 | dbg("Our thread pid = %d", pid); | 590 | thread_finished = 0; |
611 | return 0; | 591 | return 0; |
612 | } | 592 | } |
613 | 593 | ||
614 | static void | 594 | static void |
615 | cpci_stop_thread(void) | 595 | cpci_stop_thread(void) |
616 | { | 596 | { |
597 | kthread_stop(cpci_thread); | ||
617 | thread_finished = 1; | 598 | thread_finished = 1; |
618 | dbg("thread finish command given"); | ||
619 | if (controller->irq) | ||
620 | up(&event_semaphore); | ||
621 | dbg("wait for thread to exit"); | ||
622 | down(&thread_exit); | ||
623 | } | 599 | } |
624 | 600 | ||
625 | int | 601 | int |