// SPDX-License-Identifier: GPL-2.0+
/*
 * Main SSAM/SSH controller structure and functionality.
 *
 * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
 */

#include <linux/acpi.h>
#include <linux/atomic.h>
#include <linux/completion.h>
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/kref.h>
#include <linux/limits.h>
#include <linux/list.h>
#include <linux/lockdep.h>
#include <linux/mutex.h>
#include <linux/rculist.h>
#include <linux/rbtree.h>
#include <linux/rwsem.h>
#include <linux/serdev.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/srcu.h>
#include <linux/types.h>
#include <linux/workqueue.h>

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

#include "controller.h"
#include "ssh_msgb.h"
#include "ssh_request_layer.h"

#include "trace.h"


/* -- Safe counters. -------------------------------------------------------- */

/**
 * ssh_seq_reset() - Reset/initialize sequence ID counter.
 * @c: The counter to reset.
 */
static void ssh_seq_reset(struct ssh_seq_counter *c)
{
	WRITE_ONCE(c->value, 0);
}

/**
 * ssh_seq_next() - Get next sequence ID.
 * @c: The counter providing the sequence IDs.
 *
 * Return: Returns the next sequence ID of the counter.
 */
static u8 ssh_seq_next(struct ssh_seq_counter *c)
{
	u8 old = READ_ONCE(c->value);
	u8 new = old + 1;
	u8 ret;

	while (unlikely((ret = cmpxchg(&c->value, old, new)) != old)) {
		old = ret;
		new = old + 1;
	}

	return old;
}

/**
 * ssh_rqid_reset() - Reset/initialize request ID counter.
 * @c: The counter to reset.
 */
static void ssh_rqid_reset(struct ssh_rqid_counter *c)
{
	WRITE_ONCE(c->value, 0);
}

/**
 * ssh_rqid_next() - Get next request ID.
 * @c: The counter providing the request IDs.
 *
 * Return: Returns the next request ID of the counter, skipping any reserved
 * request IDs.
 */
static u16 ssh_rqid_next(struct ssh_rqid_counter *c)
{
	u16 old = READ_ONCE(c->value);
	u16 new = ssh_rqid_next_valid(old);
	u16 ret;

	while (unlikely((ret = cmpxchg(&c->value, old, new)) != old)) {
		old = ret;
		new = ssh_rqid_next_valid(old);
	}

	return old;
}


/* -- Event notifier/callbacks. --------------------------------------------- */
/*
 * The notifier system is based on linux/notifier.h, specifically the SRCU
 * implementation. The difference to that is, that some bits of the notifier
 * call return value can be tracked across multiple calls. This is done so
 * that handling of events can be tracked and a warning can be issued in case
 * an event goes unhandled. The idea of that warning is that it should help
 * discover and identify new/currently unimplemented features.
 */

/**
 * ssam_event_matches_notifier() - Test if an event matches a notifier.
 * @n: The event notifier to test against.
 * @event: The event to test.
 *
 * Return: Returns %true if the given event matches the given notifier
 * according to the rules set in the notifier's event mask, %false otherwise.
 */
static bool ssam_event_matches_notifier(const struct ssam_event_notifier *n,
					const struct ssam_event *event)
{
	bool match = n->event.id.target_category == event->target_category;

	if (n->event.mask & SSAM_EVENT_MASK_TARGET)
		match &= n->event.reg.target_id == event->target_id;

	if (n->event.mask & SSAM_EVENT_MASK_INSTANCE)
		match &= n->event.id.instance == event->instance_id;

	return match;
}

/**
 * ssam_nfblk_call_chain() - Call event notifier callbacks of the given chain.
 * @nh:    The notifier head for which the notifier callbacks should be called.
 * @event: The event data provided to the callbacks.
 *
 * Call all registered notifier callbacks in order of their priority until
 * either no notifier is left or a notifier returns a value with the
 * %SSAM_NOTIF_STOP bit set. Note that this bit is automatically set via
 * ssam_notifier_from_errno() on any non-zero error value.
 *
 * Return: Returns the notifier status value, which contains the notifier
 * status bits (%SSAM_NOTIF_HANDLED and %SSAM_NOTIF_STOP) as well as a
 * potential error value returned from the last executed notifier callback.
 * Use ssam_notifier_to_errno() to convert this value to the original error
 * value.
 */
static int ssam_nfblk_call_chain(struct ssam_nf_head *nh, struct ssam_event *event)
{
	struct ssam_event_notifier *nf;
	int ret = 0, idx;

	idx = srcu_read_lock(&nh->srcu);

	list_for_each_entry_rcu(nf, &nh->head, base.node,
				srcu_read_lock_held(&nh->srcu)) {
		if (ssam_event_matches_notifier(nf, event)) {
			ret = (ret & SSAM_NOTIF_STATE_MASK) | nf->base.fn(nf, event);
			if (ret & SSAM_NOTIF_STOP)
				break;
		}
	}

	srcu_read_unlock(&nh->srcu, idx);
	return ret;
}

/**
 * ssam_nfblk_insert() - Insert a new notifier block into the given notifier
 * list.
 * @nh: The notifier head into which the block should be inserted.
 * @nb: The notifier block to add.
 *
 * Note: This function must be synchronized by the caller with respect to other
 * insert, find, and/or remove calls by holding ``struct ssam_nf.lock``.
 *
 * Return: Returns zero on success, %-EEXIST if the notifier block has already
 * been registered.
 */
static int ssam_nfblk_insert(struct ssam_nf_head *nh, struct ssam_notifier_block *nb)
{
	struct ssam_notifier_block *p;
	struct list_head *h;

	/* Runs under lock, no need for RCU variant. */
	list_for_each(h, &nh->head) {
		p = list_entry(h, struct ssam_notifier_block, node);

		if (unlikely(p == nb)) {
			WARN(1, "double register detected");
			return -EEXIST;
		}

		if (nb->priority > p->priority)
			break;
	}

	list_add_tail_rcu(&nb->node, h);
	return 0;
}

/**
 * ssam_nfblk_find() - Check if a notifier block is registered on the given
 * notifier head.
 * list.
 * @nh: The notifier head on which to search.
 * @nb: The notifier block to search for.
 *
 * Note: This function must be synchronized by the caller with respect to other
 * insert, find, and/or remove calls by holding ``struct ssam_nf.lock``.
 *
 * Return: Returns true if the given notifier block is registered on the given
 * notifier head, false otherwise.
 */
static bool ssam_nfblk_find(struct ssam_nf_head *nh, struct ssam_notifier_block *nb)
{
	struct ssam_notifier_block *p;

	/* Runs under lock, no need for RCU variant. */
	list_for_each_entry(p, &nh->head, node) {
		if (p == nb)
			return true;
	}

	return false;
}

/**
 * ssam_nfblk_remove() - Remove a notifier block from its notifier list.
 * @nb: The notifier block to be removed.
 *
 * Note: This function must be synchronized by the caller with respect to
 * other insert, find, and/or remove calls by holding ``struct ssam_nf.lock``.
 * Furthermore, the caller _must_ ensure SRCU synchronization by calling
 * synchronize_srcu() with ``nh->srcu`` after leaving the critical section, to
 * ensure that the removed notifier block is not in use any more.
 */
static void ssam_nfblk_remove(struct ssam_notifier_block *nb)
{
	list_del_rcu(&nb->node);
}

/**
 * ssam_nf_head_init() - Initialize the given notifier head.
 * @nh: The notifier head to initialize.
 */
static int ssam_nf_head_init(struct ssam_nf_head *nh)
{
	int status;

	status = init_srcu_struct(&nh->srcu);
	if (status)
		return status;

	INIT_LIST_HEAD(&nh->head);
	return 0;
}

/**
 * ssam_nf_head_destroy() - Deinitialize the given notifier head.
 * @nh: The notifier head to deinitialize.
 */
static void ssam_nf_head_destroy(struct ssam_nf_head *nh)
{
	cleanup_srcu_struct(&nh->srcu);
}


/* -- Event/notification registry. ------------------------------------------ */

/**
 * struct ssam_nf_refcount_key - Key used for event activation reference
 * counting.
 * @reg: The registry via which the event is enabled/disabled.
 * @id:  The ID uniquely describing the event.
 */
struct ssam_nf_refcount_key {
	struct ssam_event_registry reg;
	struct ssam_event_id id;
};

/**
 * struct ssam_nf_refcount_entry - RB-tree entry for reference counting event
 * activations.
 * @node:     The node of this entry in the rb-tree.
 * @key:      The key of the event.
 * @refcount: The reference-count of the event.
 * @flags:    The flags used when enabling the event.
 */
struct ssam_nf_refcount_entry {
	struct rb_node node;
	struct ssam_nf_refcount_key key;
	int refcount;
	u8 flags;
};

/**
 * ssam_nf_refcount_inc() - Increment reference-/activation-count of the given
 * event.
 * @nf:  The notifier system reference.
 * @reg: The registry used to enable/disable the event.
 * @id:  The event ID.
 *
 * Increments the reference-/activation-count associated with the specified
 * event type/ID, allocating a new entry for this event ID if necessary. A
 * newly allocated entry will have a refcount of one.
 *
 * Note: ``nf->lock`` must be held when calling this function.
 *
 * Return: Returns the refcount entry on success. Returns an error pointer
 * with %-ENOSPC if there have already been %INT_MAX events of the specified
 * ID and type registered, or %-ENOMEM if the entry could not be allocated.
 */
static struct ssam_nf_refcount_entry *
ssam_nf_refcount_inc(struct ssam_nf *nf, struct ssam_event_registry reg,
		     struct ssam_event_id id)
{
	struct ssam_nf_refcount_entry *entry;
	struct ssam_nf_refcount_key key;
	struct rb_node **link = &nf->refcount.rb_node;
	struct rb_node *parent = NULL;
	int cmp;

	lockdep_assert_held(&nf->lock);

	key.reg = reg;
	key.id = id;

	while (*link) {
		entry = rb_entry(*link, struct ssam_nf_refcount_entry, node);
		parent = *link;

		cmp = memcmp(&key, &entry->key, sizeof(key));
		if (cmp < 0) {
			link = &(*link)->rb_left;
		} else if (cmp > 0) {
			link = &(*link)->rb_right;
		} else if (entry->refcount < INT_MAX) {
			entry->refcount++;
			return entry;
		} else {
			WARN_ON(1);
			return ERR_PTR(-ENOSPC);
		}
	}

	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
	if (!entry)
		return ERR_PTR(-ENOMEM);

	entry->key = key;
	entry->refcount = 1;

	rb_link_node(&entry->node, parent, link);
	rb_insert_color(&entry->node, &nf->refcount);

	return entry;
}

