aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pnp/resource.c68
1 files changed, 57 insertions, 11 deletions
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index d6388970a1a4..4cfe3a1efdfb 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -286,6 +286,61 @@ static irqreturn_t pnp_test_handler(int irq, void *dev_id)
286 return IRQ_HANDLED; 286 return IRQ_HANDLED;
287} 287}
288 288
289#ifdef CONFIG_PCI
290static int pci_dev_uses_irq(struct pnp_dev *pnp, struct pci_dev *pci,
291 unsigned int irq)
292{
293 u32 class;
294 u8 progif;
295
296 if (pci->irq == irq) {
297 dev_dbg(&pnp->dev, "device %s using irq %d\n",
298 pci_name(pci), irq);
299 return 1;
300 }
301
302 /*
303 * See pci_setup_device() and ata_pci_sff_activate_host() for
304 * similar IDE legacy detection.
305 */
306 pci_read_config_dword(pci, PCI_CLASS_REVISION, &class);
307 class >>= 8; /* discard revision ID */
308 progif = class & 0xff;
309 class >>= 8;
310
311 if (class == PCI_CLASS_STORAGE_IDE) {
312 /*
313 * Unless both channels are native-PCI mode only,
314 * treat the compatibility IRQs as busy.
315 */
316 if ((progif & 0x5) != 0x5)
317 if (pci_get_legacy_ide_irq(pci, 0) == irq ||
318 pci_get_legacy_ide_irq(pci, 1) == irq) {
319 dev_dbg(&pnp->dev, "legacy IDE device %s "
320 "using irq %d\n", pci_name(pci), irq);
321 return 1;
322 }
323 }
324
325 return 0;
326}
327#endif
328
329static int pci_uses_irq(struct pnp_dev *pnp, unsigned int irq)
330{
331#ifdef CONFIG_PCI
332 struct pci_dev *pci = NULL;
333
334 for_each_pci_dev(pci) {
335 if (pci_dev_uses_irq(pnp, pci, irq)) {
336 pci_dev_put(pci);
337 return 1;
338 }
339 }
340#endif
341 return 0;
342}
343
289int pnp_check_irq(struct pnp_dev *dev, struct resource *res) 344int pnp_check_irq(struct pnp_dev *dev, struct resource *res)
290{ 345{
291 int i; 346 int i;
@@ -317,18 +372,9 @@ int pnp_check_irq(struct pnp_dev *dev, struct resource *res)
317 } 372 }
318 } 373 }
319 374
320#ifdef CONFIG_PCI
321 /* check if the resource is being used by a pci device */ 375 /* check if the resource is being used by a pci device */
322 { 376 if (pci_uses_irq(dev, *irq))
323 struct pci_dev *pci = NULL; 377 return 0;
324 for_each_pci_dev(pci) {
325 if (pci->irq == *irq) {
326 pci_dev_put(pci);
327 return 0;
328 }
329 }
330 }
331#endif
332 378
333 /* check if the resource is already in use, skip if the 379 /* check if the resource is already in use, skip if the
334 * device is active because it itself may be in use */ 380 * device is active because it itself may be in use */