// SPDX-License-Identifier: GPL-2.0+
/*
 * Driver for the Surface ACPI Notify (SAN) interface/shim.
 *
 * Translates communication from ACPI to Surface System Aggregator Module
 * (SSAM/SAM) requests and back, specifically SAM-over-SSH. Translates SSAM
 * events back to ACPI notifications. Allows handling of discrete GPU
 * notifications sent from ACPI via the SAN interface by providing them to any
 * registered external driver.
 *
 * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com>
 */

#include <asm/unaligned.h>
#include <linux/acpi.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/platform_device.h>
#include <linux/rwsem.h>

#include <linux/surface_aggregator/controller.h>
#include <linux/surface_acpi_notify.h>

struct san_data {
	struct device *dev;
	struct ssam_controller *ctrl;

	struct acpi_connection_info info;

	struct ssam_event_notifier nf_bat;
	struct ssam_event_notifier nf_tmp;
};

#define to_san_data(ptr, member) \
	container_of(ptr, struct san_data, member)

static struct workqueue_struct *san_wq;

/* -- dGPU notifier interface. ---------------------------------------------- */

struct san_rqsg_if {
	struct rw_semaphore lock;
	struct device *dev;
	struct blocking_notifier_head nh;
};

static struct san_rqsg_if san_rqsg_if = {
	.lock = __RWSEM_INITIALIZER(san_rqsg_if.lock),
	.dev = NULL,
	.nh = BLOCKING_NOTIFIER_INIT(san_rqsg_if.nh),
};

static int san_set_rqsg_interface_device(struct device *dev)
{
	int status = 0;

	down_write(&san_rqsg_if.lock);
	if (!san_rqsg_if.dev && dev)
		san_rqsg_if.dev = dev;
	else
		status = -EBUSY;
	up_write(&san_rqsg_if.lock);

	return status;
}

/**
 * san_client_link() - Link client as consumer to SAN device.
 * @client: The client to link.
 *
 * Sets up a device link between the provided client device as consumer and
 * the SAN device as provider. This function can be used to ensure that the
 * SAN interface has been set up and will be set up for as long as the driver
 * of the client device is bound. This guarantees that, during that time, all
 * dGPU events will be received by any registered notifier.
 *
 * The link will be automatically removed once the client device's driver is
 * unbound.
 *
 * Return: Returns zero on success, %-ENXIO if the SAN interface has not been
 * set up yet, and %-ENOMEM if device link creation failed.
 */
int san_client_link(struct device *client)
{
	const u32 flags = DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_CONSUMER;
	struct device_link *link;

	down_read(&san_rqsg_if.lock);

	if (!san_rqsg_if.dev) {
		up_read(&san_rqsg_if.lock);
		return -ENXIO;
	}

	link = device_link_add(client, san_rqsg_if.dev, flags);
	if (!link) {
		up_read(&san_rqsg_if.lock);
		return -ENOMEM;
	}

	if (READ_ONCE(link->status) == DL_STATE_SUPPLIER_UNBIND) {
		up_read(&san_rqsg_if.lock);
		return -ENXIO;
	}

	up_read(&san_rqsg_if.lock);
	return 0;
}
EXPORT_SYMBOL_GPL(san_client_link);

/**
 * san_dgpu_notifier_register() - Register a SAN dGPU notifier.
 * @nb: The notifier-block to register.
 *
 * Registers a SAN dGPU notifier, receiving any new SAN dGPU events sent from
 * ACPI. The registered notifier will be called with &struct san_dgpu_event
 * as notifier data and the command ID of that event as notifier action.
 */
int san_dgpu_notifier_register(struct notifier_block *nb)
{
	return blocking_notifier_chain_register(&san_rqsg_if.nh, nb);
}
EXPORT_SYMBOL_GPL(san_dgpu_notifier_register);

/**
 * san_dgpu_notifier_unregister() - Unregister a SAN dGPU notifier.
 * @nb: The notifier-block to unregister.
 */
int san_dgpu_notifier_unregister(struct notifier_block *nb)
{
	return blocking_notifier_chain_unregister(&san_rqsg_if.nh, nb);
}
EXPORT_SYMBOL_GPL(san_dgpu_notifier_unregister);