/**
 * ssam_nf_refcount_dec() - Decrement reference-/activation-count of the given
 * event.
 * @nf:  The notifier system reference.
 * @reg: The registry used to enable/disable the event.
 * @id:  The event ID.
 *
 * Decrements the reference-/activation-count of the specified event,
 * returning its entry. If the returned entry has a refcount of zero, the
 * caller is responsible for freeing it using kfree().
 *
 * Note: ``nf->lock`` must be held when calling this function.
 *
 * Return: Returns the refcount entry on success or %NULL if the entry has not
 * been found.
 */
static struct ssam_nf_refcount_entry *
ssam_nf_refcount_dec(struct ssam_nf *nf, struct ssam_event_registry reg,
		     struct ssam_event_id id)
{
	struct ssam_nf_refcount_entry *entry;
	struct ssam_nf_refcount_key key;
	struct rb_node *node = nf->refcount.rb_node;
	int cmp;

	lockdep_assert_held(&nf->lock);

	key.reg = reg;
	key.id = id;

	while (node) {
		entry = rb_entry(node, struct ssam_nf_refcount_entry, node);

		cmp = memcmp(&key, &entry->key, sizeof(key));
		if (cmp < 0) {
			node = node->rb_left;
		} else if (cmp > 0) {
			node = node->rb_right;
		} else {
			entry->refcount--;
			if (entry->refcount == 0)
				rb_erase(&entry->node, &nf->refcount);

			return entry;
		}
	}

	return NULL;
}

/**
 * ssam_nf_refcount_empty() - Test if the notification system has any
 * enabled/active events.
 * @nf: The notification system.
 */
static bool ssam_nf_refcount_empty(struct ssam_nf *nf)
{
	return RB_EMPTY_ROOT(&nf->refcount);
}

/**
 * ssam_nf_call() - Call notification callbacks for the provided event.
 * @nf:    The notifier system
 * @dev:   The associated device, only used for logging.
 * @rqid:  The request ID of the event.
 * @event: The event provided to the callbacks.
 *
 * Execute registered callbacks in order of their priority until either no
 * callback is left or a callback returns a value with the %SSAM_NOTIF_STOP
 * bit set. Note that this bit is set automatically when converting non-zero
 * error values via ssam_notifier_from_errno() to notifier values.
 *
 * Also note that any callback that could handle an event should return a value
 * with bit %SSAM_NOTIF_HANDLED set, indicating that the event does not go
 * unhandled/ignored. In case no registered callback could handle an event,
 * this function will emit a warning.
 *
 * In case a callback failed, this function will emit an error message.
 */
static void ssam_nf_call(struct ssam_nf *nf, struct device *dev, u16 rqid,
			 struct ssam_event *event)
{
	struct ssam_nf_head *nf_head;
	int status, nf_ret;

	if (!ssh_rqid_is_event(rqid)) {
		dev_warn(dev, "event: unsupported rqid: %#06x\n", rqid);
		return;
	}

	nf_head = &nf->head[ssh_rqid_to_event(rqid)];
	nf_ret = ssam_nfblk_call_chain(nf_head, event);
	status = ssam_notifier_to_errno(nf_ret);

	if (status < 0) {
		dev_err(dev,
			"event: error handling event: %d (tc: %#04x, tid: %#04x, cid: %#04x, iid: %#04x)\n",
			status, event->target_category, event->target_id,
			event->command_id, event->instance_id);
	} else if (!(nf_ret & SSAM_NOTIF_HANDLED)) {
		dev_warn(dev,
			 "event: unhandled event (rqid: %#04x, tc: %#04x, tid: %#04x, cid: %#04x, iid: %#04x)\n",
			 rqid, event->target_category, event->target_id,
			 event->command_id, event->instance_id);
	}
}

/**
 * ssam_nf_init() - Initialize the notifier system.
 * @nf: The notifier system to initialize.
 */
static int ssam_nf_init(struct ssam_nf *nf)
{
	int i, status;

	for (i = 0; i < SSH_NUM_EVENTS; i++) {
		status = ssam_nf_head_init(&nf->head[i]);
		if (status)
			break;
	}

	if (status) {
		while (i--)
			ssam_nf_head_destroy(&nf->head[i]);

		return status;
	}

	mutex_init(&nf->lock);
	return 0;
}

/**
 * ssam_nf_destroy() - Deinitialize the notifier system.
 * @nf: The notifier system to deinitialize.
 */
static void ssam_nf_destroy(struct ssam_nf *nf)
{
	int i;

	for (i = 0; i < SSH_NUM_EVENTS; i++)
		ssam_nf_head_destroy(&nf->head[i]);

	mutex_destroy(&nf->lock);
}


/* -- Event/async request completion system. -------------------------------- */

#define SSAM_CPLT_WQ_NAME	"ssam_cpltq"

/*
 * SSAM_CPLT_WQ_BATCH - Maximum number of event item completions executed per
 * work execution. Used to prevent livelocking of the workqueue. Value chosen
 * via educated guess, may be adjusted.
 */
#define SSAM_CPLT_WQ_BATCH	10

/*
 * SSAM_EVENT_ITEM_CACHE_PAYLOAD_LEN - Maximum payload length for a cached
 * &struct ssam_event_item.
 *
 * This length has been chosen to be accommodate standard touchpad and
 * keyboard input events. Events with larger payloads will be allocated
 * separately.
 */
#define SSAM_EVENT_ITEM_CACHE_PAYLOAD_LEN	32

static struct kmem_cache *ssam_event_item_cache;

/**
 * ssam_event_item_cache_init() - Initialize the event item cache.
 */
int ssam_event_item_cache_init(void)
{
	const unsigned int size = sizeof(struct ssam_event_item)
				  + SSAM_EVENT_ITEM_CACHE_PAYLOAD_LEN;
	const unsigned int align = __alignof__(struct ssam_event_item);
	struct kmem_cache *cache;

	cache = kmem_cache_create("ssam_event_item", size, align, 0, NULL);
	if (!cache)
		return -ENOMEM;

	ssam_event_item_cache = cache;
	return 0;
}

/**
 * ssam_event_item_cache_destroy() - Deinitialize the event item cache.
 */
void ssam_event_item_cache_destroy(void)
{
	kmem_cache_destroy(ssam_event_item_cache);
	ssam_event_item_cache = NULL;
}

static void __ssam_event_item_free_cached(struct ssam_event_item *item)
{
	kmem_cache_free(ssam_event_item_cache, item);
}

static void __ssam_event_item_free_generic(struct ssam_event_item *item)
{
	kfree(item);
}

/**
 * ssam_event_item_free() - Free the provided event item.
 * @item: The event item to free.
 */
static void ssam_event_item_free(struct ssam_event_item *item)
{
	trace_ssam_event_item_free(item);
	item->ops.free(item);
}

/**
 * ssam_event_item_alloc() - Allocate an event item with the given payload size.
 * @len:   The event payload length.
 * @flags: The flags used for allocation.
 *
 * Allocate an event item with the given payload size, preferring allocation
 * from the event item cache if the payload is small enough (i.e. smaller than
 * %SSAM_EVENT_ITEM_CACHE_PAYLOAD_LEN). Sets the item operations and payload
 * length values. The item free callback (``ops.free``) should not be
 * overwritten after this call.
 *
 * Return: Returns the newly allocated event item.
 */
static struct ssam_event_item *ssam_event_item_alloc(size_t len, gfp_t flags)
{
	struct ssam_event_item *item;

	if (len <= SSAM_EVENT_ITEM_CACHE_PAYLOAD_LEN) {
		item = kmem_cache_alloc(ssam_event_item_cache, flags);
		if (!item)
			return NULL;

		item->ops.free = __ssam_event_item_free_cached;
	} else {
		item = kzalloc(struct_size(item, event.data, len), flags);
		if (!item)
			return NULL;

		item->ops.free = __ssam_event_item_free_generic;
	}

	item->event.length = len;

	trace_ssam_event_item_alloc(item, len);
	return item;
}

/**
 * ssam_event_queue_push() - Push an event item to the event queue.
 * @q:    The event queue.
 * @item: The item to add.
 */
static void ssam_event_queue_push(struct ssam_event_queue *q,
				  struct ssam_event_item *item)
{
	spin_lock(&q->lock);
	list_add_tail(&item->node, &q->head);
	spin_unlock(&q->lock);
}

/**
 * ssam_event_queue_pop() - Pop the next event item from the event queue.
 * @q: The event queue.
 *
 * Returns and removes the next event item from the queue. Returns %NULL If
 * there is no event item left.
 */
static struct ssam_event_item *ssam_event_queue_pop(struct ssam_event_queue *q)
{
	struct ssam_event_item *item;

	spin_lock(&q->lock);
	item = list_first_entry_or_null(&q->head, struct ssam_event_item, node);
	if (item)
		list_del(&item->node);
	spin_unlock(&q->lock);

	return item;
}

/**
 * ssam_event_queue_is_empty() - Check if the event queue is empty.
 * @q: The event queue.
 */
static bool ssam_event_queue_is_empty(struct ssam_event_queue *q)
{
	bool empty;

	spin_lock(&q->lock);
	empty = list_empty(&q->head);
	spin_unlock(&q->lock);

	return empty;
}

/**
 * ssam_cplt_get_event_queue() - Get the event queue for the given parameters.
 * @cplt: The completion system on which to look for the queue.
 * @tid:  The target ID of the queue.
 * @rqid: The request ID representing the event ID for which to get the queue.
 *
 * Return: Returns the event queue corresponding to the event type described
 * by the given parameters. If the request ID does not represent an event,
 * this function returns %NULL. If the target ID is not supported, this
 * function will fall back to the default target ID (``tid = 1``).
 */
static
struct ssam_event_queue *ssam_cplt_get_event_queue(struct ssam_cplt *cplt,
						   u8 tid, u16 rqid)
{
	u16 event = ssh_rqid_to_event(rqid);
	u16 tidx = ssh_tid_to_index(tid);

	if (!ssh_rqid_is_event(rqid)) {
		dev_err(cplt->dev, "event: unsupported request ID: %#06x\n", rqid);
		return NULL;
	}

	if (!ssh_tid_is_valid(tid)) {
		dev_warn(cplt->dev, "event: unsupported target ID: %u\n", tid);
		tidx = 0;
	}

	return &cplt->event.target[tidx].queue[event];
}

/**
 * ssam_cplt_submit() - Submit a work item to the completion system workqueue.
 * @cplt: The completion system.
 * @work: The work item to submit.
 */
static bool ssam_cplt_submit(struct ssam_cplt *cplt, struct work_struct *work)
{
	return queue_work(cplt->wq, work);
}

