Skip to content

Commit c90847b

Browse files
SiFiveHollandConchuOD
authored andcommitted
cache: sifive_ccache: Partially convert to a platform driver
Commit 8ec99b0 ("irqchip/sifive-plic: Convert PLIC driver into a platform driver") broke ccache initialization because the PLIC IRQ domain is no longer available during an arch_initcall: [ 0.087229] irq: no irq domain found for interrupt-controller@c000000 ! [ 0.087255] CCACHE: Could not request IRQ 0 Fix this by moving the IRQ handling code to a platform driver. Fixes: 8ec99b0 ("irqchip/sifive-plic: Convert PLIC driver into a platform driver") Signed-off-by: Samuel Holland <[email protected]> Tested-by: Geert Uytterhoeven <[email protected]> Signed-off-by: Conor Dooley <[email protected]>
1 parent 4cece76 commit c90847b

File tree

1 file changed

+46
-26
lines changed

1 file changed

+46
-26
lines changed

drivers/cache/sifive_ccache.c

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#include <linux/of_address.h>
1616
#include <linux/device.h>
1717
#include <linux/bitfield.h>
18+
#include <linux/platform_device.h>
19+
#include <linux/property.h>
1820
#include <asm/cacheflush.h>
1921
#include <asm/cacheinfo.h>
2022
#include <asm/dma-noncoherent.h>
@@ -247,13 +249,49 @@ static irqreturn_t ccache_int_handler(int irq, void *device)
247249
return IRQ_HANDLED;
248250
}
249251

252+
static int sifive_ccache_probe(struct platform_device *pdev)
253+
{
254+
struct device *dev = &pdev->dev;
255+
unsigned long quirks;
256+
int intr_num, rc;
257+
258+
quirks = (unsigned long)device_get_match_data(dev);
259+
260+
intr_num = platform_irq_count(pdev);
261+
if (!intr_num)
262+
return dev_err_probe(dev, -ENODEV, "No interrupts property\n");
263+
264+
for (int i = 0; i < intr_num; i++) {
265+
if (i == DATA_UNCORR && (quirks & QUIRK_BROKEN_DATA_UNCORR))
266+
continue;
267+
268+
g_irq[i] = platform_get_irq(pdev, i);
269+
if (g_irq[i] < 0)
270+
return g_irq[i];
271+
272+
rc = devm_request_irq(dev, g_irq[i], ccache_int_handler, 0, "ccache_ecc", NULL);
273+
if (rc)
274+
return dev_err_probe(dev, rc, "Could not request IRQ %d\n", g_irq[i]);
275+
}
276+
277+
return 0;
278+
}
279+
280+
static struct platform_driver sifive_ccache_driver = {
281+
.probe = sifive_ccache_probe,
282+
.driver = {
283+
.name = "sifive_ccache",
284+
.of_match_table = sifive_ccache_ids,
285+
},
286+
};
287+
250288
static int __init sifive_ccache_init(void)
251289
{
252290
struct device_node *np;
253291
struct resource res;
254-
int i, rc, intr_num;
255292
const struct of_device_id *match;
256293
unsigned long quirks;
294+
int rc;
257295

258296
np = of_find_matching_node_and_match(NULL, sifive_ccache_ids, &match);
259297
if (!np)
@@ -277,28 +315,6 @@ static int __init sifive_ccache_init(void)
277315
goto err_unmap;
278316
}
279317

280-
intr_num = of_property_count_u32_elems(np, "interrupts");
281-
if (!intr_num) {
282-
pr_err("No interrupts property\n");
283-
rc = -ENODEV;
284-
goto err_unmap;
285-
}
286-
287-
for (i = 0; i < intr_num; i++) {
288-
g_irq[i] = irq_of_parse_and_map(np, i);
289-
290-
if (i == DATA_UNCORR && (quirks & QUIRK_BROKEN_DATA_UNCORR))
291-
continue;
292-
293-
rc = request_irq(g_irq[i], ccache_int_handler, 0, "ccache_ecc",
294-
NULL);
295-
if (rc) {
296-
pr_err("Could not request IRQ %d\n", g_irq[i]);
297-
goto err_free_irq;
298-
}
299-
}
300-
of_node_put(np);
301-
302318
#ifdef CONFIG_RISCV_NONSTANDARD_CACHE_OPS
303319
if (quirks & QUIRK_NONSTANDARD_CACHE_OPS) {
304320
riscv_cbom_block_size = SIFIVE_CCACHE_LINE_SIZE;
@@ -315,11 +331,15 @@ static int __init sifive_ccache_init(void)
315331
#ifdef CONFIG_DEBUG_FS
316332
setup_sifive_debug();
317333
#endif
334+
335+
rc = platform_driver_register(&sifive_ccache_driver);
336+
if (rc)
337+
goto err_unmap;
338+
339+
of_node_put(np);
340+
318341
return 0;
319342

320-
err_free_irq:
321-
while (--i >= 0)
322-
free_irq(g_irq[i], NULL);
323343
err_unmap:
324344
iounmap(ccache_base);
325345
err_node_put:

0 commit comments

Comments
 (0)