diff options
| -rw-r--r-- | patches/drivers/mailbox/0001-mailbox-PCC-erroneous-error-message-when-parsing-ACPI-PCCT.patch | 239 | ||||
| -rw-r--r-- | patches/drivers/mailbox/acpi-pcct.scc | 2 |
2 files changed, 0 insertions, 241 deletions
diff --git a/patches/drivers/mailbox/0001-mailbox-PCC-erroneous-error-message-when-parsing-ACPI-PCCT.patch b/patches/drivers/mailbox/0001-mailbox-PCC-erroneous-error-message-when-parsing-ACPI-PCCT.patch deleted file mode 100644 index 48cdda2..0000000 --- a/patches/drivers/mailbox/0001-mailbox-PCC-erroneous-error-message-when-parsing-ACPI-PCCT.patch +++ /dev/null | |||
| @@ -1,239 +0,0 @@ | |||
| 1 | From 8f8027c5f935bf02bdc8806c109ddbb0e402283c Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Al Stone <ahs3@redhat.com> | ||
| 3 | Date: Wed, 16 May 2018 16:01:41 -0600 | ||
| 4 | Subject: [PATCH] mailbox: PCC: erroneous error message when parsing ACPI PCCT | ||
| 5 | |||
| 6 | There have been multiple reports of the following error message: | ||
| 7 | |||
| 8 | [ 0.068293] Error parsing PCC subspaces from PCCT | ||
| 9 | |||
| 10 | This error message is not correct. In multiple cases examined, the PCCT | ||
| 11 | (Platform Communications Channel Table) concerned is actually properly | ||
| 12 | constructed; the problem is that acpi_pcc_probe() which reads the PCCT | ||
| 13 | is making the assumption that the only valid PCCT is one that contains | ||
| 14 | subtables of one of two types: ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE or | ||
| 15 | ACPI_PCCT_TYPE_HW_REDUCED_TYPE2. The number of subtables of these | ||
| 16 | types are counted and as long as there is at least one of the desired | ||
| 17 | types, the acpi_pcc_probe() succeeds. When no subtables of these types | ||
| 18 | are found, regardless of whether or not any other subtable types are | ||
| 19 | present, the error mentioned above is reported. | ||
| 20 | |||
| 21 | In the cases reported to me personally, the PCCT contains exactly one | ||
| 22 | subtable of type ACPI_PCCT_TYPE_GENERIC_SUBSPACE. The function | ||
| 23 | acpi_pcc_probe() does not count it as a valid subtable, so believes | ||
| 24 | there to be no valid subtables, and hence outputs the error message. | ||
| 25 | |||
| 26 | An example of the PCCT being reported as erroneous yet perfectly fine | ||
| 27 | is the following: | ||
| 28 | |||
| 29 | Signature : "PCCT" | ||
| 30 | Table Length : 0000006E | ||
| 31 | Revision : 05 | ||
| 32 | Checksum : A9 | ||
| 33 | Oem ID : "XXXXXX" | ||
| 34 | Oem Table ID : "XXXXX " | ||
| 35 | Oem Revision : 00002280 | ||
| 36 | Asl Compiler ID : "XXXX" | ||
| 37 | Asl Compiler Revision : 00000002 | ||
| 38 | |||
| 39 | Flags (decoded below) : 00000001 | ||
| 40 | Platform : 1 | ||
| 41 | Reserved : 0000000000000000 | ||
| 42 | |||
| 43 | Subtable Type : 00 [Generic Communications Subspace] | ||
| 44 | Length : 3E | ||
| 45 | |||
| 46 | Reserved : 000000000000 | ||
| 47 | Base Address : 00000000DCE43018 | ||
| 48 | Address Length : 0000000000001000 | ||
| 49 | |||
| 50 | Doorbell Register : [Generic Address Structure] | ||
| 51 | Space ID : 01 [SystemIO] | ||
| 52 | Bit Width : 08 | ||
| 53 | Bit Offset : 00 | ||
| 54 | Encoded Access Width : 01 [Byte Access:8] | ||
| 55 | Address : 0000000000001842 | ||
| 56 | |||
| 57 | Preserve Mask : 00000000000000FD | ||
| 58 | Write Mask : 0000000000000002 | ||
| 59 | Command Latency : 00001388 | ||
| 60 | Maximum Access Rate : 00000000 | ||
| 61 | Minimum Turnaround Time : 0000 | ||
| 62 | |||
| 63 | To fix this, we count up all of the possible subtable types for the | ||
| 64 | PCCT, and only report an error when there are none (which could mean | ||
| 65 | either no subtables, or no valid subtables), or there are too many. | ||
| 66 | We also change the logic so that if there is a valid subtable, we | ||
| 67 | do try to initialize it per the PCCT subtable contents. This is a | ||
| 68 | change in functionality; previously, the probe would have returned | ||
| 69 | right after the error message and would not have tried to use any | ||
| 70 | other subtable definition. | ||
| 71 | |||
| 72 | Tested on my personal laptop which showed the error previously; the | ||
| 73 | error message no longer appears and the laptop appears to operate | ||
| 74 | normally. | ||
| 75 | |||
| 76 | Signed-off-by: Al Stone <ahs3@redhat.com> | ||
| 77 | Reviewed-by: Prashanth Prakash <pprakash@codeaurora.org> | ||
| 78 | Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> | ||
| 79 | --- | ||
| 80 | drivers/mailbox/pcc.c | 81 ++++++++++++++++++++++++--------------------------- | ||
| 81 | 1 file changed, 38 insertions(+), 43 deletions(-) | ||
| 82 | |||
| 83 | diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c | ||
| 84 | index 3ef7f036ceea..fc3c237daef2 100644 | ||
| 85 | --- a/drivers/mailbox/pcc.c | ||
| 86 | +++ b/drivers/mailbox/pcc.c | ||
| 87 | @@ -373,33 +373,24 @@ static const struct mbox_chan_ops pcc_chan_ops = { | ||
| 88 | }; | ||
| 89 | |||
| 90 | /** | ||
| 91 | - * parse_pcc_subspace - Parse the PCC table and verify PCC subspace | ||
| 92 | - * entries. There should be one entry per PCC client. | ||
| 93 | + * parse_pcc_subspaces -- Count PCC subspaces defined | ||
| 94 | * @header: Pointer to the ACPI subtable header under the PCCT. | ||
| 95 | * @end: End of subtable entry. | ||
| 96 | * | ||
| 97 | - * Return: 0 for Success, else errno. | ||
| 98 | + * Return: If we find a PCC subspace entry of a valid type, return 0. | ||
| 99 | + * Otherwise, return -EINVAL. | ||
| 100 | * | ||
| 101 | * This gets called for each entry in the PCC table. | ||
| 102 | */ | ||
| 103 | static int parse_pcc_subspace(struct acpi_subtable_header *header, | ||
| 104 | const unsigned long end) | ||
| 105 | { | ||
| 106 | - struct acpi_pcct_hw_reduced *pcct_ss; | ||
| 107 | - | ||
| 108 | - if (pcc_mbox_ctrl.num_chans <= MAX_PCC_SUBSPACES) { | ||
| 109 | - pcct_ss = (struct acpi_pcct_hw_reduced *) header; | ||
| 110 | + struct acpi_pcct_subspace *ss = (struct acpi_pcct_subspace *) header; | ||
| 111 | |||
| 112 | - if ((pcct_ss->header.type != | ||
| 113 | - ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE) | ||
| 114 | - && (pcct_ss->header.type != | ||
| 115 | - ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2)) { | ||
| 116 | - pr_err("Incorrect PCC Subspace type detected\n"); | ||
| 117 | - return -EINVAL; | ||
| 118 | - } | ||
| 119 | - } | ||
| 120 | + if (ss->header.type < ACPI_PCCT_TYPE_RESERVED) | ||
| 121 | + return 0; | ||
| 122 | |||
| 123 | - return 0; | ||
| 124 | + return -EINVAL; | ||
| 125 | } | ||
| 126 | |||
| 127 | /** | ||
| 128 | @@ -449,8 +440,8 @@ static int __init acpi_pcc_probe(void) | ||
| 129 | struct acpi_table_header *pcct_tbl; | ||
| 130 | struct acpi_subtable_header *pcct_entry; | ||
| 131 | struct acpi_table_pcct *acpi_pcct_tbl; | ||
| 132 | + struct acpi_subtable_proc proc[ACPI_PCCT_TYPE_RESERVED]; | ||
| 133 | int count, i, rc; | ||
| 134 | - int sum = 0; | ||
| 135 | acpi_status status = AE_OK; | ||
| 136 | |||
| 137 | /* Search for PCCT */ | ||
| 138 | @@ -459,43 +450,41 @@ static int __init acpi_pcc_probe(void) | ||
| 139 | if (ACPI_FAILURE(status) || !pcct_tbl) | ||
| 140 | return -ENODEV; | ||
| 141 | |||
| 142 | - count = acpi_table_parse_entries(ACPI_SIG_PCCT, | ||
| 143 | - sizeof(struct acpi_table_pcct), | ||
| 144 | - ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE, | ||
| 145 | - parse_pcc_subspace, MAX_PCC_SUBSPACES); | ||
| 146 | - sum += (count > 0) ? count : 0; | ||
| 147 | - | ||
| 148 | - count = acpi_table_parse_entries(ACPI_SIG_PCCT, | ||
| 149 | - sizeof(struct acpi_table_pcct), | ||
| 150 | - ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2, | ||
| 151 | - parse_pcc_subspace, MAX_PCC_SUBSPACES); | ||
| 152 | - sum += (count > 0) ? count : 0; | ||
| 153 | + /* Set up the subtable handlers */ | ||
| 154 | + for (i = ACPI_PCCT_TYPE_GENERIC_SUBSPACE; | ||
| 155 | + i < ACPI_PCCT_TYPE_RESERVED; i++) { | ||
| 156 | + proc[i].id = i; | ||
| 157 | + proc[i].count = 0; | ||
| 158 | + proc[i].handler = parse_pcc_subspace; | ||
| 159 | + } | ||
| 160 | |||
| 161 | - if (sum == 0 || sum >= MAX_PCC_SUBSPACES) { | ||
| 162 | - pr_err("Error parsing PCC subspaces from PCCT\n"); | ||
| 163 | + count = acpi_table_parse_entries_array(ACPI_SIG_PCCT, | ||
| 164 | + sizeof(struct acpi_table_pcct), proc, | ||
| 165 | + ACPI_PCCT_TYPE_RESERVED, MAX_PCC_SUBSPACES); | ||
| 166 | + if (count == 0 || count > MAX_PCC_SUBSPACES) { | ||
| 167 | + pr_warn("Invalid PCCT: %d PCC subspaces\n", count); | ||
| 168 | return -EINVAL; | ||
| 169 | } | ||
| 170 | |||
| 171 | - pcc_mbox_channels = kzalloc(sizeof(struct mbox_chan) * | ||
| 172 | - sum, GFP_KERNEL); | ||
| 173 | + pcc_mbox_channels = kzalloc(sizeof(struct mbox_chan) * count, GFP_KERNEL); | ||
| 174 | if (!pcc_mbox_channels) { | ||
| 175 | pr_err("Could not allocate space for PCC mbox channels\n"); | ||
| 176 | return -ENOMEM; | ||
| 177 | } | ||
| 178 | |||
| 179 | - pcc_doorbell_vaddr = kcalloc(sum, sizeof(void *), GFP_KERNEL); | ||
| 180 | + pcc_doorbell_vaddr = kcalloc(count, sizeof(void *), GFP_KERNEL); | ||
| 181 | if (!pcc_doorbell_vaddr) { | ||
| 182 | rc = -ENOMEM; | ||
| 183 | goto err_free_mbox; | ||
| 184 | } | ||
| 185 | |||
| 186 | - pcc_doorbell_ack_vaddr = kcalloc(sum, sizeof(void *), GFP_KERNEL); | ||
| 187 | + pcc_doorbell_ack_vaddr = kcalloc(count, sizeof(void *), GFP_KERNEL); | ||
| 188 | if (!pcc_doorbell_ack_vaddr) { | ||
| 189 | rc = -ENOMEM; | ||
| 190 | goto err_free_db_vaddr; | ||
| 191 | } | ||
| 192 | |||
| 193 | - pcc_doorbell_irq = kcalloc(sum, sizeof(int), GFP_KERNEL); | ||
| 194 | + pcc_doorbell_irq = kcalloc(count, sizeof(int), GFP_KERNEL); | ||
| 195 | if (!pcc_doorbell_irq) { | ||
| 196 | rc = -ENOMEM; | ||
| 197 | goto err_free_db_ack_vaddr; | ||
| 198 | @@ -509,18 +498,24 @@ static int __init acpi_pcc_probe(void) | ||
| 199 | if (acpi_pcct_tbl->flags & ACPI_PCCT_DOORBELL) | ||
| 200 | pcc_mbox_ctrl.txdone_irq = true; | ||
| 201 | |||
| 202 | - for (i = 0; i < sum; i++) { | ||
| 203 | + for (i = 0; i < count; i++) { | ||
| 204 | struct acpi_generic_address *db_reg; | ||
| 205 | - struct acpi_pcct_hw_reduced *pcct_ss; | ||
| 206 | + struct acpi_pcct_subspace *pcct_ss; | ||
| 207 | pcc_mbox_channels[i].con_priv = pcct_entry; | ||
| 208 | |||
| 209 | - pcct_ss = (struct acpi_pcct_hw_reduced *) pcct_entry; | ||
| 210 | + if (pcct_entry->type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE || | ||
| 211 | + pcct_entry->type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2) { | ||
| 212 | + struct acpi_pcct_hw_reduced *pcct_hrss; | ||
| 213 | + | ||
| 214 | + pcct_hrss = (struct acpi_pcct_hw_reduced *) pcct_entry; | ||
| 215 | |||
| 216 | - if (pcc_mbox_ctrl.txdone_irq) { | ||
| 217 | - rc = pcc_parse_subspace_irq(i, pcct_ss); | ||
| 218 | - if (rc < 0) | ||
| 219 | - goto err; | ||
| 220 | + if (pcc_mbox_ctrl.txdone_irq) { | ||
| 221 | + rc = pcc_parse_subspace_irq(i, pcct_hrss); | ||
| 222 | + if (rc < 0) | ||
| 223 | + goto err; | ||
| 224 | + } | ||
| 225 | } | ||
| 226 | + pcct_ss = (struct acpi_pcct_subspace *) pcct_entry; | ||
| 227 | |||
| 228 | /* If doorbell is in system memory cache the virt address */ | ||
| 229 | db_reg = &pcct_ss->doorbell_register; | ||
| 230 | @@ -531,7 +526,7 @@ static int __init acpi_pcc_probe(void) | ||
| 231 | ((unsigned long) pcct_entry + pcct_entry->length); | ||
| 232 | } | ||
| 233 | |||
| 234 | - pcc_mbox_ctrl.num_chans = sum; | ||
| 235 | + pcc_mbox_ctrl.num_chans = count; | ||
| 236 | |||
| 237 | pr_info("Detected %d PCC Subspaces\n", pcc_mbox_ctrl.num_chans); | ||
| 238 | |||
| 239 | |||
diff --git a/patches/drivers/mailbox/acpi-pcct.scc b/patches/drivers/mailbox/acpi-pcct.scc deleted file mode 100644 index 16d8c2c..0000000 --- a/patches/drivers/mailbox/acpi-pcct.scc +++ /dev/null | |||
| @@ -1,2 +0,0 @@ | |||
| 1 | # Upstream in kernel v4.18-rc1 and newer | ||
| 2 | patch 0001-mailbox-PCC-erroneous-error-message-when-parsing-ACPI-PCCT.patch | ||
