linux/drivers/platform/surface/aggregator/controller.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Main SSAM/SSH controller structure and functionality.
   4 *
   5 * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
   6 */
   7
   8#include <linux/acpi.h>
   9#include <linux/atomic.h>
  10#include <linux/completion.h>
  11#include <linux/gpio/consumer.h>
  12#include <linux/interrupt.h>
  13#include <linux/kref.h>
  14#include <linux/limits.h>
  15#include <linux/list.h>
  16#include <linux/lockdep.h>
  17#include <linux/mutex.h>
  18#include <linux/rculist.h>
  19#include <linux/rbtree.h>
  20#include <linux/rwsem.h>
  21#include <linux/serdev.h>
  22#include <linux/slab.h>
  23#include <linux/spinlock.h>
  24#include <linux/srcu.h>
  25#include <linux/types.h>
  26#include <linux/workqueue.h>
  27
  28#include <linux/surface_aggregator/controller.h>
  29#include <linux/surface_aggregator/serial_hub.h>
  30
  31#include "controller.h"
  32#include "ssh_msgb.h"
  33#include "ssh_request_layer.h"
  34
  35#include "trace.h"
  36
  37
  38/* -- Safe counters. -------------------------------------------------------- */
  39
  40/**
  41 * ssh_seq_reset() - Reset/initialize sequence ID counter.
  42 * @c: The counter to reset.
  43 */
  44static void ssh_seq_reset(struct ssh_seq_counter *c)
  45{
  46        WRITE_ONCE(c->value, 0);
  47}
  48
  49/**
  50 * ssh_seq_next() - Get next sequence ID.
  51 * @c: The counter providing the sequence IDs.
  52 *
  53 * Return: Returns the next sequence ID of the counter.
  54 */
  55static u8 ssh_seq_next(struct ssh_seq_counter *c)
  56{
  57        u8 old = READ_ONCE(c->value);
  58        u8 new = old + 1;
  59        u8 ret;
  60
  61        while (unlikely((ret = cmpxchg(&c->value, old, new)) != old)) {
  62                old = ret;
  63                new = old + 1;
  64        }
  65
  66        return old;
  67}
  68
  69/**
  70 * ssh_rqid_reset() - Reset/initialize request ID counter.
  71 * @c: The counter to reset.
  72 */
  73static void ssh_rqid_reset(struct ssh_rqid_counter *c)
  74{
  75        WRITE_ONCE(c->value, 0);
  76}
  77
  78/**
  79 * ssh_rqid_next() - Get next request ID.
  80 * @c: The counter providing the request IDs.
  81 *
  82 * Return: Returns the next request ID of the counter, skipping any reserved
  83 * request IDs.
  84 */
  85static u16 ssh_rqid_next(struct ssh_rqid_counter *c)
  86{
  87        u16 old = READ_ONCE(c->value);
  88        u16 new = ssh_rqid_next_valid(old);
  89        u16 ret;
  90
  91        while (unlikely((ret = cmpxchg(&c->value, old, new)) != old)) {
  92                old = ret;
  93                new = ssh_rqid_next_valid(old);
  94        }
  95
  96        return old;
  97}
  98
  99
 100/* -- Event notifier/callbacks. --------------------------------------------- */
 101/*
 102 * The notifier system is based on linux/notifier.h, specifically the SRCU
 103 * implementation. The difference to that is, that some bits of the notifier
 104 * call return value can be tracked across multiple calls. This is done so
 105 * that handling of events can be tracked and a warning can be issued in case
 106 * an event goes unhandled. The idea of that warning is that it should help
 107 * discover and identify new/currently unimplemented features.
 108 */
 109
 110/**
 111 * ssam_event_matches_notifier() - Test if an event matches a notifier.
 112 * @n: The event notifier to test against.
 113 * @event: The event to test.
 114 *
 115 * Return: Returns %true if the given event matches the given notifier
 116 * according to the rules set in the notifier's event mask, %false otherwise.
 117 */
 118static bool ssam_event_matches_notifier(const struct ssam_event_notifier *n,
 119                                        const struct ssam_event *event)
 120{
 121        bool match = n->event.id.target_category == event->target_category;
 122
 123        if (n->event.mask & SSAM_EVENT_MASK_TARGET)
 124                match &= n->event.reg.target_id == event->target_id;
 125
 126        if (n->event.mask & SSAM_EVENT_MASK_INSTANCE)
 127                match &= n->event.id.instance == event->instance_id;
 128
 129        return match;
 130}
 131
 132/**
 133 * ssam_nfblk_call_chain() - Call event notifier callbacks of the given chain.
 134 * @nh:    The notifier head for which the notifier callbacks should be called.
 135 * @event: The event data provided to the callbacks.
 136 *
 137 * Call all registered notifier callbacks in order of their priority until
 138 * either no notifier is left or a notifier returns a value with the
 139 * %SSAM_NOTIF_STOP bit set. Note that this bit is automatically set via
 140 * ssam_notifier_from_errno() on any non-zero error value.
 141 *
 142 * Return: Returns the notifier status value, which contains the notifier
 143 * status bits (%SSAM_NOTIF_HANDLED and %SSAM_NOTIF_STOP) as well as a
 144 * potential error value returned from the last executed notifier callback.
 145 * Use ssam_notifier_to_errno() to convert this value to the original error
 146 * value.
 147 */
 148static int ssam_nfblk_call_chain(struct ssam_nf_head *nh, struct ssam_event *event)
 149{
 150        struct ssam_event_notifier *nf;
 151        int ret = 0, idx;
 152
 153        idx = srcu_read_lock(&nh->srcu);
 154
 155        list_for_each_entry_rcu(nf, &nh->head, base.node,
 156                                srcu_read_lock_held(&nh->srcu)) {
 157                if (ssam_event_matches_notifier(nf, event)) {
 158                        ret = (ret & SSAM_NOTIF_STATE_MASK) | nf->base.fn(nf, event);
 159                        if (ret & SSAM_NOTIF_STOP)
 160                                break;
 161                }
 162        }
 163
 164        srcu_read_unlock(&nh->srcu, idx);
 165        return ret;
 166}
 167
 168/**
 169 * ssam_nfblk_insert() - Insert a new notifier block into the given notifier
 170 * list.
 171 * @nh: The notifier head into which the block should be inserted.
 172 * @nb: The notifier block to add.
 173 *
 174 * Note: This function must be synchronized by the caller with respect to other
 175 * insert, find, and/or remove calls by holding ``struct ssam_nf.lock``.
 176 *
 177 * Return: Returns zero on success, %-EEXIST if the notifier block has already
 178 * been registered.
 179 */
 180static int ssam_nfblk_insert(struct ssam_nf_head *nh, struct ssam_notifier_block *nb)
 181{
 182        struct ssam_notifier_block *p;
 183        struct list_head *h;
 184
 185        /* Runs under lock, no need for RCU variant. */
 186        list_for_each(h, &nh->head) {
 187                p = list_entry(h, struct ssam_notifier_block, node);
 188
 189                if (unlikely(p == nb)) {
 190                        WARN(1, "double register detected");
 191                        return -EEXIST;
 192                }
 193
 194                if (nb->priority > p->priority)
 195                        break;
 196        }
 197
 198        list_add_tail_rcu(&nb->node, h);
 199        return 0;
 200}
 201
 202/**
 203 * ssam_nfblk_find() - Check if a notifier block is registered on the given
 204 * notifier head.
 205 * list.
 206 * @nh: The notifier head on which to search.
 207 * @nb: The notifier block to search for.
 208 *
 209 * Note: This function must be synchronized by the caller with respect to other
 210 * insert, find, and/or remove calls by holding ``struct ssam_nf.lock``.
 211 *
 212 * Return: Returns true if the given notifier block is registered on the given
 213 * notifier head, false otherwise.
 214 */
 215static bool ssam_nfblk_find(struct ssam_nf_head *nh, struct ssam_notifier_block *nb)
 216{
 217        struct ssam_notifier_block *p;
 218
 219        /* Runs under lock, no need for RCU variant. */
 220        list_for_each_entry(p, &nh->head, node) {
 221                if (p == nb)
 222                        return true;
 223        }
 224
 225        return false;
 226}
 227
 228/**
 229 * ssam_nfblk_remove() - Remove a notifier block from its notifier list.
 230 * @nb: The notifier block to be removed.
 231 *
 232 * Note: This function must be synchronized by the caller with respect to
 233 * other insert, find, and/or remove calls by holding ``struct ssam_nf.lock``.
 234 * Furthermore, the caller _must_ ensure SRCU synchronization by calling
 235 * synchronize_srcu() with ``nh->srcu`` after leaving the critical section, to
 236 * ensure that the removed notifier block is not in use any more.
 237 */
 238static void ssam_nfblk_remove(struct ssam_notifier_block *nb)
 239{
 240        list_del_rcu(&nb->node);
 241}
 242
 243/**
 244 * ssam_nf_head_init() - Initialize the given notifier head.
 245 * @nh: The notifier head to initialize.
 246 */
 247static int ssam_nf_head_init(struct ssam_nf_head *nh)
 248{
 249        int status;
 250
 251        status = init_srcu_struct(&nh->srcu);
 252        if (status)
 253                return status;
 254
 255        INIT_LIST_HEAD(&nh->head);
 256        return 0;
 257}
 258
 259/**
 260 * ssam_nf_head_destroy() - Deinitialize the given notifier head.
 261 * @nh: The notifier head to deinitialize.
 262 */
 263static void ssam_nf_head_destroy(struct ssam_nf_head *nh)
 264{
 265        cleanup_srcu_struct(&nh->srcu);
 266}
 267
 268
 269/* -- Event/notification registry. ------------------------------------------ */
 270
 271/**
 272 * struct ssam_nf_refcount_key - Key used for event activation reference
 273 * counting.
 274 * @reg: The registry via which the event is enabled/disabled.
 275 * @id:  The ID uniquely describing the event.
 276 */
 277struct ssam_nf_refcount_key {
 278        struct ssam_event_registry reg;
 279        struct ssam_event_id id;
 280};
 281
 282/**
 283 * struct ssam_nf_refcount_entry - RB-tree entry for reference counting event
 284 * activations.
 285 * @node:     The node of this entry in the rb-tree.
 286 * @key:      The key of the event.
 287 * @refcount: The reference-count of the event.
 288 * @flags:    The flags used when enabling the event.
 289 */
 290struct ssam_nf_refcount_entry {
 291        struct rb_node node;
 292        struct ssam_nf_refcount_key key;
 293        int refcount;
 294        u8 flags;
 295};
 296
 297/**
 298 * ssam_nf_refcount_inc() - Increment reference-/activation-count of the given
 299 * event.
 300 * @nf:  The notifier system reference.
 301 * @reg: The registry used to enable/disable the event.
 302 * @id:  The event ID.
 303 *
 304 * Increments the reference-/activation-count associated with the specified
 305 * event type/ID, allocating a new entry for this event ID if necessary. A
 306 * newly allocated entry will have a refcount of one.
 307 *
 308 * Note: ``nf->lock`` must be held when calling this function.
 309 *
 310 * Return: Returns the refcount entry on success. Returns an error pointer
 311 * with %-ENOSPC if there have already been %INT_MAX events of the specified
 312 * ID and type registered, or %-ENOMEM if the entry could not be allocated.
 313 */
 314static struct ssam_nf_refcount_entry *
 315ssam_nf_refcount_inc(struct ssam_nf *nf, struct ssam_event_registry reg,
 316                     struct ssam_event_id id)
 317{
 318        struct ssam_nf_refcount_entry *entry;
 319        struct ssam_nf_refcount_key key;
 320        struct rb_node **link = &nf->refcount.rb_node;
 321        struct rb_node *parent = NULL;
 322        int cmp;
 323
 324        lockdep_assert_held(&nf->lock);
 325
 326        key.reg = reg;
 327        key.id = id;
 328
 329        while (*link) {
 330                entry = rb_entry(*link, struct ssam_nf_refcount_entry, node);
 331                parent = *link;
 332
 333                cmp = memcmp(&key, &entry->key, sizeof(key));
 334                if (cmp < 0) {
 335                        link = &(*link)->rb_left;
 336                } else if (cmp > 0) {
 337                        link = &(*link)->rb_right;
 338                } else if (entry->refcount < INT_MAX) {
 339                        entry->refcount++;
 340                        return entry;
 341                } else {
 342                        WARN_ON(1);
 343                        return ERR_PTR(-ENOSPC);
 344                }
 345        }
 346
 347        entry = kzalloc(sizeof(*entry), GFP_KERNEL);
 348        if (!entry)
 349                return ERR_PTR(-ENOMEM);
 350
 351        entry->key = key;
 352        entry->refcount = 1;
 353
 354        rb_link_node(&entry->node, parent, link);
 355        rb_insert_color(&entry->node, &nf->refcount);
 356
 357        return entry;
 358}
 359
 360/**
 361 * ssam_nf_refcount_dec() - Decrement reference-/activation-count of the given
 362 * event.
 363 * @nf:  The notifier system reference.
 364 * @reg: The registry used to enable/disable the event.
 365 * @id:  The event ID.
 366 *
 367 * Decrements the reference-/activation-count of the specified event,
 368 * returning its entry. If the returned entry has a refcount of zero, the
 369 * caller is responsible for freeing it using kfree().
 370 *
 371 * Note: ``nf->lock`` must be held when calling this function.
 372 *
 373 * Return: Returns the refcount entry on success or %NULL if the entry has not
 374 * been found.
 375 */
 376static struct ssam_nf_refcount_entry *
 377ssam_nf_refcount_dec(struct ssam_nf *nf, struct ssam_event_registry reg,
 378                     struct ssam_event_id id)
 379{
 380        struct ssam_nf_refcount_entry *entry;
 381        struct ssam_nf_refcount_key key;
 382        struct rb_node *node = nf->refcount.rb_node;
 383        int cmp;
 384
 385        lockdep_assert_held(&nf->lock);
 386
 387        key.reg = reg;
 388        key.id = id;
 389
 390        while (node) {
 391                entry = rb_entry(node, struct ssam_nf_refcount_entry, node);
 392
 393                cmp = memcmp(&key, &entry->key, sizeof(key));
 394                if (cmp < 0) {
 395                        node = node->rb_left;
 396                } else if (cmp > 0) {
 397                        node = node->rb_right;
 398                } else {
 399                        entry->refcount--;
 400                        if (entry->refcount == 0)
 401                                rb_erase(&entry->node, &nf->refcount);
 402
 403                        return entry;
 404                }
 405        }
 406
 407        return NULL;
 408}
 409
 410/**
 411 * ssam_nf_refcount_dec_free() - Decrement reference-/activation-count of the
 412 * given event and free its entry if the reference count reaches zero.
 413 * @nf:  The notifier system reference.
 414 * @reg: The registry used to enable/disable the event.
 415 * @id:  The event ID.
 416 *
 417 * Decrements the reference-/activation-count of the specified event, freeing
 418 * its entry if it reaches zero.
 419 *
 420 * Note: ``nf->lock`` must be held when calling this function.
 421 */
 422static void ssam_nf_refcount_dec_free(struct ssam_nf *nf,
 423                                      struct ssam_event_registry reg,
 424                                      struct ssam_event_id id)
 425{
 426        struct ssam_nf_refcount_entry *entry;
 427
 428        lockdep_assert_held(&nf->lock);
 429
 430        entry = ssam_nf_refcount_dec(nf, reg, id);
 431        if (entry && entry->refcount == 0)
 432                kfree(entry);
 433}
 434
 435/**
 436 * ssam_nf_refcount_empty() - Test if the notification system has any
 437 * enabled/active events.
 438 * @nf: The notification system.
 439 */
 440static bool ssam_nf_refcount_empty(struct ssam_nf *nf)
 441{
 442        return RB_EMPTY_ROOT(&nf->refcount);
 443}
 444
 445/**
 446 * ssam_nf_call() - Call notification callbacks for the provided event.
 447 * @nf:    The notifier system
 448 * @dev:   The associated device, only used for logging.
 449 * @rqid:  The request ID of the event.
 450 * @event: The event provided to the callbacks.
 451 *
 452 * Execute registered callbacks in order of their priority until either no
 453 * callback is left or a callback returns a value with the %SSAM_NOTIF_STOP
 454 * bit set. Note that this bit is set automatically when converting non-zero
 455 * error values via ssam_notifier_from_errno() to notifier values.
 456 *
 457 * Also note that any callback that could handle an event should return a value
 458 * with bit %SSAM_NOTIF_HANDLED set, indicating that the event does not go
 459 * unhandled/ignored. In case no registered callback could handle an event,
 460 * this function will emit a warning.
 461 *
 462 * In case a callback failed, this function will emit an error message.
 463 */
 464static void ssam_nf_call(struct ssam_nf *nf, struct device *dev, u16 rqid,
 465                         struct ssam_event *event)
 466{
 467        struct ssam_nf_head *nf_head;
 468        int status, nf_ret;
 469
 470        if (!ssh_rqid_is_event(rqid)) {
 471                dev_warn(dev, "event: unsupported rqid: %#06x\n", rqid);
 472                return;
 473        }
 474
 475        nf_head = &nf->head[ssh_rqid_to_event(rqid)];
 476        nf_ret = ssam_nfblk_call_chain(nf_head, event);
 477        status = ssam_notifier_to_errno(nf_ret);
 478
 479        if (status < 0) {
 480                dev_err(dev,
 481                        "event: error handling event: %d (tc: %#04x, tid: %#04x, cid: %#04x, iid: %#04x)\n",
 482                        status, event->target_category, event->target_id,
 483                        event->command_id, event->instance_id);
 484        } else if (!(nf_ret & SSAM_NOTIF_HANDLED)) {
 485                dev_warn(dev,
 486                         "event: unhandled event (rqid: %#04x, tc: %#04x, tid: %#04x, cid: %#04x, iid: %#04x)\n",
 487                         rqid, event->target_category, event->target_id,
 488                         event->command_id, event->instance_id);
 489        }
 490}
 491
 492/**
 493 * ssam_nf_init() - Initialize the notifier system.
 494 * @nf: The notifier system to initialize.
 495 */
 496static int ssam_nf_init(struct ssam_nf *nf)
 497{
 498        int i, status;
 499
 500        for (i = 0; i < SSH_NUM_EVENTS; i++) {
 501                status = ssam_nf_head_init(&nf->head[i]);
 502                if (status)
 503                        break;
 504        }
 505
 506        if (status) {
 507                while (i--)
 508                        ssam_nf_head_destroy(&nf->head[i]);
 509
 510                return status;
 511        }
 512
 513        mutex_init(&nf->lock);
 514        return 0;
 515}
 516
 517/**
 518 * ssam_nf_destroy() - Deinitialize the notifier system.
 519 * @nf: The notifier system to deinitialize.
 520 */
 521static void ssam_nf_destroy(struct ssam_nf *nf)
 522{
 523        int i;
 524
 525        for (i = 0; i < SSH_NUM_EVENTS; i++)
 526                ssam_nf_head_destroy(&nf->head[i]);
 527
 528        mutex_destroy(&nf->lock);
 529}
 530
 531
 532/* -- Event/async request completion system. -------------------------------- */
 533
 534#define SSAM_CPLT_WQ_NAME       "ssam_cpltq"
 535
 536/*
 537 * SSAM_CPLT_WQ_BATCH - Maximum number of event item completions executed per
 538 * work execution. Used to prevent livelocking of the workqueue. Value chosen
 539 * via educated guess, may be adjusted.
 540 */
 541#define SSAM_CPLT_WQ_BATCH      10
 542
 543/*
 544 * SSAM_EVENT_ITEM_CACHE_PAYLOAD_LEN - Maximum payload length for a cached
 545 * &struct ssam_event_item.
 546 *
 547 * This length has been chosen to be accommodate standard touchpad and
 548 * keyboard input events. Events with larger payloads will be allocated
 549 * separately.
 550 */
 551#define SSAM_EVENT_ITEM_CACHE_PAYLOAD_LEN       32
 552
 553static struct kmem_cache *ssam_event_item_cache;
 554
 555/**
 556 * ssam_event_item_cache_init() - Initialize the event item cache.
 557 */
 558int ssam_event_item_cache_init(void)
 559{
 560        const unsigned int size = sizeof(struct ssam_event_item)
 561                                  + SSAM_EVENT_ITEM_CACHE_PAYLOAD_LEN;
 562        const unsigned int align = __alignof__(struct ssam_event_item);
 563        struct kmem_cache *cache;
 564
 565        cache = kmem_cache_create("ssam_event_item", size, align, 0, NULL);
 566        if (!cache)
 567                return -ENOMEM;
 568
 569        ssam_event_item_cache = cache;
 570        return 0;
 571}
 572
 573/**
 574 * ssam_event_item_cache_destroy() - Deinitialize the event item cache.
 575 */
 576void ssam_event_item_cache_destroy(void)
 577{
 578        kmem_cache_destroy(ssam_event_item_cache);
 579        ssam_event_item_cache = NULL;
 580}
 581
 582static void __ssam_event_item_free_cached(struct ssam_event_item *item)
 583{
 584        kmem_cache_free(ssam_event_item_cache, item);
 585}
 586
 587static void __ssam_event_item_free_generic(struct ssam_event_item *item)
 588{
 589        kfree(item);
 590}
 591
 592/**
 593 * ssam_event_item_free() - Free the provided event item.
 594 * @item: The event item to free.
 595 */
 596static void ssam_event_item_free(struct ssam_event_item *item)
 597{
 598        trace_ssam_event_item_free(item);
 599        item->ops.free(item);
 600}
 601
 602/**
 603 * ssam_event_item_alloc() - Allocate an event item with the given payload size.
 604 * @len:   The event payload length.
 605 * @flags: The flags used for allocation.
 606 *
 607 * Allocate an event item with the given payload size, preferring allocation
 608 * from the event item cache if the payload is small enough (i.e. smaller than
 609 * %SSAM_EVENT_ITEM_CACHE_PAYLOAD_LEN). Sets the item operations and payload
 610 * length values. The item free callback (``ops.free``) should not be
 611 * overwritten after this call.
 612 *
 613 * Return: Returns the newly allocated event item.
 614 */
 615static struct ssam_event_item *ssam_event_item_alloc(size_t len, gfp_t flags)
 616{
 617        struct ssam_event_item *item;
 618
 619        if (len <= SSAM_EVENT_ITEM_CACHE_PAYLOAD_LEN) {
 620                item = kmem_cache_alloc(ssam_event_item_cache, flags);
 621                if (!item)
 622                        return NULL;
 623
 624                item->ops.free = __ssam_event_item_free_cached;
 625        } else {
 626                item = kzalloc(struct_size(item, event.data, len), flags);
 627                if (!item)
 628                        return NULL;
 629
 630                item->ops.free = __ssam_event_item_free_generic;
 631        }
 632
 633        item->event.length = len;
 634
 635        trace_ssam_event_item_alloc(item, len);
 636        return item;
 637}
 638
 639/**
 640 * ssam_event_queue_push() - Push an event item to the event queue.
 641 * @q:    The event queue.
 642 * @item: The item to add.
 643 */
 644static void ssam_event_queue_push(struct ssam_event_queue *q,
 645                                  struct ssam_event_item *item)
 646{
 647        spin_lock(&q->lock);
 648        list_add_tail(&item->node, &q->head);
 649        spin_unlock(&q->lock);
 650}
 651
 652/**
 653 * ssam_event_queue_pop() - Pop the next event item from the event queue.
 654 * @q: The event queue.
 655 *
 656 * Returns and removes the next event item from the queue. Returns %NULL If
 657 * there is no event item left.
 658 */
 659static struct ssam_event_item *ssam_event_queue_pop(struct ssam_event_queue *q)
 660{
 661        struct ssam_event_item *item;
 662
 663        spin_lock(&q->lock);
 664        item = list_first_entry_or_null(&q->head, struct ssam_event_item, node);
 665        if (item)
 666                list_del(&item->node);
 667        spin_unlock(&q->lock);
 668
 669        return item;
 670}
 671
 672/**
 673 * ssam_event_queue_is_empty() - Check if the event queue is empty.
 674 * @q: The event queue.
 675 */
 676static bool ssam_event_queue_is_empty(struct ssam_event_queue *q)
 677{
 678        bool empty;
 679
 680        spin_lock(&q->lock);
 681        empty = list_empty(&q->head);
 682        spin_unlock(&q->lock);
 683
 684        return empty;
 685}
 686
 687/**
 688 * ssam_cplt_get_event_queue() - Get the event queue for the given parameters.
 689 * @cplt: The completion system on which to look for the queue.
 690 * @tid:  The target ID of the queue.
 691 * @rqid: The request ID representing the event ID for which to get the queue.
 692 *
 693 * Return: Returns the event queue corresponding to the event type described
 694 * by the given parameters. If the request ID does not represent an event,
 695 * this function returns %NULL. If the target ID is not supported, this
 696 * function will fall back to the default target ID (``tid = 1``).
 697 */
 698static
 699struct ssam_event_queue *ssam_cplt_get_event_queue(struct ssam_cplt *cplt,
 700                                                   u8 tid, u16 rqid)
 701{
 702        u16 event = ssh_rqid_to_event(rqid);
 703        u16 tidx = ssh_tid_to_index(tid);
 704
 705        if (!ssh_rqid_is_event(rqid)) {
 706                dev_err(cplt->dev, "event: unsupported request ID: %#06x\n", rqid);
 707                return NULL;
 708        }
 709
 710        if (!ssh_tid_is_valid(tid)) {
 711                dev_warn(cplt->dev, "event: unsupported target ID: %u\n", tid);
 712                tidx = 0;
 713        }
 714
 715        return &cplt->event.target[tidx].queue[event];
 716}
 717
 718/**
 719 * ssam_cplt_submit() - Submit a work item to the completion system workqueue.
 720 * @cplt: The completion system.
 721 * @work: The work item to submit.
 722 */
 723static bool ssam_cplt_submit(struct ssam_cplt *cplt, struct work_struct *work)
 724{
 725        return queue_work(cplt->wq, work);
 726}
 727
 728/**
 729 * ssam_cplt_submit_event() - Submit an event to the completion system.
 730 * @cplt: The completion system.
 731 * @item: The event item to submit.
 732 *
 733 * Submits the event to the completion system by queuing it on the event item
 734 * queue and queuing the respective event queue work item on the completion
 735 * workqueue, which will eventually complete the event.
 736 *
 737 * Return: Returns zero on success, %-EINVAL if there is no event queue that
 738 * can handle the given event item.
 739 */
 740static int ssam_cplt_submit_event(struct ssam_cplt *cplt,
 741                                  struct ssam_event_item *item)
 742{
 743        struct ssam_event_queue *evq;
 744
 745        evq = ssam_cplt_get_event_queue(cplt, item->event.target_id, item->rqid);
 746        if (!evq)
 747                return -EINVAL;
 748
 749        ssam_event_queue_push(evq, item);
 750        ssam_cplt_submit(cplt, &evq->work);
 751        return 0;
 752}
 753
 754/**
 755 * ssam_cplt_flush() - Flush the completion system.
 756 * @cplt: The completion system.
 757 *
 758 * Flush the completion system by waiting until all currently submitted work
 759 * items have been completed.
 760 *
 761 * Note: This function does not guarantee that all events will have been
 762 * handled once this call terminates. In case of a larger number of
 763 * to-be-completed events, the event queue work function may re-schedule its
 764 * work item, which this flush operation will ignore.
 765 *
 766 * This operation is only intended to, during normal operation prior to
 767 * shutdown, try to complete most events and requests to get them out of the
 768 * system while the system is still fully operational. It does not aim to
 769 * provide any guarantee that all of them have been handled.
 770 */
 771static void ssam_cplt_flush(struct ssam_cplt *cplt)
 772{
 773        flush_workqueue(cplt->wq);
 774}
 775
 776static void ssam_event_queue_work_fn(struct work_struct *work)
 777{
 778        struct ssam_event_queue *queue;
 779        struct ssam_event_item *item;
 780        struct ssam_nf *nf;
 781        struct device *dev;
 782        unsigned int iterations = SSAM_CPLT_WQ_BATCH;
 783
 784        queue = container_of(work, struct ssam_event_queue, work);
 785        nf = &queue->cplt->event.notif;
 786        dev = queue->cplt->dev;
 787
 788        /* Limit number of processed events to avoid livelocking. */
 789        do {
 790                item = ssam_event_queue_pop(queue);
 791                if (!item)
 792                        return;
 793
 794                ssam_nf_call(nf, dev, item->rqid, &item->event);
 795                ssam_event_item_free(item);
 796        } while (--iterations);
 797
 798        if (!ssam_event_queue_is_empty(queue))
 799                ssam_cplt_submit(queue->cplt, &queue->work);
 800}
 801
 802/**
 803 * ssam_event_queue_init() - Initialize an event queue.
 804 * @cplt: The completion system on which the queue resides.
 805 * @evq:  The event queue to initialize.
 806 */
 807static void ssam_event_queue_init(struct ssam_cplt *cplt,
 808                                  struct ssam_event_queue *evq)
 809{
 810        evq->cplt = cplt;
 811        spin_lock_init(&evq->lock);
 812        INIT_LIST_HEAD(&evq->head);
 813        INIT_WORK(&evq->work, ssam_event_queue_work_fn);
 814}
 815
 816/**
 817 * ssam_cplt_init() - Initialize completion system.
 818 * @cplt: The completion system to initialize.
 819 * @dev:  The device used for logging.
 820 */
 821static int ssam_cplt_init(struct ssam_cplt *cplt, struct device *dev)
 822{
 823        struct ssam_event_target *target;
 824        int status, c, i;
 825
 826        cplt->dev = dev;
 827
 828        cplt->wq = create_workqueue(SSAM_CPLT_WQ_NAME);
 829        if (!cplt->wq)
 830                return -ENOMEM;
 831
 832        for (c = 0; c < ARRAY_SIZE(cplt->event.target); c++) {
 833                target = &cplt->event.target[c];
 834
 835                for (i = 0; i < ARRAY_SIZE(target->queue); i++)
 836                        ssam_event_queue_init(cplt, &target->queue[i]);
 837        }
 838
 839        status = ssam_nf_init(&cplt->event.notif);
 840        if (status)
 841                destroy_workqueue(cplt->wq);
 842
 843        return status;
 844}
 845
 846/**
 847 * ssam_cplt_destroy() - Deinitialize the completion system.
 848 * @cplt: The completion system to deinitialize.
 849 *
 850 * Deinitialize the given completion system and ensure that all pending, i.e.
 851 * yet-to-be-completed, event items and requests have been handled.
 852 */
 853static void ssam_cplt_destroy(struct ssam_cplt *cplt)
 854{
 855        /*
 856         * Note: destroy_workqueue ensures that all currently queued work will
 857         * be fully completed and the workqueue drained. This means that this
 858         * call will inherently also free any queued ssam_event_items, thus we
 859         * don't have to take care of that here explicitly.
 860         */
 861        destroy_workqueue(cplt->wq);
 862        ssam_nf_destroy(&cplt->event.notif);
 863}
 864
 865
 866/* -- Main SSAM device structures. ------------------------------------------ */
 867
 868/**
 869 * ssam_controller_device() - Get the &struct device associated with this
 870 * controller.
 871 * @c: The controller for which to get the device.
 872 *
 873 * Return: Returns the &struct device associated with this controller,
 874 * providing its lower-level transport.
 875 */
 876struct device *ssam_controller_device(struct ssam_controller *c)
 877{
 878        return ssh_rtl_get_device(&c->rtl);
 879}
 880EXPORT_SYMBOL_GPL(ssam_controller_device);
 881
 882static void __ssam_controller_release(struct kref *kref)
 883{
 884        struct ssam_controller *ctrl = to_ssam_controller(kref, kref);
 885
 886        /*
 887         * The lock-call here is to satisfy lockdep. At this point we really
 888         * expect this to be the last remaining reference to the controller.
 889         * Anything else is a bug.
 890         */
 891        ssam_controller_lock(ctrl);
 892        ssam_controller_destroy(ctrl);
 893        ssam_controller_unlock(ctrl);
 894
 895        kfree(ctrl);
 896}
 897
 898/**
 899 * ssam_controller_get() - Increment reference count of controller.
 900 * @c: The controller.
 901 *
 902 * Return: Returns the controller provided as input.
 903 */
 904struct ssam_controller *ssam_controller_get(struct ssam_controller *c)
 905{
 906        if (c)
 907                kref_get(&c->kref);
 908        return c;
 909}
 910EXPORT_SYMBOL_GPL(ssam_controller_get);
 911
 912/**
 913 * ssam_controller_put() - Decrement reference count of controller.
 914 * @c: The controller.
 915 */
 916void ssam_controller_put(struct ssam_controller *c)
 917{
 918        if (c)
 919                kref_put(&c->kref, __ssam_controller_release);
 920}
 921EXPORT_SYMBOL_GPL(ssam_controller_put);
 922
 923/**
 924 * ssam_controller_statelock() - Lock the controller against state transitions.
 925 * @c: The controller to lock.
 926 *
 927 * Lock the controller against state transitions. Holding this lock guarantees
 928 * that the controller will not transition between states, i.e. if the
 929 * controller is in state "started", when this lock has been acquired, it will
 930 * remain in this state at least until the lock has been released.
 931 *
 932 * Multiple clients may concurrently hold this lock. In other words: The
 933 * ``statelock`` functions represent the read-lock part of a r/w-semaphore.
 934 * Actions causing state transitions of the controller must be executed while
 935 * holding the write-part of this r/w-semaphore (see ssam_controller_lock()
 936 * and ssam_controller_unlock() for that).
 937 *
 938 * See ssam_controller_stateunlock() for the corresponding unlock function.
 939 */
 940void ssam_controller_statelock(struct ssam_controller *c)
 941{
 942        down_read(&c->lock);
 943}
 944EXPORT_SYMBOL_GPL(ssam_controller_statelock);
 945
 946/**
 947 * ssam_controller_stateunlock() - Unlock controller state transitions.
 948 * @c: The controller to unlock.
 949 *
 950 * See ssam_controller_statelock() for the corresponding lock function.
 951 */
 952void ssam_controller_stateunlock(struct ssam_controller *c)
 953{
 954        up_read(&c->lock);
 955}
 956EXPORT_SYMBOL_GPL(ssam_controller_stateunlock);
 957
 958/**
 959 * ssam_controller_lock() - Acquire the main controller lock.
 960 * @c: The controller to lock.
 961 *
 962 * This lock must be held for any state transitions, including transition to
 963 * suspend/resumed states and during shutdown. See ssam_controller_statelock()
 964 * for more details on controller locking.
 965 *
 966 * See ssam_controller_unlock() for the corresponding unlock function.
 967 */
 968void ssam_controller_lock(struct ssam_controller *c)
 969{
 970        down_write(&c->lock);
 971}
 972
 973/*
 974 * ssam_controller_unlock() - Release the main controller lock.
 975 * @c: The controller to unlock.
 976 *
 977 * See ssam_controller_lock() for the corresponding lock function.
 978 */
 979void ssam_controller_unlock(struct ssam_controller *c)
 980{
 981        up_write(&c->lock);
 982}
 983
 984static void ssam_handle_event(struct ssh_rtl *rtl,
 985                              const struct ssh_command *cmd,
 986                              const struct ssam_span *data)
 987{
 988        struct ssam_controller *ctrl = to_ssam_controller(rtl, rtl);
 989        struct ssam_event_item *item;
 990
 991        item = ssam_event_item_alloc(data->len, GFP_KERNEL);
 992        if (!item)
 993                return;
 994
 995        item->rqid = get_unaligned_le16(&cmd->rqid);
 996        item->event.target_category = cmd->tc;
 997        item->event.target_id = cmd->tid_in;
 998        item->event.command_id = cmd->cid;
 999        item->event.instance_id = cmd->iid;
1000        memcpy(&item->event.data[0], data->ptr, data->len);
1001
1002        if (WARN_ON(ssam_cplt_submit_event(&ctrl->cplt, item)))
1003                ssam_event_item_free(item);
1004}
1005
1006static const struct ssh_rtl_ops ssam_rtl_ops = {
1007        .handle_event = ssam_handle_event,
1008};
1009
1010static bool ssam_notifier_is_empty(struct ssam_controller *ctrl);
1011static void ssam_notifier_unregister_all(struct ssam_controller *ctrl);
1012
1013#define SSAM_SSH_DSM_REVISION   0
1014
1015/* d5e383e1-d892-4a76-89fc-f6aaae7ed5b5 */
1016static const guid_t SSAM_SSH_DSM_GUID =
1017        GUID_INIT(0xd5e383e1, 0xd892, 0x4a76,
1018                  0x89, 0xfc, 0xf6, 0xaa, 0xae, 0x7e, 0xd5, 0xb5);
1019
1020enum ssh_dsm_fn {
1021        SSH_DSM_FN_SSH_POWER_PROFILE             = 0x05,
1022        SSH_DSM_FN_SCREEN_ON_SLEEP_IDLE_TIMEOUT  = 0x06,
1023        SSH_DSM_FN_SCREEN_OFF_SLEEP_IDLE_TIMEOUT = 0x07,
1024        SSH_DSM_FN_D3_CLOSES_HANDLE              = 0x08,
1025        SSH_DSM_FN_SSH_BUFFER_SIZE               = 0x09,
1026};
1027
1028static int ssam_dsm_get_functions(acpi_handle handle, u64 *funcs)
1029{
1030        union acpi_object *obj;
1031        u64 mask = 0;
1032        int i;
1033
1034        *funcs = 0;
1035
1036        /*
1037         * The _DSM function is only present on newer models. It is not
1038         * present on 5th and 6th generation devices (i.e. up to and including
1039         * Surface Pro 6, Surface Laptop 2, Surface Book 2).
1040         *
1041         * If the _DSM is not present, indicate that no function is supported.
1042         * This will result in default values being set.
1043         */
1044        if (!acpi_has_method(handle, "_DSM"))
1045                return 0;
1046
1047        obj = acpi_evaluate_dsm_typed(handle, &SSAM_SSH_DSM_GUID,
1048                                      SSAM_SSH_DSM_REVISION, 0, NULL,
1049                                      ACPI_TYPE_BUFFER);
1050        if (!obj)
1051                return -EIO;
1052
1053        for (i = 0; i < obj->buffer.length && i < 8; i++)
1054                mask |= (((u64)obj->buffer.pointer[i]) << (i * 8));
1055
1056        if (mask & BIT(0))
1057                *funcs = mask;
1058
1059        ACPI_FREE(obj);
1060        return 0;
1061}
1062
1063static int ssam_dsm_load_u32(acpi_handle handle, u64 funcs, u64 func, u32 *ret)
1064{
1065        union acpi_object *obj;
1066        u64 val;
1067
1068        if (!(funcs & BIT_ULL(func)))
1069                return 0; /* Not supported, leave *ret at its default value */
1070
1071        obj = acpi_evaluate_dsm_typed(handle, &SSAM_SSH_DSM_GUID,
1072                                      SSAM_SSH_DSM_REVISION, func, NULL,
1073                                      ACPI_TYPE_INTEGER);
1074        if (!obj)
1075                return -EIO;
1076
1077        val = obj->integer.value;
1078        ACPI_FREE(obj);
1079
1080        if (val > U32_MAX)
1081                return -ERANGE;
1082
1083        *ret = val;
1084        return 0;
1085}
1086
1087/**
1088 * ssam_controller_caps_load_from_acpi() - Load controller capabilities from
1089 * ACPI _DSM.
1090 * @handle: The handle of the ACPI controller/SSH device.
1091 * @caps:   Where to store the capabilities in.
1092 *
1093 * Initializes the given controller capabilities with default values, then
1094 * checks and, if the respective _DSM functions are available, loads the
1095 * actual capabilities from the _DSM.
1096 *
1097 * Return: Returns zero on success, a negative error code on failure.
1098 */
1099static
1100int ssam_controller_caps_load_from_acpi(acpi_handle handle,
1101                                        struct ssam_controller_caps *caps)
1102{
1103        u32 d3_closes_handle = false;
1104        u64 funcs;
1105        int status;
1106
1107        /* Set defaults. */
1108        caps->ssh_power_profile = U32_MAX;
1109        caps->screen_on_sleep_idle_timeout = U32_MAX;
1110        caps->screen_off_sleep_idle_timeout = U32_MAX;
1111        caps->d3_closes_handle = false;
1112        caps->ssh_buffer_size = U32_MAX;
1113
1114        /* Pre-load supported DSM functions. */
1115        status = ssam_dsm_get_functions(handle, &funcs);
1116        if (status)
1117                return status;
1118
1119        /* Load actual values from ACPI, if present. */
1120        status = ssam_dsm_load_u32(handle, funcs, SSH_DSM_FN_SSH_POWER_PROFILE,
1121                                   &caps->ssh_power_profile);
1122        if (status)
1123                return status;
1124
1125        status = ssam_dsm_load_u32(handle, funcs,
1126                                   SSH_DSM_FN_SCREEN_ON_SLEEP_IDLE_TIMEOUT,
1127                                   &caps->screen_on_sleep_idle_timeout);
1128        if (status)
1129                return status;
1130
1131        status = ssam_dsm_load_u32(handle, funcs,
1132                                   SSH_DSM_FN_SCREEN_OFF_SLEEP_IDLE_TIMEOUT,
1133                                   &caps->screen_off_sleep_idle_timeout);
1134        if (status)
1135                return status;
1136
1137        status = ssam_dsm_load_u32(handle, funcs, SSH_DSM_FN_D3_CLOSES_HANDLE,
1138                                   &d3_closes_handle);
1139        if (status)
1140                return status;
1141
1142        caps->d3_closes_handle = !!d3_closes_handle;
1143
1144        status = ssam_dsm_load_u32(handle, funcs, SSH_DSM_FN_SSH_BUFFER_SIZE,
1145                                   &caps->ssh_buffer_size);
1146        if (status)
1147                return status;
1148
1149        return 0;
1150}
1151
1152/**
1153 * ssam_controller_init() - Initialize SSAM controller.
1154 * @ctrl:   The controller to initialize.
1155 * @serdev: The serial device representing the underlying data transport.
1156 *
1157 * Initializes the given controller. Does neither start receiver nor
1158 * transmitter threads. After this call, the controller has to be hooked up to
1159 * the serdev core separately via &struct serdev_device_ops, relaying calls to
1160 * ssam_controller_receive_buf() and ssam_controller_write_wakeup(). Once the
1161 * controller has been hooked up, transmitter and receiver threads may be
1162 * started via ssam_controller_start(). These setup steps need to be completed
1163 * before controller can be used for requests.
1164 */
1165int ssam_controller_init(struct ssam_controller *ctrl,
1166                         struct serdev_device *serdev)
1167{
1168        acpi_handle handle = ACPI_HANDLE(&serdev->dev);
1169        int status;
1170
1171        init_rwsem(&ctrl->lock);
1172        kref_init(&ctrl->kref);
1173
1174        status = ssam_controller_caps_load_from_acpi(handle, &ctrl->caps);
1175        if (status)
1176                return status;
1177
1178        dev_dbg(&serdev->dev,
1179                "device capabilities:\n"
1180                "  ssh_power_profile:             %u\n"
1181                "  ssh_buffer_size:               %u\n"
1182                "  screen_on_sleep_idle_timeout:  %u\n"
1183                "  screen_off_sleep_idle_timeout: %u\n"
1184                "  d3_closes_handle:              %u\n",
1185                ctrl->caps.ssh_power_profile,
1186                ctrl->caps.ssh_buffer_size,
1187                ctrl->caps.screen_on_sleep_idle_timeout,
1188                ctrl->caps.screen_off_sleep_idle_timeout,
1189                ctrl->caps.d3_closes_handle);
1190
1191        ssh_seq_reset(&ctrl->counter.seq);
1192        ssh_rqid_reset(&ctrl->counter.rqid);
1193
1194        /* Initialize event/request completion system. */
1195        status = ssam_cplt_init(&ctrl->cplt, &serdev->dev);
1196        if (status)
1197                return status;
1198
1199        /* Initialize request and packet transport layers. */
1200        status = ssh_rtl_init(&ctrl->rtl, serdev, &ssam_rtl_ops);
1201        if (status) {
1202                ssam_cplt_destroy(&ctrl->cplt);
1203                return status;
1204        }
1205
1206        /*
1207         * Set state via write_once even though we expect to be in an
1208         * exclusive context, due to smoke-testing in
1209         * ssam_request_sync_submit().
1210         */
1211        WRITE_ONCE(ctrl->state, SSAM_CONTROLLER_INITIALIZED);
1212        return 0;
1213}
1214
1215/**
1216 * ssam_controller_start() - Start the receiver and transmitter threads of the
1217 * controller.
1218 * @ctrl: The controller.
1219 *
1220 * Note: When this function is called, the controller should be properly
1221 * hooked up to the serdev core via &struct serdev_device_ops. Please refer
1222 * to ssam_controller_init() for more details on controller initialization.
1223 *
1224 * This function must be called with the main controller lock held (i.e. by
1225 * calling ssam_controller_lock()).
1226 */
1227int ssam_controller_start(struct ssam_controller *ctrl)
1228{
1229        int status;
1230
1231        lockdep_assert_held_write(&ctrl->lock);
1232
1233        if (ctrl->state != SSAM_CONTROLLER_INITIALIZED)
1234                return -EINVAL;
1235
1236        status = ssh_rtl_start(&ctrl->rtl);
1237        if (status)
1238                return status;
1239
1240        /*
1241         * Set state via write_once even though we expect to be locked/in an
1242         * exclusive context, due to smoke-testing in
1243         * ssam_request_sync_submit().
1244         */
1245        WRITE_ONCE(ctrl->state, SSAM_CONTROLLER_STARTED);
1246        return 0;
1247}
1248
1249/*
1250 * SSAM_CTRL_SHUTDOWN_FLUSH_TIMEOUT - Timeout for flushing requests during
1251 * shutdown.
1252 *
1253 * Chosen to be larger than one full request timeout, including packets timing
1254 * out. This value should give ample time to complete any outstanding requests
1255 * during normal operation and account for the odd package timeout.
1256 */
1257#define SSAM_CTRL_SHUTDOWN_FLUSH_TIMEOUT        msecs_to_jiffies(5000)
1258
1259/**
1260 * ssam_controller_shutdown() - Shut down the controller.
1261 * @ctrl: The controller.
1262 *
1263 * Shuts down the controller by flushing all pending requests and stopping the
1264 * transmitter and receiver threads. All requests submitted after this call
1265 * will fail with %-ESHUTDOWN. While it is discouraged to do so, this function
1266 * is safe to use in parallel with ongoing request submission.
1267 *
1268 * In the course of this shutdown procedure, all currently registered
1269 * notifiers will be unregistered. It is, however, strongly recommended to not
1270 * rely on this behavior, and instead the party registering the notifier
1271 * should unregister it before the controller gets shut down, e.g. via the
1272 * SSAM bus which guarantees client devices to be removed before a shutdown.
1273 *
1274 * Note that events may still be pending after this call, but, due to the
1275 * notifiers being unregistered, these events will be dropped when the
1276 * controller is subsequently destroyed via ssam_controller_destroy().
1277 *
1278 * This function must be called with the main controller lock held (i.e. by
1279 * calling ssam_controller_lock()).
1280 */
1281void ssam_controller_shutdown(struct ssam_controller *ctrl)
1282{
1283        enum ssam_controller_state s = ctrl->state;
1284        int status;
1285
1286        lockdep_assert_held_write(&ctrl->lock);
1287
1288        if (s == SSAM_CONTROLLER_UNINITIALIZED || s == SSAM_CONTROLLER_STOPPED)
1289                return;
1290
1291        /*
1292         * Try to flush pending events and requests while everything still
1293         * works. Note: There may still be packets and/or requests in the
1294         * system after this call (e.g. via control packets submitted by the
1295         * packet transport layer or flush timeout / failure, ...). Those will
1296         * be handled with the ssh_rtl_shutdown() call below.
1297         */
1298        status = ssh_rtl_flush(&ctrl->rtl, SSAM_CTRL_SHUTDOWN_FLUSH_TIMEOUT);
1299        if (status) {
1300                ssam_err(ctrl, "failed to flush request transport layer: %d\n",
1301                         status);
1302        }
1303
1304        /* Try to flush all currently completing requests and events. */
1305        ssam_cplt_flush(&ctrl->cplt);
1306
1307        /*
1308         * We expect all notifiers to have been removed by the respective client
1309         * driver that set them up at this point. If this warning occurs, some
1310         * client driver has not done that...
1311         */
1312        WARN_ON(!ssam_notifier_is_empty(ctrl));
1313
1314        /*
1315         * Nevertheless, we should still take care of drivers that don't behave
1316         * well. Thus disable all enabled events, unregister all notifiers.
1317         */
1318        ssam_notifier_unregister_all(ctrl);
1319
1320        /*
1321         * Cancel remaining requests. Ensure no new ones can be queued and stop
1322         * threads.
1323         */
1324        ssh_rtl_shutdown(&ctrl->rtl);
1325
1326        /*
1327         * Set state via write_once even though we expect to be locked/in an
1328         * exclusive context, due to smoke-testing in
1329         * ssam_request_sync_submit().
1330         */
1331        WRITE_ONCE(ctrl->state, SSAM_CONTROLLER_STOPPED);
1332        ctrl->rtl.ptl.serdev = NULL;
1333}
1334
1335/**
1336 * ssam_controller_destroy() - Destroy the controller and free its resources.
1337 * @ctrl: The controller.
1338 *
1339 * Ensures that all resources associated with the controller get freed. This
1340 * function should only be called after the controller has been stopped via
1341 * ssam_controller_shutdown(). In general, this function should not be called
1342 * directly. The only valid place to call this function directly is during
1343 * initialization, before the controller has been fully initialized and passed
1344 * to other processes. This function is called automatically when the
1345 * reference count of the controller reaches zero.
1346 *
1347 * This function must be called with the main controller lock held (i.e. by
1348 * calling ssam_controller_lock()).
1349 */
1350void ssam_controller_destroy(struct ssam_controller *ctrl)
1351{
1352        lockdep_assert_held_write(&ctrl->lock);
1353
1354        if (ctrl->state == SSAM_CONTROLLER_UNINITIALIZED)
1355                return;
1356
1357        WARN_ON(ctrl->state != SSAM_CONTROLLER_STOPPED);
1358
1359        /*
1360         * Note: New events could still have been received after the previous
1361         * flush in ssam_controller_shutdown, before the request transport layer
1362         * has been shut down. At this point, after the shutdown, we can be sure
1363         * that no new events will be queued. The call to ssam_cplt_destroy will
1364         * ensure that those remaining are being completed and freed.
1365         */
1366
1367        /* Actually free resources. */
1368        ssam_cplt_destroy(&ctrl->cplt);
1369        ssh_rtl_destroy(&ctrl->rtl);
1370
1371        /*
1372         * Set state via write_once even though we expect to be locked/in an
1373         * exclusive context, due to smoke-testing in
1374         * ssam_request_sync_submit().
1375         */
1376        WRITE_ONCE(ctrl->state, SSAM_CONTROLLER_UNINITIALIZED);
1377}
1378
1379/**
1380 * ssam_controller_suspend() - Suspend the controller.
1381 * @ctrl: The controller to suspend.
1382 *
1383 * Marks the controller as suspended. Note that display-off and D0-exit
1384 * notifications have to be sent manually before transitioning the controller
1385 * into the suspended state via this function.
1386 *
1387 * See ssam_controller_resume() for the corresponding resume function.
1388 *
1389 * Return: Returns %-EINVAL if the controller is currently not in the
1390 * "started" state.
1391 */
1392int ssam_controller_suspend(struct ssam_controller *ctrl)
1393{
1394        ssam_controller_lock(ctrl);
1395
1396        if (ctrl->state != SSAM_CONTROLLER_STARTED) {
1397                ssam_controller_unlock(ctrl);
1398                return -EINVAL;
1399        }
1400
1401        ssam_dbg(ctrl, "pm: suspending controller\n");
1402
1403        /*
1404         * Set state via write_once even though we're locked, due to
1405         * smoke-testing in ssam_request_sync_submit().
1406         */
1407        WRITE_ONCE(ctrl->state, SSAM_CONTROLLER_SUSPENDED);
1408
1409        ssam_controller_unlock(ctrl);
1410        return 0;
1411}
1412
1413/**
1414 * ssam_controller_resume() - Resume the controller from suspend.
1415 * @ctrl: The controller to resume.
1416 *
1417 * Resume the controller from the suspended state it was put into via
1418 * ssam_controller_suspend(). This function does not issue display-on and
1419 * D0-entry notifications. If required, those have to be sent manually after
1420 * this call.
1421 *
1422 * Return: Returns %-EINVAL if the controller is currently not suspended.
1423 */
1424int ssam_controller_resume(struct ssam_controller *ctrl)
1425{
1426        ssam_controller_lock(ctrl);
1427
1428        if (ctrl->state != SSAM_CONTROLLER_SUSPENDED) {
1429                ssam_controller_unlock(ctrl);
1430                return -EINVAL;
1431        }
1432
1433        ssam_dbg(ctrl, "pm: resuming controller\n");
1434
1435        /*
1436         * Set state via write_once even though we're locked, due to
1437         * smoke-testing in ssam_request_sync_submit().
1438         */
1439        WRITE_ONCE(ctrl->state, SSAM_CONTROLLER_STARTED);
1440
1441        ssam_controller_unlock(ctrl);
1442        return 0;
1443}
1444
1445
1446/* -- Top-level request interface ------------------------------------------- */
1447
1448/**
1449 * ssam_request_write_data() - Construct and write SAM request message to
1450 * buffer.
1451 * @buf:  The buffer to write the data to.
1452 * @ctrl: The controller via which the request will be sent.
1453 * @spec: The request data and specification.
1454 *
1455 * Constructs a SAM/SSH request message and writes it to the provided buffer.
1456 * The request and transport counters, specifically RQID and SEQ, will be set
1457 * in this call. These counters are obtained from the controller. It is thus
1458 * only valid to send the resulting message via the controller specified here.
1459 *
1460 * For calculation of the required buffer size, refer to the
1461 * SSH_COMMAND_MESSAGE_LENGTH() macro.
1462 *
1463 * Return: Returns the number of bytes used in the buffer on success. Returns
1464 * %-EINVAL if the payload length provided in the request specification is too
1465 * large (larger than %SSH_COMMAND_MAX_PAYLOAD_SIZE) or if the provided buffer
1466 * is too small.
1467 */
1468ssize_t ssam_request_write_data(struct ssam_span *buf,
1469                                struct ssam_controller *ctrl,
1470                                const struct ssam_request *spec)
1471{
1472        struct msgbuf msgb;
1473        u16 rqid;
1474        u8 seq;
1475
1476        if (spec->length > SSH_COMMAND_MAX_PAYLOAD_SIZE)
1477                return -EINVAL;
1478
1479        if (SSH_COMMAND_MESSAGE_LENGTH(spec->length) > buf->len)
1480                return -EINVAL;
1481
1482        msgb_init(&msgb, buf->ptr, buf->len);
1483        seq = ssh_seq_next(&ctrl->counter.seq);
1484        rqid = ssh_rqid_next(&ctrl->counter.rqid);
1485        msgb_push_cmd(&msgb, seq, rqid, spec);
1486
1487        return msgb_bytes_used(&msgb);
1488}
1489EXPORT_SYMBOL_GPL(ssam_request_write_data);
1490
1491static void ssam_request_sync_complete(struct ssh_request *rqst,
1492                                       const struct ssh_command *cmd,
1493                                       const struct ssam_span *data, int status)
1494{
1495        struct ssh_rtl *rtl = ssh_request_rtl(rqst);
1496        struct ssam_request_sync *r;
1497
1498        r = container_of(rqst, struct ssam_request_sync, base);
1499        r->status = status;
1500
1501        if (r->resp)
1502                r->resp->length = 0;
1503
1504        if (status) {
1505                rtl_dbg_cond(rtl, "rsp: request failed: %d\n", status);
1506                return;
1507        }
1508
1509        if (!data)      /* Handle requests without a response. */
1510                return;
1511
1512        if (!r->resp || !r->resp->pointer) {
1513                if (data->len)
1514                        rtl_warn(rtl, "rsp: no response buffer provided, dropping data\n");
1515                return;
1516        }
1517
1518        if (data->len > r->resp->capacity) {
1519                rtl_err(rtl,
1520                        "rsp: response buffer too small, capacity: %zu bytes, got: %zu bytes\n",
1521                        r->resp->capacity, data->len);
1522                r->status = -ENOSPC;
1523                return;
1524        }
1525
1526        r->resp->length = data->len;
1527        memcpy(r->resp->pointer, data->ptr, data->len);
1528}
1529
1530static void ssam_request_sync_release(struct ssh_request *rqst)
1531{
1532        complete_all(&container_of(rqst, struct ssam_request_sync, base)->comp);
1533}
1534
1535static const struct ssh_request_ops ssam_request_sync_ops = {
1536        .release = ssam_request_sync_release,
1537        .complete = ssam_request_sync_complete,
1538};
1539
1540/**
1541 * ssam_request_sync_alloc() - Allocate a synchronous request.
1542 * @payload_len: The length of the request payload.
1543 * @flags:       Flags used for allocation.
1544 * @rqst:        Where to store the pointer to the allocated request.
1545 * @buffer:      Where to store the buffer descriptor for the message buffer of
1546 *               the request.
1547 *
1548 * Allocates a synchronous request with corresponding message buffer. The
1549 * request still needs to be initialized ssam_request_sync_init() before
1550 * it can be submitted, and the message buffer data must still be set to the
1551 * returned buffer via ssam_request_sync_set_data() after it has been filled,
1552 * if need be with adjusted message length.
1553 *
1554 * After use, the request and its corresponding message buffer should be freed
1555 * via ssam_request_sync_free(). The buffer must not be freed separately.
1556 *
1557 * Return: Returns zero on success, %-ENOMEM if the request could not be
1558 * allocated.
1559 */
1560int ssam_request_sync_alloc(size_t payload_len, gfp_t flags,
1561                            struct ssam_request_sync **rqst,
1562                            struct ssam_span *buffer)
1563{
1564        size_t msglen = SSH_COMMAND_MESSAGE_LENGTH(payload_len);
1565
1566        *rqst = kzalloc(sizeof(**rqst) + msglen, flags);
1567        if (!*rqst)
1568                return -ENOMEM;
1569
1570        buffer->ptr = (u8 *)(*rqst + 1);
1571        buffer->len = msglen;
1572
1573        return 0;
1574}
1575EXPORT_SYMBOL_GPL(ssam_request_sync_alloc);
1576
1577/**
1578 * ssam_request_sync_free() - Free a synchronous request.
1579 * @rqst: The request to be freed.
1580 *
1581 * Free a synchronous request and its corresponding buffer allocated with
1582 * ssam_request_sync_alloc(). Do not use for requests allocated on the stack
1583 * or via any other function.
1584 *
1585 * Warning: The caller must ensure that the request is not in use any more.
1586 * I.e. the caller must ensure that it has the only reference to the request
1587 * and the request is not currently pending. This means that the caller has
1588 * either never submitted the request, request submission has failed, or the
1589 * caller has waited until the submitted request has been completed via
1590 * ssam_request_sync_wait().
1591 */
1592void ssam_request_sync_free(struct ssam_request_sync *rqst)
1593{
1594        kfree(rqst);
1595}
1596EXPORT_SYMBOL_GPL(ssam_request_sync_free);
1597
1598/**
1599 * ssam_request_sync_init() - Initialize a synchronous request struct.
1600 * @rqst:  The request to initialize.
1601 * @flags: The request flags.
1602 *
1603 * Initializes the given request struct. Does not initialize the request
1604 * message data. This has to be done explicitly after this call via
1605 * ssam_request_sync_set_data() and the actual message data has to be written
1606 * via ssam_request_write_data().
1607 *
1608 * Return: Returns zero on success or %-EINVAL if the given flags are invalid.
1609 */
1610int ssam_request_sync_init(struct ssam_request_sync *rqst,
1611                           enum ssam_request_flags flags)
1612{
1613        int status;
1614
1615        status = ssh_request_init(&rqst->base, flags, &ssam_request_sync_ops);
1616        if (status)
1617                return status;
1618
1619        init_completion(&rqst->comp);
1620        rqst->resp = NULL;
1621        rqst->status = 0;
1622
1623        return 0;
1624}
1625EXPORT_SYMBOL_GPL(ssam_request_sync_init);
1626
1627/**
1628 * ssam_request_sync_submit() - Submit a synchronous request.
1629 * @ctrl: The controller with which to submit the request.
1630 * @rqst: The request to submit.
1631 *
1632 * Submit a synchronous request. The request has to be initialized and
1633 * properly set up, including response buffer (may be %NULL if no response is
1634 * expected) and command message data. This function does not wait for the
1635 * request to be completed.
1636 *
1637 * If this function succeeds, ssam_request_sync_wait() must be used to ensure
1638 * that the request has been completed before the response data can be
1639 * accessed and/or the request can be freed. On failure, the request may
1640 * immediately be freed.
1641 *
1642 * This function may only be used if the controller is active, i.e. has been
1643 * initialized and not suspended.
1644 */
1645int ssam_request_sync_submit(struct ssam_controller *ctrl,
1646                             struct ssam_request_sync *rqst)
1647{
1648        int status;
1649
1650        /*
1651         * This is only a superficial check. In general, the caller needs to
1652         * ensure that the controller is initialized and is not (and does not
1653         * get) suspended during use, i.e. until the request has been completed
1654         * (if _absolutely_ necessary, by use of ssam_controller_statelock/
1655         * ssam_controller_stateunlock, but something like ssam_client_link
1656         * should be preferred as this needs to last until the request has been
1657         * completed).
1658         *
1659         * Note that it is actually safe to use this function while the
1660         * controller is in the process of being shut down (as ssh_rtl_submit
1661         * is safe with regards to this), but it is generally discouraged to do
1662         * so.
1663         */
1664        if (WARN_ON(READ_ONCE(ctrl->state) != SSAM_CONTROLLER_STARTED)) {
1665                ssh_request_put(&rqst->base);
1666                return -ENODEV;
1667        }
1668
1669        status = ssh_rtl_submit(&ctrl->rtl, &rqst->base);
1670        ssh_request_put(&rqst->base);
1671
1672        return status;
1673}
1674EXPORT_SYMBOL_GPL(ssam_request_sync_submit);
1675
1676/**
1677 * ssam_request_sync() - Execute a synchronous request.
1678 * @ctrl: The controller via which the request will be submitted.
1679 * @spec: The request specification and payload.
1680 * @rsp:  The response buffer.
1681 *
1682 * Allocates a synchronous request with its message data buffer on the heap
1683 * via ssam_request_sync_alloc(), fully initializes it via the provided
1684 * request specification, submits it, and finally waits for its completion
1685 * before freeing it and returning its status.
1686 *
1687 * Return: Returns the status of the request or any failure during setup.
1688 */
1689int ssam_request_sync(struct ssam_controller *ctrl,
1690                      const struct ssam_request *spec,
1691                      struct ssam_response *rsp)
1692{
1693        struct ssam_request_sync *rqst;
1694        struct ssam_span buf;
1695        ssize_t len;
1696        int status;
1697
1698        status = ssam_request_sync_alloc(spec->length, GFP_KERNEL, &rqst, &buf);
1699        if (status)
1700                return status;
1701
1702        status = ssam_request_sync_init(rqst, spec->flags);
1703        if (status)
1704                return status;
1705
1706        ssam_request_sync_set_resp(rqst, rsp);
1707
1708        len = ssam_request_write_data(&buf, ctrl, spec);
1709        if (len < 0) {
1710                ssam_request_sync_free(rqst);
1711                return len;
1712        }
1713
1714        ssam_request_sync_set_data(rqst, buf.ptr, len);
1715
1716        status = ssam_request_sync_submit(ctrl, rqst);
1717        if (!status)
1718                status = ssam_request_sync_wait(rqst);
1719
1720        ssam_request_sync_free(rqst);
1721        return status;
1722}
1723EXPORT_SYMBOL_GPL(ssam_request_sync);
1724
1725/**
1726 * ssam_request_sync_with_buffer() - Execute a synchronous request with the
1727 * provided buffer as back-end for the message buffer.
1728 * @ctrl: The controller via which the request will be submitted.
1729 * @spec: The request specification and payload.
1730 * @rsp:  The response buffer.
1731 * @buf:  The buffer for the request message data.
1732 *
1733 * Allocates a synchronous request struct on the stack, fully initializes it
1734 * using the provided buffer as message data buffer, submits it, and then
1735 * waits for its completion before returning its status. The
1736 * SSH_COMMAND_MESSAGE_LENGTH() macro can be used to compute the required
1737 * message buffer size.
1738 *
1739 * This function does essentially the same as ssam_request_sync(), but instead
1740 * of dynamically allocating the request and message data buffer, it uses the
1741 * provided message data buffer and stores the (small) request struct on the
1742 * heap.
1743 *
1744 * Return: Returns the status of the request or any failure during setup.
1745 */
1746int ssam_request_sync_with_buffer(struct ssam_controller *ctrl,
1747                                  const struct ssam_request *spec,
1748                                  struct ssam_response *rsp,
1749                                  struct ssam_span *buf)
1750{
1751        struct ssam_request_sync rqst;
1752        ssize_t len;
1753        int status;
1754
1755        status = ssam_request_sync_init(&rqst, spec->flags);
1756        if (status)
1757                return status;
1758
1759        ssam_request_sync_set_resp(&rqst, rsp);
1760
1761        len = ssam_request_write_data(buf, ctrl, spec);
1762        if (len < 0)
1763                return len;
1764
1765        ssam_request_sync_set_data(&rqst, buf->ptr, len);
1766
1767        status = ssam_request_sync_submit(ctrl, &rqst);
1768        if (!status)
1769                status = ssam_request_sync_wait(&rqst);
1770
1771        return status;
1772}
1773EXPORT_SYMBOL_GPL(ssam_request_sync_with_buffer);
1774
1775
1776/* -- Internal SAM requests. ------------------------------------------------ */
1777
1778SSAM_DEFINE_SYNC_REQUEST_R(ssam_ssh_get_firmware_version, __le32, {
1779        .target_category = SSAM_SSH_TC_SAM,
1780        .target_id       = 0x01,
1781        .command_id      = 0x13,
1782        .instance_id     = 0x00,
1783});
1784
1785SSAM_DEFINE_SYNC_REQUEST_R(ssam_ssh_notif_display_off, u8, {
1786        .target_category = SSAM_SSH_TC_SAM,
1787        .target_id       = 0x01,
1788        .command_id      = 0x15,
1789        .instance_id     = 0x00,
1790});
1791
1792SSAM_DEFINE_SYNC_REQUEST_R(ssam_ssh_notif_display_on, u8, {
1793        .target_category = SSAM_SSH_TC_SAM,
1794        .target_id       = 0x01,
1795        .command_id      = 0x16,
1796        .instance_id     = 0x00,
1797});
1798
1799SSAM_DEFINE_SYNC_REQUEST_R(ssam_ssh_notif_d0_exit, u8, {
1800        .target_category = SSAM_SSH_TC_SAM,
1801        .target_id       = 0x01,
1802        .command_id      = 0x33,
1803        .instance_id     = 0x00,
1804});
1805
1806SSAM_DEFINE_SYNC_REQUEST_R(ssam_ssh_notif_d0_entry, u8, {
1807        .target_category = SSAM_SSH_TC_SAM,
1808        .target_id       = 0x01,
1809        .command_id      = 0x34,
1810        .instance_id     = 0x00,
1811});
1812
1813/**
1814 * struct ssh_notification_params - Command payload to enable/disable SSH
1815 * notifications.
1816 * @target_category: The target category for which notifications should be
1817 *                   enabled/disabled.
1818 * @flags:           Flags determining how notifications are being sent.
1819 * @request_id:      The request ID that is used to send these notifications.
1820 * @instance_id:     The specific instance in the given target category for
1821 *                   which notifications should be enabled.
1822 */
1823struct ssh_notification_params {
1824        u8 target_category;
1825        u8 flags;
1826        __le16 request_id;
1827        u8 instance_id;
1828} __packed;
1829
1830static_assert(sizeof(struct ssh_notification_params) == 5);
1831
1832static int __ssam_ssh_event_request(struct ssam_controller *ctrl,
1833                                    struct ssam_event_registry reg, u8 cid,
1834                                    struct ssam_event_id id, u8 flags)
1835{
1836        struct ssh_notification_params params;
1837        struct ssam_request rqst;
1838        struct ssam_response result;
1839        int status;
1840
1841        u16 rqid = ssh_tc_to_rqid(id.target_category);
1842        u8 buf = 0;
1843
1844        /* Only allow RQIDs that lie within the event spectrum. */
1845        if (!ssh_rqid_is_event(rqid))
1846                return -EINVAL;
1847
1848        params.target_category = id.target_category;
1849        params.instance_id = id.instance;
1850        params.flags = flags;
1851        put_unaligned_le16(rqid, &params.request_id);
1852
1853        rqst.target_category = reg.target_category;
1854        rqst.target_id = reg.target_id;
1855        rqst.command_id = cid;
1856        rqst.instance_id = 0x00;
1857        rqst.flags = SSAM_REQUEST_HAS_RESPONSE;
1858        rqst.length = sizeof(params);
1859        rqst.payload = (u8 *)&params;
1860
1861        result.capacity = sizeof(buf);
1862        result.length = 0;
1863        result.pointer = &buf;
1864
1865        status = ssam_retry(ssam_request_sync_onstack, ctrl, &rqst, &result,
1866                            sizeof(params));
1867
1868        return status < 0 ? status : buf;
1869}
1870
1871/**
1872 * ssam_ssh_event_enable() - Enable SSH event.
1873 * @ctrl:  The controller for which to enable the event.
1874 * @reg:   The event registry describing what request to use for enabling and
1875 *         disabling the event.
1876 * @id:    The event identifier.
1877 * @flags: The event flags.
1878 *
1879 * Enables the specified event on the EC. This function does not manage
1880 * reference counting of enabled events and is basically only a wrapper for
1881 * the raw EC request. If the specified event is already enabled, the EC will
1882 * ignore this request.
1883 *
1884 * Return: Returns the status of the executed SAM request (zero on success and
1885 * negative on direct failure) or %-EPROTO if the request response indicates a
1886 * failure.
1887 */
1888static int ssam_ssh_event_enable(struct ssam_controller *ctrl,
1889                                 struct ssam_event_registry reg,
1890                                 struct ssam_event_id id, u8 flags)
1891{
1892        int status;
1893
1894        status = __ssam_ssh_event_request(ctrl, reg, reg.cid_enable, id, flags);
1895
1896        if (status < 0 && status != -EINVAL) {
1897                ssam_err(ctrl,
1898                         "failed to enable event source (tc: %#04x, iid: %#04x, reg: %#04x)\n",
1899                         id.target_category, id.instance, reg.target_category);
1900        }
1901
1902        if (status > 0) {
1903                ssam_err(ctrl,
1904                         "unexpected result while enabling event source: %#04x (tc: %#04x, iid: %#04x, reg: %#04x)\n",
1905                         status, id.target_category, id.instance, reg.target_category);
1906                return -EPROTO;
1907        }
1908
1909        return status;
1910}
1911
1912/**
1913 * ssam_ssh_event_disable() - Disable SSH event.
1914 * @ctrl:  The controller for which to disable the event.
1915 * @reg:   The event registry describing what request to use for enabling and
1916 *         disabling the event (must be same as used when enabling the event).
1917 * @id:    The event identifier.
1918 * @flags: The event flags (likely ignored for disabling of events).
1919 *
1920 * Disables the specified event on the EC. This function does not manage
1921 * reference counting of enabled events and is basically only a wrapper for
1922 * the raw EC request. If the specified event is already disabled, the EC will
1923 * ignore this request.
1924 *
1925 * Return: Returns the status of the executed SAM request (zero on success and
1926 * negative on direct failure) or %-EPROTO if the request response indicates a
1927 * failure.
1928 */
1929static int ssam_ssh_event_disable(struct ssam_controller *ctrl,
1930                                  struct ssam_event_registry reg,
1931                                  struct ssam_event_id id, u8 flags)
1932{
1933        int status;
1934
1935        status = __ssam_ssh_event_request(ctrl, reg, reg.cid_disable, id, flags);
1936
1937        if (status < 0 && status != -EINVAL) {
1938                ssam_err(ctrl,
1939                         "failed to disable event source (tc: %#04x, iid: %#04x, reg: %#04x)\n",
1940                         id.target_category, id.instance, reg.target_category);
1941        }
1942
1943        if (status > 0) {
1944                ssam_err(ctrl,
1945                         "unexpected result while disabling event source: %#04x (tc: %#04x, iid: %#04x, reg: %#04x)\n",
1946                         status, id.target_category, id.instance, reg.target_category);
1947                return -EPROTO;
1948        }
1949
1950        return status;
1951}
1952
1953
1954/* -- Wrappers for internal SAM requests. ----------------------------------- */
1955
1956/**
1957 * ssam_get_firmware_version() - Get the SAM/EC firmware version.
1958 * @ctrl:    The controller.
1959 * @version: Where to store the version number.
1960 *
1961 * Return: Returns zero on success or the status of the executed SAM request
1962 * if that request failed.
1963 */
1964int ssam_get_firmware_version(struct ssam_controller *ctrl, u32 *version)
1965{
1966        __le32 __version;
1967        int status;
1968
1969        status = ssam_retry(ssam_ssh_get_firmware_version, ctrl, &__version);
1970        if (status)
1971                return status;
1972
1973        *version = le32_to_cpu(__version);
1974        return 0;
1975}
1976
1977/**
1978 * ssam_ctrl_notif_display_off() - Notify EC that the display has been turned
1979 * off.
1980 * @ctrl: The controller.
1981 *
1982 * Notify the EC that the display has been turned off and the driver may enter
1983 * a lower-power state. This will prevent events from being sent directly.
1984 * Rather, the EC signals an event by pulling the wakeup GPIO high for as long
1985 * as there are pending events. The events then need to be manually released,
1986 * one by one, via the GPIO callback request. All pending events accumulated
1987 * during this state can also be released by issuing the display-on
1988 * notification, e.g. via ssam_ctrl_notif_display_on(), which will also reset
1989 * the GPIO.
1990 *
1991 * On some devices, specifically ones with an integrated keyboard, the keyboard
1992 * backlight will be turned off by this call.
1993 *
1994 * This function will only send the display-off notification command if
1995 * display notifications are supported by the EC. Currently all known devices
1996 * support these notifications.
1997 *
1998 * Use ssam_ctrl_notif_display_on() to reverse the effects of this function.
1999 *
2000 * Return: Returns zero on success or if no request has been executed, the
2001 * status of the executed SAM request if that request failed, or %-EPROTO if
2002 * an unexpected response has been received.
2003 */
2004int ssam_ctrl_notif_display_off(struct ssam_controller *ctrl)
2005{
2006        int status;
2007        u8 response;
2008
2009        ssam_dbg(ctrl, "pm: notifying display off\n");
2010
2011        status = ssam_retry(ssam_ssh_notif_display_off, ctrl, &response);
2012        if (status)
2013                return status;
2014
2015        if (response != 0) {
2016                ssam_err(ctrl, "unexpected response from display-off notification: %#04x\n",
2017                         response);
2018                return -EPROTO;
2019        }
2020
2021        return 0;
2022}
2023
2024/**
2025 * ssam_ctrl_notif_display_on() - Notify EC that the display has been turned on.
2026 * @ctrl: The controller.
2027 *
2028 * Notify the EC that the display has been turned back on and the driver has
2029 * exited its lower-power state. This notification is the counterpart to the
2030 * display-off notification sent via ssam_ctrl_notif_display_off() and will
2031 * reverse its effects, including resetting events to their default behavior.
2032 *
2033 * This function will only send the display-on notification command if display
2034 * notifications are supported by the EC. Currently all known devices support
2035 * these notifications.
2036 *
2037 * See ssam_ctrl_notif_display_off() for more details.
2038 *
2039 * Return: Returns zero on success or if no request has been executed, the
2040 * status of the executed SAM request if that request failed, or %-EPROTO if
2041 * an unexpected response has been received.
2042 */
2043int ssam_ctrl_notif_display_on(struct ssam_controller *ctrl)
2044{
2045        int status;
2046        u8 response;
2047
2048        ssam_dbg(ctrl, "pm: notifying display on\n");
2049
2050        status = ssam_retry(ssam_ssh_notif_display_on, ctrl, &response);
2051        if (status)
2052                return status;
2053
2054        if (response != 0) {
2055                ssam_err(ctrl, "unexpected response from display-on notification: %#04x\n",
2056                         response);
2057                return -EPROTO;
2058        }
2059
2060        return 0;
2061}
2062
2063/**
2064 * ssam_ctrl_notif_d0_exit() - Notify EC that the driver/device exits the D0
2065 * power state.
2066 * @ctrl: The controller
2067 *
2068 * Notifies the EC that the driver prepares to exit the D0 power state in
2069 * favor of a lower-power state. Exact effects of this function related to the
2070 * EC are currently unknown.
2071 *
2072 * This function will only send the D0-exit notification command if D0-state
2073 * notifications are supported by the EC. Only newer Surface generations
2074 * support these notifications.
2075 *
2076 * Use ssam_ctrl_notif_d0_entry() to reverse the effects of this function.
2077 *
2078 * Return: Returns zero on success or if no request has been executed, the
2079 * status of the executed SAM request if that request failed, or %-EPROTO if
2080 * an unexpected response has been received.
2081 */
2082int ssam_ctrl_notif_d0_exit(struct ssam_controller *ctrl)
2083{
2084        int status;
2085        u8 response;
2086
2087        if (!ctrl->caps.d3_closes_handle)
2088                return 0;
2089
2090        ssam_dbg(ctrl, "pm: notifying D0 exit\n");
2091
2092        status = ssam_retry(ssam_ssh_notif_d0_exit, ctrl, &response);
2093        if (status)
2094                return status;
2095
2096        if (response != 0) {
2097                ssam_err(ctrl, "unexpected response from D0-exit notification: %#04x\n",
2098                         response);
2099                return -EPROTO;
2100        }
2101
2102        return 0;
2103}
2104
2105/**
2106 * ssam_ctrl_notif_d0_entry() - Notify EC that the driver/device enters the D0
2107 * power state.
2108 * @ctrl: The controller
2109 *
2110 * Notifies the EC that the driver has exited a lower-power state and entered
2111 * the D0 power state. Exact effects of this function related to the EC are
2112 * currently unknown.
2113 *
2114 * This function will only send the D0-entry notification command if D0-state
2115 * notifications are supported by the EC. Only newer Surface generations
2116 * support these notifications.
2117 *
2118 * See ssam_ctrl_notif_d0_exit() for more details.
2119 *
2120 * Return: Returns zero on success or if no request has been executed, the
2121 * status of the executed SAM request if that request failed, or %-EPROTO if
2122 * an unexpected response has been received.
2123 */
2124int ssam_ctrl_notif_d0_entry(struct ssam_controller *ctrl)
2125{
2126        int status;
2127        u8 response;
2128
2129        if (!ctrl->caps.d3_closes_handle)
2130                return 0;
2131
2132        ssam_dbg(ctrl, "pm: notifying D0 entry\n");
2133
2134        status = ssam_retry(ssam_ssh_notif_d0_entry, ctrl, &response);
2135        if (status)
2136                return status;
2137
2138        if (response != 0) {
2139                ssam_err(ctrl, "unexpected response from D0-entry notification: %#04x\n",
2140                         response);
2141                return -EPROTO;
2142        }
2143
2144        return 0;
2145}
2146
2147
2148/* -- Top-level event registry interface. ----------------------------------- */
2149
2150/**
2151 * ssam_nf_refcount_enable() - Enable event for reference count entry if it has
2152 * not already been enabled.
2153 * @ctrl:  The controller to enable the event on.
2154 * @entry: The reference count entry for the event to be enabled.
2155 * @flags: The flags used for enabling the event on the EC.
2156 *
2157 * Enable the event associated with the given reference count entry if the
2158 * reference count equals one, i.e. the event has not previously been enabled.
2159 * If the event has already been enabled (i.e. reference count not equal to
2160 * one), check that the flags used for enabling match and warn about this if
2161 * they do not.
2162 *
2163 * This does not modify the reference count itself, which is done with
2164 * ssam_nf_refcount_inc() / ssam_nf_refcount_dec().
2165 *
2166 * Note: ``nf->lock`` must be held when calling this function.
2167 *
2168 * Return: Returns zero on success. If the event is enabled by this call,
2169 * returns the status of the event-enable EC command.
2170 */
2171static int ssam_nf_refcount_enable(struct ssam_controller *ctrl,
2172                                   struct ssam_nf_refcount_entry *entry, u8 flags)
2173{
2174        const struct ssam_event_registry reg = entry->key.reg;
2175        const struct ssam_event_id id = entry->key.id;
2176        struct ssam_nf *nf = &ctrl->cplt.event.notif;
2177        int status;
2178
2179        lockdep_assert_held(&nf->lock);
2180
2181        ssam_dbg(ctrl, "enabling event (reg: %#04x, tc: %#04x, iid: %#04x, rc: %d)\n",
2182                 reg.target_category, id.target_category, id.instance, entry->refcount);
2183
2184        if (entry->refcount == 1) {
2185                status = ssam_ssh_event_enable(ctrl, reg, id, flags);
2186                if (status)
2187                        return status;
2188
2189                entry->flags = flags;
2190
2191        } else if (entry->flags != flags) {
2192                ssam_warn(ctrl,
2193                          "inconsistent flags when enabling event: got %#04x, expected %#04x (reg: %#04x, tc: %#04x, iid: %#04x)\n",
2194                          flags, entry->flags, reg.target_category, id.target_category,
2195                          id.instance);
2196        }
2197
2198        return 0;
2199}
2200
2201/**
2202 * ssam_nf_refcount_disable_free() - Disable event for reference count entry if it is
2203 * no longer in use and free the corresponding entry.
2204 * @ctrl:  The controller to disable the event on.
2205 * @entry: The reference count entry for the event to be disabled.
2206 * @flags: The flags used for enabling the event on the EC.
2207 *
2208 * If the reference count equals zero, i.e. the event is no longer requested by
2209 * any client, the event will be disabled and the corresponding reference count
2210 * entry freed. The reference count entry must not be used any more after a
2211 * call to this function.
2212 *
2213 * Also checks if the flags used for disabling the event match the flags used
2214 * for enabling the event and warns if they do not (regardless of reference
2215 * count).
2216 *
2217 * This does not modify the reference count itself, which is done with
2218 * ssam_nf_refcount_inc() / ssam_nf_refcount_dec().
2219 *
2220 * Note: ``nf->lock`` must be held when calling this function.
2221 *
2222 * Return: Returns zero on success. If the event is disabled by this call,
2223 * returns the status of the event-enable EC command.
2224 */
2225static int ssam_nf_refcount_disable_free(struct ssam_controller *ctrl,
2226                                         struct ssam_nf_refcount_entry *entry, u8 flags)
2227{
2228        const struct ssam_event_registry reg = entry->key.reg;
2229        const struct ssam_event_id id = entry->key.id;
2230        struct ssam_nf *nf = &ctrl->cplt.event.notif;
2231        int status = 0;
2232
2233        lockdep_assert_held(&nf->lock);
2234
2235        ssam_dbg(ctrl, "disabling event (reg: %#04x, tc: %#04x, iid: %#04x, rc: %d)\n",
2236                 reg.target_category, id.target_category, id.instance, entry->refcount);
2237
2238        if (entry->flags != flags) {
2239                ssam_warn(ctrl,
2240                          "inconsistent flags when disabling event: got %#04x, expected %#04x (reg: %#04x, tc: %#04x, iid: %#04x)\n",
2241                          flags, entry->flags, reg.target_category, id.target_category,
2242                          id.instance);
2243        }
2244
2245        if (entry->refcount == 0) {
2246                status = ssam_ssh_event_disable(ctrl, reg, id, flags);
2247                kfree(entry);
2248        }
2249
2250        return status;
2251}
2252
2253/**
2254 * ssam_notifier_register() - Register an event notifier.
2255 * @ctrl: The controller to register the notifier on.
2256 * @n:    The event notifier to register.
2257 *
2258 * Register an event notifier. Increment the usage counter of the associated
2259 * SAM event if the notifier is not marked as an observer. If the event is not
2260 * marked as an observer and is currently not enabled, it will be enabled
2261 * during this call. If the notifier is marked as an observer, no attempt will
2262 * be made at enabling any event and no reference count will be modified.
2263 *
2264 * Notifiers marked as observers do not need to be associated with one specific
2265 * event, i.e. as long as no event matching is performed, only the event target
2266 * category needs to be set.
2267 *
2268 * Return: Returns zero on success, %-ENOSPC if there have already been
2269 * %INT_MAX notifiers for the event ID/type associated with the notifier block
2270 * registered, %-ENOMEM if the corresponding event entry could not be
2271 * allocated. If this is the first time that a notifier block is registered
2272 * for the specific associated event, returns the status of the event-enable
2273 * EC-command.
2274 */
2275int ssam_notifier_register(struct ssam_controller *ctrl, struct ssam_event_notifier *n)
2276{
2277        u16 rqid = ssh_tc_to_rqid(n->event.id.target_category);
2278        struct ssam_nf_refcount_entry *entry = NULL;
2279        struct ssam_nf_head *nf_head;
2280        struct ssam_nf *nf;
2281        int status;
2282
2283        if (!ssh_rqid_is_event(rqid))
2284                return -EINVAL;
2285
2286        nf = &ctrl->cplt.event.notif;
2287        nf_head = &nf->head[ssh_rqid_to_event(rqid)];
2288
2289        mutex_lock(&nf->lock);
2290
2291        if (!(n->flags & SSAM_EVENT_NOTIFIER_OBSERVER)) {
2292                entry = ssam_nf_refcount_inc(nf, n->event.reg, n->event.id);
2293                if (IS_ERR(entry)) {
2294                        mutex_unlock(&nf->lock);
2295                        return PTR_ERR(entry);
2296                }
2297        }
2298
2299        status = ssam_nfblk_insert(nf_head, &n->base);
2300        if (status) {
2301                if (entry)
2302                        ssam_nf_refcount_dec_free(nf, n->event.reg, n->event.id);
2303
2304                mutex_unlock(&nf->lock);
2305                return status;
2306        }
2307
2308        if (entry) {
2309                status = ssam_nf_refcount_enable(ctrl, entry, n->event.flags);
2310                if (status) {
2311                        ssam_nfblk_remove(&n->base);
2312                        ssam_nf_refcount_dec_free(nf, n->event.reg, n->event.id);
2313                        mutex_unlock(&nf->lock);
2314                        synchronize_srcu(&nf_head->srcu);
2315                        return status;
2316                }
2317        }
2318
2319        mutex_unlock(&nf->lock);
2320        return 0;
2321}
2322EXPORT_SYMBOL_GPL(ssam_notifier_register);
2323
2324/**
2325 * ssam_notifier_unregister() - Unregister an event notifier.
2326 * @ctrl: The controller the notifier has been registered on.
2327 * @n:    The event notifier to unregister.
2328 *
2329 * Unregister an event notifier. Decrement the usage counter of the associated
2330 * SAM event if the notifier is not marked as an observer. If the usage counter
2331 * reaches zero, the event will be disabled.
2332 *
2333 * Return: Returns zero on success, %-ENOENT if the given notifier block has
2334 * not been registered on the controller. If the given notifier block was the
2335 * last one associated with its specific event, returns the status of the
2336 * event-disable EC-command.
2337 */
2338int ssam_notifier_unregister(struct ssam_controller *ctrl, struct ssam_event_notifier *n)
2339{
2340        u16 rqid = ssh_tc_to_rqid(n->event.id.target_category);
2341        struct ssam_nf_refcount_entry *entry;
2342        struct ssam_nf_head *nf_head;
2343        struct ssam_nf *nf;
2344        int status = 0;
2345
2346        if (!ssh_rqid_is_event(rqid))
2347                return -EINVAL;
2348
2349        nf = &ctrl->cplt.event.notif;
2350        nf_head = &nf->head[ssh_rqid_to_event(rqid)];
2351
2352        mutex_lock(&nf->lock);
2353
2354        if (!ssam_nfblk_find(nf_head, &n->base)) {
2355                mutex_unlock(&nf->lock);
2356                return -ENOENT;
2357        }
2358
2359        /*
2360         * If this is an observer notifier, do not attempt to disable the
2361         * event, just remove it.
2362         */
2363        if (!(n->flags & SSAM_EVENT_NOTIFIER_OBSERVER)) {
2364                entry = ssam_nf_refcount_dec(nf, n->event.reg, n->event.id);
2365                if (WARN_ON(!entry)) {
2366                        /*
2367                         * If this does not return an entry, there's a logic
2368                         * error somewhere: The notifier block is registered,
2369                         * but the event refcount entry is not there. Remove
2370                         * the notifier block anyways.
2371                         */
2372                        status = -ENOENT;
2373                        goto remove;
2374                }
2375
2376                status = ssam_nf_refcount_disable_free(ctrl, entry, n->event.flags);
2377        }
2378
2379remove:
2380        ssam_nfblk_remove(&n->base);
2381        mutex_unlock(&nf->lock);
2382        synchronize_srcu(&nf_head->srcu);
2383
2384        return status;
2385}
2386EXPORT_SYMBOL_GPL(ssam_notifier_unregister);
2387
2388/**
2389 * ssam_controller_event_enable() - Enable the specified event.
2390 * @ctrl:  The controller to enable the event for.
2391 * @reg:   The event registry to use for enabling the event.
2392 * @id:    The event ID specifying the event to be enabled.
2393 * @flags: The SAM event flags used for enabling the event.
2394 *
2395 * Increment the event reference count of the specified event. If the event has
2396 * not been enabled previously, it will be enabled by this call.
2397 *
2398 * Note: In general, ssam_notifier_register() with a non-observer notifier
2399 * should be preferred for enabling/disabling events, as this will guarantee
2400 * proper ordering and event forwarding in case of errors during event
2401 * enabling/disabling.
2402 *
2403 * Return: Returns zero on success, %-ENOSPC if the reference count for the
2404 * specified event has reached its maximum, %-ENOMEM if the corresponding event
2405 * entry could not be allocated. If this is the first time that this event has
2406 * been enabled (i.e. the reference count was incremented from zero to one by
2407 * this call), returns the status of the event-enable EC-command.
2408 */
2409int ssam_controller_event_enable(struct ssam_controller *ctrl,
2410                                 struct ssam_event_registry reg,
2411                                 struct ssam_event_id id, u8 flags)
2412{
2413        u16 rqid = ssh_tc_to_rqid(id.target_category);
2414        struct ssam_nf *nf = &ctrl->cplt.event.notif;
2415        struct ssam_nf_refcount_entry *entry;
2416        int status;
2417
2418        if (!ssh_rqid_is_event(rqid))
2419                return -EINVAL;
2420
2421        mutex_lock(&nf->lock);
2422
2423        entry = ssam_nf_refcount_inc(nf, reg, id);
2424        if (IS_ERR(entry)) {
2425                mutex_unlock(&nf->lock);
2426                return PTR_ERR(entry);
2427        }
2428
2429        status = ssam_nf_refcount_enable(ctrl, entry, flags);
2430        if (status) {
2431                ssam_nf_refcount_dec_free(nf, reg, id);
2432                mutex_unlock(&nf->lock);
2433                return status;
2434        }
2435
2436        mutex_unlock(&nf->lock);
2437        return 0;
2438}
2439EXPORT_SYMBOL_GPL(ssam_controller_event_enable);
2440
2441/**
2442 * ssam_controller_event_disable() - Disable the specified event.
2443 * @ctrl:  The controller to disable the event for.
2444 * @reg:   The event registry to use for disabling the event.
2445 * @id:    The event ID specifying the event to be disabled.
2446 * @flags: The flags used when enabling the event.
2447 *
2448 * Decrement the reference count of the specified event. If the reference count
2449 * reaches zero, the event will be disabled.
2450 *
2451 * Note: In general, ssam_notifier_register()/ssam_notifier_unregister() with a
2452 * non-observer notifier should be preferred for enabling/disabling events, as
2453 * this will guarantee proper ordering and event forwarding in case of errors
2454 * during event enabling/disabling.
2455 *
2456 * Return: Returns zero on success, %-ENOENT if the given event has not been
2457 * enabled on the controller. If the reference count of the event reaches zero
2458 * during this call, returns the status of the event-disable EC-command.
2459 */
2460int ssam_controller_event_disable(struct ssam_controller *ctrl,
2461                                  struct ssam_event_registry reg,
2462                                  struct ssam_event_id id, u8 flags)
2463{
2464        u16 rqid = ssh_tc_to_rqid(id.target_category);
2465        struct ssam_nf *nf = &ctrl->cplt.event.notif;
2466        struct ssam_nf_refcount_entry *entry;
2467        int status;
2468
2469        if (!ssh_rqid_is_event(rqid))
2470                return -EINVAL;
2471
2472        mutex_lock(&nf->lock);
2473
2474        entry = ssam_nf_refcount_dec(nf, reg, id);
2475        if (!entry) {
2476                mutex_unlock(&nf->lock);
2477                return -ENOENT;
2478        }
2479
2480        status = ssam_nf_refcount_disable_free(ctrl, entry, flags);
2481
2482        mutex_unlock(&nf->lock);
2483        return status;
2484}
2485EXPORT_SYMBOL_GPL(ssam_controller_event_disable);
2486
2487/**
2488 * ssam_notifier_disable_registered() - Disable events for all registered
2489 * notifiers.
2490 * @ctrl: The controller for which to disable the notifiers/events.
2491 *
2492 * Disables events for all currently registered notifiers. In case of an error
2493 * (EC command failing), all previously disabled events will be restored and
2494 * the error code returned.
2495 *
2496 * This function is intended to disable all events prior to hibernation entry.
2497 * See ssam_notifier_restore_registered() to restore/re-enable all events
2498 * disabled with this function.
2499 *
2500 * Note that this function will not disable events for notifiers registered
2501 * after calling this function. It should thus be made sure that no new
2502 * notifiers are going to be added after this call and before the corresponding
2503 * call to ssam_notifier_restore_registered().
2504 *
2505 * Return: Returns zero on success. In case of failure returns the error code
2506 * returned by the failed EC command to disable an event.
2507 */
2508int ssam_notifier_disable_registered(struct ssam_controller *ctrl)
2509{
2510        struct ssam_nf *nf = &ctrl->cplt.event.notif;
2511        struct rb_node *n;
2512        int status;
2513
2514        mutex_lock(&nf->lock);
2515        for (n = rb_first(&nf->refcount); n; n = rb_next(n)) {
2516                struct ssam_nf_refcount_entry *e;
2517
2518                e = rb_entry(n, struct ssam_nf_refcount_entry, node);
2519                status = ssam_ssh_event_disable(ctrl, e->key.reg,
2520                                                e->key.id, e->flags);
2521                if (status)
2522                        goto err;
2523        }
2524        mutex_unlock(&nf->lock);
2525
2526        return 0;
2527
2528err:
2529        for (n = rb_prev(n); n; n = rb_prev(n)) {
2530                struct ssam_nf_refcount_entry *e;
2531
2532                e = rb_entry(n, struct ssam_nf_refcount_entry, node);
2533                ssam_ssh_event_enable(ctrl, e->key.reg, e->key.id, e->flags);
2534        }
2535        mutex_unlock(&nf->lock);
2536
2537        return status;
2538}
2539
2540/**
2541 * ssam_notifier_restore_registered() - Restore/re-enable events for all
2542 * registered notifiers.
2543 * @ctrl: The controller for which to restore the notifiers/events.
2544 *
2545 * Restores/re-enables all events for which notifiers have been registered on
2546 * the given controller. In case of a failure, the error is logged and the
2547 * function continues to try and enable the remaining events.
2548 *
2549 * This function is intended to restore/re-enable all registered events after
2550 * hibernation. See ssam_notifier_disable_registered() for the counter part
2551 * disabling the events and more details.
2552 */
2553void ssam_notifier_restore_registered(struct ssam_controller *ctrl)
2554{
2555        struct ssam_nf *nf = &ctrl->cplt.event.notif;
2556        struct rb_node *n;
2557
2558        mutex_lock(&nf->lock);
2559        for (n = rb_first(&nf->refcount); n; n = rb_next(n)) {
2560                struct ssam_nf_refcount_entry *e;
2561
2562                e = rb_entry(n, struct ssam_nf_refcount_entry, node);
2563
2564                /* Ignore errors, will get logged in call. */
2565                ssam_ssh_event_enable(ctrl, e->key.reg, e->key.id, e->flags);
2566        }
2567        mutex_unlock(&nf->lock);
2568}
2569
2570/**
2571 * ssam_notifier_is_empty() - Check if there are any registered notifiers.
2572 * @ctrl: The controller to check on.
2573 *
2574 * Return: Returns %true if there are currently no notifiers registered on the
2575 * controller, %false otherwise.
2576 */
2577static bool ssam_notifier_is_empty(struct ssam_controller *ctrl)
2578{
2579        struct ssam_nf *nf = &ctrl->cplt.event.notif;
2580        bool result;
2581
2582        mutex_lock(&nf->lock);
2583        result = ssam_nf_refcount_empty(nf);
2584        mutex_unlock(&nf->lock);
2585
2586        return result;
2587}
2588
2589/**
2590 * ssam_notifier_unregister_all() - Unregister all currently registered
2591 * notifiers.
2592 * @ctrl: The controller to unregister the notifiers on.
2593 *
2594 * Unregisters all currently registered notifiers. This function is used to
2595 * ensure that all notifiers will be unregistered and associated
2596 * entries/resources freed when the controller is being shut down.
2597 */
2598static void ssam_notifier_unregister_all(struct ssam_controller *ctrl)
2599{
2600        struct ssam_nf *nf = &ctrl->cplt.event.notif;
2601        struct ssam_nf_refcount_entry *e, *n;
2602
2603        mutex_lock(&nf->lock);
2604        rbtree_postorder_for_each_entry_safe(e, n, &nf->refcount, node) {
2605                /* Ignore errors, will get logged in call. */
2606                ssam_ssh_event_disable(ctrl, e->key.reg, e->key.id, e->flags);
2607                kfree(e);
2608        }
2609        nf->refcount = RB_ROOT;
2610        mutex_unlock(&nf->lock);
2611}
2612
2613
2614/* -- Wakeup IRQ. ----------------------------------------------------------- */
2615
2616static irqreturn_t ssam_irq_handle(int irq, void *dev_id)
2617{
2618        struct ssam_controller *ctrl = dev_id;
2619
2620        ssam_dbg(ctrl, "pm: wake irq triggered\n");
2621
2622        /*
2623         * Note: Proper wakeup detection is currently unimplemented.
2624         *       When the EC is in display-off or any other non-D0 state, it
2625         *       does not send events/notifications to the host. Instead it
2626         *       signals that there are events available via the wakeup IRQ.
2627         *       This driver is responsible for calling back to the EC to
2628         *       release these events one-by-one.
2629         *
2630         *       This IRQ should not cause a full system resume by its own.
2631         *       Instead, events should be handled by their respective subsystem
2632         *       drivers, which in turn should signal whether a full system
2633         *       resume should be performed.
2634         *
2635         * TODO: Send GPIO callback command repeatedly to EC until callback
2636         *       returns 0x00. Return flag of callback is "has more events".
2637         *       Each time the command is sent, one event is "released". Once
2638         *       all events have been released (return = 0x00), the GPIO is
2639         *       re-armed. Detect wakeup events during this process, go back to
2640         *       sleep if no wakeup event has been received.
2641         */
2642
2643        return IRQ_HANDLED;
2644}
2645
2646/**
2647 * ssam_irq_setup() - Set up SAM EC wakeup-GPIO interrupt.
2648 * @ctrl: The controller for which the IRQ should be set up.
2649 *
2650 * Set up an IRQ for the wakeup-GPIO pin of the SAM EC. This IRQ can be used
2651 * to wake the device from a low power state.
2652 *
2653 * Note that this IRQ can only be triggered while the EC is in the display-off
2654 * state. In this state, events are not sent to the host in the usual way.
2655 * Instead the wakeup-GPIO gets pulled to "high" as long as there are pending
2656 * events and these events need to be released one-by-one via the GPIO
2657 * callback request, either until there are no events left and the GPIO is
2658 * reset, or all at once by transitioning the EC out of the display-off state,
2659 * which will also clear the GPIO.
2660 *
2661 * Not all events, however, should trigger a full system wakeup. Instead the
2662 * driver should, if necessary, inspect and forward each event to the
2663 * corresponding subsystem, which in turn should decide if the system needs to
2664 * be woken up. This logic has not been implemented yet, thus wakeup by this
2665 * IRQ should be disabled by default to avoid spurious wake-ups, caused, for
2666 * example, by the remaining battery percentage changing. Refer to comments in
2667 * this function and comments in the corresponding IRQ handler for more
2668 * details on how this should be implemented.
2669 *
2670 * See also ssam_ctrl_notif_display_off() and ssam_ctrl_notif_display_off()
2671 * for functions to transition the EC into and out of the display-off state as
2672 * well as more details on it.
2673 *
2674 * The IRQ is disabled by default and has to be enabled before it can wake up
2675 * the device from suspend via ssam_irq_arm_for_wakeup(). On teardown, the IRQ
2676 * should be freed via ssam_irq_free().
2677 */
2678int ssam_irq_setup(struct ssam_controller *ctrl)
2679{
2680        struct device *dev = ssam_controller_device(ctrl);
2681        struct gpio_desc *gpiod;
2682        int irq;
2683        int status;
2684
2685        /*
2686         * The actual GPIO interrupt is declared in ACPI as TRIGGER_HIGH.
2687         * However, the GPIO line only gets reset by sending the GPIO callback
2688         * command to SAM (or alternatively the display-on notification). As
2689         * proper handling for this interrupt is not implemented yet, leaving
2690         * the IRQ at TRIGGER_HIGH would cause an IRQ storm (as the callback
2691         * never gets sent and thus the line never gets reset). To avoid this,
2692         * mark the IRQ as TRIGGER_RISING for now, only creating a single
2693         * interrupt, and let the SAM resume callback during the controller
2694         * resume process clear it.
2695         */
2696        const int irqf = IRQF_ONESHOT | IRQF_TRIGGER_RISING | IRQF_NO_AUTOEN;
2697
2698        gpiod = gpiod_get(dev, "ssam_wakeup-int", GPIOD_ASIS);
2699        if (IS_ERR(gpiod))
2700                return PTR_ERR(gpiod);
2701
2702        irq = gpiod_to_irq(gpiod);
2703        gpiod_put(gpiod);
2704
2705        if (irq < 0)
2706                return irq;
2707
2708        status = request_threaded_irq(irq, NULL, ssam_irq_handle, irqf,
2709                                      "ssam_wakeup", ctrl);
2710        if (status)
2711                return status;
2712
2713        ctrl->irq.num = irq;
2714        return 0;
2715}
2716
2717/**
2718 * ssam_irq_free() - Free SAM EC wakeup-GPIO interrupt.
2719 * @ctrl: The controller for which the IRQ should be freed.
2720 *
2721 * Free the wakeup-GPIO IRQ previously set-up via ssam_irq_setup().
2722 */
2723void ssam_irq_free(struct ssam_controller *ctrl)
2724{
2725        free_irq(ctrl->irq.num, ctrl);
2726        ctrl->irq.num = -1;
2727}
2728
2729/**
2730 * ssam_irq_arm_for_wakeup() - Arm the EC IRQ for wakeup, if enabled.
2731 * @ctrl: The controller for which the IRQ should be armed.
2732 *
2733 * Sets up the IRQ so that it can be used to wake the device. Specifically,
2734 * this function enables the irq and then, if the device is allowed to wake up
2735 * the system, calls enable_irq_wake(). See ssam_irq_disarm_wakeup() for the
2736 * corresponding function to disable the IRQ.
2737 *
2738 * This function is intended to arm the IRQ before entering S2idle suspend.
2739 *
2740 * Note: calls to ssam_irq_arm_for_wakeup() and ssam_irq_disarm_wakeup() must
2741 * be balanced.
2742 */
2743int ssam_irq_arm_for_wakeup(struct ssam_controller *ctrl)
2744{
2745        struct device *dev = ssam_controller_device(ctrl);
2746        int status;
2747
2748        enable_irq(ctrl->irq.num);
2749        if (device_may_wakeup(dev)) {
2750                status = enable_irq_wake(ctrl->irq.num);
2751                if (status) {
2752                        ssam_err(ctrl, "failed to enable wake IRQ: %d\n", status);
2753                        disable_irq(ctrl->irq.num);
2754                        return status;
2755                }
2756
2757                ctrl->irq.wakeup_enabled = true;
2758        } else {
2759                ctrl->irq.wakeup_enabled = false;
2760        }
2761
2762        return 0;
2763}
2764
2765/**
2766 * ssam_irq_disarm_wakeup() - Disarm the wakeup IRQ.
2767 * @ctrl: The controller for which the IRQ should be disarmed.
2768 *
2769 * Disarm the IRQ previously set up for wake via ssam_irq_arm_for_wakeup().
2770 *
2771 * This function is intended to disarm the IRQ after exiting S2idle suspend.
2772 *
2773 * Note: calls to ssam_irq_arm_for_wakeup() and ssam_irq_disarm_wakeup() must
2774 * be balanced.
2775 */
2776void ssam_irq_disarm_wakeup(struct ssam_controller *ctrl)
2777{
2778        int status;
2779
2780        if (ctrl->irq.wakeup_enabled) {
2781                status = disable_irq_wake(ctrl->irq.num);
2782                if (status)
2783                        ssam_err(ctrl, "failed to disable wake IRQ: %d\n", status);
2784
2785                ctrl->irq.wakeup_enabled = false;
2786        }
2787        disable_irq(ctrl->irq.num);
2788}
2789