static int san_dgpu_notifier_call(struct san_dgpu_event *evt)
{
	int ret;

	ret = blocking_notifier_call_chain(&san_rqsg_if.nh, evt->command, evt);
	return notifier_to_errno(ret);
}


/* -- ACPI _DSM event relay. ------------------------------------------------ */

#define SAN_DSM_REVISION	0

/* 93b666c5-70c6-469f-a215-3d487c91ab3c */
static const guid_t SAN_DSM_UUID =
	GUID_INIT(0x93b666c5, 0x70c6, 0x469f, 0xa2, 0x15, 0x3d,
		  0x48, 0x7c, 0x91, 0xab, 0x3c);

enum san_dsm_event_fn {
	SAN_DSM_EVENT_FN_BAT1_STAT = 0x03,
	SAN_DSM_EVENT_FN_BAT1_INFO = 0x04,
	SAN_DSM_EVENT_FN_ADP1_STAT = 0x05,
	SAN_DSM_EVENT_FN_ADP1_INFO = 0x06,
	SAN_DSM_EVENT_FN_BAT2_STAT = 0x07,
	SAN_DSM_EVENT_FN_BAT2_INFO = 0x08,
	SAN_DSM_EVENT_FN_THERMAL   = 0x09,
	SAN_DSM_EVENT_FN_DPTF      = 0x0a,
};

enum sam_event_cid_bat {
	SAM_EVENT_CID_BAT_BIX  = 0x15,
	SAM_EVENT_CID_BAT_BST  = 0x16,
	SAM_EVENT_CID_BAT_ADP  = 0x17,
	SAM_EVENT_CID_BAT_PROT = 0x18,
	SAM_EVENT_CID_BAT_DPTF = 0x4f,
};

enum sam_event_cid_tmp {
	SAM_EVENT_CID_TMP_TRIP = 0x0b,
};

struct san_event_work {
	struct delayed_work work;
	struct device *dev;
	struct ssam_event event;	/* must be last */
};

static int san_acpi_notify_event(struct device *dev, u64 func,
				 union acpi_object *param)
{
	acpi_handle san = ACPI_HANDLE(dev);
	union acpi_object *obj;
	int status = 0;

	if (!acpi_check_dsm(san, &SAN_DSM_UUID, SAN_DSM_REVISION, BIT_ULL(func)))
		return 0;

	dev_dbg(dev, "notify event %#04llx\n", func);

	obj = acpi_evaluate_dsm_typed(san, &SAN_DSM_UUID, SAN_DSM_REVISION,
				      func, param, ACPI_TYPE_BUFFER);
	if (!obj)
		return -EFAULT;

	if (obj->buffer.length != 1 || obj->buffer.pointer[0] != 0) {
		dev_err(dev, "got unexpected result from _DSM\n");
		status = -EPROTO;
	}

	ACPI_FREE(obj);
	return status;
}

static int san_evt_bat_adp(struct device *dev, const struct ssam_event *event)
{
	int status;

	status = san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_ADP1_STAT, NULL);
	if (status)
		return status;

	/*
	 * Ensure that the battery states get updated correctly. When the
	 * battery is fully charged and an adapter is plugged in, it sometimes
	 * is not updated correctly, instead showing it as charging.
	 * Explicitly trigger battery updates to fix this.
	 */

	status = san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_BAT1_STAT, NULL);
	if (status)
		return status;

	return san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_BAT2_STAT, NULL);
}

static int san_evt_bat_bix(struct device *dev, const struct ssam_event *event)
{
	enum san_dsm_event_fn fn;

	if (event->instance_id == 0x02)
		fn = SAN_DSM_EVENT_FN_BAT2_INFO;
	else
		fn = SAN_DSM_EVENT_FN_BAT1_INFO;

	return san_acpi_notify_event(dev, fn, NULL);
}

static int san_evt_bat_bst(struct device *dev, const struct ssam_event *event)
{
	enum san_dsm_event_fn fn;

	if (event->instance_id == 0x02)
		fn = SAN_DSM_EVENT_FN_BAT2_STAT;
	else
		fn = SAN_DSM_EVENT_FN_BAT1_STAT;

	return san_acpi_notify_event(dev, fn, NULL);
}

