1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Surface Serial Hub (SSH) driver for communication with the Surface/System 4 * Aggregator Module (SSAM/SAM). 5 * 6 * Provides access to a SAM-over-SSH connected EC via a controller device. 7 * Handles communication via requests as well as enabling, disabling, and 8 * relaying of events. 9 * 10 * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com> 11 */ 12 13 #include <linux/acpi.h> 14 #include <linux/atomic.h> 15 #include <linux/completion.h> 16 #include <linux/gpio/consumer.h> 17 #include <linux/kernel.h> 18 #include <linux/kref.h> 19 #include <linux/module.h> 20 #include <linux/pm.h> 21 #include <linux/serdev.h> 22 #include <linux/sysfs.h> 23 24 #include <linux/surface_aggregator/controller.h> 25 26 #include "bus.h" 27 #include "controller.h" 28 29 #define CREATE_TRACE_POINTS 30 #include "trace.h" 31 32 33 /* -- Static controller reference. ------------------------------------------ */ 34 35 /* 36 * Main controller reference. The corresponding lock must be held while 37 * accessing (reading/writing) the reference. 38 */ 39 static struct ssam_controller *__ssam_controller; 40 static DEFINE_SPINLOCK(__ssam_controller_lock); 41 42 /** 43 * ssam_get_controller() - Get reference to SSAM controller. 44 * 45 * Returns a reference to the SSAM controller of the system or %NULL if there 46 * is none, it hasn't been set up yet, or it has already been unregistered. 47 * This function automatically increments the reference count of the 48 * controller, thus the calling party must ensure that ssam_controller_put() 49 * is called when it doesn't need the controller any more. 50 */ 51 struct ssam_controller *ssam_get_controller(void) 52 { 53 struct ssam_controller *ctrl; 54 55 spin_lock(&__ssam_controller_lock); 56 57 ctrl = __ssam_controller; 58 if (!ctrl) 59 goto out; 60 61 if (WARN_ON(!kref_get_unless_zero(&ctrl->kref))) 62 ctrl = NULL; 63 64 out: 65 spin_unlock(&__ssam_controller_lock); 66 return ctrl; 67 } 68 EXPORT_SYMBOL_GPL(ssam_get_controller); 69 70 /** 71 * ssam_try_set_controller() - Try to set the main controller reference. 72 * @ctrl: The controller to which the reference should point. 73 * 74 * Set the main controller reference to the given pointer if the reference 75 * hasn't been set already. 76 * 77 * Return: Returns zero on success or %-EEXIST if the reference has already 78 * been set. 79 */ 80 static int ssam_try_set_controller(struct ssam_controller *ctrl) 81 { 82 int status = 0; 83 84 spin_lock(&__ssam_controller_lock); 85 if (!__ssam_controller) 86 __ssam_controller = ctrl; 87 else 88 status = -EEXIST; 89 spin_unlock(&__ssam_controller_lock); 90 91 return status; 92 } 93 94 /** 95 * ssam_clear_controller() - Remove/clear the main controller reference. 96 * 97 * Clears the main controller reference, i.e. sets it to %NULL. This function 98 * should be called before the controller is shut down. 99 */ 100 static void ssam_clear_controller(void) 101 { 102 spin_lock(&__ssam_controller_lock); 103 __ssam_controller = NULL; 104 spin_unlock(&__ssam_controller_lock); 105 } 106 107 /** 108 * ssam_client_link() - Link an arbitrary client device to the controller. 109 * @c: The controller to link to. 110 * @client: The client device. 111 * 112 * Link an arbitrary client device to the controller by creating a device link 113 * between it as consumer and the controller device as provider. This function 114 * can be used for non-SSAM devices (or SSAM devices not registered as child 115 * under the controller) to guarantee that the controller is valid for as long 116 * as the driver of the client device is bound, and that proper suspend and 117 * resume ordering is guaranteed. 118 * 119 * The device link does not have to be destructed manually. It is removed 120 * automatically once the driver of the client device unbinds. 121 * 122 * Return: Returns zero on success, %-ENODEV if the controller is not ready or 123 * going to be removed soon, or %-ENOMEM if the device link could not be 124 * created for other reasons. 125 */ 126 int ssam_client_link(struct ssam_controller *c, struct device *client) 127 { 128 const u32 flags = DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_CONSUMER; 129 struct device_link *link; 130 struct device *ctrldev; 131 132 ssam_controller_statelock(c); 133 134 if (c->state != SSAM_CONTROLLER_STARTED) { 135 ssam_controller_stateunlock(c); 136 return -ENODEV; 137 } 138 139 ctrldev = ssam_controller_device(c); 140 if (!ctrldev) { 141 ssam_controller_stateunlock(c); 142 return -ENODEV; 143 } 144 145 link = device_link_add(client, ctrldev, flags); 146 if (!link) { 147 ssam_controller_stateunlock(c); 148 return -ENOMEM; 149 } 150 151 /* 152 * Return -ENODEV if supplier driver is on its way to be removed. In 153 * this case, the controller won't be around for much longer and the 154 * device link is not going to save us any more, as unbinding is 155 * already in progress. 156 */ 157 if (READ_ONCE(link->status) == DL_STATE_SUPPLIER_UNBIND) { 158 ssam_controller_stateunlock(c); 159 return -ENODEV; 160 } 161 162 ssam_controller_stateunlock(c); 163 return 0; 164 } 165 EXPORT_SYMBOL_GPL(ssam_client_link); 166 167 /** 168 * ssam_client_bind() - Bind an arbitrary client device to the controller. 169 * @client: The client device. 170 * 171 * Link an arbitrary client device to the controller by creating a device link 172 * between it as consumer and the main controller device as provider. This 173 * function can be used for non-SSAM devices to guarantee that the controller 174 * returned by this function is valid for as long as the driver of the client 175 * device is bound, and that proper suspend and resume ordering is guaranteed. 176 * 177 * This function does essentially the same as ssam_client_link(), except that 178 * it first fetches the main controller reference, then creates the link, and 179 * finally returns this reference. Note that this function does not increment 180 * the reference counter of the controller, as, due to the link, the 181 * controller lifetime is assured as long as the driver of the client device 182 * is bound. 183 * 184 * It is not valid to use the controller reference obtained by this method 185 * outside of the driver bound to the client device at the time of calling 186 * this function, without first incrementing the reference count of the 187 * controller via ssam_controller_get(). Even after doing this, care must be 188 * taken that requests are only submitted and notifiers are only 189 * (un-)registered when the controller is active and not suspended. In other 190 * words: The device link only lives as long as the client driver is bound and 191 * any guarantees enforced by this link (e.g. active controller state) can 192 * only be relied upon as long as this link exists and may need to be enforced 193 * in other ways afterwards. 194 * 195 * The created device link does not have to be destructed manually. It is 196 * removed automatically once the driver of the client device unbinds. 197 * 198 * Return: Returns the controller on success, an error pointer with %-ENODEV 199 * if the controller is not present, not ready or going to be removed soon, or 200 * %-ENOMEM if the device link could not be created for other reasons. 201 */ 202 struct ssam_controller *ssam_client_bind(struct device *client) 203 { 204 struct ssam_controller *c; 205 int status; 206 207 c = ssam_get_controller(); 208 if (!c) 209 return ERR_PTR(-ENODEV); 210 211 status = ssam_client_link(c, client); 212 213 /* 214 * Note that we can drop our controller reference in both success and 215 * failure cases: On success, we have bound the controller lifetime 216 * inherently to the client driver lifetime, i.e. it the controller is 217 * now guaranteed to outlive the client driver. On failure, we're not 218 * going to use the controller any more. 219 */ 220 ssam_controller_put(c); 221 222 return status >= 0 ? c : ERR_PTR(status); 223 } 224 EXPORT_SYMBOL_GPL(ssam_client_bind); 225 226 227 /* -- Glue layer (serdev_device -> ssam_controller). ------------------------ */ 228 229 static int ssam_receive_buf(struct serdev_device *dev, const unsigned char *buf, 230 size_t n) 231 { 232 struct ssam_controller *ctrl; 233 234 ctrl = serdev_device_get_drvdata(dev); 235 return ssam_controller_receive_buf(ctrl, buf, n); 236 } 237 238 static void ssam_write_wakeup(struct serdev_device *dev) 239 { 240 ssam_controller_write_wakeup(serdev_device_get_drvdata(dev)); 241 } 242 243 static const struct serdev_device_ops ssam_serdev_ops = { 244 .receive_buf = ssam_receive_buf, 245 .write_wakeup = ssam_write_wakeup, 246 }; 247 248 249 /* -- SysFS and misc. ------------------------------------------------------- */ 250 251 static int ssam_log_firmware_version(struct ssam_controller *ctrl) 252 { 253 u32 version, a, b, c; 254 int status; 255 256 status = ssam_get_firmware_version(ctrl, &version); 257 if (status) 258 return status; 259 260 a = (version >> 24) & 0xff; 261 b = ((version >> 8) & 0xffff); 262 c = version & 0xff; 263 264 ssam_info(ctrl, "SAM firmware version: %u.%u.%u\n", a, b, c); 265 return 0; 266 } 267 268 static ssize_t firmware_version_show(struct device *dev, 269 struct device_attribute *attr, char *buf) 270 { 271 struct ssam_controller *ctrl = dev_get_drvdata(dev); 272 u32 version, a, b, c; 273 int status; 274 275 status = ssam_get_firmware_version(ctrl, &version); 276 if (status < 0) 277 return status; 278 279 a = (version >> 24) & 0xff; 280 b = ((version >> 8) & 0xffff); 281 c = version & 0xff; 282 283 return sysfs_emit(buf, "%u.%u.%u\n", a, b, c); 284 } 285 static DEVICE_ATTR_RO(firmware_version); 286 287 static struct attribute *ssam_sam_attrs[] = { 288 &dev_attr_firmware_version.attr, 289 NULL 290 }; 291 292 static const struct attribute_group ssam_sam_group = { 293 .name = "sam", 294 .attrs = ssam_sam_attrs, 295 }; 296 297 298 /* -- ACPI based device setup. ---------------------------------------------- */ 299 300 static acpi_status ssam_serdev_setup_via_acpi_crs(struct acpi_resource *rsc, 301 void *ctx) 302 { 303 struct serdev_device *serdev = ctx; 304 struct acpi_resource_common_serialbus *serial; 305 struct acpi_resource_uart_serialbus *uart; 306 bool flow_control; 307 int status = 0; 308 309 if (rsc->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) 310 return AE_OK; 311 312 serial = &rsc->data.common_serial_bus; 313 if (serial->type != ACPI_RESOURCE_SERIAL_TYPE_UART) 314 return AE_OK; 315 316 uart = &rsc->data.uart_serial_bus; 317 318 /* Set up serdev device. */ 319 serdev_device_set_baudrate(serdev, uart->default_baud_rate); 320 321 /* serdev currently only supports RTSCTS flow control. */ 322 if (uart->flow_control & (~((u8)ACPI_UART_FLOW_CONTROL_HW))) { 323 dev_warn(&serdev->dev, "setup: unsupported flow control (value: %#04x)\n", 324 uart->flow_control); 325 } 326 327 /* Set RTSCTS flow control. */ 328 flow_control = uart->flow_control & ACPI_UART_FLOW_CONTROL_HW; 329 serdev_device_set_flow_control(serdev, flow_control); 330 331 /* serdev currently only supports EVEN/ODD parity. */ 332 switch (uart->parity) { 333 case ACPI_UART_PARITY_NONE: 334 status = serdev_device_set_parity(serdev, SERDEV_PARITY_NONE); 335 break; 336 case ACPI_UART_PARITY_EVEN: 337 status = serdev_device_set_parity(serdev, SERDEV_PARITY_EVEN); 338 break; 339 case ACPI_UART_PARITY_ODD: 340 status = serdev_device_set_parity(serdev, SERDEV_PARITY_ODD); 341 break; 342 default: 343 dev_warn(&serdev->dev, "setup: unsupported parity (value: %#04x)\n", 344 uart->parity); 345 break; 346 } 347 348 if (status) { 349 dev_err(&serdev->dev, "setup: failed to set parity (value: %#04x, error: %d)\n", 350 uart->parity, status); 351 return AE_ERROR; 352 } 353 354 /* We've found the resource and are done. */ 355 return AE_CTRL_TERMINATE; 356 } 357 358 static acpi_status ssam_serdev_setup_via_acpi(acpi_handle handle, 359 struct serdev_device *serdev) 360 { 361 return acpi_walk_resources(handle, METHOD_NAME__CRS, 362 ssam_serdev_setup_via_acpi_crs, serdev); 363 } 364 365 366 /* -- Power management. ----------------------------------------------------- */ 367 368 static void ssam_serial_hub_shutdown(struct device *dev) 369 { 370 struct ssam_controller *c = dev_get_drvdata(dev); 371 int status; 372 373 /* 374 * Try to disable notifiers, signal display-off and D0-exit, ignore any 375 * errors. 376 * 377 * Note: It has not been established yet if this is actually 378 * necessary/useful for shutdown. 379 */ 380 381 status = ssam_notifier_disable_registered(c); 382 if (status) { 383 ssam_err(c, "pm: failed to disable notifiers for shutdown: %d\n", 384 status); 385 } 386 387 status = ssam_ctrl_notif_display_off(c); 388 if (status) 389 ssam_err(c, "pm: display-off notification failed: %d\n", status); 390 391 status = ssam_ctrl_notif_d0_exit(c); 392 if (status) 393 ssam_err(c, "pm: D0-exit notification failed: %d\n", status); 394 } 395 396 #ifdef CONFIG_PM_SLEEP 397 398 static int ssam_serial_hub_pm_prepare(struct device *dev) 399 { 400 struct ssam_controller *c = dev_get_drvdata(dev); 401 int status; 402 403 /* 404 * Try to signal display-off, This will quiesce events. 405 * 406 * Note: Signaling display-off/display-on should normally be done from 407 * some sort of display state notifier. As that is not available, 408 * signal it here. 409 */ 410 411 status = ssam_ctrl_notif_display_off(c); 412 if (status) 413 ssam_err(c, "pm: display-off notification failed: %d\n", status); 414 415 return status; 416 } 417 418 static void ssam_serial_hub_pm_complete(struct device *dev) 419 { 420 struct ssam_controller *c = dev_get_drvdata(dev); 421 int status; 422 423 /* 424 * Try to signal display-on. This will restore events. 425 * 426 * Note: Signaling display-off/display-on should normally be done from 427 * some sort of display state notifier. As that is not available, 428 * signal it here. 429 */ 430 431 status = ssam_ctrl_notif_display_on(c); 432 if (status) 433 ssam_err(c, "pm: display-on notification failed: %d\n", status); 434 } 435 436 static int ssam_serial_hub_pm_suspend(struct device *dev) 437 { 438 struct ssam_controller *c = dev_get_drvdata(dev); 439 int status; 440 441 /* 442 * Try to signal D0-exit, enable IRQ wakeup if specified. Abort on 443 * error. 444 */ 445 446 status = ssam_ctrl_notif_d0_exit(c); 447 if (status) { 448 ssam_err(c, "pm: D0-exit notification failed: %d\n", status); 449 goto err_notif; 450 } 451 452 status = ssam_irq_arm_for_wakeup(c); 453 if (status) 454 goto err_irq; 455 456 WARN_ON(ssam_controller_suspend(c)); 457 return 0; 458 459 err_irq: 460 ssam_ctrl_notif_d0_entry(c); 461 err_notif: 462 ssam_ctrl_notif_display_on(c); 463 return status; 464 } 465 466 static int ssam_serial_hub_pm_resume(struct device *dev) 467 { 468 struct ssam_controller *c = dev_get_drvdata(dev); 469 int status; 470 471 WARN_ON(ssam_controller_resume(c)); 472 473 /* 474 * Try to disable IRQ wakeup (if specified) and signal D0-entry. In 475 * case of errors, log them and try to restore normal operation state 476 * as far as possible. 477 * 478 * Note: Signaling display-off/display-on should normally be done from 479 * some sort of display state notifier. As that is not available, 480 * signal it here. 481 */ 482 483 ssam_irq_disarm_wakeup(c); 484 485 status = ssam_ctrl_notif_d0_entry(c); 486 if (status) 487 ssam_err(c, "pm: D0-entry notification failed: %d\n", status); 488 489 return 0; 490 } 491 492 static int ssam_serial_hub_pm_freeze(struct device *dev) 493 { 494 struct ssam_controller *c = dev_get_drvdata(dev); 495 int status; 496 497 /* 498 * During hibernation image creation, we only have to ensure that the 499 * EC doesn't send us any events. This is done via the display-off 500 * and D0-exit notifications. Note that this sets up the wakeup IRQ 501 * on the EC side, however, we have disabled it by default on our side 502 * and won't enable it here. 503 * 504 * See ssam_serial_hub_poweroff() for more details on the hibernation 505 * process. 506 */ 507 508 status = ssam_ctrl_notif_d0_exit(c); 509 if (status) { 510 ssam_err(c, "pm: D0-exit notification failed: %d\n", status); 511 ssam_ctrl_notif_display_on(c); 512 return status; 513 } 514 515 WARN_ON(ssam_controller_suspend(c)); 516 return 0; 517 } 518 519 static int ssam_serial_hub_pm_thaw(struct device *dev) 520 { 521 struct ssam_controller *c = dev_get_drvdata(dev); 522 int status; 523 524 WARN_ON(ssam_controller_resume(c)); 525 526 status = ssam_ctrl_notif_d0_entry(c); 527 if (status) 528 ssam_err(c, "pm: D0-exit notification failed: %d\n", status); 529 530 return status; 531 } 532 533 static int ssam_serial_hub_pm_poweroff(struct device *dev) 534 { 535 struct ssam_controller *c = dev_get_drvdata(dev); 536 int status; 537 538 /* 539 * When entering hibernation and powering off the system, the EC, at 540 * least on some models, may disable events. Without us taking care of 541 * that, this leads to events not being enabled/restored when the 542 * system resumes from hibernation, resulting SAM-HID subsystem devices 543 * (i.e. keyboard, touchpad) not working, AC-plug/AC-unplug events being 544 * gone, etc. 545 * 546 * To avoid these issues, we disable all registered events here (this is 547 * likely not actually required) and restore them during the drivers PM 548 * restore callback. 549 * 550 * Wakeup from the EC interrupt is not supported during hibernation, 551 * so don't arm the IRQ here. 552 */ 553 554 status = ssam_notifier_disable_registered(c); 555 if (status) { 556 ssam_err(c, "pm: failed to disable notifiers for hibernation: %d\n", 557 status); 558 return status; 559 } 560 561 status = ssam_ctrl_notif_d0_exit(c); 562 if (status) { 563 ssam_err(c, "pm: D0-exit notification failed: %d\n", status); 564 ssam_notifier_restore_registered(c); 565 return status; 566 } 567 568 WARN_ON(ssam_controller_suspend(c)); 569 return 0; 570 } 571 572 static int ssam_serial_hub_pm_restore(struct device *dev) 573 { 574 struct ssam_controller *c = dev_get_drvdata(dev); 575 int status; 576 577 /* 578 * Ignore but log errors, try to restore state as much as possible in 579 * case of failures. See ssam_serial_hub_poweroff() for more details on 580 * the hibernation process. 581 */ 582 583 WARN_ON(ssam_controller_resume(c)); 584 585 status = ssam_ctrl_notif_d0_entry(c); 586 if (status) 587 ssam_err(c, "pm: D0-entry notification failed: %d\n", status); 588 589 ssam_notifier_restore_registered(c); 590 return 0; 591 } 592 593 static const struct dev_pm_ops ssam_serial_hub_pm_ops = { 594 .prepare = ssam_serial_hub_pm_prepare, 595 .complete = ssam_serial_hub_pm_complete, 596 .suspend = ssam_serial_hub_pm_suspend, 597 .resume = ssam_serial_hub_pm_resume, 598 .freeze = ssam_serial_hub_pm_freeze, 599 .thaw = ssam_serial_hub_pm_thaw, 600 .poweroff = ssam_serial_hub_pm_poweroff, 601 .restore = ssam_serial_hub_pm_restore, 602 }; 603 604 #else /* CONFIG_PM_SLEEP */ 605 606 static const struct dev_pm_ops ssam_serial_hub_pm_ops = { }; 607 608 #endif /* CONFIG_PM_SLEEP */ 609 610 611 /* -- Device/driver setup. -------------------------------------------------- */ 612 613 static const struct acpi_gpio_params gpio_ssam_wakeup_int = { 0, 0, false }; 614 static const struct acpi_gpio_params gpio_ssam_wakeup = { 1, 0, false }; 615 616 static const struct acpi_gpio_mapping ssam_acpi_gpios[] = { 617 { "ssam_wakeup-int-gpio", &gpio_ssam_wakeup_int, 1 }, 618 { "ssam_wakeup-gpio", &gpio_ssam_wakeup, 1 }, 619 { }, 620 }; 621 622 static int ssam_serial_hub_probe(struct serdev_device *serdev) 623 { 624 struct ssam_controller *ctrl; 625 acpi_handle *ssh = ACPI_HANDLE(&serdev->dev); 626 acpi_status astatus; 627 int status; 628 629 if (gpiod_count(&serdev->dev, NULL) < 0) 630 return -ENODEV; 631 632 status = devm_acpi_dev_add_driver_gpios(&serdev->dev, ssam_acpi_gpios); 633 if (status) 634 return status; 635 636 /* Allocate controller. */ 637 ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); 638 if (!ctrl) 639 return -ENOMEM; 640 641 /* Initialize controller. */ 642 status = ssam_controller_init(ctrl, serdev); 643 if (status) 644 goto err_ctrl_init; 645 646 ssam_controller_lock(ctrl); 647 648 /* Set up serdev device. */ 649 serdev_device_set_drvdata(serdev, ctrl); 650 serdev_device_set_client_ops(serdev, &ssam_serdev_ops); 651 status = serdev_device_open(serdev); 652 if (status) 653 goto err_devopen; 654 655 astatus = ssam_serdev_setup_via_acpi(ssh, serdev); 656 if (ACPI_FAILURE(astatus)) { 657 status = -ENXIO; 658 goto err_devinit; 659 } 660 661 /* Start controller. */ 662 status = ssam_controller_start(ctrl); 663 if (status) 664 goto err_devinit; 665 666 ssam_controller_unlock(ctrl); 667 668 /* 669 * Initial SAM requests: Log version and notify default/init power 670 * states. 671 */ 672 status = ssam_log_firmware_version(ctrl); 673 if (status) 674 goto err_initrq; 675 676 status = ssam_ctrl_notif_d0_entry(ctrl); 677 if (status) 678 goto err_initrq; 679 680 status = ssam_ctrl_notif_display_on(ctrl); 681 if (status) 682 goto err_initrq; 683 684 status = sysfs_create_group(&serdev->dev.kobj, &ssam_sam_group); 685 if (status) 686 goto err_initrq; 687 688 /* Set up IRQ. */ 689 status = ssam_irq_setup(ctrl); 690 if (status) 691 goto err_irq; 692 693 /* Finally, set main controller reference. */ 694 status = ssam_try_set_controller(ctrl); 695 if (WARN_ON(status)) /* Currently, we're the only provider. */ 696 goto err_mainref; 697 698 /* 699 * TODO: The EC can wake up the system via the associated GPIO interrupt 700 * in multiple situations. One of which is the remaining battery 701 * capacity falling below a certain threshold. Normally, we should 702 * use the device_init_wakeup function, however, the EC also seems 703 * to have other reasons for waking up the system and it seems 704 * that Windows has additional checks whether the system should be 705 * resumed. In short, this causes some spurious unwanted wake-ups. 706 * For now let's thus default power/wakeup to false. 707 */ 708 device_set_wakeup_capable(&serdev->dev, true); 709 acpi_walk_dep_device_list(ssh); 710 711 return 0; 712 713 err_mainref: 714 ssam_irq_free(ctrl); 715 err_irq: 716 sysfs_remove_group(&serdev->dev.kobj, &ssam_sam_group); 717 err_initrq: 718 ssam_controller_lock(ctrl); 719 ssam_controller_shutdown(ctrl); 720 err_devinit: 721 serdev_device_close(serdev); 722 err_devopen: 723 ssam_controller_destroy(ctrl); 724 ssam_controller_unlock(ctrl); 725 err_ctrl_init: 726 kfree(ctrl); 727 return status; 728 } 729 730 static void ssam_serial_hub_remove(struct serdev_device *serdev) 731 { 732 struct ssam_controller *ctrl = serdev_device_get_drvdata(serdev); 733 int status; 734 735 /* Clear static reference so that no one else can get a new one. */ 736 ssam_clear_controller(); 737 738 /* Disable and free IRQ. */ 739 ssam_irq_free(ctrl); 740 741 sysfs_remove_group(&serdev->dev.kobj, &ssam_sam_group); 742 ssam_controller_lock(ctrl); 743 744 /* Remove all client devices. */ 745 ssam_controller_remove_clients(ctrl); 746 747 /* Act as if suspending to silence events. */ 748 status = ssam_ctrl_notif_display_off(ctrl); 749 if (status) { 750 dev_err(&serdev->dev, "display-off notification failed: %d\n", 751 status); 752 } 753 754 status = ssam_ctrl_notif_d0_exit(ctrl); 755 if (status) { 756 dev_err(&serdev->dev, "D0-exit notification failed: %d\n", 757 status); 758 } 759 760 /* Shut down controller and remove serdev device reference from it. */ 761 ssam_controller_shutdown(ctrl); 762 763 /* Shut down actual transport. */ 764 serdev_device_wait_until_sent(serdev, 0); 765 serdev_device_close(serdev); 766 767 /* Drop our controller reference. */ 768 ssam_controller_unlock(ctrl); 769 ssam_controller_put(ctrl); 770 771 device_set_wakeup_capable(&serdev->dev, false); 772 } 773 774 static const struct acpi_device_id ssam_serial_hub_match[] = { 775 { "MSHW0084", 0 }, 776 { }, 777 }; 778 MODULE_DEVICE_TABLE(acpi, ssam_serial_hub_match); 779 780 static struct serdev_device_driver ssam_serial_hub = { 781 .probe = ssam_serial_hub_probe, 782 .remove = ssam_serial_hub_remove, 783 .driver = { 784 .name = "surface_serial_hub", 785 .acpi_match_table = ssam_serial_hub_match, 786 .pm = &ssam_serial_hub_pm_ops, 787 .shutdown = ssam_serial_hub_shutdown, 788 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 789 }, 790 }; 791 792 793 /* -- Module setup. --------------------------------------------------------- */ 794 795 static int __init ssam_core_init(void) 796 { 797 int status; 798 799 status = ssam_bus_register(); 800 if (status) 801 goto err_bus; 802 803 status = ssh_ctrl_packet_cache_init(); 804 if (status) 805 goto err_cpkg; 806 807 status = ssam_event_item_cache_init(); 808 if (status) 809 goto err_evitem; 810 811 status = serdev_device_driver_register(&ssam_serial_hub); 812 if (status) 813 goto err_register; 814 815 return 0; 816 817 err_register: 818 ssam_event_item_cache_destroy(); 819 err_evitem: 820 ssh_ctrl_packet_cache_destroy(); 821 err_cpkg: 822 ssam_bus_unregister(); 823 err_bus: 824 return status; 825 } 826 module_init(ssam_core_init); 827 828 static void __exit ssam_core_exit(void) 829 { 830 serdev_device_driver_unregister(&ssam_serial_hub); 831 ssam_event_item_cache_destroy(); 832 ssh_ctrl_packet_cache_destroy(); 833 ssam_bus_unregister(); 834 } 835 module_exit(ssam_core_exit); 836 837 MODULE_AUTHOR("Maximilian Luz <luzmaximilian@gmail.com>"); 838 MODULE_DESCRIPTION("Subsystem and Surface Serial Hub driver for Surface System Aggregator Module"); 839 MODULE_LICENSE("GPL"); 840