aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShaibal Dutta <shaibal.dutta@broadcom.com>2014-02-01 22:16:46 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-02-07 17:41:05 -0500
commit22f6a0f0e3549b73b3319e26e1689f72b1f1284b (patch)
treef399dc81a4d3386c5c1269475410df2a44481762
parent5c73e74034820ca2a85101a52622f1c92237edc0 (diff)
usb: move hub init and LED blink work to power efficient workqueue
Allow the scheduler to select the best CPU to handle hub initalization and LED blinking work. This extends idle residency times on idle CPUs and conserves power. This functionality is enabled when CONFIG_WQ_POWER_EFFICIENT is selected. [zoran.markovic@linaro.org: Rebased to latest kernel. Added commit message. Changed reference from system to power efficient workqueue for LEDs in check_highspeed() and hub_port_connect_change().] Acked-by: Alan Stern <stern@rowland.harvard.edu> Cc: Sarah Sharp <sarah.a.sharp@linux.intel.com> Cc: Xenia Ragiadakou <burzalodowa@gmail.com> Cc: Julius Werner <jwerner@chromium.org> Cc: Krzysztof Mazur <krzysiek@podlesie.net> Cc: Matthias Beyer <mail@beyermatthias.de> Cc: Dan Williams <dan.j.williams@intel.com> Cc: Mathias Nyman <mathias.nyman@linux.intel.com> Cc: Thomas Pugliese <thomas.pugliese@gmail.com> Signed-off-by: Shaibal Dutta <shaibal.dutta@broadcom.com> Signed-off-by: Zoran Markovic <zoran.markovic@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/core/hub.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 64ea21971be2..519f2c3594b2 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -499,7 +499,8 @@ static void led_work (struct work_struct *work)
499 changed++; 499 changed++;
500 } 500 }
501 if (changed) 501 if (changed)
502 schedule_delayed_work(&hub->leds, LED_CYCLE_PERIOD); 502 queue_delayed_work(system_power_efficient_wq,
503 &hub->leds, LED_CYCLE_PERIOD);
503} 504}
504 505
505/* use a short timeout for hub/port status fetches */ 506/* use a short timeout for hub/port status fetches */
@@ -1041,7 +1042,8 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
1041 if (type == HUB_INIT) { 1042 if (type == HUB_INIT) {
1042 delay = hub_power_on(hub, false); 1043 delay = hub_power_on(hub, false);
1043 PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func2); 1044 PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func2);
1044 schedule_delayed_work(&hub->init_work, 1045 queue_delayed_work(system_power_efficient_wq,
1046 &hub->init_work,
1045 msecs_to_jiffies(delay)); 1047 msecs_to_jiffies(delay));
1046 1048
1047 /* Suppress autosuspend until init is done */ 1049 /* Suppress autosuspend until init is done */
@@ -1195,7 +1197,8 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
1195 /* Don't do a long sleep inside a workqueue routine */ 1197 /* Don't do a long sleep inside a workqueue routine */
1196 if (type == HUB_INIT2) { 1198 if (type == HUB_INIT2) {
1197 PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func3); 1199 PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func3);
1198 schedule_delayed_work(&hub->init_work, 1200 queue_delayed_work(system_power_efficient_wq,
1201 &hub->init_work,
1199 msecs_to_jiffies(delay)); 1202 msecs_to_jiffies(delay));
1200 return; /* Continues at init3: below */ 1203 return; /* Continues at init3: below */
1201 } else { 1204 } else {
@@ -1209,7 +1212,8 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
1209 if (status < 0) 1212 if (status < 0)
1210 dev_err(hub->intfdev, "activate --> %d\n", status); 1213 dev_err(hub->intfdev, "activate --> %d\n", status);
1211 if (hub->has_indicators && blinkenlights) 1214 if (hub->has_indicators && blinkenlights)
1212 schedule_delayed_work(&hub->leds, LED_CYCLE_PERIOD); 1215 queue_delayed_work(system_power_efficient_wq,
1216 &hub->leds, LED_CYCLE_PERIOD);
1213 1217
1214 /* Scan all ports that need attention */ 1218 /* Scan all ports that need attention */
1215 kick_khubd(hub); 1219 kick_khubd(hub);
@@ -4311,7 +4315,8 @@ check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port1)
4311 /* hub LEDs are probably harder to miss than syslog */ 4315 /* hub LEDs are probably harder to miss than syslog */
4312 if (hub->has_indicators) { 4316 if (hub->has_indicators) {
4313 hub->indicator[port1-1] = INDICATOR_GREEN_BLINK; 4317 hub->indicator[port1-1] = INDICATOR_GREEN_BLINK;
4314 schedule_delayed_work (&hub->leds, 0); 4318 queue_delayed_work(system_power_efficient_wq,
4319 &hub->leds, 0);
4315 } 4320 }
4316 } 4321 }
4317 kfree(qual); 4322 kfree(qual);
@@ -4540,7 +4545,9 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
4540 if (hub->has_indicators) { 4545 if (hub->has_indicators) {
4541 hub->indicator[port1-1] = 4546 hub->indicator[port1-1] =
4542 INDICATOR_AMBER_BLINK; 4547 INDICATOR_AMBER_BLINK;
4543 schedule_delayed_work (&hub->leds, 0); 4548 queue_delayed_work(
4549 system_power_efficient_wq,
4550 &hub->leds, 0);
4544 } 4551 }
4545 status = -ENOTCONN; /* Don't retry */ 4552 status = -ENOTCONN; /* Don't retry */
4546 goto loop_disable; 4553 goto loop_disable;