aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAndres Salomon <dilinger@queued.net>2012-07-12 20:57:28 -0400
committerAndres Salomon <dilinger@queued.net>2012-07-31 23:27:30 -0400
commit85f90cf6ca569b19cee212844b543a7355b77163 (patch)
tree1e2cd8e3c712863533f151b033a723443dd31540 /arch
parentd278b7a2f90f91f908b19b50cfa59e10632b5afc (diff)
x86: OLPC: switch over to using new EC driver on x86
This uses the new EC driver framework in drivers/platform/olpc. The XO-1 and XO-1.5-specific code is still in arch/x86, but the generic stuff (including a new workqueue; no more running EC commands with IRQs disabled!) can be shared with other architectures. 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')
-rw-r--r--arch/x86/include/asm/olpc.h5
-rw-r--r--arch/x86/platform/olpc/olpc.c53
2 files changed, 27 insertions, 31 deletions
diff --git a/arch/x86/include/asm/olpc.h b/arch/x86/include/asm/olpc.h
index 5b28f3e6975..72f9adf6eca 100644
--- a/arch/x86/include/asm/olpc.h
+++ b/arch/x86/include/asm/olpc.h
@@ -100,11 +100,6 @@ extern void olpc_xo1_pm_wakeup_clear(u16 value);
100 100
101extern int pci_olpc_init(void); 101extern int pci_olpc_init(void);
102 102
103/* EC related functions */
104
105extern int olpc_ec_cmd_x86(unsigned char cmd, unsigned char *inbuf,
106 size_t inlen, unsigned char *outbuf, size_t outlen);
107
108/* SCI source values */ 103/* SCI source values */
109 104
110#define EC_SCI_SRC_EMPTY 0x00 105#define EC_SCI_SRC_EMPTY 0x00
diff --git a/arch/x86/platform/olpc/olpc.c b/arch/x86/platform/olpc/olpc.c
index a3fa180c15c..45900968fb8 100644
--- a/arch/x86/platform/olpc/olpc.c
+++ b/arch/x86/platform/olpc/olpc.c
@@ -14,7 +14,6 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/spinlock.h>
18#include <linux/io.h> 17#include <linux/io.h>
19#include <linux/string.h> 18#include <linux/string.h>
20#include <linux/platform_device.h> 19#include <linux/platform_device.h>
@@ -32,8 +31,6 @@
32struct olpc_platform_t olpc_platform_info; 31struct olpc_platform_t olpc_platform_info;
33EXPORT_SYMBOL_GPL(olpc_platform_info); 32EXPORT_SYMBOL_GPL(olpc_platform_info);
34 33
35static DEFINE_SPINLOCK(ec_lock);
36
37/* debugfs interface to EC commands */ 34/* debugfs interface to EC commands */
38#define EC_MAX_CMD_ARGS (5 + 1) /* cmd byte + 5 args */ 35#define EC_MAX_CMD_ARGS (5 + 1) /* cmd byte + 5 args */
39#define EC_MAX_CMD_REPLY (8) 36#define EC_MAX_CMD_REPLY (8)
@@ -126,16 +123,13 @@ static int __wait_on_obf(unsigned int line, unsigned int port, int desired)
126 * <http://wiki.laptop.org/go/Ec_specification>. Unfortunately, while 123 * <http://wiki.laptop.org/go/Ec_specification>. Unfortunately, while
127 * OpenFirmware's source is available, the EC's is not. 124 * OpenFirmware's source is available, the EC's is not.
128 */ 125 */
129int olpc_ec_cmd_x86(unsigned char cmd, unsigned char *inbuf, size_t inlen, 126static int olpc_xo1_ec_cmd(u8 cmd, u8 *inbuf, size_t inlen, u8 *outbuf,
130 unsigned char *outbuf, size_t outlen) 127 size_t outlen, void *arg)
131{ 128{
132 unsigned long flags;
133 int ret = -EIO; 129 int ret = -EIO;
134 int i; 130 int i;
135 int restarts = 0; 131 int restarts = 0;
136 132
137 spin_lock_irqsave(&ec_lock, flags);
138
139 /* Clear OBF */ 133 /* Clear OBF */
140 for (i = 0; i < 10 && (obf_status(0x6c) == 1); i++) 134 for (i = 0; i < 10 && (obf_status(0x6c) == 1); i++)
141 inb(0x68); 135 inb(0x68);
@@ -199,10 +193,8 @@ restart:
199 193
200 ret = 0; 194 ret = 0;
201err: 195err:
202 spin_unlock_irqrestore(&ec_lock, flags);
203 return ret; 196 return ret;
204} 197}
205EXPORT_SYMBOL_GPL(olpc_ec_cmd_x86);
206 198
207void olpc_ec_wakeup_set(u16 value) 199void olpc_ec_wakeup_set(u16 value)
208{ 200{
@@ -366,7 +358,7 @@ static void setup_debugfs(void)
366 &ec_debugfs_genops); 358 &ec_debugfs_genops);
367} 359}
368 360
369static int olpc_ec_suspend(void) 361static int olpc_ec_suspend(struct platform_device *pdev)
370{ 362{
371 return olpc_ec_mask_write(ec_wakeup_mask); 363 return olpc_ec_mask_write(ec_wakeup_mask);
372} 364}
@@ -425,8 +417,28 @@ static int __init add_xo1_platform_devices(void)
425 return 0; 417 return 0;
426} 418}
427 419
428static struct syscore_ops olpc_syscore_ops = { 420static int olpc_xo1_ec_probe(struct platform_device *pdev)
421{
422 /* get the EC revision */
423 olpc_ec_cmd(EC_FIRMWARE_REV, NULL, 0,
424 (unsigned char *) &olpc_platform_info.ecver, 1);
425
426 /* EC version 0x5f adds support for wide SCI mask */
427 if (olpc_platform_info.ecver >= 0x5f)
428 olpc_platform_info.flags |= OLPC_F_EC_WIDE_SCI;
429
430 pr_info("OLPC board revision %s%X (EC=%x)\n",
431 ((olpc_platform_info.boardrev & 0xf) < 8) ? "pre" : "",
432 olpc_platform_info.boardrev >> 4,
433 olpc_platform_info.ecver);
434
435 return 0;
436}
437
438static struct olpc_ec_driver ec_xo1_driver = {
429 .suspend = olpc_ec_suspend, 439 .suspend = olpc_ec_suspend,
440 .probe = olpc_xo1_ec_probe,
441 .ec_cmd = olpc_xo1_ec_cmd,
430}; 442};
431 443
432static int __init olpc_init(void) 444static int __init olpc_init(void)
@@ -436,16 +448,14 @@ static int __init olpc_init(void)
436 if (!olpc_ofw_present() || !platform_detect()) 448 if (!olpc_ofw_present() || !platform_detect())
437 return 0; 449 return 0;
438 450
439 spin_lock_init(&ec_lock); 451 /* register the XO-1 and 1.5-specific EC handler */
452 olpc_ec_driver_register(&ec_xo1_driver, NULL);
453 platform_device_register_simple("olpc-ec", -1, NULL, 0);
440 454
441 /* assume B1 and above models always have a DCON */ 455 /* assume B1 and above models always have a DCON */
442 if (olpc_board_at_least(olpc_board(0xb1))) 456 if (olpc_board_at_least(olpc_board(0xb1)))
443 olpc_platform_info.flags |= OLPC_F_DCON; 457 olpc_platform_info.flags |= OLPC_F_DCON;
444 458
445 /* get the EC revision */
446 olpc_ec_cmd(EC_FIRMWARE_REV, NULL, 0,
447 (unsigned char *) &olpc_platform_info.ecver, 1);
448
449#ifdef CONFIG_PCI_OLPC 459#ifdef CONFIG_PCI_OLPC
450 /* If the VSA exists let it emulate PCI, if not emulate in kernel. 460 /* If the VSA exists let it emulate PCI, if not emulate in kernel.
451 * XO-1 only. */ 461 * XO-1 only. */
@@ -453,14 +463,6 @@ static int __init olpc_init(void)
453 !cs5535_has_vsa2()) 463 !cs5535_has_vsa2())
454 x86_init.pci.arch_init = pci_olpc_init; 464 x86_init.pci.arch_init = pci_olpc_init;
455#endif 465#endif
456 /* EC version 0x5f adds support for wide SCI mask */
457 if (olpc_platform_info.ecver >= 0x5f)
458 olpc_platform_info.flags |= OLPC_F_EC_WIDE_SCI;
459
460 printk(KERN_INFO "OLPC board revision %s%X (EC=%x)\n",
461 ((olpc_platform_info.boardrev & 0xf) < 8) ? "pre" : "",
462 olpc_platform_info.boardrev >> 4,
463 olpc_platform_info.ecver);
464 466
465 if (olpc_platform_info.boardrev < olpc_board_pre(0xd0)) { /* XO-1 */ 467 if (olpc_platform_info.boardrev < olpc_board_pre(0xd0)) { /* XO-1 */
466 r = add_xo1_platform_devices(); 468 r = add_xo1_platform_devices();
@@ -468,7 +470,6 @@ static int __init olpc_init(void)
468 return r; 470 return r;
469 } 471 }
470 472
471 register_syscore_ops(&olpc_syscore_ops);
472 setup_debugfs(); 473 setup_debugfs();
473 474
474 return 0; 475 return 0;