root/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. its_fsl_mc_msi_prepare
  2. its_fsl_mc_msi_init

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Freescale Management Complex (MC) bus driver MSI support
   4  *
   5  * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
   6  * Author: German Rivera <German.Rivera@freescale.com>
   7  *
   8  */
   9 
  10 #include <linux/of_device.h>
  11 #include <linux/of_address.h>
  12 #include <linux/irq.h>
  13 #include <linux/msi.h>
  14 #include <linux/of.h>
  15 #include <linux/of_irq.h>
  16 #include <linux/fsl/mc.h>
  17 
  18 static struct irq_chip its_msi_irq_chip = {
  19         .name = "ITS-fMSI",
  20         .irq_mask = irq_chip_mask_parent,
  21         .irq_unmask = irq_chip_unmask_parent,
  22         .irq_eoi = irq_chip_eoi_parent,
  23         .irq_set_affinity = msi_domain_set_affinity
  24 };
  25 
  26 static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain,
  27                                   struct device *dev,
  28                                   int nvec, msi_alloc_info_t *info)
  29 {
  30         struct fsl_mc_device *mc_bus_dev;
  31         struct msi_domain_info *msi_info;
  32 
  33         if (!dev_is_fsl_mc(dev))
  34                 return -EINVAL;
  35 
  36         mc_bus_dev = to_fsl_mc_device(dev);
  37         if (!(mc_bus_dev->flags & FSL_MC_IS_DPRC))
  38                 return -EINVAL;
  39 
  40         /*
  41          * Set the device Id to be passed to the GIC-ITS:
  42          *
  43          * NOTE: This device id corresponds to the IOMMU stream ID
  44          * associated with the DPRC object (ICID).
  45          */
  46         info->scratchpad[0].ul = mc_bus_dev->icid;
  47         msi_info = msi_get_domain_info(msi_domain->parent);
  48 
  49         /* Allocate at least 32 MSIs, and always as a power of 2 */
  50         nvec = max_t(int, 32, roundup_pow_of_two(nvec));
  51         return msi_info->ops->msi_prepare(msi_domain->parent, dev, nvec, info);
  52 }
  53 
  54 static struct msi_domain_ops its_fsl_mc_msi_ops __ro_after_init = {
  55         .msi_prepare = its_fsl_mc_msi_prepare,
  56 };
  57 
  58 static struct msi_domain_info its_fsl_mc_msi_domain_info = {
  59         .flags  = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS),
  60         .ops    = &its_fsl_mc_msi_ops,
  61         .chip   = &its_msi_irq_chip,
  62 };
  63 
  64 static const struct of_device_id its_device_id[] = {
  65         {       .compatible     = "arm,gic-v3-its",     },
  66         {},
  67 };
  68 
  69 static int __init its_fsl_mc_msi_init(void)
  70 {
  71         struct device_node *np;
  72         struct irq_domain *parent;
  73         struct irq_domain *mc_msi_domain;
  74 
  75         for (np = of_find_matching_node(NULL, its_device_id); np;
  76              np = of_find_matching_node(np, its_device_id)) {
  77                 if (!of_device_is_available(np))
  78                         continue;
  79                 if (!of_property_read_bool(np, "msi-controller"))
  80                         continue;
  81 
  82                 parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS);
  83                 if (!parent || !msi_get_domain_info(parent)) {
  84                         pr_err("%pOF: unable to locate ITS domain\n", np);
  85                         continue;
  86                 }
  87 
  88                 mc_msi_domain = fsl_mc_msi_create_irq_domain(
  89                                                  of_node_to_fwnode(np),
  90                                                  &its_fsl_mc_msi_domain_info,
  91                                                  parent);
  92                 if (!mc_msi_domain) {
  93                         pr_err("%pOF: unable to create fsl-mc domain\n", np);
  94                         continue;
  95                 }
  96 
  97                 pr_info("fsl-mc MSI: %pOF domain created\n", np);
  98         }
  99 
 100         return 0;
 101 }
 102 
 103 early_initcall(its_fsl_mc_msi_init);

/* [<][>][^][v][top][bottom][index][help] */