aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/tables.c
diff options
context:
space:
mode:
authorAshwin Chaugule <ashwin.chaugule@linaro.org>2014-11-26 09:01:13 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-11-26 20:06:17 -0500
commitf08bb472bff3c0397fb7d6f47bc5cec41dad76e3 (patch)
treed1e3c7a64a591f9f1c6fa14c38b2d0b595583654 /drivers/acpi/tables.c
parent5d01410fe4d92081f349b013a2e7a95429e4f2c9 (diff)
ACPI / table: Add new function to get table entries
The acpi_table_parse() function has a callback that passes a pointer to a table_header. Add a new function which takes this pointer and parses its entries. This eliminates the need to re-traverse all the tables for each call. e.g. as in acpi_table_parse_madt() which is normally called after acpi_table_parse(). Acked-by: Grant Likely <grant.likely@linaro.org> Signed-off-by: Ashwin Chaugule <ashwin.chaugule@linaro.org> Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/tables.c')
-rw-r--r--drivers/acpi/tables.c63
1 files changed, 44 insertions, 19 deletions
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 6d5a6cda0734..f1debe97dcfc 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -190,30 +190,24 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
190 } 190 }
191} 191}
192 192
193
194int __init 193int __init
195acpi_table_parse_entries(char *id, 194acpi_parse_entries(char *id, unsigned long table_size,
196 unsigned long table_size, 195 acpi_tbl_entry_handler handler,
197 int entry_id, 196 struct acpi_table_header *table_header,
198 acpi_tbl_entry_handler handler, 197 int entry_id, unsigned int max_entries)
199 unsigned int max_entries)
200{ 198{
201 struct acpi_table_header *table_header = NULL;
202 struct acpi_subtable_header *entry; 199 struct acpi_subtable_header *entry;
203 unsigned int count = 0; 200 int count = 0;
204 unsigned long table_end; 201 unsigned long table_end;
205 acpi_size tbl_size;
206 202
207 if (acpi_disabled) 203 if (acpi_disabled)
208 return -ENODEV; 204 return -ENODEV;
209 205
210 if (!handler) 206 if (!id || !handler)
211 return -EINVAL; 207 return -EINVAL;
212 208
213 if (strncmp(id, ACPI_SIG_MADT, 4) == 0) 209 if (!table_size)
214 acpi_get_table_with_size(id, acpi_apic_instance, &table_header, &tbl_size); 210 return -EINVAL;
215 else
216 acpi_get_table_with_size(id, 0, &table_header, &tbl_size);
217 211
218 if (!table_header) { 212 if (!table_header) {
219 pr_warn("%4.4s not present\n", id); 213 pr_warn("%4.4s not present\n", id);
@@ -232,7 +226,7 @@ acpi_table_parse_entries(char *id,
232 if (entry->type == entry_id 226 if (entry->type == entry_id
233 && (!max_entries || count++ < max_entries)) 227 && (!max_entries || count++ < max_entries))
234 if (handler(entry, table_end)) 228 if (handler(entry, table_end))
235 goto err; 229 return -EINVAL;
236 230
237 /* 231 /*
238 * If entry->length is 0, break from this loop to avoid 232 * If entry->length is 0, break from this loop to avoid
@@ -240,22 +234,53 @@ acpi_table_parse_entries(char *id,
240 */ 234 */
241 if (entry->length == 0) { 235 if (entry->length == 0) {
242 pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, entry_id); 236 pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, entry_id);
243 goto err; 237 return -EINVAL;
244 } 238 }
245 239
246 entry = (struct acpi_subtable_header *) 240 entry = (struct acpi_subtable_header *)
247 ((unsigned long)entry + entry->length); 241 ((unsigned long)entry + entry->length);
248 } 242 }
243
249 if (max_entries && count > max_entries) { 244 if (max_entries && count > max_entries) {
250 pr_warn("[%4.4s:0x%02x] ignored %i entries of %i found\n", 245 pr_warn("[%4.4s:0x%02x] ignored %i entries of %i found\n",
251 id, entry_id, count - max_entries, count); 246 id, entry_id, count - max_entries, count);
252 } 247 }
253 248
254 early_acpi_os_unmap_memory((char *)table_header, tbl_size);
255 return count; 249 return count;
256err: 250}
251
252int __init
253acpi_table_parse_entries(char *id,
254 unsigned long table_size,
255 int entry_id,
256 acpi_tbl_entry_handler handler,
257 unsigned int max_entries)
258{
259 struct acpi_table_header *table_header = NULL;
260 acpi_size tbl_size;
261 int count;
262 u32 instance = 0;
263
264 if (acpi_disabled)
265 return -ENODEV;
266
267 if (!id || !handler)
268 return -EINVAL;
269
270 if (!strncmp(id, ACPI_SIG_MADT, 4))
271 instance = acpi_apic_instance;
272
273 acpi_get_table_with_size(id, instance, &table_header, &tbl_size);
274 if (!table_header) {
275 pr_warn("%4.4s not present\n", id);
276 return -ENODEV;
277 }
278
279 count = acpi_parse_entries(id, table_size, handler, table_header,
280 entry_id, max_entries);
281
257 early_acpi_os_unmap_memory((char *)table_header, tbl_size); 282 early_acpi_os_unmap_memory((char *)table_header, tbl_size);
258 return -EINVAL; 283 return count;
259} 284}
260 285
261int __init 286int __init