* [PATCH 2/5] powerpc/8xx: Convert CPM1 error interrupt handler to platform driver
2022-04-05 12:12 [PATCH 1/5] powerpc/8xx: Move CPM interrupt controller into a dedicated file Christophe Leroy
@ 2022-04-05 12:12 ` Christophe Leroy
2022-04-05 12:12 ` [PATCH 3/5] powerpc/8xx: Convert CPM1 interrupt controller to platform_device Christophe Leroy
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Christophe Leroy @ 2022-04-05 12:12 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: Christophe Leroy, linux-kernel, linuxppc-dev
Add CPM error interrupt as a standalone platform driver,
to simplify the init of CPM interrupt handler.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/platforms/8xx/cpm1-ic.c | 73 +++++++++++++++++-----------
1 file changed, 44 insertions(+), 29 deletions(-)
diff --git a/arch/powerpc/platforms/8xx/cpm1-ic.c b/arch/powerpc/platforms/8xx/cpm1-ic.c
index d5cf0ee7c07d..d22b4fc2d4cf 100644
--- a/arch/powerpc/platforms/8xx/cpm1-ic.c
+++ b/arch/powerpc/platforms/8xx/cpm1-ic.c
@@ -8,6 +8,7 @@
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/of_irq.h>
+#include <linux/platform_device.h>
#include <asm/cpm1.h>
static cpic8xx_t __iomem *cpic_reg;
@@ -67,17 +68,6 @@ static int cpm_pic_host_map(struct irq_domain *h, unsigned int virq,
return 0;
}
-/*
- * The CPM can generate the error interrupt when there is a race condition
- * between generating and masking interrupts. All we have to do is ACK it
- * and return. This is a no-op function so we don't need any special
- * tests in the interrupt handler.
- */
-static irqreturn_t cpm_error_interrupt(int irq, void *dev)
-{
- return IRQ_HANDLED;
-}
-
static const struct irq_domain_ops cpm_pic_host_ops = {
.map = cpm_pic_host_map,
};
@@ -86,7 +76,7 @@ unsigned int __init cpm_pic_init(void)
{
struct device_node *np = NULL;
struct resource res;
- unsigned int sirq = 0, hwirq, eirq;
+ unsigned int sirq = 0, hwirq;
int ret;
pr_debug("cpm_pic_init\n");
@@ -126,26 +116,51 @@ unsigned int __init cpm_pic_init(void)
goto end;
}
- /* Install our own error handler. */
- np = of_find_compatible_node(NULL, NULL, "fsl,cpm1");
- if (np == NULL)
- np = of_find_node_by_type(NULL, "cpm");
- if (np == NULL) {
- printk(KERN_ERR "CPM PIC init: can not find cpm node\n");
- goto end;
- }
-
- eirq = irq_of_parse_and_map(np, 0);
- if (!eirq)
- goto end;
-
- if (request_irq(eirq, cpm_error_interrupt, IRQF_NO_THREAD, "error",
- NULL))
- printk(KERN_ERR "Could not allocate CPM error IRQ!");
-
setbits32(&cpic_reg->cpic_cicr, CICR_IEN);
end:
of_node_put(np);
return sirq;
}
+
+/*
+ * The CPM can generate the error interrupt when there is a race condition
+ * between generating and masking interrupts. All we have to do is ACK it
+ * and return. This is a no-op function so we don't need any special
+ * tests in the interrupt handler.
+ */
+static irqreturn_t cpm_error_interrupt(int irq, void *dev)
+{
+ return IRQ_HANDLED;
+}
+
+static int cpm_error_probe(struct platform_device *pdev)
+{
+ int irq;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
+
+ return request_irq(irq, cpm_error_interrupt, IRQF_NO_THREAD, "error", NULL);
+}
+
+static const struct of_device_id cpm_error_ids[] = {
+ { .compatible = "fsl,cpm1" },
+ { .type = "cpm" },
+ {},
+};
+
+static struct platform_driver cpm_error_driver = {
+ .driver = {
+ .name = "cpm-error",
+ .of_match_table = cpm_error_ids,
+ },
+ .probe = cpm_error_probe,
+};
+
+static int __init cpm_error_init(void)
+{
+ return platform_driver_register(&cpm_error_driver);
+}
+subsys_initcall(cpm_error_init);
--
2.35.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/5] powerpc/8xx: Convert CPM1 interrupt controller to platform_device
2022-04-05 12:12 [PATCH 1/5] powerpc/8xx: Move CPM interrupt controller into a dedicated file Christophe Leroy
2022-04-05 12:12 ` [PATCH 2/5] powerpc/8xx: Convert CPM1 error interrupt handler to platform driver Christophe Leroy
@ 2022-04-05 12:12 ` Christophe Leroy
2022-04-05 12:12 ` [PATCH 4/5] powerpc/8xx: Remove mpc8xx_pics_init() Christophe Leroy
2022-04-05 12:12 ` [PATCH 5/5] powerpc/8xx: Use kmalloced data structure instead of global static Christophe Leroy
3 siblings, 0 replies; 5+ messages in thread
From: Christophe Leroy @ 2022-04-05 12:12 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: Christophe Leroy, linux-kernel, linuxppc-dev
In the same logic as commit be7ecbd240b2 ("soc: fsl: qe: convert QE
interrupt controller to platform_device"), convert CPM1 interrupt
controller to platform_device.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/platforms/8xx/cpm1-ic.c | 90 ++++++++++++++-----------
arch/powerpc/platforms/8xx/m8xx_setup.c | 14 ----
arch/powerpc/platforms/8xx/pic.c | 2 -
3 files changed, 50 insertions(+), 56 deletions(-)
diff --git a/arch/powerpc/platforms/8xx/cpm1-ic.c b/arch/powerpc/platforms/8xx/cpm1-ic.c
index d22b4fc2d4cf..6f9765597a6d 100644
--- a/arch/powerpc/platforms/8xx/cpm1-ic.c
+++ b/arch/powerpc/platforms/8xx/cpm1-ic.c
@@ -7,7 +7,6 @@
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
-#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <asm/cpm1.h>
@@ -43,7 +42,7 @@ static struct irq_chip cpm_pic = {
.irq_eoi = cpm_end_irq,
};
-int cpm_get_irq(void)
+static int cpm_get_irq(void)
{
int cpm_vec;
@@ -58,11 +57,14 @@ int cpm_get_irq(void)
return irq_linear_revmap(cpm_pic_host, cpm_vec);
}
+static void cpm_cascade(struct irq_desc *desc)
+{
+ generic_handle_irq(cpm_get_irq());
+}
+
static int cpm_pic_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
- pr_debug("cpm_pic_host_map(%d, 0x%lx)\n", virq, hw);
-
irq_set_status_flags(virq, IRQ_LEVEL);
irq_set_chip_and_handler(virq, &cpm_pic, handle_fasteoi_irq);
return 0;
@@ -72,56 +74,64 @@ static const struct irq_domain_ops cpm_pic_host_ops = {
.map = cpm_pic_host_map,
};
-unsigned int __init cpm_pic_init(void)
+static int cpm_pic_probe(struct platform_device *pdev)
{
- struct device_node *np = NULL;
- struct resource res;
- unsigned int sirq = 0, hwirq;
- int ret;
-
- pr_debug("cpm_pic_init\n");
-
- np = of_find_compatible_node(NULL, NULL, "fsl,cpm1-pic");
- if (np == NULL)
- np = of_find_compatible_node(NULL, "cpm-pic", "CPM");
- if (np == NULL) {
- printk(KERN_ERR "CPM PIC init: can not find cpm-pic node\n");
- return sirq;
- }
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ int irq;
- ret = of_address_to_resource(np, 0, &res);
- if (ret)
- goto end;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
- cpic_reg = ioremap(res.start, resource_size(&res));
- if (cpic_reg == NULL)
- goto end;
+ cpic_reg = devm_ioremap(dev, res->start, resource_size(res));
+ if (!cpic_reg)
+ return -ENODEV;
- sirq = irq_of_parse_and_map(np, 0);
- if (!sirq)
- goto end;
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
/* Initialize the CPM interrupt controller. */
- hwirq = (unsigned int)virq_to_hw(sirq);
out_be32(&cpic_reg->cpic_cicr,
- (CICR_SCD_SCC4 | CICR_SCC_SCC3 | CICR_SCB_SCC2 | CICR_SCA_SCC1) |
- ((hwirq/2) << 13) | CICR_HP_MASK);
+ (CICR_SCD_SCC4 | CICR_SCC_SCC3 | CICR_SCB_SCC2 | CICR_SCA_SCC1) |
+ ((virq_to_hw(irq) / 2) << 13) | CICR_HP_MASK);
out_be32(&cpic_reg->cpic_cimr, 0);
- cpm_pic_host = irq_domain_add_linear(np, 64, &cpm_pic_host_ops, NULL);
- if (cpm_pic_host == NULL) {
- printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
- sirq = 0;
- goto end;
- }
+ cpm_pic_host = irq_domain_add_linear(dev->of_node, 64, &cpm_pic_host_ops, NULL);
+ if (!cpm_pic_host)
+ return -ENODEV;
+
+ irq_set_chained_handler(irq, cpm_cascade);
setbits32(&cpic_reg->cpic_cicr, CICR_IEN);
-end:
- of_node_put(np);
- return sirq;
+ return 0;
+}
+
+static const struct of_device_id cpm_pic_match[] = {
+ {
+ .compatible = "fsl,cpm1-pic",
+ }, {
+ .type = "cpm-pic",
+ .compatible = "CPM",
+ }, {},
+};
+
+static struct platform_driver cpm_pic_driver = {
+ .driver = {
+ .name = "cpm-pic",
+ .of_match_table = cpm_pic_match,
+ },
+ .probe = cpm_pic_probe,
+};
+
+static int __init cpm_pic_init(void)
+{
+ return platform_driver_register(&cpm_pic_driver);
}
+arch_initcall(cpm_pic_init);
/*
* The CPM can generate the error interrupt when there is a race condition
diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c
index df4d57d07f9a..a03ba0ad7312 100644
--- a/arch/powerpc/platforms/8xx/m8xx_setup.c
+++ b/arch/powerpc/platforms/8xx/m8xx_setup.c
@@ -28,9 +28,6 @@
#include "mpc8xx.h"
-extern int cpm_pic_init(void);
-extern int cpm_get_irq(void);
-
/* A place holder for time base interrupts, if they are ever enabled. */
static irqreturn_t timebase_interrupt(int irq, void *dev)
{
@@ -208,11 +205,6 @@ void __noreturn mpc8xx_restart(char *cmd)
panic("Restart failed\n");
}
-static void cpm_cascade(struct irq_desc *desc)
-{
- generic_handle_irq(cpm_get_irq());
-}
-
/* Initialize the internal interrupt controllers. The number of
* interrupts supported can vary with the processor type, and the
* 82xx family can have up to 64.
@@ -221,14 +213,8 @@ static void cpm_cascade(struct irq_desc *desc)
*/
void __init mpc8xx_pics_init(void)
{
- int irq;
-
if (mpc8xx_pic_init()) {
printk(KERN_ERR "Failed interrupt 8xx controller initialization\n");
return;
}
-
- irq = cpm_pic_init();
- if (irq)
- irq_set_chained_handler(irq, cpm_cascade);
}
diff --git a/arch/powerpc/platforms/8xx/pic.c b/arch/powerpc/platforms/8xx/pic.c
index 04a6abf14c29..eaa16338cc4b 100644
--- a/arch/powerpc/platforms/8xx/pic.c
+++ b/arch/powerpc/platforms/8xx/pic.c
@@ -14,8 +14,6 @@
#define PIC_VEC_SPURRIOUS 15
-extern int cpm_get_irq(struct pt_regs *regs);
-
static struct irq_domain *mpc8xx_pic_host;
static unsigned long mpc8xx_cached_irq_mask;
static sysconf8xx_t __iomem *siu_reg;
--
2.35.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 4/5] powerpc/8xx: Remove mpc8xx_pics_init()
2022-04-05 12:12 [PATCH 1/5] powerpc/8xx: Move CPM interrupt controller into a dedicated file Christophe Leroy
2022-04-05 12:12 ` [PATCH 2/5] powerpc/8xx: Convert CPM1 error interrupt handler to platform driver Christophe Leroy
2022-04-05 12:12 ` [PATCH 3/5] powerpc/8xx: Convert CPM1 interrupt controller to platform_device Christophe Leroy
@ 2022-04-05 12:12 ` Christophe Leroy
2022-04-05 12:12 ` [PATCH 5/5] powerpc/8xx: Use kmalloced data structure instead of global static Christophe Leroy
3 siblings, 0 replies; 5+ messages in thread
From: Christophe Leroy @ 2022-04-05 12:12 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: Christophe Leroy, linux-kernel, linuxppc-dev
mpc8xx_pics_init() is now only a trampoline to
mpc8xx_pic_init().
Remove mpc8xx_pics_init() and use mpc8xx_pic_init()
directly.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/platforms/8xx/adder875.c | 2 +-
arch/powerpc/platforms/8xx/ep88xc.c | 2 +-
arch/powerpc/platforms/8xx/m8xx_setup.c | 14 --------------
arch/powerpc/platforms/8xx/mpc86xads_setup.c | 2 +-
arch/powerpc/platforms/8xx/mpc885ads_setup.c | 2 +-
arch/powerpc/platforms/8xx/mpc8xx.h | 1 -
arch/powerpc/platforms/8xx/tqm8xx_setup.c | 2 +-
7 files changed, 5 insertions(+), 20 deletions(-)
diff --git a/arch/powerpc/platforms/8xx/adder875.c b/arch/powerpc/platforms/8xx/adder875.c
index 651486acb896..9b5c0c181fa3 100644
--- a/arch/powerpc/platforms/8xx/adder875.c
+++ b/arch/powerpc/platforms/8xx/adder875.c
@@ -104,7 +104,7 @@ define_machine(adder875) {
.name = "Adder MPC875",
.probe = adder875_probe,
.setup_arch = adder875_setup,
- .init_IRQ = mpc8xx_pics_init,
+ .init_IRQ = mpc8xx_pic_init,
.get_irq = mpc8xx_get_irq,
.restart = mpc8xx_restart,
.calibrate_decr = generic_calibrate_decr,
diff --git a/arch/powerpc/platforms/8xx/ep88xc.c b/arch/powerpc/platforms/8xx/ep88xc.c
index ebcf34a14789..7526ef88bd33 100644
--- a/arch/powerpc/platforms/8xx/ep88xc.c
+++ b/arch/powerpc/platforms/8xx/ep88xc.c
@@ -166,7 +166,7 @@ define_machine(ep88xc) {
.name = "Embedded Planet EP88xC",
.probe = ep88xc_probe,
.setup_arch = ep88xc_setup_arch,
- .init_IRQ = mpc8xx_pics_init,
+ .init_IRQ = mpc8xx_pic_init,
.get_irq = mpc8xx_get_irq,
.restart = mpc8xx_restart,
.calibrate_decr = mpc8xx_calibrate_decr,
diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c
index a03ba0ad7312..15a09b15aaa4 100644
--- a/arch/powerpc/platforms/8xx/m8xx_setup.c
+++ b/arch/powerpc/platforms/8xx/m8xx_setup.c
@@ -204,17 +204,3 @@ void __noreturn mpc8xx_restart(char *cmd)
in_8(&clk_r->res[0]);
panic("Restart failed\n");
}
-
-/* Initialize the internal interrupt controllers. The number of
- * interrupts supported can vary with the processor type, and the
- * 82xx family can have up to 64.
- * External interrupts can be either edge or level triggered, and
- * need to be initialized by the appropriate driver.
- */
-void __init mpc8xx_pics_init(void)
-{
- if (mpc8xx_pic_init()) {
- printk(KERN_ERR "Failed interrupt 8xx controller initialization\n");
- return;
- }
-}
diff --git a/arch/powerpc/platforms/8xx/mpc86xads_setup.c b/arch/powerpc/platforms/8xx/mpc86xads_setup.c
index 8d02f5ff4481..a82d69e8bb01 100644
--- a/arch/powerpc/platforms/8xx/mpc86xads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc86xads_setup.c
@@ -140,7 +140,7 @@ define_machine(mpc86x_ads) {
.name = "MPC86x ADS",
.probe = mpc86xads_probe,
.setup_arch = mpc86xads_setup_arch,
- .init_IRQ = mpc8xx_pics_init,
+ .init_IRQ = mpc8xx_pic_init,
.get_irq = mpc8xx_get_irq,
.restart = mpc8xx_restart,
.calibrate_decr = mpc8xx_calibrate_decr,
diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
index a0c83c1905c6..e02290175a19 100644
--- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
@@ -216,7 +216,7 @@ define_machine(mpc885_ads) {
.name = "Freescale MPC885 ADS",
.probe = mpc885ads_probe,
.setup_arch = mpc885ads_setup_arch,
- .init_IRQ = mpc8xx_pics_init,
+ .init_IRQ = mpc8xx_pic_init,
.get_irq = mpc8xx_get_irq,
.restart = mpc8xx_restart,
.calibrate_decr = mpc8xx_calibrate_decr,
diff --git a/arch/powerpc/platforms/8xx/mpc8xx.h b/arch/powerpc/platforms/8xx/mpc8xx.h
index 31cc2ecace42..79fae3324866 100644
--- a/arch/powerpc/platforms/8xx/mpc8xx.h
+++ b/arch/powerpc/platforms/8xx/mpc8xx.h
@@ -15,7 +15,6 @@ extern void __noreturn mpc8xx_restart(char *cmd);
extern void mpc8xx_calibrate_decr(void);
extern int mpc8xx_set_rtc_time(struct rtc_time *tm);
extern void mpc8xx_get_rtc_time(struct rtc_time *tm);
-extern void mpc8xx_pics_init(void);
extern unsigned int mpc8xx_get_irq(void);
#endif /* __MPC8xx_H */
diff --git a/arch/powerpc/platforms/8xx/tqm8xx_setup.c b/arch/powerpc/platforms/8xx/tqm8xx_setup.c
index 4cea8b1afa44..7f1131545da1 100644
--- a/arch/powerpc/platforms/8xx/tqm8xx_setup.c
+++ b/arch/powerpc/platforms/8xx/tqm8xx_setup.c
@@ -142,7 +142,7 @@ define_machine(tqm8xx) {
.name = "TQM8xx",
.probe = tqm8xx_probe,
.setup_arch = tqm8xx_setup_arch,
- .init_IRQ = mpc8xx_pics_init,
+ .init_IRQ = mpc8xx_pic_init,
.get_irq = mpc8xx_get_irq,
.restart = mpc8xx_restart,
.calibrate_decr = mpc8xx_calibrate_decr,
--
2.35.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 5/5] powerpc/8xx: Use kmalloced data structure instead of global static
2022-04-05 12:12 [PATCH 1/5] powerpc/8xx: Move CPM interrupt controller into a dedicated file Christophe Leroy
` (2 preceding siblings ...)
2022-04-05 12:12 ` [PATCH 4/5] powerpc/8xx: Remove mpc8xx_pics_init() Christophe Leroy
@ 2022-04-05 12:12 ` Christophe Leroy
3 siblings, 0 replies; 5+ messages in thread
From: Christophe Leroy @ 2022-04-05 12:12 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: Christophe Leroy, linux-kernel, linuxppc-dev
Use a kmalloced data structure to store interrupt controller internal
data instead of static global variables.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/platforms/8xx/cpm1-ic.c | 48 +++++++++++++++++-----------
1 file changed, 30 insertions(+), 18 deletions(-)
diff --git a/arch/powerpc/platforms/8xx/cpm1-ic.c b/arch/powerpc/platforms/8xx/cpm1-ic.c
index 6f9765597a6d..a18fc7c99f83 100644
--- a/arch/powerpc/platforms/8xx/cpm1-ic.c
+++ b/arch/powerpc/platforms/8xx/cpm1-ic.c
@@ -10,29 +10,33 @@
#include <linux/platform_device.h>
#include <asm/cpm1.h>
-static cpic8xx_t __iomem *cpic_reg;
-
-static struct irq_domain *cpm_pic_host;
+struct cpm_pic_data {
+ cpic8xx_t __iomem *reg;
+ struct irq_domain *host;
+};
static void cpm_mask_irq(struct irq_data *d)
{
+ struct cpm_pic_data *data = irq_data_get_irq_chip_data(d);
unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d);
- clrbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
+ clrbits32(&data->reg->cpic_cimr, (1 << cpm_vec));
}
static void cpm_unmask_irq(struct irq_data *d)
{
+ struct cpm_pic_data *data = irq_data_get_irq_chip_data(d);
unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d);
- setbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
+ setbits32(&data->reg->cpic_cimr, (1 << cpm_vec));
}
static void cpm_end_irq(struct irq_data *d)
{
+ struct cpm_pic_data *data = irq_data_get_irq_chip_data(d);
unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d);
- out_be32(&cpic_reg->cpic_cisr, (1 << cpm_vec));
+ out_be32(&data->reg->cpic_cisr, (1 << cpm_vec));
}
static struct irq_chip cpm_pic = {
@@ -42,29 +46,31 @@ static struct irq_chip cpm_pic = {
.irq_eoi = cpm_end_irq,
};
-static int cpm_get_irq(void)
+static int cpm_get_irq(struct irq_desc *desc)
{
+ struct cpm_pic_data *data = irq_desc_get_handler_data(desc);
int cpm_vec;
/*
* Get the vector by setting the ACK bit and then reading
* the register.
*/
- out_be16(&cpic_reg->cpic_civr, 1);
- cpm_vec = in_be16(&cpic_reg->cpic_civr);
+ out_be16(&data->reg->cpic_civr, 1);
+ cpm_vec = in_be16(&data->reg->cpic_civr);
cpm_vec >>= 11;
- return irq_linear_revmap(cpm_pic_host, cpm_vec);
+ return irq_linear_revmap(data->host, cpm_vec);
}
static void cpm_cascade(struct irq_desc *desc)
{
- generic_handle_irq(cpm_get_irq());
+ generic_handle_irq(cpm_get_irq(desc));
}
static int cpm_pic_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
+ irq_set_chip_data(virq, h->host_data);
irq_set_status_flags(virq, IRQ_LEVEL);
irq_set_chip_and_handler(virq, &cpm_pic, handle_fasteoi_irq);
return 0;
@@ -79,13 +85,18 @@ static int cpm_pic_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct resource *res;
int irq;
+ struct cpm_pic_data *data;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENODEV;
- cpic_reg = devm_ioremap(dev, res->start, resource_size(res));
- if (!cpic_reg)
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->reg = devm_ioremap(dev, res->start, resource_size(res));
+ if (!data->reg)
return -ENODEV;
irq = platform_get_irq(pdev, 0);
@@ -93,19 +104,20 @@ static int cpm_pic_probe(struct platform_device *pdev)
return irq;
/* Initialize the CPM interrupt controller. */
- out_be32(&cpic_reg->cpic_cicr,
+ out_be32(&data->reg->cpic_cicr,
(CICR_SCD_SCC4 | CICR_SCC_SCC3 | CICR_SCB_SCC2 | CICR_SCA_SCC1) |
((virq_to_hw(irq) / 2) << 13) | CICR_HP_MASK);
- out_be32(&cpic_reg->cpic_cimr, 0);
+ out_be32(&data->reg->cpic_cimr, 0);
- cpm_pic_host = irq_domain_add_linear(dev->of_node, 64, &cpm_pic_host_ops, NULL);
- if (!cpm_pic_host)
+ data->host = irq_domain_add_linear(dev->of_node, 64, &cpm_pic_host_ops, data);
+ if (!data->host)
return -ENODEV;
+ irq_set_handler_data(irq, data);
irq_set_chained_handler(irq, cpm_cascade);
- setbits32(&cpic_reg->cpic_cicr, CICR_IEN);
+ setbits32(&data->reg->cpic_cicr, CICR_IEN);
return 0;
}
--
2.35.1
^ permalink raw reply related [flat|nested] 5+ messages in thread