aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/hotplug/pciehp.h16
-rw-r--r--drivers/pci/hotplug/pciehp_core.c44
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c616
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c34
4 files changed, 321 insertions, 389 deletions
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index d19fcae8a7c..c98e27128cc 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -43,6 +43,7 @@ extern int pciehp_poll_mode;
43extern int pciehp_poll_time; 43extern int pciehp_poll_time;
44extern int pciehp_debug; 44extern int pciehp_debug;
45extern int pciehp_force; 45extern int pciehp_force;
46extern struct workqueue_struct *pciehp_wq;
46 47
47#define dbg(format, arg...) \ 48#define dbg(format, arg...) \
48 do { \ 49 do { \
@@ -70,14 +71,16 @@ struct slot {
70 struct list_head slot_list; 71 struct list_head slot_list;
71 char name[SLOT_NAME_SIZE]; 72 char name[SLOT_NAME_SIZE];
72 unsigned long last_emi_toggle; 73 unsigned long last_emi_toggle;
74 struct delayed_work work; /* work for button event */
75 struct mutex lock;
73}; 76};
74 77
75struct event_info { 78struct event_info {
76 u32 event_type; 79 u32 event_type;
77 u8 hp_slot; 80 struct slot *p_slot;
81 struct work_struct work;
78}; 82};
79 83
80#define MAX_EVENTS 10
81struct controller { 84struct controller {
82 struct controller *next; 85 struct controller *next;
83 struct mutex crit_sect; /* critical section mutex */ 86 struct mutex crit_sect; /* critical section mutex */
@@ -86,11 +89,9 @@ struct controller {
86 int slot_num_inc; /* 1 or -1 */ 89 int slot_num_inc; /* 1 or -1 */
87 struct pci_dev *pci_dev; 90 struct pci_dev *pci_dev;
88 struct list_head slot_list; 91 struct list_head slot_list;
89 struct event_info event_queue[MAX_EVENTS];
90 struct slot *slot; 92 struct slot *slot;
91 struct hpc_ops *hpc_ops; 93 struct hpc_ops *hpc_ops;
92 wait_queue_head_t queue; /* sleep & wake process */ 94 wait_queue_head_t queue; /* sleep & wake process */
93 u8 next_event;
94 u8 bus; 95 u8 bus;
95 u8 device; 96 u8 device;
96 u8 function; 97 u8 function;
@@ -149,16 +150,15 @@ struct controller {
149#define HP_SUPR_RM(cap) (cap & HP_SUPR_RM_SUP) 150#define HP_SUPR_RM(cap) (cap & HP_SUPR_RM_SUP)
150#define EMI(cap) (cap & EMI_PRSN) 151#define EMI(cap) (cap & EMI_PRSN)
151 152
152extern int pciehp_event_start_thread(void); 153extern int pciehp_sysfs_enable_slot(struct slot *slot);
153extern void pciehp_event_stop_thread(void); 154extern int pciehp_sysfs_disable_slot(struct slot *slot);
154extern int pciehp_enable_slot(struct slot *slot);
155extern int pciehp_disable_slot(struct slot *slot);
156extern u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl); 155extern u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl);
157extern u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl); 156extern u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl);
158extern u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl); 157extern u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl);
159extern u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl); 158extern u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl);
160extern int pciehp_configure_device(struct slot *p_slot); 159extern int pciehp_configure_device(struct slot *p_slot);
161extern int pciehp_unconfigure_device(struct slot *p_slot); 160extern int pciehp_unconfigure_device(struct slot *p_slot);
161extern void queue_pushbutton_work(struct work_struct *work);
162int pcie_init(struct controller *ctrl, struct pcie_device *dev); 162int pcie_init(struct controller *ctrl, struct pcie_device *dev);
163 163
164/* Global variables */ 164/* Global variables */
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index a92eda6e02f..749227ecdb0 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -41,6 +41,7 @@ int pciehp_debug;
41int pciehp_poll_mode; 41int pciehp_poll_mode;
42int pciehp_poll_time; 42int pciehp_poll_time;
43int pciehp_force; 43int pciehp_force;
44struct workqueue_struct *pciehp_wq;
44struct controller *pciehp_ctrl_list; 45struct controller *pciehp_ctrl_list;
45 46
46#define DRIVER_VERSION "0.4" 47#define DRIVER_VERSION "0.4"
@@ -62,7 +63,6 @@ MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing"
62 63
63#define PCIE_MODULE_NAME "pciehp" 64#define PCIE_MODULE_NAME "pciehp"
64 65
65static int pcie_start_thread (void);
66static int set_attention_status (struct hotplug_slot *slot, u8 value); 66static int set_attention_status (struct hotplug_slot *slot, u8 value);
67static int enable_slot (struct hotplug_slot *slot); 67static int enable_slot (struct hotplug_slot *slot);
68static int disable_slot (struct hotplug_slot *slot); 68static int disable_slot (struct hotplug_slot *slot);
@@ -229,6 +229,8 @@ static int init_slots(struct controller *ctrl)
229 slot->device = ctrl->slot_device_offset + i; 229 slot->device = ctrl->slot_device_offset + i;
230 slot->hpc_ops = ctrl->hpc_ops; 230 slot->hpc_ops = ctrl->hpc_ops;
231 slot->number = ctrl->first_slot; 231 slot->number = ctrl->first_slot;
232 mutex_init(&slot->lock);
233 INIT_DELAYED_WORK(&slot->work, queue_pushbutton_work);
232 234
233 /* register this slot with the hotplug pci core */ 235 /* register this slot with the hotplug pci core */
234 hotplug_slot->private = slot; 236 hotplug_slot->private = slot;
@@ -286,6 +288,9 @@ static void cleanup_slots(struct controller *ctrl)
286 if (EMI(ctrl->ctrlcap)) 288 if (EMI(ctrl->ctrlcap))
287 sysfs_remove_file(&slot->hotplug_slot->kobj, 289 sysfs_remove_file(&slot->hotplug_slot->kobj,
288 &hotplug_slot_attr_lock.attr); 290 &hotplug_slot_attr_lock.attr);
291 cancel_delayed_work(&slot->work);
292 flush_scheduled_work();
293 flush_workqueue(pciehp_wq);
289 pci_hp_deregister(slot->hotplug_slot); 294 pci_hp_deregister(slot->hotplug_slot);
290 } 295 }
291} 296}
@@ -314,7 +319,7 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
314 319
315 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); 320 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
316 321
317 return pciehp_enable_slot(slot); 322 return pciehp_sysfs_enable_slot(slot);
318} 323}
319 324
320 325
@@ -324,7 +329,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
324 329
325 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); 330 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
326 331
327 return pciehp_disable_slot(slot); 332 return pciehp_sysfs_disable_slot(slot);
328} 333}
329 334
330static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) 335static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
@@ -466,9 +471,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
466 471
467 t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); 472 t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset);
468 473
469 /* Finish setting up the hot plug ctrl device */
470 ctrl->next_event = 0;
471
472 if (!pciehp_ctrl_list) { 474 if (!pciehp_ctrl_list) {
473 pciehp_ctrl_list = ctrl; 475 pciehp_ctrl_list = ctrl;
474 ctrl->next = NULL; 476 ctrl->next = NULL;
@@ -496,22 +498,6 @@ err_out_none:
496 return -ENODEV; 498 return -ENODEV;
497} 499}
498 500
499
500static int pcie_start_thread(void)
501{
502 int retval = 0;
503
504 dbg("Initialize + Start the notification/polling mechanism \n");
505
506 retval = pciehp_event_start_thread();
507 if (retval) {
508 dbg("pciehp_event_start_thread() failed\n");
509 return retval;
510 }
511
512 return retval;
513}
514
515static void __exit unload_pciehpd(void) 501static void __exit unload_pciehpd(void)
516{ 502{
517 struct controller *ctrl; 503 struct controller *ctrl;
@@ -529,10 +515,6 @@ static void __exit unload_pciehpd(void)
529 515
530 kfree(tctrl); 516 kfree(tctrl);
531 } 517 }
532
533 /* Stop the notification mechanism */
534 pciehp_event_stop_thread();
535
536} 518}
537 519
538static void pciehp_remove (struct pcie_device *device) 520static void pciehp_remove (struct pcie_device *device)
@@ -585,21 +567,11 @@ static int __init pcied_init(void)
585 pciehp_poll_mode = 1; 567 pciehp_poll_mode = 1;
586#endif 568#endif
587 569
588 retval = pcie_start_thread();
589 if (retval)
590 goto error_hpc_init;
591
592 retval = pcie_port_service_register(&hpdriver_portdrv); 570 retval = pcie_port_service_register(&hpdriver_portdrv);
593 dbg("pcie_port_service_register = %d\n", retval); 571 dbg("pcie_port_service_register = %d\n", retval);
594 info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); 572 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
595 if (retval) 573 if (retval)
596 dbg("%s: Failure to register service\n", __FUNCTION__); 574 dbg("%s: Failure to register service\n", __FUNCTION__);
597
598error_hpc_init:
599 if (retval) {
600 pciehp_event_stop_thread();
601 };
602
603 return retval; 575 return retval;
604} 576}
605 577
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 4283ef56dbd..91441e5ae63 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -32,92 +32,61 @@
32#include <linux/types.h> 32#include <linux/types.h>
33#include <linux/smp_lock.h> 33#include <linux/smp_lock.h>
34#include <linux/pci.h> 34#include <linux/pci.h>
35#include <linux/workqueue.h>
35#include "../pci.h" 36#include "../pci.h"
36#include "pciehp.h" 37#include "pciehp.h"
37 38
38static void interrupt_event_handler(struct controller *ctrl); 39static void interrupt_event_handler(struct work_struct *work);
40static int pciehp_enable_slot(struct slot *p_slot);
41static int pciehp_disable_slot(struct slot *p_slot);
39 42
40static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ 43static int queue_interrupt_event(struct slot *p_slot, u32 event_type)
41static struct semaphore event_exit; /* guard ensure thread has exited before calling it quits */
42static int event_finished;
43static unsigned long pushbutton_pending; /* = 0 */
44static unsigned long surprise_rm_pending; /* = 0 */
45
46static inline char *slot_name(struct slot *p_slot)
47{ 44{
48 return p_slot->hotplug_slot->name; 45 struct event_info *info;
46
47 info = kmalloc(sizeof(*info), GFP_ATOMIC);
48 if (!info)
49 return -ENOMEM;
50
51 info->event_type = event_type;
52 info->p_slot = p_slot;
53 INIT_WORK(&info->work, interrupt_event_handler);
54
55 schedule_work(&info->work);
56
57 return 0;
49} 58}
50 59
51u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl) 60u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl)
52{ 61{
53 struct slot *p_slot; 62 struct slot *p_slot;
54 u8 rc = 0; 63 u32 event_type;
55 u8 getstatus;
56 struct event_info *taskInfo;
57 64
58 /* Attention Button Change */ 65 /* Attention Button Change */
59 dbg("pciehp: Attention button interrupt received.\n"); 66 dbg("pciehp: Attention button interrupt received.\n");
60
61 /* This is the structure that tells the worker thread what to do */
62 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
63 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
64
65 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
66
67 ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS;
68 taskInfo->hp_slot = hp_slot;
69 67
70 rc++; 68 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
71 69
72 /* 70 /*
73 * Button pressed - See if need to TAKE ACTION!!! 71 * Button pressed - See if need to TAKE ACTION!!!
74 */ 72 */
75 info("Button pressed on Slot(%s)\n", slot_name(p_slot)); 73 info("Button pressed on Slot(%s)\n", p_slot->name);
76 taskInfo->event_type = INT_BUTTON_PRESS; 74 event_type = INT_BUTTON_PRESS;
77
78 if ((p_slot->state == BLINKINGON_STATE)
79 || (p_slot->state == BLINKINGOFF_STATE)) {
80 /* Cancel if we are still blinking; this means that we press the
81 * attention again before the 5 sec. limit expires to cancel hot-add
82 * or hot-remove
83 */
84 taskInfo->event_type = INT_BUTTON_CANCEL;
85 info("Button cancel on Slot(%s)\n", slot_name(p_slot));
86 } else if ((p_slot->state == POWERON_STATE)
87 || (p_slot->state == POWEROFF_STATE)) {
88 /* Ignore if the slot is on power-on or power-off state; this
89 * means that the previous attention button action to hot-add or
90 * hot-remove is undergoing
91 */
92 taskInfo->event_type = INT_BUTTON_IGNORE;
93 info("Button ignore on Slot(%s)\n", slot_name(p_slot));
94 }
95 75
96 if (rc) 76 queue_interrupt_event(p_slot, event_type);
97 up(&event_semaphore); /* signal event thread that new event is posted */
98 77
99 return 0; 78 return 0;
100
101} 79}
102 80
103u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl) 81u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl)
104{ 82{
105 struct slot *p_slot; 83 struct slot *p_slot;
106 u8 rc = 0;
107 u8 getstatus; 84 u8 getstatus;
108 struct event_info *taskInfo; 85 u32 event_type;
109 86
110 /* Switch Change */ 87 /* Switch Change */
111 dbg("pciehp: Switch interrupt received.\n"); 88 dbg("pciehp: Switch interrupt received.\n");
112 89
113 /* This is the structure that tells the worker thread
114 * what to do
115 */
116 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
117 ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS;
118 taskInfo->hp_slot = hp_slot;
119
120 rc++;
121 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); 90 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
122 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 91 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
123 92
@@ -125,39 +94,30 @@ u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl)
125 /* 94 /*
126 * Switch opened 95 * Switch opened
127 */ 96 */
128 info("Latch open on Slot(%s)\n", slot_name(p_slot)); 97 info("Latch open on Slot(%s)\n", p_slot->name);
129 taskInfo->event_type = INT_SWITCH_OPEN; 98 event_type = INT_SWITCH_OPEN;
130 } else { 99 } else {
131 /* 100 /*
132 * Switch closed 101 * Switch closed
133 */ 102 */
134 info("Latch close on Slot(%s)\n", slot_name(p_slot)); 103 info("Latch close on Slot(%s)\n", p_slot->name);
135 taskInfo->event_type = INT_SWITCH_CLOSE; 104 event_type = INT_SWITCH_CLOSE;
136 } 105 }
137 106
138 if (rc) 107 queue_interrupt_event(p_slot, event_type);
139 up(&event_semaphore); /* signal event thread that new event is posted */
140 108
141 return rc; 109 return 1;
142} 110}
143 111
144u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl) 112u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl)
145{ 113{
146 struct slot *p_slot; 114 struct slot *p_slot;
147 u8 presence_save, rc = 0; 115 u32 event_type;
148 struct event_info *taskInfo; 116 u8 presence_save;
149 117
150 /* Presence Change */ 118 /* Presence Change */
151 dbg("pciehp: Presence/Notify input change.\n"); 119 dbg("pciehp: Presence/Notify input change.\n");
152 120
153 /* This is the structure that tells the worker thread
154 * what to do
155 */
156 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
157 ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS;
158 taskInfo->hp_slot = hp_slot;
159
160 rc++;
161 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); 121 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
162 122
163 /* Switch is open, assume a presence change 123 /* Switch is open, assume a presence change
@@ -168,59 +128,49 @@ u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl)
168 /* 128 /*
169 * Card Present 129 * Card Present
170 */ 130 */
171 info("Card present on Slot(%s)\n", slot_name(p_slot)); 131 info("Card present on Slot(%s)\n", p_slot->name);
172 taskInfo->event_type = INT_PRESENCE_ON; 132 event_type = INT_PRESENCE_ON;
173 } else { 133 } else {
174 /* 134 /*
175 * Not Present 135 * Not Present
176 */ 136 */
177 info("Card not present on Slot(%s)\n", slot_name(p_slot)); 137 info("Card not present on Slot(%s)\n", p_slot->name);
178 taskInfo->event_type = INT_PRESENCE_OFF; 138 event_type = INT_PRESENCE_OFF;
179 } 139 }
180 140
181 if (rc) 141 queue_interrupt_event(p_slot, event_type);
182 up(&event_semaphore); /* signal event thread that new event is posted */
183 142
184 return rc; 143 return 1;
185} 144}
186 145
187u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl) 146u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl)
188{ 147{
189 struct slot *p_slot; 148 struct slot *p_slot;
190 u8 rc = 0; 149 u32 event_type;
191 struct event_info *taskInfo;
192 150
193 /* power fault */ 151 /* power fault */
194 dbg("pciehp: Power fault interrupt received.\n"); 152 dbg("pciehp: Power fault interrupt received.\n");
195 153
196 /* this is the structure that tells the worker thread
197 * what to do
198 */
199 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
200 ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS;
201 taskInfo->hp_slot = hp_slot;
202
203 rc++;
204 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); 154 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
205 155
206 if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) { 156 if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) {
207 /* 157 /*
208 * power fault Cleared 158 * power fault Cleared
209 */ 159 */
210 info("Power fault cleared on Slot(%s)\n", slot_name(p_slot)); 160 info("Power fault cleared on Slot(%s)\n", p_slot->name);
211 taskInfo->event_type = INT_POWER_FAULT_CLEAR; 161 event_type = INT_POWER_FAULT_CLEAR;
212 } else { 162 } else {
213 /* 163 /*
214 * power fault 164 * power fault
215 */ 165 */
216 info("Power fault on Slot(%s)\n", slot_name(p_slot)); 166 info("Power fault on Slot(%s)\n", p_slot->name);
217 taskInfo->event_type = INT_POWER_FAULT; 167 event_type = INT_POWER_FAULT;
218 info("power fault bit %x set\n", hp_slot); 168 info("power fault bit %x set\n", hp_slot);
219 } 169 }
220 if (rc)
221 up(&event_semaphore); /* signal event thread that new event is posted */
222 170
223 return rc; 171 queue_interrupt_event(p_slot, event_type);
172
173 return 1;
224} 174}
225 175
226/* The following routines constitute the bulk of the 176/* The following routines constitute the bulk of the
@@ -357,13 +307,10 @@ static int remove_board(struct slot *p_slot)
357 return 0; 307 return 0;
358} 308}
359 309
360 310struct power_work_info {
361static void pushbutton_helper_thread(unsigned long data) 311 struct slot *p_slot;
362{ 312 struct work_struct work;
363 pushbutton_pending = data; 313};
364
365 up(&event_semaphore);
366}
367 314
368/** 315/**
369 * pciehp_pushbutton_thread 316 * pciehp_pushbutton_thread
@@ -372,276 +319,214 @@ static void pushbutton_helper_thread(unsigned long data)
372 * Handles all pending events and exits. 319 * Handles all pending events and exits.
373 * 320 *
374 */ 321 */
375static void pciehp_pushbutton_thread(unsigned long slot) 322static void pciehp_power_thread(struct work_struct *work)
376{ 323{
377 struct slot *p_slot = (struct slot *) slot; 324 struct power_work_info *info =
378 u8 getstatus; 325 container_of(work, struct power_work_info, work);
379 326 struct slot *p_slot = info->p_slot;
380 pushbutton_pending = 0; 327
381 328 mutex_lock(&p_slot->lock);
382 if (!p_slot) { 329 switch (p_slot->state) {
383 dbg("%s: Error! slot NULL\n", __FUNCTION__); 330 case POWEROFF_STATE:
384 return; 331 mutex_unlock(&p_slot->lock);
385 } 332 dbg("%s: disabling bus:device(%x:%x)\n",
386 333 __FUNCTION__, p_slot->bus, p_slot->device);
387 p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
388 if (getstatus) {
389 p_slot->state = POWEROFF_STATE;
390 dbg("%s: disabling bus:device(%x:%x)\n", __FUNCTION__,
391 p_slot->bus, p_slot->device);
392
393 pciehp_disable_slot(p_slot); 334 pciehp_disable_slot(p_slot);
335 mutex_lock(&p_slot->lock);
394 p_slot->state = STATIC_STATE; 336 p_slot->state = STATIC_STATE;
395 } else { 337 break;
396 p_slot->state = POWERON_STATE; 338 case POWERON_STATE:
397 dbg("%s: adding bus:device(%x:%x)\n", __FUNCTION__, 339 mutex_unlock(&p_slot->lock);
398 p_slot->bus, p_slot->device);
399
400 if (pciehp_enable_slot(p_slot) && 340 if (pciehp_enable_slot(p_slot) &&
401 PWR_LED(p_slot->ctrl->ctrlcap)) 341 PWR_LED(p_slot->ctrl->ctrlcap))
402 p_slot->hpc_ops->green_led_off(p_slot); 342 p_slot->hpc_ops->green_led_off(p_slot);
403 343 mutex_lock(&p_slot->lock);
404 p_slot->state = STATIC_STATE; 344 p_slot->state = STATIC_STATE;
345 break;
346 default:
347 break;
405 } 348 }
349 mutex_unlock(&p_slot->lock);
406 350
407 return; 351 kfree(info);
408} 352}
409 353
410/** 354void queue_pushbutton_work(struct work_struct *work)
411 * pciehp_surprise_rm_thread
412 *
413 * Scheduled procedure to handle blocking stuff for the surprise removal
414 * Handles all pending events and exits.
415 *
416 */
417static void pciehp_surprise_rm_thread(unsigned long slot)
418{ 355{
419 struct slot *p_slot = (struct slot *) slot; 356 struct slot *p_slot = container_of(work, struct slot, work.work);
420 u8 getstatus; 357 struct power_work_info *info;
421
422 surprise_rm_pending = 0;
423 358
424 if (!p_slot) { 359 info = kmalloc(sizeof(*info), GFP_KERNEL);
425 dbg("%s: Error! slot NULL\n", __FUNCTION__); 360 if (!info) {
361 err("%s: Cannot allocate memory\n", __FUNCTION__);
426 return; 362 return;
427 } 363 }
364 info->p_slot = p_slot;
365 INIT_WORK(&info->work, pciehp_power_thread);
428 366
429 p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); 367 mutex_lock(&p_slot->lock);
430 if (!getstatus) { 368 switch (p_slot->state) {
369 case BLINKINGOFF_STATE:
431 p_slot->state = POWEROFF_STATE; 370 p_slot->state = POWEROFF_STATE;
432 dbg("%s: removing bus:device(%x:%x)\n", 371 break;
433 __FUNCTION__, p_slot->bus, p_slot->device); 372 case BLINKINGON_STATE:
434
435 pciehp_disable_slot(p_slot);
436 p_slot->state = STATIC_STATE;
437 } else {
438 p_slot->state = POWERON_STATE; 373 p_slot->state = POWERON_STATE;
439 dbg("%s: adding bus:device(%x:%x)\n", 374 break;
440 __FUNCTION__, p_slot->bus, p_slot->device); 375 default:
441 376 goto out;
442 if (pciehp_enable_slot(p_slot) &&
443 PWR_LED(p_slot->ctrl->ctrlcap))
444 p_slot->hpc_ops->green_led_off(p_slot);
445
446 p_slot->state = STATIC_STATE;
447 } 377 }
448 378 queue_work(pciehp_wq, &info->work);
449 return; 379 out:
380 mutex_unlock(&p_slot->lock);
450} 381}
451 382
452
453
454/* this is the main worker thread */
455static int event_thread(void* data)
456{
457 struct controller *ctrl;
458 lock_kernel();
459 daemonize("pciehpd_event");
460
461 unlock_kernel();
462
463 while (1) {
464 dbg("!!!!event_thread sleeping\n");
465 down_interruptible (&event_semaphore);
466 dbg("event_thread woken finished = %d\n", event_finished);
467 if (event_finished || signal_pending(current))
468 break;
469 /* Do stuff here */
470 if (pushbutton_pending)
471 pciehp_pushbutton_thread(pushbutton_pending);
472 else if (surprise_rm_pending)
473 pciehp_surprise_rm_thread(surprise_rm_pending);
474 else
475 for (ctrl = pciehp_ctrl_list; ctrl; ctrl=ctrl->next)
476 interrupt_event_handler(ctrl);
477 }
478 dbg("event_thread signals exit\n");
479 up(&event_exit);
480 return 0;
481}
482
483int pciehp_event_start_thread(void)
484{
485 int pid;
486
487 /* initialize our semaphores */
488 init_MUTEX_LOCKED(&event_exit);
489 event_finished=0;
490
491 init_MUTEX_LOCKED(&event_semaphore);
492 pid = kernel_thread(event_thread, NULL, 0);
493
494 if (pid < 0) {
495 err ("Can't start up our event thread\n");
496 return -1;
497 }
498 return 0;
499}
500
501
502void pciehp_event_stop_thread(void)
503{
504 event_finished = 1;
505 up(&event_semaphore);
506 down(&event_exit);
507}
508
509
510static int update_slot_info(struct slot *slot) 383static int update_slot_info(struct slot *slot)
511{ 384{
512 struct hotplug_slot_info *info; 385 struct hotplug_slot_info *info;
513 /* char buffer[SLOT_NAME_SIZE]; */
514 int result; 386 int result;
515 387
516 info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL); 388 info = kmalloc(sizeof(*info), GFP_KERNEL);
517 if (!info) 389 if (!info)
518 return -ENOMEM; 390 return -ENOMEM;
519 391
520 /* make_slot_name (&buffer[0], SLOT_NAME_SIZE, slot); */
521
522 slot->hpc_ops->get_power_status(slot, &(info->power_status)); 392 slot->hpc_ops->get_power_status(slot, &(info->power_status));
523 slot->hpc_ops->get_attention_status(slot, &(info->attention_status)); 393 slot->hpc_ops->get_attention_status(slot, &(info->attention_status));
524 slot->hpc_ops->get_latch_status(slot, &(info->latch_status)); 394 slot->hpc_ops->get_latch_status(slot, &(info->latch_status));
525 slot->hpc_ops->get_adapter_status(slot, &(info->adapter_status)); 395 slot->hpc_ops->get_adapter_status(slot, &(info->adapter_status));
526 396
527 /* result = pci_hp_change_slot_info(buffer, info); */
528 result = pci_hp_change_slot_info(slot->hotplug_slot, info); 397 result = pci_hp_change_slot_info(slot->hotplug_slot, info);
529 kfree (info); 398 kfree (info);
530 return result; 399 return result;
531} 400}
532 401
533static void interrupt_event_handler(struct controller *ctrl) 402/*
403 * Note: This function must be called with slot->lock held
404 */
405static void handle_button_press_event(struct slot *p_slot)
534{ 406{
535 int loop = 0; 407 struct controller *ctrl = p_slot->ctrl;
536 int change = 1;
537 u8 hp_slot;
538 u8 getstatus; 408 u8 getstatus;
539 struct slot *p_slot;
540 409
541 while (change) { 410 switch (p_slot->state) {
542 change = 0; 411 case STATIC_STATE:
543 412 p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
544 for (loop = 0; loop < MAX_EVENTS; loop++) { 413 if (getstatus) {
545 if (ctrl->event_queue[loop].event_type != 0) { 414 p_slot->state = BLINKINGOFF_STATE;
546 hp_slot = ctrl->event_queue[loop].hp_slot; 415 info("PCI slot #%s - powering off due to button "
547 416 "press.\n", p_slot->name);
548 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); 417 } else {
549 418 p_slot->state = BLINKINGON_STATE;
550 if (ctrl->event_queue[loop].event_type == INT_BUTTON_CANCEL) { 419 info("PCI slot #%s - powering on due to button "
551 dbg("button cancel\n"); 420 "press.\n", p_slot->name);
552 del_timer(&p_slot->task_event); 421 }
553 422 /* blink green LED and turn off amber */
554 switch (p_slot->state) { 423 if (PWR_LED(ctrl->ctrlcap))
555 case BLINKINGOFF_STATE: 424 p_slot->hpc_ops->green_led_blink(p_slot);
556 if (PWR_LED(ctrl->ctrlcap)) 425 if (ATTN_LED(ctrl->ctrlcap))
557 p_slot->hpc_ops->green_led_on(p_slot); 426 p_slot->hpc_ops->set_attention_status(p_slot, 0);
558 427
559 if (ATTN_LED(ctrl->ctrlcap)) 428 schedule_delayed_work(&p_slot->work, 5*HZ);
560 p_slot->hpc_ops->set_attention_status(p_slot, 0); 429 break;
561 break; 430 case BLINKINGOFF_STATE:
562 case BLINKINGON_STATE: 431 case BLINKINGON_STATE:
563 if (PWR_LED(ctrl->ctrlcap)) 432 /*
564 p_slot->hpc_ops->green_led_off(p_slot); 433 * Cancel if we are still blinking; this means that we
565 434 * press the attention again before the 5 sec. limit
566 if (ATTN_LED(ctrl->ctrlcap)) 435 * expires to cancel hot-add or hot-remove
567 p_slot->hpc_ops->set_attention_status(p_slot, 0); 436 */
568 break; 437 info("Button cancel on Slot(%s)\n", p_slot->name);
569 default: 438 dbg("%s: button cancel\n", __FUNCTION__);
570 warn("Not a valid state\n"); 439 cancel_delayed_work(&p_slot->work);
571 return; 440 if (p_slot->state == BLINKINGOFF_STATE) {
572 } 441 if (PWR_LED(ctrl->ctrlcap))
573 info("PCI slot #%s - action canceled due to button press.\n", slot_name(p_slot)); 442 p_slot->hpc_ops->green_led_on(p_slot);
574 p_slot->state = STATIC_STATE; 443 } else {
575 } 444 if (PWR_LED(ctrl->ctrlcap))
576 /* ***********Button Pressed (No action on 1st press...) */ 445 p_slot->hpc_ops->green_led_off(p_slot);
577 else if (ctrl->event_queue[loop].event_type == INT_BUTTON_PRESS) { 446 }
578 447 if (ATTN_LED(ctrl->ctrlcap))
579 if (ATTN_BUTTN(ctrl->ctrlcap)) { 448 p_slot->hpc_ops->set_attention_status(p_slot, 0);
580 dbg("Button pressed\n"); 449 info("PCI slot #%s - action canceled due to button press\n",
581 p_slot->hpc_ops->get_power_status(p_slot, &getstatus); 450 p_slot->name);
582 if (getstatus) { 451 p_slot->state = STATIC_STATE;
583 /* slot is on */ 452 break;
584 dbg("slot is on\n"); 453 case POWEROFF_STATE:
585 p_slot->state = BLINKINGOFF_STATE; 454 case POWERON_STATE:
586 info("PCI slot #%s - powering off due to button press.\n", slot_name(p_slot)); 455 /*
587 } else { 456 * Ignore if the slot is on power-on or power-off state;
588 /* slot is off */ 457 * this means that the previous attention button action
589 dbg("slot is off\n"); 458 * to hot-add or hot-remove is undergoing
590 p_slot->state = BLINKINGON_STATE; 459 */
591 info("PCI slot #%s - powering on due to button press.\n", slot_name(p_slot)); 460 info("Button ignore on Slot(%s)\n", p_slot->name);
592 } 461 update_slot_info(p_slot);
593 462 break;
594 /* blink green LED and turn off amber */ 463 default:
595 if (PWR_LED(ctrl->ctrlcap)) 464 warn("Not a valid state\n");
596 p_slot->hpc_ops->green_led_blink(p_slot); 465 break;
597
598 if (ATTN_LED(ctrl->ctrlcap))
599 p_slot->hpc_ops->set_attention_status(p_slot, 0);
600
601 init_timer(&p_slot->task_event);
602 p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */
603 p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread;
604 p_slot->task_event.data = (unsigned long) p_slot;
605
606 add_timer(&p_slot->task_event);
607 }
608 }
609 /***********POWER FAULT********************/
610 else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
611 if (POWER_CTRL(ctrl->ctrlcap)) {
612 dbg("power fault\n");
613 if (ATTN_LED(ctrl->ctrlcap))
614 p_slot->hpc_ops->set_attention_status(p_slot, 1);
615
616 if (PWR_LED(ctrl->ctrlcap))
617 p_slot->hpc_ops->green_led_off(p_slot);
618 }
619 }
620 /***********SURPRISE REMOVAL********************/
621 else if ((ctrl->event_queue[loop].event_type == INT_PRESENCE_ON) ||
622 (ctrl->event_queue[loop].event_type == INT_PRESENCE_OFF)) {
623 if (HP_SUPR_RM(ctrl->ctrlcap)) {
624 dbg("Surprise Removal\n");
625 if (p_slot) {
626 surprise_rm_pending = (unsigned long) p_slot;
627 up(&event_semaphore);
628 update_slot_info(p_slot);
629 }
630 }
631 } else {
632 /* refresh notification */
633 if (p_slot)
634 update_slot_info(p_slot);
635 }
636
637 ctrl->event_queue[loop].event_type = 0;
638
639 change = 1;
640 }
641 } /* End of FOR loop */
642 } 466 }
643} 467}
644 468
469/*
470 * Note: This function must be called with slot->lock held
471 */
472static void handle_surprise_event(struct slot *p_slot)
473{
474 u8 getstatus;
475 struct power_work_info *info;
476
477 info = kmalloc(sizeof(*info), GFP_KERNEL);
478 if (!info) {
479 err("%s: Cannot allocate memory\n", __FUNCTION__);
480 return;
481 }
482 info->p_slot = p_slot;
483 INIT_WORK(&info->work, pciehp_power_thread);
484
485 p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
486 if (!getstatus)
487 p_slot->state = POWEROFF_STATE;
488 else
489 p_slot->state = POWERON_STATE;
490
491 queue_work(pciehp_wq, &info->work);
492}
493
494static void interrupt_event_handler(struct work_struct *work)
495{
496 struct event_info *info = container_of(work, struct event_info, work);
497 struct slot *p_slot = info->p_slot;
498 struct controller *ctrl = p_slot->ctrl;
499
500 mutex_lock(&p_slot->lock);
501 switch (info->event_type) {
502 case INT_BUTTON_PRESS:
503 handle_button_press_event(p_slot);
504 break;
505 case INT_POWER_FAULT:
506 if (!POWER_CTRL(ctrl->ctrlcap))
507 break;
508 if (ATTN_LED(ctrl->ctrlcap))
509 p_slot->hpc_ops->set_attention_status(p_slot, 1);
510 if (PWR_LED(ctrl->ctrlcap))
511 p_slot->hpc_ops->green_led_off(p_slot);
512 break;
513 case INT_PRESENCE_ON:
514 case INT_PRESENCE_OFF:
515 if (!HP_SUPR_RM(ctrl->ctrlcap))
516 break;
517 dbg("Surprise Removal\n");
518 update_slot_info(p_slot);
519 handle_surprise_event(p_slot);
520 break;
521 default:
522 update_slot_info(p_slot);
523 break;
524 }
525 mutex_unlock(&p_slot->lock);
526
527 kfree(info);
528}
529
645int pciehp_enable_slot(struct slot *p_slot) 530int pciehp_enable_slot(struct slot *p_slot)
646{ 531{
647 u8 getstatus = 0; 532 u8 getstatus = 0;
@@ -653,7 +538,7 @@ int pciehp_enable_slot(struct slot *p_slot)
653 rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); 538 rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
654 if (rc || !getstatus) { 539 if (rc || !getstatus) {
655 info("%s: no adapter on slot(%s)\n", __FUNCTION__, 540 info("%s: no adapter on slot(%s)\n", __FUNCTION__,
656 slot_name(p_slot)); 541 p_slot->name);
657 mutex_unlock(&p_slot->ctrl->crit_sect); 542 mutex_unlock(&p_slot->ctrl->crit_sect);
658 return -ENODEV; 543 return -ENODEV;
659 } 544 }
@@ -661,7 +546,7 @@ int pciehp_enable_slot(struct slot *p_slot)
661 rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 546 rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
662 if (rc || getstatus) { 547 if (rc || getstatus) {
663 info("%s: latch open on slot(%s)\n", __FUNCTION__, 548 info("%s: latch open on slot(%s)\n", __FUNCTION__,
664 slot_name(p_slot)); 549 p_slot->name);
665 mutex_unlock(&p_slot->ctrl->crit_sect); 550 mutex_unlock(&p_slot->ctrl->crit_sect);
666 return -ENODEV; 551 return -ENODEV;
667 } 552 }
@@ -671,7 +556,7 @@ int pciehp_enable_slot(struct slot *p_slot)
671 rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); 556 rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
672 if (rc || getstatus) { 557 if (rc || getstatus) {
673 info("%s: already enabled on slot(%s)\n", __FUNCTION__, 558 info("%s: already enabled on slot(%s)\n", __FUNCTION__,
674 slot_name(p_slot)); 559 p_slot->name);
675 mutex_unlock(&p_slot->ctrl->crit_sect); 560 mutex_unlock(&p_slot->ctrl->crit_sect);
676 return -EINVAL; 561 return -EINVAL;
677 } 562 }
@@ -706,7 +591,7 @@ int pciehp_disable_slot(struct slot *p_slot)
706 ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); 591 ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
707 if (ret || !getstatus) { 592 if (ret || !getstatus) {
708 info("%s: no adapter on slot(%s)\n", __FUNCTION__, 593 info("%s: no adapter on slot(%s)\n", __FUNCTION__,
709 slot_name(p_slot)); 594 p_slot->name);
710 mutex_unlock(&p_slot->ctrl->crit_sect); 595 mutex_unlock(&p_slot->ctrl->crit_sect);
711 return -ENODEV; 596 return -ENODEV;
712 } 597 }
@@ -716,7 +601,7 @@ int pciehp_disable_slot(struct slot *p_slot)
716 ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 601 ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
717 if (ret || getstatus) { 602 if (ret || getstatus) {
718 info("%s: latch open on slot(%s)\n", __FUNCTION__, 603 info("%s: latch open on slot(%s)\n", __FUNCTION__,
719 slot_name(p_slot)); 604 p_slot->name);
720 mutex_unlock(&p_slot->ctrl->crit_sect); 605 mutex_unlock(&p_slot->ctrl->crit_sect);
721 return -ENODEV; 606 return -ENODEV;
722 } 607 }
@@ -726,7 +611,7 @@ int pciehp_disable_slot(struct slot *p_slot)
726 ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); 611 ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
727 if (ret || !getstatus) { 612 if (ret || !getstatus) {
728 info("%s: already disabled slot(%s)\n", __FUNCTION__, 613 info("%s: already disabled slot(%s)\n", __FUNCTION__,
729 slot_name(p_slot)); 614 p_slot->name);
730 mutex_unlock(&p_slot->ctrl->crit_sect); 615 mutex_unlock(&p_slot->ctrl->crit_sect);
731 return -EINVAL; 616 return -EINVAL;
732 } 617 }
@@ -739,3 +624,66 @@ int pciehp_disable_slot(struct slot *p_slot)
739 return ret; 624 return ret;
740} 625}
741 626
627int pciehp_sysfs_enable_slot(struct slot *p_slot)
628{
629 int retval = -ENODEV;
630
631 mutex_lock(&p_slot->lock);
632 switch (p_slot->state) {
633 case BLINKINGON_STATE:
634 cancel_delayed_work(&p_slot->work);
635 case STATIC_STATE:
636 p_slot->state = POWERON_STATE;
637 mutex_unlock(&p_slot->lock);
638 retval = pciehp_enable_slot(p_slot);
639 mutex_lock(&p_slot->lock);
640 p_slot->state = STATIC_STATE;
641 break;
642 case POWERON_STATE:
643 info("Slot %s is already in powering on state\n",
644 p_slot->name);
645 break;
646 case BLINKINGOFF_STATE:
647 case POWEROFF_STATE:
648 info("Already enabled on slot %s\n", p_slot->name);
649 break;
650 default:
651 err("Not a valid state on slot %s\n", p_slot->name);
652 break;
653 }
654 mutex_unlock(&p_slot->lock);
655
656 return retval;
657}
658
659int pciehp_sysfs_disable_slot(struct slot *p_slot)
660{
661 int retval = -ENODEV;
662
663 mutex_lock(&p_slot->lock);
664 switch (p_slot->state) {
665 case BLINKINGOFF_STATE:
666 cancel_delayed_work(&p_slot->work);
667 case STATIC_STATE:
668 p_slot->state = POWEROFF_STATE;
669 mutex_unlock(&p_slot->lock);
670 retval = pciehp_disable_slot(p_slot);
671 mutex_lock(&p_slot->lock);
672 p_slot->state = STATIC_STATE;
673 break;
674 case POWEROFF_STATE:
675 info("Slot %s is already in powering off state\n",
676 p_slot->name);
677 break;
678 case BLINKINGON_STATE:
679 case POWERON_STATE:
680 info("Already disabled on slot %s\n", p_slot->name);
681 break;
682 default:
683 err("Not a valid state on slot %s\n", p_slot->name);
684 break;
685 }
686 mutex_unlock(&p_slot->lock);
687
688 return retval;
689}
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index fbc64aa2dd6..9aac6a87eb5 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -71,6 +71,8 @@
71#define DBG_LEAVE_ROUTINE 71#define DBG_LEAVE_ROUTINE
72#endif /* DEBUG */ 72#endif /* DEBUG */
73 73
74static atomic_t pciehp_num_controllers = ATOMIC_INIT(0);
75
74struct ctrl_reg { 76struct ctrl_reg {
75 u8 cap_id; 77 u8 cap_id;
76 u8 nxt_ptr; 78 u8 nxt_ptr;
@@ -219,10 +221,7 @@ static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value)
219#define EMI_STATE 0x0080 221#define EMI_STATE 0x0080
220#define EMI_STATUS_BIT 7 222#define EMI_STATUS_BIT 7
221 223
222static spinlock_t hpc_event_lock;
223
224DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */ 224DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */
225static int ctlr_seq_num = 0; /* Controller sequence # */
226 225
227static irqreturn_t pcie_isr(int irq, void *dev_id); 226static irqreturn_t pcie_isr(int irq, void *dev_id);
228static void start_int_poll_timer(struct controller *ctrl, int sec); 227static void start_int_poll_timer(struct controller *ctrl, int sec);
@@ -656,6 +655,13 @@ static void hpc_release_ctlr(struct controller *ctrl)
656 else 655 else
657 free_irq(ctrl->pci_dev->irq, ctrl); 656 free_irq(ctrl->pci_dev->irq, ctrl);
658 657
658 /*
659 * If this is the last controller to be released, destroy the
660 * pciehp work queue
661 */
662 if (atomic_dec_and_test(&pciehp_num_controllers))
663 destroy_workqueue(pciehp_wq);
664
659 DBG_LEAVE_ROUTINE 665 DBG_LEAVE_ROUTINE
660} 666}
661 667
@@ -1152,7 +1158,6 @@ int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev)
1152int pcie_init(struct controller * ctrl, struct pcie_device *dev) 1158int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1153{ 1159{
1154 int rc; 1160 int rc;
1155 static int first = 1;
1156 u16 temp_word; 1161 u16 temp_word;
1157 u16 cap_reg; 1162 u16 cap_reg;
1158 u16 intr_enable = 0; 1163 u16 intr_enable = 0;
@@ -1221,11 +1226,6 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1221 dbg("%s: SLOTCTRL offset %x slot_ctrl %x\n", 1226 dbg("%s: SLOTCTRL offset %x slot_ctrl %x\n",
1222 __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl); 1227 __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl);
1223 1228
1224 if (first) {
1225 spin_lock_init(&hpc_event_lock);
1226 first = 0;
1227 }
1228
1229 for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++) 1229 for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++)
1230 if (pci_resource_len(pdev, rc) > 0) 1230 if (pci_resource_len(pdev, rc) > 0)
1231 dbg("pci resource[%d] start=0x%llx(len=0x%llx)\n", rc, 1231 dbg("pci resource[%d] start=0x%llx(len=0x%llx)\n", rc,
@@ -1286,7 +1286,8 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1286 rc = request_irq(ctrl->pci_dev->irq, pcie_isr, IRQF_SHARED, 1286 rc = request_irq(ctrl->pci_dev->irq, pcie_isr, IRQF_SHARED,
1287 MY_NAME, (void *)ctrl); 1287 MY_NAME, (void *)ctrl);
1288 dbg("%s: request_irq %d for hpc%d (returns %d)\n", 1288 dbg("%s: request_irq %d for hpc%d (returns %d)\n",
1289 __FUNCTION__, ctrl->pci_dev->irq, ctlr_seq_num, rc); 1289 __FUNCTION__, ctrl->pci_dev->irq,
1290 atomic_read(&pciehp_num_controllers), rc);
1290 if (rc) { 1291 if (rc) {
1291 err("Can't get irq %d for the hotplug controller\n", 1292 err("Can't get irq %d for the hotplug controller\n",
1292 ctrl->pci_dev->irq); 1293 ctrl->pci_dev->irq);
@@ -1296,6 +1297,18 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1296 dbg("pciehp ctrl b:d:f:irq=0x%x:%x:%x:%x\n", pdev->bus->number, 1297 dbg("pciehp ctrl b:d:f:irq=0x%x:%x:%x:%x\n", pdev->bus->number,
1297 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq); 1298 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq);
1298 1299
1300 /*
1301 * If this is the first controller to be initialized,
1302 * initialize the pciehp work queue
1303 */
1304 if (atomic_add_return(1, &pciehp_num_controllers) == 1) {
1305 pciehp_wq = create_singlethread_workqueue("pciehpd");
1306 if (!pciehp_wq) {
1307 rc = -ENOMEM;
1308 goto abort_free_irq;
1309 }
1310 }
1311
1299 rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); 1312 rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word);
1300 if (rc) { 1313 if (rc) {
1301 err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); 1314 err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
@@ -1349,7 +1362,6 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1349 goto abort_disable_intr; 1362 goto abort_disable_intr;
1350 } 1363 }
1351 1364
1352 ctlr_seq_num++;
1353 ctrl->hpc_ops = &pciehp_hpc_ops; 1365 ctrl->hpc_ops = &pciehp_hpc_ops;
1354 1366
1355 DBG_LEAVE_ROUTINE 1367 DBG_LEAVE_ROUTINE