blob: bedc902cee0ac805bb24a03a4805a92b8efebf57 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From 0172b31512827b9fd735df47751c7aa88b6aa5f6 Mon Sep 17 00:00:00 2001
2From: Zhao Qiang <qiang.zhao@nxp.com>
3Date: Thu, 27 Apr 2017 09:52:54 +0800
4Subject: [PATCH] irqchip/qeic: move qeic driver from drivers/soc/fsl/qe
5
6move the driver from drivers/soc/fsl/qe to drivers/irqchip,
7merge qe_ic.h and qe_ic.c into irq-qeic.c.
8
9Signed-off-by: Zhao Qiang <qiang.zhao@nxp.com>
10---
11 drivers/irqchip/irq-qeic.c | 597 ++++++++++++++++++++++++++++++++++++++++++++
12 drivers/soc/fsl/qe/Makefile | 2 +-
13 drivers/soc/fsl/qe/qe_ic.c | 508 -------------------------------------
14 drivers/soc/fsl/qe/qe_ic.h | 99 --------
15 4 files changed, 598 insertions(+), 608 deletions(-)
16 create mode 100644 drivers/irqchip/irq-qeic.c
17 delete mode 100644 drivers/soc/fsl/qe/qe_ic.c
18 delete mode 100644 drivers/soc/fsl/qe/qe_ic.h
19
20--- /dev/null
21+++ b/drivers/irqchip/irq-qeic.c
22@@ -0,0 +1,597 @@
23+// SPDX-License-Identifier: GPL-2.0-or-later
24+/*
25+ * drivers/irqchip/irq-qeic.c
26+ *
27+ * Copyright (C) 2016 Freescale Semiconductor, Inc. All rights reserved.
28+ *
29+ * Author: Li Yang <leoli@freescale.com>
30+ * Based on code from Shlomi Gridish <gridish@freescale.com>
31+ *
32+ * QUICC ENGINE Interrupt Controller
33+ */
34+
35+#include <linux/of_irq.h>
36+#include <linux/of_address.h>
37+#include <linux/kernel.h>
38+#include <linux/init.h>
39+#include <linux/errno.h>
40+#include <linux/reboot.h>
41+#include <linux/slab.h>
42+#include <linux/stddef.h>
43+#include <linux/sched.h>
44+#include <linux/signal.h>
45+#include <linux/device.h>
46+#include <linux/spinlock.h>
47+#include <asm/irq.h>
48+#include <asm/io.h>
49+#include <soc/fsl/qe/qe_ic.h>
50+
51+#define NR_QE_IC_INTS 64
52+
53+/* QE IC registers offset */
54+#define QEIC_CICR 0x00
55+#define QEIC_CIVEC 0x04
56+#define QEIC_CRIPNR 0x08
57+#define QEIC_CIPNR 0x0c
58+#define QEIC_CIPXCC 0x10
59+#define QEIC_CIPYCC 0x14
60+#define QEIC_CIPWCC 0x18
61+#define QEIC_CIPZCC 0x1c
62+#define QEIC_CIMR 0x20
63+#define QEIC_CRIMR 0x24
64+#define QEIC_CICNR 0x28
65+#define QEIC_CIPRTA 0x30
66+#define QEIC_CIPRTB 0x34
67+#define QEIC_CRICR 0x3c
68+#define QEIC_CHIVEC 0x60
69+
70+/* Interrupt priority registers */
71+#define CIPCC_SHIFT_PRI0 29
72+#define CIPCC_SHIFT_PRI1 26
73+#define CIPCC_SHIFT_PRI2 23
74+#define CIPCC_SHIFT_PRI3 20
75+#define CIPCC_SHIFT_PRI4 13
76+#define CIPCC_SHIFT_PRI5 10
77+#define CIPCC_SHIFT_PRI6 7
78+#define CIPCC_SHIFT_PRI7 4
79+
80+/* CICR priority modes */
81+#define CICR_GWCC 0x00040000
82+#define CICR_GXCC 0x00020000
83+#define CICR_GYCC 0x00010000
84+#define CICR_GZCC 0x00080000
85+#define CICR_GRTA 0x00200000
86+#define CICR_GRTB 0x00400000
87+#define CICR_HPIT_SHIFT 8
88+#define CICR_HPIT_MASK 0x00000300
89+#define CICR_HP_SHIFT 24
90+#define CICR_HP_MASK 0x3f000000
91+
92+/* CICNR */
93+#define CICNR_WCC1T_SHIFT 20
94+#define CICNR_ZCC1T_SHIFT 28
95+#define CICNR_YCC1T_SHIFT 12
96+#define CICNR_XCC1T_SHIFT 4
97+
98+/* CRICR */
99+#define CRICR_RTA1T_SHIFT 20
100+#define CRICR_RTB1T_SHIFT 28
101+
102+/* Signal indicator */
103+#define SIGNAL_MASK 3
104+#define SIGNAL_HIGH 2
105+#define SIGNAL_LOW 0
106+
107+struct qe_ic {
108+ /* Control registers offset */
109+ u32 __iomem *regs;
110+
111+ /* The remapper for this QEIC */
112+ struct irq_domain *irqhost;
113+
114+ /* The "linux" controller struct */
115+ struct irq_chip hc_irq;
116+
117+ /* VIRQ numbers of QE high/low irqs */
118+ unsigned int virq_high;
119+ unsigned int virq_low;
120+};
121+
122+/*
123+ * QE interrupt controller internal structure
124+ */
125+struct qe_ic_info {
126+ /* location of this source at the QIMR register. */
127+ u32 mask;
128+
129+ /* Mask register offset */
130+ u32 mask_reg;
131+
132+ /*
133+ * for grouped interrupts sources - the interrupt
134+ * code as appears at the group priority register
135+ */
136+ u8 pri_code;
137+
138+ /* Group priority register offset */
139+ u32 pri_reg;
140+};
141+
142+static DEFINE_RAW_SPINLOCK(qe_ic_lock);
143+
144+static struct qe_ic_info qe_ic_info[] = {
145+ [1] = {
146+ .mask = 0x00008000,
147+ .mask_reg = QEIC_CIMR,
148+ .pri_code = 0,
149+ .pri_reg = QEIC_CIPWCC,
150+ },
151+ [2] = {
152+ .mask = 0x00004000,
153+ .mask_reg = QEIC_CIMR,
154+ .pri_code = 1,
155+ .pri_reg = QEIC_CIPWCC,
156+ },
157+ [3] = {
158+ .mask = 0x00002000,
159+ .mask_reg = QEIC_CIMR,
160+ .pri_code = 2,
161+ .pri_reg = QEIC_CIPWCC,
162+ },
163+ [10] = {
164+ .mask = 0x00000040,
165+ .mask_reg = QEIC_CIMR,
166+ .pri_code = 1,
167+ .pri_reg = QEIC_CIPZCC,
168+ },
169+ [11] = {
170+ .mask = 0x00000020,
171+ .mask_reg = QEIC_CIMR,
172+ .pri_code = 2,
173+ .pri_reg = QEIC_CIPZCC,
174+ },
175+ [12] = {
176+ .mask = 0x00000010,
177+ .mask_reg = QEIC_CIMR,
178+ .pri_code = 3,
179+ .pri_reg = QEIC_CIPZCC,
180+ },
181+ [13] = {
182+ .mask = 0x00000008,
183+ .mask_reg = QEIC_CIMR,
184+ .pri_code = 4,
185+ .pri_reg = QEIC_CIPZCC,
186+ },
187+ [14] = {
188+ .mask = 0x00000004,
189+ .mask_reg = QEIC_CIMR,
190+ .pri_code = 5,
191+ .pri_reg = QEIC_CIPZCC,
192+ },
193+ [15] = {
194+ .mask = 0x00000002,
195+ .mask_reg = QEIC_CIMR,
196+ .pri_code = 6,
197+ .pri_reg = QEIC_CIPZCC,
198+ },
199+ [20] = {
200+ .mask = 0x10000000,
201+ .mask_reg = QEIC_CRIMR,
202+ .pri_code = 3,
203+ .pri_reg = QEIC_CIPRTA,
204+ },
205+ [25] = {
206+ .mask = 0x00800000,
207+ .mask_reg = QEIC_CRIMR,
208+ .pri_code = 0,
209+ .pri_reg = QEIC_CIPRTB,
210+ },
211+ [26] = {
212+ .mask = 0x00400000,
213+ .mask_reg = QEIC_CRIMR,
214+ .pri_code = 1,
215+ .pri_reg = QEIC_CIPRTB,
216+ },
217+ [27] = {
218+ .mask = 0x00200000,
219+ .mask_reg = QEIC_CRIMR,
220+ .pri_code = 2,
221+ .pri_reg = QEIC_CIPRTB,
222+ },
223+ [28] = {
224+ .mask = 0x00100000,
225+ .mask_reg = QEIC_CRIMR,
226+ .pri_code = 3,
227+ .pri_reg = QEIC_CIPRTB,
228+ },
229+ [32] = {
230+ .mask = 0x80000000,
231+ .mask_reg = QEIC_CIMR,
232+ .pri_code = 0,
233+ .pri_reg = QEIC_CIPXCC,
234+ },
235+ [33] = {
236+ .mask = 0x40000000,
237+ .mask_reg = QEIC_CIMR,
238+ .pri_code = 1,
239+ .pri_reg = QEIC_CIPXCC,
240+ },
241+ [34] = {
242+ .mask = 0x20000000,
243+ .mask_reg = QEIC_CIMR,
244+ .pri_code = 2,
245+ .pri_reg = QEIC_CIPXCC,
246+ },
247+ [35] = {
248+ .mask = 0x10000000,
249+ .mask_reg = QEIC_CIMR,
250+ .pri_code = 3,
251+ .pri_reg = QEIC_CIPXCC,
252+ },
253+ [36] = {
254+ .mask = 0x08000000,
255+ .mask_reg = QEIC_CIMR,
256+ .pri_code = 4,
257+ .pri_reg = QEIC_CIPXCC,
258+ },
259+ [40] = {
260+ .mask = 0x00800000,
261+ .mask_reg = QEIC_CIMR,
262+ .pri_code = 0,
263+ .pri_reg = QEIC_CIPYCC,
264+ },
265+ [41] = {
266+ .mask = 0x00400000,
267+ .mask_reg = QEIC_CIMR,
268+ .pri_code = 1,
269+ .pri_reg = QEIC_CIPYCC,
270+ },
271+ [42] = {
272+ .mask = 0x00200000,
273+ .mask_reg = QEIC_CIMR,
274+ .pri_code = 2,
275+ .pri_reg = QEIC_CIPYCC,
276+ },
277+ [43] = {
278+ .mask = 0x00100000,
279+ .mask_reg = QEIC_CIMR,
280+ .pri_code = 3,
281+ .pri_reg = QEIC_CIPYCC,
282+ },
283+};
284+
285+static inline u32 qe_ic_read(volatile __be32 __iomem * base, unsigned int reg)
286+{
287+ return in_be32(base + (reg >> 2));
288+}
289+
290+static inline void qe_ic_write(volatile __be32 __iomem * base, unsigned int reg,
291+ u32 value)
292+{
293+ out_be32(base + (reg >> 2), value);
294+}
295+
296+static inline struct qe_ic *qe_ic_from_irq(unsigned int virq)
297+{
298+ return irq_get_chip_data(virq);
299+}
300+
301+static inline struct qe_ic *qe_ic_from_irq_data(struct irq_data *d)
302+{
303+ return irq_data_get_irq_chip_data(d);
304+}
305+
306+static void qe_ic_unmask_irq(struct irq_data *d)
307+{
308+ struct qe_ic *qe_ic = qe_ic_from_irq_data(d);
309+ unsigned int src = irqd_to_hwirq(d);
310+ unsigned long flags;
311+ u32 temp;
312+
313+ raw_spin_lock_irqsave(&qe_ic_lock, flags);
314+
315+ temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
316+ qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
317+ temp | qe_ic_info[src].mask);
318+
319+ raw_spin_unlock_irqrestore(&qe_ic_lock, flags);
320+}
321+
322+static void qe_ic_mask_irq(struct irq_data *d)
323+{
324+ struct qe_ic *qe_ic = qe_ic_from_irq_data(d);
325+ unsigned int src = irqd_to_hwirq(d);
326+ unsigned long flags;
327+ u32 temp;
328+
329+ raw_spin_lock_irqsave(&qe_ic_lock, flags);
330+
331+ temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
332+ qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
333+ temp & ~qe_ic_info[src].mask);
334+
335+ /* Flush the above write before enabling interrupts; otherwise,
336+ * spurious interrupts will sometimes happen. To be 100% sure
337+ * that the write has reached the device before interrupts are
338+ * enabled, the mask register would have to be read back; however,
339+ * this is not required for correctness, only to avoid wasting
340+ * time on a large number of spurious interrupts. In testing,
341+ * a sync reduced the observed spurious interrupts to zero.
342+ */
343+ mb();
344+
345+ raw_spin_unlock_irqrestore(&qe_ic_lock, flags);
346+}
347+
348+static struct irq_chip qe_ic_irq_chip = {
349+ .name = "QEIC",
350+ .irq_unmask = qe_ic_unmask_irq,
351+ .irq_mask = qe_ic_mask_irq,
352+ .irq_mask_ack = qe_ic_mask_irq,
353+};
354+
355+static int qe_ic_host_match(struct irq_domain *h, struct device_node *node,
356+ enum irq_domain_bus_token bus_token)
357+{
358+ /* Exact match, unless qe_ic node is NULL */
359+ struct device_node *of_node = irq_domain_get_of_node(h);
360+ return of_node == NULL || of_node == node;
361+}
362+
363+static int qe_ic_host_map(struct irq_domain *h, unsigned int virq,
364+ irq_hw_number_t hw)
365+{
366+ struct qe_ic *qe_ic = h->host_data;
367+ struct irq_chip *chip;
368+
369+ if (hw >= ARRAY_SIZE(qe_ic_info)) {
370+ pr_err("%s: Invalid hw irq number for QEIC\n", __func__);
371+ return -EINVAL;
372+ }
373+
374+ if (qe_ic_info[hw].mask == 0) {
375+ printk(KERN_ERR "Can't map reserved IRQ\n");
376+ return -EINVAL;
377+ }
378+ /* Default chip */
379+ chip = &qe_ic->hc_irq;
380+
381+ irq_set_chip_data(virq, qe_ic);
382+ irq_set_status_flags(virq, IRQ_LEVEL);
383+
384+ irq_set_chip_and_handler(virq, chip, handle_level_irq);
385+
386+ return 0;
387+}
388+
389+static const struct irq_domain_ops qe_ic_host_ops = {
390+ .match = qe_ic_host_match,
391+ .map = qe_ic_host_map,
392+ .xlate = irq_domain_xlate_onetwocell,
393+};
394+
395+/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
396+unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic)
397+{
398+ int irq;
399+
400+ BUG_ON(qe_ic == NULL);
401+
402+ /* get the interrupt source vector. */
403+ irq = qe_ic_read(qe_ic->regs, QEIC_CIVEC) >> 26;
404+
405+ if (irq == 0)
406+ return NO_IRQ;
407+
408+ return irq_linear_revmap(qe_ic->irqhost, irq);
409+}
410+
411+/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
412+unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic)
413+{
414+ int irq;
415+
416+ BUG_ON(qe_ic == NULL);
417+
418+ /* get the interrupt source vector. */
419+ irq = qe_ic_read(qe_ic->regs, QEIC_CHIVEC) >> 26;
420+
421+ if (irq == 0)
422+ return NO_IRQ;
423+
424+ return irq_linear_revmap(qe_ic->irqhost, irq);
425+}
426+
427+void __init qe_ic_init(struct device_node *node, unsigned int flags,
428+ void (*low_handler)(struct irq_desc *desc),
429+ void (*high_handler)(struct irq_desc *desc))
430+{
431+ struct qe_ic *qe_ic;
432+ struct resource res;
433+ u32 temp = 0, ret, high_active = 0;
434+
435+ ret = of_address_to_resource(node, 0, &res);
436+ if (ret)
437+ return;
438+
439+ qe_ic = kzalloc(sizeof(*qe_ic), GFP_KERNEL);
440+ if (qe_ic == NULL)
441+ return;
442+
443+ qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS,
444+ &qe_ic_host_ops, qe_ic);
445+ if (qe_ic->irqhost == NULL) {
446+ kfree(qe_ic);
447+ return;
448+ }
449+
450+ qe_ic->regs = ioremap(res.start, resource_size(&res));
451+
452+ qe_ic->hc_irq = qe_ic_irq_chip;
453+
454+ qe_ic->virq_high = irq_of_parse_and_map(node, 0);
455+ qe_ic->virq_low = irq_of_parse_and_map(node, 1);
456+
457+ if (qe_ic->virq_low == NO_IRQ) {
458+ printk(KERN_ERR "Failed to map QE_IC low IRQ\n");
459+ kfree(qe_ic);
460+ return;
461+ }
462+
463+ /* default priority scheme is grouped. If spread mode is */
464+ /* required, configure cicr accordingly. */
465+ if (flags & QE_IC_SPREADMODE_GRP_W)
466+ temp |= CICR_GWCC;
467+ if (flags & QE_IC_SPREADMODE_GRP_X)
468+ temp |= CICR_GXCC;
469+ if (flags & QE_IC_SPREADMODE_GRP_Y)
470+ temp |= CICR_GYCC;
471+ if (flags & QE_IC_SPREADMODE_GRP_Z)
472+ temp |= CICR_GZCC;
473+ if (flags & QE_IC_SPREADMODE_GRP_RISCA)
474+ temp |= CICR_GRTA;
475+ if (flags & QE_IC_SPREADMODE_GRP_RISCB)
476+ temp |= CICR_GRTB;
477+
478+ /* choose destination signal for highest priority interrupt */
479+ if (flags & QE_IC_HIGH_SIGNAL) {
480+ temp |= (SIGNAL_HIGH << CICR_HPIT_SHIFT);
481+ high_active = 1;
482+ }
483+
484+ qe_ic_write(qe_ic->regs, QEIC_CICR, temp);
485+
486+ irq_set_handler_data(qe_ic->virq_low, qe_ic);
487+ irq_set_chained_handler(qe_ic->virq_low, low_handler);
488+
489+ if (qe_ic->virq_high != NO_IRQ &&
490+ qe_ic->virq_high != qe_ic->virq_low) {
491+ irq_set_handler_data(qe_ic->virq_high, qe_ic);
492+ irq_set_chained_handler(qe_ic->virq_high, high_handler);
493+ }
494+}
495+
496+void qe_ic_set_highest_priority(unsigned int virq, int high)
497+{
498+ struct qe_ic *qe_ic = qe_ic_from_irq(virq);
499+ unsigned int src = virq_to_hw(virq);
500+ u32 temp = 0;
501+
502+ temp = qe_ic_read(qe_ic->regs, QEIC_CICR);
503+
504+ temp &= ~CICR_HP_MASK;
505+ temp |= src << CICR_HP_SHIFT;
506+
507+ temp &= ~CICR_HPIT_MASK;
508+ temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << CICR_HPIT_SHIFT;
509+
510+ qe_ic_write(qe_ic->regs, QEIC_CICR, temp);
511+}
512+
513+/* Set Priority level within its group, from 1 to 8 */
514+int qe_ic_set_priority(unsigned int virq, unsigned int priority)
515+{
516+ struct qe_ic *qe_ic = qe_ic_from_irq(virq);
517+ unsigned int src = virq_to_hw(virq);
518+ u32 temp;
519+
520+ if (priority > 8 || priority == 0)
521+ return -EINVAL;
522+ if (WARN_ONCE(src >= ARRAY_SIZE(qe_ic_info),
523+ "%s: Invalid hw irq number for QEIC\n", __func__))
524+ return -EINVAL;
525+ if (qe_ic_info[src].pri_reg == 0)
526+ return -EINVAL;
527+
528+ temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].pri_reg);
529+
530+ if (priority < 4) {
531+ temp &= ~(0x7 << (32 - priority * 3));
532+ temp |= qe_ic_info[src].pri_code << (32 - priority * 3);
533+ } else {
534+ temp &= ~(0x7 << (24 - priority * 3));
535+ temp |= qe_ic_info[src].pri_code << (24 - priority * 3);
536+ }
537+
538+ qe_ic_write(qe_ic->regs, qe_ic_info[src].pri_reg, temp);
539+
540+ return 0;
541+}
542+
543+/* Set a QE priority to use high irq, only priority 1~2 can use high irq */
544+int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high)
545+{
546+ struct qe_ic *qe_ic = qe_ic_from_irq(virq);
547+ unsigned int src = virq_to_hw(virq);
548+ u32 temp, control_reg = QEIC_CICNR, shift = 0;
549+
550+ if (priority > 2 || priority == 0)
551+ return -EINVAL;
552+ if (WARN_ONCE(src >= ARRAY_SIZE(qe_ic_info),
553+ "%s: Invalid hw irq number for QEIC\n", __func__))
554+ return -EINVAL;
555+
556+ switch (qe_ic_info[src].pri_reg) {
557+ case QEIC_CIPZCC:
558+ shift = CICNR_ZCC1T_SHIFT;
559+ break;
560+ case QEIC_CIPWCC:
561+ shift = CICNR_WCC1T_SHIFT;
562+ break;
563+ case QEIC_CIPYCC:
564+ shift = CICNR_YCC1T_SHIFT;
565+ break;
566+ case QEIC_CIPXCC:
567+ shift = CICNR_XCC1T_SHIFT;
568+ break;
569+ case QEIC_CIPRTA:
570+ shift = CRICR_RTA1T_SHIFT;
571+ control_reg = QEIC_CRICR;
572+ break;
573+ case QEIC_CIPRTB:
574+ shift = CRICR_RTB1T_SHIFT;
575+ control_reg = QEIC_CRICR;
576+ break;
577+ default:
578+ return -EINVAL;
579+ }
580+
581+ shift += (2 - priority) * 2;
582+ temp = qe_ic_read(qe_ic->regs, control_reg);
583+ temp &= ~(SIGNAL_MASK << shift);
584+ temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << shift;
585+ qe_ic_write(qe_ic->regs, control_reg, temp);
586+
587+ return 0;
588+}
589+
590+static struct bus_type qe_ic_subsys = {
591+ .name = "qe_ic",
592+ .dev_name = "qe_ic",
593+};
594+
595+static struct device device_qe_ic = {
596+ .id = 0,
597+ .bus = &qe_ic_subsys,
598+};
599+
600+static int __init init_qe_ic_sysfs(void)
601+{
602+ int rc;
603+
604+ printk(KERN_DEBUG "Registering qe_ic with sysfs...\n");
605+
606+ rc = subsys_system_register(&qe_ic_subsys, NULL);
607+ if (rc) {
608+ printk(KERN_ERR "Failed registering qe_ic sys class\n");
609+ return -ENODEV;
610+ }
611+ rc = device_register(&device_qe_ic);
612+ if (rc) {
613+ printk(KERN_ERR "Failed registering qe_ic sys device\n");
614+ return -ENODEV;
615+ }
616+ return 0;
617+}
618+
619+subsys_initcall(init_qe_ic_sysfs);
620--- a/drivers/soc/fsl/qe/Makefile
621+++ b/drivers/soc/fsl/qe/Makefile
622@@ -2,7 +2,7 @@
623 #
624 # Makefile for the linux ppc-specific parts of QE
625 #
626-obj-$(CONFIG_QUICC_ENGINE)+= qe.o qe_common.o qe_ic.o qe_io.o
627+obj-$(CONFIG_QUICC_ENGINE)+= qe.o qe_common.o qe_io.o
628 obj-$(CONFIG_CPM) += qe_common.o
629 obj-$(CONFIG_UCC) += ucc.o
630 obj-$(CONFIG_UCC_SLOW) += ucc_slow.o
631--- a/drivers/soc/fsl/qe/qe_ic.c
632+++ /dev/null
633@@ -1,508 +0,0 @@
634-// SPDX-License-Identifier: GPL-2.0-or-later
635-/*
636- * arch/powerpc/sysdev/qe_lib/qe_ic.c
637- *
638- * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
639- *
640- * Author: Li Yang <leoli@freescale.com>
641- * Based on code from Shlomi Gridish <gridish@freescale.com>
642- *
643- * QUICC ENGINE Interrupt Controller
644- */
645-
646-#include <linux/of_irq.h>
647-#include <linux/of_address.h>
648-#include <linux/kernel.h>
649-#include <linux/init.h>
650-#include <linux/errno.h>
651-#include <linux/reboot.h>
652-#include <linux/slab.h>
653-#include <linux/stddef.h>
654-#include <linux/sched.h>
655-#include <linux/signal.h>
656-#include <linux/device.h>
657-#include <linux/spinlock.h>
658-#include <asm/irq.h>
659-#include <asm/io.h>
660-#include <soc/fsl/qe/qe_ic.h>
661-
662-#include "qe_ic.h"
663-
664-static DEFINE_RAW_SPINLOCK(qe_ic_lock);
665-
666-static struct qe_ic_info qe_ic_info[] = {
667- [1] = {
668- .mask = 0x00008000,
669- .mask_reg = QEIC_CIMR,
670- .pri_code = 0,
671- .pri_reg = QEIC_CIPWCC,
672- },
673- [2] = {
674- .mask = 0x00004000,
675- .mask_reg = QEIC_CIMR,
676- .pri_code = 1,
677- .pri_reg = QEIC_CIPWCC,
678- },
679- [3] = {
680- .mask = 0x00002000,
681- .mask_reg = QEIC_CIMR,
682- .pri_code = 2,
683- .pri_reg = QEIC_CIPWCC,
684- },
685- [10] = {
686- .mask = 0x00000040,
687- .mask_reg = QEIC_CIMR,
688- .pri_code = 1,
689- .pri_reg = QEIC_CIPZCC,
690- },
691- [11] = {
692- .mask = 0x00000020,
693- .mask_reg = QEIC_CIMR,
694- .pri_code = 2,
695- .pri_reg = QEIC_CIPZCC,
696- },
697- [12] = {
698- .mask = 0x00000010,
699- .mask_reg = QEIC_CIMR,
700- .pri_code = 3,
701- .pri_reg = QEIC_CIPZCC,
702- },
703- [13] = {
704- .mask = 0x00000008,
705- .mask_reg = QEIC_CIMR,
706- .pri_code = 4,
707- .pri_reg = QEIC_CIPZCC,
708- },
709- [14] = {
710- .mask = 0x00000004,
711- .mask_reg = QEIC_CIMR,
712- .pri_code = 5,
713- .pri_reg = QEIC_CIPZCC,
714- },
715- [15] = {
716- .mask = 0x00000002,
717- .mask_reg = QEIC_CIMR,
718- .pri_code = 6,
719- .pri_reg = QEIC_CIPZCC,
720- },
721- [20] = {
722- .mask = 0x10000000,
723- .mask_reg = QEIC_CRIMR,
724- .pri_code = 3,
725- .pri_reg = QEIC_CIPRTA,
726- },
727- [25] = {
728- .mask = 0x00800000,
729- .mask_reg = QEIC_CRIMR,
730- .pri_code = 0,
731- .pri_reg = QEIC_CIPRTB,
732- },
733- [26] = {
734- .mask = 0x00400000,
735- .mask_reg = QEIC_CRIMR,
736- .pri_code = 1,
737- .pri_reg = QEIC_CIPRTB,
738- },
739- [27] = {
740- .mask = 0x00200000,
741- .mask_reg = QEIC_CRIMR,
742- .pri_code = 2,
743- .pri_reg = QEIC_CIPRTB,
744- },
745- [28] = {
746- .mask = 0x00100000,
747- .mask_reg = QEIC_CRIMR,
748- .pri_code = 3,
749- .pri_reg = QEIC_CIPRTB,
750- },
751- [32] = {
752- .mask = 0x80000000,
753- .mask_reg = QEIC_CIMR,
754- .pri_code = 0,
755- .pri_reg = QEIC_CIPXCC,
756- },
757- [33] = {
758- .mask = 0x40000000,
759- .mask_reg = QEIC_CIMR,
760- .pri_code = 1,
761- .pri_reg = QEIC_CIPXCC,
762- },
763- [34] = {
764- .mask = 0x20000000,
765- .mask_reg = QEIC_CIMR,
766- .pri_code = 2,
767- .pri_reg = QEIC_CIPXCC,
768- },
769- [35] = {
770- .mask = 0x10000000,
771- .mask_reg = QEIC_CIMR,
772- .pri_code = 3,
773- .pri_reg = QEIC_CIPXCC,
774- },
775- [36] = {
776- .mask = 0x08000000,
777- .mask_reg = QEIC_CIMR,
778- .pri_code = 4,
779- .pri_reg = QEIC_CIPXCC,
780- },
781- [40] = {
782- .mask = 0x00800000,
783- .mask_reg = QEIC_CIMR,
784- .pri_code = 0,
785- .pri_reg = QEIC_CIPYCC,
786- },
787- [41] = {
788- .mask = 0x00400000,
789- .mask_reg = QEIC_CIMR,
790- .pri_code = 1,
791- .pri_reg = QEIC_CIPYCC,
792- },
793- [42] = {
794- .mask = 0x00200000,
795- .mask_reg = QEIC_CIMR,
796- .pri_code = 2,
797- .pri_reg = QEIC_CIPYCC,
798- },
799- [43] = {
800- .mask = 0x00100000,
801- .mask_reg = QEIC_CIMR,
802- .pri_code = 3,
803- .pri_reg = QEIC_CIPYCC,
804- },
805-};
806-
807-static inline u32 qe_ic_read(volatile __be32 __iomem * base, unsigned int reg)
808-{
809- return in_be32(base + (reg >> 2));
810-}
811-
812-static inline void qe_ic_write(volatile __be32 __iomem * base, unsigned int reg,
813- u32 value)
814-{
815- out_be32(base + (reg >> 2), value);
816-}
817-
818-static inline struct qe_ic *qe_ic_from_irq(unsigned int virq)
819-{
820- return irq_get_chip_data(virq);
821-}
822-
823-static inline struct qe_ic *qe_ic_from_irq_data(struct irq_data *d)
824-{
825- return irq_data_get_irq_chip_data(d);
826-}
827-
828-static void qe_ic_unmask_irq(struct irq_data *d)
829-{
830- struct qe_ic *qe_ic = qe_ic_from_irq_data(d);
831- unsigned int src = irqd_to_hwirq(d);
832- unsigned long flags;
833- u32 temp;
834-
835- raw_spin_lock_irqsave(&qe_ic_lock, flags);
836-
837- temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
838- qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
839- temp | qe_ic_info[src].mask);
840-
841- raw_spin_unlock_irqrestore(&qe_ic_lock, flags);
842-}
843-
844-static void qe_ic_mask_irq(struct irq_data *d)
845-{
846- struct qe_ic *qe_ic = qe_ic_from_irq_data(d);
847- unsigned int src = irqd_to_hwirq(d);
848- unsigned long flags;
849- u32 temp;
850-
851- raw_spin_lock_irqsave(&qe_ic_lock, flags);
852-
853- temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
854- qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
855- temp & ~qe_ic_info[src].mask);
856-
857- /* Flush the above write before enabling interrupts; otherwise,
858- * spurious interrupts will sometimes happen. To be 100% sure
859- * that the write has reached the device before interrupts are
860- * enabled, the mask register would have to be read back; however,
861- * this is not required for correctness, only to avoid wasting
862- * time on a large number of spurious interrupts. In testing,
863- * a sync reduced the observed spurious interrupts to zero.
864- */
865- mb();
866-
867- raw_spin_unlock_irqrestore(&qe_ic_lock, flags);
868-}
869-
870-static struct irq_chip qe_ic_irq_chip = {
871- .name = "QEIC",
872- .irq_unmask = qe_ic_unmask_irq,
873- .irq_mask = qe_ic_mask_irq,
874- .irq_mask_ack = qe_ic_mask_irq,
875-};
876-
877-static int qe_ic_host_match(struct irq_domain *h, struct device_node *node,
878- enum irq_domain_bus_token bus_token)
879-{
880- /* Exact match, unless qe_ic node is NULL */
881- struct device_node *of_node = irq_domain_get_of_node(h);
882- return of_node == NULL || of_node == node;
883-}
884-
885-static int qe_ic_host_map(struct irq_domain *h, unsigned int virq,
886- irq_hw_number_t hw)
887-{
888- struct qe_ic *qe_ic = h->host_data;
889- struct irq_chip *chip;
890-
891- if (hw >= ARRAY_SIZE(qe_ic_info)) {
892- pr_err("%s: Invalid hw irq number for QEIC\n", __func__);
893- return -EINVAL;
894- }
895-
896- if (qe_ic_info[hw].mask == 0) {
897- printk(KERN_ERR "Can't map reserved IRQ\n");
898- return -EINVAL;
899- }
900- /* Default chip */
901- chip = &qe_ic->hc_irq;
902-
903- irq_set_chip_data(virq, qe_ic);
904- irq_set_status_flags(virq, IRQ_LEVEL);
905-
906- irq_set_chip_and_handler(virq, chip, handle_level_irq);
907-
908- return 0;
909-}
910-
911-static const struct irq_domain_ops qe_ic_host_ops = {
912- .match = qe_ic_host_match,
913- .map = qe_ic_host_map,
914- .xlate = irq_domain_xlate_onetwocell,
915-};
916-
917-/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
918-unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic)
919-{
920- int irq;
921-
922- BUG_ON(qe_ic == NULL);
923-
924- /* get the interrupt source vector. */
925- irq = qe_ic_read(qe_ic->regs, QEIC_CIVEC) >> 26;
926-
927- if (irq == 0)
928- return NO_IRQ;
929-
930- return irq_linear_revmap(qe_ic->irqhost, irq);
931-}
932-
933-/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
934-unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic)
935-{
936- int irq;
937-
938- BUG_ON(qe_ic == NULL);
939-
940- /* get the interrupt source vector. */
941- irq = qe_ic_read(qe_ic->regs, QEIC_CHIVEC) >> 26;
942-
943- if (irq == 0)
944- return NO_IRQ;
945-
946- return irq_linear_revmap(qe_ic->irqhost, irq);
947-}
948-
949-void __init qe_ic_init(struct device_node *node, unsigned int flags,
950- void (*low_handler)(struct irq_desc *desc),
951- void (*high_handler)(struct irq_desc *desc))
952-{
953- struct qe_ic *qe_ic;
954- struct resource res;
955- u32 temp = 0, ret, high_active = 0;
956-
957- ret = of_address_to_resource(node, 0, &res);
958- if (ret)
959- return;
960-
961- qe_ic = kzalloc(sizeof(*qe_ic), GFP_KERNEL);
962- if (qe_ic == NULL)
963- return;
964-
965- qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS,
966- &qe_ic_host_ops, qe_ic);
967- if (qe_ic->irqhost == NULL) {
968- kfree(qe_ic);
969- return;
970- }
971-
972- qe_ic->regs = ioremap(res.start, resource_size(&res));
973-
974- qe_ic->hc_irq = qe_ic_irq_chip;
975-
976- qe_ic->virq_high = irq_of_parse_and_map(node, 0);
977- qe_ic->virq_low = irq_of_parse_and_map(node, 1);
978-
979- if (qe_ic->virq_low == NO_IRQ) {
980- printk(KERN_ERR "Failed to map QE_IC low IRQ\n");
981- kfree(qe_ic);
982- return;
983- }
984-
985- /* default priority scheme is grouped. If spread mode is */
986- /* required, configure cicr accordingly. */
987- if (flags & QE_IC_SPREADMODE_GRP_W)
988- temp |= CICR_GWCC;
989- if (flags & QE_IC_SPREADMODE_GRP_X)
990- temp |= CICR_GXCC;
991- if (flags & QE_IC_SPREADMODE_GRP_Y)
992- temp |= CICR_GYCC;
993- if (flags & QE_IC_SPREADMODE_GRP_Z)
994- temp |= CICR_GZCC;
995- if (flags & QE_IC_SPREADMODE_GRP_RISCA)
996- temp |= CICR_GRTA;
997- if (flags & QE_IC_SPREADMODE_GRP_RISCB)
998- temp |= CICR_GRTB;
999-
1000- /* choose destination signal for highest priority interrupt */
1001- if (flags & QE_IC_HIGH_SIGNAL) {
1002- temp |= (SIGNAL_HIGH << CICR_HPIT_SHIFT);
1003- high_active = 1;
1004- }
1005-
1006- qe_ic_write(qe_ic->regs, QEIC_CICR, temp);
1007-
1008- irq_set_handler_data(qe_ic->virq_low, qe_ic);
1009- irq_set_chained_handler(qe_ic->virq_low, low_handler);
1010-
1011- if (qe_ic->virq_high != NO_IRQ &&
1012- qe_ic->virq_high != qe_ic->virq_low) {
1013- irq_set_handler_data(qe_ic->virq_high, qe_ic);
1014- irq_set_chained_handler(qe_ic->virq_high, high_handler);
1015- }
1016-}
1017-
1018-void qe_ic_set_highest_priority(unsigned int virq, int high)
1019-{
1020- struct qe_ic *qe_ic = qe_ic_from_irq(virq);
1021- unsigned int src = virq_to_hw(virq);
1022- u32 temp = 0;
1023-
1024- temp = qe_ic_read(qe_ic->regs, QEIC_CICR);
1025-
1026- temp &= ~CICR_HP_MASK;
1027- temp |= src << CICR_HP_SHIFT;
1028-
1029- temp &= ~CICR_HPIT_MASK;
1030- temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << CICR_HPIT_SHIFT;
1031-
1032- qe_ic_write(qe_ic->regs, QEIC_CICR, temp);
1033-}
1034-
1035-/* Set Priority level within its group, from 1 to 8 */
1036-int qe_ic_set_priority(unsigned int virq, unsigned int priority)
1037-{
1038- struct qe_ic *qe_ic = qe_ic_from_irq(virq);
1039- unsigned int src = virq_to_hw(virq);
1040- u32 temp;
1041-
1042- if (priority > 8 || priority == 0)
1043- return -EINVAL;
1044- if (WARN_ONCE(src >= ARRAY_SIZE(qe_ic_info),
1045- "%s: Invalid hw irq number for QEIC\n", __func__))
1046- return -EINVAL;
1047- if (qe_ic_info[src].pri_reg == 0)
1048- return -EINVAL;
1049-
1050- temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].pri_reg);
1051-
1052- if (priority < 4) {
1053- temp &= ~(0x7 << (32 - priority * 3));
1054- temp |= qe_ic_info[src].pri_code << (32 - priority * 3);
1055- } else {
1056- temp &= ~(0x7 << (24 - priority * 3));
1057- temp |= qe_ic_info[src].pri_code << (24 - priority * 3);
1058- }
1059-
1060- qe_ic_write(qe_ic->regs, qe_ic_info[src].pri_reg, temp);
1061-
1062- return 0;
1063-}
1064-
1065-/* Set a QE priority to use high irq, only priority 1~2 can use high irq */
1066-int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high)
1067-{
1068- struct qe_ic *qe_ic = qe_ic_from_irq(virq);
1069- unsigned int src = virq_to_hw(virq);
1070- u32 temp, control_reg = QEIC_CICNR, shift = 0;
1071-
1072- if (priority > 2 || priority == 0)
1073- return -EINVAL;
1074- if (WARN_ONCE(src >= ARRAY_SIZE(qe_ic_info),
1075- "%s: Invalid hw irq number for QEIC\n", __func__))
1076- return -EINVAL;
1077-
1078- switch (qe_ic_info[src].pri_reg) {
1079- case QEIC_CIPZCC:
1080- shift = CICNR_ZCC1T_SHIFT;
1081- break;
1082- case QEIC_CIPWCC:
1083- shift = CICNR_WCC1T_SHIFT;
1084- break;
1085- case QEIC_CIPYCC:
1086- shift = CICNR_YCC1T_SHIFT;
1087- break;
1088- case QEIC_CIPXCC:
1089- shift = CICNR_XCC1T_SHIFT;
1090- break;
1091- case QEIC_CIPRTA:
1092- shift = CRICR_RTA1T_SHIFT;
1093- control_reg = QEIC_CRICR;
1094- break;
1095- case QEIC_CIPRTB:
1096- shift = CRICR_RTB1T_SHIFT;
1097- control_reg = QEIC_CRICR;
1098- break;
1099- default:
1100- return -EINVAL;
1101- }
1102-
1103- shift += (2 - priority) * 2;
1104- temp = qe_ic_read(qe_ic->regs, control_reg);
1105- temp &= ~(SIGNAL_MASK << shift);
1106- temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << shift;
1107- qe_ic_write(qe_ic->regs, control_reg, temp);
1108-
1109- return 0;
1110-}
1111-
1112-static struct bus_type qe_ic_subsys = {
1113- .name = "qe_ic",
1114- .dev_name = "qe_ic",
1115-};
1116-
1117-static struct device device_qe_ic = {
1118- .id = 0,
1119- .bus = &qe_ic_subsys,
1120-};
1121-
1122-static int __init init_qe_ic_sysfs(void)
1123-{
1124- int rc;
1125-
1126- printk(KERN_DEBUG "Registering qe_ic with sysfs...\n");
1127-
1128- rc = subsys_system_register(&qe_ic_subsys, NULL);
1129- if (rc) {
1130- printk(KERN_ERR "Failed registering qe_ic sys class\n");
1131- return -ENODEV;
1132- }
1133- rc = device_register(&device_qe_ic);
1134- if (rc) {
1135- printk(KERN_ERR "Failed registering qe_ic sys device\n");
1136- return -ENODEV;
1137- }
1138- return 0;
1139-}
1140-
1141-subsys_initcall(init_qe_ic_sysfs);
1142--- a/drivers/soc/fsl/qe/qe_ic.h
1143+++ /dev/null
1144@@ -1,99 +0,0 @@
1145-/* SPDX-License-Identifier: GPL-2.0-or-later */
1146-/*
1147- * drivers/soc/fsl/qe/qe_ic.h
1148- *
1149- * QUICC ENGINE Interrupt Controller Header
1150- *
1151- * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
1152- *
1153- * Author: Li Yang <leoli@freescale.com>
1154- * Based on code from Shlomi Gridish <gridish@freescale.com>
1155- */
1156-#ifndef _POWERPC_SYSDEV_QE_IC_H
1157-#define _POWERPC_SYSDEV_QE_IC_H
1158-
1159-#include <soc/fsl/qe/qe_ic.h>
1160-
1161-#define NR_QE_IC_INTS 64
1162-
1163-/* QE IC registers offset */
1164-#define QEIC_CICR 0x00
1165-#define QEIC_CIVEC 0x04
1166-#define QEIC_CRIPNR 0x08
1167-#define QEIC_CIPNR 0x0c
1168-#define QEIC_CIPXCC 0x10
1169-#define QEIC_CIPYCC 0x14
1170-#define QEIC_CIPWCC 0x18
1171-#define QEIC_CIPZCC 0x1c
1172-#define QEIC_CIMR 0x20
1173-#define QEIC_CRIMR 0x24
1174-#define QEIC_CICNR 0x28
1175-#define QEIC_CIPRTA 0x30
1176-#define QEIC_CIPRTB 0x34
1177-#define QEIC_CRICR 0x3c
1178-#define QEIC_CHIVEC 0x60
1179-
1180-/* Interrupt priority registers */
1181-#define CIPCC_SHIFT_PRI0 29
1182-#define CIPCC_SHIFT_PRI1 26
1183-#define CIPCC_SHIFT_PRI2 23
1184-#define CIPCC_SHIFT_PRI3 20
1185-#define CIPCC_SHIFT_PRI4 13
1186-#define CIPCC_SHIFT_PRI5 10
1187-#define CIPCC_SHIFT_PRI6 7
1188-#define CIPCC_SHIFT_PRI7 4
1189-
1190-/* CICR priority modes */
1191-#define CICR_GWCC 0x00040000
1192-#define CICR_GXCC 0x00020000
1193-#define CICR_GYCC 0x00010000
1194-#define CICR_GZCC 0x00080000
1195-#define CICR_GRTA 0x00200000
1196-#define CICR_GRTB 0x00400000
1197-#define CICR_HPIT_SHIFT 8
1198-#define CICR_HPIT_MASK 0x00000300
1199-#define CICR_HP_SHIFT 24
1200-#define CICR_HP_MASK 0x3f000000
1201-
1202-/* CICNR */
1203-#define CICNR_WCC1T_SHIFT 20
1204-#define CICNR_ZCC1T_SHIFT 28
1205-#define CICNR_YCC1T_SHIFT 12
1206-#define CICNR_XCC1T_SHIFT 4
1207-
1208-/* CRICR */
1209-#define CRICR_RTA1T_SHIFT 20
1210-#define CRICR_RTB1T_SHIFT 28
1211-
1212-/* Signal indicator */
1213-#define SIGNAL_MASK 3
1214-#define SIGNAL_HIGH 2
1215-#define SIGNAL_LOW 0
1216-
1217-struct qe_ic {
1218- /* Control registers offset */
1219- volatile u32 __iomem *regs;
1220-
1221- /* The remapper for this QEIC */
1222- struct irq_domain *irqhost;
1223-
1224- /* The "linux" controller struct */
1225- struct irq_chip hc_irq;
1226-
1227- /* VIRQ numbers of QE high/low irqs */
1228- unsigned int virq_high;
1229- unsigned int virq_low;
1230-};
1231-
1232-/*
1233- * QE interrupt controller internal structure
1234- */
1235-struct qe_ic_info {
1236- u32 mask; /* location of this source at the QIMR register. */
1237- u32 mask_reg; /* Mask register offset */
1238- u8 pri_code; /* for grouped interrupts sources - the interrupt
1239- code as appears at the group priority register */
1240- u32 pri_reg; /* Group priority register offset */
1241-};
1242-
1243-#endif /* _POWERPC_SYSDEV_QE_IC_H */