arm: tegra: sd: enable sd dpd
[linux-2.6.git] / arch / arm / mach-tegra / tegra_fiq_debugger.c
1 /*
2  * arch/arm/mach-tegra/fiq_debugger.c
3  *
4  * Serial Debugger Interface for Tegra
5  *
6  * Copyright (C) 2008 Google, Inc.
7  *
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.
11  *
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.
16  */
17
18 #include <stdarg.h>
19 #include <linux/module.h>
20 #include <linux/io.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>
31 #include <mach/fiq.h>
32
33 #include <linux/uaccess.h>
34
35 struct tegra_fiq_debugger {
36         struct fiq_debugger_pdata pdata;
37         void __iomem *debug_port_base;
38         bool break_seen;
39 };
40
41 static inline void tegra_write(struct tegra_fiq_debugger *t,
42         unsigned int val, unsigned int off)
43 {
44         __raw_writeb(val, t->debug_port_base + off * 4);
45 }
46
47 static inline unsigned int tegra_read(struct tegra_fiq_debugger *t,
48         unsigned int off)
49 {
50         return __raw_readb(t->debug_port_base + off * 4);
51 }
52
53 static inline unsigned int tegra_read_lsr(struct tegra_fiq_debugger *t)
54 {
55         unsigned int lsr;
56
57         lsr = tegra_read(t, UART_LSR);
58         if (lsr & UART_LSR_BI)
59                 t->break_seen = true;
60
61         return lsr;
62 }
63
64 static int debug_port_init(struct platform_device *pdev)
65 {
66         struct tegra_fiq_debugger *t;
67         t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
68
69         if (tegra_read(t, UART_LSR) & UART_LSR_DR)
70                 (void)tegra_read(t, UART_RX);
71         /* enable rx and lsr interrupt */
72         tegra_write(t, UART_IER_RLSI | UART_IER_RDI, UART_IER);
73         /* interrupt on every character */
74         tegra_write(t, 0, UART_IIR);
75
76         return 0;
77 }
78
79 static int debug_getc(struct platform_device *pdev)
80 {
81         unsigned int lsr;
82         struct tegra_fiq_debugger *t;
83         t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
84
85         lsr = tegra_read_lsr(t);
86
87         if (lsr & UART_LSR_BI || t->break_seen) {
88                 t->break_seen = false;
89                 return FIQ_DEBUGGER_BREAK;
90         }
91
92         if (lsr & UART_LSR_DR)
93                 return tegra_read(t, UART_RX);
94
95         return FIQ_DEBUGGER_NO_CHAR;
96 }
97
98 static void debug_putc(struct platform_device *pdev, unsigned int c)
99 {
100         struct tegra_fiq_debugger *t;
101         t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
102
103         while (!(tegra_read_lsr(t) & UART_LSR_THRE))
104                 cpu_relax();
105
106         tegra_write(t, c, UART_TX);
107 }
108
109 static void debug_flush(struct platform_device *pdev)
110 {
111         struct tegra_fiq_debugger *t;
112         t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
113
114         while (!(tegra_read_lsr(t) & UART_LSR_TEMT))
115                 cpu_relax();
116 }
117
118 static void fiq_enable(struct platform_device *pdev, unsigned int irq, bool on)
119 {
120         if (on)
121                 tegra_fiq_enable(irq);
122         else
123                 tegra_fiq_disable(irq);
124 }
125
126 static int tegra_fiq_debugger_id;
127
128 void tegra_serial_debug_init(unsigned int base, int irq,
129                            struct clk *clk, int signal_irq, int wakeup_irq)
130 {
131         struct tegra_fiq_debugger *t;
132         struct platform_device *pdev;
133         struct resource *res;
134         int res_count;
135
136         t = kzalloc(sizeof(struct tegra_fiq_debugger), GFP_KERNEL);
137         if (!t) {
138                 pr_err("Failed to allocate for fiq debugger\n");
139                 return;
140         }
141
142         t->pdata.uart_init = debug_port_init;
143         t->pdata.uart_getc = debug_getc;
144         t->pdata.uart_putc = debug_putc;
145         t->pdata.uart_flush = debug_flush;
146         t->pdata.fiq_enable = fiq_enable;
147
148         t->debug_port_base = ioremap(base, PAGE_SIZE);
149         if (!t->debug_port_base) {
150                 pr_err("Failed to ioremap for fiq debugger\n");
151                 goto out1;
152         }
153
154         res = kzalloc(sizeof(struct resource) * 3, GFP_KERNEL);
155         if (!res) {
156                 pr_err("Failed to alloc fiq debugger resources\n");
157                 goto out2;
158         }
159
160         pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
161         if (!pdev) {
162                 pr_err("Failed to alloc fiq debugger platform device\n");
163                 goto out3;
164         };
165
166         res[0].flags = IORESOURCE_IRQ;
167         res[0].start = irq;
168         res[0].end = irq;
169         res[0].name = "fiq";
170
171         res[1].flags = IORESOURCE_IRQ;
172         res[1].start = signal_irq;
173         res[1].end = signal_irq;
174         res[1].name = "signal";
175         res_count = 2;
176
177         if (wakeup_irq >= 0) {
178                 res[2].flags = IORESOURCE_IRQ;
179                 res[2].start = wakeup_irq;
180                 res[2].end = wakeup_irq;
181                 res[2].name = "wakeup";
182                 res_count++;
183         }
184
185         pdev->name = "fiq_debugger";
186         pdev->id = tegra_fiq_debugger_id++;
187         pdev->dev.platform_data = &t->pdata;
188         pdev->resource = res;
189         pdev->num_resources = res_count;
190
191         if (platform_device_register(pdev)) {
192                 pr_err("Failed to register fiq debugger\n");
193                 goto out4;
194         }
195
196         return;
197
198 out4:
199         kfree(pdev);
200 out3:
201         kfree(res);
202 out2:
203         iounmap(t->debug_port_base);
204 out1:
205         kfree(t);
206 }