Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* pci_msi.c: Sparc64 MSI support common layer.
0003  *
0004  * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
0005  */
0006 #include <linux/kernel.h>
0007 #include <linux/interrupt.h>
0008 #include <linux/slab.h>
0009 #include <linux/irq.h>
0010 
0011 #include "pci_impl.h"
0012 
0013 static irqreturn_t sparc64_msiq_interrupt(int irq, void *cookie)
0014 {
0015     struct sparc64_msiq_cookie *msiq_cookie = cookie;
0016     struct pci_pbm_info *pbm = msiq_cookie->pbm;
0017     unsigned long msiqid = msiq_cookie->msiqid;
0018     const struct sparc64_msiq_ops *ops;
0019     unsigned long orig_head, head;
0020     int err;
0021 
0022     ops = pbm->msi_ops;
0023 
0024     err = ops->get_head(pbm, msiqid, &head);
0025     if (unlikely(err < 0))
0026         goto err_get_head;
0027 
0028     orig_head = head;
0029     for (;;) {
0030         unsigned long msi;
0031 
0032         err = ops->dequeue_msi(pbm, msiqid, &head, &msi);
0033         if (likely(err > 0)) {
0034             unsigned int irq;
0035 
0036             irq = pbm->msi_irq_table[msi - pbm->msi_first];
0037             generic_handle_irq(irq);
0038         }
0039 
0040         if (unlikely(err < 0))
0041             goto err_dequeue;
0042 
0043         if (err == 0)
0044             break;
0045     }
0046     if (likely(head != orig_head)) {
0047         err = ops->set_head(pbm, msiqid, head);
0048         if (unlikely(err < 0))
0049             goto err_set_head;
0050     }
0051     return IRQ_HANDLED;
0052 
0053 err_get_head:
0054     printk(KERN_EMERG "MSI: Get head on msiqid[%lu] gives error %d\n",
0055            msiqid, err);
0056     goto err_out;
0057 
0058 err_dequeue:
0059     printk(KERN_EMERG "MSI: Dequeue head[%lu] from msiqid[%lu] "
0060            "gives error %d\n",
0061            head, msiqid, err);
0062     goto err_out;
0063 
0064 err_set_head:
0065     printk(KERN_EMERG "MSI: Set head[%lu] on msiqid[%lu] "
0066            "gives error %d\n",
0067            head, msiqid, err);
0068     goto err_out;
0069 
0070 err_out:
0071     return IRQ_NONE;
0072 }
0073 
0074 static u32 pick_msiq(struct pci_pbm_info *pbm)
0075 {
0076     static DEFINE_SPINLOCK(rotor_lock);
0077     unsigned long flags;
0078     u32 ret, rotor;
0079 
0080     spin_lock_irqsave(&rotor_lock, flags);
0081 
0082     rotor = pbm->msiq_rotor;
0083     ret = pbm->msiq_first + rotor;
0084 
0085     if (++rotor >= pbm->msiq_num)
0086         rotor = 0;
0087     pbm->msiq_rotor = rotor;
0088 
0089     spin_unlock_irqrestore(&rotor_lock, flags);
0090 
0091     return ret;
0092 }
0093 
0094 
0095 static int alloc_msi(struct pci_pbm_info *pbm)
0096 {
0097     int i;
0098 
0099     for (i = 0; i < pbm->msi_num; i++) {
0100         if (!test_and_set_bit(i, pbm->msi_bitmap))
0101             return i + pbm->msi_first;
0102     }
0103 
0104     return -ENOENT;
0105 }
0106 
0107 static void free_msi(struct pci_pbm_info *pbm, int msi_num)
0108 {
0109     msi_num -= pbm->msi_first;
0110     clear_bit(msi_num, pbm->msi_bitmap);
0111 }
0112 
0113 static struct irq_chip msi_irq = {
0114     .name       = "PCI-MSI",
0115     .irq_mask   = pci_msi_mask_irq,
0116     .irq_unmask = pci_msi_unmask_irq,
0117     .irq_enable = pci_msi_unmask_irq,
0118     .irq_disable    = pci_msi_mask_irq,
0119     /* XXX affinity XXX */
0120 };
0121 
0122 static int sparc64_setup_msi_irq(unsigned int *irq_p,
0123                  struct pci_dev *pdev,
0124                  struct msi_desc *entry)
0125 {
0126     struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller;
0127     const struct sparc64_msiq_ops *ops = pbm->msi_ops;
0128     struct msi_msg msg;
0129     int msi, err;
0130     u32 msiqid;
0131 
0132     *irq_p = irq_alloc(0, 0);
0133     err = -ENOMEM;
0134     if (!*irq_p)
0135         goto out_err;
0136 
0137     irq_set_chip_and_handler_name(*irq_p, &msi_irq, handle_simple_irq,
0138                       "MSI");
0139 
0140     err = alloc_msi(pbm);
0141     if (unlikely(err < 0))
0142         goto out_irq_free;
0143 
0144     msi = err;
0145 
0146     msiqid = pick_msiq(pbm);
0147 
0148     err = ops->msi_setup(pbm, msiqid, msi,
0149                  (entry->pci.msi_attrib.is_64 ? 1 : 0));
0150     if (err)
0151         goto out_msi_free;
0152 
0153     pbm->msi_irq_table[msi - pbm->msi_first] = *irq_p;
0154 
0155     if (entry->pci.msi_attrib.is_64) {
0156         msg.address_hi = pbm->msi64_start >> 32;
0157         msg.address_lo = pbm->msi64_start & 0xffffffff;
0158     } else {
0159         msg.address_hi = 0;
0160         msg.address_lo = pbm->msi32_start;
0161     }
0162     msg.data = msi;
0163 
0164     irq_set_msi_desc(*irq_p, entry);
0165     pci_write_msi_msg(*irq_p, &msg);
0166 
0167     return 0;
0168 
0169 out_msi_free:
0170     free_msi(pbm, msi);
0171 
0172 out_irq_free:
0173     irq_set_chip(*irq_p, NULL);
0174     irq_free(*irq_p);
0175     *irq_p = 0;
0176 
0177 out_err:
0178     return err;
0179 }
0180 
0181 static void sparc64_teardown_msi_irq(unsigned int irq,
0182                      struct pci_dev *pdev)
0183 {
0184     struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller;
0185     const struct sparc64_msiq_ops *ops = pbm->msi_ops;
0186     unsigned int msi_num;
0187     int i, err;
0188 
0189     for (i = 0; i < pbm->msi_num; i++) {
0190         if (pbm->msi_irq_table[i] == irq)
0191             break;
0192     }
0193     if (i >= pbm->msi_num) {
0194         pci_err(pdev, "%s: teardown: No MSI for irq %u\n", pbm->name,
0195             irq);
0196         return;
0197     }
0198 
0199     msi_num = pbm->msi_first + i;
0200     pbm->msi_irq_table[i] = ~0U;
0201 
0202     err = ops->msi_teardown(pbm, msi_num);
0203     if (err) {
0204         pci_err(pdev, "%s: teardown: ops->teardown() on MSI %u, "
0205             "irq %u, gives error %d\n", pbm->name, msi_num, irq,
0206             err);
0207         return;
0208     }
0209 
0210     free_msi(pbm, msi_num);
0211 
0212     irq_set_chip(irq, NULL);
0213     irq_free(irq);
0214 }
0215 
0216 static int msi_bitmap_alloc(struct pci_pbm_info *pbm)
0217 {
0218     unsigned long size, bits_per_ulong;
0219 
0220     bits_per_ulong = sizeof(unsigned long) * 8;
0221     size = (pbm->msi_num + (bits_per_ulong - 1)) & ~(bits_per_ulong - 1);
0222     size /= 8;
0223     BUG_ON(size % sizeof(unsigned long));
0224 
0225     pbm->msi_bitmap = kzalloc(size, GFP_KERNEL);
0226     if (!pbm->msi_bitmap)
0227         return -ENOMEM;
0228 
0229     return 0;
0230 }
0231 
0232 static void msi_bitmap_free(struct pci_pbm_info *pbm)
0233 {
0234     kfree(pbm->msi_bitmap);
0235     pbm->msi_bitmap = NULL;
0236 }
0237 
0238 static int msi_table_alloc(struct pci_pbm_info *pbm)
0239 {
0240     int size, i;
0241 
0242     size = pbm->msiq_num * sizeof(struct sparc64_msiq_cookie);
0243     pbm->msiq_irq_cookies = kzalloc(size, GFP_KERNEL);
0244     if (!pbm->msiq_irq_cookies)
0245         return -ENOMEM;
0246 
0247     for (i = 0; i < pbm->msiq_num; i++) {
0248         struct sparc64_msiq_cookie *p;
0249 
0250         p = &pbm->msiq_irq_cookies[i];
0251         p->pbm = pbm;
0252         p->msiqid = pbm->msiq_first + i;
0253     }
0254 
0255     size = pbm->msi_num * sizeof(unsigned int);
0256     pbm->msi_irq_table = kzalloc(size, GFP_KERNEL);
0257     if (!pbm->msi_irq_table) {
0258         kfree(pbm->msiq_irq_cookies);
0259         pbm->msiq_irq_cookies = NULL;
0260         return -ENOMEM;
0261     }
0262 
0263     return 0;
0264 }
0265 
0266 static void msi_table_free(struct pci_pbm_info *pbm)
0267 {
0268     kfree(pbm->msiq_irq_cookies);
0269     pbm->msiq_irq_cookies = NULL;
0270 
0271     kfree(pbm->msi_irq_table);
0272     pbm->msi_irq_table = NULL;
0273 }
0274 
0275 static int bringup_one_msi_queue(struct pci_pbm_info *pbm,
0276                  const struct sparc64_msiq_ops *ops,
0277                  unsigned long msiqid,
0278                  unsigned long devino)
0279 {
0280     int irq = ops->msiq_build_irq(pbm, msiqid, devino);
0281     int err, nid;
0282 
0283     if (irq < 0)
0284         return irq;
0285 
0286     nid = pbm->numa_node;
0287     if (nid != -1) {
0288         cpumask_t numa_mask;
0289 
0290         cpumask_copy(&numa_mask, cpumask_of_node(nid));
0291         irq_set_affinity(irq, &numa_mask);
0292     }
0293     err = request_irq(irq, sparc64_msiq_interrupt, 0,
0294               "MSIQ",
0295               &pbm->msiq_irq_cookies[msiqid - pbm->msiq_first]);
0296     if (err)
0297         return err;
0298 
0299     return 0;
0300 }
0301 
0302 static int sparc64_bringup_msi_queues(struct pci_pbm_info *pbm,
0303                       const struct sparc64_msiq_ops *ops)
0304 {
0305     int i;
0306 
0307     for (i = 0; i < pbm->msiq_num; i++) {
0308         unsigned long msiqid = i + pbm->msiq_first;
0309         unsigned long devino = i + pbm->msiq_first_devino;
0310         int err;
0311 
0312         err = bringup_one_msi_queue(pbm, ops, msiqid, devino);
0313         if (err)
0314             return err;
0315     }
0316 
0317     return 0;
0318 }
0319 
0320 void sparc64_pbm_msi_init(struct pci_pbm_info *pbm,
0321               const struct sparc64_msiq_ops *ops)
0322 {
0323     const u32 *val;
0324     int len;
0325 
0326     val = of_get_property(pbm->op->dev.of_node, "#msi-eqs", &len);
0327     if (!val || len != 4)
0328         goto no_msi;
0329     pbm->msiq_num = *val;
0330     if (pbm->msiq_num) {
0331         const struct msiq_prop {
0332             u32 first_msiq;
0333             u32 num_msiq;
0334             u32 first_devino;
0335         } *mqp;
0336         const struct msi_range_prop {
0337             u32 first_msi;
0338             u32 num_msi;
0339         } *mrng;
0340         const struct addr_range_prop {
0341             u32 msi32_high;
0342             u32 msi32_low;
0343             u32 msi32_len;
0344             u32 msi64_high;
0345             u32 msi64_low;
0346             u32 msi64_len;
0347         } *arng;
0348 
0349         val = of_get_property(pbm->op->dev.of_node, "msi-eq-size", &len);
0350         if (!val || len != 4)
0351             goto no_msi;
0352 
0353         pbm->msiq_ent_count = *val;
0354 
0355         mqp = of_get_property(pbm->op->dev.of_node,
0356                       "msi-eq-to-devino", &len);
0357         if (!mqp)
0358             mqp = of_get_property(pbm->op->dev.of_node,
0359                           "msi-eq-devino", &len);
0360         if (!mqp || len != sizeof(struct msiq_prop))
0361             goto no_msi;
0362 
0363         pbm->msiq_first = mqp->first_msiq;
0364         pbm->msiq_first_devino = mqp->first_devino;
0365 
0366         val = of_get_property(pbm->op->dev.of_node, "#msi", &len);
0367         if (!val || len != 4)
0368             goto no_msi;
0369         pbm->msi_num = *val;
0370 
0371         mrng = of_get_property(pbm->op->dev.of_node, "msi-ranges", &len);
0372         if (!mrng || len != sizeof(struct msi_range_prop))
0373             goto no_msi;
0374         pbm->msi_first = mrng->first_msi;
0375 
0376         val = of_get_property(pbm->op->dev.of_node, "msi-data-mask", &len);
0377         if (!val || len != 4)
0378             goto no_msi;
0379         pbm->msi_data_mask = *val;
0380 
0381         val = of_get_property(pbm->op->dev.of_node, "msix-data-width", &len);
0382         if (!val || len != 4)
0383             goto no_msi;
0384         pbm->msix_data_width = *val;
0385 
0386         arng = of_get_property(pbm->op->dev.of_node, "msi-address-ranges",
0387                        &len);
0388         if (!arng || len != sizeof(struct addr_range_prop))
0389             goto no_msi;
0390         pbm->msi32_start = ((u64)arng->msi32_high << 32) |
0391             (u64) arng->msi32_low;
0392         pbm->msi64_start = ((u64)arng->msi64_high << 32) |
0393             (u64) arng->msi64_low;
0394         pbm->msi32_len = arng->msi32_len;
0395         pbm->msi64_len = arng->msi64_len;
0396 
0397         if (msi_bitmap_alloc(pbm))
0398             goto no_msi;
0399 
0400         if (msi_table_alloc(pbm)) {
0401             msi_bitmap_free(pbm);
0402             goto no_msi;
0403         }
0404 
0405         if (ops->msiq_alloc(pbm)) {
0406             msi_table_free(pbm);
0407             msi_bitmap_free(pbm);
0408             goto no_msi;
0409         }
0410 
0411         if (sparc64_bringup_msi_queues(pbm, ops)) {
0412             ops->msiq_free(pbm);
0413             msi_table_free(pbm);
0414             msi_bitmap_free(pbm);
0415             goto no_msi;
0416         }
0417 
0418         printk(KERN_INFO "%s: MSI Queue first[%u] num[%u] count[%u] "
0419                "devino[0x%x]\n",
0420                pbm->name,
0421                pbm->msiq_first, pbm->msiq_num,
0422                pbm->msiq_ent_count,
0423                pbm->msiq_first_devino);
0424         printk(KERN_INFO "%s: MSI first[%u] num[%u] mask[0x%x] "
0425                "width[%u]\n",
0426                pbm->name,
0427                pbm->msi_first, pbm->msi_num, pbm->msi_data_mask,
0428                pbm->msix_data_width);
0429         printk(KERN_INFO "%s: MSI addr32[0x%llx:0x%x] "
0430                "addr64[0x%llx:0x%x]\n",
0431                pbm->name,
0432                pbm->msi32_start, pbm->msi32_len,
0433                pbm->msi64_start, pbm->msi64_len);
0434         printk(KERN_INFO "%s: MSI queues at RA [%016lx]\n",
0435                pbm->name,
0436                __pa(pbm->msi_queues));
0437 
0438         pbm->msi_ops = ops;
0439         pbm->setup_msi_irq = sparc64_setup_msi_irq;
0440         pbm->teardown_msi_irq = sparc64_teardown_msi_irq;
0441     }
0442     return;
0443 
0444 no_msi:
0445     pbm->msiq_num = 0;
0446     printk(KERN_INFO "%s: No MSI support.\n", pbm->name);
0447 }