diff options
Diffstat (limited to 'drivers/pci/hotplug/cpqphp_ctrl.c')
-rw-r--r-- | drivers/pci/hotplug/cpqphp_ctrl.c | 74 |
1 files changed, 22 insertions, 52 deletions
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index 37d72f123a80..3ef0a4875a62 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/smp_lock.h> | 37 | #include <linux/smp_lock.h> |
38 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
39 | #include <linux/pci_hotplug.h> | 39 | #include <linux/pci_hotplug.h> |
40 | #include <linux/kthread.h> | ||
40 | #include "cpqphp.h" | 41 | #include "cpqphp.h" |
41 | 42 | ||
42 | static u32 configure_new_device(struct controller* ctrl, struct pci_func *func, | 43 | static u32 configure_new_device(struct controller* ctrl, struct pci_func *func, |
@@ -45,34 +46,20 @@ static int configure_new_function(struct controller* ctrl, struct pci_func *func | |||
45 | u8 behind_bridge, struct resource_lists *resources); | 46 | u8 behind_bridge, struct resource_lists *resources); |
46 | static void interrupt_event_handler(struct controller *ctrl); | 47 | static void interrupt_event_handler(struct controller *ctrl); |
47 | 48 | ||
48 | static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ | ||
49 | static struct semaphore event_exit; /* guard ensure thread has exited before calling it quits */ | ||
50 | static int event_finished; | ||
51 | static unsigned long pushbutton_pending; /* = 0 */ | ||
52 | 49 | ||
53 | /* things needed for the long_delay function */ | 50 | static struct task_struct *cpqhp_event_thread; |
54 | static struct semaphore delay_sem; | 51 | static unsigned long pushbutton_pending; /* = 0 */ |
55 | static wait_queue_head_t delay_wait; | ||
56 | 52 | ||
57 | /* delay is in jiffies to wait for */ | 53 | /* delay is in jiffies to wait for */ |
58 | static void long_delay(int delay) | 54 | static void long_delay(int delay) |
59 | { | 55 | { |
60 | DECLARE_WAITQUEUE(wait, current); | 56 | /* |
61 | 57 | * XXX(hch): if someone is bored please convert all callers | |
62 | /* only allow 1 customer into the delay queue at once | 58 | * to call msleep_interruptible directly. They really want |
63 | * yes this makes some people wait even longer, but who really cares? | 59 | * to specify timeouts in natural units and spend a lot of |
64 | * this is for _huge_ delays to make the hardware happy as the | 60 | * effort converting them to jiffies.. |
65 | * signals bounce around | ||
66 | */ | 61 | */ |
67 | down (&delay_sem); | ||
68 | |||
69 | init_waitqueue_head(&delay_wait); | ||
70 | |||
71 | add_wait_queue(&delay_wait, &wait); | ||
72 | msleep_interruptible(jiffies_to_msecs(delay)); | 62 | msleep_interruptible(jiffies_to_msecs(delay)); |
73 | remove_wait_queue(&delay_wait, &wait); | ||
74 | |||
75 | up(&delay_sem); | ||
76 | } | 63 | } |
77 | 64 | ||
78 | 65 | ||
@@ -955,8 +942,8 @@ irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data) | |||
955 | } | 942 | } |
956 | 943 | ||
957 | if (schedule_flag) { | 944 | if (schedule_flag) { |
958 | up(&event_semaphore); | 945 | wake_up_process(cpqhp_event_thread); |
959 | dbg("Signal event_semaphore\n"); | 946 | dbg("Waking even thread"); |
960 | } | 947 | } |
961 | return IRQ_HANDLED; | 948 | return IRQ_HANDLED; |
962 | } | 949 | } |
@@ -973,16 +960,13 @@ struct pci_func *cpqhp_slot_create(u8 busnumber) | |||
973 | struct pci_func *new_slot; | 960 | struct pci_func *new_slot; |
974 | struct pci_func *next; | 961 | struct pci_func *next; |
975 | 962 | ||
976 | new_slot = kmalloc(sizeof(*new_slot), GFP_KERNEL); | 963 | new_slot = kzalloc(sizeof(*new_slot), GFP_KERNEL); |
977 | |||
978 | if (new_slot == NULL) { | 964 | if (new_slot == NULL) { |
979 | /* I'm not dead yet! | 965 | /* I'm not dead yet! |
980 | * You will be. */ | 966 | * You will be. */ |
981 | return new_slot; | 967 | return new_slot; |
982 | } | 968 | } |
983 | 969 | ||
984 | memset(new_slot, 0, sizeof(struct pci_func)); | ||
985 | |||
986 | new_slot->next = NULL; | 970 | new_slot->next = NULL; |
987 | new_slot->configured = 1; | 971 | new_slot->configured = 1; |
988 | 972 | ||
@@ -1738,7 +1722,7 @@ static u32 remove_board(struct pci_func * func, u32 replace_flag, struct control | |||
1738 | static void pushbutton_helper_thread(unsigned long data) | 1722 | static void pushbutton_helper_thread(unsigned long data) |
1739 | { | 1723 | { |
1740 | pushbutton_pending = data; | 1724 | pushbutton_pending = data; |
1741 | up(&event_semaphore); | 1725 | wake_up_process(cpqhp_event_thread); |
1742 | } | 1726 | } |
1743 | 1727 | ||
1744 | 1728 | ||
@@ -1747,13 +1731,13 @@ static int event_thread(void* data) | |||
1747 | { | 1731 | { |
1748 | struct controller *ctrl; | 1732 | struct controller *ctrl; |
1749 | 1733 | ||
1750 | daemonize("phpd_event"); | ||
1751 | |||
1752 | while (1) { | 1734 | while (1) { |
1753 | dbg("!!!!event_thread sleeping\n"); | 1735 | dbg("!!!!event_thread sleeping\n"); |
1754 | down_interruptible (&event_semaphore); | 1736 | set_current_state(TASK_INTERRUPTIBLE); |
1755 | dbg("event_thread woken finished = %d\n", event_finished); | 1737 | schedule(); |
1756 | if (event_finished) break; | 1738 | |
1739 | if (kthread_should_stop()) | ||
1740 | break; | ||
1757 | /* Do stuff here */ | 1741 | /* Do stuff here */ |
1758 | if (pushbutton_pending) | 1742 | if (pushbutton_pending) |
1759 | cpqhp_pushbutton_thread(pushbutton_pending); | 1743 | cpqhp_pushbutton_thread(pushbutton_pending); |
@@ -1762,38 +1746,24 @@ static int event_thread(void* data) | |||
1762 | interrupt_event_handler(ctrl); | 1746 | interrupt_event_handler(ctrl); |
1763 | } | 1747 | } |
1764 | dbg("event_thread signals exit\n"); | 1748 | dbg("event_thread signals exit\n"); |
1765 | up(&event_exit); | ||
1766 | return 0; | 1749 | return 0; |
1767 | } | 1750 | } |
1768 | 1751 | ||
1769 | |||
1770 | int cpqhp_event_start_thread(void) | 1752 | int cpqhp_event_start_thread(void) |
1771 | { | 1753 | { |
1772 | int pid; | 1754 | cpqhp_event_thread = kthread_run(event_thread, NULL, "phpd_event"); |
1773 | 1755 | if (IS_ERR(cpqhp_event_thread)) { | |
1774 | /* initialize our semaphores */ | ||
1775 | init_MUTEX(&delay_sem); | ||
1776 | init_MUTEX_LOCKED(&event_semaphore); | ||
1777 | init_MUTEX_LOCKED(&event_exit); | ||
1778 | event_finished=0; | ||
1779 | |||
1780 | pid = kernel_thread(event_thread, NULL, 0); | ||
1781 | if (pid < 0) { | ||
1782 | err ("Can't start up our event thread\n"); | 1756 | err ("Can't start up our event thread\n"); |
1783 | return -1; | 1757 | return PTR_ERR(cpqhp_event_thread); |
1784 | } | 1758 | } |
1785 | dbg("Our event thread pid = %d\n", pid); | 1759 | |
1786 | return 0; | 1760 | return 0; |
1787 | } | 1761 | } |
1788 | 1762 | ||
1789 | 1763 | ||
1790 | void cpqhp_event_stop_thread(void) | 1764 | void cpqhp_event_stop_thread(void) |
1791 | { | 1765 | { |
1792 | event_finished = 1; | 1766 | kthread_stop(cpqhp_event_thread); |
1793 | dbg("event_thread finish command given\n"); | ||
1794 | up(&event_semaphore); | ||
1795 | dbg("wait for event_thread to exit\n"); | ||
1796 | down(&event_exit); | ||
1797 | } | 1767 | } |
1798 | 1768 | ||
1799 | 1769 | ||