/**
 * ssam_cplt_submit_event() - Submit an event to the completion system.
 * @cplt: The completion system.
 * @item: The event item to submit.
 *
 * Submits the event to the completion system by queuing it on the event item
 * queue and queuing the respective event queue work item on the completion
 * workqueue, which will eventually complete the event.
 *
 * Return: Returns zero on success, %-EINVAL if there is no event queue that
 * can handle the given event item.
 */
static int ssam_cplt_submit_event(struct ssam_cplt *cplt,
				  struct ssam_event_item *item)
{
	struct ssam_event_queue *evq;

	evq = ssam_cplt_get_event_queue(cplt, item->event.target_id, item->rqid);
	if (!evq)
		return -EINVAL;

	ssam_event_queue_push(evq, item);
	ssam_cplt_submit(cplt, &evq->work);
	return 0;
}

/**
 * ssam_cplt_flush() - Flush the completion system.
 * @cplt: The completion system.
 *
 * Flush the completion system by waiting until all currently submitted work
 * items have been completed.
 *
 * Note: This function does not guarantee that all events will have been
 * handled once this call terminates. In case of a larger number of
 * to-be-completed events, the event queue work function may re-schedule its
 * work item, which this flush operation will ignore.
 *
 * This operation is only intended to, during normal operation prior to
 * shutdown, try to complete most events and requests to get them out of the
 * system while the system is still fully operational. It does not aim to
 * provide any guarantee that all of them have been handled.
 */
static void ssam_cplt_flush(struct ssam_cplt *cplt)
{
	flush_workqueue(cplt->wq);
}

static void ssam_event_queue_work_fn(struct work_struct *work)
{
	struct ssam_event_queue *queue;
	struct ssam_event_item *item;
	struct ssam_nf *nf;
	struct device *dev;
	unsigned int iterations = SSAM_CPLT_WQ_BATCH;

	queue = container_of(work, struct ssam_event_queue, work);
	nf = &queue->cplt->event.notif;
	dev = queue->cplt->dev;

	/* Limit number of processed events to avoid livelocking. */
	do {
		item = ssam_event_queue_pop(queue);
		if (!item)
			return;

		ssam_nf_call(nf, dev, item->rqid, &item->event);
		ssam_event_item_free(item);
	} while (--iterations);

	if (!ssam_event_queue_is_empty(queue))
		ssam_cplt_submit(queue->cplt, &queue->work);
}

/**
 * ssam_event_queue_init() - Initialize an event queue.
 * @cplt: The completion system on which the queue resides.
 * @evq:  The event queue to initialize.
 */
static void ssam_event_queue_init(struct ssam_cplt *cplt,
				  struct ssam_event_queue *evq)
{
	evq->cplt = cplt;
	spin_lock_init(&evq->lock);
	INIT_LIST_HEAD(&evq->head);
	INIT_WORK(&evq->work, ssam_event_queue_work_fn);
}

/**
 * ssam_cplt_init() - Initialize completion system.
 * @cplt: The completion system to initialize.
 * @dev:  The device used for logging.
 */
static int ssam_cplt_init(struct ssam_cplt *cplt, struct device *dev)
{
	struct ssam_event_target *target;
	int status, c, i;

	cplt->dev = dev;

	cplt->wq = create_workqueue(SSAM_CPLT_WQ_NAME);
	if (!cplt->wq)
		return -ENOMEM;

	for (c = 0; c < ARRAY_SIZE(cplt->event.target); c++) {
		target = &cplt->event.target[c];

		for (i = 0; i < ARRAY_SIZE(target->queue); i++)
			ssam_event_queue_init(cplt, &target->queue[i]);
	}

	status = ssam_nf_init(&cplt->event.notif);
	if (status)
		destroy_workqueue(cplt->wq);

	return status;
}

/**
 * ssam_cplt_destroy() - Deinitialize the completion system.
 * @cplt: The completion system to deinitialize.
 *
 * Deinitialize the given completion system and ensure that all pending, i.e.
 * yet-to-be-completed, event items and requests have been handled.
 */
static void ssam_cplt_destroy(struct ssam_cplt *cplt)
{
	/*
	 * Note: destroy_workqueue ensures that all currently queued work will
	 * be fully completed and the workqueue drained. This means that this
	 * call will inherently also free any queued ssam_event_items, thus we
	 * don't have to take care of that here explicitly.
	 */
	destroy_workqueue(cplt->wq);
	ssam_nf_destroy(&cplt->event.notif);
}


/* -- Main SSAM device structures. ------------------------------------------ */

/**
 * ssam_controller_device() - Get the &struct device associated with this
 * controller.
 * @c: The controller for which to get the device.
 *
 * Return: Returns the &struct device associated with this controller,
 * providing its lower-level transport.
 */
struct device *ssam_controller_device(struct ssam_controller *c)
{
	return ssh_rtl_get_device(&c->rtl);
}
EXPORT_SYMBOL_GPL(ssam_controller_device);

static void __ssam_controller_release(struct kref *kref)
{
	struct ssam_controller *ctrl = to_ssam_controller(kref, kref);

	/*
	 * The lock-call here is to satisfy lockdep. At this point we really
	 * expect this to be the last remaining reference to the controller.
	 * Anything else is a bug.
	 */
	ssam_controller_lock(ctrl);
	ssam_controller_destroy(ctrl);
	ssam_controller_unlock(ctrl);

	kfree(ctrl);
}

/**
 * ssam_controller_get() - Increment reference count of controller.
 * @c: The controller.
 *
 * Return: Returns the controller provided as input.
 */
struct ssam_controller *ssam_controller_get(struct ssam_controller *c)
{
	if (c)
		kref_get(&c->kref);
	return c;
}
EXPORT_SYMBOL_GPL(ssam_controller_get);

/**
 * ssam_controller_put() - Decrement reference count of controller.
 * @c: The controller.
 */
void ssam_controller_put(struct ssam_controller *c)
{
	if (c)
		kref_put(&c->kref, __ssam_controller_release);
}
EXPORT_SYMBOL_GPL(ssam_controller_put);

/**
 * ssam_controller_statelock() - Lock the controller against state transitions.
 * @c: The controller to lock.
 *
 * Lock the controller against state transitions. Holding this lock guarantees
 * that the controller will not transition between states, i.e. if the
 * controller is in state "started", when this lock has been acquired, it will
 * remain in this state at least until the lock has been released.
 *
 * Multiple clients may concurrently hold this lock. In other words: The
 * ``statelock`` functions represent the read-lock part of a r/w-semaphore.
 * Actions causing state transitions of the controller must be executed while
 * holding the write-part of this r/w-semaphore (see ssam_controller_lock()
 * and ssam_controller_unlock() for that).
 *
 * See ssam_controller_stateunlock() for the corresponding unlock function.
 */
void ssam_controller_statelock(struct ssam_controller *c)
{
	down_read(&c->lock);
}
EXPORT_SYMBOL_GPL(ssam_controller_statelock);

/**
 * ssam_controller_stateunlock() - Unlock controller state transitions.
 * @c: The controller to unlock.
 *
 * See ssam_controller_statelock() for the corresponding lock function.
 */
void ssam_controller_stateunlock(struct ssam_controller *c)
{
	up_read(&c->lock);
}
EXPORT_SYMBOL_GPL(ssam_controller_stateunlock);

/**
 * ssam_controller_lock() - Acquire the main controller lock.
 * @c: The controller to lock.
 *
 * This lock must be held for any state transitions, including transition to
 * suspend/resumed states and during shutdown. See ssam_controller_statelock()
 * for more details on controller locking.
 *
 * See ssam_controller_unlock() for the corresponding unlock function.
 */
void ssam_controller_lock(struct ssam_controller *c)
{
	down_write(&c->lock);
}

/*
 * ssam_controller_unlock() - Release the main controller lock.
 * @c: The controller to unlock.
 *
 * See ssam_controller_lock() for the corresponding lock function.
 */
void ssam_controller_unlock(struct ssam_controller *c)
{
	up_write(&c->lock);
}

static void ssam_handle_event(struct ssh_rtl *rtl,
			      const struct ssh_command *cmd,
			      const struct ssam_span *data)
{
	struct ssam_controller *ctrl = to_ssam_controller(rtl, rtl);
	struct ssam_event_item *item;

	item = ssam_event_item_alloc(data->len, GFP_KERNEL);
	if (!item)
		return;

	item->rqid = get_unaligned_le16(&cmd->rqid);
	item->event.target_category = cmd->tc;
	item->event.target_id = cmd->tid_in;
	item->event.command_id = cmd->cid;
	item->event.instance_id = cmd->iid;
	memcpy(&item->event.data[0], data->ptr, data->len);

	if (WARN_ON(ssam_cplt_submit_event(&ctrl->cplt, item)))
		ssam_event_item_free(item);
}

static const struct ssh_rtl_ops ssam_rtl_ops = {
	.handle_event = ssam_handle_event,
};

static bool ssam_notifier_is_empty(struct ssam_controller *ctrl);
static void ssam_notifier_unregister_all(struct ssam_controller *ctrl);

#define SSAM_SSH_DSM_REVISION	0

/* d5e383e1-d892-4a76-89fc-f6aaae7ed5b5 */
static const guid_t SSAM_SSH_DSM_GUID =
	GUID_INIT(0xd5e383e1, 0xd892, 0x4a76,
		  0x89, 0xfc, 0xf6, 0xaa, 0xae, 0x7e, 0xd5, 0xb5);

enum ssh_dsm_fn {
	SSH_DSM_FN_SSH_POWER_PROFILE             = 0x05,
	SSH_DSM_FN_SCREEN_ON_SLEEP_IDLE_TIMEOUT  = 0x06,
	SSH_DSM_FN_SCREEN_OFF_SLEEP_IDLE_TIMEOUT = 0x07,
	SSH_DSM_FN_D3_CLOSES_HANDLE              = 0x08,
	SSH_DSM_FN_SSH_BUFFER_SIZE               = 0x09,
};

static int ssam_dsm_get_functions(acpi_handle handle, u64 *funcs)
{
	union acpi_object *obj;
	u64 mask = 0;
	int i;

	*funcs = 0;

	/*
	 * The _DSM function is only present on newer models. It is not
	 * present on 5th and 6th generation devices (i.e. up to and including
	 * Surface Pro 6, Surface Laptop 2, Surface Book 2).
	 *
	 * If the _DSM is not present, indicate that no function is supported.
	 * This will result in default values being set.
	 */
	if (!acpi_has_method(handle, "_DSM"))
		return 0;

	obj = acpi_evaluate_dsm_typed(handle, &SSAM_SSH_DSM_GUID,
				      SSAM_SSH_DSM_REVISION, 0, NULL,
				      ACPI_TYPE_BUFFER);
	if (!obj)
		return -EIO;

	for (i = 0; i < obj->buffer.length && i < 8; i++)
		mask |= (((u64)obj->buffer.pointer[i]) << (i * 8));

	if (mask & BIT(0))
		*funcs = mask;

	ACPI_FREE(obj);
	return 0;
}

