aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2015-10-12 15:10:12 -0400
committerBjorn Helgaas <bhelgaas@google.com>2015-10-21 14:55:37 -0400
commitbee67756eb4ae51ededeb8ce56e7f4fb91d30b43 (patch)
tree678a5fc78d9959f5398004e9e3f048e130868edc
parent6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f (diff)
PCI: pciehp: Queue power work requests in dedicated function
Up to now, work items to be queued to be handled by pciehp_power_thread() are allocated using kmalloc() in three different locations. If not needed, kfree() is called to free the allocated data. Introduce a separate function to allocate the work item and queue it, and call it only if needed. This reduces code duplication and avoids having to free memory if the work item does not need to get executed. [bhelgaas: tweak "no memory" message, make pciehp_queue_power_work() static] Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c75
1 files changed, 23 insertions, 52 deletions
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index f3796124ad7c..4c8f4cde6854 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -204,36 +204,39 @@ static void pciehp_power_thread(struct work_struct *work)
204 kfree(info); 204 kfree(info);
205} 205}
206 206
207void pciehp_queue_pushbutton_work(struct work_struct *work) 207static void pciehp_queue_power_work(struct slot *p_slot, int req)
208{ 208{
209 struct slot *p_slot = container_of(work, struct slot, work.work);
210 struct power_work_info *info; 209 struct power_work_info *info;
211 210
211 p_slot->state = (req == ENABLE_REQ) ? POWERON_STATE : POWEROFF_STATE;
212
212 info = kmalloc(sizeof(*info), GFP_KERNEL); 213 info = kmalloc(sizeof(*info), GFP_KERNEL);
213 if (!info) { 214 if (!info) {
214 ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n", 215 ctrl_err(p_slot->ctrl, "no memory to queue %s request\n",
215 __func__); 216 (req == ENABLE_REQ) ? "poweron" : "poweroff");
216 return; 217 return;
217 } 218 }
218 info->p_slot = p_slot; 219 info->p_slot = p_slot;
219 INIT_WORK(&info->work, pciehp_power_thread); 220 INIT_WORK(&info->work, pciehp_power_thread);
221 info->req = req;
222 queue_work(p_slot->wq, &info->work);
223}
224
225void pciehp_queue_pushbutton_work(struct work_struct *work)
226{
227 struct slot *p_slot = container_of(work, struct slot, work.work);
220 228
221 mutex_lock(&p_slot->lock); 229 mutex_lock(&p_slot->lock);
222 switch (p_slot->state) { 230 switch (p_slot->state) {
223 case BLINKINGOFF_STATE: 231 case BLINKINGOFF_STATE:
224 p_slot->state = POWEROFF_STATE; 232 pciehp_queue_power_work(p_slot, DISABLE_REQ);
225 info->req = DISABLE_REQ;
226 break; 233 break;
227 case BLINKINGON_STATE: 234 case BLINKINGON_STATE:
228 p_slot->state = POWERON_STATE; 235 pciehp_queue_power_work(p_slot, ENABLE_REQ);
229 info->req = ENABLE_REQ;
230 break; 236 break;
231 default: 237 default:
232 kfree(info); 238 break;
233 goto out;
234 } 239 }
235 queue_work(p_slot->wq, &info->work);
236 out:
237 mutex_unlock(&p_slot->lock); 240 mutex_unlock(&p_slot->lock);
238} 241}
239 242
@@ -301,27 +304,12 @@ static void handle_button_press_event(struct slot *p_slot)
301static void handle_surprise_event(struct slot *p_slot) 304static void handle_surprise_event(struct slot *p_slot)
302{ 305{
303 u8 getstatus; 306 u8 getstatus;
304 struct power_work_info *info;
305
306 info = kmalloc(sizeof(*info), GFP_KERNEL);
307 if (!info) {
308 ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n",
309 __func__);
310 return;
311 }
312 info->p_slot = p_slot;
313 INIT_WORK(&info->work, pciehp_power_thread);
314 307
315 pciehp_get_adapter_status(p_slot, &getstatus); 308 pciehp_get_adapter_status(p_slot, &getstatus);
316 if (!getstatus) { 309 if (!getstatus)
317 p_slot->state = POWEROFF_STATE; 310 pciehp_queue_power_work(p_slot, DISABLE_REQ);
318 info->req = DISABLE_REQ; 311 else
319 } else { 312 pciehp_queue_power_work(p_slot, ENABLE_REQ);
320 p_slot->state = POWERON_STATE;
321 info->req = ENABLE_REQ;
322 }
323
324 queue_work(p_slot->wq, &info->work);
325} 313}
326 314
327/* 315/*
@@ -330,17 +318,6 @@ static void handle_surprise_event(struct slot *p_slot)
330static void handle_link_event(struct slot *p_slot, u32 event) 318static void handle_link_event(struct slot *p_slot, u32 event)
331{ 319{
332 struct controller *ctrl = p_slot->ctrl; 320 struct controller *ctrl = p_slot->ctrl;
333 struct power_work_info *info;
334
335 info = kmalloc(sizeof(*info), GFP_KERNEL);
336 if (!info) {
337 ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n",
338 __func__);
339 return;
340 }
341 info->p_slot = p_slot;
342 info->req = event == INT_LINK_UP ? ENABLE_REQ : DISABLE_REQ;
343 INIT_WORK(&info->work, pciehp_power_thread);
344 321
345 switch (p_slot->state) { 322 switch (p_slot->state) {
346 case BLINKINGON_STATE: 323 case BLINKINGON_STATE:
@@ -348,22 +325,19 @@ static void handle_link_event(struct slot *p_slot, u32 event)
348 cancel_delayed_work(&p_slot->work); 325 cancel_delayed_work(&p_slot->work);
349 /* Fall through */ 326 /* Fall through */
350 case STATIC_STATE: 327 case STATIC_STATE:
351 p_slot->state = event == INT_LINK_UP ? 328 pciehp_queue_power_work(p_slot, event == INT_LINK_UP ?
352 POWERON_STATE : POWEROFF_STATE; 329 ENABLE_REQ : DISABLE_REQ);
353 queue_work(p_slot->wq, &info->work);
354 break; 330 break;
355 case POWERON_STATE: 331 case POWERON_STATE:
356 if (event == INT_LINK_UP) { 332 if (event == INT_LINK_UP) {
357 ctrl_info(ctrl, 333 ctrl_info(ctrl,
358 "Link Up event ignored on slot(%s): already powering on\n", 334 "Link Up event ignored on slot(%s): already powering on\n",
359 slot_name(p_slot)); 335 slot_name(p_slot));
360 kfree(info);
361 } else { 336 } else {
362 ctrl_info(ctrl, 337 ctrl_info(ctrl,
363 "Link Down event queued on slot(%s): currently getting powered on\n", 338 "Link Down event queued on slot(%s): currently getting powered on\n",
364 slot_name(p_slot)); 339 slot_name(p_slot));
365 p_slot->state = POWEROFF_STATE; 340 pciehp_queue_power_work(p_slot, DISABLE_REQ);
366 queue_work(p_slot->wq, &info->work);
367 } 341 }
368 break; 342 break;
369 case POWEROFF_STATE: 343 case POWEROFF_STATE:
@@ -371,19 +345,16 @@ static void handle_link_event(struct slot *p_slot, u32 event)
371 ctrl_info(ctrl, 345 ctrl_info(ctrl,
372 "Link Up event queued on slot(%s): currently getting powered off\n", 346 "Link Up event queued on slot(%s): currently getting powered off\n",
373 slot_name(p_slot)); 347 slot_name(p_slot));
374 p_slot->state = POWERON_STATE; 348 pciehp_queue_power_work(p_slot, ENABLE_REQ);
375 queue_work(p_slot->wq, &info->work);
376 } else { 349 } else {
377 ctrl_info(ctrl, 350 ctrl_info(ctrl,
378 "Link Down event ignored on slot(%s): already powering off\n", 351 "Link Down event ignored on slot(%s): already powering off\n",
379 slot_name(p_slot)); 352 slot_name(p_slot));
380 kfree(info);
381 } 353 }
382 break; 354 break;
383 default: 355 default:
384 ctrl_err(ctrl, "ignoring invalid state %#x on slot(%s)\n", 356 ctrl_err(ctrl, "ignoring invalid state %#x on slot(%s)\n",
385 p_slot->state, slot_name(p_slot)); 357 p_slot->state, slot_name(p_slot));
386 kfree(info);
387 break; 358 break;
388 } 359 }
389} 360}