linux/drivers/platform/surface/surface_acpi_notify.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Driver for the Surface ACPI Notify (SAN) interface/shim.
   4 *
   5 * Translates communication from ACPI to Surface System Aggregator Module
   6 * (SSAM/SAM) requests and back, specifically SAM-over-SSH. Translates SSAM
   7 * events back to ACPI notifications. Allows handling of discrete GPU
   8 * notifications sent from ACPI via the SAN interface by providing them to any
   9 * registered external driver.
  10 *
  11 * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
  12 */
  13
  14#include <asm/unaligned.h>
  15#include <linux/acpi.h>
  16#include <linux/delay.h>
  17#include <linux/jiffies.h>
  18#include <linux/kernel.h>
  19#include <linux/module.h>
  20#include <linux/notifier.h>
  21#include <linux/platform_device.h>
  22#include <linux/rwsem.h>
  23
  24#include <linux/surface_aggregator/controller.h>
  25#include <linux/surface_acpi_notify.h>
  26
  27struct san_data {
  28        struct device *dev;
  29        struct ssam_controller *ctrl;
  30
  31        struct acpi_connection_info info;
  32
  33        struct ssam_event_notifier nf_bat;
  34        struct ssam_event_notifier nf_tmp;
  35};
  36
  37#define to_san_data(ptr, member) \
  38        container_of(ptr, struct san_data, member)
  39
  40
  41/* -- dGPU notifier interface. ---------------------------------------------- */
  42
  43struct san_rqsg_if {
  44        struct rw_semaphore lock;
  45        struct device *dev;
  46        struct blocking_notifier_head nh;
  47};
  48
  49static struct san_rqsg_if san_rqsg_if = {
  50        .lock = __RWSEM_INITIALIZER(san_rqsg_if.lock),
  51        .dev = NULL,
  52        .nh = BLOCKING_NOTIFIER_INIT(san_rqsg_if.nh),
  53};
  54
  55static int san_set_rqsg_interface_device(struct device *dev)
  56{
  57        int status = 0;
  58
  59        down_write(&san_rqsg_if.lock);
  60        if (!san_rqsg_if.dev && dev)
  61                san_rqsg_if.dev = dev;
  62        else
  63                status = -EBUSY;
  64        up_write(&san_rqsg_if.lock);
  65
  66        return status;
  67}
  68
  69/**
  70 * san_client_link() - Link client as consumer to SAN device.
  71 * @client: The client to link.
  72 *
  73 * Sets up a device link between the provided client device as consumer and
  74 * the SAN device as provider. This function can be used to ensure that the
  75 * SAN interface has been set up and will be set up for as long as the driver
  76 * of the client device is bound. This guarantees that, during that time, all
  77 * dGPU events will be received by any registered notifier.
  78 *
  79 * The link will be automatically removed once the client device's driver is
  80 * unbound.
  81 *
  82 * Return: Returns zero on success, %-ENXIO if the SAN interface has not been
  83 * set up yet, and %-ENOMEM if device link creation failed.
  84 */
  85int san_client_link(struct device *client)
  86{
  87        const u32 flags = DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_CONSUMER;
  88        struct device_link *link;
  89
  90        down_read(&san_rqsg_if.lock);
  91
  92        if (!san_rqsg_if.dev) {
  93                up_read(&san_rqsg_if.lock);
  94                return -ENXIO;
  95        }
  96
  97        link = device_link_add(client, san_rqsg_if.dev, flags);
  98        if (!link) {
  99                up_read(&san_rqsg_if.lock);
 100                return -ENOMEM;
 101        }
 102
 103        if (READ_ONCE(link->status) == DL_STATE_SUPPLIER_UNBIND) {
 104                up_read(&san_rqsg_if.lock);
 105                return -ENXIO;
 106        }
 107
 108        up_read(&san_rqsg_if.lock);
 109        return 0;
 110}
 111EXPORT_SYMBOL_GPL(san_client_link);
 112
 113/**
 114 * san_dgpu_notifier_register() - Register a SAN dGPU notifier.
 115 * @nb: The notifier-block to register.
 116 *
 117 * Registers a SAN dGPU notifier, receiving any new SAN dGPU events sent from
 118 * ACPI. The registered notifier will be called with &struct san_dgpu_event
 119 * as notifier data and the command ID of that event as notifier action.
 120 */
 121int san_dgpu_notifier_register(struct notifier_block *nb)
 122{
 123        return blocking_notifier_chain_register(&san_rqsg_if.nh, nb);
 124}
 125EXPORT_SYMBOL_GPL(san_dgpu_notifier_register);
 126
 127/**
 128 * san_dgpu_notifier_unregister() - Unregister a SAN dGPU notifier.
 129 * @nb: The notifier-block to unregister.
 130 */
 131int san_dgpu_notifier_unregister(struct notifier_block *nb)
 132{
 133        return blocking_notifier_chain_unregister(&san_rqsg_if.nh, nb);
 134}
 135EXPORT_SYMBOL_GPL(san_dgpu_notifier_unregister);
 136
 137static int san_dgpu_notifier_call(struct san_dgpu_event *evt)
 138{
 139        int ret;
 140
 141        ret = blocking_notifier_call_chain(&san_rqsg_if.nh, evt->command, evt);
 142        return notifier_to_errno(ret);
 143}
 144
 145
 146/* -- ACPI _DSM event relay. ------------------------------------------------ */
 147
 148#define SAN_DSM_REVISION        0
 149
 150/* 93b666c5-70c6-469f-a215-3d487c91ab3c */
 151static const guid_t SAN_DSM_UUID =
 152        GUID_INIT(0x93b666c5, 0x70c6, 0x469f, 0xa2, 0x15, 0x3d,
 153                  0x48, 0x7c, 0x91, 0xab, 0x3c);
 154
 155enum san_dsm_event_fn {
 156        SAN_DSM_EVENT_FN_BAT1_STAT = 0x03,
 157        SAN_DSM_EVENT_FN_BAT1_INFO = 0x04,
 158        SAN_DSM_EVENT_FN_ADP1_STAT = 0x05,
 159        SAN_DSM_EVENT_FN_ADP1_INFO = 0x06,
 160        SAN_DSM_EVENT_FN_BAT2_STAT = 0x07,
 161        SAN_DSM_EVENT_FN_BAT2_INFO = 0x08,
 162        SAN_DSM_EVENT_FN_THERMAL   = 0x09,
 163        SAN_DSM_EVENT_FN_DPTF      = 0x0a,
 164};
 165
 166enum sam_event_cid_bat {
 167        SAM_EVENT_CID_BAT_BIX  = 0x15,
 168        SAM_EVENT_CID_BAT_BST  = 0x16,
 169        SAM_EVENT_CID_BAT_ADP  = 0x17,
 170        SAM_EVENT_CID_BAT_PROT = 0x18,
 171        SAM_EVENT_CID_BAT_DPTF = 0x4f,
 172};
 173
 174enum sam_event_cid_tmp {
 175        SAM_EVENT_CID_TMP_TRIP = 0x0b,
 176};
 177
 178struct san_event_work {
 179        struct delayed_work work;
 180        struct device *dev;
 181        struct ssam_event event;        /* must be last */
 182};
 183
 184static int san_acpi_notify_event(struct device *dev, u64 func,
 185                                 union acpi_object *param)
 186{
 187        acpi_handle san = ACPI_HANDLE(dev);
 188        union acpi_object *obj;
 189        int status = 0;
 190
 191        if (!acpi_check_dsm(san, &SAN_DSM_UUID, SAN_DSM_REVISION, BIT_ULL(func)))
 192                return 0;
 193
 194        dev_dbg(dev, "notify event %#04llx\n", func);
 195
 196        obj = acpi_evaluate_dsm_typed(san, &SAN_DSM_UUID, SAN_DSM_REVISION,
 197                                      func, param, ACPI_TYPE_BUFFER);
 198        if (!obj)
 199                return -EFAULT;
 200
 201        if (obj->buffer.length != 1 || obj->buffer.pointer[0] != 0) {
 202                dev_err(dev, "got unexpected result from _DSM\n");
 203                status = -EPROTO;
 204        }
 205
 206        ACPI_FREE(obj);
 207        return status;
 208}
 209
 210static int san_evt_bat_adp(struct device *dev, const struct ssam_event *event)
 211{
 212        int status;
 213
 214        status = san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_ADP1_STAT, NULL);
 215        if (status)
 216                return status;
 217
 218        /*
 219         * Ensure that the battery states get updated correctly. When the
 220         * battery is fully charged and an adapter is plugged in, it sometimes
 221         * is not updated correctly, instead showing it as charging.
 222         * Explicitly trigger battery updates to fix this.
 223         */
 224
 225        status = san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_BAT1_STAT, NULL);
 226        if (status)
 227                return status;
 228
 229        return san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_BAT2_STAT, NULL);
 230}
 231
 232static int san_evt_bat_bix(struct device *dev, const struct ssam_event *event)
 233{
 234        enum san_dsm_event_fn fn;
 235
 236        if (event->instance_id == 0x02)
 237                fn = SAN_DSM_EVENT_FN_BAT2_INFO;
 238        else
 239                fn = SAN_DSM_EVENT_FN_BAT1_INFO;
 240
 241        return san_acpi_notify_event(dev, fn, NULL);
 242}
 243
 244static int san_evt_bat_bst(struct device *dev, const struct ssam_event *event)
 245{
 246        enum san_dsm_event_fn fn;
 247
 248        if (event->instance_id == 0x02)
 249                fn = SAN_DSM_EVENT_FN_BAT2_STAT;
 250        else
 251                fn = SAN_DSM_EVENT_FN_BAT1_STAT;
 252
 253        return san_acpi_notify_event(dev, fn, NULL);
 254}
 255
 256static int san_evt_bat_dptf(struct device *dev, const struct ssam_event *event)
 257{
 258        union acpi_object payload;
 259
 260        /*
 261         * The Surface ACPI expects a buffer and not a package. It specifically
 262         * checks for ObjectType (Arg3) == 0x03. This will cause a warning in
 263         * acpica/nsarguments.c, but that warning can be safely ignored.
 264         */
 265        payload.type = ACPI_TYPE_BUFFER;
 266        payload.buffer.length = event->length;
 267        payload.buffer.pointer = (u8 *)&event->data[0];
 268
 269        return san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_DPTF, &payload);
 270}
 271
 272static unsigned long san_evt_bat_delay(u8 cid)
 273{
 274        switch (cid) {
 275        case SAM_EVENT_CID_BAT_ADP:
 276                /*
 277                 * Wait for battery state to update before signaling adapter
 278                 * change.
 279                 */
 280                return msecs_to_jiffies(5000);
 281
 282        case SAM_EVENT_CID_BAT_BST:
 283                /* Ensure we do not miss anything important due to caching. */
 284                return msecs_to_jiffies(2000);
 285
 286        default:
 287                return 0;
 288        }
 289}
 290
 291static bool san_evt_bat(const struct ssam_event *event, struct device *dev)
 292{
 293        int status;
 294
 295        switch (event->command_id) {
 296        case SAM_EVENT_CID_BAT_BIX:
 297                status = san_evt_bat_bix(dev, event);
 298                break;
 299
 300        case SAM_EVENT_CID_BAT_BST:
 301                status = san_evt_bat_bst(dev, event);
 302                break;
 303
 304        case SAM_EVENT_CID_BAT_ADP:
 305                status = san_evt_bat_adp(dev, event);
 306                break;
 307
 308        case SAM_EVENT_CID_BAT_PROT:
 309                /*
 310                 * TODO: Implement support for battery protection status change
 311                 *       event.
 312                 */
 313                return true;
 314
 315        case SAM_EVENT_CID_BAT_DPTF:
 316                status = san_evt_bat_dptf(dev, event);
 317                break;
 318
 319        default:
 320                return false;
 321        }
 322
 323        if (status) {
 324                dev_err(dev, "error handling power event (cid = %#04x)\n",
 325                        event->command_id);
 326        }
 327
 328        return true;
 329}
 330
 331static void san_evt_bat_workfn(struct work_struct *work)
 332{
 333        struct san_event_work *ev;
 334
 335        ev = container_of(work, struct san_event_work, work.work);
 336        san_evt_bat(&ev->event, ev->dev);
 337        kfree(ev);
 338}
 339
 340static u32 san_evt_bat_nf(struct ssam_event_notifier *nf,
 341                          const struct ssam_event *event)
 342{
 343        struct san_data *d = to_san_data(nf, nf_bat);
 344        struct san_event_work *work;
 345        unsigned long delay = san_evt_bat_delay(event->command_id);
 346
 347        if (delay == 0)
 348                return san_evt_bat(event, d->dev) ? SSAM_NOTIF_HANDLED : 0;
 349
 350        work = kzalloc(sizeof(*work) + event->length, GFP_KERNEL);
 351        if (!work)
 352                return ssam_notifier_from_errno(-ENOMEM);
 353
 354        INIT_DELAYED_WORK(&work->work, san_evt_bat_workfn);
 355        work->dev = d->dev;
 356
 357        memcpy(&work->event, event, sizeof(struct ssam_event) + event->length);
 358
 359        schedule_delayed_work(&work->work, delay);
 360        return SSAM_NOTIF_HANDLED;
 361}
 362
 363static int san_evt_tmp_trip(struct device *dev, const struct ssam_event *event)
 364{
 365        union acpi_object param;
 366
 367        /*
 368         * The Surface ACPI expects an integer and not a package. This will
 369         * cause a warning in acpica/nsarguments.c, but that warning can be
 370         * safely ignored.
 371         */
 372        param.type = ACPI_TYPE_INTEGER;
 373        param.integer.value = event->instance_id;
 374
 375        return san_acpi_notify_event(dev, SAN_DSM_EVENT_FN_THERMAL, &param);
 376}
 377
 378static bool san_evt_tmp(const struct ssam_event *event, struct device *dev)
 379{
 380        int status;
 381
 382        switch (event->command_id) {
 383        case SAM_EVENT_CID_TMP_TRIP:
 384                status = san_evt_tmp_trip(dev, event);
 385                break;
 386
 387        default:
 388                return false;
 389        }
 390
 391        if (status) {
 392                dev_err(dev, "error handling thermal event (cid = %#04x)\n",
 393                        event->command_id);
 394        }
 395
 396        return true;
 397}
 398
 399static u32 san_evt_tmp_nf(struct ssam_event_notifier *nf,
 400                          const struct ssam_event *event)
 401{
 402        struct san_data *d = to_san_data(nf, nf_tmp);
 403
 404        return san_evt_tmp(event, d->dev) ? SSAM_NOTIF_HANDLED : 0;
 405}
 406
 407
 408/* -- ACPI GSB OperationRegion handler -------------------------------------- */
 409
 410struct gsb_data_in {
 411        u8 cv;
 412} __packed;
 413
 414struct gsb_data_rqsx {
 415        u8 cv;                          /* Command value (san_gsb_request_cv). */
 416        u8 tc;                          /* Target category. */
 417        u8 tid;                         /* Target ID. */
 418        u8 iid;                         /* Instance ID. */
 419        u8 snc;                         /* Expect-response-flag. */
 420        u8 cid;                         /* Command ID. */
 421        u16 cdl;                        /* Payload length. */
 422        u8 pld[];                       /* Payload. */
 423} __packed;
 424
 425struct gsb_data_etwl {
 426        u8 cv;                          /* Command value (should be 0x02). */
 427        u8 etw3;                        /* Unknown. */
 428        u8 etw4;                        /* Unknown. */
 429        u8 msg[];                       /* Error message (ASCIIZ). */
 430} __packed;
 431
 432struct gsb_data_out {
 433        u8 status;                      /* _SSH communication status. */
 434        u8 len;                         /* _SSH payload length. */
 435        u8 pld[];                       /* _SSH payload. */
 436} __packed;
 437
 438union gsb_buffer_data {
 439        struct gsb_data_in   in;        /* Common input. */
 440        struct gsb_data_rqsx rqsx;      /* RQSX input. */
 441        struct gsb_data_etwl etwl;      /* ETWL input. */
 442        struct gsb_data_out  out;       /* Output. */
 443};
 444
 445struct gsb_buffer {
 446        u8 status;                      /* GSB AttribRawProcess status. */
 447        u8 len;                         /* GSB AttribRawProcess length. */
 448        union gsb_buffer_data data;
 449} __packed;
 450
 451#define SAN_GSB_MAX_RQSX_PAYLOAD  (U8_MAX - 2 - sizeof(struct gsb_data_rqsx))
 452#define SAN_GSB_MAX_RESPONSE      (U8_MAX - 2 - sizeof(struct gsb_data_out))
 453
 454#define SAN_GSB_COMMAND         0
 455
 456enum san_gsb_request_cv {
 457        SAN_GSB_REQUEST_CV_RQST = 0x01,
 458        SAN_GSB_REQUEST_CV_ETWL = 0x02,
 459        SAN_GSB_REQUEST_CV_RQSG = 0x03,
 460};
 461
 462#define SAN_REQUEST_NUM_TRIES   5
 463
 464static acpi_status san_etwl(struct san_data *d, struct gsb_buffer *b)
 465{
 466        struct gsb_data_etwl *etwl = &b->data.etwl;
 467
 468        if (b->len < sizeof(struct gsb_data_etwl)) {
 469                dev_err(d->dev, "invalid ETWL package (len = %d)\n", b->len);
 470                return AE_OK;
 471        }
 472
 473        dev_err(d->dev, "ETWL(%#04x, %#04x): %.*s\n", etwl->etw3, etwl->etw4,
 474                (unsigned int)(b->len - sizeof(struct gsb_data_etwl)),
 475                (char *)etwl->msg);
 476
 477        /* Indicate success. */
 478        b->status = 0x00;
 479        b->len = 0x00;
 480
 481        return AE_OK;
 482}
 483
 484static
 485struct gsb_data_rqsx *san_validate_rqsx(struct device *dev, const char *type,
 486                                        struct gsb_buffer *b)
 487{
 488        struct gsb_data_rqsx *rqsx = &b->data.rqsx;
 489
 490        if (b->len < sizeof(struct gsb_data_rqsx)) {
 491                dev_err(dev, "invalid %s package (len = %d)\n", type, b->len);
 492                return NULL;
 493        }
 494
 495        if (get_unaligned(&rqsx->cdl) != b->len - sizeof(struct gsb_data_rqsx)) {
 496                dev_err(dev, "bogus %s package (len = %d, cdl = %d)\n",
 497                        type, b->len, get_unaligned(&rqsx->cdl));
 498                return NULL;
 499        }
 500
 501        if (get_unaligned(&rqsx->cdl) > SAN_GSB_MAX_RQSX_PAYLOAD) {
 502                dev_err(dev, "payload for %s package too large (cdl = %d)\n",
 503                        type, get_unaligned(&rqsx->cdl));
 504                return NULL;
 505        }
 506
 507        return rqsx;
 508}
 509
 510static void gsb_rqsx_response_error(struct gsb_buffer *gsb, int status)
 511{
 512        gsb->status = 0x00;
 513        gsb->len = 0x02;
 514        gsb->data.out.status = (u8)(-status);
 515        gsb->data.out.len = 0x00;
 516}
 517
 518static void gsb_rqsx_response_success(struct gsb_buffer *gsb, u8 *ptr, size_t len)
 519{
 520        gsb->status = 0x00;
 521        gsb->len = len + 2;
 522        gsb->data.out.status = 0x00;
 523        gsb->data.out.len = len;
 524
 525        if (len)
 526                memcpy(&gsb->data.out.pld[0], ptr, len);
 527}
 528
 529static acpi_status san_rqst_fixup_suspended(struct san_data *d,
 530                                            struct ssam_request *rqst,
 531                                            struct gsb_buffer *gsb)
 532{
 533        if (rqst->target_category == SSAM_SSH_TC_BAS && rqst->command_id == 0x0D) {
 534                u8 base_state = 1;
 535
 536                /* Base state quirk:
 537                 * The base state may be queried from ACPI when the EC is still
 538                 * suspended. In this case it will return '-EPERM'. This query
 539                 * will only be triggered from the ACPI lid GPE interrupt, thus
 540                 * we are either in laptop or studio mode (base status 0x01 or
 541                 * 0x02). Furthermore, we will only get here if the device (and
 542                 * EC) have been suspended.
 543                 *
 544                 * We now assume that the device is in laptop mode (0x01). This
 545                 * has the drawback that it will wake the device when unfolding
 546                 * it in studio mode, but it also allows us to avoid actively
 547                 * waiting for the EC to wake up, which may incur a notable
 548                 * delay.
 549                 */
 550
 551                dev_dbg(d->dev, "rqst: fixup: base-state quirk\n");
 552
 553                gsb_rqsx_response_success(gsb, &base_state, sizeof(base_state));
 554                return AE_OK;
 555        }
 556
 557        gsb_rqsx_response_error(gsb, -ENXIO);
 558        return AE_OK;
 559}
 560
 561static acpi_status san_rqst(struct san_data *d, struct gsb_buffer *buffer)
 562{
 563        u8 rspbuf[SAN_GSB_MAX_RESPONSE];
 564        struct gsb_data_rqsx *gsb_rqst;
 565        struct ssam_request rqst;
 566        struct ssam_response rsp;
 567        int status = 0;
 568
 569        gsb_rqst = san_validate_rqsx(d->dev, "RQST", buffer);
 570        if (!gsb_rqst)
 571                return AE_OK;
 572
 573        rqst.target_category = gsb_rqst->tc;
 574        rqst.target_id = gsb_rqst->tid;
 575        rqst.command_id = gsb_rqst->cid;
 576        rqst.instance_id = gsb_rqst->iid;
 577        rqst.flags = gsb_rqst->snc ? SSAM_REQUEST_HAS_RESPONSE : 0;
 578        rqst.length = get_unaligned(&gsb_rqst->cdl);
 579        rqst.payload = &gsb_rqst->pld[0];
 580
 581        rsp.capacity = ARRAY_SIZE(rspbuf);
 582        rsp.length = 0;
 583        rsp.pointer = &rspbuf[0];
 584
 585        /* Handle suspended device. */
 586        if (d->dev->power.is_suspended) {
 587                dev_warn(d->dev, "rqst: device is suspended, not executing\n");
 588                return san_rqst_fixup_suspended(d, &rqst, buffer);
 589        }
 590
 591        status = __ssam_retry(ssam_request_sync_onstack, SAN_REQUEST_NUM_TRIES,
 592                              d->ctrl, &rqst, &rsp, SAN_GSB_MAX_RQSX_PAYLOAD);
 593
 594        if (!status) {
 595                gsb_rqsx_response_success(buffer, rsp.pointer, rsp.length);
 596        } else {
 597                dev_err(d->dev, "rqst: failed with error %d\n", status);
 598                gsb_rqsx_response_error(buffer, status);
 599        }
 600
 601        return AE_OK;
 602}
 603
 604static acpi_status san_rqsg(struct san_data *d, struct gsb_buffer *buffer)
 605{
 606        struct gsb_data_rqsx *gsb_rqsg;
 607        struct san_dgpu_event evt;
 608        int status;
 609
 610        gsb_rqsg = san_validate_rqsx(d->dev, "RQSG", buffer);
 611        if (!gsb_rqsg)
 612                return AE_OK;
 613
 614        evt.category = gsb_rqsg->tc;
 615        evt.target = gsb_rqsg->tid;
 616        evt.command = gsb_rqsg->cid;
 617        evt.instance = gsb_rqsg->iid;
 618        evt.length = get_unaligned(&gsb_rqsg->cdl);
 619        evt.payload = &gsb_rqsg->pld[0];
 620
 621        status = san_dgpu_notifier_call(&evt);
 622        if (!status) {
 623                gsb_rqsx_response_success(buffer, NULL, 0);
 624        } else {
 625                dev_err(d->dev, "rqsg: failed with error %d\n", status);
 626                gsb_rqsx_response_error(buffer, status);
 627        }
 628
 629        return AE_OK;
 630}
 631
 632static acpi_status san_opreg_handler(u32 function, acpi_physical_address command,
 633                                     u32 bits, u64 *value64, void *opreg_context,
 634                                     void *region_context)
 635{
 636        struct san_data *d = to_san_data(opreg_context, info);
 637        struct gsb_buffer *buffer = (struct gsb_buffer *)value64;
 638        int accessor_type = (function & 0xFFFF0000) >> 16;
 639
 640        if (command != SAN_GSB_COMMAND) {
 641                dev_warn(d->dev, "unsupported command: %#04llx\n", command);
 642                return AE_OK;
 643        }
 644
 645        if (accessor_type != ACPI_GSB_ACCESS_ATTRIB_RAW_PROCESS) {
 646                dev_err(d->dev, "invalid access type: %#04x\n", accessor_type);
 647                return AE_OK;
 648        }
 649
 650        /* Buffer must have at least contain the command-value. */
 651        if (buffer->len == 0) {
 652                dev_err(d->dev, "request-package too small\n");
 653                return AE_OK;
 654        }
 655
 656        switch (buffer->data.in.cv) {
 657        case SAN_GSB_REQUEST_CV_RQST:
 658                return san_rqst(d, buffer);
 659
 660        case SAN_GSB_REQUEST_CV_ETWL:
 661                return san_etwl(d, buffer);
 662
 663        case SAN_GSB_REQUEST_CV_RQSG:
 664                return san_rqsg(d, buffer);
 665
 666        default:
 667                dev_warn(d->dev, "unsupported SAN0 request (cv: %#04x)\n",
 668                         buffer->data.in.cv);
 669                return AE_OK;
 670        }
 671}
 672
 673
 674/* -- Driver setup. --------------------------------------------------------- */
 675
 676static int san_events_register(struct platform_device *pdev)
 677{
 678        struct san_data *d = platform_get_drvdata(pdev);
 679        int status;
 680
 681        d->nf_bat.base.priority = 1;
 682        d->nf_bat.base.fn = san_evt_bat_nf;
 683        d->nf_bat.event.reg = SSAM_EVENT_REGISTRY_SAM;
 684        d->nf_bat.event.id.target_category = SSAM_SSH_TC_BAT;
 685        d->nf_bat.event.id.instance = 0;
 686        d->nf_bat.event.mask = SSAM_EVENT_MASK_TARGET;
 687        d->nf_bat.event.flags = SSAM_EVENT_SEQUENCED;
 688
 689        d->nf_tmp.base.priority = 1;
 690        d->nf_tmp.base.fn = san_evt_tmp_nf;
 691        d->nf_tmp.event.reg = SSAM_EVENT_REGISTRY_SAM;
 692        d->nf_tmp.event.id.target_category = SSAM_SSH_TC_TMP;
 693        d->nf_tmp.event.id.instance = 0;
 694        d->nf_tmp.event.mask = SSAM_EVENT_MASK_TARGET;
 695        d->nf_tmp.event.flags = SSAM_EVENT_SEQUENCED;
 696
 697        status = ssam_notifier_register(d->ctrl, &d->nf_bat);
 698        if (status)
 699                return status;
 700
 701        status = ssam_notifier_register(d->ctrl, &d->nf_tmp);
 702        if (status)
 703                ssam_notifier_unregister(d->ctrl, &d->nf_bat);
 704
 705        return status;
 706}
 707
 708static void san_events_unregister(struct platform_device *pdev)
 709{
 710        struct san_data *d = platform_get_drvdata(pdev);
 711
 712        ssam_notifier_unregister(d->ctrl, &d->nf_bat);
 713        ssam_notifier_unregister(d->ctrl, &d->nf_tmp);
 714}
 715
 716#define san_consumer_printk(level, dev, handle, fmt, ...)                       \
 717do {                                                                            \
 718        char *path = "<error getting consumer path>";                           \
 719        struct acpi_buffer buffer = {                                           \
 720                .length = ACPI_ALLOCATE_BUFFER,                                 \
 721                .pointer = NULL,                                                \
 722        };                                                                      \
 723                                                                                \
 724        if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer)))   \
 725                path = buffer.pointer;                                          \
 726                                                                                \
 727        dev_##level(dev, "[%s]: " fmt, path, ##__VA_ARGS__);                    \
 728        kfree(buffer.pointer);                                                  \
 729} while (0)
 730
 731#define san_consumer_dbg(dev, handle, fmt, ...) \
 732        san_consumer_printk(dbg, dev, handle, fmt, ##__VA_ARGS__)
 733
 734#define san_consumer_warn(dev, handle, fmt, ...) \
 735        san_consumer_printk(warn, dev, handle, fmt, ##__VA_ARGS__)
 736
 737static bool is_san_consumer(struct platform_device *pdev, acpi_handle handle)
 738{
 739        struct acpi_handle_list dep_devices;
 740        acpi_handle supplier = ACPI_HANDLE(&pdev->dev);
 741        acpi_status status;
 742        int i;
 743
 744        if (!acpi_has_method(handle, "_DEP"))
 745                return false;
 746
 747        status = acpi_evaluate_reference(handle, "_DEP", NULL, &dep_devices);
 748        if (ACPI_FAILURE(status)) {
 749                san_consumer_dbg(&pdev->dev, handle, "failed to evaluate _DEP\n");
 750                return false;
 751        }
 752
 753        for (i = 0; i < dep_devices.count; i++) {
 754                if (dep_devices.handles[i] == supplier)
 755                        return true;
 756        }
 757
 758        return false;
 759}
 760
 761static acpi_status san_consumer_setup(acpi_handle handle, u32 lvl,
 762                                      void *context, void **rv)
 763{
 764        const u32 flags = DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER;
 765        struct platform_device *pdev = context;
 766        struct acpi_device *adev;
 767        struct device_link *link;
 768
 769        if (!is_san_consumer(pdev, handle))
 770                return AE_OK;
 771
 772        /* Ignore ACPI devices that are not present. */
 773        if (acpi_bus_get_device(handle, &adev) != 0)
 774                return AE_OK;
 775
 776        san_consumer_dbg(&pdev->dev, handle, "creating device link\n");
 777
 778        /* Try to set up device links, ignore but log errors. */
 779        link = device_link_add(&adev->dev, &pdev->dev, flags);
 780        if (!link) {
 781                san_consumer_warn(&pdev->dev, handle, "failed to create device link\n");
 782                return AE_OK;
 783        }
 784
 785        return AE_OK;
 786}
 787
 788static int san_consumer_links_setup(struct platform_device *pdev)
 789{
 790        acpi_status status;
 791
 792        status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
 793                                     ACPI_UINT32_MAX, san_consumer_setup, NULL,
 794                                     pdev, NULL);
 795
 796        return status ? -EFAULT : 0;
 797}
 798
 799static int san_probe(struct platform_device *pdev)
 800{
 801        struct acpi_device *san = ACPI_COMPANION(&pdev->dev);
 802        struct ssam_controller *ctrl;
 803        struct san_data *data;
 804        acpi_status astatus;
 805        int status;
 806
 807        ctrl = ssam_client_bind(&pdev->dev);
 808        if (IS_ERR(ctrl))
 809                return PTR_ERR(ctrl) == -ENODEV ? -EPROBE_DEFER : PTR_ERR(ctrl);
 810
 811        status = san_consumer_links_setup(pdev);
 812        if (status)
 813                return status;
 814
 815        data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
 816        if (!data)
 817                return -ENOMEM;
 818
 819        data->dev = &pdev->dev;
 820        data->ctrl = ctrl;
 821
 822        platform_set_drvdata(pdev, data);
 823
 824        astatus = acpi_install_address_space_handler(san->handle,
 825                                                     ACPI_ADR_SPACE_GSBUS,
 826                                                     &san_opreg_handler, NULL,
 827                                                     &data->info);
 828        if (ACPI_FAILURE(astatus))
 829                return -ENXIO;
 830
 831        status = san_events_register(pdev);
 832        if (status)
 833                goto err_enable_events;
 834
 835        status = san_set_rqsg_interface_device(&pdev->dev);
 836        if (status)
 837                goto err_install_dev;
 838
 839        acpi_dev_clear_dependencies(san);
 840        return 0;
 841
 842err_install_dev:
 843        san_events_unregister(pdev);
 844err_enable_events:
 845        acpi_remove_address_space_handler(san, ACPI_ADR_SPACE_GSBUS,
 846                                          &san_opreg_handler);
 847        return status;
 848}
 849
 850static int san_remove(struct platform_device *pdev)
 851{
 852        acpi_handle san = ACPI_HANDLE(&pdev->dev);
 853
 854        san_set_rqsg_interface_device(NULL);
 855        acpi_remove_address_space_handler(san, ACPI_ADR_SPACE_GSBUS,
 856                                          &san_opreg_handler);
 857        san_events_unregister(pdev);
 858
 859        /*
 860         * We have unregistered our event sources. Now we need to ensure that
 861         * all delayed works they may have spawned are run to completion.
 862         */
 863        flush_scheduled_work();
 864
 865        return 0;
 866}
 867
 868static const struct acpi_device_id san_match[] = {
 869        { "MSHW0091" },
 870        { },
 871};
 872MODULE_DEVICE_TABLE(acpi, san_match);
 873
 874static struct platform_driver surface_acpi_notify = {
 875        .probe = san_probe,
 876        .remove = san_remove,
 877        .driver = {
 878                .name = "surface_acpi_notify",
 879                .acpi_match_table = san_match,
 880                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
 881        },
 882};
 883module_platform_driver(surface_acpi_notify);
 884
 885MODULE_AUTHOR("Maximilian Luz <luzmaximilian@gmail.com>");
 886MODULE_DESCRIPTION("Surface ACPI Notify driver for Surface System Aggregator Module");
 887MODULE_LICENSE("GPL");
 888