[POWERPC] Fix interrupt routing and setup of ULI M1575 on FSL boards
[cascardo/linux.git] / arch / powerpc / platforms / 85xx / mpc8544_ds.c
index 4905f6f..0f834d8 100644 (file)
@@ -114,211 +114,25 @@ void __init mpc8544_ds_pic_init(void)
 }
 
 #ifdef CONFIG_PCI
-enum pirq { PIRQA = 8, PIRQB, PIRQC, PIRQD, PIRQE, PIRQF, PIRQG, PIRQH };
+extern int uses_fsl_uli_m1575;
+extern int uli_exclude_device(struct pci_controller *hose,
+                               u_char bus, u_char devfn);
 
-/*
- * Value in  table -- IRQ number
- */
-const unsigned char uli1575_irq_route_table[16] = {
-       0,              /* 0: Reserved */
-       0x8,
-       0,              /* 2: Reserved */
-       0x2,
-       0x4,
-       0x5,
-       0x7,
-       0x6,
-       0,              /* 8: Reserved */
-       0x1,
-       0x3,
-       0x9,
-       0xb,
-       0,              /* 13: Reserved */
-       0xd,
-       0xf,
-};
-
-static int __devinit
-get_pci_irq_from_of(struct pci_controller *hose, int slot, int pin)
-{
-       struct of_irq oirq;
-       u32 laddr[3];
-       struct device_node *hosenode = hose ? hose->arch_data : NULL;
-
-       if (!hosenode)
-               return -EINVAL;
-
-       laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(slot, 0) << 8);
-       laddr[1] = laddr[2] = 0;
-       of_irq_map_raw(hosenode, &pin, 1, laddr, &oirq);
-       DBG("mpc8544_ds: pci irq addr %x, slot %d, pin %d, irq %d\n",
-           laddr[0], slot, pin, oirq.specifier[0]);
-       return oirq.specifier[0];
-}
-
-/*8259*/
-static void __devinit quirk_uli1575(struct pci_dev *dev)
-{
-       unsigned short temp;
-       struct pci_controller *hose = pci_bus_to_host(dev->bus);
-       unsigned char irq2pin[16];
-       unsigned long pirq_map_word = 0;
-       u32 irq;
-       int i;
-
-       /*
-        * ULI1575 interrupts route setup
-        */
-       memset(irq2pin, 0, 16); /* Initialize default value 0 */
-
-       irq2pin[6]=PIRQA+3;     /* enabled mapping for IRQ6 to PIRQD, used by SATA */
-
-       /*
-        * PIRQE -> PIRQF mapping set manually
-        *
-        * IRQ pin   IRQ#
-        * PIRQE ---- 9
-        * PIRQF ---- 10
-        * PIRQG ---- 11
-        * PIRQH ---- 12
-        */
-       for (i = 0; i < 4; i++)
-               irq2pin[i + 9] = PIRQE + i;
-
-       /* Set IRQ-PIRQ Mapping to ULI1575 */
-       for (i = 0; i < 16; i++)
-               if (irq2pin[i])
-                       pirq_map_word |= (uli1575_irq_route_table[i] & 0xf)
-                           << ((irq2pin[i] - PIRQA) * 4);
-
-       pirq_map_word |= 1<<26; /* disable INTx in EP mode*/
-
-       /* ULI1575 IRQ mapping conf register default value is 0xb9317542 */
-       DBG("Setup ULI1575 IRQ mapping configuration register value = 0x%x\n",
-               (int)pirq_map_word);
-       pci_write_config_dword(dev, 0x48, pirq_map_word);
-
-#define ULI1575_SET_DEV_IRQ(slot, pin, reg)                            \
-       do {                                                            \
-               int irq;                                                \
-               irq = get_pci_irq_from_of(hose, slot, pin);             \
-               if (irq > 0 && irq < 16)                                \
-                       pci_write_config_byte(dev, reg, irq2pin[irq]);  \
-               else                                                    \
-                       printk(KERN_WARNING "ULI1575 device"            \
-                               "(slot %d, pin %d) irq %d is invalid.\n", \
-                               slot, pin, irq);                        \
-       } while(0)
-
-       /* USB 1.1 OHCI controller 1, slot 28, pin 1 */
-       ULI1575_SET_DEV_IRQ(28, 1, 0x86);
-
-       /* USB 1.1 OHCI controller 2, slot 28, pin 2 */
-       ULI1575_SET_DEV_IRQ(28, 2, 0x87);
-
-       /* USB 1.1 OHCI controller 3, slot 28, pin 3 */
-       ULI1575_SET_DEV_IRQ(28, 3, 0x88);
-
-       /* USB 2.0 controller, slot 28, pin 4 */
-       irq = get_pci_irq_from_of(hose, 28, 4);
-       if (irq >= 0 && irq <= 15)
-               pci_write_config_dword(dev, 0x74, uli1575_irq_route_table[irq]);
-
-       /* Audio controller, slot 29, pin 1 */
-       ULI1575_SET_DEV_IRQ(29, 1, 0x8a);
-
-       /* Modem controller, slot 29, pin 2 */
-       ULI1575_SET_DEV_IRQ(29, 2, 0x8b);
-
-       /* HD audio controller, slot 29, pin 3 */
-       ULI1575_SET_DEV_IRQ(29, 3, 0x8c);
-
-       /* SMB interrupt: slot 30, pin 1 */
-       ULI1575_SET_DEV_IRQ(30, 1, 0x8e);
-
-       /* PMU ACPI SCI interrupt: slot 30, pin 2 */
-       ULI1575_SET_DEV_IRQ(30, 2, 0x8f);
-
-       /* Serial ATA interrupt: slot 31, pin 1 */
-       ULI1575_SET_DEV_IRQ(31, 1, 0x8d);
-
-       /* Primary PATA IDE IRQ: 14
-        * Secondary PATA IDE IRQ: 15
-        */
-       pci_write_config_byte(dev, 0x44, 0x30 | uli1575_irq_route_table[14]);
-       pci_write_config_byte(dev, 0x75, uli1575_irq_route_table[15]);
-
-       /* Set IRQ14 and IRQ15 to legacy IRQs */
-       pci_read_config_word(dev, 0x46, &temp);
-       temp |= 0xc000;
-       pci_write_config_word(dev, 0x46, temp);
-
-       /* Set i8259 interrupt trigger
-        * IRQ 3:  Level
-        * IRQ 4:  Level
-        * IRQ 5:  Level
-        * IRQ 6:  Level
-        * IRQ 7:  Level
-        * IRQ 9:  Level
-        * IRQ 10: Level
-        * IRQ 11: Level
-        * IRQ 12: Level
-        * IRQ 14: Edge
-        * IRQ 15: Edge
-        */
-       outb(0xfa, 0x4d0);
-       outb(0x1e, 0x4d1);
-
-#undef ULI1575_SET_DEV_IRQ
-}
-
-/* SATA */
-static void __devinit quirk_uli5288(struct pci_dev *dev)
+static int mpc85xx_exclude_device(struct pci_controller *hose,
+                                  u_char bus, u_char devfn)
 {
-       unsigned char c;
-
-       pci_read_config_byte(dev, 0x83, &c);
-       c |= 0x80;              /* read/write lock */
-       pci_write_config_byte(dev, 0x83, c);
-
-       pci_write_config_byte(dev, 0x09, 0x01); /* Base class code: storage */
-       pci_write_config_byte(dev, 0x0a, 0x06); /* IDE disk */
+       struct device_node* node;       
+       struct resource rsrc;
 
-       pci_read_config_byte(dev, 0x83, &c);
-       c &= 0x7f;
-       pci_write_config_byte(dev, 0x83, c);
-
-       pci_read_config_byte(dev, 0x84, &c);
-       c |= 0x01;                              /* emulated PATA mode enabled */
-       pci_write_config_byte(dev, 0x84, c);
-}
+       node = (struct device_node *)hose->arch_data;
+       of_address_to_resource(node, 0, &rsrc);
 
