diff options
Diffstat (limited to 'drivers/parisc')
| -rw-r--r-- | drivers/parisc/Kconfig | 8 | ||||
| -rw-r--r-- | drivers/parisc/ccio-dma.c | 1 | ||||
| -rw-r--r-- | drivers/parisc/dino.c | 106 | ||||
| -rw-r--r-- | drivers/parisc/eisa_eeprom.c | 15 | ||||
| -rw-r--r-- | drivers/parisc/hppb.c | 6 | ||||
| -rw-r--r-- | drivers/parisc/iommu-helpers.h | 2 | ||||
| -rw-r--r-- | drivers/parisc/iosapic.c | 87 | ||||
| -rw-r--r-- | drivers/parisc/lba_pci.c | 193 | ||||
| -rw-r--r-- | drivers/parisc/led.c | 4 | ||||
| -rw-r--r-- | drivers/parisc/pdc_stable.c | 6 | ||||
| -rw-r--r-- | drivers/parisc/sba_iommu.c | 37 | ||||
| -rw-r--r-- | drivers/parisc/superio.c | 17 |
12 files changed, 288 insertions, 194 deletions
diff --git a/drivers/parisc/Kconfig b/drivers/parisc/Kconfig index 553a9905299..592de566e72 100644 --- a/drivers/parisc/Kconfig +++ b/drivers/parisc/Kconfig @@ -108,13 +108,6 @@ config IOMMU_HELPER depends on IOMMU_SBA || IOMMU_CCIO default y -#config PCI_EPIC -# bool "EPIC/SAGA PCI support" -# depends on PCI -# default y -# help -# Say Y here for V-class PCI, DMA/IOMMU, IRQ subsystem support. - source "drivers/pcmcia/Kconfig" source "drivers/pci/hotplug/Kconfig" @@ -135,6 +128,7 @@ config SUPERIO config CHASSIS_LCD_LED bool "Chassis LCD and LED support" default y + select VM_EVENT_COUNTERS help Say Y here if you want to enable support for the Heartbeat, Disk/Network activities LEDs on some PA-RISC machines, diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index 75a80e46b39..8b490d77054 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c @@ -44,6 +44,7 @@ #include <linux/seq_file.h> #include <linux/scatterlist.h> #include <linux/iommu-helper.h> +#include <linux/export.h> #include <asm/byteorder.h> #include <asm/cache.h> /* for L1_CACHE_BYTES */ diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index bcd5d54b7d4..9eae9834bcc 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c @@ -55,7 +55,6 @@ #include <asm/pdc.h> #include <asm/page.h> -#include <asm/system.h> #include <asm/io.h> #include <asm/hardware.h> @@ -175,7 +174,7 @@ static int dino_cfg_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) { struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->bridge)); - u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary; + u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start; u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3); void __iomem *base_addr = d->hba.base_addr; unsigned long flags; @@ -210,7 +209,7 @@ static int dino_cfg_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) { struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->bridge)); - u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary; + u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start; u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3); void __iomem *base_addr = d->hba.base_addr; unsigned long flags; @@ -431,7 +430,7 @@ static void dino_choose_irq(struct parisc_device *dev, void *ctrl) * Cirrus 6832 Cardbus reports wrong irq on RDI Tadpole PARISC Laptop (deller@gmx.de) * (the irqs are off-by-one, not sure yet if this is a cirrus, dino-hardware or dino-driver problem...) */ -static void __devinit quirk_cirrus_cardbus(struct pci_dev *dev) +static void quirk_cirrus_cardbus(struct pci_dev *dev) { u8 new_irq = dev->irq - 1; printk(KERN_INFO "PCI: Cirrus Cardbus IRQ fixup for %s, from %d to %d\n", @@ -478,14 +477,12 @@ dino_card_setup(struct pci_bus *bus, void __iomem *base_addr) if (ccio_allocate_resource(dino_dev->hba.dev, res, _8MB, F_EXTEND(0xf0000000UL) | _8MB, F_EXTEND(0xffffffffUL) &~ _8MB, _8MB) < 0) { - struct list_head *ln, *tmp_ln; + struct pci_dev *dev, *tmp; printk(KERN_ERR "Dino: cannot attach bus %s\n", dev_name(bus->bridge)); /* kill the bus, we can't do anything with it */ - list_for_each_safe(ln, tmp_ln, &bus->devices) { - struct pci_dev *dev = pci_dev_b(ln); - + list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { list_del(&dev->bus_list); } @@ -550,31 +547,16 @@ dino_card_fixup(struct pci_dev *dev) static void __init dino_fixup_bus(struct pci_bus *bus) { - struct list_head *ln; struct pci_dev *dev; struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge)); - int port_base = HBA_PORT_BASE(dino_dev->hba.hba_num); DBG(KERN_WARNING "%s(0x%p) bus %d platform_data 0x%p\n", - __func__, bus, bus->secondary, + __func__, bus, bus->busn_res.start, bus->bridge->platform_data); /* Firmware doesn't set up card-mode dino, so we have to */ if (is_card_dino(&dino_dev->hba.dev->id)) { dino_card_setup(bus, dino_dev->hba.base_addr); - } else if(bus->parent == NULL) { - /* must have a dino above it, reparent the resources - * into the dino window */ - int i; - struct resource *res = &dino_dev->hba.lmmio_space; - - bus->resource[0] = &(dino_dev->hba.io_space); - for(i = 0; i < DINO_MAX_LMMIO_RESOURCES; i++) { - if(res[i].flags == 0) - break; - bus->resource[i+1] = &res[i]; - } - } else if (bus->parent) { int i; @@ -598,23 +580,18 @@ dino_fixup_bus(struct pci_bus *bus) } - DBG("DEBUG %s assigning %d [0x%lx,0x%lx]\n", + DBG("DEBUG %s assigning %d [%pR]\n", dev_name(&bus->self->dev), i, - bus->self->resource[i].start, - bus->self->resource[i].end); + &bus->self->resource[i]); WARN_ON(pci_assign_resource(bus->self, i)); - DBG("DEBUG %s after assign %d [0x%lx,0x%lx]\n", + DBG("DEBUG %s after assign %d [%pR]\n", dev_name(&bus->self->dev), i, - bus->self->resource[i].start, - bus->self->resource[i].end); + &bus->self->resource[i]); } } - list_for_each(ln, &bus->devices) { - int i; - - dev = pci_dev_b(ln); + list_for_each_entry(dev, &bus->devices, bus_list) { if (is_card_dino(&dino_dev->hba.dev->id)) dino_card_fixup(dev); @@ -625,21 +602,6 @@ dino_fixup_bus(struct pci_bus *bus) if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) continue; - /* Adjust the I/O Port space addresses */ - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - struct resource *res = &dev->resource[i]; - if (res->flags & IORESOURCE_IO) { - res->start |= port_base; - res->end |= port_base; - } -#ifdef __LP64__ - /* Sign Extend MMIO addresses */ - else if (res->flags & IORESOURCE_MEM) { - res->start |= F_EXTEND(0UL); - res->end |= F_EXTEND(0UL); - } -#endif - } /* null out the ROM resource if there is one (we don't * care about an expansion rom on parisc, since it * usually contains (x86) bios code) */ @@ -808,8 +770,7 @@ dino_bridge_init(struct dino_device *dino_dev, const char *name) result = ccio_request_resource(dino_dev->hba.dev, &res[i]); if (result < 0) { printk(KERN_ERR "%s: failed to claim PCI Bus address " - "space %d (0x%lx-0x%lx)!\n", name, i, - (unsigned long)res[i].start, (unsigned long)res[i].end); + "space %d (%pR)!\n", name, i, &res[i]); return result; } } @@ -927,8 +888,10 @@ static int __init dino_probe(struct parisc_device *dev) const char *version = "unknown"; char *name; int is_cujo = 0; + LIST_HEAD(resources); struct pci_bus *bus; unsigned long hpa = dev->hpa.start; + int max; name = "Dino"; if (is_card_dino(&dev->id)) { @@ -1003,26 +966,45 @@ static int __init dino_probe(struct parisc_device *dev) dev->dev.platform_data = dino_dev; + pci_add_resource_offset(&resources, &dino_dev->hba.io_space, + HBA_PORT_BASE(dino_dev->hba.hba_num)); + if (dino_dev->hba.lmmio_space.flags) + pci_add_resource_offset(&resources, &dino_dev->hba.lmmio_space, + dino_dev->hba.lmmio_space_offset); + if (dino_dev->hba.elmmio_space.flags) + pci_add_resource_offset(&resources, &dino_dev->hba.elmmio_space, + dino_dev->hba.lmmio_space_offset); + if (dino_dev->hba.gmmio_space.flags) + pci_add_resource(&resources, &dino_dev->hba.gmmio_space); + + dino_dev->hba.bus_num.start = dino_current_bus; + dino_dev->hba.bus_num.end = 255; + dino_dev->hba.bus_num.flags = IORESOURCE_BUS; + pci_add_resource(&resources, &dino_dev->hba.bus_num); /* ** It's not used to avoid chicken/egg problems ** with configuration accessor functions. */ - dino_dev->hba.hba_bus = bus = pci_scan_bus_parented(&dev->dev, - dino_current_bus, &dino_cfg_ops, NULL); - - if(bus) { - /* This code *depends* on scanning being single threaded - * if it isn't, this global bus number count will fail - */ - dino_current_bus = bus->subordinate + 1; - pci_bus_assign_resources(bus); - pci_bus_add_devices(bus); - } else { + dino_dev->hba.hba_bus = bus = pci_create_root_bus(&dev->dev, + dino_current_bus, &dino_cfg_ops, NULL, &resources); + if (!bus) { printk(KERN_ERR "ERROR: failed to scan PCI bus on %s (duplicate bus number %d?)\n", dev_name(&dev->dev), dino_current_bus); + pci_free_resource_list(&resources); /* increment the bus number in case of duplicates */ dino_current_bus++; + return 0; } + + max = pci_scan_child_bus(bus); + pci_bus_update_busn_res_end(bus, max); + + /* This code *depends* on scanning being single threaded + * if it isn't, this global bus number count will fail + */ + dino_current_bus = max + 1; + pci_bus_assign_resources(bus); + pci_bus_add_devices(bus); return 0; } diff --git a/drivers/parisc/eisa_eeprom.c b/drivers/parisc/eisa_eeprom.c index af212c6a615..783906fe659 100644 --- a/drivers/parisc/eisa_eeprom.c +++ b/drivers/parisc/eisa_eeprom.c @@ -31,20 +31,9 @@ #define EISA_EEPROM_MINOR 241 -static loff_t eisa_eeprom_llseek(struct file *file, loff_t offset, int origin ) +static loff_t eisa_eeprom_llseek(struct file *file, loff_t offset, int origin) { - switch (origin) { - case 0: - /* nothing to do */ - break; - case 1: - offset += file->f_pos; - break; - case 2: - offset += HPEE_MAX_LENGTH; - break; - } - return (offset >= 0 && offset < HPEE_MAX_LENGTH) ? (file->f_pos = offset) : -EINVAL; + return fixed_size_llseek(file, offset, origin, HPEE_MAX_LENGTH); } static ssize_t eisa_eeprom_read(struct file * file, diff --git a/drivers/parisc/hppb.c b/drivers/parisc/hppb.c index 815db175d42..898208e4f30 100644 --- a/drivers/parisc/hppb.c +++ b/drivers/parisc/hppb.c @@ -74,10 +74,8 @@ static int hppb_probe(struct parisc_device *dev) status = ccio_request_resource(dev, &card->mmio_region); if(status < 0) { - printk(KERN_ERR "%s: failed to claim HP-PB " - "bus space (0x%08llx, 0x%08llx)\n", - __FILE__, (unsigned long long) card->mmio_region.start, - (unsigned long long) card->mmio_region.end); + printk(KERN_ERR "%s: failed to claim HP-PB bus space (%pR)\n", + __FILE__, &card->mmio_region); } return 0; diff --git a/drivers/parisc/iommu-helpers.h b/drivers/parisc/iommu-helpers.h index a9c46cc2db3..8c33491b21f 100644 --- a/drivers/parisc/iommu-helpers.h +++ b/drivers/parisc/iommu-helpers.h @@ -1,3 +1,5 @@ +#include <linux/prefetch.h> + /** * iommu_fill_pdir - Insert coalesced scatter/gather chunks into the I/O Pdir. * @ioc: The I/O Controller. diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 95930d01623..9ee04b4b68b 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c @@ -140,14 +140,13 @@ #include <asm/pdc.h> #include <asm/pdcpat.h> #include <asm/page.h> -#include <asm/system.h> #include <asm/io.h> /* read/write functions */ #ifdef CONFIG_SUPERIO #include <asm/superio.h> #endif #include <asm/ropes.h> -#include "./iosapic_private.h" +#include "iosapic_private.h" #define MODULE_NAME "iosapic" @@ -533,7 +532,7 @@ iosapic_xlate_pin(struct iosapic_info *isi, struct pci_dev *pcidev) intr_slot = PCI_SLOT(pcidev->devfn); } DBG_IRT("iosapic_xlate_pin: bus %d slot %d pin %d\n", - pcidev->bus->secondary, intr_slot, intr_pin); + pcidev->bus->busn_res.start, intr_slot, intr_pin); return irt_find_irqline(isi, intr_slot, intr_pin); } @@ -812,6 +811,86 @@ int iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev) return pcidev->irq; } +static struct iosapic_info *iosapic_list; + +#ifdef CONFIG_64BIT +int iosapic_serial_irq(struct parisc_device *dev) +{ + struct iosapic_info *isi; + struct irt_entry *irte; + struct vector_info *vi; + int cnt; + int intin; + + intin = (dev->mod_info >> 24) & 15; + + /* lookup IRT entry for isi/slot/pin set */ + for (cnt = 0; cnt < irt_num_entry; cnt++) { + irte = &irt_cell[cnt]; + if (COMPARE_IRTE_ADDR(irte, dev->mod0) && + irte->dest_iosapic_intin == intin) + break; + } + if (cnt >= irt_num_entry) + return 0; /* no irq found, force polling */ + + DBG_IRT("iosapic_serial_irq(): irte %p %x %x %x %x %x %x %x %x\n", + irte, + irte->entry_type, + irte->entry_length, + irte->polarity_trigger, + irte->src_bus_irq_devno, + irte->src_bus_id, + irte->src_seg_id, + irte->dest_iosapic_intin, + (u32) irte->dest_iosapic_addr); + + /* search for iosapic */ + for (isi = iosapic_list; isi; isi = isi->isi_next) + if (isi->isi_hpa == dev->mod0) + break; + if (!isi) + return 0; /* no iosapic found, force polling */ + + /* get vector info for this input line */ + vi = isi->isi_vector + intin; + DBG_IRT("iosapic_serial_irq: line %d vi 0x%p\n", iosapic_intin, vi); + + /* If this IRQ line has already been setup, skip it */ + if (vi->irte) + goto out; + + vi->irte = irte; + + /* + * Allocate processor IRQ + * + * XXX/FIXME The txn_alloc_irq() code and related code should be + * moved to enable_irq(). That way we only allocate processor IRQ + * bits for devices that actually have drivers claiming them. + * Right now we assign an IRQ to every PCI device present, + * regardless of whether it's used or not. + */ + vi->txn_irq = txn_alloc_irq(8); + + if (vi->txn_irq < 0) + panic("I/O sapic: couldn't get TXN IRQ\n"); + + /* enable_irq() will use txn_* to program IRdT */ + vi->txn_addr = txn_alloc_addr(vi->txn_irq); + vi->txn_data = txn_alloc_data(vi->txn_irq); + + vi->eoi_addr = isi->addr + IOSAPIC_REG_EOI; + vi->eoi_data = cpu_to_le32(vi->txn_data); + + cpu_claim_irq(vi->txn_irq, &iosapic_interrupt_type, vi); + + out: + + return vi->txn_irq; +} +#endif + /* ** squirrel away the I/O Sapic Version @@ -878,6 +957,8 @@ void *iosapic_register(unsigned long hpa) vip->irqline = (unsigned char) cnt; vip->iosapic = isi; } + isi->isi_next = iosapic_list; + iosapic_list = isi; return isi; } diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index 3aeb3279c92..37e71ff6408 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c @@ -34,7 +34,7 @@ #include <linux/types.h> #include <linux/kernel.h> #include <linux/spinlock.h> -#include <linux/init.h> /* for __init and __devinit */ +#include <linux/init.h> /* for __init */ #include <linux/pci.h> #include <linux/ioport.h> #include <linux/slab.h> @@ -43,7 +43,6 @@ #include <asm/pdc.h> #include <asm/pdcpat.h> #include <asm/page.h> -#include <asm/system.h> #include <asm/ropes.h> #include <asm/hardware.h> /* for register_parisc_driver() stuff */ @@ -190,8 +189,8 @@ lba_dump_res(struct resource *r, int d) static int lba_device_present(u8 bus, u8 dfn, struct lba_device *d) { - u8 first_bus = d->hba.hba_bus->secondary; - u8 last_sub_bus = d->hba.hba_bus->subordinate; + u8 first_bus = d->hba.hba_bus->busn_res.start; + u8 last_sub_bus = d->hba.hba_bus->busn_res.end; if ((bus < first_bus) || (bus > last_sub_bus) || @@ -365,7 +364,7 @@ lba_rd_cfg(struct lba_device *d, u32 tok, u8 reg, u32 size) static int elroy_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 *data) { struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge)); - u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary; + u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start; u32 tok = LBA_CFG_TOK(local_bus, devfn); void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA; @@ -381,7 +380,7 @@ static int elroy_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int return 0; } - if (LBA_SKIP_PROBE(d) && !lba_device_present(bus->secondary, devfn, d)) { + if (LBA_SKIP_PROBE(d) && !lba_device_present(bus->busn_res.start, devfn, d)) { DBG_CFG("%s(%x+%2x) -> -1 (b)\n", __func__, tok, pos); /* either don't want to look or know device isn't present. */ *data = ~0U; @@ -432,7 +431,7 @@ lba_wr_cfg(struct lba_device *d, u32 tok, u8 reg, u32 data, u32 size) static int elroy_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 data) { struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge)); - u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary; + u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start; u32 tok = LBA_CFG_TOK(local_bus,devfn); if ((pos > 255) || (devfn > 255)) @@ -445,7 +444,7 @@ static int elroy_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, int return 0; } - if (LBA_SKIP_PROBE(d) && (!lba_device_present(bus->secondary, devfn, d))) { + if (LBA_SKIP_PROBE(d) && (!lba_device_present(bus->busn_res.start, devfn, d))) { DBG_CFG("%s(%x+%2x) = 0x%x (b)\n", __func__, tok, pos,data); return 1; /* New Workaround */ } @@ -482,7 +481,7 @@ static struct pci_ops elroy_cfg_ops = { static int mercury_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 *data) { struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge)); - u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary; + u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start; u32 tok = LBA_CFG_TOK(local_bus, devfn); void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA; @@ -515,7 +514,7 @@ static int mercury_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, i { struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge)); void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA; - u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary; + u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start; u32 tok = LBA_CFG_TOK(local_bus,devfn); if ((pos > 255) || (devfn > 255)) @@ -614,6 +613,54 @@ truncate_pat_collision(struct resource *root, struct resource *new) return 0; /* truncation successful */ } +/* + * extend_lmmio_len: extend lmmio range to maximum length + * + * This is needed at least on C8000 systems to get the ATI FireGL card + * working. On other systems we will currently not extend the lmmio space. + */ +static unsigned long +extend_lmmio_len(unsigned long start, unsigned long end, unsigned long lba_len) +{ + struct resource *tmp; + + pr_debug("LMMIO mismatch: PAT length = 0x%lx, MASK register = 0x%lx\n", + end - start, lba_len); + + lba_len = min(lba_len+1, 256UL*1024*1024); /* limit to 256 MB */ + + pr_debug("LBA: lmmio_space [0x%lx-0x%lx] - original\n", start, end); + + if (boot_cpu_data.cpu_type < mako) { + pr_info("LBA: Not a C8000 system - not extending LMMIO range.\n"); + return end; + } + + end += lba_len; + if (end < start) /* fix overflow */ + end = -1ULL; + + pr_debug("LBA: lmmio_space [0x%lx-0x%lx] - current\n", start, end); + + /* first overlap */ + for (tmp = iomem_resource.child; tmp; tmp = tmp->sibling) { + pr_debug("LBA: testing %pR\n", tmp); + if (tmp->start == start) + continue; /* ignore ourself */ + if (tmp->end < start) + continue; + if (tmp->start > end) + continue; + if (end >= tmp->start) + end = tmp->start - 1; + } + + pr_info("LBA: lmmio_space [0x%lx-0x%lx] - new\n", start, end); + + /* return new end */ + return end; +} + #else #define truncate_pat_collision(r,n) (0) #endif @@ -630,15 +677,14 @@ truncate_pat_collision(struct resource *root, struct resource *new) static void lba_fixup_bus(struct pci_bus *bus) { - struct list_head *ln; + struct pci_dev *dev; #ifdef FBB_SUPPORT u16 status; #endif struct lba_device *ldev = LBA_DEV(parisc_walk_tree(bus->bridge)); - int lba_portbase = HBA_PORT_BASE(ldev->hba.hba_num); DBG("lba_fixup_bus(0x%p) bus %d platform_data 0x%p\n", - bus, bus->secondary, bus->bridge->platform_data); + bus, (int)bus->busn_res.start, bus->bridge->platform_data); /* ** Properly Setup MMIO resources for this bus. @@ -653,7 +699,7 @@ lba_fixup_bus(struct pci_bus *bus) } } else { /* Host-PCI Bridge */ - int err, i; + int err; DBG("lba_fixup_bus() %s [%lx/%lx]/%lx\n", ldev->hba.io_space.name, @@ -669,11 +715,8 @@ lba_fixup_bus(struct pci_bus *bus) lba_dump_res(&ioport_resource, 2); BUG(); } - /* advertize Host bridge resources to PCI bus */ - bus->resource[0] = &(ldev->hba.io_space); - i = 1; - if (ldev->hba.elmmio_space.start) { + if (ldev->hba.elmmio_space.flags) { err = request_resource(&iomem_resource, &(ldev->hba.elmmio_space)); if (err < 0) { @@ -685,35 +728,17 @@ lba_fixup_bus(struct pci_bus *bus) /* lba_dump_res(&iomem_resource, 2); */ /* BUG(); */ - } else - bus->resource[i++] = &(ldev->hba.elmmio_space); + } } - - /* Overlaps with elmmio can (and should) fail here. - * We will prune (or ignore) the distributed range. - * - * FIXME: SBA code should register all elmmio ranges first. - * that would take care of elmmio ranges routed - * to a different rope (already discovered) from - * getting registered *after* LBA code has already - * registered it's distributed lmmio range. - */ - if (truncate_pat_collision(&iomem_resource, - &(ldev->hba.lmmio_space))) { - - printk(KERN_WARNING "LBA: lmmio_space [%lx/%lx] duplicate!\n", - (long)ldev->hba.lmmio_space.start, - (long)ldev->hba.lmmio_space.end); - } else { + if (ldev->hba.lmmio_space.flags) { err = request_resource(&iomem_resource, &(ldev->hba.lmmio_space)); if (err < 0) { printk(KERN_ERR "FAILED: lba_fixup_bus() request for " "lmmio_space [%lx/%lx]\n", (long)ldev->hba.lmmio_space.start, (long)ldev->hba.lmmio_space.end); - } else - bus->resource[i++] = &(ldev->hba.lmmio_space); + } } #ifdef CONFIG_64BIT @@ -728,15 +753,13 @@ lba_fixup_bus(struct pci_bus *bus) lba_dump_res(&iomem_resource, 2); BUG(); } - bus->resource[i++] = &(ldev->hba.gmmio_space); } #endif } - list_for_each(ln, &bus->devices) { + list_for_each_entry(dev, &bus->devices, bus_list) { int i; - struct pci_dev *dev = pci_dev_b(ln); DBG("lba_fixup_bus() %s\n", pci_name(dev)); @@ -748,27 +771,6 @@ lba_fixup_bus(struct pci_bus *bus) if (!res->start) continue; - if (res->flags & IORESOURCE_IO) { - DBG("lba_fixup_bus() I/O Ports [%lx/%lx] -> ", - res->start, res->end); - res->start |= lba_portbase; - res->end |= lba_portbase; - DBG("[%lx/%lx]\n", res->start, res->end); - } else if (res->flags & IORESOURCE_MEM) { - /* - ** Convert PCI (IO_VIEW) addresses to - ** processor (PA_VIEW) addresses - */ - DBG("lba_fixup_bus() MMIO [%lx/%lx] -> ", - res->start, res->end); - res->start = PCI_HOST_ADDR(HBA_DATA(ldev), res->start); - res->end = PCI_HOST_ADDR(HBA_DATA(ldev), res->end); - DBG("[%lx/%lx]\n", res->start, res->end); - } else { - DBG("lba_fixup_bus() WTF? 0x%lx [%lx/%lx] XXX", - res->flags, res->start, res->end); - } - /* ** FIXME: this will result in whinging for devices ** that share expansion ROMs (think quad tulip), but @@ -815,7 +817,7 @@ lba_fixup_bus(struct pci_bus *bus) } /* Lastly enable FBB/PERR/SERR on all devices too */ - list_for_each(ln, &bus->devices) { + list_for_each_entry(dev, &bus->devices, bus_list) { (void) pci_read_config_word(dev, PCI_COMMAND, &status); status |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR | fbb_enable; (void) pci_write_config_word(dev, PCI_COMMAND, status); @@ -1034,11 +1036,20 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev) case PAT_PBNUM: lba_dev->hba.bus_num.start = p->start; lba_dev->hba.bus_num.end = p->end; + lba_dev->hba.bus_num.flags = IORESOURCE_BUS; break; case PAT_LMMIO: /* used to fix up pre-initialized MEM BARs */ - if (!lba_dev->hba.lmmio_space.start) { + if (!lba_dev->hba.lmmio_space.flags) { + unsigned long lba_len; + + lba_len = ~READ_REG32(lba_dev->hba.base_addr + + LBA_LMMIO_MASK); + if ((p->end - p->start) != lba_len) + p->end = extend_lmmio_len(p->start, + p->end, lba_len); + sprintf(lba_dev->hba.lmmio_name, "PCI%02x LMMIO", (int)lba_dev->hba.bus_num.start); @@ -1046,7 +1057,7 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev) io->start; r = &lba_dev->hba.lmmio_space; r->name = lba_dev->hba.lmmio_name; - } else if (!lba_dev->hba.elmmio_space.start) { + } else if (!lba_dev->hba.elmmio_space.flags) { sprintf(lba_dev->hba.elmmio_name, "PCI%02x ELMMIO", (int)lba_dev->hba.bus_num.start); @@ -1141,6 +1152,7 @@ lba_legacy_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev) r->name = "LBA PCI Busses"; r->start = lba_num & 0xff; r->end = (lba_num>>8) & 0xff; + r->flags = IORESOURCE_BUS; /* Set up local PCI Bus resources - we don't need them for ** Legacy boxes but it's nice to see in /proc/iomem. @@ -1404,12 +1416,14 @@ static int __init lba_driver_probe(struct parisc_device *dev) { struct lba_device *lba_dev; + LIST_HEAD(resources); struct pci_bus *lba_bus; struct pci_ops *cfg_ops; u32 func_class; void *tmp_obj; char *version; void __iomem *addr = ioremap_nocache(dev->hpa.start, 4096); + int max; /* Read HW Rev First */ func_class = READ_REG32(addr + LBA_FCLASS); @@ -1518,10 +1532,46 @@ lba_driver_probe(struct parisc_device *dev) if (lba_dev->hba.bus_num.start < lba_next_bus) lba_dev->hba.bus_num.start = lba_next_bus; + /* Overlaps with elmmio can (and should) fail here. + * We will prune (or ignore) the distributed range. + * + * FIXME: SBA code should register all elmmio ranges first. + * that would take care of elmmio ranges routed + * to a different rope (already discovered) from + * getting registered *after* LBA code has already + * registered it's distributed lmmio range. + */ + if (truncate_pat_collision(&iomem_resource, + &(lba_dev->hba.lmmio_space))) { + printk(KERN_WARNING "LBA: lmmio_space [%lx/%lx] duplicate!\n", + (long)lba_dev->hba.lmmio_space.start, + (long)lba_dev->hba.lmmio_space.end); + lba_dev->hba.lmmio_space.flags = 0; + } + + pci_add_resource_offset(&resources, &lba_dev->hba.io_space, + HBA_PORT_BASE(lba_dev->hba.hba_num)); + if (lba_dev->hba.elmmio_space.flags) + pci_add_resource_offset(&resources, &lba_dev->hba.elmmio_space, + lba_dev->hba.lmmio_space_offset); + if (lba_dev->hba.lmmio_space.flags) + pci_add_resource_offset(&resources, &lba_dev->hba.lmmio_space, + lba_dev->hba.lmmio_space_offset); + if (lba_dev->hba.gmmio_space.flags) + pci_add_resource(&resources, &lba_dev->hba.gmmio_space); + + pci_add_resource(&resources, &lba_dev->hba.bus_num); + dev->dev.platform_data = lba_dev; lba_bus = lba_dev->hba.hba_bus = - pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start, - cfg_ops, NULL); + pci_create_root_bus(&dev->dev, lba_dev->hba.bus_num.start, + cfg_ops, NULL, &resources); + if (!lba_bus) { + pci_free_resource_list(&resources); + return 0; + } + + max = pci_scan_child_bus(lba_bus); /* This is in lieu of calling pci_assign_unassigned_resources() */ if (is_pdc_pat()) { @@ -1540,7 +1590,6 @@ lba_driver_probe(struct parisc_device *dev) lba_dump_res(&lba_dev->hba.lmmio_space, 2); #endif } - pci_enable_bridges(lba_bus); /* ** Once PCI register ops has walked the bus, access to config @@ -1551,10 +1600,8 @@ lba_driver_probe(struct parisc_device *dev) lba_dev->flags |= LBA_FLAG_SKIP_PROBE; } - if (lba_bus) { - lba_next_bus = lba_bus->subordinate + 1; - pci_bus_add_devices(lba_bus); - } + lba_next_bus = max + 1; + pci_bus_add_devices(lba_bus); /* Whew! Finally done! Tell services we got this one covered. */ return 0; diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c index f2f501e5b6a..b4824313199 100644 --- a/drivers/parisc/led.c +++ b/drivers/parisc/led.c @@ -172,14 +172,14 @@ static int led_proc_show(struct seq_file *m, void *v) static int led_proc_open(struct inode *inode, struct file *file) { - return single_open(file, led_proc_show, PDE(inode)->data); + return single_open(file, led_proc_show, PDE_DATA(inode)); } static ssize_t led_proc_write(struct file *file, const char *buf, size_t count, loff_t *pos) { - void *data = PDE(file->f_path.dentry->d_inode)->data; + void *data = PDE_DATA(file_inode(file)); char *cur, lbuf[32]; int d; diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c index 246a92f677e..0f54ab6260d 100644 --- a/drivers/parisc/pdc_stable.c +++ b/drivers/parisc/pdc_stable.c @@ -212,12 +212,10 @@ pdcspath_store(struct pdcspath_entry *entry) entry, devpath, entry->addr); /* addr, devpath and count must be word aligned */ - if (pdc_stable_write(entry->addr, devpath, sizeof(*devpath)) != PDC_OK) { - printk(KERN_ERR "%s: an error occurred when writing to PDC.\n" + if (pdc_stable_write(entry->addr, devpath, sizeof(*devpath)) != PDC_OK) + WARN(1, KERN_ERR "%s: an error occurred when writing to PDC.\n" "It is likely that the Stable Storage data has been corrupted.\n" "Please check it carefully upon next reboot.\n", __func__); - WARN_ON(1); - } /* kobject is already registered */ entry->ready = 2; diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index 57a6d19eba4..1ff1b67e8b2 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c @@ -39,10 +39,12 @@ #include <linux/proc_fs.h> #include <linux/seq_file.h> +#include <linux/module.h> #include <asm/ropes.h> #include <asm/mckinley.h> /* for proc_mckinley_root */ #include <asm/runway.h> /* for proc_runway_root */ +#include <asm/page.h> /* for PAGE0 */ #include <asm/pdc.h> /* for PDC_MODEL_* */ #include <asm/pdcpat.h> /* for is_pdc_pat() */ #include <asm/parisc-device.h> @@ -573,7 +575,7 @@ sba_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba, mtsp(sid,1); asm("lci 0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba)); - pa |= (ci >> 12) & 0xff; /* move CI (8 bits) into lowest byte */ + pa |= (ci >> PAGE_SHIFT) & 0xff; /* move CI (8 bits) into lowest byte */ pa |= SBA_PDIR_VALID_BIT; /* set "valid" bit */ *pdir_ptr = cpu_to_le64(pa); /* swap and store into I/O Pdir */ @@ -668,7 +670,7 @@ sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt) * @dev: instance of PCI owned by the driver that's asking * @mask: number of address bits this PCI device can handle * - * See Documentation/PCI/PCI-DMA-mapping.txt + * See Documentation/DMA-API-HOWTO.txt */ static int sba_dma_supported( struct device *dev, u64 mask) { @@ -680,7 +682,7 @@ static int sba_dma_supported( struct device *dev, u64 mask) return(0); } - /* Documentation/PCI/PCI-DMA-mapping.txt tells drivers to try 64-bit + /* Documentation/DMA-API-HOWTO.txt tells drivers to try 64-bit * first, then fall back to 32-bit if that fails. * We are just "encouraging" 32-bit DMA masks here since we can * never allow IOMMU bypass unless we add special support for ZX1. @@ -706,7 +708,7 @@ static int sba_dma_supported( struct device *dev, u64 mask) * @size: number of bytes to map in driver buffer. * @direction: R/W or both. * - * See Documentation/PCI/PCI-DMA-mapping.txt + * See Documentation/DMA-API-HOWTO.txt */ static dma_addr_t sba_map_single(struct device *dev, void *addr, size_t size, @@ -785,7 +787,7 @@ sba_map_single(struct device *dev, void *addr, size_t size, * @size: number of bytes mapped in driver buffer. * @direction: R/W or both. * - * See Documentation/PCI/PCI-DMA-mapping.txt + * See Documentation/DMA-API-HOWTO.txt */ static void sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size, @@ -861,7 +863,7 @@ sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size, * @size: number of bytes mapped in driver buffer. * @dma_handle: IOVA of new buffer. * - * See Documentation/PCI/PCI-DMA-mapping.txt + * See Documentation/DMA-API-HOWTO.txt */ static void *sba_alloc_consistent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t gfp) @@ -892,7 +894,7 @@ static void *sba_alloc_consistent(struct device *hwdev, size_t size, * @vaddr: virtual address IOVA of "consistent" buffer. * @dma_handler: IO virtual address of "consistent" buffer. * - * See Documentation/PCI/PCI-DMA-mapping.txt + * See Documentation/DMA-API-HOWTO.txt */ static void sba_free_consistent(struct device *hwdev, size_t size, void *vaddr, @@ -927,7 +929,7 @@ int dump_run_sg = 0; * @nents: number of entries in list * @direction: R/W or both. * - * See Documentation/PCI/PCI-DMA-mapping.txt + * See Documentation/DMA-API-HOWTO.txt */ static int sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, @@ -1011,7 +1013,7 @@ sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, * @nents: number of entries in list * @direction: R/W or both. * - * See Documentation/PCI/PCI-DMA-mapping.txt + * See Documentation/DMA-API-HOWTO.txt */ static void sba_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents, @@ -1374,7 +1376,7 @@ static void sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num) { u32 iova_space_size, iova_space_mask; - unsigned int pdir_size, iov_order; + unsigned int pdir_size, iov_order, tcnfg; /* ** Determine IOVA Space size from memory size. @@ -1466,8 +1468,19 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num) WRITE_REG(ioc->ibase | 1, ioc->ioc_hpa+IOC_IBASE); WRITE_REG(ioc->imask, ioc->ioc_hpa+IOC_IMASK); - /* Set I/O PDIR Page size to 4K */ - WRITE_REG(0, ioc->ioc_hpa+IOC_TCNFG); + /* Set I/O PDIR Page size to system page size */ + switch (PAGE_SHIFT) { + case 12: tcnfg = 0; break; /* 4K */ + case 13: tcnfg = 1; break; /* 8K */ + case 14: tcnfg = 2; break; /* 16K */ + case 16: tcnfg = 3; break; /* 64K */ + default: + panic(__FILE__ "Unsupported system page size %d", + 1 << PAGE_SHIFT); + break; + } + /* Set I/O PDIR Page size to PAGE_SIZE (4k/16k/...) */ + WRITE_REG(tcnfg, ioc->ioc_hpa+IOC_TCNFG); /* ** Clear I/O TLB of any possible entries. diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c index e3b76d409de..a042d065a0c 100644 --- a/drivers/parisc/superio.c +++ b/drivers/parisc/superio.c @@ -274,7 +274,7 @@ superio_init(struct pci_dev *pcidev) else printk(KERN_ERR PFX "USB regulator not initialized!\n"); - if (request_irq(pdev->irq, superio_interrupt, IRQF_DISABLED, + if (request_irq(pdev->irq, superio_interrupt, 0, SUPERIO, (void *)sio)) { printk(KERN_ERR PFX "could not get irq\n"); @@ -348,7 +348,7 @@ int superio_fixup_irq(struct pci_dev *pcidev) BUG(); return -1; } - printk("superio_fixup_irq(%s) ven 0x%x dev 0x%x from %p\n", + printk("superio_fixup_irq(%s) ven 0x%x dev 0x%x from %pf\n", pci_name(pcidev), pcidev->vendor, pcidev->device, __builtin_return_address(0)); @@ -494,15 +494,4 @@ static struct pci_driver superio_driver = { .probe = superio_probe, }; -static int __init superio_modinit(void) -{ - return pci_register_driver(&superio_driver); -} - -static void __exit superio_exit(void) -{ - pci_unregister_driver(&superio_driver); -} - -module_init(superio_modinit); -module_exit(superio_exit); +module_pci_driver(superio_driver); |
