summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/irqchip/irq-mvebu-icu.c57
1 files changed, 32 insertions, 25 deletions
diff --git a/drivers/irqchip/irq-mvebu-icu.c b/drivers/irqchip/irq-mvebu-icu.c
index 0f2655d7f19e..d09f220a2701 100644
--- a/drivers/irqchip/irq-mvebu-icu.c
+++ b/drivers/irqchip/irq-mvebu-icu.c
@@ -39,7 +39,6 @@
39struct mvebu_icu { 39struct mvebu_icu {
40 struct irq_chip irq_chip; 40 struct irq_chip irq_chip;
41 void __iomem *base; 41 void __iomem *base;
42 struct irq_domain *domain;
43 struct device *dev; 42 struct device *dev;
44 atomic_t initialized; 43 atomic_t initialized;
45}; 44};
@@ -204,11 +203,39 @@ static const struct irq_domain_ops mvebu_icu_domain_ops = {
204 .free = mvebu_icu_irq_domain_free, 203 .free = mvebu_icu_irq_domain_free,
205}; 204};
206 205
206static int mvebu_icu_subset_probe(struct platform_device *pdev)
207{
208 struct device_node *msi_parent_dn;
209 struct device *dev = &pdev->dev;
210 struct irq_domain *irq_domain;
211 struct mvebu_icu *icu;
212
213 icu = dev_get_drvdata(dev);
214
215 dev->msi_domain = of_msi_get_domain(dev, dev->of_node,
216 DOMAIN_BUS_PLATFORM_MSI);
217 if (!dev->msi_domain)
218 return -EPROBE_DEFER;
219
220 msi_parent_dn = irq_domain_get_of_node(dev->msi_domain);
221 if (!msi_parent_dn)
222 return -ENODEV;
223
224 irq_domain = platform_msi_create_device_tree_domain(dev, ICU_MAX_IRQS,
225 mvebu_icu_write_msg,
226 &mvebu_icu_domain_ops,
227 icu);
228 if (!irq_domain) {
229 dev_err(dev, "Failed to create ICU MSI domain\n");
230 return -ENOMEM;
231 }
232
233 return 0;
234}
235
207static int mvebu_icu_probe(struct platform_device *pdev) 236static int mvebu_icu_probe(struct platform_device *pdev)
208{ 237{
209 struct mvebu_icu *icu; 238 struct mvebu_icu *icu;
210 struct device_node *node = pdev->dev.of_node;
211 struct device_node *gicp_dn;
212 struct resource *res; 239 struct resource *res;
213 int i; 240 int i;
214 241
@@ -241,19 +268,6 @@ static int mvebu_icu_probe(struct platform_device *pdev)
241#endif 268#endif
242 269
243 /* 270 /*
244 * We're probed after MSI domains have been resolved, so force
245 * resolution here.
246 */
247 pdev->dev.msi_domain = of_msi_get_domain(&pdev->dev, node,
248 DOMAIN_BUS_PLATFORM_MSI);
249 if (!pdev->dev.msi_domain)
250 return -EPROBE_DEFER;
251
252 gicp_dn = irq_domain_get_of_node(pdev->dev.msi_domain);
253 if (!gicp_dn)
254 return -ENODEV;
255
256 /*
257 * Clean all ICU interrupts with type SPI_NSR, required to 271 * Clean all ICU interrupts with type SPI_NSR, required to
258 * avoid unpredictable SPI assignments done by firmware. 272 * avoid unpredictable SPI assignments done by firmware.
259 */ 273 */
@@ -267,16 +281,9 @@ static int mvebu_icu_probe(struct platform_device *pdev)
267 writel_relaxed(0x0, icu->base + ICU_INT_CFG(i)); 281 writel_relaxed(0x0, icu->base + ICU_INT_CFG(i));
268 } 282 }
269 283
270 icu->domain = 284 platform_set_drvdata(pdev, icu);
271 platform_msi_create_device_domain(&pdev->dev, ICU_MAX_IRQS,
272 mvebu_icu_write_msg,
273 &mvebu_icu_domain_ops, icu);
274 if (!icu->domain) {
275 dev_err(&pdev->dev, "Failed to create ICU domain\n");
276 return -ENOMEM;
277 }
278 285
279 return 0; 286 return mvebu_icu_subset_probe(pdev);
280} 287}
281 288
282static const struct of_device_id mvebu_icu_of_match[] = { 289static const struct of_device_id mvebu_icu_of_match[] = {