static int ssam_dsm_load_u32(acpi_handle handle, u64 funcs, u64 func, u32 *ret)
{
	union acpi_object *obj;
	u64 val;

	if (!(funcs & BIT_ULL(func)))
		return 0; /* Not supported, leave *ret at its default value */

	obj = acpi_evaluate_dsm_typed(handle, &SSAM_SSH_DSM_GUID,
				      SSAM_SSH_DSM_REVISION, func, NULL,
				      ACPI_TYPE_INTEGER);
	if (!obj)
		return -EIO;

	val = obj->integer.value;
	ACPI_FREE(obj);

	if (val > U32_MAX)
		return -ERANGE;

	*ret = val;
	return 0;
}

/**
 * ssam_controller_caps_load_from_acpi() - Load controller capabilities from
 * ACPI _DSM.
 * @handle: The handle of the ACPI controller/SSH device.
 * @caps:   Where to store the capabilities in.
 *
 * Initializes the given controller capabilities with default values, then
 * checks and, if the respective _DSM functions are available, loads the
 * actual capabilities from the _DSM.
 *
 * Return: Returns zero on success, a negative error code on failure.
 */
static
int ssam_controller_caps_load_from_acpi(acpi_handle handle,
					struct ssam_controller_caps *caps)
{
	u32 d3_closes_handle = false;
	u64 funcs;
	int status;

	/* Set defaults. */
	caps->ssh_power_profile = U32_MAX;
	caps->screen_on_sleep_idle_timeout = U32_MAX;
	caps->screen_off_sleep_idle_timeout = U32_MAX;
	caps->d3_closes_handle = false;
	caps->ssh_buffer_size = U32_MAX;

	/* Pre-load supported DSM functions. */
	status = ssam_dsm_get_functions(handle, &funcs);
	if (status)
		return status;

	/* Load actual values from ACPI, if present. */
	status = ssam_dsm_load_u32(handle, funcs, SSH_DSM_FN_SSH_POWER_PROFILE,
				   &caps->ssh_power_profile);
	if (status)
		return status;

	status = ssam_dsm_load_u32(handle, funcs,
				   SSH_DSM_FN_SCREEN_ON_SLEEP_IDLE_TIMEOUT,
				   &caps->screen_on_sleep_idle_timeout);
	if (status)
		return status;

	status = ssam_dsm_load_u32(handle, funcs,
				   SSH_DSM_FN_SCREEN_OFF_SLEEP_IDLE_TIMEOUT,
				   &caps->screen_off_sleep_idle_timeout);
	if (status)
		return status;

	status = ssam_dsm_load_u32(handle, funcs, SSH_DSM_FN_D3_CLOSES_HANDLE,
				   &d3_closes_handle);
	if (status)
		return status;

	caps->d3_closes_handle = !!d3_closes_handle;

	status = ssam_dsm_load_u32(handle, funcs, SSH_DSM_FN_SSH_BUFFER_SIZE,
				   &caps->ssh_buffer_size);
	if (status)
		return status;

	return 0;
}

/**
 * ssam_controller_init() - Initialize SSAM controller.
 * @ctrl:   The controller to initialize.
 * @serdev: The serial device representing the underlying data transport.
 *
 * Initializes the given controller. Does neither start receiver nor
 * transmitter threads. After this call, the controller has to be hooked up to
 * the serdev core separately via &struct serdev_device_ops, relaying calls to
 * ssam_controller_receive_buf() and ssam_controller_write_wakeup(). Once the
 * controller has been hooked up, transmitter and receiver threads may be
 * started via ssam_controller_start(). These setup steps need to be completed
 * before controller can be used for requests.
 */
int ssam_controller_init(struct ssam_controller *ctrl,
			 struct serdev_device *serdev)
{
	acpi_handle handle = ACPI_HANDLE(&serdev->dev);
	int status;

	init_rwsem(&ctrl->lock);
	kref_init(&ctrl->kref);

	status = ssam_controller_caps_load_from_acpi(handle, &ctrl->caps);
	if (status)
		return status;

	dev_dbg(&serdev->dev,
		"device capabilities:\n"
		"  ssh_power_profile:             %u\n"
		"  ssh_buffer_size:               %u\n"
		"  screen_on_sleep_idle_timeout:  %u\n"
		"  screen_off_sleep_idle_timeout: %u\n"
		"  d3_closes_handle:              %u\n",
		ctrl->caps.ssh_power_profile,
		ctrl->caps.ssh_buffer_size,
		ctrl->caps.screen_on_sleep_idle_timeout,
		ctrl->caps.screen_off_sleep_idle_timeout,
		ctrl->caps.d3_closes_handle);

	ssh_seq_reset(&ctrl->counter.seq);
	ssh_rqid_reset(&ctrl->counter.rqid);

	/* Initialize event/request completion system. */
	status = ssam_cplt_init(&ctrl->cplt, &serdev->dev);
	if (status)
		return status;

	/* Initialize request and packet transport layers. */
	status = ssh_rtl_init(&ctrl->rtl, serdev, &ssam_rtl_ops);
	if (status) {
		ssam_cplt_destroy(&ctrl->cplt);
		return status;
	}

	/*
	 * Set state via write_once even though we expect to be in an
	 * exclusive context, due to smoke-testing in
	 * ssam_request_sync_submit().
	 */
	WRITE_ONCE(ctrl->state, SSAM_CONTROLLER_INITIALIZED);
	return 0;
}

/**
 * ssam_controller_start() - Start the receiver and transmitter threads of the
 * controller.
 * @ctrl: The controller.
 *
 * Note: When this function is called, the controller should be properly
 * hooked up to the serdev core via &struct serdev_device_ops. Please refer
 * to ssam_controller_init() for more details on controller initialization.
 *
 * This function must be called with the main controller lock held (i.e. by
 * calling ssam_controller_lock()).
 */
int ssam_controller_start(struct ssam_controller *ctrl)
{
	int status;

	lockdep_assert_held_write(&ctrl->lock);

	if (ctrl->state != SSAM_CONTROLLER_INITIALIZED)
		return -EINVAL;

	status = ssh_rtl_start(&ctrl->rtl);
	if (status)
		return status;

	/*
	 * Set state via write_once even though we expect to be locked/in an
	 * exclusive context, due to smoke-testing in
	 * ssam_request_sync_submit().
	 */
	WRITE_ONCE(ctrl->state, SSAM_CONTROLLER_STARTED);
	return 0;
}

/*
 * SSAM_CTRL_SHUTDOWN_FLUSH_TIMEOUT - Timeout for flushing requests during
 * shutdown.
 *
 * Chosen to be larger than one full request timeout, including packets timing
 * out. This value should give ample time to complete any outstanding requests
 * during normal operation and account for the odd package timeout.
 */
#define SSAM_CTRL_SHUTDOWN_FLUSH_TIMEOUT	msecs_to_jiffies(5000)

/**
 * ssam_controller_shutdown() - Shut down the controller.
 * @ctrl: The controller.
 *
 * Shuts down the controller by flushing all pending requests and stopping the
 * transmitter and receiver threads. All requests submitted after this call
 * will fail with %-ESHUTDOWN. While it is discouraged to do so, this function
 * is safe to use in parallel with ongoing request submission.
 *
 * In the course of this shutdown procedure, all currently registered
 * notifiers will be unregistered. It is, however, strongly recommended to not
 * rely on this behavior, and instead the party registering the notifier
 * should unregister it before the controller gets shut down, e.g. via the
 * SSAM bus which guarantees client devices to be removed before a shutdown.
 *
 * Note that events may still be pending after this call, but, due to the
 * notifiers being unregistered, these events will be dropped when the
 * controller is subsequently destroyed via ssam_controller_destroy().
 *
 * This function must be called with the main controller lock held (i.e. by
 * calling ssam_controller_lock()).
 */
void ssam_controller_shutdown(struct ssam_controller *ctrl)
{
	enum ssam_controller_state s = ctrl->state;
	int status;

	lockdep_assert_held_write(&ctrl->lock);

	if (s == SSAM_CONTROLLER_UNINITIALIZED || s == SSAM_CONTROLLER_STOPPED)
		return;

	/*
	 * Try to flush pending events and requests while everything still
	 * works. Note: There may still be packets and/or requests in the
	 * system after this call (e.g. via control packets submitted by the
	 * packet transport layer or flush timeout / failure, ...). Those will
	 * be handled with the ssh_rtl_shutdown() call below.
	 */
	status = ssh_rtl_flush(&ctrl->rtl, SSAM_CTRL_SHUTDOWN_FLUSH_TIMEOUT);
	if (status) {
		ssam_err(ctrl, "failed to flush request transport layer: %d\n",
			 status);
	}

	/* Try to flush all currently completing requests and events. */
	ssam_cplt_flush(&ctrl->cplt);

	/*
	 * We expect all notifiers to have been removed by the respective client
	 * driver that set them up at this point. If this warning occurs, some
	 * client driver has not done that...
	 */
	WARN_ON(!ssam_notifier_is_empty(ctrl));

	/*
	 * Nevertheless, we should still take care of drivers that don't behave
	 * well. Thus disable all enabled events, unregister all notifiers.
	 */
	ssam_notifier_unregister_all(ctrl);

	/*
	 * Cancel remaining requests. Ensure no new ones can be queued and stop
	 * threads.
	 */
	ssh_rtl_shutdown(&ctrl->rtl);

	/*
	 * Set state via write_once even though we expect to be locked/in an
	 * exclusive context, due to smoke-testing in
	 * ssam_request_sync_submit().
	 */
	WRITE_ONCE(ctrl->state, SSAM_CONTROLLER_STOPPED);
	ctrl->rtl.ptl.serdev = NULL;
}

/**
 * ssam_controller_destroy() - Destroy the controller and free its resources.
 * @ctrl: The controller.
 *
 * Ensures that all resources associated with the controller get freed. This
 * function should only be called after the controller has been stopped via
 * ssam_controller_shutdown(). In general, this function should not be called
 * directly. The only valid place to call this function directly is during
 * initialization, before the controller has been fully initialized and passed
 * to other processes. This function is called automatically when the
 * reference count of the controller reaches zero.
 *
 * This function must be called with the main controller lock held (i.e. by
 * calling ssam_controller_lock()).
 */
