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