static int san_evt_bat_dptf(struct device *dev, const struct ssam_event *event)
{
	union acpi_object payload;

	/*
	 * The Surface ACPI expects a buffer and not a package. It specifically
	 * checks for ObjectType (Arg3) == 0x03. This will cause a warning in
	 * acpica/nsarguments.c, but that warning can be safely ignored.
	 */
	payload.type = ACPI_TYPE_BUFFER;
	payload.buffer.length = event->length;
	payload.buffer.pointer = (u8 *)&event->data[0];

	return san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_DPTF, &payload);
}

static unsigned long san_evt_bat_delay(u8 cid)
{
	switch (cid) {
	case SAM_EVENT_CID_BAT_ADP:
		/*
		 * Wait for battery state to update before signaling adapter
		 * change.
		 */
		return msecs_to_jiffies(5000);

	case SAM_EVENT_CID_BAT_BST:
		/* Ensure we do not miss anything important due to caching. */
		return msecs_to_jiffies(2000);

	default:
		return 0;
	}
}

static bool san_evt_bat(const struct ssam_event *event, struct device *dev)
{
	int status;

	switch (event->command_id) {
	case SAM_EVENT_CID_BAT_BIX:
		status = san_evt_bat_bix(dev, event);
		break;

	case SAM_EVENT_CID_BAT_BST:
		status = san_evt_bat_bst(dev, event);
		break;

	case SAM_EVENT_CID_BAT_ADP:
		status = san_evt_bat_adp(dev, event);
		break;

	case SAM_EVENT_CID_BAT_PROT:
		/*
		 * TODO: Implement support for battery protection status change
		 *       event.
		 */
		return true;

	case SAM_EVENT_CID_BAT_DPTF:
		status = san_evt_bat_dptf(dev, event);
		break;

	default:
		return false;
	}

	if (status) {
		dev_err(dev, "error handling power event (cid = %#04x)\n",
			event->command_id);
	}

	return true;
}

static void san_evt_bat_workfn(struct work_struct *work)
{
	struct san_event_work *ev;

	ev = container_of(work, struct san_event_work, work.work);
	san_evt_bat(&ev->event, ev->dev);
	kfree(ev);
}

static u32 san_evt_bat_nf(struct ssam_event_notifier *nf,
			  const struct ssam_event *event)
{
	struct san_data *d = to_san_data(nf, nf_bat);
	struct san_event_work *work;
	unsigned long delay = san_evt_bat_delay(event->command_id);

	if (delay == 0)
		return san_evt_bat(event, d->dev) ? SSAM_NOTIF_HANDLED : 0;

	work = kzalloc(sizeof(*work) + event->length, GFP_KERNEL);
	if (!work)
		return ssam_notifier_from_errno(-ENOMEM);

	INIT_DELAYED_WORK(&work->work, san_evt_bat_workfn);
	work->dev = d->dev;

	work->event = *event;
	memcpy(work->event.data, event->data, event->length);

	queue_delayed_work(san_wq, &work->work, delay);
	return SSAM_NOTIF_HANDLED;
}

static int san_evt_tmp_trip(struct device *dev, const struct ssam_event *event)
{
	union acpi_object param;

	/*
	 * The Surface ACPI expects an integer and not a package. This will
	 * cause a warning in acpica/nsarguments.c, but that warning can be
	 * safely ignored.
	 */
	param.type = ACPI_TYPE_INTEGER;
	param.integer.value = event->instance_id;

	return san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_THERMAL, &param);
}

static bool san_evt_tmp(const struct ssam_event *event, struct device *dev)
{
	int status;

	switch (event->command_id) {
	case SAM_EVENT_CID_TMP_TRIP:
		status = san_evt_tmp_trip(dev, event);
		break;

	default:
		return false;
	}

	if (status) {
		dev_err(dev, "error handling thermal event (cid = %#04x)\n",
			event->command_id);
	}

	return true;
}

static u32 san_evt_tmp_nf(struct ssam_event_notifier *nf,
			  const struct ssam_event *event)
{
	struct san_data *d = to_san_data(nf, nf_tmp);

	return san_evt_tmp(event, d->dev) ? SSAM_NOTIF_HANDLED : 0;
}