void ssam_controller_destroy(struct ssam_controller *ctrl)
{
	lockdep_assert_held_write(&ctrl->lock);

	if (ctrl->state == SSAM_CONTROLLER_UNINITIALIZED)
		return;

	WARN_ON(ctrl->state != SSAM_CONTROLLER_STOPPED);

	/*
	 * Note: New events could still have been received after the previous
	 * flush in ssam_controller_shutdown, before the request transport layer
	 * has been shut down. At this point, after the shutdown, we can be sure
	 * that no new events will be queued. The call to ssam_cplt_destroy will
	 * ensure that those remaining are being completed and freed.
	 */

	/* Actually free resources. */
	ssam_cplt_destroy(&ctrl->cplt);
	ssh_rtl_destroy(&ctrl->rtl);

	/*
	 * Set state via write_once even though we expect to be locked/in an
	 * exclusive context, due to smoke-testing in
	 * ssam_request_sync_submit().
	 */
	WRITE_ONCE(ctrl->state, SSAM_CONTROLLER_UNINITIALIZED);
}

/**
 * ssam_controller_suspend() - Suspend the controller.
 * @ctrl: The controller to suspend.
 *
 * Marks the controller as suspended. Note that display-off and D0-exit
 * notifications have to be sent manually before transitioning the controller
 * into the suspended state via this function.
 *
 * See ssam_controller_resume() for the corresponding resume function.
 *
 * Return: Returns %-EINVAL if the controller is currently not in the
 * "started" state.
 */
int ssam_controller_suspend(struct ssam_controller *ctrl)
{
	ssam_controller_lock(ctrl);

	if (ctrl->state != SSAM_CONTROLLER_STARTED) {
		ssam_controller_unlock(ctrl);
		return -EINVAL;
	}

	ssam_dbg(ctrl, "pm: suspending controller\n");

	/*
	 * Set state via write_once even though we're locked, due to
	 * smoke-testing in ssam_request_sync_submit().
	 */
	WRITE_ONCE(ctrl->state, SSAM_CONTROLLER_SUSPENDED);

	ssam_controller_unlock(ctrl);
	return 0;
}

/**
 * ssam_controller_resume() - Resume the controller from suspend.
 * @ctrl: The controller to resume.
 *
 * Resume the controller from the suspended state it was put into via
 * ssam_controller_suspend(). This function does not issue display-on and
 * D0-entry notifications. If required, those have to be sent manually after
 * this call.
 *
 * Return: Returns %-EINVAL if the controller is currently not suspended.
 */
int ssam_controller_resume(struct ssam_controller *ctrl)
{
	ssam_controller_lock(ctrl);

	if (ctrl->state != SSAM_CONTROLLER_SUSPENDED) {
		ssam_controller_unlock(ctrl);
		return -EINVAL;
	}

	ssam_dbg(ctrl, "pm: resuming controller\n");

	/*
	 * Set state via write_once even though we're locked, due to
	 * smoke-testing in ssam_request_sync_submit().
	 */
	WRITE_ONCE(ctrl->state, SSAM_CONTROLLER_STARTED);

	ssam_controller_unlock(ctrl);
	return 0;
}


/* -- Top-level request interface ------------------------------------------- */

/**
 * ssam_request_write_data() - Construct and write SAM request message to
 * buffer.
 * @buf:  The buffer to write the data to.
 * @ctrl: The controller via which the request will be sent.
 * @spec: The request data and specification.
 *
 * Constructs a SAM/SSH request message and writes it to the provided buffer.
 * The request and transport counters, specifically RQID and SEQ, will be set
 * in this call. These counters are obtained from the controller. It is thus
 * only valid to send the resulting message via the controller specified here.
 *
 * For calculation of the required buffer size, refer to the
 * SSH_COMMAND_MESSAGE_LENGTH() macro.
 *
 * Return: Returns the number of bytes used in the buffer on success. Returns
 * %-EINVAL if the payload length provided in the request specification is too
 * large (larger than %SSH_COMMAND_MAX_PAYLOAD_SIZE) or if the provided buffer
 * is too small.
 */
ssize_t ssam_request_write_data(struct ssam_span *buf,
				struct ssam_controller *ctrl,
				const struct ssam_request *spec)
{
	struct msgbuf msgb;
	u16 rqid;
	u8 seq;

	if (spec->length > SSH_COMMAND_MAX_PAYLOAD_SIZE)
		return -EINVAL;

	if (SSH_COMMAND_MESSAGE_LENGTH(spec->length) > buf->len)
		return -EINVAL;

	msgb_init(&msgb, buf->ptr, buf->len);
	seq = ssh_seq_next(&ctrl->counter.seq);
	rqid = ssh_rqid_next(&ctrl->counter.rqid);
	msgb_push_cmd(&msgb, seq, rqid, spec);

	return msgb_bytes_used(&msgb);
}
EXPORT_SYMBOL_GPL(ssam_request_write_data);

static void ssam_request_sync_complete(struct ssh_request *rqst,
				       const struct ssh_command *cmd,
				       const struct ssam_span *data, int status)
{
	struct ssh_rtl *rtl = ssh_request_rtl(rqst);
	struct ssam_request_sync *r;

	r = container_of(rqst, struct ssam_request_sync, base);
	r->status = status;

	if (r->resp)
		r->resp->length = 0;

	if (status) {
		rtl_dbg_cond(rtl, "rsp: request failed: %d\n", status);
		return;
	}

	if (!data)	/* Handle requests without a response. */
		return;

	if (!r->resp || !r->resp->pointer) {
		if (data->len)
			rtl_warn(rtl, "rsp: no response buffer provided, dropping data\n");
		return;
	}

	if (data->len > r->resp->capacity) {
		rtl_err(rtl,
			"rsp: response buffer too small, capacity: %zu bytes, got: %zu bytes\n",
			r->resp->capacity, data->len);
		r->status = -ENOSPC;
		return;
	}

	r->resp->length = data->len;
	memcpy(r->resp->pointer, data->ptr, data->len);
}

static void ssam_request_sync_release(struct ssh_request *rqst)
{
	complete_all(&container_of(rqst, struct ssam_request_sync, base)->comp);
}

static const struct ssh_request_ops ssam_request_sync_ops = {
	.release = ssam_request_sync_release,
	.complete = ssam_request_sync_complete,
};

/**
 * ssam_request_sync_alloc() - Allocate a synchronous request.
 * @payload_len: The length of the request payload.
 * @flags:       Flags used for allocation.
 * @rqst:        Where to store the pointer to the allocated request.
 * @buffer:      Where to store the buffer descriptor for the message buffer of
 *               the request.
 *
 * Allocates a synchronous request with corresponding message buffer. The
 * request still needs to be initialized ssam_request_sync_init() before
 * it can be submitted, and the message buffer data must still be set to the
 * returned buffer via ssam_request_sync_set_data() after it has been filled,
 * if need be with adjusted message length.
 *
 * After use, the request and its corresponding message buffer should be freed
 * via ssam_request_sync_free(). The buffer must not be freed separately.
 *
 * Return: Returns zero on success, %-ENOMEM if the request could not be
 * allocated.
 */
int ssam_request_sync_alloc(size_t payload_len, gfp_t flags,
			    struct ssam_request_sync **rqst,
			    struct ssam_span *buffer)
{
	size_t msglen = SSH_COMMAND_MESSAGE_LENGTH(payload_len);

	*rqst = kzalloc(sizeof(**rqst) + msglen, flags);
	if (!*rqst)
		return -ENOMEM;

	buffer->ptr = (u8 *)(*rqst + 1);
	buffer->len = msglen;

	return 0;
}
EXPORT_SYMBOL_GPL(ssam_request_sync_alloc);

/**
 * ssam_request_sync_free() - Free a synchronous request.
 * @rqst: The request to be freed.
 *
 * Free a synchronous request and its corresponding buffer allocated with
 * ssam_request_sync_alloc(). Do not use for requests allocated on the stack
 * or via any other function.
 *
 * Warning: The caller must ensure that the request is not in use any more.
 * I.e. the caller must ensure that it has the only reference to the request
 * and the request is not currently pending. This means that the caller has
 * either never submitted the request, request submission has failed, or the
 * caller has waited until the submitted request has been completed via
 * ssam_request_sync_wait().
 */
void ssam_request_sync_free(struct ssam_request_sync *rqst)
{
	kfree(rqst);
}
EXPORT_SYMBOL_GPL(ssam_request_sync_free);

/**
 * ssam_request_sync_init() - Initialize a synchronous request struct.
 * @rqst:  The request to initialize.
 * @flags: The request flags.
 *
 * Initializes the given request struct. Does not initialize the request
 * message data. This has to be done explicitly after this call via
 * ssam_request_sync_set_data() and the actual message data has to be written
 * via ssam_request_write_data().
 *
 * Return: Returns zero on success or %-EINVAL if the given flags are invalid.
 */
int ssam_request_sync_init(struct ssam_request_sync *rqst,
			   enum ssam_request_flags flags)
{
	int status;

	status = ssh_request_init(&rqst->base, flags, &ssam_request_sync_ops);
	if (status)
		return status;

	init_completion(&rqst->comp);
	rqst->resp = NULL;
	rqst->status = 0;

	return 0;
}
EXPORT_SYMBOL_GPL(ssam_request_sync_init);

/**
 * ssam_request_sync_submit() - Submit a synchronous request.
 * @ctrl: The controller with which to submit the request.
 * @rqst: The request to submit.
 *
 * Submit a synchronous request. The request has to be initialized and
 * properly set up, including response buffer (may be %NULL if no response is
 * expected) and command message data. This function does not wait for the
 * request to be completed.
 *
 * If this function succeeds, ssam_request_sync_wait() must be used to ensure
 * that the request has been completed before the response data can be
 * accessed and/or the request can be freed. On failure, the request may
 * immediately be freed.
 *
 * This function may only be used if the controller is active, i.e. has been
 * initialized and not suspended.
 */
int ssam_request_sync_submit(struct ssam_controller *ctrl,
			     struct ssam_request_sync *rqst)
{
	int status;

	/*
	 * This is only a superficial check. In general, the caller needs to
	 * ensure that the controller is initialized and is not (and does not
	 * get) suspended during use, i.e. until the request has been completed
	 * (if _absolutely_ necessary, by use of ssam_controller_statelock/
	 * ssam_controller_stateunlock, but something like ssam_client_link
	 * should be preferred as this needs to last until the request has been
	 * completed).
	 *
	 * Note that it is actually safe to use this function while the
	 * controller is in the process of being shut down (as ssh_rtl_submit
	 * is safe with regards to this), but it is generally discouraged to do
	 * so.
	 */
	if (WARN_ON(READ_ONCE(ctrl->state) != SSAM_CONTROLLER_STARTED)) {
		ssh_request_put(&rqst->base);
		return -ENODEV;
	}

