|
22 | 22 | #include <linux/pci.h>
|
23 | 23 | #include <linux/platform_device.h>
|
24 | 24 | #include <linux/rtc.h>
|
| 25 | +#include <linux/serio.h> |
25 | 26 | #include <linux/suspend.h>
|
26 | 27 | #include <linux/seq_file.h>
|
27 | 28 | #include <linux/uaccess.h>
|
@@ -653,6 +654,33 @@ static int amd_pmc_get_os_hint(struct amd_pmc_dev *dev)
|
653 | 654 | return -EINVAL;
|
654 | 655 | }
|
655 | 656 |
|
| 657 | +static int amd_pmc_czn_wa_irq1(struct amd_pmc_dev *pdev) |
| 658 | +{ |
| 659 | + struct device *d; |
| 660 | + int rc; |
| 661 | + |
| 662 | + if (!pdev->major) { |
| 663 | + rc = amd_pmc_get_smu_version(pdev); |
| 664 | + if (rc) |
| 665 | + return rc; |
| 666 | + } |
| 667 | + |
| 668 | + if (pdev->major > 64 || (pdev->major == 64 && pdev->minor > 65)) |
| 669 | + return 0; |
| 670 | + |
| 671 | + d = bus_find_device_by_name(&serio_bus, NULL, "serio0"); |
| 672 | + if (!d) |
| 673 | + return 0; |
| 674 | + if (device_may_wakeup(d)) { |
| 675 | + dev_info_once(d, "Disabling IRQ1 wakeup source to avoid platform firmware bug\n"); |
| 676 | + disable_irq_wake(1); |
| 677 | + device_set_wakeup_enable(d, false); |
| 678 | + } |
| 679 | + put_device(d); |
| 680 | + |
| 681 | + return 0; |
| 682 | +} |
| 683 | + |
656 | 684 | static int amd_pmc_verify_czn_rtc(struct amd_pmc_dev *pdev, u32 *arg)
|
657 | 685 | {
|
658 | 686 | struct rtc_device *rtc_device;
|
@@ -782,6 +810,25 @@ static struct acpi_s2idle_dev_ops amd_pmc_s2idle_dev_ops = {
|
782 | 810 | .check = amd_pmc_s2idle_check,
|
783 | 811 | .restore = amd_pmc_s2idle_restore,
|
784 | 812 | };
|
| 813 | + |
| 814 | +static int __maybe_unused amd_pmc_suspend_handler(struct device *dev) |
| 815 | +{ |
| 816 | + struct amd_pmc_dev *pdev = dev_get_drvdata(dev); |
| 817 | + |
| 818 | + if (pdev->cpu_id == AMD_CPU_ID_CZN) { |
| 819 | + int rc = amd_pmc_czn_wa_irq1(pdev); |
| 820 | + |
| 821 | + if (rc) { |
| 822 | + dev_err(pdev->dev, "failed to adjust keyboard wakeup: %d\n", rc); |
| 823 | + return rc; |
| 824 | + } |
| 825 | + } |
| 826 | + |
| 827 | + return 0; |
| 828 | +} |
| 829 | + |
| 830 | +static SIMPLE_DEV_PM_OPS(amd_pmc_pm, amd_pmc_suspend_handler, NULL); |
| 831 | + |
785 | 832 | #endif
|
786 | 833 |
|
787 | 834 | static const struct pci_device_id pmc_pci_ids[] = {
|
@@ -980,6 +1027,9 @@ static struct platform_driver amd_pmc_driver = {
|
980 | 1027 | .name = "amd_pmc",
|
981 | 1028 | .acpi_match_table = amd_pmc_acpi_ids,
|
982 | 1029 | .dev_groups = pmc_groups,
|
| 1030 | +#ifdef CONFIG_SUSPEND |
| 1031 | + .pm = &amd_pmc_pm, |
| 1032 | +#endif |
983 | 1033 | },
|
984 | 1034 | .probe = amd_pmc_probe,
|
985 | 1035 | .remove = amd_pmc_remove,
|
|
0 commit comments