Lines Matching +full:msi +full:- +full:base +full:- +full:spi
5 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
18 #include <linux/msi.h>
23 #include "irq-msi-lib.h"
25 #include <dt-bindings/interrupt-controller/mvebu-icu.h>
55 void __iomem *base; member
71 struct mvebu_icu_msi_data *msi_data = d->host_data; in mvebu_icu_translate()
72 struct mvebu_icu *icu = msi_data->icu; in mvebu_icu_translate()
75 if (WARN_ON(fwspec->param_count != param_count)) { in mvebu_icu_translate()
76 dev_err(icu->dev, "wrong ICU parameter count %d\n", in mvebu_icu_translate()
77 fwspec->param_count); in mvebu_icu_translate()
78 return -EINVAL; in mvebu_icu_translate()
82 *hwirq = fwspec->param[1]; in mvebu_icu_translate()
83 *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK; in mvebu_icu_translate()
84 if (fwspec->param[0] != ICU_GRP_NSR) { in mvebu_icu_translate()
85 dev_err(icu->dev, "wrong ICU group type %x\n", in mvebu_icu_translate()
86 fwspec->param[0]); in mvebu_icu_translate()
87 return -EINVAL; in mvebu_icu_translate()
90 *hwirq = fwspec->param[0]; in mvebu_icu_translate()
91 *type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK; in mvebu_icu_translate()
99 if (msi_data->subset_data->icu_group == ICU_GRP_SEI) in mvebu_icu_translate()
104 dev_err(icu->dev, "invalid interrupt number %ld\n", *hwirq); in mvebu_icu_translate()
105 return -EINVAL; in mvebu_icu_translate()
115 const struct mvebu_icu_subset_data *subset = msi_data->subset_data; in mvebu_icu_init()
117 if (atomic_cmpxchg(&msi_data->initialized, false, true)) in mvebu_icu_init()
120 /* Set 'SET' ICU SPI message address in AP */ in mvebu_icu_init()
121 writel_relaxed(msg[0].address_hi, icu->base + subset->offset_set_ah); in mvebu_icu_init()
122 writel_relaxed(msg[0].address_lo, icu->base + subset->offset_set_al); in mvebu_icu_init()
124 if (subset->icu_group != ICU_GRP_NSR) in mvebu_icu_init()
127 /* Set 'CLEAR' ICU SPI message address in AP (level-MSI only) */ in mvebu_icu_init()
128 writel_relaxed(msg[1].address_hi, icu->base + subset->offset_clr_ah); in mvebu_icu_init()
129 writel_relaxed(msg[1].address_lo, icu->base + subset->offset_clr_al); in mvebu_icu_init()
135 irq_domain_set_hwirq_and_chip(domain, virq, hwirq, info->chip, info->chip_data); in mvebu_icu_msi_init()
141 arg->desc = desc; in mvebu_icu_set_desc()
142 arg->hwirq = (u32)desc->data.icookie.value; in mvebu_icu_set_desc()
147 struct mvebu_icu_msi_data *msi_data = d->chip_data; in mvebu_icu_write_msi_msg()
148 unsigned int icu_group = msi_data->subset_data->icu_group; in mvebu_icu_write_msi_msg()
150 struct mvebu_icu *icu = msi_data->icu; in mvebu_icu_write_msi_msg()
154 if (msg->address_lo || msg->address_hi) { in mvebu_icu_write_msi_msg()
158 icu_int = msg->data | ICU_INT_ENABLE; in mvebu_icu_write_msi_msg()
159 type = (unsigned int)(desc->data.icookie.value >> 32); in mvebu_icu_write_msi_msg()
164 /* De-configure the ICU */ in mvebu_icu_write_msi_msg()
168 writel_relaxed(icu_int, icu->base + ICU_INT_CFG(d->hwirq)); in mvebu_icu_write_msi_msg()
179 if (d->hwirq == ICU_SATA0_ICU_ID || d->hwirq == ICU_SATA1_ICU_ID) { in mvebu_icu_write_msi_msg()
180 writel_relaxed(icu_int, icu->base + ICU_INT_CFG(ICU_SATA0_ICU_ID)); in mvebu_icu_write_msi_msg()
181 writel_relaxed(icu_int, icu->base + ICU_INT_CFG(ICU_SATA1_ICU_ID)); in mvebu_icu_write_msi_msg()
187 .name = "ICU-NSR",
211 .name = "ICU-SEI",
249 .compatible = "marvell,cp110-icu-nsr",
253 .compatible = "marvell,cp110-icu-sei",
263 struct device *dev = &pdev->dev; in mvebu_icu_subset_probe()
268 return -ENOMEM; in mvebu_icu_subset_probe()
271 msi_data->icu = dev_get_drvdata(dev); in mvebu_icu_subset_probe()
272 msi_data->subset_data = &mvebu_icu_nsr_subset_data; in mvebu_icu_subset_probe()
274 msi_data->icu = dev_get_drvdata(dev->parent); in mvebu_icu_subset_probe()
275 msi_data->subset_data = of_device_get_match_data(dev); in mvebu_icu_subset_probe()
278 dev->msi.domain = of_msi_get_domain(dev, dev->of_node, DOMAIN_BUS_PLATFORM_MSI); in mvebu_icu_subset_probe()
279 if (!dev->msi.domain) in mvebu_icu_subset_probe()
280 return -EPROBE_DEFER; in mvebu_icu_subset_probe()
282 if (!irq_domain_get_of_node(dev->msi.domain)) in mvebu_icu_subset_probe()
283 return -ENODEV; in mvebu_icu_subset_probe()
285 sei = msi_data->subset_data->icu_group == ICU_GRP_SEI; in mvebu_icu_subset_probe()
290 dev_err(dev, "Failed to create ICU MSI domain\n"); in mvebu_icu_subset_probe()
291 return -ENOMEM; in mvebu_icu_subset_probe()
300 .name = "mvebu-icu-subset",
311 icu = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_icu), in mvebu_icu_probe()
314 return -ENOMEM; in mvebu_icu_probe()
316 icu->dev = &pdev->dev; in mvebu_icu_probe()
318 icu->base = devm_platform_ioremap_resource(pdev, 0); in mvebu_icu_probe()
319 if (IS_ERR(icu->base)) in mvebu_icu_probe()
320 return PTR_ERR(icu->base); in mvebu_icu_probe()
323 * Legacy bindings: ICU is one node with one MSI parent: force manually in mvebu_icu_probe()
326 * having its own MSI parent: call platform_populate(). in mvebu_icu_probe()
329 if (!of_get_child_count(pdev->dev.of_node)) in mvebu_icu_probe()
334 * avoid unpredictable SPI assignments done by firmware. in mvebu_icu_probe()
339 icu_int = readl_relaxed(icu->base + ICU_INT_CFG(i)); in mvebu_icu_probe()
345 writel_relaxed(0x0, icu->base + ICU_INT_CFG(i)); in mvebu_icu_probe()
353 return devm_of_platform_populate(&pdev->dev); in mvebu_icu_probe()
357 { .compatible = "marvell,cp110-icu", },
364 .name = "mvebu-icu",