* [PATCH] OLPC: Add XO-1 poweroff support
@ 2010-10-07 18:59 Daniel Drake
2010-10-07 20:09 ` Andres Salomon
0 siblings, 1 reply; 4+ messages in thread
From: Daniel Drake @ 2010-10-07 18:59 UTC (permalink / raw)
To: tglx, mingo, hpa, x86; +Cc: dilinger, linux-kernel
Add a pm_power_off handler for the OLPC XO-1 laptop.
Signed-off-by: Daniel Drake <dsd@laptop.org>
---
arch/x86/Kconfig | 6 ++
arch/x86/kernel/Makefile | 1 +
arch/x86/kernel/olpc-xo1.c | 112 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 119 insertions(+), 0 deletions(-)
create mode 100644 arch/x86/kernel/olpc-xo1.c
The new olpc-xo1.c file will also be used for further functionality
(suspend/resume, lid switch device, etc); patches to be submitted shortly
after the review/merge of this one.
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index cea0cd9..19e6439 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2065,6 +2065,12 @@ config OLPC
Add support for detecting the unique features of the OLPC
XO hardware.
+config OLPC_XO1
+ bool "OLPC XO-1 support"
+ depends on OLPC
+ ---help---
+ Add support for non-essential features of the OLPC XO-1 laptop.
+
config OLPC_OPENFIRMWARE
bool "Support for OLPC's Open Firmware"
depends on !X86_64 && !X86_PAE
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index fedf32a..247588f 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -106,6 +106,7 @@ obj-$(CONFIG_SCx200) += scx200.o
scx200-y += scx200_32.o
obj-$(CONFIG_OLPC) += olpc.o
+obj-$(CONFIG_OLPC_XO1) += olpc-xo1.o
obj-$(CONFIG_OLPC_OPENFIRMWARE) += olpc_ofw.o
obj-$(CONFIG_X86_MRST) += mrst.o
diff --git a/arch/x86/kernel/olpc-xo1.c b/arch/x86/kernel/olpc-xo1.c
new file mode 100644
index 0000000..ee840de
--- /dev/null
+++ b/arch/x86/kernel/olpc-xo1.c
@@ -0,0 +1,112 @@
+/*
+ * Support for features of the OLPC XO-1 laptop
+ *
+ * Copyright (C) 2010 One Laptop per Child
+ * Copyright (C) 2006 Red Hat, Inc.
+ * 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/init.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/pm.h>
+
+#include <asm/io.h>
+#include <asm/olpc.h>
+
+#define DRV_NAME "olpc-xo1"
+
+#define PMS_BAR 4
+#define ACPI_BAR 5
+
+/* PMC registers (PMS block) */
+#define PM_SCLK 0x10
+#define PM_IN_SLPCTL 0x20
+#define PM_WKXD 0x34
+#define PM_WKD 0x30
+#define PM_SSC 0x54
+
+/* PM registers (ACPI block) */
+#define PM1_CNT 0x08
+#define PM_GPE0_STS 0x18
+
+static unsigned long acpi_base;
+static unsigned long pms_base;
+
+static void xo1_power_off(void)
+{
+ printk(KERN_INFO "OLPC XO-1 power off sequence...\n");
+
+ /* Enable all of these controls with 0 delay */
+ outl(0x40000000, pms_base + PM_SCLK);
+ outl(0x40000000, pms_base + PM_IN_SLPCTL);
+ outl(0x40000000, pms_base + PM_WKXD);
+ outl(0x40000000, pms_base + PM_WKD);
+
+ /* Clear status bits (possibly unnecessary) */
+ outl(0x0002ffff, pms_base + PM_SSC);
+ outl(0xffffffff, acpi_base + PM_GPE0_STS);
+
+ /* Write SLP_EN bit to start the machinery */
+ outl(0x00002000, acpi_base + PM1_CNT);
+}
+
+/* Read the base addresses from the PCI BAR info */
+static int __init setup_bases(struct pci_dev *pdev)
+{
+ int r;
+
+ r = pci_enable_device_io(pdev);
+ if (r) {
+ dev_err(&pdev->dev, "can't enable device IO\n");
+ return r;
+ }
+
+ r = pci_request_region(pdev, ACPI_BAR, DRV_NAME);
+ if (r) {
+ dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", ACPI_BAR);
+ return r;
+ }
+
+ r = pci_request_region(pdev, PMS_BAR, DRV_NAME);
+ if (r) {
+ dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", PMS_BAR);
+ pci_release_region(pdev, ACPI_BAR);
+ return r;
+ }
+
+ acpi_base = pci_resource_start(pdev, ACPI_BAR);
+ pms_base = pci_resource_start(pdev, PMS_BAR);
+
+ return 0;
+}
+
+static int __init olpc_xo1_init(void)
+{
+ struct pci_dev *pdev;
+ int r;
+
+ if (olpc_board_at_least(olpc_board_pre(0xd0))) /* XO-1 only */
+ return 0;
+
+ pdev = pci_get_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA,
+ NULL);
+ if (!pdev)
+ return -ENODEV;
+
+ r = setup_bases(pdev);
+ if (r)
+ return r;
+
+ pm_power_off = xo1_power_off;
+
+ printk(KERN_INFO "OLPC XO-1 support registered\n");
+ return 0;
+}
+device_initcall(olpc_xo1_init);
+
--
1.7.2.3
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] OLPC: Add XO-1 poweroff support
2010-10-07 18:59 [PATCH] OLPC: Add XO-1 poweroff support Daniel Drake
@ 2010-10-07 20:09 ` Andres Salomon
2010-10-07 20:42 ` Daniel Drake
0 siblings, 1 reply; 4+ messages in thread
From: Andres Salomon @ 2010-10-07 20:09 UTC (permalink / raw)
To: Daniel Drake; +Cc: tglx, mingo, hpa, x86, linux-kernel
On Thu, 7 Oct 2010 19:59:52 +0100 (BST)
Daniel Drake <dsd@laptop.org> wrote:
> Add a pm_power_off handler for the OLPC XO-1 laptop.
>
> Signed-off-by: Daniel Drake <dsd@laptop.org>
> ---
> arch/x86/Kconfig | 6 ++
> arch/x86/kernel/Makefile | 1 +
> arch/x86/kernel/olpc-xo1.c | 112
> ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 119
> insertions(+), 0 deletions(-) create mode 100644
> arch/x86/kernel/olpc-xo1.c
>
> The new olpc-xo1.c file will also be used for further functionality
> (suspend/resume, lid switch device, etc); patches to be submitted
> shortly after the review/merge of this one.
>
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index cea0cd9..19e6439 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -2065,6 +2065,12 @@ config OLPC
> Add support for detecting the unique features of the OLPC
> XO hardware.
>
> +config OLPC_XO1
> + bool "OLPC XO-1 support"
Any particular reason why this can't be modular?
[...]
> +
> + pm_power_off = xo1_power_off;
> +
If this were to be modular, I'm not sure what the best option is for
pm_power_off. If the old value was saved upon module load, and
restored upon module unload, I could imagine races like the following:
module A load:
saved_ppo = pm_power_off; /* NULL */
pm_power_off = frob;
module B load:
old_ppo = pm_power_off; /* frob */
pm_power_off = foo;
module A unload:
pm_power_off = saved_ppo; /* NULL */
So I guess just clobbering whatever's in pm_power_off and setting back
to NULL upon unload, with the assumption that driver's only really
going to clobber it in the case of actual OLPC hardware, and the
callbacks being clobbered wouldn't really have done the correct thing
anyways?
> + printk(KERN_INFO "OLPC XO-1 support registered\n");
> + return 0;
> +}
> +device_initcall(olpc_xo1_init);
> +
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] OLPC: Add XO-1 poweroff support
2010-10-07 20:09 ` Andres Salomon
@ 2010-10-07 20:42 ` Daniel Drake
2010-10-07 21:20 ` Andres Salomon
0 siblings, 1 reply; 4+ messages in thread
From: Daniel Drake @ 2010-10-07 20:42 UTC (permalink / raw)
To: Andres Salomon; +Cc: tglx, mingo, hpa, x86, linux-kernel
On 7 October 2010 21:09, Andres Salomon <dilinger@queued.net> wrote:
> Any particular reason why this can't be modular?
Because of the pm_power_off thing.
Also, a similar situation would be encountered with set_suspend_ops().
I don't really understand your suggestion. If we set it to NULL on
module unload then the power off would crash on shutdown, right?
Daniel
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] OLPC: Add XO-1 poweroff support
2010-10-07 20:42 ` Daniel Drake
@ 2010-10-07 21:20 ` Andres Salomon
0 siblings, 0 replies; 4+ messages in thread
From: Andres Salomon @ 2010-10-07 21:20 UTC (permalink / raw)
To: Daniel Drake; +Cc: tglx, mingo, hpa, x86, linux-kernel
On Thu, 7 Oct 2010 21:42:59 +0100
Daniel Drake <dsd@laptop.org> wrote:
> On 7 October 2010 21:09, Andres Salomon <dilinger@queued.net> wrote:
> > Any particular reason why this can't be modular?
>
> Because of the pm_power_off thing.
> Also, a similar situation would be encountered with set_suspend_ops().
>
> I don't really understand your suggestion. If we set it to NULL on
> module unload then the power off would crash on shutdown, right?
>
> Daniel
See arch/x86/kernel/apm_32.c for an example of modular pm_power_off
handling.
Power off shouldn't crash; at least, native_machine_power_off first
check if pm_power_off is !NULL before calling it.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2010-10-07 21:18 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-07 18:59 [PATCH] OLPC: Add XO-1 poweroff support Daniel Drake
2010-10-07 20:09 ` Andres Salomon
2010-10-07 20:42 ` Daniel Drake
2010-10-07 21:20 ` Andres Salomon
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox