summaryrefslogtreecommitdiff
path: root/target/linux/olpc/files/arch/i386/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/olpc/files/arch/i386/kernel')
-rw-r--r--target/linux/olpc/files/arch/i386/kernel/mfgpt.c354
-rw-r--r--target/linux/olpc/files/arch/i386/kernel/ofw.c100
-rw-r--r--target/linux/olpc/files/arch/i386/kernel/olpc-pm.c785
-rw-r--r--target/linux/olpc/files/arch/i386/kernel/olpc-sleep.S39
-rw-r--r--target/linux/olpc/files/arch/i386/kernel/olpc-wakeup.S122
-rw-r--r--target/linux/olpc/files/arch/i386/kernel/olpc.c320
-rw-r--r--target/linux/olpc/files/arch/i386/kernel/prom.c478
7 files changed, 0 insertions, 2198 deletions
diff --git a/target/linux/olpc/files/arch/i386/kernel/mfgpt.c b/target/linux/olpc/files/arch/i386/kernel/mfgpt.c
deleted file mode 100644
index 2e62a41e7f..0000000000
--- a/target/linux/olpc/files/arch/i386/kernel/mfgpt.c
+++ /dev/null
@@ -1,354 +0,0 @@
-/* Driver/API for AMD Geode Multi-Function General Purpose Timers (MFGPT)
- *
- * Copyright (C) 2006, Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-/* The MFPGT timers on the CS5536 provide us with suitable timers to use
- * as clock event sources - not as good as a HPET or APIC, but certainly
- * better then the PIT. This isn't a general purpose MFGPT driver, but
- * a simplified one designed specifically to act as a clock event source.
- * For full details about the MFGPT, please consult the CS5536 data sheet.
-*/
-
-/* We are using the 32Khz input clock - its the only one that has the
- * ranges we find desirable. The following table lists the suitable
- * divisors and the associated hz, minimum interval
- * and the maximum interval:
-
- Divisor Hz Min Delta (S) Max Delta (S)
- 1 32000 .0005 2.048
- 2 16000 .001 4.096
- 4 8000 .002 8.192
- 8 4000 .004 16.384
- 16 2000 .008 32.768
- 32 1000 .016 65.536
- 64 500 .032 131.072
- 128 250 .064 262.144
- 256 125 .128 524.288
-*/
-
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
-#include <asm/geode.h>
-
-#include "do_timer.h"
-
-#define MFGPT_MAX_TIMERS 8
-
-#define F_AVAIL 0x01
-
-static struct mfgpt_timer_t {
- int flags;
- struct module *owner;
-} mfgpt_timers[MFGPT_MAX_TIMERS];
-
-/* Selected from the table above */
-
-#define MFGPT_DIVISOR 16
-#define MFGPT_SCALE 4 /* divisor = 2^(scale) */
-#define MFGPT_HZ (32000 / MFGPT_DIVISOR)
-#define MFGPT_PERIODIC (MFGPT_HZ / HZ)
-
-#ifdef CONFIG_GEODE_MFGPT_TIMER
-static int __init mfgpt_timer_setup(void);
-#else
-#define mfgpt_timer_setup() (0)
-#endif
-
-/* Allow for disabling of MFGPTs */
-static int disable = 0;
-static int __init mfgpt_disable(char *s)
-{
- disable = 1;
- return 1;
-}
-__setup("nomfgpt", mfgpt_disable);
-
-/*
- * Check whether any MFGPTs are available for the kernel to use. In most
- * cases, firmware that uses AMD's VSA code will claim all timers during
- * bootup; we certainly don't want to take them if they're already in use.
- * In other cases (such as with VSAless OpenFirmware), the system firmware
- * leaves timers available for us to use.
- */
-int __init geode_mfgpt_detect(void)
-{
- int count = 0, i;
- u16 val;
-
- if (disable) {
- printk(KERN_INFO "geode-mfgpt: Skipping MFGPT setup\n");
- return 0;
- }
-
- for (i = 0; i < MFGPT_MAX_TIMERS; i++) {
- val = geode_mfgpt_read(i, MFGPT_REG_SETUP);
- if (!(val & MFGPT_SETUP_SETUP)) {
- mfgpt_timers[i].flags = F_AVAIL;
- count++;
- }
- }
-
- /* set up clock event device, if desired */
- i = mfgpt_timer_setup();
-
- return count;
-}
-
-int geode_mfgpt_toggle_event(int timer, int cmp, int event, int enable)
-{
- u32 msr, mask, value, dummy;
- int shift = (cmp == MFGPT_CMP1) ? 0 : 8;
-
- if (timer < 0 || timer >= MFGPT_MAX_TIMERS)
- return -EIO;
-
- /*
- * The register maps for these are described in sections 6.17.1.x of
- * the AMD Geode CS5536 Companion Device Data Book.
- */
- switch(event) {
- case MFGPT_EVENT_RESET:
- /* XXX: According to the docs, we cannot reset timers above
- * 6; that is, resets for 7 and 8 will be ignored. Is this
- * a problem? */
- msr = MFGPT_NR_MSR;
- mask = 1 << (timer + 24);
- break;
-
- case MFGPT_EVENT_NMI:
- msr = MFGPT_NR_MSR;
- mask = 1 << (timer + shift);
- break;
-
- case MFGPT_EVENT_IRQ:
- msr = MFGPT_IRQ_MSR;
- mask = 1 << (timer + shift);
- break;
-
- default:
- return -EIO;
- }
-
- rdmsr(msr, value, dummy);
-
- if (enable)
- value |= mask;
- else
- value &= ~mask;
-
- wrmsr(msr, value, dummy);
- return 0;
-}
-EXPORT_SYMBOL(geode_mfgpt_toggle_event);
-
-int geode_mfgpt_set_irq(int timer, int cmp, int irq, int enable)
-{
- u32 val, dummy;
- int offset;
-
- if (timer < 0 || timer >= MFGPT_MAX_TIMERS)
- return -EIO;
-
- if (geode_mfgpt_toggle_event(timer, cmp, MFGPT_EVENT_IRQ, enable))
- return -EIO;
-
- rdmsr(0x51400022, val, dummy);
-
- offset = (timer % 4) * 4;
-
- val &= ~((0xF << offset) | (0xF << (offset + 16)));
-
- if (enable) {
- val |= (irq & 0x0F) << (offset);
- val |= (irq & 0x0F) << (offset + 16);
- }
-
- wrmsr(0x51400022, val, dummy);
- return 0;
-}
-EXPORT_SYMBOL(geode_mfgpt_set_irq);
-
-static int mfgpt_get(int timer, struct module *owner)
-{
- mfgpt_timers[timer].flags &= ~F_AVAIL;
- mfgpt_timers[timer].owner = owner;
- printk(KERN_INFO "geode-mfgpt: Registered timer %d\n", timer);
- return timer;
-}
-
-int geode_mfgpt_alloc_timer(int timer, int domain, struct module *owner)
-{
- int i;
-
- if (!geode_get_dev_base(GEODE_DEV_MFGPT))
- return -ENODEV;
- if (timer >= MFGPT_MAX_TIMERS)
- return -EIO;
-
- if (timer < 0) {
- /* Try to find an available timer */
- for (i = 0; i < MFGPT_MAX_TIMERS; i++) {
- if (mfgpt_timers[i].flags & F_AVAIL)
- return mfgpt_get(i, owner);
-
- if (i == 5 && domain == MFGPT_DOMAIN_WORKING)
- break;
- }
- }
- else {
- /* If they requested a specific timer, try to honor that */
- if (mfgpt_timers[timer].flags & F_AVAIL)
- return mfgpt_get(timer, owner);
- }
-
- /* No timers available - too bad */
- return -1;
-}
-EXPORT_SYMBOL(geode_mfgpt_alloc_timer);
-
-#ifdef CONFIG_GEODE_MFGPT_TIMER
-
-static unsigned int mfgpt_tick_mode = CLOCK_EVT_MODE_SHUTDOWN;
-static u16 mfgpt_event_clock;
-
-static int irq = 7;
-static int __init mfgpt_setup(char *str)
-{
- get_option(&str, &irq);
- return 1;
-}
-__setup("mfgpt_irq=", mfgpt_setup);
-
-static inline void mfgpt_disable_timer(u16 clock)
-{
- u16 val = geode_mfgpt_read(clock, MFGPT_REG_SETUP);
- geode_mfgpt_write(clock, MFGPT_REG_SETUP, val & ~MFGPT_SETUP_CNTEN);
-}
-
-static int mfgpt_next_event(unsigned long, struct clock_event_device *);
-static void mfgpt_set_mode(enum clock_event_mode, struct clock_event_device *);
-
-static struct clock_event_device mfgpt_clockevent = {
- .name = "mfgpt-timer",
- .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
- .set_mode = mfgpt_set_mode,
- .set_next_event = mfgpt_next_event,
- .rating = 250,
- .cpumask = CPU_MASK_ALL,
- .shift = 32
-};
-
-static inline void mfgpt_start_timer(u16 clock, u16 delta)
-{
- geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_CMP2, (u16) delta);
- geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_COUNTER, 0);
-
- geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_SETUP,
- MFGPT_SETUP_CNTEN | MFGPT_SETUP_CMP2);
-}
-
-static void mfgpt_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
-{
- mfgpt_disable_timer(mfgpt_event_clock);
-
- if (mode == CLOCK_EVT_MODE_PERIODIC)
- mfgpt_start_timer(mfgpt_event_clock, MFGPT_PERIODIC);
-
- mfgpt_tick_mode = mode;
-}
-
-static int mfgpt_next_event(unsigned long delta, struct clock_event_device *evt)
-{
- mfgpt_start_timer(mfgpt_event_clock, delta);
- return 0;
-}
-
-/* Assume (foolishly?), that this interrupt was due to our tick */
-
-static irqreturn_t mfgpt_tick(int irq, void *dev_id)
-{
- if (mfgpt_tick_mode == CLOCK_EVT_MODE_SHUTDOWN)
- return IRQ_HANDLED;
-
- /* Turn off the clock */
- mfgpt_disable_timer(mfgpt_event_clock);
-
- /* Clear the counter */
- geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_COUNTER, 0);
-
- /* Restart the clock in periodic mode */
-
- if (mfgpt_tick_mode == CLOCK_EVT_MODE_PERIODIC) {
- geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_SETUP,
- MFGPT_SETUP_CNTEN | MFGPT_SETUP_CMP2);
- }
-
- mfgpt_clockevent.event_handler(&mfgpt_clockevent);
- return IRQ_HANDLED;
-}
-
-static struct irqaction mfgptirq = {
- .handler = mfgpt_tick,
- .flags = IRQF_DISABLED | IRQF_NOBALANCING,
- .mask = CPU_MASK_NONE,
- .name = "mfgpt-timer"
-};
-
-static int __init mfgpt_timer_setup(void)
-{
- int timer, ret;
- u16 val;
-
- timer = geode_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING, THIS_MODULE);
- if (timer < 0) {
- printk(KERN_ERR "mfgpt-timer: Could not allocate a MFPGT timer\n");
- return -ENODEV;
- }
-
- mfgpt_event_clock = timer;
- /* Set the clock scale and enable the event mode for CMP2 */
- val = MFGPT_SCALE | (3 << 8);
-
- geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_SETUP, val);
-
- /* Set up the IRQ on the MFGPT side */
- if (geode_mfgpt_setup_irq(mfgpt_event_clock, MFGPT_CMP2, irq)) {
- printk(KERN_ERR "mfgpt-timer: Could not set up IRQ %d\n", irq);
- return -EIO;
- }
-
- /* And register it with the kernel */
- ret = setup_irq(irq, &mfgptirq);
-
- if (ret) {
- printk(KERN_ERR "mfgpt-timer: Unable to set up the interrupt.\n");
- goto err;
- }
-
- /* Set up the clock event */
- mfgpt_clockevent.mult = div_sc(MFGPT_HZ, NSEC_PER_SEC, 32);
- mfgpt_clockevent.min_delta_ns = clockevent_delta2ns(0xF, &mfgpt_clockevent);
- mfgpt_clockevent.max_delta_ns = clockevent_delta2ns(0xFFFE, &mfgpt_clockevent);
-
- printk("mfgpt-timer: registering the MFGT timer as a clock event.\n");
- clockevents_register_device(&mfgpt_clockevent);
-
- return 0;
-
-err:
- geode_mfgpt_release_irq(mfgpt_event_clock, MFGPT_CMP2, irq);
- printk(KERN_ERR "mfgpt-timer: Unable to set up the MFGPT clock source\n");
- return -EIO;
-}
-
-#endif
diff --git a/target/linux/olpc/files/arch/i386/kernel/ofw.c b/target/linux/olpc/files/arch/i386/kernel/ofw.c
deleted file mode 100644
index fdcd93629a..0000000000
--- a/target/linux/olpc/files/arch/i386/kernel/ofw.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * ofw.c - Open Firmware client interface for 32-bit systems.
- * This code is intended to be portable to any 32-bit Open Firmware
- * implementation with a standard client interface that can be
- * called when Linux is running.
- *
- * Copyright (C) 2007 Mitch Bradley <wmb@firmworks.com>
- * Copyright (C) 2007 Andres Salomon <dilinger@debian.org>
- */
-
-#include <stdarg.h>
-#include <linux/spinlock.h>
-#include <linux/module.h>
-#include <asm/ofw.h>
-
-
-int (*call_firmware)(int *);
-
-static DEFINE_SPINLOCK(prom_lock);
-
-#define MAXARGS 20
-
-/*
- * The return value from ofw() in all cases is 0 if the attempt to call the
- * function succeeded, <0 otherwise. That return value is from the
- * gateway function only. Any results from the called function are returned
- * via output argument pointers.
- *
- * Here are call templates for all the standard OFW client services:
- *
- * ofw("test", 1, 1, namestr, &missing);
- * ofw("peer", 1, 1, phandle, &sibling_phandle);
- * ofw("child", 1, 1, phandle, &child_phandle);
- * ofw("parent", 1, 1, phandle, &parent_phandle);
- * ofw("instance_to_package", 1, 1, ihandle, &phandle);
- * ofw("getproplen", 2, 1, phandle, namestr, &proplen);
- * ofw("getprop", 4, 1, phandle, namestr, bufaddr, buflen, &size);
- * ofw("nextprop", 3, 1, phandle, previousstr, bufaddr, &flag);
- * ofw("setprop", 4, 1, phandle, namestr, bufaddr, len, &size);
- * ofw("canon", 3, 1, devspecstr, bufaddr, buflen, &length);
- * ofw("finddevice", 1, 1, devspecstr, &phandle);
- * ofw("instance-to-path", 3, 1, ihandle, bufaddr, buflen, &length);
- * ofw("package-to-path", 3, 1, phandle, bufaddr, buflen, &length);
- * ofw("call_method", numin, numout, in0, in1, ..., &out0, &out1, ...);
- * ofw("open", 1, 1, devspecstr, &ihandle);
- * ofw("close", 1, 0, ihandle);
- * ofw("read", 3, 1, ihandle, addr, len, &actual);
- * ofw("write", 3, 1, ihandle, addr, len, &actual);
- * ofw("seek", 3, 1, ihandle, pos_hi, pos_lo, &status);
- * ofw("claim", 3, 1, virtaddr, size, align, &baseaddr);
- * ofw("release", 2, 0, virtaddr, size);
- * ofw("boot", 1, 0, bootspecstr);
- * ofw("enter", 0, 0);
- * ofw("exit", 0, 0);
- * ofw("chain", 5, 0, virtaddr, size, entryaddr, argsaddr, len);
- * ofw("interpret", numin+1, numout+1, cmdstr, in0, ..., &catchres, &out0, ...);
- * ofw("set-callback", 1, 1, newfuncaddr, &oldfuncaddr);
- * ofw("set-symbol-lookup", 2, 0, symtovaladdr, valtosymaddr);
- * ofw("milliseconds", 0, 1, &ms);
- */
-
-int ofw(char *name, int numargs, int numres, ...)
-{
- va_list ap;
- int argarray[MAXARGS+3];
- int argnum = 3;
- int retval;
- int *intp;
- unsigned long flags;
-
- if (!call_firmware)
- return -1;
- if ((numargs + numres) > MAXARGS)
- return -1; /* spit out an error? */
-
- argarray[0] = (int) name;
- argarray[1] = numargs;
- argarray[2] = numres;
-
- va_start(ap, numres);
- while (numargs) {
- argarray[argnum++] = va_arg(ap, int);
- numargs--;
- }
-
- spin_lock_irqsave(&prom_lock, flags);
- retval = call_firmware(argarray);
- spin_unlock_irqrestore(&prom_lock, flags);
-
- if (retval == 0) {
- while (numres) {
- intp = va_arg(ap, int *);
- *intp = argarray[argnum++];
- numres--;
- }
- }
- va_end(ap);
- return retval;
-}
-EXPORT_SYMBOL(ofw);
diff --git a/target/linux/olpc/files/arch/i386/kernel/olpc-pm.c b/target/linux/olpc/files/arch/i386/kernel/olpc-pm.c
deleted file mode 100644
index 93149f1c38..0000000000
--- a/target/linux/olpc/files/arch/i386/kernel/olpc-pm.c
+++ /dev/null
@@ -1,785 +0,0 @@
-/* olpc-pm.c
- * © 2006 Red Hat, Inc.
- * Portions also copyright 2006 Advanced Micro Devices, Inc.
- * GPLv2
- */
-
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/input.h>
-#include <linux/suspend.h>
-#include <linux/bootmem.h>
-#include <linux/platform_device.h>
-#include <linux/rtc.h>
-#include <linux/mc146818rtc.h>
-#include <asm/io.h>
-
-#include <asm/olpc.h>
-
-/* A few words about accessing the ACPI and PM registers. Long story short,
- byte and word accesses of the ACPI and PM registers is broken. The only
- way to do it really correctly is to use dword accesses, which we do
- throughout this code. For more details, please consult Eratta 17 and 18
- here:
-
- http://www.amd.com/files/connectivitysolutions/geode/geode_gx/34472D_CS5536_B1_specupdate.pdf
-*/
-
-#define PM_IRQ 3
-
-#define CS5536_PM_PWRBTN (1 << 8)
-#define CS5536_PM_RTC (1 << 10)
-
-#define GPIO_WAKEUP_EC (1 << 31)
-#define GPIO_WAKEUP_LID (1 << 30)
-
-#define PM_MODE_NORMAL 0
-#define PM_MODE_TEST 1
-#define PM_MODE_MAX 2
-
-/* These, and the battery EC commands, should be in an olpc.h. */
-#define EC_WRITE_SCI_MASK 0x1b
-#define EC_READ_SCI_MASK 0x1c
-
-extern void do_olpc_suspend_lowlevel(void);
-
-static struct {
- unsigned long address;
- unsigned short segment;
-} ofw_bios_entry = { 0, __KERNEL_CS };
-
-static int olpc_pm_mode = PM_MODE_NORMAL;
-static unsigned long acpi_base;
-static unsigned long pms_base;
-static int sci_irq;
-static int olpc_lid_flag;
-
-static struct input_dev *pm_inputdev;
-static struct input_dev *lid_inputdev;
-static struct input_dev *ebook_inputdev;
-static struct pm_ops olpc_pm_ops;
-
-static int gpio_wake_events = 0;
-static int ebook_state = -1;
-static u16 olpc_wakeup_mask = 0;
-
-struct platform_device olpc_powerbutton_dev = {
- .name = "powerbutton",
- .id = -1,
-};
-
-struct platform_device olpc_lid_dev = {
- .name = "lid",
- .id = -1,
-};
-
-static void __init init_ebook_state(void)
-{
- if (olpc_ec_cmd(0x2a, NULL, 0, (unsigned char *) &ebook_state, 1)) {
- printk(KERN_WARNING "olpc-pm: failed to get EBOOK state!\n");
- ebook_state = 0;
- }
- ebook_state &= 1;
-
- /* the input layer needs to know what value to default to as well */
- input_report_switch(ebook_inputdev, SW_TABLET_MODE, ebook_state);
- input_sync(ebook_inputdev);
-}
-
-static void (*battery_callback)(unsigned long);
-static DEFINE_SPINLOCK(battery_callback_lock);
-
-/* propagate_events is non-NULL if run from workqueue,
- NULL when called at init time to flush SCI queue */
-static void process_sci_queue(struct work_struct *propagate_events)
-{
- unsigned char data = 0;
- unsigned char battery_events = 0;
- int ret;
-
- do {
- ret = olpc_ec_cmd(0x84, NULL, 0, &data, 1);
- if (!ret) {
- printk(KERN_DEBUG "olpc-pm: SCI 0x%x received\n",
- data);
-
- switch (data) {
- case EC_SCI_SRC_EMPTY:
- case EC_SCI_SRC_GAME:
- case EC_SCI_SRC_WLAN:
- /* we ignore these for now */
- break;
- case EC_SCI_SRC_BATERR:
- printk(KERN_ERR "olpc-pm: Battery Management System detected an error! Remove turnip from battery slot.\n");
- case EC_SCI_SRC_BATSOC:
- case EC_SCI_SRC_BATTERY:
- case EC_SCI_SRC_ACPWR:
- battery_events |= data;
- break;
- case EC_SCI_SRC_EBOOK:
- ebook_state = !ebook_state;
- if (propagate_events) {
- input_report_switch(ebook_inputdev,
- SW_TABLET_MODE, ebook_state);
- input_sync(ebook_inputdev);
- }
- break;
- default:
- printk(KERN_ERR "olpc-pm: Unknown SCI event 0x%x occurred!\n", data);
- }
- }
- } while (data && !ret);
-
- if (battery_events && battery_callback && propagate_events) {
- void (*cbk)(unsigned long);
-
- /* Older EC versions didn't distinguish between AC and battery
- events */
- if (olpc_platform_info.ecver < 0x45)
- battery_events = EC_SCI_SRC_BATTERY | EC_SCI_SRC_ACPWR;
-
- spin_lock(&battery_callback_lock);
- cbk = battery_callback;
- spin_unlock(&battery_callback_lock);
-
- cbk(battery_events);
- }
-
- if (ret)
- printk(KERN_WARNING "Failed to clear SCI queue!\n");
-}
-
-static DECLARE_WORK(sci_work, process_sci_queue);
-
-void olpc_register_battery_callback(void (*f)(unsigned long))
-{
- spin_lock(&battery_callback_lock);
- battery_callback = f;
- spin_unlock(&battery_callback_lock);
-}
-EXPORT_SYMBOL_GPL(olpc_register_battery_callback);
-
-void olpc_deregister_battery_callback(void)
-{
- spin_lock(&battery_callback_lock);
- battery_callback = NULL;
- spin_unlock(&battery_callback_lock);
- cancel_work_sync(&sci_work);
-}
-EXPORT_SYMBOL_GPL(olpc_deregister_battery_callback);
-
-
-static int olpc_pm_interrupt(int irq, void *id)
-{
- uint32_t sts, gpe = 0;
-
- sts = inl(acpi_base + PM1_STS);
- outl(sts | 0xFFFF, acpi_base + PM1_STS);
-
- if (olpc_get_rev() >= OLPC_REV_B2) {
- gpe = inl(acpi_base + PM_GPE0_STS);
- outl(0xFFFFFFFF, acpi_base + PM_GPE0_STS);
- }
-
- if (sts & CS5536_PM_PWRBTN) {
- input_report_key(pm_inputdev, KEY_POWER, 1);
- input_sync(pm_inputdev);
- printk(KERN_DEBUG "olpm-pm: PM_PWRBTN event received\n");
- /* Do we need to delay this (and hence schedule_work)? */
- input_report_key(pm_inputdev, KEY_POWER, 0);
- input_sync(pm_inputdev);
- }
-
- if (gpe & GPIO_WAKEUP_EC) {
- geode_gpio_clear(OLPC_GPIO_ECSCI, GPIO_NEGATIVE_EDGE_STS);
- schedule_work(&sci_work);
- }
-
- if (gpe & GPIO_WAKEUP_LID) {
- /* Disable events */
- geode_gpio_clear(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
-
- /* Clear the edge */
-
- if (olpc_lid_flag)
- geode_gpio_clear(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_EN);
- else
- geode_gpio_clear(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_EN);
-
- /* Clear the status too */
- geode_gpio_set(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_STS);
- geode_gpio_set(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_STS);
-
- /* The line is high when the LID is open, but SW_LID
- * should be high when the LID is closed, so we pass the old
- * value of olpc_lid_flag
- */
-
- input_report_switch(lid_inputdev, SW_LID, olpc_lid_flag);
- input_sync(lid_inputdev);
-
- /* Swap the status */
- olpc_lid_flag = !olpc_lid_flag;
-
- if (olpc_lid_flag)
- geode_gpio_set(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_EN);
- else
- geode_gpio_set(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_EN);
-
- /* re-enable the event */
- geode_gpio_set(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
- }
-
- return IRQ_HANDLED;
-}
-
-/*
- * For now, only support STR. We also don't support suspending on
- * B1s, due to difficulties with the cafe FPGA.
- */
-static int olpc_pm_state_valid(suspend_state_t pm_state)
-{
- if (pm_state == PM_SUSPEND_MEM && olpc_rev_after(OLPC_REV_B1))
- return 1;
-
- return 0;
-}
-
-/* This is a catchall function for operations that just don't belong
- * anywhere else. Later we will evaluate if these belong in the
- * individual device drivers or the firmware.
- * If you add something to this function, please explain yourself with
- * a comment.
- */
-
-extern void gxfb_flatpanel_control(int state);
-
-static u32 gpio_wakeup[2];
-static u64 irq_sources[4];
-static u64 mfgpt_irq_msr, mfgpt_nr_msr;
-
-void olpc_fixup_wakeup(void)
-{
- u32 base = geode_gpio_base();
- int i;
-
- /* This clears any pending events from the status register -
- * the firmware also does this, but its possible that it tries
- * it too early before the key has a chance to debounce
- */
-
- outl((CS5536_PM_PWRBTN << 16) | 0xFFFF, acpi_base + PM1_STS);
-
- /* Enable the flatpanel sequencing as early as possible, because
- it takes ~64ms to resume. This probably belongs in the firmware */
-
- //gxfb_flatpanel_control(1);
-
- /* Restore the interrupt sources */
- wrmsrl(MSR_PIC_YSEL_LOW, irq_sources[0]);
- wrmsrl(MSR_PIC_ZSEL_LOW, irq_sources[1]);
- wrmsrl(MSR_PIC_YSEL_HIGH, irq_sources[2]);
- wrmsrl(MSR_PIC_ZSEL_HIGH, irq_sources[3]);
-
- /* Restore the X and Y sources for GPIO */
- outl(gpio_wakeup[0], base + GPIO_MAP_X);
- outl(gpio_wakeup[1], base + GPIO_MAP_Y);
-
- /* Resture the MFGPT MSRs */
- wrmsrl(MFGPT_IRQ_MSR, mfgpt_irq_msr);
- wrmsrl(MFGPT_NR_MSR, mfgpt_nr_msr);
-
- for (i=0;i<2;i++) {
- /* tell the wireless module to restart USB communication */
- olpc_ec_cmd(0x24, NULL, 0, NULL, 0);
- }
-}
-
-void olpc_fixup_sleep(void)
-{
- u32 base = geode_gpio_base();
- int i;
-
- /* Save the X and Y sources for GPIO */
- gpio_wakeup[0] = inl(base + GPIO_MAP_X);
- gpio_wakeup[1] = inl(base + GPIO_MAP_Y);
-
- /* Save the Y and Z unrestricted sources */
-
- rdmsrl(MSR_PIC_YSEL_LOW, irq_sources[0]);
- rdmsrl(MSR_PIC_ZSEL_LOW, irq_sources[1]);
- rdmsrl(MSR_PIC_YSEL_HIGH, irq_sources[2]);
- rdmsrl(MSR_PIC_ZSEL_HIGH, irq_sources[3]);
-
- /* Turn off the MFGPT timers on the way down */
-
- for(i = 0; i < 8; i++) {
- u32 val = geode_mfgpt_read(i, MFGPT_REG_SETUP);
-
- if (val & MFGPT_SETUP_SETUP) {
- val &= ~MFGPT_SETUP_CNTEN;
- geode_mfgpt_write(i, MFGPT_REG_SETUP, val);
- }
- }
-
- /* Save the MFGPT MSRs */
- rdmsrl(MFGPT_IRQ_MSR, mfgpt_irq_msr);
- rdmsrl(MFGPT_NR_MSR, mfgpt_nr_msr);
-
- if (device_may_wakeup(&olpc_powerbutton_dev.dev))
- olpc_wakeup_mask |= CS5536_PM_PWRBTN;
- else
- olpc_wakeup_mask &= ~(CS5536_PM_PWRBTN);
-
- if (device_may_wakeup(&olpc_lid_dev.dev)) {
- geode_gpio_set(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
- gpio_wake_events |= GPIO_WAKEUP_LID;
- } else {
- geode_gpio_clear(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
- gpio_wake_events &= ~(GPIO_WAKEUP_LID);
- }
-}
-
-static int olpc_pm_enter(suspend_state_t pm_state)
-{
- /* Only STR is supported */
- if (pm_state != PM_SUSPEND_MEM)
- return -EINVAL;
-
- olpc_fixup_sleep();
-
- /* Set the GPIO wakeup bits */
- outl(gpio_wake_events, acpi_base + PM_GPE0_EN);
- outl(0xFFFFFFFF, acpi_base + PM_GPE0_STS);
-
- /* Save CPU state */
- do_olpc_suspend_lowlevel();
-
- olpc_fixup_wakeup();
-
- /* Restore the SCI wakeup events */
- outl(gpio_wake_events, acpi_base + PM_GPE0_EN);
-
- return 0;
-}
-
-int asmlinkage olpc_do_sleep(u8 sleep_state)
-{
- void *pgd_addr = __va(read_cr3());
- printk(KERN_ERR "olpc_do_sleep!\n"); /* this needs to remain here so
- * that gcc doesn't optimize
- * away our __va! */
- /* FIXME: Set the SCI bits we want to wake up on here */
-
- /* FIXME: Set any other SCI events that we might want here */
-
- outl((olpc_wakeup_mask << 16) | 0xFFFF, acpi_base + PM1_STS);
-
- /* If we are in test mode, then just return (simulate a successful
- suspend/resume). Otherwise, if we are doing the real thing,
- then go for the gusto */
-
- if (olpc_pm_mode != PM_MODE_TEST) {
- __asm__ __volatile__("movl %0,%%eax" : : "r" (pgd_addr));
- __asm__("call *(%%edi); cld"
- : : "D" (&ofw_bios_entry));
- }
-
- return 0;
-}
-
-/* This code will slowly disappear as we fixup the issues in the BIOS */
-
-static void __init olpc_fixup_bios(void)
-{
- unsigned long hi, lo;
-
- if (olpc_has_vsa()) {
- /* The VSA aggressively sets up the ACPI and PM register for
- * trapping - its not enough to force these values in the BIOS -
- * they seem to be changed during PCI init as well.
- */
-
- /* Change the PM registers to decode to the DD */
-
- rdmsr(0x510100e2, lo, hi);
- hi |= 0x80000000;
- wrmsr(0x510100e2, lo, hi);
-
- /* Change the ACPI registers to decode to the DD */
-
- rdmsr(0x510100e3, lo, hi);
- hi |= 0x80000000;
- wrmsr(0x510100e3, lo, hi);
- }
-
- /* GPIO24 controls WORK_AUX */
-
- geode_gpio_set(OLPC_GPIO_WORKAUX, GPIO_OUTPUT_ENABLE);
- geode_gpio_set(OLPC_GPIO_WORKAUX, GPIO_OUTPUT_AUX1);
-
- if (olpc_get_rev() >= OLPC_REV_B2) {
- /* GPIO10 is connected to the thermal alarm */
- geode_gpio_set(OLPC_GPIO_THRM_ALRM, GPIO_INPUT_ENABLE);
- geode_gpio_set(OLPC_GPIO_THRM_ALRM, GPIO_INPUT_AUX1);
-
- /* Set up to get LID events */
- geode_gpio_set(OLPC_GPIO_LID, GPIO_INPUT_ENABLE);
-
- /* Clear edge detection and event enable for now */
- geode_gpio_clear(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
- geode_gpio_clear(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_EN);
- geode_gpio_clear(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_EN);
-
- geode_gpio_set(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_STS);
- geode_gpio_set(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_STS);
-
- /* Set the LID to cause an PME event on group 6 */
- geode_gpio_event_pme(OLPC_GPIO_LID, 6);
-
- /* Set PME group 6 to fire the SCI interrupt */
- geode_gpio_set_irq(6, sci_irq);
- }
-
- geode_gpio_set(OLPC_GPIO_ECSCI, GPIO_INPUT_ENABLE);
-
- /* Clear pending events */
-
- geode_gpio_set(OLPC_GPIO_ECSCI, GPIO_NEGATIVE_EDGE_STS);
- geode_gpio_set(OLPC_GPIO_ECSCI, GPIO_POSITIVE_EDGE_STS);
-
- //geode_gpio_set(OLPC_GPIO_ECSCI, GPIO_NEGATIVE_EDGE_EN);
- geode_gpio_set(OLPC_GPIO_ECSCI, GPIO_EVENTS_ENABLE);
-
- /* Set the SCI to cause a PME event on group 7 */
- geode_gpio_event_pme(OLPC_GPIO_ECSCI, 7);
-
- /* And have group 6 also fire the SCI interrupt */
- geode_gpio_set_irq(7, sci_irq);
-}
-
-/* This provides a control file for setting up testing of the
- power management system. For now, there is just one setting:
- "test" which means that we don't actually enter the power
- off routine.
-*/
-
-static const char * const pm_states[] = {
- [PM_MODE_NORMAL] = "normal",
- [PM_MODE_TEST] = "test",
-};
-
-extern struct mutex pm_mutex;
-extern struct kset power_subsys;
-
-static ssize_t control_show(struct kset *s, char *buf)
-{
- return sprintf(buf, "%s\n", pm_states[olpc_pm_mode]);
-}
-
-static ssize_t control_store(struct kset *s, const char *buf, size_t n)
-{
- int i, len;
- char *p;
-
- p = memchr(buf, '\n', n);
- len = p ? p - buf : n;
-
- /* Grab the mutex */
- mutex_lock(&pm_mutex);
-
- for(i = 0; i < PM_MODE_MAX; i++) {
- if (!strncmp(buf, pm_states[i], len)) {
- olpc_pm_mode = i;
- break;
- }
- }
-
- mutex_unlock(&pm_mutex);
-
- return (i == PM_MODE_MAX) ? -EINVAL : n;
-}
-
-static struct subsys_attribute control_attr = {
- .attr = {
- .name = "olpc-pm",
- .mode = 0644,
- },
- .show = control_show,
- .store = control_store,
-};
-
-static struct attribute * olpc_attributes[] = {
- &control_attr.attr,
- NULL
-};
-
-static struct attribute_group olpc_attrs = {
- .attrs = olpc_attributes,
-};
-
-static int __init alloc_inputdevs(void)
-{
- int ret = -ENOMEM;
-
- pm_inputdev = input_allocate_device();
- if (!pm_inputdev)
- goto err;
-
- pm_inputdev->name = "OLPC PM";
- pm_inputdev->phys = "olpc_pm/input0";
- set_bit(EV_KEY, pm_inputdev->evbit);
- set_bit(KEY_POWER, pm_inputdev->keybit);
-
- ret = input_register_device(pm_inputdev);
- if (ret) {
- printk(KERN_ERR "olpc-pm: failed to register PM input device: %d\n", ret);
- goto err;
- }
-
- lid_inputdev = input_allocate_device();
- if (!lid_inputdev)
- goto err;
-
- lid_inputdev->name = "OLPC lid switch";
- lid_inputdev->phys = "olpc_pm/input1";
- set_bit(EV_SW, lid_inputdev->evbit);
- set_bit(SW_LID, lid_inputdev->swbit);
-
- ret = input_register_device(lid_inputdev);
- if (ret) {
- printk(KERN_ERR "olpc-pm: failed to register lid input device: %d\n", ret);
- goto err;
- }
-
- ebook_inputdev = input_allocate_device();
- if (!ebook_inputdev)
- goto err;
-
- ebook_inputdev->name = "OLPC ebook switch";
- ebook_inputdev->phys = "olpc_pm/input2";
- set_bit(EV_SW, ebook_inputdev->evbit);
- set_bit(SW_TABLET_MODE, ebook_inputdev->swbit);
-
- ret = input_register_device(ebook_inputdev);
- if (ret) {
- printk(KERN_ERR "olpc-pm: failed to register ebook input device: %d\n", ret);
- goto err;
- }
-
- return ret;
-err:
- if (ebook_inputdev) {
- input_unregister_device(ebook_inputdev);
- ebook_inputdev = NULL;
- }
- if (lid_inputdev) {
- input_unregister_device(lid_inputdev);
- lid_inputdev = NULL;
- }
- if (pm_inputdev) {
- input_unregister_device(pm_inputdev);
- pm_inputdev = NULL;
- }
-
- return ret;
-}
-
-static int __init olpc_pm_init(void)
-{
- uint32_t lo, hi;
- int ret;
- uint8_t ec_byte;
-
- if (!machine_is_olpc())
- return -ENODEV;
-
- acpi_base = geode_acpi_base();
- pms_base = geode_pms_base();
-
- if (!acpi_base || !pms_base)
- return -ENODEV;
-
- ret = alloc_inputdevs();
- if (ret)
- return ret;
-
- rdmsr(0x51400020, lo, hi);
- sci_irq = (lo >> 20) & 15;
-
- if (sci_irq) {
- printk(KERN_INFO "SCI is mapped to IRQ %d\n", sci_irq);
- } else {
- /* Zero doesn't mean zero -- it means masked */
- printk(KERN_INFO "SCI unmapped. Mapping to IRQ 3\n");
- sci_irq = 3;
- lo |= 0x00300000;
- wrmsrl(0x51400020, lo);
- }
-
- olpc_fixup_bios();
-
- lo = inl(pms_base + PM_FSD);
-
- /* Lock, enable failsafe, 4 seconds */
- outl(0xc001f400, pms_base + PM_FSD);
-
- /* Here we set up the SCI events we're interested in during
- * real-time. We have no sleep button, and the RTC doesn't make
- * sense, so set up the power button
- */
-
- outl(inl(acpi_base) | ((CS5536_PM_PWRBTN) << 16), acpi_base);
-
- if (olpc_get_rev() >= OLPC_REV_B2) {
- gpio_wake_events |= GPIO_WAKEUP_LID;
-
- /* Get the current value of the GPIO, and set up the edges */
- olpc_lid_flag = geode_gpio_isset(OLPC_GPIO_LID, GPIO_READ_BACK);
-
- /* Watch for the opposite edge */
-
- if (olpc_lid_flag)
- geode_gpio_set(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_EN);
- else
- geode_gpio_set(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_EN);
-
- /* Enable the event */
- geode_gpio_set(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
- }
-
- /* Set up the mask for wakeups the EC will generate SCIs on */
-
- ret = olpc_ec_cmd(EC_READ_SCI_MASK, NULL, 0, &ec_byte, 1);
- if (ret)
- printk(KERN_ERR "Error getting the EC SCI mask: %d\n", ret);
-
- /* Disable battery 1% charge wakeups */
- ec_byte &= ~EC_SCI_SRC_BATSOC;
-
- ret = olpc_ec_cmd(EC_WRITE_SCI_MASK, &ec_byte, 1, NULL, 0);
- if (ret)
- printk(KERN_ERR "Error setting the EC SCI mask: %d\n", ret);
-
- /* Set up the EC SCI */
-
- gpio_wake_events |= GPIO_WAKEUP_EC;
-
- outl(gpio_wake_events, acpi_base + PM_GPE0_EN);
- outl(0xFFFFFFFF, acpi_base + PM_GPE0_STS);
-
- /* Select level triggered in PIC */
-
- if (sci_irq < 8) {
- lo = inb(0x4d0);
- lo |= 1 << sci_irq;
- outb(lo, 0x4d0);
- } else {
- lo = inb(0x4d1);
- lo |= 1 << (sci_irq - 8);
- outb(lo, 0x4d1);
- }
- /* Clear pending interrupt */
- outl(inl(acpi_base) | 0xFFFF, acpi_base);
- process_sci_queue(0); /* we just want to flush the queue here */
- init_ebook_state();
-
- /* Enable the interrupt */
-
- ret = request_irq(sci_irq, &olpc_pm_interrupt, 0, "SCI", &acpi_base);
-
- if (ret) {
- printk(KERN_ERR "Error registering SCI: %d\n", ret);
- return ret;
- }
-
- ofw_bios_entry.address = 0xF0000 + PAGE_OFFSET;
- pm_set_ops(&olpc_pm_ops);
-
- sysfs_create_group(&power_subsys.kobj, &olpc_attrs);
-
- return 0;
-}
-
-
-#if defined (CONFIG_RTC_DRV_CMOS) || defined (CONFIG_RTC_DRV_CMOS_MODULE)
-struct resource rtc_platform_resource[2] = {
- {
- .flags = IORESOURCE_IO,
- .start = RTC_PORT(0),
- .end = RTC_PORT(0) + RTC_IO_EXTENT
- },
- {
- .flags = IORESOURCE_IRQ,
- .start = 8,
- .end = 8,
- },
-};
-
-
-static void rtc_wake_on(struct device *dev)
-{
- olpc_wakeup_mask |= CS5536_PM_RTC;
-}
-
-static void rtc_wake_off(struct device *dev)
-{
- olpc_wakeup_mask &= ~(CS5536_PM_RTC);
-}
-
-static struct cmos_rtc_board_info rtc_info = {
- .rtc_day_alarm = 0,
- .rtc_mon_alarm = 0,
- .rtc_century = 0,
- .wake_on = rtc_wake_on,
- .wake_off = rtc_wake_off,
-};
-
-struct platform_device olpc_rtc_device = {
- .name = "rtc_cmos",
- .id = -1,
- .num_resources = ARRAY_SIZE(rtc_platform_resource),
- .dev.platform_data = &rtc_info,
- .resource = rtc_platform_resource,
-};
-
-static int __init olpc_platform_init(void)
-{
- (void)platform_device_register(&olpc_rtc_device);
- device_init_wakeup(&olpc_rtc_device.dev, 1);
-
- (void)platform_device_register(&olpc_powerbutton_dev);
- device_init_wakeup(&olpc_powerbutton_dev.dev, 1);
-
- (void)platform_device_register(&olpc_lid_dev);
- device_init_wakeup(&olpc_lid_dev.dev, 1);
-
- return 0;
-}
-arch_initcall(olpc_platform_init);
-#endif /* CONFIG_RTC_DRV_CMOS */
-
-static void olpc_pm_exit(void)
-{
- /* Clear any pending events, and disable them */
- outl(0xFFFF, acpi_base+2);
-
- free_irq(sci_irq, &acpi_base);
- input_unregister_device(pm_inputdev);
- input_unregister_device(lid_inputdev);
- input_unregister_device(ebook_inputdev);
-}
-
-static struct pm_ops olpc_pm_ops = {
- .valid = olpc_pm_state_valid,
- .enter = olpc_pm_enter,
-};
-
-module_init(olpc_pm_init);
-module_exit(olpc_pm_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-MODULE_DESCRIPTION("AMD Geode power management for OLPC CL1");
diff --git a/target/linux/olpc/files/arch/i386/kernel/olpc-sleep.S b/target/linux/olpc/files/arch/i386/kernel/olpc-sleep.S
deleted file mode 100644
index 9535c9a941..0000000000
--- a/target/linux/olpc/files/arch/i386/kernel/olpc-sleep.S
+++ /dev/null
@@ -1,39 +0,0 @@
-.text
-
-ENTRY(olpc_sleep_asm)
-olpc_sleep:
- ;; Get the value of PM1_CNT and store it off
-
- add 08h, ax
- mov bx,dx
- in dx,eax
- or 2000h, ax
- mov ax,di
-
- ;; flush the cache
- wbinvd
-
- ;; GX2 must disable refresh before going into self-refresh
- mov 2000000180xh, ecx
- rdmsr
- mov eax, esi
- and 0FF0000FFh, eax
- wrmsr
-
- ;; Now, put the memory into self refresh
- mov 2004, cx
- xor edx, edx
- xor eax, eax
- mov 04h, al
- wrmsr
-
- ;; Thats all she wrote - time to go to sleep
-
- mov bx, dx
- movzx di, eax
- out eax, dx
-
- ;;
-
-
-
diff --git a/target/linux/olpc/files/arch/i386/kernel/olpc-wakeup.S b/target/linux/olpc/files/arch/i386/kernel/olpc-wakeup.S
deleted file mode 100644
index a92cc61e24..0000000000
--- a/target/linux/olpc/files/arch/i386/kernel/olpc-wakeup.S
+++ /dev/null
@@ -1,122 +0,0 @@
-.text
-#include <linux/linkage.h>
-#include <asm/segment.h>
-#include <asm/page.h>
-
-ALIGN
- .align 4096
-
-wakeup_start:
-# jmp wakeup_start
-
- cli
- cld
-
- # Clear any dangerous flags
-
- pushl $0
- popfl
-
- # Set up %cr3
- movl $swsusp_pg_dir - __PAGE_OFFSET, %eax
- movl %eax, %cr3
-
- movl saved_cr4, %eax
- movl %eax, %cr4
-
- movl saved_cr0, %eax
- movl %eax, %cr0
-
- jmp 1f
-1:
- ljmpl $__KERNEL_CS,$wakeup_return
-
-
-.org 0x1000
-
-wakeup_return:
- movw $__KERNEL_DS, %ax
- movw %ax, %ss
- movw %ax, %ds
- movw %ax, %es
- movw %ax, %fs
- movw %ax, %gs
-
- lgdt saved_gdt
- lidt saved_idt
- lldt saved_ldt
- ljmp $(__KERNEL_CS),$1f
-1:
- movl %cr3, %eax
- movl %eax, %cr3
- wbinvd
-
- # Go back to the return point
- jmp ret_point
-
-save_registers:
- sgdt saved_gdt
- sidt saved_idt
- sldt saved_ldt
-
- pushl %edx
- movl %cr4, %edx
- movl %edx, saved_cr4
-
- movl %cr0, %edx
- movl %edx, saved_cr0
-
- popl %edx
-
-
- movl %ebx, saved_context_ebx
- movl %ebp, saved_context_ebp
- movl %esi, saved_context_esi
- movl %edi, saved_context_edi
-
- pushfl
- popl saved_context_eflags
-
- ret
-
-
-restore_registers:
- movl saved_context_ebp, %ebp
- movl saved_context_ebx, %ebx
- movl saved_context_esi, %esi
- movl saved_context_edi, %edi
-
- pushl saved_context_eflags
- popfl
-
- ret
-
-
-ENTRY(do_olpc_suspend_lowlevel)
- call save_processor_state
- call save_registers
-
- # This is the stack context we want to remember
- movl %esp, saved_context_esp
-
- pushl $3
- call olpc_do_sleep
-
- jmp wakeup_start
- .p2align 4,,7
-ret_point:
- movl saved_context_esp, %esp
-
- call restore_registers
- call restore_processor_state
- ret
-
-.data
-ALIGN
-
-saved_gdt: .long 0,0
-saved_idt: .long 0,0
-saved_ldt: .long 0
-saved_cr4: .long 0
-saved_cr0: .long 0
-
diff --git a/target/linux/olpc/files/arch/i386/kernel/olpc.c b/target/linux/olpc/files/arch/i386/kernel/olpc.c
deleted file mode 100644
index d540cb0eae..0000000000
--- a/target/linux/olpc/files/arch/i386/kernel/olpc.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/* Support for the OLPC DCON and OLPC EC access
- * Copyright (C) 2006, Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/autoconf.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/mc146818rtc.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
-
-#include <asm/olpc.h>
-#include <asm/ofw.h>
-
-/* This is our new multi-purpose structure used to contain the
- * information about the platform that we detect
- */
-
-struct olpc_platform_t olpc_platform_info;
-EXPORT_SYMBOL_GPL(olpc_platform_info);
-
-/*********************************************************************
- * EC locking and access
- *********************************************************************/
-
-static DEFINE_SPINLOCK(ec_lock);
-
-/* what the timeout *should* be (in ms) */
-#define EC_BASE_TIMEOUT 20
-
-/* the timeout that bugs in the EC might force us to actually use */
-static int ec_timeout = EC_BASE_TIMEOUT;
-
-static int __init olpc_ec_timeout_set(char *str)
-{
- if (get_option(&str, &ec_timeout) != 1) {
- ec_timeout = EC_BASE_TIMEOUT;
- printk(KERN_ERR "olpc-ec: invalid argument to "
- "'olpc_ec_timeout=', ignoring!\n");
- }
- printk(KERN_DEBUG "olpc-ec: using %d ms delay for EC commands.\n",
- ec_timeout);
- return 1;
-}
-__setup("olpc_ec_timeout=", olpc_ec_timeout_set);
-
-/*
- * These *bf_status functions return whether the buffers are full or not.
- */
-
-static inline unsigned int ibf_status(unsigned int port)
-{
- return inb(port) & 0x02;
-}
-
-static inline unsigned int obf_status(unsigned int port)
-{
- return inb(port) & 0x01;
-}
-
-#define wait_on_ibf(p, d) __wait_on_ibf(__LINE__, (p), (d))
-static int __wait_on_ibf(unsigned int line, unsigned int port, int desired)
-{
- unsigned int timeo;
- int state = ibf_status(port);
-
- for (timeo = ec_timeout; state != desired && timeo; timeo--) {
- mdelay(1);
- state = ibf_status(port);
- }
-
- if ((state == desired) && (ec_timeout > EC_BASE_TIMEOUT) &&
- timeo < (ec_timeout - EC_BASE_TIMEOUT)) {
- printk(KERN_WARNING "olpc-ec: waited %u ms for IBF (%d)!\n",
- EC_BASE_TIMEOUT-timeo, line);
- }
-
- return !(state == desired);
-}
-
-#define wait_on_obf(p, d) __wait_on_obf(__LINE__, (p), (d))
-static int __wait_on_obf(unsigned int line, unsigned int port, int desired)
-{
- unsigned int timeo;
- int state = obf_status(port);
-
- for (timeo = ec_timeout; state != desired && timeo; timeo--) {
- mdelay(1);
- state = obf_status(port);
- }
-
- if ((state == desired) && (ec_timeout > EC_BASE_TIMEOUT) &&
- timeo < (ec_timeout - EC_BASE_TIMEOUT)) {
- printk(KERN_WARNING "olpc-ec: waited %u ms for OBF (%d)!\n",
- EC_BASE_TIMEOUT-timeo, line);
- }
-
- return !(state == desired);
-}
-
-int olpc_ec_cmd(unsigned char cmd, unsigned char *inbuf, size_t inlen,
- unsigned char *outbuf, size_t outlen)
-{
- unsigned long flags;
- int ret = -EIO;
- int i;
-
- spin_lock_irqsave(&ec_lock, flags);
-
- if (wait_on_ibf(0x6c, 0)) {
- printk(KERN_ERR "olpc-ec: timeout waiting for EC to "
- "quiesce!\n");
- goto err;
- }
-
-restart:
- /*
- * Note that if we time out during any IBF checks, that's a failure;
- * we have to return. There's no way for the kernel to clear that.
- *
- * If we time out during an OBF check, we can restart the command;
- * reissuing it will clear the OBF flag, and we should be alright.
- * The OBF flag will sometimes misbehave due to what we believe
- * is a hardware quirk..
- */
- printk(KERN_DEBUG "olpc-ec: running cmd 0x%x\n", cmd);
- outb(cmd, 0x6c);
-
- if (wait_on_ibf(0x6c, 0)) {
- printk(KERN_ERR "olpc-ec: timeout waiting for EC to read "
- "command!\n");
- goto err;
- }
-
- if (inbuf && inlen) {
- /* write data to EC */
- for (i = 0; i < inlen; i++) {
- if (wait_on_ibf(0x6c, 0)) {
- printk(KERN_ERR "olpc-ec: timeout waiting for"
- " EC accept data!\n");
- goto err;
- }
- printk(KERN_DEBUG "olpc-ec: sending cmd arg 0x%x\n",
- inbuf[i]);
- outb(inbuf[i], 0x68);
- }
- }
- if (outbuf && outlen) {
- /* read data from EC */
- for (i = 0; i < outlen; i++) {
- if (wait_on_obf(0x6c, 1)) {
- printk(KERN_ERR "olpc-ec: timeout waiting for"
- " EC to provide data!\n");
- goto restart;
- }
- outbuf[i] = inb(0x68);
- printk(KERN_DEBUG "olpc-ec: received 0x%x\n",
- outbuf[i]);
- }
- }
-
- ret = 0;
-err:
- spin_unlock_irqrestore(&ec_lock, flags);
- return ret;
-}
-EXPORT_SYMBOL_GPL(olpc_ec_cmd);
-
-/*********************************************************************
- * DCON stuff
- *********************************************************************/
-
-static void olpc_power_off(void)
-{
- printk(KERN_INFO "OLPC power off sequence...\n");
- outb(0xff, 0x381);
- outb(0x14, 0x382);
- outb(0x01, 0x383);
- outb(0xff, 0x381);
- outb(0x14, 0x382);
- outb(0x00, 0x383);
-}
-
-static void __init
-ec_detect(void)
-{
- olpc_ec_cmd(0x08, NULL, 0, (unsigned char *) &olpc_platform_info.ecver, 1);
-}
-
-/* Check to see if this version of the OLPC board has VSA built
- * in, and set a flag
- */
-
-static void __init vsa_detect(void)
-{
- u16 rev;
-
- outw(0xFC53, 0xAC1C);
- outw(0x0003, 0xAC1C);
-
- rev = inw(0xAC1E);
-
- if (rev == 0x4132)
- olpc_platform_info.flags |= OLPC_F_VSA;
-}
-
-/* Map OFW revisions to what OLPC_REV_* */
-static const char __initdata *olpc_boardrev_str[] = {
- "A1",
- "preB1",
- "B1",
- "preB2",
- "B2",
- "preB3",
- "B3",
- "B4",
- "C1",
- "R1",
-};
-
-static void __init platform_detect(char *revision, size_t len)
-{
- size_t propsize;
- int i;
-
- BUG_ON(ARRAY_SIZE(olpc_boardrev_str) != OLPC_REV_UNKNOWN);
-
- if (ofw("getprop", 4, 1, NULL, "model", revision, len, &propsize)) {
- printk(KERN_ERR "ofw: getprop call failed!\n");
- goto failed;
- }
- if (len < propsize) {
- printk(KERN_ERR "ofw: revision string is too long!\n");
- goto failed;
- }
-
- for (i=0; i < ARRAY_SIZE(olpc_boardrev_str); i++) {
- if (strcmp(revision, olpc_boardrev_str[i]) == 0) {
- olpc_platform_info.boardrev = i;
- return;
- }
- }
-
-failed:
- strncpy(revision, "Unknown", len);
- olpc_platform_info.boardrev = OLPC_REV_UNKNOWN;
-}
-
-static int olpc_dcon_present = -1;
-module_param(olpc_dcon_present, int, 0444);
-
-/* REV_A CMOS map:
- * bit 440; DCON present bit
- */
-
-#define OLPC_CMOS_DCON_OFFSET (440 / 8)
-#define OLPC_CMOS_DCON_MASK 0x01
-
-static int __init olpc_init(void)
-{
- unsigned char *romsig;
- char revision[10];
-
- spin_lock_init(&ec_lock);
-
- romsig = ioremap(0xffffffc0, 16);
-
- if (!romsig)
- return 0;
-
- if (strncmp(romsig, "CL1 Q", 7))
- goto unmap;
- if (strncmp(romsig+6, romsig+13, 3)) {
- printk(KERN_INFO "OLPC BIOS signature looks invalid. Assuming not OLPC\n");
- goto unmap;
- }
- printk(KERN_INFO "OLPC board with OpenFirmware: %.16s\n", romsig);
-
- olpc_platform_info.flags |= OLPC_F_PRESENT;
-
- pm_power_off = olpc_power_off;
-
- /* Get the platform revision */
- platform_detect(revision, sizeof(revision));
-
- /* If olpc_dcon_present isn't set by the command line, then
- * "detect" it
- */
-
- if (olpc_dcon_present == -1) {
- /* B1 and greater always has a DCON */
- if (olpc_platform_info.boardrev >= OLPC_REV_B1 &&
- olpc_platform_info.boardrev < OLPC_REV_UNKNOWN)
- olpc_dcon_present = 1;
- }
-
- if (olpc_dcon_present)
- olpc_platform_info.flags |= OLPC_F_DCON;
-
- /* Get the EC revision */
- ec_detect();
-
- /* Check to see if the VSA exists */
- vsa_detect();
-
- printk(KERN_INFO "OLPC board revision: %s (EC=%x)\n", revision,
- olpc_platform_info.ecver);
-
- unmap:
- iounmap(romsig);
-
- return 0;
-}
-
-postcore_initcall(olpc_init);
diff --git a/target/linux/olpc/files/arch/i386/kernel/prom.c b/target/linux/olpc/files/arch/i386/kernel/prom.c
deleted file mode 100644
index d64bb276f2..0000000000
--- a/target/linux/olpc/files/arch/i386/kernel/prom.c
+++ /dev/null
@@ -1,478 +0,0 @@
-/*
- * Procedures for creating, accessing and interpreting the device tree.
- *
- * Paul Mackerras August 1996.
- * Copyright (C) 1996-2005 Paul Mackerras.
- *
- * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
- * {engebret|bergner}@us.ibm.com
- *
- * Adapted for sparc64 by David S. Miller davem@davemloft.net
- *
- * Adapter for i386/OLPC by Andres Salomon <dilinger@debian.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/bootmem.h>
-#include <linux/module.h>
-#include <asm/prom.h>
-#include <asm/ofw.h>
-
-/*
- * XXX: This is very much a stub; right now we're keeping 2 device trees
- * in memory (one for promfs, and one here). That will not remain
- * for long!
- */
-
-static struct device_node *allnodes;
-
-/* use when traversing tree through the allnext, child, sibling,
- * or parent members of struct device_node.
- */
-static DEFINE_RWLOCK(devtree_lock);
-
-int of_device_is_compatible(const struct device_node *device,
- const char *compat)
-{
- const char* cp;
- int cplen, l;
-
- cp = of_get_property(device, "compatible", &cplen);
- if (cp == NULL)
- return 0;
- while (cplen > 0) {
- if (strncmp(cp, compat, strlen(compat)) == 0)
- return 1;
- l = strlen(cp) + 1;
- cp += l;
- cplen -= l;
- }
-
- return 0;
-}
-EXPORT_SYMBOL(of_device_is_compatible);
-
-struct device_node *of_get_parent(const struct device_node *node)
-{
- struct device_node *np;
-
- if (!node)
- return NULL;
-
- np = node->parent;
-
- return np;
-}
-EXPORT_SYMBOL(of_get_parent);
-
-struct device_node *of_get_next_child(const struct device_node *node,
- struct device_node *prev)
-{
- struct device_node *next;
-
- next = prev ? prev->sibling : node->child;
- for (; next != 0; next = next->sibling) {
- break;
- }
-
- return next;
-}
-EXPORT_SYMBOL(of_get_next_child);
-
-struct device_node *of_find_node_by_path(const char *path)
-{
- struct device_node *np = allnodes;
-
- for (; np != 0; np = np->allnext) {
- if (np->full_name != 0 && strcmp(np->full_name, path) == 0)
- break;
- }
-
- return np;
-}
-EXPORT_SYMBOL(of_find_node_by_path);
-
-struct device_node *of_find_node_by_phandle(phandle handle)
-{
- struct device_node *np;
-
- for (np = allnodes; np != 0; np = np->allnext)
- if (np->node == handle)
- break;
-
- return np;
-}
-EXPORT_SYMBOL(of_find_node_by_phandle);
-
-struct device_node *of_find_node_by_name(struct device_node *from,
- const char *name)
-{
- struct device_node *np;
-
- np = from ? from->allnext : allnodes;
- for (; np != NULL; np = np->allnext)
- if (np->name != NULL && strcmp(np->name, name) == 0)
- break;
-
- return np;
-}
-EXPORT_SYMBOL(of_find_node_by_name);
-
-struct device_node *of_find_node_by_type(struct device_node *from,
- const char *type)
-{
- struct device_node *np;
-
- np = from ? from->allnext : allnodes;
- for (; np != 0; np = np->allnext)
- if (np->type != 0 && strcmp(np->type, type) == 0)
- break;
-
- return np;
-}
-EXPORT_SYMBOL(of_find_node_by_type);
-
-struct device_node *of_find_compatible_node(struct device_node *from,
- const char *type, const char *compatible)
-{
- struct device_node *np;
-
- np = from ? from->allnext : allnodes;
- for (; np != 0; np = np->allnext) {
- if (type != NULL
- && !(np->type != 0 && strcmp(np->type, type) == 0))
- continue;
- if (of_device_is_compatible(np, compatible))
- break;
- }
-
- return np;
-}
-EXPORT_SYMBOL(of_find_compatible_node);
-
-struct property *of_find_property(const struct device_node *np,
- const char *name,
- int *lenp)
-{
- struct property *pp;
-
- for (pp = np->properties; pp != 0; pp = pp->next) {
- if (strcasecmp(pp->name, name) == 0) {
- if (lenp != 0)
- *lenp = pp->length;
- break;
- }
- }
- return pp;
-}
-EXPORT_SYMBOL(of_find_property);
-
-/*
- * Find a property with a given name for a given node
- * and return the value.
- */
-const void *of_get_property(const struct device_node *np, const char *name,
- int *lenp)
-{
- struct property *pp = of_find_property(np,name,lenp);
- return pp ? pp->value : NULL;
-}
-EXPORT_SYMBOL(of_get_property);
-
-int of_getintprop_default(struct device_node *np, const char *name, int def)
-{
- struct property *prop;
- int len;
-
- prop = of_find_property(np, name, &len);
- if (!prop || len != 4)
- return def;
-
- return *(int *) prop->value;
-}
-EXPORT_SYMBOL(of_getintprop_default);
-
-int of_n_addr_cells(struct device_node *np)
-{
- const int* ip;
- do {
- if (np->parent)
- np = np->parent;
- ip = of_get_property(np, "#address-cells", NULL);
- if (ip != NULL)
- return *ip;
- } while (np->parent);
- /* No #address-cells property for the root node, default to 2 */
- return 2;
-}
-EXPORT_SYMBOL(of_n_addr_cells);
-
-int of_n_size_cells(struct device_node *np)
-{
- const int* ip;
- do {
- if (np->parent)
- np = np->parent;
- ip = of_get_property(np, "#size-cells", NULL);
- if (ip != NULL)
- return *ip;
- } while (np->parent);
- /* No #size-cells property for the root node, default to 1 */
- return 1;
-}
-EXPORT_SYMBOL(of_n_size_cells);
-
-int of_set_property(struct device_node *dp, const char *name, void *val, int len)
-{
- return -EIO;
-}
-EXPORT_SYMBOL(of_set_property);
-
-static unsigned int prom_early_allocated;
-
-static void * __init prom_early_alloc(unsigned long size)
-{
- void *ret;
-
- ret = kmalloc(size, GFP_KERNEL);
- if (ret != NULL)
- memset(ret, 0, size);
- else
- printk(KERN_ERR "ACK! couldn't allocate prom memory!\n");
-
- prom_early_allocated += size;
-
- return ret;
-}
-
-static int is_root_node(const struct device_node *dp)
-{
- if (!dp)
- return 0;
-
- return (dp->parent == NULL);
-}
-
-static char * __init build_path_component(struct device_node *dp)
-{
- int pathlen;
- char *n, *i;
-
- if (ofw("package-to-path", 3, 1, dp->node, NULL, 0, &pathlen)) {
- printk(KERN_ERR "PROM: unable to get path name from OFW!\n");
- return "ERROR";
- }
- n = prom_early_alloc(pathlen + 1);
- if (ofw("package-to-path", 3, 1, dp->node, n, pathlen+1, &pathlen))
- printk(KERN_ERR "PROM: unable to get path name from OFW\n");
-
- if ((i = strrchr(n, '/')))
- n = ++i; /* we only want the file name */
- return n;
-}
-
-static char * __init build_full_name(struct device_node *dp)
-{
- int len, ourlen, plen;
- char *n;
-
- plen = strlen(dp->parent->full_name);
- ourlen = strlen(dp->path_component_name);
- len = ourlen + plen + 2;
-
- n = prom_early_alloc(len);
- strcpy(n, dp->parent->full_name);
- if (!is_root_node(dp->parent)) {
- strcpy(n + plen, "/");
- plen++;
- }
- strcpy(n + plen, dp->path_component_name);
-
- return n;
-}
-
-static struct property * __init build_one_prop(phandle node, char *prev, char *special_name, void *special_val, int special_len)
-{
- static struct property *tmp = NULL;
- struct property *p;
-
- if (tmp) {
- p = tmp;
- memset(p, 0, sizeof(*p) + 32);
- tmp = NULL;
- } else {
- p = prom_early_alloc(sizeof(struct property) + 32);
- }
-
- p->name = (char *) (p + 1);
- if (special_name) {
- strcpy(p->name, special_name);
- p->length = special_len;
- p->value = prom_early_alloc(special_len);
- memcpy(p->value, special_val, special_len);
- } else {
- int fl;
- if (prev == NULL) {
- if (ofw("nextprop", 3, 1, node, "", p->name, &fl)) {
- printk(KERN_ERR "PROM: %s: nextprop failed!\n", __func__);
- return NULL;
- }
- } else {
- if (ofw("nextprop", 3, 1, node, prev, p->name, &fl)) {
- printk(KERN_ERR "PROM: %s: nextprop failed!\n", __func__);
- return NULL;
- }
- }
- if (strlen(p->name) == 0 || fl != 1) {
- tmp = p;
- return NULL;
- }
- if (ofw("getproplen", 2, 1, node, p->name, &p->length)) {
- printk(KERN_ERR "PROM: %s: getproplen failed!\n", __func__);
- return NULL;
- }
- if (p->length <= 0) {
- p->length = 0;
- } else {
- p->value = prom_early_alloc(p->length + 1);
- if (ofw("getprop", 4, 1, node, p->name, p->value, p->length, &p->length)) {
- printk(KERN_ERR "PROM: %s: getprop failed!\n", __func__);
- return NULL;
- }
- ((unsigned char *)p->value)[p->length] = '\0';
- }
- }
- return p;
-}
-
-static struct property * __init build_prop_list(phandle node)
-{
- struct property *head, *tail;
-
- head = tail = build_one_prop(node, NULL,
- ".node", &node, sizeof(node));
-
- tail->next = build_one_prop(node, NULL, NULL, NULL, 0);
- tail = tail->next;
- while(tail) {
- tail->next = build_one_prop(node, tail->name,
- NULL, NULL, 0);
- tail = tail->next;
- }
-
- return head;
-}
-
-static char * __init get_one_property(phandle node, const char *name)
-{
- char *buf = "<NULL>";
- int len;
-
- if (ofw("getproplen", 2, 1, node, name, &len)) {
- printk(KERN_ERR "PROM: %s: getproplen failed!\n", __func__);
- return NULL;
- }
- if (len > 0) {
- buf = prom_early_alloc(len);
- if (ofw("getprop", 4, 1, node, name, buf, len, &len)) {
- printk(KERN_ERR "PROM: %s: getprop failed!\n", __func__);
- return NULL;
- }
- }
-
- return buf;
-}
-
-static struct device_node * __init create_node(phandle node, struct device_node *parent)
-{
- struct device_node *dp;
-
- if (!node)
- return NULL;
-
- dp = prom_early_alloc(sizeof(*dp));
- dp->parent = parent;
-
- kref_init(&dp->kref);
-
- dp->name = get_one_property(node, "name");
- dp->type = get_one_property(node, "device_type");
- dp->node = node;
-
- dp->properties = build_prop_list(node);
-
- return dp;
-}
-
-static struct device_node * __init build_tree(struct device_node *parent, phandle node, struct device_node ***nextp)
-{
- struct device_node *ret = NULL, *prev_sibling = NULL;
- struct device_node *dp;
- u32 child;
-
- while (1) {
- dp = create_node(node, parent);
- if (!dp)
- break;
-
- if (prev_sibling)
- prev_sibling->sibling = dp;
-
- if (!ret)
- ret = dp;
- prev_sibling = dp;
-
- *(*nextp) = dp;
- *nextp = &dp->allnext;
-
- dp->path_component_name = build_path_component(dp);
- dp->full_name = build_full_name(dp);
-
- if (ofw("child", 1, 1, node, &child)) {
- printk(KERN_ERR "PROM: %s: fetching child failed!\n", __func__);
- return NULL;
- }
- dp->child = build_tree(dp, child, nextp);
-
- if (ofw("peer", 1, 1, node, &node)) {
- printk(KERN_ERR "PROM: %s: fetching peer failed!\n", __func__);
- return NULL;
- }
- }
-
- return ret;
-}
-
-static phandle root_node;
-
-void __init prom_build_devicetree(void)
-{
- struct device_node **nextp;
- u32 child;
-
- if (ofw("peer", 1, 1, 0, &root_node)) {
- printk(KERN_ERR "PROM: unable to get root node from OFW!\n");
- return;
- }
-
- allnodes = create_node(root_node, NULL);
- allnodes->path_component_name = "";
- allnodes->full_name = "/";
-
- nextp = &allnodes->allnext;
- if (ofw("child", 1, 1, allnodes->node, &child)) {
- printk(KERN_ERR "PROM: unable to get child node from OFW!\n");
- return;
- }
- allnodes->child = build_tree(allnodes, child, &nextp);
- printk("PROM: Built device tree with %u bytes of memory.\n",
- prom_early_allocated);
-}