[SPARC64]: Move over to GENERIC_HARDIRQS.
[firefly-linux-kernel-4.4.55.git] / arch / sparc64 / kernel / pci_sabre.c
index 53d333b4a4e809f7ebf48231c46bb5e65af86ec3..b7d997b55f0a7469228e7aec9f0413846f5a7e7c 100644 (file)
@@ -523,86 +523,31 @@ static unsigned long __onboard_imap_off[] = {
        ((ino & 0x20) ? (SABRE_ICLR_SCSI + (((ino) & 0x1f) << 3)) :  \
                        (SABRE_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3)))
 
-/* PCI SABRE INO number to Sparc PIL level. */
-static unsigned char sabre_pil_table[] = {
-/*0x00*/0, 0, 0, 0,    /* PCI A slot 0  Int A, B, C, D */
-/*0x04*/0, 0, 0, 0,    /* PCI A slot 1  Int A, B, C, D */
-/*0x08*/0, 0, 0, 0,    /* PCI A slot 2  Int A, B, C, D */
-/*0x0c*/0, 0, 0, 0,    /* PCI A slot 3  Int A, B, C, D */
-/*0x10*/0, 0, 0, 0,    /* PCI B slot 0  Int A, B, C, D */
-/*0x14*/0, 0, 0, 0,    /* PCI B slot 1  Int A, B, C, D */
-/*0x18*/0, 0, 0, 0,    /* PCI B slot 2  Int A, B, C, D */
-/*0x1c*/0, 0, 0, 0,    /* PCI B slot 3  Int A, B, C, D */
-/*0x20*/4,             /* SCSI                         */
-/*0x21*/5,             /* Ethernet                     */
-/*0x22*/8,             /* Parallel Port                */
-/*0x23*/13,            /* Audio Record                 */
-/*0x24*/14,            /* Audio Playback               */
-/*0x25*/15,            /* PowerFail                    */
-/*0x26*/4,             /* second SCSI                  */
-/*0x27*/11,            /* Floppy                       */
-/*0x28*/4,             /* Spare Hardware               */
-/*0x29*/9,             /* Keyboard                     */
-/*0x2a*/4,             /* Mouse                        */
-/*0x2b*/12,            /* Serial                       */
-/*0x2c*/10,            /* Timer 0                      */
-/*0x2d*/11,            /* Timer 1                      */
-/*0x2e*/15,            /* Uncorrectable ECC            */
-/*0x2f*/15,            /* Correctable ECC              */
-/*0x30*/15,            /* PCI Bus A Error              */
-/*0x31*/15,            /* PCI Bus B Error              */
-/*0x32*/15,            /* Power Management             */
-};
-
-static int __init sabre_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
+/* When a device lives behind a bridge deeper in the PCI bus topology
+ * than APB, a special sequence must run to make sure all pending DMA
+ * transfers at the time of IRQ delivery are visible in the coherency
+ * domain by the cpu.  This sequence is to perform a read on the far
+ * side of the non-APB bridge, then perform a read of Sabre's DMA
+ * write-sync register.
+ */
+static void sabre_wsync_handler(unsigned int ino, void *_arg1, void *_arg2)
 {
-       int ret;
-
-       if (pdev &&
-           pdev->vendor == PCI_VENDOR_ID_SUN &&
-           pdev->device == PCI_DEVICE_ID_SUN_RIO_USB)
-               return 9;
-
-       ret = sabre_pil_table[ino];
-       if (ret == 0 && pdev == NULL) {
-               ret = 4;
-       } else if (ret == 0) {
-               switch ((pdev->class >> 16) & 0xff) {
-               case PCI_BASE_CLASS_STORAGE:
-                       ret = 4;
-                       break;
-
-               case PCI_BASE_CLASS_NETWORK:
-                       ret = 6;
-                       break;
-
-               case PCI_BASE_CLASS_DISPLAY:
-                       ret = 9;
-                       break;
-
-               case PCI_BASE_CLASS_MULTIMEDIA:
-               case PCI_BASE_CLASS_MEMORY:
-               case PCI_BASE_CLASS_BRIDGE:
-               case PCI_BASE_CLASS_SERIAL:
-                       ret = 10;
-                       break;
+       struct pci_dev *pdev = _arg1;
+       unsigned long sync_reg = (unsigned long) _arg2;
+       u16 _unused;
 
-               default:
-                       ret = 4;
-                       break;
-               };
-       }
-       return ret;
+       pci_read_config_word(pdev, PCI_VENDOR_ID, &_unused);
+       sabre_read(sync_reg);
 }
 
