18 #include <linux/pci.h>
19 #include <linux/slab.h>
23 #include <asm/hw_irq.h>
45 return in_be32(base + (reg >> 2));
52 static void fsl_msi_end_irq(
struct irq_data *
d)
56 static struct irq_chip fsl_msi_chip = {
59 .irq_ack = fsl_msi_end_irq,
63 static int fsl_msi_host_map(
struct irq_domain *
h,
unsigned int virq,
78 .map = fsl_msi_host_map,
81 static int fsl_msi_init_allocator(
struct fsl_msi *msi_data)
99 static int fsl_msi_check_device(
struct pci_dev *pdev,
int nvec,
int type)
102 pr_debug(
"fslmsi: MSI-X untested, trying anyway.\n");
107 static void fsl_teardown_msi_irqs(
struct pci_dev *pdev)
115 msi_data = irq_get_chip_data(entry->
irq);
125 static void fsl_compose_msi_msg(
struct pci_dev *pdev,
int hwirq,
129 struct fsl_msi *msi_data = fsl_msi_data;
137 if (reg && (len ==
sizeof(
u64)))
147 pr_debug(
"%s: allocated srs: %d, ibs: %d\n",
151 static int fsl_setup_msi_irqs(
struct pci_dev *pdev,
int nvec,
int type)
173 "node %s has an invalid fsl,msi phandle %u\n",
174 hose->dn->full_name, np->
phandle);
193 if (phandle && (phandle != msi_data->
phandle))
203 dev_err(&pdev->
dev,
"could not allocate MSI interrupt\n");
210 dev_err(&pdev->
dev,
"fail mapping hwirq %i\n", hwirq);
218 fsl_compose_msi_msg(pdev, hwirq, &msg, msi_data);
228 static void fsl_msi_cascade(
unsigned int irq,
struct irq_desc *
desc)
231 struct irq_data *idata = irq_desc_get_irq_data(desc);
241 cascade_data = irq_get_handler_data(irq);
254 if (
unlikely(irqd_irq_inprogress(idata)))
257 msir_index = cascade_data->
index;
262 irqd_set_chained_irq_inprogress(idata);
265 msir_value = fsl_msi_read(msi_data->
msi_regs,
269 msir_value = fsl_msi_read(msi_data->
msi_regs, msir_index * 0x4);
272 ret = fh_vmpic_get_msir(
virq_to_hw(irq), &msir_value);
274 pr_err(
"fsl-msi: fh_vmpic_get_msir() failed for "
275 "irq %u (ret=%u)\n", irq, ret);
282 intr_index =
ffs(msir_value) - 1;
286 intr_index + have_shift);
287 if (cascade_irq !=
NO_IRQ)
289 have_shift += intr_index + 1;
290 msir_value = msir_value >> (intr_index + 1);
292 irqd_clr_chained_irq_inprogress(idata);
300 if (!irqd_irq_disabled(idata) && chip->
irq_unmask)
310 struct fsl_msi *msi = platform_get_drvdata(ofdev);
319 cascade_data = irq_get_handler_data(virq);
335 int offset,
int irq_index)
341 if (virt_msir ==
NO_IRQ) {
342 dev_err(&dev->
dev,
"%s: Cannot translate IRQ index %d\n",
343 __func__, irq_index);
349 dev_err(&dev->
dev,
"No memory for MSI cascade data\n");
357 irq_set_chained_handler(virt_msir, fsl_msi_cascade);
379 features = match->
data;
385 dev_err(&dev->
dev,
"No memory for MSI structure\n");
388 platform_set_drvdata(dev, msi);
394 dev_err(&dev->
dev,
"No memory for MSI irqhost\n");
406 dev_err(&dev->
dev,
"invalid resource for node %s\n",
407 dev->
dev.of_node->full_name);
415 dev->
dev.of_node->full_name);
430 rc = fsl_msi_init_allocator(msi);
432 dev_err(&dev->
dev,
"Error allocating MSI bitmap\n");
437 if (p && len % (2 *
sizeof(
u32)) != 0) {
438 dev_err(&dev->
dev,
"%s: Malformed msi-available-ranges property\n",
446 len =
sizeof(all_avail);
449 for (irq_index = 0, i = 0; i < len / (2 *
sizeof(
u32)); i++) {
453 __func__, dev->
dev.of_node->full_name,
454 p[i * 2 + 1], p[i * 2]);
462 for (j = 0; j <
count; j++, irq_index++) {
463 err = fsl_msi_setup_hwirq(msi, dev, offset + j, irq_index);
472 if (!
ppc_md.setup_msi_irqs) {
473 ppc_md.setup_msi_irqs = fsl_setup_msi_irqs;
474 ppc_md.teardown_msi_irqs = fsl_teardown_msi_irqs;
475 ppc_md.msi_check_device = fsl_msi_check_device;
476 }
else if (
ppc_md.setup_msi_irqs != fsl_setup_msi_irqs) {
477 dev_err(&dev->
dev,
"Different MSI driver already installed!\n");
483 fsl_of_msi_remove(dev);
489 .msiir_offset = 0x140,
494 .msiir_offset = 0x38,
504 .compatible =
"fsl,mpic-msi",
505 .data = &mpic_msi_feature,
508 .compatible =
"fsl,ipic-msi",
509 .data = &ipic_msi_feature,
512 .compatible =
"fsl,vmpic-msi",
513 .data = &vmpic_msi_feature,
522 .of_match_table = fsl_of_msi_ids,
524 .probe = fsl_of_msi_probe,
525 .remove = fsl_of_msi_remove,
528 static __init int fsl_of_msi_init(
void)