2 * arch/arm/mach-tegra/fiq_debugger.c
4 * Serial Debugger Interface for Tegra
6 * Copyright (C) 2008 Google, Inc.
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
19 #include <linux/module.h>
21 #include <linux/interrupt.h>
22 #include <linux/clk.h>
23 #include <linux/platform_device.h>
24 #include <linux/irq.h>
25 #include <linux/serial_reg.h>
26 #include <linux/slab.h>
27 #include <linux/stacktrace.h>
28 #include <asm/fiq_debugger.h>
29 #include <mach/tegra_fiq_debugger.h>
30 #include <mach/system.h>
33 #include <linux/uaccess.h>
35 #include <mach/legacy_irq.h>
37 struct tegra_fiq_debugger {
38 struct fiq_debugger_pdata pdata;
39 void __iomem *debug_port_base;
43 static inline void tegra_write(struct tegra_fiq_debugger *t,
44 unsigned int val, unsigned int off)
46 __raw_writeb(val, t->debug_port_base + off * 4);
49 static inline unsigned int tegra_read(struct tegra_fiq_debugger *t,
52 return __raw_readb(t->debug_port_base + off * 4);
55 static inline unsigned int tegra_read_lsr(struct tegra_fiq_debugger *t)
59 lsr = tegra_read(t, UART_LSR);
60 if (lsr & UART_LSR_BI)
66 static int debug_port_init(struct platform_device *pdev)
68 struct tegra_fiq_debugger *t;
69 t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
71 if (tegra_read(t, UART_LSR) & UART_LSR_DR)
72 (void)tegra_read(t, UART_RX);
73 /* enable rx and lsr interrupt */
74 tegra_write(t, UART_IER_RLSI | UART_IER_RDI, UART_IER);
75 /* interrupt on every character */
76 tegra_write(t, 0, UART_IIR);
81 static int debug_getc(struct platform_device *pdev)
84 struct tegra_fiq_debugger *t;
85 t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
87 lsr = tegra_read_lsr(t);
89 if (lsr & UART_LSR_BI || t->break_seen) {
90 t->break_seen = false;
91 return FIQ_DEBUGGER_BREAK;
94 if (lsr & UART_LSR_DR)
95 return tegra_read(t, UART_RX);
97 return FIQ_DEBUGGER_NO_CHAR;
100 static void debug_putc(struct platform_device *pdev, unsigned int c)
102 struct tegra_fiq_debugger *t;
103 t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
105 while (!(tegra_read_lsr(t) & UART_LSR_THRE))
108 tegra_write(t, c, UART_TX);
111 static void debug_flush(struct platform_device *pdev)
113 struct tegra_fiq_debugger *t;
114 t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
116 while (!(tegra_read_lsr(t) & UART_LSR_TEMT))
120 static void fiq_enable(struct platform_device *pdev, unsigned int irq, bool on)
123 tegra_fiq_enable(irq);
125 tegra_fiq_disable(irq);
128 static int tegra_fiq_debugger_id;
130 void tegra_serial_debug_init(unsigned int base, int irq,
131 struct clk *clk, int signal_irq, int wakeup_irq)
133 struct tegra_fiq_debugger *t;
134 struct platform_device *pdev;
135 struct resource *res;
138 t = kzalloc(sizeof(struct tegra_fiq_debugger), GFP_KERNEL);
140 pr_err("Failed to allocate for fiq debugger\n");
144 t->pdata.uart_init = debug_port_init;
145 t->pdata.uart_getc = debug_getc;
146 t->pdata.uart_putc = debug_putc;
147 t->pdata.uart_flush = debug_flush;
148 t->pdata.fiq_enable = fiq_enable;
150 t->debug_port_base = ioremap(base, PAGE_SIZE);
151 if (!t->debug_port_base) {
152 pr_err("Failed to ioremap for fiq debugger\n");
156 res = kzalloc(sizeof(struct resource) * 3, GFP_KERNEL);
158 pr_err("Failed to alloc fiq debugger resources\n");
162 pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
164 pr_err("Failed to alloc fiq debugger platform device\n");
168 res[0].flags = IORESOURCE_IRQ;
173 res[1].flags = IORESOURCE_IRQ;
174 res[1].start = signal_irq;
175 res[1].end = signal_irq;
176 res[1].name = "signal";
179 if (wakeup_irq >= 0) {
180 res[2].flags = IORESOURCE_IRQ;
181 res[2].start = wakeup_irq;
182 res[2].end = wakeup_irq;
183 res[2].name = "wakeup";
187 pdev->name = "fiq_debugger";
188 pdev->id = tegra_fiq_debugger_id++;
189 pdev->dev.platform_data = &t->pdata;
190 pdev->resource = res;
191 pdev->num_resources = res_count;
193 if (platform_device_register(pdev)) {
194 pr_err("Failed to register fiq debugger\n");
205 iounmap(t->debug_port_base);