diff options
Diffstat (limited to 'drivers/pnp/resource.c')
-rw-r--r-- | drivers/pnp/resource.c | 361 |
1 files changed, 293 insertions, 68 deletions
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index e50ebcffb962..2041620d5682 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c | |||
@@ -53,6 +53,8 @@ struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev) | |||
53 | if (dev->independent) | 53 | if (dev->independent) |
54 | dev_err(&dev->dev, "independent resource already registered\n"); | 54 | dev_err(&dev->dev, "independent resource already registered\n"); |
55 | dev->independent = option; | 55 | dev->independent = option; |
56 | |||
57 | dev_dbg(&dev->dev, "new independent option\n"); | ||
56 | return option; | 58 | return option; |
57 | } | 59 | } |
58 | 60 | ||
@@ -70,12 +72,18 @@ struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev, | |||
70 | parent->next = option; | 72 | parent->next = option; |
71 | } else | 73 | } else |
72 | dev->dependent = option; | 74 | dev->dependent = option; |
75 | |||
76 | dev_dbg(&dev->dev, "new dependent option (priority %#x)\n", priority); | ||
73 | return option; | 77 | return option; |
74 | } | 78 | } |
75 | 79 | ||
76 | int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data) | 80 | int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option, |
81 | struct pnp_irq *data) | ||
77 | { | 82 | { |
78 | struct pnp_irq *ptr; | 83 | struct pnp_irq *ptr; |
84 | #ifdef DEBUG | ||
85 | char buf[PNP_IRQ_NR]; /* hex-encoded, so this is overkill but safe */ | ||
86 | #endif | ||
79 | 87 | ||
80 | ptr = option->irq; | 88 | ptr = option->irq; |
81 | while (ptr && ptr->next) | 89 | while (ptr && ptr->next) |
@@ -94,10 +102,17 @@ int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data) | |||
94 | pcibios_penalize_isa_irq(i, 0); | 102 | pcibios_penalize_isa_irq(i, 0); |
95 | } | 103 | } |
96 | #endif | 104 | #endif |
105 | |||
106 | #ifdef DEBUG | ||
107 | bitmap_scnprintf(buf, sizeof(buf), data->map, PNP_IRQ_NR); | ||
108 | dev_dbg(&dev->dev, " irq bitmask %s flags %#x\n", buf, | ||
109 | data->flags); | ||
110 | #endif | ||
97 | return 0; | 111 | return 0; |
98 | } | 112 | } |
99 | 113 | ||
100 | int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data) | 114 | int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option, |
115 | struct pnp_dma *data) | ||
101 | { | 116 | { |
102 | struct pnp_dma *ptr; | 117 | struct pnp_dma *ptr; |
103 | 118 | ||
@@ -109,10 +124,13 @@ int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data) | |||
109 | else | 124 | else |
110 | option->dma = data; | 125 | option->dma = data; |
111 | 126 | ||
127 | dev_dbg(&dev->dev, " dma bitmask %#x flags %#x\n", data->map, | ||
128 | data->flags); | ||
112 | return 0; | 129 | return 0; |
113 | } | 130 | } |
114 | 131 | ||
115 | int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data) | 132 | int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option, |
133 | struct pnp_port *data) | ||
116 | { | 134 | { |
117 | struct pnp_port *ptr; | 135 | struct pnp_port *ptr; |
118 | 136 | ||
@@ -124,10 +142,14 @@ int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data) | |||
124 | else | 142 | else |
125 | option->port = data; | 143 | option->port = data; |
126 | 144 | ||
145 | dev_dbg(&dev->dev, " io " | ||
146 | "min %#x max %#x align %d size %d flags %#x\n", | ||
147 | data->min, data->max, data->align, data->size, data->flags); | ||
127 | return 0; | 148 | return 0; |
128 | } | 149 | } |
129 | 150 | ||
130 | int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data) | 151 | int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option, |
152 | struct pnp_mem *data) | ||
131 | { | 153 | { |
132 | struct pnp_mem *ptr; | 154 | struct pnp_mem *ptr; |
133 | 155 | ||
@@ -138,6 +160,10 @@ int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data) | |||
138 | ptr->next = data; | 160 | ptr->next = data; |
139 | else | 161 | else |
140 | option->mem = data; | 162 | option->mem = data; |
163 | |||
164 | dev_dbg(&dev->dev, " mem " | ||
165 | "min %#x max %#x align %d size %d flags %#x\n", | ||
166 | data->min, data->max, data->align, data->size, data->flags); | ||
141 | return 0; | 167 | return 0; |
142 | } | 168 | } |
143 | 169 | ||
@@ -213,17 +239,18 @@ void pnp_free_option(struct pnp_option *option) | |||
213 | #define cannot_compare(flags) \ | 239 | #define cannot_compare(flags) \ |
214 | ((flags) & (IORESOURCE_UNSET | IORESOURCE_DISABLED)) | 240 | ((flags) & (IORESOURCE_UNSET | IORESOURCE_DISABLED)) |
215 | 241 | ||
216 | int pnp_check_port(struct pnp_dev *dev, int idx) | 242 | int pnp_check_port(struct pnp_dev *dev, struct resource *res) |
217 | { | 243 | { |
218 | int tmp; | 244 | int i; |
219 | struct pnp_dev *tdev; | 245 | struct pnp_dev *tdev; |
246 | struct resource *tres; | ||
220 | resource_size_t *port, *end, *tport, *tend; | 247 | resource_size_t *port, *end, *tport, *tend; |
221 | 248 | ||
222 | port = &dev->res.port_resource[idx].start; | 249 | port = &res->start; |
223 | end = &dev->res.port_resource[idx].end; | 250 | end = &res->end; |
224 | 251 | ||
225 | /* if the resource doesn't exist, don't complain about it */ | 252 | /* if the resource doesn't exist, don't complain about it */ |
226 | if (cannot_compare(dev->res.port_resource[idx].flags)) | 253 | if (cannot_compare(res->flags)) |
227 | return 1; | 254 | return 1; |
228 | 255 | ||
229 | /* check if the resource is already in use, skip if the | 256 | /* check if the resource is already in use, skip if the |
@@ -234,18 +261,18 @@ int pnp_check_port(struct pnp_dev *dev, int idx) | |||
234 | } | 261 | } |
235 | 262 | ||
236 | /* check if the resource is reserved */ | 263 | /* check if the resource is reserved */ |
237 | for (tmp = 0; tmp < 8; tmp++) { | 264 | for (i = 0; i < 8; i++) { |
238 | int rport = pnp_reserve_io[tmp << 1]; | 265 | int rport = pnp_reserve_io[i << 1]; |
239 | int rend = pnp_reserve_io[(tmp << 1) + 1] + rport - 1; | 266 | int rend = pnp_reserve_io[(i << 1) + 1] + rport - 1; |
240 | if (ranged_conflict(port, end, &rport, &rend)) | 267 | if (ranged_conflict(port, end, &rport, &rend)) |
241 | return 0; | 268 | return 0; |
242 | } | 269 | } |
243 | 270 | ||
244 | /* check for internal conflicts */ | 271 | /* check for internal conflicts */ |
245 | for (tmp = 0; tmp < PNP_MAX_PORT && tmp != idx; tmp++) { | 272 | for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) { |
246 | if (dev->res.port_resource[tmp].flags & IORESOURCE_IO) { | 273 | if (tres != res && tres->flags & IORESOURCE_IO) { |
247 | tport = &dev->res.port_resource[tmp].start; | 274 | tport = &tres->start; |
248 | tend = &dev->res.port_resource[tmp].end; | 275 | tend = &tres->end; |
249 | if (ranged_conflict(port, end, tport, tend)) | 276 | if (ranged_conflict(port, end, tport, tend)) |
250 | return 0; | 277 | return 0; |
251 | } | 278 | } |
@@ -255,13 +282,14 @@ int pnp_check_port(struct pnp_dev *dev, int idx) | |||
255 | pnp_for_each_dev(tdev) { | 282 | pnp_for_each_dev(tdev) { |
256 | if (tdev == dev) | 283 | if (tdev == dev) |
257 | continue; | 284 | continue; |
258 | for (tmp = 0; tmp < PNP_MAX_PORT; tmp++) { | 285 | for (i = 0; |
259 | if (tdev->res.port_resource[tmp].flags & IORESOURCE_IO) { | 286 | (tres = pnp_get_resource(tdev, IORESOURCE_IO, i)); |
260 | if (cannot_compare | 287 | i++) { |
261 | (tdev->res.port_resource[tmp].flags)) | 288 | if (tres->flags & IORESOURCE_IO) { |
289 | if (cannot_compare(tres->flags)) | ||
262 | continue; | 290 | continue; |
263 | tport = &tdev->res.port_resource[tmp].start; | 291 | tport = &tres->start; |
264 | tend = &tdev->res.port_resource[tmp].end; | 292 | tend = &tres->end; |
265 | if (ranged_conflict(port, end, tport, tend)) | 293 | if (ranged_conflict(port, end, tport, tend)) |
266 | return 0; | 294 | return 0; |
267 | } | 295 | } |
@@ -271,17 +299,18 @@ int pnp_check_port(struct pnp_dev *dev, int idx) | |||
271 | return 1; | 299 | return 1; |
272 | } | 300 | } |
273 | 301 | ||
274 | int pnp_check_mem(struct pnp_dev *dev, int idx) | 302 | int pnp_check_mem(struct pnp_dev *dev, struct resource *res) |
275 | { | 303 | { |
276 | int tmp; | 304 | int i; |
277 | struct pnp_dev *tdev; | 305 | struct pnp_dev *tdev; |
306 | struct resource *tres; | ||
278 | resource_size_t *addr, *end, *taddr, *tend; | 307 | resource_size_t *addr, *end, *taddr, *tend; |
279 | 308 | ||
280 | addr = &dev->res.mem_resource[idx].start; | 309 | addr = &res->start; |
281 | end = &dev->res.mem_resource[idx].end; | 310 | end = &res->end; |
282 | 311 | ||
283 | /* if the resource doesn't exist, don't complain about it */ | 312 | /* if the resource doesn't exist, don't complain about it */ |
284 | if (cannot_compare(dev->res.mem_resource[idx].flags)) | 313 | if (cannot_compare(res->flags)) |
285 | return 1; | 314 | return 1; |
286 | 315 | ||
287 | /* check if the resource is already in use, skip if the | 316 | /* check if the resource is already in use, skip if the |
@@ -292,18 +321,18 @@ int pnp_check_mem(struct pnp_dev *dev, int idx) | |||
292 | } | 321 | } |
293 | 322 | ||
294 | /* check if the resource is reserved */ | 323 | /* check if the resource is reserved */ |
295 | for (tmp = 0; tmp < 8; tmp++) { | 324 | for (i = 0; i < 8; i++) { |
296 | int raddr = pnp_reserve_mem[tmp << 1]; | 325 | int raddr = pnp_reserve_mem[i << 1]; |
297 | int rend = pnp_reserve_mem[(tmp << 1) + 1] + raddr - 1; | 326 | int rend = pnp_reserve_mem[(i << 1) + 1] + raddr - 1; |
298 | if (ranged_conflict(addr, end, &raddr, &rend)) | 327 | if (ranged_conflict(addr, end, &raddr, &rend)) |
299 | return 0; | 328 | return 0; |
300 | } | 329 | } |
301 | 330 | ||
302 | /* check for internal conflicts */ | 331 | /* check for internal conflicts */ |
303 | for (tmp = 0; tmp < PNP_MAX_MEM && tmp != idx; tmp++) { | 332 | for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) { |
304 | if (dev->res.mem_resource[tmp].flags & IORESOURCE_MEM) { | 333 | if (tres != res && tres->flags & IORESOURCE_MEM) { |
305 | taddr = &dev->res.mem_resource[tmp].start; | 334 | taddr = &tres->start; |
306 | tend = &dev->res.mem_resource[tmp].end; | 335 | tend = &tres->end; |
307 | if (ranged_conflict(addr, end, taddr, tend)) | 336 | if (ranged_conflict(addr, end, taddr, tend)) |
308 | return 0; | 337 | return 0; |
309 | } | 338 | } |
@@ -313,13 +342,14 @@ int pnp_check_mem(struct pnp_dev *dev, int idx) | |||
313 | pnp_for_each_dev(tdev) { | 342 | pnp_for_each_dev(tdev) { |
314 | if (tdev == dev) | 343 | if (tdev == dev) |
315 | continue; | 344 | continue; |
316 | for (tmp = 0; tmp < PNP_MAX_MEM; tmp++) { | 345 | for (i = 0; |
317 | if (tdev->res.mem_resource[tmp].flags & IORESOURCE_MEM) { | 346 | (tres = pnp_get_resource(tdev, IORESOURCE_MEM, i)); |
318 | if (cannot_compare | 347 | i++) { |
319 | (tdev->res.mem_resource[tmp].flags)) | 348 | if (tres->flags & IORESOURCE_MEM) { |
349 | if (cannot_compare(tres->flags)) | ||
320 | continue; | 350 | continue; |
321 | taddr = &tdev->res.mem_resource[tmp].start; | 351 | taddr = &tres->start; |
322 | tend = &tdev->res.mem_resource[tmp].end; | 352 | tend = &tres->end; |
323 | if (ranged_conflict(addr, end, taddr, tend)) | 353 | if (ranged_conflict(addr, end, taddr, tend)) |
324 | return 0; | 354 | return 0; |
325 | } | 355 | } |
@@ -334,14 +364,17 @@ static irqreturn_t pnp_test_handler(int irq, void *dev_id) | |||
334 | return IRQ_HANDLED; | 364 | return IRQ_HANDLED; |
335 | } | 365 | } |
336 | 366 | ||
337 | int pnp_check_irq(struct pnp_dev *dev, int idx) | 367 | int pnp_check_irq(struct pnp_dev *dev, struct resource *res) |
338 | { | 368 | { |
339 | int tmp; | 369 | int i; |
340 | struct pnp_dev *tdev; | 370 | struct pnp_dev *tdev; |
341 | resource_size_t *irq = &dev->res.irq_resource[idx].start; | 371 | struct resource *tres; |
372 | resource_size_t *irq; | ||
373 | |||
374 | irq = &res->start; | ||
342 | 375 | ||
343 | /* if the resource doesn't exist, don't complain about it */ | 376 | /* if the resource doesn't exist, don't complain about it */ |
344 | if (cannot_compare(dev->res.irq_resource[idx].flags)) | 377 | if (cannot_compare(res->flags)) |
345 | return 1; | 378 | return 1; |
346 | 379 | ||
347 | /* check if the resource is valid */ | 380 | /* check if the resource is valid */ |
@@ -349,15 +382,15 @@ int pnp_check_irq(struct pnp_dev *dev, int idx) | |||
349 | return 0; | 382 | return 0; |
350 | 383 | ||
351 | /* check if the resource is reserved */ | 384 | /* check if the resource is reserved */ |
352 | for (tmp = 0; tmp < 16; tmp++) { | 385 | for (i = 0; i < 16; i++) { |
353 | if (pnp_reserve_irq[tmp] == *irq) | 386 | if (pnp_reserve_irq[i] == *irq) |
354 | return 0; | 387 | return 0; |
355 | } | 388 | } |
356 | 389 | ||
357 | /* check for internal conflicts */ | 390 | /* check for internal conflicts */ |
358 | for (tmp = 0; tmp < PNP_MAX_IRQ && tmp != idx; tmp++) { | 391 | for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) { |
359 | if (dev->res.irq_resource[tmp].flags & IORESOURCE_IRQ) { | 392 | if (tres != res && tres->flags & IORESOURCE_IRQ) { |
360 | if (dev->res.irq_resource[tmp].start == *irq) | 393 | if (tres->start == *irq) |
361 | return 0; | 394 | return 0; |
362 | } | 395 | } |
363 | } | 396 | } |
@@ -388,12 +421,13 @@ int pnp_check_irq(struct pnp_dev *dev, int idx) | |||
388 | pnp_for_each_dev(tdev) { | 421 | pnp_for_each_dev(tdev) { |
389 | if (tdev == dev) | 422 | if (tdev == dev) |
390 | continue; | 423 | continue; |
391 | for (tmp = 0; tmp < PNP_MAX_IRQ; tmp++) { | 424 | for (i = 0; |
392 | if (tdev->res.irq_resource[tmp].flags & IORESOURCE_IRQ) { | 425 | (tres = pnp_get_resource(tdev, IORESOURCE_IRQ, i)); |
393 | if (cannot_compare | 426 | i++) { |
394 | (tdev->res.irq_resource[tmp].flags)) | 427 | if (tres->flags & IORESOURCE_IRQ) { |
428 | if (cannot_compare(tres->flags)) | ||
395 | continue; | 429 | continue; |
396 | if ((tdev->res.irq_resource[tmp].start == *irq)) | 430 | if (tres->start == *irq) |
397 | return 0; | 431 | return 0; |
398 | } | 432 | } |
399 | } | 433 | } |
@@ -402,15 +436,18 @@ int pnp_check_irq(struct pnp_dev *dev, int idx) | |||
402 | return 1; | 436 | return 1; |
403 | } | 437 | } |
404 | 438 | ||
405 | int pnp_check_dma(struct pnp_dev *dev, int idx) | 439 | int pnp_check_dma(struct pnp_dev *dev, struct resource *res) |
406 | { | 440 | { |
407 | #ifndef CONFIG_IA64 | 441 | #ifndef CONFIG_IA64 |
408 | int tmp; | 442 | int i; |
409 | struct pnp_dev *tdev; | 443 | struct pnp_dev *tdev; |
410 | resource_size_t *dma = &dev->res.dma_resource[idx].start; | 444 | struct resource *tres; |
445 | resource_size_t *dma; | ||
446 | |||
447 | dma = &res->start; | ||
411 | 448 | ||
412 | /* if the resource doesn't exist, don't complain about it */ | 449 | /* if the resource doesn't exist, don't complain about it */ |
413 | if (cannot_compare(dev->res.dma_resource[idx].flags)) | 450 | if (cannot_compare(res->flags)) |
414 | return 1; | 451 | return 1; |
415 | 452 | ||
416 | /* check if the resource is valid */ | 453 | /* check if the resource is valid */ |
@@ -418,15 +455,15 @@ int pnp_check_dma(struct pnp_dev *dev, int idx) | |||
418 | return 0; | 455 | return 0; |
419 | 456 | ||
420 | /* check if the resource is reserved */ | 457 | /* check if the resource is reserved */ |
421 | for (tmp = 0; tmp < 8; tmp++) { | 458 | for (i = 0; i < 8; i++) { |
422 | if (pnp_reserve_dma[tmp] == *dma) | 459 | if (pnp_reserve_dma[i] == *dma) |
423 | return 0; | 460 | return 0; |
424 | } | 461 | } |
425 | 462 | ||
426 | /* check for internal conflicts */ | 463 | /* check for internal conflicts */ |
427 | for (tmp = 0; tmp < PNP_MAX_DMA && tmp != idx; tmp++) { | 464 | for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) { |
428 | if (dev->res.dma_resource[tmp].flags & IORESOURCE_DMA) { | 465 | if (tres != res && tres->flags & IORESOURCE_DMA) { |
429 | if (dev->res.dma_resource[tmp].start == *dma) | 466 | if (tres->start == *dma) |
430 | return 0; | 467 | return 0; |
431 | } | 468 | } |
432 | } | 469 | } |
@@ -443,12 +480,13 @@ int pnp_check_dma(struct pnp_dev *dev, int idx) | |||
443 | pnp_for_each_dev(tdev) { | 480 | pnp_for_each_dev(tdev) { |
444 | if (tdev == dev) | 481 | if (tdev == dev) |
445 | continue; | 482 | continue; |
446 | for (tmp = 0; tmp < PNP_MAX_DMA; tmp++) { | 483 | for (i = 0; |
447 | if (tdev->res.dma_resource[tmp].flags & IORESOURCE_DMA) { | 484 | (tres = pnp_get_resource(tdev, IORESOURCE_DMA, i)); |
448 | if (cannot_compare | 485 | i++) { |
449 | (tdev->res.dma_resource[tmp].flags)) | 486 | if (tres->flags & IORESOURCE_DMA) { |
487 | if (cannot_compare(tres->flags)) | ||
450 | continue; | 488 | continue; |
451 | if ((tdev->res.dma_resource[tmp].start == *dma)) | 489 | if (tres->start == *dma) |
452 | return 0; | 490 | return 0; |
453 | } | 491 | } |
454 | } | 492 | } |
@@ -461,6 +499,193 @@ int pnp_check_dma(struct pnp_dev *dev, int idx) | |||
461 | #endif | 499 | #endif |
462 | } | 500 | } |
463 | 501 | ||
502 | struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev, | ||
503 | unsigned int type, unsigned int num) | ||
504 | { | ||
505 | struct pnp_resource_table *res = dev->res; | ||
506 | |||
507 | switch (type) { | ||
508 | case IORESOURCE_IO: | ||
509 | if (num >= PNP_MAX_PORT) | ||
510 | return NULL; | ||
511 | return &res->port[num]; | ||
512 | case IORESOURCE_MEM: | ||
513 | if (num >= PNP_MAX_MEM) | ||
514 | return NULL; | ||
515 | return &res->mem[num]; | ||
516 | case IORESOURCE_IRQ: | ||
517 | if (num >= PNP_MAX_IRQ) | ||
518 | return NULL; | ||
519 | return &res->irq[num]; | ||
520 | case IORESOURCE_DMA: | ||
521 | if (num >= PNP_MAX_DMA) | ||
522 | return NULL; | ||
523 | return &res->dma[num]; | ||
524 | } | ||
525 | return NULL; | ||
526 | } | ||
527 | |||
528 | struct resource *pnp_get_resource(struct pnp_dev *dev, | ||
529 | unsigned int type, unsigned int num) | ||
530 | { | ||
531 | struct pnp_resource *pnp_res; | ||
532 | |||
533 | pnp_res = pnp_get_pnp_resource(dev, type, num); | ||
534 | if (pnp_res) | ||
535 | return &pnp_res->res; | ||
536 | |||
537 | return NULL; | ||
538 | } | ||
539 | EXPORT_SYMBOL(pnp_get_resource); | ||
540 | |||
541 | static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev, int type) | ||
542 | { | ||
543 | struct pnp_resource *pnp_res; | ||
544 | int i; | ||
545 | |||
546 | switch (type) { | ||
547 | case IORESOURCE_IO: | ||
548 | for (i = 0; i < PNP_MAX_PORT; i++) { | ||
549 | pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, i); | ||
550 | if (pnp_res && !pnp_resource_valid(&pnp_res->res)) | ||
551 | return pnp_res; | ||
552 | } | ||
553 | break; | ||
554 | case IORESOURCE_MEM: | ||
555 | for (i = 0; i < PNP_MAX_MEM; i++) { | ||
556 | pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, i); | ||
557 | if (pnp_res && !pnp_resource_valid(&pnp_res->res)) | ||
558 | return pnp_res; | ||
559 | } | ||
560 | break; | ||
561 | case IORESOURCE_IRQ: | ||
562 | for (i = 0; i < PNP_MAX_IRQ; i++) { | ||
563 | pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, i); | ||
564 | if (pnp_res && !pnp_resource_valid(&pnp_res->res)) | ||
565 | return pnp_res; | ||
566 | } | ||
567 | break; | ||
568 | case IORESOURCE_DMA: | ||
569 | for (i = 0; i < PNP_MAX_DMA; i++) { | ||
570 | pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, i); | ||
571 | if (pnp_res && !pnp_resource_valid(&pnp_res->res)) | ||
572 | return pnp_res; | ||
573 | } | ||
574 | break; | ||
575 | } | ||
576 | return NULL; | ||
577 | } | ||
578 | |||
579 | struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, | ||
580 | int flags) | ||
581 | { | ||
582 | struct pnp_resource *pnp_res; | ||
583 | struct resource *res; | ||
584 | static unsigned char warned; | ||
585 | |||
586 | pnp_res = pnp_new_resource(dev, IORESOURCE_IRQ); | ||
587 | if (!pnp_res) { | ||
588 | if (!warned) { | ||
589 | dev_err(&dev->dev, "can't add resource for IRQ %d\n", | ||
590 | irq); | ||
591 | warned = 1; | ||
592 | } | ||
593 | return NULL; | ||
594 | } | ||
595 | |||
596 | res = &pnp_res->res; | ||
597 | res->flags = IORESOURCE_IRQ | flags; | ||
598 | res->start = irq; | ||
599 | res->end = irq; | ||
600 | |||
601 | dev_dbg(&dev->dev, " add irq %d flags %#x\n", irq, flags); | ||
602 | return pnp_res; | ||
603 | } | ||
604 | |||
605 | struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma, | ||
606 | int flags) | ||
607 | { | ||
608 | struct pnp_resource *pnp_res; | ||
609 | struct resource *res; | ||
610 | static unsigned char warned; | ||
611 | |||
612 | pnp_res = pnp_new_resource(dev, IORESOURCE_DMA); | ||
613 | if (!pnp_res) { | ||
614 | if (!warned) { | ||
615 | dev_err(&dev->dev, "can't add resource for DMA %d\n", | ||
616 | dma); | ||
617 | warned = 1; | ||
618 | } | ||
619 | return NULL; | ||
620 | } | ||
621 | |||
622 | res = &pnp_res->res; | ||
623 | res->flags = IORESOURCE_DMA | flags; | ||
624 | res->start = dma; | ||
625 | res->end = dma; | ||
626 | |||
627 | dev_dbg(&dev->dev, " add dma %d flags %#x\n", dma, flags); | ||
628 | return pnp_res; | ||
629 | } | ||
630 | |||
631 | struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev, | ||
632 | resource_size_t start, | ||
633 | resource_size_t end, int flags) | ||
634 | { | ||
635 | struct pnp_resource *pnp_res; | ||
636 | struct resource *res; | ||
637 | static unsigned char warned; | ||
638 | |||
639 | pnp_res = pnp_new_resource(dev, IORESOURCE_IO); | ||
640 | if (!pnp_res) { | ||
641 | if (!warned) { | ||
642 | dev_err(&dev->dev, "can't add resource for IO " | ||
643 | "%#llx-%#llx\n",(unsigned long long) start, | ||
644 | (unsigned long long) end); | ||
645 | warned = 1; | ||
646 | } | ||
647 | return NULL; | ||
648 | } | ||
649 | |||
650 | res = &pnp_res->res; | ||
651 | res->flags = IORESOURCE_IO | flags; | ||
652 | res->start = start; | ||
653 | res->end = end; | ||
654 | |||
655 | dev_dbg(&dev->dev, " add io %#llx-%#llx flags %#x\n", | ||
656 | (unsigned long long) start, (unsigned long long) end, flags); | ||
657 | return pnp_res; | ||
658 | } | ||
659 | |||
660 | struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, | ||
661 | resource_size_t start, | ||
662 | resource_size_t end, int flags) | ||
663 | { | ||
664 | struct pnp_resource *pnp_res; | ||
665 | struct resource *res; | ||
666 | static unsigned char warned; | ||
667 | |||
668 | pnp_res = pnp_new_resource(dev, IORESOURCE_MEM); | ||
669 | if (!pnp_res) { | ||
670 | if (!warned) { | ||
671 | dev_err(&dev->dev, "can't add resource for MEM " | ||
672 | "%#llx-%#llx\n",(unsigned long long) start, | ||
673 | (unsigned long long) end); | ||
674 | warned = 1; | ||
675 | } | ||
676 | return NULL; | ||
677 | } | ||
678 | |||
679 | res = &pnp_res->res; | ||
680 | res->flags = IORESOURCE_MEM | flags; | ||
681 | res->start = start; | ||
682 | res->end = end; | ||
683 | |||
684 | dev_dbg(&dev->dev, " add mem %#llx-%#llx flags %#x\n", | ||
685 | (unsigned long long) start, (unsigned long long) end, flags); | ||
686 | return pnp_res; | ||
687 | } | ||
688 | |||
464 | /* format is: pnp_reserve_irq=irq1[,irq2] .... */ | 689 | /* format is: pnp_reserve_irq=irq1[,irq2] .... */ |
465 | static int __init pnp_setup_reserve_irq(char *str) | 690 | static int __init pnp_setup_reserve_irq(char *str) |
466 | { | 691 | { |