/* -- ACPI GSB OperationRegion handler -------------------------------------- */

struct gsb_data_in {
	u8 cv;
} __packed;

struct gsb_data_rqsx {
	u8 cv;				/* Command value (san_gsb_request_cv). */
	u8 tc;				/* Target category. */
	u8 tid;				/* Target ID. */
	u8 iid;				/* Instance ID. */
	u8 snc;				/* Expect-response-flag. */
	u8 cid;				/* Command ID. */
	u16 cdl;			/* Payload length. */
	u8 pld[];			/* Payload. */
} __packed;

struct gsb_data_etwl {
	u8 cv;				/* Command value (should be 0x02). */
	u8 etw3;			/* Unknown. */
	u8 etw4;			/* Unknown. */
	u8 msg[];			/* Error message (ASCIIZ). */
} __packed;

struct gsb_data_out {
	u8 status;			/* _SSH communication status. */
	u8 len;				/* _SSH payload length. */
	u8 pld[];			/* _SSH payload. */
} __packed;

union gsb_buffer_data {
	struct gsb_data_in   in;	/* Common input. */
	struct gsb_data_rqsx rqsx;	/* RQSX input. */
	struct gsb_data_etwl etwl;	/* ETWL input. */
	struct gsb_data_out  out;	/* Output. */
};

struct gsb_buffer {
	u8 status;			/* GSB AttribRawProcess status. */
	u8 len;				/* GSB AttribRawProcess length. */
	union gsb_buffer_data data;
} __packed;

#define SAN_GSB_MAX_RQSX_PAYLOAD  (U8_MAX - 2 - sizeof(struct gsb_data_rqsx))
#define SAN_GSB_MAX_RESPONSE	  (U8_MAX - 2 - sizeof(struct gsb_data_out))

#define SAN_GSB_COMMAND		0

enum san_gsb_request_cv {
	SAN_GSB_REQUEST_CV_RQST = 0x01,
	SAN_GSB_REQUEST_CV_ETWL = 0x02,
	SAN_GSB_REQUEST_CV_RQSG = 0x03,
};

#define SAN_REQUEST_NUM_TRIES	5

static acpi_status san_etwl(struct san_data *d, struct gsb_buffer *b)
{
	struct gsb_data_etwl *etwl = &b->data.etwl;

	if (b->len < sizeof(struct gsb_data_etwl)) {
		dev_err(d->dev, "invalid ETWL package (len = %d)\n", b->len);
		return AE_OK;
	}

	dev_err(d->dev, "ETWL(%#04x, %#04x): %.*s\n", etwl->etw3, etwl->etw4,
		(unsigned int)(b->len - sizeof(struct gsb_data_etwl)),
		(char *)etwl->msg);

	/* Indicate success. */
	b->status = 0x00;
	b->len = 0x00;

	return AE_OK;
}

static
struct gsb_data_rqsx *san_validate_rqsx(struct device *dev, const char *type,
					struct gsb_buffer *b)
{
	struct gsb_data_rqsx *rqsx = &b->data.rqsx;

	if (b->len < sizeof(struct gsb_data_rqsx)) {
		dev_err(dev, "invalid %s package (len = %d)\n", type, b->len);
		return NULL;
	}

	if (get_unaligned(&rqsx->cdl) != b->len - sizeof(struct gsb_data_rqsx)) {
		dev_err(dev, "bogus %s package (len = %d, cdl = %d)\n",
			type, b->len, get_unaligned(&rqsx->cdl));
		return NULL;
	}

	if (get_unaligned(&rqsx->cdl) > SAN_GSB_MAX_RQSX_PAYLOAD) {
		dev_err(dev, "payload for %s package too large (cdl = %d)\n",
			type, get_unaligned(&rqsx->cdl));
		return NULL;
	}

	return rqsx;
}

static void gsb_rqsx_response_error(struct gsb_buffer *gsb, int status)
{
	gsb->status = 0x00;
	gsb->len = 0x02;
	gsb->data.out.status = (u8)(-status);
	gsb->data.out.len = 0x00;
}

