resource.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781
  1. /*
  2. * drivers/acpi/resource.c - ACPI device resources interpretation.
  3. *
  4. * Copyright (C) 2012, Intel Corp.
  5. * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  6. *
  7. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2 as published
  11. * by the Free Software Foundation.
  12. *
  13. * This program is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * General Public License for more details.
  17. *
  18. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  19. */
  20. #include <linux/acpi.h>
  21. #include <linux/device.h>
  22. #include <linux/export.h>
  23. #include <linux/ioport.h>
  24. #include <linux/list.h>
  25. #include <linux/slab.h>
  26. #ifdef CONFIG_X86
  27. #define valid_IRQ(i) (((i) != 0) && ((i) != 2))
  28. #else
  29. #define valid_IRQ(i) (true)
  30. #endif
  31. static bool acpi_dev_resource_len_valid(u64 start, u64 end, u64 len, bool io)
  32. {
  33. u64 reslen = end - start + 1;
  34. /*
  35. * CHECKME: len might be required to check versus a minimum
  36. * length as well. 1 for io is fine, but for memory it does
  37. * not make any sense at all.
  38. * Note: some BIOSes report incorrect length for ACPI address space
  39. * descriptor, so remove check of 'reslen == len' to avoid regression.
  40. */
  41. if (len && reslen && start <= end)
  42. return true;
  43. pr_debug("ACPI: invalid or unassigned resource %s [%016llx - %016llx] length [%016llx]\n",
  44. io ? "io" : "mem", start, end, len);
  45. return false;
  46. }
  47. static void acpi_dev_memresource_flags(struct resource *res, u64 len,
  48. u8 write_protect)
  49. {
  50. res->flags = IORESOURCE_MEM;
  51. if (!acpi_dev_resource_len_valid(res->start, res->end, len, false))
  52. res->flags |= IORESOURCE_DISABLED | IORESOURCE_UNSET;
  53. if (write_protect == ACPI_READ_WRITE_MEMORY)
  54. res->flags |= IORESOURCE_MEM_WRITEABLE;
  55. }
  56. static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len,
  57. u8 write_protect)
  58. {
  59. res->start = start;
  60. res->end = start + len - 1;
  61. acpi_dev_memresource_flags(res, len, write_protect);
  62. }
  63. /**
  64. * acpi_dev_resource_memory - Extract ACPI memory resource information.
  65. * @ares: Input ACPI resource object.
  66. * @res: Output generic resource object.
  67. *
  68. * Check if the given ACPI resource object represents a memory resource and
  69. * if that's the case, use the information in it to populate the generic
  70. * resource object pointed to by @res.
  71. *
  72. * Return:
  73. * 1) false with res->flags setting to zero: not the expected resource type
  74. * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource
  75. * 3) true: valid assigned resource
  76. */
  77. bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res)
  78. {
  79. struct acpi_resource_memory24 *memory24;
  80. struct acpi_resource_memory32 *memory32;
  81. struct acpi_resource_fixed_memory32 *fixed_memory32;
  82. switch (ares->type) {
  83. case ACPI_RESOURCE_TYPE_MEMORY24:
  84. memory24 = &ares->data.memory24;
  85. acpi_dev_get_memresource(res, memory24->minimum << 8,
  86. memory24->address_length << 8,
  87. memory24->write_protect);
  88. break;
  89. case ACPI_RESOURCE_TYPE_MEMORY32:
  90. memory32 = &ares->data.memory32;
  91. acpi_dev_get_memresource(res, memory32->minimum,
  92. memory32->address_length,
  93. memory32->write_protect);
  94. break;
  95. case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
  96. fixed_memory32 = &ares->data.fixed_memory32;
  97. acpi_dev_get_memresource(res, fixed_memory32->address,
  98. fixed_memory32->address_length,
  99. fixed_memory32->write_protect);
  100. break;
  101. default:
  102. res->flags = 0;
  103. return false;
  104. }
  105. return !(res->flags & IORESOURCE_DISABLED);
  106. }
  107. EXPORT_SYMBOL_GPL(acpi_dev_resource_memory);
  108. static void acpi_dev_ioresource_flags(struct resource *res, u64 len,
  109. u8 io_decode)
  110. {
  111. res->flags = IORESOURCE_IO;
  112. if (!acpi_dev_resource_len_valid(res->start, res->end, len, true))
  113. res->flags |= IORESOURCE_DISABLED | IORESOURCE_UNSET;
  114. if (res->end >= 0x10003)
  115. res->flags |= IORESOURCE_DISABLED | IORESOURCE_UNSET;
  116. if (io_decode == ACPI_DECODE_16)
  117. res->flags |= IORESOURCE_IO_16BIT_ADDR;
  118. }
  119. static void acpi_dev_get_ioresource(struct resource *res, u64 start, u64 len,
  120. u8 io_decode)
  121. {
  122. res->start = start;
  123. res->end = start + len - 1;
  124. acpi_dev_ioresource_flags(res, len, io_decode);
  125. }
  126. /**
  127. * acpi_dev_resource_io - Extract ACPI I/O resource information.
  128. * @ares: Input ACPI resource object.
  129. * @res: Output generic resource object.
  130. *
  131. * Check if the given ACPI resource object represents an I/O resource and
  132. * if that's the case, use the information in it to populate the generic
  133. * resource object pointed to by @res.
  134. *
  135. * Return:
  136. * 1) false with res->flags setting to zero: not the expected resource type
  137. * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource
  138. * 3) true: valid assigned resource
  139. */
  140. bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res)
  141. {
  142. struct acpi_resource_io *io;
  143. struct acpi_resource_fixed_io *fixed_io;
  144. switch (ares->type) {
  145. case ACPI_RESOURCE_TYPE_IO:
  146. io = &ares->data.io;
  147. acpi_dev_get_ioresource(res, io->minimum,
  148. io->address_length,
  149. io->io_decode);
  150. break;
  151. case ACPI_RESOURCE_TYPE_FIXED_IO:
  152. fixed_io = &ares->data.fixed_io;
  153. acpi_dev_get_ioresource(res, fixed_io->address,
  154. fixed_io->address_length,
  155. ACPI_DECODE_10);
  156. break;
  157. default:
  158. res->flags = 0;
  159. return false;
  160. }
  161. return !(res->flags & IORESOURCE_DISABLED);
  162. }
  163. EXPORT_SYMBOL_GPL(acpi_dev_resource_io);
  164. static bool acpi_decode_space(struct resource_win *win,
  165. struct acpi_resource_address *addr,
  166. struct acpi_address64_attribute *attr)
  167. {
  168. u8 iodec = attr->granularity == 0xfff ? ACPI_DECODE_10 : ACPI_DECODE_16;
  169. bool wp = addr->info.mem.write_protect;
  170. u64 len = attr->address_length;
  171. struct resource *res = &win->res;
  172. /*
  173. * Filter out invalid descriptor according to ACPI Spec 5.0, section
  174. * 6.4.3.5 Address Space Resource Descriptors.
  175. */
  176. if ((addr->min_address_fixed != addr->max_address_fixed && len) ||
  177. (addr->min_address_fixed && addr->max_address_fixed && !len))
  178. pr_debug("ACPI: Invalid address space min_addr_fix %d, max_addr_fix %d, len %llx\n",
  179. addr->min_address_fixed, addr->max_address_fixed, len);
  180. res->start = attr->minimum;
  181. res->end = attr->maximum;
  182. /*
  183. * For bridges that translate addresses across the bridge,
  184. * translation_offset is the offset that must be added to the
  185. * address on the secondary side to obtain the address on the
  186. * primary side. Non-bridge devices must list 0 for all Address
  187. * Translation offset bits.
  188. */
  189. if (addr->producer_consumer == ACPI_PRODUCER) {
  190. res->start += attr->translation_offset;
  191. res->end += attr->translation_offset;
  192. } else if (attr->translation_offset) {
  193. pr_debug("ACPI: translation_offset(%lld) is invalid for non-bridge device.\n",
  194. attr->translation_offset);
  195. }
  196. switch (addr->resource_type) {
  197. case ACPI_MEMORY_RANGE:
  198. acpi_dev_memresource_flags(res, len, wp);
  199. break;
  200. case ACPI_IO_RANGE:
  201. acpi_dev_ioresource_flags(res, len, iodec);
  202. break;
  203. case ACPI_BUS_NUMBER_RANGE:
  204. res->flags = IORESOURCE_BUS;
  205. break;
  206. default:
  207. return false;
  208. }
  209. win->offset = attr->translation_offset;
  210. if (addr->producer_consumer == ACPI_PRODUCER)
  211. res->flags |= IORESOURCE_WINDOW;
  212. if (addr->info.mem.caching == ACPI_PREFETCHABLE_MEMORY)
  213. res->flags |= IORESOURCE_PREFETCH;
  214. return !(res->flags & IORESOURCE_DISABLED);
  215. }
  216. /**
  217. * acpi_dev_resource_address_space - Extract ACPI address space information.
  218. * @ares: Input ACPI resource object.
  219. * @win: Output generic resource object.
  220. *
  221. * Check if the given ACPI resource object represents an address space resource
  222. * and if that's the case, use the information in it to populate the generic
  223. * resource object pointed to by @win.
  224. *
  225. * Return:
  226. * 1) false with win->res.flags setting to zero: not the expected resource type
  227. * 2) false with IORESOURCE_DISABLED in win->res.flags: valid unassigned
  228. * resource
  229. * 3) true: valid assigned resource
  230. */
  231. bool acpi_dev_resource_address_space(struct acpi_resource *ares,
  232. struct resource_win *win)
  233. {
  234. struct acpi_resource_address64 addr;
  235. win->res.flags = 0;
  236. if (ACPI_FAILURE(acpi_resource_to_address64(ares, &addr)))
  237. return false;
  238. return acpi_decode_space(win, (struct acpi_resource_address *)&addr,
  239. &addr.address);
  240. }
  241. EXPORT_SYMBOL_GPL(acpi_dev_resource_address_space);
  242. /**
  243. * acpi_dev_resource_ext_address_space - Extract ACPI address space information.
  244. * @ares: Input ACPI resource object.
  245. * @win: Output generic resource object.
  246. *
  247. * Check if the given ACPI resource object represents an extended address space
  248. * resource and if that's the case, use the information in it to populate the
  249. * generic resource object pointed to by @win.
  250. *
  251. * Return:
  252. * 1) false with win->res.flags setting to zero: not the expected resource type
  253. * 2) false with IORESOURCE_DISABLED in win->res.flags: valid unassigned
  254. * resource
  255. * 3) true: valid assigned resource
  256. */
  257. bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares,
  258. struct resource_win *win)
  259. {
  260. struct acpi_resource_extended_address64 *ext_addr;
  261. win->res.flags = 0;
  262. if (ares->type != ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64)
  263. return false;
  264. ext_addr = &ares->data.ext_address64;
  265. return acpi_decode_space(win, (struct acpi_resource_address *)ext_addr,
  266. &ext_addr->address);
  267. }
  268. EXPORT_SYMBOL_GPL(acpi_dev_resource_ext_address_space);
  269. /**
  270. * acpi_dev_irq_flags - Determine IRQ resource flags.
  271. * @triggering: Triggering type as provided by ACPI.
  272. * @polarity: Interrupt polarity as provided by ACPI.
  273. * @shareable: Whether or not the interrupt is shareable.
  274. */
  275. unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable)
  276. {
  277. unsigned long flags;
  278. if (triggering == ACPI_LEVEL_SENSITIVE)
  279. flags = polarity == ACPI_ACTIVE_LOW ?
  280. IORESOURCE_IRQ_LOWLEVEL : IORESOURCE_IRQ_HIGHLEVEL;
  281. else
  282. flags = polarity == ACPI_ACTIVE_LOW ?
  283. IORESOURCE_IRQ_LOWEDGE : IORESOURCE_IRQ_HIGHEDGE;
  284. if (shareable == ACPI_SHARED)
  285. flags |= IORESOURCE_IRQ_SHAREABLE;
  286. return flags | IORESOURCE_IRQ;
  287. }
  288. EXPORT_SYMBOL_GPL(acpi_dev_irq_flags);
  289. static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi)
  290. {
  291. res->start = gsi;
  292. res->end = gsi;
  293. res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET;
  294. }
  295. static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
  296. u8 triggering, u8 polarity, u8 shareable,
  297. bool legacy)
  298. {
  299. int irq, p, t;
  300. if (!valid_IRQ(gsi)) {
  301. acpi_dev_irqresource_disabled(res, gsi);
  302. return;
  303. }
  304. /*
  305. * In IO-APIC mode, use overrided attribute. Two reasons:
  306. * 1. BIOS bug in DSDT
  307. * 2. BIOS uses IO-APIC mode Interrupt Source Override
  308. *
  309. * We do this only if we are dealing with IRQ() or IRQNoFlags()
  310. * resource (the legacy ISA resources). With modern ACPI 5 devices
  311. * using extended IRQ descriptors we take the IRQ configuration
  312. * from _CRS directly.
  313. */
  314. if (legacy && !acpi_get_override_irq(gsi, &t, &p)) {
  315. u8 trig = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
  316. u8 pol = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
  317. if (triggering != trig || polarity != pol) {
  318. pr_warning("ACPI: IRQ %d override to %s, %s\n", gsi,
  319. t ? "level" : "edge", p ? "low" : "high");
  320. triggering = trig;
  321. polarity = pol;
  322. }
  323. }
  324. res->flags = acpi_dev_irq_flags(triggering, polarity, shareable);
  325. irq = acpi_register_gsi(NULL, gsi, triggering, polarity);
  326. if (irq >= 0) {
  327. res->start = irq;
  328. res->end = irq;
  329. } else {
  330. acpi_dev_irqresource_disabled(res, gsi);
  331. }
  332. }
  333. /**
  334. * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information.
  335. * @ares: Input ACPI resource object.
  336. * @index: Index into the array of GSIs represented by the resource.
  337. * @res: Output generic resource object.
  338. *
  339. * Check if the given ACPI resource object represents an interrupt resource
  340. * and @index does not exceed the resource's interrupt count (true is returned
  341. * in that case regardless of the results of the other checks)). If that's the
  342. * case, register the GSI corresponding to @index from the array of interrupts
  343. * represented by the resource and populate the generic resource object pointed
  344. * to by @res accordingly. If the registration of the GSI is not successful,
  345. * IORESOURCE_DISABLED will be set it that object's flags.
  346. *
  347. * Return:
  348. * 1) false with res->flags setting to zero: not the expected resource type
  349. * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource
  350. * 3) true: valid assigned resource
  351. */
  352. bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
  353. struct resource *res)
  354. {
  355. struct acpi_resource_irq *irq;
  356. struct acpi_resource_extended_irq *ext_irq;
  357. switch (ares->type) {
  358. case ACPI_RESOURCE_TYPE_IRQ:
  359. /*
  360. * Per spec, only one interrupt per descriptor is allowed in
  361. * _CRS, but some firmware violates this, so parse them all.
  362. */
  363. irq = &ares->data.irq;
  364. if (index >= irq->interrupt_count) {
  365. acpi_dev_irqresource_disabled(res, 0);
  366. return false;
  367. }
  368. acpi_dev_get_irqresource(res, irq->interrupts[index],
  369. irq->triggering, irq->polarity,
  370. irq->sharable, true);
  371. break;
  372. case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
  373. ext_irq = &ares->data.extended_irq;
  374. if (index >= ext_irq->interrupt_count) {
  375. acpi_dev_irqresource_disabled(res, 0);
  376. return false;
  377. }
  378. acpi_dev_get_irqresource(res, ext_irq->interrupts[index],
  379. ext_irq->triggering, ext_irq->polarity,
  380. ext_irq->sharable, false);
  381. break;
  382. default:
  383. res->flags = 0;
  384. return false;
  385. }
  386. return true;
  387. }
  388. EXPORT_SYMBOL_GPL(acpi_dev_resource_interrupt);
  389. /**
  390. * acpi_dev_free_resource_list - Free resource from %acpi_dev_get_resources().
  391. * @list: The head of the resource list to free.
  392. */
  393. void acpi_dev_free_resource_list(struct list_head *list)
  394. {
  395. resource_list_free(list);
  396. }
  397. EXPORT_SYMBOL_GPL(acpi_dev_free_resource_list);
  398. struct res_proc_context {
  399. struct list_head *list;
  400. int (*preproc)(struct acpi_resource *, void *);
  401. void *preproc_data;
  402. int count;
  403. int error;
  404. };
  405. static acpi_status acpi_dev_new_resource_entry(struct resource_win *win,
  406. struct res_proc_context *c)
  407. {
  408. struct resource_entry *rentry;
  409. rentry = resource_list_create_entry(NULL, 0);
  410. if (!rentry) {
  411. c->error = -ENOMEM;
  412. return AE_NO_MEMORY;
  413. }
  414. *rentry->res = win->res;
  415. rentry->offset = win->offset;
  416. resource_list_add_tail(rentry, c->list);
  417. c->count++;
  418. return AE_OK;
  419. }
  420. static acpi_status acpi_dev_process_resource(struct acpi_resource *ares,
  421. void *context)
  422. {
  423. struct res_proc_context *c = context;
  424. struct resource_win win;
  425. struct resource *res = &win.res;
  426. int i;
  427. if (c->preproc) {
  428. int ret;
  429. ret = c->preproc(ares, c->preproc_data);
  430. if (ret < 0) {
  431. c->error = ret;
  432. return AE_CTRL_TERMINATE;
  433. } else if (ret > 0) {
  434. return AE_OK;
  435. }
  436. }
  437. memset(&win, 0, sizeof(win));
  438. if (acpi_dev_resource_memory(ares, res)
  439. || acpi_dev_resource_io(ares, res)
  440. || acpi_dev_resource_address_space(ares, &win)
  441. || acpi_dev_resource_ext_address_space(ares, &win))
  442. return acpi_dev_new_resource_entry(&win, c);
  443. for (i = 0; acpi_dev_resource_interrupt(ares, i, res); i++) {
  444. acpi_status status;
  445. status = acpi_dev_new_resource_entry(&win, c);
  446. if (ACPI_FAILURE(status))
  447. return status;
  448. }
  449. return AE_OK;
  450. }
  451. /**
  452. * acpi_dev_get_resources - Get current resources of a device.
  453. * @adev: ACPI device node to get the resources for.
  454. * @list: Head of the resultant list of resources (must be empty).
  455. * @preproc: The caller's preprocessing routine.
  456. * @preproc_data: Pointer passed to the caller's preprocessing routine.
  457. *
  458. * Evaluate the _CRS method for the given device node and process its output by
  459. * (1) executing the @preproc() rountine provided by the caller, passing the
  460. * resource pointer and @preproc_data to it as arguments, for each ACPI resource
  461. * returned and (2) converting all of the returned ACPI resources into struct
  462. * resource objects if possible. If the return value of @preproc() in step (1)
  463. * is different from 0, step (2) is not applied to the given ACPI resource and
  464. * if that value is negative, the whole processing is aborted and that value is
  465. * returned as the final error code.
  466. *
  467. * The resultant struct resource objects are put on the list pointed to by
  468. * @list, that must be empty initially, as members of struct resource_entry
  469. * objects. Callers of this routine should use %acpi_dev_free_resource_list() to
  470. * free that list.
  471. *
  472. * The number of resources in the output list is returned on success, an error
  473. * code reflecting the error condition is returned otherwise.
  474. */
  475. int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
  476. int (*preproc)(struct acpi_resource *, void *),
  477. void *preproc_data)
  478. {
  479. struct res_proc_context c;
  480. acpi_status status;
  481. if (!adev || !adev->handle || !list_empty(list))
  482. return -EINVAL;
  483. if (!acpi_has_method(adev->handle, METHOD_NAME__CRS))
  484. return 0;
  485. c.list = list;
  486. c.preproc = preproc;
  487. c.preproc_data = preproc_data;
  488. c.count = 0;
  489. c.error = 0;
  490. status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
  491. acpi_dev_process_resource, &c);
  492. if (ACPI_FAILURE(status)) {
  493. acpi_dev_free_resource_list(list);
  494. return c.error ? c.error : -EIO;
  495. }
  496. return c.count;
  497. }
  498. EXPORT_SYMBOL_GPL(acpi_dev_get_resources);
  499. /**
  500. * acpi_dev_filter_resource_type - Filter ACPI resource according to resource
  501. * types
  502. * @ares: Input ACPI resource object.
  503. * @types: Valid resource types of IORESOURCE_XXX
  504. *
  505. * This is a helper function to support acpi_dev_get_resources(), which filters
  506. * ACPI resource objects according to resource types.
  507. */
  508. int acpi_dev_filter_resource_type(struct acpi_resource *ares,
  509. unsigned long types)
  510. {
  511. unsigned long type = 0;
  512. switch (ares->type) {
  513. case ACPI_RESOURCE_TYPE_MEMORY24:
  514. case ACPI_RESOURCE_TYPE_MEMORY32:
  515. case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
  516. type = IORESOURCE_MEM;
  517. break;
  518. case ACPI_RESOURCE_TYPE_IO:
  519. case ACPI_RESOURCE_TYPE_FIXED_IO:
  520. type = IORESOURCE_IO;
  521. break;
  522. case ACPI_RESOURCE_TYPE_IRQ:
  523. case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
  524. type = IORESOURCE_IRQ;
  525. break;
  526. case ACPI_RESOURCE_TYPE_DMA:
  527. case ACPI_RESOURCE_TYPE_FIXED_DMA:
  528. type = IORESOURCE_DMA;
  529. break;
  530. case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
  531. type = IORESOURCE_REG;
  532. break;
  533. case ACPI_RESOURCE_TYPE_ADDRESS16:
  534. case ACPI_RESOURCE_TYPE_ADDRESS32:
  535. case ACPI_RESOURCE_TYPE_ADDRESS64:
  536. case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
  537. if (ares->data.address.resource_type == ACPI_MEMORY_RANGE)
  538. type = IORESOURCE_MEM;
  539. else if (ares->data.address.resource_type == ACPI_IO_RANGE)
  540. type = IORESOURCE_IO;
  541. else if (ares->data.address.resource_type ==
  542. ACPI_BUS_NUMBER_RANGE)
  543. type = IORESOURCE_BUS;
  544. break;
  545. default:
  546. break;
  547. }
  548. return (type & types) ? 0 : 1;
  549. }
  550. EXPORT_SYMBOL_GPL(acpi_dev_filter_resource_type);
  551. struct reserved_region {
  552. struct list_head node;
  553. u64 start;
  554. u64 end;
  555. };
  556. static LIST_HEAD(reserved_io_regions);
  557. static LIST_HEAD(reserved_mem_regions);
  558. static int request_range(u64 start, u64 end, u8 space_id, unsigned long flags,
  559. char *desc)
  560. {
  561. unsigned int length = end - start + 1;
  562. struct resource *res;
  563. res = space_id == ACPI_ADR_SPACE_SYSTEM_IO ?
  564. request_region(start, length, desc) :
  565. request_mem_region(start, length, desc);
  566. if (!res)
  567. return -EIO;
  568. res->flags &= ~flags;
  569. return 0;
  570. }
  571. static int add_region_before(u64 start, u64 end, u8 space_id,
  572. unsigned long flags, char *desc,
  573. struct list_head *head)
  574. {
  575. struct reserved_region *reg;
  576. int error;
  577. reg = kmalloc(sizeof(*reg), GFP_KERNEL);
  578. if (!reg)
  579. return -ENOMEM;
  580. error = request_range(start, end, space_id, flags, desc);
  581. if (error) {
  582. kfree(reg);
  583. return error;
  584. }
  585. reg->start = start;
  586. reg->end = end;
  587. list_add_tail(&reg->node, head);
  588. return 0;
  589. }
  590. /**
  591. * acpi_reserve_region - Reserve an I/O or memory region as a system resource.
  592. * @start: Starting address of the region.
  593. * @length: Length of the region.
  594. * @space_id: Identifier of address space to reserve the region from.
  595. * @flags: Resource flags to clear for the region after requesting it.
  596. * @desc: Region description (for messages).
  597. *
  598. * Reserve an I/O or memory region as a system resource to prevent others from
  599. * using it. If the new region overlaps with one of the regions (in the given
  600. * address space) already reserved by this routine, only the non-overlapping
  601. * parts of it will be reserved.
  602. *
  603. * Returned is either 0 (success) or a negative error code indicating a resource
  604. * reservation problem. It is the code of the first encountered error, but the
  605. * routine doesn't abort until it has attempted to request all of the parts of
  606. * the new region that don't overlap with other regions reserved previously.
  607. *
  608. * The resources requested by this routine are never released.
  609. */
  610. int acpi_reserve_region(u64 start, unsigned int length, u8 space_id,
  611. unsigned long flags, char *desc)
  612. {
  613. struct list_head *regions;
  614. struct reserved_region *reg;
  615. u64 end = start + length - 1;
  616. int ret = 0, error = 0;
  617. if (space_id == ACPI_ADR_SPACE_SYSTEM_IO)
  618. regions = &reserved_io_regions;
  619. else if (space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
  620. regions = &reserved_mem_regions;
  621. else
  622. return -EINVAL;
  623. if (list_empty(regions))
  624. return add_region_before(start, end, space_id, flags, desc, regions);
  625. list_for_each_entry(reg, regions, node)
  626. if (reg->start == end + 1) {
  627. /* The new region can be prepended to this one. */
  628. ret = request_range(start, end, space_id, flags, desc);
  629. if (!ret)
  630. reg->start = start;
  631. return ret;
  632. } else if (reg->start > end) {
  633. /* No overlap. Add the new region here and get out. */
  634. return add_region_before(start, end, space_id, flags,
  635. desc, &reg->node);
  636. } else if (reg->end == start - 1) {
  637. goto combine;
  638. } else if (reg->end >= start) {
  639. goto overlap;
  640. }
  641. /* The new region goes after the last existing one. */
  642. return add_region_before(start, end, space_id, flags, desc, regions);
  643. overlap:
  644. /*
  645. * The new region overlaps an existing one.
  646. *
  647. * The head part of the new region immediately preceding the existing
  648. * overlapping one can be combined with it right away.
  649. */
  650. if (reg->start > start) {
  651. error = request_range(start, reg->start - 1, space_id, flags, desc);
  652. if (error)
  653. ret = error;
  654. else
  655. reg->start = start;
  656. }
  657. combine:
  658. /*
  659. * The new region is adjacent to an existing one. If it extends beyond
  660. * that region all the way to the next one, it is possible to combine
  661. * all three of them.
  662. */
  663. while (reg->end < end) {
  664. struct reserved_region *next = NULL;
  665. u64 a = reg->end + 1, b = end;
  666. if (!list_is_last(&reg->node, regions)) {
  667. next = list_next_entry(reg, node);
  668. if (next->start <= end)
  669. b = next->start - 1;
  670. }
  671. error = request_range(a, b, space_id, flags, desc);
  672. if (!error) {
  673. if (next && next->start == b + 1) {
  674. reg->end = next->end;
  675. list_del(&next->node);
  676. kfree(next);
  677. } else {
  678. reg->end = end;
  679. break;
  680. }
  681. } else if (next) {
  682. if (!ret)
  683. ret = error;
  684. reg = next;
  685. } else {
  686. break;
  687. }
  688. }
  689. return ret ? ret : error;
  690. }
  691. EXPORT_SYMBOL_GPL(acpi_reserve_region);