/*
 * Support for power management features of the OLPC XO-1 laptop
 *
 * Copyright (C) 2010 Andres Salomon <dilinger@queued.net>
 * 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/cs5535.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/mfd/core.h>
#include <linux/suspend.h>

#include <asm/io.h>
#include <asm/olpc.h>

#define DRV_NAME "olpc-xo1-pm"

static unsigned long acpi_base;
static unsigned long pms_base;

static u16 wakeup_mask = CS5536_PM_PWRBTN;

static struct {
	unsigned long address;
	unsigned short segment;
} ofw_bios_entry = { 0xF0000 + PAGE_OFFSET, __KERNEL_CS };

/* Set bits in the wakeup mask */
void olpc_xo1_pm_wakeup_set(u16 value)
{
	wakeup_mask |= value;
}
EXPORT_SYMBOL_GPL(olpc_xo1_pm_wakeup_set);

/* Clear bits in the wakeup mask */
void olpc_xo1_pm_wakeup_clear(u16 value)
{
	wakeup_mask &= ~value;
}
EXPORT_SYMBOL_GPL(olpc_xo1_pm_wakeup_clear);

static int xo1_power_state_enter(suspend_state_t pm_state)
{
	unsigned long saved_sci_mask;
	int r;

	/* Only STR is supported */
	if (pm_state != PM_SUSPEND_MEM)
		return -EINVAL;

	r = olpc_ec_cmd(EC_SET_SCI_INHIBIT, NULL, 0, NULL, 0);
	if (r)
		return r;

	/*
	 * Save SCI mask (this gets lost since PM1_EN is used as a mask for
	 * wakeup events, which is not necessarily the same event set)
	 */
	saved_sci_mask = inl(acpi_base + CS5536_PM1_STS);
	saved_sci_mask &= 0xffff0000;

	/* Save CPU state */
	do_olpc_suspend_lowlevel();

	/* Resume path starts here */

	/* Restore SCI mask (using dword access to CS5536_PM1_EN) */
	outl(saved_sci_mask, acpi_base + CS5536_PM1_STS);

	/* Tell the EC to stop inhibiting SCIs */
	olpc_ec_cmd(EC_SET_SCI_INHIBIT_RELEASE, NULL, 0, NULL, 0);

	/*
	 * Tell the wireless module to restart USB communication.
	 * Must be done twice.
	 */
	olpc_ec_cmd(EC_WAKE_UP_WLAN, NULL, 0, NULL, 0);
	olpc_ec_cmd(EC_WAKE_UP_WLAN, NULL, 0, NULL, 0);

	return 0;
}

asmlinkage int xo1_do_sleep(u8 sleep_state)
{
	void *pgd_addr = __va(read_cr3());

	/* Program wakeup mask (using dword access to CS5536_PM1_EN) */
	outl(wakeup_mask << 16, acpi_base + CS5536_PM1_STS);

	__asm__("movl %0,%%eax" : : "r" (pgd_addr));
	__asm__("call *(%%edi); cld"
		: : "D" (&ofw_bios_entry));
	__asm__("movb $0x34, %al\n\t"
		"outb %al, $0x70\n\t"
		"movb $0x30, %al\n\t"
		"outb %al, $0x71\n\t");
	return 0;
}

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 + CS5536_PM_SCLK);
	outl(0x40000000, pms_base + CS5536_PM_IN_SLPCTL);
	outl(0x40000000, pms_base + CS5536_PM_WKXD);
	outl(0x40000000, pms_base + CS5536_PM_WKD);

	/* Clear status bits (possibly unnecessary) */
	outl(0x0002ffff, pms_base  + CS5536_PM_SSC);
	outl(0xffffffff, acpi_base + CS5536_PM_GPE0_STS);

	/* Write SLP_EN bit to start the machinery */
	outl(0x00002000, acpi_base + CS5536_PM1_CNT);
}

static int xo1_power_state_valid(suspend_state_t pm_state)
{
	/* suspend-to-RAM only */
	return pm_state == PM_SUSPEND_MEM;
}

static const struct platform_suspend_ops xo1_suspend_ops = {
	.valid = xo1_power_state_valid,
	.enter = xo1_power_state_enter,
};

static int __devinit xo1_pm_probe(struct platform_device *pdev)
{
	struct resource *res;
	int err;

	/* don't run on non-XOs */
	if (!machine_is_olpc())
		return -ENODEV;

	err = mfd_cell_enable(pdev);
	if (err)
		return err;

	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
	if (!res) {
		dev_err(&pdev->dev, "can't fetch device resource info\n");
		return -EIO;
	}
	if (strcmp(pdev->name, "cs5535-pms") == 0)
		pms_base = res->start;
	else if (strcmp(pdev->name, "olpc-xo1-pm-acpi") == 0)
		acpi_base = res->start;

	/* If we have both addresses, we can override the poweroff hook */
	if (pms_base && acpi_base) {
		suspend_set_ops(&xo1_suspend_ops);
		pm_power_off = xo1_power_off;
		printk(KERN_INFO "OLPC XO-1 support registered\n");
	}

	return 0;
}

static int __devexit xo1_pm_remove(struct platform_device *pdev)
{
	mfd_cell_disable(pdev);

	if (strcmp(pdev->name, "cs5535-pms") == 0)
		pms_base = 0;
	else if (strcmp(pdev->name, "olpc-xo1-pm-acpi") == 0)
		acpi_base = 0;

	pm_power_off = NULL;
	return 0;
}

static struct platform_driver cs5535_pms_driver = {
	.driver = {
		.name = "cs5535-pms",
		.owner = THIS_MODULE,
	},
	.probe = xo1_pm_probe,
	.remove = __devexit_p(xo1_pm_remove),
};

static struct platform_driver cs5535_acpi_driver = {
	.driver = {
		.name = "olpc-xo1-pm-acpi",
		.owner = THIS_MODULE,
	},
	.probe = xo1_pm_probe,
	.remove = __devexit_p(xo1_pm_remove),
};

static int __init xo1_pm_init(void)
{
	int r;

	r = platform_driver_register(&cs5535_pms_driver);
	if (r)
		return r;

	r = platform_driver_register(&cs5535_acpi_driver);
	if (r)
		platform_driver_unregister(&cs5535_pms_driver);

	return r;
}
arch_initcall(xo1_pm_init);
