aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/sh-sci.c
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2013-12-06 04:59:16 -0500
committerSimon Horman <horms+renesas@verge.net.au>2013-12-23 21:17:44 -0500
commit1fcc91a607de0bf72d3a6073dfe459f7e9145ac5 (patch)
tree2ca355cad0c1b0565437ccc782e8e56f93a86e24 /drivers/tty/serial/sh-sci.c
parentbc14e00672b563f41a1ac1d421b5c78c94868983 (diff)
serial: sh-sci: Support resources passed through platform resources
Memory and IRQ resources are currently passed to the driver through platform data. Support passing them through the standard platform resources mechanism instead. This deprecates platform data resources. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
Diffstat (limited to 'drivers/tty/serial/sh-sci.c')
-rw-r--r--drivers/tty/serial/sh-sci.c65
1 files changed, 49 insertions, 16 deletions
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index b3d0e00ecedf..e9c6e2339884 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -74,6 +74,7 @@ struct sci_port {
74 /* Function clock */ 74 /* Function clock */
75 struct clk *fclk; 75 struct clk *fclk;
76 76
77 int irqs[SCIx_NR_IRQS];
77 char *irqstr[SCIx_NR_IRQS]; 78 char *irqstr[SCIx_NR_IRQS];
78 char *gpiostr[SCIx_NR_FNS]; 79 char *gpiostr[SCIx_NR_FNS];
79 80
@@ -1079,19 +1080,19 @@ static int sci_request_irq(struct sci_port *port)
1079 1080
1080 for (i = j = 0; i < SCIx_NR_IRQS; i++, j++) { 1081 for (i = j = 0; i < SCIx_NR_IRQS; i++, j++) {
1081 struct sci_irq_desc *desc; 1082 struct sci_irq_desc *desc;
1082 unsigned int irq; 1083 int irq;
1083 1084
1084 if (SCIx_IRQ_IS_MUXED(port)) { 1085 if (SCIx_IRQ_IS_MUXED(port)) {
1085 i = SCIx_MUX_IRQ; 1086 i = SCIx_MUX_IRQ;
1086 irq = up->irq; 1087 irq = up->irq;
1087 } else { 1088 } else {
1088 irq = port->cfg->irqs[i]; 1089 irq = port->irqs[i];
1089 1090
1090 /* 1091 /*
1091 * Certain port types won't support all of the 1092 * Certain port types won't support all of the
1092 * available interrupt sources. 1093 * available interrupt sources.
1093 */ 1094 */
1094 if (unlikely(!irq)) 1095 if (unlikely(irq < 0))
1095 continue; 1096 continue;
1096 } 1097 }
1097 1098
@@ -1116,7 +1117,7 @@ static int sci_request_irq(struct sci_port *port)
1116 1117
1117out_noirq: 1118out_noirq:
1118 while (--i >= 0) 1119 while (--i >= 0)
1119 free_irq(port->cfg->irqs[i], port); 1120 free_irq(port->irqs[i], port);
1120 1121
1121out_nomem: 1122out_nomem:
1122 while (--j >= 0) 1123 while (--j >= 0)
@@ -1134,16 +1135,16 @@ static void sci_free_irq(struct sci_port *port)
1134 * IRQ first. 1135 * IRQ first.
1135 */ 1136 */
1136 for (i = 0; i < SCIx_NR_IRQS; i++) { 1137 for (i = 0; i < SCIx_NR_IRQS; i++) {
1137 unsigned int irq = port->cfg->irqs[i]; 1138 int irq = port->irqs[i];
1138 1139
1139 /* 1140 /*
1140 * Certain port types won't support all of the available 1141 * Certain port types won't support all of the available
1141 * interrupt sources. 1142 * interrupt sources.
1142 */ 1143 */
1143 if (unlikely(!irq)) 1144 if (unlikely(irq < 0))
1144 continue; 1145 continue;
1145 1146
1146 free_irq(port->cfg->irqs[i], port); 1147 free_irq(port->irqs[i], port);
1147 kfree(port->irqstr[i]); 1148 kfree(port->irqstr[i]);
1148 1149
1149 if (SCIx_IRQ_IS_MUXED(port)) { 1150 if (SCIx_IRQ_IS_MUXED(port)) {
@@ -1659,7 +1660,7 @@ static void rx_timer_fn(unsigned long arg)
1659 1660
1660 if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { 1661 if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
1661 scr &= ~0x4000; 1662 scr &= ~0x4000;
1662 enable_irq(s->cfg->irqs[1]); 1663 enable_irq(s->irqs[SCIx_RXI_IRQ]);
1663 } 1664 }
1664 serial_port_out(port, SCSCR, scr | SCSCR_RIE); 1665 serial_port_out(port, SCSCR, scr | SCSCR_RIE);
1665 dev_dbg(port->dev, "DMA Rx timed out\n"); 1666 dev_dbg(port->dev, "DMA Rx timed out\n");
@@ -2150,11 +2151,12 @@ static struct uart_ops sci_uart_ops = {
2150}; 2151};
2151 2152
2152static int sci_init_single(struct platform_device *dev, 2153static int sci_init_single(struct platform_device *dev,
2153 struct sci_port *sci_port, 2154 struct sci_port *sci_port, unsigned int index,
2154 unsigned int index, 2155 struct plat_sci_port *p, bool early)
2155 struct plat_sci_port *p)
2156{ 2156{
2157 struct uart_port *port = &sci_port->port; 2157 struct uart_port *port = &sci_port->port;
2158 const struct resource *res;
2159 unsigned int i;
2158 int ret; 2160 int ret;
2159 2161
2160 sci_port->cfg = p; 2162 sci_port->cfg = p;
@@ -2163,6 +2165,38 @@ static int sci_init_single(struct platform_device *dev,
2163 port->iotype = UPIO_MEM; 2165 port->iotype = UPIO_MEM;
2164 port->line = index; 2166 port->line = index;
2165 2167
2168 if (dev->num_resources) {
2169 /* Device has resources, use them. */
2170 res = platform_get_resource(dev, IORESOURCE_MEM, 0);
2171 if (res == NULL)
2172 return -ENOMEM;
2173
2174 port->mapbase = res->start;
2175
2176 for (i = 0; i < ARRAY_SIZE(sci_port->irqs); ++i)
2177 sci_port->irqs[i] = platform_get_irq(dev, i);
2178
2179 /* The SCI generates several interrupts. They can be muxed
2180 * together or connected to different interrupt lines. In the
2181 * muxed case only one interrupt resource is specified. In the
2182 * non-muxed case three or four interrupt resources are
2183 * specified, as the BRI interrupt is optional.
2184 */
2185 if (sci_port->irqs[0] < 0)
2186 return -ENXIO;
2187
2188 if (sci_port->irqs[1] < 0) {
2189 sci_port->irqs[1] = sci_port->irqs[0];
2190 sci_port->irqs[2] = sci_port->irqs[0];
2191 sci_port->irqs[3] = sci_port->irqs[0];
2192 }
2193 } else {
2194 /* No resources, use old-style platform data. */
2195 port->mapbase = p->mapbase;
2196 for (i = 0; i < ARRAY_SIZE(sci_port->irqs); ++i)
2197 sci_port->irqs[i] = p->irqs[i] ? p->irqs[i] : -ENXIO;
2198 }
2199
2166 switch (p->type) { 2200 switch (p->type) {
2167 case PORT_SCIFB: 2201 case PORT_SCIFB:
2168 port->fifosize = 256; 2202 port->fifosize = 256;
@@ -2187,7 +2221,7 @@ static int sci_init_single(struct platform_device *dev,
2187 return ret; 2221 return ret;
2188 } 2222 }
2189 2223
2190 if (dev) { 2224 if (!early) {
2191 sci_port->iclk = clk_get(&dev->dev, "sci_ick"); 2225 sci_port->iclk = clk_get(&dev->dev, "sci_ick");
2192 if (IS_ERR(sci_port->iclk)) { 2226 if (IS_ERR(sci_port->iclk)) {
2193 sci_port->iclk = clk_get(&dev->dev, "peripheral_clk"); 2227 sci_port->iclk = clk_get(&dev->dev, "peripheral_clk");
@@ -2242,7 +2276,6 @@ static int sci_init_single(struct platform_device *dev,
2242 p->error_mask |= (1 << p->overrun_bit); 2276 p->error_mask |= (1 << p->overrun_bit);
2243 } 2277 }
2244 2278
2245 port->mapbase = p->mapbase;
2246 port->type = p->type; 2279 port->type = p->type;
2247 port->flags = UPF_FIXED_PORT | p->flags; 2280 port->flags = UPF_FIXED_PORT | p->flags;
2248 port->regshift = p->regshift; 2281 port->regshift = p->regshift;
@@ -2254,7 +2287,7 @@ static int sci_init_single(struct platform_device *dev,
2254 * 2287 *
2255 * For the muxed case there's nothing more to do. 2288 * For the muxed case there's nothing more to do.
2256 */ 2289 */
2257 port->irq = p->irqs[SCIx_RXI_IRQ]; 2290 port->irq = sci_port->irqs[SCIx_RXI_IRQ];
2258 port->irqflags = 0; 2291 port->irqflags = 0;
2259 2292
2260 port->serial_in = sci_serial_in; 2293 port->serial_in = sci_serial_in;
@@ -2386,7 +2419,7 @@ static int sci_probe_earlyprintk(struct platform_device *pdev)
2386 2419
2387 early_serial_console.index = pdev->id; 2420 early_serial_console.index = pdev->id;
2388 2421
2389 sci_init_single(NULL, &sci_ports[pdev->id], pdev->id, cfg); 2422 sci_init_single(pdev, &sci_ports[pdev->id], pdev->id, cfg, true);
2390 2423
2391 serial_console_setup(&early_serial_console, early_serial_buf); 2424 serial_console_setup(&early_serial_console, early_serial_buf);
2392 2425
@@ -2453,7 +2486,7 @@ static int sci_probe_single(struct platform_device *dev,
2453 return -EINVAL; 2486 return -EINVAL;
2454 } 2487 }
2455 2488
2456 ret = sci_init_single(dev, sciport, index, p); 2489 ret = sci_init_single(dev, sciport, index, p, false);
2457 if (ret) 2490 if (ret)
2458 return ret; 2491 return ret;
2459 2492