diff options
Diffstat (limited to 'drivers/parisc/dino.c')
-rw-r--r-- | drivers/parisc/dino.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index 5ab75334c579..216d1d859326 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c | |||
@@ -83,7 +83,8 @@ | |||
83 | ** bus number for each dino. | 83 | ** bus number for each dino. |
84 | */ | 84 | */ |
85 | 85 | ||
86 | #define is_card_dino(id) ((id)->hw_type == HPHW_A_DMA) | 86 | #define is_card_dino(id) ((id)->hw_type == HPHW_A_DMA) |
87 | #define is_cujo(id) ((id)->hversion == 0x682) | ||
87 | 88 | ||
88 | #define DINO_IAR0 0x004 | 89 | #define DINO_IAR0 0x004 |
89 | #define DINO_IODC_ADDR 0x008 | 90 | #define DINO_IODC_ADDR 0x008 |
@@ -124,6 +125,7 @@ | |||
124 | 125 | ||
125 | #define DINO_IRQS 11 /* bits 0-10 are architected */ | 126 | #define DINO_IRQS 11 /* bits 0-10 are architected */ |
126 | #define DINO_IRR_MASK 0x5ff /* only 10 bits are implemented */ | 127 | #define DINO_IRR_MASK 0x5ff /* only 10 bits are implemented */ |
128 | #define DINO_LOCAL_IRQS (DINO_IRQS+1) | ||
127 | 129 | ||
128 | #define DINO_MASK_IRQ(x) (1<<(x)) | 130 | #define DINO_MASK_IRQ(x) (1<<(x)) |
129 | 131 | ||
@@ -146,7 +148,7 @@ struct dino_device | |||
146 | unsigned long txn_addr; /* EIR addr to generate interrupt */ | 148 | unsigned long txn_addr; /* EIR addr to generate interrupt */ |
147 | u32 txn_data; /* EIR data assign to each dino */ | 149 | u32 txn_data; /* EIR data assign to each dino */ |
148 | u32 imr; /* IRQ's which are enabled */ | 150 | u32 imr; /* IRQ's which are enabled */ |
149 | int global_irq[12]; /* map IMR bit to global irq */ | 151 | int global_irq[DINO_LOCAL_IRQS]; /* map IMR bit to global irq */ |
150 | #ifdef DINO_DEBUG | 152 | #ifdef DINO_DEBUG |
151 | unsigned int dino_irr0; /* save most recent IRQ line stat */ | 153 | unsigned int dino_irr0; /* save most recent IRQ line stat */ |
152 | #endif | 154 | #endif |
@@ -297,7 +299,7 @@ struct pci_port_ops dino_port_ops = { | |||
297 | static void dino_disable_irq(unsigned int irq) | 299 | static void dino_disable_irq(unsigned int irq) |
298 | { | 300 | { |
299 | struct dino_device *dino_dev = irq_desc[irq].handler_data; | 301 | struct dino_device *dino_dev = irq_desc[irq].handler_data; |
300 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, irq); | 302 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); |
301 | 303 | ||
302 | DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq); | 304 | DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq); |
303 | 305 | ||
@@ -309,7 +311,7 @@ static void dino_disable_irq(unsigned int irq) | |||
309 | static void dino_enable_irq(unsigned int irq) | 311 | static void dino_enable_irq(unsigned int irq) |
310 | { | 312 | { |
311 | struct dino_device *dino_dev = irq_desc[irq].handler_data; | 313 | struct dino_device *dino_dev = irq_desc[irq].handler_data; |
312 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, irq); | 314 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); |
313 | u32 tmp; | 315 | u32 tmp; |
314 | 316 | ||
315 | DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq); | 317 | DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq); |
@@ -435,6 +437,21 @@ static void dino_choose_irq(struct parisc_device *dev, void *ctrl) | |||
435 | dino_assign_irq(dino, irq, &dev->irq); | 437 | dino_assign_irq(dino, irq, &dev->irq); |
436 | } | 438 | } |
437 | 439 | ||
440 | |||
441 | /* | ||
442 | * Cirrus 6832 Cardbus reports wrong irq on RDI Tadpole PARISC Laptop (deller@gmx.de) | ||
443 | * (the irqs are off-by-one, not sure yet if this is a cirrus, dino-hardware or dino-driver problem...) | ||
444 | */ | ||
445 | static void __devinit quirk_cirrus_cardbus(struct pci_dev *dev) | ||
446 | { | ||
447 | u8 new_irq = dev->irq - 1; | ||
448 | printk(KERN_INFO "PCI: Cirrus Cardbus IRQ fixup for %s, from %d to %d\n", | ||
449 | pci_name(dev), dev->irq, new_irq); | ||
450 | dev->irq = new_irq; | ||
451 | } | ||
452 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_6832, quirk_cirrus_cardbus ); | ||
453 | |||
454 | |||
438 | static void __init | 455 | static void __init |
439 | dino_bios_init(void) | 456 | dino_bios_init(void) |
440 | { | 457 | { |
@@ -666,7 +683,6 @@ dino_fixup_bus(struct pci_bus *bus) | |||
666 | printk(KERN_WARNING "Device %s has unassigned IRQ\n", pci_name(dev)); | 683 | printk(KERN_WARNING "Device %s has unassigned IRQ\n", pci_name(dev)); |
667 | #endif | 684 | #endif |
668 | } else { | 685 | } else { |
669 | |||
670 | /* Adjust INT_LINE for that busses region */ | 686 | /* Adjust INT_LINE for that busses region */ |
671 | dino_assign_irq(dino_dev, dev->irq, &dev->irq); | 687 | dino_assign_irq(dino_dev, dev->irq, &dev->irq); |
672 | } | 688 | } |
@@ -872,7 +888,7 @@ static int __init dino_common_init(struct parisc_device *dev, | |||
872 | 888 | ||
873 | /* allocate I/O Port resource region */ | 889 | /* allocate I/O Port resource region */ |
874 | res = &dino_dev->hba.io_space; | 890 | res = &dino_dev->hba.io_space; |
875 | if (dev->id.hversion == 0x680 || is_card_dino(&dev->id)) { | 891 | if (!is_cujo(&dev->id)) { |
876 | res->name = "Dino I/O Port"; | 892 | res->name = "Dino I/O Port"; |
877 | } else { | 893 | } else { |
878 | res->name = "Cujo I/O Port"; | 894 | res->name = "Cujo I/O Port"; |
@@ -927,7 +943,7 @@ static int __init dino_probe(struct parisc_device *dev) | |||
927 | if (is_card_dino(&dev->id)) { | 943 | if (is_card_dino(&dev->id)) { |
928 | version = "3.x (card mode)"; | 944 | version = "3.x (card mode)"; |
929 | } else { | 945 | } else { |
930 | if(dev->id.hversion == 0x680) { | 946 | if (!is_cujo(&dev->id)) { |
931 | if (dev->id.hversion_rev < 4) { | 947 | if (dev->id.hversion_rev < 4) { |
932 | version = dino_vers[dev->id.hversion_rev]; | 948 | version = dino_vers[dev->id.hversion_rev]; |
933 | } | 949 | } |