-static unsigned int __init sabre_irq_build(struct pci_pbm_info *pbm,
-                                          struct pci_dev *pdev,
-                                          unsigned int ino)
+static unsigned int sabre_irq_build(struct pci_pbm_info *pbm,
+                                   struct pci_dev *pdev,
+                                   unsigned int ino)
 {
-       struct ino_bucket *bucket;
        unsigned long imap, iclr;
        unsigned long imap_off, iclr_off;
-       int pil, inofixup = 0;
+       int inofixup = 0;
+       int virt_irq;
 
        ino &= PCI_IRQ_INO;
        if (ino < SABRE_ONBOARD_IRQ_BASE) {
@@ -618,11 +563,6 @@ static unsigned int __init sabre_irq_build(struct pci_pbm_info *pbm,
        }
 
        /* Now build the IRQ bucket. */
-       pil = sabre_ino_to_pil(pdev, ino);
-
-       if (PIL_RESERVED(pil))
-               BUG();
-
        imap = pbm->controller_regs + imap_off;
        imap += 4;
 
@@ -633,33 +573,23 @@ static unsigned int __init sabre_irq_build(struct pci_pbm_info *pbm,
        if ((ino & 0x20) == 0)
                inofixup = ino & 0x03;
 
-       bucket = __bucket(build_irq(pil, inofixup, iclr, imap));
-       bucket->flags |= IBF_PCI;
+       virt_irq = build_irq(inofixup, iclr, imap);
 
        if (pdev) {
                struct pcidev_cookie *pcp = pdev->sysdata;
 
-               /* When a device lives behind a bridge deeper in the
-                * PCI bus topology than APB, a special sequence must
-                * run to make sure all pending DMA transfers at the
-                * time of IRQ delivery are visible in the coherency
-                * domain by the cpu.  This sequence is to perform
-                * a read on the far side of the non-APB bridge, then
-                * perform a read of Sabre's DMA write-sync register.
-                *
-                * Currently, the PCI_CONFIG register for the device
-                * is used for this read from the far side of the bridge.
-                */
                if (pdev->bus->number != pcp->pbm->pci_first_busno) {
-                       bucket->flags |= IBF_DMA_SYNC;
-                       bucket->synctab_ent = dma_sync_reg_table_entry++;
-                       dma_sync_reg_table[bucket->synctab_ent] =
-                               (unsigned long) sabre_pci_config_mkaddr(
-                                       pcp->pbm,
-                                       pdev->bus->number, pdev->devfn, PCI_COMMAND);
+                       struct pci_controller_info *p = pcp->pbm->parent;
+
+                       irq_install_pre_handler(virt_irq,
+                                               sabre_wsync_handler,
+                                               pdev,
+                                               (void *)
+                                               p->pbm_A.controller_regs +
+                                               SABRE_WRSYNC);
                }
        }
-       return __irq(bucket);
+       return virt_irq;
 }
 
 /* SABRE error handling support. */
@@ -1002,7 +932,7 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs
 #define SABRE_UE_INO           0x2e
 #define SABRE_CE_INO           0x2f
 #define SABRE_PCIERR_INO       0x30
-static void __init sabre_register_error_handlers(struct pci_controller_info *p)
+static void sabre_register_error_handlers(struct pci_controller_info *p)
 {
        struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */
        unsigned long base = pbm->controller_regs;
@@ -1049,9 +979,9 @@ static void __init sabre_register_error_handlers(struct pci_controller_info *p)
        sabre_write(base + SABRE_PCICTRL, tmp);
 }
 
-static void __init sabre_resource_adjust(struct pci_dev *pdev,
-                                        struct resource *res,
-                                        struct resource *root)
+static void sabre_resource_adjust(struct pci_dev *pdev,
+                                 struct resource *res,
+                                 struct resource *root)
 {
        struct pci_pbm_info *pbm = pdev->bus->sysdata;
        unsigned long base;
@@ -1065,7 +995,7 @@ static void __init sabre_resource_adjust(struct pci_dev *pdev,
        res->end += base;
 }
 
-static void __init sabre_base_address_update(struct pci_dev *pdev, int resource)
+static void sabre_base_address_update(struct pci_dev *pdev, int resource)
 {
        struct pcidev_cookie *pcp = pdev->sysdata;
        struct pci_pbm_info *pbm = pcp->pbm;
@@ -1111,7 +1041,7 @@ static void __init sabre_base_address_update(struct pci_dev *pdev, int resource)
                pci_write_config_dword(pdev, where + 4, 0);
 }
 
-static void __init apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus)
+static void apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus)
 {
        struct pci_dev *pdev;
 
@@ -1160,7 +1090,7 @@ static void __init apb_init(struct pci_controller_info *p, struct pci_bus *sabre
 
 static struct pcidev_cookie *alloc_bridge_cookie(struct pci_pbm_info *pbm)
 {
-       struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL);
+       struct pcidev_cookie *cookie = kzalloc(sizeof(*cookie), GFP_KERNEL);
 
        if (!cookie) {
                prom_printf("SABRE: Critical allocation failure.\n");
@@ -1168,13 +1098,12 @@ static struct pcidev_cookie *alloc_bridge_cookie(struct pci_pbm_info *pbm)
        }
 
        /* All we care about is the PBM. */
-       memset(cookie, 0, sizeof(*cookie));
        cookie->pbm = pbm;
 
        return cookie;
 }
 
-static void __init sabre_scan_bus(struct pci_controller_info *p)
+static void sabre_scan_bus(struct pci_controller_info *p)
 {
        static int once;
        struct pci_bus *sabre_bus, *pbus;
@@ -1255,18 +1184,14 @@ static void __init sabre_scan_bus(struct pci_controller_info *p)
        sabre_register_error_handlers(p);
 }
 
-static void __init sabre_iommu_init(struct pci_controller_info *p,
-                                   int tsbsize, unsigned long dvma_offset,
-                                   u32 dma_mask)
+static void sabre_iommu_init(struct pci_controller_info *p,
+                            int tsbsize, unsigned long dvma_offset,
+                            u32 dma_mask)
 {
        struct pci_iommu *iommu = p->pbm_A.iommu;
-       unsigned long tsbbase, i, order;
+       unsigned long i;
        u64 control;
 
-       /* Setup initial software IOMMU state. */
-       spin_lock_init(&iommu->lock);
-       iommu->ctx_lowest_free = 1;
-
        /* Register addresses. */
        iommu->iommu_control  = p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL;
        iommu->iommu_tsbbase  = p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE;
@@ -1288,26 +1213,10 @@ static void __init sabre_iommu_init(struct pci_controller_info *p,
        /* Leave diag mode enabled for full-flushing done
         * in pci_iommu.c
         */
+       pci_iommu_table_init(iommu, tsbsize * 1024 * 8, dvma_offset, dma_mask);
 
-       iommu->dummy_page = __get_free_pages(GFP_KERNEL, 0);
-       if (!iommu->dummy_page) {
-               prom_printf("PSYCHO_IOMMU: Error, gfp(dummy_page) failed.\n");
-               prom_halt();
-       }
-       memset((void *)iommu->dummy_page, 0, PAGE_SIZE);
-       iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page);
-
-       tsbbase = __get_free_pages(GFP_KERNEL, order = get_order(tsbsize * 1024 * 8));
-       if (!tsbbase) {
-               prom_printf("SABRE_IOMMU: Error, gfp(tsb) failed.\n");
-               prom_halt();
-       }
-       iommu->page_table = (iopte_t *)tsbbase;
-       iommu->page_table_map_base = dvma_offset;
-       iommu->dma_addr_mask = dma_mask;
-       pci_iommu_table_init(iommu, PAGE_SIZE << order);
-
-       sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE, __pa(tsbbase));
+       sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE,
+                   __pa(iommu->page_table));
 
        control = sabre_read(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL);
        control &= ~(SABRE_IOMMUCTRL_TSBSZ | SABRE_IOMMUCTRL_TBWSZ);
@@ -1315,11 +1224,9 @@ static void __init sabre_iommu_init(struct pci_controller_info *p,
        switch(tsbsize) {
        case 64:
                control |= SABRE_IOMMU_TSBSZ_64K;
-               iommu->page_table_sz_bits = 16;
                break;
        case 128:
                control |= SABRE_IOMMU_TSBSZ_128K;
-               iommu->page_table_sz_bits = 17;
                break;
        default:
                prom_printf("iommu_init: Illegal TSB size %d\n", tsbsize);
@@ -1327,19 +1234,10 @@ static void __init sabre_iommu_init(struct pci_controller_info *p,
                break;
        }
        sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL, control);
-
-       /* We start with no consistent mappings. */
-       iommu->lowest_consistent_map =
-               1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS);
-
-       for (i = 0; i < PBM_NCLUSTERS; i++) {
-               iommu->alloc_info[i].flush = 0;
-               iommu->alloc_info[i].next = 0;
-       }
 }
 
