aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/platform/olpc
diff options
context:
space:
mode:
authorAndres Salomon <dilinger@queued.net>2012-07-17 04:26:10 -0400
committerAndres Salomon <dilinger@queued.net>2012-07-31 23:27:31 -0400
commit1fcfd08bd0704e1888bd73153e8d2ca3640e22f2 (patch)
tree8aacc28564c985e96927ec16360ef9b4d73efb45 /arch/x86/platform/olpc
parent99ecb01cdf0378783b317b8f839ac9cc5e128aa5 (diff)
x86: OLPC: move s/r-related EC cmds to EC driver
The new EC driver calls platform-specific suspend and resume hooks; run XO-1-specific EC commands from there, rather than deep in s/r code. If we attempt to run EC commands after the new EC driver has suspended, it is refused by the ec->suspended checks. Signed-off-by: Andres Salomon <dilinger@queued.net> Acked-by: Paul Fox <pgf@laptop.org> Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/platform/olpc')
-rw-r--r--arch/x86/platform/olpc/olpc-xo1-pm.c15
-rw-r--r--arch/x86/platform/olpc/olpc.c43
2 files changed, 36 insertions, 22 deletions
diff --git a/arch/x86/platform/olpc/olpc-xo1-pm.c b/arch/x86/platform/olpc/olpc-xo1-pm.c
index 8054b64ec4ce..d75582d1aa55 100644
--- a/arch/x86/platform/olpc/olpc-xo1-pm.c
+++ b/arch/x86/platform/olpc/olpc-xo1-pm.c
@@ -52,16 +52,11 @@ EXPORT_SYMBOL_GPL(olpc_xo1_pm_wakeup_clear);
52static int xo1_power_state_enter(suspend_state_t pm_state) 52static int xo1_power_state_enter(suspend_state_t pm_state)
53{ 53{
54 unsigned long saved_sci_mask; 54 unsigned long saved_sci_mask;
55 int r;
56 55
57 /* Only STR is supported */ 56 /* Only STR is supported */
58 if (pm_state != PM_SUSPEND_MEM) 57 if (pm_state != PM_SUSPEND_MEM)
59 return -EINVAL; 58 return -EINVAL;
60 59
61 r = olpc_ec_cmd(EC_SET_SCI_INHIBIT, NULL, 0, NULL, 0);
62 if (r)
63 return r;
64
65 /* 60 /*
66 * Save SCI mask (this gets lost since PM1_EN is used as a mask for 61 * Save SCI mask (this gets lost since PM1_EN is used as a mask for
67 * wakeup events, which is not necessarily the same event set) 62 * wakeup events, which is not necessarily the same event set)
@@ -77,16 +72,6 @@ static int xo1_power_state_enter(suspend_state_t pm_state)
77 /* Restore SCI mask (using dword access to CS5536_PM1_EN) */ 72 /* Restore SCI mask (using dword access to CS5536_PM1_EN) */
78 outl(saved_sci_mask, acpi_base + CS5536_PM1_STS); 73 outl(saved_sci_mask, acpi_base + CS5536_PM1_STS);
79 74
80 /* Tell the EC to stop inhibiting SCIs */
81 olpc_ec_cmd(EC_SET_SCI_INHIBIT_RELEASE, NULL, 0, NULL, 0);
82
83 /*
84 * Tell the wireless module to restart USB communication.
85 * Must be done twice.
86 */
87 olpc_ec_cmd(EC_WAKE_UP_WLAN, NULL, 0, NULL, 0);
88 olpc_ec_cmd(EC_WAKE_UP_WLAN, NULL, 0, NULL, 0);
89
90 return 0; 75 return 0;
91} 76}
92 77
diff --git a/arch/x86/platform/olpc/olpc.c b/arch/x86/platform/olpc/olpc.c
index ed41b437b37b..27376081ddec 100644
--- a/arch/x86/platform/olpc/olpc.c
+++ b/arch/x86/platform/olpc/olpc.c
@@ -263,11 +263,6 @@ int olpc_ec_sci_query(u16 *sci_value)
263} 263}
264EXPORT_SYMBOL_GPL(olpc_ec_sci_query); 264EXPORT_SYMBOL_GPL(olpc_ec_sci_query);
265 265
266static int olpc_ec_suspend(struct platform_device *pdev)
267{
268 return olpc_ec_mask_write(ec_wakeup_mask);
269}
270
271static bool __init check_ofw_architecture(struct device_node *root) 266static bool __init check_ofw_architecture(struct device_node *root)
272{ 267{
273 const char *olpc_arch; 268 const char *olpc_arch;
@@ -339,9 +334,40 @@ static int olpc_xo1_ec_probe(struct platform_device *pdev)
339 334
340 return 0; 335 return 0;
341} 336}
337static int olpc_xo1_ec_suspend(struct platform_device *pdev)
338{
339 olpc_ec_mask_write(ec_wakeup_mask);
340
341 /*
342 * Squelch SCIs while suspended. This is a fix for
343 * <http://dev.laptop.org/ticket/1835>.
344 */
345 return olpc_ec_cmd(EC_SET_SCI_INHIBIT, NULL, 0, NULL, 0);
346}
347
348static int olpc_xo1_ec_resume(struct platform_device *pdev)
349{
350 /* Tell the EC to stop inhibiting SCIs */
351 olpc_ec_cmd(EC_SET_SCI_INHIBIT_RELEASE, NULL, 0, NULL, 0);
352
353 /*
354 * Tell the wireless module to restart USB communication.
355 * Must be done twice.
356 */
357 olpc_ec_cmd(EC_WAKE_UP_WLAN, NULL, 0, NULL, 0);
358 olpc_ec_cmd(EC_WAKE_UP_WLAN, NULL, 0, NULL, 0);
359
360 return 0;
361}
342 362
343static struct olpc_ec_driver ec_xo1_driver = { 363static struct olpc_ec_driver ec_xo1_driver = {
344 .suspend = olpc_ec_suspend, 364 .probe = olpc_xo1_ec_probe,
365 .suspend = olpc_xo1_ec_suspend,
366 .resume = olpc_xo1_ec_resume,
367 .ec_cmd = olpc_xo1_ec_cmd,
368};
369
370static struct olpc_ec_driver ec_xo1_5_driver = {
345 .probe = olpc_xo1_ec_probe, 371 .probe = olpc_xo1_ec_probe,
346 .ec_cmd = olpc_xo1_ec_cmd, 372 .ec_cmd = olpc_xo1_ec_cmd,
347}; 373};
@@ -354,7 +380,10 @@ static int __init olpc_init(void)
354 return 0; 380 return 0;
355 381
356 /* register the XO-1 and 1.5-specific EC handler */ 382 /* register the XO-1 and 1.5-specific EC handler */
357 olpc_ec_driver_register(&ec_xo1_driver, NULL); 383 if (olpc_platform_info.boardrev < olpc_board_pre(0xd0)) /* XO-1 */
384 olpc_ec_driver_register(&ec_xo1_driver, NULL);
385 else
386 olpc_ec_driver_register(&ec_xo1_5_driver, NULL);
358 platform_device_register_simple("olpc-ec", -1, NULL, 0); 387 platform_device_register_simple("olpc-ec", -1, NULL, 0);
359 388
360 /* assume B1 and above models always have a DCON */ 389 /* assume B1 and above models always have a DCON */