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