rsparser.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087
  1. /*
  2. * pnpacpi -- PnP ACPI driver
  3. *
  4. * Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr>
  5. * Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation; either version 2, or (at your option) any
  10. * later version.
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. */
  21. #include <linux/kernel.h>
  22. #include <linux/acpi.h>
  23. #include <linux/pci.h>
  24. #include <linux/pnp.h>
  25. #include "../base.h"
  26. #include "pnpacpi.h"
  27. #ifdef CONFIG_IA64
  28. #define valid_IRQ(i) (1)
  29. #else
  30. #define valid_IRQ(i) (((i) != 0) && ((i) != 2))
  31. #endif
  32. /*
  33. * Allocated Resources
  34. */
  35. static int irq_flags(int triggering, int polarity, int shareable)
  36. {
  37. int flags;
  38. if (triggering == ACPI_LEVEL_SENSITIVE) {
  39. if (polarity == ACPI_ACTIVE_LOW)
  40. flags = IORESOURCE_IRQ_LOWLEVEL;
  41. else
  42. flags = IORESOURCE_IRQ_HIGHLEVEL;
  43. } else {
  44. if (polarity == ACPI_ACTIVE_LOW)
  45. flags = IORESOURCE_IRQ_LOWEDGE;
  46. else
  47. flags = IORESOURCE_IRQ_HIGHEDGE;
  48. }
  49. if (shareable)
  50. flags |= IORESOURCE_IRQ_SHAREABLE;
  51. return flags;
  52. }
  53. static void decode_irq_flags(int flag, int *triggering, int *polarity)
  54. {
  55. switch (flag) {
  56. case IORESOURCE_IRQ_LOWLEVEL:
  57. *triggering = ACPI_LEVEL_SENSITIVE;
  58. *polarity = ACPI_ACTIVE_LOW;
  59. break;
  60. case IORESOURCE_IRQ_HIGHLEVEL:
  61. *triggering = ACPI_LEVEL_SENSITIVE;
  62. *polarity = ACPI_ACTIVE_HIGH;
  63. break;
  64. case IORESOURCE_IRQ_LOWEDGE:
  65. *triggering = ACPI_EDGE_SENSITIVE;
  66. *polarity = ACPI_ACTIVE_LOW;
  67. break;
  68. case IORESOURCE_IRQ_HIGHEDGE:
  69. *triggering = ACPI_EDGE_SENSITIVE;
  70. *polarity = ACPI_ACTIVE_HIGH;
  71. break;
  72. }
  73. }
  74. static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev,
  75. u32 gsi, int triggering,
  76. int polarity, int shareable)
  77. {
  78. struct pnp_resource_table *res = dev->res;
  79. int i = 0;
  80. int irq;
  81. int p, t;
  82. static unsigned char warned;
  83. if (!valid_IRQ(gsi))
  84. return;
  85. while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) &&
  86. i < PNP_MAX_IRQ)
  87. i++;
  88. if (i >= PNP_MAX_IRQ) {
  89. if (!warned) {
  90. printk(KERN_WARNING "pnpacpi: exceeded the max number"
  91. " of IRQ resources: %d\n", PNP_MAX_IRQ);
  92. warned = 1;
  93. }
  94. return;
  95. }
  96. /*
  97. * in IO-APIC mode, use overrided attribute. Two reasons:
  98. * 1. BIOS bug in DSDT
  99. * 2. BIOS uses IO-APIC mode Interrupt Source Override
  100. */
  101. if (!acpi_get_override_irq(gsi, &t, &p)) {
  102. t = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
  103. p = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
  104. if (triggering != t || polarity != p) {
  105. dev_warn(&dev->dev, "IRQ %d override to %s, %s\n",
  106. gsi, t ? "edge":"level", p ? "low":"high");
  107. triggering = t;
  108. polarity = p;
  109. }
  110. }
  111. res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag
  112. res->irq_resource[i].flags |= irq_flags(triggering, polarity, shareable);
  113. irq = acpi_register_gsi(gsi, triggering, polarity);
  114. if (irq < 0) {
  115. res->irq_resource[i].flags |= IORESOURCE_DISABLED;
  116. return;
  117. }
  118. res->irq_resource[i].start = irq;
  119. res->irq_resource[i].end = irq;
  120. pcibios_penalize_isa_irq(irq, 1);
  121. }
  122. static int dma_flags(int type, int bus_master, int transfer)
  123. {
  124. int flags = 0;
  125. if (bus_master)
  126. flags |= IORESOURCE_DMA_MASTER;
  127. switch (type) {
  128. case ACPI_COMPATIBILITY:
  129. flags |= IORESOURCE_DMA_COMPATIBLE;
  130. break;
  131. case ACPI_TYPE_A:
  132. flags |= IORESOURCE_DMA_TYPEA;
  133. break;
  134. case ACPI_TYPE_B:
  135. flags |= IORESOURCE_DMA_TYPEB;
  136. break;
  137. case ACPI_TYPE_F:
  138. flags |= IORESOURCE_DMA_TYPEF;
  139. break;
  140. default:
  141. /* Set a default value ? */
  142. flags |= IORESOURCE_DMA_COMPATIBLE;
  143. pnp_err("Invalid DMA type");
  144. }
  145. switch (transfer) {
  146. case ACPI_TRANSFER_8:
  147. flags |= IORESOURCE_DMA_8BIT;
  148. break;
  149. case ACPI_TRANSFER_8_16:
  150. flags |= IORESOURCE_DMA_8AND16BIT;
  151. break;
  152. case ACPI_TRANSFER_16:
  153. flags |= IORESOURCE_DMA_16BIT;
  154. break;
  155. default:
  156. /* Set a default value ? */
  157. flags |= IORESOURCE_DMA_8AND16BIT;
  158. pnp_err("Invalid DMA transfer type");
  159. }
  160. return flags;
  161. }
  162. static void pnpacpi_parse_allocated_dmaresource(struct pnp_dev *dev,
  163. u32 dma, int flags)
  164. {
  165. struct pnp_resource_table *res = dev->res;
  166. int i = 0;
  167. static unsigned char warned;
  168. while (i < PNP_MAX_DMA &&
  169. !(res->dma_resource[i].flags & IORESOURCE_UNSET))
  170. i++;
  171. if (i < PNP_MAX_DMA) {
  172. res->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag
  173. res->dma_resource[i].flags |= flags;
  174. if (dma == -1) {
  175. res->dma_resource[i].flags |= IORESOURCE_DISABLED;
  176. return;
  177. }
  178. res->dma_resource[i].start = dma;
  179. res->dma_resource[i].end = dma;
  180. } else if (!warned) {
  181. printk(KERN_WARNING "pnpacpi: exceeded the max number of DMA "
  182. "resources: %d \n", PNP_MAX_DMA);
  183. warned = 1;
  184. }
  185. }
  186. static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev,
  187. u64 io, u64 len, int io_decode)
  188. {
  189. struct pnp_resource_table *res = dev->res;
  190. int i = 0;
  191. static unsigned char warned;
  192. while (!(res->port_resource[i].flags & IORESOURCE_UNSET) &&
  193. i < PNP_MAX_PORT)
  194. i++;
  195. if (i < PNP_MAX_PORT) {
  196. res->port_resource[i].flags = IORESOURCE_IO; // Also clears _UNSET flag
  197. if (io_decode == ACPI_DECODE_16)
  198. res->port_resource[i].flags |= PNP_PORT_FLAG_16BITADDR;
  199. if (len <= 0 || (io + len - 1) >= 0x10003) {
  200. res->port_resource[i].flags |= IORESOURCE_DISABLED;
  201. return;
  202. }
  203. res->port_resource[i].start = io;
  204. res->port_resource[i].end = io + len - 1;
  205. } else if (!warned) {
  206. printk(KERN_WARNING "pnpacpi: exceeded the max number of IO "
  207. "resources: %d \n", PNP_MAX_PORT);
  208. warned = 1;
  209. }
  210. }
  211. static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev,
  212. u64 mem, u64 len,
  213. int write_protect)
  214. {
  215. struct pnp_resource_table *res = dev->res;
  216. int i = 0;
  217. static unsigned char warned;
  218. while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) &&
  219. (i < PNP_MAX_MEM))
  220. i++;
  221. if (i < PNP_MAX_MEM) {
  222. res->mem_resource[i].flags = IORESOURCE_MEM; // Also clears _UNSET flag
  223. if (len <= 0) {
  224. res->mem_resource[i].flags |= IORESOURCE_DISABLED;
  225. return;
  226. }
  227. if (write_protect == ACPI_READ_WRITE_MEMORY)
  228. res->mem_resource[i].flags |= IORESOURCE_MEM_WRITEABLE;
  229. res->mem_resource[i].start = mem;
  230. res->mem_resource[i].end = mem + len - 1;
  231. } else if (!warned) {
  232. printk(KERN_WARNING "pnpacpi: exceeded the max number of mem "
  233. "resources: %d\n", PNP_MAX_MEM);
  234. warned = 1;
  235. }
  236. }
  237. static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
  238. struct acpi_resource *res)
  239. {
  240. struct acpi_resource_address64 addr, *p = &addr;
  241. acpi_status status;
  242. status = acpi_resource_to_address64(res, p);
  243. if (!ACPI_SUCCESS(status)) {
  244. dev_warn(&dev->dev, "failed to convert resource type %d\n",
  245. res->type);
  246. return;
  247. }
  248. if (p->producer_consumer == ACPI_PRODUCER)
  249. return;
  250. if (p->resource_type == ACPI_MEMORY_RANGE)
  251. pnpacpi_parse_allocated_memresource(dev,
  252. p->minimum, p->address_length,
  253. p->info.mem.write_protect);
  254. else if (p->resource_type == ACPI_IO_RANGE)
  255. pnpacpi_parse_allocated_ioresource(dev,
  256. p->minimum, p->address_length,
  257. p->granularity == 0xfff ? ACPI_DECODE_10 :
  258. ACPI_DECODE_16);
  259. }
  260. static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
  261. void *data)
  262. {
  263. struct pnp_dev *dev = data;
  264. struct acpi_resource_irq *irq;
  265. struct acpi_resource_dma *dma;
  266. struct acpi_resource_io *io;
  267. struct acpi_resource_fixed_io *fixed_io;
  268. struct acpi_resource_memory24 *memory24;
  269. struct acpi_resource_memory32 *memory32;
  270. struct acpi_resource_fixed_memory32 *fixed_memory32;
  271. struct acpi_resource_extended_irq *extended_irq;
  272. int i;
  273. switch (res->type) {
  274. case ACPI_RESOURCE_TYPE_IRQ:
  275. /*
  276. * Per spec, only one interrupt per descriptor is allowed in
  277. * _CRS, but some firmware violates this, so parse them all.
  278. */
  279. irq = &res->data.irq;
  280. for (i = 0; i < irq->interrupt_count; i++) {
  281. pnpacpi_parse_allocated_irqresource(dev,
  282. irq->interrupts[i],
  283. irq->triggering,
  284. irq->polarity,
  285. irq->sharable);
  286. }
  287. break;
  288. case ACPI_RESOURCE_TYPE_DMA:
  289. dma = &res->data.dma;
  290. if (dma->channel_count > 0)
  291. pnpacpi_parse_allocated_dmaresource(dev,
  292. dma->channels[0],
  293. dma_flags(dma->type, dma->bus_master,
  294. dma->transfer));
  295. break;
  296. case ACPI_RESOURCE_TYPE_IO:
  297. io = &res->data.io;
  298. pnpacpi_parse_allocated_ioresource(dev,
  299. io->minimum,
  300. io->address_length,
  301. io->io_decode);
  302. break;
  303. case ACPI_RESOURCE_TYPE_START_DEPENDENT:
  304. case ACPI_RESOURCE_TYPE_END_DEPENDENT:
  305. break;
  306. case ACPI_RESOURCE_TYPE_FIXED_IO:
  307. fixed_io = &res->data.fixed_io;
  308. pnpacpi_parse_allocated_ioresource(dev,
  309. fixed_io->address,
  310. fixed_io->address_length,
  311. ACPI_DECODE_10);
  312. break;
  313. case ACPI_RESOURCE_TYPE_VENDOR:
  314. break;
  315. case ACPI_RESOURCE_TYPE_END_TAG:
  316. break;
  317. case ACPI_RESOURCE_TYPE_MEMORY24:
  318. memory24 = &res->data.memory24;
  319. pnpacpi_parse_allocated_memresource(dev,
  320. memory24->minimum,
  321. memory24->address_length,
  322. memory24->write_protect);
  323. break;
  324. case ACPI_RESOURCE_TYPE_MEMORY32:
  325. memory32 = &res->data.memory32;
  326. pnpacpi_parse_allocated_memresource(dev,
  327. memory32->minimum,
  328. memory32->address_length,
  329. memory32->write_protect);
  330. break;
  331. case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
  332. fixed_memory32 = &res->data.fixed_memory32;
  333. pnpacpi_parse_allocated_memresource(dev,
  334. fixed_memory32->address,
  335. fixed_memory32->address_length,
  336. fixed_memory32->write_protect);
  337. break;
  338. case ACPI_RESOURCE_TYPE_ADDRESS16:
  339. case ACPI_RESOURCE_TYPE_ADDRESS32:
  340. case ACPI_RESOURCE_TYPE_ADDRESS64:
  341. pnpacpi_parse_allocated_address_space(dev, res);
  342. break;
  343. case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
  344. if (res->data.ext_address64.producer_consumer == ACPI_PRODUCER)
  345. return AE_OK;
  346. break;
  347. case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
  348. extended_irq = &res->data.extended_irq;
  349. if (extended_irq->producer_consumer == ACPI_PRODUCER)
  350. return AE_OK;
  351. for (i = 0; i < extended_irq->interrupt_count; i++) {
  352. pnpacpi_parse_allocated_irqresource(dev,
  353. extended_irq->interrupts[i],
  354. extended_irq->triggering,
  355. extended_irq->polarity,
  356. extended_irq->sharable);
  357. }
  358. break;
  359. case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
  360. break;
  361. default:
  362. dev_warn(&dev->dev, "unknown resource type %d in _CRS\n",
  363. res->type);
  364. return AE_ERROR;
  365. }
  366. return AE_OK;
  367. }
  368. acpi_status pnpacpi_parse_allocated_resource(struct pnp_dev *dev)
  369. {
  370. acpi_handle handle = dev->data;
  371. dev_dbg(&dev->dev, "parse allocated resources\n");
  372. pnp_init_resources(dev);
  373. return acpi_walk_resources(handle, METHOD_NAME__CRS,
  374. pnpacpi_allocated_resource, dev);
  375. }
  376. static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev,
  377. struct pnp_option *option,
  378. struct acpi_resource_dma *p)
  379. {
  380. int i;
  381. struct pnp_dma *dma;
  382. if (p->channel_count == 0)
  383. return;
  384. dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
  385. if (!dma)
  386. return;
  387. for (i = 0; i < p->channel_count; i++)
  388. dma->map |= 1 << p->channels[i];
  389. dma->flags = dma_flags(p->type, p->bus_master, p->transfer);
  390. pnp_register_dma_resource(dev, option, dma);
  391. }
  392. static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev,
  393. struct pnp_option *option,
  394. struct acpi_resource_irq *p)
  395. {
  396. int i;
  397. struct pnp_irq *irq;
  398. if (p->interrupt_count == 0)
  399. return;
  400. irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
  401. if (!irq)
  402. return;
  403. for (i = 0; i < p->interrupt_count; i++)
  404. if (p->interrupts[i])
  405. __set_bit(p->interrupts[i], irq->map);
  406. irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
  407. pnp_register_irq_resource(dev, option, irq);
  408. }
  409. static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
  410. struct pnp_option *option,
  411. struct acpi_resource_extended_irq *p)
  412. {
  413. int i;
  414. struct pnp_irq *irq;
  415. if (p->interrupt_count == 0)
  416. return;
  417. irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
  418. if (!irq)
  419. return;
  420. for (i = 0; i < p->interrupt_count; i++)
  421. if (p->interrupts[i])
  422. __set_bit(p->interrupts[i], irq->map);
  423. irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
  424. pnp_register_irq_resource(dev, option, irq);
  425. }
  426. static __init void pnpacpi_parse_port_option(struct pnp_dev *dev,
  427. struct pnp_option *option,
  428. struct acpi_resource_io *io)
  429. {
  430. struct pnp_port *port;
  431. if (io->address_length == 0)
  432. return;
  433. port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
  434. if (!port)
  435. return;
  436. port->min = io->minimum;
  437. port->max = io->maximum;
  438. port->align = io->alignment;
  439. port->size = io->address_length;
  440. port->flags = ACPI_DECODE_16 == io->io_decode ?
  441. PNP_PORT_FLAG_16BITADDR : 0;
  442. pnp_register_port_resource(dev, option, port);
  443. }
  444. static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev,
  445. struct pnp_option *option,
  446. struct acpi_resource_fixed_io *io)
  447. {
  448. struct pnp_port *port;
  449. if (io->address_length == 0)
  450. return;
  451. port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
  452. if (!port)
  453. return;
  454. port->min = port->max = io->address;
  455. port->size = io->address_length;
  456. port->align = 0;
  457. port->flags = PNP_PORT_FLAG_FIXED;
  458. pnp_register_port_resource(dev, option, port);
  459. }
  460. static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev,
  461. struct pnp_option *option,
  462. struct acpi_resource_memory24 *p)
  463. {
  464. struct pnp_mem *mem;
  465. if (p->address_length == 0)
  466. return;
  467. mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
  468. if (!mem)
  469. return;
  470. mem->min = p->minimum;
  471. mem->max = p->maximum;
  472. mem->align = p->alignment;
  473. mem->size = p->address_length;
  474. mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
  475. IORESOURCE_MEM_WRITEABLE : 0;
  476. pnp_register_mem_resource(dev, option, mem);
  477. }
  478. static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev,
  479. struct pnp_option *option,
  480. struct acpi_resource_memory32 *p)
  481. {
  482. struct pnp_mem *mem;
  483. if (p->address_length == 0)
  484. return;
  485. mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
  486. if (!mem)
  487. return;
  488. mem->min = p->minimum;
  489. mem->max = p->maximum;
  490. mem->align = p->alignment;
  491. mem->size = p->address_length;
  492. mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
  493. IORESOURCE_MEM_WRITEABLE : 0;
  494. pnp_register_mem_resource(dev, option, mem);
  495. }
  496. static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev,
  497. struct pnp_option *option,
  498. struct acpi_resource_fixed_memory32 *p)
  499. {
  500. struct pnp_mem *mem;
  501. if (p->address_length == 0)
  502. return;
  503. mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
  504. if (!mem)
  505. return;
  506. mem->min = mem->max = p->address;
  507. mem->size = p->address_length;
  508. mem->align = 0;
  509. mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
  510. IORESOURCE_MEM_WRITEABLE : 0;
  511. pnp_register_mem_resource(dev, option, mem);
  512. }
  513. static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
  514. struct pnp_option *option,
  515. struct acpi_resource *r)
  516. {
  517. struct acpi_resource_address64 addr, *p = &addr;
  518. acpi_status status;
  519. struct pnp_mem *mem;
  520. struct pnp_port *port;
  521. status = acpi_resource_to_address64(r, p);
  522. if (!ACPI_SUCCESS(status)) {
  523. pnp_warn("PnPACPI: failed to convert resource type %d",
  524. r->type);
  525. return;
  526. }
  527. if (p->address_length == 0)
  528. return;
  529. if (p->resource_type == ACPI_MEMORY_RANGE) {
  530. mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
  531. if (!mem)
  532. return;
  533. mem->min = mem->max = p->minimum;
  534. mem->size = p->address_length;
  535. mem->align = 0;
  536. mem->flags = (p->info.mem.write_protect ==
  537. ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE
  538. : 0;
  539. pnp_register_mem_resource(dev, option, mem);
  540. } else if (p->resource_type == ACPI_IO_RANGE) {
  541. port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
  542. if (!port)
  543. return;
  544. port->min = port->max = p->minimum;
  545. port->size = p->address_length;
  546. port->align = 0;
  547. port->flags = PNP_PORT_FLAG_FIXED;
  548. pnp_register_port_resource(dev, option, port);
  549. }
  550. }
  551. struct acpipnp_parse_option_s {
  552. struct pnp_option *option;
  553. struct pnp_option *option_independent;
  554. struct pnp_dev *dev;
  555. };
  556. static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
  557. void *data)
  558. {
  559. int priority = 0;
  560. struct acpipnp_parse_option_s *parse_data = data;
  561. struct pnp_dev *dev = parse_data->dev;
  562. struct pnp_option *option = parse_data->option;
  563. switch (res->type) {
  564. case ACPI_RESOURCE_TYPE_IRQ:
  565. pnpacpi_parse_irq_option(dev, option, &res->data.irq);
  566. break;
  567. case ACPI_RESOURCE_TYPE_DMA:
  568. pnpacpi_parse_dma_option(dev, option, &res->data.dma);
  569. break;
  570. case ACPI_RESOURCE_TYPE_START_DEPENDENT:
  571. switch (res->data.start_dpf.compatibility_priority) {
  572. case ACPI_GOOD_CONFIGURATION:
  573. priority = PNP_RES_PRIORITY_PREFERRED;
  574. break;
  575. case ACPI_ACCEPTABLE_CONFIGURATION:
  576. priority = PNP_RES_PRIORITY_ACCEPTABLE;
  577. break;
  578. case ACPI_SUB_OPTIMAL_CONFIGURATION:
  579. priority = PNP_RES_PRIORITY_FUNCTIONAL;
  580. break;
  581. default:
  582. priority = PNP_RES_PRIORITY_INVALID;
  583. break;
  584. }
  585. /* TBD: Consider performance/robustness bits */
  586. option = pnp_register_dependent_option(dev, priority);
  587. if (!option)
  588. return AE_ERROR;
  589. parse_data->option = option;
  590. break;
  591. case ACPI_RESOURCE_TYPE_END_DEPENDENT:
  592. /*only one EndDependentFn is allowed */
  593. if (!parse_data->option_independent) {
  594. dev_warn(&dev->dev, "more than one EndDependentFn "
  595. "in _PRS\n");
  596. return AE_ERROR;
  597. }
  598. parse_data->option = parse_data->option_independent;
  599. parse_data->option_independent = NULL;
  600. dev_dbg(&dev->dev, "end dependent options\n");
  601. break;
  602. case ACPI_RESOURCE_TYPE_IO:
  603. pnpacpi_parse_port_option(dev, option, &res->data.io);
  604. break;
  605. case ACPI_RESOURCE_TYPE_FIXED_IO:
  606. pnpacpi_parse_fixed_port_option(dev, option,
  607. &res->data.fixed_io);
  608. break;
  609. case ACPI_RESOURCE_TYPE_VENDOR:
  610. case ACPI_RESOURCE_TYPE_END_TAG:
  611. break;
  612. case ACPI_RESOURCE_TYPE_MEMORY24:
  613. pnpacpi_parse_mem24_option(dev, option, &res->data.memory24);
  614. break;
  615. case ACPI_RESOURCE_TYPE_MEMORY32:
  616. pnpacpi_parse_mem32_option(dev, option, &res->data.memory32);
  617. break;
  618. case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
  619. pnpacpi_parse_fixed_mem32_option(dev, option,
  620. &res->data.fixed_memory32);
  621. break;
  622. case ACPI_RESOURCE_TYPE_ADDRESS16:
  623. case ACPI_RESOURCE_TYPE_ADDRESS32:
  624. case ACPI_RESOURCE_TYPE_ADDRESS64:
  625. pnpacpi_parse_address_option(dev, option, res);
  626. break;
  627. case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
  628. break;
  629. case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
  630. pnpacpi_parse_ext_irq_option(dev, option,
  631. &res->data.extended_irq);
  632. break;
  633. case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
  634. break;
  635. default:
  636. dev_warn(&dev->dev, "unknown resource type %d in _PRS\n",
  637. res->type);
  638. return AE_ERROR;
  639. }
  640. return AE_OK;
  641. }
  642. acpi_status __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev)
  643. {
  644. acpi_handle handle = dev->data;
  645. acpi_status status;
  646. struct acpipnp_parse_option_s parse_data;
  647. dev_dbg(&dev->dev, "parse resource options\n");
  648. parse_data.option = pnp_register_independent_option(dev);
  649. if (!parse_data.option)
  650. return AE_ERROR;
  651. parse_data.option_independent = parse_data.option;
  652. parse_data.dev = dev;
  653. status = acpi_walk_resources(handle, METHOD_NAME__PRS,
  654. pnpacpi_option_resource, &parse_data);
  655. return status;
  656. }
  657. static int pnpacpi_supported_resource(struct acpi_resource *res)
  658. {
  659. switch (res->type) {
  660. case ACPI_RESOURCE_TYPE_IRQ:
  661. case ACPI_RESOURCE_TYPE_DMA:
  662. case ACPI_RESOURCE_TYPE_IO:
  663. case ACPI_RESOURCE_TYPE_FIXED_IO:
  664. case ACPI_RESOURCE_TYPE_MEMORY24:
  665. case ACPI_RESOURCE_TYPE_MEMORY32:
  666. case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
  667. case ACPI_RESOURCE_TYPE_ADDRESS16:
  668. case ACPI_RESOURCE_TYPE_ADDRESS32:
  669. case ACPI_RESOURCE_TYPE_ADDRESS64:
  670. case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
  671. return 1;
  672. }
  673. return 0;
  674. }
  675. /*
  676. * Set resource
  677. */
  678. static acpi_status pnpacpi_count_resources(struct acpi_resource *res,
  679. void *data)
  680. {
  681. int *res_cnt = data;
  682. if (pnpacpi_supported_resource(res))
  683. (*res_cnt)++;
  684. return AE_OK;
  685. }
  686. static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data)
  687. {
  688. struct acpi_resource **resource = data;
  689. if (pnpacpi_supported_resource(res)) {
  690. (*resource)->type = res->type;
  691. (*resource)->length = sizeof(struct acpi_resource);
  692. (*resource)++;
  693. }
  694. return AE_OK;
  695. }
  696. int pnpacpi_build_resource_template(struct pnp_dev *dev,
  697. struct acpi_buffer *buffer)
  698. {
  699. acpi_handle handle = dev->data;
  700. struct acpi_resource *resource;
  701. int res_cnt = 0;
  702. acpi_status status;
  703. status = acpi_walk_resources(handle, METHOD_NAME__CRS,
  704. pnpacpi_count_resources, &res_cnt);
  705. if (ACPI_FAILURE(status)) {
  706. dev_err(&dev->dev, "can't evaluate _CRS\n");
  707. return -EINVAL;
  708. }
  709. if (!res_cnt)
  710. return -EINVAL;
  711. buffer->length = sizeof(struct acpi_resource) * (res_cnt + 1) + 1;
  712. buffer->pointer = kzalloc(buffer->length - 1, GFP_KERNEL);
  713. if (!buffer->pointer)
  714. return -ENOMEM;
  715. resource = (struct acpi_resource *)buffer->pointer;
  716. status = acpi_walk_resources(handle, METHOD_NAME__CRS,
  717. pnpacpi_type_resources, &resource);
  718. if (ACPI_FAILURE(status)) {
  719. kfree(buffer->pointer);
  720. dev_err(&dev->dev, "can't evaluate _CRS\n");
  721. return -EINVAL;
  722. }
  723. /* resource will pointer the end resource now */
  724. resource->type = ACPI_RESOURCE_TYPE_END_TAG;
  725. return 0;
  726. }
  727. static void pnpacpi_encode_irq(struct pnp_dev *dev,
  728. struct acpi_resource *resource,
  729. struct resource *p)
  730. {
  731. struct acpi_resource_irq *irq = &resource->data.irq;
  732. int triggering, polarity;
  733. decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity);
  734. irq->triggering = triggering;
  735. irq->polarity = polarity;
  736. if (triggering == ACPI_EDGE_SENSITIVE)
  737. irq->sharable = ACPI_EXCLUSIVE;
  738. else
  739. irq->sharable = ACPI_SHARED;
  740. irq->interrupt_count = 1;
  741. irq->interrupts[0] = p->start;
  742. dev_dbg(&dev->dev, " encode irq %d %s %s %s\n", (int) p->start,
  743. triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge",
  744. polarity == ACPI_ACTIVE_LOW ? "low" : "high",
  745. irq->sharable == ACPI_SHARED ? "shared" : "exclusive");
  746. }
  747. static void pnpacpi_encode_ext_irq(struct pnp_dev *dev,
  748. struct acpi_resource *resource,
  749. struct resource *p)
  750. {
  751. struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq;
  752. int triggering, polarity;
  753. decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity);
  754. extended_irq->producer_consumer = ACPI_CONSUMER;
  755. extended_irq->triggering = triggering;
  756. extended_irq->polarity = polarity;
  757. if (triggering == ACPI_EDGE_SENSITIVE)
  758. extended_irq->sharable = ACPI_EXCLUSIVE;
  759. else
  760. extended_irq->sharable = ACPI_SHARED;
  761. extended_irq->interrupt_count = 1;
  762. extended_irq->interrupts[0] = p->start;
  763. dev_dbg(&dev->dev, " encode irq %d %s %s %s\n", (int) p->start,
  764. triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge",
  765. polarity == ACPI_ACTIVE_LOW ? "low" : "high",
  766. extended_irq->sharable == ACPI_SHARED ? "shared" : "exclusive");
  767. }
  768. static void pnpacpi_encode_dma(struct pnp_dev *dev,
  769. struct acpi_resource *resource,
  770. struct resource *p)
  771. {
  772. struct acpi_resource_dma *dma = &resource->data.dma;
  773. /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */
  774. switch (p->flags & IORESOURCE_DMA_SPEED_MASK) {
  775. case IORESOURCE_DMA_TYPEA:
  776. dma->type = ACPI_TYPE_A;
  777. break;
  778. case IORESOURCE_DMA_TYPEB:
  779. dma->type = ACPI_TYPE_B;
  780. break;
  781. case IORESOURCE_DMA_TYPEF:
  782. dma->type = ACPI_TYPE_F;
  783. break;
  784. default:
  785. dma->type = ACPI_COMPATIBILITY;
  786. }
  787. switch (p->flags & IORESOURCE_DMA_TYPE_MASK) {
  788. case IORESOURCE_DMA_8BIT:
  789. dma->transfer = ACPI_TRANSFER_8;
  790. break;
  791. case IORESOURCE_DMA_8AND16BIT:
  792. dma->transfer = ACPI_TRANSFER_8_16;
  793. break;
  794. default:
  795. dma->transfer = ACPI_TRANSFER_16;
  796. }
  797. dma->bus_master = !!(p->flags & IORESOURCE_DMA_MASTER);
  798. dma->channel_count = 1;
  799. dma->channels[0] = p->start;
  800. dev_dbg(&dev->dev, " encode dma %d "
  801. "type %#x transfer %#x master %d\n",
  802. (int) p->start, dma->type, dma->transfer, dma->bus_master);
  803. }
  804. static void pnpacpi_encode_io(struct pnp_dev *dev,
  805. struct acpi_resource *resource,
  806. struct resource *p)
  807. {
  808. struct acpi_resource_io *io = &resource->data.io;
  809. /* Note: pnp_assign_port will copy pnp_port->flags into p->flags */
  810. io->io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ?
  811. ACPI_DECODE_16 : ACPI_DECODE_10;
  812. io->minimum = p->start;
  813. io->maximum = p->end;
  814. io->alignment = 0; /* Correct? */
  815. io->address_length = p->end - p->start + 1;
  816. dev_dbg(&dev->dev, " encode io %#llx-%#llx decode %#x\n",
  817. (unsigned long long) p->start, (unsigned long long) p->end,
  818. io->io_decode);
  819. }
  820. static void pnpacpi_encode_fixed_io(struct pnp_dev *dev,
  821. struct acpi_resource *resource,
  822. struct resource *p)
  823. {
  824. struct acpi_resource_fixed_io *fixed_io = &resource->data.fixed_io;
  825. fixed_io->address = p->start;
  826. fixed_io->address_length = p->end - p->start + 1;
  827. dev_dbg(&dev->dev, " encode fixed_io %#llx-%#llx\n",
  828. (unsigned long long) p->start, (unsigned long long) p->end);
  829. }
  830. static void pnpacpi_encode_mem24(struct pnp_dev *dev,
  831. struct acpi_resource *resource,
  832. struct resource *p)
  833. {
  834. struct acpi_resource_memory24 *memory24 = &resource->data.memory24;
  835. /* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */
  836. memory24->write_protect =
  837. (p->flags & IORESOURCE_MEM_WRITEABLE) ?
  838. ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
  839. memory24->minimum = p->start;
  840. memory24->maximum = p->end;
  841. memory24->alignment = 0;
  842. memory24->address_length = p->end - p->start + 1;
  843. dev_dbg(&dev->dev, " encode mem24 %#llx-%#llx write_protect %#x\n",
  844. (unsigned long long) p->start, (unsigned long long) p->end,
  845. memory24->write_protect);
  846. }
  847. static void pnpacpi_encode_mem32(struct pnp_dev *dev,
  848. struct acpi_resource *resource,
  849. struct resource *p)
  850. {
  851. struct acpi_resource_memory32 *memory32 = &resource->data.memory32;
  852. memory32->write_protect =
  853. (p->flags & IORESOURCE_MEM_WRITEABLE) ?
  854. ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
  855. memory32->minimum = p->start;
  856. memory32->maximum = p->end;
  857. memory32->alignment = 0;
  858. memory32->address_length = p->end - p->start + 1;
  859. dev_dbg(&dev->dev, " encode mem32 %#llx-%#llx write_protect %#x\n",
  860. (unsigned long long) p->start, (unsigned long long) p->end,
  861. memory32->write_protect);
  862. }
  863. static void pnpacpi_encode_fixed_mem32(struct pnp_dev *dev,
  864. struct acpi_resource *resource,
  865. struct resource *p)
  866. {
  867. struct acpi_resource_fixed_memory32 *fixed_memory32 = &resource->data.fixed_memory32;
  868. fixed_memory32->write_protect =
  869. (p->flags & IORESOURCE_MEM_WRITEABLE) ?
  870. ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
  871. fixed_memory32->address = p->start;
  872. fixed_memory32->address_length = p->end - p->start + 1;
  873. dev_dbg(&dev->dev, " encode fixed_mem32 %#llx-%#llx "
  874. "write_protect %#x\n",
  875. (unsigned long long) p->start, (unsigned long long) p->end,
  876. fixed_memory32->write_protect);
  877. }
  878. int pnpacpi_encode_resources(struct pnp_dev *dev, struct acpi_buffer *buffer)
  879. {
  880. int i = 0;
  881. /* pnpacpi_build_resource_template allocates extra mem */
  882. int res_cnt = (buffer->length - 1) / sizeof(struct acpi_resource) - 1;
  883. struct acpi_resource *resource = buffer->pointer;
  884. int port = 0, irq = 0, dma = 0, mem = 0;
  885. dev_dbg(&dev->dev, "encode %d resources\n", res_cnt);
  886. while (i < res_cnt) {
  887. switch (resource->type) {
  888. case ACPI_RESOURCE_TYPE_IRQ:
  889. pnpacpi_encode_irq(dev, resource,
  890. pnp_get_resource(dev, IORESOURCE_IRQ, irq));
  891. irq++;
  892. break;
  893. case ACPI_RESOURCE_TYPE_DMA:
  894. pnpacpi_encode_dma(dev, resource,
  895. pnp_get_resource(dev, IORESOURCE_DMA, dma));
  896. dma++;
  897. break;
  898. case ACPI_RESOURCE_TYPE_IO:
  899. pnpacpi_encode_io(dev, resource,
  900. pnp_get_resource(dev, IORESOURCE_IO, port));
  901. port++;
  902. break;
  903. case ACPI_RESOURCE_TYPE_FIXED_IO:
  904. pnpacpi_encode_fixed_io(dev, resource,
  905. pnp_get_resource(dev, IORESOURCE_IO, port));
  906. port++;
  907. break;
  908. case ACPI_RESOURCE_TYPE_MEMORY24:
  909. pnpacpi_encode_mem24(dev, resource,
  910. pnp_get_resource(dev, IORESOURCE_MEM, mem));
  911. mem++;
  912. break;
  913. case ACPI_RESOURCE_TYPE_MEMORY32:
  914. pnpacpi_encode_mem32(dev, resource,
  915. pnp_get_resource(dev, IORESOURCE_MEM, mem));
  916. mem++;
  917. break;
  918. case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
  919. pnpacpi_encode_fixed_mem32(dev, resource,
  920. pnp_get_resource(dev, IORESOURCE_MEM, mem));
  921. mem++;
  922. break;
  923. case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
  924. pnpacpi_encode_ext_irq(dev, resource,
  925. pnp_get_resource(dev, IORESOURCE_IRQ, irq));
  926. irq++;
  927. break;
  928. case ACPI_RESOURCE_TYPE_START_DEPENDENT:
  929. case ACPI_RESOURCE_TYPE_END_DEPENDENT:
  930. case ACPI_RESOURCE_TYPE_VENDOR:
  931. case ACPI_RESOURCE_TYPE_END_TAG:
  932. case ACPI_RESOURCE_TYPE_ADDRESS16:
  933. case ACPI_RESOURCE_TYPE_ADDRESS32:
  934. case ACPI_RESOURCE_TYPE_ADDRESS64:
  935. case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
  936. case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
  937. default: /* other type */
  938. dev_warn(&dev->dev, "can't encode unknown resource "
  939. "type %d\n", resource->type);
  940. return -EINVAL;
  941. }
  942. resource++;
  943. i++;
  944. }
  945. return 0;
  946. }