diff options
author | Simon Horman <horms+renesas@verge.net.au> | 2013-12-24 07:08:27 -0500 |
---|---|---|
committer | Simon Horman <horms+renesas@verge.net.au> | 2013-12-24 07:08:27 -0500 |
commit | e62db3848cd61e85a2b0b7828eb47de3ccda83e2 (patch) | |
tree | 612fda333f33316dbcdf52ea25f7344856c7c30b | |
parent | 250d829f68ecb5e775a99deb03c56832acec28f4 (diff) | |
parent | ec09c5eb491834d4011c72538e58d8b7096076bd (diff) |
Merge branch 'sh-sci' into soc3-base
-rw-r--r-- | drivers/tty/serial/sh-sci.c | 320 | ||||
-rw-r--r-- | drivers/tty/serial/sh-sci.h | 2 | ||||
-rw-r--r-- | include/linux/serial_sci.h | 34 |
3 files changed, 164 insertions, 192 deletions
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 7d8103cd3e2e..e4bf0e435af6 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
@@ -23,35 +23,34 @@ | |||
23 | 23 | ||
24 | #undef DEBUG | 24 | #undef DEBUG |
25 | 25 | ||
26 | #include <linux/module.h> | 26 | #include <linux/clk.h> |
27 | #include <linux/console.h> | ||
28 | #include <linux/ctype.h> | ||
29 | #include <linux/cpufreq.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/dmaengine.h> | ||
32 | #include <linux/dma-mapping.h> | ||
33 | #include <linux/err.h> | ||
27 | #include <linux/errno.h> | 34 | #include <linux/errno.h> |
28 | #include <linux/sh_dma.h> | 35 | #include <linux/init.h> |
29 | #include <linux/timer.h> | ||
30 | #include <linux/interrupt.h> | 36 | #include <linux/interrupt.h> |
31 | #include <linux/tty.h> | ||
32 | #include <linux/tty_flip.h> | ||
33 | #include <linux/serial.h> | ||
34 | #include <linux/major.h> | ||
35 | #include <linux/string.h> | ||
36 | #include <linux/sysrq.h> | ||
37 | #include <linux/ioport.h> | 37 | #include <linux/ioport.h> |
38 | #include <linux/major.h> | ||
39 | #include <linux/module.h> | ||
38 | #include <linux/mm.h> | 40 | #include <linux/mm.h> |
39 | #include <linux/init.h> | ||
40 | #include <linux/delay.h> | ||
41 | #include <linux/console.h> | ||
42 | #include <linux/platform_device.h> | ||
43 | #include <linux/serial_sci.h> | ||
44 | #include <linux/notifier.h> | 41 | #include <linux/notifier.h> |
42 | #include <linux/platform_device.h> | ||
45 | #include <linux/pm_runtime.h> | 43 | #include <linux/pm_runtime.h> |
46 | #include <linux/cpufreq.h> | ||
47 | #include <linux/clk.h> | ||
48 | #include <linux/ctype.h> | ||
49 | #include <linux/err.h> | ||
50 | #include <linux/dmaengine.h> | ||
51 | #include <linux/dma-mapping.h> | ||
52 | #include <linux/scatterlist.h> | 44 | #include <linux/scatterlist.h> |
45 | #include <linux/serial.h> | ||
46 | #include <linux/serial_sci.h> | ||
47 | #include <linux/sh_dma.h> | ||
53 | #include <linux/slab.h> | 48 | #include <linux/slab.h> |
54 | #include <linux/gpio.h> | 49 | #include <linux/string.h> |
50 | #include <linux/sysrq.h> | ||
51 | #include <linux/timer.h> | ||
52 | #include <linux/tty.h> | ||
53 | #include <linux/tty_flip.h> | ||
55 | 54 | ||
56 | #ifdef CONFIG_SUPERH | 55 | #ifdef CONFIG_SUPERH |
57 | #include <asm/sh_bios.h> | 56 | #include <asm/sh_bios.h> |
@@ -64,6 +63,10 @@ struct sci_port { | |||
64 | 63 | ||
65 | /* Platform configuration */ | 64 | /* Platform configuration */ |
66 | struct plat_sci_port *cfg; | 65 | struct plat_sci_port *cfg; |
66 | int overrun_bit; | ||
67 | unsigned int error_mask; | ||
68 | unsigned int sampling_rate; | ||
69 | |||
67 | 70 | ||
68 | /* Break timer */ | 71 | /* Break timer */ |
69 | struct timer_list break_timer; | 72 | struct timer_list break_timer; |
@@ -74,8 +77,8 @@ struct sci_port { | |||
74 | /* Function clock */ | 77 | /* Function clock */ |
75 | struct clk *fclk; | 78 | struct clk *fclk; |
76 | 79 | ||
80 | int irqs[SCIx_NR_IRQS]; | ||
77 | char *irqstr[SCIx_NR_IRQS]; | 81 | char *irqstr[SCIx_NR_IRQS]; |
78 | char *gpiostr[SCIx_NR_FNS]; | ||
79 | 82 | ||
80 | struct dma_chan *chan_tx; | 83 | struct dma_chan *chan_tx; |
81 | struct dma_chan *chan_rx; | 84 | struct dma_chan *chan_rx; |
@@ -421,9 +424,9 @@ static void sci_port_enable(struct sci_port *sci_port) | |||
421 | 424 | ||
422 | pm_runtime_get_sync(sci_port->port.dev); | 425 | pm_runtime_get_sync(sci_port->port.dev); |
423 | 426 | ||
424 | clk_enable(sci_port->iclk); | 427 | clk_prepare_enable(sci_port->iclk); |
425 | sci_port->port.uartclk = clk_get_rate(sci_port->iclk); | 428 | sci_port->port.uartclk = clk_get_rate(sci_port->iclk); |
426 | clk_enable(sci_port->fclk); | 429 | clk_prepare_enable(sci_port->fclk); |
427 | } | 430 | } |
428 | 431 | ||
429 | static void sci_port_disable(struct sci_port *sci_port) | 432 | static void sci_port_disable(struct sci_port *sci_port) |
@@ -431,8 +434,16 @@ static void sci_port_disable(struct sci_port *sci_port) | |||
431 | if (!sci_port->port.dev) | 434 | if (!sci_port->port.dev) |
432 | return; | 435 | return; |
433 | 436 | ||
434 | clk_disable(sci_port->fclk); | 437 | /* Cancel the break timer to ensure that the timer handler will not try |
435 | clk_disable(sci_port->iclk); | 438 | * to access the hardware with clocks and power disabled. Reset the |
439 | * break flag to make the break debouncing state machine ready for the | ||
440 | * next break. | ||
441 | */ | ||
442 | del_timer_sync(&sci_port->break_timer); | ||
443 | sci_port->break_flag = 0; | ||
444 | |||
445 | clk_disable_unprepare(sci_port->fclk); | ||
446 | clk_disable_unprepare(sci_port->iclk); | ||
436 | 447 | ||
437 | pm_runtime_put_sync(sci_port->port.dev); | 448 | pm_runtime_put_sync(sci_port->port.dev); |
438 | } | 449 | } |
@@ -557,7 +568,7 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
557 | return 1; | 568 | return 1; |
558 | 569 | ||
559 | /* Cast for ARM damage */ | 570 | /* Cast for ARM damage */ |
560 | return !!__raw_readb((void __iomem *)s->cfg->port_reg); | 571 | return !!__raw_readb((void __iomem *)(uintptr_t)s->cfg->port_reg); |
561 | } | 572 | } |
562 | 573 | ||
563 | /* ********************************************************************** * | 574 | /* ********************************************************************** * |
@@ -733,8 +744,6 @@ static void sci_break_timer(unsigned long data) | |||
733 | { | 744 | { |
734 | struct sci_port *port = (struct sci_port *)data; | 745 | struct sci_port *port = (struct sci_port *)data; |
735 | 746 | ||
736 | sci_port_enable(port); | ||
737 | |||
738 | if (sci_rxd_in(&port->port) == 0) { | 747 | if (sci_rxd_in(&port->port) == 0) { |
739 | port->break_flag = 1; | 748 | port->break_flag = 1; |
740 | sci_schedule_break_timer(port); | 749 | sci_schedule_break_timer(port); |
@@ -744,8 +753,6 @@ static void sci_break_timer(unsigned long data) | |||
744 | sci_schedule_break_timer(port); | 753 | sci_schedule_break_timer(port); |
745 | } else | 754 | } else |
746 | port->break_flag = 0; | 755 | port->break_flag = 0; |
747 | |||
748 | sci_port_disable(port); | ||
749 | } | 756 | } |
750 | 757 | ||
751 | static int sci_handle_errors(struct uart_port *port) | 758 | static int sci_handle_errors(struct uart_port *port) |
@@ -755,19 +762,15 @@ static int sci_handle_errors(struct uart_port *port) | |||
755 | struct tty_port *tport = &port->state->port; | 762 | struct tty_port *tport = &port->state->port; |
756 | struct sci_port *s = to_sci_port(port); | 763 | struct sci_port *s = to_sci_port(port); |
757 | 764 | ||
758 | /* | 765 | /* Handle overruns */ |
759 | * Handle overruns, if supported. | 766 | if (status & (1 << s->overrun_bit)) { |
760 | */ | 767 | port->icount.overrun++; |
761 | if (s->cfg->overrun_bit != SCIx_NOT_SUPPORTED) { | ||
762 | if (status & (1 << s->cfg->overrun_bit)) { | ||
763 | port->icount.overrun++; | ||
764 | 768 | ||
765 | /* overrun error */ | 769 | /* overrun error */ |
766 | if (tty_insert_flip_char(tport, 0, TTY_OVERRUN)) | 770 | if (tty_insert_flip_char(tport, 0, TTY_OVERRUN)) |
767 | copied++; | 771 | copied++; |
768 | 772 | ||
769 | dev_notice(port->dev, "overrun error"); | 773 | dev_notice(port->dev, "overrun error"); |
770 | } | ||
771 | } | 774 | } |
772 | 775 | ||
773 | if (status & SCxSR_FER(port)) { | 776 | if (status & SCxSR_FER(port)) { |
@@ -829,7 +832,7 @@ static int sci_handle_fifo_overrun(struct uart_port *port) | |||
829 | if (!reg->size) | 832 | if (!reg->size) |
830 | return 0; | 833 | return 0; |
831 | 834 | ||
832 | if ((serial_port_in(port, SCLSR) & (1 << s->cfg->overrun_bit))) { | 835 | if ((serial_port_in(port, SCLSR) & (1 << s->overrun_bit))) { |
833 | serial_port_out(port, SCLSR, 0); | 836 | serial_port_out(port, SCLSR, 0); |
834 | 837 | ||
835 | port->icount.overrun++; | 838 | port->icount.overrun++; |
@@ -1075,19 +1078,19 @@ static int sci_request_irq(struct sci_port *port) | |||
1075 | 1078 | ||
1076 | for (i = j = 0; i < SCIx_NR_IRQS; i++, j++) { | 1079 | for (i = j = 0; i < SCIx_NR_IRQS; i++, j++) { |
1077 | struct sci_irq_desc *desc; | 1080 | struct sci_irq_desc *desc; |
1078 | unsigned int irq; | 1081 | int irq; |
1079 | 1082 | ||
1080 | if (SCIx_IRQ_IS_MUXED(port)) { | 1083 | if (SCIx_IRQ_IS_MUXED(port)) { |
1081 | i = SCIx_MUX_IRQ; | 1084 | i = SCIx_MUX_IRQ; |
1082 | irq = up->irq; | 1085 | irq = up->irq; |
1083 | } else { | 1086 | } else { |
1084 | irq = port->cfg->irqs[i]; | 1087 | irq = port->irqs[i]; |
1085 | 1088 | ||
1086 | /* | 1089 | /* |
1087 | * Certain port types won't support all of the | 1090 | * Certain port types won't support all of the |
1088 | * available interrupt sources. | 1091 | * available interrupt sources. |
1089 | */ | 1092 | */ |
1090 | if (unlikely(!irq)) | 1093 | if (unlikely(irq < 0)) |
1091 | continue; | 1094 | continue; |
1092 | } | 1095 | } |
1093 | 1096 | ||
@@ -1112,7 +1115,7 @@ static int sci_request_irq(struct sci_port *port) | |||
1112 | 1115 | ||
1113 | out_noirq: | 1116 | out_noirq: |
1114 | while (--i >= 0) | 1117 | while (--i >= 0) |
1115 | free_irq(port->cfg->irqs[i], port); | 1118 | free_irq(port->irqs[i], port); |
1116 | 1119 | ||
1117 | out_nomem: | 1120 | out_nomem: |
1118 | while (--j >= 0) | 1121 | while (--j >= 0) |
@@ -1130,16 +1133,16 @@ static void sci_free_irq(struct sci_port *port) | |||
1130 | * IRQ first. | 1133 | * IRQ first. |
1131 | */ | 1134 | */ |
1132 | for (i = 0; i < SCIx_NR_IRQS; i++) { | 1135 | for (i = 0; i < SCIx_NR_IRQS; i++) { |
1133 | unsigned int irq = port->cfg->irqs[i]; | 1136 | int irq = port->irqs[i]; |
1134 | 1137 | ||
1135 | /* | 1138 | /* |
1136 | * Certain port types won't support all of the available | 1139 | * Certain port types won't support all of the available |
1137 | * interrupt sources. | 1140 | * interrupt sources. |
1138 | */ | 1141 | */ |
1139 | if (unlikely(!irq)) | 1142 | if (unlikely(irq < 0)) |
1140 | continue; | 1143 | continue; |
1141 | 1144 | ||
1142 | free_irq(port->cfg->irqs[i], port); | 1145 | free_irq(port->irqs[i], port); |
1143 | kfree(port->irqstr[i]); | 1146 | kfree(port->irqstr[i]); |
1144 | 1147 | ||
1145 | if (SCIx_IRQ_IS_MUXED(port)) { | 1148 | if (SCIx_IRQ_IS_MUXED(port)) { |
@@ -1149,67 +1152,6 @@ static void sci_free_irq(struct sci_port *port) | |||
1149 | } | 1152 | } |
1150 | } | 1153 | } |
1151 | 1154 | ||
1152 | static const char *sci_gpio_names[SCIx_NR_FNS] = { | ||
1153 | "sck", "rxd", "txd", "cts", "rts", | ||
1154 | }; | ||
1155 | |||
1156 | static const char *sci_gpio_str(unsigned int index) | ||
1157 | { | ||
1158 | return sci_gpio_names[index]; | ||
1159 | } | ||
1160 | |||
1161 | static void sci_init_gpios(struct sci_port *port) | ||
1162 | { | ||
1163 | struct uart_port *up = &port->port; | ||
1164 | int i; | ||
1165 | |||
1166 | if (!port->cfg) | ||
1167 | return; | ||
1168 | |||
1169 | for (i = 0; i < SCIx_NR_FNS; i++) { | ||
1170 | const char *desc; | ||
1171 | int ret; | ||
1172 | |||
1173 | if (!port->cfg->gpios[i]) | ||
1174 | continue; | ||
1175 | |||
1176 | desc = sci_gpio_str(i); | ||
1177 | |||
1178 | port->gpiostr[i] = kasprintf(GFP_KERNEL, "%s:%s", | ||
1179 | dev_name(up->dev), desc); | ||
1180 | |||
1181 | /* | ||
1182 | * If we've failed the allocation, we can still continue | ||
1183 | * on with a NULL string. | ||
1184 | */ | ||
1185 | if (!port->gpiostr[i]) | ||
1186 | dev_notice(up->dev, "%s string allocation failure\n", | ||
1187 | desc); | ||
1188 | |||
1189 | ret = gpio_request(port->cfg->gpios[i], port->gpiostr[i]); | ||
1190 | if (unlikely(ret != 0)) { | ||
1191 | dev_notice(up->dev, "failed %s gpio request\n", desc); | ||
1192 | |||
1193 | /* | ||
1194 | * If we can't get the GPIO for whatever reason, | ||
1195 | * no point in keeping the verbose string around. | ||
1196 | */ | ||
1197 | kfree(port->gpiostr[i]); | ||
1198 | } | ||
1199 | } | ||
1200 | } | ||
1201 | |||
1202 | static void sci_free_gpios(struct sci_port *port) | ||
1203 | { | ||
1204 | int i; | ||
1205 | |||
1206 | for (i = 0; i < SCIx_NR_FNS; i++) | ||
1207 | if (port->cfg->gpios[i]) { | ||
1208 | gpio_free(port->cfg->gpios[i]); | ||
1209 | kfree(port->gpiostr[i]); | ||
1210 | } | ||
1211 | } | ||
1212 | |||
1213 | static unsigned int sci_tx_empty(struct uart_port *port) | 1155 | static unsigned int sci_tx_empty(struct uart_port *port) |
1214 | { | 1156 | { |
1215 | unsigned short status = serial_port_in(port, SCxSR); | 1157 | unsigned short status = serial_port_in(port, SCxSR); |
@@ -1309,7 +1251,7 @@ static int sci_dma_rx_push(struct sci_port *s, size_t count) | |||
1309 | } | 1251 | } |
1310 | 1252 | ||
1311 | if (room < count) | 1253 | if (room < count) |
1312 | dev_warn(port->dev, "Rx overrun: dropping %u bytes\n", | 1254 | dev_warn(port->dev, "Rx overrun: dropping %zu bytes\n", |
1313 | count - room); | 1255 | count - room); |
1314 | if (!room) | 1256 | if (!room) |
1315 | return room; | 1257 | return room; |
@@ -1442,7 +1384,7 @@ static void work_fn_rx(struct work_struct *work) | |||
1442 | int count; | 1384 | int count; |
1443 | 1385 | ||
1444 | chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); | 1386 | chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); |
1445 | dev_dbg(port->dev, "Read %u bytes with cookie %d\n", | 1387 | dev_dbg(port->dev, "Read %zu bytes with cookie %d\n", |
1446 | sh_desc->partial, sh_desc->cookie); | 1388 | sh_desc->partial, sh_desc->cookie); |
1447 | 1389 | ||
1448 | spin_lock_irqsave(&port->lock, flags); | 1390 | spin_lock_irqsave(&port->lock, flags); |
@@ -1655,7 +1597,7 @@ static void rx_timer_fn(unsigned long arg) | |||
1655 | 1597 | ||
1656 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { | 1598 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { |
1657 | scr &= ~0x4000; | 1599 | scr &= ~0x4000; |
1658 | enable_irq(s->cfg->irqs[1]); | 1600 | enable_irq(s->irqs[SCIx_RXI_IRQ]); |
1659 | } | 1601 | } |
1660 | serial_port_out(port, SCSCR, scr | SCSCR_RIE); | 1602 | serial_port_out(port, SCSCR, scr | SCSCR_RIE); |
1661 | dev_dbg(port->dev, "DMA Rx timed out\n"); | 1603 | dev_dbg(port->dev, "DMA Rx timed out\n"); |
@@ -1691,16 +1633,17 @@ static void sci_request_dma(struct uart_port *port) | |||
1691 | s->chan_tx = chan; | 1633 | s->chan_tx = chan; |
1692 | sg_init_table(&s->sg_tx, 1); | 1634 | sg_init_table(&s->sg_tx, 1); |
1693 | /* UART circular tx buffer is an aligned page. */ | 1635 | /* UART circular tx buffer is an aligned page. */ |
1694 | BUG_ON((int)port->state->xmit.buf & ~PAGE_MASK); | 1636 | BUG_ON((uintptr_t)port->state->xmit.buf & ~PAGE_MASK); |
1695 | sg_set_page(&s->sg_tx, virt_to_page(port->state->xmit.buf), | 1637 | sg_set_page(&s->sg_tx, virt_to_page(port->state->xmit.buf), |
1696 | UART_XMIT_SIZE, (int)port->state->xmit.buf & ~PAGE_MASK); | 1638 | UART_XMIT_SIZE, |
1639 | (uintptr_t)port->state->xmit.buf & ~PAGE_MASK); | ||
1697 | nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE); | 1640 | nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE); |
1698 | if (!nent) | 1641 | if (!nent) |
1699 | sci_tx_dma_release(s, false); | 1642 | sci_tx_dma_release(s, false); |
1700 | else | 1643 | else |
1701 | dev_dbg(port->dev, "%s: mapped %d@%p to %x\n", __func__, | 1644 | dev_dbg(port->dev, "%s: mapped %d@%p to %pad\n", __func__, |
1702 | sg_dma_len(&s->sg_tx), | 1645 | sg_dma_len(&s->sg_tx), port->state->xmit.buf, |
1703 | port->state->xmit.buf, sg_dma_address(&s->sg_tx)); | 1646 | &sg_dma_address(&s->sg_tx)); |
1704 | 1647 | ||
1705 | s->sg_len_tx = nent; | 1648 | s->sg_len_tx = nent; |
1706 | 1649 | ||
@@ -1740,7 +1683,7 @@ static void sci_request_dma(struct uart_port *port) | |||
1740 | 1683 | ||
1741 | sg_init_table(sg, 1); | 1684 | sg_init_table(sg, 1); |
1742 | sg_set_page(sg, virt_to_page(buf[i]), s->buf_len_rx, | 1685 | sg_set_page(sg, virt_to_page(buf[i]), s->buf_len_rx, |
1743 | (int)buf[i] & ~PAGE_MASK); | 1686 | (uintptr_t)buf[i] & ~PAGE_MASK); |
1744 | sg_dma_address(sg) = dma[i]; | 1687 | sg_dma_address(sg) = dma[i]; |
1745 | } | 1688 | } |
1746 | 1689 | ||
@@ -1808,20 +1751,21 @@ static void sci_shutdown(struct uart_port *port) | |||
1808 | sci_free_irq(s); | 1751 | sci_free_irq(s); |
1809 | } | 1752 | } |
1810 | 1753 | ||
1811 | static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, | 1754 | static unsigned int sci_scbrr_calc(struct sci_port *s, unsigned int bps, |
1812 | unsigned long freq) | 1755 | unsigned long freq) |
1813 | { | 1756 | { |
1814 | switch (algo_id) { | 1757 | if (s->sampling_rate) |
1758 | return DIV_ROUND_CLOSEST(freq, s->sampling_rate * bps) - 1; | ||
1759 | |||
1760 | switch (s->cfg->scbrr_algo_id) { | ||
1815 | case SCBRR_ALGO_1: | 1761 | case SCBRR_ALGO_1: |
1816 | return ((freq + 16 * bps) / (16 * bps) - 1); | 1762 | return freq / (16 * bps); |
1817 | case SCBRR_ALGO_2: | 1763 | case SCBRR_ALGO_2: |
1818 | return ((freq + 16 * bps) / (32 * bps) - 1); | 1764 | return DIV_ROUND_CLOSEST(freq, 32 * bps) - 1; |
1819 | case SCBRR_ALGO_3: | 1765 | case SCBRR_ALGO_3: |
1820 | return (((freq * 2) + 16 * bps) / (16 * bps) - 1); | 1766 | return freq / (8 * bps); |
1821 | case SCBRR_ALGO_4: | 1767 | case SCBRR_ALGO_4: |
1822 | return (((freq * 2) + 16 * bps) / (32 * bps) - 1); | 1768 | return DIV_ROUND_CLOSEST(freq, 16 * bps) - 1; |
1823 | case SCBRR_ALGO_5: | ||
1824 | return (((freq * 1000 / 32) / bps) - 1); | ||
1825 | } | 1769 | } |
1826 | 1770 | ||
1827 | /* Warn, but use a safe default */ | 1771 | /* Warn, but use a safe default */ |
@@ -1903,12 +1847,11 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1903 | 1847 | ||
1904 | baud = uart_get_baud_rate(port, termios, old, 0, max_baud); | 1848 | baud = uart_get_baud_rate(port, termios, old, 0, max_baud); |
1905 | if (likely(baud && port->uartclk)) { | 1849 | if (likely(baud && port->uartclk)) { |
1906 | if (s->cfg->scbrr_algo_id == SCBRR_ALGO_6) { | 1850 | if (s->cfg->type == PORT_HSCIF) { |
1907 | sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, | 1851 | sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, |
1908 | &cks); | 1852 | &cks); |
1909 | } else { | 1853 | } else { |
1910 | t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, | 1854 | t = sci_scbrr_calc(s, baud, port->uartclk); |
1911 | port->uartclk); | ||
1912 | for (cks = 0; t >= 256 && cks <= 3; cks++) | 1855 | for (cks = 0; t >= 256 && cks <= 3; cks++) |
1913 | t >>= 2; | 1856 | t >>= 2; |
1914 | } | 1857 | } |
@@ -2115,10 +2058,6 @@ static void sci_config_port(struct uart_port *port, int flags) | |||
2115 | 2058 | ||
2116 | static int sci_verify_port(struct uart_port *port, struct serial_struct *ser) | 2059 | static int sci_verify_port(struct uart_port *port, struct serial_struct *ser) |
2117 | { | 2060 | { |
2118 | struct sci_port *s = to_sci_port(port); | ||
2119 | |||
2120 | if (ser->irq != s->cfg->irqs[SCIx_TXI_IRQ] || ser->irq > nr_irqs) | ||
2121 | return -EINVAL; | ||
2122 | if (ser->baud_base < 2400) | 2061 | if (ser->baud_base < 2400) |
2123 | /* No paper tape reader for Mitch.. */ | 2062 | /* No paper tape reader for Mitch.. */ |
2124 | return -EINVAL; | 2063 | return -EINVAL; |
@@ -2151,11 +2090,13 @@ static struct uart_ops sci_uart_ops = { | |||
2151 | }; | 2090 | }; |
2152 | 2091 | ||
2153 | static int sci_init_single(struct platform_device *dev, | 2092 | static int sci_init_single(struct platform_device *dev, |
2154 | struct sci_port *sci_port, | 2093 | struct sci_port *sci_port, unsigned int index, |
2155 | unsigned int index, | 2094 | struct plat_sci_port *p, bool early) |
2156 | struct plat_sci_port *p) | ||
2157 | { | 2095 | { |
2158 | struct uart_port *port = &sci_port->port; | 2096 | struct uart_port *port = &sci_port->port; |
2097 | const struct resource *res; | ||
2098 | unsigned int sampling_rate; | ||
2099 | unsigned int i; | ||
2159 | int ret; | 2100 | int ret; |
2160 | 2101 | ||
2161 | sci_port->cfg = p; | 2102 | sci_port->cfg = p; |
@@ -2164,31 +2105,90 @@ static int sci_init_single(struct platform_device *dev, | |||
2164 | port->iotype = UPIO_MEM; | 2105 | port->iotype = UPIO_MEM; |
2165 | port->line = index; | 2106 | port->line = index; |
2166 | 2107 | ||
2108 | if (dev->num_resources) { | ||
2109 | /* Device has resources, use them. */ | ||
2110 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
2111 | if (res == NULL) | ||
2112 | return -ENOMEM; | ||
2113 | |||
2114 | port->mapbase = res->start; | ||
2115 | |||
2116 | for (i = 0; i < ARRAY_SIZE(sci_port->irqs); ++i) | ||
2117 | sci_port->irqs[i] = platform_get_irq(dev, i); | ||
2118 | |||
2119 | /* The SCI generates several interrupts. They can be muxed | ||
2120 | * together or connected to different interrupt lines. In the | ||
2121 | * muxed case only one interrupt resource is specified. In the | ||
2122 | * non-muxed case three or four interrupt resources are | ||
2123 | * specified, as the BRI interrupt is optional. | ||
2124 | */ | ||
2125 | if (sci_port->irqs[0] < 0) | ||
2126 | return -ENXIO; | ||
2127 | |||
2128 | if (sci_port->irqs[1] < 0) { | ||
2129 | sci_port->irqs[1] = sci_port->irqs[0]; | ||
2130 | sci_port->irqs[2] = sci_port->irqs[0]; | ||
2131 | sci_port->irqs[3] = sci_port->irqs[0]; | ||
2132 | } | ||
2133 | } else { | ||
2134 | /* No resources, use old-style platform data. */ | ||
2135 | port->mapbase = p->mapbase; | ||
2136 | for (i = 0; i < ARRAY_SIZE(sci_port->irqs); ++i) | ||
2137 | sci_port->irqs[i] = p->irqs[i] ? p->irqs[i] : -ENXIO; | ||
2138 | } | ||
2139 | |||
2140 | if (p->regtype == SCIx_PROBE_REGTYPE) { | ||
2141 | ret = sci_probe_regmap(p); | ||
2142 | if (unlikely(ret)) | ||
2143 | return ret; | ||
2144 | } | ||
2145 | |||
2167 | switch (p->type) { | 2146 | switch (p->type) { |
2168 | case PORT_SCIFB: | 2147 | case PORT_SCIFB: |
2169 | port->fifosize = 256; | 2148 | port->fifosize = 256; |
2149 | sci_port->overrun_bit = 9; | ||
2150 | sampling_rate = 16; | ||
2170 | break; | 2151 | break; |
2171 | case PORT_HSCIF: | 2152 | case PORT_HSCIF: |
2172 | port->fifosize = 128; | 2153 | port->fifosize = 128; |
2154 | sampling_rate = 0; | ||
2155 | sci_port->overrun_bit = 0; | ||
2173 | break; | 2156 | break; |
2174 | case PORT_SCIFA: | 2157 | case PORT_SCIFA: |
2175 | port->fifosize = 64; | 2158 | port->fifosize = 64; |
2159 | sci_port->overrun_bit = 9; | ||
2160 | sampling_rate = 16; | ||
2176 | break; | 2161 | break; |
2177 | case PORT_SCIF: | 2162 | case PORT_SCIF: |
2178 | port->fifosize = 16; | 2163 | port->fifosize = 16; |
2164 | if (p->regtype == SCIx_SH7705_SCIF_REGTYPE) { | ||
2165 | sci_port->overrun_bit = 9; | ||
2166 | sampling_rate = 16; | ||
2167 | } else { | ||
2168 | sci_port->overrun_bit = 0; | ||
2169 | sampling_rate = 32; | ||
2170 | } | ||
2179 | break; | 2171 | break; |
2180 | default: | 2172 | default: |
2181 | port->fifosize = 1; | 2173 | port->fifosize = 1; |
2174 | sci_port->overrun_bit = 5; | ||
2175 | sampling_rate = 32; | ||
2182 | break; | 2176 | break; |
2183 | } | 2177 | } |
2184 | 2178 | ||
2185 | if (p->regtype == SCIx_PROBE_REGTYPE) { | 2179 | /* Set the sampling rate if the baud rate calculation algorithm isn't |
2186 | ret = sci_probe_regmap(p); | 2180 | * specified. |
2187 | if (unlikely(ret)) | 2181 | */ |
2188 | return ret; | 2182 | if (p->scbrr_algo_id == SCBRR_ALGO_NONE) { |
2183 | /* SCIFA on sh7723 and sh7724 need a custom sampling rate that | ||
2184 | * doesn't match the SoC datasheet, this should be investigated. | ||
2185 | * Let platform data override the sampling rate for now. | ||
2186 | */ | ||
2187 | sci_port->sampling_rate = p->sampling_rate ? p->sampling_rate | ||
2188 | : sampling_rate; | ||
2189 | } | 2189 | } |
2190 | 2190 | ||
2191 | if (dev) { | 2191 | if (!early) { |
2192 | sci_port->iclk = clk_get(&dev->dev, "sci_ick"); | 2192 | sci_port->iclk = clk_get(&dev->dev, "sci_ick"); |
2193 | if (IS_ERR(sci_port->iclk)) { | 2193 | if (IS_ERR(sci_port->iclk)) { |
2194 | sci_port->iclk = clk_get(&dev->dev, "peripheral_clk"); | 2194 | sci_port->iclk = clk_get(&dev->dev, "peripheral_clk"); |
@@ -2208,8 +2208,6 @@ static int sci_init_single(struct platform_device *dev, | |||
2208 | 2208 | ||
2209 | port->dev = &dev->dev; | 2209 | port->dev = &dev->dev; |
2210 | 2210 | ||
2211 | sci_init_gpios(sci_port); | ||
2212 | |||
2213 | pm_runtime_enable(&dev->dev); | 2211 | pm_runtime_enable(&dev->dev); |
2214 | } | 2212 | } |
2215 | 2213 | ||
@@ -2220,32 +2218,22 @@ static int sci_init_single(struct platform_device *dev, | |||
2220 | /* | 2218 | /* |
2221 | * Establish some sensible defaults for the error detection. | 2219 | * Establish some sensible defaults for the error detection. |
2222 | */ | 2220 | */ |
2223 | if (!p->error_mask) | 2221 | sci_port->error_mask = (p->type == PORT_SCI) ? |
2224 | p->error_mask = (p->type == PORT_SCI) ? | ||
2225 | SCI_DEFAULT_ERROR_MASK : SCIF_DEFAULT_ERROR_MASK; | 2222 | SCI_DEFAULT_ERROR_MASK : SCIF_DEFAULT_ERROR_MASK; |
2226 | 2223 | ||
2227 | /* | 2224 | /* |
2228 | * Establish sensible defaults for the overrun detection, unless | 2225 | * Establish sensible defaults for the overrun detection, unless |
2229 | * the part has explicitly disabled support for it. | 2226 | * the part has explicitly disabled support for it. |
2230 | */ | 2227 | */ |
2231 | if (p->overrun_bit != SCIx_NOT_SUPPORTED) { | ||
2232 | if (p->type == PORT_SCI) | ||
2233 | p->overrun_bit = 5; | ||
2234 | else if (p->scbrr_algo_id == SCBRR_ALGO_4) | ||
2235 | p->overrun_bit = 9; | ||
2236 | else | ||
2237 | p->overrun_bit = 0; | ||
2238 | 2228 | ||
2239 | /* | 2229 | /* |
2240 | * Make the error mask inclusive of overrun detection, if | 2230 | * Make the error mask inclusive of overrun detection, if |
2241 | * supported. | 2231 | * supported. |
2242 | */ | 2232 | */ |
2243 | p->error_mask |= (1 << p->overrun_bit); | 2233 | sci_port->error_mask |= 1 << sci_port->overrun_bit; |
2244 | } | ||
2245 | 2234 | ||
2246 | port->mapbase = p->mapbase; | ||
2247 | port->type = p->type; | 2235 | port->type = p->type; |
2248 | port->flags = p->flags; | 2236 | port->flags = UPF_FIXED_PORT | p->flags; |
2249 | port->regshift = p->regshift; | 2237 | port->regshift = p->regshift; |
2250 | 2238 | ||
2251 | /* | 2239 | /* |
@@ -2255,7 +2243,7 @@ static int sci_init_single(struct platform_device *dev, | |||
2255 | * | 2243 | * |
2256 | * For the muxed case there's nothing more to do. | 2244 | * For the muxed case there's nothing more to do. |
2257 | */ | 2245 | */ |
2258 | port->irq = p->irqs[SCIx_RXI_IRQ]; | 2246 | port->irq = sci_port->irqs[SCIx_RXI_IRQ]; |
2259 | port->irqflags = 0; | 2247 | port->irqflags = 0; |
2260 | 2248 | ||
2261 | port->serial_in = sci_serial_in; | 2249 | port->serial_in = sci_serial_in; |
@@ -2270,8 +2258,6 @@ static int sci_init_single(struct platform_device *dev, | |||
2270 | 2258 | ||
2271 | static void sci_cleanup_single(struct sci_port *port) | 2259 | static void sci_cleanup_single(struct sci_port *port) |
2272 | { | 2260 | { |
2273 | sci_free_gpios(port); | ||
2274 | |||
2275 | clk_put(port->iclk); | 2261 | clk_put(port->iclk); |
2276 | clk_put(port->fclk); | 2262 | clk_put(port->fclk); |
2277 | 2263 | ||
@@ -2387,7 +2373,7 @@ static int sci_probe_earlyprintk(struct platform_device *pdev) | |||
2387 | 2373 | ||
2388 | early_serial_console.index = pdev->id; | 2374 | early_serial_console.index = pdev->id; |
2389 | 2375 | ||
2390 | sci_init_single(NULL, &sci_ports[pdev->id], pdev->id, cfg); | 2376 | sci_init_single(pdev, &sci_ports[pdev->id], pdev->id, cfg, true); |
2391 | 2377 | ||
2392 | serial_console_setup(&early_serial_console, early_serial_buf); | 2378 | serial_console_setup(&early_serial_console, early_serial_buf); |
2393 | 2379 | ||
@@ -2454,7 +2440,7 @@ static int sci_probe_single(struct platform_device *dev, | |||
2454 | return -EINVAL; | 2440 | return -EINVAL; |
2455 | } | 2441 | } |
2456 | 2442 | ||
2457 | ret = sci_init_single(dev, sciport, index, p); | 2443 | ret = sci_init_single(dev, sciport, index, p, false); |
2458 | if (ret) | 2444 | if (ret) |
2459 | return ret; | 2445 | return ret; |
2460 | 2446 | ||
diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h index 5aca7364634c..d5db81a0a430 100644 --- a/drivers/tty/serial/sh-sci.h +++ b/drivers/tty/serial/sh-sci.h | |||
@@ -9,7 +9,7 @@ | |||
9 | #define SCxSR_PER(port) (((port)->type == PORT_SCI) ? SCI_PER : SCIF_PER) | 9 | #define SCxSR_PER(port) (((port)->type == PORT_SCI) ? SCI_PER : SCIF_PER) |
10 | #define SCxSR_BRK(port) (((port)->type == PORT_SCI) ? 0x00 : SCIF_BRK) | 10 | #define SCxSR_BRK(port) (((port)->type == PORT_SCI) ? 0x00 : SCIF_BRK) |
11 | 11 | ||
12 | #define SCxSR_ERRORS(port) (to_sci_port(port)->cfg->error_mask) | 12 | #define SCxSR_ERRORS(port) (to_sci_port(port)->error_mask) |
13 | 13 | ||
14 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | 14 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ |
15 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 15 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index 50fe651da965..af414e1895a5 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h | |||
@@ -11,11 +11,11 @@ | |||
11 | #define SCIx_NOT_SUPPORTED (-1) | 11 | #define SCIx_NOT_SUPPORTED (-1) |
12 | 12 | ||
13 | enum { | 13 | enum { |
14 | SCBRR_ALGO_1, /* ((clk + 16 * bps) / (16 * bps) - 1) */ | 14 | SCBRR_ALGO_NONE, /* Compute sampling rate in the driver */ |
15 | SCBRR_ALGO_2, /* ((clk + 16 * bps) / (32 * bps) - 1) */ | 15 | SCBRR_ALGO_1, /* clk / (16 * bps) */ |
16 | SCBRR_ALGO_3, /* (((clk * 2) + 16 * bps) / (16 * bps) - 1) */ | 16 | SCBRR_ALGO_2, /* DIV_ROUND_CLOSEST(clk, 32 * bps) - 1 */ |
17 | SCBRR_ALGO_4, /* (((clk * 2) + 16 * bps) / (32 * bps) - 1) */ | 17 | SCBRR_ALGO_3, /* clk / (8 * bps) */ |
18 | SCBRR_ALGO_5, /* (((clk * 1000 / 32) / bps) - 1) */ | 18 | SCBRR_ALGO_4, /* DIV_ROUND_CLOSEST(clk, 16 * bps) - 1 */ |
19 | SCBRR_ALGO_6, /* HSCIF variable sample rate algorithm */ | 19 | SCBRR_ALGO_6, /* HSCIF variable sample rate algorithm */ |
20 | }; | 20 | }; |
21 | 21 | ||
@@ -70,17 +70,6 @@ enum { | |||
70 | SCIx_MUX_IRQ = SCIx_NR_IRQS, /* special case */ | 70 | SCIx_MUX_IRQ = SCIx_NR_IRQS, /* special case */ |
71 | }; | 71 | }; |
72 | 72 | ||
73 | /* Offsets into the sci_port->gpios array */ | ||
74 | enum { | ||
75 | SCIx_SCK, | ||
76 | SCIx_RXD, | ||
77 | SCIx_TXD, | ||
78 | SCIx_CTS, | ||
79 | SCIx_RTS, | ||
80 | |||
81 | SCIx_NR_FNS, | ||
82 | }; | ||
83 | |||
84 | enum { | 73 | enum { |
85 | SCIx_PROBE_REGTYPE, | 74 | SCIx_PROBE_REGTYPE, |
86 | 75 | ||
@@ -108,10 +97,10 @@ enum { | |||
108 | } | 97 | } |
109 | 98 | ||
110 | #define SCIx_IRQ_IS_MUXED(port) \ | 99 | #define SCIx_IRQ_IS_MUXED(port) \ |
111 | ((port)->cfg->irqs[SCIx_ERI_IRQ] == \ | 100 | ((port)->irqs[SCIx_ERI_IRQ] == \ |
112 | (port)->cfg->irqs[SCIx_RXI_IRQ]) || \ | 101 | (port)->irqs[SCIx_RXI_IRQ]) || \ |
113 | ((port)->cfg->irqs[SCIx_ERI_IRQ] && \ | 102 | ((port)->irqs[SCIx_ERI_IRQ] && \ |
114 | !(port)->cfg->irqs[SCIx_RXI_IRQ]) | 103 | ((port)->irqs[SCIx_RXI_IRQ] < 0)) |
115 | /* | 104 | /* |
116 | * SCI register subset common for all port types. | 105 | * SCI register subset common for all port types. |
117 | * Not all registers will exist on all parts. | 106 | * Not all registers will exist on all parts. |
@@ -142,20 +131,17 @@ struct plat_sci_port_ops { | |||
142 | struct plat_sci_port { | 131 | struct plat_sci_port { |
143 | unsigned long mapbase; /* resource base */ | 132 | unsigned long mapbase; /* resource base */ |
144 | unsigned int irqs[SCIx_NR_IRQS]; /* ERI, RXI, TXI, BRI */ | 133 | unsigned int irqs[SCIx_NR_IRQS]; /* ERI, RXI, TXI, BRI */ |
145 | unsigned int gpios[SCIx_NR_FNS]; /* SCK, RXD, TXD, CTS, RTS */ | ||
146 | unsigned int type; /* SCI / SCIF / IRDA / HSCIF */ | 134 | unsigned int type; /* SCI / SCIF / IRDA / HSCIF */ |
147 | upf_t flags; /* UPF_* flags */ | 135 | upf_t flags; /* UPF_* flags */ |
148 | unsigned long capabilities; /* Port features/capabilities */ | 136 | unsigned long capabilities; /* Port features/capabilities */ |
149 | 137 | ||
138 | unsigned int sampling_rate; | ||
150 | unsigned int scbrr_algo_id; /* SCBRR calculation algo */ | 139 | unsigned int scbrr_algo_id; /* SCBRR calculation algo */ |
151 | unsigned int scscr; /* SCSCR initialization */ | 140 | unsigned int scscr; /* SCSCR initialization */ |
152 | 141 | ||
153 | /* | 142 | /* |
154 | * Platform overrides if necessary, defaults otherwise. | 143 | * Platform overrides if necessary, defaults otherwise. |
155 | */ | 144 | */ |
156 | int overrun_bit; | ||
157 | unsigned int error_mask; | ||
158 | |||
159 | int port_reg; | 145 | int port_reg; |
160 | unsigned char regshift; | 146 | unsigned char regshift; |
161 | unsigned char regtype; | 147 | unsigned char regtype; |