Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 260301
b: refs/heads/master
c: bc4ecd5
h: refs/heads/master
i:
  260299: 42b4c20
v: v3
  • Loading branch information
Daniel Drake authored and H. Peter Anvin committed Jul 6, 2011
1 parent 91bc295 commit 8a650e1
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 7 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7feda8e9f35ebb0e9f90e03acb02280bc137f784
refs/heads/master: bc4ecd5a5efc2435e6debfb7b279a15ae96697fd
31 changes: 25 additions & 6 deletions trunk/arch/x86/include/asm/olpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ struct olpc_platform_t {

#define OLPC_F_PRESENT 0x01
#define OLPC_F_DCON 0x02
#define OLPC_F_EC_WIDE_SCI 0x04

#ifdef CONFIG_OLPC

Expand Down Expand Up @@ -62,6 +63,13 @@ static inline int olpc_board_at_least(uint32_t rev)
return olpc_platform_info.boardrev >= rev;
}

extern void olpc_ec_wakeup_set(u16 value);
extern void olpc_ec_wakeup_clear(u16 value);
extern bool olpc_ec_wakeup_available(void);

extern int olpc_ec_mask_write(u16 bits);
extern int olpc_ec_sci_query(u16 *sci_value);

#else

static inline int machine_is_olpc(void)
Expand All @@ -74,6 +82,14 @@ static inline int olpc_has_dcon(void)
return 0;
}

static inline void olpc_ec_wakeup_set(u16 value) { }
static inline void olpc_ec_wakeup_clear(u16 value) { }

static inline bool olpc_ec_wakeup_available(void)
{
return false;
}

#endif

#ifdef CONFIG_OLPC_XO1_PM
Expand All @@ -89,17 +105,18 @@ extern int pci_olpc_init(void);
extern int olpc_ec_cmd(unsigned char cmd, unsigned char *inbuf, size_t inlen,
unsigned char *outbuf, size_t outlen);

extern int olpc_ec_mask_set(uint8_t bits);
extern int olpc_ec_mask_unset(uint8_t bits);

/* EC commands */

#define EC_FIRMWARE_REV 0x08
#define EC_WRITE_SCI_MASK 0x1b
#define EC_WAKE_UP_WLAN 0x24
#define EC_WLAN_LEAVE_RESET 0x25
#define EC_SET_SCI_INHIBIT 0x32
#define EC_SET_SCI_INHIBIT_RELEASE 0x34
#define EC_WLAN_ENTER_RESET 0x35
#define EC_WRITE_EXT_SCI_MASK 0x38
#define EC_SCI_QUERY 0x84
#define EC_EXT_SCI_QUERY 0x85

/* SCI source values */

Expand All @@ -108,10 +125,12 @@ extern int olpc_ec_mask_unset(uint8_t bits);
#define EC_SCI_SRC_BATTERY 0x02
#define EC_SCI_SRC_BATSOC 0x04
#define EC_SCI_SRC_BATERR 0x08
#define EC_SCI_SRC_EBOOK 0x10
#define EC_SCI_SRC_WLAN 0x20
#define EC_SCI_SRC_EBOOK 0x10 /* XO-1 only */
#define EC_SCI_SRC_WLAN 0x20 /* XO-1 only */
#define EC_SCI_SRC_ACPWR 0x40
#define EC_SCI_SRC_ALL 0x7F
#define EC_SCI_SRC_BATCRIT 0x80
#define EC_SCI_SRC_GPWAKE 0x100 /* XO-1.5 only */
#define EC_SCI_SRC_ALL 0x1FF

/* GPIO assignments */

Expand Down
86 changes: 86 additions & 0 deletions trunk/arch/x86/platform/olpc/olpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <linux/string.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/syscore_ops.h>

#include <asm/geode.h>
#include <asm/setup.h>
Expand All @@ -30,6 +31,9 @@ EXPORT_SYMBOL_GPL(olpc_platform_info);

static DEFINE_SPINLOCK(ec_lock);

