2 * arch/arm/plat-rk/rk_fiq_debugger.c
4 * Serial Debugger Interface for Rockchip
6 * Copyright (C) 2012 ROCKCHIP, Inc.
7 * Copyright (C) 2008 Google, Inc.
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
20 #include <linux/module.h>
23 #include <linux/of_address.h>
24 #include <linux/of_irq.h>
25 #include <linux/interrupt.h>
26 #include <linux/clk.h>
27 #include <linux/platform_device.h>
28 #include <linux/irq.h>
29 #include <linux/serial_reg.h>
30 #include <linux/slab.h>
31 #include <linux/stacktrace.h>
32 #include <linux/uaccess.h>
33 #include <linux/kfifo.h>
34 #include <linux/kthread.h>
35 #include <linux/sched/rt.h>
36 #include <asm/fiq_debugger.h>
37 #include <linux/irqchip/arm-gic.h>
38 #include "rk_fiq_debugger.h"
40 struct rk_fiq_debugger {
41 struct fiq_debugger_pdata pdata;
42 void __iomem *debug_port_base;
44 #ifdef CONFIG_RK_CONSOLE_THREAD
45 struct task_struct *console_task;
49 static inline void rk_fiq_write(struct rk_fiq_debugger *t,
50 unsigned int val, unsigned int off)
52 __raw_writel(val, t->debug_port_base + off * 4);
55 static inline unsigned int rk_fiq_read(struct rk_fiq_debugger *t,
58 return __raw_readl(t->debug_port_base + off * 4);
61 static inline unsigned int rk_fiq_read_lsr(struct rk_fiq_debugger *t)
65 lsr = rk_fiq_read(t, UART_LSR);
66 if (lsr & UART_LSR_BI)
72 static int debug_port_init(struct platform_device *pdev)
74 struct rk_fiq_debugger *t;
75 t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
77 if (rk_fiq_read(t, UART_LSR) & UART_LSR_DR)
78 (void)rk_fiq_read(t, UART_RX);
79 /* enable rx and lsr interrupt */
80 rk_fiq_write(t, UART_IER_RLSI | UART_IER_RDI, UART_IER);
81 /* interrupt on every character when receive,but we can enable fifo for TX
82 I found that if we enable the RX fifo, some problem may vanish such as when
83 you continuously input characters in the command line the uart irq may be disable
84 because of the uart irq is served when CPU is at IRQ exception,but it is
85 found unregistered, so it is disable.
87 rk_fiq_write(t, 0xc1, UART_FCR);
92 static int debug_getc(struct platform_device *pdev)
95 struct rk_fiq_debugger *t;
96 t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
98 lsr = rk_fiq_read_lsr(t);
100 if (lsr & UART_LSR_BI || t->break_seen) {
101 t->break_seen = false;
102 return FIQ_DEBUGGER_BREAK;
105 if (lsr & UART_LSR_DR)
106 return rk_fiq_read(t, UART_RX);
108 return FIQ_DEBUGGER_NO_CHAR;
111 static void debug_putc(struct platform_device *pdev, unsigned int c)
113 struct rk_fiq_debugger *t;
114 t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
116 // while (!(rk_fiq_read_lsr(t) & UART_LSR_THRE))
119 while (!(rk_fiq_read(t, 0x1F) & 0x02))
121 rk_fiq_write(t, c, UART_TX);
124 static void debug_flush(struct platform_device *pdev)
126 struct rk_fiq_debugger *t;
127 t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
129 while (!(rk_fiq_read_lsr(t) & UART_LSR_TEMT))
133 #ifdef CONFIG_RK_CONSOLE_THREAD
134 static DEFINE_KFIFO(fifo, unsigned char, SZ_64K);
136 static int console_thread(void *data)
138 struct platform_device *pdev = data;
139 struct rk_fiq_debugger *t;
141 t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
144 set_current_state(TASK_INTERRUPTIBLE);
146 if (kthread_should_stop())
148 set_current_state(TASK_RUNNING);
149 while (kfifo_get(&fifo, &c))
157 static void console_write(struct platform_device *pdev, const char *s, unsigned int count)
159 unsigned char c, r = '\r';
160 static bool oops = false;
161 struct rk_fiq_debugger *t;
162 t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
164 if (oops_in_progress || oops) {
166 while (kfifo_get(&fifo, &c))
172 debug_putc(pdev, *s++);
181 kfifo_put(&fifo, &r);
183 kfifo_put(&fifo, s++);
185 wake_up_process(t->console_task);
190 static void fiq_enable(struct platform_device *pdev, unsigned int irq, bool on)
198 static int rk_fiq_debugger_id;
200 void rk_serial_debug_init(void __iomem *base, int irq, int signal_irq, int wakeup_irq)
202 struct rk_fiq_debugger *t = NULL;
203 struct platform_device *pdev = NULL;
204 struct resource *res = NULL;
208 pr_err("Invalid fiq debugger uart base\n");
212 t = kzalloc(sizeof(struct rk_fiq_debugger), GFP_KERNEL);
214 pr_err("Failed to allocate for fiq debugger\n");
218 t->pdata.uart_init = debug_port_init;
219 t->pdata.uart_getc = debug_getc;
220 t->pdata.uart_putc = debug_putc;
221 #ifndef CONFIG_RK_CONSOLE_THREAD
222 t->pdata.uart_flush = debug_flush;
224 t->pdata.fiq_enable = fiq_enable;
225 t->pdata.force_irq = NULL; //force_irq;
226 t->debug_port_base = base;
228 res = kzalloc(sizeof(struct resource) * 3, GFP_KERNEL);
230 pr_err("Failed to alloc fiq debugger resources\n");
234 pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
236 pr_err("Failed to alloc fiq debugger platform device\n");
241 res[0].flags = IORESOURCE_IRQ;
248 if (signal_irq > 0) {
249 res[1].flags = IORESOURCE_IRQ;
250 res[1].start = signal_irq;
251 res[1].end = signal_irq;
252 res[1].name = "signal";
256 if (wakeup_irq > 0) {
257 res[2].flags = IORESOURCE_IRQ;
258 res[2].start = wakeup_irq;
259 res[2].end = wakeup_irq;
260 res[2].name = "wakeup";
264 #ifdef CONFIG_RK_CONSOLE_THREAD
265 t->console_task = kthread_create(console_thread, pdev, "kconsole");
266 if (!IS_ERR(t->console_task)) {
267 struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
268 t->pdata.console_write = console_write;
269 sched_setscheduler_nocheck(t->console_task, SCHED_FIFO, ¶m);
273 pdev->name = "fiq_debugger";
274 pdev->id = rk_fiq_debugger_id++;
275 pdev->dev.platform_data = &t->pdata;
276 pdev->resource = res;
277 pdev->num_resources = res_count;
278 if (platform_device_register(pdev)) {
279 pr_err("Failed to register fiq debugger\n");
292 static const struct of_device_id ids[] __initconst = {
293 { .compatible = "rockchip,fiq-debugger" },
297 static int __init rk_fiq_debugger_init(void) {
300 struct device_node *np;
301 unsigned int i, id, serial_id, ok = 0;
302 u32 irq, signal_irq = 0, wake_irq = 0;
304 np = of_find_matching_node(NULL, ids);
307 printk("fiq-debugger is missing in device tree!\n");
311 if (!of_device_is_available(np)) {
312 printk("fiq-debugger is disabled in device tree\n");
316 if (of_property_read_u32(np, "rockchip,serial-id", &serial_id)) {
320 if (of_property_read_u32(np, "rockchip,signal-irq", &signal_irq)) {
324 if (of_property_read_u32(np, "rockchip,wake-irq", &wake_irq)) {
329 for (i = 0; i < 5; i++) {
330 np = of_find_node_by_name(np, "serial");
332 id = of_alias_get_id(np, "serial");
333 if (id == serial_id) {
342 irq = irq_of_parse_and_map(np, 0);
346 base = of_iomap(np, 0);
348 rk_serial_debug_init(base, irq, signal_irq, wake_irq);
353 postcore_initcall_sync(rk_fiq_debugger_init);