aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2014-01-02 13:57:05 -0500
committerOlof Johansson <olof@lixom.net>2014-01-02 13:57:05 -0500
commitc7fed591a6d5ce080482e4237bd02c99857c0d4f (patch)
treef697a76b366a228e21c222061bcef7000b973949 /drivers/tty
parentefcf3d38f128cfbfc7a62c3a5dc3fb42991c12e5 (diff)
parent20bdcab8268cb05702e12ae9013be96ecc7ec3a6 (diff)
Merge tag 'renesas-sh-sci3-for-v3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas into next/drivers
From Simon Horman: Third Round of Renesas SH SCI Updates for v3.14 * Add Device Tree Support * Remove platform data mapbase and irqs fields * Remove platform data scbrr_algo_id field * tag 'renesas-sh-sci3-for-v3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas: serial: sh-sci: Add OF support serial: sh-sci: Add device tree bindings documentation serial: sh-sci: Remove platform data mapbase and irqs fields serial: sh-sci: Remove platform data scbrr_algo_id field Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/sh-sci.c187
1 files changed, 137 insertions, 50 deletions
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index e4bf0e435af6..be33d2b0613b 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -39,6 +39,7 @@
39#include <linux/module.h> 39#include <linux/module.h>
40#include <linux/mm.h> 40#include <linux/mm.h>
41#include <linux/notifier.h> 41#include <linux/notifier.h>
42#include <linux/of.h>
42#include <linux/platform_device.h> 43#include <linux/platform_device.h>
43#include <linux/pm_runtime.h> 44#include <linux/pm_runtime.h>
44#include <linux/scatterlist.h> 45#include <linux/scatterlist.h>
@@ -58,6 +59,23 @@
58 59
59#include "sh-sci.h" 60#include "sh-sci.h"
60 61
62/* Offsets into the sci_port->irqs array */
63enum {
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
61struct sci_port { 79struct sci_port {
62 struct uart_port port; 80 struct uart_port port;
63 81
@@ -1757,17 +1775,6 @@ static unsigned int sci_scbrr_calc(struct sci_port *s, unsigned int bps,
1757 if (s->sampling_rate) 1775 if (s->sampling_rate)
1758 return DIV_ROUND_CLOSEST(freq, s->sampling_rate * bps) - 1; 1776 return DIV_ROUND_CLOSEST(freq, s->sampling_rate * bps) - 1;
1759 1777
1760 switch (s->cfg->scbrr_algo_id) {
1761 case SCBRR_ALGO_1:
1762 return freq / (16 * bps);
1763 case SCBRR_ALGO_2:
1764 return DIV_ROUND_CLOSEST(freq, 32 * bps) - 1;
1765 case SCBRR_ALGO_3:
1766 return freq / (8 * bps);
1767 case SCBRR_ALGO_4:
1768 return DIV_ROUND_CLOSEST(freq, 16 * bps) - 1;
1769 }
1770
1771 /* Warn, but use a safe default */ 1778 /* Warn, but use a safe default */
1772 WARN_ON(1); 1779 WARN_ON(1);
1773 1780
@@ -2105,36 +2112,27 @@ static int sci_init_single(struct platform_device *dev,
2105 port->iotype = UPIO_MEM; 2112 port->iotype = UPIO_MEM;
2106 port->line = index; 2113 port->line = index;
2107 2114
2108 if (dev->num_resources) { 2115 res = platform_get_resource(dev, IORESOURCE_MEM, 0);
2109 /* Device has resources, use them. */ 2116 if (res == NULL)
2110 res = platform_get_resource(dev, IORESOURCE_MEM, 0); 2117 return -ENOMEM;
2111 if (res == NULL)
2112 return -ENOMEM;
2113 2118
2114 port->mapbase = res->start; 2119 port->mapbase = res->start;
2115 2120
2116 for (i = 0; i < ARRAY_SIZE(sci_port->irqs); ++i) 2121 for (i = 0; i < ARRAY_SIZE(sci_port->irqs); ++i)
2117 sci_port->irqs[i] = platform_get_irq(dev, i); 2122 sci_port->irqs[i] = platform_get_irq(dev, i);
2118 2123
2119 /* The SCI generates several interrupts. They can be muxed 2124 /* The SCI generates several interrupts. They can be muxed together or
2120 * together or connected to different interrupt lines. In the 2125 * connected to different interrupt lines. In the muxed case only one
2121 * muxed case only one interrupt resource is specified. In the 2126 * interrupt resource is specified. In the non-muxed case three or four
2122 * non-muxed case three or four interrupt resources are 2127 * interrupt resources are specified, as the BRI interrupt is optional.
2123 * specified, as the BRI interrupt is optional. 2128 */
2124 */ 2129 if (sci_port->irqs[0] < 0)
2125 if (sci_port->irqs[0] < 0) 2130 return -ENXIO;
2126 return -ENXIO;
2127 2131
2128 if (sci_port->irqs[1] < 0) { 2132 if (sci_port->irqs[1] < 0) {
2129 sci_port->irqs[1] = sci_port->irqs[0]; 2133 sci_port->irqs[1] = sci_port->irqs[0];
2130 sci_port->irqs[2] = sci_port->irqs[0]; 2134 sci_port->irqs[2] = sci_port->irqs[0];
2131 sci_port->irqs[3] = sci_port->irqs[0]; 2135 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 } 2136 }
2139 2137
2140 if (p->regtype == SCIx_PROBE_REGTYPE) { 2138 if (p->regtype == SCIx_PROBE_REGTYPE) {
@@ -2176,17 +2174,12 @@ static int sci_init_single(struct platform_device *dev,
2176 break; 2174 break;
2177 } 2175 }
2178 2176
2179 /* Set the sampling rate if the baud rate calculation algorithm isn't 2177 /* SCIFA on sh7723 and sh7724 need a custom sampling rate that doesn't
2180 * specified. 2178 * match the SoC datasheet, this should be investigated. Let platform
2179 * data override the sampling rate for now.
2181 */ 2180 */
2182 if (p->scbrr_algo_id == SCBRR_ALGO_NONE) { 2181 sci_port->sampling_rate = p->sampling_rate ? p->sampling_rate
2183 /* SCIFA on sh7723 and sh7724 need a custom sampling rate that 2182 : sampling_rate;
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 }
2190 2183
2191 if (!early) { 2184 if (!early) {
2192 sci_port->iclk = clk_get(&dev->dev, "sci_ick"); 2185 sci_port->iclk = clk_get(&dev->dev, "sci_ick");
@@ -2423,6 +2416,83 @@ static int sci_remove(struct platform_device *dev)
2423 return 0; 2416 return 0;
2424} 2417}
2425 2418
2419struct sci_port_info {
2420 unsigned int type;
2421 unsigned int regtype;
2422};
2423
2424static 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};
2453MODULE_DEVICE_TABLE(of, of_sci_match);
2454
2455static struct plat_sci_port *
2456sci_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
2426static int sci_probe_single(struct platform_device *dev, 2496static int sci_probe_single(struct platform_device *dev,
2427 unsigned int index, 2497 unsigned int index,
2428 struct plat_sci_port *p, 2498 struct plat_sci_port *p,
@@ -2455,8 +2525,9 @@ static int sci_probe_single(struct platform_device *dev,
2455 2525
2456static int sci_probe(struct platform_device *dev) 2526static int sci_probe(struct platform_device *dev)
2457{ 2527{
2458 struct plat_sci_port *p = dev_get_platdata(&dev->dev); 2528 struct plat_sci_port *p;
2459 struct sci_port *sp = &sci_ports[dev->id]; 2529 struct sci_port *sp;
2530 unsigned int dev_id;
2460 int ret; 2531 int ret;
2461 2532
2462 /* 2533 /*
@@ -2467,9 +2538,24 @@ static int sci_probe(struct platform_device *dev)
2467 if (is_early_platform_device(dev)) 2538 if (is_early_platform_device(dev))
2468 return sci_probe_earlyprintk(dev); 2539 return sci_probe_earlyprintk(dev);
2469 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];
2470 platform_set_drvdata(dev, sp); 2556 platform_set_drvdata(dev, sp);
2471 2557
2472 ret = sci_probe_single(dev, dev->id, p, sp); 2558 ret = sci_probe_single(dev, dev_id, p, sp);
2473 if (ret) 2559 if (ret)
2474 return ret; 2560 return ret;
2475 2561
@@ -2521,6 +2607,7 @@ static struct platform_driver sci_driver = {
2521 .name = "sh-sci", 2607 .name = "sh-sci",
2522 .owner = THIS_MODULE, 2608 .owner = THIS_MODULE,
2523 .pm = &sci_dev_pm_ops, 2609 .pm = &sci_dev_pm_ops,
2610 .of_match_table = of_match_ptr(of_sci_match),
2524 }, 2611 },
2525}; 2612};
2526 2613