-static void __init pbm_register_toplevel_resources(struct pci_controller_info *p,
-                                                  struct pci_pbm_info *pbm)
+static void pbm_register_toplevel_resources(struct pci_controller_info *p,
+                                           struct pci_pbm_info *pbm)
 {
        char *name = pbm->name;
        unsigned long ibase = p->pbm_A.controller_regs + SABRE_IOSPACE;
@@ -1408,7 +1306,7 @@ static void __init pbm_register_toplevel_resources(struct pci_controller_info *p
                                            &pbm->mem_space);
 }
 
-static void __init sabre_pbm_init(struct pci_controller_info *p, int sabre_node, u32 dma_begin)
+static void sabre_pbm_init(struct pci_controller_info *p, int sabre_node, u32 dma_begin)
 {
        struct pci_pbm_info *pbm;
        char namebuf[128];
@@ -1545,7 +1443,7 @@ static void __init sabre_pbm_init(struct pci_controller_info *p, int sabre_node,
        }
 }
 
-void __init sabre_init(int pnode, char *model_name)
+void sabre_init(int pnode, char *model_name)
 {
        struct linux_prom64_registers pr_regs[2];
        struct pci_controller_info *p;
@@ -1580,19 +1478,17 @@ void __init sabre_init(int pnode, char *model_name)
                }
        }
 