-/* PATA */
-static void __devinit quirk_uli5229(struct pci_dev *dev)
-{
-       unsigned short temp;
-       pci_write_config_word(dev, 0x04, 0x0405);       /* MEM IO MSI */
-       pci_read_config_word(dev, 0x4a, &temp);
-       temp |= 0x1000;                         /* Enable Native IRQ 14/15 */
-       pci_write_config_word(dev, 0x4a, temp);
-}
+       if ((rsrc.start & 0xfffff) == 0xb000) {
+               return uli_exclude_device(hose, bus, devfn);
+       }
 
-/*Bridge*/
-static void __devinit early_uli5249(struct pci_dev *dev)
-{
-       unsigned char temp;
-       pci_write_config_word(dev, 0x04, 0x0007);       /* mem access */
-       pci_read_config_byte(dev, 0x7c, &temp);
-       pci_write_config_byte(dev, 0x7c, 0x80); /* R/W lock control */
-       pci_write_config_byte(dev, 0x09, 0x01); /* set as pci-pci bridge */
-       pci_write_config_byte(dev, 0x7c, temp); /* restore pci bus debug control */
-       dev->class |= 0x1;
+       return PCIBIOS_SUCCESSFUL;
 }
-
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_uli1575);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229);
-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249);
 #endif /* CONFIG_PCI */
 
 /*
@@ -342,6 +156,8 @@ static void __init mpc8544_ds_setup_arch(void)
                else
                        fsl_add_bridge(np, 0);
        }
+       uses_fsl_uli_m1575 = 1;
+       ppc_md.pci_exclude_device = mpc85xx_exclude_device;
 #endif
 
        printk("MPC8544 DS board from Freescale Semiconductor\n");