From patchwork Mon Jun 20 11:02:28 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Abraham X-Patchwork-Id: 896912 Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p5KAswES025563 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 20 Jun 2011 10:55:19 GMT Received: from canuck.infradead.org ([2001:4978:20e::1]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1QYc7e-00005p-TP; Mon, 20 Jun 2011 10:54:27 +0000 Received: from localhost ([127.0.0.1] helo=canuck.infradead.org) by canuck.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1QYc7e-00072H-In; Mon, 20 Jun 2011 10:54:26 +0000 Received: from mailout4.samsung.com ([203.254.224.34]) by canuck.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1QYc6V-0006nw-1e for linux-arm-kernel@lists.infradead.org; Mon, 20 Jun 2011 10:53:17 +0000 Received: from epcpsbgm1.samsung.com (mailout4.samsung.com [203.254.224.34]) by mailout4.samsung.com (Oracle Communications Messaging Exchange Server 7u4-19.01 64bit (built Sep 7 2010)) with ESMTP id <0LN3002UK4WH3MC0@mailout4.samsung.com> for linux-arm-kernel@lists.infradead.org; Mon, 20 Jun 2011 19:53:09 +0900 (KST) X-AuditID: cbfee61a-b7ce2ae000001a8f-e9-4dff26940aa1 Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm1.samsung.com (MMPCPMTA) with SMTP id E9.9E.06799.4962FFD4; Mon, 20 Jun 2011 19:53:08 +0900 (KST) Received: from localhost.localdomain ([107.108.73.37]) by mmp2.samsung.com (iPlanet Messaging Server 5.2 Patch 2 (built Jul 14 2004)) with ESMTPA id <0LN300JSM4W4PB@mmp2.samsung.com> for linux-arm-kernel@lists.infradead.org; Mon, 20 Jun 2011 19:53:09 +0900 (KST) Date: Mon, 20 Jun 2011 16:32:28 +0530 From: Thomas Abraham Subject: [PATCH 2/6] serial: samsung: Add device tree support for s5pv210 uart driver In-reply-to: <1308567752-13451-1-git-send-email-thomas.abraham@linaro.org> To: devicetree-discuss@lists.ozlabs.org Message-id: <1308567752-13451-3-git-send-email-thomas.abraham@linaro.org> X-Mailer: git-send-email 1.6.6.rc2 References: <1308567752-13451-1-git-send-email-thomas.abraham@linaro.org> X-Brightmail-Tracker: AAAAAA== X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.7.6 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20110620_065315_495303_C89A11A2 X-CRM114-Status: GOOD ( 30.02 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.3.1 on canuck.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [203.254.224.34 listed in list.dnswl.org] Cc: kgene.kim@samsung.com, linaro-dev@lists.linaro.org, patches@linaro.org, linux-samsung-soc@vger.kernel.org, ben-linux@fluff.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Mon, 20 Jun 2011 10:55:19 +0000 (UTC) For device tree based probe, the dependecy on pdev->id to attach a corresponding default port info to the driver's private data is removed. The fifosize parameter is obtained from the device tree node and the next available instance of port info is updated with the fifosize value and attached to the driver's private data. The samsung uart core driver is also modified to parse the device tree node and pick up the platform data from the node. Signed-off-by: Thomas Abraham --- .../bindings/tty/serial/samsung_uart.txt | 50 +++++++++++ drivers/tty/serial/s5pv210.c | 27 ++++++- drivers/tty/serial/samsung.c | 90 ++++++++++++++++++++ 3 files changed, 166 insertions(+), 1 deletions(-) create mode 100644 Documentation/devicetree/bindings/tty/serial/samsung_uart.txt diff --git a/Documentation/devicetree/bindings/tty/serial/samsung_uart.txt b/Documentation/devicetree/bindings/tty/serial/samsung_uart.txt new file mode 100644 index 0000000..4c0783d --- /dev/null +++ b/Documentation/devicetree/bindings/tty/serial/samsung_uart.txt @@ -0,0 +1,50 @@ +* Samsung's UART Controller + +The Samsung's UART controller is used for serial communications on all of +Samsung's s3c24xx, s3c64xx and s5p series application processors. + +Required properties: +- compatible : should be specific to the application processor + - "samsung,s5pv210-uart" , for s5pc110, s5pv210 and Exynos4 family. + - "samsung,s3c6400-uart", for s3c64xx, s5p64xx and s5pc100. + - "samsung,s3c2410-uart", for s3c2410. + - "samsung,s3c2412-uart", for s3c2412. + - "samsung,s3c2440-uart", for s3c244x. + +- reg : base physical address of the controller and length of memory mapped + region. + +- interrupts : Three interrupt numbers should be specified in the following + order - TX interrupt, RX interrupt, Error Interrupt. + +- hwport : Instance number of the UART controller in the processor. + (ToDo: Remove this from the driver). + +- flags : Not used, but set value as 0. (ToDo: Remove this flag from driver). + +- uart_flags : Additional serial core flags to passed to the serial core + when the driver is registred. For example: UPF_CONS_FLOW. + +- has_fracval : Set to 1, if the controller supports fractional part of + for the baud divisor, otherwise, set to 0. + +- ucon_default : Default board specific setting of UCON register. + +- ulcon_default : Default board specific setting of ULCON register. + +- ufcon_default : Default board specific setting of UFCON register. + +- uart_clksrc : One or more child nodes representing the clock sources that + could be used to derive the buad rate. Each of these child nodes + has four required properties. + + - name : Name of the parent clock. + - divisor : divisor from the clock to the uart controller. + - min_baud : Minimum baud rate for which this clock can be used. + Set to zero, if there is no limitation. + - max_buad : Maximum baud rate for which this clock can be used. + Set to zero, if there is no limitation. + +Optional properties: +- fifosize: Size of the tx/rx fifo used in the controller. If not specified, + the default value of the fifosize is 16. diff --git a/drivers/tty/serial/s5pv210.c b/drivers/tty/serial/s5pv210.c index 3b2021a..9aacbda 100644 --- a/drivers/tty/serial/s5pv210.c +++ b/drivers/tty/serial/s5pv210.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -131,15 +132,39 @@ static struct s3c24xx_uart_info *s5p_uart_inf[] = { /* device management */ static int s5p_serial_probe(struct platform_device *pdev) { - return s3c24xx_serial_probe(pdev, s5p_uart_inf[pdev->id]); + const void *prop; + unsigned int port = pdev->id; + unsigned int fifosize = 16; + static unsigned int probe_index; + + if (pdev->dev.of_node) { + prop = of_get_property(pdev->dev.of_node, "fifosize", NULL); + if (prop) + fifosize = be32_to_cpu(*(u32 *)prop); + s5p_uart_inf[probe_index]->fifosize = fifosize; + port = probe_index++; + } + + return s3c24xx_serial_probe(pdev, s5p_uart_inf[port]); } +#ifdef CONFIG_OF +static const struct of_device_id s5pv210_uart_match[] = { + { .compatible = "samsung,s5pv210-uart" }, + {}, +}; +MODULE_DEVICE_TABLE(of, s5pv210_uart_match); +#else +#define s5pv210_uart_match NULL +#endif + static struct platform_driver s5p_serial_driver = { .probe = s5p_serial_probe, .remove = __devexit_p(s3c24xx_serial_remove), .driver = { .name = "s5pv210-uart", .owner = THIS_MODULE, + .of_match_table = s5pv210_uart_match, }, }; diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 77d900f..1e58a7b 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -43,6 +43,7 @@ #include #include #include +#include #include @@ -1047,6 +1048,91 @@ static inline void s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *p } #endif +/* + * s3c24xx_serial_parse_dt + * + * Parse the platform data from the device tree and keep a copy of it. + */ + +static int s3c24xx_serial_parse_dt(struct device_node *np, + struct s3c2410_uartcfg *cfg) +{ + struct s3c24xx_uart_clksrc *clksrc = NULL; + struct device_node *child = NULL; + unsigned int len; + const void *prop; + + if (!np) + return -EINVAL; + + prop = of_get_property(np, "hwport", &len); + if (prop && len) + cfg->hwport = be32_to_cpu(*(u32 *)prop); + + prop = of_get_property(np, "flags", &len); + if (prop && len) + cfg->flags = be32_to_cpu(*(u32 *)prop); + + prop = of_get_property(np, "uart_flags", &len); + if (prop && len) + cfg->uart_flags = be32_to_cpu(*(u32 *)prop); + + prop = of_get_property(np, "has_fracval", &len); + if (prop && len) + cfg->has_fracval = be32_to_cpu(*(u32 *)prop); + + prop = of_get_property(np, "ucon_default", &len); + if (prop && len) + cfg->ucon = be32_to_cpu(*(u32 *)prop); + + prop = of_get_property(np, "ulcon_default", &len); + if (prop && len) + cfg->ulcon = be32_to_cpu(*(u32 *)prop); + + prop = of_get_property(np, "ufcon_default", &len); + if (prop && len) + cfg->ufcon = be32_to_cpu(*(u32 *)prop); + + /* Count the number of clock source options available */ + len = 0; + + while ((child = of_get_next_child(np, child))) + len++; + + if (len) { + clksrc = kzalloc(sizeof(struct s3c24xx_uart_clksrc) * len, + GFP_KERNEL); + if (!clksrc) + return -ENOMEM; + } + + cfg->clocks = clksrc; + cfg->clocks_size = len; + + /* Read the information about all clock sources */ + for_each_child_of_node(np, child) { + prop = of_get_property(child, "clk_name", &len); + if (prop && len) + clksrc->name = (const char *)prop; + + prop = of_get_property(child, "divisor", &len); + if (prop && len) + clksrc->divisor = be32_to_cpu(*(u32 *)prop); + + prop = of_get_property(child, "min_baud", &len); + if (prop && len) + clksrc->min_baud = be32_to_cpu(*(u32 *)prop); + + prop = of_get_property(child, "max_baud", &len); + if (prop && len) + clksrc->max_baud = be32_to_cpu(*(u32 *)prop); + + clksrc++; + } + + return 0; +} + /* s3c24xx_serial_init_port * * initialise a single serial port from the platform device given @@ -1077,6 +1163,10 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, return -ENOMEM; memcpy(info->cfg.clocks, cfg->clocks, sizeof(struct s3c24xx_uart_clksrc) * cfg->clocks_size); + } else { + ret = s3c24xx_serial_parse_dt(platdev->dev.of_node, &info->cfg); + if (ret) + return ret; } cfg = &info->cfg;