aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris/arch-v32
diff options
context:
space:
mode:
authorJesper Nilsson <jespern@axis.com>2014-10-08 09:52:49 -0400
committerJesper Nilsson <jespern@axis.com>2014-12-19 18:05:49 -0500
commit4729d77332a4383770c780b7709d5e14f12a4d1e (patch)
treebcea3bc26897cf5bb6ae005e66a8cf2206f13936 /arch/cris/arch-v32
parent421d085252613c4caf9c4f2fda3c722a9f5bc554 (diff)
CRISv32: Implement early console
Signed-off-by: Jesper Nilsson <jesper.nilsson@axis.com>
Diffstat (limited to 'arch/cris/arch-v32')
-rw-r--r--arch/cris/arch-v32/kernel/debugport.c82
1 files changed, 56 insertions, 26 deletions
diff --git a/arch/cris/arch-v32/kernel/debugport.c b/arch/cris/arch-v32/kernel/debugport.c
index 610909b003f6..02e33ebe51ec 100644
--- a/arch/cris/arch-v32/kernel/debugport.c
+++ b/arch/cris/arch-v32/kernel/debugport.c
@@ -3,7 +3,9 @@
3 */ 3 */
4 4
5#include <linux/console.h> 5#include <linux/console.h>
6#include <linux/kernel.h>
6#include <linux/init.h> 7#include <linux/init.h>
8#include <linux/string.h>
7#include <hwregs/reg_rdwr.h> 9#include <hwregs/reg_rdwr.h>
8#include <hwregs/reg_map.h> 10#include <hwregs/reg_map.h>
9#include <hwregs/ser_defs.h> 11#include <hwregs/ser_defs.h>
@@ -65,6 +67,7 @@ struct dbg_port ports[] =
65 }, 67 },
66#endif 68#endif
67}; 69};
70
68static struct dbg_port *port = 71static struct dbg_port *port =
69#if defined(CONFIG_ETRAX_DEBUG_PORT0) 72#if defined(CONFIG_ETRAX_DEBUG_PORT0)
70 &ports[0]; 73 &ports[0];
@@ -97,14 +100,19 @@ static struct dbg_port *kgdb_port =
97#endif 100#endif
98#endif 101#endif
99 102
100static void 103static void start_port(struct dbg_port *p)
101start_port(struct dbg_port* p)
102{ 104{
103 if (!p) 105 /* Set up serial port registers */
104 return; 106 reg_ser_rw_tr_ctrl tr_ctrl = {0};
107 reg_ser_rw_tr_dma_en tr_dma_en = {0};
105 108
106 if (p->started) 109 reg_ser_rw_rec_ctrl rec_ctrl = {0};
110 reg_ser_rw_tr_baud_div tr_baud_div = {0};
111 reg_ser_rw_rec_baud_div rec_baud_div = {0};
112
113 if (!p || p->started)
107 return; 114 return;
115
108 p->started = 1; 116 p->started = 1;
109 117
110 if (p->nbr == 1) 118 if (p->nbr == 1)
@@ -118,36 +126,24 @@ start_port(struct dbg_port* p)
118 crisv32_pinmux_alloc_fixed(pinmux_ser4); 126 crisv32_pinmux_alloc_fixed(pinmux_ser4);
119#endif 127#endif
120 128
121 /* Set up serial port registers */
122 reg_ser_rw_tr_ctrl tr_ctrl = {0};
123 reg_ser_rw_tr_dma_en tr_dma_en = {0};
124
125 reg_ser_rw_rec_ctrl rec_ctrl = {0};
126 reg_ser_rw_tr_baud_div tr_baud_div = {0};
127 reg_ser_rw_rec_baud_div rec_baud_div = {0};
128
129 tr_ctrl.base_freq = rec_ctrl.base_freq = regk_ser_f29_493; 129 tr_ctrl.base_freq = rec_ctrl.base_freq = regk_ser_f29_493;
130 tr_dma_en.en = rec_ctrl.dma_mode = regk_ser_no; 130 tr_dma_en.en = rec_ctrl.dma_mode = regk_ser_no;
131 tr_baud_div.div = rec_baud_div.div = 29493000 / p->baudrate / 8; 131 tr_baud_div.div = rec_baud_div.div = 29493000 / p->baudrate / 8;
132 tr_ctrl.en = rec_ctrl.en = 1; 132 tr_ctrl.en = rec_ctrl.en = 1;
133 133
134 if (p->parity == 'O') 134 if (p->parity == 'O') {
135 {
136 tr_ctrl.par_en = regk_ser_yes; 135 tr_ctrl.par_en = regk_ser_yes;
137 tr_ctrl.par = regk_ser_odd; 136 tr_ctrl.par = regk_ser_odd;
138 rec_ctrl.par_en = regk_ser_yes; 137 rec_ctrl.par_en = regk_ser_yes;
139 rec_ctrl.par = regk_ser_odd; 138 rec_ctrl.par = regk_ser_odd;
140 } 139 } else if (p->parity == 'E') {
141 else if (p->parity == 'E')
142 {
143 tr_ctrl.par_en = regk_ser_yes; 140 tr_ctrl.par_en = regk_ser_yes;
144 tr_ctrl.par = regk_ser_even; 141 tr_ctrl.par = regk_ser_even;
145 rec_ctrl.par_en = regk_ser_yes; 142 rec_ctrl.par_en = regk_ser_yes;
146 rec_ctrl.par = regk_ser_odd; 143 rec_ctrl.par = regk_ser_odd;
147 } 144 }
148 145
149 if (p->bits == 7) 146 if (p->bits == 7) {
150 {
151 tr_ctrl.data_bits = regk_ser_bits7; 147 tr_ctrl.data_bits = regk_ser_bits7;
152 rec_ctrl.data_bits = regk_ser_bits7; 148 rec_ctrl.data_bits = regk_ser_bits7;
153 } 149 }
@@ -161,8 +157,7 @@ start_port(struct dbg_port* p)
161 157
162#ifdef CONFIG_ETRAX_KGDB 158#ifdef CONFIG_ETRAX_KGDB
163/* Use polling to get a single character from the kernel debug port */ 159/* Use polling to get a single character from the kernel debug port */
164int 160int getDebugChar(void)
165getDebugChar(void)
166{ 161{
167 reg_ser_rs_stat_din stat; 162 reg_ser_rs_stat_din stat;
168 reg_ser_rw_ack_intr ack_intr = { 0 }; 163 reg_ser_rw_ack_intr ack_intr = { 0 };
@@ -179,8 +174,7 @@ getDebugChar(void)
179} 174}
180 175
181/* Use polling to put a single character to the kernel debug port */ 176/* Use polling to put a single character to the kernel debug port */
182void 177void putDebugChar(int val)
183putDebugChar(int val)
184{ 178{
185 reg_ser_r_stat_din stat; 179 reg_ser_r_stat_din stat;
186 do { 180 do {
@@ -190,12 +184,48 @@ putDebugChar(int val)
190} 184}
191#endif /* CONFIG_ETRAX_KGDB */ 185#endif /* CONFIG_ETRAX_KGDB */
192 186
187static void __init early_putch(int c)
188{
189 reg_ser_r_stat_din stat;
190 /* Wait until transmitter is ready and send. */
191 do
192 stat = REG_RD(ser, port->instance, r_stat_din);
193 while (!stat.tr_rdy);
194 REG_WR_INT(ser, port->instance, rw_dout, c);
195}
196
197static void __init
198early_console_write(struct console *con, const char *s, unsigned n)
199{
200 extern void reset_watchdog(void);
201 int i;
202
203 /* Send data. */
204 for (i = 0; i < n; i++) {
205 /* TODO: the '\n' -> '\n\r' translation should be done at the
206 receiver. Remove it when the serial driver removes it. */
207 if (s[i] == '\n')
208 early_putch('\r');
209 early_putch(s[i]);
210 reset_watchdog();
211 }
212}
213
214static struct console early_console_dev __initdata = {
215 .name = "early",
216 .write = early_console_write,
217 .flags = CON_PRINTBUFFER | CON_BOOT,
218 .index = -1
219};
220
193/* Register console for printk's, etc. */ 221/* Register console for printk's, etc. */
194int __init 222int __init init_etrax_debug(void)
195init_etrax_debug(void)
196{ 223{
197 start_port(port); 224 start_port(port);
198 225
226 /* Register an early console if a debug port was chosen. */
227 register_console(&early_console_dev);
228
199#ifdef CONFIG_ETRAX_KGDB 229#ifdef CONFIG_ETRAX_KGDB
200 start_port(kgdb_port); 230 start_port(kgdb_port);
201#endif /* CONFIG_ETRAX_KGDB */ 231#endif /* CONFIG_ETRAX_KGDB */