diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-15 14:37:02 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-15 14:37:02 -0500 |
commit | a9724125ad014decf008d782e60447c811391326 (patch) | |
tree | 4fac069d155f2495907fa9c296cc5426d0eebf55 /drivers/tty | |
parent | 46f7b635569731ff81a3b72d1bcd4415b293b637 (diff) | |
parent | c09babfab7ae8c7d79a5dce9d866fbb28b82dde4 (diff) |
Merge tag 'tty-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial driver patches from Greg KH:
"Here's the big tty/serial driver update for 3.20-rc1. Nothing huge
here, just lots of driver updates and some core tty layer fixes as
well. All have been in linux-next with no reported issues"
* tag 'tty-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (119 commits)
serial: 8250: Fix UART_BUG_TXEN workaround
serial: driver for ETRAX FS UART
tty: remove unused variable sprop
serial: of-serial: fetch line number from DT
serial: samsung: earlycon support depends on CONFIG_SERIAL_SAMSUNG_CONSOLE
tty/serial: serial8250_set_divisor() can be static
tty/serial: Add Spreadtrum sc9836-uart driver support
Documentation: DT: Add bindings for Spreadtrum SoC Platform
serial: samsung: remove redundant interrupt enabling
tty: Remove external interface for tty_set_termios()
serial: omap: Fix RTS handling
serial: 8250_omap: Use UPSTAT_AUTORTS for RTS handling
serial: core: Rework hw-assisted flow control support
tty/serial: 8250_early: Add support for PXA UARTs
tty/serial: of_serial: add support for PXA/MMP uarts
tty/serial: of_serial: add DT alias ID handling
serial: 8250: Prevent concurrent updates to shadow registers
serial: 8250: Use canary to restart console after suspend
serial: 8250: Refactor XR17V35X divisor calculation
serial: 8250: Refactor divisor programming
...
Diffstat (limited to 'drivers/tty')
43 files changed, 4176 insertions, 1605 deletions
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index d9f85f95eb2a..b2d760055952 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c | |||
@@ -931,7 +931,7 @@ static void rs_send_xchar(struct tty_struct *tty, char ch) | |||
931 | struct serial_state *info = tty->driver_data; | 931 | struct serial_state *info = tty->driver_data; |
932 | unsigned long flags; | 932 | unsigned long flags; |
933 | 933 | ||
934 | if (serial_paranoia_check(info, tty->name, "rs_send_char")) | 934 | if (serial_paranoia_check(info, tty->name, "rs_send_xchar")) |
935 | return; | 935 | return; |
936 | 936 | ||
937 | info->x_char = ch; | 937 | info->x_char = ch; |
diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index 3c60923b0957..342b36b9ad35 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c | |||
@@ -112,7 +112,6 @@ static void disable_tx_interrupt(struct ehv_bc_data *bc) | |||
112 | static int find_console_handle(void) | 112 | static int find_console_handle(void) |
113 | { | 113 | { |
114 | struct device_node *np = of_stdout; | 114 | struct device_node *np = of_stdout; |
115 | const char *sprop = NULL; | ||
116 | const uint32_t *iprop; | 115 | const uint32_t *iprop; |
117 | 116 | ||
118 | /* We don't care what the aliased node is actually called. We only | 117 | /* We don't care what the aliased node is actually called. We only |
diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c index 59ed783c4bcd..2054427992e0 100644 --- a/drivers/tty/isicom.c +++ b/drivers/tty/isicom.c | |||
@@ -1055,7 +1055,7 @@ static int isicom_send_break(struct tty_struct *tty, int length) | |||
1055 | 1055 | ||
1056 | outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base); | 1056 | outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base); |
1057 | outw((length & 0xff) << 8 | 0x00, base); | 1057 | outw((length & 0xff) << 8 | 0x00, base); |
1058 | outw((length & 0xff00), base); | 1058 | outw((length & 0xff00u), base); |
1059 | InterruptTheCard(base); | 1059 | InterruptTheCard(base); |
1060 | 1060 | ||
1061 | unlock_card(card); | 1061 | unlock_card(card); |
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 4ddfa60c9222..cf6e0f2e1331 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
@@ -90,6 +90,7 @@ | |||
90 | struct n_tty_data { | 90 | struct n_tty_data { |
91 | /* producer-published */ | 91 | /* producer-published */ |
92 | size_t read_head; | 92 | size_t read_head; |
93 | size_t commit_head; | ||
93 | size_t canon_head; | 94 | size_t canon_head; |
94 | size_t echo_head; | 95 | size_t echo_head; |
95 | size_t echo_commit; | 96 | size_t echo_commit; |
@@ -161,36 +162,11 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x, | |||
161 | return put_user(x, ptr); | 162 | return put_user(x, ptr); |
162 | } | 163 | } |
163 | 164 | ||
164 | static int receive_room(struct tty_struct *tty) | ||
165 | { | ||
166 | struct n_tty_data *ldata = tty->disc_data; | ||
167 | int left; | ||
168 | |||
169 | if (I_PARMRK(tty)) { | ||
170 | /* Multiply read_cnt by 3, since each byte might take up to | ||
171 | * three times as many spaces when PARMRK is set (depending on | ||
172 | * its flags, e.g. parity error). */ | ||
173 | left = N_TTY_BUF_SIZE - read_cnt(ldata) * 3 - 1; | ||
174 | } else | ||
175 | left = N_TTY_BUF_SIZE - read_cnt(ldata) - 1; | ||
176 | |||
177 | /* | ||
178 | * If we are doing input canonicalization, and there are no | ||
179 | * pending newlines, let characters through without limit, so | ||
180 | * that erase characters will be handled. Other excess | ||
181 | * characters will be beeped. | ||
182 | */ | ||
183 | if (left <= 0) | ||
184 | left = ldata->icanon && ldata->canon_head == ldata->read_tail; | ||
185 | |||
186 | return left; | ||
187 | } | ||
188 | |||
189 | /** | 165 | /** |
190 | * n_tty_set_room - receive space | 166 | * n_tty_kick_worker - start input worker (if required) |
191 | * @tty: terminal | 167 | * @tty: terminal |
192 | * | 168 | * |
193 | * Re-schedules the flip buffer work if space just became available. | 169 | * Re-schedules the flip buffer work if it may have stopped |
194 | * | 170 | * |
195 | * Caller holds exclusive termios_rwsem | 171 | * Caller holds exclusive termios_rwsem |
196 | * or | 172 | * or |
@@ -198,12 +174,12 @@ static int receive_room(struct tty_struct *tty) | |||
198 | * holds non-exclusive termios_rwsem | 174 | * holds non-exclusive termios_rwsem |
199 | */ | 175 | */ |
200 | 176 | ||
201 | static void n_tty_set_room(struct tty_struct *tty) | 177 | static void n_tty_kick_worker(struct tty_struct *tty) |
202 | { | 178 | { |
203 | struct n_tty_data *ldata = tty->disc_data; | 179 | struct n_tty_data *ldata = tty->disc_data; |
204 | 180 | ||
205 | /* Did this open up the receive buffer? We may need to flip */ | 181 | /* Did the input worker stop? Restart it */ |
206 | if (unlikely(ldata->no_room) && receive_room(tty)) { | 182 | if (unlikely(ldata->no_room)) { |
207 | ldata->no_room = 0; | 183 | ldata->no_room = 0; |
208 | 184 | ||
209 | WARN_RATELIMIT(tty->port->itty == NULL, | 185 | WARN_RATELIMIT(tty->port->itty == NULL, |
@@ -224,7 +200,7 @@ static ssize_t chars_in_buffer(struct tty_struct *tty) | |||
224 | ssize_t n = 0; | 200 | ssize_t n = 0; |
225 | 201 | ||
226 | if (!ldata->icanon) | 202 | if (!ldata->icanon) |
227 | n = read_cnt(ldata); | 203 | n = ldata->commit_head - ldata->read_tail; |
228 | else | 204 | else |
229 | n = ldata->canon_head - ldata->read_tail; | 205 | n = ldata->canon_head - ldata->read_tail; |
230 | return n; | 206 | return n; |
@@ -247,17 +223,20 @@ static void n_tty_write_wakeup(struct tty_struct *tty) | |||
247 | 223 | ||
248 | static void n_tty_check_throttle(struct tty_struct *tty) | 224 | static void n_tty_check_throttle(struct tty_struct *tty) |
249 | { | 225 | { |
250 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY) | 226 | struct n_tty_data *ldata = tty->disc_data; |
251 | return; | 227 | |
252 | /* | 228 | /* |
253 | * Check the remaining room for the input canonicalization | 229 | * Check the remaining room for the input canonicalization |
254 | * mode. We don't want to throttle the driver if we're in | 230 | * mode. We don't want to throttle the driver if we're in |
255 | * canonical mode and don't have a newline yet! | 231 | * canonical mode and don't have a newline yet! |
256 | */ | 232 | */ |
233 | if (ldata->icanon && ldata->canon_head == ldata->read_tail) | ||
234 | return; | ||
235 | |||
257 | while (1) { | 236 | while (1) { |
258 | int throttled; | 237 | int throttled; |
259 | tty_set_flow_change(tty, TTY_THROTTLE_SAFE); | 238 | tty_set_flow_change(tty, TTY_THROTTLE_SAFE); |
260 | if (receive_room(tty) >= TTY_THRESHOLD_THROTTLE) | 239 | if (N_TTY_BUF_SIZE - read_cnt(ldata) >= TTY_THRESHOLD_THROTTLE) |
261 | break; | 240 | break; |
262 | throttled = tty_throttle_safe(tty); | 241 | throttled = tty_throttle_safe(tty); |
263 | if (!throttled) | 242 | if (!throttled) |
@@ -274,7 +253,7 @@ static void n_tty_check_unthrottle(struct tty_struct *tty) | |||
274 | return; | 253 | return; |
275 | if (!tty->count) | 254 | if (!tty->count) |
276 | return; | 255 | return; |
277 | n_tty_set_room(tty); | 256 | n_tty_kick_worker(tty); |
278 | n_tty_write_wakeup(tty->link); | 257 | n_tty_write_wakeup(tty->link); |
279 | if (waitqueue_active(&tty->link->write_wait)) | 258 | if (waitqueue_active(&tty->link->write_wait)) |
280 | wake_up_interruptible_poll(&tty->link->write_wait, POLLOUT); | 259 | wake_up_interruptible_poll(&tty->link->write_wait, POLLOUT); |
@@ -296,7 +275,7 @@ static void n_tty_check_unthrottle(struct tty_struct *tty) | |||
296 | break; | 275 | break; |
297 | if (!tty->count) | 276 | if (!tty->count) |
298 | break; | 277 | break; |
299 | n_tty_set_room(tty); | 278 | n_tty_kick_worker(tty); |
300 | unthrottled = tty_unthrottle_safe(tty); | 279 | unthrottled = tty_unthrottle_safe(tty); |
301 | if (!unthrottled) | 280 | if (!unthrottled) |
302 | break; | 281 | break; |
@@ -313,10 +292,6 @@ static void n_tty_check_unthrottle(struct tty_struct *tty) | |||
313 | * | 292 | * |
314 | * n_tty_receive_buf()/producer path: | 293 | * n_tty_receive_buf()/producer path: |
315 | * caller holds non-exclusive termios_rwsem | 294 | * caller holds non-exclusive termios_rwsem |
316 | * modifies read_head | ||
317 | * | ||
318 | * read_head is only considered 'published' if canonical mode is | ||
319 | * not active. | ||
320 | */ | 295 | */ |
321 | 296 | ||
322 | static inline void put_tty_queue(unsigned char c, struct n_tty_data *ldata) | 297 | static inline void put_tty_queue(unsigned char c, struct n_tty_data *ldata) |
@@ -340,6 +315,7 @@ static void reset_buffer_flags(struct n_tty_data *ldata) | |||
340 | { | 315 | { |
341 | ldata->read_head = ldata->canon_head = ldata->read_tail = 0; | 316 | ldata->read_head = ldata->canon_head = ldata->read_tail = 0; |
342 | ldata->echo_head = ldata->echo_tail = ldata->echo_commit = 0; | 317 | ldata->echo_head = ldata->echo_tail = ldata->echo_commit = 0; |
318 | ldata->commit_head = 0; | ||
343 | ldata->echo_mark = 0; | 319 | ldata->echo_mark = 0; |
344 | ldata->line_start = 0; | 320 | ldata->line_start = 0; |
345 | 321 | ||
@@ -379,7 +355,7 @@ static void n_tty_flush_buffer(struct tty_struct *tty) | |||
379 | { | 355 | { |
380 | down_write(&tty->termios_rwsem); | 356 | down_write(&tty->termios_rwsem); |
381 | reset_buffer_flags(tty->disc_data); | 357 | reset_buffer_flags(tty->disc_data); |
382 | n_tty_set_room(tty); | 358 | n_tty_kick_worker(tty); |
383 | 359 | ||
384 | if (tty->link) | 360 | if (tty->link) |
385 | n_tty_packet_mode_flush(tty); | 361 | n_tty_packet_mode_flush(tty); |
@@ -987,10 +963,6 @@ static inline void finish_erasing(struct n_tty_data *ldata) | |||
987 | * | 963 | * |
988 | * n_tty_receive_buf()/producer path: | 964 | * n_tty_receive_buf()/producer path: |
989 | * caller holds non-exclusive termios_rwsem | 965 | * caller holds non-exclusive termios_rwsem |
990 | * modifies read_head | ||
991 | * | ||
992 | * Modifying the read_head is not considered a publish in this context | ||
993 | * because canonical mode is active -- only canon_head publishes | ||
994 | */ | 966 | */ |
995 | 967 | ||
996 | static void eraser(unsigned char c, struct tty_struct *tty) | 968 | static void eraser(unsigned char c, struct tty_struct *tty) |
@@ -1118,16 +1090,45 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
1118 | * Called when a signal is being sent due to terminal input. | 1090 | * Called when a signal is being sent due to terminal input. |
1119 | * Called from the driver receive_buf path so serialized. | 1091 | * Called from the driver receive_buf path so serialized. |
1120 | * | 1092 | * |
1093 | * Performs input and output flush if !NOFLSH. In this context, the echo | ||
1094 | * buffer is 'output'. The signal is processed first to alert any current | ||
1095 | * readers or writers to discontinue and exit their i/o loops. | ||
1096 | * | ||
1121 | * Locking: ctrl_lock | 1097 | * Locking: ctrl_lock |
1122 | */ | 1098 | */ |
1123 | 1099 | ||
1124 | static void isig(int sig, struct tty_struct *tty) | 1100 | static void isig(int sig, struct tty_struct *tty) |
1125 | { | 1101 | { |
1102 | struct n_tty_data *ldata = tty->disc_data; | ||
1126 | struct pid *tty_pgrp = tty_get_pgrp(tty); | 1103 | struct pid *tty_pgrp = tty_get_pgrp(tty); |
1127 | if (tty_pgrp) { | 1104 | if (tty_pgrp) { |
1128 | kill_pgrp(tty_pgrp, sig, 1); | 1105 | kill_pgrp(tty_pgrp, sig, 1); |
1129 | put_pid(tty_pgrp); | 1106 | put_pid(tty_pgrp); |
1130 | } | 1107 | } |
1108 | |||
1109 | if (!L_NOFLSH(tty)) { | ||
1110 | up_read(&tty->termios_rwsem); | ||
1111 | down_write(&tty->termios_rwsem); | ||
1112 | |||
1113 | /* clear echo buffer */ | ||
1114 | mutex_lock(&ldata->output_lock); | ||
1115 | ldata->echo_head = ldata->echo_tail = 0; | ||
1116 | ldata->echo_mark = ldata->echo_commit = 0; | ||
1117 | mutex_unlock(&ldata->output_lock); | ||
1118 | |||
1119 | /* clear output buffer */ | ||
1120 | tty_driver_flush_buffer(tty); | ||
1121 | |||
1122 | /* clear input buffer */ | ||
1123 | reset_buffer_flags(tty->disc_data); | ||
1124 | |||
1125 | /* notify pty master of flush */ | ||
1126 | if (tty->link) | ||
1127 | n_tty_packet_mode_flush(tty); | ||
1128 | |||
1129 | up_write(&tty->termios_rwsem); | ||
1130 | down_read(&tty->termios_rwsem); | ||
1131 | } | ||
1131 | } | 1132 | } |
1132 | 1133 | ||
1133 | /** | 1134 | /** |
@@ -1139,7 +1140,6 @@ static void isig(int sig, struct tty_struct *tty) | |||
1139 | * | 1140 | * |
1140 | * n_tty_receive_buf()/producer path: | 1141 | * n_tty_receive_buf()/producer path: |
1141 | * caller holds non-exclusive termios_rwsem | 1142 | * caller holds non-exclusive termios_rwsem |
1142 | * publishes read_head via put_tty_queue() | ||
1143 | * | 1143 | * |
1144 | * Note: may get exclusive termios_rwsem if flushing input buffer | 1144 | * Note: may get exclusive termios_rwsem if flushing input buffer |
1145 | */ | 1145 | */ |
@@ -1152,13 +1152,6 @@ static void n_tty_receive_break(struct tty_struct *tty) | |||
1152 | return; | 1152 | return; |
1153 | if (I_BRKINT(tty)) { | 1153 | if (I_BRKINT(tty)) { |
1154 | isig(SIGINT, tty); | 1154 | isig(SIGINT, tty); |
1155 | if (!L_NOFLSH(tty)) { | ||
1156 | /* flushing needs exclusive termios_rwsem */ | ||
1157 | up_read(&tty->termios_rwsem); | ||
1158 | n_tty_flush_buffer(tty); | ||
1159 | tty_driver_flush_buffer(tty); | ||
1160 | down_read(&tty->termios_rwsem); | ||
1161 | } | ||
1162 | return; | 1155 | return; |
1163 | } | 1156 | } |
1164 | if (I_PARMRK(tty)) { | 1157 | if (I_PARMRK(tty)) { |
@@ -1209,7 +1202,6 @@ static void n_tty_receive_overrun(struct tty_struct *tty) | |||
1209 | * | 1202 | * |
1210 | * n_tty_receive_buf()/producer path: | 1203 | * n_tty_receive_buf()/producer path: |
1211 | * caller holds non-exclusive termios_rwsem | 1204 | * caller holds non-exclusive termios_rwsem |
1212 | * publishes read_head via put_tty_queue() | ||
1213 | */ | 1205 | */ |
1214 | static void n_tty_receive_parity_error(struct tty_struct *tty, unsigned char c) | 1206 | static void n_tty_receive_parity_error(struct tty_struct *tty, unsigned char c) |
1215 | { | 1207 | { |
@@ -1233,13 +1225,7 @@ static void n_tty_receive_parity_error(struct tty_struct *tty, unsigned char c) | |||
1233 | static void | 1225 | static void |
1234 | n_tty_receive_signal_char(struct tty_struct *tty, int signal, unsigned char c) | 1226 | n_tty_receive_signal_char(struct tty_struct *tty, int signal, unsigned char c) |
1235 | { | 1227 | { |
1236 | if (!L_NOFLSH(tty)) { | 1228 | isig(signal, tty); |
1237 | /* flushing needs exclusive termios_rwsem */ | ||
1238 | up_read(&tty->termios_rwsem); | ||
1239 | n_tty_flush_buffer(tty); | ||
1240 | tty_driver_flush_buffer(tty); | ||
1241 | down_read(&tty->termios_rwsem); | ||
1242 | } | ||
1243 | if (I_IXON(tty)) | 1229 | if (I_IXON(tty)) |
1244 | start_tty(tty); | 1230 | start_tty(tty); |
1245 | if (L_ECHO(tty)) { | 1231 | if (L_ECHO(tty)) { |
@@ -1247,7 +1233,6 @@ n_tty_receive_signal_char(struct tty_struct *tty, int signal, unsigned char c) | |||
1247 | commit_echoes(tty); | 1233 | commit_echoes(tty); |
1248 | } else | 1234 | } else |
1249 | process_echoes(tty); | 1235 | process_echoes(tty); |
1250 | isig(signal, tty); | ||
1251 | return; | 1236 | return; |
1252 | } | 1237 | } |
1253 | 1238 | ||
@@ -1263,7 +1248,6 @@ n_tty_receive_signal_char(struct tty_struct *tty, int signal, unsigned char c) | |||
1263 | * n_tty_receive_buf()/producer path: | 1248 | * n_tty_receive_buf()/producer path: |
1264 | * caller holds non-exclusive termios_rwsem | 1249 | * caller holds non-exclusive termios_rwsem |
1265 | * publishes canon_head if canonical mode is active | 1250 | * publishes canon_head if canonical mode is active |
1266 | * otherwise, publishes read_head via put_tty_queue() | ||
1267 | * | 1251 | * |
1268 | * Returns 1 if LNEXT was received, else returns 0 | 1252 | * Returns 1 if LNEXT was received, else returns 0 |
1269 | */ | 1253 | */ |
@@ -1376,7 +1360,7 @@ n_tty_receive_char_special(struct tty_struct *tty, unsigned char c) | |||
1376 | handle_newline: | 1360 | handle_newline: |
1377 | set_bit(ldata->read_head & (N_TTY_BUF_SIZE - 1), ldata->read_flags); | 1361 | set_bit(ldata->read_head & (N_TTY_BUF_SIZE - 1), ldata->read_flags); |
1378 | put_tty_queue(c, ldata); | 1362 | put_tty_queue(c, ldata); |
1379 | ldata->canon_head = ldata->read_head; | 1363 | smp_store_release(&ldata->canon_head, ldata->read_head); |
1380 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); | 1364 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); |
1381 | if (waitqueue_active(&tty->read_wait)) | 1365 | if (waitqueue_active(&tty->read_wait)) |
1382 | wake_up_interruptible_poll(&tty->read_wait, POLLIN); | 1366 | wake_up_interruptible_poll(&tty->read_wait, POLLIN); |
@@ -1512,23 +1496,6 @@ n_tty_receive_char_lnext(struct tty_struct *tty, unsigned char c, char flag) | |||
1512 | n_tty_receive_char_flagged(tty, c, flag); | 1496 | n_tty_receive_char_flagged(tty, c, flag); |
1513 | } | 1497 | } |
1514 | 1498 | ||
1515 | /** | ||
1516 | * n_tty_receive_buf - data receive | ||
1517 | * @tty: terminal device | ||
1518 | * @cp: buffer | ||
1519 | * @fp: flag buffer | ||
1520 | * @count: characters | ||
1521 | * | ||
1522 | * Called by the terminal driver when a block of characters has | ||
1523 | * been received. This function must be called from soft contexts | ||
1524 | * not from interrupt context. The driver is responsible for making | ||
1525 | * calls one at a time and in order (or using flush_to_ldisc) | ||
1526 | * | ||
1527 | * n_tty_receive_buf()/producer path: | ||
1528 | * claims non-exclusive termios_rwsem | ||
1529 | * publishes read_head and canon_head | ||
1530 | */ | ||
1531 | |||
1532 | static void | 1499 | static void |
1533 | n_tty_receive_buf_real_raw(struct tty_struct *tty, const unsigned char *cp, | 1500 | n_tty_receive_buf_real_raw(struct tty_struct *tty, const unsigned char *cp, |
1534 | char *fp, int count) | 1501 | char *fp, int count) |
@@ -1537,16 +1504,14 @@ n_tty_receive_buf_real_raw(struct tty_struct *tty, const unsigned char *cp, | |||
1537 | size_t n, head; | 1504 | size_t n, head; |
1538 | 1505 | ||
1539 | head = ldata->read_head & (N_TTY_BUF_SIZE - 1); | 1506 | head = ldata->read_head & (N_TTY_BUF_SIZE - 1); |
1540 | n = N_TTY_BUF_SIZE - max(read_cnt(ldata), head); | 1507 | n = min_t(size_t, count, N_TTY_BUF_SIZE - head); |
1541 | n = min_t(size_t, count, n); | ||
1542 | memcpy(read_buf_addr(ldata, head), cp, n); | 1508 | memcpy(read_buf_addr(ldata, head), cp, n); |
1543 | ldata->read_head += n; | 1509 | ldata->read_head += n; |
1544 | cp += n; | 1510 | cp += n; |
1545 | count -= n; | 1511 | count -= n; |
1546 | 1512 | ||
1547 | head = ldata->read_head & (N_TTY_BUF_SIZE - 1); | 1513 | head = ldata->read_head & (N_TTY_BUF_SIZE - 1); |
1548 | n = N_TTY_BUF_SIZE - max(read_cnt(ldata), head); | 1514 | n = min_t(size_t, count, N_TTY_BUF_SIZE - head); |
1549 | n = min_t(size_t, count, n); | ||
1550 | memcpy(read_buf_addr(ldata, head), cp, n); | 1515 | memcpy(read_buf_addr(ldata, head), cp, n); |
1551 | ldata->read_head += n; | 1516 | ldata->read_head += n; |
1552 | } | 1517 | } |
@@ -1676,32 +1641,98 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
1676 | tty->ops->flush_chars(tty); | 1641 | tty->ops->flush_chars(tty); |
1677 | } | 1642 | } |
1678 | 1643 | ||
1679 | if ((!ldata->icanon && (read_cnt(ldata) >= ldata->minimum_to_wake)) || | 1644 | if (ldata->icanon && !L_EXTPROC(tty)) |
1680 | L_EXTPROC(tty)) { | 1645 | return; |
1646 | |||
1647 | /* publish read_head to consumer */ | ||
1648 | smp_store_release(&ldata->commit_head, ldata->read_head); | ||
1649 | |||
1650 | if ((read_cnt(ldata) >= ldata->minimum_to_wake) || L_EXTPROC(tty)) { | ||
1681 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); | 1651 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); |
1682 | if (waitqueue_active(&tty->read_wait)) | 1652 | if (waitqueue_active(&tty->read_wait)) |
1683 | wake_up_interruptible_poll(&tty->read_wait, POLLIN); | 1653 | wake_up_interruptible_poll(&tty->read_wait, POLLIN); |
1684 | } | 1654 | } |
1685 | } | 1655 | } |
1686 | 1656 | ||
1657 | /** | ||
1658 | * n_tty_receive_buf_common - process input | ||
1659 | * @tty: device to receive input | ||
1660 | * @cp: input chars | ||
1661 | * @fp: flags for each char (if NULL, all chars are TTY_NORMAL) | ||
1662 | * @count: number of input chars in @cp | ||
1663 | * | ||
1664 | * Called by the terminal driver when a block of characters has | ||
1665 | * been received. This function must be called from soft contexts | ||
1666 | * not from interrupt context. The driver is responsible for making | ||
1667 | * calls one at a time and in order (or using flush_to_ldisc) | ||
1668 | * | ||
1669 | * Returns the # of input chars from @cp which were processed. | ||
1670 | * | ||
1671 | * In canonical mode, the maximum line length is 4096 chars (including | ||
1672 | * the line termination char); lines longer than 4096 chars are | ||
1673 | * truncated. After 4095 chars, input data is still processed but | ||
1674 | * not stored. Overflow processing ensures the tty can always | ||
1675 | * receive more input until at least one line can be read. | ||
1676 | * | ||
1677 | * In non-canonical mode, the read buffer will only accept 4095 chars; | ||
1678 | * this provides the necessary space for a newline char if the input | ||
1679 | * mode is switched to canonical. | ||
1680 | * | ||
1681 | * Note it is possible for the read buffer to _contain_ 4096 chars | ||
1682 | * in non-canonical mode: the read buffer could already contain the | ||
1683 | * maximum canon line of 4096 chars when the mode is switched to | ||
1684 | * non-canonical. | ||
1685 | * | ||
1686 | * n_tty_receive_buf()/producer path: | ||
1687 | * claims non-exclusive termios_rwsem | ||
1688 | * publishes commit_head or canon_head | ||
1689 | */ | ||
1687 | static int | 1690 | static int |
1688 | n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp, | 1691 | n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp, |
1689 | char *fp, int count, int flow) | 1692 | char *fp, int count, int flow) |
1690 | { | 1693 | { |
1691 | struct n_tty_data *ldata = tty->disc_data; | 1694 | struct n_tty_data *ldata = tty->disc_data; |
1692 | int room, n, rcvd = 0; | 1695 | int room, n, rcvd = 0, overflow; |
1693 | 1696 | ||
1694 | down_read(&tty->termios_rwsem); | 1697 | down_read(&tty->termios_rwsem); |
1695 | 1698 | ||
1696 | while (1) { | 1699 | while (1) { |
1697 | room = receive_room(tty); | 1700 | /* |
1701 | * When PARMRK is set, each input char may take up to 3 chars | ||
1702 | * in the read buf; reduce the buffer space avail by 3x | ||
1703 | * | ||
1704 | * If we are doing input canonicalization, and there are no | ||
1705 | * pending newlines, let characters through without limit, so | ||
1706 | * that erase characters will be handled. Other excess | ||
1707 | * characters will be beeped. | ||
1708 | * | ||
1709 | * paired with store in *_copy_from_read_buf() -- guarantees | ||
1710 | * the consumer has loaded the data in read_buf up to the new | ||
1711 | * read_tail (so this producer will not overwrite unread data) | ||
1712 | */ | ||
1713 | size_t tail = smp_load_acquire(&ldata->read_tail); | ||
1714 | |||
1715 | room = N_TTY_BUF_SIZE - (ldata->read_head - tail); | ||
1716 | if (I_PARMRK(tty)) | ||
1717 | room = (room + 2) / 3; | ||
1718 | room--; | ||
1719 | if (room <= 0) { | ||
1720 | overflow = ldata->icanon && ldata->canon_head == tail; | ||
1721 | if (overflow && room < 0) | ||
1722 | ldata->read_head--; | ||
1723 | room = overflow; | ||
1724 | ldata->no_room = flow && !room; | ||
1725 | } else | ||
1726 | overflow = 0; | ||
1727 | |||
1698 | n = min(count, room); | 1728 | n = min(count, room); |
1699 | if (!n) { | 1729 | if (!n) |
1700 | if (flow && !room) | ||
1701 | ldata->no_room = 1; | ||
1702 | break; | 1730 | break; |
1703 | } | 1731 | |
1704 | __receive_buf(tty, cp, fp, n); | 1732 | /* ignore parity errors if handling overflow */ |
1733 | if (!overflow || !fp || *fp != TTY_PARITY) | ||
1734 | __receive_buf(tty, cp, fp, n); | ||
1735 | |||
1705 | cp += n; | 1736 | cp += n; |
1706 | if (fp) | 1737 | if (fp) |
1707 | fp += n; | 1738 | fp += n; |
@@ -1710,7 +1741,17 @@ n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp, | |||
1710 | } | 1741 | } |
1711 | 1742 | ||
1712 | tty->receive_room = room; | 1743 | tty->receive_room = room; |
1713 | n_tty_check_throttle(tty); | 1744 | |
1745 | /* Unthrottle if handling overflow on pty */ | ||
1746 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY) { | ||
1747 | if (overflow) { | ||
1748 | tty_set_flow_change(tty, TTY_UNTHROTTLE_SAFE); | ||
1749 | tty_unthrottle_safe(tty); | ||
1750 | __tty_set_flow_change(tty, 0); | ||
1751 | } | ||
1752 | } else | ||
1753 | n_tty_check_throttle(tty); | ||
1754 | |||
1714 | up_read(&tty->termios_rwsem); | 1755 | up_read(&tty->termios_rwsem); |
1715 | 1756 | ||
1716 | return rcvd; | 1757 | return rcvd; |
@@ -1764,6 +1805,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
1764 | ldata->canon_head = ldata->read_head; | 1805 | ldata->canon_head = ldata->read_head; |
1765 | ldata->push = 1; | 1806 | ldata->push = 1; |
1766 | } | 1807 | } |
1808 | ldata->commit_head = ldata->read_head; | ||
1767 | ldata->erasing = 0; | 1809 | ldata->erasing = 0; |
1768 | ldata->lnext = 0; | 1810 | ldata->lnext = 0; |
1769 | } | 1811 | } |
@@ -1817,7 +1859,6 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
1817 | else | 1859 | else |
1818 | ldata->real_raw = 0; | 1860 | ldata->real_raw = 0; |
1819 | } | 1861 | } |
1820 | n_tty_set_room(tty); | ||
1821 | /* | 1862 | /* |
1822 | * Fix tty hang when I_IXON(tty) is cleared, but the tty | 1863 | * Fix tty hang when I_IXON(tty) is cleared, but the tty |
1823 | * been stopped by STOP_CHAR(tty) before it. | 1864 | * been stopped by STOP_CHAR(tty) before it. |
@@ -1905,7 +1946,7 @@ static inline int input_available_p(struct tty_struct *tty, int poll) | |||
1905 | if (ldata->icanon && !L_EXTPROC(tty)) | 1946 | if (ldata->icanon && !L_EXTPROC(tty)) |
1906 | return ldata->canon_head != ldata->read_tail; | 1947 | return ldata->canon_head != ldata->read_tail; |
1907 | else | 1948 | else |
1908 | return read_cnt(ldata) >= amt; | 1949 | return ldata->commit_head - ldata->read_tail >= amt; |
1909 | } | 1950 | } |
1910 | 1951 | ||
1911 | /** | 1952 | /** |
@@ -1937,10 +1978,11 @@ static int copy_from_read_buf(struct tty_struct *tty, | |||
1937 | int retval; | 1978 | int retval; |
1938 | size_t n; | 1979 | size_t n; |
1939 | bool is_eof; | 1980 | bool is_eof; |
1981 | size_t head = smp_load_acquire(&ldata->commit_head); | ||
1940 | size_t tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1); | 1982 | size_t tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1); |
1941 | 1983 | ||
1942 | retval = 0; | 1984 | retval = 0; |
1943 | n = min(read_cnt(ldata), N_TTY_BUF_SIZE - tail); | 1985 | n = min(head - ldata->read_tail, N_TTY_BUF_SIZE - tail); |
1944 | n = min(*nr, n); | 1986 | n = min(*nr, n); |
1945 | if (n) { | 1987 | if (n) { |
1946 | retval = copy_to_user(*b, read_buf_addr(ldata, tail), n); | 1988 | retval = copy_to_user(*b, read_buf_addr(ldata, tail), n); |
@@ -1948,9 +1990,10 @@ static int copy_from_read_buf(struct tty_struct *tty, | |||
1948 | is_eof = n == 1 && read_buf(ldata, tail) == EOF_CHAR(tty); | 1990 | is_eof = n == 1 && read_buf(ldata, tail) == EOF_CHAR(tty); |
1949 | tty_audit_add_data(tty, read_buf_addr(ldata, tail), n, | 1991 | tty_audit_add_data(tty, read_buf_addr(ldata, tail), n, |
1950 | ldata->icanon); | 1992 | ldata->icanon); |
1951 | ldata->read_tail += n; | 1993 | smp_store_release(&ldata->read_tail, ldata->read_tail + n); |
1952 | /* Turn single EOF into zero-length read */ | 1994 | /* Turn single EOF into zero-length read */ |
1953 | if (L_EXTPROC(tty) && ldata->icanon && is_eof && !read_cnt(ldata)) | 1995 | if (L_EXTPROC(tty) && ldata->icanon && is_eof && |
1996 | (head == ldata->read_tail)) | ||
1954 | n = 0; | 1997 | n = 0; |
1955 | *b += n; | 1998 | *b += n; |
1956 | *nr -= n; | 1999 | *nr -= n; |
@@ -1993,7 +2036,7 @@ static int canon_copy_from_read_buf(struct tty_struct *tty, | |||
1993 | bool eof_push = 0; | 2036 | bool eof_push = 0; |
1994 | 2037 | ||
1995 | /* N.B. avoid overrun if nr == 0 */ | 2038 | /* N.B. avoid overrun if nr == 0 */ |
1996 | n = min(*nr, read_cnt(ldata)); | 2039 | n = min(*nr, smp_load_acquire(&ldata->canon_head) - ldata->read_tail); |
1997 | if (!n) | 2040 | if (!n) |
1998 | return 0; | 2041 | return 0; |
1999 | 2042 | ||
@@ -2043,8 +2086,7 @@ static int canon_copy_from_read_buf(struct tty_struct *tty, | |||
2043 | 2086 | ||
2044 | if (found) | 2087 | if (found) |
2045 | clear_bit(eol, ldata->read_flags); | 2088 | clear_bit(eol, ldata->read_flags); |
2046 | smp_mb__after_atomic(); | 2089 | smp_store_release(&ldata->read_tail, ldata->read_tail + c); |
2047 | ldata->read_tail += c; | ||
2048 | 2090 | ||
2049 | if (found) { | 2091 | if (found) { |
2050 | if (!ldata->push) | 2092 | if (!ldata->push) |
@@ -2130,6 +2172,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, | |||
2130 | ssize_t retval = 0; | 2172 | ssize_t retval = 0; |
2131 | long timeout; | 2173 | long timeout; |
2132 | int packet; | 2174 | int packet; |
2175 | size_t tail; | ||
2133 | 2176 | ||
2134 | c = job_control(tty, file); | 2177 | c = job_control(tty, file); |
2135 | if (c < 0) | 2178 | if (c < 0) |
@@ -2166,6 +2209,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, | |||
2166 | } | 2209 | } |
2167 | 2210 | ||
2168 | packet = tty->packet; | 2211 | packet = tty->packet; |
2212 | tail = ldata->read_tail; | ||
2169 | 2213 | ||
2170 | add_wait_queue(&tty->read_wait, &wait); | 2214 | add_wait_queue(&tty->read_wait, &wait); |
2171 | while (nr) { | 2215 | while (nr) { |
@@ -2208,7 +2252,6 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, | |||
2208 | retval = -ERESTARTSYS; | 2252 | retval = -ERESTARTSYS; |
2209 | break; | 2253 | break; |
2210 | } | 2254 | } |
2211 | n_tty_set_room(tty); | ||
2212 | up_read(&tty->termios_rwsem); | 2255 | up_read(&tty->termios_rwsem); |
2213 | 2256 | ||
2214 | timeout = wait_woken(&wait, TASK_INTERRUPTIBLE, | 2257 | timeout = wait_woken(&wait, TASK_INTERRUPTIBLE, |
@@ -2253,7 +2296,8 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, | |||
2253 | if (time) | 2296 | if (time) |
2254 | timeout = time; | 2297 | timeout = time; |
2255 | } | 2298 | } |
2256 | n_tty_set_room(tty); | 2299 | if (tail != ldata->read_tail) |
2300 | n_tty_kick_worker(tty); | ||
2257 | up_read(&tty->termios_rwsem); | 2301 | up_read(&tty->termios_rwsem); |
2258 | 2302 | ||
2259 | remove_wait_queue(&tty->read_wait, &wait); | 2303 | remove_wait_queue(&tty->read_wait, &wait); |
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index a9d256d6e909..e72ee629cead 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c | |||
@@ -88,19 +88,6 @@ static void pty_unthrottle(struct tty_struct *tty) | |||
88 | } | 88 | } |
89 | 89 | ||
90 | /** | 90 | /** |
91 | * pty_space - report space left for writing | ||
92 | * @to: tty we are writing into | ||
93 | * | ||
94 | * Limit the buffer space used by ptys to 8k. | ||
95 | */ | ||
96 | |||
97 | static int pty_space(struct tty_struct *to) | ||
98 | { | ||
99 | int n = tty_buffer_space_avail(to->port); | ||
100 | return min(n, 8192); | ||
101 | } | ||
102 | |||
103 | /** | ||
104 | * pty_write - write to a pty | 91 | * pty_write - write to a pty |
105 | * @tty: the tty we write from | 92 | * @tty: the tty we write from |
106 | * @buf: kernel buffer of data | 93 | * @buf: kernel buffer of data |
@@ -141,7 +128,7 @@ static int pty_write_room(struct tty_struct *tty) | |||
141 | { | 128 | { |
142 | if (tty->stopped) | 129 | if (tty->stopped) |
143 | return 0; | 130 | return 0; |
144 | return pty_space(tty->link); | 131 | return tty_buffer_space_avail(tty->link->port); |
145 | } | 132 | } |
146 | 133 | ||
147 | /** | 134 | /** |
@@ -210,6 +197,9 @@ static int pty_signal(struct tty_struct *tty, int sig) | |||
210 | { | 197 | { |
211 | struct pid *pgrp; | 198 | struct pid *pgrp; |
212 | 199 | ||
200 | if (sig != SIGINT && sig != SIGQUIT && sig != SIGTSTP) | ||
201 | return -EINVAL; | ||
202 | |||
213 | if (tty->link) { | 203 | if (tty->link) { |
214 | pgrp = tty_get_pgrp(tty->link); | 204 | pgrp = tty_get_pgrp(tty->link); |
215 | if (pgrp) | 205 | if (pgrp) |
@@ -222,10 +212,16 @@ static int pty_signal(struct tty_struct *tty, int sig) | |||
222 | static void pty_flush_buffer(struct tty_struct *tty) | 212 | static void pty_flush_buffer(struct tty_struct *tty) |
223 | { | 213 | { |
224 | struct tty_struct *to = tty->link; | 214 | struct tty_struct *to = tty->link; |
215 | struct tty_ldisc *ld; | ||
225 | 216 | ||
226 | if (!to) | 217 | if (!to) |
227 | return; | 218 | return; |
228 | /* tty_buffer_flush(to); FIXME */ | 219 | |
220 | ld = tty_ldisc_ref(to); | ||
221 | tty_buffer_flush(to, ld); | ||
222 | if (ld) | ||
223 | tty_ldisc_deref(ld); | ||
224 | |||
229 | if (to->packet) { | 225 | if (to->packet) { |
230 | spin_lock_irq(&tty->ctrl_lock); | 226 | spin_lock_irq(&tty->ctrl_lock); |
231 | tty->ctrl_status |= TIOCPKT_FLUSHWRITE; | 227 | tty->ctrl_status |= TIOCPKT_FLUSHWRITE; |
@@ -399,6 +395,7 @@ static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty, | |||
399 | goto err_put_module; | 395 | goto err_put_module; |
400 | 396 | ||
401 | tty_set_lock_subclass(o_tty); | 397 | tty_set_lock_subclass(o_tty); |
398 | lockdep_set_subclass(&o_tty->termios_rwsem, TTY_LOCK_SLAVE); | ||
402 | 399 | ||
403 | if (legacy) { | 400 | if (legacy) { |
404 | /* We always use new tty termios data so we can do this | 401 | /* We always use new tty termios data so we can do this |
@@ -429,10 +426,14 @@ static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty, | |||
429 | o_tty->link = tty; | 426 | o_tty->link = tty; |
430 | tty_port_init(ports[0]); | 427 | tty_port_init(ports[0]); |
431 | tty_port_init(ports[1]); | 428 | tty_port_init(ports[1]); |
429 | tty_buffer_set_limit(ports[0], 8192); | ||
430 | tty_buffer_set_limit(ports[1], 8192); | ||
432 | o_tty->port = ports[0]; | 431 | o_tty->port = ports[0]; |
433 | tty->port = ports[1]; | 432 | tty->port = ports[1]; |
434 | o_tty->port->itty = o_tty; | 433 | o_tty->port->itty = o_tty; |
435 | 434 | ||
435 | tty_buffer_set_lock_subclass(o_tty->port); | ||
436 | |||
436 | tty_driver_kref_get(driver); | 437 | tty_driver_kref_get(driver); |
437 | tty->count++; | 438 | tty->count++; |
438 | o_tty->count++; | 439 | o_tty->count++; |
diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c index 383c4c796637..c8dd8dc31086 100644 --- a/drivers/tty/rocket.c +++ b/drivers/tty/rocket.c | |||
@@ -1390,7 +1390,7 @@ static void rp_unthrottle(struct tty_struct *tty) | |||
1390 | tty->ldisc.chars_in_buffer(tty)); | 1390 | tty->ldisc.chars_in_buffer(tty)); |
1391 | #endif | 1391 | #endif |
1392 | 1392 | ||
1393 | if (rocket_paranoia_check(info, "rp_throttle")) | 1393 | if (rocket_paranoia_check(info, "rp_unthrottle")) |
1394 | return; | 1394 | return; |
1395 | 1395 | ||
1396 | if (I_IXOFF(tty)) | 1396 | if (I_IXOFF(tty)) |
@@ -1458,7 +1458,7 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1458 | 1458 | ||
1459 | orig_jiffies = jiffies; | 1459 | orig_jiffies = jiffies; |
1460 | #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT | 1460 | #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT |
1461 | printk(KERN_INFO "In RP_wait_until_sent(%d) (jiff=%lu)...\n", timeout, | 1461 | printk(KERN_INFO "In %s(%d) (jiff=%lu)...\n", __func__, timeout, |
1462 | jiffies); | 1462 | jiffies); |
1463 | printk(KERN_INFO "cps=%d...\n", info->cps); | 1463 | printk(KERN_INFO "cps=%d...\n", info->cps); |
1464 | #endif | 1464 | #endif |
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 11c66856ba2f..e3b9570a1eff 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c | |||
@@ -329,6 +329,17 @@ static const struct serial8250_config uart_config[] = { | |||
329 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 329 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
330 | .flags = UART_CAP_FIFO | UART_CAP_AFE, | 330 | .flags = UART_CAP_FIFO | UART_CAP_AFE, |
331 | }, | 331 | }, |
332 | /* tx_loadsz is set to 63-bytes instead of 64-bytes to implement | ||
333 | workaround of errata A-008006 which states that tx_loadsz should be | ||
334 | configured less than Maximum supported fifo bytes */ | ||
335 | [PORT_16550A_FSL64] = { | ||
336 | .name = "16550A_FSL64", | ||
337 | .fifo_size = 64, | ||
338 | .tx_loadsz = 63, | ||
339 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 | | ||
340 | UART_FCR7_64BYTE, | ||
341 | .flags = UART_CAP_FIFO, | ||
342 | }, | ||
332 | }; | 343 | }; |
333 | 344 | ||
334 | /* Uart divisor latch read */ | 345 | /* Uart divisor latch read */ |
@@ -956,7 +967,17 @@ static void autoconfig_16550a(struct uart_8250_port *up) | |||
956 | up->port.type = PORT_16650; | 967 | up->port.type = PORT_16650; |
957 | up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP; | 968 | up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP; |
958 | } else { | 969 | } else { |
959 | DEBUG_AUTOCONF("Motorola 8xxx DUART "); | 970 | serial_out(up, UART_LCR, 0); |
971 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | | ||
972 | UART_FCR7_64BYTE); | ||
973 | status1 = serial_in(up, UART_IIR) >> 5; | ||
974 | serial_out(up, UART_FCR, 0); | ||
975 | serial_out(up, UART_LCR, 0); | ||
976 | |||
977 | if (status1 == 7) | ||
978 | up->port.type = PORT_16550A_FSL64; | ||
979 | else | ||
980 | DEBUG_AUTOCONF("Motorola 8xxx DUART "); | ||
960 | } | 981 | } |
961 | serial_out(up, UART_EFR, 0); | 982 | serial_out(up, UART_EFR, 0); |
962 | return; | 983 | return; |
@@ -1355,9 +1376,11 @@ static void serial8250_start_tx(struct uart_port *port) | |||
1355 | struct uart_8250_port *up = up_to_u8250p(port); | 1376 | struct uart_8250_port *up = up_to_u8250p(port); |
1356 | 1377 | ||
1357 | serial8250_rpm_get_tx(up); | 1378 | serial8250_rpm_get_tx(up); |
1358 | if (up->dma && !up->dma->tx_dma(up)) { | 1379 | |
1380 | if (up->dma && !up->dma->tx_dma(up)) | ||
1359 | return; | 1381 | return; |
1360 | } else if (!(up->ier & UART_IER_THRI)) { | 1382 | |
1383 | if (!(up->ier & UART_IER_THRI)) { | ||
1361 | up->ier |= UART_IER_THRI; | 1384 | up->ier |= UART_IER_THRI; |
1362 | serial_port_out(port, UART_IER, up->ier); | 1385 | serial_port_out(port, UART_IER, up->ier); |
1363 | 1386 | ||
@@ -1365,7 +1388,7 @@ static void serial8250_start_tx(struct uart_port *port) | |||
1365 | unsigned char lsr; | 1388 | unsigned char lsr; |
1366 | lsr = serial_in(up, UART_LSR); | 1389 | lsr = serial_in(up, UART_LSR); |
1367 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | 1390 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; |
1368 | if (lsr & UART_LSR_TEMT) | 1391 | if (lsr & UART_LSR_THRE) |
1369 | serial8250_tx_chars(up); | 1392 | serial8250_tx_chars(up); |
1370 | } | 1393 | } |
1371 | } | 1394 | } |
@@ -1924,7 +1947,7 @@ static unsigned int serial8250_get_mctrl(struct uart_port *port) | |||
1924 | return ret; | 1947 | return ret; |
1925 | } | 1948 | } |
1926 | 1949 | ||
1927 | static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl) | 1950 | void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl) |
1928 | { | 1951 | { |
1929 | struct uart_8250_port *up = up_to_u8250p(port); | 1952 | struct uart_8250_port *up = up_to_u8250p(port); |
1930 | unsigned char mcr = 0; | 1953 | unsigned char mcr = 0; |
@@ -1944,6 +1967,14 @@ static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
1944 | 1967 | ||
1945 | serial_port_out(port, UART_MCR, mcr); | 1968 | serial_port_out(port, UART_MCR, mcr); |
1946 | } | 1969 | } |
1970 | EXPORT_SYMBOL_GPL(serial8250_do_set_mctrl); | ||
1971 | |||
1972 | static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
1973 | { | ||
1974 | if (port->set_mctrl) | ||
1975 | return port->set_mctrl(port, mctrl); | ||
1976 | return serial8250_do_set_mctrl(port, mctrl); | ||
1977 | } | ||
1947 | 1978 | ||
1948 | static void serial8250_break_ctl(struct uart_port *port, int break_state) | 1979 | static void serial8250_break_ctl(struct uart_port *port, int break_state) |
1949 | { | 1980 | { |
@@ -2382,13 +2413,34 @@ static void serial8250_shutdown(struct uart_port *port) | |||
2382 | serial8250_do_shutdown(port); | 2413 | serial8250_do_shutdown(port); |
2383 | } | 2414 | } |
2384 | 2415 | ||
2385 | static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud) | 2416 | /* |
2417 | * XR17V35x UARTs have an extra fractional divisor register (DLD) | ||
2418 | * Calculate divisor with extra 4-bit fractional portion | ||
2419 | */ | ||
2420 | static unsigned int xr17v35x_get_divisor(struct uart_8250_port *up, | ||
2421 | unsigned int baud, | ||
2422 | unsigned int *frac) | ||
2423 | { | ||
2424 | struct uart_port *port = &up->port; | ||
2425 | unsigned int quot_16; | ||
2426 | |||
2427 | quot_16 = DIV_ROUND_CLOSEST(port->uartclk, baud); | ||
2428 | *frac = quot_16 & 0x0f; | ||
2429 | |||
2430 | return quot_16 >> 4; | ||
2431 | } | ||
2432 | |||
2433 | static unsigned int serial8250_get_divisor(struct uart_8250_port *up, | ||
2434 | unsigned int baud, | ||
2435 | unsigned int *frac) | ||
2386 | { | 2436 | { |
2437 | struct uart_port *port = &up->port; | ||
2387 | unsigned int quot; | 2438 | unsigned int quot; |
2388 | 2439 | ||
2389 | /* | 2440 | /* |
2390 | * Handle magic divisors for baud rates above baud_base on | 2441 | * Handle magic divisors for baud rates above baud_base on |
2391 | * SMSC SuperIO chips. | 2442 | * SMSC SuperIO chips. |
2443 | * | ||
2392 | */ | 2444 | */ |
2393 | if ((port->flags & UPF_MAGIC_MULTIPLIER) && | 2445 | if ((port->flags & UPF_MAGIC_MULTIPLIER) && |
2394 | baud == (port->uartclk/4)) | 2446 | baud == (port->uartclk/4)) |
@@ -2396,22 +2448,26 @@ static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int | |||
2396 | else if ((port->flags & UPF_MAGIC_MULTIPLIER) && | 2448 | else if ((port->flags & UPF_MAGIC_MULTIPLIER) && |
2397 | baud == (port->uartclk/8)) | 2449 | baud == (port->uartclk/8)) |
2398 | quot = 0x8002; | 2450 | quot = 0x8002; |
2451 | else if (up->port.type == PORT_XR17V35X) | ||
2452 | quot = xr17v35x_get_divisor(up, baud, frac); | ||
2399 | else | 2453 | else |
2400 | quot = uart_get_divisor(port, baud); | 2454 | quot = uart_get_divisor(port, baud); |
2401 | 2455 | ||
2456 | /* | ||
2457 | * Oxford Semi 952 rev B workaround | ||
2458 | */ | ||
2459 | if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0) | ||
2460 | quot++; | ||
2461 | |||
2402 | return quot; | 2462 | return quot; |
2403 | } | 2463 | } |
2404 | 2464 | ||
2405 | void | 2465 | static unsigned char serial8250_compute_lcr(struct uart_8250_port *up, |
2406 | serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | 2466 | tcflag_t c_cflag) |
2407 | struct ktermios *old) | ||
2408 | { | 2467 | { |
2409 | struct uart_8250_port *up = up_to_u8250p(port); | ||
2410 | unsigned char cval; | 2468 | unsigned char cval; |
2411 | unsigned long flags; | ||
2412 | unsigned int baud, quot; | ||
2413 | 2469 | ||
2414 | switch (termios->c_cflag & CSIZE) { | 2470 | switch (c_cflag & CSIZE) { |
2415 | case CS5: | 2471 | case CS5: |
2416 | cval = UART_LCR_WLEN5; | 2472 | cval = UART_LCR_WLEN5; |
2417 | break; | 2473 | break; |
@@ -2427,33 +2483,80 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2427 | break; | 2483 | break; |
2428 | } | 2484 | } |
2429 | 2485 | ||
2430 | if (termios->c_cflag & CSTOPB) | 2486 | if (c_cflag & CSTOPB) |
2431 | cval |= UART_LCR_STOP; | 2487 | cval |= UART_LCR_STOP; |
2432 | if (termios->c_cflag & PARENB) { | 2488 | if (c_cflag & PARENB) { |
2433 | cval |= UART_LCR_PARITY; | 2489 | cval |= UART_LCR_PARITY; |
2434 | if (up->bugs & UART_BUG_PARITY) | 2490 | if (up->bugs & UART_BUG_PARITY) |
2435 | up->fifo_bug = true; | 2491 | up->fifo_bug = true; |
2436 | } | 2492 | } |
2437 | if (!(termios->c_cflag & PARODD)) | 2493 | if (!(c_cflag & PARODD)) |
2438 | cval |= UART_LCR_EPAR; | 2494 | cval |= UART_LCR_EPAR; |
2439 | #ifdef CMSPAR | 2495 | #ifdef CMSPAR |
2440 | if (termios->c_cflag & CMSPAR) | 2496 | if (c_cflag & CMSPAR) |
2441 | cval |= UART_LCR_SPAR; | 2497 | cval |= UART_LCR_SPAR; |
2442 | #endif | 2498 | #endif |
2443 | 2499 | ||
2500 | return cval; | ||
2501 | } | ||
2502 | |||
2503 | static void serial8250_set_divisor(struct uart_port *port, unsigned int baud, | ||
2504 | unsigned int quot, unsigned int quot_frac) | ||
2505 | { | ||
2506 | struct uart_8250_port *up = up_to_u8250p(port); | ||
2507 | |||
2508 | /* Workaround to enable 115200 baud on OMAP1510 internal ports */ | ||
2509 | if (is_omap1510_8250(up)) { | ||
2510 | if (baud == 115200) { | ||
2511 | quot = 1; | ||
2512 | serial_port_out(port, UART_OMAP_OSC_12M_SEL, 1); | ||
2513 | } else | ||
2514 | serial_port_out(port, UART_OMAP_OSC_12M_SEL, 0); | ||
2515 | } | ||
2516 | |||
2517 | /* | ||
2518 | * For NatSemi, switch to bank 2 not bank 1, to avoid resetting EXCR2, | ||
2519 | * otherwise just set DLAB | ||
2520 | */ | ||
2521 | if (up->capabilities & UART_NATSEMI) | ||
2522 | serial_port_out(port, UART_LCR, 0xe0); | ||
2523 | else | ||
2524 | serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB); | ||
2525 | |||
2526 | serial_dl_write(up, quot); | ||
2527 | |||
2528 | /* XR17V35x UARTs have an extra fractional divisor register (DLD) */ | ||
2529 | if (up->port.type == PORT_XR17V35X) | ||
2530 | serial_port_out(port, 0x2, quot_frac); | ||
2531 | } | ||
2532 | |||
2533 | void | ||
2534 | serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | ||
2535 | struct ktermios *old) | ||
2536 | { | ||
2537 | struct uart_8250_port *up = up_to_u8250p(port); | ||
2538 | unsigned char cval; | ||
2539 | unsigned long flags; | ||
2540 | unsigned int baud, quot, frac = 0; | ||
2541 | |||
2542 | cval = serial8250_compute_lcr(up, termios->c_cflag); | ||
2543 | |||
2444 | /* | 2544 | /* |
2445 | * Ask the core to calculate the divisor for us. | 2545 | * Ask the core to calculate the divisor for us. |
2446 | */ | 2546 | */ |
2447 | baud = uart_get_baud_rate(port, termios, old, | 2547 | baud = uart_get_baud_rate(port, termios, old, |
2448 | port->uartclk / 16 / 0xffff, | 2548 | port->uartclk / 16 / 0xffff, |
2449 | port->uartclk / 16); | 2549 | port->uartclk / 16); |
2450 | quot = serial8250_get_divisor(port, baud); | 2550 | quot = serial8250_get_divisor(up, baud, &frac); |
2451 | 2551 | ||
2452 | /* | 2552 | /* |
2453 | * Oxford Semi 952 rev B workaround | 2553 | * Ok, we're now changing the port state. Do it with |
2554 | * interrupts disabled. | ||
2454 | */ | 2555 | */ |
2455 | if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0) | 2556 | serial8250_rpm_get(up); |
2456 | quot++; | 2557 | spin_lock_irqsave(&port->lock, flags); |
2558 | |||
2559 | up->lcr = cval; /* Save computed LCR */ | ||
2457 | 2560 | ||
2458 | if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) { | 2561 | if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) { |
2459 | /* NOTE: If fifo_bug is not set, a user can set RX_trigger. */ | 2562 | /* NOTE: If fifo_bug is not set, a user can set RX_trigger. */ |
@@ -2478,13 +2581,6 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2478 | } | 2581 | } |
2479 | 2582 | ||
2480 | /* | 2583 | /* |
2481 | * Ok, we're now changing the port state. Do it with | ||
2482 | * interrupts disabled. | ||
2483 | */ | ||
2484 | serial8250_rpm_get(up); | ||
2485 | spin_lock_irqsave(&port->lock, flags); | ||
2486 | |||
2487 | /* | ||
2488 | * Update the per-port timeout. | 2584 | * Update the per-port timeout. |
2489 | */ | 2585 | */ |
2490 | uart_update_timeout(port, termios->c_cflag, baud); | 2586 | uart_update_timeout(port, termios->c_cflag, baud); |
@@ -2548,43 +2644,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2548 | serial_port_out(port, UART_EFR, efr); | 2644 | serial_port_out(port, UART_EFR, efr); |
2549 | } | 2645 | } |
2550 | 2646 | ||
2551 | /* Workaround to enable 115200 baud on OMAP1510 internal ports */ | 2647 | serial8250_set_divisor(port, baud, quot, frac); |
2552 | if (is_omap1510_8250(up)) { | ||
2553 | if (baud == 115200) { | ||
2554 | quot = 1; | ||
2555 | serial_port_out(port, UART_OMAP_OSC_12M_SEL, 1); | ||
2556 | } else | ||
2557 | serial_port_out(port, UART_OMAP_OSC_12M_SEL, 0); | ||
2558 | } | ||
2559 | |||
2560 | /* | ||
2561 | * For NatSemi, switch to bank 2 not bank 1, to avoid resetting EXCR2, | ||
2562 | * otherwise just set DLAB | ||
2563 | */ | ||
2564 | if (up->capabilities & UART_NATSEMI) | ||
2565 | serial_port_out(port, UART_LCR, 0xe0); | ||
2566 | else | ||
2567 | serial_port_out(port, UART_LCR, cval | UART_LCR_DLAB); | ||
2568 | |||
2569 | serial_dl_write(up, quot); | ||
2570 | |||
2571 | /* | ||
2572 | * XR17V35x UARTs have an extra fractional divisor register (DLD) | ||
2573 | * | ||
2574 | * We need to recalculate all of the registers, because DLM and DLL | ||
2575 | * are already rounded to a whole integer. | ||
2576 | * | ||
2577 | * When recalculating we use a 32x clock instead of a 16x clock to | ||
2578 | * allow 1-bit for rounding in the fractional part. | ||
2579 | */ | ||
2580 | if (up->port.type == PORT_XR17V35X) { | ||
2581 | unsigned int baud_x32 = (port->uartclk * 2) / baud; | ||
2582 | u16 quot = baud_x32 / 32; | ||
2583 | u8 quot_frac = DIV_ROUND_CLOSEST(baud_x32 % 32, 2); | ||
2584 | |||
2585 | serial_dl_write(up, quot); | ||
2586 | serial_port_out(port, 0x2, quot_frac & 0xf); | ||
2587 | } | ||
2588 | 2648 | ||
2589 | /* | 2649 | /* |
2590 | * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR | 2650 | * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR |
@@ -2593,8 +2653,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2593 | if (port->type == PORT_16750) | 2653 | if (port->type == PORT_16750) |
2594 | serial_port_out(port, UART_FCR, up->fcr); | 2654 | serial_port_out(port, UART_FCR, up->fcr); |
2595 | 2655 | ||
2596 | serial_port_out(port, UART_LCR, cval); /* reset DLAB */ | 2656 | serial_port_out(port, UART_LCR, up->lcr); /* reset DLAB */ |
2597 | up->lcr = cval; /* Save LCR */ | ||
2598 | if (port->type != PORT_16750) { | 2657 | if (port->type != PORT_16750) { |
2599 | /* emulated UARTs (Lucent Venus 167x) need two steps */ | 2658 | /* emulated UARTs (Lucent Venus 167x) need two steps */ |
2600 | if (up->fcr & UART_FCR_ENABLE_FIFO) | 2659 | if (up->fcr & UART_FCR_ENABLE_FIFO) |
@@ -3208,6 +3267,27 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) | |||
3208 | else | 3267 | else |
3209 | serial_port_out(port, UART_IER, 0); | 3268 | serial_port_out(port, UART_IER, 0); |
3210 | 3269 | ||
3270 | /* check scratch reg to see if port powered off during system sleep */ | ||
3271 | if (up->canary && (up->canary != serial_port_in(port, UART_SCR))) { | ||
3272 | struct ktermios termios; | ||
3273 | unsigned int baud, quot, frac = 0; | ||
3274 | |||
3275 | termios.c_cflag = port->cons->cflag; | ||
3276 | if (port->state->port.tty && termios.c_cflag == 0) | ||
3277 | termios.c_cflag = port->state->port.tty->termios.c_cflag; | ||
3278 | |||
3279 | baud = uart_get_baud_rate(port, &termios, NULL, | ||
3280 | port->uartclk / 16 / 0xffff, | ||
3281 | port->uartclk / 16); | ||
3282 | quot = serial8250_get_divisor(up, baud, &frac); | ||
3283 | |||
3284 | serial8250_set_divisor(port, baud, quot, frac); | ||
3285 | serial_port_out(port, UART_LCR, up->lcr); | ||
3286 | serial_port_out(port, UART_MCR, UART_MCR_DTR | UART_MCR_RTS); | ||
3287 | |||
3288 | up->canary = 0; | ||
3289 | } | ||
3290 | |||
3211 | uart_console_write(port, s, count, serial8250_console_putchar); | 3291 | uart_console_write(port, s, count, serial8250_console_putchar); |
3212 | 3292 | ||
3213 | /* | 3293 | /* |
@@ -3358,7 +3438,17 @@ int __init early_serial_setup(struct uart_port *port) | |||
3358 | */ | 3438 | */ |
3359 | void serial8250_suspend_port(int line) | 3439 | void serial8250_suspend_port(int line) |
3360 | { | 3440 | { |
3361 | uart_suspend_port(&serial8250_reg, &serial8250_ports[line].port); | 3441 | struct uart_8250_port *up = &serial8250_ports[line]; |
3442 | struct uart_port *port = &up->port; | ||
3443 | |||
3444 | if (!console_suspend_enabled && uart_console(port) && | ||
3445 | port->type != PORT_8250) { | ||
3446 | unsigned char canary = 0xa5; | ||
3447 | serial_out(up, UART_SCR, canary); | ||
3448 | up->canary = canary; | ||
3449 | } | ||
3450 | |||
3451 | uart_suspend_port(&serial8250_reg, port); | ||
3362 | } | 3452 | } |
3363 | 3453 | ||
3364 | /** | 3454 | /** |
@@ -3372,6 +3462,8 @@ void serial8250_resume_port(int line) | |||
3372 | struct uart_8250_port *up = &serial8250_ports[line]; | 3462 | struct uart_8250_port *up = &serial8250_ports[line]; |
3373 | struct uart_port *port = &up->port; | 3463 | struct uart_port *port = &up->port; |
3374 | 3464 | ||
3465 | up->canary = 0; | ||
3466 | |||
3375 | if (up->capabilities & UART_NATSEMI) { | 3467 | if (up->capabilities & UART_NATSEMI) { |
3376 | /* Ensure it's still in high speed mode */ | 3468 | /* Ensure it's still in high speed mode */ |
3377 | serial_port_out(port, UART_LCR, 0xE0); | 3469 | serial_port_out(port, UART_LCR, 0xE0); |
@@ -3605,6 +3697,8 @@ int serial8250_register_8250_port(struct uart_8250_port *up) | |||
3605 | /* Possibly override set_termios call */ | 3697 | /* Possibly override set_termios call */ |
3606 | if (up->port.set_termios) | 3698 | if (up->port.set_termios) |
3607 | uart->port.set_termios = up->port.set_termios; | 3699 | uart->port.set_termios = up->port.set_termios; |
3700 | if (up->port.set_mctrl) | ||
3701 | uart->port.set_mctrl = up->port.set_mctrl; | ||
3608 | if (up->port.startup) | 3702 | if (up->port.startup) |
3609 | uart->port.startup = up->port.startup; | 3703 | uart->port.startup = up->port.startup; |
3610 | if (up->port.shutdown) | 3704 | if (up->port.shutdown) |
diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c index fcd7ac6af2fc..21d01a491405 100644 --- a/drivers/tty/serial/8250/8250_dma.c +++ b/drivers/tty/serial/8250/8250_dma.c | |||
@@ -59,7 +59,6 @@ static void __dma_rx_complete(void *param) | |||
59 | 59 | ||
60 | dma->rx_running = 0; | 60 | dma->rx_running = 0; |
61 | dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); | 61 | dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); |
62 | dmaengine_terminate_all(dma->rxchan); | ||
63 | 62 | ||
64 | count = dma->rx_size - state.residue; | 63 | count = dma->rx_size - state.residue; |
65 | 64 | ||
@@ -81,6 +80,10 @@ int serial8250_tx_dma(struct uart_8250_port *p) | |||
81 | return 0; | 80 | return 0; |
82 | 81 | ||
83 | dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); | 82 | dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); |
83 | if (dma->tx_size < p->port.fifosize) { | ||
84 | ret = -EINVAL; | ||
85 | goto err; | ||
86 | } | ||
84 | 87 | ||
85 | desc = dmaengine_prep_slave_single(dma->txchan, | 88 | desc = dmaengine_prep_slave_single(dma->txchan, |
86 | dma->tx_addr + xmit->tail, | 89 | dma->tx_addr + xmit->tail, |
@@ -131,6 +134,7 @@ int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir) | |||
131 | if (dma->rx_running) { | 134 | if (dma->rx_running) { |
132 | dmaengine_pause(dma->rxchan); | 135 | dmaengine_pause(dma->rxchan); |
133 | __dma_rx_complete(p); | 136 | __dma_rx_complete(p); |
137 | dmaengine_terminate_all(dma->rxchan); | ||
134 | } | 138 | } |
135 | return -ETIMEDOUT; | 139 | return -ETIMEDOUT; |
136 | default: | 140 | default: |
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index 555de07db593..e60116235836 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c | |||
@@ -351,10 +351,20 @@ static int dw8250_probe_of(struct uart_port *p, | |||
351 | static int dw8250_probe_acpi(struct uart_8250_port *up, | 351 | static int dw8250_probe_acpi(struct uart_8250_port *up, |
352 | struct dw8250_data *data) | 352 | struct dw8250_data *data) |
353 | { | 353 | { |
354 | const struct acpi_device_id *id; | ||
354 | struct uart_port *p = &up->port; | 355 | struct uart_port *p = &up->port; |
355 | 356 | ||
356 | dw8250_setup_port(up); | 357 | dw8250_setup_port(up); |
357 | 358 | ||
359 | id = acpi_match_device(p->dev->driver->acpi_match_table, p->dev); | ||
360 | if (!id) | ||
361 | return -ENODEV; | ||
362 | |||
363 | if (!p->uartclk) | ||
364 | if (device_property_read_u32(p->dev, "clock-frequency", | ||
365 | &p->uartclk)) | ||
366 | return -EINVAL; | ||
367 | |||
358 | p->iotype = UPIO_MEM32; | 368 | p->iotype = UPIO_MEM32; |
359 | p->serial_in = dw8250_serial_in32; | 369 | p->serial_in = dw8250_serial_in32; |
360 | p->serial_out = dw8250_serial_out32; | 370 | p->serial_out = dw8250_serial_out32; |
@@ -577,6 +587,7 @@ static const struct acpi_device_id dw8250_acpi_match[] = { | |||
577 | { "INT3435", 0 }, | 587 | { "INT3435", 0 }, |
578 | { "80860F0A", 0 }, | 588 | { "80860F0A", 0 }, |
579 | { "8086228A", 0 }, | 589 | { "8086228A", 0 }, |
590 | { "APMC0D08", 0}, | ||
580 | { }, | 591 | { }, |
581 | }; | 592 | }; |
582 | MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match); | 593 | MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match); |
diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c index 4858b8a99d3b..c31a22b4f845 100644 --- a/drivers/tty/serial/8250/8250_early.c +++ b/drivers/tty/serial/8250/8250_early.c | |||
@@ -93,15 +93,18 @@ static void __init early_serial8250_write(struct console *console, | |||
93 | struct uart_port *port = &early_device->port; | 93 | struct uart_port *port = &early_device->port; |
94 | unsigned int ier; | 94 | unsigned int ier; |
95 | 95 | ||
96 | /* Save the IER and disable interrupts */ | 96 | /* Save the IER and disable interrupts preserving the UUE bit */ |
97 | ier = serial8250_early_in(port, UART_IER); | 97 | ier = serial8250_early_in(port, UART_IER); |
98 | serial8250_early_out(port, UART_IER, 0); | 98 | if (ier) |
99 | serial8250_early_out(port, UART_IER, ier & UART_IER_UUE); | ||
99 | 100 | ||
100 | uart_console_write(port, s, count, serial_putc); | 101 | uart_console_write(port, s, count, serial_putc); |
101 | 102 | ||
102 | /* Wait for transmitter to become empty and restore the IER */ | 103 | /* Wait for transmitter to become empty and restore the IER */ |
103 | wait_for_xmitr(port); | 104 | wait_for_xmitr(port); |
104 | serial8250_early_out(port, UART_IER, ier); | 105 | |
106 | if (ier) | ||
107 | serial8250_early_out(port, UART_IER, ier); | ||
105 | } | 108 | } |
106 | 109 | ||
107 | static unsigned int __init probe_baud(struct uart_port *port) | 110 | static unsigned int __init probe_baud(struct uart_port *port) |
@@ -124,9 +127,11 @@ static void __init init_port(struct earlycon_device *device) | |||
124 | struct uart_port *port = &device->port; | 127 | struct uart_port *port = &device->port; |
125 | unsigned int divisor; | 128 | unsigned int divisor; |
126 | unsigned char c; | 129 | unsigned char c; |
130 | unsigned int ier; | ||
127 | 131 | ||
128 | serial8250_early_out(port, UART_LCR, 0x3); /* 8n1 */ | 132 | serial8250_early_out(port, UART_LCR, 0x3); /* 8n1 */ |
129 | serial8250_early_out(port, UART_IER, 0); /* no interrupt */ | 133 | ier = serial8250_early_in(port, UART_IER); |
134 | serial8250_early_out(port, UART_IER, ier & UART_IER_UUE); /* no interrupt */ | ||
130 | serial8250_early_out(port, UART_FCR, 0); /* no fifo */ | 135 | serial8250_early_out(port, UART_FCR, 0); /* no fifo */ |
131 | serial8250_early_out(port, UART_MCR, 0x3); /* DTR + RTS */ | 136 | serial8250_early_out(port, UART_MCR, 0x3); /* DTR + RTS */ |
132 | 137 | ||
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 96b69bfd773f..fe6d2e51da09 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c | |||
@@ -106,6 +106,28 @@ static u32 uart_read(struct uart_8250_port *up, u32 reg) | |||
106 | return readl(up->port.membase + (reg << up->port.regshift)); | 106 | return readl(up->port.membase + (reg << up->port.regshift)); |
107 | } | 107 | } |
108 | 108 | ||
109 | static void omap8250_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
110 | { | ||
111 | struct uart_8250_port *up = up_to_u8250p(port); | ||
112 | struct omap8250_priv *priv = up->port.private_data; | ||
113 | u8 lcr; | ||
114 | |||
115 | serial8250_do_set_mctrl(port, mctrl); | ||
116 | |||
117 | /* | ||
118 | * Turn off autoRTS if RTS is lowered and restore autoRTS setting | ||
119 | * if RTS is raised | ||
120 | */ | ||
121 | lcr = serial_in(up, UART_LCR); | ||
122 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | ||
123 | if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS)) | ||
124 | priv->efr |= UART_EFR_RTS; | ||
125 | else | ||
126 | priv->efr &= ~UART_EFR_RTS; | ||
127 | serial_out(up, UART_EFR, priv->efr); | ||
128 | serial_out(up, UART_LCR, lcr); | ||
129 | } | ||
130 | |||
109 | /* | 131 | /* |
110 | * Work Around for Errata i202 (2430, 3430, 3630, 4430 and 4460) | 132 | * Work Around for Errata i202 (2430, 3430, 3630, 4430 and 4460) |
111 | * The access to uart register after MDR1 Access | 133 | * The access to uart register after MDR1 Access |
@@ -397,12 +419,12 @@ static void omap_8250_set_termios(struct uart_port *port, | |||
397 | 419 | ||
398 | priv->efr = 0; | 420 | priv->efr = 0; |
399 | up->mcr &= ~(UART_MCR_RTS | UART_MCR_XONANY); | 421 | up->mcr &= ~(UART_MCR_RTS | UART_MCR_XONANY); |
400 | if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW) { | 422 | up->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS | UPSTAT_AUTOXOFF); |
401 | /* Enable AUTORTS and AUTOCTS */ | ||
402 | priv->efr |= UART_EFR_CTS | UART_EFR_RTS; | ||
403 | 423 | ||
404 | /* Ensure MCR RTS is asserted */ | 424 | if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW) { |
405 | up->mcr |= UART_MCR_RTS; | 425 | /* Enable AUTOCTS (autoRTS is enabled when RTS is raised) */ |
426 | up->port.status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS; | ||
427 | priv->efr |= UART_EFR_CTS; | ||
406 | } else if (up->port.flags & UPF_SOFT_FLOW) { | 428 | } else if (up->port.flags & UPF_SOFT_FLOW) { |
407 | /* | 429 | /* |
408 | * IXON Flag: | 430 | * IXON Flag: |
@@ -417,8 +439,10 @@ static void omap_8250_set_termios(struct uart_port *port, | |||
417 | * Enable XON/XOFF flow control on output. | 439 | * Enable XON/XOFF flow control on output. |
418 | * Transmit XON1, XOFF1 | 440 | * Transmit XON1, XOFF1 |
419 | */ | 441 | */ |
420 | if (termios->c_iflag & IXOFF) | 442 | if (termios->c_iflag & IXOFF) { |
443 | up->port.status |= UPSTAT_AUTOXOFF; | ||
421 | priv->efr |= OMAP_UART_SW_TX; | 444 | priv->efr |= OMAP_UART_SW_TX; |
445 | } | ||
422 | 446 | ||
423 | /* | 447 | /* |
424 | * IXANY Flag: | 448 | * IXANY Flag: |
@@ -450,18 +474,18 @@ static void omap_8250_set_termios(struct uart_port *port, | |||
450 | static void omap_8250_pm(struct uart_port *port, unsigned int state, | 474 | static void omap_8250_pm(struct uart_port *port, unsigned int state, |
451 | unsigned int oldstate) | 475 | unsigned int oldstate) |
452 | { | 476 | { |
453 | struct uart_8250_port *up = | 477 | struct uart_8250_port *up = up_to_u8250p(port); |
454 | container_of(port, struct uart_8250_port, port); | 478 | u8 efr; |
455 | struct omap8250_priv *priv = up->port.private_data; | ||
456 | 479 | ||
457 | pm_runtime_get_sync(port->dev); | 480 | pm_runtime_get_sync(port->dev); |
458 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | 481 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
459 | serial_out(up, UART_EFR, priv->efr | UART_EFR_ECB); | 482 | efr = serial_in(up, UART_EFR); |
483 | serial_out(up, UART_EFR, efr | UART_EFR_ECB); | ||
460 | serial_out(up, UART_LCR, 0); | 484 | serial_out(up, UART_LCR, 0); |
461 | 485 | ||
462 | serial_out(up, UART_IER, (state != 0) ? UART_IERX_SLEEP : 0); | 486 | serial_out(up, UART_IER, (state != 0) ? UART_IERX_SLEEP : 0); |
463 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | 487 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
464 | serial_out(up, UART_EFR, priv->efr); | 488 | serial_out(up, UART_EFR, efr); |
465 | serial_out(up, UART_LCR, 0); | 489 | serial_out(up, UART_LCR, 0); |
466 | 490 | ||
467 | pm_runtime_mark_last_busy(port->dev); | 491 | pm_runtime_mark_last_busy(port->dev); |
@@ -1007,6 +1031,7 @@ static int omap8250_probe(struct platform_device *pdev) | |||
1007 | up.capabilities |= UART_CAP_RPM; | 1031 | up.capabilities |= UART_CAP_RPM; |
1008 | #endif | 1032 | #endif |
1009 | up.port.set_termios = omap_8250_set_termios; | 1033 | up.port.set_termios = omap_8250_set_termios; |
1034 | up.port.set_mctrl = omap8250_set_mctrl; | ||
1010 | up.port.pm = omap_8250_pm; | 1035 | up.port.pm = omap_8250_pm; |
1011 | up.port.startup = omap_8250_startup; | 1036 | up.port.startup = omap_8250_startup; |
1012 | up.port.shutdown = omap_8250_shutdown; | 1037 | up.port.shutdown = omap_8250_shutdown; |
@@ -1248,6 +1273,46 @@ static int omap8250_runtime_resume(struct device *dev) | |||
1248 | } | 1273 | } |
1249 | #endif | 1274 | #endif |
1250 | 1275 | ||
1276 | #ifdef CONFIG_SERIAL_8250_OMAP_TTYO_FIXUP | ||
1277 | static int __init omap8250_console_fixup(void) | ||
1278 | { | ||
1279 | char *omap_str; | ||
1280 | char *options; | ||
1281 | u8 idx; | ||
1282 | |||
1283 | if (strstr(boot_command_line, "console=ttyS")) | ||
1284 | /* user set a ttyS based name for the console */ | ||
1285 | return 0; | ||
1286 | |||
1287 | omap_str = strstr(boot_command_line, "console=ttyO"); | ||
1288 | if (!omap_str) | ||
1289 | /* user did not set ttyO based console, so we don't care */ | ||
1290 | return 0; | ||
1291 | |||
1292 | omap_str += 12; | ||
1293 | if ('0' <= *omap_str && *omap_str <= '9') | ||
1294 | idx = *omap_str - '0'; | ||
1295 | else | ||
1296 | return 0; | ||
1297 | |||
1298 | omap_str++; | ||
1299 | if (omap_str[0] == ',') { | ||
1300 | omap_str++; | ||
1301 | options = omap_str; | ||
1302 | } else { | ||
1303 | options = NULL; | ||
1304 | } | ||
1305 | |||
1306 | add_preferred_console("ttyS", idx, options); | ||
1307 | pr_err("WARNING: Your 'console=ttyO%d' has been replaced by 'ttyS%d'\n", | ||
1308 | idx, idx); | ||
1309 | pr_err("This ensures that you still see kernel messages. Please\n"); | ||
1310 | pr_err("update your kernel commandline.\n"); | ||
1311 | return 0; | ||
1312 | } | ||
1313 | console_initcall(omap8250_console_fixup); | ||
1314 | #endif | ||
1315 | |||
1251 | static const struct dev_pm_ops omap8250_dev_pm_ops = { | 1316 | static const struct dev_pm_ops omap8250_dev_pm_ops = { |
1252 | SET_SYSTEM_SLEEP_PM_OPS(omap8250_suspend, omap8250_resume) | 1317 | SET_SYSTEM_SLEEP_PM_OPS(omap8250_suspend, omap8250_resume) |
1253 | SET_RUNTIME_PM_OPS(omap8250_runtime_suspend, | 1318 | SET_RUNTIME_PM_OPS(omap8250_runtime_suspend, |
@@ -1269,7 +1334,6 @@ static struct platform_driver omap8250_platform_driver = { | |||
1269 | .name = "omap8250", | 1334 | .name = "omap8250", |
1270 | .pm = &omap8250_dev_pm_ops, | 1335 | .pm = &omap8250_dev_pm_ops, |
1271 | .of_match_table = omap8250_dt_ids, | 1336 | .of_match_table = omap8250_dt_ids, |
1272 | .owner = THIS_MODULE, | ||
1273 | }, | 1337 | }, |
1274 | .probe = omap8250_probe, | 1338 | .probe = omap8250_probe, |
1275 | .remove = omap8250_remove, | 1339 | .remove = omap8250_remove, |
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index d1f8dc6aabcb..daf2c82984e9 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c | |||
@@ -221,13 +221,13 @@ pci_hp_diva_setup(struct serial_private *priv, | |||
221 | */ | 221 | */ |
222 | static int pci_inteli960ni_init(struct pci_dev *dev) | 222 | static int pci_inteli960ni_init(struct pci_dev *dev) |
223 | { | 223 | { |
224 | unsigned long oldval; | 224 | u32 oldval; |
225 | 225 | ||
226 | if (!(dev->subsystem_device & 0x1000)) | 226 | if (!(dev->subsystem_device & 0x1000)) |
227 | return -ENODEV; | 227 | return -ENODEV; |
228 | 228 | ||
229 | /* is firmware started? */ | 229 | /* is firmware started? */ |
230 | pci_read_config_dword(dev, 0x44, (void *)&oldval); | 230 | pci_read_config_dword(dev, 0x44, &oldval); |
231 | if (oldval == 0x00001000L) { /* RESET value */ | 231 | if (oldval == 0x00001000L) { /* RESET value */ |
232 | dev_dbg(&dev->dev, "Local i960 firmware missing\n"); | 232 | dev_dbg(&dev->dev, "Local i960 firmware missing\n"); |
233 | return -ENODEV; | 233 | return -ENODEV; |
diff --git a/drivers/tty/serial/8250/8250_pnp.c b/drivers/tty/serial/8250/8250_pnp.c index 682a2fbe5c06..50a09cd76d50 100644 --- a/drivers/tty/serial/8250/8250_pnp.c +++ b/drivers/tty/serial/8250/8250_pnp.c | |||
@@ -426,7 +426,7 @@ static int serial_pnp_guess_board(struct pnp_dev *dev) | |||
426 | static int | 426 | static int |
427 | serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) | 427 | serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) |
428 | { | 428 | { |
429 | struct uart_8250_port uart; | 429 | struct uart_8250_port uart, *port; |
430 | int ret, line, flags = dev_id->driver_data; | 430 | int ret, line, flags = dev_id->driver_data; |
431 | 431 | ||
432 | if (flags & UNKNOWN_DEV) { | 432 | if (flags & UNKNOWN_DEV) { |
@@ -471,6 +471,10 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) | |||
471 | if (line < 0 || (flags & CIR_PORT)) | 471 | if (line < 0 || (flags & CIR_PORT)) |
472 | return -ENODEV; | 472 | return -ENODEV; |
473 | 473 | ||
474 | port = serial8250_get_port(line); | ||
475 | if (uart_console(&port->port)) | ||
476 | dev->capabilities |= PNP_CONSOLE; | ||
477 | |||
474 | pnp_set_drvdata(dev, (void *)((long)line + 1)); | 478 | pnp_set_drvdata(dev, (void *)((long)line + 1)); |
475 | return 0; | 479 | return 0; |
476 | } | 480 | } |
@@ -478,6 +482,8 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) | |||
478 | static void serial_pnp_remove(struct pnp_dev *dev) | 482 | static void serial_pnp_remove(struct pnp_dev *dev) |
479 | { | 483 | { |
480 | long line = (long)pnp_get_drvdata(dev); | 484 | long line = (long)pnp_get_drvdata(dev); |
485 | |||
486 | dev->capabilities &= ~PNP_CONSOLE; | ||
481 | if (line) | 487 | if (line) |
482 | serial8250_unregister_port(line - 1); | 488 | serial8250_unregister_port(line - 1); |
483 | } | 489 | } |
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index 0fcbcd29502f..6f7f2d753def 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig | |||
@@ -308,6 +308,25 @@ config SERIAL_8250_OMAP | |||
308 | 308 | ||
309 | This driver uses ttyS instead of ttyO. | 309 | This driver uses ttyS instead of ttyO. |
310 | 310 | ||
311 | config SERIAL_8250_OMAP_TTYO_FIXUP | ||
312 | bool "Replace ttyO with ttyS" | ||
313 | depends on SERIAL_8250_OMAP=y && SERIAL_8250_CONSOLE | ||
314 | default y | ||
315 | help | ||
316 | This option replaces the "console=ttyO" argument with the matching | ||
317 | ttyS argument if the user did not specified it on the command line. | ||
318 | This ensures that the user can see the kernel output during boot | ||
319 | which he wouldn't see otherwise. The getty has still to be configured | ||
320 | for ttyS instead of ttyO regardless of this option. | ||
321 | This option is intended for people who "automatically" enable this | ||
322 | driver without knowing that this driver requires a different console= | ||
323 | argument. If you read this, please keep this option disabled and | ||
324 | instead update your kernel command line. If you prepare a kernel for a | ||
325 | distribution or other kind of larger user base then you probably want | ||
326 | to keep this option enabled. Otherwise people might complain about a | ||
327 | not booting kernel because the serial console remains silent in case | ||
328 | they forgot to update the command line. | ||
329 | |||
311 | config SERIAL_8250_FINTEK | 330 | config SERIAL_8250_FINTEK |
312 | tristate "Support for Fintek F81216A LPC to 4 UART" | 331 | tristate "Support for Fintek F81216A LPC to 4 UART" |
313 | depends on SERIAL_8250 && PNP | 332 | depends on SERIAL_8250 && PNP |
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index c79b43cd6014..5d916c7a216b 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -241,6 +241,7 @@ config SERIAL_SAMSUNG | |||
241 | tristate "Samsung SoC serial support" | 241 | tristate "Samsung SoC serial support" |
242 | depends on PLAT_SAMSUNG || ARCH_EXYNOS | 242 | depends on PLAT_SAMSUNG || ARCH_EXYNOS |
243 | select SERIAL_CORE | 243 | select SERIAL_CORE |
244 | select SERIAL_EARLYCON | ||
244 | help | 245 | help |
245 | Support for the on-chip UARTs on the Samsung S3C24XX series CPUs, | 246 | Support for the on-chip UARTs on the Samsung S3C24XX series CPUs, |
246 | providing /dev/ttySAC0, 1 and 2 (note, some machines may not | 247 | providing /dev/ttySAC0, 1 and 2 (note, some machines may not |
@@ -482,16 +483,6 @@ config SERIAL_SA1100_CONSOLE | |||
482 | your boot loader (lilo or loadlin) about how to pass options to the | 483 | your boot loader (lilo or loadlin) about how to pass options to the |
483 | kernel at boot time.) | 484 | kernel at boot time.) |
484 | 485 | ||
485 | config SERIAL_MRST_MAX3110 | ||
486 | tristate "SPI UART driver for Max3110" | ||
487 | depends on SPI_DW_PCI | ||
488 | select SERIAL_CORE | ||
489 | select SERIAL_CORE_CONSOLE | ||
490 | help | ||
491 | This is the UART protocol driver for the MAX3110 device on | ||
492 | the Intel Moorestown platform. On other systems use the max3100 | ||
493 | driver. | ||
494 | |||
495 | config SERIAL_MFD_HSU | 486 | config SERIAL_MFD_HSU |
496 | tristate "Medfield High Speed UART support" | 487 | tristate "Medfield High Speed UART support" |
497 | depends on PCI | 488 | depends on PCI |
@@ -1094,6 +1085,16 @@ config SERIAL_VT8500_CONSOLE | |||
1094 | depends on SERIAL_VT8500=y | 1085 | depends on SERIAL_VT8500=y |
1095 | select SERIAL_CORE_CONSOLE | 1086 | select SERIAL_CORE_CONSOLE |
1096 | 1087 | ||
1088 | config SERIAL_ETRAXFS | ||
1089 | bool "ETRAX FS serial port support" | ||
1090 | depends on ETRAX_ARCH_V32 && OF | ||
1091 | select SERIAL_CORE | ||
1092 | |||
1093 | config SERIAL_ETRAXFS_CONSOLE | ||
1094 | bool "ETRAX FS serial console support" | ||
1095 | depends on SERIAL_ETRAXFS | ||
1096 | select SERIAL_CORE_CONSOLE | ||
1097 | |||
1097 | config SERIAL_NETX | 1098 | config SERIAL_NETX |
1098 | tristate "NetX serial port support" | 1099 | tristate "NetX serial port support" |
1099 | depends on ARCH_NETX | 1100 | depends on ARCH_NETX |
@@ -1549,6 +1550,21 @@ config SERIAL_FSL_LPUART_CONSOLE | |||
1549 | If you have enabled the lpuart serial port on the Freescale SoCs, | 1550 | If you have enabled the lpuart serial port on the Freescale SoCs, |
1550 | you can make it the console by answering Y to this option. | 1551 | you can make it the console by answering Y to this option. |
1551 | 1552 | ||
1553 | config SERIAL_CONEXANT_DIGICOLOR | ||
1554 | tristate "Conexant Digicolor CX92xxx USART serial port support" | ||
1555 | depends on OF | ||
1556 | select SERIAL_CORE | ||
1557 | help | ||
1558 | Support for the on-chip USART on Conexant Digicolor SoCs. | ||
1559 | |||
1560 | config SERIAL_CONEXANT_DIGICOLOR_CONSOLE | ||
1561 | bool "Console on Conexant Digicolor serial port" | ||
1562 | depends on SERIAL_CONEXANT_DIGICOLOR=y | ||
1563 | select SERIAL_CORE_CONSOLE | ||
1564 | help | ||
1565 | If you have enabled the USART serial port on Conexant Digicolor | ||
1566 | SoCs, you can make it the console by answering Y to this option. | ||
1567 | |||
1552 | config SERIAL_ST_ASC | 1568 | config SERIAL_ST_ASC |
1553 | tristate "ST ASC serial port support" | 1569 | tristate "ST ASC serial port support" |
1554 | select SERIAL_CORE | 1570 | select SERIAL_CORE |
@@ -1577,6 +1593,24 @@ config SERIAL_MEN_Z135 | |||
1577 | This driver can also be build as a module. If so, the module will be called | 1593 | This driver can also be build as a module. If so, the module will be called |
1578 | men_z135_uart.ko | 1594 | men_z135_uart.ko |
1579 | 1595 | ||
1596 | config SERIAL_SPRD | ||
1597 | tristate "Support for Spreadtrum serial" | ||
1598 | depends on ARCH_SPRD | ||
1599 | select SERIAL_CORE | ||
1600 | help | ||
1601 | This enables the driver for the Spreadtrum's serial. | ||
1602 | |||
1603 | config SERIAL_SPRD_CONSOLE | ||
1604 | bool "Spreadtrum UART console support" | ||
1605 | depends on SERIAL_SPRD=y | ||
1606 | select SERIAL_CORE_CONSOLE | ||
1607 | select SERIAL_EARLYCON | ||
1608 | help | ||
1609 | Support for early debug console using Spreadtrum's serial. This enables | ||
1610 | the console before standard serial driver is probed. This is enabled | ||
1611 | with "earlycon" on the kernel command line. The console is | ||
1612 | enabled when early_param is processed. | ||
1613 | |||
1580 | endmenu | 1614 | endmenu |
1581 | 1615 | ||
1582 | config SERIAL_MCTRL_GPIO | 1616 | config SERIAL_MCTRL_GPIO |
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index 9a548acf5fdc..599be4b05a26 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile | |||
@@ -51,6 +51,7 @@ obj-$(CONFIG_SERIAL_MPSC) += mpsc.o | |||
51 | obj-$(CONFIG_SERIAL_MESON) += meson_uart.o | 51 | obj-$(CONFIG_SERIAL_MESON) += meson_uart.o |
52 | obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o | 52 | obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o |
53 | obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o | 53 | obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o |
54 | obj-$(CONFIG_SERIAL_ETRAXFS) += etraxfs-uart.o | ||
54 | obj-$(CONFIG_SERIAL_SCCNXP) += sccnxp.o | 55 | obj-$(CONFIG_SERIAL_SCCNXP) += sccnxp.o |
55 | obj-$(CONFIG_SERIAL_SC16IS7XX) += sc16is7xx.o | 56 | obj-$(CONFIG_SERIAL_SC16IS7XX) += sc16is7xx.o |
56 | obj-$(CONFIG_SERIAL_JSM) += jsm/ | 57 | obj-$(CONFIG_SERIAL_JSM) += jsm/ |
@@ -77,7 +78,6 @@ obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o | |||
77 | obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o | 78 | obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o |
78 | obj-$(CONFIG_SERIAL_ALTERA_JTAGUART) += altera_jtaguart.o | 79 | obj-$(CONFIG_SERIAL_ALTERA_JTAGUART) += altera_jtaguart.o |
79 | obj-$(CONFIG_SERIAL_VT8500) += vt8500_serial.o | 80 | obj-$(CONFIG_SERIAL_VT8500) += vt8500_serial.o |
80 | obj-$(CONFIG_SERIAL_MRST_MAX3110) += mrst_max3110.o | ||
81 | obj-$(CONFIG_SERIAL_MFD_HSU) += mfd.o | 81 | obj-$(CONFIG_SERIAL_MFD_HSU) += mfd.o |
82 | obj-$(CONFIG_SERIAL_IFX6X60) += ifx6x60.o | 82 | obj-$(CONFIG_SERIAL_IFX6X60) += ifx6x60.o |
83 | obj-$(CONFIG_SERIAL_PCH_UART) += pch_uart.o | 83 | obj-$(CONFIG_SERIAL_PCH_UART) += pch_uart.o |
@@ -92,7 +92,9 @@ obj-$(CONFIG_SERIAL_EFM32_UART) += efm32-uart.o | |||
92 | obj-$(CONFIG_SERIAL_ARC) += arc_uart.o | 92 | obj-$(CONFIG_SERIAL_ARC) += arc_uart.o |
93 | obj-$(CONFIG_SERIAL_RP2) += rp2.o | 93 | obj-$(CONFIG_SERIAL_RP2) += rp2.o |
94 | obj-$(CONFIG_SERIAL_FSL_LPUART) += fsl_lpuart.o | 94 | obj-$(CONFIG_SERIAL_FSL_LPUART) += fsl_lpuart.o |
95 | obj-$(CONFIG_SERIAL_CONEXANT_DIGICOLOR) += digicolor-usart.o | ||
95 | obj-$(CONFIG_SERIAL_MEN_Z135) += men_z135_uart.o | 96 | obj-$(CONFIG_SERIAL_MEN_Z135) += men_z135_uart.o |
97 | obj-$(CONFIG_SERIAL_SPRD) += sprd_serial.o | ||
96 | 98 | ||
97 | # GPIOLIB helpers for modem control lines | 99 | # GPIOLIB helpers for modem control lines |
98 | obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o | 100 | obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o |
diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index 192d0435bb86..0fefdd8931a2 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c | |||
@@ -441,6 +441,7 @@ static int altera_jtaguart_probe(struct platform_device *pdev) | |||
441 | port->iotype = SERIAL_IO_MEM; | 441 | port->iotype = SERIAL_IO_MEM; |
442 | port->ops = &altera_jtaguart_ops; | 442 | port->ops = &altera_jtaguart_ops; |
443 | port->flags = UPF_BOOT_AUTOCONF; | 443 | port->flags = UPF_BOOT_AUTOCONF; |
444 | port->dev = &pdev->dev; | ||
444 | 445 | ||
445 | uart_add_one_port(&altera_jtaguart_driver, port); | 446 | uart_add_one_port(&altera_jtaguart_driver, port); |
446 | 447 | ||
diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index eb15a50623cb..b2859fe07e14 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c | |||
@@ -589,6 +589,7 @@ static int altera_uart_probe(struct platform_device *pdev) | |||
589 | port->iotype = SERIAL_IO_MEM; | 589 | port->iotype = SERIAL_IO_MEM; |
590 | port->ops = &altera_uart_ops; | 590 | port->ops = &altera_uart_ops; |
591 | port->flags = UPF_BOOT_AUTOCONF; | 591 | port->flags = UPF_BOOT_AUTOCONF; |
592 | port->dev = &pdev->dev; | ||
592 | 593 | ||
593 | platform_set_drvdata(pdev, port); | 594 | platform_set_drvdata(pdev, port); |
594 | 595 | ||
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 4d848a29e223..846552bff67d 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c | |||
@@ -341,13 +341,37 @@ static u_int atmel_tx_empty(struct uart_port *port) | |||
341 | static void atmel_set_mctrl(struct uart_port *port, u_int mctrl) | 341 | static void atmel_set_mctrl(struct uart_port *port, u_int mctrl) |
342 | { | 342 | { |
343 | unsigned int control = 0; | 343 | unsigned int control = 0; |
344 | unsigned int mode; | 344 | unsigned int mode = UART_GET_MR(port); |
345 | unsigned int rts_paused, rts_ready; | ||
345 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 346 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
346 | 347 | ||
348 | /* override mode to RS485 if needed, otherwise keep the current mode */ | ||
349 | if (port->rs485.flags & SER_RS485_ENABLED) { | ||
350 | if ((port->rs485.delay_rts_after_send) > 0) | ||
351 | UART_PUT_TTGR(port, port->rs485.delay_rts_after_send); | ||
352 | mode &= ~ATMEL_US_USMODE; | ||
353 | mode |= ATMEL_US_USMODE_RS485; | ||
354 | } | ||
355 | |||
356 | /* set the RTS line state according to the mode */ | ||
357 | if ((mode & ATMEL_US_USMODE) == ATMEL_US_USMODE_HWHS) { | ||
358 | /* force RTS line to high level */ | ||
359 | rts_paused = ATMEL_US_RTSEN; | ||
360 | |||
361 | /* give the control of the RTS line back to the hardware */ | ||
362 | rts_ready = ATMEL_US_RTSDIS; | ||
363 | } else { | ||
364 | /* force RTS line to high level */ | ||
365 | rts_paused = ATMEL_US_RTSDIS; | ||
366 | |||
367 | /* force RTS line to low level */ | ||
368 | rts_ready = ATMEL_US_RTSEN; | ||
369 | } | ||
370 | |||
347 | if (mctrl & TIOCM_RTS) | 371 | if (mctrl & TIOCM_RTS) |
348 | control |= ATMEL_US_RTSEN; | 372 | control |= rts_ready; |
349 | else | 373 | else |
350 | control |= ATMEL_US_RTSDIS; | 374 | control |= rts_paused; |
351 | 375 | ||
352 | if (mctrl & TIOCM_DTR) | 376 | if (mctrl & TIOCM_DTR) |
353 | control |= ATMEL_US_DTREN; | 377 | control |= ATMEL_US_DTREN; |
@@ -359,23 +383,12 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl) | |||
359 | mctrl_gpio_set(atmel_port->gpios, mctrl); | 383 | mctrl_gpio_set(atmel_port->gpios, mctrl); |
360 | 384 | ||
361 | /* Local loopback mode? */ | 385 | /* Local loopback mode? */ |
362 | mode = UART_GET_MR(port) & ~ATMEL_US_CHMODE; | 386 | mode &= ~ATMEL_US_CHMODE; |
363 | if (mctrl & TIOCM_LOOP) | 387 | if (mctrl & TIOCM_LOOP) |
364 | mode |= ATMEL_US_CHMODE_LOC_LOOP; | 388 | mode |= ATMEL_US_CHMODE_LOC_LOOP; |
365 | else | 389 | else |
366 | mode |= ATMEL_US_CHMODE_NORMAL; | 390 | mode |= ATMEL_US_CHMODE_NORMAL; |
367 | 391 | ||
368 | /* Resetting serial mode to RS232 (0x0) */ | ||
369 | mode &= ~ATMEL_US_USMODE; | ||
370 | |||
371 | if (port->rs485.flags & SER_RS485_ENABLED) { | ||
372 | dev_dbg(port->dev, "Setting UART to RS485\n"); | ||
373 | if ((port->rs485.delay_rts_after_send) > 0) | ||
374 | UART_PUT_TTGR(port, port->rs485.delay_rts_after_send); | ||
375 | mode |= ATMEL_US_USMODE_RS485; | ||
376 | } else { | ||
377 | dev_dbg(port->dev, "Setting UART to RS232\n"); | ||
378 | } | ||
379 | UART_PUT_MR(port, mode); | 392 | UART_PUT_MR(port, mode); |
380 | } | 393 | } |
381 | 394 | ||
@@ -725,7 +738,11 @@ static void atmel_complete_tx_dma(void *arg) | |||
725 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 738 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
726 | uart_write_wakeup(port); | 739 | uart_write_wakeup(port); |
727 | 740 | ||
728 | /* Do we really need this? */ | 741 | /* |
742 | * xmit is a circular buffer so, if we have just send data from | ||
743 | * xmit->tail to the end of xmit->buf, now we have to transmit the | ||
744 | * remaining data from the beginning of xmit->buf to xmit->head. | ||
745 | */ | ||
729 | if (!uart_circ_empty(xmit)) | 746 | if (!uart_circ_empty(xmit)) |
730 | tasklet_schedule(&atmel_port->tasklet); | 747 | tasklet_schedule(&atmel_port->tasklet); |
731 | 748 | ||
@@ -784,17 +801,17 @@ static void atmel_tx_dma(struct uart_port *port) | |||
784 | BUG_ON(!sg_dma_len(sg)); | 801 | BUG_ON(!sg_dma_len(sg)); |
785 | 802 | ||
786 | desc = dmaengine_prep_slave_sg(chan, | 803 | desc = dmaengine_prep_slave_sg(chan, |
787 | sg, | 804 | sg, |
788 | 1, | 805 | 1, |
789 | DMA_MEM_TO_DEV, | 806 | DMA_MEM_TO_DEV, |
790 | DMA_PREP_INTERRUPT | | 807 | DMA_PREP_INTERRUPT | |
791 | DMA_CTRL_ACK); | 808 | DMA_CTRL_ACK); |
792 | if (!desc) { | 809 | if (!desc) { |
793 | dev_err(port->dev, "Failed to send via dma!\n"); | 810 | dev_err(port->dev, "Failed to send via dma!\n"); |
794 | return; | 811 | return; |
795 | } | 812 | } |
796 | 813 | ||
797 | dma_sync_sg_for_device(port->dev, sg, 1, DMA_MEM_TO_DEV); | 814 | dma_sync_sg_for_device(port->dev, sg, 1, DMA_TO_DEVICE); |
798 | 815 | ||
799 | atmel_port->desc_tx = desc; | 816 | atmel_port->desc_tx = desc; |
800 | desc->callback = atmel_complete_tx_dma; | 817 | desc->callback = atmel_complete_tx_dma; |
@@ -927,7 +944,7 @@ static void atmel_rx_from_dma(struct uart_port *port) | |||
927 | dma_sync_sg_for_cpu(port->dev, | 944 | dma_sync_sg_for_cpu(port->dev, |
928 | &atmel_port->sg_rx, | 945 | &atmel_port->sg_rx, |
929 | 1, | 946 | 1, |
930 | DMA_DEV_TO_MEM); | 947 | DMA_FROM_DEVICE); |
931 | 948 | ||
932 | /* | 949 | /* |
933 | * ring->head points to the end of data already written by the DMA. | 950 | * ring->head points to the end of data already written by the DMA. |
@@ -974,7 +991,7 @@ static void atmel_rx_from_dma(struct uart_port *port) | |||
974 | dma_sync_sg_for_device(port->dev, | 991 | dma_sync_sg_for_device(port->dev, |
975 | &atmel_port->sg_rx, | 992 | &atmel_port->sg_rx, |
976 | 1, | 993 | 1, |
977 | DMA_DEV_TO_MEM); | 994 | DMA_FROM_DEVICE); |
978 | 995 | ||
979 | /* | 996 | /* |
980 | * Drop the lock here since it might end up calling | 997 | * Drop the lock here since it might end up calling |
@@ -1012,13 +1029,13 @@ static int atmel_prepare_rx_dma(struct uart_port *port) | |||
1012 | /* UART circular rx buffer is an aligned page. */ | 1029 | /* UART circular rx buffer is an aligned page. */ |
1013 | BUG_ON((int)port->state->xmit.buf & ~PAGE_MASK); | 1030 | BUG_ON((int)port->state->xmit.buf & ~PAGE_MASK); |
1014 | sg_set_page(&atmel_port->sg_rx, | 1031 | sg_set_page(&atmel_port->sg_rx, |
1015 | virt_to_page(ring->buf), | 1032 | virt_to_page(ring->buf), |
1016 | ATMEL_SERIAL_RINGSIZE, | 1033 | ATMEL_SERIAL_RINGSIZE, |
1017 | (int)ring->buf & ~PAGE_MASK); | 1034 | (int)ring->buf & ~PAGE_MASK); |
1018 | nent = dma_map_sg(port->dev, | 1035 | nent = dma_map_sg(port->dev, |
1019 | &atmel_port->sg_rx, | 1036 | &atmel_port->sg_rx, |
1020 | 1, | 1037 | 1, |
1021 | DMA_FROM_DEVICE); | 1038 | DMA_FROM_DEVICE); |
1022 | 1039 | ||
1023 | if (!nent) { | 1040 | if (!nent) { |
1024 | dev_dbg(port->dev, "need to release resource of dma\n"); | 1041 | dev_dbg(port->dev, "need to release resource of dma\n"); |
@@ -1047,11 +1064,11 @@ static int atmel_prepare_rx_dma(struct uart_port *port) | |||
1047 | * each one is half ring buffer size | 1064 | * each one is half ring buffer size |
1048 | */ | 1065 | */ |
1049 | desc = dmaengine_prep_dma_cyclic(atmel_port->chan_rx, | 1066 | desc = dmaengine_prep_dma_cyclic(atmel_port->chan_rx, |
1050 | sg_dma_address(&atmel_port->sg_rx), | 1067 | sg_dma_address(&atmel_port->sg_rx), |
1051 | sg_dma_len(&atmel_port->sg_rx), | 1068 | sg_dma_len(&atmel_port->sg_rx), |
1052 | sg_dma_len(&atmel_port->sg_rx)/2, | 1069 | sg_dma_len(&atmel_port->sg_rx)/2, |
1053 | DMA_DEV_TO_MEM, | 1070 | DMA_DEV_TO_MEM, |
1054 | DMA_PREP_INTERRUPT); | 1071 | DMA_PREP_INTERRUPT); |
1055 | desc->callback = atmel_complete_rx_dma; | 1072 | desc->callback = atmel_complete_rx_dma; |
1056 | desc->callback_param = port; | 1073 | desc->callback_param = port; |
1057 | atmel_port->desc_rx = desc; | 1074 | atmel_port->desc_rx = desc; |
@@ -1921,12 +1938,14 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1921 | struct ktermios *old) | 1938 | struct ktermios *old) |
1922 | { | 1939 | { |
1923 | unsigned long flags; | 1940 | unsigned long flags; |
1924 | unsigned int mode, imr, quot, baud; | 1941 | unsigned int old_mode, mode, imr, quot, baud; |
1925 | 1942 | ||
1926 | /* Get current mode register */ | 1943 | /* save the current mode register */ |
1927 | mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL | 1944 | mode = old_mode = UART_GET_MR(port); |
1928 | | ATMEL_US_NBSTOP | ATMEL_US_PAR | 1945 | |
1929 | | ATMEL_US_USMODE); | 1946 | /* reset the mode, clock divisor, parity, stop bits and data size */ |
1947 | mode &= ~(ATMEL_US_USCLKS | ATMEL_US_CHRL | ATMEL_US_NBSTOP | | ||
1948 | ATMEL_US_PAR | ATMEL_US_USMODE); | ||
1930 | 1949 | ||
1931 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); | 1950 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); |
1932 | quot = uart_get_divisor(port, baud); | 1951 | quot = uart_get_divisor(port, baud); |
@@ -1971,12 +1990,6 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1971 | } else | 1990 | } else |
1972 | mode |= ATMEL_US_PAR_NONE; | 1991 | mode |= ATMEL_US_PAR_NONE; |
1973 | 1992 | ||
1974 | /* hardware handshake (RTS/CTS) */ | ||
1975 | if (termios->c_cflag & CRTSCTS) | ||
1976 | mode |= ATMEL_US_USMODE_HWHS; | ||
1977 | else | ||
1978 | mode |= ATMEL_US_USMODE_NORMAL; | ||
1979 | |||
1980 | spin_lock_irqsave(&port->lock, flags); | 1993 | spin_lock_irqsave(&port->lock, flags); |
1981 | 1994 | ||
1982 | port->read_status_mask = ATMEL_US_OVRE; | 1995 | port->read_status_mask = ATMEL_US_OVRE; |
@@ -2020,18 +2033,40 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2020 | /* disable receiver and transmitter */ | 2033 | /* disable receiver and transmitter */ |
2021 | UART_PUT_CR(port, ATMEL_US_TXDIS | ATMEL_US_RXDIS); | 2034 | UART_PUT_CR(port, ATMEL_US_TXDIS | ATMEL_US_RXDIS); |
2022 | 2035 | ||
2023 | /* Resetting serial mode to RS232 (0x0) */ | 2036 | /* mode */ |
2024 | mode &= ~ATMEL_US_USMODE; | ||
2025 | |||
2026 | if (port->rs485.flags & SER_RS485_ENABLED) { | 2037 | if (port->rs485.flags & SER_RS485_ENABLED) { |
2027 | if ((port->rs485.delay_rts_after_send) > 0) | 2038 | if ((port->rs485.delay_rts_after_send) > 0) |
2028 | UART_PUT_TTGR(port, port->rs485.delay_rts_after_send); | 2039 | UART_PUT_TTGR(port, port->rs485.delay_rts_after_send); |
2029 | mode |= ATMEL_US_USMODE_RS485; | 2040 | mode |= ATMEL_US_USMODE_RS485; |
2041 | } else if (termios->c_cflag & CRTSCTS) { | ||
2042 | /* RS232 with hardware handshake (RTS/CTS) */ | ||
2043 | mode |= ATMEL_US_USMODE_HWHS; | ||
2044 | } else { | ||
2045 | /* RS232 without hadware handshake */ | ||
2046 | mode |= ATMEL_US_USMODE_NORMAL; | ||
2030 | } | 2047 | } |
2031 | 2048 | ||
2032 | /* set the parity, stop bits and data size */ | 2049 | /* set the mode, clock divisor, parity, stop bits and data size */ |
2033 | UART_PUT_MR(port, mode); | 2050 | UART_PUT_MR(port, mode); |
2034 | 2051 | ||
2052 | /* | ||
2053 | * when switching the mode, set the RTS line state according to the | ||
2054 | * new mode, otherwise keep the former state | ||
2055 | */ | ||
2056 | if ((old_mode & ATMEL_US_USMODE) != (mode & ATMEL_US_USMODE)) { | ||
2057 | unsigned int rts_state; | ||
2058 | |||
2059 | if ((mode & ATMEL_US_USMODE) == ATMEL_US_USMODE_HWHS) { | ||
2060 | /* let the hardware control the RTS line */ | ||
2061 | rts_state = ATMEL_US_RTSDIS; | ||
2062 | } else { | ||
2063 | /* force RTS line to low level */ | ||
2064 | rts_state = ATMEL_US_RTSEN; | ||
2065 | } | ||
2066 | |||
2067 | UART_PUT_CR(port, rts_state); | ||
2068 | } | ||
2069 | |||
2035 | /* set the baud rate */ | 2070 | /* set the baud rate */ |
2036 | UART_PUT_BRGR(port, quot); | 2071 | UART_PUT_BRGR(port, quot); |
2037 | UART_PUT_CR(port, ATMEL_US_RSTSTA | ATMEL_US_RSTRX); | 2072 | UART_PUT_CR(port, ATMEL_US_RSTSTA | ATMEL_US_RSTRX); |
@@ -2565,7 +2600,7 @@ static int atmel_serial_probe(struct platform_device *pdev) | |||
2565 | 2600 | ||
2566 | ret = atmel_init_port(port, pdev); | 2601 | ret = atmel_init_port(port, pdev); |
2567 | if (ret) | 2602 | if (ret) |
2568 | goto err; | 2603 | goto err_clear_bit; |
2569 | 2604 | ||
2570 | if (!atmel_use_pdc_rx(&port->uart)) { | 2605 | if (!atmel_use_pdc_rx(&port->uart)) { |
2571 | ret = -ENOMEM; | 2606 | ret = -ENOMEM; |
@@ -2596,6 +2631,12 @@ static int atmel_serial_probe(struct platform_device *pdev) | |||
2596 | device_init_wakeup(&pdev->dev, 1); | 2631 | device_init_wakeup(&pdev->dev, 1); |
2597 | platform_set_drvdata(pdev, port); | 2632 | platform_set_drvdata(pdev, port); |
2598 | 2633 | ||
2634 | /* | ||
2635 | * The peripheral clock has been disabled by atmel_init_port(): | ||
2636 | * enable it before accessing I/O registers | ||
2637 | */ | ||
2638 | clk_prepare_enable(port->clk); | ||
2639 | |||
2599 | if (rs485_enabled) { | 2640 | if (rs485_enabled) { |
2600 | UART_PUT_MR(&port->uart, ATMEL_US_USMODE_NORMAL); | 2641 | UART_PUT_MR(&port->uart, ATMEL_US_USMODE_NORMAL); |
2601 | UART_PUT_CR(&port->uart, ATMEL_US_RTSEN); | 2642 | UART_PUT_CR(&port->uart, ATMEL_US_RTSEN); |
@@ -2606,6 +2647,12 @@ static int atmel_serial_probe(struct platform_device *pdev) | |||
2606 | */ | 2647 | */ |
2607 | atmel_get_ip_name(&port->uart); | 2648 | atmel_get_ip_name(&port->uart); |
2608 | 2649 | ||
2650 | /* | ||
2651 | * The peripheral clock can now safely be disabled till the port | ||
2652 | * is used | ||
2653 | */ | ||
2654 | clk_disable_unprepare(port->clk); | ||
2655 | |||
2609 | return 0; | 2656 | return 0; |
2610 | 2657 | ||
2611 | err_add_port: | 2658 | err_add_port: |
@@ -2616,6 +2663,8 @@ err_alloc_ring: | |||
2616 | clk_put(port->clk); | 2663 | clk_put(port->clk); |
2617 | port->clk = NULL; | 2664 | port->clk = NULL; |
2618 | } | 2665 | } |
2666 | err_clear_bit: | ||
2667 | clear_bit(port->uart.line, atmel_ports_in_use); | ||
2619 | err: | 2668 | err: |
2620 | return ret; | 2669 | return ret; |
2621 | } | 2670 | } |
diff --git a/drivers/tty/serial/digicolor-usart.c b/drivers/tty/serial/digicolor-usart.c new file mode 100644 index 000000000000..a80cdad114f3 --- /dev/null +++ b/drivers/tty/serial/digicolor-usart.c | |||
@@ -0,0 +1,560 @@ | |||
1 | /* | ||
2 | * Driver for Conexant Digicolor serial ports (USART) | ||
3 | * | ||
4 | * Author: Baruch Siach <baruch@tkos.co.il> | ||
5 | * | ||
6 | * Copyright (C) 2014 Paradox Innovation Ltd. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/console.h> | ||
16 | #include <linux/serial_core.h> | ||
17 | #include <linux/serial.h> | ||
18 | #include <linux/clk.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <linux/tty.h> | ||
21 | #include <linux/tty_flip.h> | ||
22 | #include <linux/of.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/workqueue.h> | ||
25 | |||
26 | #define UA_ENABLE 0x00 | ||
27 | #define UA_ENABLE_ENABLE BIT(0) | ||
28 | |||
29 | #define UA_CONTROL 0x01 | ||
30 | #define UA_CONTROL_RX_ENABLE BIT(0) | ||
31 | #define UA_CONTROL_TX_ENABLE BIT(1) | ||
32 | #define UA_CONTROL_SOFT_RESET BIT(2) | ||
33 | |||
34 | #define UA_STATUS 0x02 | ||
35 | #define UA_STATUS_PARITY_ERR BIT(0) | ||
36 | #define UA_STATUS_FRAME_ERR BIT(1) | ||
37 | #define UA_STATUS_OVERRUN_ERR BIT(2) | ||
38 | #define UA_STATUS_TX_READY BIT(6) | ||
39 | |||
40 | #define UA_CONFIG 0x03 | ||
41 | #define UA_CONFIG_CHAR_LEN BIT(0) | ||
42 | #define UA_CONFIG_STOP_BITS BIT(1) | ||
43 | #define UA_CONFIG_PARITY BIT(2) | ||
44 | #define UA_CONFIG_ODD_PARITY BIT(4) | ||
45 | |||
46 | #define UA_EMI_REC 0x04 | ||
47 | |||
48 | #define UA_HBAUD_LO 0x08 | ||
49 | #define UA_HBAUD_HI 0x09 | ||
50 | |||
51 | #define UA_STATUS_FIFO 0x0a | ||
52 | #define UA_STATUS_FIFO_RX_EMPTY BIT(2) | ||
53 | #define UA_STATUS_FIFO_RX_INT_ALMOST BIT(3) | ||
54 | #define UA_STATUS_FIFO_TX_FULL BIT(4) | ||
55 | #define UA_STATUS_FIFO_TX_INT_ALMOST BIT(7) | ||
56 | |||
57 | #define UA_CONFIG_FIFO 0x0b | ||
58 | #define UA_CONFIG_FIFO_RX_THRESH 7 | ||
59 | #define UA_CONFIG_FIFO_RX_FIFO_MODE BIT(3) | ||
60 | #define UA_CONFIG_FIFO_TX_FIFO_MODE BIT(7) | ||
61 | |||
62 | #define UA_INTFLAG_CLEAR 0x1c | ||
63 | #define UA_INTFLAG_SET 0x1d | ||
64 | #define UA_INT_ENABLE 0x1e | ||
65 | #define UA_INT_STATUS 0x1f | ||
66 | |||
67 | #define UA_INT_TX BIT(0) | ||
68 | #define UA_INT_RX BIT(1) | ||
69 | |||
70 | #define DIGICOLOR_USART_NR 3 | ||
71 | |||
72 | /* | ||
73 | * We use the 16 bytes hardware FIFO to buffer Rx traffic. Rx interrupt is | ||
74 | * only produced when the FIFO is filled more than a certain configurable | ||
75 | * threshold. Unfortunately, there is no way to set this threshold below half | ||
76 | * FIFO. This means that we must periodically poll the FIFO status register to | ||
77 | * see whether there are waiting Rx bytes. | ||
78 | */ | ||
79 | |||
80 | struct digicolor_port { | ||
81 | struct uart_port port; | ||
82 | struct delayed_work rx_poll_work; | ||
83 | }; | ||
84 | |||
85 | static struct uart_port *digicolor_ports[DIGICOLOR_USART_NR]; | ||
86 | |||
87 | static bool digicolor_uart_tx_full(struct uart_port *port) | ||
88 | { | ||
89 | return !!(readb_relaxed(port->membase + UA_STATUS_FIFO) & | ||
90 | UA_STATUS_FIFO_TX_FULL); | ||
91 | } | ||
92 | |||
93 | static bool digicolor_uart_rx_empty(struct uart_port *port) | ||
94 | { | ||
95 | return !!(readb_relaxed(port->membase + UA_STATUS_FIFO) & | ||
96 | UA_STATUS_FIFO_RX_EMPTY); | ||
97 | } | ||
98 | |||
99 | static void digicolor_uart_stop_tx(struct uart_port *port) | ||
100 | { | ||
101 | u8 int_enable = readb_relaxed(port->membase + UA_INT_ENABLE); | ||
102 | |||
103 | int_enable &= ~UA_INT_TX; | ||
104 | writeb_relaxed(int_enable, port->membase + UA_INT_ENABLE); | ||
105 | } | ||
106 | |||
107 | static void digicolor_uart_start_tx(struct uart_port *port) | ||
108 | { | ||
109 | u8 int_enable = readb_relaxed(port->membase + UA_INT_ENABLE); | ||
110 | |||
111 | int_enable |= UA_INT_TX; | ||
112 | writeb_relaxed(int_enable, port->membase + UA_INT_ENABLE); | ||
113 | } | ||
114 | |||
115 | static void digicolor_uart_stop_rx(struct uart_port *port) | ||
116 | { | ||
117 | u8 int_enable = readb_relaxed(port->membase + UA_INT_ENABLE); | ||
118 | |||
119 | int_enable &= ~UA_INT_RX; | ||
120 | writeb_relaxed(int_enable, port->membase + UA_INT_ENABLE); | ||
121 | } | ||
122 | |||
123 | static void digicolor_rx_poll(struct work_struct *work) | ||
124 | { | ||
125 | struct digicolor_port *dp = | ||
126 | container_of(to_delayed_work(work), | ||
127 | struct digicolor_port, rx_poll_work); | ||
128 | |||
129 | if (!digicolor_uart_rx_empty(&dp->port)) | ||
130 | /* force RX interrupt */ | ||
131 | writeb_relaxed(UA_INT_RX, dp->port.membase + UA_INTFLAG_SET); | ||
132 | |||
133 | schedule_delayed_work(&dp->rx_poll_work, msecs_to_jiffies(100)); | ||
134 | } | ||
135 | |||
136 | static void digicolor_uart_rx(struct uart_port *port) | ||
137 | { | ||
138 | unsigned long flags; | ||
139 | |||
140 | spin_lock_irqsave(&port->lock, flags); | ||
141 | |||
142 | while (1) { | ||
143 | u8 status, ch; | ||
144 | unsigned int ch_flag; | ||
145 | |||
146 | if (digicolor_uart_rx_empty(port)) | ||
147 | break; | ||
148 | |||
149 | ch = readb_relaxed(port->membase + UA_EMI_REC); | ||
150 | status = readb_relaxed(port->membase + UA_STATUS); | ||
151 | |||
152 | port->icount.rx++; | ||
153 | ch_flag = TTY_NORMAL; | ||
154 | |||
155 | if (status) { | ||
156 | if (status & UA_STATUS_PARITY_ERR) | ||
157 | port->icount.parity++; | ||
158 | else if (status & UA_STATUS_FRAME_ERR) | ||
159 | port->icount.frame++; | ||
160 | else if (status & UA_STATUS_OVERRUN_ERR) | ||
161 | port->icount.overrun++; | ||
162 | |||
163 | status &= port->read_status_mask; | ||
164 | |||
165 | if (status & UA_STATUS_PARITY_ERR) | ||
166 | ch_flag = TTY_PARITY; | ||
167 | else if (status & UA_STATUS_FRAME_ERR) | ||
168 | ch_flag = TTY_FRAME; | ||
169 | else if (status & UA_STATUS_OVERRUN_ERR) | ||
170 | ch_flag = TTY_OVERRUN; | ||
171 | } | ||
172 | |||
173 | if (status & port->ignore_status_mask) | ||
174 | continue; | ||
175 | |||
176 | uart_insert_char(port, status, UA_STATUS_OVERRUN_ERR, ch, | ||
177 | ch_flag); | ||
178 | } | ||
179 | |||
180 | spin_unlock_irqrestore(&port->lock, flags); | ||
181 | |||
182 | tty_flip_buffer_push(&port->state->port); | ||
183 | } | ||
184 | |||
185 | static void digicolor_uart_tx(struct uart_port *port) | ||
186 | { | ||
187 | struct circ_buf *xmit = &port->state->xmit; | ||
188 | unsigned long flags; | ||
189 | |||
190 | if (digicolor_uart_tx_full(port)) | ||
191 | return; | ||
192 | |||
193 | spin_lock_irqsave(&port->lock, flags); | ||
194 | |||
195 | if (port->x_char) { | ||
196 | writeb_relaxed(port->x_char, port->membase + UA_EMI_REC); | ||
197 | port->icount.tx++; | ||
198 | port->x_char = 0; | ||
199 | goto out; | ||
200 | } | ||
201 | |||
202 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { | ||
203 | digicolor_uart_stop_tx(port); | ||
204 | goto out; | ||
205 | } | ||
206 | |||
207 | while (!uart_circ_empty(xmit)) { | ||
208 | writeb(xmit->buf[xmit->tail], port->membase + UA_EMI_REC); | ||
209 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
210 | port->icount.tx++; | ||
211 | |||
212 | if (digicolor_uart_tx_full(port)) | ||
213 | break; | ||
214 | } | ||
215 | |||
216 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
217 | uart_write_wakeup(port); | ||
218 | |||
219 | out: | ||
220 | spin_unlock_irqrestore(&port->lock, flags); | ||
221 | } | ||
222 | |||
223 | static irqreturn_t digicolor_uart_int(int irq, void *dev_id) | ||
224 | { | ||
225 | struct uart_port *port = dev_id; | ||
226 | u8 int_status = readb_relaxed(port->membase + UA_INT_STATUS); | ||
227 | |||
228 | writeb_relaxed(UA_INT_RX | UA_INT_TX, | ||
229 | port->membase + UA_INTFLAG_CLEAR); | ||
230 | |||
231 | if (int_status & UA_INT_RX) | ||
232 | digicolor_uart_rx(port); | ||
233 | if (int_status & UA_INT_TX) | ||
234 | digicolor_uart_tx(port); | ||
235 | |||
236 | return IRQ_HANDLED; | ||
237 | } | ||
238 | |||
239 | static unsigned int digicolor_uart_tx_empty(struct uart_port *port) | ||
240 | { | ||
241 | u8 status = readb_relaxed(port->membase + UA_STATUS); | ||
242 | |||
243 | return (status & UA_STATUS_TX_READY) ? TIOCSER_TEMT : 0; | ||
244 | } | ||
245 | |||
246 | static unsigned int digicolor_uart_get_mctrl(struct uart_port *port) | ||
247 | { | ||
248 | return TIOCM_CTS; | ||
249 | } | ||
250 | |||
251 | static void digicolor_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
252 | { | ||
253 | } | ||
254 | |||
255 | static void digicolor_uart_break_ctl(struct uart_port *port, int state) | ||
256 | { | ||
257 | } | ||
258 | |||
259 | static int digicolor_uart_startup(struct uart_port *port) | ||
260 | { | ||
261 | struct digicolor_port *dp = | ||
262 | container_of(port, struct digicolor_port, port); | ||
263 | |||
264 | writeb_relaxed(UA_ENABLE_ENABLE, port->membase + UA_ENABLE); | ||
265 | writeb_relaxed(UA_CONTROL_SOFT_RESET, port->membase + UA_CONTROL); | ||
266 | writeb_relaxed(0, port->membase + UA_CONTROL); | ||
267 | |||
268 | writeb_relaxed(UA_CONFIG_FIFO_RX_FIFO_MODE | ||
269 | | UA_CONFIG_FIFO_TX_FIFO_MODE | UA_CONFIG_FIFO_RX_THRESH, | ||
270 | port->membase + UA_CONFIG_FIFO); | ||
271 | writeb_relaxed(UA_STATUS_FIFO_RX_INT_ALMOST, | ||
272 | port->membase + UA_STATUS_FIFO); | ||
273 | writeb_relaxed(UA_CONTROL_RX_ENABLE | UA_CONTROL_TX_ENABLE, | ||
274 | port->membase + UA_CONTROL); | ||
275 | writeb_relaxed(UA_INT_TX | UA_INT_RX, | ||
276 | port->membase + UA_INT_ENABLE); | ||
277 | |||
278 | schedule_delayed_work(&dp->rx_poll_work, msecs_to_jiffies(100)); | ||
279 | |||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | static void digicolor_uart_shutdown(struct uart_port *port) | ||
284 | { | ||
285 | struct digicolor_port *dp = | ||
286 | container_of(port, struct digicolor_port, port); | ||
287 | |||
288 | writeb_relaxed(0, port->membase + UA_ENABLE); | ||
289 | cancel_delayed_work_sync(&dp->rx_poll_work); | ||
290 | } | ||
291 | |||
292 | static void digicolor_uart_set_termios(struct uart_port *port, | ||
293 | struct ktermios *termios, | ||
294 | struct ktermios *old) | ||
295 | { | ||
296 | unsigned int baud, divisor; | ||
297 | u8 config = 0; | ||
298 | unsigned long flags; | ||
299 | |||
300 | /* Mask termios capabilities we don't support */ | ||
301 | termios->c_cflag &= ~CMSPAR; | ||
302 | termios->c_iflag &= ~(BRKINT | IGNBRK); | ||
303 | |||
304 | /* Limit baud rates so that we don't need the fractional divider */ | ||
305 | baud = uart_get_baud_rate(port, termios, old, | ||
306 | port->uartclk / (0x10000*16), | ||
307 | port->uartclk / 256); | ||
308 | divisor = uart_get_divisor(port, baud) - 1; | ||
309 | |||
310 | switch (termios->c_cflag & CSIZE) { | ||
311 | case CS7: | ||
312 | break; | ||
313 | case CS8: | ||
314 | default: | ||
315 | config |= UA_CONFIG_CHAR_LEN; | ||
316 | break; | ||
317 | } | ||
318 | |||
319 | if (termios->c_cflag & CSTOPB) | ||
320 | config |= UA_CONFIG_STOP_BITS; | ||
321 | |||
322 | if (termios->c_cflag & PARENB) { | ||
323 | config |= UA_CONFIG_PARITY; | ||
324 | if (termios->c_cflag & PARODD) | ||
325 | config |= UA_CONFIG_ODD_PARITY; | ||
326 | } | ||
327 | |||
328 | /* Set read status mask */ | ||
329 | port->read_status_mask = UA_STATUS_OVERRUN_ERR; | ||
330 | if (termios->c_iflag & INPCK) | ||
331 | port->read_status_mask |= UA_STATUS_PARITY_ERR | ||
332 | | UA_STATUS_FRAME_ERR; | ||
333 | |||
334 | /* Set status ignore mask */ | ||
335 | port->ignore_status_mask = 0; | ||
336 | if (!(termios->c_cflag & CREAD)) | ||
337 | port->ignore_status_mask |= UA_STATUS_OVERRUN_ERR | ||
338 | | UA_STATUS_PARITY_ERR | UA_STATUS_FRAME_ERR; | ||
339 | |||
340 | spin_lock_irqsave(&port->lock, flags); | ||
341 | |||
342 | uart_update_timeout(port, termios->c_cflag, baud); | ||
343 | |||
344 | writeb_relaxed(config, port->membase + UA_CONFIG); | ||
345 | writeb_relaxed(divisor & 0xff, port->membase + UA_HBAUD_LO); | ||
346 | writeb_relaxed(divisor >> 8, port->membase + UA_HBAUD_HI); | ||
347 | |||
348 | spin_unlock_irqrestore(&port->lock, flags); | ||
349 | } | ||
350 | |||
351 | static const char *digicolor_uart_type(struct uart_port *port) | ||
352 | { | ||
353 | return (port->type == PORT_DIGICOLOR) ? "DIGICOLOR USART" : NULL; | ||
354 | } | ||
355 | |||
356 | static void digicolor_uart_config_port(struct uart_port *port, int flags) | ||
357 | { | ||
358 | if (flags & UART_CONFIG_TYPE) | ||
359 | port->type = PORT_DIGICOLOR; | ||
360 | } | ||
361 | |||
362 | static void digicolor_uart_release_port(struct uart_port *port) | ||
363 | { | ||
364 | } | ||
365 | |||
366 | static int digicolor_uart_request_port(struct uart_port *port) | ||
367 | { | ||
368 | return 0; | ||
369 | } | ||
370 | |||
371 | static const struct uart_ops digicolor_uart_ops = { | ||
372 | .tx_empty = digicolor_uart_tx_empty, | ||
373 | .set_mctrl = digicolor_uart_set_mctrl, | ||
374 | .get_mctrl = digicolor_uart_get_mctrl, | ||
375 | .stop_tx = digicolor_uart_stop_tx, | ||
376 | .start_tx = digicolor_uart_start_tx, | ||
377 | .stop_rx = digicolor_uart_stop_rx, | ||
378 | .break_ctl = digicolor_uart_break_ctl, | ||
379 | .startup = digicolor_uart_startup, | ||
380 | .shutdown = digicolor_uart_shutdown, | ||
381 | .set_termios = digicolor_uart_set_termios, | ||
382 | .type = digicolor_uart_type, | ||
383 | .config_port = digicolor_uart_config_port, | ||
384 | .release_port = digicolor_uart_release_port, | ||
385 | .request_port = digicolor_uart_request_port, | ||
386 | }; | ||
387 | |||
388 | static void digicolor_uart_console_putchar(struct uart_port *port, int ch) | ||
389 | { | ||
390 | while (digicolor_uart_tx_full(port)) | ||
391 | cpu_relax(); | ||
392 | |||
393 | writeb_relaxed(ch, port->membase + UA_EMI_REC); | ||
394 | } | ||
395 | |||
396 | static void digicolor_uart_console_write(struct console *co, const char *c, | ||
397 | unsigned n) | ||
398 | { | ||
399 | struct uart_port *port = digicolor_ports[co->index]; | ||
400 | u8 status; | ||
401 | unsigned long flags; | ||
402 | int locked = 1; | ||
403 | |||
404 | if (oops_in_progress) | ||
405 | locked = spin_trylock_irqsave(&port->lock, flags); | ||
406 | else | ||
407 | spin_lock_irqsave(&port->lock, flags); | ||
408 | |||
409 | uart_console_write(port, c, n, digicolor_uart_console_putchar); | ||
410 | |||
411 | if (locked) | ||
412 | spin_unlock_irqrestore(&port->lock, flags); | ||
413 | |||
414 | /* Wait for transmitter to become empty */ | ||
415 | do { | ||
416 | status = readb_relaxed(port->membase + UA_STATUS); | ||
417 | } while ((status & UA_STATUS_TX_READY) == 0); | ||
418 | } | ||
419 | |||
420 | static int digicolor_uart_console_setup(struct console *co, char *options) | ||
421 | { | ||
422 | int baud = 115200, bits = 8, parity = 'n', flow = 'n'; | ||
423 | struct uart_port *port; | ||
424 | |||
425 | if (co->index < 0 || co->index >= DIGICOLOR_USART_NR) | ||
426 | return -EINVAL; | ||
427 | |||
428 | port = digicolor_ports[co->index]; | ||
429 | if (!port) | ||
430 | return -ENODEV; | ||
431 | |||
432 | if (options) | ||
433 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
434 | |||
435 | return uart_set_options(port, co, baud, parity, bits, flow); | ||
436 | } | ||
437 | |||
438 | static struct console digicolor_console = { | ||
439 | .name = "ttyS", | ||
440 | .device = uart_console_device, | ||
441 | .write = digicolor_uart_console_write, | ||
442 | .setup = digicolor_uart_console_setup, | ||
443 | .flags = CON_PRINTBUFFER, | ||
444 | .index = -1, | ||
445 | }; | ||
446 | |||
447 | static struct uart_driver digicolor_uart = { | ||
448 | .driver_name = "digicolor-usart", | ||
449 | .dev_name = "ttyS", | ||
450 | .nr = DIGICOLOR_USART_NR, | ||
451 | }; | ||
452 | |||
453 | static int digicolor_uart_probe(struct platform_device *pdev) | ||
454 | { | ||
455 | struct device_node *np = pdev->dev.of_node; | ||
456 | int ret, index; | ||
457 | struct digicolor_port *dp; | ||
458 | struct resource *res; | ||
459 | struct clk *uart_clk; | ||
460 | |||
461 | if (!np) { | ||
462 | dev_err(&pdev->dev, "Missing device tree node\n"); | ||
463 | return -ENXIO; | ||
464 | } | ||
465 | |||
466 | index = of_alias_get_id(np, "serial"); | ||
467 | if (index < 0 || index >= DIGICOLOR_USART_NR) | ||
468 | return -EINVAL; | ||
469 | |||
470 | dp = devm_kzalloc(&pdev->dev, sizeof(*dp), GFP_KERNEL); | ||
471 | if (!dp) | ||
472 | return -ENOMEM; | ||
473 | |||
474 | uart_clk = devm_clk_get(&pdev->dev, NULL); | ||
475 | if (IS_ERR(uart_clk)) | ||
476 | return PTR_ERR(uart_clk); | ||
477 | |||
478 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
479 | dp->port.mapbase = res->start; | ||
480 | dp->port.membase = devm_ioremap_resource(&pdev->dev, res); | ||
481 | if (IS_ERR(dp->port.membase)) | ||
482 | return PTR_ERR(dp->port.membase); | ||
483 | |||
484 | dp->port.irq = platform_get_irq(pdev, 0); | ||
485 | if (IS_ERR_VALUE(dp->port.irq)) | ||
486 | return dp->port.irq; | ||
487 | |||
488 | dp->port.iotype = UPIO_MEM; | ||
489 | dp->port.uartclk = clk_get_rate(uart_clk); | ||
490 | dp->port.fifosize = 16; | ||
491 | dp->port.dev = &pdev->dev; | ||
492 | dp->port.ops = &digicolor_uart_ops; | ||
493 | dp->port.line = index; | ||
494 | dp->port.type = PORT_DIGICOLOR; | ||
495 | spin_lock_init(&dp->port.lock); | ||
496 | |||
497 | digicolor_ports[index] = &dp->port; | ||
498 | platform_set_drvdata(pdev, &dp->port); | ||
499 | |||
500 | INIT_DELAYED_WORK(&dp->rx_poll_work, digicolor_rx_poll); | ||
501 | |||
502 | ret = devm_request_irq(&pdev->dev, dp->port.irq, digicolor_uart_int, 0, | ||
503 | dev_name(&pdev->dev), &dp->port); | ||
504 | if (ret) | ||
505 | return ret; | ||
506 | |||
507 | return uart_add_one_port(&digicolor_uart, &dp->port); | ||
508 | } | ||
509 | |||
510 | static int digicolor_uart_remove(struct platform_device *pdev) | ||
511 | { | ||
512 | struct uart_port *port = platform_get_drvdata(pdev); | ||
513 | |||
514 | uart_remove_one_port(&digicolor_uart, port); | ||
515 | |||
516 | return 0; | ||
517 | } | ||
518 | |||
519 | static const struct of_device_id digicolor_uart_dt_ids[] = { | ||
520 | { .compatible = "cnxt,cx92755-usart", }, | ||
521 | { } | ||
522 | }; | ||
523 | MODULE_DEVICE_TABLE(of, digicolor_uart_dt_ids); | ||
524 | |||
525 | static struct platform_driver digicolor_uart_platform = { | ||
526 | .driver = { | ||
527 | .name = "digicolor-usart", | ||
528 | .of_match_table = of_match_ptr(digicolor_uart_dt_ids), | ||
529 | }, | ||
530 | .probe = digicolor_uart_probe, | ||
531 | .remove = digicolor_uart_remove, | ||
532 | }; | ||
533 | |||
534 | static int __init digicolor_uart_init(void) | ||
535 | { | ||
536 | int ret; | ||
537 | |||
538 | if (IS_ENABLED(CONFIG_SERIAL_CONEXANT_DIGICOLOR_CONSOLE)) { | ||
539 | digicolor_uart.cons = &digicolor_console; | ||
540 | digicolor_console.data = &digicolor_uart; | ||
541 | } | ||
542 | |||
543 | ret = uart_register_driver(&digicolor_uart); | ||
544 | if (ret) | ||
545 | return ret; | ||
546 | |||
547 | return platform_driver_register(&digicolor_uart_platform); | ||
548 | } | ||
549 | module_init(digicolor_uart_init); | ||
550 | |||
551 | static void __exit digicolor_uart_exit(void) | ||
552 | { | ||
553 | platform_driver_unregister(&digicolor_uart_platform); | ||
554 | uart_unregister_driver(&digicolor_uart); | ||
555 | } | ||
556 | module_exit(digicolor_uart_exit); | ||
557 | |||
558 | MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>"); | ||
559 | MODULE_DESCRIPTION("Conexant Digicolor USART serial driver"); | ||
560 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/tty/serial/etraxfs-uart.c b/drivers/tty/serial/etraxfs-uart.c new file mode 100644 index 000000000000..a57301a6fe42 --- /dev/null +++ b/drivers/tty/serial/etraxfs-uart.c | |||
@@ -0,0 +1,996 @@ | |||
1 | #include <linux/module.h> | ||
2 | #include <linux/init.h> | ||
3 | #include <linux/console.h> | ||
4 | #include <linux/platform_device.h> | ||
5 | #include <linux/serial_core.h> | ||
6 | #include <linux/tty_flip.h> | ||
7 | #include <linux/of.h> | ||
8 | #include <linux/gpio.h> | ||
9 | #include <linux/of_irq.h> | ||
10 | #include <linux/of_address.h> | ||
11 | #include <hwregs/ser_defs.h> | ||
12 | |||
13 | #define DRV_NAME "etraxfs-uart" | ||
14 | #define UART_NR CONFIG_ETRAX_SERIAL_PORTS | ||
15 | |||
16 | #define MODIFY_REG(instance, reg, var) \ | ||
17 | do { \ | ||
18 | if (REG_RD_INT(ser, instance, reg) != \ | ||
19 | REG_TYPE_CONV(int, reg_ser_##reg, var)) \ | ||
20 | REG_WR(ser, instance, reg, var); \ | ||
21 | } while (0) | ||
22 | |||
23 | struct uart_cris_port { | ||
24 | struct uart_port port; | ||
25 | |||
26 | int initialized; | ||
27 | int irq; | ||
28 | |||
29 | void __iomem *regi_ser; | ||
30 | |||
31 | struct gpio_desc *dtr_pin; | ||
32 | struct gpio_desc *dsr_pin; | ||
33 | struct gpio_desc *ri_pin; | ||
34 | struct gpio_desc *cd_pin; | ||
35 | |||
36 | int write_ongoing; | ||
37 | }; | ||
38 | |||
39 | static struct uart_driver etraxfs_uart_driver; | ||
40 | static struct uart_port *console_port; | ||
41 | static int console_baud = 115200; | ||
42 | static struct uart_cris_port *etraxfs_uart_ports[UART_NR]; | ||
43 | |||
44 | static void cris_serial_port_init(struct uart_port *port, int line); | ||
45 | static void etraxfs_uart_stop_rx(struct uart_port *port); | ||
46 | static inline void etraxfs_uart_start_tx_bottom(struct uart_port *port); | ||
47 | |||
48 | #ifdef CONFIG_SERIAL_ETRAXFS_CONSOLE | ||
49 | static void | ||
50 | cris_console_write(struct console *co, const char *s, unsigned int count) | ||
51 | { | ||
52 | struct uart_cris_port *up; | ||
53 | int i; | ||
54 | reg_ser_r_stat_din stat; | ||
55 | reg_ser_rw_tr_dma_en tr_dma_en, old; | ||
56 | |||
57 | up = etraxfs_uart_ports[co->index]; | ||
58 | |||
59 | if (!up) | ||
60 | return; | ||
61 | |||
62 | /* Switch to manual mode. */ | ||
63 | tr_dma_en = old = REG_RD(ser, up->regi_ser, rw_tr_dma_en); | ||
64 | if (tr_dma_en.en == regk_ser_yes) { | ||
65 | tr_dma_en.en = regk_ser_no; | ||
66 | REG_WR(ser, up->regi_ser, rw_tr_dma_en, tr_dma_en); | ||
67 | } | ||
68 | |||
69 | /* Send data. */ | ||
70 | for (i = 0; i < count; i++) { | ||
71 | /* LF -> CRLF */ | ||
72 | if (s[i] == '\n') { | ||
73 | do { | ||
74 | stat = REG_RD(ser, up->regi_ser, r_stat_din); | ||
75 | } while (!stat.tr_rdy); | ||
76 | REG_WR_INT(ser, up->regi_ser, rw_dout, '\r'); | ||
77 | } | ||
78 | /* Wait until transmitter is ready and send. */ | ||
79 | do { | ||
80 | stat = REG_RD(ser, up->regi_ser, r_stat_din); | ||
81 | } while (!stat.tr_rdy); | ||
82 | REG_WR_INT(ser, up->regi_ser, rw_dout, s[i]); | ||
83 | } | ||
84 | |||
85 | /* Restore mode. */ | ||
86 | if (tr_dma_en.en != old.en) | ||
87 | REG_WR(ser, up->regi_ser, rw_tr_dma_en, old); | ||
88 | } | ||
89 | |||
90 | static int __init | ||
91 | cris_console_setup(struct console *co, char *options) | ||
92 | { | ||
93 | struct uart_port *port; | ||
94 | int baud = 115200; | ||
95 | int bits = 8; | ||
96 | int parity = 'n'; | ||
97 | int flow = 'n'; | ||
98 | |||
99 | if (co->index < 0 || co->index >= UART_NR) | ||
100 | co->index = 0; | ||
101 | port = &etraxfs_uart_ports[co->index]->port; | ||
102 | console_port = port; | ||
103 | |||
104 | co->flags |= CON_CONSDEV; | ||
105 | |||
106 | if (options) | ||
107 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
108 | console_baud = baud; | ||
109 | cris_serial_port_init(port, co->index); | ||
110 | uart_set_options(port, co, baud, parity, bits, flow); | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static struct tty_driver *cris_console_device(struct console *co, int *index) | ||
116 | { | ||
117 | struct uart_driver *p = co->data; | ||
118 | *index = co->index; | ||
119 | return p->tty_driver; | ||
120 | } | ||
121 | |||
122 | static struct console cris_console = { | ||
123 | .name = "ttyS", | ||
124 | .write = cris_console_write, | ||
125 | .device = cris_console_device, | ||
126 | .setup = cris_console_setup, | ||
127 | .flags = CON_PRINTBUFFER, | ||
128 | .index = -1, | ||
129 | .data = &etraxfs_uart_driver, | ||
130 | }; | ||
131 | #endif /* CONFIG_SERIAL_ETRAXFS_CONSOLE */ | ||
132 | |||
133 | static struct uart_driver etraxfs_uart_driver = { | ||
134 | .owner = THIS_MODULE, | ||
135 | .driver_name = "serial", | ||
136 | .dev_name = "ttyS", | ||
137 | .major = TTY_MAJOR, | ||
138 | .minor = 64, | ||
139 | .nr = UART_NR, | ||
140 | #ifdef CONFIG_SERIAL_ETRAXFS_CONSOLE | ||
141 | .cons = &cris_console, | ||
142 | #endif /* CONFIG_SERIAL_ETRAXFS_CONSOLE */ | ||
143 | }; | ||
144 | |||
145 | static inline int crisv32_serial_get_rts(struct uart_cris_port *up) | ||
146 | { | ||
147 | void __iomem *regi_ser = up->regi_ser; | ||
148 | /* | ||
149 | * Return what the user has controlled rts to or | ||
150 | * what the pin is? (if auto_rts is used it differs during tx) | ||
151 | */ | ||
152 | reg_ser_r_stat_din rstat = REG_RD(ser, regi_ser, r_stat_din); | ||
153 | |||
154 | return !(rstat.rts_n == regk_ser_active); | ||
155 | } | ||
156 | |||
157 | /* | ||
158 | * A set = 0 means 3.3V on the pin, bitvalue: 0=active, 1=inactive | ||
159 | * 0=0V , 1=3.3V | ||
160 | */ | ||
161 | static inline void crisv32_serial_set_rts(struct uart_cris_port *up, | ||
162 | int set, int force) | ||
163 | { | ||
164 | void __iomem *regi_ser = up->regi_ser; | ||
165 | |||
166 | unsigned long flags; | ||
167 | reg_ser_rw_rec_ctrl rec_ctrl; | ||
168 | |||
169 | local_irq_save(flags); | ||
170 | rec_ctrl = REG_RD(ser, regi_ser, rw_rec_ctrl); | ||
171 | |||
172 | if (set) | ||
173 | rec_ctrl.rts_n = regk_ser_active; | ||
174 | else | ||
175 | rec_ctrl.rts_n = regk_ser_inactive; | ||
176 | REG_WR(ser, regi_ser, rw_rec_ctrl, rec_ctrl); | ||
177 | local_irq_restore(flags); | ||
178 | } | ||
179 | |||
180 | static inline int crisv32_serial_get_cts(struct uart_cris_port *up) | ||
181 | { | ||
182 | void __iomem *regi_ser = up->regi_ser; | ||
183 | reg_ser_r_stat_din rstat = REG_RD(ser, regi_ser, r_stat_din); | ||
184 | |||
185 | return (rstat.cts_n == regk_ser_active); | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | * Send a single character for XON/XOFF purposes. We do it in this separate | ||
190 | * function instead of the alternative support port.x_char, in the ...start_tx | ||
191 | * function, so we don't mix up this case with possibly enabling transmission | ||
192 | * of queued-up data (in case that's disabled after *receiving* an XOFF or | ||
193 | * negative CTS). This function is used for both DMA and non-DMA case; see HW | ||
194 | * docs specifically blessing sending characters manually when DMA for | ||
195 | * transmission is enabled and running. We may be asked to transmit despite | ||
196 | * the transmitter being disabled by a ..._stop_tx call so we need to enable | ||
197 | * it temporarily but restore the state afterwards. | ||
198 | */ | ||
199 | static void etraxfs_uart_send_xchar(struct uart_port *port, char ch) | ||
200 | { | ||
201 | struct uart_cris_port *up = (struct uart_cris_port *)port; | ||
202 | reg_ser_rw_dout dout = { .data = ch }; | ||
203 | reg_ser_rw_ack_intr ack_intr = { .tr_rdy = regk_ser_yes }; | ||
204 | reg_ser_r_stat_din rstat; | ||
205 | reg_ser_rw_tr_ctrl prev_tr_ctrl, tr_ctrl; | ||
206 | void __iomem *regi_ser = up->regi_ser; | ||
207 | unsigned long flags; | ||
208 | |||
209 | /* | ||
210 | * Wait for tr_rdy in case a character is already being output. Make | ||
211 | * sure we have integrity between the register reads and the writes | ||
212 | * below, but don't busy-wait with interrupts off and the port lock | ||
213 | * taken. | ||
214 | */ | ||
215 | spin_lock_irqsave(&port->lock, flags); | ||
216 | do { | ||
217 | spin_unlock_irqrestore(&port->lock, flags); | ||
218 | spin_lock_irqsave(&port->lock, flags); | ||
219 | prev_tr_ctrl = tr_ctrl = REG_RD(ser, regi_ser, rw_tr_ctrl); | ||
220 | rstat = REG_RD(ser, regi_ser, r_stat_din); | ||
221 | } while (!rstat.tr_rdy); | ||
222 | |||
223 | /* | ||
224 | * Ack an interrupt if one was just issued for the previous character | ||
225 | * that was output. This is required for non-DMA as the interrupt is | ||
226 | * used as the only indicator that the transmitter is ready and it | ||
227 | * isn't while this x_char is being transmitted. | ||
228 | */ | ||
229 | REG_WR(ser, regi_ser, rw_ack_intr, ack_intr); | ||
230 | |||
231 | /* Enable the transmitter in case it was disabled. */ | ||
232 | tr_ctrl.stop = 0; | ||
233 | REG_WR(ser, regi_ser, rw_tr_ctrl, tr_ctrl); | ||
234 | |||
235 | /* | ||
236 | * Finally, send the blessed character; nothing should stop it now, | ||
237 | * except for an xoff-detected state, which we'll handle below. | ||
238 | */ | ||
239 | REG_WR(ser, regi_ser, rw_dout, dout); | ||
240 | up->port.icount.tx++; | ||
241 | |||
242 | /* There might be an xoff state to clear. */ | ||
243 | rstat = REG_RD(ser, up->regi_ser, r_stat_din); | ||
244 | |||
245 | /* | ||
246 | * Clear any xoff state that *may* have been there to | ||
247 | * inhibit transmission of the character. | ||
248 | */ | ||
249 | if (rstat.xoff_detect) { | ||
250 | reg_ser_rw_xoff_clr xoff_clr = { .clr = 1 }; | ||
251 | reg_ser_rw_tr_dma_en tr_dma_en; | ||
252 | |||
253 | REG_WR(ser, regi_ser, rw_xoff_clr, xoff_clr); | ||
254 | tr_dma_en = REG_RD(ser, regi_ser, rw_tr_dma_en); | ||
255 | |||
256 | /* | ||
257 | * If we had an xoff state but cleared it, instead sneak in a | ||
258 | * disabled state for the transmitter, after the character we | ||
259 | * sent. Thus we keep the port disabled, just as if the xoff | ||
260 | * state was still in effect (or actually, as if stop_tx had | ||
261 | * been called, as we stop DMA too). | ||
262 | */ | ||
263 | prev_tr_ctrl.stop = 1; | ||
264 | |||
265 | tr_dma_en.en = 0; | ||
266 | REG_WR(ser, regi_ser, rw_tr_dma_en, tr_dma_en); | ||
267 | } | ||
268 | |||
269 | /* Restore "previous" enabled/disabled state of the transmitter. */ | ||
270 | REG_WR(ser, regi_ser, rw_tr_ctrl, prev_tr_ctrl); | ||
271 | |||
272 | spin_unlock_irqrestore(&port->lock, flags); | ||
273 | } | ||
274 | |||
275 | /* | ||
276 | * Do not spin_lock_irqsave or disable interrupts by other means here; it's | ||
277 | * already done by the caller. | ||
278 | */ | ||
279 | static void etraxfs_uart_start_tx(struct uart_port *port) | ||
280 | { | ||
281 | struct uart_cris_port *up = (struct uart_cris_port *)port; | ||
282 | |||
283 | /* we have already done below if a write is ongoing */ | ||
284 | if (up->write_ongoing) | ||
285 | return; | ||
286 | |||
287 | /* Signal that write is ongoing */ | ||
288 | up->write_ongoing = 1; | ||
289 | |||
290 | etraxfs_uart_start_tx_bottom(port); | ||
291 | } | ||
292 | |||
293 | static inline void etraxfs_uart_start_tx_bottom(struct uart_port *port) | ||
294 | { | ||
295 | struct uart_cris_port *up = (struct uart_cris_port *)port; | ||
296 | void __iomem *regi_ser = up->regi_ser; | ||
297 | reg_ser_rw_tr_ctrl tr_ctrl; | ||
298 | reg_ser_rw_intr_mask intr_mask; | ||
299 | |||
300 | tr_ctrl = REG_RD(ser, regi_ser, rw_tr_ctrl); | ||
301 | tr_ctrl.stop = regk_ser_no; | ||
302 | REG_WR(ser, regi_ser, rw_tr_ctrl, tr_ctrl); | ||
303 | intr_mask = REG_RD(ser, regi_ser, rw_intr_mask); | ||
304 | intr_mask.tr_rdy = regk_ser_yes; | ||
305 | REG_WR(ser, regi_ser, rw_intr_mask, intr_mask); | ||
306 | } | ||
307 | |||
308 | /* | ||
309 | * This function handles both the DMA and non-DMA case by ordering the | ||
310 | * transmitter to stop of after the current character. We don't need to wait | ||
311 | * for any such character to be completely transmitted; we do that where it | ||
312 | * matters, like in etraxfs_uart_set_termios. Don't busy-wait here; see | ||
313 | * Documentation/serial/driver: this function is called within | ||
314 | * spin_lock_irq{,save} and thus separate ones would be disastrous (when SMP). | ||
315 | * There's no documented need to set the txd pin to any particular value; | ||
316 | * break setting is controlled solely by etraxfs_uart_break_ctl. | ||
317 | */ | ||
318 | static void etraxfs_uart_stop_tx(struct uart_port *port) | ||
319 | { | ||
320 | struct uart_cris_port *up = (struct uart_cris_port *)port; | ||
321 | void __iomem *regi_ser = up->regi_ser; | ||
322 | reg_ser_rw_tr_ctrl tr_ctrl; | ||
323 | reg_ser_rw_intr_mask intr_mask; | ||
324 | reg_ser_rw_tr_dma_en tr_dma_en = {0}; | ||
325 | reg_ser_rw_xoff_clr xoff_clr = {0}; | ||
326 | |||
327 | /* | ||
328 | * For the non-DMA case, we'd get a tr_rdy interrupt that we're not | ||
329 | * interested in as we're not transmitting any characters. For the | ||
330 | * DMA case, that interrupt is already turned off, but no reason to | ||
331 | * waste code on conditionals here. | ||
332 | */ | ||
333 | intr_mask = REG_RD(ser, regi_ser, rw_intr_mask); | ||
334 | intr_mask.tr_rdy = regk_ser_no; | ||
335 | REG_WR(ser, regi_ser, rw_intr_mask, intr_mask); | ||
336 | |||
337 | tr_ctrl = REG_RD(ser, regi_ser, rw_tr_ctrl); | ||
338 | tr_ctrl.stop = 1; | ||
339 | REG_WR(ser, regi_ser, rw_tr_ctrl, tr_ctrl); | ||
340 | |||
341 | /* | ||
342 | * Always clear possible hardware xoff-detected state here, no need to | ||
343 | * unnecessary consider mctrl settings and when they change. We clear | ||
344 | * it here rather than in start_tx: both functions are called as the | ||
345 | * effect of XOFF processing, but start_tx is also called when upper | ||
346 | * levels tell the driver that there are more characters to send, so | ||
347 | * avoid adding code there. | ||
348 | */ | ||
349 | xoff_clr.clr = 1; | ||
350 | REG_WR(ser, regi_ser, rw_xoff_clr, xoff_clr); | ||
351 | |||
352 | /* | ||
353 | * Disable transmitter DMA, so that if we're in XON/XOFF, we can send | ||
354 | * those single characters without also giving go-ahead for queued up | ||
355 | * DMA data. | ||
356 | */ | ||
357 | tr_dma_en.en = 0; | ||
358 | REG_WR(ser, regi_ser, rw_tr_dma_en, tr_dma_en); | ||
359 | |||
360 | /* | ||
361 | * Make sure that write_ongoing is reset when stopping tx. | ||
362 | */ | ||
363 | up->write_ongoing = 0; | ||
364 | } | ||
365 | |||
366 | static void etraxfs_uart_stop_rx(struct uart_port *port) | ||
367 | { | ||
368 | struct uart_cris_port *up = (struct uart_cris_port *)port; | ||
369 | void __iomem *regi_ser = up->regi_ser; | ||
370 | reg_ser_rw_rec_ctrl rec_ctrl = REG_RD(ser, regi_ser, rw_rec_ctrl); | ||
371 | |||
372 | rec_ctrl.en = regk_ser_no; | ||
373 | REG_WR(ser, regi_ser, rw_rec_ctrl, rec_ctrl); | ||
374 | } | ||
375 | |||
376 | static void etraxfs_uart_enable_ms(struct uart_port *port) | ||
377 | { | ||
378 | } | ||
379 | |||
380 | static void check_modem_status(struct uart_cris_port *up) | ||
381 | { | ||
382 | } | ||
383 | |||
384 | static unsigned int etraxfs_uart_tx_empty(struct uart_port *port) | ||
385 | { | ||
386 | struct uart_cris_port *up = (struct uart_cris_port *)port; | ||
387 | unsigned long flags; | ||
388 | unsigned int ret; | ||
389 | reg_ser_r_stat_din rstat = {0}; | ||
390 | |||
391 | spin_lock_irqsave(&up->port.lock, flags); | ||
392 | |||
393 | rstat = REG_RD(ser, up->regi_ser, r_stat_din); | ||
394 | ret = rstat.tr_empty ? TIOCSER_TEMT : 0; | ||
395 | |||
396 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
397 | return ret; | ||
398 | } | ||
399 | static unsigned int etraxfs_uart_get_mctrl(struct uart_port *port) | ||
400 | { | ||
401 | struct uart_cris_port *up = (struct uart_cris_port *)port; | ||
402 | unsigned int ret; | ||
403 | |||
404 | ret = 0; | ||
405 | if (crisv32_serial_get_rts(up)) | ||
406 | ret |= TIOCM_RTS; | ||
407 | /* DTR is active low */ | ||
408 | if (up->dtr_pin && !gpiod_get_raw_value(up->dtr_pin)) | ||
409 | ret |= TIOCM_DTR; | ||
410 | /* CD is active low */ | ||
411 | if (up->cd_pin && !gpiod_get_raw_value(up->cd_pin)) | ||
412 | ret |= TIOCM_CD; | ||
413 | /* RI is active low */ | ||
414 | if (up->ri_pin && !gpiod_get_raw_value(up->ri_pin)) | ||
415 | ret |= TIOCM_RI; | ||
416 | /* DSR is active low */ | ||
417 | if (up->dsr_pin && !gpiod_get_raw_value(up->dsr_pin)) | ||
418 | ret |= TIOCM_DSR; | ||
419 | if (crisv32_serial_get_cts(up)) | ||
420 | ret |= TIOCM_CTS; | ||
421 | return ret; | ||
422 | } | ||
423 | |||
424 | static void etraxfs_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
425 | { | ||
426 | struct uart_cris_port *up = (struct uart_cris_port *)port; | ||
427 | |||
428 | crisv32_serial_set_rts(up, mctrl & TIOCM_RTS ? 1 : 0, 0); | ||
429 | /* DTR is active low */ | ||
430 | if (up->dtr_pin) | ||
431 | gpiod_set_raw_value(up->dtr_pin, mctrl & TIOCM_DTR ? 0 : 1); | ||
432 | /* RI is active low */ | ||
433 | if (up->ri_pin) | ||
434 | gpiod_set_raw_value(up->ri_pin, mctrl & TIOCM_RNG ? 0 : 1); | ||
435 | /* CD is active low */ | ||
436 | if (up->cd_pin) | ||
437 | gpiod_set_raw_value(up->cd_pin, mctrl & TIOCM_CD ? 0 : 1); | ||
438 | } | ||
439 | |||
440 | static void etraxfs_uart_break_ctl(struct uart_port *port, int break_state) | ||
441 | { | ||
442 | struct uart_cris_port *up = (struct uart_cris_port *)port; | ||
443 | unsigned long flags; | ||
444 | reg_ser_rw_tr_ctrl tr_ctrl; | ||
445 | reg_ser_rw_tr_dma_en tr_dma_en; | ||
446 | reg_ser_rw_intr_mask intr_mask; | ||
447 | |||
448 | spin_lock_irqsave(&up->port.lock, flags); | ||
449 | tr_ctrl = REG_RD(ser, up->regi_ser, rw_tr_ctrl); | ||
450 | tr_dma_en = REG_RD(ser, up->regi_ser, rw_tr_dma_en); | ||
451 | intr_mask = REG_RD(ser, up->regi_ser, rw_intr_mask); | ||
452 | |||
453 | if (break_state != 0) { /* Send break */ | ||
454 | /* | ||
455 | * We need to disable DMA (if used) or tr_rdy interrupts if no | ||
456 | * DMA. No need to make this conditional on use of DMA; | ||
457 | * disabling will be a no-op for the other mode. | ||
458 | */ | ||
459 | intr_mask.tr_rdy = regk_ser_no; | ||
460 | tr_dma_en.en = 0; | ||
461 | |||
462 | /* | ||
463 | * Stop transmission and set the txd pin to 0 after the | ||
464 | * current character. The txd setting will take effect after | ||
465 | * any current transmission has completed. | ||
466 | */ | ||
467 | tr_ctrl.stop = 1; | ||
468 | tr_ctrl.txd = 0; | ||
469 | } else { | ||
470 | /* Re-enable the serial interrupt. */ | ||
471 | intr_mask.tr_rdy = regk_ser_yes; | ||
472 | |||
473 | tr_ctrl.stop = 0; | ||
474 | tr_ctrl.txd = 1; | ||
475 | } | ||
476 | REG_WR(ser, up->regi_ser, rw_tr_ctrl, tr_ctrl); | ||
477 | REG_WR(ser, up->regi_ser, rw_tr_dma_en, tr_dma_en); | ||
478 | REG_WR(ser, up->regi_ser, rw_intr_mask, intr_mask); | ||
479 | |||
480 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
481 | } | ||
482 | |||
483 | static void | ||
484 | transmit_chars_no_dma(struct uart_cris_port *up) | ||
485 | { | ||
486 | int max_count; | ||
487 | struct circ_buf *xmit = &up->port.state->xmit; | ||
488 | |||
489 | void __iomem *regi_ser = up->regi_ser; | ||
490 | reg_ser_r_stat_din rstat; | ||
491 | reg_ser_rw_ack_intr ack_intr = { .tr_rdy = regk_ser_yes }; | ||
492 | |||
493 | if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { | ||
494 | /* No more to send, so disable the interrupt. */ | ||
495 | reg_ser_rw_intr_mask intr_mask; | ||
496 | |||
497 | intr_mask = REG_RD(ser, regi_ser, rw_intr_mask); | ||
498 | intr_mask.tr_rdy = 0; | ||
499 | intr_mask.tr_empty = 0; | ||
500 | REG_WR(ser, regi_ser, rw_intr_mask, intr_mask); | ||
501 | up->write_ongoing = 0; | ||
502 | return; | ||
503 | } | ||
504 | |||
505 | /* If the serport is fast, we send up to max_count bytes before | ||
506 | exiting the loop. */ | ||
507 | max_count = 64; | ||
508 | do { | ||
509 | reg_ser_rw_dout dout = { .data = xmit->buf[xmit->tail] }; | ||
510 | |||
511 | REG_WR(ser, regi_ser, rw_dout, dout); | ||
512 | REG_WR(ser, regi_ser, rw_ack_intr, ack_intr); | ||
513 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1); | ||
514 | up->port.icount.tx++; | ||
515 | if (xmit->head == xmit->tail) | ||
516 | break; | ||
517 | rstat = REG_RD(ser, regi_ser, r_stat_din); | ||
518 | } while ((--max_count > 0) && rstat.tr_rdy); | ||
519 | |||
520 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
521 | uart_write_wakeup(&up->port); | ||
522 | } | ||
523 | |||
524 | static void receive_chars_no_dma(struct uart_cris_port *up) | ||
525 | { | ||
526 | reg_ser_rs_stat_din stat_din; | ||
527 | reg_ser_r_stat_din rstat; | ||
528 | struct tty_port *port; | ||
529 | struct uart_icount *icount; | ||
530 | int max_count = 16; | ||
531 | char flag; | ||
532 | reg_ser_rw_ack_intr ack_intr = { 0 }; | ||
533 | |||
534 | rstat = REG_RD(ser, up->regi_ser, r_stat_din); | ||
535 | icount = &up->port.icount; | ||
536 | port = &up->port.state->port; | ||
537 | |||
538 | do { | ||
539 | stat_din = REG_RD(ser, up->regi_ser, rs_stat_din); | ||
540 | |||
541 | flag = TTY_NORMAL; | ||
542 | ack_intr.dav = 1; | ||
543 | REG_WR(ser, up->regi_ser, rw_ack_intr, ack_intr); | ||
544 | icount->rx++; | ||
545 | |||
546 | if (stat_din.framing_err | stat_din.par_err | stat_din.orun) { | ||
547 | if (stat_din.data == 0x00 && | ||
548 | stat_din.framing_err) { | ||
549 | /* Most likely a break. */ | ||
550 | flag = TTY_BREAK; | ||
551 | icount->brk++; | ||
552 | } else if (stat_din.par_err) { | ||
553 | flag = TTY_PARITY; | ||
554 | icount->parity++; | ||
555 | } else if (stat_din.orun) { | ||
556 | flag = TTY_OVERRUN; | ||
557 | icount->overrun++; | ||
558 | } else if (stat_din.framing_err) { | ||
559 | flag = TTY_FRAME; | ||
560 | icount->frame++; | ||
561 | } | ||
562 | } | ||
563 | |||
564 | /* | ||
565 | * If this becomes important, we probably *could* handle this | ||
566 | * gracefully by keeping track of the unhandled character. | ||
567 | */ | ||
568 | if (!tty_insert_flip_char(port, stat_din.data, flag)) | ||
569 | panic("%s: No tty buffer space", __func__); | ||
570 | rstat = REG_RD(ser, up->regi_ser, r_stat_din); | ||
571 | } while (rstat.dav && (max_count-- > 0)); | ||
572 | spin_unlock(&up->port.lock); | ||
573 | tty_flip_buffer_push(port); | ||
574 | spin_lock(&up->port.lock); | ||
575 | } | ||
576 | |||
577 | static irqreturn_t | ||
578 | ser_interrupt(int irq, void *dev_id) | ||
579 | { | ||
580 | struct uart_cris_port *up = (struct uart_cris_port *)dev_id; | ||
581 | void __iomem *regi_ser; | ||
582 | int handled = 0; | ||
583 | |||
584 | spin_lock(&up->port.lock); | ||
585 | |||
586 | regi_ser = up->regi_ser; | ||
587 | |||
588 | if (regi_ser) { | ||
589 | reg_ser_r_masked_intr masked_intr; | ||
590 | |||
591 | masked_intr = REG_RD(ser, regi_ser, r_masked_intr); | ||
592 | /* | ||
593 | * Check what interrupts are active before taking | ||
594 | * actions. If DMA is used the interrupt shouldn't | ||
595 | * be enabled. | ||
596 | */ | ||
597 | if (masked_intr.dav) { | ||
598 | receive_chars_no_dma(up); | ||
599 | handled = 1; | ||
600 | } | ||
601 | check_modem_status(up); | ||
602 | |||
603 | if (masked_intr.tr_rdy) { | ||
604 | transmit_chars_no_dma(up); | ||
605 | handled = 1; | ||
606 | } | ||
607 | } | ||
608 | spin_unlock(&up->port.lock); | ||
609 | return IRQ_RETVAL(handled); | ||
610 | } | ||
611 | |||
612 | #ifdef CONFIG_CONSOLE_POLL | ||
613 | static int etraxfs_uart_get_poll_char(struct uart_port *port) | ||
614 | { | ||
615 | reg_ser_rs_stat_din stat; | ||
616 | reg_ser_rw_ack_intr ack_intr = { 0 }; | ||
617 | struct uart_cris_port *up = (struct uart_cris_port *)port; | ||
618 | |||
619 | do { | ||
620 | stat = REG_RD(ser, up->regi_ser, rs_stat_din); | ||
621 | } while (!stat.dav); | ||
622 | |||
623 | /* Ack the data_avail interrupt. */ | ||
624 | ack_intr.dav = 1; | ||
625 | REG_WR(ser, up->regi_ser, rw_ack_intr, ack_intr); | ||
626 | |||
627 | return stat.data; | ||
628 | } | ||
629 | |||
630 | static void etraxfs_uart_put_poll_char(struct uart_port *port, | ||
631 | unsigned char c) | ||
632 | { | ||
633 | reg_ser_r_stat_din stat; | ||
634 | struct uart_cris_port *up = (struct uart_cris_port *)port; | ||
635 | |||
636 | do { | ||
637 | stat = REG_RD(ser, up->regi_ser, r_stat_din); | ||
638 | } while (!stat.tr_rdy); | ||
639 | REG_WR_INT(ser, up->regi_ser, rw_dout, c); | ||
640 | } | ||
641 | #endif /* CONFIG_CONSOLE_POLL */ | ||
642 | |||
643 | static int etraxfs_uart_startup(struct uart_port *port) | ||
644 | { | ||
645 | struct uart_cris_port *up = (struct uart_cris_port *)port; | ||
646 | unsigned long flags; | ||
647 | reg_ser_rw_intr_mask ser_intr_mask = {0}; | ||
648 | |||
649 | ser_intr_mask.dav = regk_ser_yes; | ||
650 | |||
651 | if (request_irq(etraxfs_uart_ports[port->line]->irq, ser_interrupt, | ||
652 | 0, DRV_NAME, etraxfs_uart_ports[port->line])) | ||
653 | panic("irq ser%d", port->line); | ||
654 | |||
655 | spin_lock_irqsave(&up->port.lock, flags); | ||
656 | |||
657 | REG_WR(ser, up->regi_ser, rw_intr_mask, ser_intr_mask); | ||
658 | |||
659 | etraxfs_uart_set_mctrl(&up->port, up->port.mctrl); | ||
660 | |||
661 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
662 | |||
663 | return 0; | ||
664 | } | ||
665 | |||
666 | static void etraxfs_uart_shutdown(struct uart_port *port) | ||
667 | { | ||
668 | struct uart_cris_port *up = (struct uart_cris_port *)port; | ||
669 | unsigned long flags; | ||
670 | |||
671 | spin_lock_irqsave(&up->port.lock, flags); | ||
672 | |||
673 | etraxfs_uart_stop_tx(port); | ||
674 | etraxfs_uart_stop_rx(port); | ||
675 | |||
676 | free_irq(etraxfs_uart_ports[port->line]->irq, | ||
677 | etraxfs_uart_ports[port->line]); | ||
678 | |||
679 | etraxfs_uart_set_mctrl(&up->port, up->port.mctrl); | ||
680 | |||
681 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
682 | |||
683 | } | ||
684 | |||
685 | static void | ||
686 | etraxfs_uart_set_termios(struct uart_port *port, struct ktermios *termios, | ||
687 | struct ktermios *old) | ||
688 | { | ||
689 | struct uart_cris_port *up = (struct uart_cris_port *)port; | ||
690 | unsigned long flags; | ||
691 | reg_ser_rw_xoff xoff; | ||
692 | reg_ser_rw_xoff_clr xoff_clr = {0}; | ||
693 | reg_ser_rw_tr_ctrl tx_ctrl = {0}; | ||
694 | reg_ser_rw_tr_dma_en tx_dma_en = {0}; | ||
695 | reg_ser_rw_rec_ctrl rx_ctrl = {0}; | ||
696 | reg_ser_rw_tr_baud_div tx_baud_div = {0}; | ||
697 | reg_ser_rw_rec_baud_div rx_baud_div = {0}; | ||
698 | int baud; | ||
699 | |||
700 | if (old && | ||
701 | termios->c_cflag == old->c_cflag && | ||
702 | termios->c_iflag == old->c_iflag) | ||
703 | return; | ||
704 | |||
705 | /* Tx: 8 bit, no/even parity, 1 stop bit, no cts. */ | ||
706 | tx_ctrl.base_freq = regk_ser_f29_493; | ||
707 | tx_ctrl.en = 0; | ||
708 | tx_ctrl.stop = 0; | ||
709 | tx_ctrl.auto_rts = regk_ser_no; | ||
710 | tx_ctrl.txd = 1; | ||
711 | tx_ctrl.auto_cts = 0; | ||
712 | /* Rx: 8 bit, no/even parity. */ | ||
713 | rx_ctrl.dma_err = regk_ser_stop; | ||
714 | rx_ctrl.sampling = regk_ser_majority; | ||
715 | rx_ctrl.timeout = 1; | ||
716 | |||
717 | rx_ctrl.rts_n = regk_ser_inactive; | ||
718 | |||
719 | /* Common for tx and rx: 8N1. */ | ||
720 | tx_ctrl.data_bits = regk_ser_bits8; | ||
721 | rx_ctrl.data_bits = regk_ser_bits8; | ||
722 | tx_ctrl.par = regk_ser_even; | ||
723 | rx_ctrl.par = regk_ser_even; | ||
724 | tx_ctrl.par_en = regk_ser_no; | ||
725 | rx_ctrl.par_en = regk_ser_no; | ||
726 | |||
727 | tx_ctrl.stop_bits = regk_ser_bits1; | ||
728 | |||
729 | /* | ||
730 | * Change baud-rate and write it to the hardware. | ||
731 | * | ||
732 | * baud_clock = base_freq / (divisor*8) | ||
733 | * divisor = base_freq / (baud_clock * 8) | ||
734 | * base_freq is either: | ||
735 | * off, ext, 29.493MHz, 32.000 MHz, 32.768 MHz or 100 MHz | ||
736 | * 20.493MHz is used for standard baudrates | ||
737 | */ | ||
738 | |||
739 | /* | ||
740 | * For the console port we keep the original baudrate here. Not very | ||
741 | * beautiful. | ||
742 | */ | ||
743 | if ((port != console_port) || old) | ||
744 | baud = uart_get_baud_rate(port, termios, old, 0, | ||
745 | port->uartclk / 8); | ||
746 | else | ||
747 | baud = console_baud; | ||
748 | |||
749 | tx_baud_div.div = 29493000 / (8 * baud); | ||
750 | /* Rx uses same as tx. */ | ||
751 | rx_baud_div.div = tx_baud_div.div; | ||
752 | rx_ctrl.base_freq = tx_ctrl.base_freq; | ||
753 | |||
754 | if ((termios->c_cflag & CSIZE) == CS7) { | ||
755 | /* Set 7 bit mode. */ | ||
756 | tx_ctrl.data_bits = regk_ser_bits7; | ||
757 | rx_ctrl.data_bits = regk_ser_bits7; | ||
758 | } | ||
759 | |||
760 | if (termios->c_cflag & CSTOPB) { | ||
761 | /* Set 2 stop bit mode. */ | ||
762 | tx_ctrl.stop_bits = regk_ser_bits2; | ||
763 | } | ||
764 | |||
765 | if (termios->c_cflag & PARENB) { | ||
766 | /* Enable parity. */ | ||
767 | tx_ctrl.par_en = regk_ser_yes; | ||
768 | rx_ctrl.par_en = regk_ser_yes; | ||
769 | } | ||
770 | |||
771 | if (termios->c_cflag & CMSPAR) { | ||
772 | if (termios->c_cflag & PARODD) { | ||
773 | /* Set mark parity if PARODD and CMSPAR. */ | ||
774 | tx_ctrl.par = regk_ser_mark; | ||
775 | rx_ctrl.par = regk_ser_mark; | ||
776 | } else { | ||
777 | tx_ctrl.par = regk_ser_space; | ||
778 | rx_ctrl.par = regk_ser_space; | ||
779 | } | ||
780 | } else { | ||
781 | if (termios->c_cflag & PARODD) { | ||
782 | /* Set odd parity. */ | ||
783 | tx_ctrl.par = regk_ser_odd; | ||
784 | rx_ctrl.par = regk_ser_odd; | ||
785 | } | ||
786 | } | ||
787 | |||
788 | if (termios->c_cflag & CRTSCTS) { | ||
789 | /* Enable automatic CTS handling. */ | ||
790 | tx_ctrl.auto_cts = regk_ser_yes; | ||
791 | } | ||
792 | |||
793 | /* Make sure the tx and rx are enabled. */ | ||
794 | tx_ctrl.en = regk_ser_yes; | ||
795 | rx_ctrl.en = regk_ser_yes; | ||
796 | |||
797 | spin_lock_irqsave(&port->lock, flags); | ||
798 | |||
799 | tx_dma_en.en = 0; | ||
800 | REG_WR(ser, up->regi_ser, rw_tr_dma_en, tx_dma_en); | ||
801 | |||
802 | /* Actually write the control regs (if modified) to the hardware. */ | ||
803 | uart_update_timeout(port, termios->c_cflag, port->uartclk/8); | ||
804 | MODIFY_REG(up->regi_ser, rw_rec_baud_div, rx_baud_div); | ||
805 | MODIFY_REG(up->regi_ser, rw_rec_ctrl, rx_ctrl); | ||
806 | |||
807 | MODIFY_REG(up->regi_ser, rw_tr_baud_div, tx_baud_div); | ||
808 | MODIFY_REG(up->regi_ser, rw_tr_ctrl, tx_ctrl); | ||
809 | |||
810 | tx_dma_en.en = 0; | ||
811 | REG_WR(ser, up->regi_ser, rw_tr_dma_en, tx_dma_en); | ||
812 | |||
813 | xoff = REG_RD(ser, up->regi_ser, rw_xoff); | ||
814 | |||
815 | if (up->port.state && up->port.state->port.tty && | ||
816 | (up->port.state->port.tty->termios.c_iflag & IXON)) { | ||
817 | xoff.chr = STOP_CHAR(up->port.state->port.tty); | ||
818 | xoff.automatic = regk_ser_yes; | ||
819 | } else | ||
820 | xoff.automatic = regk_ser_no; | ||
821 | |||
822 | MODIFY_REG(up->regi_ser, rw_xoff, xoff); | ||
823 | |||
824 | /* | ||
825 | * Make sure we don't start in an automatically shut-off state due to | ||
826 | * a previous early exit. | ||
827 | */ | ||
828 | xoff_clr.clr = 1; | ||
829 | REG_WR(ser, up->regi_ser, rw_xoff_clr, xoff_clr); | ||
830 | |||
831 | etraxfs_uart_set_mctrl(&up->port, up->port.mctrl); | ||
832 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
833 | } | ||
834 | |||
835 | static const char * | ||
836 | etraxfs_uart_type(struct uart_port *port) | ||
837 | { | ||
838 | return "CRISv32"; | ||
839 | } | ||
840 | |||
841 | static void etraxfs_uart_release_port(struct uart_port *port) | ||
842 | { | ||
843 | } | ||
844 | |||
845 | static int etraxfs_uart_request_port(struct uart_port *port) | ||
846 | { | ||
847 | return 0; | ||
848 | } | ||
849 | |||
850 | static void etraxfs_uart_config_port(struct uart_port *port, int flags) | ||
851 | { | ||
852 | struct uart_cris_port *up = (struct uart_cris_port *)port; | ||
853 | |||
854 | up->port.type = PORT_CRIS; | ||
855 | } | ||
856 | |||
857 | static const struct uart_ops etraxfs_uart_pops = { | ||
858 | .tx_empty = etraxfs_uart_tx_empty, | ||
859 | .set_mctrl = etraxfs_uart_set_mctrl, | ||
860 | .get_mctrl = etraxfs_uart_get_mctrl, | ||
861 | .stop_tx = etraxfs_uart_stop_tx, | ||
862 | .start_tx = etraxfs_uart_start_tx, | ||
863 | .send_xchar = etraxfs_uart_send_xchar, | ||
864 | .stop_rx = etraxfs_uart_stop_rx, | ||
865 | .enable_ms = etraxfs_uart_enable_ms, | ||
866 | .break_ctl = etraxfs_uart_break_ctl, | ||
867 | .startup = etraxfs_uart_startup, | ||
868 | .shutdown = etraxfs_uart_shutdown, | ||
869 | .set_termios = etraxfs_uart_set_termios, | ||
870 | .type = etraxfs_uart_type, | ||
871 | .release_port = etraxfs_uart_release_port, | ||
872 | .request_port = etraxfs_uart_request_port, | ||
873 | .config_port = etraxfs_uart_config_port, | ||
874 | #ifdef CONFIG_CONSOLE_POLL | ||
875 | .poll_get_char = etraxfs_uart_get_poll_char, | ||
876 | .poll_put_char = etraxfs_uart_put_poll_char, | ||
877 | #endif | ||
878 | }; | ||
879 | |||
880 | static void cris_serial_port_init(struct uart_port *port, int line) | ||
881 | { | ||
882 | struct uart_cris_port *up = (struct uart_cris_port *)port; | ||
883 | |||
884 | if (up->initialized) | ||
885 | return; | ||
886 | up->initialized = 1; | ||
887 | port->line = line; | ||
888 | spin_lock_init(&port->lock); | ||
889 | port->ops = &etraxfs_uart_pops; | ||
890 | port->irq = up->irq; | ||
891 | port->iobase = (unsigned long) up->regi_ser; | ||
892 | port->uartclk = 29493000; | ||
893 | |||
894 | /* | ||
895 | * We can't fit any more than 255 here (unsigned char), though | ||
896 | * actually UART_XMIT_SIZE characters could be pending output. | ||
897 | * At time of this writing, the definition of "fifosize" is here the | ||
898 | * amount of characters that can be pending output after a start_tx call | ||
899 | * until tx_empty returns 1: see serial_core.c:uart_wait_until_sent. | ||
900 | * This matters for timeout calculations unfortunately, but keeping | ||
901 | * larger amounts at the DMA wouldn't win much so let's just play nice. | ||
902 | */ | ||
903 | port->fifosize = 255; | ||
904 | port->flags = UPF_BOOT_AUTOCONF; | ||
905 | } | ||
906 | |||
907 | static int etraxfs_uart_probe(struct platform_device *pdev) | ||
908 | { | ||
909 | struct device_node *np = pdev->dev.of_node; | ||
910 | struct uart_cris_port *up; | ||
911 | int dev_id; | ||
912 | |||
913 | if (!np) | ||
914 | return -ENODEV; | ||
915 | |||
916 | dev_id = of_alias_get_id(np, "serial"); | ||
917 | if (dev_id < 0) | ||
918 | dev_id = 0; | ||
919 | |||
920 | if (dev_id >= UART_NR) | ||
921 | return -EINVAL; | ||
922 | |||
923 | if (etraxfs_uart_ports[dev_id]) | ||
924 | return -EBUSY; | ||
925 | |||
926 | up = devm_kzalloc(&pdev->dev, sizeof(struct uart_cris_port), | ||
927 | GFP_KERNEL); | ||
928 | if (!up) | ||
929 | return -ENOMEM; | ||
930 | |||
931 | up->irq = irq_of_parse_and_map(np, 0); | ||
932 | up->regi_ser = of_iomap(np, 0); | ||
933 | up->dtr_pin = devm_gpiod_get_optional(&pdev->dev, "dtr"); | ||
934 | up->dsr_pin = devm_gpiod_get_optional(&pdev->dev, "dsr"); | ||
935 | up->ri_pin = devm_gpiod_get_optional(&pdev->dev, "ri"); | ||
936 | up->cd_pin = devm_gpiod_get_optional(&pdev->dev, "cd"); | ||
937 | up->port.dev = &pdev->dev; | ||
938 | cris_serial_port_init(&up->port, dev_id); | ||
939 | |||
940 | etraxfs_uart_ports[dev_id] = up; | ||
941 | platform_set_drvdata(pdev, &up->port); | ||
942 | uart_add_one_port(&etraxfs_uart_driver, &up->port); | ||
943 | |||
944 | return 0; | ||
945 | } | ||
946 | |||
947 | static int etraxfs_uart_remove(struct platform_device *pdev) | ||
948 | { | ||
949 | struct uart_port *port; | ||
950 | |||
951 | port = platform_get_drvdata(pdev); | ||
952 | uart_remove_one_port(&etraxfs_uart_driver, port); | ||
953 | etraxfs_uart_ports[pdev->id] = NULL; | ||
954 | |||
955 | return 0; | ||
956 | } | ||
957 | |||
958 | static const struct of_device_id etraxfs_uart_dt_ids[] = { | ||
959 | { .compatible = "axis,etraxfs-uart" }, | ||
960 | { /* sentinel */ } | ||
961 | }; | ||
962 | |||
963 | MODULE_DEVICE_TABLE(of, etraxfs_uart_dt_ids); | ||
964 | |||
965 | static struct platform_driver etraxfs_uart_platform_driver = { | ||
966 | .driver = { | ||
967 | .name = DRV_NAME, | ||
968 | .of_match_table = of_match_ptr(etraxfs_uart_dt_ids), | ||
969 | }, | ||
970 | .probe = etraxfs_uart_probe, | ||
971 | .remove = etraxfs_uart_remove, | ||
972 | }; | ||
973 | |||
974 | static int __init etraxfs_uart_init(void) | ||
975 | { | ||
976 | int ret; | ||
977 | |||
978 | ret = uart_register_driver(&etraxfs_uart_driver); | ||
979 | if (ret) | ||
980 | return ret; | ||
981 | |||
982 | ret = platform_driver_register(&etraxfs_uart_platform_driver); | ||
983 | if (ret) | ||
984 | uart_unregister_driver(&etraxfs_uart_driver); | ||
985 | |||
986 | return ret; | ||
987 | } | ||
988 | |||
989 | static void __exit etraxfs_uart_exit(void) | ||
990 | { | ||
991 | platform_driver_unregister(&etraxfs_uart_platform_driver); | ||
992 | uart_unregister_driver(&etraxfs_uart_driver); | ||
993 | } | ||
994 | |||
995 | module_init(etraxfs_uart_init); | ||
996 | module_exit(etraxfs_uart_exit); | ||
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index e7cde3a9566d..b1893f3f88f1 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c | |||
@@ -237,7 +237,8 @@ struct lpuart_port { | |||
237 | unsigned int rxfifo_size; | 237 | unsigned int rxfifo_size; |
238 | bool lpuart32; | 238 | bool lpuart32; |
239 | 239 | ||
240 | bool lpuart_dma_use; | 240 | bool lpuart_dma_tx_use; |
241 | bool lpuart_dma_rx_use; | ||
241 | struct dma_chan *dma_tx_chan; | 242 | struct dma_chan *dma_tx_chan; |
242 | struct dma_chan *dma_rx_chan; | 243 | struct dma_chan *dma_rx_chan; |
243 | struct dma_async_tx_descriptor *dma_tx_desc; | 244 | struct dma_async_tx_descriptor *dma_tx_desc; |
@@ -454,6 +455,15 @@ static int lpuart_dma_rx(struct lpuart_port *sport) | |||
454 | return 0; | 455 | return 0; |
455 | } | 456 | } |
456 | 457 | ||
458 | static void lpuart_flush_buffer(struct uart_port *port) | ||
459 | { | ||
460 | struct lpuart_port *sport = container_of(port, struct lpuart_port, port); | ||
461 | if (sport->lpuart_dma_tx_use) { | ||
462 | dmaengine_terminate_all(sport->dma_tx_chan); | ||
463 | sport->dma_tx_in_progress = 0; | ||
464 | } | ||
465 | } | ||
466 | |||
457 | static void lpuart_dma_rx_complete(void *arg) | 467 | static void lpuart_dma_rx_complete(void *arg) |
458 | { | 468 | { |
459 | struct lpuart_port *sport = arg; | 469 | struct lpuart_port *sport = arg; |
@@ -461,6 +471,7 @@ static void lpuart_dma_rx_complete(void *arg) | |||
461 | unsigned long flags; | 471 | unsigned long flags; |
462 | 472 | ||
463 | async_tx_ack(sport->dma_rx_desc); | 473 | async_tx_ack(sport->dma_rx_desc); |
474 | mod_timer(&sport->lpuart_timer, jiffies + sport->dma_rx_timeout); | ||
464 | 475 | ||
465 | spin_lock_irqsave(&sport->port.lock, flags); | 476 | spin_lock_irqsave(&sport->port.lock, flags); |
466 | 477 | ||
@@ -506,9 +517,6 @@ static inline void lpuart_prepare_rx(struct lpuart_port *sport) | |||
506 | 517 | ||
507 | spin_lock_irqsave(&sport->port.lock, flags); | 518 | spin_lock_irqsave(&sport->port.lock, flags); |
508 | 519 | ||
509 | init_timer(&sport->lpuart_timer); | ||
510 | sport->lpuart_timer.function = lpuart_timer_func; | ||
511 | sport->lpuart_timer.data = (unsigned long)sport; | ||
512 | sport->lpuart_timer.expires = jiffies + sport->dma_rx_timeout; | 520 | sport->lpuart_timer.expires = jiffies + sport->dma_rx_timeout; |
513 | add_timer(&sport->lpuart_timer); | 521 | add_timer(&sport->lpuart_timer); |
514 | 522 | ||
@@ -571,7 +579,7 @@ static void lpuart_start_tx(struct uart_port *port) | |||
571 | temp = readb(port->membase + UARTCR2); | 579 | temp = readb(port->membase + UARTCR2); |
572 | writeb(temp | UARTCR2_TIE, port->membase + UARTCR2); | 580 | writeb(temp | UARTCR2_TIE, port->membase + UARTCR2); |
573 | 581 | ||
574 | if (sport->lpuart_dma_use) { | 582 | if (sport->lpuart_dma_tx_use) { |
575 | if (!uart_circ_empty(xmit) && !sport->dma_tx_in_progress) | 583 | if (!uart_circ_empty(xmit) && !sport->dma_tx_in_progress) |
576 | lpuart_prepare_tx(sport); | 584 | lpuart_prepare_tx(sport); |
577 | } else { | 585 | } else { |
@@ -758,19 +766,19 @@ out: | |||
758 | static irqreturn_t lpuart_int(int irq, void *dev_id) | 766 | static irqreturn_t lpuart_int(int irq, void *dev_id) |
759 | { | 767 | { |
760 | struct lpuart_port *sport = dev_id; | 768 | struct lpuart_port *sport = dev_id; |
761 | unsigned char sts; | 769 | unsigned char sts, crdma; |
762 | 770 | ||
763 | sts = readb(sport->port.membase + UARTSR1); | 771 | sts = readb(sport->port.membase + UARTSR1); |
772 | crdma = readb(sport->port.membase + UARTCR5); | ||
764 | 773 | ||
765 | if (sts & UARTSR1_RDRF) { | 774 | if (sts & UARTSR1_RDRF && !(crdma & UARTCR5_RDMAS)) { |
766 | if (sport->lpuart_dma_use) | 775 | if (sport->lpuart_dma_rx_use) |
767 | lpuart_prepare_rx(sport); | 776 | lpuart_prepare_rx(sport); |
768 | else | 777 | else |
769 | lpuart_rxint(irq, dev_id); | 778 | lpuart_rxint(irq, dev_id); |
770 | } | 779 | } |
771 | if (sts & UARTSR1_TDRE && | 780 | if (sts & UARTSR1_TDRE && !(crdma & UARTCR5_TDMAS)) { |
772 | !(readb(sport->port.membase + UARTCR5) & UARTCR5_TDMAS)) { | 781 | if (sport->lpuart_dma_tx_use) |
773 | if (sport->lpuart_dma_use) | ||
774 | lpuart_pio_tx(sport); | 782 | lpuart_pio_tx(sport); |
775 | else | 783 | else |
776 | lpuart_txint(irq, dev_id); | 784 | lpuart_txint(irq, dev_id); |
@@ -953,26 +961,17 @@ static int lpuart_dma_tx_request(struct uart_port *port) | |||
953 | { | 961 | { |
954 | struct lpuart_port *sport = container_of(port, | 962 | struct lpuart_port *sport = container_of(port, |
955 | struct lpuart_port, port); | 963 | struct lpuart_port, port); |
956 | struct dma_chan *tx_chan; | ||
957 | struct dma_slave_config dma_tx_sconfig; | 964 | struct dma_slave_config dma_tx_sconfig; |
958 | dma_addr_t dma_bus; | 965 | dma_addr_t dma_bus; |
959 | unsigned char *dma_buf; | 966 | unsigned char *dma_buf; |
960 | int ret; | 967 | int ret; |
961 | 968 | ||
962 | tx_chan = dma_request_slave_channel(sport->port.dev, "tx"); | 969 | dma_bus = dma_map_single(sport->dma_tx_chan->device->dev, |
963 | |||
964 | if (!tx_chan) { | ||
965 | dev_err(sport->port.dev, "Dma tx channel request failed!\n"); | ||
966 | return -ENODEV; | ||
967 | } | ||
968 | |||
969 | dma_bus = dma_map_single(tx_chan->device->dev, | ||
970 | sport->port.state->xmit.buf, | 970 | sport->port.state->xmit.buf, |
971 | UART_XMIT_SIZE, DMA_TO_DEVICE); | 971 | UART_XMIT_SIZE, DMA_TO_DEVICE); |
972 | 972 | ||
973 | if (dma_mapping_error(tx_chan->device->dev, dma_bus)) { | 973 | if (dma_mapping_error(sport->dma_tx_chan->device->dev, dma_bus)) { |
974 | dev_err(sport->port.dev, "dma_map_single tx failed\n"); | 974 | dev_err(sport->port.dev, "dma_map_single tx failed\n"); |
975 | dma_release_channel(tx_chan); | ||
976 | return -ENOMEM; | 975 | return -ENOMEM; |
977 | } | 976 | } |
978 | 977 | ||
@@ -981,16 +980,14 @@ static int lpuart_dma_tx_request(struct uart_port *port) | |||
981 | dma_tx_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | 980 | dma_tx_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; |
982 | dma_tx_sconfig.dst_maxburst = sport->txfifo_size; | 981 | dma_tx_sconfig.dst_maxburst = sport->txfifo_size; |
983 | dma_tx_sconfig.direction = DMA_MEM_TO_DEV; | 982 | dma_tx_sconfig.direction = DMA_MEM_TO_DEV; |
984 | ret = dmaengine_slave_config(tx_chan, &dma_tx_sconfig); | 983 | ret = dmaengine_slave_config(sport->dma_tx_chan, &dma_tx_sconfig); |
985 | 984 | ||
986 | if (ret < 0) { | 985 | if (ret < 0) { |
987 | dev_err(sport->port.dev, | 986 | dev_err(sport->port.dev, |
988 | "Dma slave config failed, err = %d\n", ret); | 987 | "Dma slave config failed, err = %d\n", ret); |
989 | dma_release_channel(tx_chan); | ||
990 | return ret; | 988 | return ret; |
991 | } | 989 | } |
992 | 990 | ||
993 | sport->dma_tx_chan = tx_chan; | ||
994 | sport->dma_tx_buf_virt = dma_buf; | 991 | sport->dma_tx_buf_virt = dma_buf; |
995 | sport->dma_tx_buf_bus = dma_bus; | 992 | sport->dma_tx_buf_bus = dma_bus; |
996 | sport->dma_tx_in_progress = 0; | 993 | sport->dma_tx_in_progress = 0; |
@@ -1002,34 +999,24 @@ static int lpuart_dma_rx_request(struct uart_port *port) | |||
1002 | { | 999 | { |
1003 | struct lpuart_port *sport = container_of(port, | 1000 | struct lpuart_port *sport = container_of(port, |
1004 | struct lpuart_port, port); | 1001 | struct lpuart_port, port); |
1005 | struct dma_chan *rx_chan; | ||
1006 | struct dma_slave_config dma_rx_sconfig; | 1002 | struct dma_slave_config dma_rx_sconfig; |
1007 | dma_addr_t dma_bus; | 1003 | dma_addr_t dma_bus; |
1008 | unsigned char *dma_buf; | 1004 | unsigned char *dma_buf; |
1009 | int ret; | 1005 | int ret; |
1010 | 1006 | ||
1011 | rx_chan = dma_request_slave_channel(sport->port.dev, "rx"); | ||
1012 | |||
1013 | if (!rx_chan) { | ||
1014 | dev_err(sport->port.dev, "Dma rx channel request failed!\n"); | ||
1015 | return -ENODEV; | ||
1016 | } | ||
1017 | |||
1018 | dma_buf = devm_kzalloc(sport->port.dev, | 1007 | dma_buf = devm_kzalloc(sport->port.dev, |
1019 | FSL_UART_RX_DMA_BUFFER_SIZE, GFP_KERNEL); | 1008 | FSL_UART_RX_DMA_BUFFER_SIZE, GFP_KERNEL); |
1020 | 1009 | ||
1021 | if (!dma_buf) { | 1010 | if (!dma_buf) { |
1022 | dev_err(sport->port.dev, "Dma rx alloc failed\n"); | 1011 | dev_err(sport->port.dev, "Dma rx alloc failed\n"); |
1023 | dma_release_channel(rx_chan); | ||
1024 | return -ENOMEM; | 1012 | return -ENOMEM; |
1025 | } | 1013 | } |
1026 | 1014 | ||
1027 | dma_bus = dma_map_single(rx_chan->device->dev, dma_buf, | 1015 | dma_bus = dma_map_single(sport->dma_rx_chan->device->dev, dma_buf, |
1028 | FSL_UART_RX_DMA_BUFFER_SIZE, DMA_FROM_DEVICE); | 1016 | FSL_UART_RX_DMA_BUFFER_SIZE, DMA_FROM_DEVICE); |
1029 | 1017 | ||
1030 | if (dma_mapping_error(rx_chan->device->dev, dma_bus)) { | 1018 | if (dma_mapping_error(sport->dma_rx_chan->device->dev, dma_bus)) { |
1031 | dev_err(sport->port.dev, "dma_map_single rx failed\n"); | 1019 | dev_err(sport->port.dev, "dma_map_single rx failed\n"); |
1032 | dma_release_channel(rx_chan); | ||
1033 | return -ENOMEM; | 1020 | return -ENOMEM; |
1034 | } | 1021 | } |
1035 | 1022 | ||
@@ -1037,16 +1024,14 @@ static int lpuart_dma_rx_request(struct uart_port *port) | |||
1037 | dma_rx_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | 1024 | dma_rx_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; |
1038 | dma_rx_sconfig.src_maxburst = 1; | 1025 | dma_rx_sconfig.src_maxburst = 1; |
1039 | dma_rx_sconfig.direction = DMA_DEV_TO_MEM; | 1026 | dma_rx_sconfig.direction = DMA_DEV_TO_MEM; |
1040 | ret = dmaengine_slave_config(rx_chan, &dma_rx_sconfig); | 1027 | ret = dmaengine_slave_config(sport->dma_rx_chan, &dma_rx_sconfig); |
1041 | 1028 | ||
1042 | if (ret < 0) { | 1029 | if (ret < 0) { |
1043 | dev_err(sport->port.dev, | 1030 | dev_err(sport->port.dev, |
1044 | "Dma slave config failed, err = %d\n", ret); | 1031 | "Dma slave config failed, err = %d\n", ret); |
1045 | dma_release_channel(rx_chan); | ||
1046 | return ret; | 1032 | return ret; |
1047 | } | 1033 | } |
1048 | 1034 | ||
1049 | sport->dma_rx_chan = rx_chan; | ||
1050 | sport->dma_rx_buf_virt = dma_buf; | 1035 | sport->dma_rx_buf_virt = dma_buf; |
1051 | sport->dma_rx_buf_bus = dma_bus; | 1036 | sport->dma_rx_buf_bus = dma_bus; |
1052 | sport->dma_rx_in_progress = 0; | 1037 | sport->dma_rx_in_progress = 0; |
@@ -1058,31 +1043,24 @@ static void lpuart_dma_tx_free(struct uart_port *port) | |||
1058 | { | 1043 | { |
1059 | struct lpuart_port *sport = container_of(port, | 1044 | struct lpuart_port *sport = container_of(port, |
1060 | struct lpuart_port, port); | 1045 | struct lpuart_port, port); |
1061 | struct dma_chan *dma_chan; | ||
1062 | 1046 | ||
1063 | dma_unmap_single(sport->port.dev, sport->dma_tx_buf_bus, | 1047 | dma_unmap_single(sport->port.dev, sport->dma_tx_buf_bus, |
1064 | UART_XMIT_SIZE, DMA_TO_DEVICE); | 1048 | UART_XMIT_SIZE, DMA_TO_DEVICE); |
1065 | dma_chan = sport->dma_tx_chan; | 1049 | |
1066 | sport->dma_tx_chan = NULL; | ||
1067 | sport->dma_tx_buf_bus = 0; | 1050 | sport->dma_tx_buf_bus = 0; |
1068 | sport->dma_tx_buf_virt = NULL; | 1051 | sport->dma_tx_buf_virt = NULL; |
1069 | dma_release_channel(dma_chan); | ||
1070 | } | 1052 | } |
1071 | 1053 | ||
1072 | static void lpuart_dma_rx_free(struct uart_port *port) | 1054 | static void lpuart_dma_rx_free(struct uart_port *port) |
1073 | { | 1055 | { |
1074 | struct lpuart_port *sport = container_of(port, | 1056 | struct lpuart_port *sport = container_of(port, |
1075 | struct lpuart_port, port); | 1057 | struct lpuart_port, port); |
1076 | struct dma_chan *dma_chan; | ||
1077 | 1058 | ||
1078 | dma_unmap_single(sport->port.dev, sport->dma_rx_buf_bus, | 1059 | dma_unmap_single(sport->port.dev, sport->dma_rx_buf_bus, |
1079 | FSL_UART_RX_DMA_BUFFER_SIZE, DMA_FROM_DEVICE); | 1060 | FSL_UART_RX_DMA_BUFFER_SIZE, DMA_FROM_DEVICE); |
1080 | 1061 | ||
1081 | dma_chan = sport->dma_rx_chan; | ||
1082 | sport->dma_rx_chan = NULL; | ||
1083 | sport->dma_rx_buf_bus = 0; | 1062 | sport->dma_rx_buf_bus = 0; |
1084 | sport->dma_rx_buf_virt = NULL; | 1063 | sport->dma_rx_buf_virt = NULL; |
1085 | dma_release_channel(dma_chan); | ||
1086 | } | 1064 | } |
1087 | 1065 | ||
1088 | static int lpuart_startup(struct uart_port *port) | 1066 | static int lpuart_startup(struct uart_port *port) |
@@ -1101,14 +1079,21 @@ static int lpuart_startup(struct uart_port *port) | |||
1101 | sport->rxfifo_size = 0x1 << (((temp >> UARTPFIFO_RXSIZE_OFF) & | 1079 | sport->rxfifo_size = 0x1 << (((temp >> UARTPFIFO_RXSIZE_OFF) & |
1102 | UARTPFIFO_FIFOSIZE_MASK) + 1); | 1080 | UARTPFIFO_FIFOSIZE_MASK) + 1); |
1103 | 1081 | ||
1104 | /* Whether use dma support by dma request results */ | 1082 | if (sport->dma_rx_chan && !lpuart_dma_rx_request(port)) { |
1105 | if (lpuart_dma_tx_request(port) || lpuart_dma_rx_request(port)) { | 1083 | sport->lpuart_dma_rx_use = true; |
1106 | sport->lpuart_dma_use = false; | 1084 | setup_timer(&sport->lpuart_timer, lpuart_timer_func, |
1107 | } else { | 1085 | (unsigned long)sport); |
1108 | sport->lpuart_dma_use = true; | 1086 | } else |
1087 | sport->lpuart_dma_rx_use = false; | ||
1088 | |||
1089 | |||
1090 | if (sport->dma_tx_chan && !lpuart_dma_tx_request(port)) { | ||
1091 | sport->lpuart_dma_tx_use = true; | ||
1109 | temp = readb(port->membase + UARTCR5); | 1092 | temp = readb(port->membase + UARTCR5); |
1093 | temp &= ~UARTCR5_RDMAS; | ||
1110 | writeb(temp | UARTCR5_TDMAS, port->membase + UARTCR5); | 1094 | writeb(temp | UARTCR5_TDMAS, port->membase + UARTCR5); |
1111 | } | 1095 | } else |
1096 | sport->lpuart_dma_tx_use = false; | ||
1112 | 1097 | ||
1113 | ret = devm_request_irq(port->dev, port->irq, lpuart_int, 0, | 1098 | ret = devm_request_irq(port->dev, port->irq, lpuart_int, 0, |
1114 | DRIVER_NAME, sport); | 1099 | DRIVER_NAME, sport); |
@@ -1179,10 +1164,13 @@ static void lpuart_shutdown(struct uart_port *port) | |||
1179 | 1164 | ||
1180 | devm_free_irq(port->dev, port->irq, sport); | 1165 | devm_free_irq(port->dev, port->irq, sport); |
1181 | 1166 | ||
1182 | if (sport->lpuart_dma_use) { | 1167 | if (sport->lpuart_dma_rx_use) { |
1183 | lpuart_dma_tx_free(port); | 1168 | lpuart_dma_rx_free(&sport->port); |
1184 | lpuart_dma_rx_free(port); | 1169 | del_timer_sync(&sport->lpuart_timer); |
1185 | } | 1170 | } |
1171 | |||
1172 | if (sport->lpuart_dma_tx_use) | ||
1173 | lpuart_dma_tx_free(&sport->port); | ||
1186 | } | 1174 | } |
1187 | 1175 | ||
1188 | static void lpuart32_shutdown(struct uart_port *port) | 1176 | static void lpuart32_shutdown(struct uart_port *port) |
@@ -1304,7 +1292,7 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1304 | /* update the per-port timeout */ | 1292 | /* update the per-port timeout */ |
1305 | uart_update_timeout(port, termios->c_cflag, baud); | 1293 | uart_update_timeout(port, termios->c_cflag, baud); |
1306 | 1294 | ||
1307 | if (sport->lpuart_dma_use) { | 1295 | if (sport->lpuart_dma_rx_use) { |
1308 | /* Calculate delay for 1.5 DMA buffers */ | 1296 | /* Calculate delay for 1.5 DMA buffers */ |
1309 | sport->dma_rx_timeout = (sport->port.timeout - HZ / 50) * | 1297 | sport->dma_rx_timeout = (sport->port.timeout - HZ / 50) * |
1310 | FSL_UART_RX_DMA_BUFFER_SIZE * 3 / | 1298 | FSL_UART_RX_DMA_BUFFER_SIZE * 3 / |
@@ -1517,6 +1505,7 @@ static struct uart_ops lpuart_pops = { | |||
1517 | .release_port = lpuart_release_port, | 1505 | .release_port = lpuart_release_port, |
1518 | .config_port = lpuart_config_port, | 1506 | .config_port = lpuart_config_port, |
1519 | .verify_port = lpuart_verify_port, | 1507 | .verify_port = lpuart_verify_port, |
1508 | .flush_buffer = lpuart_flush_buffer, | ||
1520 | }; | 1509 | }; |
1521 | 1510 | ||
1522 | static struct uart_ops lpuart32_pops = { | 1511 | static struct uart_ops lpuart32_pops = { |
@@ -1535,6 +1524,7 @@ static struct uart_ops lpuart32_pops = { | |||
1535 | .release_port = lpuart_release_port, | 1524 | .release_port = lpuart_release_port, |
1536 | .config_port = lpuart_config_port, | 1525 | .config_port = lpuart_config_port, |
1537 | .verify_port = lpuart_verify_port, | 1526 | .verify_port = lpuart_verify_port, |
1527 | .flush_buffer = lpuart_flush_buffer, | ||
1538 | }; | 1528 | }; |
1539 | 1529 | ||
1540 | static struct lpuart_port *lpuart_ports[UART_NR]; | 1530 | static struct lpuart_port *lpuart_ports[UART_NR]; |
@@ -1833,6 +1823,16 @@ static int lpuart_probe(struct platform_device *pdev) | |||
1833 | return ret; | 1823 | return ret; |
1834 | } | 1824 | } |
1835 | 1825 | ||
1826 | sport->dma_tx_chan = dma_request_slave_channel(sport->port.dev, "tx"); | ||
1827 | if (!sport->dma_tx_chan) | ||
1828 | dev_info(sport->port.dev, "DMA tx channel request failed, " | ||
1829 | "operating without tx DMA\n"); | ||
1830 | |||
1831 | sport->dma_rx_chan = dma_request_slave_channel(sport->port.dev, "rx"); | ||
1832 | if (!sport->dma_rx_chan) | ||
1833 | dev_info(sport->port.dev, "DMA rx channel request failed, " | ||
1834 | "operating without rx DMA\n"); | ||
1835 | |||
1836 | return 0; | 1836 | return 0; |
1837 | } | 1837 | } |
1838 | 1838 | ||
@@ -1844,6 +1844,12 @@ static int lpuart_remove(struct platform_device *pdev) | |||
1844 | 1844 | ||
1845 | clk_disable_unprepare(sport->clk); | 1845 | clk_disable_unprepare(sport->clk); |
1846 | 1846 | ||
1847 | if (sport->dma_tx_chan) | ||
1848 | dma_release_channel(sport->dma_tx_chan); | ||
1849 | |||
1850 | if (sport->dma_rx_chan) | ||
1851 | dma_release_channel(sport->dma_rx_chan); | ||
1852 | |||
1847 | return 0; | 1853 | return 0; |
1848 | } | 1854 | } |
1849 | 1855 | ||
@@ -1851,6 +1857,19 @@ static int lpuart_remove(struct platform_device *pdev) | |||
1851 | static int lpuart_suspend(struct device *dev) | 1857 | static int lpuart_suspend(struct device *dev) |
1852 | { | 1858 | { |
1853 | struct lpuart_port *sport = dev_get_drvdata(dev); | 1859 | struct lpuart_port *sport = dev_get_drvdata(dev); |
1860 | unsigned long temp; | ||
1861 | |||
1862 | if (sport->lpuart32) { | ||
1863 | /* disable Rx/Tx and interrupts */ | ||
1864 | temp = lpuart32_read(sport->port.membase + UARTCTRL); | ||
1865 | temp &= ~(UARTCTRL_TE | UARTCTRL_TIE | UARTCTRL_TCIE); | ||
1866 | lpuart32_write(temp, sport->port.membase + UARTCTRL); | ||
1867 | } else { | ||
1868 | /* disable Rx/Tx and interrupts */ | ||
1869 | temp = readb(sport->port.membase + UARTCR2); | ||
1870 | temp &= ~(UARTCR2_TE | UARTCR2_TIE | UARTCR2_TCIE); | ||
1871 | writeb(temp, sport->port.membase + UARTCR2); | ||
1872 | } | ||
1854 | 1873 | ||
1855 | uart_suspend_port(&lpuart_reg, &sport->port); | 1874 | uart_suspend_port(&lpuart_reg, &sport->port); |
1856 | 1875 | ||
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 4c5e9092e2d7..0eb29b1c47ac 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c | |||
@@ -74,6 +74,7 @@ | |||
74 | #define IMX21_UTS 0xb4 /* UART Test Register on all other i.mx*/ | 74 | #define IMX21_UTS 0xb4 /* UART Test Register on all other i.mx*/ |
75 | 75 | ||
76 | /* UART Control Register Bit Fields.*/ | 76 | /* UART Control Register Bit Fields.*/ |
77 | #define URXD_DUMMY_READ (1<<16) | ||
77 | #define URXD_CHARRDY (1<<15) | 78 | #define URXD_CHARRDY (1<<15) |
78 | #define URXD_ERR (1<<14) | 79 | #define URXD_ERR (1<<14) |
79 | #define URXD_OVRRUN (1<<13) | 80 | #define URXD_OVRRUN (1<<13) |
@@ -463,13 +464,17 @@ static void imx_enable_ms(struct uart_port *port) | |||
463 | mod_timer(&sport->timer, jiffies); | 464 | mod_timer(&sport->timer, jiffies); |
464 | } | 465 | } |
465 | 466 | ||
467 | static void imx_dma_tx(struct imx_port *sport); | ||
466 | static inline void imx_transmit_buffer(struct imx_port *sport) | 468 | static inline void imx_transmit_buffer(struct imx_port *sport) |
467 | { | 469 | { |
468 | struct circ_buf *xmit = &sport->port.state->xmit; | 470 | struct circ_buf *xmit = &sport->port.state->xmit; |
471 | unsigned long temp; | ||
469 | 472 | ||
470 | if (sport->port.x_char) { | 473 | if (sport->port.x_char) { |
471 | /* Send next char */ | 474 | /* Send next char */ |
472 | writel(sport->port.x_char, sport->port.membase + URTX0); | 475 | writel(sport->port.x_char, sport->port.membase + URTX0); |
476 | sport->port.icount.tx++; | ||
477 | sport->port.x_char = 0; | ||
473 | return; | 478 | return; |
474 | } | 479 | } |
475 | 480 | ||
@@ -478,6 +483,22 @@ static inline void imx_transmit_buffer(struct imx_port *sport) | |||
478 | return; | 483 | return; |
479 | } | 484 | } |
480 | 485 | ||
486 | if (sport->dma_is_enabled) { | ||
487 | /* | ||
488 | * We've just sent a X-char Ensure the TX DMA is enabled | ||
489 | * and the TX IRQ is disabled. | ||
490 | **/ | ||
491 | temp = readl(sport->port.membase + UCR1); | ||
492 | temp &= ~UCR1_TXMPTYEN; | ||
493 | if (sport->dma_is_txing) { | ||
494 | temp |= UCR1_TDMAEN; | ||
495 | writel(temp, sport->port.membase + UCR1); | ||
496 | } else { | ||
497 | writel(temp, sport->port.membase + UCR1); | ||
498 | imx_dma_tx(sport); | ||
499 | } | ||
500 | } | ||
501 | |||
481 | while (!uart_circ_empty(xmit) && | 502 | while (!uart_circ_empty(xmit) && |
482 | !(readl(sport->port.membase + uts_reg(sport)) & UTS_TXFULL)) { | 503 | !(readl(sport->port.membase + uts_reg(sport)) & UTS_TXFULL)) { |
483 | /* send xmit->buf[xmit->tail] | 504 | /* send xmit->buf[xmit->tail] |
@@ -500,26 +521,39 @@ static void dma_tx_callback(void *data) | |||
500 | struct scatterlist *sgl = &sport->tx_sgl[0]; | 521 | struct scatterlist *sgl = &sport->tx_sgl[0]; |
501 | struct circ_buf *xmit = &sport->port.state->xmit; | 522 | struct circ_buf *xmit = &sport->port.state->xmit; |
502 | unsigned long flags; | 523 | unsigned long flags; |
524 | unsigned long temp; | ||
525 | |||
526 | spin_lock_irqsave(&sport->port.lock, flags); | ||
503 | 527 | ||
504 | dma_unmap_sg(sport->port.dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE); | 528 | dma_unmap_sg(sport->port.dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE); |
505 | 529 | ||
506 | sport->dma_is_txing = 0; | 530 | temp = readl(sport->port.membase + UCR1); |
531 | temp &= ~UCR1_TDMAEN; | ||
532 | writel(temp, sport->port.membase + UCR1); | ||
507 | 533 | ||
508 | /* update the stat */ | 534 | /* update the stat */ |
509 | spin_lock_irqsave(&sport->port.lock, flags); | ||
510 | xmit->tail = (xmit->tail + sport->tx_bytes) & (UART_XMIT_SIZE - 1); | 535 | xmit->tail = (xmit->tail + sport->tx_bytes) & (UART_XMIT_SIZE - 1); |
511 | sport->port.icount.tx += sport->tx_bytes; | 536 | sport->port.icount.tx += sport->tx_bytes; |
512 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
513 | 537 | ||
514 | dev_dbg(sport->port.dev, "we finish the TX DMA.\n"); | 538 | dev_dbg(sport->port.dev, "we finish the TX DMA.\n"); |
515 | 539 | ||
516 | uart_write_wakeup(&sport->port); | 540 | sport->dma_is_txing = 0; |
541 | |||
542 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
543 | |||
544 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
545 | uart_write_wakeup(&sport->port); | ||
517 | 546 | ||
518 | if (waitqueue_active(&sport->dma_wait)) { | 547 | if (waitqueue_active(&sport->dma_wait)) { |
519 | wake_up(&sport->dma_wait); | 548 | wake_up(&sport->dma_wait); |
520 | dev_dbg(sport->port.dev, "exit in %s.\n", __func__); | 549 | dev_dbg(sport->port.dev, "exit in %s.\n", __func__); |
521 | return; | 550 | return; |
522 | } | 551 | } |
552 | |||
553 | spin_lock_irqsave(&sport->port.lock, flags); | ||
554 | if (!uart_circ_empty(xmit) && !uart_tx_stopped(&sport->port)) | ||
555 | imx_dma_tx(sport); | ||
556 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
523 | } | 557 | } |
524 | 558 | ||
525 | static void imx_dma_tx(struct imx_port *sport) | 559 | static void imx_dma_tx(struct imx_port *sport) |
@@ -529,24 +563,23 @@ static void imx_dma_tx(struct imx_port *sport) | |||
529 | struct dma_async_tx_descriptor *desc; | 563 | struct dma_async_tx_descriptor *desc; |
530 | struct dma_chan *chan = sport->dma_chan_tx; | 564 | struct dma_chan *chan = sport->dma_chan_tx; |
531 | struct device *dev = sport->port.dev; | 565 | struct device *dev = sport->port.dev; |
532 | enum dma_status status; | 566 | unsigned long temp; |
533 | int ret; | 567 | int ret; |
534 | 568 | ||
535 | status = dmaengine_tx_status(chan, (dma_cookie_t)0, NULL); | 569 | if (sport->dma_is_txing) |
536 | if (DMA_IN_PROGRESS == status) | ||
537 | return; | 570 | return; |
538 | 571 | ||
539 | sport->tx_bytes = uart_circ_chars_pending(xmit); | 572 | sport->tx_bytes = uart_circ_chars_pending(xmit); |
540 | 573 | ||
541 | if (xmit->tail > xmit->head && xmit->head > 0) { | 574 | if (xmit->tail < xmit->head) { |
575 | sport->dma_tx_nents = 1; | ||
576 | sg_init_one(sgl, xmit->buf + xmit->tail, sport->tx_bytes); | ||
577 | } else { | ||
542 | sport->dma_tx_nents = 2; | 578 | sport->dma_tx_nents = 2; |
543 | sg_init_table(sgl, 2); | 579 | sg_init_table(sgl, 2); |
544 | sg_set_buf(sgl, xmit->buf + xmit->tail, | 580 | sg_set_buf(sgl, xmit->buf + xmit->tail, |
545 | UART_XMIT_SIZE - xmit->tail); | 581 | UART_XMIT_SIZE - xmit->tail); |
546 | sg_set_buf(sgl + 1, xmit->buf, xmit->head); | 582 | sg_set_buf(sgl + 1, xmit->buf, xmit->head); |
547 | } else { | ||
548 | sport->dma_tx_nents = 1; | ||
549 | sg_init_one(sgl, xmit->buf + xmit->tail, sport->tx_bytes); | ||
550 | } | 583 | } |
551 | 584 | ||
552 | ret = dma_map_sg(dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE); | 585 | ret = dma_map_sg(dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE); |
@@ -557,6 +590,8 @@ static void imx_dma_tx(struct imx_port *sport) | |||
557 | desc = dmaengine_prep_slave_sg(chan, sgl, sport->dma_tx_nents, | 590 | desc = dmaengine_prep_slave_sg(chan, sgl, sport->dma_tx_nents, |
558 | DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT); | 591 | DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT); |
559 | if (!desc) { | 592 | if (!desc) { |
593 | dma_unmap_sg(dev, sgl, sport->dma_tx_nents, | ||
594 | DMA_TO_DEVICE); | ||
560 | dev_err(dev, "We cannot prepare for the TX slave dma!\n"); | 595 | dev_err(dev, "We cannot prepare for the TX slave dma!\n"); |
561 | return; | 596 | return; |
562 | } | 597 | } |
@@ -565,6 +600,11 @@ static void imx_dma_tx(struct imx_port *sport) | |||
565 | 600 | ||
566 | dev_dbg(dev, "TX: prepare to send %lu bytes by DMA.\n", | 601 | dev_dbg(dev, "TX: prepare to send %lu bytes by DMA.\n", |
567 | uart_circ_chars_pending(xmit)); | 602 | uart_circ_chars_pending(xmit)); |
603 | |||
604 | temp = readl(sport->port.membase + UCR1); | ||
605 | temp |= UCR1_TDMAEN; | ||
606 | writel(temp, sport->port.membase + UCR1); | ||
607 | |||
568 | /* fire it */ | 608 | /* fire it */ |
569 | sport->dma_is_txing = 1; | 609 | sport->dma_is_txing = 1; |
570 | dmaengine_submit(desc); | 610 | dmaengine_submit(desc); |
@@ -590,13 +630,6 @@ static void imx_start_tx(struct uart_port *port) | |||
590 | temp &= ~(UCR1_RRDYEN); | 630 | temp &= ~(UCR1_RRDYEN); |
591 | writel(temp, sport->port.membase + UCR1); | 631 | writel(temp, sport->port.membase + UCR1); |
592 | } | 632 | } |
593 | /* Clear any pending ORE flag before enabling interrupt */ | ||
594 | temp = readl(sport->port.membase + USR2); | ||
595 | writel(temp | USR2_ORE, sport->port.membase + USR2); | ||
596 | |||
597 | temp = readl(sport->port.membase + UCR4); | ||
598 | temp |= UCR4_OREN; | ||
599 | writel(temp, sport->port.membase + UCR4); | ||
600 | 633 | ||
601 | if (!sport->dma_is_enabled) { | 634 | if (!sport->dma_is_enabled) { |
602 | temp = readl(sport->port.membase + UCR1); | 635 | temp = readl(sport->port.membase + UCR1); |
@@ -614,15 +647,21 @@ static void imx_start_tx(struct uart_port *port) | |||
614 | } | 647 | } |
615 | 648 | ||
616 | if (sport->dma_is_enabled) { | 649 | if (sport->dma_is_enabled) { |
617 | /* FIXME: port->x_char must be transmitted if != 0 */ | 650 | if (sport->port.x_char) { |
651 | /* We have X-char to send, so enable TX IRQ and | ||
652 | * disable TX DMA to let TX interrupt to send X-char */ | ||
653 | temp = readl(sport->port.membase + UCR1); | ||
654 | temp &= ~UCR1_TDMAEN; | ||
655 | temp |= UCR1_TXMPTYEN; | ||
656 | writel(temp, sport->port.membase + UCR1); | ||
657 | return; | ||
658 | } | ||
659 | |||
618 | if (!uart_circ_empty(&port->state->xmit) && | 660 | if (!uart_circ_empty(&port->state->xmit) && |
619 | !uart_tx_stopped(port)) | 661 | !uart_tx_stopped(port)) |
620 | imx_dma_tx(sport); | 662 | imx_dma_tx(sport); |
621 | return; | 663 | return; |
622 | } | 664 | } |
623 | |||
624 | if (readl(sport->port.membase + uts_reg(sport)) & UTS_TXEMPTY) | ||
625 | imx_transmit_buffer(sport); | ||
626 | } | 665 | } |
627 | 666 | ||
628 | static irqreturn_t imx_rtsint(int irq, void *dev_id) | 667 | static irqreturn_t imx_rtsint(int irq, void *dev_id) |
@@ -694,7 +733,7 @@ static irqreturn_t imx_rxint(int irq, void *dev_id) | |||
694 | continue; | 733 | continue; |
695 | } | 734 | } |
696 | 735 | ||
697 | rx &= sport->port.read_status_mask; | 736 | rx &= (sport->port.read_status_mask | 0xFF); |
698 | 737 | ||
699 | if (rx & URXD_BRK) | 738 | if (rx & URXD_BRK) |
700 | flg = TTY_BREAK; | 739 | flg = TTY_BREAK; |
@@ -710,6 +749,9 @@ static irqreturn_t imx_rxint(int irq, void *dev_id) | |||
710 | #endif | 749 | #endif |
711 | } | 750 | } |
712 | 751 | ||
752 | if (sport->port.ignore_status_mask & URXD_DUMMY_READ) | ||
753 | goto out; | ||
754 | |||
713 | tty_insert_flip_char(port, rx, flg); | 755 | tty_insert_flip_char(port, rx, flg); |
714 | } | 756 | } |
715 | 757 | ||
@@ -727,6 +769,9 @@ static int start_rx_dma(struct imx_port *sport); | |||
727 | static void imx_dma_rxint(struct imx_port *sport) | 769 | static void imx_dma_rxint(struct imx_port *sport) |
728 | { | 770 | { |
729 | unsigned long temp; | 771 | unsigned long temp; |
772 | unsigned long flags; | ||
773 | |||
774 | spin_lock_irqsave(&sport->port.lock, flags); | ||
730 | 775 | ||
731 | temp = readl(sport->port.membase + USR2); | 776 | temp = readl(sport->port.membase + USR2); |
732 | if ((temp & USR2_RDR) && !sport->dma_is_rxing) { | 777 | if ((temp & USR2_RDR) && !sport->dma_is_rxing) { |
@@ -740,6 +785,8 @@ static void imx_dma_rxint(struct imx_port *sport) | |||
740 | /* tell the DMA to receive the data. */ | 785 | /* tell the DMA to receive the data. */ |
741 | start_rx_dma(sport); | 786 | start_rx_dma(sport); |
742 | } | 787 | } |
788 | |||
789 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
743 | } | 790 | } |
744 | 791 | ||
745 | static irqreturn_t imx_int(int irq, void *dev_id) | 792 | static irqreturn_t imx_int(int irq, void *dev_id) |
@@ -869,6 +916,9 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode) | |||
869 | static void imx_rx_dma_done(struct imx_port *sport) | 916 | static void imx_rx_dma_done(struct imx_port *sport) |
870 | { | 917 | { |
871 | unsigned long temp; | 918 | unsigned long temp; |
919 | unsigned long flags; | ||
920 | |||
921 | spin_lock_irqsave(&sport->port.lock, flags); | ||
872 | 922 | ||
873 | /* Enable this interrupt when the RXFIFO is empty. */ | 923 | /* Enable this interrupt when the RXFIFO is empty. */ |
874 | temp = readl(sport->port.membase + UCR1); | 924 | temp = readl(sport->port.membase + UCR1); |
@@ -880,6 +930,8 @@ static void imx_rx_dma_done(struct imx_port *sport) | |||
880 | /* Is the shutdown waiting for us? */ | 930 | /* Is the shutdown waiting for us? */ |
881 | if (waitqueue_active(&sport->dma_wait)) | 931 | if (waitqueue_active(&sport->dma_wait)) |
882 | wake_up(&sport->dma_wait); | 932 | wake_up(&sport->dma_wait); |
933 | |||
934 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
883 | } | 935 | } |
884 | 936 | ||
885 | /* | 937 | /* |
@@ -910,12 +962,26 @@ static void dma_rx_callback(void *data) | |||
910 | dev_dbg(sport->port.dev, "We get %d bytes.\n", count); | 962 | dev_dbg(sport->port.dev, "We get %d bytes.\n", count); |
911 | 963 | ||
912 | if (count) { | 964 | if (count) { |
913 | tty_insert_flip_string(port, sport->rx_buf, count); | 965 | if (!(sport->port.ignore_status_mask & URXD_DUMMY_READ)) |
966 | tty_insert_flip_string(port, sport->rx_buf, count); | ||
914 | tty_flip_buffer_push(port); | 967 | tty_flip_buffer_push(port); |
915 | 968 | ||
916 | start_rx_dma(sport); | 969 | start_rx_dma(sport); |
917 | } else | 970 | } else if (readl(sport->port.membase + USR2) & USR2_RDR) { |
971 | /* | ||
972 | * start rx_dma directly once data in RXFIFO, more efficient | ||
973 | * than before: | ||
974 | * 1. call imx_rx_dma_done to stop dma if no data received | ||
975 | * 2. wait next RDR interrupt to start dma transfer. | ||
976 | */ | ||
977 | start_rx_dma(sport); | ||
978 | } else { | ||
979 | /* | ||
980 | * stop dma to prevent too many IDLE event trigged if no data | ||
981 | * in RXFIFO | ||
982 | */ | ||
918 | imx_rx_dma_done(sport); | 983 | imx_rx_dma_done(sport); |
984 | } | ||
919 | } | 985 | } |
920 | 986 | ||
921 | static int start_rx_dma(struct imx_port *sport) | 987 | static int start_rx_dma(struct imx_port *sport) |
@@ -935,6 +1001,7 @@ static int start_rx_dma(struct imx_port *sport) | |||
935 | desc = dmaengine_prep_slave_sg(chan, sgl, 1, DMA_DEV_TO_MEM, | 1001 | desc = dmaengine_prep_slave_sg(chan, sgl, 1, DMA_DEV_TO_MEM, |
936 | DMA_PREP_INTERRUPT); | 1002 | DMA_PREP_INTERRUPT); |
937 | if (!desc) { | 1003 | if (!desc) { |
1004 | dma_unmap_sg(dev, sgl, 1, DMA_FROM_DEVICE); | ||
938 | dev_err(dev, "We cannot prepare for the RX slave dma!\n"); | 1005 | dev_err(dev, "We cannot prepare for the RX slave dma!\n"); |
939 | return -EINVAL; | 1006 | return -EINVAL; |
940 | } | 1007 | } |
@@ -1108,12 +1175,20 @@ static int imx_startup(struct uart_port *port) | |||
1108 | while (!(readl(sport->port.membase + UCR2) & UCR2_SRST) && (--i > 0)) | 1175 | while (!(readl(sport->port.membase + UCR2) & UCR2_SRST) && (--i > 0)) |
1109 | udelay(1); | 1176 | udelay(1); |
1110 | 1177 | ||
1178 | /* Can we enable the DMA support? */ | ||
1179 | if (is_imx6q_uart(sport) && !uart_console(port) && | ||
1180 | !sport->dma_is_inited) | ||
1181 | imx_uart_dma_init(sport); | ||
1182 | |||
1111 | spin_lock_irqsave(&sport->port.lock, flags); | 1183 | spin_lock_irqsave(&sport->port.lock, flags); |
1112 | /* | 1184 | /* |
1113 | * Finally, clear and enable interrupts | 1185 | * Finally, clear and enable interrupts |
1114 | */ | 1186 | */ |
1115 | writel(USR1_RTSD, sport->port.membase + USR1); | 1187 | writel(USR1_RTSD, sport->port.membase + USR1); |
1116 | 1188 | ||
1189 | if (sport->dma_is_inited && !sport->dma_is_enabled) | ||
1190 | imx_enable_dma(sport); | ||
1191 | |||
1117 | temp = readl(sport->port.membase + UCR1); | 1192 | temp = readl(sport->port.membase + UCR1); |
1118 | temp |= UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN; | 1193 | temp |= UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN; |
1119 | 1194 | ||
@@ -1124,6 +1199,14 @@ static int imx_startup(struct uart_port *port) | |||
1124 | 1199 | ||
1125 | writel(temp, sport->port.membase + UCR1); | 1200 | writel(temp, sport->port.membase + UCR1); |
1126 | 1201 | ||
1202 | /* Clear any pending ORE flag before enabling interrupt */ | ||
1203 | temp = readl(sport->port.membase + USR2); | ||
1204 | writel(temp | USR2_ORE, sport->port.membase + USR2); | ||
1205 | |||
1206 | temp = readl(sport->port.membase + UCR4); | ||
1207 | temp |= UCR4_OREN; | ||
1208 | writel(temp, sport->port.membase + UCR4); | ||
1209 | |||
1127 | temp = readl(sport->port.membase + UCR2); | 1210 | temp = readl(sport->port.membase + UCR2); |
1128 | temp |= (UCR2_RXEN | UCR2_TXEN); | 1211 | temp |= (UCR2_RXEN | UCR2_TXEN); |
1129 | if (!sport->have_rtscts) | 1212 | if (!sport->have_rtscts) |
@@ -1189,9 +1272,11 @@ static void imx_shutdown(struct uart_port *port) | |||
1189 | dmaengine_terminate_all(sport->dma_chan_tx); | 1272 | dmaengine_terminate_all(sport->dma_chan_tx); |
1190 | dmaengine_terminate_all(sport->dma_chan_rx); | 1273 | dmaengine_terminate_all(sport->dma_chan_rx); |
1191 | } | 1274 | } |
1275 | spin_lock_irqsave(&sport->port.lock, flags); | ||
1192 | imx_stop_tx(port); | 1276 | imx_stop_tx(port); |
1193 | imx_stop_rx(port); | 1277 | imx_stop_rx(port); |
1194 | imx_disable_dma(sport); | 1278 | imx_disable_dma(sport); |
1279 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
1195 | imx_uart_dma_exit(sport); | 1280 | imx_uart_dma_exit(sport); |
1196 | } | 1281 | } |
1197 | 1282 | ||
@@ -1233,11 +1318,48 @@ static void imx_shutdown(struct uart_port *port) | |||
1233 | static void imx_flush_buffer(struct uart_port *port) | 1318 | static void imx_flush_buffer(struct uart_port *port) |
1234 | { | 1319 | { |
1235 | struct imx_port *sport = (struct imx_port *)port; | 1320 | struct imx_port *sport = (struct imx_port *)port; |
1321 | struct scatterlist *sgl = &sport->tx_sgl[0]; | ||
1322 | unsigned long temp; | ||
1323 | int i = 100, ubir, ubmr, ubrc, uts; | ||
1236 | 1324 | ||
1237 | if (sport->dma_is_enabled) { | 1325 | if (!sport->dma_chan_tx) |
1238 | sport->tx_bytes = 0; | 1326 | return; |
1239 | dmaengine_terminate_all(sport->dma_chan_tx); | 1327 | |
1328 | sport->tx_bytes = 0; | ||
1329 | dmaengine_terminate_all(sport->dma_chan_tx); | ||
1330 | if (sport->dma_is_txing) { | ||
1331 | dma_unmap_sg(sport->port.dev, sgl, sport->dma_tx_nents, | ||
1332 | DMA_TO_DEVICE); | ||
1333 | temp = readl(sport->port.membase + UCR1); | ||
1334 | temp &= ~UCR1_TDMAEN; | ||
1335 | writel(temp, sport->port.membase + UCR1); | ||
1336 | sport->dma_is_txing = false; | ||
1240 | } | 1337 | } |
1338 | |||
1339 | /* | ||
1340 | * According to the Reference Manual description of the UART SRST bit: | ||
1341 | * "Reset the transmit and receive state machines, | ||
1342 | * all FIFOs and register USR1, USR2, UBIR, UBMR, UBRC, URXD, UTXD | ||
1343 | * and UTS[6-3]". As we don't need to restore the old values from | ||
1344 | * USR1, USR2, URXD, UTXD, only save/restore the other four registers | ||
1345 | */ | ||
1346 | ubir = readl(sport->port.membase + UBIR); | ||
1347 | ubmr = readl(sport->port.membase + UBMR); | ||
1348 | ubrc = readl(sport->port.membase + UBRC); | ||
1349 | uts = readl(sport->port.membase + IMX21_UTS); | ||
1350 | |||
1351 | temp = readl(sport->port.membase + UCR2); | ||
1352 | temp &= ~UCR2_SRST; | ||
1353 | writel(temp, sport->port.membase + UCR2); | ||
1354 | |||
1355 | while (!(readl(sport->port.membase + UCR2) & UCR2_SRST) && (--i > 0)) | ||
1356 | udelay(1); | ||
1357 | |||
1358 | /* Restore the registers */ | ||
1359 | writel(ubir, sport->port.membase + UBIR); | ||
1360 | writel(ubmr, sport->port.membase + UBMR); | ||
1361 | writel(ubrc, sport->port.membase + UBRC); | ||
1362 | writel(uts, sport->port.membase + IMX21_UTS); | ||
1241 | } | 1363 | } |
1242 | 1364 | ||
1243 | static void | 1365 | static void |
@@ -1280,11 +1402,6 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1280 | if (sport->have_rtscts) { | 1402 | if (sport->have_rtscts) { |
1281 | ucr2 &= ~UCR2_IRTS; | 1403 | ucr2 &= ~UCR2_IRTS; |
1282 | ucr2 |= UCR2_CTSC; | 1404 | ucr2 |= UCR2_CTSC; |
1283 | |||
1284 | /* Can we enable the DMA support? */ | ||
1285 | if (is_imx6q_uart(sport) && !uart_console(port) | ||
1286 | && !sport->dma_is_inited) | ||
1287 | imx_uart_dma_init(sport); | ||
1288 | } else { | 1405 | } else { |
1289 | termios->c_cflag &= ~CRTSCTS; | 1406 | termios->c_cflag &= ~CRTSCTS; |
1290 | } | 1407 | } |
@@ -1319,7 +1436,7 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1319 | */ | 1436 | */ |
1320 | sport->port.ignore_status_mask = 0; | 1437 | sport->port.ignore_status_mask = 0; |
1321 | if (termios->c_iflag & IGNPAR) | 1438 | if (termios->c_iflag & IGNPAR) |
1322 | sport->port.ignore_status_mask |= URXD_PRERR; | 1439 | sport->port.ignore_status_mask |= URXD_PRERR | URXD_FRMERR; |
1323 | if (termios->c_iflag & IGNBRK) { | 1440 | if (termios->c_iflag & IGNBRK) { |
1324 | sport->port.ignore_status_mask |= URXD_BRK; | 1441 | sport->port.ignore_status_mask |= URXD_BRK; |
1325 | /* | 1442 | /* |
@@ -1330,6 +1447,9 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1330 | sport->port.ignore_status_mask |= URXD_OVRRUN; | 1447 | sport->port.ignore_status_mask |= URXD_OVRRUN; |
1331 | } | 1448 | } |
1332 | 1449 | ||
1450 | if ((termios->c_cflag & CREAD) == 0) | ||
1451 | sport->port.ignore_status_mask |= URXD_DUMMY_READ; | ||
1452 | |||
1333 | /* | 1453 | /* |
1334 | * Update the per-port timeout. | 1454 | * Update the per-port timeout. |
1335 | */ | 1455 | */ |
@@ -1403,8 +1523,6 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1403 | if (UART_ENABLE_MS(&sport->port, termios->c_cflag)) | 1523 | if (UART_ENABLE_MS(&sport->port, termios->c_cflag)) |
1404 | imx_enable_ms(&sport->port); | 1524 | imx_enable_ms(&sport->port); |
1405 | 1525 | ||
1406 | if (sport->dma_is_inited && !sport->dma_is_enabled) | ||
1407 | imx_enable_dma(sport); | ||
1408 | spin_unlock_irqrestore(&sport->port.lock, flags); | 1526 | spin_unlock_irqrestore(&sport->port.lock, flags); |
1409 | } | 1527 | } |
1410 | 1528 | ||
diff --git a/drivers/tty/serial/mcf.c b/drivers/tty/serial/mcf.c index 10496672dfdb..a9b0ab38a68c 100644 --- a/drivers/tty/serial/mcf.c +++ b/drivers/tty/serial/mcf.c | |||
@@ -3,7 +3,7 @@ | |||
3 | /* | 3 | /* |
4 | * mcf.c -- Freescale ColdFire UART driver | 4 | * mcf.c -- Freescale ColdFire UART driver |
5 | * | 5 | * |
6 | * (C) Copyright 2003-2007, Greg Ungerer <gerg@snapgear.com> | 6 | * (C) Copyright 2003-2007, Greg Ungerer <gerg@uclinux.org> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
@@ -198,7 +198,6 @@ static void mcf_shutdown(struct uart_port *port) | |||
198 | static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, | 198 | static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, |
199 | struct ktermios *old) | 199 | struct ktermios *old) |
200 | { | 200 | { |
201 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | ||
202 | unsigned long flags; | 201 | unsigned long flags; |
203 | unsigned int baud, baudclk; | 202 | unsigned int baud, baudclk; |
204 | #if defined(CONFIG_M5272) | 203 | #if defined(CONFIG_M5272) |
@@ -441,7 +440,6 @@ static int mcf_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
441 | /* Enable or disable the RS485 support */ | 440 | /* Enable or disable the RS485 support */ |
442 | static int mcf_config_rs485(struct uart_port *port, struct serial_rs485 *rs485) | 441 | static int mcf_config_rs485(struct uart_port *port, struct serial_rs485 *rs485) |
443 | { | 442 | { |
444 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | ||
445 | unsigned char mr1, mr2; | 443 | unsigned char mr1, mr2; |
446 | 444 | ||
447 | /* Get mode registers */ | 445 | /* Get mode registers */ |
@@ -631,6 +629,7 @@ static int mcf_probe(struct platform_device *pdev) | |||
631 | port->mapbase = platp[i].mapbase; | 629 | port->mapbase = platp[i].mapbase; |
632 | port->membase = (platp[i].membase) ? platp[i].membase : | 630 | port->membase = (platp[i].membase) ? platp[i].membase : |
633 | (unsigned char __iomem *) platp[i].mapbase; | 631 | (unsigned char __iomem *) platp[i].mapbase; |
632 | port->dev = &pdev->dev; | ||
634 | port->iotype = SERIAL_IO_MEM; | 633 | port->iotype = SERIAL_IO_MEM; |
635 | port->irq = platp[i].irq; | 634 | port->irq = platp[i].irq; |
636 | port->uartclk = MCF_BUSCLK; | 635 | port->uartclk = MCF_BUSCLK; |
@@ -702,7 +701,7 @@ static void __exit mcf_exit(void) | |||
702 | module_init(mcf_init); | 701 | module_init(mcf_init); |
703 | module_exit(mcf_exit); | 702 | module_exit(mcf_exit); |
704 | 703 | ||
705 | MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>"); | 704 | MODULE_AUTHOR("Greg Ungerer <gerg@uclinux.org>"); |
706 | MODULE_DESCRIPTION("Freescale ColdFire UART driver"); | 705 | MODULE_DESCRIPTION("Freescale ColdFire UART driver"); |
707 | MODULE_LICENSE("GPL"); | 706 | MODULE_LICENSE("GPL"); |
708 | MODULE_ALIAS("platform:mcfuart"); | 707 | MODULE_ALIAS("platform:mcfuart"); |
diff --git a/drivers/tty/serial/men_z135_uart.c b/drivers/tty/serial/men_z135_uart.c index 517cd073dc08..35c55505b3eb 100644 --- a/drivers/tty/serial/men_z135_uart.c +++ b/drivers/tty/serial/men_z135_uart.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #define MEN_Z135_MAX_PORTS 12 | 23 | #define MEN_Z135_MAX_PORTS 12 |
24 | #define MEN_Z135_BASECLK 29491200 | 24 | #define MEN_Z135_BASECLK 29491200 |
25 | #define MEN_Z135_FIFO_SIZE 1024 | 25 | #define MEN_Z135_FIFO_SIZE 1024 |
26 | #define MEN_Z135_NUM_MSI_VECTORS 2 | ||
27 | #define MEN_Z135_FIFO_WATERMARK 1020 | 26 | #define MEN_Z135_FIFO_WATERMARK 1020 |
28 | 27 | ||
29 | #define MEN_Z135_STAT_REG 0x0 | 28 | #define MEN_Z135_STAT_REG 0x0 |
@@ -34,12 +33,11 @@ | |||
34 | #define MEN_Z135_CONF_REG 0x808 | 33 | #define MEN_Z135_CONF_REG 0x808 |
35 | #define MEN_Z135_UART_FREQ 0x80c | 34 | #define MEN_Z135_UART_FREQ 0x80c |
36 | #define MEN_Z135_BAUD_REG 0x810 | 35 | #define MEN_Z135_BAUD_REG 0x810 |
37 | #define MENZ135_TIMEOUT 0x814 | 36 | #define MEN_Z135_TIMEOUT 0x814 |
38 | 37 | ||
39 | #define MEN_Z135_MEM_SIZE 0x818 | 38 | #define MEN_Z135_MEM_SIZE 0x818 |
40 | 39 | ||
41 | #define IS_IRQ(x) ((x) & 1) | 40 | #define IRQ_ID(x) ((x) & 0x1f) |
42 | #define IRQ_ID(x) (((x) >> 1) & 7) | ||
43 | 41 | ||
44 | #define MEN_Z135_IER_RXCIEN BIT(0) /* RX Space IRQ */ | 42 | #define MEN_Z135_IER_RXCIEN BIT(0) /* RX Space IRQ */ |
45 | #define MEN_Z135_IER_TXCIEN BIT(1) /* TX Space IRQ */ | 43 | #define MEN_Z135_IER_TXCIEN BIT(1) /* TX Space IRQ */ |
@@ -94,11 +92,11 @@ | |||
94 | #define MEN_Z135_LSR_TEXP BIT(6) | 92 | #define MEN_Z135_LSR_TEXP BIT(6) |
95 | #define MEN_Z135_LSR_RXFIFOERR BIT(7) | 93 | #define MEN_Z135_LSR_RXFIFOERR BIT(7) |
96 | 94 | ||
97 | #define MEN_Z135_IRQ_ID_MST 0 | 95 | #define MEN_Z135_IRQ_ID_RLS BIT(0) |
98 | #define MEN_Z135_IRQ_ID_TSA 1 | 96 | #define MEN_Z135_IRQ_ID_RDA BIT(1) |
99 | #define MEN_Z135_IRQ_ID_RDA 2 | 97 | #define MEN_Z135_IRQ_ID_CTI BIT(2) |
100 | #define MEN_Z135_IRQ_ID_RLS 3 | 98 | #define MEN_Z135_IRQ_ID_TSA BIT(3) |
101 | #define MEN_Z135_IRQ_ID_CTI 6 | 99 | #define MEN_Z135_IRQ_ID_MST BIT(4) |
102 | 100 | ||
103 | #define LCR(x) (((x) >> MEN_Z135_LCR_SHIFT) & 0xff) | 101 | #define LCR(x) (((x) >> MEN_Z135_LCR_SHIFT) & 0xff) |
104 | 102 | ||
@@ -118,12 +116,18 @@ static int align; | |||
118 | module_param(align, int, S_IRUGO); | 116 | module_param(align, int, S_IRUGO); |
119 | MODULE_PARM_DESC(align, "Keep hardware FIFO write pointer aligned, default 0"); | 117 | MODULE_PARM_DESC(align, "Keep hardware FIFO write pointer aligned, default 0"); |
120 | 118 | ||
119 | static uint rx_timeout; | ||
120 | module_param(rx_timeout, uint, S_IRUGO); | ||
121 | MODULE_PARM_DESC(rx_timeout, "RX timeout. " | ||
122 | "Timeout in seconds = (timeout_reg * baud_reg * 4) / freq_reg"); | ||
123 | |||
121 | struct men_z135_port { | 124 | struct men_z135_port { |
122 | struct uart_port port; | 125 | struct uart_port port; |
123 | struct mcb_device *mdev; | 126 | struct mcb_device *mdev; |
124 | unsigned char *rxbuf; | 127 | unsigned char *rxbuf; |
125 | u32 stat_reg; | 128 | u32 stat_reg; |
126 | spinlock_t lock; | 129 | spinlock_t lock; |
130 | bool automode; | ||
127 | }; | 131 | }; |
128 | #define to_men_z135(port) container_of((port), struct men_z135_port, port) | 132 | #define to_men_z135(port) container_of((port), struct men_z135_port, port) |
129 | 133 | ||
@@ -180,12 +184,16 @@ static inline void men_z135_reg_clr(struct men_z135_port *uart, | |||
180 | */ | 184 | */ |
181 | static void men_z135_handle_modem_status(struct men_z135_port *uart) | 185 | static void men_z135_handle_modem_status(struct men_z135_port *uart) |
182 | { | 186 | { |
183 | if (uart->stat_reg & MEN_Z135_MSR_DDCD) | 187 | u8 msr; |
188 | |||
189 | msr = (uart->stat_reg >> 8) & 0xff; | ||
190 | |||
191 | if (msr & MEN_Z135_MSR_DDCD) | ||
184 | uart_handle_dcd_change(&uart->port, | 192 | uart_handle_dcd_change(&uart->port, |
185 | uart->stat_reg & ~MEN_Z135_MSR_DCD); | 193 | msr & MEN_Z135_MSR_DCD); |
186 | if (uart->stat_reg & MEN_Z135_MSR_DCTS) | 194 | if (msr & MEN_Z135_MSR_DCTS) |
187 | uart_handle_cts_change(&uart->port, | 195 | uart_handle_cts_change(&uart->port, |
188 | uart->stat_reg & ~MEN_Z135_MSR_CTS); | 196 | msr & MEN_Z135_MSR_CTS); |
189 | } | 197 | } |
190 | 198 | ||
191 | static void men_z135_handle_lsr(struct men_z135_port *uart) | 199 | static void men_z135_handle_lsr(struct men_z135_port *uart) |
@@ -322,7 +330,8 @@ static void men_z135_handle_tx(struct men_z135_port *uart) | |||
322 | 330 | ||
323 | txfree = MEN_Z135_FIFO_WATERMARK - txc; | 331 | txfree = MEN_Z135_FIFO_WATERMARK - txc; |
324 | if (txfree <= 0) { | 332 | if (txfree <= 0) { |
325 | pr_err("Not enough room in TX FIFO have %d, need %d\n", | 333 | dev_err(&uart->mdev->dev, |
334 | "Not enough room in TX FIFO have %d, need %d\n", | ||
326 | txfree, qlen); | 335 | txfree, qlen); |
327 | goto irq_en; | 336 | goto irq_en; |
328 | } | 337 | } |
@@ -373,43 +382,54 @@ out: | |||
373 | * @irq: The IRQ number | 382 | * @irq: The IRQ number |
374 | * @data: Pointer to UART port | 383 | * @data: Pointer to UART port |
375 | * | 384 | * |
376 | * Check IIR register to see which tasklet to start. | 385 | * Check IIR register to find the cause of the interrupt and handle it. |
386 | * It is possible that multiple interrupts reason bits are set and reading | ||
387 | * the IIR is a destructive read, so we always need to check for all possible | ||
388 | * interrupts and handle them. | ||
377 | */ | 389 | */ |
378 | static irqreturn_t men_z135_intr(int irq, void *data) | 390 | static irqreturn_t men_z135_intr(int irq, void *data) |
379 | { | 391 | { |
380 | struct men_z135_port *uart = (struct men_z135_port *)data; | 392 | struct men_z135_port *uart = (struct men_z135_port *)data; |
381 | struct uart_port *port = &uart->port; | 393 | struct uart_port *port = &uart->port; |
394 | bool handled = false; | ||
395 | unsigned long flags; | ||
382 | int irq_id; | 396 | int irq_id; |
383 | 397 | ||
384 | uart->stat_reg = ioread32(port->membase + MEN_Z135_STAT_REG); | 398 | uart->stat_reg = ioread32(port->membase + MEN_Z135_STAT_REG); |
385 | /* IRQ pending is low active */ | ||
386 | if (IS_IRQ(uart->stat_reg)) | ||
387 | return IRQ_NONE; | ||
388 | |||
389 | irq_id = IRQ_ID(uart->stat_reg); | 399 | irq_id = IRQ_ID(uart->stat_reg); |
390 | switch (irq_id) { | 400 | |
391 | case MEN_Z135_IRQ_ID_MST: | 401 | if (!irq_id) |
392 | men_z135_handle_modem_status(uart); | 402 | goto out; |
393 | break; | 403 | |
394 | case MEN_Z135_IRQ_ID_TSA: | 404 | spin_lock_irqsave(&port->lock, flags); |
395 | men_z135_handle_tx(uart); | 405 | /* It's save to write to IIR[7:6] RXC[9:8] */ |
396 | break; | 406 | iowrite8(irq_id, port->membase + MEN_Z135_STAT_REG); |
397 | case MEN_Z135_IRQ_ID_CTI: | 407 | |
398 | dev_dbg(&uart->mdev->dev, "Character Timeout Indication\n"); | 408 | if (irq_id & MEN_Z135_IRQ_ID_RLS) { |
399 | /* Fallthrough */ | ||
400 | case MEN_Z135_IRQ_ID_RDA: | ||
401 | /* Reading data clears RX IRQ */ | ||
402 | men_z135_handle_rx(uart); | ||
403 | break; | ||
404 | case MEN_Z135_IRQ_ID_RLS: | ||
405 | men_z135_handle_lsr(uart); | 409 | men_z135_handle_lsr(uart); |
406 | break; | 410 | handled = true; |
407 | default: | 411 | } |
408 | dev_warn(&uart->mdev->dev, "Unknown IRQ id %d\n", irq_id); | 412 | |
409 | return IRQ_NONE; | 413 | if (irq_id & (MEN_Z135_IRQ_ID_RDA | MEN_Z135_IRQ_ID_CTI)) { |
414 | if (irq_id & MEN_Z135_IRQ_ID_CTI) | ||
415 | dev_dbg(&uart->mdev->dev, "Character Timeout Indication\n"); | ||
416 | men_z135_handle_rx(uart); | ||
417 | handled = true; | ||
418 | } | ||
419 | |||
420 | if (irq_id & MEN_Z135_IRQ_ID_TSA) { | ||
421 | men_z135_handle_tx(uart); | ||
422 | handled = true; | ||
410 | } | 423 | } |
411 | 424 | ||
412 | return IRQ_HANDLED; | 425 | if (irq_id & MEN_Z135_IRQ_ID_MST) { |
426 | men_z135_handle_modem_status(uart); | ||
427 | handled = true; | ||
428 | } | ||
429 | |||
430 | spin_unlock_irqrestore(&port->lock, flags); | ||
431 | out: | ||
432 | return IRQ_RETVAL(handled); | ||
413 | } | 433 | } |
414 | 434 | ||
415 | /** | 435 | /** |
@@ -464,21 +484,37 @@ static unsigned int men_z135_tx_empty(struct uart_port *port) | |||
464 | */ | 484 | */ |
465 | static void men_z135_set_mctrl(struct uart_port *port, unsigned int mctrl) | 485 | static void men_z135_set_mctrl(struct uart_port *port, unsigned int mctrl) |
466 | { | 486 | { |
467 | struct men_z135_port *uart = to_men_z135(port); | 487 | u32 old; |
468 | u32 conf_reg = 0; | 488 | u32 conf_reg; |
469 | 489 | ||
490 | conf_reg = old = ioread32(port->membase + MEN_Z135_CONF_REG); | ||
470 | if (mctrl & TIOCM_RTS) | 491 | if (mctrl & TIOCM_RTS) |
471 | conf_reg |= MEN_Z135_MCR_RTS; | 492 | conf_reg |= MEN_Z135_MCR_RTS; |
493 | else | ||
494 | conf_reg &= ~MEN_Z135_MCR_RTS; | ||
495 | |||
472 | if (mctrl & TIOCM_DTR) | 496 | if (mctrl & TIOCM_DTR) |
473 | conf_reg |= MEN_Z135_MCR_DTR; | 497 | conf_reg |= MEN_Z135_MCR_DTR; |
498 | else | ||
499 | conf_reg &= ~MEN_Z135_MCR_DTR; | ||
500 | |||
474 | if (mctrl & TIOCM_OUT1) | 501 | if (mctrl & TIOCM_OUT1) |
475 | conf_reg |= MEN_Z135_MCR_OUT1; | 502 | conf_reg |= MEN_Z135_MCR_OUT1; |
503 | else | ||
504 | conf_reg &= ~MEN_Z135_MCR_OUT1; | ||
505 | |||
476 | if (mctrl & TIOCM_OUT2) | 506 | if (mctrl & TIOCM_OUT2) |
477 | conf_reg |= MEN_Z135_MCR_OUT2; | 507 | conf_reg |= MEN_Z135_MCR_OUT2; |
508 | else | ||
509 | conf_reg &= ~MEN_Z135_MCR_OUT2; | ||
510 | |||
478 | if (mctrl & TIOCM_LOOP) | 511 | if (mctrl & TIOCM_LOOP) |
479 | conf_reg |= MEN_Z135_MCR_LOOP; | 512 | conf_reg |= MEN_Z135_MCR_LOOP; |
513 | else | ||
514 | conf_reg &= ~MEN_Z135_MCR_LOOP; | ||
480 | 515 | ||
481 | men_z135_reg_set(uart, MEN_Z135_CONF_REG, conf_reg); | 516 | if (conf_reg != old) |
517 | iowrite32(conf_reg, port->membase + MEN_Z135_CONF_REG); | ||
482 | } | 518 | } |
483 | 519 | ||
484 | /** | 520 | /** |
@@ -490,12 +526,9 @@ static void men_z135_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
490 | static unsigned int men_z135_get_mctrl(struct uart_port *port) | 526 | static unsigned int men_z135_get_mctrl(struct uart_port *port) |
491 | { | 527 | { |
492 | unsigned int mctrl = 0; | 528 | unsigned int mctrl = 0; |
493 | u32 stat_reg; | ||
494 | u8 msr; | 529 | u8 msr; |
495 | 530 | ||
496 | stat_reg = ioread32(port->membase + MEN_Z135_STAT_REG); | 531 | msr = ioread8(port->membase + MEN_Z135_STAT_REG + 1); |
497 | |||
498 | msr = ~((stat_reg >> 8) & 0xff); | ||
499 | 532 | ||
500 | if (msr & MEN_Z135_MSR_CTS) | 533 | if (msr & MEN_Z135_MSR_CTS) |
501 | mctrl |= TIOCM_CTS; | 534 | mctrl |= TIOCM_CTS; |
@@ -524,6 +557,19 @@ static void men_z135_stop_tx(struct uart_port *port) | |||
524 | men_z135_reg_clr(uart, MEN_Z135_CONF_REG, MEN_Z135_IER_TXCIEN); | 557 | men_z135_reg_clr(uart, MEN_Z135_CONF_REG, MEN_Z135_IER_TXCIEN); |
525 | } | 558 | } |
526 | 559 | ||
560 | /* | ||
561 | * men_z135_disable_ms() - Disable Modem Status | ||
562 | * port: The UART port | ||
563 | * | ||
564 | * Enable Modem Status IRQ. | ||
565 | */ | ||
566 | static void men_z135_disable_ms(struct uart_port *port) | ||
567 | { | ||
568 | struct men_z135_port *uart = to_men_z135(port); | ||
569 | |||
570 | men_z135_reg_clr(uart, MEN_Z135_CONF_REG, MEN_Z135_IER_MSIEN); | ||
571 | } | ||
572 | |||
527 | /** | 573 | /** |
528 | * men_z135_start_tx() - Start transmitting characters | 574 | * men_z135_start_tx() - Start transmitting characters |
529 | * @port: The UART port | 575 | * @port: The UART port |
@@ -535,6 +581,9 @@ static void men_z135_start_tx(struct uart_port *port) | |||
535 | { | 581 | { |
536 | struct men_z135_port *uart = to_men_z135(port); | 582 | struct men_z135_port *uart = to_men_z135(port); |
537 | 583 | ||
584 | if (uart->automode) | ||
585 | men_z135_disable_ms(port); | ||
586 | |||
538 | men_z135_handle_tx(uart); | 587 | men_z135_handle_tx(uart); |
539 | } | 588 | } |
540 | 589 | ||
@@ -584,6 +633,9 @@ static int men_z135_startup(struct uart_port *port) | |||
584 | 633 | ||
585 | iowrite32(conf_reg, port->membase + MEN_Z135_CONF_REG); | 634 | iowrite32(conf_reg, port->membase + MEN_Z135_CONF_REG); |
586 | 635 | ||
636 | if (rx_timeout) | ||
637 | iowrite32(rx_timeout, port->membase + MEN_Z135_TIMEOUT); | ||
638 | |||
587 | return 0; | 639 | return 0; |
588 | } | 640 | } |
589 | 641 | ||
@@ -603,6 +655,7 @@ static void men_z135_set_termios(struct uart_port *port, | |||
603 | struct ktermios *termios, | 655 | struct ktermios *termios, |
604 | struct ktermios *old) | 656 | struct ktermios *old) |
605 | { | 657 | { |
658 | struct men_z135_port *uart = to_men_z135(port); | ||
606 | unsigned int baud; | 659 | unsigned int baud; |
607 | u32 conf_reg; | 660 | u32 conf_reg; |
608 | u32 bd_reg; | 661 | u32 bd_reg; |
@@ -643,6 +696,16 @@ static void men_z135_set_termios(struct uart_port *port, | |||
643 | } else | 696 | } else |
644 | lcr |= MEN_Z135_PAR_DIS << MEN_Z135_PEN_SHIFT; | 697 | lcr |= MEN_Z135_PAR_DIS << MEN_Z135_PEN_SHIFT; |
645 | 698 | ||
699 | conf_reg |= MEN_Z135_IER_MSIEN; | ||
700 | if (termios->c_cflag & CRTSCTS) { | ||
701 | conf_reg |= MEN_Z135_MCR_RCFC; | ||
702 | uart->automode = true; | ||
703 | termios->c_cflag &= ~CLOCAL; | ||
704 | } else { | ||
705 | conf_reg &= ~MEN_Z135_MCR_RCFC; | ||
706 | uart->automode = false; | ||
707 | } | ||
708 | |||
646 | termios->c_cflag &= ~CMSPAR; /* Mark/Space parity is not supported */ | 709 | termios->c_cflag &= ~CMSPAR; /* Mark/Space parity is not supported */ |
647 | 710 | ||
648 | conf_reg |= lcr << MEN_Z135_LCR_SHIFT; | 711 | conf_reg |= lcr << MEN_Z135_LCR_SHIFT; |
diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c deleted file mode 100644 index 77239d5e620d..000000000000 --- a/drivers/tty/serial/mrst_max3110.c +++ /dev/null | |||
@@ -1,909 +0,0 @@ | |||
1 | /* | ||
2 | * mrst_max3110.c - spi uart protocol driver for Maxim 3110 | ||
3 | * | ||
4 | * Copyright (c) 2008-2010, Intel Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along with | ||
16 | * this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | */ | ||
19 | |||
20 | /* | ||
21 | * Note: | ||
22 | * 1. From Max3110 spec, the Rx FIFO has 8 words, while the Tx FIFO only has | ||
23 | * 1 word. If SPI master controller doesn't support sclk frequency change, | ||
24 | * then the char need be sent out one by one with some delay | ||
25 | * | ||
26 | * 2. Currently only RX available interrupt is used, no need for waiting TXE | ||
27 | * interrupt for a low speed UART device | ||
28 | */ | ||
29 | |||
30 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
31 | |||
32 | #ifdef CONFIG_MAGIC_SYSRQ | ||
33 | #define SUPPORT_SYSRQ | ||
34 | #endif | ||
35 | |||
36 | #include <linux/module.h> | ||
37 | #include <linux/ioport.h> | ||
38 | #include <linux/irq.h> | ||
39 | #include <linux/init.h> | ||
40 | #include <linux/console.h> | ||
41 | #include <linux/tty.h> | ||
42 | #include <linux/tty_flip.h> | ||
43 | #include <linux/serial_core.h> | ||
44 | #include <linux/serial_reg.h> | ||
45 | |||
46 | #include <linux/kthread.h> | ||
47 | #include <linux/spi/spi.h> | ||
48 | #include <linux/pm.h> | ||
49 | |||
50 | #include "mrst_max3110.h" | ||
51 | |||
52 | #define UART_TX_NEEDED 1 | ||
53 | #define CON_TX_NEEDED 2 | ||
54 | #define BIT_IRQ_PENDING 3 | ||
55 | |||
56 | struct uart_max3110 { | ||
57 | struct uart_port port; | ||
58 | struct spi_device *spi; | ||
59 | char name[SPI_NAME_SIZE]; | ||
60 | |||
61 | wait_queue_head_t wq; | ||
62 | struct task_struct *main_thread; | ||
63 | struct task_struct *read_thread; | ||
64 | struct mutex thread_mutex; | ||
65 | struct mutex io_mutex; | ||
66 | |||
67 | u32 baud; | ||
68 | u16 cur_conf; | ||
69 | u8 clock; | ||
70 | u8 parity, word_7bits; | ||
71 | u16 irq; | ||
72 | |||
73 | unsigned long uart_flags; | ||
74 | |||
75 | /* console related */ | ||
76 | struct circ_buf con_xmit; | ||
77 | }; | ||
78 | |||
79 | /* global data structure, may need be removed */ | ||
80 | static struct uart_max3110 *pmax; | ||
81 | |||
82 | static int receive_chars(struct uart_max3110 *max, | ||
83 | unsigned short *str, int len); | ||
84 | static int max3110_read_multi(struct uart_max3110 *max); | ||
85 | static void max3110_con_receive(struct uart_max3110 *max); | ||
86 | |||
87 | static int max3110_write_then_read(struct uart_max3110 *max, | ||
88 | const void *txbuf, void *rxbuf, unsigned len, int always_fast) | ||
89 | { | ||
90 | struct spi_device *spi = max->spi; | ||
91 | struct spi_message message; | ||
92 | struct spi_transfer x; | ||
93 | int ret; | ||
94 | |||
95 | mutex_lock(&max->io_mutex); | ||
96 | spi_message_init(&message); | ||
97 | memset(&x, 0, sizeof x); | ||
98 | x.len = len; | ||
99 | x.tx_buf = txbuf; | ||
100 | x.rx_buf = rxbuf; | ||
101 | spi_message_add_tail(&x, &message); | ||
102 | |||
103 | if (always_fast) | ||
104 | x.speed_hz = spi->max_speed_hz; | ||
105 | else if (max->baud) | ||
106 | x.speed_hz = max->baud; | ||
107 | |||
108 | /* Do the i/o */ | ||
109 | ret = spi_sync(spi, &message); | ||
110 | mutex_unlock(&max->io_mutex); | ||
111 | return ret; | ||
112 | } | ||
113 | |||
114 | /* Write a 16b word to the device */ | ||
115 | static int max3110_out(struct uart_max3110 *max, const u16 out) | ||
116 | { | ||
117 | void *buf; | ||
118 | u16 *obuf, *ibuf; | ||
119 | int ret; | ||
120 | |||
121 | buf = kzalloc(8, GFP_KERNEL | GFP_DMA); | ||
122 | if (!buf) | ||
123 | return -ENOMEM; | ||
124 | |||
125 | obuf = buf; | ||
126 | ibuf = buf + 4; | ||
127 | *obuf = out; | ||
128 | ret = max3110_write_then_read(max, obuf, ibuf, 2, 1); | ||
129 | if (ret) { | ||
130 | pr_warn("%s: get err msg %d when sending 0x%x\n", | ||
131 | __func__, ret, out); | ||
132 | goto exit; | ||
133 | } | ||
134 | |||
135 | receive_chars(max, ibuf, 1); | ||
136 | |||
137 | exit: | ||
138 | kfree(buf); | ||
139 | return ret; | ||
140 | } | ||
141 | |||
142 | /* | ||
143 | * This is usually used to read data from SPIC RX FIFO, which doesn't | ||
144 | * need any delay like flushing character out. | ||
145 | * | ||
146 | * Return how many valide bytes are read back | ||
147 | */ | ||
148 | static int max3110_read_multi(struct uart_max3110 *max) | ||
149 | { | ||
150 | void *buf; | ||
151 | u16 *obuf, *ibuf; | ||
152 | int ret, blen; | ||
153 | |||
154 | blen = M3110_RX_FIFO_DEPTH * sizeof(u16); | ||
155 | buf = kzalloc(blen * 2, GFP_KERNEL | GFP_DMA); | ||
156 | if (!buf) | ||
157 | return 0; | ||
158 | |||
159 | /* tx/rx always have the same length */ | ||
160 | obuf = buf; | ||
161 | ibuf = buf + blen; | ||
162 | |||
163 | if (max3110_write_then_read(max, obuf, ibuf, blen, 1)) { | ||
164 | kfree(buf); | ||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | ret = receive_chars(max, ibuf, M3110_RX_FIFO_DEPTH); | ||
169 | |||
170 | kfree(buf); | ||
171 | return ret; | ||
172 | } | ||
173 | |||
174 | static void serial_m3110_con_putchar(struct uart_port *port, int ch) | ||
175 | { | ||
176 | struct uart_max3110 *max = | ||
177 | container_of(port, struct uart_max3110, port); | ||
178 | struct circ_buf *xmit = &max->con_xmit; | ||
179 | |||
180 | if (uart_circ_chars_free(xmit)) { | ||
181 | xmit->buf[xmit->head] = (char)ch; | ||
182 | xmit->head = (xmit->head + 1) & (PAGE_SIZE - 1); | ||
183 | } | ||
184 | } | ||
185 | |||
186 | /* | ||
187 | * Print a string to the serial port trying not to disturb | ||
188 | * any possible real use of the port... | ||
189 | * | ||
190 | * The console_lock must be held when we get here. | ||
191 | */ | ||
192 | static void serial_m3110_con_write(struct console *co, | ||
193 | const char *s, unsigned int count) | ||
194 | { | ||
195 | if (!pmax) | ||
196 | return; | ||
197 | |||
198 | uart_console_write(&pmax->port, s, count, serial_m3110_con_putchar); | ||
199 | |||
200 | if (!test_and_set_bit(CON_TX_NEEDED, &pmax->uart_flags)) | ||
201 | wake_up(&pmax->wq); | ||
202 | } | ||
203 | |||
204 | static int __init | ||
205 | serial_m3110_con_setup(struct console *co, char *options) | ||
206 | { | ||
207 | struct uart_max3110 *max = pmax; | ||
208 | int baud = 115200; | ||
209 | int bits = 8; | ||
210 | int parity = 'n'; | ||
211 | int flow = 'n'; | ||
212 | |||
213 | pr_info("setting up console\n"); | ||
214 | |||
215 | if (co->index == -1) | ||
216 | co->index = 0; | ||
217 | |||
218 | if (!max) { | ||
219 | pr_err("pmax is NULL, return\n"); | ||
220 | return -ENODEV; | ||
221 | } | ||
222 | |||
223 | if (options) | ||
224 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
225 | |||
226 | return uart_set_options(&max->port, co, baud, parity, bits, flow); | ||
227 | } | ||
228 | |||
229 | static struct tty_driver *serial_m3110_con_device(struct console *co, | ||
230 | int *index) | ||
231 | { | ||
232 | struct uart_driver *p = co->data; | ||
233 | *index = co->index; | ||
234 | return p->tty_driver; | ||
235 | } | ||
236 | |||
237 | static struct uart_driver serial_m3110_reg; | ||
238 | static struct console serial_m3110_console = { | ||
239 | .name = "ttyS", | ||
240 | .write = serial_m3110_con_write, | ||
241 | .device = serial_m3110_con_device, | ||
242 | .setup = serial_m3110_con_setup, | ||
243 | .flags = CON_PRINTBUFFER, | ||
244 | .index = -1, | ||
245 | .data = &serial_m3110_reg, | ||
246 | }; | ||
247 | |||
248 | static unsigned int serial_m3110_tx_empty(struct uart_port *port) | ||
249 | { | ||
250 | return 1; | ||
251 | } | ||
252 | |||
253 | static void serial_m3110_stop_tx(struct uart_port *port) | ||
254 | { | ||
255 | return; | ||
256 | } | ||
257 | |||
258 | /* stop_rx will be called in spin_lock env */ | ||
259 | static void serial_m3110_stop_rx(struct uart_port *port) | ||
260 | { | ||
261 | return; | ||
262 | } | ||
263 | |||
264 | #define WORDS_PER_XFER 128 | ||
265 | static void send_circ_buf(struct uart_max3110 *max, | ||
266 | struct circ_buf *xmit) | ||
267 | { | ||
268 | void *buf; | ||
269 | u16 *obuf, *ibuf; | ||
270 | int i, len, blen, dma_size, left, ret = 0; | ||
271 | |||
272 | |||
273 | dma_size = WORDS_PER_XFER * sizeof(u16) * 2; | ||
274 | buf = kzalloc(dma_size, GFP_KERNEL | GFP_DMA); | ||
275 | if (!buf) | ||
276 | return; | ||
277 | obuf = buf; | ||
278 | ibuf = buf + dma_size/2; | ||
279 | |||
280 | while (!uart_circ_empty(xmit)) { | ||
281 | left = uart_circ_chars_pending(xmit); | ||
282 | while (left) { | ||
283 | len = min(left, WORDS_PER_XFER); | ||
284 | blen = len * sizeof(u16); | ||
285 | memset(ibuf, 0, blen); | ||
286 | |||
287 | for (i = 0; i < len; i++) { | ||
288 | obuf[i] = (u8)xmit->buf[xmit->tail] | WD_TAG; | ||
289 | xmit->tail = (xmit->tail + 1) & | ||
290 | (UART_XMIT_SIZE - 1); | ||
291 | } | ||
292 | |||
293 | /* Fail to send msg to console is not very critical */ | ||
294 | |||
295 | ret = max3110_write_then_read(max, obuf, ibuf, blen, 0); | ||
296 | if (ret) | ||
297 | pr_warn("%s: get err msg %d\n", __func__, ret); | ||
298 | |||
299 | receive_chars(max, ibuf, len); | ||
300 | |||
301 | max->port.icount.tx += len; | ||
302 | left -= len; | ||
303 | } | ||
304 | } | ||
305 | |||
306 | kfree(buf); | ||
307 | } | ||
308 | |||
309 | static void transmit_char(struct uart_max3110 *max) | ||
310 | { | ||
311 | struct uart_port *port = &max->port; | ||
312 | struct circ_buf *xmit = &port->state->xmit; | ||
313 | |||
314 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) | ||
315 | return; | ||
316 | |||
317 | send_circ_buf(max, xmit); | ||
318 | |||
319 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
320 | uart_write_wakeup(port); | ||
321 | |||
322 | if (uart_circ_empty(xmit)) | ||
323 | serial_m3110_stop_tx(port); | ||
324 | } | ||
325 | |||
326 | /* | ||
327 | * This will be called by uart_write() and tty_write, can't | ||
328 | * go to sleep | ||
329 | */ | ||
330 | static void serial_m3110_start_tx(struct uart_port *port) | ||
331 | { | ||
332 | struct uart_max3110 *max = | ||
333 | container_of(port, struct uart_max3110, port); | ||
334 | |||
335 | if (!test_and_set_bit(UART_TX_NEEDED, &max->uart_flags)) | ||
336 | wake_up(&max->wq); | ||
337 | } | ||
338 | |||
339 | static int | ||
340 | receive_chars(struct uart_max3110 *max, unsigned short *str, int len) | ||
341 | { | ||
342 | struct uart_port *port = &max->port; | ||
343 | struct tty_port *tport; | ||
344 | char buf[M3110_RX_FIFO_DEPTH]; | ||
345 | int r, w, usable; | ||
346 | |||
347 | /* If uart is not opened, just return */ | ||
348 | if (!port->state) | ||
349 | return 0; | ||
350 | |||
351 | tport = &port->state->port; | ||
352 | |||
353 | for (r = 0, w = 0; r < len; r++) { | ||
354 | if (str[r] & MAX3110_BREAK && | ||
355 | uart_handle_break(port)) | ||
356 | continue; | ||
357 | |||
358 | if (str[r] & MAX3110_READ_DATA_AVAILABLE) { | ||
359 | if (uart_handle_sysrq_char(port, str[r] & 0xff)) | ||
360 | continue; | ||
361 | |||
362 | buf[w++] = str[r] & 0xff; | ||
363 | } | ||
364 | } | ||
365 | |||
366 | if (!w) | ||
367 | return 0; | ||
368 | |||
369 | for (r = 0; w; r += usable, w -= usable) { | ||
370 | usable = tty_buffer_request_room(tport, w); | ||
371 | if (usable) { | ||
372 | tty_insert_flip_string(tport, buf + r, usable); | ||
373 | port->icount.rx += usable; | ||
374 | } | ||
375 | } | ||
376 | tty_flip_buffer_push(tport); | ||
377 | |||
378 | return r; | ||
379 | } | ||
380 | |||
381 | /* | ||
382 | * This routine will be used in read_thread or RX IRQ handling, | ||
383 | * it will first do one round buffer read(8 words), if there is some | ||
384 | * valid RX data, will try to read 5 more rounds till all data | ||
385 | * is read out. | ||
386 | * | ||
387 | * Use stack space as data buffer to save some system load, and chose | ||
388 | * 504 Btyes as a threadhold to do a bulk push to upper tty layer when | ||
389 | * receiving bulk data, a much bigger buffer may cause stack overflow | ||
390 | */ | ||
391 | static void max3110_con_receive(struct uart_max3110 *max) | ||
392 | { | ||
393 | int loop = 1, num; | ||
394 | |||
395 | do { | ||
396 | num = max3110_read_multi(max); | ||
397 | |||
398 | if (num) { | ||
399 | loop = 5; | ||
400 | } | ||
401 | } while (--loop); | ||
402 | } | ||
403 | |||
404 | static int max3110_main_thread(void *_max) | ||
405 | { | ||
406 | struct uart_max3110 *max = _max; | ||
407 | wait_queue_head_t *wq = &max->wq; | ||
408 | int ret = 0; | ||
409 | struct circ_buf *xmit = &max->con_xmit; | ||
410 | |||
411 | pr_info("start main thread\n"); | ||
412 | |||
413 | do { | ||
414 | wait_event_interruptible(*wq, | ||
415 | max->uart_flags || kthread_should_stop()); | ||
416 | |||
417 | mutex_lock(&max->thread_mutex); | ||
418 | |||
419 | if (test_and_clear_bit(BIT_IRQ_PENDING, &max->uart_flags)) | ||
420 | max3110_con_receive(max); | ||
421 | |||
422 | /* first handle console output */ | ||
423 | if (test_and_clear_bit(CON_TX_NEEDED, &max->uart_flags)) | ||
424 | send_circ_buf(max, xmit); | ||
425 | |||
426 | /* handle uart output */ | ||
427 | if (test_and_clear_bit(UART_TX_NEEDED, &max->uart_flags)) | ||
428 | transmit_char(max); | ||
429 | |||
430 | mutex_unlock(&max->thread_mutex); | ||
431 | |||
432 | } while (!kthread_should_stop()); | ||
433 | |||
434 | return ret; | ||
435 | } | ||
436 | |||
437 | static irqreturn_t serial_m3110_irq(int irq, void *dev_id) | ||
438 | { | ||
439 | struct uart_max3110 *max = dev_id; | ||
440 | |||
441 | /* max3110's irq is a falling edge, not level triggered, | ||
442 | * so no need to disable the irq */ | ||
443 | |||
444 | if (!test_and_set_bit(BIT_IRQ_PENDING, &max->uart_flags)) | ||
445 | wake_up(&max->wq); | ||
446 | |||
447 | return IRQ_HANDLED; | ||
448 | } | ||
449 | |||
450 | /* if don't use RX IRQ, then need a thread to polling read */ | ||
451 | static int max3110_read_thread(void *_max) | ||
452 | { | ||
453 | struct uart_max3110 *max = _max; | ||
454 | |||
455 | pr_info("start read thread\n"); | ||
456 | do { | ||
457 | /* | ||
458 | * If can't acquire the mutex, it means the main thread | ||
459 | * is running which will also perform the rx job | ||
460 | */ | ||
461 | if (mutex_trylock(&max->thread_mutex)) { | ||
462 | max3110_con_receive(max); | ||
463 | mutex_unlock(&max->thread_mutex); | ||
464 | } | ||
465 | |||
466 | set_current_state(TASK_INTERRUPTIBLE); | ||
467 | schedule_timeout(HZ / 20); | ||
468 | } while (!kthread_should_stop()); | ||
469 | |||
470 | return 0; | ||
471 | } | ||
472 | |||
473 | static int serial_m3110_startup(struct uart_port *port) | ||
474 | { | ||
475 | struct uart_max3110 *max = | ||
476 | container_of(port, struct uart_max3110, port); | ||
477 | u16 config = 0; | ||
478 | int ret = 0; | ||
479 | |||
480 | if (port->line != 0) { | ||
481 | pr_err("uart port startup failed\n"); | ||
482 | return -1; | ||
483 | } | ||
484 | |||
485 | /* Disable all IRQ and config it to 115200, 8n1 */ | ||
486 | config = WC_TAG | WC_FIFO_ENABLE | ||
487 | | WC_1_STOPBITS | ||
488 | | WC_8BIT_WORD | ||
489 | | WC_BAUD_DR2; | ||
490 | |||
491 | /* as we use thread to handle tx/rx, need set low latency */ | ||
492 | port->state->port.low_latency = 1; | ||
493 | |||
494 | if (max->irq) { | ||
495 | /* Enable RX IRQ only */ | ||
496 | config |= WC_RXA_IRQ_ENABLE; | ||
497 | } else { | ||
498 | /* If IRQ is disabled, start a read thread for input data */ | ||
499 | max->read_thread = | ||
500 | kthread_run(max3110_read_thread, max, "max3110_read"); | ||
501 | if (IS_ERR(max->read_thread)) { | ||
502 | ret = PTR_ERR(max->read_thread); | ||
503 | max->read_thread = NULL; | ||
504 | pr_err("Can't create read thread!\n"); | ||
505 | return ret; | ||
506 | } | ||
507 | } | ||
508 | |||
509 | ret = max3110_out(max, config); | ||
510 | if (ret) { | ||
511 | if (max->read_thread) | ||
512 | kthread_stop(max->read_thread); | ||
513 | max->read_thread = NULL; | ||
514 | return ret; | ||
515 | } | ||
516 | |||
517 | max->cur_conf = config; | ||
518 | return 0; | ||
519 | } | ||
520 | |||
521 | static void serial_m3110_shutdown(struct uart_port *port) | ||
522 | { | ||
523 | struct uart_max3110 *max = | ||
524 | container_of(port, struct uart_max3110, port); | ||
525 | u16 config; | ||
526 | |||
527 | if (max->read_thread) { | ||
528 | kthread_stop(max->read_thread); | ||
529 | max->read_thread = NULL; | ||
530 | } | ||
531 | |||
532 | /* Disable interrupts from this port */ | ||
533 | config = WC_TAG | WC_SW_SHDI; | ||
534 | max3110_out(max, config); | ||
535 | } | ||
536 | |||
537 | static void serial_m3110_release_port(struct uart_port *port) | ||
538 | { | ||
539 | } | ||
540 | |||
541 | static int serial_m3110_request_port(struct uart_port *port) | ||
542 | { | ||
543 | return 0; | ||
544 | } | ||
545 | |||
546 | static void serial_m3110_config_port(struct uart_port *port, int flags) | ||
547 | { | ||
548 | port->type = PORT_MAX3100; | ||
549 | } | ||
550 | |||
551 | static int | ||
552 | serial_m3110_verify_port(struct uart_port *port, struct serial_struct *ser) | ||
553 | { | ||
554 | /* we don't want the core code to modify any port params */ | ||
555 | return -EINVAL; | ||
556 | } | ||
557 | |||
558 | |||
559 | static const char *serial_m3110_type(struct uart_port *port) | ||
560 | { | ||
561 | struct uart_max3110 *max = | ||
562 | container_of(port, struct uart_max3110, port); | ||
563 | return max->name; | ||
564 | } | ||
565 | |||
566 | static void | ||
567 | serial_m3110_set_termios(struct uart_port *port, struct ktermios *termios, | ||
568 | struct ktermios *old) | ||
569 | { | ||
570 | struct uart_max3110 *max = | ||
571 | container_of(port, struct uart_max3110, port); | ||
572 | unsigned char cval; | ||
573 | unsigned int baud, parity = 0; | ||
574 | int clk_div = -1; | ||
575 | u16 new_conf = max->cur_conf; | ||
576 | |||
577 | switch (termios->c_cflag & CSIZE) { | ||
578 | case CS7: | ||
579 | cval = UART_LCR_WLEN7; | ||
580 | new_conf |= WC_7BIT_WORD; | ||
581 | break; | ||
582 | default: | ||
583 | /* We only support CS7 & CS8 */ | ||
584 | termios->c_cflag &= ~CSIZE; | ||
585 | termios->c_cflag |= CS8; | ||
586 | case CS8: | ||
587 | cval = UART_LCR_WLEN8; | ||
588 | new_conf |= WC_8BIT_WORD; | ||
589 | break; | ||
590 | } | ||
591 | |||
592 | baud = uart_get_baud_rate(port, termios, old, 0, 230400); | ||
593 | |||
594 | /* First calc the div for 1.8MHZ clock case */ | ||
595 | switch (baud) { | ||
596 | case 300: | ||
597 | clk_div = WC_BAUD_DR384; | ||
598 | break; | ||
599 | case 600: | ||
600 | clk_div = WC_BAUD_DR192; | ||
601 | break; | ||
602 | case 1200: | ||
603 | clk_div = WC_BAUD_DR96; | ||
604 | break; | ||
605 | case 2400: | ||
606 | clk_div = WC_BAUD_DR48; | ||
607 | break; | ||
608 | case 4800: | ||
609 | clk_div = WC_BAUD_DR24; | ||
610 | break; | ||
611 | case 9600: | ||
612 | clk_div = WC_BAUD_DR12; | ||
613 | break; | ||
614 | case 19200: | ||
615 | clk_div = WC_BAUD_DR6; | ||
616 | break; | ||
617 | case 38400: | ||
618 | clk_div = WC_BAUD_DR3; | ||
619 | break; | ||
620 | case 57600: | ||
621 | clk_div = WC_BAUD_DR2; | ||
622 | break; | ||
623 | case 115200: | ||
624 | clk_div = WC_BAUD_DR1; | ||
625 | break; | ||
626 | case 230400: | ||
627 | if (max->clock & MAX3110_HIGH_CLK) | ||
628 | break; | ||
629 | default: | ||
630 | /* Pick the previous baud rate */ | ||
631 | baud = max->baud; | ||
632 | clk_div = max->cur_conf & WC_BAUD_DIV_MASK; | ||
633 | tty_termios_encode_baud_rate(termios, baud, baud); | ||
634 | } | ||
635 | |||
636 | if (max->clock & MAX3110_HIGH_CLK) { | ||
637 | clk_div += 1; | ||
638 | /* High clk version max3110 doesn't support B300 */ | ||
639 | if (baud == 300) { | ||
640 | baud = 600; | ||
641 | clk_div = WC_BAUD_DR384; | ||
642 | } | ||
643 | if (baud == 230400) | ||
644 | clk_div = WC_BAUD_DR1; | ||
645 | tty_termios_encode_baud_rate(termios, baud, baud); | ||
646 | } | ||
647 | |||
648 | new_conf = (new_conf & ~WC_BAUD_DIV_MASK) | clk_div; | ||
649 | |||
650 | if (unlikely(termios->c_cflag & CMSPAR)) | ||
651 | termios->c_cflag &= ~CMSPAR; | ||
652 | |||
653 | if (termios->c_cflag & CSTOPB) | ||
654 | new_conf |= WC_2_STOPBITS; | ||
655 | else | ||
656 | new_conf &= ~WC_2_STOPBITS; | ||
657 | |||
658 | if (termios->c_cflag & PARENB) { | ||
659 | new_conf |= WC_PARITY_ENABLE; | ||
660 | parity |= UART_LCR_PARITY; | ||
661 | } else | ||
662 | new_conf &= ~WC_PARITY_ENABLE; | ||
663 | |||
664 | if (!(termios->c_cflag & PARODD)) | ||
665 | parity |= UART_LCR_EPAR; | ||
666 | max->parity = parity; | ||
667 | |||
668 | uart_update_timeout(port, termios->c_cflag, baud); | ||
669 | |||
670 | new_conf |= WC_TAG; | ||
671 | if (new_conf != max->cur_conf) { | ||
672 | if (!max3110_out(max, new_conf)) { | ||
673 | max->cur_conf = new_conf; | ||
674 | max->baud = baud; | ||
675 | } | ||
676 | } | ||
677 | } | ||
678 | |||
679 | /* Don't handle hw handshaking */ | ||
680 | static unsigned int serial_m3110_get_mctrl(struct uart_port *port) | ||
681 | { | ||
682 | return TIOCM_DSR | TIOCM_CAR | TIOCM_DSR; | ||
683 | } | ||
684 | |||
685 | static void serial_m3110_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
686 | { | ||
687 | } | ||
688 | |||
689 | static void serial_m3110_break_ctl(struct uart_port *port, int break_state) | ||
690 | { | ||
691 | } | ||
692 | |||
693 | static void serial_m3110_pm(struct uart_port *port, unsigned int state, | ||
694 | unsigned int oldstate) | ||
695 | { | ||
696 | } | ||
697 | |||
698 | static struct uart_ops serial_m3110_ops = { | ||
699 | .tx_empty = serial_m3110_tx_empty, | ||
700 | .set_mctrl = serial_m3110_set_mctrl, | ||
701 | .get_mctrl = serial_m3110_get_mctrl, | ||
702 | .stop_tx = serial_m3110_stop_tx, | ||
703 | .start_tx = serial_m3110_start_tx, | ||
704 | .stop_rx = serial_m3110_stop_rx, | ||
705 | .break_ctl = serial_m3110_break_ctl, | ||
706 | .startup = serial_m3110_startup, | ||
707 | .shutdown = serial_m3110_shutdown, | ||
708 | .set_termios = serial_m3110_set_termios, | ||
709 | .pm = serial_m3110_pm, | ||
710 | .type = serial_m3110_type, | ||
711 | .release_port = serial_m3110_release_port, | ||
712 | .request_port = serial_m3110_request_port, | ||
713 | .config_port = serial_m3110_config_port, | ||
714 | .verify_port = serial_m3110_verify_port, | ||
715 | }; | ||
716 | |||
717 | static struct uart_driver serial_m3110_reg = { | ||
718 | .owner = THIS_MODULE, | ||
719 | .driver_name = "MRST serial", | ||
720 | .dev_name = "ttyS", | ||
721 | .major = TTY_MAJOR, | ||
722 | .minor = 64, | ||
723 | .nr = 1, | ||
724 | .cons = &serial_m3110_console, | ||
725 | }; | ||
726 | |||
727 | #ifdef CONFIG_PM_SLEEP | ||
728 | static int serial_m3110_suspend(struct device *dev) | ||
729 | { | ||
730 | struct spi_device *spi = to_spi_device(dev); | ||
731 | struct uart_max3110 *max = spi_get_drvdata(spi); | ||
732 | |||
733 | if (max->irq > 0) | ||
734 | disable_irq(max->irq); | ||
735 | uart_suspend_port(&serial_m3110_reg, &max->port); | ||
736 | max3110_out(max, max->cur_conf | WC_SW_SHDI); | ||
737 | return 0; | ||
738 | } | ||
739 | |||
740 | static int serial_m3110_resume(struct device *dev) | ||
741 | { | ||
742 | struct spi_device *spi = to_spi_device(dev); | ||
743 | struct uart_max3110 *max = spi_get_drvdata(spi); | ||
744 | |||
745 | max3110_out(max, max->cur_conf); | ||
746 | uart_resume_port(&serial_m3110_reg, &max->port); | ||
747 | if (max->irq > 0) | ||
748 | enable_irq(max->irq); | ||
749 | return 0; | ||
750 | } | ||
751 | |||
752 | static SIMPLE_DEV_PM_OPS(serial_m3110_pm_ops, serial_m3110_suspend, | ||
753 | serial_m3110_resume); | ||
754 | #define SERIAL_M3110_PM_OPS (&serial_m3110_pm_ops) | ||
755 | |||
756 | #else | ||
757 | #define SERIAL_M3110_PM_OPS NULL | ||
758 | #endif | ||
759 | |||
760 | static int serial_m3110_probe(struct spi_device *spi) | ||
761 | { | ||
762 | struct uart_max3110 *max; | ||
763 | void *buffer; | ||
764 | u16 res; | ||
765 | int ret = 0; | ||
766 | |||
767 | max = kzalloc(sizeof(*max), GFP_KERNEL); | ||
768 | if (!max) | ||
769 | return -ENOMEM; | ||
770 | |||
771 | /* Set spi info */ | ||
772 | spi->bits_per_word = 16; | ||
773 | max->clock = MAX3110_HIGH_CLK; | ||
774 | |||
775 | spi_setup(spi); | ||
776 | |||
777 | max->port.type = PORT_MAX3100; | ||
778 | max->port.fifosize = 2; /* Only have 16b buffer */ | ||
779 | max->port.ops = &serial_m3110_ops; | ||
780 | max->port.line = 0; | ||
781 | max->port.dev = &spi->dev; | ||
782 | max->port.uartclk = 115200; | ||
783 | |||
784 | max->spi = spi; | ||
785 | strcpy(max->name, spi->modalias); | ||
786 | max->irq = (u16)spi->irq; | ||
787 | |||
788 | mutex_init(&max->thread_mutex); | ||
789 | mutex_init(&max->io_mutex); | ||
790 | |||
791 | max->word_7bits = 0; | ||
792 | max->parity = 0; | ||
793 | max->baud = 0; | ||
794 | |||
795 | max->cur_conf = 0; | ||
796 | max->uart_flags = 0; | ||
797 | |||
798 | /* Check if reading configuration register returns something sane */ | ||
799 | |||
800 | res = RC_TAG; | ||
801 | ret = max3110_write_then_read(max, (u8 *)&res, (u8 *)&res, 2, 0); | ||
802 | if (ret < 0 || res == 0 || res == 0xffff) { | ||
803 | dev_dbg(&spi->dev, "MAX3111 deemed not present (conf reg %04x)", | ||
804 | res); | ||
805 | ret = -ENODEV; | ||
806 | goto err_get_page; | ||
807 | } | ||
808 | |||
809 | buffer = (void *)__get_free_page(GFP_KERNEL); | ||
810 | if (!buffer) { | ||
811 | ret = -ENOMEM; | ||
812 | goto err_get_page; | ||
813 | } | ||
814 | max->con_xmit.buf = buffer; | ||
815 | max->con_xmit.head = 0; | ||
816 | max->con_xmit.tail = 0; | ||
817 | |||
818 | init_waitqueue_head(&max->wq); | ||
819 | |||
820 | max->main_thread = kthread_run(max3110_main_thread, | ||
821 | max, "max3110_main"); | ||
822 | if (IS_ERR(max->main_thread)) { | ||
823 | ret = PTR_ERR(max->main_thread); | ||
824 | goto err_kthread; | ||
825 | } | ||
826 | |||
827 | if (max->irq) { | ||
828 | ret = request_irq(max->irq, serial_m3110_irq, | ||
829 | IRQ_TYPE_EDGE_FALLING, "max3110", max); | ||
830 | if (ret) { | ||
831 | max->irq = 0; | ||
832 | dev_warn(&spi->dev, | ||
833 | "unable to allocate IRQ, will use polling method\n"); | ||
834 | } | ||
835 | } | ||
836 | |||
837 | spi_set_drvdata(spi, max); | ||
838 | pmax = max; | ||
839 | |||
840 | /* Give membase a psudo value to pass serial_core's check */ | ||
841 | max->port.membase = (unsigned char __iomem *)0xff110000; | ||
842 | uart_add_one_port(&serial_m3110_reg, &max->port); | ||
843 | |||
844 | return 0; | ||
845 | |||
846 | err_kthread: | ||
847 | free_page((unsigned long)buffer); | ||
848 | err_get_page: | ||
849 | kfree(max); | ||
850 | return ret; | ||
851 | } | ||
852 | |||
853 | static int serial_m3110_remove(struct spi_device *dev) | ||
854 | { | ||
855 | struct uart_max3110 *max = spi_get_drvdata(dev); | ||
856 | |||
857 | if (!max) | ||
858 | return 0; | ||
859 | |||
860 | uart_remove_one_port(&serial_m3110_reg, &max->port); | ||
861 | |||
862 | free_page((unsigned long)max->con_xmit.buf); | ||
863 | |||
864 | if (max->irq) | ||
865 | free_irq(max->irq, max); | ||
866 | |||
867 | if (max->main_thread) | ||
868 | kthread_stop(max->main_thread); | ||
869 | |||
870 | kfree(max); | ||
871 | return 0; | ||
872 | } | ||
873 | |||
874 | static struct spi_driver uart_max3110_driver = { | ||
875 | .driver = { | ||
876 | .name = "spi_max3111", | ||
877 | .owner = THIS_MODULE, | ||
878 | .pm = SERIAL_M3110_PM_OPS, | ||
879 | }, | ||
880 | .probe = serial_m3110_probe, | ||
881 | .remove = serial_m3110_remove, | ||
882 | }; | ||
883 | |||
884 | static int __init serial_m3110_init(void) | ||
885 | { | ||
886 | int ret = 0; | ||
887 | |||
888 | ret = uart_register_driver(&serial_m3110_reg); | ||
889 | if (ret) | ||
890 | return ret; | ||
891 | |||
892 | ret = spi_register_driver(&uart_max3110_driver); | ||
893 | if (ret) | ||
894 | uart_unregister_driver(&serial_m3110_reg); | ||
895 | |||
896 | return ret; | ||
897 | } | ||
898 | |||
899 | static void __exit serial_m3110_exit(void) | ||
900 | { | ||
901 | spi_unregister_driver(&uart_max3110_driver); | ||
902 | uart_unregister_driver(&serial_m3110_reg); | ||
903 | } | ||
904 | |||
905 | module_init(serial_m3110_init); | ||
906 | module_exit(serial_m3110_exit); | ||
907 | |||
908 | MODULE_LICENSE("GPL v2"); | ||
909 | MODULE_ALIAS("spi:max3110-uart"); | ||
diff --git a/drivers/tty/serial/mrst_max3110.h b/drivers/tty/serial/mrst_max3110.h deleted file mode 100644 index 35af0739513b..000000000000 --- a/drivers/tty/serial/mrst_max3110.h +++ /dev/null | |||
@@ -1,61 +0,0 @@ | |||
1 | #ifndef _MRST_MAX3110_H | ||
2 | #define _MRST_MAX3110_H | ||
3 | |||
4 | #define MAX3110_HIGH_CLK 0x1 /* 3.6864 MHZ */ | ||
5 | #define MAX3110_LOW_CLK 0x0 /* 1.8432 MHZ */ | ||
6 | |||
7 | /* status bits for all 4 MAX3110 operate modes */ | ||
8 | #define MAX3110_READ_DATA_AVAILABLE (1 << 15) | ||
9 | #define MAX3110_WRITE_BUF_EMPTY (1 << 14) | ||
10 | #define MAX3110_BREAK (1 << 10) | ||
11 | |||
12 | #define WC_TAG (3 << 14) | ||
13 | #define RC_TAG (1 << 14) | ||
14 | #define WD_TAG (2 << 14) | ||
15 | #define RD_TAG (0 << 14) | ||
16 | |||
17 | /* bits def for write configuration */ | ||
18 | #define WC_FIFO_ENABLE_MASK (1 << 13) | ||
19 | #define WC_FIFO_ENABLE (0 << 13) | ||
20 | |||
21 | #define WC_SW_SHDI (1 << 12) | ||
22 | |||
23 | #define WC_IRQ_MASK (0xF << 8) | ||
24 | #define WC_TXE_IRQ_ENABLE (1 << 11) /* TX empty irq */ | ||
25 | #define WC_RXA_IRQ_ENABLE (1 << 10) /* RX available irq */ | ||
26 | #define WC_PAR_HIGH_IRQ_ENABLE (1 << 9) | ||
27 | #define WC_REC_ACT_IRQ_ENABLE (1 << 8) | ||
28 | |||
29 | #define WC_IRDA_ENABLE (1 << 7) | ||
30 | |||
31 | #define WC_STOPBITS_MASK (1 << 6) | ||
32 | #define WC_2_STOPBITS (1 << 6) | ||
33 | #define WC_1_STOPBITS (0 << 6) | ||
34 | |||
35 | #define WC_PARITY_ENABLE_MASK (1 << 5) | ||
36 | #define WC_PARITY_ENABLE (1 << 5) | ||
37 | |||
38 | #define WC_WORDLEN_MASK (1 << 4) | ||
39 | #define WC_7BIT_WORD (1 << 4) | ||
40 | #define WC_8BIT_WORD (0 << 4) | ||
41 | |||
42 | #define WC_BAUD_DIV_MASK (0xF) | ||
43 | #define WC_BAUD_DR1 (0x0) | ||
44 | #define WC_BAUD_DR2 (0x1) | ||
45 | #define WC_BAUD_DR4 (0x2) | ||
46 | #define WC_BAUD_DR8 (0x3) | ||
47 | #define WC_BAUD_DR16 (0x4) | ||
48 | #define WC_BAUD_DR32 (0x5) | ||
49 | #define WC_BAUD_DR64 (0x6) | ||
50 | #define WC_BAUD_DR128 (0x7) | ||
51 | #define WC_BAUD_DR3 (0x8) | ||
52 | #define WC_BAUD_DR6 (0x9) | ||
53 | #define WC_BAUD_DR12 (0xA) | ||
54 | #define WC_BAUD_DR24 (0xB) | ||
55 | #define WC_BAUD_DR48 (0xC) | ||
56 | #define WC_BAUD_DR96 (0xD) | ||
57 | #define WC_BAUD_DR192 (0xE) | ||
58 | #define WC_BAUD_DR384 (0xF) | ||
59 | |||
60 | #define M3110_RX_FIFO_DEPTH 8 | ||
61 | #endif | ||
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index c88b522ccd73..b73889c8ed4b 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c | |||
@@ -920,14 +920,15 @@ static void msm_console_write(struct console *co, const char *s, | |||
920 | static int __init msm_console_setup(struct console *co, char *options) | 920 | static int __init msm_console_setup(struct console *co, char *options) |
921 | { | 921 | { |
922 | struct uart_port *port; | 922 | struct uart_port *port; |
923 | struct msm_port *msm_port; | 923 | int baud = 115200; |
924 | int baud = 0, flow, bits, parity; | 924 | int bits = 8; |
925 | int parity = 'n'; | ||
926 | int flow = 'n'; | ||
925 | 927 | ||
926 | if (unlikely(co->index >= UART_NR || co->index < 0)) | 928 | if (unlikely(co->index >= UART_NR || co->index < 0)) |
927 | return -ENXIO; | 929 | return -ENXIO; |
928 | 930 | ||
929 | port = get_port_from_line(co->index); | 931 | port = get_port_from_line(co->index); |
930 | msm_port = UART_TO_MSM(port); | ||
931 | 932 | ||
932 | if (unlikely(!port->membase)) | 933 | if (unlikely(!port->membase)) |
933 | return -ENXIO; | 934 | return -ENXIO; |
@@ -937,23 +938,6 @@ static int __init msm_console_setup(struct console *co, char *options) | |||
937 | if (options) | 938 | if (options) |
938 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 939 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
939 | 940 | ||
940 | bits = 8; | ||
941 | parity = 'n'; | ||
942 | flow = 'n'; | ||
943 | msm_write(port, UART_MR2_BITS_PER_CHAR_8 | UART_MR2_STOP_BIT_LEN_ONE, | ||
944 | UART_MR2); /* 8N1 */ | ||
945 | |||
946 | if (baud < 300 || baud > 115200) | ||
947 | baud = 115200; | ||
948 | msm_set_baud_rate(port, baud); | ||
949 | |||
950 | msm_reset(port); | ||
951 | |||
952 | if (msm_port->is_uartdm) { | ||
953 | msm_write(port, UART_CR_CMD_PROTECTION_EN, UART_CR); | ||
954 | msm_write(port, UART_CR_TX_ENABLE, UART_CR); | ||
955 | } | ||
956 | |||
957 | pr_info("msm_serial: console setup on port #%d\n", port->line); | 941 | pr_info("msm_serial: console setup on port #%d\n", port->line); |
958 | 942 | ||
959 | return uart_set_options(port, co, baud, parity, bits, flow); | 943 | return uart_set_options(port, co, baud, parity, bits, flow); |
@@ -1142,9 +1126,6 @@ static int __init msm_serial_init(void) | |||
1142 | 1126 | ||
1143 | static void __exit msm_serial_exit(void) | 1127 | static void __exit msm_serial_exit(void) |
1144 | { | 1128 | { |
1145 | #ifdef CONFIG_SERIAL_MSM_CONSOLE | ||
1146 | unregister_console(&msm_console); | ||
1147 | #endif | ||
1148 | platform_driver_unregister(&msm_platform_driver); | 1129 | platform_driver_unregister(&msm_platform_driver); |
1149 | uart_unregister_driver(&msm_uart_driver); | 1130 | uart_unregister_driver(&msm_uart_driver); |
1150 | } | 1131 | } |
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index ec553f8eb218..d1298b6cc68e 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c | |||
@@ -152,8 +152,6 @@ struct mxs_auart_port { | |||
152 | unsigned int mctrl_prev; | 152 | unsigned int mctrl_prev; |
153 | enum mxs_auart_type devtype; | 153 | enum mxs_auart_type devtype; |
154 | 154 | ||
155 | unsigned int irq; | ||
156 | |||
157 | struct clk *clk; | 155 | struct clk *clk; |
158 | struct device *dev; | 156 | struct device *dev; |
159 | 157 | ||
@@ -1228,37 +1226,32 @@ static int mxs_auart_probe(struct platform_device *pdev) | |||
1228 | of_match_device(mxs_auart_dt_ids, &pdev->dev); | 1226 | of_match_device(mxs_auart_dt_ids, &pdev->dev); |
1229 | struct mxs_auart_port *s; | 1227 | struct mxs_auart_port *s; |
1230 | u32 version; | 1228 | u32 version; |
1231 | int ret = 0; | 1229 | int ret, irq; |
1232 | struct resource *r; | 1230 | struct resource *r; |
1233 | 1231 | ||
1234 | s = kzalloc(sizeof(struct mxs_auart_port), GFP_KERNEL); | 1232 | s = devm_kzalloc(&pdev->dev, sizeof(*s), GFP_KERNEL); |
1235 | if (!s) { | 1233 | if (!s) |
1236 | ret = -ENOMEM; | 1234 | return -ENOMEM; |
1237 | goto out; | ||
1238 | } | ||
1239 | 1235 | ||
1240 | ret = serial_mxs_probe_dt(s, pdev); | 1236 | ret = serial_mxs_probe_dt(s, pdev); |
1241 | if (ret > 0) | 1237 | if (ret > 0) |
1242 | s->port.line = pdev->id < 0 ? 0 : pdev->id; | 1238 | s->port.line = pdev->id < 0 ? 0 : pdev->id; |
1243 | else if (ret < 0) | 1239 | else if (ret < 0) |
1244 | goto out_free; | 1240 | return ret; |
1245 | 1241 | ||
1246 | if (of_id) { | 1242 | if (of_id) { |
1247 | pdev->id_entry = of_id->data; | 1243 | pdev->id_entry = of_id->data; |
1248 | s->devtype = pdev->id_entry->driver_data; | 1244 | s->devtype = pdev->id_entry->driver_data; |
1249 | } | 1245 | } |
1250 | 1246 | ||
1251 | s->clk = clk_get(&pdev->dev, NULL); | 1247 | s->clk = devm_clk_get(&pdev->dev, NULL); |
1252 | if (IS_ERR(s->clk)) { | 1248 | if (IS_ERR(s->clk)) |
1253 | ret = PTR_ERR(s->clk); | 1249 | return PTR_ERR(s->clk); |
1254 | goto out_free; | ||
1255 | } | ||
1256 | 1250 | ||
1257 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1251 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1258 | if (!r) { | 1252 | if (!r) |
1259 | ret = -ENXIO; | 1253 | return -ENXIO; |
1260 | goto out_free_clk; | 1254 | |
1261 | } | ||
1262 | 1255 | ||
1263 | s->port.mapbase = r->start; | 1256 | s->port.mapbase = r->start; |
1264 | s->port.membase = ioremap(r->start, resource_size(r)); | 1257 | s->port.membase = ioremap(r->start, resource_size(r)); |
@@ -1271,11 +1264,15 @@ static int mxs_auart_probe(struct platform_device *pdev) | |||
1271 | 1264 | ||
1272 | s->mctrl_prev = 0; | 1265 | s->mctrl_prev = 0; |
1273 | 1266 | ||
1274 | s->irq = platform_get_irq(pdev, 0); | 1267 | irq = platform_get_irq(pdev, 0); |
1275 | s->port.irq = s->irq; | 1268 | if (irq < 0) |
1276 | ret = request_irq(s->irq, mxs_auart_irq_handle, 0, dev_name(&pdev->dev), s); | 1269 | return irq; |
1270 | |||
1271 | s->port.irq = irq; | ||
1272 | ret = devm_request_irq(&pdev->dev, irq, mxs_auart_irq_handle, 0, | ||
1273 | dev_name(&pdev->dev), s); | ||
1277 | if (ret) | 1274 | if (ret) |
1278 | goto out_free_clk; | 1275 | return ret; |
1279 | 1276 | ||
1280 | platform_set_drvdata(pdev, s); | 1277 | platform_set_drvdata(pdev, s); |
1281 | 1278 | ||
@@ -1288,7 +1285,7 @@ static int mxs_auart_probe(struct platform_device *pdev) | |||
1288 | */ | 1285 | */ |
1289 | ret = mxs_auart_request_gpio_irq(s); | 1286 | ret = mxs_auart_request_gpio_irq(s); |
1290 | if (ret) | 1287 | if (ret) |
1291 | goto out_free_irq; | 1288 | return ret; |
1292 | 1289 | ||
1293 | auart_port[s->port.line] = s; | 1290 | auart_port[s->port.line] = s; |
1294 | 1291 | ||
@@ -1307,14 +1304,7 @@ static int mxs_auart_probe(struct platform_device *pdev) | |||
1307 | 1304 | ||
1308 | out_free_gpio_irq: | 1305 | out_free_gpio_irq: |
1309 | mxs_auart_free_gpio_irq(s); | 1306 | mxs_auart_free_gpio_irq(s); |
1310 | out_free_irq: | ||
1311 | auart_port[pdev->id] = NULL; | 1307 | auart_port[pdev->id] = NULL; |
1312 | free_irq(s->irq, s); | ||
1313 | out_free_clk: | ||
1314 | clk_put(s->clk); | ||
1315 | out_free: | ||
1316 | kfree(s); | ||
1317 | out: | ||
1318 | return ret; | 1308 | return ret; |
1319 | } | 1309 | } |
1320 | 1310 | ||
@@ -1323,13 +1313,8 @@ static int mxs_auart_remove(struct platform_device *pdev) | |||
1323 | struct mxs_auart_port *s = platform_get_drvdata(pdev); | 1313 | struct mxs_auart_port *s = platform_get_drvdata(pdev); |
1324 | 1314 | ||
1325 | uart_remove_one_port(&auart_driver, &s->port); | 1315 | uart_remove_one_port(&auart_driver, &s->port); |
1326 | |||
1327 | auart_port[pdev->id] = NULL; | 1316 | auart_port[pdev->id] = NULL; |
1328 | |||
1329 | mxs_auart_free_gpio_irq(s); | 1317 | mxs_auart_free_gpio_irq(s); |
1330 | clk_put(s->clk); | ||
1331 | free_irq(s->irq, s); | ||
1332 | kfree(s); | ||
1333 | 1318 | ||
1334 | return 0; | 1319 | return 0; |
1335 | } | 1320 | } |
diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index 64f1bab7e9d7..7ff61e24a195 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c | |||
@@ -102,6 +102,11 @@ static int of_platform_serial_setup(struct platform_device *ofdev, | |||
102 | if (of_property_read_u32(np, "fifo-size", &prop) == 0) | 102 | if (of_property_read_u32(np, "fifo-size", &prop) == 0) |
103 | port->fifosize = prop; | 103 | port->fifosize = prop; |
104 | 104 | ||
105 | /* Check for a fixed line number */ | ||
106 | ret = of_alias_get_id(np, "serial"); | ||
107 | if (ret >= 0) | ||
108 | port->line = ret; | ||
109 | |||
105 | port->irq = irq_of_parse_and_map(np, 0); | 110 | port->irq = irq_of_parse_and_map(np, 0); |
106 | port->iotype = UPIO_MEM; | 111 | port->iotype = UPIO_MEM; |
107 | if (of_property_read_u32(np, "reg-io-width", &prop) == 0) { | 112 | if (of_property_read_u32(np, "reg-io-width", &prop) == 0) { |
@@ -128,6 +133,10 @@ static int of_platform_serial_setup(struct platform_device *ofdev, | |||
128 | if (of_find_property(np, "no-loopback-test", NULL)) | 133 | if (of_find_property(np, "no-loopback-test", NULL)) |
129 | port->flags |= UPF_SKIP_TEST; | 134 | port->flags |= UPF_SKIP_TEST; |
130 | 135 | ||
136 | ret = of_alias_get_id(np, "serial"); | ||
137 | if (ret >= 0) | ||
138 | port->line = ret; | ||
139 | |||
131 | port->dev = &ofdev->dev; | 140 | port->dev = &ofdev->dev; |
132 | 141 | ||
133 | switch (type) { | 142 | switch (type) { |
@@ -331,6 +340,10 @@ static struct of_device_id of_platform_serial_table[] = { | |||
331 | .data = (void *)PORT_ALTR_16550_F64, }, | 340 | .data = (void *)PORT_ALTR_16550_F64, }, |
332 | { .compatible = "altr,16550-FIFO128", | 341 | { .compatible = "altr,16550-FIFO128", |
333 | .data = (void *)PORT_ALTR_16550_F128, }, | 342 | .data = (void *)PORT_ALTR_16550_F128, }, |
343 | { .compatible = "mrvl,mmp-uart", | ||
344 | .data = (void *)PORT_XSCALE, }, | ||
345 | { .compatible = "mrvl,pxa-uart", | ||
346 | .data = (void *)PORT_XSCALE, }, | ||
334 | #ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL | 347 | #ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL |
335 | { .compatible = "ibm,qpace-nwp-serial", | 348 | { .compatible = "ibm,qpace-nwp-serial", |
336 | .data = (void *)PORT_NWPSERIAL, }, | 349 | .data = (void *)PORT_NWPSERIAL, }, |
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 2e1073da6719..10256fa04b40 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c | |||
@@ -63,7 +63,7 @@ | |||
63 | #define UART_ERRATA_i202_MDR1_ACCESS BIT(0) | 63 | #define UART_ERRATA_i202_MDR1_ACCESS BIT(0) |
64 | #define UART_ERRATA_i291_DMA_FORCEIDLE BIT(1) | 64 | #define UART_ERRATA_i291_DMA_FORCEIDLE BIT(1) |
65 | 65 | ||
66 | #define DEFAULT_CLK_SPEED 48000000 /* 48Mhz*/ | 66 | #define DEFAULT_CLK_SPEED 48000000 /* 48Mhz */ |
67 | 67 | ||
68 | /* SCR register bitmasks */ | 68 | /* SCR register bitmasks */ |
69 | #define OMAP_UART_SCR_RX_TRIG_GRANU1_MASK (1 << 7) | 69 | #define OMAP_UART_SCR_RX_TRIG_GRANU1_MASK (1 << 7) |
@@ -93,7 +93,7 @@ | |||
93 | /* WER = 0x7F | 93 | /* WER = 0x7F |
94 | * Enable module level wakeup in WER reg | 94 | * Enable module level wakeup in WER reg |
95 | */ | 95 | */ |
96 | #define OMAP_UART_WER_MOD_WKUP 0X7F | 96 | #define OMAP_UART_WER_MOD_WKUP 0x7F |
97 | 97 | ||
98 | /* Enable XON/XOFF flow control on output */ | 98 | /* Enable XON/XOFF flow control on output */ |
99 | #define OMAP_UART_SW_TX 0x08 | 99 | #define OMAP_UART_SW_TX 0x08 |
@@ -114,7 +114,7 @@ struct uart_omap_dma { | |||
114 | dma_addr_t tx_buf_dma_phys; | 114 | dma_addr_t tx_buf_dma_phys; |
115 | unsigned int uart_base; | 115 | unsigned int uart_base; |
116 | /* | 116 | /* |
117 | * Buffer for rx dma.It is not required for tx because the buffer | 117 | * Buffer for rx dma. It is not required for tx because the buffer |
118 | * comes from port structure. | 118 | * comes from port structure. |
119 | */ | 119 | */ |
120 | unsigned char *rx_buf; | 120 | unsigned char *rx_buf; |
@@ -151,7 +151,7 @@ struct uart_omap_port { | |||
151 | int use_dma; | 151 | int use_dma; |
152 | /* | 152 | /* |
153 | * Some bits in registers are cleared on a read, so they must | 153 | * Some bits in registers are cleared on a read, so they must |
154 | * be saved whenever the register is read but the bits will not | 154 | * be saved whenever the register is read, but the bits will not |
155 | * be immediately processed. | 155 | * be immediately processed. |
156 | */ | 156 | */ |
157 | unsigned int lsr_break_flag; | 157 | unsigned int lsr_break_flag; |
@@ -681,7 +681,7 @@ static unsigned int serial_omap_get_mctrl(struct uart_port *port) | |||
681 | static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl) | 681 | static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl) |
682 | { | 682 | { |
683 | struct uart_omap_port *up = to_uart_omap_port(port); | 683 | struct uart_omap_port *up = to_uart_omap_port(port); |
684 | unsigned char mcr = 0, old_mcr; | 684 | unsigned char mcr = 0, old_mcr, lcr; |
685 | 685 | ||
686 | dev_dbg(up->port.dev, "serial_omap_set_mctrl+%d\n", up->port.line); | 686 | dev_dbg(up->port.dev, "serial_omap_set_mctrl+%d\n", up->port.line); |
687 | if (mctrl & TIOCM_RTS) | 687 | if (mctrl & TIOCM_RTS) |
@@ -701,6 +701,17 @@ static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
701 | UART_MCR_DTR | UART_MCR_RTS); | 701 | UART_MCR_DTR | UART_MCR_RTS); |
702 | up->mcr = old_mcr | mcr; | 702 | up->mcr = old_mcr | mcr; |
703 | serial_out(up, UART_MCR, up->mcr); | 703 | serial_out(up, UART_MCR, up->mcr); |
704 | |||
705 | /* Turn off autoRTS if RTS is lowered; restore autoRTS if RTS raised */ | ||
706 | lcr = serial_in(up, UART_LCR); | ||
707 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | ||
708 | if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS)) | ||
709 | up->efr |= UART_EFR_RTS; | ||
710 | else | ||
711 | up->efr &= UART_EFR_RTS; | ||
712 | serial_out(up, UART_EFR, up->efr); | ||
713 | serial_out(up, UART_LCR, lcr); | ||
714 | |||
704 | pm_runtime_mark_last_busy(up->dev); | 715 | pm_runtime_mark_last_busy(up->dev); |
705 | pm_runtime_put_autosuspend(up->dev); | 716 | pm_runtime_put_autosuspend(up->dev); |
706 | } | 717 | } |
@@ -756,8 +767,6 @@ static int serial_omap_startup(struct uart_port *port) | |||
756 | * (they will be reenabled in set_termios()) | 767 | * (they will be reenabled in set_termios()) |
757 | */ | 768 | */ |
758 | serial_omap_clear_fifos(up); | 769 | serial_omap_clear_fifos(up); |
759 | /* For Hardware flow control */ | ||
760 | serial_out(up, UART_MCR, UART_MCR_RTS); | ||
761 | 770 | ||
762 | /* | 771 | /* |
763 | * Clear the interrupt registers. | 772 | * Clear the interrupt registers. |
@@ -1053,12 +1062,12 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1053 | 1062 | ||
1054 | serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG); | 1063 | serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG); |
1055 | 1064 | ||
1056 | if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW) { | 1065 | up->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS | UPSTAT_AUTOXOFF); |
1057 | /* Enable AUTORTS and AUTOCTS */ | ||
1058 | up->efr |= UART_EFR_CTS | UART_EFR_RTS; | ||
1059 | 1066 | ||
1060 | /* Ensure MCR RTS is asserted */ | 1067 | if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW) { |
1061 | up->mcr |= UART_MCR_RTS; | 1068 | /* Enable AUTOCTS (autoRTS is enabled when RTS is raised) */ |
1069 | up->port.status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS; | ||
1070 | up->efr |= UART_EFR_CTS; | ||
1062 | } else { | 1071 | } else { |
1063 | /* Disable AUTORTS and AUTOCTS */ | 1072 | /* Disable AUTORTS and AUTOCTS */ |
1064 | up->efr &= ~(UART_EFR_CTS | UART_EFR_RTS); | 1073 | up->efr &= ~(UART_EFR_CTS | UART_EFR_RTS); |
@@ -1081,8 +1090,10 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1081 | * Enable XON/XOFF flow control on output. | 1090 | * Enable XON/XOFF flow control on output. |
1082 | * Transmit XON1, XOFF1 | 1091 | * Transmit XON1, XOFF1 |
1083 | */ | 1092 | */ |
1084 | if (termios->c_iflag & IXOFF) | 1093 | if (termios->c_iflag & IXOFF) { |
1094 | up->port.status |= UPSTAT_AUTOXOFF; | ||
1085 | up->efr |= OMAP_UART_SW_TX; | 1095 | up->efr |= OMAP_UART_SW_TX; |
1096 | } | ||
1086 | 1097 | ||
1087 | /* | 1098 | /* |
1088 | * IXANY Flag: | 1099 | * IXANY Flag: |
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 107e80722575..af821a908720 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c | |||
@@ -28,6 +28,9 @@ | |||
28 | #define SUPPORT_SYSRQ | 28 | #define SUPPORT_SYSRQ |
29 | #endif | 29 | #endif |
30 | 30 | ||
31 | #include <linux/dmaengine.h> | ||
32 | #include <linux/dma-mapping.h> | ||
33 | #include <linux/slab.h> | ||
31 | #include <linux/module.h> | 34 | #include <linux/module.h> |
32 | #include <linux/ioport.h> | 35 | #include <linux/ioport.h> |
33 | #include <linux/io.h> | 36 | #include <linux/io.h> |
@@ -78,6 +81,10 @@ static void dbg(const char *fmt, ...) | |||
78 | #define S3C24XX_SERIAL_MAJOR 204 | 81 | #define S3C24XX_SERIAL_MAJOR 204 |
79 | #define S3C24XX_SERIAL_MINOR 64 | 82 | #define S3C24XX_SERIAL_MINOR 64 |
80 | 83 | ||
84 | #define S3C24XX_TX_PIO 1 | ||
85 | #define S3C24XX_TX_DMA 2 | ||
86 | #define S3C24XX_RX_PIO 1 | ||
87 | #define S3C24XX_RX_DMA 2 | ||
81 | /* macros to change one thing to another */ | 88 | /* macros to change one thing to another */ |
82 | 89 | ||
83 | #define tx_enabled(port) ((port)->unused[0]) | 90 | #define tx_enabled(port) ((port)->unused[0]) |
@@ -154,39 +161,272 @@ static void s3c24xx_serial_rx_disable(struct uart_port *port) | |||
154 | static void s3c24xx_serial_stop_tx(struct uart_port *port) | 161 | static void s3c24xx_serial_stop_tx(struct uart_port *port) |
155 | { | 162 | { |
156 | struct s3c24xx_uart_port *ourport = to_ourport(port); | 163 | struct s3c24xx_uart_port *ourport = to_ourport(port); |
164 | struct s3c24xx_uart_dma *dma = ourport->dma; | ||
165 | struct circ_buf *xmit = &port->state->xmit; | ||
166 | struct dma_tx_state state; | ||
167 | int count; | ||
157 | 168 | ||
158 | if (tx_enabled(port)) { | 169 | if (!tx_enabled(port)) |
159 | if (s3c24xx_serial_has_interrupt_mask(port)) | 170 | return; |
160 | __set_bit(S3C64XX_UINTM_TXD, | 171 | |
161 | portaddrl(port, S3C64XX_UINTM)); | 172 | if (s3c24xx_serial_has_interrupt_mask(port)) |
162 | else | 173 | __set_bit(S3C64XX_UINTM_TXD, |
163 | disable_irq_nosync(ourport->tx_irq); | 174 | portaddrl(port, S3C64XX_UINTM)); |
164 | tx_enabled(port) = 0; | 175 | else |
165 | if (port->flags & UPF_CONS_FLOW) | 176 | disable_irq_nosync(ourport->tx_irq); |
166 | s3c24xx_serial_rx_enable(port); | 177 | |
178 | if (dma && dma->tx_chan && ourport->tx_in_progress == S3C24XX_TX_DMA) { | ||
179 | dmaengine_pause(dma->tx_chan); | ||
180 | dmaengine_tx_status(dma->tx_chan, dma->tx_cookie, &state); | ||
181 | dmaengine_terminate_all(dma->tx_chan); | ||
182 | dma_sync_single_for_cpu(ourport->port.dev, | ||
183 | dma->tx_transfer_addr, dma->tx_size, DMA_TO_DEVICE); | ||
184 | async_tx_ack(dma->tx_desc); | ||
185 | count = dma->tx_bytes_requested - state.residue; | ||
186 | xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); | ||
187 | port->icount.tx += count; | ||
167 | } | 188 | } |
189 | |||
190 | tx_enabled(port) = 0; | ||
191 | ourport->tx_in_progress = 0; | ||
192 | |||
193 | if (port->flags & UPF_CONS_FLOW) | ||
194 | s3c24xx_serial_rx_enable(port); | ||
195 | |||
196 | ourport->tx_mode = 0; | ||
168 | } | 197 | } |
169 | 198 | ||
170 | static void s3c24xx_serial_start_tx(struct uart_port *port) | 199 | static void s3c24xx_serial_start_next_tx(struct s3c24xx_uart_port *ourport); |
200 | |||
201 | static void s3c24xx_serial_tx_dma_complete(void *args) | ||
202 | { | ||
203 | struct s3c24xx_uart_port *ourport = args; | ||
204 | struct uart_port *port = &ourport->port; | ||
205 | struct circ_buf *xmit = &port->state->xmit; | ||
206 | struct s3c24xx_uart_dma *dma = ourport->dma; | ||
207 | struct dma_tx_state state; | ||
208 | unsigned long flags; | ||
209 | int count; | ||
210 | |||
211 | |||
212 | dmaengine_tx_status(dma->tx_chan, dma->tx_cookie, &state); | ||
213 | count = dma->tx_bytes_requested - state.residue; | ||
214 | async_tx_ack(dma->tx_desc); | ||
215 | |||
216 | dma_sync_single_for_cpu(ourport->port.dev, dma->tx_transfer_addr, | ||
217 | dma->tx_size, DMA_TO_DEVICE); | ||
218 | |||
219 | spin_lock_irqsave(&port->lock, flags); | ||
220 | |||
221 | xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); | ||
222 | port->icount.tx += count; | ||
223 | ourport->tx_in_progress = 0; | ||
224 | |||
225 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
226 | uart_write_wakeup(port); | ||
227 | |||
228 | s3c24xx_serial_start_next_tx(ourport); | ||
229 | spin_unlock_irqrestore(&port->lock, flags); | ||
230 | } | ||
231 | |||
232 | static void enable_tx_dma(struct s3c24xx_uart_port *ourport) | ||
233 | { | ||
234 | struct uart_port *port = &ourport->port; | ||
235 | u32 ucon; | ||
236 | |||
237 | /* Mask Tx interrupt */ | ||
238 | if (s3c24xx_serial_has_interrupt_mask(port)) | ||
239 | __set_bit(S3C64XX_UINTM_TXD, | ||
240 | portaddrl(port, S3C64XX_UINTM)); | ||
241 | else | ||
242 | disable_irq_nosync(ourport->tx_irq); | ||
243 | |||
244 | /* Enable tx dma mode */ | ||
245 | ucon = rd_regl(port, S3C2410_UCON); | ||
246 | ucon &= ~(S3C64XX_UCON_TXBURST_MASK | S3C64XX_UCON_TXMODE_MASK); | ||
247 | ucon |= (dma_get_cache_alignment() >= 16) ? | ||
248 | S3C64XX_UCON_TXBURST_16 : S3C64XX_UCON_TXBURST_1; | ||
249 | ucon |= S3C64XX_UCON_TXMODE_DMA; | ||
250 | wr_regl(port, S3C2410_UCON, ucon); | ||
251 | |||
252 | ourport->tx_mode = S3C24XX_TX_DMA; | ||
253 | } | ||
254 | |||
255 | static void enable_tx_pio(struct s3c24xx_uart_port *ourport) | ||
256 | { | ||
257 | struct uart_port *port = &ourport->port; | ||
258 | u32 ucon, ufcon; | ||
259 | |||
260 | /* Set ufcon txtrig */ | ||
261 | ourport->tx_in_progress = S3C24XX_TX_PIO; | ||
262 | ufcon = rd_regl(port, S3C2410_UFCON); | ||
263 | wr_regl(port, S3C2410_UFCON, ufcon); | ||
264 | |||
265 | /* Enable tx pio mode */ | ||
266 | ucon = rd_regl(port, S3C2410_UCON); | ||
267 | ucon &= ~(S3C64XX_UCON_TXMODE_MASK); | ||
268 | ucon |= S3C64XX_UCON_TXMODE_CPU; | ||
269 | wr_regl(port, S3C2410_UCON, ucon); | ||
270 | |||
271 | /* Unmask Tx interrupt */ | ||
272 | if (s3c24xx_serial_has_interrupt_mask(port)) | ||
273 | __clear_bit(S3C64XX_UINTM_TXD, | ||
274 | portaddrl(port, S3C64XX_UINTM)); | ||
275 | else | ||
276 | enable_irq(ourport->tx_irq); | ||
277 | |||
278 | ourport->tx_mode = S3C24XX_TX_PIO; | ||
279 | } | ||
280 | |||
281 | static void s3c24xx_serial_start_tx_pio(struct s3c24xx_uart_port *ourport) | ||
282 | { | ||
283 | if (ourport->tx_mode != S3C24XX_TX_PIO) | ||
284 | enable_tx_pio(ourport); | ||
285 | } | ||
286 | |||
287 | static int s3c24xx_serial_start_tx_dma(struct s3c24xx_uart_port *ourport, | ||
288 | unsigned int count) | ||
289 | { | ||
290 | struct uart_port *port = &ourport->port; | ||
291 | struct circ_buf *xmit = &port->state->xmit; | ||
292 | struct s3c24xx_uart_dma *dma = ourport->dma; | ||
293 | |||
294 | |||
295 | if (ourport->tx_mode != S3C24XX_TX_DMA) | ||
296 | enable_tx_dma(ourport); | ||
297 | |||
298 | while (xmit->tail & (dma_get_cache_alignment() - 1)) { | ||
299 | if (rd_regl(port, S3C2410_UFSTAT) & ourport->info->tx_fifofull) | ||
300 | return 0; | ||
301 | wr_regb(port, S3C2410_UTXH, xmit->buf[xmit->tail]); | ||
302 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
303 | port->icount.tx++; | ||
304 | count--; | ||
305 | } | ||
306 | |||
307 | dma->tx_size = count & ~(dma_get_cache_alignment() - 1); | ||
308 | dma->tx_transfer_addr = dma->tx_addr + xmit->tail; | ||
309 | |||
310 | dma_sync_single_for_device(ourport->port.dev, dma->tx_transfer_addr, | ||
311 | dma->tx_size, DMA_TO_DEVICE); | ||
312 | |||
313 | dma->tx_desc = dmaengine_prep_slave_single(dma->tx_chan, | ||
314 | dma->tx_transfer_addr, dma->tx_size, | ||
315 | DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT); | ||
316 | if (!dma->tx_desc) { | ||
317 | dev_err(ourport->port.dev, "Unable to get desc for Tx\n"); | ||
318 | return -EIO; | ||
319 | } | ||
320 | |||
321 | dma->tx_desc->callback = s3c24xx_serial_tx_dma_complete; | ||
322 | dma->tx_desc->callback_param = ourport; | ||
323 | dma->tx_bytes_requested = dma->tx_size; | ||
324 | |||
325 | ourport->tx_in_progress = S3C24XX_TX_DMA; | ||
326 | dma->tx_cookie = dmaengine_submit(dma->tx_desc); | ||
327 | dma_async_issue_pending(dma->tx_chan); | ||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | static void s3c24xx_serial_start_next_tx(struct s3c24xx_uart_port *ourport) | ||
332 | { | ||
333 | struct uart_port *port = &ourport->port; | ||
334 | struct circ_buf *xmit = &port->state->xmit; | ||
335 | unsigned long count; | ||
336 | |||
337 | /* Get data size up to the end of buffer */ | ||
338 | count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); | ||
339 | |||
340 | if (!count) { | ||
341 | s3c24xx_serial_stop_tx(port); | ||
342 | return; | ||
343 | } | ||
344 | |||
345 | if (!ourport->dma || !ourport->dma->tx_chan || count < port->fifosize) | ||
346 | s3c24xx_serial_start_tx_pio(ourport); | ||
347 | else | ||
348 | s3c24xx_serial_start_tx_dma(ourport, count); | ||
349 | } | ||
350 | |||
351 | void s3c24xx_serial_start_tx(struct uart_port *port) | ||
171 | { | 352 | { |
172 | struct s3c24xx_uart_port *ourport = to_ourport(port); | 353 | struct s3c24xx_uart_port *ourport = to_ourport(port); |
354 | struct circ_buf *xmit = &port->state->xmit; | ||
173 | 355 | ||
174 | if (!tx_enabled(port)) { | 356 | if (!tx_enabled(port)) { |
175 | if (port->flags & UPF_CONS_FLOW) | 357 | if (port->flags & UPF_CONS_FLOW) |
176 | s3c24xx_serial_rx_disable(port); | 358 | s3c24xx_serial_rx_disable(port); |
177 | 359 | ||
178 | if (s3c24xx_serial_has_interrupt_mask(port)) | ||
179 | __clear_bit(S3C64XX_UINTM_TXD, | ||
180 | portaddrl(port, S3C64XX_UINTM)); | ||
181 | else | ||
182 | enable_irq(ourport->tx_irq); | ||
183 | tx_enabled(port) = 1; | 360 | tx_enabled(port) = 1; |
361 | if (!ourport->dma || !ourport->dma->tx_chan) | ||
362 | s3c24xx_serial_start_tx_pio(ourport); | ||
363 | } | ||
364 | |||
365 | if (ourport->dma && ourport->dma->tx_chan) { | ||
366 | if (!uart_circ_empty(xmit) && !ourport->tx_in_progress) | ||
367 | s3c24xx_serial_start_next_tx(ourport); | ||
368 | } | ||
369 | } | ||
370 | |||
371 | static void s3c24xx_uart_copy_rx_to_tty(struct s3c24xx_uart_port *ourport, | ||
372 | struct tty_port *tty, int count) | ||
373 | { | ||
374 | struct s3c24xx_uart_dma *dma = ourport->dma; | ||
375 | int copied; | ||
376 | |||
377 | if (!count) | ||
378 | return; | ||
379 | |||
380 | dma_sync_single_for_cpu(ourport->port.dev, dma->rx_addr, | ||
381 | dma->rx_size, DMA_FROM_DEVICE); | ||
382 | |||
383 | ourport->port.icount.rx += count; | ||
384 | if (!tty) { | ||
385 | dev_err(ourport->port.dev, "No tty port\n"); | ||
386 | return; | ||
387 | } | ||
388 | copied = tty_insert_flip_string(tty, | ||
389 | ((unsigned char *)(ourport->dma->rx_buf)), count); | ||
390 | if (copied != count) { | ||
391 | WARN_ON(1); | ||
392 | dev_err(ourport->port.dev, "RxData copy to tty layer failed\n"); | ||
393 | } | ||
394 | } | ||
395 | |||
396 | static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport, | ||
397 | unsigned long ufstat); | ||
398 | |||
399 | static void uart_rx_drain_fifo(struct s3c24xx_uart_port *ourport) | ||
400 | { | ||
401 | struct uart_port *port = &ourport->port; | ||
402 | struct tty_port *tty = &port->state->port; | ||
403 | unsigned int ch, ufstat; | ||
404 | unsigned int count; | ||
405 | |||
406 | ufstat = rd_regl(port, S3C2410_UFSTAT); | ||
407 | count = s3c24xx_serial_rx_fifocnt(ourport, ufstat); | ||
408 | |||
409 | if (!count) | ||
410 | return; | ||
411 | |||
412 | while (count-- > 0) { | ||
413 | ch = rd_regb(port, S3C2410_URXH); | ||
414 | |||
415 | ourport->port.icount.rx++; | ||
416 | tty_insert_flip_char(tty, ch, TTY_NORMAL); | ||
184 | } | 417 | } |
418 | |||
419 | tty_flip_buffer_push(tty); | ||
185 | } | 420 | } |
186 | 421 | ||
187 | static void s3c24xx_serial_stop_rx(struct uart_port *port) | 422 | static void s3c24xx_serial_stop_rx(struct uart_port *port) |
188 | { | 423 | { |
189 | struct s3c24xx_uart_port *ourport = to_ourport(port); | 424 | struct s3c24xx_uart_port *ourport = to_ourport(port); |
425 | struct s3c24xx_uart_dma *dma = ourport->dma; | ||
426 | struct tty_port *t = &port->state->port; | ||
427 | struct dma_tx_state state; | ||
428 | enum dma_status dma_status; | ||
429 | unsigned int received; | ||
190 | 430 | ||
191 | if (rx_enabled(port)) { | 431 | if (rx_enabled(port)) { |
192 | dbg("s3c24xx_serial_stop_rx: port=%p\n", port); | 432 | dbg("s3c24xx_serial_stop_rx: port=%p\n", port); |
@@ -197,6 +437,17 @@ static void s3c24xx_serial_stop_rx(struct uart_port *port) | |||
197 | disable_irq_nosync(ourport->rx_irq); | 437 | disable_irq_nosync(ourport->rx_irq); |
198 | rx_enabled(port) = 0; | 438 | rx_enabled(port) = 0; |
199 | } | 439 | } |
440 | if (dma && dma->rx_chan) { | ||
441 | dmaengine_pause(dma->tx_chan); | ||
442 | dma_status = dmaengine_tx_status(dma->rx_chan, | ||
443 | dma->rx_cookie, &state); | ||
444 | if (dma_status == DMA_IN_PROGRESS || | ||
445 | dma_status == DMA_PAUSED) { | ||
446 | received = dma->rx_bytes_requested - state.residue; | ||
447 | dmaengine_terminate_all(dma->rx_chan); | ||
448 | s3c24xx_uart_copy_rx_to_tty(ourport, t, received); | ||
449 | } | ||
450 | } | ||
200 | } | 451 | } |
201 | 452 | ||
202 | static inline struct s3c24xx_uart_info | 453 | static inline struct s3c24xx_uart_info |
@@ -228,12 +479,157 @@ static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport, | |||
228 | return (ufstat & info->rx_fifomask) >> info->rx_fifoshift; | 479 | return (ufstat & info->rx_fifomask) >> info->rx_fifoshift; |
229 | } | 480 | } |
230 | 481 | ||
482 | static void s3c64xx_start_rx_dma(struct s3c24xx_uart_port *ourport); | ||
483 | static void s3c24xx_serial_rx_dma_complete(void *args) | ||
484 | { | ||
485 | struct s3c24xx_uart_port *ourport = args; | ||
486 | struct uart_port *port = &ourport->port; | ||
487 | |||
488 | struct s3c24xx_uart_dma *dma = ourport->dma; | ||
489 | struct tty_port *t = &port->state->port; | ||
490 | struct tty_struct *tty = tty_port_tty_get(&ourport->port.state->port); | ||
491 | |||
492 | struct dma_tx_state state; | ||
493 | unsigned long flags; | ||
494 | int received; | ||
495 | |||
496 | dmaengine_tx_status(dma->rx_chan, dma->rx_cookie, &state); | ||
497 | received = dma->rx_bytes_requested - state.residue; | ||
498 | async_tx_ack(dma->rx_desc); | ||
499 | |||
500 | spin_lock_irqsave(&port->lock, flags); | ||
501 | |||
502 | if (received) | ||
503 | s3c24xx_uart_copy_rx_to_tty(ourport, t, received); | ||
504 | |||
505 | if (tty) { | ||
506 | tty_flip_buffer_push(t); | ||
507 | tty_kref_put(tty); | ||
508 | } | ||
509 | |||
510 | s3c64xx_start_rx_dma(ourport); | ||
511 | |||
512 | spin_unlock_irqrestore(&port->lock, flags); | ||
513 | } | ||
514 | |||
515 | static void s3c64xx_start_rx_dma(struct s3c24xx_uart_port *ourport) | ||
516 | { | ||
517 | struct s3c24xx_uart_dma *dma = ourport->dma; | ||
518 | |||
519 | dma_sync_single_for_device(ourport->port.dev, dma->rx_addr, | ||
520 | dma->rx_size, DMA_FROM_DEVICE); | ||
521 | |||
522 | dma->rx_desc = dmaengine_prep_slave_single(dma->rx_chan, | ||
523 | dma->rx_addr, dma->rx_size, DMA_DEV_TO_MEM, | ||
524 | DMA_PREP_INTERRUPT); | ||
525 | if (!dma->rx_desc) { | ||
526 | dev_err(ourport->port.dev, "Unable to get desc for Rx\n"); | ||
527 | return; | ||
528 | } | ||
529 | |||
530 | dma->rx_desc->callback = s3c24xx_serial_rx_dma_complete; | ||
531 | dma->rx_desc->callback_param = ourport; | ||
532 | dma->rx_bytes_requested = dma->rx_size; | ||
533 | |||
534 | dma->rx_cookie = dmaengine_submit(dma->rx_desc); | ||
535 | dma_async_issue_pending(dma->rx_chan); | ||
536 | } | ||
231 | 537 | ||
232 | /* ? - where has parity gone?? */ | 538 | /* ? - where has parity gone?? */ |
233 | #define S3C2410_UERSTAT_PARITY (0x1000) | 539 | #define S3C2410_UERSTAT_PARITY (0x1000) |
234 | 540 | ||
235 | static irqreturn_t | 541 | static void enable_rx_dma(struct s3c24xx_uart_port *ourport) |
236 | s3c24xx_serial_rx_chars(int irq, void *dev_id) | 542 | { |
543 | struct uart_port *port = &ourport->port; | ||
544 | unsigned int ucon; | ||
545 | |||
546 | /* set Rx mode to DMA mode */ | ||
547 | ucon = rd_regl(port, S3C2410_UCON); | ||
548 | ucon &= ~(S3C64XX_UCON_RXBURST_MASK | | ||
549 | S3C64XX_UCON_TIMEOUT_MASK | | ||
550 | S3C64XX_UCON_EMPTYINT_EN | | ||
551 | S3C64XX_UCON_DMASUS_EN | | ||
552 | S3C64XX_UCON_TIMEOUT_EN | | ||
553 | S3C64XX_UCON_RXMODE_MASK); | ||
554 | ucon |= S3C64XX_UCON_RXBURST_16 | | ||
555 | 0xf << S3C64XX_UCON_TIMEOUT_SHIFT | | ||
556 | S3C64XX_UCON_EMPTYINT_EN | | ||
557 | S3C64XX_UCON_TIMEOUT_EN | | ||
558 | S3C64XX_UCON_RXMODE_DMA; | ||
559 | wr_regl(port, S3C2410_UCON, ucon); | ||
560 | |||
561 | ourport->rx_mode = S3C24XX_RX_DMA; | ||
562 | } | ||
563 | |||
564 | static void enable_rx_pio(struct s3c24xx_uart_port *ourport) | ||
565 | { | ||
566 | struct uart_port *port = &ourport->port; | ||
567 | unsigned int ucon; | ||
568 | |||
569 | /* set Rx mode to DMA mode */ | ||
570 | ucon = rd_regl(port, S3C2410_UCON); | ||
571 | ucon &= ~(S3C64XX_UCON_TIMEOUT_MASK | | ||
572 | S3C64XX_UCON_EMPTYINT_EN | | ||
573 | S3C64XX_UCON_DMASUS_EN | | ||
574 | S3C64XX_UCON_TIMEOUT_EN | | ||
575 | S3C64XX_UCON_RXMODE_MASK); | ||
576 | ucon |= 0xf << S3C64XX_UCON_TIMEOUT_SHIFT | | ||
577 | S3C64XX_UCON_TIMEOUT_EN | | ||
578 | S3C64XX_UCON_RXMODE_CPU; | ||
579 | wr_regl(port, S3C2410_UCON, ucon); | ||
580 | |||
581 | ourport->rx_mode = S3C24XX_RX_PIO; | ||
582 | } | ||
583 | |||
584 | static irqreturn_t s3c24xx_serial_rx_chars_dma(int irq, void *dev_id) | ||
585 | { | ||
586 | unsigned int utrstat, ufstat, received; | ||
587 | struct s3c24xx_uart_port *ourport = dev_id; | ||
588 | struct uart_port *port = &ourport->port; | ||
589 | struct s3c24xx_uart_dma *dma = ourport->dma; | ||
590 | struct tty_struct *tty = tty_port_tty_get(&ourport->port.state->port); | ||
591 | struct tty_port *t = &port->state->port; | ||
592 | unsigned long flags; | ||
593 | struct dma_tx_state state; | ||
594 | |||
595 | utrstat = rd_regl(port, S3C2410_UTRSTAT); | ||
596 | ufstat = rd_regl(port, S3C2410_UFSTAT); | ||
597 | |||
598 | spin_lock_irqsave(&port->lock, flags); | ||
599 | |||
600 | if (!(utrstat & S3C2410_UTRSTAT_TIMEOUT)) { | ||
601 | s3c64xx_start_rx_dma(ourport); | ||
602 | if (ourport->rx_mode == S3C24XX_RX_PIO) | ||
603 | enable_rx_dma(ourport); | ||
604 | goto finish; | ||
605 | } | ||
606 | |||
607 | if (ourport->rx_mode == S3C24XX_RX_DMA) { | ||
608 | dmaengine_pause(dma->rx_chan); | ||
609 | dmaengine_tx_status(dma->rx_chan, dma->rx_cookie, &state); | ||
610 | dmaengine_terminate_all(dma->rx_chan); | ||
611 | received = dma->rx_bytes_requested - state.residue; | ||
612 | s3c24xx_uart_copy_rx_to_tty(ourport, t, received); | ||
613 | |||
614 | enable_rx_pio(ourport); | ||
615 | } | ||
616 | |||
617 | uart_rx_drain_fifo(ourport); | ||
618 | |||
619 | if (tty) { | ||
620 | tty_flip_buffer_push(t); | ||
621 | tty_kref_put(tty); | ||
622 | } | ||
623 | |||
624 | wr_regl(port, S3C2410_UTRSTAT, S3C2410_UTRSTAT_TIMEOUT); | ||
625 | |||
626 | finish: | ||
627 | spin_unlock_irqrestore(&port->lock, flags); | ||
628 | |||
629 | return IRQ_HANDLED; | ||
630 | } | ||
631 | |||
632 | static irqreturn_t s3c24xx_serial_rx_chars_pio(int irq, void *dev_id) | ||
237 | { | 633 | { |
238 | struct s3c24xx_uart_port *ourport = dev_id; | 634 | struct s3c24xx_uart_port *ourport = dev_id; |
239 | struct uart_port *port = &ourport->port; | 635 | struct uart_port *port = &ourport->port; |
@@ -324,16 +720,33 @@ out: | |||
324 | return IRQ_HANDLED; | 720 | return IRQ_HANDLED; |
325 | } | 721 | } |
326 | 722 | ||
723 | |||
724 | static irqreturn_t s3c24xx_serial_rx_chars(int irq, void *dev_id) | ||
725 | { | ||
726 | struct s3c24xx_uart_port *ourport = dev_id; | ||
727 | |||
728 | if (ourport->dma && ourport->dma->rx_chan) | ||
729 | return s3c24xx_serial_rx_chars_dma(irq, dev_id); | ||
730 | return s3c24xx_serial_rx_chars_pio(irq, dev_id); | ||
731 | } | ||
732 | |||
327 | static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) | 733 | static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) |
328 | { | 734 | { |
329 | struct s3c24xx_uart_port *ourport = id; | 735 | struct s3c24xx_uart_port *ourport = id; |
330 | struct uart_port *port = &ourport->port; | 736 | struct uart_port *port = &ourport->port; |
331 | struct circ_buf *xmit = &port->state->xmit; | 737 | struct circ_buf *xmit = &port->state->xmit; |
332 | unsigned long flags; | 738 | unsigned long flags; |
333 | int count = port->fifosize; | 739 | int count; |
334 | 740 | ||
335 | spin_lock_irqsave(&port->lock, flags); | 741 | spin_lock_irqsave(&port->lock, flags); |
336 | 742 | ||
743 | count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); | ||
744 | |||
745 | if (ourport->dma && ourport->dma->tx_chan && count >= port->fifosize) { | ||
746 | s3c24xx_serial_start_tx_dma(ourport, count); | ||
747 | goto out; | ||
748 | } | ||
749 | |||
337 | if (port->x_char) { | 750 | if (port->x_char) { |
338 | wr_regb(port, S3C2410_UTXH, port->x_char); | 751 | wr_regb(port, S3C2410_UTXH, port->x_char); |
339 | port->icount.tx++; | 752 | port->icount.tx++; |
@@ -352,6 +765,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) | |||
352 | 765 | ||
353 | /* try and drain the buffer... */ | 766 | /* try and drain the buffer... */ |
354 | 767 | ||
768 | count = port->fifosize; | ||
355 | while (!uart_circ_empty(xmit) && count-- > 0) { | 769 | while (!uart_circ_empty(xmit) && count-- > 0) { |
356 | if (rd_regl(port, S3C2410_UFSTAT) & ourport->info->tx_fifofull) | 770 | if (rd_regl(port, S3C2410_UFSTAT) & ourport->info->tx_fifofull) |
357 | break; | 771 | break; |
@@ -453,6 +867,93 @@ static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state) | |||
453 | spin_unlock_irqrestore(&port->lock, flags); | 867 | spin_unlock_irqrestore(&port->lock, flags); |
454 | } | 868 | } |
455 | 869 | ||
870 | static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p) | ||
871 | { | ||
872 | struct s3c24xx_uart_dma *dma = p->dma; | ||
873 | dma_cap_mask_t mask; | ||
874 | unsigned long flags; | ||
875 | |||
876 | /* Default slave configuration parameters */ | ||
877 | dma->rx_conf.direction = DMA_DEV_TO_MEM; | ||
878 | dma->rx_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
879 | dma->rx_conf.src_addr = p->port.mapbase + S3C2410_URXH; | ||
880 | dma->rx_conf.src_maxburst = 16; | ||
881 | |||
882 | dma->tx_conf.direction = DMA_MEM_TO_DEV; | ||
883 | dma->tx_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
884 | dma->tx_conf.dst_addr = p->port.mapbase + S3C2410_UTXH; | ||
885 | if (dma_get_cache_alignment() >= 16) | ||
886 | dma->tx_conf.dst_maxburst = 16; | ||
887 | else | ||
888 | dma->tx_conf.dst_maxburst = 1; | ||
889 | |||
890 | dma_cap_zero(mask); | ||
891 | dma_cap_set(DMA_SLAVE, mask); | ||
892 | |||
893 | dma->rx_chan = dma_request_slave_channel_compat(mask, dma->fn, | ||
894 | dma->rx_param, p->port.dev, "rx"); | ||
895 | if (!dma->rx_chan) | ||
896 | return -ENODEV; | ||
897 | |||
898 | dmaengine_slave_config(dma->rx_chan, &dma->rx_conf); | ||
899 | |||
900 | dma->tx_chan = dma_request_slave_channel_compat(mask, dma->fn, | ||
901 | dma->tx_param, p->port.dev, "tx"); | ||
902 | if (!dma->tx_chan) { | ||
903 | dma_release_channel(dma->rx_chan); | ||
904 | return -ENODEV; | ||
905 | } | ||
906 | |||
907 | dmaengine_slave_config(dma->tx_chan, &dma->tx_conf); | ||
908 | |||
909 | /* RX buffer */ | ||
910 | dma->rx_size = PAGE_SIZE; | ||
911 | |||
912 | dma->rx_buf = kmalloc(dma->rx_size, GFP_KERNEL); | ||
913 | |||
914 | if (!dma->rx_buf) { | ||
915 | dma_release_channel(dma->rx_chan); | ||
916 | dma_release_channel(dma->tx_chan); | ||
917 | return -ENOMEM; | ||
918 | } | ||
919 | |||
920 | dma->rx_addr = dma_map_single(dma->rx_chan->device->dev, dma->rx_buf, | ||
921 | dma->rx_size, DMA_FROM_DEVICE); | ||
922 | |||
923 | spin_lock_irqsave(&p->port.lock, flags); | ||
924 | |||
925 | /* TX buffer */ | ||
926 | dma->tx_addr = dma_map_single(dma->tx_chan->device->dev, | ||
927 | p->port.state->xmit.buf, | ||
928 | UART_XMIT_SIZE, DMA_TO_DEVICE); | ||
929 | |||
930 | spin_unlock_irqrestore(&p->port.lock, flags); | ||
931 | |||
932 | return 0; | ||
933 | } | ||
934 | |||
935 | static void s3c24xx_serial_release_dma(struct s3c24xx_uart_port *p) | ||
936 | { | ||
937 | struct s3c24xx_uart_dma *dma = p->dma; | ||
938 | |||
939 | if (dma->rx_chan) { | ||
940 | dmaengine_terminate_all(dma->rx_chan); | ||
941 | dma_unmap_single(dma->rx_chan->device->dev, dma->rx_addr, | ||
942 | dma->rx_size, DMA_FROM_DEVICE); | ||
943 | kfree(dma->rx_buf); | ||
944 | dma_release_channel(dma->rx_chan); | ||
945 | dma->rx_chan = NULL; | ||
946 | } | ||
947 | |||
948 | if (dma->tx_chan) { | ||
949 | dmaengine_terminate_all(dma->tx_chan); | ||
950 | dma_unmap_single(dma->tx_chan->device->dev, dma->tx_addr, | ||
951 | UART_XMIT_SIZE, DMA_TO_DEVICE); | ||
952 | dma_release_channel(dma->tx_chan); | ||
953 | dma->tx_chan = NULL; | ||
954 | } | ||
955 | } | ||
956 | |||
456 | static void s3c24xx_serial_shutdown(struct uart_port *port) | 957 | static void s3c24xx_serial_shutdown(struct uart_port *port) |
457 | { | 958 | { |
458 | struct s3c24xx_uart_port *ourport = to_ourport(port); | 959 | struct s3c24xx_uart_port *ourport = to_ourport(port); |
@@ -478,6 +979,11 @@ static void s3c24xx_serial_shutdown(struct uart_port *port) | |||
478 | wr_regl(port, S3C64XX_UINTP, 0xf); | 979 | wr_regl(port, S3C64XX_UINTP, 0xf); |
479 | wr_regl(port, S3C64XX_UINTM, 0xf); | 980 | wr_regl(port, S3C64XX_UINTM, 0xf); |
480 | } | 981 | } |
982 | |||
983 | if (ourport->dma) | ||
984 | s3c24xx_serial_release_dma(ourport); | ||
985 | |||
986 | ourport->tx_in_progress = 0; | ||
481 | } | 987 | } |
482 | 988 | ||
483 | static int s3c24xx_serial_startup(struct uart_port *port) | 989 | static int s3c24xx_serial_startup(struct uart_port *port) |
@@ -529,12 +1035,21 @@ err: | |||
529 | static int s3c64xx_serial_startup(struct uart_port *port) | 1035 | static int s3c64xx_serial_startup(struct uart_port *port) |
530 | { | 1036 | { |
531 | struct s3c24xx_uart_port *ourport = to_ourport(port); | 1037 | struct s3c24xx_uart_port *ourport = to_ourport(port); |
1038 | unsigned long flags; | ||
1039 | unsigned int ufcon; | ||
532 | int ret; | 1040 | int ret; |
533 | 1041 | ||
534 | dbg("s3c64xx_serial_startup: port=%p (%08llx,%p)\n", | 1042 | dbg("s3c64xx_serial_startup: port=%p (%08llx,%p)\n", |
535 | port, (unsigned long long)port->mapbase, port->membase); | 1043 | port, (unsigned long long)port->mapbase, port->membase); |
536 | 1044 | ||
537 | wr_regl(port, S3C64XX_UINTM, 0xf); | 1045 | wr_regl(port, S3C64XX_UINTM, 0xf); |
1046 | if (ourport->dma) { | ||
1047 | ret = s3c24xx_serial_request_dma(ourport); | ||
1048 | if (ret < 0) { | ||
1049 | dev_warn(port->dev, "DMA request failed\n"); | ||
1050 | return ret; | ||
1051 | } | ||
1052 | } | ||
538 | 1053 | ||
539 | ret = request_irq(port->irq, s3c64xx_serial_handle_irq, IRQF_SHARED, | 1054 | ret = request_irq(port->irq, s3c64xx_serial_handle_irq, IRQF_SHARED, |
540 | s3c24xx_serial_portname(port), ourport); | 1055 | s3c24xx_serial_portname(port), ourport); |
@@ -549,8 +1064,20 @@ static int s3c64xx_serial_startup(struct uart_port *port) | |||
549 | tx_enabled(port) = 0; | 1064 | tx_enabled(port) = 0; |
550 | ourport->tx_claimed = 1; | 1065 | ourport->tx_claimed = 1; |
551 | 1066 | ||
1067 | spin_lock_irqsave(&port->lock, flags); | ||
1068 | |||
1069 | ufcon = rd_regl(port, S3C2410_UFCON); | ||
1070 | ufcon |= S3C2410_UFCON_RESETRX | S3C2410_UFCON_RESETTX | | ||
1071 | S5PV210_UFCON_RXTRIG8; | ||
1072 | wr_regl(port, S3C2410_UFCON, ufcon); | ||
1073 | |||
1074 | enable_rx_pio(ourport); | ||
1075 | |||
1076 | spin_unlock_irqrestore(&port->lock, flags); | ||
1077 | |||
552 | /* Enable Rx Interrupt */ | 1078 | /* Enable Rx Interrupt */ |
553 | __clear_bit(S3C64XX_UINTM_RXD, portaddrl(port, S3C64XX_UINTM)); | 1079 | __clear_bit(S3C64XX_UINTM_RXD, portaddrl(port, S3C64XX_UINTM)); |
1080 | |||
554 | dbg("s3c64xx_serial_startup ok\n"); | 1081 | dbg("s3c64xx_serial_startup ok\n"); |
555 | return ret; | 1082 | return ret; |
556 | } | 1083 | } |
@@ -1209,6 +1736,18 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, | |||
1209 | ret = platform_get_irq(platdev, 1); | 1736 | ret = platform_get_irq(platdev, 1); |
1210 | if (ret > 0) | 1737 | if (ret > 0) |
1211 | ourport->tx_irq = ret; | 1738 | ourport->tx_irq = ret; |
1739 | /* | ||
1740 | * DMA is currently supported only on DT platforms, if DMA properties | ||
1741 | * are specified. | ||
1742 | */ | ||
1743 | if (platdev->dev.of_node && of_find_property(platdev->dev.of_node, | ||
1744 | "dmas", NULL)) { | ||
1745 | ourport->dma = devm_kzalloc(port->dev, | ||
1746 | sizeof(*ourport->dma), | ||
1747 | GFP_KERNEL); | ||
1748 | if (!ourport->dma) | ||
1749 | return -ENOMEM; | ||
1750 | } | ||
1212 | 1751 | ||
1213 | ourport->clk = clk_get(&platdev->dev, "uart"); | 1752 | ourport->clk = clk_get(&platdev->dev, "uart"); |
1214 | if (IS_ERR(ourport->clk)) { | 1753 | if (IS_ERR(ourport->clk)) { |
@@ -1857,6 +2396,111 @@ static struct platform_driver samsung_serial_driver = { | |||
1857 | 2396 | ||
1858 | module_platform_driver(samsung_serial_driver); | 2397 | module_platform_driver(samsung_serial_driver); |
1859 | 2398 | ||
2399 | #ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE | ||
2400 | /* | ||
2401 | * Early console. | ||
2402 | */ | ||
2403 | |||
2404 | struct samsung_early_console_data { | ||
2405 | u32 txfull_mask; | ||
2406 | }; | ||
2407 | |||
2408 | static void samsung_early_busyuart(struct uart_port *port) | ||
2409 | { | ||
2410 | while (!(readl(port->membase + S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXFE)) | ||
2411 | ; | ||
2412 | } | ||
2413 | |||
2414 | static void samsung_early_busyuart_fifo(struct uart_port *port) | ||
2415 | { | ||
2416 | struct samsung_early_console_data *data = port->private_data; | ||
2417 | |||
2418 | while (readl(port->membase + S3C2410_UFSTAT) & data->txfull_mask) | ||
2419 | ; | ||
2420 | } | ||
2421 | |||
2422 | static void samsung_early_putc(struct uart_port *port, int c) | ||
2423 | { | ||
2424 | if (readl(port->membase + S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) | ||
2425 | samsung_early_busyuart_fifo(port); | ||
2426 | else | ||
2427 | samsung_early_busyuart(port); | ||
2428 | |||
2429 | writeb(c, port->membase + S3C2410_UTXH); | ||
2430 | } | ||
2431 | |||
2432 | static void samsung_early_write(struct console *con, const char *s, unsigned n) | ||
2433 | { | ||
2434 | struct earlycon_device *dev = con->data; | ||
2435 | |||
2436 | uart_console_write(&dev->port, s, n, samsung_early_putc); | ||
2437 | } | ||
2438 | |||
2439 | static int __init samsung_early_console_setup(struct earlycon_device *device, | ||
2440 | const char *opt) | ||
2441 | { | ||
2442 | if (!device->port.membase) | ||
2443 | return -ENODEV; | ||
2444 | |||
2445 | device->con->write = samsung_early_write; | ||
2446 | return 0; | ||
2447 | } | ||
2448 | |||
2449 | /* S3C2410 */ | ||
2450 | static struct samsung_early_console_data s3c2410_early_console_data = { | ||
2451 | .txfull_mask = S3C2410_UFSTAT_TXFULL, | ||
2452 | }; | ||
2453 | |||
2454 | static int __init s3c2410_early_console_setup(struct earlycon_device *device, | ||
2455 | const char *opt) | ||
2456 | { | ||
2457 | device->port.private_data = &s3c2410_early_console_data; | ||
2458 | return samsung_early_console_setup(device, opt); | ||
2459 | } | ||
2460 | OF_EARLYCON_DECLARE(s3c2410, "samsung,s3c2410-uart", | ||
2461 | s3c2410_early_console_setup); | ||
2462 | EARLYCON_DECLARE(s3c2410, s3c2410_early_console_setup); | ||
2463 | |||
2464 | /* S3C2412, S3C2440, S3C64xx */ | ||
2465 | static struct samsung_early_console_data s3c2440_early_console_data = { | ||
2466 | .txfull_mask = S3C2440_UFSTAT_TXFULL, | ||
2467 | }; | ||
2468 | |||
2469 | static int __init s3c2440_early_console_setup(struct earlycon_device *device, | ||
2470 | const char *opt) | ||
2471 | { | ||
2472 | device->port.private_data = &s3c2440_early_console_data; | ||
2473 | return samsung_early_console_setup(device, opt); | ||
2474 | } | ||
2475 | OF_EARLYCON_DECLARE(s3c2412, "samsung,s3c2412-uart", | ||
2476 | s3c2440_early_console_setup); | ||
2477 | OF_EARLYCON_DECLARE(s3c2440, "samsung,s3c2440-uart", | ||
2478 | s3c2440_early_console_setup); | ||
2479 | OF_EARLYCON_DECLARE(s3c6400, "samsung,s3c6400-uart", | ||
2480 | s3c2440_early_console_setup); | ||
2481 | EARLYCON_DECLARE(s3c2412, s3c2440_early_console_setup); | ||
2482 | EARLYCON_DECLARE(s3c2440, s3c2440_early_console_setup); | ||
2483 | EARLYCON_DECLARE(s3c6400, s3c2440_early_console_setup); | ||
2484 | |||
2485 | /* S5PV210, EXYNOS */ | ||
2486 | static struct samsung_early_console_data s5pv210_early_console_data = { | ||
2487 | .txfull_mask = S5PV210_UFSTAT_TXFULL, | ||
2488 | }; | ||
2489 | |||
2490 | static int __init s5pv210_early_console_setup(struct earlycon_device *device, | ||
2491 | const char *opt) | ||
2492 | { | ||
2493 | device->port.private_data = &s5pv210_early_console_data; | ||
2494 | return samsung_early_console_setup(device, opt); | ||
2495 | } | ||
2496 | OF_EARLYCON_DECLARE(s5pv210, "samsung,s5pv210-uart", | ||
2497 | s5pv210_early_console_setup); | ||
2498 | OF_EARLYCON_DECLARE(exynos4210, "samsung,exynos4210-uart", | ||
2499 | s5pv210_early_console_setup); | ||
2500 | EARLYCON_DECLARE(s5pv210, s5pv210_early_console_setup); | ||
2501 | EARLYCON_DECLARE(exynos4210, s5pv210_early_console_setup); | ||
2502 | #endif | ||
2503 | |||
1860 | MODULE_ALIAS("platform:samsung-uart"); | 2504 | MODULE_ALIAS("platform:samsung-uart"); |
1861 | MODULE_DESCRIPTION("Samsung SoC Serial port driver"); | 2505 | MODULE_DESCRIPTION("Samsung SoC Serial port driver"); |
1862 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); | 2506 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); |
diff --git a/drivers/tty/serial/samsung.h b/drivers/tty/serial/samsung.h index eb071dd19b2d..d275032aa68d 100644 --- a/drivers/tty/serial/samsung.h +++ b/drivers/tty/serial/samsung.h | |||
@@ -12,6 +12,8 @@ | |||
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/dmaengine.h> | ||
16 | |||
15 | struct s3c24xx_uart_info { | 17 | struct s3c24xx_uart_info { |
16 | char *name; | 18 | char *name; |
17 | unsigned int type; | 19 | unsigned int type; |
@@ -41,6 +43,40 @@ struct s3c24xx_serial_drv_data { | |||
41 | unsigned int fifosize[CONFIG_SERIAL_SAMSUNG_UARTS]; | 43 | unsigned int fifosize[CONFIG_SERIAL_SAMSUNG_UARTS]; |
42 | }; | 44 | }; |
43 | 45 | ||
46 | struct s3c24xx_uart_dma { | ||
47 | dma_filter_fn fn; | ||
48 | void *rx_param; | ||
49 | void *tx_param; | ||
50 | |||
51 | unsigned int rx_chan_id; | ||
52 | unsigned int tx_chan_id; | ||
53 | |||
54 | struct dma_slave_config rx_conf; | ||
55 | struct dma_slave_config tx_conf; | ||
56 | |||
57 | struct dma_chan *rx_chan; | ||
58 | struct dma_chan *tx_chan; | ||
59 | |||
60 | dma_addr_t rx_addr; | ||
61 | dma_addr_t tx_addr; | ||
62 | |||
63 | dma_cookie_t rx_cookie; | ||
64 | dma_cookie_t tx_cookie; | ||
65 | |||
66 | char *rx_buf; | ||
67 | |||
68 | dma_addr_t tx_transfer_addr; | ||
69 | |||
70 | size_t rx_size; | ||
71 | size_t tx_size; | ||
72 | |||
73 | struct dma_async_tx_descriptor *tx_desc; | ||
74 | struct dma_async_tx_descriptor *rx_desc; | ||
75 | |||
76 | int tx_bytes_requested; | ||
77 | int rx_bytes_requested; | ||
78 | }; | ||
79 | |||
44 | struct s3c24xx_uart_port { | 80 | struct s3c24xx_uart_port { |
45 | unsigned char rx_claimed; | 81 | unsigned char rx_claimed; |
46 | unsigned char tx_claimed; | 82 | unsigned char tx_claimed; |
@@ -50,6 +86,10 @@ struct s3c24xx_uart_port { | |||
50 | unsigned int rx_irq; | 86 | unsigned int rx_irq; |
51 | unsigned int tx_irq; | 87 | unsigned int tx_irq; |
52 | 88 | ||
89 | unsigned int tx_in_progress; | ||
90 | unsigned int tx_mode; | ||
91 | unsigned int rx_mode; | ||
92 | |||
53 | struct s3c24xx_uart_info *info; | 93 | struct s3c24xx_uart_info *info; |
54 | struct clk *clk; | 94 | struct clk *clk; |
55 | struct clk *baudclk; | 95 | struct clk *baudclk; |
@@ -59,6 +99,8 @@ struct s3c24xx_uart_port { | |||
59 | /* reference to platform data */ | 99 | /* reference to platform data */ |
60 | struct s3c2410_uartcfg *cfg; | 100 | struct s3c2410_uartcfg *cfg; |
61 | 101 | ||
102 | struct s3c24xx_uart_dma *dma; | ||
103 | |||
62 | #ifdef CONFIG_CPU_FREQ | 104 | #ifdef CONFIG_CPU_FREQ |
63 | struct notifier_block freq_transition; | 105 | struct notifier_block freq_transition; |
64 | #endif | 106 | #endif |
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 984605bb5bf1..6a1055ae3437 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c | |||
@@ -179,14 +179,6 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, | |||
179 | if (tty->termios.c_cflag & CBAUD) | 179 | if (tty->termios.c_cflag & CBAUD) |
180 | uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR); | 180 | uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR); |
181 | } | 181 | } |
182 | |||
183 | spin_lock_irq(&uport->lock); | ||
184 | if (uart_cts_enabled(uport) && | ||
185 | !(uport->ops->get_mctrl(uport) & TIOCM_CTS)) | ||
186 | uport->hw_stopped = 1; | ||
187 | else | ||
188 | uport->hw_stopped = 0; | ||
189 | spin_unlock_irq(&uport->lock); | ||
190 | } | 182 | } |
191 | 183 | ||
192 | /* | 184 | /* |
@@ -442,6 +434,7 @@ static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, | |||
442 | { | 434 | { |
443 | struct uart_port *uport = state->uart_port; | 435 | struct uart_port *uport = state->uart_port; |
444 | struct ktermios *termios; | 436 | struct ktermios *termios; |
437 | int hw_stopped; | ||
445 | 438 | ||
446 | /* | 439 | /* |
447 | * If we have no tty, termios, or the port does not exist, | 440 | * If we have no tty, termios, or the port does not exist, |
@@ -466,6 +459,18 @@ static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, | |||
466 | uport->status &= ~UPSTAT_DCD_ENABLE; | 459 | uport->status &= ~UPSTAT_DCD_ENABLE; |
467 | else | 460 | else |
468 | uport->status |= UPSTAT_DCD_ENABLE; | 461 | uport->status |= UPSTAT_DCD_ENABLE; |
462 | |||
463 | /* reset sw-assisted CTS flow control based on (possibly) new mode */ | ||
464 | hw_stopped = uport->hw_stopped; | ||
465 | uport->hw_stopped = uart_softcts_mode(uport) && | ||
466 | !(uport->ops->get_mctrl(uport) & TIOCM_CTS); | ||
467 | if (uport->hw_stopped) { | ||
468 | if (!hw_stopped) | ||
469 | uport->ops->stop_tx(uport); | ||
470 | } else { | ||
471 | if (hw_stopped) | ||
472 | __uart_start(tty); | ||
473 | } | ||
469 | spin_unlock_irq(&uport->lock); | 474 | spin_unlock_irq(&uport->lock); |
470 | } | 475 | } |
471 | 476 | ||
@@ -619,22 +624,22 @@ static void uart_throttle(struct tty_struct *tty) | |||
619 | { | 624 | { |
620 | struct uart_state *state = tty->driver_data; | 625 | struct uart_state *state = tty->driver_data; |
621 | struct uart_port *port = state->uart_port; | 626 | struct uart_port *port = state->uart_port; |
622 | upf_t mask = 0; | 627 | upstat_t mask = 0; |
623 | 628 | ||
624 | if (I_IXOFF(tty)) | 629 | if (I_IXOFF(tty)) |
625 | mask |= UPF_SOFT_FLOW; | 630 | mask |= UPSTAT_AUTOXOFF; |
626 | if (tty->termios.c_cflag & CRTSCTS) | 631 | if (tty->termios.c_cflag & CRTSCTS) |
627 | mask |= UPF_HARD_FLOW; | 632 | mask |= UPSTAT_AUTORTS; |
628 | 633 | ||
629 | if (port->flags & mask) { | 634 | if (port->status & mask) { |
630 | port->ops->throttle(port); | 635 | port->ops->throttle(port); |
631 | mask &= ~port->flags; | 636 | mask &= ~port->status; |
632 | } | 637 | } |
633 | 638 | ||
634 | if (mask & UPF_SOFT_FLOW) | 639 | if (mask & UPSTAT_AUTOXOFF) |
635 | uart_send_xchar(tty, STOP_CHAR(tty)); | 640 | uart_send_xchar(tty, STOP_CHAR(tty)); |
636 | 641 | ||
637 | if (mask & UPF_HARD_FLOW) | 642 | if (mask & UPSTAT_AUTORTS) |
638 | uart_clear_mctrl(port, TIOCM_RTS); | 643 | uart_clear_mctrl(port, TIOCM_RTS); |
639 | } | 644 | } |
640 | 645 | ||
@@ -642,22 +647,22 @@ static void uart_unthrottle(struct tty_struct *tty) | |||
642 | { | 647 | { |
643 | struct uart_state *state = tty->driver_data; | 648 | struct uart_state *state = tty->driver_data; |
644 | struct uart_port *port = state->uart_port; | 649 | struct uart_port *port = state->uart_port; |
645 | upf_t mask = 0; | 650 | upstat_t mask = 0; |
646 | 651 | ||
647 | if (I_IXOFF(tty)) | 652 | if (I_IXOFF(tty)) |
648 | mask |= UPF_SOFT_FLOW; | 653 | mask |= UPSTAT_AUTOXOFF; |
649 | if (tty->termios.c_cflag & CRTSCTS) | 654 | if (tty->termios.c_cflag & CRTSCTS) |
650 | mask |= UPF_HARD_FLOW; | 655 | mask |= UPSTAT_AUTORTS; |
651 | 656 | ||
652 | if (port->flags & mask) { | 657 | if (port->status & mask) { |
653 | port->ops->unthrottle(port); | 658 | port->ops->unthrottle(port); |
654 | mask &= ~port->flags; | 659 | mask &= ~port->status; |
655 | } | 660 | } |
656 | 661 | ||
657 | if (mask & UPF_SOFT_FLOW) | 662 | if (mask & UPSTAT_AUTOXOFF) |
658 | uart_send_xchar(tty, START_CHAR(tty)); | 663 | uart_send_xchar(tty, START_CHAR(tty)); |
659 | 664 | ||
660 | if (mask & UPF_HARD_FLOW) | 665 | if (mask & UPSTAT_AUTORTS) |
661 | uart_set_mctrl(port, TIOCM_RTS); | 666 | uart_set_mctrl(port, TIOCM_RTS); |
662 | } | 667 | } |
663 | 668 | ||
@@ -1351,30 +1356,6 @@ static void uart_set_termios(struct tty_struct *tty, | |||
1351 | mask |= TIOCM_RTS; | 1356 | mask |= TIOCM_RTS; |
1352 | uart_set_mctrl(uport, mask); | 1357 | uart_set_mctrl(uport, mask); |
1353 | } | 1358 | } |
1354 | |||
1355 | /* | ||
1356 | * If the port is doing h/w assisted flow control, do nothing. | ||
1357 | * We assume that port->hw_stopped has never been set. | ||
1358 | */ | ||
1359 | if (uport->flags & UPF_HARD_FLOW) | ||
1360 | return; | ||
1361 | |||
1362 | /* Handle turning off CRTSCTS */ | ||
1363 | if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) { | ||
1364 | spin_lock_irq(&uport->lock); | ||
1365 | uport->hw_stopped = 0; | ||
1366 | __uart_start(tty); | ||
1367 | spin_unlock_irq(&uport->lock); | ||
1368 | } | ||
1369 | /* Handle turning on CRTSCTS */ | ||
1370 | else if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) { | ||
1371 | spin_lock_irq(&uport->lock); | ||
1372 | if (!(uport->ops->get_mctrl(uport) & TIOCM_CTS)) { | ||
1373 | uport->hw_stopped = 1; | ||
1374 | uport->ops->stop_tx(uport); | ||
1375 | } | ||
1376 | spin_unlock_irq(&uport->lock); | ||
1377 | } | ||
1378 | } | 1359 | } |
1379 | 1360 | ||
1380 | /* | 1361 | /* |
@@ -2008,23 +1989,24 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) | |||
2008 | } | 1989 | } |
2009 | put_device(tty_dev); | 1990 | put_device(tty_dev); |
2010 | 1991 | ||
2011 | if (console_suspend_enabled || !uart_console(uport)) | 1992 | /* Nothing to do if the console is not suspending */ |
2012 | uport->suspended = 1; | 1993 | if (!console_suspend_enabled && uart_console(uport)) |
1994 | goto unlock; | ||
1995 | |||
1996 | uport->suspended = 1; | ||
2013 | 1997 | ||
2014 | if (port->flags & ASYNC_INITIALIZED) { | 1998 | if (port->flags & ASYNC_INITIALIZED) { |
2015 | const struct uart_ops *ops = uport->ops; | 1999 | const struct uart_ops *ops = uport->ops; |
2016 | int tries; | 2000 | int tries; |
2017 | 2001 | ||
2018 | if (console_suspend_enabled || !uart_console(uport)) { | 2002 | set_bit(ASYNCB_SUSPENDED, &port->flags); |
2019 | set_bit(ASYNCB_SUSPENDED, &port->flags); | 2003 | clear_bit(ASYNCB_INITIALIZED, &port->flags); |
2020 | clear_bit(ASYNCB_INITIALIZED, &port->flags); | 2004 | |
2021 | 2005 | spin_lock_irq(&uport->lock); | |
2022 | spin_lock_irq(&uport->lock); | 2006 | ops->stop_tx(uport); |
2023 | ops->stop_tx(uport); | 2007 | ops->set_mctrl(uport, 0); |
2024 | ops->set_mctrl(uport, 0); | 2008 | ops->stop_rx(uport); |
2025 | ops->stop_rx(uport); | 2009 | spin_unlock_irq(&uport->lock); |
2026 | spin_unlock_irq(&uport->lock); | ||
2027 | } | ||
2028 | 2010 | ||
2029 | /* | 2011 | /* |
2030 | * Wait for the transmitter to empty. | 2012 | * Wait for the transmitter to empty. |
@@ -2036,19 +2018,17 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) | |||
2036 | drv->dev_name, | 2018 | drv->dev_name, |
2037 | drv->tty_driver->name_base + uport->line); | 2019 | drv->tty_driver->name_base + uport->line); |
2038 | 2020 | ||
2039 | if (console_suspend_enabled || !uart_console(uport)) | 2021 | ops->shutdown(uport); |
2040 | ops->shutdown(uport); | ||
2041 | } | 2022 | } |
2042 | 2023 | ||
2043 | /* | 2024 | /* |
2044 | * Disable the console device before suspending. | 2025 | * Disable the console device before suspending. |
2045 | */ | 2026 | */ |
2046 | if (console_suspend_enabled && uart_console(uport)) | 2027 | if (uart_console(uport)) |
2047 | console_stop(uport->cons); | 2028 | console_stop(uport->cons); |
2048 | 2029 | ||
2049 | if (console_suspend_enabled || !uart_console(uport)) | 2030 | uart_change_pm(state, UART_PM_STATE_OFF); |
2050 | uart_change_pm(state, UART_PM_STATE_OFF); | 2031 | unlock: |
2051 | |||
2052 | mutex_unlock(&port->mutex); | 2032 | mutex_unlock(&port->mutex); |
2053 | 2033 | ||
2054 | return 0; | 2034 | return 0; |
@@ -2856,7 +2836,7 @@ void uart_handle_cts_change(struct uart_port *uport, unsigned int status) | |||
2856 | 2836 | ||
2857 | uport->icount.cts++; | 2837 | uport->icount.cts++; |
2858 | 2838 | ||
2859 | if (uart_cts_enabled(uport)) { | 2839 | if (uart_softcts_mode(uport)) { |
2860 | if (uport->hw_stopped) { | 2840 | if (uport->hw_stopped) { |
2861 | if (status) { | 2841 | if (status) { |
2862 | uport->hw_stopped = 0; | 2842 | uport->hw_stopped = 0; |
@@ -2869,6 +2849,7 @@ void uart_handle_cts_change(struct uart_port *uport, unsigned int status) | |||
2869 | uport->ops->stop_tx(uport); | 2849 | uport->ops->stop_tx(uport); |
2870 | } | 2850 | } |
2871 | } | 2851 | } |
2852 | |||
2872 | } | 2853 | } |
2873 | } | 2854 | } |
2874 | EXPORT_SYMBOL_GPL(uart_handle_cts_change); | 2855 | EXPORT_SYMBOL_GPL(uart_handle_cts_change); |
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index e032963989fc..5b50c792ad5f 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
@@ -858,7 +858,7 @@ static int sci_handle_fifo_overrun(struct uart_port *port) | |||
858 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); | 858 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
859 | tty_flip_buffer_push(tport); | 859 | tty_flip_buffer_push(tport); |
860 | 860 | ||
861 | dev_notice(port->dev, "overrun error\n"); | 861 | dev_dbg(port->dev, "overrun error\n"); |
862 | copied++; | 862 | copied++; |
863 | } | 863 | } |
864 | 864 | ||
@@ -997,12 +997,15 @@ static inline unsigned long port_rx_irq_mask(struct uart_port *port) | |||
997 | static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) | 997 | static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) |
998 | { | 998 | { |
999 | unsigned short ssr_status, scr_status, err_enabled; | 999 | unsigned short ssr_status, scr_status, err_enabled; |
1000 | unsigned short slr_status = 0; | ||
1000 | struct uart_port *port = ptr; | 1001 | struct uart_port *port = ptr; |
1001 | struct sci_port *s = to_sci_port(port); | 1002 | struct sci_port *s = to_sci_port(port); |
1002 | irqreturn_t ret = IRQ_NONE; | 1003 | irqreturn_t ret = IRQ_NONE; |
1003 | 1004 | ||
1004 | ssr_status = serial_port_in(port, SCxSR); | 1005 | ssr_status = serial_port_in(port, SCxSR); |
1005 | scr_status = serial_port_in(port, SCSCR); | 1006 | scr_status = serial_port_in(port, SCSCR); |
1007 | if (port->type == PORT_SCIF || port->type == PORT_HSCIF) | ||
1008 | slr_status = serial_port_in(port, SCLSR); | ||
1006 | err_enabled = scr_status & port_rx_irq_mask(port); | 1009 | err_enabled = scr_status & port_rx_irq_mask(port); |
1007 | 1010 | ||
1008 | /* Tx Interrupt */ | 1011 | /* Tx Interrupt */ |
@@ -1015,8 +1018,11 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) | |||
1015 | * DR flags | 1018 | * DR flags |
1016 | */ | 1019 | */ |
1017 | if (((ssr_status & SCxSR_RDxF(port)) || s->chan_rx) && | 1020 | if (((ssr_status & SCxSR_RDxF(port)) || s->chan_rx) && |
1018 | (scr_status & SCSCR_RIE)) | 1021 | (scr_status & SCSCR_RIE)) { |
1022 | if (port->type == PORT_SCIF || port->type == PORT_HSCIF) | ||
1023 | sci_handle_fifo_overrun(port); | ||
1019 | ret = sci_rx_interrupt(irq, ptr); | 1024 | ret = sci_rx_interrupt(irq, ptr); |
1025 | } | ||
1020 | 1026 | ||
1021 | /* Error Interrupt */ | 1027 | /* Error Interrupt */ |
1022 | if ((ssr_status & SCxSR_ERRORS(port)) && err_enabled) | 1028 | if ((ssr_status & SCxSR_ERRORS(port)) && err_enabled) |
@@ -1026,6 +1032,12 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) | |||
1026 | if ((ssr_status & SCxSR_BRK(port)) && err_enabled) | 1032 | if ((ssr_status & SCxSR_BRK(port)) && err_enabled) |
1027 | ret = sci_br_interrupt(irq, ptr); | 1033 | ret = sci_br_interrupt(irq, ptr); |
1028 | 1034 | ||
1035 | /* Overrun Interrupt */ | ||
1036 | if (port->type == PORT_SCIF || port->type == PORT_HSCIF) { | ||
1037 | if (slr_status & 0x01) | ||
1038 | sci_handle_fifo_overrun(port); | ||
1039 | } | ||
1040 | |||
1029 | return ret; | 1041 | return ret; |
1030 | } | 1042 | } |
1031 | 1043 | ||
@@ -2605,7 +2617,7 @@ static int sci_probe(struct platform_device *dev) | |||
2605 | return 0; | 2617 | return 0; |
2606 | } | 2618 | } |
2607 | 2619 | ||
2608 | static int sci_suspend(struct device *dev) | 2620 | static __maybe_unused int sci_suspend(struct device *dev) |
2609 | { | 2621 | { |
2610 | struct sci_port *sport = dev_get_drvdata(dev); | 2622 | struct sci_port *sport = dev_get_drvdata(dev); |
2611 | 2623 | ||
@@ -2615,7 +2627,7 @@ static int sci_suspend(struct device *dev) | |||
2615 | return 0; | 2627 | return 0; |
2616 | } | 2628 | } |
2617 | 2629 | ||
2618 | static int sci_resume(struct device *dev) | 2630 | static __maybe_unused int sci_resume(struct device *dev) |
2619 | { | 2631 | { |
2620 | struct sci_port *sport = dev_get_drvdata(dev); | 2632 | struct sci_port *sport = dev_get_drvdata(dev); |
2621 | 2633 | ||
@@ -2625,10 +2637,7 @@ static int sci_resume(struct device *dev) | |||
2625 | return 0; | 2637 | return 0; |
2626 | } | 2638 | } |
2627 | 2639 | ||
2628 | static const struct dev_pm_ops sci_dev_pm_ops = { | 2640 | static SIMPLE_DEV_PM_OPS(sci_dev_pm_ops, sci_suspend, sci_resume); |
2629 | .suspend = sci_suspend, | ||
2630 | .resume = sci_resume, | ||
2631 | }; | ||
2632 | 2641 | ||
2633 | static struct platform_driver sci_driver = { | 2642 | static struct platform_driver sci_driver = { |
2634 | .probe = sci_probe, | 2643 | .probe = sci_probe, |
diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index b269f6bd16d6..27ed0e960880 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c | |||
@@ -177,7 +177,7 @@ static void sirfsoc_uart_stop_tx(struct uart_port *port) | |||
177 | dmaengine_pause(sirfport->tx_dma_chan); | 177 | dmaengine_pause(sirfport->tx_dma_chan); |
178 | sirfport->tx_dma_state = TX_DMA_PAUSE; | 178 | sirfport->tx_dma_state = TX_DMA_PAUSE; |
179 | } else { | 179 | } else { |
180 | if (!sirfport->is_marco) | 180 | if (!sirfport->is_atlas7) |
181 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 181 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
182 | rd_regl(port, ureg->sirfsoc_int_en_reg) & | 182 | rd_regl(port, ureg->sirfsoc_int_en_reg) & |
183 | ~uint_en->sirfsoc_txfifo_empty_en); | 183 | ~uint_en->sirfsoc_txfifo_empty_en); |
@@ -186,7 +186,7 @@ static void sirfsoc_uart_stop_tx(struct uart_port *port) | |||
186 | uint_en->sirfsoc_txfifo_empty_en); | 186 | uint_en->sirfsoc_txfifo_empty_en); |
187 | } | 187 | } |
188 | } else { | 188 | } else { |
189 | if (!sirfport->is_marco) | 189 | if (!sirfport->is_atlas7) |
190 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 190 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
191 | rd_regl(port, ureg->sirfsoc_int_en_reg) & | 191 | rd_regl(port, ureg->sirfsoc_int_en_reg) & |
192 | ~uint_en->sirfsoc_txfifo_empty_en); | 192 | ~uint_en->sirfsoc_txfifo_empty_en); |
@@ -217,7 +217,7 @@ static void sirfsoc_uart_tx_with_dma(struct sirfsoc_uart_port *sirfport) | |||
217 | } | 217 | } |
218 | if (sirfport->tx_dma_state == TX_DMA_RUNNING) | 218 | if (sirfport->tx_dma_state == TX_DMA_RUNNING) |
219 | return; | 219 | return; |
220 | if (!sirfport->is_marco) | 220 | if (!sirfport->is_atlas7) |
221 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 221 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
222 | rd_regl(port, ureg->sirfsoc_int_en_reg)& | 222 | rd_regl(port, ureg->sirfsoc_int_en_reg)& |
223 | ~(uint_en->sirfsoc_txfifo_empty_en)); | 223 | ~(uint_en->sirfsoc_txfifo_empty_en)); |
@@ -244,7 +244,7 @@ static void sirfsoc_uart_tx_with_dma(struct sirfsoc_uart_port *sirfport) | |||
244 | } | 244 | } |
245 | if (tran_size < 4) | 245 | if (tran_size < 4) |
246 | sirfsoc_uart_pio_tx_chars(sirfport, tran_size); | 246 | sirfsoc_uart_pio_tx_chars(sirfport, tran_size); |
247 | if (!sirfport->is_marco) | 247 | if (!sirfport->is_atlas7) |
248 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 248 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
249 | rd_regl(port, ureg->sirfsoc_int_en_reg)| | 249 | rd_regl(port, ureg->sirfsoc_int_en_reg)| |
250 | uint_en->sirfsoc_txfifo_empty_en); | 250 | uint_en->sirfsoc_txfifo_empty_en); |
@@ -293,7 +293,7 @@ static void sirfsoc_uart_start_tx(struct uart_port *port) | |||
293 | sirfsoc_uart_pio_tx_chars(sirfport, | 293 | sirfsoc_uart_pio_tx_chars(sirfport, |
294 | SIRFSOC_UART_IO_TX_REASONABLE_CNT); | 294 | SIRFSOC_UART_IO_TX_REASONABLE_CNT); |
295 | wr_regl(port, ureg->sirfsoc_tx_fifo_op, SIRFUART_FIFO_START); | 295 | wr_regl(port, ureg->sirfsoc_tx_fifo_op, SIRFUART_FIFO_START); |
296 | if (!sirfport->is_marco) | 296 | if (!sirfport->is_atlas7) |
297 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 297 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
298 | rd_regl(port, ureg->sirfsoc_int_en_reg)| | 298 | rd_regl(port, ureg->sirfsoc_int_en_reg)| |
299 | uint_en->sirfsoc_txfifo_empty_en); | 299 | uint_en->sirfsoc_txfifo_empty_en); |
@@ -311,7 +311,7 @@ static void sirfsoc_uart_stop_rx(struct uart_port *port) | |||
311 | 311 | ||
312 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0); | 312 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0); |
313 | if (sirfport->rx_dma_chan) { | 313 | if (sirfport->rx_dma_chan) { |
314 | if (!sirfport->is_marco) | 314 | if (!sirfport->is_atlas7) |
315 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 315 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
316 | rd_regl(port, ureg->sirfsoc_int_en_reg) & | 316 | rd_regl(port, ureg->sirfsoc_int_en_reg) & |
317 | ~(SIRFUART_RX_DMA_INT_EN(port, uint_en) | | 317 | ~(SIRFUART_RX_DMA_INT_EN(port, uint_en) | |
@@ -322,7 +322,7 @@ static void sirfsoc_uart_stop_rx(struct uart_port *port) | |||
322 | uint_en->sirfsoc_rx_done_en); | 322 | uint_en->sirfsoc_rx_done_en); |
323 | dmaengine_terminate_all(sirfport->rx_dma_chan); | 323 | dmaengine_terminate_all(sirfport->rx_dma_chan); |
324 | } else { | 324 | } else { |
325 | if (!sirfport->is_marco) | 325 | if (!sirfport->is_atlas7) |
326 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 326 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
327 | rd_regl(port, ureg->sirfsoc_int_en_reg)& | 327 | rd_regl(port, ureg->sirfsoc_int_en_reg)& |
328 | ~(SIRFUART_RX_IO_INT_EN(port, uint_en))); | 328 | ~(SIRFUART_RX_IO_INT_EN(port, uint_en))); |
@@ -344,7 +344,7 @@ static void sirfsoc_uart_disable_ms(struct uart_port *port) | |||
344 | if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { | 344 | if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { |
345 | wr_regl(port, ureg->sirfsoc_afc_ctrl, | 345 | wr_regl(port, ureg->sirfsoc_afc_ctrl, |
346 | rd_regl(port, ureg->sirfsoc_afc_ctrl) & ~0x3FF); | 346 | rd_regl(port, ureg->sirfsoc_afc_ctrl) & ~0x3FF); |
347 | if (!sirfport->is_marco) | 347 | if (!sirfport->is_atlas7) |
348 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 348 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
349 | rd_regl(port, ureg->sirfsoc_int_en_reg)& | 349 | rd_regl(port, ureg->sirfsoc_int_en_reg)& |
350 | ~uint_en->sirfsoc_cts_en); | 350 | ~uint_en->sirfsoc_cts_en); |
@@ -380,7 +380,7 @@ static void sirfsoc_uart_enable_ms(struct uart_port *port) | |||
380 | wr_regl(port, ureg->sirfsoc_afc_ctrl, | 380 | wr_regl(port, ureg->sirfsoc_afc_ctrl, |
381 | rd_regl(port, ureg->sirfsoc_afc_ctrl) | | 381 | rd_regl(port, ureg->sirfsoc_afc_ctrl) | |
382 | SIRFUART_AFC_TX_EN | SIRFUART_AFC_RX_EN); | 382 | SIRFUART_AFC_TX_EN | SIRFUART_AFC_RX_EN); |
383 | if (!sirfport->is_marco) | 383 | if (!sirfport->is_atlas7) |
384 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 384 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
385 | rd_regl(port, ureg->sirfsoc_int_en_reg) | 385 | rd_regl(port, ureg->sirfsoc_int_en_reg) |
386 | | uint_en->sirfsoc_cts_en); | 386 | | uint_en->sirfsoc_cts_en); |
@@ -544,7 +544,7 @@ static void sirfsoc_rx_tmo_process_tl(unsigned long param) | |||
544 | sirfport->rx_io_count = 0; | 544 | sirfport->rx_io_count = 0; |
545 | wr_regl(port, ureg->sirfsoc_int_st_reg, | 545 | wr_regl(port, ureg->sirfsoc_int_st_reg, |
546 | uint_st->sirfsoc_rx_done); | 546 | uint_st->sirfsoc_rx_done); |
547 | if (!sirfport->is_marco) | 547 | if (!sirfport->is_atlas7) |
548 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 548 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
549 | rd_regl(port, ureg->sirfsoc_int_en_reg) & | 549 | rd_regl(port, ureg->sirfsoc_int_en_reg) & |
550 | ~(uint_en->sirfsoc_rx_done_en)); | 550 | ~(uint_en->sirfsoc_rx_done_en)); |
@@ -555,7 +555,7 @@ static void sirfsoc_rx_tmo_process_tl(unsigned long param) | |||
555 | } else { | 555 | } else { |
556 | wr_regl(port, ureg->sirfsoc_int_st_reg, | 556 | wr_regl(port, ureg->sirfsoc_int_st_reg, |
557 | uint_st->sirfsoc_rx_done); | 557 | uint_st->sirfsoc_rx_done); |
558 | if (!sirfport->is_marco) | 558 | if (!sirfport->is_atlas7) |
559 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 559 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
560 | rd_regl(port, ureg->sirfsoc_int_en_reg) | | 560 | rd_regl(port, ureg->sirfsoc_int_en_reg) | |
561 | (uint_en->sirfsoc_rx_done_en)); | 561 | (uint_en->sirfsoc_rx_done_en)); |
@@ -578,7 +578,7 @@ static void sirfsoc_uart_handle_rx_tmo(struct sirfsoc_uart_port *sirfport) | |||
578 | dmaengine_terminate_all(sirfport->rx_dma_chan); | 578 | dmaengine_terminate_all(sirfport->rx_dma_chan); |
579 | sirfport->rx_dma_items[sirfport->rx_issued].xmit.head = | 579 | sirfport->rx_dma_items[sirfport->rx_issued].xmit.head = |
580 | SIRFSOC_RX_DMA_BUF_SIZE - tx_state.residue; | 580 | SIRFSOC_RX_DMA_BUF_SIZE - tx_state.residue; |
581 | if (!sirfport->is_marco) | 581 | if (!sirfport->is_atlas7) |
582 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 582 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
583 | rd_regl(port, ureg->sirfsoc_int_en_reg) & | 583 | rd_regl(port, ureg->sirfsoc_int_en_reg) & |
584 | ~(uint_en->sirfsoc_rx_timeout_en)); | 584 | ~(uint_en->sirfsoc_rx_timeout_en)); |
@@ -598,7 +598,7 @@ static void sirfsoc_uart_handle_rx_done(struct sirfsoc_uart_port *sirfport) | |||
598 | sirfsoc_uart_pio_rx_chars(port, 4 - sirfport->rx_io_count); | 598 | sirfsoc_uart_pio_rx_chars(port, 4 - sirfport->rx_io_count); |
599 | if (sirfport->rx_io_count == 4) { | 599 | if (sirfport->rx_io_count == 4) { |
600 | sirfport->rx_io_count = 0; | 600 | sirfport->rx_io_count = 0; |
601 | if (!sirfport->is_marco) | 601 | if (!sirfport->is_atlas7) |
602 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 602 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
603 | rd_regl(port, ureg->sirfsoc_int_en_reg) & | 603 | rd_regl(port, ureg->sirfsoc_int_en_reg) & |
604 | ~(uint_en->sirfsoc_rx_done_en)); | 604 | ~(uint_en->sirfsoc_rx_done_en)); |
@@ -748,7 +748,7 @@ static void sirfsoc_uart_start_next_rx_dma(struct uart_port *port) | |||
748 | for (i = 0; i < SIRFSOC_RX_LOOP_BUF_CNT; i++) | 748 | for (i = 0; i < SIRFSOC_RX_LOOP_BUF_CNT; i++) |
749 | sirfsoc_rx_submit_one_dma_desc(port, i); | 749 | sirfsoc_rx_submit_one_dma_desc(port, i); |
750 | sirfport->rx_completed = sirfport->rx_issued = 0; | 750 | sirfport->rx_completed = sirfport->rx_issued = 0; |
751 | if (!sirfport->is_marco) | 751 | if (!sirfport->is_atlas7) |
752 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 752 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
753 | rd_regl(port, ureg->sirfsoc_int_en_reg) | | 753 | rd_regl(port, ureg->sirfsoc_int_en_reg) | |
754 | SIRFUART_RX_DMA_INT_EN(port, uint_en)); | 754 | SIRFUART_RX_DMA_INT_EN(port, uint_en)); |
@@ -770,7 +770,7 @@ static void sirfsoc_uart_start_rx(struct uart_port *port) | |||
770 | if (sirfport->rx_dma_chan) | 770 | if (sirfport->rx_dma_chan) |
771 | sirfsoc_uart_start_next_rx_dma(port); | 771 | sirfsoc_uart_start_next_rx_dma(port); |
772 | else { | 772 | else { |
773 | if (!sirfport->is_marco) | 773 | if (!sirfport->is_atlas7) |
774 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 774 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
775 | rd_regl(port, ureg->sirfsoc_int_en_reg) | | 775 | rd_regl(port, ureg->sirfsoc_int_en_reg) | |
776 | SIRFUART_RX_IO_INT_EN(port, uint_en)); | 776 | SIRFUART_RX_IO_INT_EN(port, uint_en)); |
@@ -1124,7 +1124,7 @@ static void sirfsoc_uart_shutdown(struct uart_port *port) | |||
1124 | { | 1124 | { |
1125 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | 1125 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); |
1126 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; | 1126 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; |
1127 | if (!sirfport->is_marco) | 1127 | if (!sirfport->is_atlas7) |
1128 | wr_regl(port, ureg->sirfsoc_int_en_reg, 0); | 1128 | wr_regl(port, ureg->sirfsoc_int_en_reg, 0); |
1129 | else | 1129 | else |
1130 | wr_regl(port, SIRFUART_INT_EN_CLR, ~0UL); | 1130 | wr_regl(port, SIRFUART_INT_EN_CLR, ~0UL); |
@@ -1271,7 +1271,7 @@ static struct uart_driver sirfsoc_uart_drv = { | |||
1271 | 1271 | ||
1272 | static struct of_device_id sirfsoc_uart_ids[] = { | 1272 | static struct of_device_id sirfsoc_uart_ids[] = { |
1273 | { .compatible = "sirf,prima2-uart", .data = &sirfsoc_uart,}, | 1273 | { .compatible = "sirf,prima2-uart", .data = &sirfsoc_uart,}, |
1274 | { .compatible = "sirf,marco-uart", .data = &sirfsoc_uart}, | 1274 | { .compatible = "sirf,atlas7-uart", .data = &sirfsoc_uart}, |
1275 | { .compatible = "sirf,prima2-usp-uart", .data = &sirfsoc_usp}, | 1275 | { .compatible = "sirf,prima2-usp-uart", .data = &sirfsoc_usp}, |
1276 | {} | 1276 | {} |
1277 | }; | 1277 | }; |
@@ -1350,8 +1350,8 @@ static int sirfsoc_uart_probe(struct platform_device *pdev) | |||
1350 | gpio_direction_output(sirfport->rts_gpio, 1); | 1350 | gpio_direction_output(sirfport->rts_gpio, 1); |
1351 | } | 1351 | } |
1352 | usp_no_flow_control: | 1352 | usp_no_flow_control: |
1353 | if (of_device_is_compatible(pdev->dev.of_node, "sirf,marco-uart")) | 1353 | if (of_device_is_compatible(pdev->dev.of_node, "sirf,atlas7-uart")) |
1354 | sirfport->is_marco = true; | 1354 | sirfport->is_atlas7 = true; |
1355 | 1355 | ||
1356 | if (of_property_read_u32(pdev->dev.of_node, | 1356 | if (of_property_read_u32(pdev->dev.of_node, |
1357 | "fifosize", | 1357 | "fifosize", |
@@ -1393,7 +1393,7 @@ usp_no_flow_control: | |||
1393 | goto err; | 1393 | goto err; |
1394 | } | 1394 | } |
1395 | port->uartclk = clk_get_rate(sirfport->clk); | 1395 | port->uartclk = clk_get_rate(sirfport->clk); |
1396 | if (of_device_is_compatible(pdev->dev.of_node, "sirf,marco-bt-uart")) { | 1396 | if (of_device_is_compatible(pdev->dev.of_node, "sirf,atlas7-bt-uart")) { |
1397 | sirfport->clk_general = devm_clk_get(&pdev->dev, "general"); | 1397 | sirfport->clk_general = devm_clk_get(&pdev->dev, "general"); |
1398 | if (IS_ERR(sirfport->clk_general)) { | 1398 | if (IS_ERR(sirfport->clk_general)) { |
1399 | ret = PTR_ERR(sirfport->clk_general); | 1399 | ret = PTR_ERR(sirfport->clk_general); |
diff --git a/drivers/tty/serial/sirfsoc_uart.h b/drivers/tty/serial/sirfsoc_uart.h index 275d03893990..727eb6b88fff 100644 --- a/drivers/tty/serial/sirfsoc_uart.h +++ b/drivers/tty/serial/sirfsoc_uart.h | |||
@@ -421,8 +421,8 @@ struct sirfsoc_uart_port { | |||
421 | bool is_bt_uart; | 421 | bool is_bt_uart; |
422 | struct clk *clk_general; | 422 | struct clk *clk_general; |
423 | struct clk *clk_noc; | 423 | struct clk *clk_noc; |
424 | /* for SiRFmarco, there are SET/CLR for UART_INT_EN */ | 424 | /* for SiRFatlas7, there are SET/CLR for UART_INT_EN */ |
425 | bool is_marco; | 425 | bool is_atlas7; |
426 | struct sirfsoc_uart_register *uart_reg; | 426 | struct sirfsoc_uart_register *uart_reg; |
427 | struct dma_chan *rx_dma_chan; | 427 | struct dma_chan *rx_dma_chan; |
428 | struct dma_chan *tx_dma_chan; | 428 | struct dma_chan *tx_dma_chan; |
diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c new file mode 100644 index 000000000000..594b63331ef4 --- /dev/null +++ b/drivers/tty/serial/sprd_serial.c | |||
@@ -0,0 +1,793 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012-2015 Spreadtrum Communications Inc. | ||
3 | * | ||
4 | * This software is licensed under the terms of the GNU General Public | ||
5 | * License version 2, as published by the Free Software Foundation, and | ||
6 | * may be copied, distributed, and modified under those terms. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #if defined(CONFIG_SERIAL_SPRD_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | ||
15 | #define SUPPORT_SYSRQ | ||
16 | #endif | ||
17 | |||
18 | #include <linux/clk.h> | ||
19 | #include <linux/console.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/ioport.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/of.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/serial_core.h> | ||
28 | #include <linux/serial.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/tty.h> | ||
31 | #include <linux/tty_flip.h> | ||
32 | |||
33 | /* device name */ | ||
34 | #define UART_NR_MAX 8 | ||
35 | #define SPRD_TTY_NAME "ttyS" | ||
36 | #define SPRD_FIFO_SIZE 128 | ||
37 | #define SPRD_DEF_RATE 26000000 | ||
38 | #define SPRD_BAUD_IO_LIMIT 3000000 | ||
39 | #define SPRD_TIMEOUT 256 | ||
40 | |||
41 | /* the offset of serial registers and BITs for them */ | ||
42 | /* data registers */ | ||
43 | #define SPRD_TXD 0x0000 | ||
44 | #define SPRD_RXD 0x0004 | ||
45 | |||
46 | /* line status register and its BITs */ | ||
47 | #define SPRD_LSR 0x0008 | ||
48 | #define SPRD_LSR_OE BIT(4) | ||
49 | #define SPRD_LSR_FE BIT(3) | ||
50 | #define SPRD_LSR_PE BIT(2) | ||
51 | #define SPRD_LSR_BI BIT(7) | ||
52 | #define SPRD_LSR_TX_OVER BIT(15) | ||
53 | |||
54 | /* data number in TX and RX fifo */ | ||
55 | #define SPRD_STS1 0x000C | ||
56 | |||
57 | /* interrupt enable register and its BITs */ | ||
58 | #define SPRD_IEN 0x0010 | ||
59 | #define SPRD_IEN_RX_FULL BIT(0) | ||
60 | #define SPRD_IEN_TX_EMPTY BIT(1) | ||
61 | #define SPRD_IEN_BREAK_DETECT BIT(7) | ||
62 | #define SPRD_IEN_TIMEOUT BIT(13) | ||
63 | |||
64 | /* interrupt clear register */ | ||
65 | #define SPRD_ICLR 0x0014 | ||
66 | |||
67 | /* line control register */ | ||
68 | #define SPRD_LCR 0x0018 | ||
69 | #define SPRD_LCR_STOP_1BIT 0x10 | ||
70 | #define SPRD_LCR_STOP_2BIT 0x30 | ||
71 | #define SPRD_LCR_DATA_LEN (BIT(2) | BIT(3)) | ||
72 | #define SPRD_LCR_DATA_LEN5 0x0 | ||
73 | #define SPRD_LCR_DATA_LEN6 0x4 | ||
74 | #define SPRD_LCR_DATA_LEN7 0x8 | ||
75 | #define SPRD_LCR_DATA_LEN8 0xc | ||
76 | #define SPRD_LCR_PARITY (BIT(0) | BIT(1)) | ||
77 | #define SPRD_LCR_PARITY_EN 0x2 | ||
78 | #define SPRD_LCR_EVEN_PAR 0x0 | ||
79 | #define SPRD_LCR_ODD_PAR 0x1 | ||
80 | |||
81 | /* control register 1 */ | ||
82 | #define SPRD_CTL1 0x001C | ||
83 | #define RX_HW_FLOW_CTL_THLD BIT(6) | ||
84 | #define RX_HW_FLOW_CTL_EN BIT(7) | ||
85 | #define TX_HW_FLOW_CTL_EN BIT(8) | ||
86 | #define RX_TOUT_THLD_DEF 0x3E00 | ||
87 | #define RX_HFC_THLD_DEF 0x40 | ||
88 | |||
89 | /* fifo threshold register */ | ||
90 | #define SPRD_CTL2 0x0020 | ||
91 | #define THLD_TX_EMPTY 0x40 | ||
92 | #define THLD_RX_FULL 0x40 | ||
93 | |||
94 | /* config baud rate register */ | ||
95 | #define SPRD_CLKD0 0x0024 | ||
96 | #define SPRD_CLKD1 0x0028 | ||
97 | |||
98 | /* interrupt mask status register */ | ||
99 | #define SPRD_IMSR 0x002C | ||
100 | #define SPRD_IMSR_RX_FIFO_FULL BIT(0) | ||
101 | #define SPRD_IMSR_TX_FIFO_EMPTY BIT(1) | ||
102 | #define SPRD_IMSR_BREAK_DETECT BIT(7) | ||
103 | #define SPRD_IMSR_TIMEOUT BIT(13) | ||
104 | |||
105 | struct reg_backup { | ||
106 | u32 ien; | ||
107 | u32 ctrl0; | ||
108 | u32 ctrl1; | ||
109 | u32 ctrl2; | ||
110 | u32 clkd0; | ||
111 | u32 clkd1; | ||
112 | u32 dspwait; | ||
113 | }; | ||
114 | |||
115 | struct sprd_uart_port { | ||
116 | struct uart_port port; | ||
117 | struct reg_backup reg_bak; | ||
118 | char name[16]; | ||
119 | }; | ||
120 | |||
121 | static struct sprd_uart_port *sprd_port[UART_NR_MAX]; | ||
122 | static int sprd_ports_num; | ||
123 | |||
124 | static inline unsigned int serial_in(struct uart_port *port, int offset) | ||
125 | { | ||
126 | return readl_relaxed(port->membase + offset); | ||
127 | } | ||
128 | |||
129 | static inline void serial_out(struct uart_port *port, int offset, int value) | ||
130 | { | ||
131 | writel_relaxed(value, port->membase + offset); | ||
132 | } | ||
133 | |||
134 | static unsigned int sprd_tx_empty(struct uart_port *port) | ||
135 | { | ||
136 | if (serial_in(port, SPRD_STS1) & 0xff00) | ||
137 | return 0; | ||
138 | else | ||
139 | return TIOCSER_TEMT; | ||
140 | } | ||
141 | |||
142 | static unsigned int sprd_get_mctrl(struct uart_port *port) | ||
143 | { | ||
144 | return TIOCM_DSR | TIOCM_CTS; | ||
145 | } | ||
146 | |||
147 | static void sprd_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
148 | { | ||
149 | /* nothing to do */ | ||
150 | } | ||
151 | |||
152 | static void sprd_stop_tx(struct uart_port *port) | ||
153 | { | ||
154 | unsigned int ien, iclr; | ||
155 | |||
156 | iclr = serial_in(port, SPRD_ICLR); | ||
157 | ien = serial_in(port, SPRD_IEN); | ||
158 | |||
159 | iclr |= SPRD_IEN_TX_EMPTY; | ||
160 | ien &= ~SPRD_IEN_TX_EMPTY; | ||
161 | |||
162 | serial_out(port, SPRD_ICLR, iclr); | ||
163 | serial_out(port, SPRD_IEN, ien); | ||
164 | } | ||
165 | |||
166 | static void sprd_start_tx(struct uart_port *port) | ||
167 | { | ||
168 | unsigned int ien; | ||
169 | |||
170 | ien = serial_in(port, SPRD_IEN); | ||
171 | if (!(ien & SPRD_IEN_TX_EMPTY)) { | ||
172 | ien |= SPRD_IEN_TX_EMPTY; | ||
173 | serial_out(port, SPRD_IEN, ien); | ||
174 | } | ||
175 | } | ||
176 | |||
177 | static void sprd_stop_rx(struct uart_port *port) | ||
178 | { | ||
179 | unsigned int ien, iclr; | ||
180 | |||
181 | iclr = serial_in(port, SPRD_ICLR); | ||
182 | ien = serial_in(port, SPRD_IEN); | ||
183 | |||
184 | ien &= ~(SPRD_IEN_RX_FULL | SPRD_IEN_BREAK_DETECT); | ||
185 | iclr |= SPRD_IEN_RX_FULL | SPRD_IEN_BREAK_DETECT; | ||
186 | |||
187 | serial_out(port, SPRD_IEN, ien); | ||
188 | serial_out(port, SPRD_ICLR, iclr); | ||
189 | } | ||
190 | |||
191 | /* The Sprd serial does not support this function. */ | ||
192 | static void sprd_break_ctl(struct uart_port *port, int break_state) | ||
193 | { | ||
194 | /* nothing to do */ | ||
195 | } | ||
196 | |||
197 | static int handle_lsr_errors(struct uart_port *port, | ||
198 | unsigned int *flag, | ||
199 | unsigned int *lsr) | ||
200 | { | ||
201 | int ret = 0; | ||
202 | |||
203 | /* statistics */ | ||
204 | if (*lsr & SPRD_LSR_BI) { | ||
205 | *lsr &= ~(SPRD_LSR_FE | SPRD_LSR_PE); | ||
206 | port->icount.brk++; | ||
207 | ret = uart_handle_break(port); | ||
208 | if (ret) | ||
209 | return ret; | ||
210 | } else if (*lsr & SPRD_LSR_PE) | ||
211 | port->icount.parity++; | ||
212 | else if (*lsr & SPRD_LSR_FE) | ||
213 | port->icount.frame++; | ||
214 | if (*lsr & SPRD_LSR_OE) | ||
215 | port->icount.overrun++; | ||
216 | |||
217 | /* mask off conditions which should be ignored */ | ||
218 | *lsr &= port->read_status_mask; | ||
219 | if (*lsr & SPRD_LSR_BI) | ||
220 | *flag = TTY_BREAK; | ||
221 | else if (*lsr & SPRD_LSR_PE) | ||
222 | *flag = TTY_PARITY; | ||
223 | else if (*lsr & SPRD_LSR_FE) | ||
224 | *flag = TTY_FRAME; | ||
225 | |||
226 | return ret; | ||
227 | } | ||
228 | |||
229 | static inline void sprd_rx(struct uart_port *port) | ||
230 | { | ||
231 | struct tty_port *tty = &port->state->port; | ||
232 | unsigned int ch, flag, lsr, max_count = SPRD_TIMEOUT; | ||
233 | |||
234 | while ((serial_in(port, SPRD_STS1) & 0x00ff) && max_count--) { | ||
235 | lsr = serial_in(port, SPRD_LSR); | ||
236 | ch = serial_in(port, SPRD_RXD); | ||
237 | flag = TTY_NORMAL; | ||
238 | port->icount.rx++; | ||
239 | |||
240 | if (lsr & (SPRD_LSR_BI | SPRD_LSR_PE | | ||
241 | SPRD_LSR_FE | SPRD_LSR_OE)) | ||
242 | if (handle_lsr_errors(port, &lsr, &flag)) | ||
243 | continue; | ||
244 | if (uart_handle_sysrq_char(port, ch)) | ||
245 | continue; | ||
246 | |||
247 | uart_insert_char(port, lsr, SPRD_LSR_OE, ch, flag); | ||
248 | } | ||
249 | |||
250 | tty_flip_buffer_push(tty); | ||
251 | } | ||
252 | |||
253 | static inline void sprd_tx(struct uart_port *port) | ||
254 | { | ||
255 | struct circ_buf *xmit = &port->state->xmit; | ||
256 | int count; | ||
257 | |||
258 | if (port->x_char) { | ||
259 | serial_out(port, SPRD_TXD, port->x_char); | ||
260 | port->icount.tx++; | ||
261 | port->x_char = 0; | ||
262 | return; | ||
263 | } | ||
264 | |||
265 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { | ||
266 | sprd_stop_tx(port); | ||
267 | return; | ||
268 | } | ||
269 | |||
270 | count = THLD_TX_EMPTY; | ||
271 | do { | ||
272 | serial_out(port, SPRD_TXD, xmit->buf[xmit->tail]); | ||
273 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
274 | port->icount.tx++; | ||
275 | if (uart_circ_empty(xmit)) | ||
276 | break; | ||
277 | } while (--count > 0); | ||
278 | |||
279 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
280 | uart_write_wakeup(port); | ||
281 | |||
282 | if (uart_circ_empty(xmit)) | ||
283 | sprd_stop_tx(port); | ||
284 | } | ||
285 | |||
286 | /* this handles the interrupt from one port */ | ||
287 | static irqreturn_t sprd_handle_irq(int irq, void *dev_id) | ||
288 | { | ||
289 | struct uart_port *port = dev_id; | ||
290 | unsigned int ims; | ||
291 | |||
292 | spin_lock(&port->lock); | ||
293 | |||
294 | ims = serial_in(port, SPRD_IMSR); | ||
295 | |||
296 | if (!ims) | ||
297 | return IRQ_NONE; | ||
298 | |||
299 | serial_out(port, SPRD_ICLR, ~0); | ||
300 | |||
301 | if (ims & (SPRD_IMSR_RX_FIFO_FULL | | ||
302 | SPRD_IMSR_BREAK_DETECT | SPRD_IMSR_TIMEOUT)) | ||
303 | sprd_rx(port); | ||
304 | |||
305 | if (ims & SPRD_IMSR_TX_FIFO_EMPTY) | ||
306 | sprd_tx(port); | ||
307 | |||
308 | spin_unlock(&port->lock); | ||
309 | |||
310 | return IRQ_HANDLED; | ||
311 | } | ||
312 | |||
313 | static int sprd_startup(struct uart_port *port) | ||
314 | { | ||
315 | int ret = 0; | ||
316 | unsigned int ien, fc; | ||
317 | unsigned int timeout; | ||
318 | struct sprd_uart_port *sp; | ||
319 | unsigned long flags; | ||
320 | |||
321 | serial_out(port, SPRD_CTL2, ((THLD_TX_EMPTY << 8) | THLD_RX_FULL)); | ||
322 | |||
323 | /* clear rx fifo */ | ||
324 | timeout = SPRD_TIMEOUT; | ||
325 | while (timeout-- && serial_in(port, SPRD_STS1) & 0x00ff) | ||
326 | serial_in(port, SPRD_RXD); | ||
327 | |||
328 | /* clear tx fifo */ | ||
329 | timeout = SPRD_TIMEOUT; | ||
330 | while (timeout-- && serial_in(port, SPRD_STS1) & 0xff00) | ||
331 | cpu_relax(); | ||
332 | |||
333 | /* clear interrupt */ | ||
334 | serial_out(port, SPRD_IEN, 0); | ||
335 | serial_out(port, SPRD_ICLR, ~0); | ||
336 | |||
337 | /* allocate irq */ | ||
338 | sp = container_of(port, struct sprd_uart_port, port); | ||
339 | snprintf(sp->name, sizeof(sp->name), "sprd_serial%d", port->line); | ||
340 | ret = devm_request_irq(port->dev, port->irq, sprd_handle_irq, | ||
341 | IRQF_SHARED, sp->name, port); | ||
342 | if (ret) { | ||
343 | dev_err(port->dev, "fail to request serial irq %d, ret=%d\n", | ||
344 | port->irq, ret); | ||
345 | return ret; | ||
346 | } | ||
347 | fc = serial_in(port, SPRD_CTL1); | ||
348 | fc |= RX_TOUT_THLD_DEF | RX_HFC_THLD_DEF; | ||
349 | serial_out(port, SPRD_CTL1, fc); | ||
350 | |||
351 | /* enable interrupt */ | ||
352 | spin_lock_irqsave(&port->lock, flags); | ||
353 | ien = serial_in(port, SPRD_IEN); | ||
354 | ien |= SPRD_IEN_RX_FULL | SPRD_IEN_BREAK_DETECT | SPRD_IEN_TIMEOUT; | ||
355 | serial_out(port, SPRD_IEN, ien); | ||
356 | spin_unlock_irqrestore(&port->lock, flags); | ||
357 | |||
358 | return 0; | ||
359 | } | ||
360 | |||
361 | static void sprd_shutdown(struct uart_port *port) | ||
362 | { | ||
363 | serial_out(port, SPRD_IEN, 0); | ||
364 | serial_out(port, SPRD_ICLR, ~0); | ||
365 | devm_free_irq(port->dev, port->irq, port); | ||
366 | } | ||
367 | |||
368 | static void sprd_set_termios(struct uart_port *port, | ||
369 | struct ktermios *termios, | ||
370 | struct ktermios *old) | ||
371 | { | ||
372 | unsigned int baud, quot; | ||
373 | unsigned int lcr = 0, fc; | ||
374 | unsigned long flags; | ||
375 | |||
376 | /* ask the core to calculate the divisor for us */ | ||
377 | baud = uart_get_baud_rate(port, termios, old, 0, SPRD_BAUD_IO_LIMIT); | ||
378 | |||
379 | quot = (unsigned int)((port->uartclk + baud / 2) / baud); | ||
380 | |||
381 | /* set data length */ | ||
382 | switch (termios->c_cflag & CSIZE) { | ||
383 | case CS5: | ||
384 | lcr |= SPRD_LCR_DATA_LEN5; | ||
385 | break; | ||
386 | case CS6: | ||
387 | lcr |= SPRD_LCR_DATA_LEN6; | ||
388 | break; | ||
389 | case CS7: | ||
390 | lcr |= SPRD_LCR_DATA_LEN7; | ||
391 | break; | ||
392 | case CS8: | ||
393 | default: | ||
394 | lcr |= SPRD_LCR_DATA_LEN8; | ||
395 | break; | ||
396 | } | ||
397 | |||
398 | /* calculate stop bits */ | ||
399 | lcr &= ~(SPRD_LCR_STOP_1BIT | SPRD_LCR_STOP_2BIT); | ||
400 | if (termios->c_cflag & CSTOPB) | ||
401 | lcr |= SPRD_LCR_STOP_2BIT; | ||
402 | else | ||
403 | lcr |= SPRD_LCR_STOP_1BIT; | ||
404 | |||
405 | /* calculate parity */ | ||
406 | lcr &= ~SPRD_LCR_PARITY; | ||
407 | termios->c_cflag &= ~CMSPAR; /* no support mark/space */ | ||
408 | if (termios->c_cflag & PARENB) { | ||
409 | lcr |= SPRD_LCR_PARITY_EN; | ||
410 | if (termios->c_cflag & PARODD) | ||
411 | lcr |= SPRD_LCR_ODD_PAR; | ||
412 | else | ||
413 | lcr |= SPRD_LCR_EVEN_PAR; | ||
414 | } | ||
415 | |||
416 | spin_lock_irqsave(&port->lock, flags); | ||
417 | |||
418 | /* update the per-port timeout */ | ||
419 | uart_update_timeout(port, termios->c_cflag, baud); | ||
420 | |||
421 | port->read_status_mask = SPRD_LSR_OE; | ||
422 | if (termios->c_iflag & INPCK) | ||
423 | port->read_status_mask |= SPRD_LSR_FE | SPRD_LSR_PE; | ||
424 | if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) | ||
425 | port->read_status_mask |= SPRD_LSR_BI; | ||
426 | |||
427 | /* characters to ignore */ | ||
428 | port->ignore_status_mask = 0; | ||
429 | if (termios->c_iflag & IGNPAR) | ||
430 | port->ignore_status_mask |= SPRD_LSR_PE | SPRD_LSR_FE; | ||
431 | if (termios->c_iflag & IGNBRK) { | ||
432 | port->ignore_status_mask |= SPRD_LSR_BI; | ||
433 | /* | ||
434 | * If we're ignoring parity and break indicators, | ||
435 | * ignore overruns too (for real raw support). | ||
436 | */ | ||
437 | if (termios->c_iflag & IGNPAR) | ||
438 | port->ignore_status_mask |= SPRD_LSR_OE; | ||
439 | } | ||
440 | |||
441 | /* flow control */ | ||
442 | fc = serial_in(port, SPRD_CTL1); | ||
443 | fc &= ~(RX_HW_FLOW_CTL_THLD | RX_HW_FLOW_CTL_EN | TX_HW_FLOW_CTL_EN); | ||
444 | if (termios->c_cflag & CRTSCTS) { | ||
445 | fc |= RX_HW_FLOW_CTL_THLD; | ||
446 | fc |= RX_HW_FLOW_CTL_EN; | ||
447 | fc |= TX_HW_FLOW_CTL_EN; | ||
448 | } | ||
449 | |||
450 | /* clock divider bit0~bit15 */ | ||
451 | serial_out(port, SPRD_CLKD0, quot & 0xffff); | ||
452 | |||
453 | /* clock divider bit16~bit20 */ | ||
454 | serial_out(port, SPRD_CLKD1, (quot & 0x1f0000) >> 16); | ||
455 | serial_out(port, SPRD_LCR, lcr); | ||
456 | fc |= RX_TOUT_THLD_DEF | RX_HFC_THLD_DEF; | ||
457 | serial_out(port, SPRD_CTL1, fc); | ||
458 | |||
459 | spin_unlock_irqrestore(&port->lock, flags); | ||
460 | |||
461 | /* Don't rewrite B0 */ | ||
462 | if (tty_termios_baud_rate(termios)) | ||
463 | tty_termios_encode_baud_rate(termios, baud, baud); | ||
464 | } | ||
465 | |||
466 | static const char *sprd_type(struct uart_port *port) | ||
467 | { | ||
468 | return "SPX"; | ||
469 | } | ||
470 | |||
471 | static void sprd_release_port(struct uart_port *port) | ||
472 | { | ||
473 | /* nothing to do */ | ||
474 | } | ||
475 | |||
476 | static int sprd_request_port(struct uart_port *port) | ||
477 | { | ||
478 | return 0; | ||
479 | } | ||
480 | |||
481 | static void sprd_config_port(struct uart_port *port, int flags) | ||
482 | { | ||
483 | if (flags & UART_CONFIG_TYPE) | ||
484 | port->type = PORT_SPRD; | ||
485 | } | ||
486 | |||
487 | static int sprd_verify_port(struct uart_port *port, | ||
488 | struct serial_struct *ser) | ||
489 | { | ||
490 | if (ser->type != PORT_SPRD) | ||
491 | return -EINVAL; | ||
492 | if (port->irq != ser->irq) | ||
493 | return -EINVAL; | ||
494 | return 0; | ||
495 | } | ||
496 | |||
497 | static struct uart_ops serial_sprd_ops = { | ||
498 | .tx_empty = sprd_tx_empty, | ||
499 | .get_mctrl = sprd_get_mctrl, | ||
500 | .set_mctrl = sprd_set_mctrl, | ||
501 | .stop_tx = sprd_stop_tx, | ||
502 | .start_tx = sprd_start_tx, | ||
503 | .stop_rx = sprd_stop_rx, | ||
504 | .break_ctl = sprd_break_ctl, | ||
505 | .startup = sprd_startup, | ||
506 | .shutdown = sprd_shutdown, | ||
507 | .set_termios = sprd_set_termios, | ||
508 | .type = sprd_type, | ||
509 | .release_port = sprd_release_port, | ||
510 | .request_port = sprd_request_port, | ||
511 | .config_port = sprd_config_port, | ||
512 | .verify_port = sprd_verify_port, | ||
513 | }; | ||
514 | |||
515 | #ifdef CONFIG_SERIAL_SPRD_CONSOLE | ||
516 | static inline void wait_for_xmitr(struct uart_port *port) | ||
517 | { | ||
518 | unsigned int status, tmout = 10000; | ||
519 | |||
520 | /* wait up to 10ms for the character(s) to be sent */ | ||
521 | do { | ||
522 | status = serial_in(port, SPRD_STS1); | ||
523 | if (--tmout == 0) | ||
524 | break; | ||
525 | udelay(1); | ||
526 | } while (status & 0xff00); | ||
527 | } | ||
528 | |||
529 | static void sprd_console_putchar(struct uart_port *port, int ch) | ||
530 | { | ||
531 | wait_for_xmitr(port); | ||
532 | serial_out(port, SPRD_TXD, ch); | ||
533 | } | ||
534 | |||
535 | static void sprd_console_write(struct console *co, const char *s, | ||
536 | unsigned int count) | ||
537 | { | ||
538 | struct uart_port *port = &sprd_port[co->index]->port; | ||
539 | int locked = 1; | ||
540 | unsigned long flags; | ||
541 | |||
542 | if (port->sysrq) | ||
543 | locked = 0; | ||
544 | else if (oops_in_progress) | ||
545 | locked = spin_trylock_irqsave(&port->lock, flags); | ||
546 | else | ||
547 | spin_lock_irqsave(&port->lock, flags); | ||
548 | |||
549 | uart_console_write(port, s, count, sprd_console_putchar); | ||
550 | |||
551 | /* wait for transmitter to become empty */ | ||
552 | wait_for_xmitr(port); | ||
553 | |||
554 | if (locked) | ||
555 | spin_unlock_irqrestore(&port->lock, flags); | ||
556 | } | ||
557 | |||
558 | static int __init sprd_console_setup(struct console *co, char *options) | ||
559 | { | ||
560 | struct uart_port *port; | ||
561 | int baud = 115200; | ||
562 | int bits = 8; | ||
563 | int parity = 'n'; | ||
564 | int flow = 'n'; | ||
565 | |||
566 | if (co->index >= UART_NR_MAX || co->index < 0) | ||
567 | co->index = 0; | ||
568 | |||
569 | port = &sprd_port[co->index]->port; | ||
570 | if (port == NULL) { | ||
571 | pr_info("serial port %d not yet initialized\n", co->index); | ||
572 | return -ENODEV; | ||
573 | } | ||
574 | if (options) | ||
575 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
576 | |||
577 | return uart_set_options(port, co, baud, parity, bits, flow); | ||
578 | } | ||
579 | |||
580 | static struct uart_driver sprd_uart_driver; | ||
581 | static struct console sprd_console = { | ||
582 | .name = SPRD_TTY_NAME, | ||
583 | .write = sprd_console_write, | ||
584 | .device = uart_console_device, | ||
585 | .setup = sprd_console_setup, | ||
586 | .flags = CON_PRINTBUFFER, | ||
587 | .index = -1, | ||
588 | .data = &sprd_uart_driver, | ||
589 | }; | ||
590 | |||
591 | #define SPRD_CONSOLE (&sprd_console) | ||
592 | |||
593 | /* Support for earlycon */ | ||
594 | static void sprd_putc(struct uart_port *port, int c) | ||
595 | { | ||
596 | unsigned int timeout = SPRD_TIMEOUT; | ||
597 | |||
598 | while (timeout-- && | ||
599 | !(readl(port->membase + SPRD_LSR) & SPRD_LSR_TX_OVER)) | ||
600 | cpu_relax(); | ||
601 | |||
602 | writeb(c, port->membase + SPRD_TXD); | ||
603 | } | ||
604 | |||
605 | static void sprd_early_write(struct console *con, const char *s, | ||
606 | unsigned n) | ||
607 | { | ||
608 | struct earlycon_device *dev = con->data; | ||
609 | |||
610 | uart_console_write(&dev->port, s, n, sprd_putc); | ||
611 | } | ||
612 | |||
613 | static int __init sprd_early_console_setup( | ||
614 | struct earlycon_device *device, | ||
615 | const char *opt) | ||
616 | { | ||
617 | if (!device->port.membase) | ||
618 | return -ENODEV; | ||
619 | |||
620 | device->con->write = sprd_early_write; | ||
621 | return 0; | ||
622 | } | ||
623 | |||
624 | EARLYCON_DECLARE(sprd_serial, sprd_early_console_setup); | ||
625 | OF_EARLYCON_DECLARE(sprd_serial, "sprd,sc9836-uart", | ||
626 | sprd_early_console_setup); | ||
627 | |||
628 | #else /* !CONFIG_SERIAL_SPRD_CONSOLE */ | ||
629 | #define SPRD_CONSOLE NULL | ||
630 | #endif | ||
631 | |||
632 | static struct uart_driver sprd_uart_driver = { | ||
633 | .owner = THIS_MODULE, | ||
634 | .driver_name = "sprd_serial", | ||
635 | .dev_name = SPRD_TTY_NAME, | ||
636 | .major = 0, | ||
637 | .minor = 0, | ||
638 | .nr = UART_NR_MAX, | ||
639 | .cons = SPRD_CONSOLE, | ||
640 | }; | ||
641 | |||
642 | static int sprd_probe_dt_alias(int index, struct device *dev) | ||
643 | { | ||
644 | struct device_node *np; | ||
645 | int ret = index; | ||
646 | |||
647 | if (!IS_ENABLED(CONFIG_OF)) | ||
648 | return ret; | ||
649 | |||
650 | np = dev->of_node; | ||
651 | if (!np) | ||
652 | return ret; | ||
653 | |||
654 | ret = of_alias_get_id(np, "serial"); | ||
655 | if (IS_ERR_VALUE(ret)) | ||
656 | ret = index; | ||
657 | else if (ret >= ARRAY_SIZE(sprd_port) || sprd_port[ret] != NULL) { | ||
658 | dev_warn(dev, "requested serial port %d not available.\n", ret); | ||
659 | ret = index; | ||
660 | } | ||
661 | |||
662 | return ret; | ||
663 | } | ||
664 | |||
665 | static int sprd_remove(struct platform_device *dev) | ||
666 | { | ||
667 | struct sprd_uart_port *sup = platform_get_drvdata(dev); | ||
668 | |||
669 | if (sup) { | ||
670 | uart_remove_one_port(&sprd_uart_driver, &sup->port); | ||
671 | sprd_port[sup->port.line] = NULL; | ||
672 | sprd_ports_num--; | ||
673 | } | ||
674 | |||
675 | if (!sprd_ports_num) | ||
676 | uart_unregister_driver(&sprd_uart_driver); | ||
677 | |||
678 | return 0; | ||
679 | } | ||
680 | |||
681 | static int sprd_probe(struct platform_device *pdev) | ||
682 | { | ||
683 | struct resource *res; | ||
684 | struct uart_port *up; | ||
685 | struct clk *clk; | ||
686 | int irq; | ||
687 | int index; | ||
688 | int ret; | ||
689 | |||
690 | for (index = 0; index < ARRAY_SIZE(sprd_port); index++) | ||
691 | if (sprd_port[index] == NULL) | ||
692 | break; | ||
693 | |||
694 | if (index == ARRAY_SIZE(sprd_port)) | ||
695 | return -EBUSY; | ||
696 | |||
697 | index = sprd_probe_dt_alias(index, &pdev->dev); | ||
698 | |||
699 | sprd_port[index] = devm_kzalloc(&pdev->dev, | ||
700 | sizeof(*sprd_port[index]), GFP_KERNEL); | ||
701 | if (!sprd_port[index]) | ||
702 | return -ENOMEM; | ||
703 | |||
704 | up = &sprd_port[index]->port; | ||
705 | up->dev = &pdev->dev; | ||
706 | up->line = index; | ||
707 | up->type = PORT_SPRD; | ||
708 | up->iotype = SERIAL_IO_PORT; | ||
709 | up->uartclk = SPRD_DEF_RATE; | ||
710 | up->fifosize = SPRD_FIFO_SIZE; | ||
711 | up->ops = &serial_sprd_ops; | ||
712 | up->flags = UPF_BOOT_AUTOCONF; | ||
713 | |||
714 | clk = devm_clk_get(&pdev->dev, NULL); | ||
715 | if (!IS_ERR(clk)) | ||
716 | up->uartclk = clk_get_rate(clk); | ||
717 | |||
718 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
719 | if (!res) { | ||
720 | dev_err(&pdev->dev, "not provide mem resource\n"); | ||
721 | return -ENODEV; | ||
722 | } | ||
723 | up->mapbase = res->start; | ||
724 | up->membase = devm_ioremap_resource(&pdev->dev, res); | ||
725 | if (IS_ERR(up->membase)) | ||
726 | return PTR_ERR(up->membase); | ||
727 | |||
728 | irq = platform_get_irq(pdev, 0); | ||
729 | if (irq < 0) { | ||
730 | dev_err(&pdev->dev, "not provide irq resource\n"); | ||
731 | return -ENODEV; | ||
732 | } | ||
733 | up->irq = irq; | ||
734 | |||
735 | if (!sprd_ports_num) { | ||
736 | ret = uart_register_driver(&sprd_uart_driver); | ||
737 | if (ret < 0) { | ||
738 | pr_err("Failed to register SPRD-UART driver\n"); | ||
739 | return ret; | ||
740 | } | ||
741 | } | ||
742 | sprd_ports_num++; | ||
743 | |||
744 | ret = uart_add_one_port(&sprd_uart_driver, up); | ||
745 | if (ret) { | ||
746 | sprd_port[index] = NULL; | ||
747 | sprd_remove(pdev); | ||
748 | } | ||
749 | |||
750 | platform_set_drvdata(pdev, up); | ||
751 | |||
752 | return ret; | ||
753 | } | ||
754 | |||
755 | static int sprd_suspend(struct device *dev) | ||
756 | { | ||
757 | struct sprd_uart_port *sup = dev_get_drvdata(dev); | ||
758 | |||
759 | uart_suspend_port(&sprd_uart_driver, &sup->port); | ||
760 | |||
761 | return 0; | ||
762 | } | ||
763 | |||
764 | static int sprd_resume(struct device *dev) | ||
765 | { | ||
766 | struct sprd_uart_port *sup = dev_get_drvdata(dev); | ||
767 | |||
768 | uart_resume_port(&sprd_uart_driver, &sup->port); | ||
769 | |||
770 | return 0; | ||
771 | } | ||
772 | |||
773 | static SIMPLE_DEV_PM_OPS(sprd_pm_ops, sprd_suspend, sprd_resume); | ||
774 | |||
775 | static const struct of_device_id serial_ids[] = { | ||
776 | {.compatible = "sprd,sc9836-uart",}, | ||
777 | {} | ||
778 | }; | ||
779 | |||
780 | static struct platform_driver sprd_platform_driver = { | ||
781 | .probe = sprd_probe, | ||
782 | .remove = sprd_remove, | ||
783 | .driver = { | ||
784 | .name = "sprd_serial", | ||
785 | .of_match_table = of_match_ptr(serial_ids), | ||
786 | .pm = &sprd_pm_ops, | ||
787 | }, | ||
788 | }; | ||
789 | |||
790 | module_platform_driver(sprd_platform_driver); | ||
791 | |||
792 | MODULE_LICENSE("GPL v2"); | ||
793 | MODULE_DESCRIPTION("Spreadtrum SoC serial driver series"); | ||
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index 542bab37e502..cff531a51a78 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c | |||
@@ -637,10 +637,12 @@ static void cdns_uart_set_termios(struct uart_port *port, | |||
637 | 637 | ||
638 | spin_lock_irqsave(&port->lock, flags); | 638 | spin_lock_irqsave(&port->lock, flags); |
639 | 639 | ||
640 | /* Empty the receive FIFO 1st before making changes */ | 640 | /* Wait for the transmit FIFO to empty before making changes */ |
641 | while ((cdns_uart_readl(CDNS_UART_SR_OFFSET) & | 641 | if (!(cdns_uart_readl(CDNS_UART_CR_OFFSET) & CDNS_UART_CR_TX_DIS)) { |
642 | CDNS_UART_SR_RXEMPTY) != CDNS_UART_SR_RXEMPTY) { | 642 | while (!(cdns_uart_readl(CDNS_UART_SR_OFFSET) & |
643 | cdns_uart_readl(CDNS_UART_FIFO_OFFSET); | 643 | CDNS_UART_SR_TXEMPTY)) { |
644 | cpu_relax(); | ||
645 | } | ||
644 | } | 646 | } |
645 | 647 | ||
646 | /* Disable the TX and RX to set baud rate */ | 648 | /* Disable the TX and RX to set baud rate */ |
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 3605103fc1ac..75661641f5fe 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c | |||
@@ -557,3 +557,9 @@ int tty_buffer_set_limit(struct tty_port *port, int limit) | |||
557 | return 0; | 557 | return 0; |
558 | } | 558 | } |
559 | EXPORT_SYMBOL_GPL(tty_buffer_set_limit); | 559 | EXPORT_SYMBOL_GPL(tty_buffer_set_limit); |
560 | |||
561 | /* slave ptys can claim nested buffer lock when handling BRK and INTR */ | ||
562 | void tty_buffer_set_lock_subclass(struct tty_port *port) | ||
563 | { | ||
564 | lockdep_set_subclass(&port->buf.lock, TTY_LOCK_SLAVE); | ||
565 | } | ||
diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 1787fa4d9448..a5cf253b2544 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c | |||
@@ -530,7 +530,7 @@ EXPORT_SYMBOL(tty_termios_hw_change); | |||
530 | * Locking: termios_rwsem | 530 | * Locking: termios_rwsem |
531 | */ | 531 | */ |
532 | 532 | ||
533 | int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios) | 533 | static int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios) |
534 | { | 534 | { |
535 | struct ktermios old_termios; | 535 | struct ktermios old_termios; |
536 | struct tty_ldisc *ld; | 536 | struct tty_ldisc *ld; |
@@ -563,7 +563,6 @@ int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios) | |||
563 | up_write(&tty->termios_rwsem); | 563 | up_write(&tty->termios_rwsem); |
564 | return 0; | 564 | return 0; |
565 | } | 565 | } |
566 | EXPORT_SYMBOL_GPL(tty_set_termios); | ||
567 | 566 | ||
568 | /** | 567 | /** |
569 | * set_termios - set termios values for a tty | 568 | * set_termios - set termios values for a tty |
diff --git a/drivers/tty/tty_mutex.c b/drivers/tty/tty_mutex.c index 4486741190c4..0efcf713b756 100644 --- a/drivers/tty/tty_mutex.c +++ b/drivers/tty/tty_mutex.c | |||
@@ -4,18 +4,8 @@ | |||
4 | #include <linux/semaphore.h> | 4 | #include <linux/semaphore.h> |
5 | #include <linux/sched.h> | 5 | #include <linux/sched.h> |
6 | 6 | ||
7 | /* | ||
8 | * Nested tty locks are necessary for releasing pty pairs. | ||
9 | * The stable lock order is master pty first, then slave pty. | ||
10 | */ | ||
11 | |||
12 | /* Legacy tty mutex glue */ | 7 | /* Legacy tty mutex glue */ |
13 | 8 | ||
14 | enum { | ||
15 | TTY_MUTEX_NORMAL, | ||
16 | TTY_MUTEX_SLAVE, | ||
17 | }; | ||
18 | |||
19 | /* | 9 | /* |
20 | * Getting the big tty mutex. | 10 | * Getting the big tty mutex. |
21 | */ | 11 | */ |
@@ -46,12 +36,8 @@ EXPORT_SYMBOL(tty_unlock); | |||
46 | 36 | ||
47 | void __lockfunc tty_lock_slave(struct tty_struct *tty) | 37 | void __lockfunc tty_lock_slave(struct tty_struct *tty) |
48 | { | 38 | { |
49 | if (tty && tty != tty->link) { | 39 | if (tty && tty != tty->link) |
50 | WARN_ON(!mutex_is_locked(&tty->link->legacy_mutex) || | ||
51 | !tty->driver->type == TTY_DRIVER_TYPE_PTY || | ||
52 | !tty->driver->type == PTY_TYPE_SLAVE); | ||
53 | tty_lock(tty); | 40 | tty_lock(tty); |
54 | } | ||
55 | } | 41 | } |
56 | 42 | ||
57 | void __lockfunc tty_unlock_slave(struct tty_struct *tty) | 43 | void __lockfunc tty_unlock_slave(struct tty_struct *tty) |
@@ -62,5 +48,5 @@ void __lockfunc tty_unlock_slave(struct tty_struct *tty) | |||
62 | 48 | ||
63 | void tty_set_lock_subclass(struct tty_struct *tty) | 49 | void tty_set_lock_subclass(struct tty_struct *tty) |
64 | { | 50 | { |
65 | lockdep_set_subclass(&tty->legacy_mutex, TTY_MUTEX_SLAVE); | 51 | lockdep_set_subclass(&tty->legacy_mutex, TTY_LOCK_SLAVE); |
66 | } | 52 | } |
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index f3fbbbca9bde..6e00572cbeb9 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
@@ -500,6 +500,7 @@ void invert_screen(struct vc_data *vc, int offset, int count, int viewed) | |||
500 | #endif | 500 | #endif |
501 | if (DO_UPDATE(vc)) | 501 | if (DO_UPDATE(vc)) |
502 | do_update_region(vc, (unsigned long) p, count); | 502 | do_update_region(vc, (unsigned long) p, count); |
503 | notify_update(vc); | ||
503 | } | 504 | } |
504 | 505 | ||
505 | /* used by selection: complement pointer position */ | 506 | /* used by selection: complement pointer position */ |
@@ -516,6 +517,7 @@ void complement_pos(struct vc_data *vc, int offset) | |||
516 | scr_writew(old, screenpos(vc, old_offset, 1)); | 517 | scr_writew(old, screenpos(vc, old_offset, 1)); |
517 | if (DO_UPDATE(vc)) | 518 | if (DO_UPDATE(vc)) |
518 | vc->vc_sw->con_putc(vc, old, oldy, oldx); | 519 | vc->vc_sw->con_putc(vc, old, oldy, oldx); |
520 | notify_update(vc); | ||
519 | } | 521 | } |
520 | 522 | ||
521 | old_offset = offset; | 523 | old_offset = offset; |
@@ -533,8 +535,8 @@ void complement_pos(struct vc_data *vc, int offset) | |||
533 | oldy = (offset >> 1) / vc->vc_cols; | 535 | oldy = (offset >> 1) / vc->vc_cols; |
534 | vc->vc_sw->con_putc(vc, new, oldy, oldx); | 536 | vc->vc_sw->con_putc(vc, new, oldy, oldx); |
535 | } | 537 | } |
538 | notify_update(vc); | ||
536 | } | 539 | } |
537 | |||
538 | } | 540 | } |
539 | 541 | ||
540 | static void insert_char(struct vc_data *vc, unsigned int nr) | 542 | static void insert_char(struct vc_data *vc, unsigned int nr) |
@@ -3318,11 +3320,8 @@ static int vt_bind(struct con_driver *con) | |||
3318 | if (first == 0 && last == MAX_NR_CONSOLES -1) | 3320 | if (first == 0 && last == MAX_NR_CONSOLES -1) |
3319 | deflt = 1; | 3321 | deflt = 1; |
3320 | 3322 | ||
3321 | if (first != -1) { | 3323 | if (first != -1) |
3322 | console_lock(); | ||
3323 | do_bind_con_driver(csw, first, last, deflt); | 3324 | do_bind_con_driver(csw, first, last, deflt); |
3324 | console_unlock(); | ||
3325 | } | ||
3326 | 3325 | ||
3327 | first = -1; | 3326 | first = -1; |
3328 | last = -1; | 3327 | last = -1; |
@@ -3362,9 +3361,7 @@ static int vt_unbind(struct con_driver *con) | |||
3362 | deflt = 1; | 3361 | deflt = 1; |
3363 | 3362 | ||
3364 | if (first != -1) { | 3363 | if (first != -1) { |
3365 | console_lock(); | ||
3366 | ret = do_unbind_con_driver(csw, first, last, deflt); | 3364 | ret = do_unbind_con_driver(csw, first, last, deflt); |
3367 | console_unlock(); | ||
3368 | if (ret != 0) | 3365 | if (ret != 0) |
3369 | return ret; | 3366 | return ret; |
3370 | } | 3367 | } |
@@ -3394,11 +3391,15 @@ static ssize_t store_bind(struct device *dev, struct device_attribute *attr, | |||
3394 | struct con_driver *con = dev_get_drvdata(dev); | 3391 | struct con_driver *con = dev_get_drvdata(dev); |
3395 | int bind = simple_strtoul(buf, NULL, 0); | 3392 | int bind = simple_strtoul(buf, NULL, 0); |
3396 | 3393 | ||
3394 | console_lock(); | ||
3395 | |||
3397 | if (bind) | 3396 | if (bind) |
3398 | vt_bind(con); | 3397 | vt_bind(con); |
3399 | else | 3398 | else |
3400 | vt_unbind(con); | 3399 | vt_unbind(con); |
3401 | 3400 | ||
3401 | console_unlock(); | ||
3402 | |||
3402 | return count; | 3403 | return count; |
3403 | } | 3404 | } |
3404 | 3405 | ||
@@ -3665,8 +3666,7 @@ int do_unregister_con_driver(const struct consw *csw) | |||
3665 | for (i = 0; i < MAX_NR_CON_DRIVER; i++) { | 3666 | for (i = 0; i < MAX_NR_CON_DRIVER; i++) { |
3666 | struct con_driver *con_driver = ®istered_con_driver[i]; | 3667 | struct con_driver *con_driver = ®istered_con_driver[i]; |
3667 | 3668 | ||
3668 | if (con_driver->con == csw && | 3669 | if (con_driver->con == csw) { |
3669 | con_driver->flag & CON_DRIVER_FLAG_INIT) { | ||
3670 | vtconsole_deinit_device(con_driver); | 3670 | vtconsole_deinit_device(con_driver); |
3671 | device_destroy(vtconsole_class, | 3671 | device_destroy(vtconsole_class, |
3672 | MKDEV(0, con_driver->node)); | 3672 | MKDEV(0, con_driver->node)); |