diff options
Diffstat (limited to 'drivers/parisc/dino.c')
| -rw-r--r-- | drivers/parisc/dino.c | 129 | 
1 files changed, 55 insertions, 74 deletions
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index d9f51485bee..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; @@ -296,25 +295,25 @@ static struct pci_port_ops dino_port_ops = {  	.outl	= dino_out32  }; -static void dino_mask_irq(unsigned int irq) +static void dino_mask_irq(struct irq_data *d)  { -	struct dino_device *dino_dev = get_irq_chip_data(irq); -	int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); +	struct dino_device *dino_dev = irq_data_get_irq_chip_data(d); +	int local_irq = gsc_find_local_irq(d->irq, dino_dev->global_irq, DINO_LOCAL_IRQS); -	DBG(KERN_WARNING "%s(0x%p, %d)\n", __func__, dino_dev, irq); +	DBG(KERN_WARNING "%s(0x%p, %d)\n", __func__, dino_dev, d->irq);  	/* Clear the matching bit in the IMR register */  	dino_dev->imr &= ~(DINO_MASK_IRQ(local_irq));  	__raw_writel(dino_dev->imr, dino_dev->hba.base_addr+DINO_IMR);  } -static void dino_unmask_irq(unsigned int irq) +static void dino_unmask_irq(struct irq_data *d)  { -	struct dino_device *dino_dev = get_irq_chip_data(irq); -	int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); +	struct dino_device *dino_dev = irq_data_get_irq_chip_data(d); +	int local_irq = gsc_find_local_irq(d->irq, dino_dev->global_irq, DINO_LOCAL_IRQS);  	u32 tmp; -	DBG(KERN_WARNING "%s(0x%p, %d)\n", __func__, dino_dev, irq); +	DBG(KERN_WARNING "%s(0x%p, %d)\n", __func__, dino_dev, d->irq);  	/*  	** clear pending IRQ bits @@ -346,10 +345,9 @@ static void dino_unmask_irq(unsigned int irq)  }  static struct irq_chip dino_interrupt_type = { -	.name	= "GSC-PCI", -	.unmask	= dino_unmask_irq, -	.mask	= dino_mask_irq, -	.ack	= no_ack_irq, +	.name		= "GSC-PCI", +	.irq_unmask	= dino_unmask_irq, +	.irq_mask	= dino_mask_irq,  }; @@ -432,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", @@ -479,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);  		} @@ -551,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; @@ -599,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); @@ -626,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) */ @@ -809,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;  		}  	} @@ -928,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)) { @@ -1004,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;  }  | 
