linux/arch/powerpc/sysdev/mpic_msi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright 2006-2007, Michael Ellerman, IBM Corporation.
   4 */
   5
   6#include <linux/irq.h>
   7#include <linux/bitmap.h>
   8#include <linux/msi.h>
   9#include <asm/mpic.h>
  10#include <asm/prom.h>
  11#include <asm/hw_irq.h>
  12#include <asm/ppc-pci.h>
  13#include <asm/msi_bitmap.h>
  14
  15#include <sysdev/mpic.h>
  16
  17void mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq)
  18{
  19        /* The mpic calls this even when there is no allocator setup */
  20        if (!mpic->msi_bitmap.bitmap)
  21                return;
  22
  23        msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, hwirq);
  24}
  25
  26#ifdef CONFIG_MPIC_U3_HT_IRQS
  27static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
  28{
  29        irq_hw_number_t hwirq;
  30        const struct irq_domain_ops *ops = mpic->irqhost->ops;
  31        struct device_node *np;
  32        int flags, index, i;
  33        struct of_phandle_args oirq;
  34
  35        pr_debug("mpic: found U3, guessing msi allocator setup\n");
  36
  37        /* Reserve source numbers we know are reserved in the HW.
  38         *
  39         * This is a bit of a mix of U3 and U4 reserves but that's going
  40         * to work fine, we have plenty enugh numbers left so let's just
  41         * mark anything we don't like reserved.
  42         */
  43        for (i = 0;   i < 8;   i++)
  44                msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i);
  45
  46        for (i = 42;  i < 46;  i++)
  47                msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i);
  48
  49        for (i = 100; i < 105; i++)
  50                msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i);
  51
  52        for (i = 124; i < mpic->num_sources; i++)
  53                msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i);
  54
  55
  56        np = NULL;
  57        while ((np = of_find_all_nodes(np))) {
  58                pr_debug("mpic: mapping hwirqs for %pOF\n", np);
  59
  60                index = 0;
  61                while (of_irq_parse_one(np, index++, &oirq) == 0) {
  62                        ops->xlate(mpic->irqhost, NULL, oirq.args,
  63                                                oirq.args_count, &hwirq, &flags);
  64                        msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, hwirq);
  65                }
  66        }
  67
  68        return 0;
  69}
  70#else
  71static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
  72{
  73        return -1;
  74}
  75#endif
  76
  77int mpic_msi_init_allocator(struct mpic *mpic)
  78{
  79        int rc;
  80
  81        rc = msi_bitmap_alloc(&mpic->msi_bitmap, mpic->num_sources,
  82                              irq_domain_get_of_node(mpic->irqhost));
  83        if (rc)
  84                return rc;
  85
  86        rc = msi_bitmap_reserve_dt_hwirqs(&mpic->msi_bitmap);
  87        if (rc > 0) {
  88                if (mpic->flags & MPIC_U3_HT_IRQS)
  89                        rc = mpic_msi_reserve_u3_hwirqs(mpic);
  90
  91                if (rc) {
  92                        msi_bitmap_free(&mpic->msi_bitmap);
  93                        return rc;
  94                }
  95        }
  96
  97        return 0;
  98}
  99