|
1 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | 2 | /* |
3 | | - * |
4 | 3 | * Add CIX SKY1 SoC Version driver |
5 | 4 | * |
6 | 5 | */ |
|
9 | 8 | #include <linux/platform_device.h> |
10 | 9 | #include <linux/types.h> |
11 | 10 | #include <linux/acpi.h> |
| 11 | +#include <linux/soc/cix/cpu.h> |
| 12 | + |
| 13 | +enum { |
| 14 | + DENY_PCIE = 0, |
| 15 | + DENY_USB, |
| 16 | + DENY_SCMI_CLKS, |
| 17 | + DENY_MAX, |
| 18 | +}; |
| 19 | + |
| 20 | +static bool pcie_pnp_en; |
| 21 | +static bool usb_pnp_en; |
| 22 | +static bool acpi_scmi_en = true; |
| 23 | + |
| 24 | +static int __init pcie_pnp_update(char *str) |
| 25 | +{ |
| 26 | + pcie_pnp_en = true; |
| 27 | + |
| 28 | + return 0; |
| 29 | +} |
| 30 | +early_param("pcie_pnp_en", pcie_pnp_update); |
| 31 | + |
| 32 | +static int __init usb_pnp_update(char *str) |
| 33 | +{ |
| 34 | + usb_pnp_en = true; |
| 35 | + |
| 36 | + return 0; |
| 37 | +} |
| 38 | +early_param("usb_pnp_en", usb_pnp_update); |
| 39 | + |
| 40 | +static int __init parse_acpi_scmi_support(char *arg) |
| 41 | +{ |
| 42 | + if (!arg) |
| 43 | + return -EINVAL; |
| 44 | + |
| 45 | + if (strcmp(arg, "off") == 0) |
| 46 | + acpi_scmi_en = false; |
| 47 | + else if (strcmp(arg, "on") == 0) |
| 48 | + acpi_scmi_en = true; |
| 49 | + else |
| 50 | + return -EINVAL; |
| 51 | + |
| 52 | + return 0; |
| 53 | +} |
| 54 | +early_param("acpi_scmi_en", parse_acpi_scmi_support); |
| 55 | + |
| 56 | +static struct acpi_device_id pcie_pnp_deny_ids[] = { |
| 57 | + /* override PCIE acpi scan handler */ |
| 58 | + {"PNP0A03", 0}, /* PCIE */ |
| 59 | + {"PNP0C0F", 0}, /* PCIE Links */ |
| 60 | + {"", 0}, |
| 61 | +}; |
12 | 62 |
|
13 | | -static const struct acpi_device_id device_deny_ids[] = { |
| 63 | +static struct acpi_device_id usb_pnp_deny_ids[] = { |
14 | 64 | {"PNP0D10", 0}, |
15 | 65 | {"", 0}, |
16 | 66 | }; |
17 | 67 |
|
| 68 | +static struct acpi_device_id pcie_cdns_deny_ids[] = { |
| 69 | + {"CIXH2020", 0}, /* pcie rc */ |
| 70 | + {"CIXH2021", 0}, /* pcie ep */ |
| 71 | + {"CIXH2023", 0}, /* pcie phy */ |
| 72 | + {"", 0}, |
| 73 | +}; |
| 74 | + |
| 75 | +static struct acpi_device_id usb_cdns_deny_ids[] = { |
| 76 | + {"CIXH2030", 0}, /* sky1 usbssp */ |
| 77 | + {"CIXH2031", 0}, /* cdns usbssp */ |
| 78 | + {"CIXH2032", 0}, /* usb 2.0 phy */ |
| 79 | + /* CIXH2033 is combo phy, also used by dp */ |
| 80 | + {"CIXH2034", 0}, /* usb 3.0 phy */ |
| 81 | + {"", 0}, |
| 82 | +}; |
| 83 | + |
| 84 | +static struct acpi_device_id acpi_clks_deny_ids[] = { |
| 85 | + {"CIXHA010", 0}, |
| 86 | + {"", 0}, |
| 87 | +}; |
| 88 | + |
| 89 | +static struct acpi_device_id scmi_clks_deny_ids[] = { |
| 90 | + {"CIXHA009", 0}, |
| 91 | + {"", 0}, |
| 92 | +}; |
| 93 | + |
18 | 94 | static int acpi_device_deny(struct acpi_device *adev, |
19 | 95 | const struct acpi_device_id *not_used) |
20 | 96 | { |
21 | | - acpi_set_device_status(adev, 0); |
22 | | - |
23 | 97 | dev_dbg(&adev->dev, "acpi disable dev[%s]\n", dev_name(&adev->dev)); |
24 | 98 |
|
25 | 99 | return -1; /* return -1 to block platform device enumeration */ |
26 | 100 | } |
27 | 101 |
|
28 | | -static struct acpi_scan_handler device_deny_handler = { |
29 | | - .ids = device_deny_ids, |
30 | | - .attach = acpi_device_deny, |
| 102 | +static struct acpi_scan_handler acpi_deny_handler[DENY_MAX] = { |
| 103 | + { |
| 104 | + .ids = pcie_pnp_deny_ids, |
| 105 | + .attach = acpi_device_deny, |
| 106 | + }, |
| 107 | + { |
| 108 | + .ids = usb_pnp_deny_ids, |
| 109 | + .attach = acpi_device_deny, |
| 110 | + } |
31 | 111 | }; |
32 | 112 |
|
33 | | -int cix_acpi_plat_arch_init(void) |
| 113 | +static void device_deny_id_init(void) |
34 | 114 | { |
35 | | - acpi_scan_add_handler(&device_deny_handler); |
| 115 | + int i; |
| 116 | + |
| 117 | + if (pcie_pnp_en) |
| 118 | + acpi_deny_handler[DENY_PCIE].ids = pcie_cdns_deny_ids; |
| 119 | + |
| 120 | + if (usb_pnp_en) |
| 121 | + acpi_deny_handler[DENY_USB].ids = usb_cdns_deny_ids; |
| 122 | + |
| 123 | + if (acpi_scmi_en) |
| 124 | + acpi_deny_handler[DENY_SCMI_CLKS].ids = acpi_clks_deny_ids; |
| 125 | + else |
| 126 | + acpi_deny_handler[DENY_SCMI_CLKS].ids = scmi_clks_deny_ids; |
| 127 | + |
| 128 | + for (i = 0; i < DENY_MAX; i++) |
| 129 | + acpi_scan_add_handler(&acpi_deny_handler[i]); |
| 130 | +} |
36 | 131 |
|
| 132 | +void cix_pcie_io_space_init(void) |
| 133 | +{ |
| 134 | + /* |
| 135 | + * Default IO space is limited to IO_SPACE_LIMIT, which not enough |
| 136 | + * for current usage. Especially in acpi case. So extend it here. |
| 137 | + */ |
| 138 | + ioport_resource.end = -1; |
| 139 | +} |
| 140 | + |
| 141 | +int cix_acpi_plat_arch_init(void) |
| 142 | +{ |
| 143 | + if (cpu_is_cix_p1_family()) { |
| 144 | + cix_pcie_io_space_init(); |
| 145 | + device_deny_id_init(); |
| 146 | + } |
37 | 147 | return 0; |
38 | 148 | } |
39 | 149 | arch_initcall(cix_acpi_plat_arch_init); |
0 commit comments