	status = ssh_rtl_submit(&ctrl->rtl, &rqst->base);
	ssh_request_put(&rqst->base);

	return status;
}
EXPORT_SYMBOL_GPL(ssam_request_sync_submit);

/**
 * ssam_request_sync() - Execute a synchronous request.
 * @ctrl: The controller via which the request will be submitted.
 * @spec: The request specification and payload.
 * @rsp:  The response buffer.
 *
 * Allocates a synchronous request with its message data buffer on the heap
 * via ssam_request_sync_alloc(), fully initializes it via the provided
 * request specification, submits it, and finally waits for its completion
 * before freeing it and returning its status.
 *
 * Return: Returns the status of the request or any failure during setup.
 */
int ssam_request_sync(struct ssam_controller *ctrl,
		      const struct ssam_request *spec,
		      struct ssam_response *rsp)
{
	struct ssam_request_sync *rqst;
	struct ssam_span buf;
	ssize_t len;
	int status;

	status = ssam_request_sync_alloc(spec->length, GFP_KERNEL, &rqst, &buf);
	if (status)
		return status;

	status = ssam_request_sync_init(rqst, spec->flags);
	if (status)
		return status;

	ssam_request_sync_set_resp(rqst, rsp);

	len = ssam_request_write_data(&buf, ctrl, spec);
	if (len < 0) {
		ssam_request_sync_free(rqst);
		return len;
	}

	ssam_request_sync_set_data(rqst, buf.ptr, len);

	status = ssam_request_sync_submit(ctrl, rqst);
	if (!status)
		status = ssam_request_sync_wait(rqst);

	ssam_request_sync_free(rqst);
	return status;
}
EXPORT_SYMBOL_GPL(ssam_request_sync);

/**
 * ssam_request_sync_with_buffer() - Execute a synchronous request with the
 * provided buffer as back-end for the message buffer.
 * @ctrl: The controller via which the request will be submitted.
 * @spec: The request specification and payload.
 * @rsp:  The response buffer.
 * @buf:  The buffer for the request message data.
 *
 * Allocates a synchronous request struct on the stack, fully initializes it
 * using the provided buffer as message data buffer, submits it, and then
 * waits for its completion before returning its status. The
 * SSH_COMMAND_MESSAGE_LENGTH() macro can be used to compute the required
 * message buffer size.
 *
 * This function does essentially the same as ssam_request_sync(), but instead
 * of dynamically allocating the request and message data buffer, it uses the
 * provided message data buffer and stores the (small) request struct on the
 * heap.
 *
 * Return: Returns the status of the request or any failure during setup.
 */
int ssam_request_sync_with_buffer(struct ssam_controller *ctrl,
				  const struct ssam_request *spec,
				  struct ssam_response *rsp,
				  struct ssam_span *buf)
{
	struct ssam_request_sync rqst;
	ssize_t len;
	int status;

	status = ssam_request_sync_init(&rqst, spec->flags);
	if (status)
		return status;

	ssam_request_sync_set_resp(&rqst, rsp);

	len = ssam_request_write_data(buf, ctrl, spec);
	if (len < 0)
		return len;

	ssam_request_sync_set_data(&rqst, buf->ptr, len);

	status = ssam_request_sync_submit(ctrl, &rqst);
	if (!status)
		status = ssam_request_sync_wait(&rqst);

	return status;
}
EXPORT_SYMBOL_GPL(ssam_request_sync_with_buffer);


/* -- Internal SAM requests. ------------------------------------------------ */

SSAM_DEFINE_SYNC_REQUEST_R(ssam_ssh_get_firmware_version, __le32, {
	.target_category = SSAM_SSH_TC_SAM,
	.target_id       = 0x01,
	.command_id      = 0x13,
	.instance_id     = 0x00,
});

SSAM_DEFINE_SYNC_REQUEST_R(ssam_ssh_notif_display_off, u8, {
	.target_category = SSAM_SSH_TC_SAM,
	.target_id       = 0x01,
	.command_id      = 0x15,
	.instance_id     = 0x00,
});

SSAM_DEFINE_SYNC_REQUEST_R(ssam_ssh_notif_display_on, u8, {
	.target_category = SSAM_SSH_TC_SAM,
	.target_id       = 0x01,
	.command_id      = 0x16,
	.instance_id     = 0x00,
});

SSAM_DEFINE_SYNC_REQUEST_R(ssam_ssh_notif_d0_exit, u8, {
	.target_category = SSAM_SSH_TC_SAM,
	.target_id       = 0x01,
	.command_id      = 0x33,
	.instance_id     = 0x00,
});

SSAM_DEFINE_SYNC_REQUEST_R(ssam_ssh_notif_d0_entry, u8, {
	.target_category = SSAM_SSH_TC_SAM,
	.target_id       = 0x01,
	.command_id      = 0x34,
	.instance_id     = 0x00,
});

/**
 * struct ssh_notification_params - Command payload to enable/disable SSH
 * notifications.
 * @target_category: The target category for which notifications should be
 *                   enabled/disabled.
 * @flags:           Flags determining how notifications are being sent.
 * @request_id:      The request ID that is used to send these notifications.
 * @instance_id:     The specific instance in the given target category for
 *                   which notifications should be enabled.
 */
struct ssh_notification_params {
	u8 target_category;
	u8 flags;
	__le16 request_id;
	u8 instance_id;
} __packed;

static_assert(sizeof(struct ssh_notification_params) == 5);

static int __ssam_ssh_event_request(struct ssam_controller *ctrl,
				    struct ssam_event_registry reg, u8 cid,
				    struct ssam_event_id id, u8 flags)
{
	struct ssh_notification_params params;
	struct ssam_request rqst;
	struct ssam_response result;
	int status;

	u16 rqid = ssh_tc_to_rqid(id.target_category);
	u8 buf = 0;

	/* Only allow RQIDs that lie within the event spectrum. */
	if (!ssh_rqid_is_event(rqid))
		return -EINVAL;

	params.target_category = id.target_category;
	params.instance_id = id.instance;
	params.flags = flags;
	put_unaligned_le16(rqid, &params.request_id);

	rqst.target_category = reg.target_category;
	rqst.target_id = reg.target_id;
	rqst.command_id = cid;
	rqst.instance_id = 0x00;
	rqst.flags = SSAM_REQUEST_HAS_RESPONSE;
	rqst.length = sizeof(params);
	rqst.payload = (u8 *)&params;

	result.capacity = sizeof(buf);
	result.length = 0;
	result.pointer = &buf;

	status = ssam_retry(ssam_request_sync_onstack, ctrl, &rqst, &result,
			    sizeof(params));

	return status < 0 ? status : buf;
}

/**
 * ssam_ssh_event_enable() - Enable SSH event.
 * @ctrl:  The controller for which to enable the event.
 * @reg:   The event registry describing what request to use for enabling and
 *         disabling the event.
 * @id:    The event identifier.
 * @flags: The event flags.
 *
 * Enables the specified event on the EC. This function does not manage
 * reference counting of enabled events and is basically only a wrapper for
 * the raw EC request. If the specified event is already enabled, the EC will
 * ignore this request.
 *
 * Return: Returns the status of the executed SAM request (zero on success and
 * negative on direct failure) or %-EPROTO if the request response indicates a
 * failure.
 */
static int ssam_ssh_event_enable(struct ssam_controller *ctrl,
				 struct ssam_event_registry reg,
				 struct ssam_event_id id, u8 flags)
{
	int status;

	status = __ssam_ssh_event_request(ctrl, reg, reg.cid_enable, id, flags);

	if (status < 0 && status != -EINVAL) {
		ssam_err(ctrl,
			 "failed to enable event source (tc: %#04x, iid: %#04x, reg: %#04x)\n",
			 id.target_category, id.instance, reg.target_category);
	}

	if (status > 0) {
		ssam_err(ctrl,
			 "unexpected result while enabling event source: %#04x (tc: %#04x, iid: %#04x, reg: %#04x)\n",
			 status, id.target_category, id.instance, reg.target_category);
		return -EPROTO;
	}

	return status;
}

/**
 * ssam_ssh_event_disable() - Disable SSH event.
 * @ctrl:  The controller for which to disable the event.
 * @reg:   The event registry describing what request to use for enabling and
 *         disabling the event (must be same as used when enabling the event).
 * @id:    The event identifier.
 * @flags: The event flags (likely ignored for disabling of events).
 *
 * Disables the specified event on the EC. This function does not manage
 * reference counting of enabled events and is basically only a wrapper for
 * the raw EC request. If the specified event is already disabled, the EC will
 * ignore this request.
 *
 * Return: Returns the status of the executed SAM request (zero on success and
 * negative on direct failure) or %-EPROTO if the request response indicates a
 * failure.
 */
static int ssam_ssh_event_disable(struct ssam_controller *ctrl,
				  struct ssam_event_registry reg,
				  struct ssam_event_id id, u8 flags)
{
	int status;

	status = __ssam_ssh_event_request(ctrl, reg, reg.cid_enable, id, flags);

	if (status < 0 && status != -EINVAL) {
		ssam_err(ctrl,
			 "failed to disable event source (tc: %#04x, iid: %#04x, reg: %#04x)\n",
			 id.target_category, id.instance, reg.target_category);
	}

	if (status > 0) {
		ssam_err(ctrl,
			 "unexpected result while disabling event source: %#04x (tc: %#04x, iid: %#04x, reg: %#04x)\n",
			 status, id.target_category, id.instance, reg.target_category);
		return -EPROTO;
	}

	return status;
}


/* -- Wrappers for internal SAM requests. ----------------------------------- */

/**
 * ssam_get_firmware_version() - Get the SAM/EC firmware version.
 * @ctrl:    The controller.
 * @version: Where to store the version number.
 *
 * Return: Returns zero on success or the status of the executed SAM request
 * if that request failed.
 */
int ssam_get_firmware_version(struct ssam_controller *ctrl, u32 *version)
{
	__le32 __version;
	int status;

	status = ssam_retry(ssam_ssh_get_firmware_version, ctrl, &__version);
	if (status)
		return status;

	*version = le32_to_cpu(__version);
	return 0;
}

/**
 * ssam_ctrl_notif_display_off() - Notify EC that the display has been turned
 * off.
 * @ctrl: The controller.
 *
 * Notify the EC that the display has been turned off and the driver may enter
 * a lower-power state. This will prevent events from being sent directly.
 * Rather, the EC signals an event by pulling the wakeup GPIO high for as long
 * as there are pending events. The events then need to be manually released,
 * one by one, via the GPIO callback request. All pending events accumulated
 * during this state can also be released by issuing the display-on
 * notification, e.g. via ssam_ctrl_notif_display_on(), which will also reset
 * the GPIO.
 *
 * On some devices, specifically ones with an integrated keyboard, the keyboard
 * backlight will be turned off by this call.
 *
 * This function will only send the display-off notification command if
 * display notifications are supported by the EC. Currently all known devices
 * support these notifications.
 *
 * Use ssam_ctrl_notif_display_on() to reverse the effects of this function.
 *
 * Return: Returns zero on success or if no request has been executed, the
 * status of the executed SAM request if that request failed, or %-EPROTO if
 * an unexpected response has been received.
 */
