summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/8xx
diff options
context:
space:
mode:
authorChristophe Leroy <christophe.leroy@csgroup.eu>2022-04-06 08:23:17 +0200
committerMichael Ellerman <mpe@ellerman.id.au>2022-05-11 23:06:39 +1000
commitacf9e575d889eb8806be2c8451e7ad12bf444b50 (patch)
tree3c3623068d601bff1dcb9b0fbbb3b856219b665a /arch/powerpc/platforms/8xx
parentd8d2af70b98109418bb16ff6638d7c1c4336f7fe (diff)
downloadlinux-stable-acf9e575d889eb8806be2c8451e7ad12bf444b50.tar.gz
linux-stable-acf9e575d889eb8806be2c8451e7ad12bf444b50.tar.bz2
linux-stable-acf9e575d889eb8806be2c8451e7ad12bf444b50.zip
powerpc/8xx: Move CPM interrupt controller into a dedicated file
CPM interrupt controller is quite standalone. Move it into a dedicated file. It will help for next step which will change it to a platform driver. This is pure code move, checkpatch report is ignored at this point, except one parenthesis alignment which would remain at the end of the series. All other points fly away with following patches. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/d3a7dc832d905bed14b35d83410cdb69a7ba20e8.1649226186.git.christophe.leroy@csgroup.eu
Diffstat (limited to 'arch/powerpc/platforms/8xx')
-rw-r--r--arch/powerpc/platforms/8xx/Makefile2
-rw-r--r--arch/powerpc/platforms/8xx/cpm1-ic.c151
-rw-r--r--arch/powerpc/platforms/8xx/cpm1.c139
3 files changed, 152 insertions, 140 deletions
diff --git a/arch/powerpc/platforms/8xx/Makefile b/arch/powerpc/platforms/8xx/Makefile
index 27a7c6f828e0..5a098f7d5d31 100644
--- a/arch/powerpc/platforms/8xx/Makefile
+++ b/arch/powerpc/platforms/8xx/Makefile
@@ -3,7 +3,7 @@
# Makefile for the PowerPC 8xx linux kernel.
#
obj-y += m8xx_setup.o machine_check.o pic.o
-obj-$(CONFIG_CPM1) += cpm1.o
+obj-$(CONFIG_CPM1) += cpm1.o cpm1-ic.o
obj-$(CONFIG_UCODE_PATCH) += micropatch.o
obj-$(CONFIG_MPC885ADS) += mpc885ads_setup.o
obj-$(CONFIG_MPC86XADS) += mpc86xads_setup.o
diff --git a/arch/powerpc/platforms/8xx/cpm1-ic.c b/arch/powerpc/platforms/8xx/cpm1-ic.c
new file mode 100644
index 000000000000..d5cf0ee7c07d
--- /dev/null
+++ b/arch/powerpc/platforms/8xx/cpm1-ic.c
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Interrupt controller for the
+ * Communication Processor Module.
+ * Copyright (c) 1997 Dan error_act (dmalek@jlc.net)
+ */
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/of_irq.h>
+#include <asm/cpm1.h>
+
+static cpic8xx_t __iomem *cpic_reg;
+
+static struct irq_domain *cpm_pic_host;
+
+static void cpm_mask_irq(struct irq_data *d)
+{
+ unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d);
+
+ clrbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
+}
+
+static void cpm_unmask_irq(struct irq_data *d)
+{
+ unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d);
+
+ setbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
+}
+
+static void cpm_end_irq(struct irq_data *d)
+{
+ unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d);
+
+ out_be32(&cpic_reg->cpic_cisr, (1 << cpm_vec));
+}
+
+static struct irq_chip cpm_pic = {
+ .name = "CPM PIC",
+ .irq_mask = cpm_mask_irq,
+ .irq_unmask = cpm_unmask_irq,
+ .irq_eoi = cpm_end_irq,
+};
+
+int cpm_get_irq(void)
+{
+ 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);
+ cpm_vec >>= 11;
+
+ return irq_linear_revmap(cpm_pic_host, cpm_vec);
+}
+
+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;
+}
+
+/*
+ * 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,
+};
+
+unsigned int __init cpm_pic_init(void)
+{
+ struct device_node *np = NULL;
+ struct resource res;
+ unsigned int sirq = 0, hwirq, eirq;
+ 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;
+ }
+
+ ret = of_address_to_resource(np, 0, &res);
+ if (ret)
+ goto end;
+
+ cpic_reg = ioremap(res.start, resource_size(&res));
+ if (cpic_reg == NULL)
+ goto end;
+
+ sirq = irq_of_parse_and_map(np, 0);
+ if (!sirq)
+ goto end;
+
+ /* 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);
+
+ 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;
+ }
+
+ /* 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;
+}
diff --git a/arch/powerpc/platforms/8xx/cpm1.c b/arch/powerpc/platforms/8xx/cpm1.c
index a3857df16472..bb38c8d8f8de 100644
--- a/arch/powerpc/platforms/8xx/cpm1.c
+++ b/arch/powerpc/platforms/8xx/cpm1.c
@@ -51,145 +51,6 @@
cpm8xx_t __iomem *cpmp; /* Pointer to comm processor space */
immap_t __iomem *mpc8xx_immr = (void __iomem *)VIRT_IMMR_BASE;
-static cpic8xx_t __iomem *cpic_reg;
-
-static struct irq_domain *cpm_pic_host;
-
-static void cpm_mask_irq(struct irq_data *d)
-{
- unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d);
-
- clrbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
-}
-
-static void cpm_unmask_irq(struct irq_data *d)
-{
- unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d);
-
- setbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
-}
-
-static void cpm_end_irq(struct irq_data *d)
-{
- unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d);
-
- out_be32(&cpic_reg->cpic_cisr, (1 << cpm_vec));
-}
-
-static struct irq_chip cpm_pic = {
- .name = "CPM PIC",
- .irq_mask = cpm_mask_irq,
- .irq_unmask = cpm_unmask_irq,
- .irq_eoi = cpm_end_irq,
-};
-
-int cpm_get_irq(void)
-{
- 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);
- cpm_vec >>= 11;
-
- return irq_linear_revmap(cpm_pic_host, cpm_vec);
-}
-
-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;
-}
-
-/*
- * 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,
-};
-
-unsigned int __init cpm_pic_init(void)
-{
- struct device_node *np = NULL;
- struct resource res;
- unsigned int sirq = 0, hwirq, eirq;
- 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;
- }
-
- ret = of_address_to_resource(np, 0, &res);
- if (ret)
- goto end;
-
- cpic_reg = ioremap(res.start, resource_size(&res));
- if (cpic_reg == NULL)
- goto end;
-
- sirq = irq_of_parse_and_map(np, 0);
- if (!sirq)
- goto end;
-
- /* 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);
-
- 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;
- }
-
- /* 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;
-}
void __init cpm_reset(void)
{