Commit 4729d77332a4383770c780b7709d5e14f12a4d1e

Authored by Jesper Nilsson
1 parent 421d085252

CRISv32: Implement early console

Signed-off-by: Jesper Nilsson <jesper.nilsson@axis.com>

Showing 1 changed file with 56 additions and 26 deletions Side-by-side Diff

arch/cris/arch-v32/kernel/debugport.c
... ... @@ -3,7 +3,9 @@
3 3 */
4 4  
5 5 #include <linux/console.h>
  6 +#include <linux/kernel.h>
6 7 #include <linux/init.h>
  8 +#include <linux/string.h>
7 9 #include <hwregs/reg_rdwr.h>
8 10 #include <hwregs/reg_map.h>
9 11 #include <hwregs/ser_defs.h>
... ... @@ -65,6 +67,7 @@
65 67 },
66 68 #endif
67 69 };
  70 +
68 71 static struct dbg_port *port =
69 72 #if defined(CONFIG_ETRAX_DEBUG_PORT0)
70 73 &ports[0];
71 74  
72 75  
73 76  
... ... @@ -97,14 +100,19 @@
97 100 #endif
98 101 #endif
99 102  
100   -static void
101   -start_port(struct dbg_port* p)
  103 +static void start_port(struct dbg_port *p)
102 104 {
103   - if (!p)
104   - return;
  105 + /* Set up serial port registers */
  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 114 return;
  115 +
108 116 p->started = 1;
109 117  
110 118 if (p->nbr == 1)
111 119  
112 120  
113 121  
... ... @@ -118,36 +126,24 @@
118 126 crisv32_pinmux_alloc_fixed(pinmux_ser4);
119 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 129 tr_ctrl.base_freq = rec_ctrl.base_freq = regk_ser_f29_493;
130 130 tr_dma_en.en = rec_ctrl.dma_mode = regk_ser_no;
131 131 tr_baud_div.div = rec_baud_div.div = 29493000 / p->baudrate / 8;
132 132 tr_ctrl.en = rec_ctrl.en = 1;
133 133  
134   - if (p->parity == 'O')
135   - {
  134 + if (p->parity == 'O') {
136 135 tr_ctrl.par_en = regk_ser_yes;
137 136 tr_ctrl.par = regk_ser_odd;
138 137 rec_ctrl.par_en = regk_ser_yes;
139 138 rec_ctrl.par = regk_ser_odd;
140   - }
141   - else if (p->parity == 'E')
142   - {
  139 + } else if (p->parity == 'E') {
143 140 tr_ctrl.par_en = regk_ser_yes;
144 141 tr_ctrl.par = regk_ser_even;
145 142 rec_ctrl.par_en = regk_ser_yes;
146 143 rec_ctrl.par = regk_ser_odd;
147 144 }
148 145  
149   - if (p->bits == 7)
150   - {
  146 + if (p->bits == 7) {
151 147 tr_ctrl.data_bits = regk_ser_bits7;
152 148 rec_ctrl.data_bits = regk_ser_bits7;
153 149 }
... ... @@ -161,8 +157,7 @@
161 157  
162 158 #ifdef CONFIG_ETRAX_KGDB
163 159 /* Use polling to get a single character from the kernel debug port */
164   -int
165   -getDebugChar(void)
  160 +int getDebugChar(void)
166 161 {
167 162 reg_ser_rs_stat_din stat;
168 163 reg_ser_rw_ack_intr ack_intr = { 0 };
... ... @@ -179,8 +174,7 @@
179 174 }
180 175  
181 176 /* Use polling to put a single character to the kernel debug port */
182   -void
183   -putDebugChar(int val)
  177 +void putDebugChar(int val)
184 178 {
185 179 reg_ser_r_stat_din stat;
186 180 do {
187 181  
188 182  
... ... @@ -190,11 +184,47 @@
190 184 }
191 185 #endif /* CONFIG_ETRAX_KGDB */
192 186  
  187 +static 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 +
  197 +static void __init
  198 +early_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 +
  214 +static 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 221 /* Register console for printk's, etc. */
194   -int __init
195   -init_etrax_debug(void)
  222 +int __init init_etrax_debug(void)
196 223 {
197 224 start_port(port);
  225 +
  226 + /* Register an early console if a debug port was chosen. */
  227 + register_console(&early_console_dev);
198 228  
199 229 #ifdef CONFIG_ETRAX_KGDB
200 230 start_port(kgdb_port);