int ssam_ctrl_notif_display_off(struct ssam_controller *ctrl)
{
	int status;
	u8 response;

	ssam_dbg(ctrl, "pm: notifying display off\n");

	status = ssam_retry(ssam_ssh_notif_display_off, ctrl, &response);
	if (status)
		return status;

	if (response != 0) {
		ssam_err(ctrl, "unexpected response from display-off notification: %#04x\n",
			 response);
		return -EPROTO;
	}

	return 0;
}

/**
 * ssam_ctrl_notif_display_on() - Notify EC that the display has been turned on.
 * @ctrl: The controller.
 *
 * Notify the EC that the display has been turned back on and the driver has
 * exited its lower-power state. This notification is the counterpart to the
 * display-off notification sent via ssam_ctrl_notif_display_off() and will
 * reverse its effects, including resetting events to their default behavior.
 *
 * This function will only send the display-on notification command if display
 * notifications are supported by the EC. Currently all known devices support
 * these notifications.
 *
 * See ssam_ctrl_notif_display_off() for more details.
 *
 * Return: Returns zero on success or if no request has been executed, the
 * status of the executed SAM request if that request failed, or %-EPROTO if
 * an unexpected response has been received.
 */
int ssam_ctrl_notif_display_on(struct ssam_controller *ctrl)
{
	int status;
	u8 response;

	ssam_dbg(ctrl, "pm: notifying display on\n");

	status = ssam_retry(ssam_ssh_notif_display_on, ctrl, &response);
	if (status)
		return status;

	if (response != 0) {
		ssam_err(ctrl, "unexpected response from display-on notification: %#04x\n",
			 response);
		return -EPROTO;
	}

	return 0;
}

/**
 * ssam_ctrl_notif_d0_exit() - Notify EC that the driver/device exits the D0
 * power state.
 * @ctrl: The controller
 *
 * Notifies the EC that the driver prepares to exit the D0 power state in
 * favor of a lower-power state. Exact effects of this function related to the
 * EC are currently unknown.
 *
 * This function will only send the D0-exit notification command if D0-state
 * notifications are supported by the EC. Only newer Surface generations
 * support these notifications.
 *
 * Use ssam_ctrl_notif_d0_entry() to reverse the effects of this function.
 *
 * Return: Returns zero on success or if no request has been executed, the
 * status of the executed SAM request if that request failed, or %-EPROTO if
 * an unexpected response has been received.
 */
int ssam_ctrl_notif_d0_exit(struct ssam_controller *ctrl)
{
	int status;
	u8 response;

	if (!ctrl->caps.d3_closes_handle)
		return 0;

	ssam_dbg(ctrl, "pm: notifying D0 exit\n");

	status = ssam_retry(ssam_ssh_notif_d0_exit, ctrl, &response);
	if (status)
		return status;

	if (response != 0) {
		ssam_err(ctrl, "unexpected response from D0-exit notification: %#04x\n",
			 response);
		return -EPROTO;
	}

	return 0;
}

/**
 * ssam_ctrl_notif_d0_entry() - Notify EC that the driver/device enters the D0
 * power state.
 * @ctrl: The controller
 *
 * Notifies the EC that the driver has exited a lower-power state and entered
 * the D0 power state. Exact effects of this function related to the EC are
 * currently unknown.
 *
 * This function will only send the D0-entry notification command if D0-state
 * notifications are supported by the EC. Only newer Surface generations
 * support these notifications.
 *
 * See ssam_ctrl_notif_d0_exit() for more details.
 *
 * Return: Returns zero on success or if no request has been executed, the
 * status of the executed SAM request if that request failed, or %-EPROTO if
 * an unexpected response has been received.
 */
int ssam_ctrl_notif_d0_entry(struct ssam_controller *ctrl)
{
	int status;
	u8 response;

	if (!ctrl->caps.d3_closes_handle)
		return 0;

	ssam_dbg(ctrl, "pm: notifying D0 entry\n");

	status = ssam_retry(ssam_ssh_notif_d0_entry, ctrl, &response);
	if (status)
		return status;

	if (response != 0) {
		ssam_err(ctrl, "unexpected response from D0-entry notification: %#04x\n",
			 response);
		return -EPROTO;
	}

	return 0;
}


/* -- Top-level event registry interface. ----------------------------------- */

/**
 * ssam_notifier_register() - Register an event notifier.
 * @ctrl: The controller to register the notifier on.
 * @n:    The event notifier to register.
 *
 * Register an event notifier and increment the usage counter of the
 * associated SAM event. If the event was previously not enabled, it will be
 * enabled during this call.
 *
 * Return: Returns zero on success, %-ENOSPC if there have already been
 * %INT_MAX notifiers for the event ID/type associated with the notifier block
 * registered, %-ENOMEM if the corresponding event entry could not be
 * allocated. If this is the first time that a notifier block is registered
 * for the specific associated event, returns the status of the event-enable
 * EC-command.
 */
int ssam_notifier_register(struct ssam_controller *ctrl,
			   struct ssam_event_notifier *n)
{
	u16 rqid = ssh_tc_to_rqid(n->event.id.target_category);
	struct ssam_nf_refcount_entry *entry;
	struct ssam_nf_head *nf_head;
	struct ssam_nf *nf;
	int status;

	if (!ssh_rqid_is_event(rqid))
		return -EINVAL;

	nf = &ctrl->cplt.event.notif;
	nf_head = &nf->head[ssh_rqid_to_event(rqid)];

	mutex_lock(&nf->lock);

	entry = ssam_nf_refcount_inc(nf, n->event.reg, n->event.id);
	if (IS_ERR(entry)) {
		mutex_unlock(&nf->lock);
		return PTR_ERR(entry);
	}

	ssam_dbg(ctrl, "enabling event (reg: %#04x, tc: %#04x, iid: %#04x, rc: %d)\n",
		 n->event.reg.target_category, n->event.id.target_category,
		 n->event.id.instance, entry->refcount);

	status = ssam_nfblk_insert(nf_head, &n->base);
	if (status) {
		entry = ssam_nf_refcount_dec(nf, n->event.reg, n->event.id);
		if (entry->refcount == 0)
			kfree(entry);

		mutex_unlock(&nf->lock);
		return status;
	}

	if (entry->refcount == 1) {
		status = ssam_ssh_event_enable(ctrl, n->event.reg, n->event.id,
					       n->event.flags);
		if (status) {
			ssam_nfblk_remove(&n->base);
			kfree(ssam_nf_refcount_dec(nf, n->event.reg, n->event.id));
			mutex_unlock(&nf->lock);
			synchronize_srcu(&nf_head->srcu);
			return status;
		}

		entry->flags = n->event.flags;

	} else if (entry->flags != n->event.flags) {
		ssam_warn(ctrl,
			  "inconsistent flags when enabling event: got %#04x, expected %#04x (reg: %#04x, tc: %#04x, iid: %#04x)\n",
			  n->event.flags, entry->flags, n->event.reg.target_category,
			  n->event.id.target_category, n->event.id.instance);
	}

	mutex_unlock(&nf->lock);
	return 0;
}
EXPORT_SYMBOL_GPL(ssam_notifier_register);

/**
 * ssam_notifier_unregister() - Unregister an event notifier.
 * @ctrl: The controller the notifier has been registered on.
 * @n:    The event notifier to unregister.
 *
 * Unregister an event notifier and decrement the usage counter of the
 * associated SAM event. If the usage counter reaches zero, the event will be
 * disabled.
 *
 * Return: Returns zero on success, %-ENOENT if the given notifier block has
 * not been registered on the controller. If the given notifier block was the
 * last one associated with its specific event, returns the status of the
 * event-disable EC-command.
 */
int ssam_notifier_unregister(struct ssam_controller *ctrl,
			     struct ssam_event_notifier *n)
{
	u16 rqid = ssh_tc_to_rqid(n->event.id.target_category);
	struct ssam_nf_refcount_entry *entry;
	struct ssam_nf_head *nf_head;
	struct ssam_nf *nf;
	int status = 0;

	if (!ssh_rqid_is_event(rqid))
		return -EINVAL;

	nf = &ctrl->cplt.event.notif;
	nf_head = &nf->head[ssh_rqid_to_event(rqid)];

	mutex_lock(&nf->lock);

	if (!ssam_nfblk_find(nf_head, &n->base)) {
		mutex_unlock(&nf->lock);
		return -ENOENT;
	}

	entry = ssam_nf_refcount_dec(nf, n->event.reg, n->event.id);
	if (WARN_ON(!entry)) {
		/*
		 * If this does not return an entry, there's a logic error
		 * somewhere: The notifier block is registered, but the event
		 * refcount entry is not there. Remove the notifier block
		 * anyways.
		 */
		status = -ENOENT;
		goto remove;
	}

	ssam_dbg(ctrl, "disabling event (reg: %#04x, tc: %#04x, iid: %#04x, rc: %d)\n",
		 n->event.reg.target_category, n->event.id.target_category,
		 n->event.id.instance, entry->refcount);

	if (entry->flags != n->event.flags) {
		ssam_warn(ctrl,
			  "inconsistent flags when disabling event: got %#04x, expected %#04x (reg: %#04x, tc: %#04x, iid: %#04x)\n",
			  n->event.flags, entry->flags, n->event.reg.target_category,
			  n->event.id.target_category, n->event.id.instance);
	}

	if (entry->refcount == 0) {
		status = ssam_ssh_event_disable(ctrl, n->event.reg, n->event.id,
						n->event.flags);
		kfree(entry);
	}

remove:
	ssam_nfblk_remove(&n->base);
	mutex_unlock(&nf->lock);
	synchronize_srcu(&nf_head->srcu);

	return status;
}
EXPORT_SYMBOL_GPL(ssam_notifier_unregister);

/**
 * ssam_notifier_disable_registered() - Disable events for all registered
 * notifiers.
 * @ctrl: The controller for which to disable the notifiers/events.
 *
 * Disables events for all currently registered notifiers. In case of an error
 * (EC command failing), all previously disabled events will be restored and
 * the error code returned.
 *
 * This function is intended to disable all events prior to hibernation entry.
 * See ssam_notifier_restore_registered() to restore/re-enable all events
 * disabled with this function.
 *
 * Note that this function will not disable events for notifiers registered
 * after calling this function. It should thus be made sure that no new
 * notifiers are going to be added after this call and before the corresponding
 * call to ssam_notifier_restore_registered().
 *
 * Return: Returns zero on success. In case of failure returns the error code
 * returned by the failed EC command to disable an event.
 */