-       p = kmalloc(sizeof(*p), GFP_ATOMIC);
+       p = kzalloc(sizeof(*p), GFP_ATOMIC);
        if (!p) {
                prom_printf("SABRE: Error, kmalloc(pci_controller_info) failed.\n");
                prom_halt();
        }
-       memset(p, 0, sizeof(*p));
 
-       iommu = kmalloc(sizeof(*iommu), GFP_ATOMIC);
+       iommu = kzalloc(sizeof(*iommu), GFP_ATOMIC);
        if (!iommu) {
                prom_printf("SABRE: Error, kmalloc(pci_iommu) failed.\n");
                prom_halt();
        }
-       memset(iommu, 0, sizeof(*iommu));
        p->pbm_A.iommu = p->pbm_B.iommu = iommu;
 
        upa_portid = prom_getintdefault(pnode, "upa-portid", 0xff);
@@ -1626,10 +1522,9 @@ void __init sabre_init(int pnode, char *model_name)
         */
        p->pbm_A.controller_regs = pr_regs[0].phys_addr;
        p->pbm_B.controller_regs = pr_regs[0].phys_addr;
-       pci_dma_wsync = p->pbm_A.controller_regs + SABRE_WRSYNC;
 
-       printk("PCI: Found SABRE, main regs at %016lx, wsync at %016lx\n",
-              p->pbm_A.controller_regs, pci_dma_wsync);
+       printk("PCI: Found SABRE, main regs at %016lx\n",
+              p->pbm_A.controller_regs);
 
        /* Clear interrupts */