static int __devinit snd_mpu401_pnp(int dev, struct pnp_dev *device, const struct pnp_device_id *id) { if (!pnp_port_valid(device, 0) || pnp_port_flags(device, 0) & IORESOURCE_DISABLED) { snd_printk(KERN_ERR "no PnP port\n"); return -ENODEV; } if (pnp_port_len(device, 0) < IO_EXTENT) { snd_printk(KERN_ERR "PnP port length is %llu, expected %d\n", (unsigned long long)pnp_port_len(device, 0), IO_EXTENT); return -ENODEV; } port[dev] = pnp_port_start(device, 0); if (!pnp_irq_valid(device, 0) || pnp_irq_flags(device, 0) & IORESOURCE_DISABLED) { snd_printk(KERN_WARNING "no PnP irq, using polling\n"); irq[dev] = -1; } else { irq[dev] = pnp_irq(device, 0); } return 0; }
static int serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) { struct uart_8250_port uart; int ret, line, flags = dev_id->driver_data; struct resource *res = NULL; if (flags & UNKNOWN_DEV) { ret = serial_pnp_guess_board(dev); if (ret < 0) return ret; } memset(&uart, 0, sizeof(uart)); if (pnp_irq_valid(dev, 0)) uart.port.irq = pnp_irq(dev, 0); if ((flags & CIR_PORT) && pnp_port_valid(dev, 2)) res = pnp_get_resource(dev, IORESOURCE_IO, 2); else if (pnp_port_valid(dev, 0)) res = pnp_get_resource(dev, IORESOURCE_IO, 0); if (pnp_resource_enabled(res)) { uart.port.iobase = res->start; uart.port.iotype = UPIO_PORT; } else if (pnp_mem_valid(dev, 0)) { uart.port.mapbase = pnp_mem_start(dev, 0); uart.port.iotype = UPIO_MEM; uart.port.flags = UPF_IOREMAP; } else return -ENODEV; #ifdef SERIAL_DEBUG_PNP printk(KERN_DEBUG "Setup PNP port: port %x, mem 0x%lx, irq %d, type %d\n", uart.port.iobase, uart.port.mapbase, uart.port.irq, uart.port.iotype); #endif if (flags & CIR_PORT) { uart.port.flags |= UPF_FIXED_PORT | UPF_FIXED_TYPE; uart.port.type = PORT_8250_CIR; } uart.port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE) uart.port.flags |= UPF_SHARE_IRQ; uart.port.uartclk = 1843200; uart.port.dev = &dev->dev; line = serial8250_register_8250_port(&uart); if (line < 0 || (flags & CIR_PORT)) return -ENODEV; pnp_set_drvdata(dev, (void *)((long)line + 1)); return 0; }
static int parport_pc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id) { struct parport *pdata; unsigned long io_lo, io_hi; int dma, irq; if (pnp_port_valid(dev, 0) && !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) { io_lo = pnp_port_start(dev, 0); } else return -EINVAL; #if 0 if (pnp_port_valid(dev,1) && !(pnp_port_flags(dev,1) & IORESOURCE_DISABLED)) { io_hi = pnp_port_start(dev,1); } else io_hi = 0; #endif #if 0 if (pnp_irq_valid(dev,0) && !(pnp_irq_flags(dev,0) & IORESOURCE_DISABLED)) { irq = pnp_irq(dev,0); } else irq = PARPORT_IRQ_NONE; #endif #if 0 if (pnp_dma_valid(dev,0) && !(pnp_dma_flags(dev,0) & IORESOURCE_DISABLED)) { dma = pnp_dma(dev,0); } else dma = PARPORT_DMA_NONE; #endif #if 0 printk(KERN_INFO "parport: PnPBIOS parport detected.\n"); if (!(pdata = parport_pc_probe_port (io_lo, io_hi, irq, dma, NULL))) return -ENODEV; pnp_set_drvdata(dev,pdata); #endif return 0; }
static int __devinit serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) { struct uart_port port; int ret, line, flags = dev_id->driver_data; if (flags & UNKNOWN_DEV) { ret = serial_pnp_guess_board(dev, &flags); if (ret < 0) return ret; } memset(&port, 0, sizeof(struct uart_port)); if (pnp_irq_valid(dev, 0)) port.irq = pnp_irq(dev, 0); if (pnp_port_valid(dev, 0)) { port.iobase = pnp_port_start(dev, 0); port.iotype = UPIO_PORT; } else if (pnp_mem_valid(dev, 0)) { port.mapbase = pnp_mem_start(dev, 0); port.iotype = UPIO_MEM; port.flags = UPF_IOREMAP; } else return -ENODEV; #ifdef SERIAL_DEBUG_PNP printk(KERN_DEBUG "Setup PNP port: port %x, mem 0x%lx, irq %d, type %d\n", port.iobase, port.mapbase, port.irq, port.iotype); #endif port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE) port.flags |= UPF_SHARE_IRQ; port.uartclk = 1843200; port.dev = &dev->dev; line = serial8250_register_port(&port); if (line < 0) return -ENODEV; pnp_set_drvdata(dev, (void *)((long)line + 1)); return 0; }
/* it works in parport_pc's probe function, so why not here? */ static int c2_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id) { if (pnp_port_valid(dev,0) && !(pnp_port_flags(dev,0) & IORESOURCE_DISABLED)) { io_base = pnp_port_start(dev,0); } else { return -EINVAL; } if (pnp_irq_valid(dev,0) && !(pnp_irq_flags(dev,0) & IORESOURCE_DISABLED)) { irq = pnp_irq(dev,0); if (request_irq(irq, c2_interrupt, SA_INTERRUPT, DEVICE_NAME, NULL)) { return -EINVAL; } } else { return -EINVAL; } return 0; }
int pnp_check_irq(struct pnp_dev * dev, int idx) { int tmp; struct pnp_dev *tdev; unsigned long * irq = &dev->res.irq_resource[idx].start; /* if the resource doesn't exist, don't complain about it */ if (dev->res.irq_resource[idx].flags & IORESOURCE_UNSET) return 1; /* check if the resource is valid */ if (*irq < 0 || *irq > 15) return 0; /* check if the resource is reserved */ for (tmp = 0; tmp < 16; tmp++) { if (pnp_reserve_irq[tmp] == *irq) return 0; } /* check for internal conflicts */ for (tmp = 0; tmp < PNP_MAX_IRQ && tmp != idx; tmp++) { if (dev->res.irq_resource[tmp].flags & IORESOURCE_IRQ) { if (dev->res.irq_resource[tmp].start == *irq) return 0; } } #ifdef CONFIG_PCI /* check if the resource is being used by a pci device */ if (!pnp_skip_pci_scan) { struct pci_dev * pci = NULL; while ((pci = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci)) != NULL) { if (pci->irq == *irq) return 0; } } #endif /* check if the resource is already in use, skip if the * device is active because it itself may be in use */ if(!dev->active) { if (request_irq(*irq, pnp_test_handler, SA_INTERRUPT, "pnp", NULL)) return 0; free_irq(*irq, NULL); } /* check for conflicts with other pnp devices */ pnp_for_each_dev(tdev) { if (tdev == dev) continue; for (tmp = 0; tmp < PNP_MAX_IRQ; tmp++) { if (tdev->res.irq_resource[tmp].flags & IORESOURCE_IRQ) { if (pnp_irq_flags(dev, tmp) & IORESOURCE_DISABLED) continue; if ((tdev->res.irq_resource[tmp].start == *irq)) return 0; } } } return 1; }
static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_attribute *attr, char *buf) { struct pnp_dev *dev = to_pnp_dev(dmdev); int i, ret; pnp_info_buffer_t *buffer; if (!dev) return -EINVAL; buffer = (pnp_info_buffer_t *) pnp_alloc(sizeof(pnp_info_buffer_t)); if (!buffer) return -ENOMEM; buffer->len = PAGE_SIZE; buffer->buffer = buf; buffer->curr = buffer->buffer; pnp_printf(buffer,"state = "); if (dev->active) pnp_printf(buffer,"active\n"); else pnp_printf(buffer,"disabled\n"); for (i = 0; i < PNP_MAX_PORT; i++) { if (pnp_port_valid(dev, i)) { pnp_printf(buffer,"io"); if (pnp_port_flags(dev, i) & IORESOURCE_DISABLED) pnp_printf(buffer," disabled\n"); else pnp_printf(buffer," 0x%llx-0x%llx\n", (unsigned long long)pnp_port_start(dev, i), (unsigned long long)pnp_port_end(dev, i)); } } for (i = 0; i < PNP_MAX_MEM; i++) { if (pnp_mem_valid(dev, i)) { pnp_printf(buffer,"mem"); if (pnp_mem_flags(dev, i) & IORESOURCE_DISABLED) pnp_printf(buffer," disabled\n"); else pnp_printf(buffer," 0x%llx-0x%llx\n", (unsigned long long)pnp_mem_start(dev, i), (unsigned long long)pnp_mem_end(dev, i)); } } for (i = 0; i < PNP_MAX_IRQ; i++) { if (pnp_irq_valid(dev, i)) { pnp_printf(buffer,"irq"); if (pnp_irq_flags(dev, i) & IORESOURCE_DISABLED) pnp_printf(buffer," disabled\n"); else pnp_printf(buffer," %lld\n", (unsigned long long)pnp_irq(dev, i)); } } for (i = 0; i < PNP_MAX_DMA; i++) { if (pnp_dma_valid(dev, i)) { pnp_printf(buffer,"dma"); if (pnp_dma_flags(dev, i) & IORESOURCE_DISABLED) pnp_printf(buffer," disabled\n"); else pnp_printf(buffer," %lld\n", (unsigned long long)pnp_dma(dev, i)); } } ret = (buffer->curr - buf); kfree(buffer); return ret; }