int ssam_notifier_disable_registered(struct ssam_controller *ctrl)
{
	struct ssam_nf *nf = &ctrl->cplt.event.notif;
	struct rb_node *n;
	int status;

	mutex_lock(&nf->lock);
	for (n = rb_first(&nf->refcount); n; n = rb_next(n)) {
		struct ssam_nf_refcount_entry *e;

		e = rb_entry(n, struct ssam_nf_refcount_entry, node);
		status = ssam_ssh_event_disable(ctrl, e->key.reg,
						e->key.id, e->flags);
		if (status)
			goto err;
	}
	mutex_unlock(&nf->lock);

	return 0;

err:
	for (n = rb_prev(n); n; n = rb_prev(n)) {
		struct ssam_nf_refcount_entry *e;

		e = rb_entry(n, struct ssam_nf_refcount_entry, node);
		ssam_ssh_event_enable(ctrl, e->key.reg, e->key.id, e->flags);
	}
	mutex_unlock(&nf->lock);

	return status;
}

/**
 * ssam_notifier_restore_registered() - Restore/re-enable events for all
 * registered notifiers.
 * @ctrl: The controller for which to restore the notifiers/events.
 *
 * Restores/re-enables all events for which notifiers have been registered on
 * the given controller. In case of a failure, the error is logged and the
 * function continues to try and enable the remaining events.
 *
 * This function is intended to restore/re-enable all registered events after
 * hibernation. See ssam_notifier_disable_registered() for the counter part
 * disabling the events and more details.
 */
void ssam_notifier_restore_registered(struct ssam_controller *ctrl)
{
	struct ssam_nf *nf = &ctrl->cplt.event.notif;
	struct rb_node *n;

	mutex_lock(&nf->lock);
	for (n = rb_first(&nf->refcount); n; n = rb_next(n)) {
		struct ssam_nf_refcount_entry *e;

		e = rb_entry(n, struct ssam_nf_refcount_entry, node);

		/* Ignore errors, will get logged in call. */
		ssam_ssh_event_enable(ctrl, e->key.reg, e->key.id, e->flags);
	}
	mutex_unlock(&nf->lock);
}

/**
 * ssam_notifier_is_empty() - Check if there are any registered notifiers.
 * @ctrl: The controller to check on.
 *
 * Return: Returns %true if there are currently no notifiers registered on the
 * controller, %false otherwise.
 */
static bool ssam_notifier_is_empty(struct ssam_controller *ctrl)
{
	struct ssam_nf *nf = &ctrl->cplt.event.notif;
	bool result;

	mutex_lock(&nf->lock);
	result = ssam_nf_refcount_empty(nf);
	mutex_unlock(&nf->lock);

	return result;
}

/**
 * ssam_notifier_unregister_all() - Unregister all currently registered
 * notifiers.
 * @ctrl: The controller to unregister the notifiers on.
 *
 * Unregisters all currently registered notifiers. This function is used to
 * ensure that all notifiers will be unregistered and associated
 * entries/resources freed when the controller is being shut down.
 */
static void ssam_notifier_unregister_all(struct ssam_controller *ctrl)
{
	struct ssam_nf *nf = &ctrl->cplt.event.notif;
	struct ssam_nf_refcount_entry *e, *n;

	mutex_lock(&nf->lock);
	rbtree_postorder_for_each_entry_safe(e, n, &nf->refcount, node) {
		/* Ignore errors, will get logged in call. */
		ssam_ssh_event_disable(ctrl, e->key.reg, e->key.id, e->flags);
		kfree(e);
	}
	nf->refcount = RB_ROOT;
	mutex_unlock(&nf->lock);
}


/* -- Wakeup IRQ. ----------------------------------------------------------- */

static irqreturn_t ssam_irq_handle(int irq, void *dev_id)
{
	struct ssam_controller *ctrl = dev_id;

	ssam_dbg(ctrl, "pm: wake irq triggered\n");

	/*
	 * Note: Proper wakeup detection is currently unimplemented.
	 *       When the EC is in display-off or any other non-D0 state, it
	 *       does not send events/notifications to the host. Instead it
	 *       signals that there are events available via the wakeup IRQ.
	 *       This driver is responsible for calling back to the EC to
	 *       release these events one-by-one.
	 *
	 *       This IRQ should not cause a full system resume by its own.
	 *       Instead, events should be handled by their respective subsystem
	 *       drivers, which in turn should signal whether a full system
	 *       resume should be performed.
	 *
	 * TODO: Send GPIO callback command repeatedly to EC until callback
	 *       returns 0x00. Return flag of callback is "has more events".
	 *       Each time the command is sent, one event is "released". Once
	 *       all events have been released (return = 0x00), the GPIO is
	 *       re-armed. Detect wakeup events during this process, go back to
	 *       sleep if no wakeup event has been received.
	 */

	return IRQ_HANDLED;
}

/**
 * ssam_irq_setup() - Set up SAM EC wakeup-GPIO interrupt.
 * @ctrl: The controller for which the IRQ should be set up.
 *
 * Set up an IRQ for the wakeup-GPIO pin of the SAM EC. This IRQ can be used
 * to wake the device from a low power state.
 *
 * Note that this IRQ can only be triggered while the EC is in the display-off
 * state. In this state, events are not sent to the host in the usual way.
 * Instead the wakeup-GPIO gets pulled to "high" as long as there are pending
 * events and these events need to be released one-by-one via the GPIO
 * callback request, either until there are no events left and the GPIO is
 * reset, or all at once by transitioning the EC out of the display-off state,
 * which will also clear the GPIO.
 *
 * Not all events, however, should trigger a full system wakeup. Instead the
 * driver should, if necessary, inspect and forward each event to the
 * corresponding subsystem, which in turn should decide if the system needs to
 * be woken up. This logic has not been implemented yet, thus wakeup by this
 * IRQ should be disabled by default to avoid spurious wake-ups, caused, for
 * example, by the remaining battery percentage changing. Refer to comments in
 * this function and comments in the corresponding IRQ handler for more
 * details on how this should be implemented.
 *
 * See also ssam_ctrl_notif_display_off() and ssam_ctrl_notif_display_off()
 * for functions to transition the EC into and out of the display-off state as
 * well as more details on it.
 *
 * The IRQ is disabled by default and has to be enabled before it can wake up
 * the device from suspend via ssam_irq_arm_for_wakeup(). On teardown, the IRQ
 * should be freed via ssam_irq_free().
 */
int ssam_irq_setup(struct ssam_controller *ctrl)
{
	struct device *dev = ssam_controller_device(ctrl);
	struct gpio_desc *gpiod;
	int irq;
	int status;

	/*
	 * The actual GPIO interrupt is declared in ACPI as TRIGGER_HIGH.
	 * However, the GPIO line only gets reset by sending the GPIO callback
	 * command to SAM (or alternatively the display-on notification). As
	 * proper handling for this interrupt is not implemented yet, leaving
	 * the IRQ at TRIGGER_HIGH would cause an IRQ storm (as the callback
	 * never gets sent and thus the line never gets reset). To avoid this,
	 * mark the IRQ as TRIGGER_RISING for now, only creating a single
	 * interrupt, and let the SAM resume callback during the controller
	 * resume process clear it.
	 */
	const int irqf = IRQF_SHARED | IRQF_ONESHOT |
			 IRQF_TRIGGER_RISING | IRQF_NO_AUTOEN;

	gpiod = gpiod_get(dev, "ssam_wakeup-int", GPIOD_ASIS);
	if (IS_ERR(gpiod))
		return PTR_ERR(gpiod);

	irq = gpiod_to_irq(gpiod);
	gpiod_put(gpiod);

	if (irq < 0)
		return irq;

	status = request_threaded_irq(irq, NULL, ssam_irq_handle, irqf,
				      "ssam_wakeup", ctrl);
	if (status)
		return status;

	ctrl->irq.num = irq;
	return 0;
}

/**
 * ssam_irq_free() - Free SAM EC wakeup-GPIO interrupt.
 * @ctrl: The controller for which the IRQ should be freed.
 *
 * Free the wakeup-GPIO IRQ previously set-up via ssam_irq_setup().
 */
void ssam_irq_free(struct ssam_controller *ctrl)
{
	free_irq(ctrl->irq.num, ctrl);
	ctrl->irq.num = -1;
}

/**
 * ssam_irq_arm_for_wakeup() - Arm the EC IRQ for wakeup, if enabled.
 * @ctrl: The controller for which the IRQ should be armed.
 *
 * Sets up the IRQ so that it can be used to wake the device. Specifically,
 * this function enables the irq and then, if the device is allowed to wake up
 * the system, calls enable_irq_wake(). See ssam_irq_disarm_wakeup() for the
 * corresponding function to disable the IRQ.
 *
 * This function is intended to arm the IRQ before entering S2idle suspend.
 *
 * Note: calls to ssam_irq_arm_for_wakeup() and ssam_irq_disarm_wakeup() must
 * be balanced.
 */
int ssam_irq_arm_for_wakeup(struct ssam_controller *ctrl)
{
	struct device *dev = ssam_controller_device(ctrl);
	int status;

	enable_irq(ctrl->irq.num);
	if (device_may_wakeup(dev)) {
		status = enable_irq_wake(ctrl->irq.num);
		if (status) {
			ssam_err(ctrl, "failed to enable wake IRQ: %d\n", status);
			disable_irq(ctrl->irq.num);
			return status;
		}

		ctrl->irq.wakeup_enabled = true;
	} else {
		ctrl->irq.wakeup_enabled = false;
	}

	return 0;
}

/**
 * ssam_irq_disarm_wakeup() - Disarm the wakeup IRQ.
 * @ctrl: The controller for which the IRQ should be disarmed.
 *
 * Disarm the IRQ previously set up for wake via ssam_irq_arm_for_wakeup().
 *
 * This function is intended to disarm the IRQ after exiting S2idle suspend.
 *
 * Note: calls to ssam_irq_arm_for_wakeup() and ssam_irq_disarm_wakeup() must
 * be balanced.
 */
void ssam_irq_disarm_wakeup(struct ssam_controller *ctrl)
{
	int status;

	if (ctrl->irq.wakeup_enabled) {
		status = disable_irq_wake(ctrl->irq.num);
		if (status)
			ssam_err(ctrl, "failed to disable wake IRQ: %d\n", status);

		ctrl->irq.wakeup_enabled = false;
	}
	disable_irq(ctrl->irq.num);
}