static void gsb_rqsx_response_success(struct gsb_buffer *gsb, u8 *ptr, size_t len)
{
	gsb->status = 0x00;
	gsb->len = len + 2;
	gsb->data.out.status = 0x00;
	gsb->data.out.len = len;

	if (len)
		memcpy(&gsb->data.out.pld[0], ptr, len);
}

static acpi_status san_rqst_fixup_suspended(struct san_data *d,
					    struct ssam_request *rqst,
					    struct gsb_buffer *gsb)
{
	if (rqst->target_category == SSAM_SSH_TC_BAS && rqst->command_id == 0x0D) {
		u8 base_state = 1;

		/* Base state quirk:
		 * The base state may be queried from ACPI when the EC is still
		 * suspended. In this case it will return '-EPERM'. This query
		 * will only be triggered from the ACPI lid GPE interrupt, thus
		 * we are either in laptop or studio mode (base status 0x01 or
		 * 0x02). Furthermore, we will only get here if the device (and
		 * EC) have been suspended.
		 *
		 * We now assume that the device is in laptop mode (0x01). This
		 * has the drawback that it will wake the device when unfolding
		 * it in studio mode, but it also allows us to avoid actively
		 * waiting for the EC to wake up, which may incur a notable
		 * delay.
		 */

		dev_dbg(d->dev, "rqst: fixup: base-state quirk\n");

		gsb_rqsx_response_success(gsb, &base_state, sizeof(base_state));
		return AE_OK;
	}

	gsb_rqsx_response_error(gsb, -ENXIO);
	return AE_OK;
}

static acpi_status san_rqst(struct san_data *d, struct gsb_buffer *buffer)
{
	u8 rspbuf[SAN_GSB_MAX_RESPONSE];
	struct gsb_data_rqsx *gsb_rqst;
	struct ssam_request rqst;
	struct ssam_response rsp;
	int status = 0;

	gsb_rqst = san_validate_rqsx(d->dev, "RQST", buffer);
	if (!gsb_rqst)
		return AE_OK;

	rqst.target_category = gsb_rqst->tc;
	rqst.target_id = gsb_rqst->tid;
	rqst.command_id = gsb_rqst->cid;
	rqst.instance_id = gsb_rqst->iid;
	rqst.flags = gsb_rqst->snc ? SSAM_REQUEST_HAS_RESPONSE : 0;
	rqst.length = get_unaligned(&gsb_rqst->cdl);
	rqst.payload = &gsb_rqst->pld[0];

	rsp.capacity = ARRAY_SIZE(rspbuf);
	rsp.length = 0;
	rsp.pointer = &rspbuf[0];

	/* Handle suspended device. */
	if (d->dev->power.is_suspended) {
		dev_warn(d->dev, "rqst: device is suspended, not executing\n");
		return san_rqst_fixup_suspended(d, &rqst, buffer);
	}

	status = __ssam_retry(ssam_request_do_sync_onstack, SAN_REQUEST_NUM_TRIES,
			      d->ctrl, &rqst, &rsp, SAN_GSB_MAX_RQSX_PAYLOAD);

	if (!status) {
		gsb_rqsx_response_success(buffer, rsp.pointer, rsp.length);
	} else {
		dev_err(d->dev, "rqst: failed with error %d\n", status);
		gsb_rqsx_response_error(buffer, status);
	}

	return AE_OK;
}

static acpi_status san_rqsg(struct san_data *d, struct gsb_buffer *buffer)
{
	struct gsb_data_rqsx *gsb_rqsg;
	struct san_dgpu_event evt;
	int status;

	gsb_rqsg = san_validate_rqsx(d->dev, "RQSG", buffer);
	if (!gsb_rqsg)
		return AE_OK;

	evt.category = gsb_rqsg->tc;
	evt.target = gsb_rqsg->tid;
	evt.command = gsb_rqsg->cid;
	evt.instance = gsb_rqsg->iid;
	evt.length = get_unaligned(&gsb_rqsg->cdl);
	evt.payload = &gsb_rqsg->pld[0];

	status = san_dgpu_notifier_call(&evt);
	if (!status) {
		gsb_rqsx_response_success(buffer, NULL, 0);
	} else {
		dev_err(d->dev, "rqsg: failed with error %d\n", status);
		gsb_rqsx_response_error(buffer, status);
	}

	return AE_OK;
}

