• Home
  • Raw
  • Download

Lines Matching +full:msi +full:- +full:base +full:- +full:spi

5  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
17 #include <linux/msi.h>
22 #include <dt-bindings/interrupt-controller/mvebu-icu.h>
41 void __iomem *base; member
55 if (atomic_cmpxchg(&icu->initialized, false, true)) in mvebu_icu_init()
58 /* Set Clear/Set ICU SPI message address in AP */ in mvebu_icu_init()
59 writel_relaxed(msg[0].address_hi, icu->base + ICU_SETSPI_NSR_AH); in mvebu_icu_init()
60 writel_relaxed(msg[0].address_lo, icu->base + ICU_SETSPI_NSR_AL); in mvebu_icu_init()
61 writel_relaxed(msg[1].address_hi, icu->base + ICU_CLRSPI_NSR_AH); in mvebu_icu_init()
62 writel_relaxed(msg[1].address_lo, icu->base + ICU_CLRSPI_NSR_AL); in mvebu_icu_init()
67 struct irq_data *d = irq_get_irq_data(desc->irq); in mvebu_icu_write_msg()
68 struct mvebu_icu_irq_data *icu_irqd = d->chip_data; in mvebu_icu_write_msg()
69 struct mvebu_icu *icu = icu_irqd->icu; in mvebu_icu_write_msg()
72 if (msg->address_lo || msg->address_hi) { in mvebu_icu_write_msg()
76 icu_int = msg->data | ICU_INT_ENABLE; in mvebu_icu_write_msg()
77 if (icu_irqd->type & IRQ_TYPE_EDGE_RISING) in mvebu_icu_write_msg()
79 icu_int |= icu_irqd->icu_group << ICU_GROUP_SHIFT; in mvebu_icu_write_msg()
81 /* De-configure the ICU */ in mvebu_icu_write_msg()
85 writel_relaxed(icu_int, icu->base + ICU_INT_CFG(d->hwirq)); in mvebu_icu_write_msg()
96 if (d->hwirq == ICU_SATA0_ICU_ID || d->hwirq == ICU_SATA1_ICU_ID) { in mvebu_icu_write_msg()
98 icu->base + ICU_INT_CFG(ICU_SATA0_ICU_ID)); in mvebu_icu_write_msg()
100 icu->base + ICU_INT_CFG(ICU_SATA1_ICU_ID)); in mvebu_icu_write_msg()
112 if (WARN_ON(fwspec->param_count < 3)) { in mvebu_icu_irq_domain_translate()
113 dev_err(icu->dev, "wrong ICU parameter count %d\n", in mvebu_icu_irq_domain_translate()
114 fwspec->param_count); in mvebu_icu_irq_domain_translate()
115 return -EINVAL; in mvebu_icu_irq_domain_translate()
119 icu_group = fwspec->param[0]; in mvebu_icu_irq_domain_translate()
122 dev_err(icu->dev, "wrong ICU group type %x\n", icu_group); in mvebu_icu_irq_domain_translate()
123 return -EINVAL; in mvebu_icu_irq_domain_translate()
126 *hwirq = fwspec->param[1]; in mvebu_icu_irq_domain_translate()
128 dev_err(icu->dev, "invalid interrupt number %ld\n", *hwirq); in mvebu_icu_irq_domain_translate()
129 return -EINVAL; in mvebu_icu_irq_domain_translate()
133 *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK; in mvebu_icu_irq_domain_translate()
150 return -ENOMEM; in mvebu_icu_irq_domain_alloc()
153 &icu_irqd->type); in mvebu_icu_irq_domain_alloc()
155 dev_err(icu->dev, "failed to translate ICU parameters\n"); in mvebu_icu_irq_domain_alloc()
159 icu_irqd->icu_group = fwspec->param[0]; in mvebu_icu_irq_domain_alloc()
160 icu_irqd->icu = icu; in mvebu_icu_irq_domain_alloc()
164 dev_err(icu->dev, "failed to allocate ICU interrupt in parent domain\n"); in mvebu_icu_irq_domain_alloc()
174 &icu->irq_chip, icu_irqd); in mvebu_icu_irq_domain_alloc()
176 dev_err(icu->dev, "failed to set the data to IRQ domain\n"); in mvebu_icu_irq_domain_alloc()
194 struct mvebu_icu_irq_data *icu_irqd = d->chip_data; in mvebu_icu_irq_domain_free()
210 struct device_node *node = pdev->dev.of_node; in mvebu_icu_probe()
215 icu = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_icu), in mvebu_icu_probe()
218 return -ENOMEM; in mvebu_icu_probe()
220 icu->dev = &pdev->dev; in mvebu_icu_probe()
223 icu->base = devm_ioremap_resource(&pdev->dev, res); in mvebu_icu_probe()
224 if (IS_ERR(icu->base)) { in mvebu_icu_probe()
225 dev_err(&pdev->dev, "Failed to map icu base address.\n"); in mvebu_icu_probe()
226 return PTR_ERR(icu->base); in mvebu_icu_probe()
229 icu->irq_chip.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, in mvebu_icu_probe()
231 (unsigned int)res->start); in mvebu_icu_probe()
232 if (!icu->irq_chip.name) in mvebu_icu_probe()
233 return -ENOMEM; in mvebu_icu_probe()
235 icu->irq_chip.irq_mask = irq_chip_mask_parent; in mvebu_icu_probe()
236 icu->irq_chip.irq_unmask = irq_chip_unmask_parent; in mvebu_icu_probe()
237 icu->irq_chip.irq_eoi = irq_chip_eoi_parent; in mvebu_icu_probe()
238 icu->irq_chip.irq_set_type = irq_chip_set_type_parent; in mvebu_icu_probe()
240 icu->irq_chip.irq_set_affinity = irq_chip_set_affinity_parent; in mvebu_icu_probe()
244 * We're probed after MSI domains have been resolved, so force in mvebu_icu_probe()
247 pdev->dev.msi_domain = of_msi_get_domain(&pdev->dev, node, in mvebu_icu_probe()
249 if (!pdev->dev.msi_domain) in mvebu_icu_probe()
250 return -EPROBE_DEFER; in mvebu_icu_probe()
252 gicp_dn = irq_domain_get_of_node(pdev->dev.msi_domain); in mvebu_icu_probe()
254 return -ENODEV; in mvebu_icu_probe()
258 * avoid unpredictable SPI assignments done by firmware. in mvebu_icu_probe()
261 u32 icu_int = readl_relaxed(icu->base + ICU_INT_CFG(i)); in mvebu_icu_probe()
263 writel_relaxed(0x0, icu->base + ICU_INT_CFG(i)); in mvebu_icu_probe()
266 icu->domain = in mvebu_icu_probe()
267 platform_msi_create_device_domain(&pdev->dev, ICU_MAX_IRQS, in mvebu_icu_probe()
270 if (!icu->domain) { in mvebu_icu_probe()
271 dev_err(&pdev->dev, "Failed to create ICU domain\n"); in mvebu_icu_probe()
272 return -ENOMEM; in mvebu_icu_probe()
279 { .compatible = "marvell,cp110-icu", },
286 .name = "mvebu-icu",