Lines Matching +full:message +full:- +full:handling +full:- +full:unit
5 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
23 #include <dt-bindings/interrupt-controller/mvebu-icu.h>
75 const struct mvebu_icu_subset_data *subset = msi_data->subset_data; in mvebu_icu_init()
77 if (atomic_cmpxchg(&msi_data->initialized, false, true)) in mvebu_icu_init()
80 /* Set 'SET' ICU SPI message address in AP */ in mvebu_icu_init()
81 writel_relaxed(msg[0].address_hi, icu->base + subset->offset_set_ah); in mvebu_icu_init()
82 writel_relaxed(msg[0].address_lo, icu->base + subset->offset_set_al); in mvebu_icu_init()
84 if (subset->icu_group != ICU_GRP_NSR) in mvebu_icu_init()
87 /* Set 'CLEAR' ICU SPI message address in AP (level-MSI only) */ in mvebu_icu_init()
88 writel_relaxed(msg[1].address_hi, icu->base + subset->offset_clr_ah); in mvebu_icu_init()
89 writel_relaxed(msg[1].address_lo, icu->base + subset->offset_clr_al); in mvebu_icu_init()
94 struct irq_data *d = irq_get_irq_data(desc->irq); in mvebu_icu_write_msg()
95 struct mvebu_icu_msi_data *msi_data = platform_msi_get_host_data(d->domain); in mvebu_icu_write_msg()
96 struct mvebu_icu_irq_data *icu_irqd = d->chip_data; in mvebu_icu_write_msg()
97 struct mvebu_icu *icu = icu_irqd->icu; in mvebu_icu_write_msg()
100 if (msg->address_lo || msg->address_hi) { in mvebu_icu_write_msg()
104 icu_int = msg->data | ICU_INT_ENABLE; in mvebu_icu_write_msg()
105 if (icu_irqd->type & IRQ_TYPE_EDGE_RISING) in mvebu_icu_write_msg()
107 icu_int |= icu_irqd->icu_group << ICU_GROUP_SHIFT; in mvebu_icu_write_msg()
109 /* De-configure the ICU */ in mvebu_icu_write_msg()
113 writel_relaxed(icu_int, icu->base + ICU_INT_CFG(d->hwirq)); in mvebu_icu_write_msg()
116 * The SATA unit has 2 ports, and a dedicated ICU entry per in mvebu_icu_write_msg()
118 * per SATA unit. To solve this conflict, we configure the 2 in mvebu_icu_write_msg()
124 if (d->hwirq == ICU_SATA0_ICU_ID || d->hwirq == ICU_SATA1_ICU_ID) { in mvebu_icu_write_msg()
126 icu->base + ICU_INT_CFG(ICU_SATA0_ICU_ID)); in mvebu_icu_write_msg()
128 icu->base + ICU_INT_CFG(ICU_SATA1_ICU_ID)); in mvebu_icu_write_msg()
133 .name = "ICU-NSR",
142 .name = "ICU-SEI",
159 if (WARN_ON(fwspec->param_count != param_count)) { in mvebu_icu_irq_domain_translate()
160 dev_err(icu->dev, "wrong ICU parameter count %d\n", in mvebu_icu_irq_domain_translate()
161 fwspec->param_count); in mvebu_icu_irq_domain_translate()
162 return -EINVAL; in mvebu_icu_irq_domain_translate()
166 *hwirq = fwspec->param[1]; in mvebu_icu_irq_domain_translate()
167 *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK; in mvebu_icu_irq_domain_translate()
168 if (fwspec->param[0] != ICU_GRP_NSR) { in mvebu_icu_irq_domain_translate()
169 dev_err(icu->dev, "wrong ICU group type %x\n", in mvebu_icu_irq_domain_translate()
170 fwspec->param[0]); in mvebu_icu_irq_domain_translate()
171 return -EINVAL; in mvebu_icu_irq_domain_translate()
174 *hwirq = fwspec->param[0]; in mvebu_icu_irq_domain_translate()
175 *type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK; in mvebu_icu_irq_domain_translate()
181 * handling unreliable. in mvebu_icu_irq_domain_translate()
183 if (msi_data->subset_data->icu_group == ICU_GRP_SEI) in mvebu_icu_irq_domain_translate()
188 dev_err(icu->dev, "invalid interrupt number %ld\n", *hwirq); in mvebu_icu_irq_domain_translate()
189 return -EINVAL; in mvebu_icu_irq_domain_translate()
203 struct mvebu_icu *icu = msi_data->icu; in mvebu_icu_irq_domain_alloc()
209 return -ENOMEM; in mvebu_icu_irq_domain_alloc()
212 &icu_irqd->type); in mvebu_icu_irq_domain_alloc()
214 dev_err(icu->dev, "failed to translate ICU parameters\n"); in mvebu_icu_irq_domain_alloc()
219 icu_irqd->icu_group = fwspec->param[0]; in mvebu_icu_irq_domain_alloc()
221 icu_irqd->icu_group = msi_data->subset_data->icu_group; in mvebu_icu_irq_domain_alloc()
222 icu_irqd->icu = icu; in mvebu_icu_irq_domain_alloc()
226 dev_err(icu->dev, "failed to allocate ICU interrupt in parent domain\n"); in mvebu_icu_irq_domain_alloc()
235 if (icu_irqd->icu_group == ICU_GRP_SEI) in mvebu_icu_irq_domain_alloc()
241 dev_err(icu->dev, "failed to set the data to IRQ domain\n"); in mvebu_icu_irq_domain_alloc()
259 struct mvebu_icu_irq_data *icu_irqd = d->chip_data; in mvebu_icu_irq_domain_free()
288 .compatible = "marvell,cp110-icu-nsr",
292 .compatible = "marvell,cp110-icu-sei",
302 struct device *dev = &pdev->dev; in mvebu_icu_subset_probe()
307 return -ENOMEM; in mvebu_icu_subset_probe()
310 msi_data->icu = dev_get_drvdata(dev); in mvebu_icu_subset_probe()
311 msi_data->subset_data = &mvebu_icu_nsr_subset_data; in mvebu_icu_subset_probe()
313 msi_data->icu = dev_get_drvdata(dev->parent); in mvebu_icu_subset_probe()
314 msi_data->subset_data = of_device_get_match_data(dev); in mvebu_icu_subset_probe()
317 dev->msi.domain = of_msi_get_domain(dev, dev->of_node, in mvebu_icu_subset_probe()
319 if (!dev->msi.domain) in mvebu_icu_subset_probe()
320 return -EPROBE_DEFER; in mvebu_icu_subset_probe()
322 msi_parent_dn = irq_domain_get_of_node(dev->msi.domain); in mvebu_icu_subset_probe()
324 return -ENODEV; in mvebu_icu_subset_probe()
332 return -ENOMEM; in mvebu_icu_subset_probe()
341 .name = "mvebu-icu-subset",
352 icu = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_icu), in mvebu_icu_probe()
355 return -ENOMEM; in mvebu_icu_probe()
357 icu->dev = &pdev->dev; in mvebu_icu_probe()
359 icu->base = devm_platform_ioremap_resource(pdev, 0); in mvebu_icu_probe()
360 if (IS_ERR(icu->base)) in mvebu_icu_probe()
361 return PTR_ERR(icu->base); in mvebu_icu_probe()
370 if (!of_get_child_count(pdev->dev.of_node)) in mvebu_icu_probe()
380 icu_int = readl_relaxed(icu->base + ICU_INT_CFG(i)); in mvebu_icu_probe()
386 writel_relaxed(0x0, icu->base + ICU_INT_CFG(i)); in mvebu_icu_probe()
394 return devm_of_platform_populate(&pdev->dev); in mvebu_icu_probe()
398 { .compatible = "marvell,cp110-icu", },
405 .name = "mvebu-icu",