static acpi_status san_opreg_handler(u32 function, acpi_physical_address command,
				     u32 bits, u64 *value64, void *opreg_context,
				     void *region_context)
{
	struct san_data *d = to_san_data(opreg_context, info);
	struct gsb_buffer *buffer = (struct gsb_buffer *)value64;
	int accessor_type = (function & 0xFFFF0000) >> 16;

	if (command != SAN_GSB_COMMAND) {
		dev_warn(d->dev, "unsupported command: %#04llx\n", command);
		return AE_OK;
	}

	if (accessor_type != ACPI_GSB_ACCESS_ATTRIB_RAW_PROCESS) {
		dev_err(d->dev, "invalid access type: %#04x\n", accessor_type);
		return AE_OK;
	}

	/* Buffer must have at least contain the command-value. */
	if (buffer->len == 0) {
		dev_err(d->dev, "request-package too small\n");
		return AE_OK;
	}

	switch (buffer->data.in.cv) {
	case SAN_GSB_REQUEST_CV_RQST:
		return san_rqst(d, buffer);

	case SAN_GSB_REQUEST_CV_ETWL:
		return san_etwl(d, buffer);

	case SAN_GSB_REQUEST_CV_RQSG:
		return san_rqsg(d, buffer);

	default:
		dev_warn(d->dev, "unsupported SAN0 request (cv: %#04x)\n",
			 buffer->data.in.cv);
		return AE_OK;
	}
}


/* -- Driver setup. --------------------------------------------------------- */

static int san_events_register(struct platform_device *pdev)
{
	struct san_data *d = platform_get_drvdata(pdev);
	int status;

	d->nf_bat.base.priority = 1;
	d->nf_bat.base.fn = san_evt_bat_nf;
	d->nf_bat.event.reg = SSAM_EVENT_REGISTRY_SAM;
	d->nf_bat.event.id.target_category = SSAM_SSH_TC_BAT;
	d->nf_bat.event.id.instance = 0;
	d->nf_bat.event.mask = SSAM_EVENT_MASK_TARGET;
	d->nf_bat.event.flags = SSAM_EVENT_SEQUENCED;

	d->nf_tmp.base.priority = 1;
	d->nf_tmp.base.fn = san_evt_tmp_nf;
	d->nf_tmp.event.reg = SSAM_EVENT_REGISTRY_SAM;
	d->nf_tmp.event.id.target_category = SSAM_SSH_TC_TMP;
	d->nf_tmp.event.id.instance = 0;
	d->nf_tmp.event.mask = SSAM_EVENT_MASK_TARGET;
	d->nf_tmp.event.flags = SSAM_EVENT_SEQUENCED;

	status = ssam_notifier_register(d->ctrl, &d->nf_bat);
	if (status)
		return status;

	status = ssam_notifier_register(d->ctrl, &d->nf_tmp);
	if (status)
		ssam_notifier_unregister(d->ctrl, &d->nf_bat);

	return status;
}

static void san_events_unregister(struct platform_device *pdev)
{
	struct san_data *d = platform_get_drvdata(pdev);

	ssam_notifier_unregister(d->ctrl, &d->nf_bat);
	ssam_notifier_unregister(d->ctrl, &d->nf_tmp);
}

#define san_consumer_printk(level, dev, handle, fmt, ...)			\
do {										\
	char *path = "<error getting consumer path>";				\
	struct acpi_buffer buffer = {						\
		.length = ACPI_ALLOCATE_BUFFER,					\
		.pointer = NULL,						\
	};									\
										\
	if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer)))	\
		path = buffer.pointer;						\
										\
	dev_##level(dev, "[%s]: " fmt, path, ##__VA_ARGS__);			\
	kfree(buffer.pointer);							\
} while (0)