/* EC event mask to be applied during suspend (defining wakeup sources). */
static u16 ec_wakeup_mask;

/* what the timeout *should* be (in ms) */
#define EC_BASE_TIMEOUT 20

Expand Down Expand Up @@ -188,6 +192,79 @@ int olpc_ec_cmd(unsigned char cmd, unsigned char *inbuf, size_t inlen,
}
EXPORT_SYMBOL_GPL(olpc_ec_cmd);

void olpc_ec_wakeup_set(u16 value)
{
ec_wakeup_mask |= value;
}
EXPORT_SYMBOL_GPL(olpc_ec_wakeup_set);

void olpc_ec_wakeup_clear(u16 value)
{
ec_wakeup_mask &= ~value;
}
EXPORT_SYMBOL_GPL(olpc_ec_wakeup_clear);

/*
* Returns true if the compile and runtime configurations allow for EC events
* to wake the system.
*/
bool olpc_ec_wakeup_available(void)
{
if (!machine_is_olpc())
return false;

/*
* XO-1 EC wakeups are available when olpc-xo1-sci driver is
* compiled in
*/
#ifdef CONFIG_OLPC_XO1_SCI
if (olpc_platform_info.boardrev < olpc_board_pre(0xd0)) /* XO-1 */
return true;
#endif

return false;
}
EXPORT_SYMBOL_GPL(olpc_ec_wakeup_available);

int olpc_ec_mask_write(u16 bits)
{
if (olpc_platform_info.flags & OLPC_F_EC_WIDE_SCI) {
__be16 ec_word = cpu_to_be16(bits);
return olpc_ec_cmd(EC_WRITE_EXT_SCI_MASK, (void *) &ec_word, 2,
NULL, 0);
} else {
unsigned char ec_byte = bits & 0xff;
return olpc_ec_cmd(EC_WRITE_SCI_MASK, &ec_byte, 1, NULL, 0);
}
}
EXPORT_SYMBOL_GPL(olpc_ec_mask_write);

int olpc_ec_sci_query(u16 *sci_value)
{
int ret;

if (olpc_platform_info.flags & OLPC_F_EC_WIDE_SCI) {
__be16 ec_word;
ret = olpc_ec_cmd(EC_EXT_SCI_QUERY,
NULL, 0, (void *) &ec_word, 2);
if (ret == 0)
*sci_value = be16_to_cpu(ec_word);
} else {
unsigned char ec_byte;
ret = olpc_ec_cmd(EC_SCI_QUERY, NULL, 0, &ec_byte, 1);
if (ret == 0)
*sci_value = ec_byte;
}

return ret;
}
EXPORT_SYMBOL_GPL(olpc_ec_sci_query);

static int olpc_ec_suspend(void)
{
return olpc_ec_mask_write(ec_wakeup_mask);
}

static bool __init check_ofw_architecture(struct device_node *root)
{
const char *olpc_arch;
Expand Down Expand Up @@ -242,6 +319,10 @@ static int __init add_xo1_platform_devices(void)
return 0;
}

static struct syscore_ops olpc_syscore_ops = {
.suspend = olpc_ec_suspend,
};

static int __init olpc_init(void)
{
int r = 0;
Expand All @@ -266,6 +347,9 @@ static int __init olpc_init(void)
!cs5535_has_vsa2())
x86_init.pci.arch_init = pci_olpc_init;
#endif
/* EC version 0x5f adds support for wide SCI mask */
if (olpc_platform_info.ecver >= 0x5f)
olpc_platform_info.flags |= OLPC_F_EC_WIDE_SCI;

printk(KERN_INFO "OLPC board revision %s%X (EC=%x)\n",
((olpc_platform_info.boardrev & 0xf) < 8) ? "pre" : "",
Expand All @@ -278,6 +362,8 @@ static int __init olpc_init(void)
return r;
}

register_syscore_ops(&olpc_syscore_ops);

return 0;
}

Expand Down

0 comments on commit 8a650e1

Please sign in to comment.