surface_acpi_notify.c (23026B)
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, ¶m); 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 adev = acpi_fetch_acpi_dev(handle); 774 if (!adev) 775 return AE_OK; 776 777 san_consumer_dbg(&pdev->dev, handle, "creating device link\n"); 778 779 /* Try to set up device links, ignore but log errors. */ 780 link = device_link_add(&adev->dev, &pdev->dev, flags); 781 if (!link) { 782 san_consumer_warn(&pdev->dev, handle, "failed to create device link\n"); 783 return AE_OK; 784 } 785 786 return AE_OK; 787} 788 789static int san_consumer_links_setup(struct platform_device *pdev) 790{ 791 acpi_status status; 792 793 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 794 ACPI_UINT32_MAX, san_consumer_setup, NULL, 795 pdev, NULL); 796 797 return status ? -EFAULT : 0; 798} 799 800static int san_probe(struct platform_device *pdev) 801{ 802 struct acpi_device *san = ACPI_COMPANION(&pdev->dev); 803 struct ssam_controller *ctrl; 804 struct san_data *data; 805 acpi_status astatus; 806 int status; 807 808 ctrl = ssam_client_bind(&pdev->dev); 809 if (IS_ERR(ctrl)) 810 return PTR_ERR(ctrl) == -ENODEV ? -EPROBE_DEFER : PTR_ERR(ctrl); 811 812 status = san_consumer_links_setup(pdev); 813 if (status) 814 return status; 815 816 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 817 if (!data) 818 return -ENOMEM; 819 820 data->dev = &pdev->dev; 821 data->ctrl = ctrl; 822 823 platform_set_drvdata(pdev, data); 824 825 astatus = acpi_install_address_space_handler(san->handle, 826 ACPI_ADR_SPACE_GSBUS, 827 &san_opreg_handler, NULL, 828 &data->info); 829 if (ACPI_FAILURE(astatus)) 830 return -ENXIO; 831 832 status = san_events_register(pdev); 833 if (status) 834 goto err_enable_events; 835 836 status = san_set_rqsg_interface_device(&pdev->dev); 837 if (status) 838 goto err_install_dev; 839 840 acpi_dev_clear_dependencies(san); 841 return 0; 842 843err_install_dev: 844 san_events_unregister(pdev); 845err_enable_events: 846 acpi_remove_address_space_handler(san, ACPI_ADR_SPACE_GSBUS, 847 &san_opreg_handler); 848 return status; 849} 850 851static int san_remove(struct platform_device *pdev) 852{ 853 acpi_handle san = ACPI_HANDLE(&pdev->dev); 854 855 san_set_rqsg_interface_device(NULL); 856 acpi_remove_address_space_handler(san, ACPI_ADR_SPACE_GSBUS, 857 &san_opreg_handler); 858 san_events_unregister(pdev); 859 860 /* 861 * We have unregistered our event sources. Now we need to ensure that 862 * all delayed works they may have spawned are run to completion. 863 */ 864 flush_scheduled_work(); 865 866 return 0; 867} 868 869static const struct acpi_device_id san_match[] = { 870 { "MSHW0091" }, 871 { }, 872}; 873MODULE_DEVICE_TABLE(acpi, san_match); 874 875static struct platform_driver surface_acpi_notify = { 876 .probe = san_probe, 877 .remove = san_remove, 878 .driver = { 879 .name = "surface_acpi_notify", 880 .acpi_match_table = san_match, 881 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 882 }, 883}; 884module_platform_driver(surface_acpi_notify); 885 886MODULE_AUTHOR("Maximilian Luz <luzmaximilian@gmail.com>"); 887MODULE_DESCRIPTION("Surface ACPI Notify driver for Surface System Aggregator Module"); 888MODULE_LICENSE("GPL");