// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Support for OLPC XO-1.5 System Control Interrupts (SCI)
 *
 * Copyright (C) 2009-2010 One Laptop per Child
 */

#include <linux/device.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/power_supply.h>
#include <linux/olpc-ec.h>

#include <linux/acpi.h>
#include <asm/olpc.h>

#define DRV_NAME			"olpc-xo15-sci"
#define PFX				DRV_NAME ": "
#define XO15_SCI_CLASS			DRV_NAME
#define XO15_SCI_DEVICE_NAME		"OLPC XO-1.5 SCI"

static unsigned long			xo15_sci_gpe;
static bool				lid_wake_on_close;

/*
 * The normal ACPI LID wakeup behavior is wake-on-open, but not
 * wake-on-close. This is implemented as standard by the XO-1.5 DSDT.
 *
 * We provide here a sysfs attribute that will additionally enable
 * wake-on-close behavior. This is useful (e.g.) when we opportunistically
 * suspend with the display running; if the lid is then closed, we want to
 * wake up to turn the display off.
 *
 * This is controlled through a custom method in the XO-1.5 DSDT.
 */
static int set_lid_wake_behavior(bool wake_on_close)
{
	acpi_status status;

	status = acpi_execute_simple_method(NULL, "\\_SB.PCI0.LID.LIDW", wake_on_close);
	if (ACPI_FAILURE(status)) {
		pr_warn(PFX "failed to set lid behavior\n");
		return 1;
	}

	lid_wake_on_close = wake_on_close;

	return 0;
}

static ssize_t
lid_wake_on_close_show(struct kobject *s, struct kobj_attribute *attr, char *buf)
{
	return sprintf(buf, "%u\n", lid_wake_on_close);
}

static ssize_t lid_wake_on_close_store(struct kobject *s,
				       struct kobj_attribute *attr,
				       const char *buf, size_t n)
{
	unsigned int val;

	if (sscanf(buf, "%u", &val) != 1)
		return -EINVAL;

	set_lid_wake_behavior(!!val);

	return n;
}

static struct kobj_attribute lid_wake_on_close_attr =
	__ATTR(lid_wake_on_close, 0644,
	       lid_wake_on_close_show,
	       lid_wake_on_close_store);

static void battery_status_changed(void)
{
	struct power_supply *psy = power_supply_get_by_name("olpc_battery");

	if (psy) {
		power_supply_changed(psy);
		power_supply_put(psy);
	}
}

static void ac_status_changed(void)
{
	struct power_supply *psy = power_supply_get_by_name("olpc_ac");

	if (psy) {
		power_supply_changed(psy);
		power_supply_put(psy);
	}
}

static void process_sci_queue(void)
{
	u16 data;
	int r;

	do {
		r = olpc_ec_sci_query(&data);
		if (r || !data)
			break;

		pr_debug(PFX "SCI 0x%x received\n", data);

		switch (data) {
		case EC_SCI_SRC_BATERR:
		case EC_SCI_SRC_BATSOC:
		case EC_SCI_SRC_BATTERY:
		case EC_SCI_SRC_BATCRIT:
			battery_status_changed();
			break;
		case EC_SCI_SRC_ACPWR:
			ac_status_changed();
			break;
		}
	} while (data);

	if (r)
		pr_err(PFX "Failed to clear SCI queue");
}

static void process_sci_queue_work(struct work_struct *work)
{
	process_sci_queue();
}

static DECLARE_WORK(sci_work, process_sci_queue_work);

static u32 xo15_sci_gpe_handler(acpi_handle gpe_device, u32 gpe, void *context)
{
	schedule_work(&sci_work);
	return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE;
}

static int xo15_sci_add(struct acpi_device *device)
{
	unsigned long long tmp;
	acpi_status status;
	int r;

	if (!device)
		return -EINVAL;

	strcpy(acpi_device_name(device), XO15_SCI_DEVICE_NAME);
	strcpy(acpi_device_class(device), XO15_SCI_CLASS);

	/* Get GPE bit assignment (EC events). */
	status = acpi_evaluate_integer(device->handle, "_GPE", NULL, &tmp);
	if (ACPI_FAILURE(status))
		return -EINVAL;

	xo15_sci_gpe = tmp;
	status = acpi_install_gpe_handler(NULL, xo15_sci_gpe,
					  ACPI_GPE_EDGE_TRIGGERED,
					  xo15_sci_gpe_handler, device);
	if (ACPI_FAILURE(status))
		return -ENODEV;

	dev_info(&device->dev, "Initialized, GPE = 0x%lx\n", xo15_sci_gpe);

	r = sysfs_create_file(&device->dev.kobj, &lid_wake_on_close_attr.attr);
	if (r)
		goto err_sysfs;

	/* Flush queue, and enable all SCI events */
	process_sci_queue();
	olpc_ec_mask_write(EC_SCI_SRC_ALL);

	acpi_enable_gpe(NULL, xo15_sci_gpe);

	/* Enable wake-on-EC */
	if (device->wakeup.flags.valid)
		device_init_wakeup(&device->dev, true);

	return 0;

err_sysfs:
	acpi_remove_gpe_handler(NULL, xo15_sci_gpe, xo15_sci_gpe_handler);
	cancel_work_sync(&sci_work);
	return r;
}

static int xo15_sci_remove(struct acpi_device *device)
{
	acpi_disable_gpe(NULL, xo15_sci_gpe);
	acpi_remove_gpe_handler(NULL, xo15_sci_gpe, xo15_sci_gpe_handler);
	cancel_work_sync(&sci_work);
	sysfs_remove_file(&device->dev.kobj, &lid_wake_on_close_attr.attr);
	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int xo15_sci_resume(struct device *dev)
{
	/* Enable all EC events */
	olpc_ec_mask_write(EC_SCI_SRC_ALL);

	/* Power/battery status might have changed */
	battery_status_changed();
	ac_status_changed();

	return 0;
}
#endif

static SIMPLE_DEV_PM_OPS(xo15_sci_pm, NULL, xo15_sci_resume);

static const struct acpi_device_id xo15_sci_device_ids[] = {
	{"XO15EC", 0},
	{"", 0},
};

static struct acpi_driver xo15_sci_drv = {
	.name = DRV_NAME,
	.class = XO15_SCI_CLASS,
	.ids = xo15_sci_device_ids,
	.ops = {
		.add = xo15_sci_add,
		.remove = xo15_sci_remove,
	},
	.drv.pm = &xo15_sci_pm,
};

static int __init xo15_sci_init(void)
{
	return acpi_bus_register_driver(&xo15_sci_drv);
}
device_initcall(xo15_sci_init);
