0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0014
0015 #include <linux/irqchip.h>
0016 #include <linux/irqchip/arm-gic.h>
0017 #include <linux/msi.h>
0018 #include <linux/of.h>
0019 #include <linux/of_address.h>
0020 #include <linux/of_irq.h>
0021 #include <linux/of_pci.h>
0022 #include <linux/pci.h>
0023 #include <linux/slab.h>
0024
0025 #include <asm/irq.h>
0026 #include <asm/msi.h>
0027
0028
0029 #define ALPINE_MSIX_SPI_TARGET_CLUSTER0 BIT(16)
0030
0031 struct alpine_msix_data {
0032 spinlock_t msi_map_lock;
0033 phys_addr_t addr;
0034 u32 spi_first;
0035 u32 num_spis;
0036 unsigned long *msi_map;
0037 };
0038
0039 static void alpine_msix_mask_msi_irq(struct irq_data *d)
0040 {
0041 pci_msi_mask_irq(d);
0042 irq_chip_mask_parent(d);
0043 }
0044
0045 static void alpine_msix_unmask_msi_irq(struct irq_data *d)
0046 {
0047 pci_msi_unmask_irq(d);
0048 irq_chip_unmask_parent(d);
0049 }
0050
0051 static struct irq_chip alpine_msix_irq_chip = {
0052 .name = "MSIx",
0053 .irq_mask = alpine_msix_mask_msi_irq,
0054 .irq_unmask = alpine_msix_unmask_msi_irq,
0055 .irq_eoi = irq_chip_eoi_parent,
0056 .irq_set_affinity = irq_chip_set_affinity_parent,
0057 };
0058
0059 static int alpine_msix_allocate_sgi(struct alpine_msix_data *priv, int num_req)
0060 {
0061 int first;
0062
0063 spin_lock(&priv->msi_map_lock);
0064
0065 first = bitmap_find_next_zero_area(priv->msi_map, priv->num_spis, 0,
0066 num_req, 0);
0067 if (first >= priv->num_spis) {
0068 spin_unlock(&priv->msi_map_lock);
0069 return -ENOSPC;
0070 }
0071
0072 bitmap_set(priv->msi_map, first, num_req);
0073
0074 spin_unlock(&priv->msi_map_lock);
0075
0076 return priv->spi_first + first;
0077 }
0078
0079 static void alpine_msix_free_sgi(struct alpine_msix_data *priv, unsigned sgi,
0080 int num_req)
0081 {
0082 int first = sgi - priv->spi_first;
0083
0084 spin_lock(&priv->msi_map_lock);
0085
0086 bitmap_clear(priv->msi_map, first, num_req);
0087
0088 spin_unlock(&priv->msi_map_lock);
0089 }
0090
0091 static void alpine_msix_compose_msi_msg(struct irq_data *data,
0092 struct msi_msg *msg)
0093 {
0094 struct alpine_msix_data *priv = irq_data_get_irq_chip_data(data);
0095 phys_addr_t msg_addr = priv->addr;
0096
0097 msg_addr |= (data->hwirq << 3);
0098
0099 msg->address_hi = upper_32_bits(msg_addr);
0100 msg->address_lo = lower_32_bits(msg_addr);
0101 msg->data = 0;
0102 }
0103
0104 static struct msi_domain_info alpine_msix_domain_info = {
0105 .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
0106 MSI_FLAG_PCI_MSIX,
0107 .chip = &alpine_msix_irq_chip,
0108 };
0109
0110 static struct irq_chip middle_irq_chip = {
0111 .name = "alpine_msix_middle",
0112 .irq_mask = irq_chip_mask_parent,
0113 .irq_unmask = irq_chip_unmask_parent,
0114 .irq_eoi = irq_chip_eoi_parent,
0115 .irq_set_affinity = irq_chip_set_affinity_parent,
0116 .irq_compose_msi_msg = alpine_msix_compose_msi_msg,
0117 };
0118
0119 static int alpine_msix_gic_domain_alloc(struct irq_domain *domain,
0120 unsigned int virq, int sgi)
0121 {
0122 struct irq_fwspec fwspec;
0123 struct irq_data *d;
0124 int ret;
0125
0126 if (!is_of_node(domain->parent->fwnode))
0127 return -EINVAL;
0128
0129 fwspec.fwnode = domain->parent->fwnode;
0130 fwspec.param_count = 3;
0131 fwspec.param[0] = 0;
0132 fwspec.param[1] = sgi;
0133 fwspec.param[2] = IRQ_TYPE_EDGE_RISING;
0134
0135 ret = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec);
0136 if (ret)
0137 return ret;
0138
0139 d = irq_domain_get_irq_data(domain->parent, virq);
0140 d->chip->irq_set_type(d, IRQ_TYPE_EDGE_RISING);
0141
0142 return 0;
0143 }
0144
0145 static int alpine_msix_middle_domain_alloc(struct irq_domain *domain,
0146 unsigned int virq,
0147 unsigned int nr_irqs, void *args)
0148 {
0149 struct alpine_msix_data *priv = domain->host_data;
0150 int sgi, err, i;
0151
0152 sgi = alpine_msix_allocate_sgi(priv, nr_irqs);
0153 if (sgi < 0)
0154 return sgi;
0155
0156 for (i = 0; i < nr_irqs; i++) {
0157 err = alpine_msix_gic_domain_alloc(domain, virq + i, sgi + i);
0158 if (err)
0159 goto err_sgi;
0160
0161 irq_domain_set_hwirq_and_chip(domain, virq + i, sgi + i,
0162 &middle_irq_chip, priv);
0163 }
0164
0165 return 0;
0166
0167 err_sgi:
0168 irq_domain_free_irqs_parent(domain, virq, i - 1);
0169 alpine_msix_free_sgi(priv, sgi, nr_irqs);
0170 return err;
0171 }
0172
0173 static void alpine_msix_middle_domain_free(struct irq_domain *domain,
0174 unsigned int virq,
0175 unsigned int nr_irqs)
0176 {
0177 struct irq_data *d = irq_domain_get_irq_data(domain, virq);
0178 struct alpine_msix_data *priv = irq_data_get_irq_chip_data(d);
0179
0180 irq_domain_free_irqs_parent(domain, virq, nr_irqs);
0181 alpine_msix_free_sgi(priv, d->hwirq, nr_irqs);
0182 }
0183
0184 static const struct irq_domain_ops alpine_msix_middle_domain_ops = {
0185 .alloc = alpine_msix_middle_domain_alloc,
0186 .free = alpine_msix_middle_domain_free,
0187 };
0188
0189 static int alpine_msix_init_domains(struct alpine_msix_data *priv,
0190 struct device_node *node)
0191 {
0192 struct irq_domain *middle_domain, *msi_domain, *gic_domain;
0193 struct device_node *gic_node;
0194
0195 gic_node = of_irq_find_parent(node);
0196 if (!gic_node) {
0197 pr_err("Failed to find the GIC node\n");
0198 return -ENODEV;
0199 }
0200
0201 gic_domain = irq_find_host(gic_node);
0202 if (!gic_domain) {
0203 pr_err("Failed to find the GIC domain\n");
0204 return -ENXIO;
0205 }
0206
0207 middle_domain = irq_domain_add_tree(NULL,
0208 &alpine_msix_middle_domain_ops,
0209 priv);
0210 if (!middle_domain) {
0211 pr_err("Failed to create the MSIX middle domain\n");
0212 return -ENOMEM;
0213 }
0214
0215 middle_domain->parent = gic_domain;
0216
0217 msi_domain = pci_msi_create_irq_domain(of_node_to_fwnode(node),
0218 &alpine_msix_domain_info,
0219 middle_domain);
0220 if (!msi_domain) {
0221 pr_err("Failed to create MSI domain\n");
0222 irq_domain_remove(middle_domain);
0223 return -ENOMEM;
0224 }
0225
0226 return 0;
0227 }
0228
0229 static int alpine_msix_init(struct device_node *node,
0230 struct device_node *parent)
0231 {
0232 struct alpine_msix_data *priv;
0233 struct resource res;
0234 int ret;
0235
0236 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
0237 if (!priv)
0238 return -ENOMEM;
0239
0240 spin_lock_init(&priv->msi_map_lock);
0241
0242 ret = of_address_to_resource(node, 0, &res);
0243 if (ret) {
0244 pr_err("Failed to allocate resource\n");
0245 goto err_priv;
0246 }
0247
0248
0249
0250
0251
0252
0253
0254
0255 priv->addr = res.start & GENMASK_ULL(63,20);
0256 priv->addr |= ALPINE_MSIX_SPI_TARGET_CLUSTER0;
0257
0258 if (of_property_read_u32(node, "al,msi-base-spi", &priv->spi_first)) {
0259 pr_err("Unable to parse MSI base\n");
0260 ret = -EINVAL;
0261 goto err_priv;
0262 }
0263
0264 if (of_property_read_u32(node, "al,msi-num-spis", &priv->num_spis)) {
0265 pr_err("Unable to parse MSI numbers\n");
0266 ret = -EINVAL;
0267 goto err_priv;
0268 }
0269
0270 priv->msi_map = bitmap_zalloc(priv->num_spis, GFP_KERNEL);
0271 if (!priv->msi_map) {
0272 ret = -ENOMEM;
0273 goto err_priv;
0274 }
0275
0276 pr_debug("Registering %d msixs, starting at %d\n",
0277 priv->num_spis, priv->spi_first);
0278
0279 ret = alpine_msix_init_domains(priv, node);
0280 if (ret)
0281 goto err_map;
0282
0283 return 0;
0284
0285 err_map:
0286 bitmap_free(priv->msi_map);
0287 err_priv:
0288 kfree(priv);
0289 return ret;
0290 }
0291 IRQCHIP_DECLARE(alpine_msix, "al,alpine-msix", alpine_msix_init);