| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * i8042 keyboard and mouse controller driver for Linux |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (c) 1999-2004 Vojtech Pavlik |
|---|
| 5 | 6 | */ |
|---|
| 6 | 7 | |
|---|
| 7 | | -/* |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 9 | | - * under the terms of the GNU General Public License version 2 as published by |
|---|
| 10 | | - * the Free Software Foundation. |
|---|
| 11 | | - */ |
|---|
| 12 | 8 | |
|---|
| 13 | 9 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
|---|
| 14 | 10 | |
|---|
| .. | .. |
|---|
| 25 | 21 | #include <linux/i8042.h> |
|---|
| 26 | 22 | #include <linux/slab.h> |
|---|
| 27 | 23 | #include <linux/suspend.h> |
|---|
| 24 | +#include <linux/property.h> |
|---|
| 28 | 25 | |
|---|
| 29 | 26 | #include <asm/io.h> |
|---|
| 30 | 27 | |
|---|
| .. | .. |
|---|
| 133 | 130 | static bool i8042_bypass_aux_irq_test; |
|---|
| 134 | 131 | static char i8042_kbd_firmware_id[128]; |
|---|
| 135 | 132 | static char i8042_aux_firmware_id[128]; |
|---|
| 133 | +static struct fwnode_handle *i8042_kbd_fwnode; |
|---|
| 136 | 134 | |
|---|
| 137 | 135 | #include "i8042.h" |
|---|
| 138 | 136 | |
|---|
| .. | .. |
|---|
| 444 | 442 | { |
|---|
| 445 | 443 | struct i8042_port *port = serio->port_data; |
|---|
| 446 | 444 | |
|---|
| 445 | + device_set_wakeup_capable(&serio->dev, true); |
|---|
| 446 | + |
|---|
| 447 | + /* |
|---|
| 448 | + * On platforms using suspend-to-idle, allow the keyboard to |
|---|
| 449 | + * wake up the system from sleep by enabling keyboard wakeups |
|---|
| 450 | + * by default. This is consistent with keyboard wakeup |
|---|
| 451 | + * behavior on many platforms using suspend-to-RAM (ACPI S3) |
|---|
| 452 | + * by default. |
|---|
| 453 | + */ |
|---|
| 454 | + if (pm_suspend_default_s2idle() && |
|---|
| 455 | + serio == i8042_ports[I8042_KBD_PORT_NO].serio) { |
|---|
| 456 | + device_set_wakeup_enable(&serio->dev, true); |
|---|
| 457 | + } |
|---|
| 458 | + |
|---|
| 447 | 459 | spin_lock_irq(&i8042_lock); |
|---|
| 448 | 460 | port->exists = true; |
|---|
| 449 | 461 | spin_unlock_irq(&i8042_lock); |
|---|
| .. | .. |
|---|
| 558 | 570 | str = last_str; |
|---|
| 559 | 571 | break; |
|---|
| 560 | 572 | } |
|---|
| 561 | | - /* fall through - report timeout */ |
|---|
| 573 | + fallthrough; /* report timeout */ |
|---|
| 562 | 574 | case 0xfc: |
|---|
| 563 | 575 | case 0xfd: |
|---|
| 564 | 576 | case 0xfe: dfl = SERIO_TIMEOUT; data = 0xfe; break; |
|---|
| .. | .. |
|---|
| 580 | 592 | |
|---|
| 581 | 593 | port = &i8042_ports[port_no]; |
|---|
| 582 | 594 | serio = port->exists ? port->serio : NULL; |
|---|
| 583 | | - |
|---|
| 584 | | - if (irq && serio) |
|---|
| 585 | | - pm_wakeup_event(&serio->dev, 0); |
|---|
| 586 | 595 | |
|---|
| 587 | 596 | filter_dbg(port->driver_bound, data, "<- i8042 (interrupt, %d, %d%s%s)\n", |
|---|
| 588 | 597 | port_no, irq, |
|---|
| .. | .. |
|---|
| 1336 | 1345 | strlcpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys)); |
|---|
| 1337 | 1346 | strlcpy(serio->firmware_id, i8042_kbd_firmware_id, |
|---|
| 1338 | 1347 | sizeof(serio->firmware_id)); |
|---|
| 1348 | + set_primary_fwnode(&serio->dev, i8042_kbd_fwnode); |
|---|
| 1339 | 1349 | |
|---|
| 1340 | 1350 | port->serio = serio; |
|---|
| 1341 | 1351 | port->irq = I8042_KBD_IRQ; |
|---|
| .. | .. |
|---|
| 1412 | 1422 | (unsigned long) I8042_COMMAND_REG, |
|---|
| 1413 | 1423 | i8042_ports[i].irq); |
|---|
| 1414 | 1424 | serio_register_port(serio); |
|---|
| 1415 | | - device_set_wakeup_capable(&serio->dev, true); |
|---|
| 1416 | | - |
|---|
| 1417 | | - /* |
|---|
| 1418 | | - * On platforms using suspend-to-idle, allow the keyboard to |
|---|
| 1419 | | - * wake up the system from sleep by enabling keyboard wakeups |
|---|
| 1420 | | - * by default. This is consistent with keyboard wakeup |
|---|
| 1421 | | - * behavior on many platforms using suspend-to-RAM (ACPI S3) |
|---|
| 1422 | | - * by default. |
|---|
| 1423 | | - */ |
|---|
| 1424 | | - if (pm_suspend_via_s2idle() && i == I8042_KBD_PORT_NO) |
|---|
| 1425 | | - device_set_wakeup_enable(&serio->dev, true); |
|---|
| 1426 | 1425 | } |
|---|
| 1427 | 1426 | } |
|---|
| 1428 | 1427 | |
|---|
| .. | .. |
|---|
| 1544 | 1543 | { |
|---|
| 1545 | 1544 | int error; |
|---|
| 1546 | 1545 | |
|---|
| 1547 | | - i8042_platform_device = dev; |
|---|
| 1548 | | - |
|---|
| 1549 | 1546 | if (i8042_reset == I8042_RESET_ALWAYS) { |
|---|
| 1550 | 1547 | error = i8042_controller_selftest(); |
|---|
| 1551 | 1548 | if (error) |
|---|
| .. | .. |
|---|
| 1583 | 1580 | i8042_free_aux_ports(); /* in case KBD failed but AUX not */ |
|---|
| 1584 | 1581 | i8042_free_irqs(); |
|---|
| 1585 | 1582 | i8042_controller_reset(false); |
|---|
| 1586 | | - i8042_platform_device = NULL; |
|---|
| 1587 | 1583 | |
|---|
| 1588 | 1584 | return error; |
|---|
| 1589 | 1585 | } |
|---|
| .. | .. |
|---|
| 1593 | 1589 | i8042_unregister_ports(); |
|---|
| 1594 | 1590 | i8042_free_irqs(); |
|---|
| 1595 | 1591 | i8042_controller_reset(false); |
|---|
| 1596 | | - i8042_platform_device = NULL; |
|---|
| 1597 | 1592 | |
|---|
| 1598 | 1593 | return 0; |
|---|
| 1599 | 1594 | } |
|---|