aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-23 21:49:36 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-23 21:49:36 -0500
commit0ba3307a8ec35252f7b1e222e32889a6f3d9ceb3 (patch)
tree26126ed7a2080a706f0488c215549fc9f5f76a59 /drivers/tty
parent903a9f77d1d00c8621bc37afd959ac45a4b3ebec (diff)
parentcd2f43a1f7400a74a084094502f70df2e169c6e8 (diff)
Merge tag 'drivers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM driver updates from Olof Johansson: "Updates of SoC-near drivers and other driver updates that makes more sense to take through our tree. The largest part of this is a conversion of device registration for some renesas shmobile/sh devices over to use resources. This has required coordination with the corresponding arch/sh changes, and we've agreed to merge the arch/sh changes through our tree. Added in this branch is support for Trusted Foundations secure firmware, which is what is used on many of the commercial Nvidia Tegra products that are in the market, including the Nvidia Shield. The code is local to arch/arm at this time since it's uncertain whether it will be shared with arm64 longer-term, if needed we will refactor later. A couple of new RTC drivers used on ARM boards, merged through our tree on request by the RTC maintainer. ... plus a bunch of smaller updates across the board, gpio conversions for davinci, etc" * tag 'drivers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (45 commits) watchdog: davinci: rename platform driver to davinci-wdt tty: serial: Limit msm_serial_hs driver to platforms that use it mmc: msm_sdcc: Limit driver to platforms that use it usb: phy: msm: Move mach dependent code to platform data clk: versatile: fixup IM-PD1 clock implementation clk: versatile: pass a name to ICST clock provider ARM: integrator: pass parent IRQ to the SIC irqchip: versatile FPGA: support cascaded interrupts from DT gpio: davinci: don't create irq_domain in case of unbanked irqs gpio: davinci: use chained_irq_enter/chained_irq_exit API gpio: davinci: add OF support gpio: davinci: remove unused variable intc_irq_num gpio: davinci: convert to use irqdomain support. gpio: introduce GPIO_DAVINCI kconfig option gpio: davinci: get rid of DAVINCI_N_GPIO gpio: davinci: use {readl|writel}_relaxed() instead of __raw_* 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 ...
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/Kconfig2
-rw-r--r--drivers/tty/serial/sh-sci.c187
2 files changed, 138 insertions, 51 deletions
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 441ada489874..a3815eaed421 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1034,7 +1034,7 @@ config SERIAL_MSM_CONSOLE
1034 1034
1035config SERIAL_MSM_HS 1035config SERIAL_MSM_HS
1036 tristate "MSM UART High Speed: Serial Driver" 1036 tristate "MSM UART High Speed: Serial Driver"
1037 depends on ARCH_MSM 1037 depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
1038 select SERIAL_CORE 1038 select SERIAL_CORE
1039 help 1039 help
1040 If you have a machine based on MSM family of SoCs, you 1040 If you have a machine based on MSM family of SoCs, you
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