From 93ef77fa858d4843e25cd11439acb25280517eaf Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:27:00 -0500 Subject: [PATCH] Import 2.3.15pre2 --- drivers/pci/pci.c | 23 ++- drivers/pnp/isapnp.c | 284 +++++++++++++------------- drivers/pnp/isapnp_proc.c | 48 ++--- drivers/video/atyfb.c | 4 +- drivers/video/modedb.c | 410 ++++++++++++++++++++++++++++++++++++++ include/linux/ioport.h | 42 ++-- include/linux/isapnp.h | 13 ++ include/linux/pci.h | 17 +- 8 files changed, 629 insertions(+), 212 deletions(-) create mode 100644 drivers/video/modedb.c diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index ec9749d8d59e..8e42297646c3 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -141,6 +141,21 @@ pci_set_master(struct pci_dev *dev) } } +/* + * Translate the low bits of the PCI base + * to the resource type + */ +static inline unsigned int pci_resource_flags(unsigned int flags) +{ + if (flags & PCI_BASE_ADDRESS_SPACE_IO) + return IORESOURCE_IO | flags; + + if (flags & PCI_BASE_ADDRESS_MEM_PREFETCH) + return IORESOURCE_MEM | IORESOURCE_PREFETCH; + + return IORESOURCE_MEM; +} + void __init pci_read_bases(struct pci_dev *dev, unsigned int howmany) { unsigned int reg; @@ -168,16 +183,16 @@ void __init pci_read_bases(struct pci_dev *dev, unsigned int howmany) continue; res->start = l & mask; - res->flags = l & ~mask; + l &= ~mask; + res->flags = l | pci_resource_flags(l); size = 1; do { size <<= 1; } while (!(size & newval)); - /* 64-bit memory? */ - if ((l & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK)) - == (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64)) { + /* 64-bit decode? */ + if ((l & (PCI_BASE_ADDRESS_MEM_TYPE_MASK | PCI_BASE_ADDRESS_SPACE)) == PCI_BASE_ADDRESS_MEM_TYPE_64) { unsigned int high; reg++; pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + (reg << 2), &high); diff --git a/drivers/pnp/isapnp.c b/drivers/pnp/isapnp.c index 149df9b594d6..d0c31a791976 100644 --- a/drivers/pnp/isapnp.c +++ b/drivers/pnp/isapnp.c @@ -1199,6 +1199,30 @@ struct pci_dev *isapnp_find_dev(struct pci_bus *card, return NULL; } +/* + * FIXME! We should probably save away more than just the type + * in the DMA resource fields.. + */ +static unsigned int isapnp_dma_resource_flags(struct isapnp_dma *dma) +{ + return dma->type | IORESOURCE_DMA | IORESOURCE_AUTO; +} + +static unsigned int isapnp_mem_resource_flags(struct isapnp_mem *mem) +{ + return mem->type | IORESOURCE_MEM | IORESOURCE_AUTO; +} + +static unsigned int isapnp_irq_resource_flags(struct isapnp_irq *irq) +{ + return irq->flags | IORESOURCE_IRQ | IORESOURCE_AUTO; +} + +static unsigned int isapnp_port_resource_flags(struct isapnp_port *port) +{ + return port->flags | IORESOURCE_IO | IORESOURCE_AUTO; +} + static int isapnp_config_prepare(struct pci_dev *dev) { struct isapnp_resources *res, *resa; @@ -1216,47 +1240,41 @@ static int isapnp_config_prepare(struct pci_dev *dev) return -EINVAL; if (dev->active || dev->ro) return -EBUSY; - dev->irq = dev->irq2 = DEVICE_IRQ_NOTSET; - dev->irq_flags = dev->irq2_flags = 0; + for (idx = 0; idx < DEVICE_COUNT_IRQ; idx++) { + dev->irq_resource[idx].name = NULL; + dev->irq_resource[idx].start = 0; + dev->irq_resource[idx].end = 0; + dev->irq_resource[idx].flags = 0; + } for (idx = 0; idx < DEVICE_COUNT_DMA; idx++) { - dev->dma[idx] = DEVICE_DMA_NOTSET; - dev->dma_type[idx] = DEVICE_DMA_TYPE_8AND16BIT; - dev->dma_flags[idx] = 0; - dev->dma_speed[idx] = DEVICE_DMA_SPEED_COMPATIBLE; + dev->dma_resource[idx].name = NULL; + dev->dma_resource[idx].start = 0; + dev->dma_resource[idx].end = 0; + dev->dma_resource[idx].flags = 0; } for (idx = 0; idx < DEVICE_COUNT_RESOURCE; idx++) { dev->resource[idx].name = NULL; - dev->resource[idx].start = DEVICE_IO_NOTSET; + dev->resource[idx].start = 0; dev->resource[idx].end = 0; - dev->resource[idx].fixed = 0; - dev->resource[idx].bits = 12; - dev->resource[idx].hw_flags = 0; - dev->resource[idx].type = DEVICE_IO_TYPE_8AND16BIT; + dev->resource[idx].flags = 0; } port_count = irq_count = dma_count = mem_count = 0; for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) { port_count1 = irq_count1 = dma_count1 = mem_count1 = 0; for (resa = res; resa; resa = resa->alt) { for (port = resa->port, idx = 0; port; port = port->next, idx++) { - if (dev->resource[port_count + idx].start == DEVICE_IO_NOTSET) { - dev->resource[port_count + idx].start = DEVICE_IO_AUTO; + if (dev->resource[port_count + idx].flags == 0) { + dev->resource[port_count + idx].flags = isapnp_port_resource_flags(port); dev->resource[port_count + idx].end = port->size; - dev->resource[port_count + idx].bits = port->flags & ISAPNP_PORT_FLAG_16BITADDR ? 16 : 12; - dev->resource[port_count + idx].fixed = port->flags & ISAPNP_PORT_FLAG_FIXED ? 1 : 0; } } if (port_count1 < idx) port_count1 = idx; for (irq = resa->irq, idx = 0; irq; irq = irq->next, idx++) { - if (irq_count + idx == 0) { - if (dev->irq == DEVICE_IRQ_NOTSET) { - dev->irq = DEVICE_IRQ_AUTO; - dev->irq_flags = irq->flags; - } - } else if (irq_count + idx == 1) { - if (dev->irq2 == DEVICE_IRQ_NOTSET) { - dev->irq2 = DEVICE_IRQ_AUTO; - dev->irq2_flags = irq->flags; + int count = irq_count + idx; + if (count < DEVICE_COUNT_IRQ) { + if (dev->irq_resource[count].flags == 0) { + dev->irq_resource[count].flags = isapnp_irq_resource_flags(irq); } } @@ -1264,22 +1282,14 @@ static int isapnp_config_prepare(struct pci_dev *dev) if (irq_count1 < idx) irq_count1 = idx; for (dma = resa->dma, idx = 0; dma; dma = dma->next, idx++) - if (dev->dma[idx] == DEVICE_DMA_NOTSET) { - dev->dma[idx] = DEVICE_DMA_AUTO; - dev->dma_type[idx] = dma->type; - dev->dma_flags[idx] = dma->flags; - dev->dma_speed[idx] = dma->speed; + if (dev->dma_resource[idx].flags == 0) { + dev->dma_resource[idx].flags = isapnp_dma_resource_flags(dma); } if (dma_count1 < idx) dma_count1 = idx; for (mem = resa->mem, idx = 0; mem; mem = mem->next, idx++) - if (dev->resource[mem_count + idx + 8].start == DEVICE_IO_AUTO) { - dev->resource[mem_count + idx].start = DEVICE_IO_AUTO; - dev->resource[mem_count + idx].end = mem->size; - dev->resource[mem_count + idx].bits = 24; - dev->resource[mem_count + idx].fixed = 0; - dev->resource[mem_count + idx].hw_flags = mem->flags; - dev->resource[mem_count + idx].type = mem->type; + if (dev->resource[mem_count + idx + 8].flags == 0) { + dev->resource[mem_count + idx].flags = isapnp_mem_resource_flags(mem); } if (mem_count1 < idx) mem_count1 = idx; @@ -1315,7 +1325,7 @@ static int isapnp_alternative_switch(struct isapnp_cfgtmp *cfg, return -EINVAL; /* process port settings */ for (tmp = 0; tmp < 8; tmp++) { - if (cfg->request->resource[tmp].start != DEVICE_IO_AUTO) + if (!(cfg->request->resource[tmp].flags & IORESOURCE_AUTO)) continue; /* don't touch */ port = cfg->port[tmp]; if (!port) { @@ -1331,21 +1341,17 @@ static int isapnp_alternative_switch(struct isapnp_cfgtmp *cfg, for (tmp1 = tmp; tmp1 > 0 && port; tmp1--) port = port->next; cfg->port[tmp] = port; - cfg->result.resource[tmp].start = DEVICE_IO_AUTO; if (!port) return -ENOENT; + cfg->result.resource[tmp].flags = isapnp_port_resource_flags(port); } } } /* process irq settings */ for (tmp = 0; tmp < 2; tmp++) { - if (tmp == 0) { - if (cfg->request->irq != DEVICE_IRQ_AUTO) - continue; /* don't touch */ - } else { - if (cfg->request->irq2 != DEVICE_IRQ_AUTO) - continue; /* don't touch */ - } + if (!(cfg->request->irq_resource[tmp].flags & IORESOURCE_AUTO)) + continue; /* don't touch */ + irq = cfg->irq[tmp]; if (!irq) { cfg->irq[tmp] = irq = isapnp_find_irq(cfg->request, tmp); @@ -1360,20 +1366,17 @@ static int isapnp_alternative_switch(struct isapnp_cfgtmp *cfg, for (tmp1 = tmp; tmp1 > 0 && irq; tmp1--) irq = irq->next; cfg->irq[tmp] = irq; - if (tmp == 0) { - cfg->result.irq = DEVICE_IRQ_AUTO; - } else { - cfg->result.irq2 = DEVICE_IRQ_AUTO; - } if (!irq) return -ENOENT; + cfg->result.irq_resource[tmp].flags = isapnp_irq_resource_flags(irq); } } } /* process dma settings */ for (tmp = 0; tmp < 2; tmp++) { - if (cfg->request->dma[tmp] != DEVICE_DMA_AUTO) + if (!(cfg->request->dma_resource[tmp].flags & IORESOURCE_AUTO)) continue; /* don't touch */ + dma = cfg->dma[tmp]; if (!dma) { cfg->dma[tmp] = dma = isapnp_find_dma(cfg->request, tmp); @@ -1388,15 +1391,15 @@ static int isapnp_alternative_switch(struct isapnp_cfgtmp *cfg, for (tmp1 = tmp; tmp1 > 0 && dma; tmp1--) dma = dma->next; cfg->dma[tmp] = dma; - cfg->result.dma[tmp] = DEVICE_DMA_AUTO; if (!dma) return -ENOENT; + cfg->result.dma_resource[tmp].flags = isapnp_dma_resource_flags(dma); } } } /* process memory settings */ for (tmp = 0; tmp < 4; tmp++) { - if (cfg->request->resource[tmp + 8].start != DEVICE_IO_AUTO) + if (!(cfg->request->resource[tmp + 8].flags & IORESOURCE_AUTO)) continue; /* don't touch */ mem = cfg->mem[tmp]; if (!mem) { @@ -1412,9 +1415,9 @@ static int isapnp_alternative_switch(struct isapnp_cfgtmp *cfg, for (tmp1 = tmp; tmp1 > 0 && mem; tmp1--) mem = mem->next; cfg->mem[tmp] = mem; - cfg->result.resource[tmp + 8].start = DEVICE_IO_AUTO; if (!mem) return -ENOENT; + cfg->result.resource[tmp + 8].flags = isapnp_mem_resource_flags(mem); } } } @@ -1440,7 +1443,7 @@ static int isapnp_check_port(struct isapnp_cfgtmp *cfg, int port, int size, int for (dev = isapnp_devices; dev; dev = dev->next) { if (dev->active) { for (tmp = 0; tmp < 8; tmp++) { - if (dev->resource[tmp].start != DEVICE_IO_NOTSET) { + if (dev->resource[tmp].flags) { rport = dev->resource[tmp].start; rsize = (dev->resource[tmp].end - rport) + 1; if (port >= rport && port < rport + rsize) @@ -1452,18 +1455,20 @@ static int isapnp_check_port(struct isapnp_cfgtmp *cfg, int port, int size, int } } for (i = 0; i < 8; i++) { + unsigned int flags; if (i == idx) continue; - tmp = cfg->request->resource[i].start; - if (tmp == DEVICE_IO_NOTSET) + flags = cfg->request->resource[i].flags; + if (!flags) continue; - if (tmp == DEVICE_IO_AUTO) { /* auto */ + tmp = cfg->request->resource[i].start; + if (flags & IORESOURCE_AUTO) { /* auto */ xport = cfg->port[i]; if (!xport) return 1; - tmp = cfg->result.resource[i].start; - if (tmp == DEVICE_IO_AUTO) + if (cfg->result.resource[i].flags & IORESOURCE_AUTO) continue; + tmp = cfg->result.resource[i].start; if (tmp + xport->size >= port && tmp <= port + xport->size) return 1; continue; @@ -1487,14 +1492,14 @@ static int isapnp_valid_port(struct isapnp_cfgtmp *cfg, int idx) if (!cfg || idx < 0 || idx > 7) return -EINVAL; - if (cfg->result.resource[idx].start != DEVICE_IO_AUTO) /* don't touch */ + if (!(cfg->result.resource[idx].flags & IORESOURCE_AUTO)) /* don't touch */ return 0; __again: port = cfg->port[idx]; if (!port) return -EINVAL; value = &cfg->result.resource[idx].start; - if (*value == DEVICE_IO_AUTO) { + if (cfg->result.resource[idx].flags & IORESOURCE_AUTO) { if (!isapnp_check_port(cfg, *value = port->min, port->size, idx)) return 0; } @@ -1529,24 +1534,23 @@ static int isapnp_check_interrupt(struct isapnp_cfgtmp *cfg, int irq, int idx) } for (dev = isapnp_devices; dev; dev = dev->next) { if (dev->active) { - if (dev->irq == irq || dev->irq2 == irq) + if (dev->irq_resource[0].start == irq || + dev->irq_resource[1].start == irq) return 1; } } if (request_irq(irq, isapnp_test_handler, SA_INTERRUPT, "isapnp", NULL)) return 1; free_irq(irq, NULL); - if (idx != 0) { - if (cfg->result.irq != DEVICE_IRQ_AUTO && - cfg->result.irq != DEVICE_IRQ_NOTSET) - if (cfg->result.irq == irq) - return 1; - } - if (idx != 1) { - if (cfg->result.irq2 != DEVICE_IRQ_AUTO && - cfg->result.irq2 != DEVICE_IRQ_NOTSET) - if (cfg->result.irq2 == irq) - return 1; + for (i = 0; i < DEVICE_COUNT_IRQ; i++) { + if (i == idx) + continue; + if (!cfg->result.irq_resource[i].flags) + continue; + if (cfg->result.irq_resource[i].flags & IORESOURCE_AUTO) + continue; + if (cfg->result.irq_resource[i].start == irq) + return 1; } return 0; } @@ -1558,28 +1562,19 @@ static int isapnp_valid_irq(struct isapnp_cfgtmp *cfg, int idx) 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2 }; int err, i; - unsigned int *value; + unsigned long *value; struct isapnp_irq *irq; if (!cfg || idx < 0 || idx > 1) return -EINVAL; - if (idx == 0) { - if (cfg->result.irq != DEVICE_IRQ_AUTO) /* don't touch */ - return 0; - } else { - if (cfg->result.irq2 != DEVICE_IRQ_AUTO) /* don't touch */ - return 0; - } + if (!(cfg->result.irq_resource[idx].flags & IORESOURCE_AUTO)) + return 0; __again: irq = cfg->irq[idx]; if (!irq) return -EINVAL; - if (idx == 0) { - value = &cfg->result.irq; - } else { - value = &cfg->result.irq2; - } - if (*value == DEVICE_IRQ_AUTO) { + value = &cfg->result.irq_resource[idx].start; + if (cfg->result.irq_resource[idx].flags & IORESOURCE_AUTO) { for (i = 0; i < 16 && !(irq->map & (1<= 16) return -ENOENT; @@ -1616,7 +1611,7 @@ static int isapnp_check_dma(struct isapnp_cfgtmp *cfg, int dma, int idx) } for (dev = isapnp_devices; dev; dev = dev->next) { if (dev->active) { - if (dev->dma[0] == dma || dev->dma[1] == dma) + if (dev->dma_resource[0].start == dma || dev->dma_resource[1].start == dma) return 1; } } @@ -1626,10 +1621,10 @@ static int isapnp_check_dma(struct isapnp_cfgtmp *cfg, int dma, int idx) for (i = 0; i < 2; i++) { if (i == idx) continue; - if (cfg->result.dma[i] == DEVICE_DMA_NOTSET || - cfg->result.dma[i] == DEVICE_DMA_AUTO) + if (!cfg->result.dma_resource[i].flags || + (cfg->result.dma_resource[i].flags & IORESOURCE_AUTO)) continue; - if (cfg->result.dma[i] == dma) + if (cfg->result.dma_resource[i].start == dma) return 1; } return 0; @@ -1638,19 +1633,19 @@ static int isapnp_check_dma(struct isapnp_cfgtmp *cfg, int dma, int idx) static int isapnp_valid_dma(struct isapnp_cfgtmp *cfg, int idx) { int err, i; - unsigned char *value; + unsigned long *value; struct isapnp_dma *dma; if (!cfg || idx < 0 || idx > 1) return -EINVAL; - if (cfg->result.dma[idx] != DEVICE_DMA_AUTO) /* don't touch */ + if (!(cfg->result.dma_resource[idx].flags & IORESOURCE_AUTO)) /* don't touch */ return 0; __again: dma = cfg->dma[idx]; if (!dma) return -EINVAL; - value = &cfg->result.dma[idx]; - if (*value == DEVICE_DMA_AUTO) { + value = &cfg->result.dma_resource[idx].start; + if (cfg->result.dma_resource[idx].flags & IORESOURCE_AUTO) { for (i = 0; i < 8 && !(dma->map & (1<= 8) return -ENOENT; @@ -1693,7 +1688,7 @@ static int isapnp_check_mem(struct isapnp_cfgtmp *cfg, unsigned int addr, unsign for (dev = isapnp_devices; dev; dev = dev->next) { if (dev->active) { for (tmp = 0; tmp < 4; tmp++) { - if (dev->resource[tmp].start != DEVICE_IO_NOTSET) { + if (dev->resource[tmp].flags) { raddr = dev->resource[tmp + 8].start; rsize = (dev->resource[tmp + 8].end - raddr) + 1; if (addr >= raddr && addr < raddr + rsize) @@ -1705,17 +1700,17 @@ static int isapnp_check_mem(struct isapnp_cfgtmp *cfg, unsigned int addr, unsign } } for (i = 0; i < 4; i++) { + unsigned int flags = cfg->request->resource[i + 8].flags; if (i == idx) continue; - tmp = cfg->request->resource[i + 8].start; - if (tmp == DEVICE_IO_NOTSET) + if (!flags) continue; - if (tmp == DEVICE_IO_AUTO) { /* auto */ + tmp = cfg->result.resource[i + 8].start; + if (flags & IORESOURCE_AUTO) { /* auto */ xmem = cfg->mem[i]; if (!xmem) return 1; - tmp = cfg->result.resource[i + 8].start; - if (tmp == DEVICE_IO_AUTO) + if (cfg->result.resource[i + 8].flags & IORESOURCE_AUTO) continue; if (tmp + xmem->size >= addr && tmp <= addr + xmem->size) return 1; @@ -1735,19 +1730,21 @@ static int isapnp_check_mem(struct isapnp_cfgtmp *cfg, unsigned int addr, unsign static int isapnp_valid_mem(struct isapnp_cfgtmp *cfg, int idx) { int err; + unsigned int flags; unsigned long *value; struct isapnp_mem *mem; if (!cfg || idx < 0 || idx > 3) return -EINVAL; - if (cfg->result.resource[idx + 8].start != DEVICE_IO_AUTO) /* don't touch */ + flags = cfg->result.resource[idx + 8].flags; + if (flags && (flags & IORESOURCE_AUTO)) /* don't touch */ return 0; __again: mem = cfg->mem[idx]; if (!mem) return -EINVAL; value = &cfg->result.resource[idx].start; - if (*value == DEVICE_IO_AUTO) { + if (flags & IORESOURCE_AUTO) { *value = mem->min; if (!isapnp_check_mem(cfg, *value, mem->size, idx)) return 0; @@ -1771,17 +1768,16 @@ static int isapnp_check_valid(struct isapnp_cfgtmp *cfg) int tmp; for (tmp = 0; tmp < 8; tmp++) - if (cfg->result.resource[tmp].start == DEVICE_IO_AUTO) + if (cfg->result.resource[tmp].flags & IORESOURCE_AUTO) return -EAGAIN; - if (cfg->result.irq == DEVICE_IRQ_AUTO) - return -EAGAIN; - if (cfg->result.irq2 == DEVICE_IRQ_AUTO) - return -EAGAIN; for (tmp = 0; tmp < 2; tmp++) - if (cfg->result.dma[tmp] == DEVICE_DMA_AUTO) + if (cfg->result.irq_resource[tmp].flags & IORESOURCE_AUTO) + return -EAGAIN; + for (tmp = 0; tmp < 2; tmp++) + if (cfg->result.dma_resource[tmp].flags & IORESOURCE_AUTO) return -EAGAIN; for (tmp = 0; tmp < 4; tmp++) - if (cfg->result.resource[tmp + 1].start == DEVICE_IO_AUTO) + if (cfg->result.resource[tmp + 8].flags & IORESOURCE_AUTO) return -EAGAIN; return 0; } @@ -1800,19 +1796,19 @@ static int isapnp_config_activate(struct pci_dev *dev) memcpy(&cfg.result, dev, sizeof(struct pci_dev)); /* check if all values are set, otherwise try auto-configuration */ for (tmp = fauto = 0; !fauto && tmp < 8; tmp++) { - if (dev->resource[tmp].start == DEVICE_IO_AUTO) + if (dev->resource[tmp].flags & IORESOURCE_AUTO) + fauto++; + } + for (tmp = 0; !fauto && tmp < 2; tmp++) { + if (dev->irq_resource[tmp].flags & IORESOURCE_AUTO) fauto++; } - if (dev->irq == DEVICE_IRQ_AUTO) - fauto++; - if (dev->irq2 == DEVICE_IRQ_AUTO) - fauto++; for (tmp = 0; !fauto && tmp < 2; tmp++) { - if (dev->dma[tmp] == DEVICE_DMA_AUTO) + if (dev->dma_resource[tmp].flags & IORESOURCE_AUTO) fauto++; } for (tmp = 0; !fauto && tmp < 4; tmp++) { - if (dev->resource[tmp + 8].start == DEVICE_IO_AUTO) + if (dev->resource[tmp + 8].flags & IORESOURCE_AUTO) fauto++; } if (!fauto) @@ -1823,19 +1819,16 @@ static int isapnp_config_activate(struct pci_dev *dev) /* find first valid configuration */ fauto = 0; do { - for (tmp = 0; tmp < 8 && cfg.result.resource[tmp].start != DEVICE_IO_NOTSET; tmp++) + for (tmp = 0; tmp < 8 && cfg.result.resource[tmp].flags ; tmp++) if ((err = isapnp_valid_port(&cfg, tmp))<0) return err; - if (cfg.result.irq != DEVICE_IRQ_NOTSET) + for (tmp = 0; tmp < 2 && cfg.result.irq_resource[tmp].flags ; tmp++) if ((err = isapnp_valid_irq(&cfg, 0))<0) return err; - if (cfg.result.irq2 != DEVICE_IRQ_NOTSET) - if ((err = isapnp_valid_irq(&cfg, 1))<0) - return err; - for (tmp = 0; tmp < 2 && tmp < cfg.result.dma[tmp] != DEVICE_DMA_NOTSET; tmp++) + for (tmp = 0; tmp < 2 && cfg.result.dma_resource[tmp].flags; tmp++) if ((err = isapnp_valid_dma(&cfg, tmp))<0) return err; - for (tmp = 0; tmp < 4 && tmp < cfg.result.resource[tmp + 8].start != DEVICE_IO_NOTSET; tmp++) + for (tmp = 0; tmp < 4 && cfg.result.resource[tmp + 8].flags; tmp++) if ((err = isapnp_valid_mem(&cfg, tmp))<0) return err; } while (isapnp_check_valid(&cfg)<0 && fauto++ < 20); @@ -1845,31 +1838,24 @@ static int isapnp_config_activate(struct pci_dev *dev) /* we have valid configuration, try configure hardware */ isapnp_cfg_begin(dev->bus->number, dev->devfn); dev->active = 1; - dev->irq = cfg.result.irq; - dev->irq2 = cfg.result.irq2; - dev->dma[0] = cfg.result.dma[0]; - dev->dma[1] = cfg.result.dma[1]; + dev->irq_resource[0] = cfg.result.irq_resource[0]; + dev->irq_resource[1] = cfg.result.irq_resource[1]; + dev->dma_resource[0] = cfg.result.dma_resource[0]; + dev->dma_resource[1] = cfg.result.dma_resource[1]; for (tmp = 0; tmp < 12; tmp++) { - dev->resource[tmp].start = cfg.result.resource[tmp].start; - if (cfg.result.resource[tmp].start != DEVICE_IO_NOTSET && - cfg.result.resource[tmp].end != DEVICE_IO_AUTO) - dev->resource[tmp].end += cfg.result.resource[tmp].start; + dev->resource[tmp] = cfg.result.resource[tmp]; } - for (tmp = 0; tmp < 8 && dev->resource[tmp].start != DEVICE_IO_NOTSET; tmp++) + for (tmp = 0; tmp < 8 && dev->resource[tmp].flags; tmp++) isapnp_write_word(ISAPNP_CFG_PORT+(tmp<<1), dev->resource[tmp].start); - if (dev->irq != DEVICE_IRQ_NOTSET) { - if (dev->irq == 2) - dev->irq = 9; - isapnp_write_byte(ISAPNP_CFG_IRQ+(0<<1), dev->irq); - } - if (dev->irq2 != DEVICE_IRQ_NOTSET) { - if (dev->irq2 == 2) - dev->irq2 = 9; - isapnp_write_byte(ISAPNP_CFG_IRQ+(1<<1), dev->irq2); - } - for (tmp = 0; tmp < 2 && dev->dma[tmp] != DEVICE_DMA_NOTSET; tmp++) - isapnp_write_byte(ISAPNP_CFG_DMA+tmp, dev->dma[tmp]); - for (tmp = 0; tmp < 4 && dev->resource[tmp].start != DEVICE_IO_NOTSET; tmp++) + for (tmp = 0; tmp < 2 && dev->irq_resource[tmp].flags; tmp++) { + int irq = dev->irq_resource[tmp].start; + if (irq == 2) + irq = 9; + isapnp_write_byte(ISAPNP_CFG_IRQ+(tmp<<1), irq); + } + for (tmp = 0; tmp < 2 && dev->dma_resource[tmp].flags; tmp++) + isapnp_write_byte(ISAPNP_CFG_DMA+tmp, dev->dma_resource[tmp].start); + for (tmp = 0; tmp < 4 && dev->resource[tmp+8].flags; tmp++) isapnp_write_word(ISAPNP_CFG_MEM+(tmp<<2), (dev->resource[tmp + 8].start >> 8) & 0xffff); isapnp_activate(dev->devfn); isapnp_cfg_end(); @@ -1882,7 +1868,7 @@ static int isapnp_config_deactivate(struct pci_dev *dev) return -EINVAL; isapnp_cfg_begin(dev->bus->number, dev->devfn); isapnp_deactivate(dev->devfn); - dev->activate = 0; + dev->active = 0; isapnp_cfg_end(); return 0; } @@ -1971,7 +1957,7 @@ static void isapnp_free_device(struct pci_dev *dev) struct pci_dev *next; while (dev) { - next = dev->next; + next = dev->sibling; isapnp_free_resources((struct isapnp_resources *)dev->sysdata, 0); kfree(dev); dev = next; diff --git a/drivers/pnp/isapnp_proc.c b/drivers/pnp/isapnp_proc.c index 9c6f0be2a9c2..edabd9a14834 100644 --- a/drivers/pnp/isapnp_proc.c +++ b/drivers/pnp/isapnp_proc.c @@ -380,21 +380,21 @@ static void isapnp_print_mem(isapnp_info_buffer_t *buffer, char *space, struct i isapnp_printf(buffer, "%sMemory 0x%x-0x%x, align 0x%x, size 0x%x", space, mem->min, mem->max, mem->align, mem->size); - if (mem->flags & DEVICE_IO_FLAG_WRITEABLE) + if (mem->flags & ISAPNP_FLAG_WRITEABLE) isapnp_printf(buffer, ", writeable"); - if (mem->flags & DEVICE_IO_FLAG_CACHEABLE) + if (mem->flags & ISAPNP_FLAG_CACHEABLE) isapnp_printf(buffer, ", cacheable"); - if (mem->flags & DEVICE_IO_FLAG_RANGELENGTH) + if (mem->flags & ISAPNP_FLAG_RANGELENGTH) isapnp_printf(buffer, ", range-length"); - if (mem->flags & DEVICE_IO_FLAG_SHADOWABLE) + if (mem->flags & ISAPNP_FLAG_SHADOWABLE) isapnp_printf(buffer, ", shadowable"); - if (mem->flags & DEVICE_IO_FLAG_EXPANSIONROM) + if (mem->flags & ISAPNP_FLAG_EXPANSIONROM) isapnp_printf(buffer, ", expansion ROM"); switch (mem->type) { - case DEVICE_IO_TYPE_8BIT: + case ISAPNP_TYPE_8BIT: s = "8-bit"; break; - case DEVICE_IO_TYPE_8AND16BIT: + case ISAPNP_TYPE_8AND16BIT: s = "8-bit&16-bit"; break; default: @@ -734,9 +734,9 @@ static int isapnp_set_port(char *line) return 1; } isapnp_write_word(ISAPNP_CFG_PORT + (idx << 1), port); - if (isapnp_info_device->resource[idx].start == DEVICE_IO_NOTSET) + if (isapnp_info_device->resource[idx].start == ISAPNP_NOTSET) return 0; - if (isapnp_info_device->resource[idx].start == DEVICE_IO_AUTO) { + if (isapnp_info_device->resource[idx].start == ISAPNP_AUTO) { isapnp_info_device->resource[idx].start = port; isapnp_info_device->resource[idx].end += port - 1; } else { @@ -746,6 +746,12 @@ static int isapnp_set_port(char *line) } return 0; } + +static void isapnp_set_irqresource(struct resource *res, int irq) +{ + res->start = res->end = irq; + res->flags = IORESOURCE_IRQ; +} static int isapnp_set_irq(char *line) { @@ -767,18 +773,16 @@ static int isapnp_set_irq(char *line) return 1; } isapnp_write_byte(ISAPNP_CFG_IRQ + (idx << 1), irq); - if (idx == 0) { - if (isapnp_info_device->irq == DEVICE_IRQ_NOTSET) - return 0; - isapnp_info_device->irq = irq; - } else { - if (isapnp_info_device->irq2 == DEVICE_IRQ_NOTSET) - return 0; - isapnp_info_device->irq2 = irq; - } + isapnp_set_irqresource(isapnp_info_device->irq_resource + idx, irq); return 0; } +static void isapnp_set_dmaresource(struct resource *res, int dma) +{ + res->start = res->end = dma; + res->flags = IORESOURCE_DMA; +} + static int isapnp_set_dma(char *line) { int idx, dma; @@ -797,9 +801,7 @@ static int isapnp_set_dma(char *line) return 1; } isapnp_write_byte(ISAPNP_CFG_DMA + idx, dma); - if (isapnp_info_device->dma[idx] == DEVICE_DMA_NOTSET) - return 0; - isapnp_info_device->dma[idx] = dma; + isapnp_set_dmaresource(isapnp_info_device->dma_resource + idx, dma); return 0; } @@ -819,9 +821,9 @@ static int isapnp_set_mem(char *line) } mem >>= 8; isapnp_write_word(ISAPNP_CFG_MEM + (idx<<2), mem & 0xffff); - if (isapnp_info_device->resource[idx + 8].start == DEVICE_IO_NOTSET) + if (isapnp_info_device->resource[idx + 8].start == ISAPNP_NOTSET) return 0; - if (isapnp_info_device->resource[idx + 8].start == DEVICE_IO_AUTO) { + if (isapnp_info_device->resource[idx + 8].start == ISAPNP_AUTO) { isapnp_info_device->resource[idx + 8].start = mem & ~0x00ffff00; isapnp_info_device->resource[idx + 8].end += (mem & ~0x00ffff00) - 1; } else { diff --git a/drivers/video/atyfb.c b/drivers/video/atyfb.c index d13782b50cfe..68dab49ff42a 100644 --- a/drivers/video/atyfb.c +++ b/drivers/video/atyfb.c @@ -1951,11 +1951,11 @@ static int encode_fix(struct fb_fix_screeninfo *fix, fix->mmio_len = 0x400; fix->accel = FB_ACCEL_ATI_MACH64CT; } else if (Gx == VT_CHIP_ID || Gx == VU_CHIP_ID || Gx == VV_CHIP_ID) { - fix->mmio_start = info->ati_regbase_phys-0x400); + fix->mmio_start = info->ati_regbase_phys-0x400; fix->mmio_len = 0x800; fix->accel = FB_ACCEL_ATI_MACH64VT; } else { - fix->mmio_start = info->ati_regbase_phys-0x400); + fix->mmio_start = info->ati_regbase_phys-0x400; fix->mmio_len = 0x800; fix->accel = FB_ACCEL_ATI_MACH64GT; } diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c new file mode 100644 index 000000000000..af58b457ae9c --- /dev/null +++ b/drivers/video/modedb.c @@ -0,0 +1,410 @@ +/* + * linux/drivers/video/modedb.c -- Standard video mode database management + * + * Copyright (C) 1999 Geert Uytterhoeven + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#include +#include +#include +#include + + +#define DEBUG + +#define name_matches(v, s, l) \ + ((v).name && !strncmp((s), (v).name, (l)) && strlen((v).name) == (l)) +#define res_matches(v, x, y) \ + ((v).xres == (x) && (v).yres == (y)) + +#ifdef DEBUG +#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args) +#else +#define DPRINTK(fmt, args...) +#endif + + +const char *global_mode_option = NULL; + + + /* + * Standard video mode definitions (taken from XFree86) + */ + +#define DEFAULT_MODEDB_INDEX 0 + +static const struct fb_videomode modedb[] __initdata = { + { + /* 640x400 @ 70 Hz, 31.5 kHz hsync */ + NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2, + 0, FB_VMODE_NONINTERLACED + }, { + /* 640x480 @ 60 Hz, 31.5 kHz hsync */ + NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2, + 0, FB_VMODE_NONINTERLACED + }, { + /* 800x600 @ 56 Hz, 35.15 kHz hsync */ + NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */ + NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8, + 0, FB_VMODE_INTERLACED + }, { + /* 640x400 @ 85 Hz, 37.86 kHz hsync */ + NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 640x480 @ 72 Hz, 36.5 kHz hsync */ + NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 640x480 @ 75 Hz, 37.50 kHz hsync */ + NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 800x600 @ 60 Hz, 37.8 kHz hsync */ + NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 640x480 @ 85 Hz, 43.27 kHz hsync */ + NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */ + NULL, 69, 1152, 864, 15384, 96, 16, 110, 1, 216, 10, + 0, FB_VMODE_INTERLACED + }, { + /* 800x600 @ 72 Hz, 48.0 kHz hsync */ + NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1024x768 @ 60 Hz, 48.4 kHz hsync */ + NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6, + 0, FB_VMODE_NONINTERLACED + }, { + /* 640x480 @ 100 Hz, 53.01 kHz hsync */ + NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1152x864 @ 60 Hz, 53.5 kHz hsync */ + NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8, + 0, FB_VMODE_NONINTERLACED + }, { + /* 800x600 @ 85 Hz, 55.84 kHz hsync */ + NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1024x768 @ 70 Hz, 56.5 kHz hsync */ + NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */ + NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12, + 0, FB_VMODE_INTERLACED + }, { + /* 800x600 @ 100 Hz, 64.02 kHz hsync */ + NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1024x768 @ 76 Hz, 62.5 kHz hsync */ + NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1152x864 @ 70 Hz, 62.4 kHz hsync */ + NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */ + NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1024x768 @ 85 Hz, 70.24 kHz hsync */ + NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1152x864 @ 78 Hz, 70.8 kHz hsync */ + NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */ + NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1600x1200 @ 60Hz, 75.00 kHz hsync */ + NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1152x864 @ 84 Hz, 76.0 kHz hsync */ + NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */ + NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1024x768 @ 100Hz, 80.21 kHz hsync */ + NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */ + NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */ + NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1152x864 @ 100 Hz, 89.62 kHz hsync */ + NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */ + NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */ + NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */ + NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */ + NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15, + 0, FB_VMODE_NONINTERLACED + }, { + /* 1800x1440 @ 64Hz, 96.15 kHz hsync */ + NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1800x1440 @ 70Hz, 104.52 kHz hsync */ + NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 512x384 @ 78 Hz, 31.50 kHz hsync */ + NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 512x384 @ 85 Hz, 34.38 kHz hsync */ + NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3, + 0, FB_VMODE_NONINTERLACED + }, { + /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */ + NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1, + 0, FB_VMODE_DOUBLE + }, { + /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */ + NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1, + 0, FB_VMODE_DOUBLE + }, { + /* 320x240 @ 72 Hz, 36.5 kHz hsync */ + NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2, + 0, FB_VMODE_DOUBLE + }, { + /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */ + NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1, + 0, FB_VMODE_DOUBLE + }, { + /* 400x300 @ 60 Hz, 37.8 kHz hsync */ + NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2, + 0, FB_VMODE_DOUBLE + }, { + /* 400x300 @ 72 Hz, 48.0 kHz hsync */ + NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3, + 0, FB_VMODE_DOUBLE + }, { + /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */ + NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1, + 0, FB_VMODE_DOUBLE + }, { + /* 480x300 @ 60 Hz, 37.8 kHz hsync */ + NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2, + 0, FB_VMODE_DOUBLE + }, { + /* 480x300 @ 63 Hz, 39.6 kHz hsync */ + NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2, + 0, FB_VMODE_DOUBLE + }, { + /* 480x300 @ 72 Hz, 48.0 kHz hsync */ + NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3, + 0, FB_VMODE_DOUBLE + }, +}; + + +static int __init my_atoi(const char *name) +{ + int val = 0; + + for (;; name++) { + switch (*name) { + case '0'...'9': + val = 10*val+(*name-'0'); + break; + default: + return val; + } + } +} + +static int __init PROC_CONSOLE(const struct fb_info *info) +{ + int fgc; + + if (info->display_fg != NULL) + fgc = info->display_fg->vc_num; + else + return -1; + + if (!current->tty) + return fgc; + + if (current->tty->driver.type != TTY_DRIVER_TYPE_CONSOLE) + /* XXX Should report error here? */ + return fgc; + + if (MINOR(current->tty->device) < 1) + return fgc; + + return MINOR(current->tty->device) - 1; +} + +static int __init try_mode(struct fb_var_screeninfo *var, struct fb_info *info, + const struct fb_videomode *mode, unsigned int bpp) +{ + int err; + + DPRINTK("Trying mode %s %dx%d-%d@%d\n", mode->name ? mode->name : "noname", + mode->xres, mode->yres, bpp, mode->refresh); + var->xres = mode->xres; + var->yres = mode->yres; + var->xres_virtual = mode->xres; + var->yres_virtual = mode->yres; + var->xoffset = 0; + var->yoffset = 0; + var->bits_per_pixel = bpp; + var->activate |= FB_ACTIVATE_TEST; + var->pixclock = mode->pixclock; + var->left_margin = mode->left_margin; + var->right_margin = mode->right_margin; + var->upper_margin = mode->upper_margin; + var->lower_margin = mode->lower_margin; + var->hsync_len = mode->hsync_len; + var->vsync_len = mode->vsync_len; + var->sync = mode->sync; + var->vmode = mode->vmode; + err = info->fbops->fb_set_var(var, PROC_CONSOLE(info), info); + var->activate &= ~FB_ACTIVATE_TEST; + return !err; +} + + + /* + * + * Find a suitable video mode + * + * Valid mode specifiers (mode_option): + * + * x[-][@] + * [-][@] + * + * with , , and decimal numbers and a + * string + * + * The passed struct fb_var_screeninfo is _not_ cleared! This allows you + * to supply values for e.g. the grayscale and accel_flags fields. + */ + +int __init fb_find_mode(struct fb_var_screeninfo *var, + struct fb_info *info, const char *mode_option, + const struct fb_videomode *db, unsigned int dbsize, + const struct fb_videomode *default_mode, + unsigned int default_bpp) +{ + int i, j; + + /* Set up defaults */ + if (!db) { + db = modedb; + dbsize = sizeof(modedb)/sizeof(*modedb); + } + if (!default_mode) + default_mode = &modedb[DEFAULT_MODEDB_INDEX]; + if (!default_bpp) + default_bpp = 8; + + /* Did the user specify a video mode? */ + if (mode_option || (mode_option = global_mode_option)) { + const char *name = mode_option; + unsigned int namelen = strlen(name); + int res_specified = 0, bpp_specified = 0, refresh_specified = 0; + unsigned int xres = 0, yres = 0, bpp = default_bpp, refresh = 0; + int yres_specified = 0; + + for (i = namelen-1; i >= 0; i--) { + switch (name[i]) { + case '@': + namelen = i; + if (!refresh_specified && !bpp_specified && + !yres_specified) { + refresh = my_atoi(&name[i+1]); + refresh_specified = 1; + } else + goto done; + break; + case '-': + namelen = i; + if (!bpp_specified && !yres_specified) { + bpp = my_atoi(&name[i+1]); + bpp_specified = 1; + } else + goto done; + break; + case 'x': + if (!yres_specified) { + yres = my_atoi(&name[i+1]); + yres_specified = 1; + } else + goto done; + break; + case '0'...'9': + break; + default: + goto done; + } + } + if (i < 0 && yres_specified) { + xres = my_atoi(name); + res_specified = 1; + } +done: + for (i = refresh_specified; i >= 0; i--) { + DPRINTK("Trying specified video mode%s\n", + i ? "" : " (ignoring refresh rate)"); + for (j = 0; j < dbsize; j++) + if ((name_matches(db[j], name, namelen) || + (res_specified && res_matches(db[j], xres, yres))) && + (!i || db[j].refresh == refresh) && + try_mode(var, info, &db[j], bpp)) + return 2-i; + } + } + + DPRINTK("Trying default video mode\n"); + if (try_mode(var, info, default_mode, default_bpp)) + return 3; + + DPRINTK("Trying all modes\n"); + for (i = 0; i < dbsize; i++) + if (try_mode(var, info, &db[i], default_bpp)) + return 4; + + DPRINTK("No valid mode found\n"); + return 0; +} diff --git a/include/linux/ioport.h b/include/linux/ioport.h index b22c43a0b523..555ebdf1dda2 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -8,19 +8,6 @@ #ifndef _LINUX_IOPORT_H #define _LINUX_IOPORT_H -#define DEVICE_IO_NOTSET (~0) -#define DEVICE_IO_AUTO ((~0)-1) - -#define DEVICE_IO_FLAG_WRITEABLE (1<<0) -#define DEVICE_IO_FLAG_CACHEABLE (1<<1) -#define DEVICE_IO_FLAG_RANGELENGTH (1<<2) -#define DEVICE_IO_FLAG_SHADOWABLE (1<<4) -#define DEVICE_IO_FLAG_EXPANSIONROM (1<<5) - -#define DEVICE_IO_TYPE_8BIT 0 -#define DEVICE_IO_TYPE_16BIT 1 -#define DEVICE_IO_TYPE_8AND16BIT 2 - /* * Resources are tree-like, allowing * nesting etc.. @@ -29,22 +16,29 @@ struct resource { const char *name; unsigned long start, end; unsigned long flags; - unsigned char bits; /* decoded bits */ - unsigned char fixed; /* fixed range */ - unsigned short hw_flags; /* hardware flags */ - unsigned short type; /* region type */ struct resource *parent, *sibling, *child; }; /* - * PCI-like IO resources have these defined flags. - * The low four bits come directly from the PCI specs, - * the rest are extended sw flags.. + * IO resources have these defined flags. */ -#define IORESOURCE_IOPORT 0x01 /* 0 - memory mapped, 1 - IO ports */ -#define IORESOURCE_MEMTYPE_MASK 0x06 /* PCI-specific mapping info */ -#define IORESOURCE_PREFETCH 0x08 /* No side effects */ -#define IORESOURCE_BUSY 0x10 /* Driver uses this resource */ +#define IORESOURCE_BITS 0x000000ff /* Bus-specific bits */ + +#define IORESOURCE_IO 0x00000100 /* Resource type */ +#define IORESOURCE_MEM 0x00000200 +#define IORESOURCE_IRQ 0x00000400 +#define IORESOURCE_DMA 0x00000800 + +#define IORESOURCE_PREFETCH 0x00001000 /* No side effects */ +#define IORESOURCE_READONLY 0x00002000 +#define IORESOURCE_CACHEABLE 0x00004000 +#define IORESOURCE_RANGELENGTH 0x00008000 +#define IORESOURCE_SHADOWABLE 0x00010000 + +#define IORESOURCE_UNSET 0x00020000 +#define IORESOURCE_AUTO 0x00040000 + +#define IORESOURCE_BUSY 0x80000000 /* Driver has marked this resource busy */ /* PC/ISA/whatever - the normal PC address spaces: IO and memory */ extern struct resource ioport_resource; diff --git a/include/linux/isapnp.h b/include/linux/isapnp.h index 9aab523090a6..d7b9e276c461 100644 --- a/include/linux/isapnp.h +++ b/include/linux/isapnp.h @@ -24,6 +24,19 @@ #include +#define ISAPNP_NOTSET (~0) +#define ISAPNP_AUTO ((~0)-1) + +#define ISAPNP_FLAG_WRITEABLE (1<<0) +#define ISAPNP_FLAG_CACHEABLE (1<<1) +#define ISAPNP_FLAG_RANGELENGTH (1<<2) +#define ISAPNP_FLAG_SHADOWABLE (1<<4) +#define ISAPNP_FLAG_EXPANSIONROM (1<<5) + +#define ISAPNP_TYPE_8BIT 0 +#define ISAPNP_TYPE_16BIT 1 +#define ISAPNP_TYPE_8AND16BIT 2 + /* * Configuration registers (TODO: change by specification) */ diff --git a/include/linux/pci.h b/include/linux/pci.h index e9111e6bd21b..624b7d053320 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1209,6 +1209,7 @@ #include #define DEVICE_COUNT_COMPATIBLE 4 +#define DEVICE_COUNT_IRQ 2 #define DEVICE_COUNT_DMA 2 #define DEVICE_COUNT_RESOURCE 12 @@ -1276,19 +1277,15 @@ struct pci_dev { * necessary. The field must not be 0 unless the device * cannot generate interrupts at all. */ - unsigned int irq; /* irq generated by this device */ - unsigned short irq_flags; /* irq type */ - unsigned int irq2; - unsigned short irq2_flags; - unsigned char dma[DEVICE_COUNT_DMA]; - unsigned char dma_type[DEVICE_COUNT_DMA]; - unsigned char dma_flags[DEVICE_COUNT_DMA]; - unsigned char dma_speed[DEVICE_COUNT_DMA]; - - /* Base registers for this device, can be adjusted by + unsigned int irq; + + /* + * Base registers for this device, can be adjusted by * pcibios_fixup() as necessary. */ struct resource resource[DEVICE_COUNT_RESOURCE]; + struct resource dma_resource[DEVICE_COUNT_DMA]; + struct resource irq_resource[DEVICE_COUNT_IRQ]; unsigned long rom_address; int (*prepare)(struct pci_dev *dev); -- 2.39.5