#define san_consumer_dbg(dev, handle, fmt, ...) \
	san_consumer_printk(dbg, dev, handle, fmt, ##__VA_ARGS__)

#define san_consumer_warn(dev, handle, fmt, ...) \
	san_consumer_printk(warn, dev, handle, fmt, ##__VA_ARGS__)

static acpi_status san_consumer_setup(acpi_handle handle, u32 lvl,
				      void *context, void **rv)
{
	const u32 flags = DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER;
	struct platform_device *pdev = context;
	struct acpi_device *adev;
	struct device_link *link;

	if (!acpi_device_dep(handle, ACPI_HANDLE(&pdev->dev)))
		return AE_OK;

	/* Ignore ACPI devices that are not present. */
	adev = acpi_fetch_acpi_dev(handle);
	if (!adev)
		return AE_OK;

	san_consumer_dbg(&pdev->dev, handle, "creating device link\n");

	/* Try to set up device links, ignore but log errors. */
	link = device_link_add(&adev->dev, &pdev->dev, flags);
	if (!link) {
		san_consumer_warn(&pdev->dev, handle, "failed to create device link\n");
		return AE_OK;
	}

	return AE_OK;
}

static int san_consumer_links_setup(struct platform_device *pdev)
{
	acpi_status status;

	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
				     ACPI_UINT32_MAX, san_consumer_setup, NULL,
				     pdev, NULL);

	return status ? -EFAULT : 0;
}

static int san_probe(struct platform_device *pdev)
{
	struct acpi_device *san = ACPI_COMPANION(&pdev->dev);
	struct ssam_controller *ctrl;
	struct san_data *data;
	acpi_status astatus;
	int status;

	ctrl = ssam_client_bind(&pdev->dev);
	if (IS_ERR(ctrl))
		return PTR_ERR(ctrl) == -ENODEV ? -EPROBE_DEFER : PTR_ERR(ctrl);

	status = san_consumer_links_setup(pdev);
	if (status)
		return status;

	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->dev = &pdev->dev;
	data->ctrl = ctrl;

	platform_set_drvdata(pdev, data);

	astatus = acpi_install_address_space_handler(san->handle,
						     ACPI_ADR_SPACE_GSBUS,
						     &san_opreg_handler, NULL,
						     &data->info);
	if (ACPI_FAILURE(astatus))
		return -ENXIO;

	status = san_events_register(pdev);
	if (status)
		goto err_enable_events;

	status = san_set_rqsg_interface_device(&pdev->dev);
	if (status)
		goto err_install_dev;

	acpi_dev_clear_dependencies(san);
	return 0;

err_install_dev:
	san_events_unregister(pdev);
err_enable_events:
	acpi_remove_address_space_handler(san, ACPI_ADR_SPACE_GSBUS,
					  &san_opreg_handler);
	return status;
}

static void san_remove(struct platform_device *pdev)
{
	acpi_handle san = ACPI_HANDLE(&pdev->dev);

	san_set_rqsg_interface_device(NULL);
	acpi_remove_address_space_handler(san, ACPI_ADR_SPACE_GSBUS,
					  &san_opreg_handler);
	san_events_unregister(pdev);

	/*
	 * We have unregistered our event sources. Now we need to ensure that
	 * all delayed works they may have spawned are run to completion.
	 */
	flush_workqueue(san_wq);
}

static const struct acpi_device_id san_match[] = {
	{ "MSHW0091" },
	{ },
};
MODULE_DEVICE_TABLE(acpi, san_match);

static struct platform_driver surface_acpi_notify = {
	.probe = san_probe,
	.remove_new = san_remove,
	.driver = {
		.name = "surface_acpi_notify",
		.acpi_match_table = san_match,
		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
	},
};

static int __init san_init(void)
{
	int ret;

	san_wq = alloc_workqueue("san_wq", 0, 0);
	if (!san_wq)
		return -ENOMEM;
	ret = platform_driver_register(&surface_acpi_notify);
	if (ret)
		destroy_workqueue(san_wq);
	return ret;
}
module_init(san_init);

static void __exit san_exit(void)
{
	platform_driver_unregister(&surface_acpi_notify);
	destroy_workqueue(san_wq);
}
module_exit(san_exit);

MODULE_AUTHOR("Maximilian Luz <luzmaximilian@gmail.com>");
MODULE_DESCRIPTION("Surface ACPI Notify driver for Surface System Aggregator Module");
MODULE_LICENSE("GPL");
