diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-19 14:36:03 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-19 14:36:03 -0400 |
commit | 7c7cbaf5b82c418cd3b1dcf718f71d0e6057e639 (patch) | |
tree | da9aaa5a246af464b1e10d88618c1cad07b76314 /drivers/serial | |
parent | ba0234ec35127fe21d373db53cbaf9fe20620cb6 (diff) | |
parent | 4d0956b8f597aac10208ca763f8fe641fde16aab (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: (127 commits)
sh: update defconfigs.
sh: Fix up the NUMA build for recent LMB changes.
sh64: provide a stub per_cpu_trap_init() definition.
sh: fix up CONFIG_KEXEC=n build.
sh: fixup the docbook paths for clock framework shuffling.
driver core: Early dev_name() depends on slab_is_available().
sh: simplify WARN usage in SH clock driver
sh: Check return value of clk_get on ms7724
sh: Check return value of clk_get on ecovec24
sh: move sh clock-cpg.c contents to drivers/sh/clk-cpg.c
sh: move sh clock.c contents to drivers/sh/clk.
sh: move sh asm/clock.h contents to linux/sh_clk.h V2
sh: remove unused clock lookup
sh: switch boards to clkdev
sh: switch sh4-202 to clkdev
sh: switch shx3 to clkdev
sh: switch sh7757 to clkdev
sh: switch sh7763 to clkdev
sh: switch sh7780 to clkdev
sh: switch sh7786 to clkdev
...
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/sh-sci.c | 189 |
1 files changed, 126 insertions, 63 deletions
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 8eb094c1f61b..8d993c4cceac 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -83,16 +83,16 @@ struct sci_port { | |||
83 | 83 | ||
84 | /* Interface clock */ | 84 | /* Interface clock */ |
85 | struct clk *iclk; | 85 | struct clk *iclk; |
86 | /* Data clock */ | 86 | /* Function clock */ |
87 | struct clk *dclk; | 87 | struct clk *fclk; |
88 | 88 | ||
89 | struct list_head node; | 89 | struct list_head node; |
90 | struct dma_chan *chan_tx; | 90 | struct dma_chan *chan_tx; |
91 | struct dma_chan *chan_rx; | 91 | struct dma_chan *chan_rx; |
92 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | 92 | #ifdef CONFIG_SERIAL_SH_SCI_DMA |
93 | struct device *dma_dev; | 93 | struct device *dma_dev; |
94 | enum sh_dmae_slave_chan_id slave_tx; | 94 | unsigned int slave_tx; |
95 | enum sh_dmae_slave_chan_id slave_rx; | 95 | unsigned int slave_rx; |
96 | struct dma_async_tx_descriptor *desc_tx; | 96 | struct dma_async_tx_descriptor *desc_tx; |
97 | struct dma_async_tx_descriptor *desc_rx[2]; | 97 | struct dma_async_tx_descriptor *desc_rx[2]; |
98 | dma_cookie_t cookie_tx; | 98 | dma_cookie_t cookie_tx; |
@@ -107,6 +107,7 @@ struct sci_port { | |||
107 | struct work_struct work_tx; | 107 | struct work_struct work_tx; |
108 | struct work_struct work_rx; | 108 | struct work_struct work_rx; |
109 | struct timer_list rx_timer; | 109 | struct timer_list rx_timer; |
110 | unsigned int rx_timeout; | ||
110 | #endif | 111 | #endif |
111 | }; | 112 | }; |
112 | 113 | ||
@@ -674,22 +675,22 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr) | |||
674 | struct sci_port *s = to_sci_port(port); | 675 | struct sci_port *s = to_sci_port(port); |
675 | 676 | ||
676 | if (s->chan_rx) { | 677 | if (s->chan_rx) { |
677 | unsigned long tout; | ||
678 | u16 scr = sci_in(port, SCSCR); | 678 | u16 scr = sci_in(port, SCSCR); |
679 | u16 ssr = sci_in(port, SCxSR); | 679 | u16 ssr = sci_in(port, SCxSR); |
680 | 680 | ||
681 | /* Disable future Rx interrupts */ | 681 | /* Disable future Rx interrupts */ |
682 | sci_out(port, SCSCR, scr & ~SCI_CTRL_FLAGS_RIE); | 682 | if (port->type == PORT_SCIFA) { |
683 | disable_irq_nosync(irq); | ||
684 | scr |= 0x4000; | ||
685 | } else { | ||
686 | scr &= ~SCI_CTRL_FLAGS_RIE; | ||
687 | } | ||
688 | sci_out(port, SCSCR, scr); | ||
683 | /* Clear current interrupt */ | 689 | /* Clear current interrupt */ |
684 | sci_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port))); | 690 | sci_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port))); |
685 | /* Calculate delay for 1.5 DMA buffers */ | 691 | dev_dbg(port->dev, "Rx IRQ %lu: setup t-out in %u jiffies\n", |
686 | tout = (port->timeout - HZ / 50) * s->buf_len_rx * 3 / | 692 | jiffies, s->rx_timeout); |
687 | port->fifosize / 2; | 693 | mod_timer(&s->rx_timer, jiffies + s->rx_timeout); |
688 | dev_dbg(port->dev, "Rx IRQ: setup timeout in %lu ms\n", | ||
689 | tout * 1000 / HZ); | ||
690 | if (tout < 2) | ||
691 | tout = 2; | ||
692 | mod_timer(&s->rx_timer, jiffies + tout); | ||
693 | 694 | ||
694 | return IRQ_HANDLED; | 695 | return IRQ_HANDLED; |
695 | } | 696 | } |
@@ -799,7 +800,7 @@ static int sci_notifier(struct notifier_block *self, | |||
799 | (phase == CPUFREQ_RESUMECHANGE)) { | 800 | (phase == CPUFREQ_RESUMECHANGE)) { |
800 | spin_lock_irqsave(&priv->lock, flags); | 801 | spin_lock_irqsave(&priv->lock, flags); |
801 | list_for_each_entry(sci_port, &priv->ports, node) | 802 | list_for_each_entry(sci_port, &priv->ports, node) |
802 | sci_port->port.uartclk = clk_get_rate(sci_port->dclk); | 803 | sci_port->port.uartclk = clk_get_rate(sci_port->iclk); |
803 | spin_unlock_irqrestore(&priv->lock, flags); | 804 | spin_unlock_irqrestore(&priv->lock, flags); |
804 | } | 805 | } |
805 | 806 | ||
@@ -810,21 +811,17 @@ static void sci_clk_enable(struct uart_port *port) | |||
810 | { | 811 | { |
811 | struct sci_port *sci_port = to_sci_port(port); | 812 | struct sci_port *sci_port = to_sci_port(port); |
812 | 813 | ||
813 | clk_enable(sci_port->dclk); | 814 | clk_enable(sci_port->iclk); |
814 | sci_port->port.uartclk = clk_get_rate(sci_port->dclk); | 815 | sci_port->port.uartclk = clk_get_rate(sci_port->iclk); |
815 | 816 | clk_enable(sci_port->fclk); | |
816 | if (sci_port->iclk) | ||
817 | clk_enable(sci_port->iclk); | ||
818 | } | 817 | } |
819 | 818 | ||
820 | static void sci_clk_disable(struct uart_port *port) | 819 | static void sci_clk_disable(struct uart_port *port) |
821 | { | 820 | { |
822 | struct sci_port *sci_port = to_sci_port(port); | 821 | struct sci_port *sci_port = to_sci_port(port); |
823 | 822 | ||
824 | if (sci_port->iclk) | 823 | clk_disable(sci_port->fclk); |
825 | clk_disable(sci_port->iclk); | 824 | clk_disable(sci_port->iclk); |
826 | |||
827 | clk_disable(sci_port->dclk); | ||
828 | } | 825 | } |
829 | 826 | ||
830 | static int sci_request_irq(struct sci_port *port) | 827 | static int sci_request_irq(struct sci_port *port) |
@@ -913,22 +910,26 @@ static void sci_dma_tx_complete(void *arg) | |||
913 | 910 | ||
914 | spin_lock_irqsave(&port->lock, flags); | 911 | spin_lock_irqsave(&port->lock, flags); |
915 | 912 | ||
916 | xmit->tail += s->sg_tx.length; | 913 | xmit->tail += sg_dma_len(&s->sg_tx); |
917 | xmit->tail &= UART_XMIT_SIZE - 1; | 914 | xmit->tail &= UART_XMIT_SIZE - 1; |
918 | 915 | ||
919 | port->icount.tx += s->sg_tx.length; | 916 | port->icount.tx += sg_dma_len(&s->sg_tx); |
920 | 917 | ||
921 | async_tx_ack(s->desc_tx); | 918 | async_tx_ack(s->desc_tx); |
922 | s->cookie_tx = -EINVAL; | 919 | s->cookie_tx = -EINVAL; |
923 | s->desc_tx = NULL; | 920 | s->desc_tx = NULL; |
924 | 921 | ||
925 | spin_unlock_irqrestore(&port->lock, flags); | ||
926 | |||
927 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 922 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
928 | uart_write_wakeup(port); | 923 | uart_write_wakeup(port); |
929 | 924 | ||
930 | if (uart_circ_chars_pending(xmit)) | 925 | if (!uart_circ_empty(xmit)) { |
931 | schedule_work(&s->work_tx); | 926 | schedule_work(&s->work_tx); |
927 | } else if (port->type == PORT_SCIFA) { | ||
928 | u16 ctrl = sci_in(port, SCSCR); | ||
929 | sci_out(port, SCSCR, ctrl & ~SCI_CTRL_FLAGS_TIE); | ||
930 | } | ||
931 | |||
932 | spin_unlock_irqrestore(&port->lock, flags); | ||
932 | } | 933 | } |
933 | 934 | ||
934 | /* Locking: called with port lock held */ | 935 | /* Locking: called with port lock held */ |
@@ -972,13 +973,13 @@ static void sci_dma_rx_complete(void *arg) | |||
972 | unsigned long flags; | 973 | unsigned long flags; |
973 | int count; | 974 | int count; |
974 | 975 | ||
975 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); | 976 | dev_dbg(port->dev, "%s(%d) active #%d\n", __func__, port->line, s->active_rx); |
976 | 977 | ||
977 | spin_lock_irqsave(&port->lock, flags); | 978 | spin_lock_irqsave(&port->lock, flags); |
978 | 979 | ||
979 | count = sci_dma_rx_push(s, tty, s->buf_len_rx); | 980 | count = sci_dma_rx_push(s, tty, s->buf_len_rx); |
980 | 981 | ||
981 | mod_timer(&s->rx_timer, jiffies + msecs_to_jiffies(5)); | 982 | mod_timer(&s->rx_timer, jiffies + s->rx_timeout); |
982 | 983 | ||
983 | spin_unlock_irqrestore(&port->lock, flags); | 984 | spin_unlock_irqrestore(&port->lock, flags); |
984 | 985 | ||
@@ -1050,6 +1051,8 @@ static void sci_submit_rx(struct sci_port *s) | |||
1050 | sci_rx_dma_release(s, true); | 1051 | sci_rx_dma_release(s, true); |
1051 | return; | 1052 | return; |
1052 | } | 1053 | } |
1054 | dev_dbg(s->port.dev, "%s(): cookie %d to #%d\n", __func__, | ||
1055 | s->cookie_rx[i], i); | ||
1053 | } | 1056 | } |
1054 | 1057 | ||
1055 | s->active_rx = s->cookie_rx[0]; | 1058 | s->active_rx = s->cookie_rx[0]; |
@@ -1107,10 +1110,10 @@ static void work_fn_rx(struct work_struct *work) | |||
1107 | return; | 1110 | return; |
1108 | } | 1111 | } |
1109 | 1112 | ||
1110 | dev_dbg(port->dev, "%s: cookie %d #%d\n", __func__, | ||
1111 | s->cookie_rx[new], new); | ||
1112 | |||
1113 | s->active_rx = s->cookie_rx[!new]; | 1113 | s->active_rx = s->cookie_rx[!new]; |
1114 | |||
1115 | dev_dbg(port->dev, "%s: cookie %d #%d, new active #%d\n", __func__, | ||
1116 | s->cookie_rx[new], new, s->active_rx); | ||
1114 | } | 1117 | } |
1115 | 1118 | ||
1116 | static void work_fn_tx(struct work_struct *work) | 1119 | static void work_fn_tx(struct work_struct *work) |
@@ -1131,14 +1134,13 @@ static void work_fn_tx(struct work_struct *work) | |||
1131 | */ | 1134 | */ |
1132 | spin_lock_irq(&port->lock); | 1135 | spin_lock_irq(&port->lock); |
1133 | sg->offset = xmit->tail & (UART_XMIT_SIZE - 1); | 1136 | sg->offset = xmit->tail & (UART_XMIT_SIZE - 1); |
1134 | sg->dma_address = (sg_dma_address(sg) & ~(UART_XMIT_SIZE - 1)) + | 1137 | sg_dma_address(sg) = (sg_dma_address(sg) & ~(UART_XMIT_SIZE - 1)) + |
1135 | sg->offset; | 1138 | sg->offset; |
1136 | sg->length = min((int)CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE), | 1139 | sg_dma_len(sg) = min((int)CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE), |
1137 | CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE)); | 1140 | CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE)); |
1138 | sg->dma_length = sg->length; | ||
1139 | spin_unlock_irq(&port->lock); | 1141 | spin_unlock_irq(&port->lock); |
1140 | 1142 | ||
1141 | BUG_ON(!sg->length); | 1143 | BUG_ON(!sg_dma_len(sg)); |
1142 | 1144 | ||
1143 | desc = chan->device->device_prep_slave_sg(chan, | 1145 | desc = chan->device->device_prep_slave_sg(chan, |
1144 | sg, s->sg_len_tx, DMA_TO_DEVICE, | 1146 | sg, s->sg_len_tx, DMA_TO_DEVICE, |
@@ -1173,23 +1175,28 @@ static void work_fn_tx(struct work_struct *work) | |||
1173 | 1175 | ||
1174 | static void sci_start_tx(struct uart_port *port) | 1176 | static void sci_start_tx(struct uart_port *port) |
1175 | { | 1177 | { |
1178 | struct sci_port *s = to_sci_port(port); | ||
1176 | unsigned short ctrl; | 1179 | unsigned short ctrl; |
1177 | 1180 | ||
1178 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | 1181 | #ifdef CONFIG_SERIAL_SH_SCI_DMA |
1179 | struct sci_port *s = to_sci_port(port); | 1182 | if (port->type == PORT_SCIFA) { |
1180 | 1183 | u16 new, scr = sci_in(port, SCSCR); | |
1181 | if (s->chan_tx) { | 1184 | if (s->chan_tx) |
1182 | if (!uart_circ_empty(&s->port.state->xmit) && s->cookie_tx < 0) | 1185 | new = scr | 0x8000; |
1183 | schedule_work(&s->work_tx); | 1186 | else |
1184 | 1187 | new = scr & ~0x8000; | |
1185 | return; | 1188 | if (new != scr) |
1189 | sci_out(port, SCSCR, new); | ||
1186 | } | 1190 | } |
1191 | if (s->chan_tx && !uart_circ_empty(&s->port.state->xmit) && | ||
1192 | s->cookie_tx < 0) | ||
1193 | schedule_work(&s->work_tx); | ||
1187 | #endif | 1194 | #endif |
1188 | 1195 | if (!s->chan_tx || port->type == PORT_SCIFA) { | |
1189 | /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */ | 1196 | /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */ |
1190 | ctrl = sci_in(port, SCSCR); | 1197 | ctrl = sci_in(port, SCSCR); |
1191 | ctrl |= SCI_CTRL_FLAGS_TIE; | 1198 | sci_out(port, SCSCR, ctrl | SCI_CTRL_FLAGS_TIE); |
1192 | sci_out(port, SCSCR, ctrl); | 1199 | } |
1193 | } | 1200 | } |
1194 | 1201 | ||
1195 | static void sci_stop_tx(struct uart_port *port) | 1202 | static void sci_stop_tx(struct uart_port *port) |
@@ -1198,6 +1205,8 @@ static void sci_stop_tx(struct uart_port *port) | |||
1198 | 1205 | ||
1199 | /* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */ | 1206 | /* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */ |
1200 | ctrl = sci_in(port, SCSCR); | 1207 | ctrl = sci_in(port, SCSCR); |
1208 | if (port->type == PORT_SCIFA) | ||
1209 | ctrl &= ~0x8000; | ||
1201 | ctrl &= ~SCI_CTRL_FLAGS_TIE; | 1210 | ctrl &= ~SCI_CTRL_FLAGS_TIE; |
1202 | sci_out(port, SCSCR, ctrl); | 1211 | sci_out(port, SCSCR, ctrl); |
1203 | } | 1212 | } |
@@ -1208,6 +1217,8 @@ static void sci_start_rx(struct uart_port *port) | |||
1208 | 1217 | ||
1209 | /* Set RIE (Receive Interrupt Enable) bit in SCSCR */ | 1218 | /* Set RIE (Receive Interrupt Enable) bit in SCSCR */ |
1210 | ctrl |= sci_in(port, SCSCR); | 1219 | ctrl |= sci_in(port, SCSCR); |
1220 | if (port->type == PORT_SCIFA) | ||
1221 | ctrl &= ~0x4000; | ||
1211 | sci_out(port, SCSCR, ctrl); | 1222 | sci_out(port, SCSCR, ctrl); |
1212 | } | 1223 | } |
1213 | 1224 | ||
@@ -1217,6 +1228,8 @@ static void sci_stop_rx(struct uart_port *port) | |||
1217 | 1228 | ||
1218 | /* Clear RIE (Receive Interrupt Enable) bit in SCSCR */ | 1229 | /* Clear RIE (Receive Interrupt Enable) bit in SCSCR */ |
1219 | ctrl = sci_in(port, SCSCR); | 1230 | ctrl = sci_in(port, SCSCR); |
1231 | if (port->type == PORT_SCIFA) | ||
1232 | ctrl &= ~0x4000; | ||
1220 | ctrl &= ~(SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE); | 1233 | ctrl &= ~(SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE); |
1221 | sci_out(port, SCSCR, ctrl); | 1234 | sci_out(port, SCSCR, ctrl); |
1222 | } | 1235 | } |
@@ -1251,8 +1264,12 @@ static void rx_timer_fn(unsigned long arg) | |||
1251 | { | 1264 | { |
1252 | struct sci_port *s = (struct sci_port *)arg; | 1265 | struct sci_port *s = (struct sci_port *)arg; |
1253 | struct uart_port *port = &s->port; | 1266 | struct uart_port *port = &s->port; |
1254 | |||
1255 | u16 scr = sci_in(port, SCSCR); | 1267 | u16 scr = sci_in(port, SCSCR); |
1268 | |||
1269 | if (port->type == PORT_SCIFA) { | ||
1270 | scr &= ~0x4000; | ||
1271 | enable_irq(s->irqs[1]); | ||
1272 | } | ||
1256 | sci_out(port, SCSCR, scr | SCI_CTRL_FLAGS_RIE); | 1273 | sci_out(port, SCSCR, scr | SCI_CTRL_FLAGS_RIE); |
1257 | dev_dbg(port->dev, "DMA Rx timed out\n"); | 1274 | dev_dbg(port->dev, "DMA Rx timed out\n"); |
1258 | schedule_work(&s->work_rx); | 1275 | schedule_work(&s->work_rx); |
@@ -1339,8 +1356,7 @@ static void sci_request_dma(struct uart_port *port) | |||
1339 | sg_init_table(sg, 1); | 1356 | sg_init_table(sg, 1); |
1340 | sg_set_page(sg, virt_to_page(buf[i]), s->buf_len_rx, | 1357 | sg_set_page(sg, virt_to_page(buf[i]), s->buf_len_rx, |
1341 | (int)buf[i] & ~PAGE_MASK); | 1358 | (int)buf[i] & ~PAGE_MASK); |
1342 | sg->dma_address = dma[i]; | 1359 | sg_dma_address(sg) = dma[i]; |
1343 | sg->dma_length = sg->length; | ||
1344 | } | 1360 | } |
1345 | 1361 | ||
1346 | INIT_WORK(&s->work_rx, work_fn_rx); | 1362 | INIT_WORK(&s->work_rx, work_fn_rx); |
@@ -1403,8 +1419,12 @@ static void sci_shutdown(struct uart_port *port) | |||
1403 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | 1419 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, |
1404 | struct ktermios *old) | 1420 | struct ktermios *old) |
1405 | { | 1421 | { |
1422 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
1423 | struct sci_port *s = to_sci_port(port); | ||
1424 | #endif | ||
1406 | unsigned int status, baud, smr_val, max_baud; | 1425 | unsigned int status, baud, smr_val, max_baud; |
1407 | int t = -1; | 1426 | int t = -1; |
1427 | u16 scfcr = 0; | ||
1408 | 1428 | ||
1409 | /* | 1429 | /* |
1410 | * earlyprintk comes here early on with port->uartclk set to zero. | 1430 | * earlyprintk comes here early on with port->uartclk set to zero. |
@@ -1427,7 +1447,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1427 | sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */ | 1447 | sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */ |
1428 | 1448 | ||
1429 | if (port->type != PORT_SCI) | 1449 | if (port->type != PORT_SCI) |
1430 | sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST); | 1450 | sci_out(port, SCFCR, scfcr | SCFCR_RFRST | SCFCR_TFRST); |
1431 | 1451 | ||
1432 | smr_val = sci_in(port, SCSMR) & 3; | 1452 | smr_val = sci_in(port, SCSMR) & 3; |
1433 | if ((termios->c_cflag & CSIZE) == CS7) | 1453 | if ((termios->c_cflag & CSIZE) == CS7) |
@@ -1458,10 +1478,32 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1458 | } | 1478 | } |
1459 | 1479 | ||
1460 | sci_init_pins(port, termios->c_cflag); | 1480 | sci_init_pins(port, termios->c_cflag); |
1461 | sci_out(port, SCFCR, (termios->c_cflag & CRTSCTS) ? SCFCR_MCE : 0); | 1481 | sci_out(port, SCFCR, scfcr | ((termios->c_cflag & CRTSCTS) ? SCFCR_MCE : 0)); |
1462 | 1482 | ||
1463 | sci_out(port, SCSCR, SCSCR_INIT(port)); | 1483 | sci_out(port, SCSCR, SCSCR_INIT(port)); |
1464 | 1484 | ||
1485 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
1486 | /* | ||
1487 | * Calculate delay for 1.5 DMA buffers: see | ||
1488 | * drivers/serial/serial_core.c::uart_update_timeout(). With 10 bits | ||
1489 | * (CS8), 250Hz, 115200 baud and 64 bytes FIFO, the above function | ||
1490 | * calculates 1 jiffie for the data plus 5 jiffies for the "slop(e)." | ||
1491 | * Then below we calculate 3 jiffies (12ms) for 1.5 DMA buffers (3 FIFO | ||
1492 | * sizes), but it has been found out experimentally, that this is not | ||
1493 | * enough: the driver too often needlessly runs on a DMA timeout. 20ms | ||
1494 | * as a minimum seem to work perfectly. | ||
1495 | */ | ||
1496 | if (s->chan_rx) { | ||
1497 | s->rx_timeout = (port->timeout - HZ / 50) * s->buf_len_rx * 3 / | ||
1498 | port->fifosize / 2; | ||
1499 | dev_dbg(port->dev, | ||
1500 | "DMA Rx t-out %ums, tty t-out %u jiffies\n", | ||
1501 | s->rx_timeout * 1000 / HZ, port->timeout); | ||
1502 | if (s->rx_timeout < msecs_to_jiffies(20)) | ||
1503 | s->rx_timeout = msecs_to_jiffies(20); | ||
1504 | } | ||
1505 | #endif | ||
1506 | |||
1465 | if ((termios->c_cflag & CREAD) != 0) | 1507 | if ((termios->c_cflag & CREAD) != 0) |
1466 | sci_start_rx(port); | 1508 | sci_start_rx(port); |
1467 | } | 1509 | } |
@@ -1553,10 +1595,10 @@ static struct uart_ops sci_uart_ops = { | |||
1553 | #endif | 1595 | #endif |
1554 | }; | 1596 | }; |
1555 | 1597 | ||
1556 | static void __devinit sci_init_single(struct platform_device *dev, | 1598 | static int __devinit sci_init_single(struct platform_device *dev, |
1557 | struct sci_port *sci_port, | 1599 | struct sci_port *sci_port, |
1558 | unsigned int index, | 1600 | unsigned int index, |
1559 | struct plat_sci_port *p) | 1601 | struct plat_sci_port *p) |
1560 | { | 1602 | { |
1561 | struct uart_port *port = &sci_port->port; | 1603 | struct uart_port *port = &sci_port->port; |
1562 | 1604 | ||
@@ -1577,8 +1619,23 @@ static void __devinit sci_init_single(struct platform_device *dev, | |||
1577 | } | 1619 | } |
1578 | 1620 | ||
1579 | if (dev) { | 1621 | if (dev) { |
1580 | sci_port->iclk = p->clk ? clk_get(&dev->dev, p->clk) : NULL; | 1622 | sci_port->iclk = clk_get(&dev->dev, "sci_ick"); |
1581 | sci_port->dclk = clk_get(&dev->dev, "peripheral_clk"); | 1623 | if (IS_ERR(sci_port->iclk)) { |
1624 | sci_port->iclk = clk_get(&dev->dev, "peripheral_clk"); | ||
1625 | if (IS_ERR(sci_port->iclk)) { | ||
1626 | dev_err(&dev->dev, "can't get iclk\n"); | ||
1627 | return PTR_ERR(sci_port->iclk); | ||
1628 | } | ||
1629 | } | ||
1630 | |||
1631 | /* | ||
1632 | * The function clock is optional, ignore it if we can't | ||
1633 | * find it. | ||
1634 | */ | ||
1635 | sci_port->fclk = clk_get(&dev->dev, "sci_fck"); | ||
1636 | if (IS_ERR(sci_port->fclk)) | ||
1637 | sci_port->fclk = NULL; | ||
1638 | |||
1582 | sci_port->enable = sci_clk_enable; | 1639 | sci_port->enable = sci_clk_enable; |
1583 | sci_port->disable = sci_clk_disable; | 1640 | sci_port->disable = sci_clk_disable; |
1584 | port->dev = &dev->dev; | 1641 | port->dev = &dev->dev; |
@@ -1605,6 +1662,7 @@ static void __devinit sci_init_single(struct platform_device *dev, | |||
1605 | #endif | 1662 | #endif |
1606 | 1663 | ||
1607 | memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); | 1664 | memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); |
1665 | return 0; | ||
1608 | } | 1666 | } |
1609 | 1667 | ||
1610 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE | 1668 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE |
@@ -1754,8 +1812,11 @@ static int sci_remove(struct platform_device *dev) | |||
1754 | cpufreq_unregister_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER); | 1812 | cpufreq_unregister_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER); |
1755 | 1813 | ||
1756 | spin_lock_irqsave(&priv->lock, flags); | 1814 | spin_lock_irqsave(&priv->lock, flags); |
1757 | list_for_each_entry(p, &priv->ports, node) | 1815 | list_for_each_entry(p, &priv->ports, node) { |
1758 | uart_remove_one_port(&sci_uart_driver, &p->port); | 1816 | uart_remove_one_port(&sci_uart_driver, &p->port); |
1817 | clk_put(p->iclk); | ||
1818 | clk_put(p->fclk); | ||
1819 | } | ||
1759 | spin_unlock_irqrestore(&priv->lock, flags); | 1820 | spin_unlock_irqrestore(&priv->lock, flags); |
1760 | 1821 | ||
1761 | kfree(priv); | 1822 | kfree(priv); |
@@ -1781,7 +1842,9 @@ static int __devinit sci_probe_single(struct platform_device *dev, | |||
1781 | return 0; | 1842 | return 0; |
1782 | } | 1843 | } |
1783 | 1844 | ||
1784 | sci_init_single(dev, sciport, index, p); | 1845 | ret = sci_init_single(dev, sciport, index, p); |
1846 | if (ret) | ||
1847 | return ret; | ||
1785 | 1848 | ||
1786 | ret = uart_add_one_port(&sci_uart_driver, &sciport->port); | 1849 | ret = uart_add_one_port(&sci_uart_driver, &sciport->port); |
1787 | if (ret) | 1850 | if (ret) |