diff options
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r-- | drivers/tty/serial/sh-sci.c | 425 | ||||
-rw-r--r-- | drivers/tty/serial/sh-sci.h | 2 |
2 files changed, 250 insertions, 177 deletions
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 7d8103cd3e2e..be33d2b0613b 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
@@ -23,35 +23,35 @@ | |||
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/of.h> | ||
43 | #include <linux/platform_device.h> | ||
45 | #include <linux/pm_runtime.h> | 44 | #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> | 45 | #include <linux/scatterlist.h> |
46 | #include <linux/serial.h> | ||
47 | #include <linux/serial_sci.h> | ||
48 | #include <linux/sh_dma.h> | ||
53 | #include <linux/slab.h> | 49 | #include <linux/slab.h> |
54 | #include <linux/gpio.h> | 50 | #include <linux/string.h> |
51 | #include <linux/sysrq.h> | ||
52 | #include <linux/timer.h> | ||
53 | #include <linux/tty.h> | ||
54 | #include <linux/tty_flip.h> | ||
55 | 55 | ||
56 | #ifdef CONFIG_SUPERH | 56 | #ifdef CONFIG_SUPERH |
57 | #include <asm/sh_bios.h> | 57 | #include <asm/sh_bios.h> |
@@ -59,11 +59,32 @@ | |||
59 | 59 | ||
60 | #include "sh-sci.h" | 60 | #include "sh-sci.h" |
61 | 61 | ||
62 | /* Offsets into the sci_port->irqs array */ | ||
63 | enum { | ||
64 | SCIx_ERI_IRQ, | ||
65 | SCIx_RXI_IRQ, | ||
66 | SCIx_TXI_IRQ, | ||
67 | SCIx_BRI_IRQ, | ||
68 | SCIx_NR_IRQS, | ||
69 | |||
70 | SCIx_MUX_IRQ = SCIx_NR_IRQS, /* special case */ | ||
71 | }; | ||
72 | |||
73 | #define SCIx_IRQ_IS_MUXED(port) \ | ||
74 | ((port)->irqs[SCIx_ERI_IRQ] == \ | ||
75 | (port)->irqs[SCIx_RXI_IRQ]) || \ | ||
76 | ((port)->irqs[SCIx_ERI_IRQ] && \ | ||
77 | ((port)->irqs[SCIx_RXI_IRQ] < 0)) | ||
78 | |||
62 | struct sci_port { | 79 | struct sci_port { |
63 | struct uart_port port; | 80 | struct uart_port port; |
64 | 81 | ||
65 | /* Platform configuration */ | 82 | /* Platform configuration */ |
66 | struct plat_sci_port *cfg; | 83 | struct plat_sci_port *cfg; |
84 | int overrun_bit; | ||
85 | unsigned int error_mask; | ||
86 | unsigned int sampling_rate; | ||
87 | |||
67 | 88 | ||
68 | /* Break timer */ | 89 | /* Break timer */ |
69 | struct timer_list break_timer; | 90 | struct timer_list break_timer; |
@@ -74,8 +95,8 @@ struct sci_port { | |||
74 | /* Function clock */ | 95 | /* Function clock */ |
75 | struct clk *fclk; | 96 | struct clk *fclk; |
76 | 97 | ||
98 | int irqs[SCIx_NR_IRQS]; | ||
77 | char *irqstr[SCIx_NR_IRQS]; | 99 | char *irqstr[SCIx_NR_IRQS]; |
78 | char *gpiostr[SCIx_NR_FNS]; | ||
79 | 100 | ||
80 | struct dma_chan *chan_tx; | 101 | struct dma_chan *chan_tx; |
81 | struct dma_chan *chan_rx; | 102 | struct dma_chan *chan_rx; |
@@ -421,9 +442,9 @@ static void sci_port_enable(struct sci_port *sci_port) | |||
421 | 442 | ||
422 | pm_runtime_get_sync(sci_port->port.dev); | 443 | pm_runtime_get_sync(sci_port->port.dev); |
423 | 444 | ||
424 | clk_enable(sci_port->iclk); | 445 | clk_prepare_enable(sci_port->iclk); |
425 | sci_port->port.uartclk = clk_get_rate(sci_port->iclk); | 446 | sci_port->port.uartclk = clk_get_rate(sci_port->iclk); |
426 | clk_enable(sci_port->fclk); | 447 | clk_prepare_enable(sci_port->fclk); |
427 | } | 448 | } |
428 | 449 | ||
429 | static void sci_port_disable(struct sci_port *sci_port) | 450 | static void sci_port_disable(struct sci_port *sci_port) |
@@ -431,8 +452,16 @@ static void sci_port_disable(struct sci_port *sci_port) | |||
431 | if (!sci_port->port.dev) | 452 | if (!sci_port->port.dev) |
432 | return; | 453 | return; |
433 | 454 | ||
434 | clk_disable(sci_port->fclk); | 455 | /* Cancel the break timer to ensure that the timer handler will not try |
435 | clk_disable(sci_port->iclk); | 456 | * to access the hardware with clocks and power disabled. Reset the |
457 | * break flag to make the break debouncing state machine ready for the | ||
458 | * next break. | ||
459 | */ | ||
460 | del_timer_sync(&sci_port->break_timer); | ||
461 | sci_port->break_flag = 0; | ||
462 | |||
463 | clk_disable_unprepare(sci_port->fclk); | ||
464 | clk_disable_unprepare(sci_port->iclk); | ||
436 | 465 | ||
437 | pm_runtime_put_sync(sci_port->port.dev); | 466 | pm_runtime_put_sync(sci_port->port.dev); |
438 | } | 467 | } |
@@ -557,7 +586,7 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
557 | return 1; | 586 | return 1; |
558 | 587 | ||
559 | /* Cast for ARM damage */ | 588 | /* Cast for ARM damage */ |
560 | return !!__raw_readb((void __iomem *)s->cfg->port_reg); | 589 | return !!__raw_readb((void __iomem *)(uintptr_t)s->cfg->port_reg); |
561 | } | 590 | } |
562 | 591 | ||
563 | /* ********************************************************************** * | 592 | /* ********************************************************************** * |
@@ -733,8 +762,6 @@ static void sci_break_timer(unsigned long data) | |||
733 | { | 762 | { |
734 | struct sci_port *port = (struct sci_port *)data; | 763 | struct sci_port *port = (struct sci_port *)data; |
735 | 764 | ||
736 | sci_port_enable(port); | ||
737 | |||
738 | if (sci_rxd_in(&port->port) == 0) { | 765 | if (sci_rxd_in(&port->port) == 0) { |
739 | port->break_flag = 1; | 766 | port->break_flag = 1; |
740 | sci_schedule_break_timer(port); | 767 | sci_schedule_break_timer(port); |
@@ -744,8 +771,6 @@ static void sci_break_timer(unsigned long data) | |||
744 | sci_schedule_break_timer(port); | 771 | sci_schedule_break_timer(port); |
745 | } else | 772 | } else |
746 | port->break_flag = 0; | 773 | port->break_flag = 0; |
747 | |||
748 | sci_port_disable(port); | ||
749 | } | 774 | } |
750 | 775 | ||
751 | static int sci_handle_errors(struct uart_port *port) | 776 | static int sci_handle_errors(struct uart_port *port) |
@@ -755,19 +780,15 @@ static int sci_handle_errors(struct uart_port *port) | |||
755 | struct tty_port *tport = &port->state->port; | 780 | struct tty_port *tport = &port->state->port; |
756 | struct sci_port *s = to_sci_port(port); | 781 | struct sci_port *s = to_sci_port(port); |
757 | 782 | ||
758 | /* | 783 | /* Handle overruns */ |
759 | * Handle overruns, if supported. | 784 | if (status & (1 << s->overrun_bit)) { |
760 | */ | 785 | 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 | 786 | ||
765 | /* overrun error */ | 787 | /* overrun error */ |
766 | if (tty_insert_flip_char(tport, 0, TTY_OVERRUN)) | 788 | if (tty_insert_flip_char(tport, 0, TTY_OVERRUN)) |
767 | copied++; | 789 | copied++; |
768 | 790 | ||
769 | dev_notice(port->dev, "overrun error"); | 791 | dev_notice(port->dev, "overrun error"); |
770 | } | ||
771 | } | 792 | } |
772 | 793 | ||
773 | if (status & SCxSR_FER(port)) { | 794 | if (status & SCxSR_FER(port)) { |
@@ -829,7 +850,7 @@ static int sci_handle_fifo_overrun(struct uart_port *port) | |||
829 | if (!reg->size) | 850 | if (!reg->size) |
830 | return 0; | 851 | return 0; |
831 | 852 | ||
832 | if ((serial_port_in(port, SCLSR) & (1 << s->cfg->overrun_bit))) { | 853 | if ((serial_port_in(port, SCLSR) & (1 << s->overrun_bit))) { |
833 | serial_port_out(port, SCLSR, 0); | 854 | serial_port_out(port, SCLSR, 0); |
834 | 855 | ||
835 | port->icount.overrun++; | 856 | port->icount.overrun++; |
@@ -1075,19 +1096,19 @@ static int sci_request_irq(struct sci_port *port) | |||
1075 | 1096 | ||
1076 | for (i = j = 0; i < SCIx_NR_IRQS; i++, j++) { | 1097 | for (i = j = 0; i < SCIx_NR_IRQS; i++, j++) { |
1077 | struct sci_irq_desc *desc; | 1098 | struct sci_irq_desc *desc; |
1078 | unsigned int irq; | 1099 | int irq; |
1079 | 1100 | ||
1080 | if (SCIx_IRQ_IS_MUXED(port)) { | 1101 | if (SCIx_IRQ_IS_MUXED(port)) { |
1081 | i = SCIx_MUX_IRQ; | 1102 | i = SCIx_MUX_IRQ; |
1082 | irq = up->irq; | 1103 | irq = up->irq; |
1083 | } else { | 1104 | } else { |
1084 | irq = port->cfg->irqs[i]; | 1105 | irq = port->irqs[i]; |
1085 | 1106 | ||
1086 | /* | 1107 | /* |
1087 | * Certain port types won't support all of the | 1108 | * Certain port types won't support all of the |
1088 | * available interrupt sources. | 1109 | * available interrupt sources. |
1089 | */ | 1110 | */ |
1090 | if (unlikely(!irq)) | 1111 | if (unlikely(irq < 0)) |
1091 | continue; | 1112 | continue; |
1092 | } | 1113 | } |
1093 | 1114 | ||
@@ -1112,7 +1133,7 @@ static int sci_request_irq(struct sci_port *port) | |||
1112 | 1133 | ||
1113 | out_noirq: | 1134 | out_noirq: |
1114 | while (--i >= 0) | 1135 | while (--i >= 0) |
1115 | free_irq(port->cfg->irqs[i], port); | 1136 | free_irq(port->irqs[i], port); |
1116 | 1137 | ||
1117 | out_nomem: | 1138 | out_nomem: |
1118 | while (--j >= 0) | 1139 | while (--j >= 0) |
@@ -1130,16 +1151,16 @@ static void sci_free_irq(struct sci_port *port) | |||
1130 | * IRQ first. | 1151 | * IRQ first. |
1131 | */ | 1152 | */ |
1132 | for (i = 0; i < SCIx_NR_IRQS; i++) { | 1153 | for (i = 0; i < SCIx_NR_IRQS; i++) { |
1133 | unsigned int irq = port->cfg->irqs[i]; | 1154 | int irq = port->irqs[i]; |
1134 | 1155 | ||
1135 | /* | 1156 | /* |
1136 | * Certain port types won't support all of the available | 1157 | * Certain port types won't support all of the available |
1137 | * interrupt sources. | 1158 | * interrupt sources. |
1138 | */ | 1159 | */ |
1139 | if (unlikely(!irq)) | 1160 | if (unlikely(irq < 0)) |
1140 | continue; | 1161 | continue; |
1141 | 1162 | ||
1142 | free_irq(port->cfg->irqs[i], port); | 1163 | free_irq(port->irqs[i], port); |
1143 | kfree(port->irqstr[i]); | 1164 | kfree(port->irqstr[i]); |
1144 | 1165 | ||
1145 | if (SCIx_IRQ_IS_MUXED(port)) { | 1166 | if (SCIx_IRQ_IS_MUXED(port)) { |
@@ -1149,67 +1170,6 @@ static void sci_free_irq(struct sci_port *port) | |||
1149 | } | 1170 | } |
1150 | } | 1171 | } |
1151 | 1172 | ||
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) | 1173 | static unsigned int sci_tx_empty(struct uart_port *port) |
1214 | { | 1174 | { |
1215 | unsigned short status = serial_port_in(port, SCxSR); | 1175 | unsigned short status = serial_port_in(port, SCxSR); |
@@ -1309,7 +1269,7 @@ static int sci_dma_rx_push(struct sci_port *s, size_t count) | |||
1309 | } | 1269 | } |
1310 | 1270 | ||
1311 | if (room < count) | 1271 | if (room < count) |
1312 | dev_warn(port->dev, "Rx overrun: dropping %u bytes\n", | 1272 | dev_warn(port->dev, "Rx overrun: dropping %zu bytes\n", |
1313 | count - room); | 1273 | count - room); |
1314 | if (!room) | 1274 | if (!room) |
1315 | return room; | 1275 | return room; |
@@ -1442,7 +1402,7 @@ static void work_fn_rx(struct work_struct *work) | |||
1442 | int count; | 1402 | int count; |
1443 | 1403 | ||
1444 | chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); | 1404 | chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); |
1445 | dev_dbg(port->dev, "Read %u bytes with cookie %d\n", | 1405 | dev_dbg(port->dev, "Read %zu bytes with cookie %d\n", |
1446 | sh_desc->partial, sh_desc->cookie); | 1406 | sh_desc->partial, sh_desc->cookie); |
1447 | 1407 | ||
1448 | spin_lock_irqsave(&port->lock, flags); | 1408 | spin_lock_irqsave(&port->lock, flags); |
@@ -1655,7 +1615,7 @@ static void rx_timer_fn(unsigned long arg) | |||
1655 | 1615 | ||
1656 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { | 1616 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { |
1657 | scr &= ~0x4000; | 1617 | scr &= ~0x4000; |
1658 | enable_irq(s->cfg->irqs[1]); | 1618 | enable_irq(s->irqs[SCIx_RXI_IRQ]); |
1659 | } | 1619 | } |
1660 | serial_port_out(port, SCSCR, scr | SCSCR_RIE); | 1620 | serial_port_out(port, SCSCR, scr | SCSCR_RIE); |
1661 | dev_dbg(port->dev, "DMA Rx timed out\n"); | 1621 | dev_dbg(port->dev, "DMA Rx timed out\n"); |
@@ -1691,16 +1651,17 @@ static void sci_request_dma(struct uart_port *port) | |||
1691 | s->chan_tx = chan; | 1651 | s->chan_tx = chan; |
1692 | sg_init_table(&s->sg_tx, 1); | 1652 | sg_init_table(&s->sg_tx, 1); |
1693 | /* UART circular tx buffer is an aligned page. */ | 1653 | /* UART circular tx buffer is an aligned page. */ |
1694 | BUG_ON((int)port->state->xmit.buf & ~PAGE_MASK); | 1654 | BUG_ON((uintptr_t)port->state->xmit.buf & ~PAGE_MASK); |
1695 | sg_set_page(&s->sg_tx, virt_to_page(port->state->xmit.buf), | 1655 | sg_set_page(&s->sg_tx, virt_to_page(port->state->xmit.buf), |
1696 | UART_XMIT_SIZE, (int)port->state->xmit.buf & ~PAGE_MASK); | 1656 | UART_XMIT_SIZE, |
1657 | (uintptr_t)port->state->xmit.buf & ~PAGE_MASK); | ||
1697 | nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE); | 1658 | nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE); |
1698 | if (!nent) | 1659 | if (!nent) |
1699 | sci_tx_dma_release(s, false); | 1660 | sci_tx_dma_release(s, false); |
1700 | else | 1661 | else |
1701 | dev_dbg(port->dev, "%s: mapped %d@%p to %x\n", __func__, | 1662 | dev_dbg(port->dev, "%s: mapped %d@%p to %pad\n", __func__, |
1702 | sg_dma_len(&s->sg_tx), | 1663 | sg_dma_len(&s->sg_tx), port->state->xmit.buf, |
1703 | port->state->xmit.buf, sg_dma_address(&s->sg_tx)); | 1664 | &sg_dma_address(&s->sg_tx)); |
1704 | 1665 | ||
1705 | s->sg_len_tx = nent; | 1666 | s->sg_len_tx = nent; |
1706 | 1667 | ||
@@ -1740,7 +1701,7 @@ static void sci_request_dma(struct uart_port *port) | |||
1740 | 1701 | ||
1741 | sg_init_table(sg, 1); | 1702 | sg_init_table(sg, 1); |
1742 | sg_set_page(sg, virt_to_page(buf[i]), s->buf_len_rx, | 1703 | sg_set_page(sg, virt_to_page(buf[i]), s->buf_len_rx, |
1743 | (int)buf[i] & ~PAGE_MASK); | 1704 | (uintptr_t)buf[i] & ~PAGE_MASK); |
1744 | sg_dma_address(sg) = dma[i]; | 1705 | sg_dma_address(sg) = dma[i]; |
1745 | } | 1706 | } |
1746 | 1707 | ||
@@ -1808,21 +1769,11 @@ static void sci_shutdown(struct uart_port *port) | |||
1808 | sci_free_irq(s); | 1769 | sci_free_irq(s); |
1809 | } | 1770 | } |
1810 | 1771 | ||
1811 | static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, | 1772 | static unsigned int sci_scbrr_calc(struct sci_port *s, unsigned int bps, |
1812 | unsigned long freq) | 1773 | unsigned long freq) |
1813 | { | 1774 | { |
1814 | switch (algo_id) { | 1775 | if (s->sampling_rate) |
1815 | case SCBRR_ALGO_1: | 1776 | return DIV_ROUND_CLOSEST(freq, s->sampling_rate * bps) - 1; |
1816 | return ((freq + 16 * bps) / (16 * bps) - 1); | ||
1817 | case SCBRR_ALGO_2: | ||
1818 | return ((freq + 16 * bps) / (32 * bps) - 1); | ||
1819 | case SCBRR_ALGO_3: | ||
1820 | return (((freq * 2) + 16 * bps) / (16 * bps) - 1); | ||
1821 | case SCBRR_ALGO_4: | ||
1822 | return (((freq * 2) + 16 * bps) / (32 * bps) - 1); | ||
1823 | case SCBRR_ALGO_5: | ||
1824 | return (((freq * 1000 / 32) / bps) - 1); | ||
1825 | } | ||
1826 | 1777 | ||
1827 | /* Warn, but use a safe default */ | 1778 | /* Warn, but use a safe default */ |
1828 | WARN_ON(1); | 1779 | WARN_ON(1); |
@@ -1903,12 +1854,11 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1903 | 1854 | ||
1904 | baud = uart_get_baud_rate(port, termios, old, 0, max_baud); | 1855 | baud = uart_get_baud_rate(port, termios, old, 0, max_baud); |
1905 | if (likely(baud && port->uartclk)) { | 1856 | if (likely(baud && port->uartclk)) { |
1906 | if (s->cfg->scbrr_algo_id == SCBRR_ALGO_6) { | 1857 | if (s->cfg->type == PORT_HSCIF) { |
1907 | sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, | 1858 | sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, |
1908 | &cks); | 1859 | &cks); |
1909 | } else { | 1860 | } else { |
1910 | t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, | 1861 | t = sci_scbrr_calc(s, baud, port->uartclk); |
1911 | port->uartclk); | ||
1912 | for (cks = 0; t >= 256 && cks <= 3; cks++) | 1862 | for (cks = 0; t >= 256 && cks <= 3; cks++) |
1913 | t >>= 2; | 1863 | t >>= 2; |
1914 | } | 1864 | } |
@@ -2115,10 +2065,6 @@ static void sci_config_port(struct uart_port *port, int flags) | |||
2115 | 2065 | ||
2116 | static int sci_verify_port(struct uart_port *port, struct serial_struct *ser) | 2066 | static int sci_verify_port(struct uart_port *port, struct serial_struct *ser) |
2117 | { | 2067 | { |
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) | 2068 | if (ser->baud_base < 2400) |
2123 | /* No paper tape reader for Mitch.. */ | 2069 | /* No paper tape reader for Mitch.. */ |
2124 | return -EINVAL; | 2070 | return -EINVAL; |
@@ -2151,11 +2097,13 @@ static struct uart_ops sci_uart_ops = { | |||
2151 | }; | 2097 | }; |
2152 | 2098 | ||
2153 | static int sci_init_single(struct platform_device *dev, | 2099 | static int sci_init_single(struct platform_device *dev, |
2154 | struct sci_port *sci_port, | 2100 | struct sci_port *sci_port, unsigned int index, |
2155 | unsigned int index, | 2101 | struct plat_sci_port *p, bool early) |
2156 | struct plat_sci_port *p) | ||
2157 | { | 2102 | { |
2158 | struct uart_port *port = &sci_port->port; | 2103 | struct uart_port *port = &sci_port->port; |
2104 | const struct resource *res; | ||
2105 | unsigned int sampling_rate; | ||
2106 | unsigned int i; | ||
2159 | int ret; | 2107 | int ret; |
2160 | 2108 | ||
2161 | sci_port->cfg = p; | 2109 | sci_port->cfg = p; |
@@ -2164,31 +2112,76 @@ static int sci_init_single(struct platform_device *dev, | |||
2164 | port->iotype = UPIO_MEM; | 2112 | port->iotype = UPIO_MEM; |
2165 | port->line = index; | 2113 | port->line = index; |
2166 | 2114 | ||
2115 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
2116 | if (res == NULL) | ||
2117 | return -ENOMEM; | ||
2118 | |||
2119 | port->mapbase = res->start; | ||
2120 | |||
2121 | for (i = 0; i < ARRAY_SIZE(sci_port->irqs); ++i) | ||
2122 | sci_port->irqs[i] = platform_get_irq(dev, i); | ||
2123 | |||
2124 | /* The SCI generates several interrupts. They can be muxed together or | ||
2125 | * connected to different interrupt lines. In the muxed case only one | ||
2126 | * interrupt resource is specified. In the non-muxed case three or four | ||
2127 | * interrupt resources are specified, as the BRI interrupt is optional. | ||
2128 | */ | ||
2129 | if (sci_port->irqs[0] < 0) | ||
2130 | return -ENXIO; | ||
2131 | |||
2132 | if (sci_port->irqs[1] < 0) { | ||
2133 | sci_port->irqs[1] = sci_port->irqs[0]; | ||
2134 | sci_port->irqs[2] = sci_port->irqs[0]; | ||
2135 | sci_port->irqs[3] = sci_port->irqs[0]; | ||
2136 | } | ||
2137 | |||
2138 | if (p->regtype == SCIx_PROBE_REGTYPE) { | ||
2139 | ret = sci_probe_regmap(p); | ||
2140 | if (unlikely(ret)) | ||
2141 | return ret; | ||
2142 | } | ||
2143 | |||
2167 | switch (p->type) { | 2144 | switch (p->type) { |
2168 | case PORT_SCIFB: | 2145 | case PORT_SCIFB: |
2169 | port->fifosize = 256; | 2146 | port->fifosize = 256; |
2147 | sci_port->overrun_bit = 9; | ||
2148 | sampling_rate = 16; | ||
2170 | break; | 2149 | break; |
2171 | case PORT_HSCIF: | 2150 | case PORT_HSCIF: |
2172 | port->fifosize = 128; | 2151 | port->fifosize = 128; |
2152 | sampling_rate = 0; | ||
2153 | sci_port->overrun_bit = 0; | ||
2173 | break; | 2154 | break; |
2174 | case PORT_SCIFA: | 2155 | case PORT_SCIFA: |
2175 | port->fifosize = 64; | 2156 | port->fifosize = 64; |
2157 | sci_port->overrun_bit = 9; | ||
2158 | sampling_rate = 16; | ||
2176 | break; | 2159 | break; |
2177 | case PORT_SCIF: | 2160 | case PORT_SCIF: |
2178 | port->fifosize = 16; | 2161 | port->fifosize = 16; |
2162 | if (p->regtype == SCIx_SH7705_SCIF_REGTYPE) { | ||
2163 | sci_port->overrun_bit = 9; | ||
2164 | sampling_rate = 16; | ||
2165 | } else { | ||
2166 | sci_port->overrun_bit = 0; | ||
2167 | sampling_rate = 32; | ||
2168 | } | ||
2179 | break; | 2169 | break; |
2180 | default: | 2170 | default: |
2181 | port->fifosize = 1; | 2171 | port->fifosize = 1; |
2172 | sci_port->overrun_bit = 5; | ||
2173 | sampling_rate = 32; | ||
2182 | break; | 2174 | break; |
2183 | } | 2175 | } |
2184 | 2176 | ||
2185 | if (p->regtype == SCIx_PROBE_REGTYPE) { | 2177 | /* SCIFA on sh7723 and sh7724 need a custom sampling rate that doesn't |
2186 | ret = sci_probe_regmap(p); | 2178 | * match the SoC datasheet, this should be investigated. Let platform |
2187 | if (unlikely(ret)) | 2179 | * data override the sampling rate for now. |
2188 | return ret; | 2180 | */ |
2189 | } | 2181 | sci_port->sampling_rate = p->sampling_rate ? p->sampling_rate |
2182 | : sampling_rate; | ||
2190 | 2183 | ||
2191 | if (dev) { | 2184 | if (!early) { |
2192 | sci_port->iclk = clk_get(&dev->dev, "sci_ick"); | 2185 | sci_port->iclk = clk_get(&dev->dev, "sci_ick"); |
2193 | if (IS_ERR(sci_port->iclk)) { | 2186 | if (IS_ERR(sci_port->iclk)) { |
2194 | sci_port->iclk = clk_get(&dev->dev, "peripheral_clk"); | 2187 | sci_port->iclk = clk_get(&dev->dev, "peripheral_clk"); |
@@ -2208,8 +2201,6 @@ static int sci_init_single(struct platform_device *dev, | |||
2208 | 2201 | ||
2209 | port->dev = &dev->dev; | 2202 | port->dev = &dev->dev; |
2210 | 2203 | ||
2211 | sci_init_gpios(sci_port); | ||
2212 | |||
2213 | pm_runtime_enable(&dev->dev); | 2204 | pm_runtime_enable(&dev->dev); |
2214 | } | 2205 | } |
2215 | 2206 | ||
@@ -2220,32 +2211,22 @@ static int sci_init_single(struct platform_device *dev, | |||
2220 | /* | 2211 | /* |
2221 | * Establish some sensible defaults for the error detection. | 2212 | * Establish some sensible defaults for the error detection. |
2222 | */ | 2213 | */ |
2223 | if (!p->error_mask) | 2214 | 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; | 2215 | SCI_DEFAULT_ERROR_MASK : SCIF_DEFAULT_ERROR_MASK; |
2226 | 2216 | ||
2227 | /* | 2217 | /* |
2228 | * Establish sensible defaults for the overrun detection, unless | 2218 | * Establish sensible defaults for the overrun detection, unless |
2229 | * the part has explicitly disabled support for it. | 2219 | * the part has explicitly disabled support for it. |
2230 | */ | 2220 | */ |
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 | 2221 | ||
2239 | /* | 2222 | /* |
2240 | * Make the error mask inclusive of overrun detection, if | 2223 | * Make the error mask inclusive of overrun detection, if |
2241 | * supported. | 2224 | * supported. |
2242 | */ | 2225 | */ |
2243 | p->error_mask |= (1 << p->overrun_bit); | 2226 | sci_port->error_mask |= 1 << sci_port->overrun_bit; |
2244 | } | ||
2245 | 2227 | ||
2246 | port->mapbase = p->mapbase; | ||
2247 | port->type = p->type; | 2228 | port->type = p->type; |
2248 | port->flags = p->flags; | 2229 | port->flags = UPF_FIXED_PORT | p->flags; |
2249 | port->regshift = p->regshift; | 2230 | port->regshift = p->regshift; |
2250 | 2231 | ||
2251 | /* | 2232 | /* |
@@ -2255,7 +2236,7 @@ static int sci_init_single(struct platform_device *dev, | |||
2255 | * | 2236 | * |
2256 | * For the muxed case there's nothing more to do. | 2237 | * For the muxed case there's nothing more to do. |
2257 | */ | 2238 | */ |
2258 | port->irq = p->irqs[SCIx_RXI_IRQ]; | 2239 | port->irq = sci_port->irqs[SCIx_RXI_IRQ]; |
2259 | port->irqflags = 0; | 2240 | port->irqflags = 0; |
2260 | 2241 | ||
2261 | port->serial_in = sci_serial_in; | 2242 | port->serial_in = sci_serial_in; |
@@ -2270,8 +2251,6 @@ static int sci_init_single(struct platform_device *dev, | |||
2270 | 2251 | ||
2271 | static void sci_cleanup_single(struct sci_port *port) | 2252 | static void sci_cleanup_single(struct sci_port *port) |
2272 | { | 2253 | { |
2273 | sci_free_gpios(port); | ||
2274 | |||
2275 | clk_put(port->iclk); | 2254 | clk_put(port->iclk); |
2276 | clk_put(port->fclk); | 2255 | clk_put(port->fclk); |
2277 | 2256 | ||
@@ -2387,7 +2366,7 @@ static int sci_probe_earlyprintk(struct platform_device *pdev) | |||
2387 | 2366 | ||
2388 | early_serial_console.index = pdev->id; | 2367 | early_serial_console.index = pdev->id; |
2389 | 2368 | ||
2390 | sci_init_single(NULL, &sci_ports[pdev->id], pdev->id, cfg); | 2369 | sci_init_single(pdev, &sci_ports[pdev->id], pdev->id, cfg, true); |
2391 | 2370 | ||
2392 | serial_console_setup(&early_serial_console, early_serial_buf); | 2371 | serial_console_setup(&early_serial_console, early_serial_buf); |
2393 | 2372 | ||
@@ -2437,6 +2416,83 @@ static int sci_remove(struct platform_device *dev) | |||
2437 | return 0; | 2416 | return 0; |
2438 | } | 2417 | } |
2439 | 2418 | ||
2419 | struct sci_port_info { | ||
2420 | unsigned int type; | ||
2421 | unsigned int regtype; | ||
2422 | }; | ||
2423 | |||
2424 | static const struct of_device_id of_sci_match[] = { | ||
2425 | { | ||
2426 | .compatible = "renesas,scif", | ||
2427 | .data = (void *)&(const struct sci_port_info) { | ||
2428 | .type = PORT_SCIF, | ||
2429 | .regtype = SCIx_SH4_SCIF_REGTYPE, | ||
2430 | }, | ||
2431 | }, { | ||
2432 | .compatible = "renesas,scifa", | ||
2433 | .data = (void *)&(const struct sci_port_info) { | ||
2434 | .type = PORT_SCIFA, | ||
2435 | .regtype = SCIx_SCIFA_REGTYPE, | ||
2436 | }, | ||
2437 | }, { | ||
2438 | .compatible = "renesas,scifb", | ||
2439 | .data = (void *)&(const struct sci_port_info) { | ||
2440 | .type = PORT_SCIFB, | ||
2441 | .regtype = SCIx_SCIFB_REGTYPE, | ||
2442 | }, | ||
2443 | }, { | ||
2444 | .compatible = "renesas,hscif", | ||
2445 | .data = (void *)&(const struct sci_port_info) { | ||
2446 | .type = PORT_HSCIF, | ||
2447 | .regtype = SCIx_HSCIF_REGTYPE, | ||
2448 | }, | ||
2449 | }, { | ||
2450 | /* Terminator */ | ||
2451 | }, | ||
2452 | }; | ||
2453 | MODULE_DEVICE_TABLE(of, of_sci_match); | ||
2454 | |||
2455 | static struct plat_sci_port * | ||
2456 | sci_parse_dt(struct platform_device *pdev, unsigned int *dev_id) | ||
2457 | { | ||
2458 | struct device_node *np = pdev->dev.of_node; | ||
2459 | const struct of_device_id *match; | ||
2460 | const struct sci_port_info *info; | ||
2461 | struct plat_sci_port *p; | ||
2462 | int id; | ||
2463 | |||
2464 | if (!IS_ENABLED(CONFIG_OF) || !np) | ||
2465 | return NULL; | ||
2466 | |||
2467 | match = of_match_node(of_sci_match, pdev->dev.of_node); | ||
2468 | if (!match) | ||
2469 | return NULL; | ||
2470 | |||
2471 | info = match->data; | ||
2472 | |||
2473 | p = devm_kzalloc(&pdev->dev, sizeof(struct plat_sci_port), GFP_KERNEL); | ||
2474 | if (!p) { | ||
2475 | dev_err(&pdev->dev, "failed to allocate DT config data\n"); | ||
2476 | return NULL; | ||
2477 | } | ||
2478 | |||
2479 | /* Get the line number for the aliases node. */ | ||
2480 | id = of_alias_get_id(np, "serial"); | ||
2481 | if (id < 0) { | ||
2482 | dev_err(&pdev->dev, "failed to get alias id (%d)\n", id); | ||
2483 | return NULL; | ||
2484 | } | ||
2485 | |||
2486 | *dev_id = id; | ||
2487 | |||
2488 | p->flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; | ||
2489 | p->type = info->type; | ||
2490 | p->regtype = info->regtype; | ||
2491 | p->scscr = SCSCR_RE | SCSCR_TE; | ||
2492 | |||
2493 | return p; | ||
2494 | } | ||
2495 | |||
2440 | static int sci_probe_single(struct platform_device *dev, | 2496 | static int sci_probe_single(struct platform_device *dev, |
2441 | unsigned int index, | 2497 | unsigned int index, |
2442 | struct plat_sci_port *p, | 2498 | struct plat_sci_port *p, |
@@ -2454,7 +2510,7 @@ static int sci_probe_single(struct platform_device *dev, | |||
2454 | return -EINVAL; | 2510 | return -EINVAL; |
2455 | } | 2511 | } |
2456 | 2512 | ||
2457 | ret = sci_init_single(dev, sciport, index, p); | 2513 | ret = sci_init_single(dev, sciport, index, p, false); |
2458 | if (ret) | 2514 | if (ret) |
2459 | return ret; | 2515 | return ret; |
2460 | 2516 | ||
@@ -2469,8 +2525,9 @@ static int sci_probe_single(struct platform_device *dev, | |||
2469 | 2525 | ||
2470 | static int sci_probe(struct platform_device *dev) | 2526 | static int sci_probe(struct platform_device *dev) |
2471 | { | 2527 | { |
2472 | struct plat_sci_port *p = dev_get_platdata(&dev->dev); | 2528 | struct plat_sci_port *p; |
2473 | struct sci_port *sp = &sci_ports[dev->id]; | 2529 | struct sci_port *sp; |
2530 | unsigned int dev_id; | ||
2474 | int ret; | 2531 | int ret; |
2475 | 2532 | ||
2476 | /* | 2533 | /* |
@@ -2481,9 +2538,24 @@ static int sci_probe(struct platform_device *dev) | |||
2481 | if (is_early_platform_device(dev)) | 2538 | if (is_early_platform_device(dev)) |
2482 | return sci_probe_earlyprintk(dev); | 2539 | return sci_probe_earlyprintk(dev); |
2483 | 2540 | ||
2541 | if (dev->dev.of_node) { | ||
2542 | p = sci_parse_dt(dev, &dev_id); | ||
2543 | if (p == NULL) | ||
2544 | return -EINVAL; | ||
2545 | } else { | ||
2546 | p = dev->dev.platform_data; | ||
2547 | if (p == NULL) { | ||
2548 | dev_err(&dev->dev, "no platform data supplied\n"); | ||
2549 | return -EINVAL; | ||
2550 | } | ||
2551 | |||
2552 | dev_id = dev->id; | ||
2553 | } | ||
2554 | |||
2555 | sp = &sci_ports[dev_id]; | ||
2484 | platform_set_drvdata(dev, sp); | 2556 | platform_set_drvdata(dev, sp); |
2485 | 2557 | ||
2486 | ret = sci_probe_single(dev, dev->id, p, sp); | 2558 | ret = sci_probe_single(dev, dev_id, p, sp); |
2487 | if (ret) | 2559 | if (ret) |
2488 | return ret; | 2560 | return ret; |
2489 | 2561 | ||
@@ -2535,6 +2607,7 @@ static struct platform_driver sci_driver = { | |||
2535 | .name = "sh-sci", | 2607 | .name = "sh-sci", |
2536 | .owner = THIS_MODULE, | 2608 | .owner = THIS_MODULE, |
2537 | .pm = &sci_dev_pm_ops, | 2609 | .pm = &sci_dev_pm_ops, |
2610 | .of_match_table = of_match_ptr(of_sci_match), | ||
2538 | }, | 2611 | }, |
2539 | }; | 2612 | }; |
2540 | 2613 | ||
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) || \ |