From patchwork Wed Jun 6 12:41:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Simek X-Patchwork-Id: 10450161 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id DE7AD60234 for ; Wed, 6 Jun 2018 12:50:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B161029E13 for ; Wed, 6 Jun 2018 12:50:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0C22C29E02; Wed, 6 Jun 2018 12:50:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6325529F35 for ; Wed, 6 Jun 2018 12:44:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=4fSVH34lDtDeBbAbYoXIZG5gDlO9qaT8uW+EIB1TsB4=; b=tCOEtNzAPixrFHqRcEFT5602j/ dHI0TAeoF/3X6aWGwqh2uqUYIJHlnNMc5/LXP+rwma0xiJ6UNtTduufJoGzSSB4eF9c7lJTAfIc+R xkL/bFG7LotCcyJ0OrbO2I+6Nn0v3JhvHyNPJ0To3Q/bfwroEPSvI/mR2kXiZLBxf5DJ8kba33njS cApwu3AdPIP4CPJodvUhe6PqEax5X9oCfh78f8AfpwAFvATAACQHaACQRVzPvDbeWa+N5J1KpvqI5 TdlA6ml3YRbJ8ypCbNWIHRK+bzhVArIHFB+FGOTAuHNc/+jD1U+oI4RCuDBExm8D6EdOfyog0e5e4 g4cFKRmw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fQXnP-0002Ej-La; Wed, 06 Jun 2018 12:44:11 +0000 Received: from mail-wr0-x241.google.com ([2a00:1450:400c:c0c::241]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fQXlD-0000jl-VK for linux-arm-kernel@lists.infradead.org; Wed, 06 Jun 2018 12:42:00 +0000 Received: by mail-wr0-x241.google.com with SMTP id o12-v6so6123264wrm.12 for ; Wed, 06 Jun 2018 05:41:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=monstr-eu.20150623.gappssmtp.com; s=20150623; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=eI1+LirapJdF2ReYEKSMyIvACGEbCWa/6STpGG6jNeI=; b=MhDWO1ZHYajjE77YqGvKQyEWJJpo/4HnEtyKIPQkXDwe7H36VpWtJjP/+G3/9JTnue 4RPSdTYBbLNAVFTBDEBpQCxHB2EBGXxMhqe06kTwc9dIH/s/s8ImicX81iziVeHf2vqy 530AgcqrzCYLSDE5wXVpX6zWhhR0cDRluranj7ZkOGH198lz0NEiI+PITsx1LxSIDK8G krA9+FWvlvtnk6VsfFnI1NA8J5ylk4yMhwbfoMcVElobnc00KbezjLJ+HHi+8bp0aCo/ q7I+s5Rcxyq3937ZV9PiGmHIGo4vsuMH3RjmrEVrjRa1o5qBYTT5gq+pQ4/fUydiwBbr 45Sg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:in-reply-to:references; bh=eI1+LirapJdF2ReYEKSMyIvACGEbCWa/6STpGG6jNeI=; b=NTrA08PT08H20eaIb28pD8mLWDS/56oxbszrakRIKNLlynjhwZDfzWzWDEn9Qukunv ETu2/0nQpu2eBwGpR03bHAlTCYL+MXC0zmUInvniDicSmn1LAl8UdTC5/8hh8Yec1SUD HLORJz43srGvzzkbEKPtRimq5HxkfjtO5VN+wCMFFC0Uc0r7yilmSIjGPwNc2cMCF801 OGrHybgQQcjTN8OGr2Foywrx8GwV6GDB3T8tuOkKUKoIx28U+W9CaXMcN+jXq9ZblDwo Ccnz2Tu84V0IOlU8yabkHuoDoIga+4Bn/DFtEsoc+uSKOhRwdMewJ4msfoVxNFr8uRM2 FdcA== X-Gm-Message-State: APt69E3ZSImerRQT4rHL6+a64rLo15PbdfufvPCBv6/kZ4/qDlPBpwL7 rm7B4k7nIuht60NpyKVcahJY2Q== X-Google-Smtp-Source: ADUXVKKpynFPHVgJE6vr1FeEcGsPUyMRllm31fkESD78bmohbqtpypAYQAxec+qVXTKf1ejkyyORhw== X-Received: by 2002:adf:b839:: with SMTP id h54-v6mr2353703wrf.36.1528288912030; Wed, 06 Jun 2018 05:41:52 -0700 (PDT) Received: from localhost (nat-35.starnet.cz. [178.255.168.35]) by smtp.gmail.com with ESMTPSA id c53-v6sm58559951wrg.12.2018.06.06.05.41.51 (version=TLS1_2 cipher=AES128-SHA bits=128/128); Wed, 06 Jun 2018 05:41:51 -0700 (PDT) From: Michal Simek To: linux-kernel@vger.kernel.org, monstr@monstr.eu, gnomes@lxorguk.ukuu.org.uk, Alexander Graf , shubhraj@xilinx.com, robh@kernel.org Subject: [RFC PATCH v2 6/6] serial: uartps: Remove CDNS_UART_NR_PORTS macro Date: Wed, 6 Jun 2018 14:41:39 +0200 Message-Id: <8e2c1a052ab678274c49990bdbfb595208e2cc6d.1528288895.git.michal.simek@xilinx.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: References: In-Reply-To: References: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180606_054156_024741_035038B2 X-CRM114-Status: GOOD ( 23.91 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org, linux-serial@vger.kernel.org, Jiri Slaby MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP This patch is removing CDNS_UART_NR_PORTS macro which limits number of ports which can be used. Every instance is registering own struct uart_driver with minor number which corresponds to alias ID (or 0 now). and with 1 uart port. The same alias ID is saved to tty_driver->name_base which is key field for creating ttyPSX name. Because name_base and minor number are setup already there is no need to setup any port->line number because 0 is the right value. ~# find /proc/tty/ -name "*uartps*" /proc/tty/driver/xuartps0 /proc/tty/driver/xuartps100 Unfortunately this driver is setting up major number to 0 for using dynamic assignment and kernel is allocating different major numbers for every instance instead of using the same major and different minor number. ~# ls -la /dev/ttyPS* crw------- 1 root root 252, 0 Jan 1 03:36 /dev/ttyPS0 crw--w---- 1 root root 253, 1 Jan 1 00:00 /dev/ttyPS1 When major number is not 0. For example 252 then major/minor combinations are in expected form ~# ls -la /dev/ttyPS* crw------- 1 root root 252, 0 Jan 1 04:04 /dev/ttyPS0 crw--w---- 1 root root 252, 1 Jan 1 00:00 /dev/ttyPS1 Signed-off-by: Michal Simek --- Changes in v2: - Register one uart_driver with unique minor at probe time This patch not done because id is not unique. This needs to be solved before this patch can be applied. In v1 I have created of_alias_check_id() for that. https://lkml.org/lkml/2018/4/26/551 Also we need to run more testing on this to make sure that everything is working properly. --- drivers/tty/serial/xilinx_uartps.c | 78 +++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 30 deletions(-) diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index d76efe8cb3df..82cc17ec7b5d 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -30,8 +30,6 @@ #define CDNS_UART_TTY_NAME "ttyPS" #define CDNS_UART_NAME "xuartps" #define CDNS_UART_MAJOR 0 /* use dynamic node allocation */ -#define CDNS_UART_MINOR 0 /* works best with devtmpfs */ -#define CDNS_UART_NR_PORTS 2 #define CDNS_UART_FIFO_SIZE 64 /* FIFO size */ #define CDNS_UART_REGISTER_SPACE 0x1000 @@ -1247,8 +1245,6 @@ static int __init cdns_uart_console_setup(struct console *co, char *options) return uart_set_options(port, co, baud, parity, bits, flow); } -static struct uart_driver cdns_uart_uart_driver; - static struct console cdns_uart_console = { .name = CDNS_UART_TTY_NAME, .write = cdns_uart_console_write, @@ -1256,7 +1252,6 @@ static int __init cdns_uart_console_setup(struct console *co, char *options) .setup = cdns_uart_console_setup, .flags = CON_PRINTBUFFER, .index = -1, /* Specified on the cmdline (e.g. console=ttyPS ) */ - .data = &cdns_uart_uart_driver, }; #endif /* CONFIG_SERIAL_XILINX_PS_UART_CONSOLE */ @@ -1419,6 +1414,8 @@ static int cdns_uart_probe(struct platform_device *pdev) struct resource *res; struct cdns_uart *cdns_uart_data; const struct of_device_id *match; + struct uart_driver *cdns_uart_uart_driver; + char *driver_name; cdns_uart_data = devm_kzalloc(&pdev->dev, sizeof(*cdns_uart_data), GFP_KERNEL); @@ -1431,32 +1428,49 @@ static int cdns_uart_probe(struct platform_device *pdev) /* Look for a serialN alias */ id = of_alias_get_id(pdev->dev.of_node, "serial"); if (id < 0) + /* + * FIXME this is not enough because if there the next instance + * without alias it will get also id = 0 which is wrong + */ id = 0; - if (id >= CDNS_UART_NR_PORTS) { - dev_err(&pdev->dev, "Cannot get uart_port structure\n"); - return -ENODEV; - } + cdns_uart_uart_driver = devm_kzalloc(&pdev->dev, + sizeof(*cdns_uart_uart_driver), + GFP_KERNEL); + if (!cdns_uart_uart_driver) + return -ENOMEM; + + /* There is a need to use unique driver name */ + driver_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s%d", + CDNS_UART_NAME, id); + if (!driver_name) + return -ENOMEM; - if (!cdns_uart_uart_driver.state) { - cdns_uart_uart_driver.owner = THIS_MODULE, - cdns_uart_uart_driver.driver_name = CDNS_UART_NAME, - cdns_uart_uart_driver.dev_name = CDNS_UART_TTY_NAME, - cdns_uart_uart_driver.major = CDNS_UART_MAJOR, - cdns_uart_uart_driver.minor = CDNS_UART_MINOR, - cdns_uart_uart_driver.nr = CDNS_UART_NR_PORTS, + cdns_uart_uart_driver->owner = THIS_MODULE; + cdns_uart_uart_driver->driver_name = driver_name; + cdns_uart_uart_driver->dev_name = CDNS_UART_TTY_NAME; + cdns_uart_uart_driver->major = CDNS_UART_MAJOR; + cdns_uart_uart_driver->minor = id; + cdns_uart_uart_driver->nr = 1; #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE - cdns_uart_uart_driver.cons = &cdns_uart_console, + cdns_uart_uart_driver->cons = &cdns_uart_console; + cdns_uart_console.data = cdns_uart_uart_driver; #endif - rc = uart_register_driver(&cdns_uart_uart_driver); - if (rc < 0) { - dev_err(&pdev->dev, "Failed to register driver\n"); - return rc; - } + rc = uart_register_driver(cdns_uart_uart_driver); + if (rc < 0) { + dev_err(&pdev->dev, "Failed to register driver\n"); + return rc; } - cdns_uart_data->cdns_uart_driver = &cdns_uart_uart_driver; + /* + * Setting up proper name_base needs to be done after uart + * registration because tty_driver structure is not filled. + * name_base is 0 by default. + */ + cdns_uart_uart_driver->tty_driver->name_base = id; + + cdns_uart_data->cdns_uart_driver = cdns_uart_uart_driver; match = of_match_node(cdns_uart_of_match, pdev->dev.of_node); if (match && match->data) { @@ -1473,7 +1487,8 @@ static int cdns_uart_probe(struct platform_device *pdev) } if (IS_ERR(cdns_uart_data->pclk)) { dev_err(&pdev->dev, "pclk clock not found.\n"); - return PTR_ERR(cdns_uart_data->pclk); + rc = PTR_ERR(cdns_uart_data->pclk); + goto err_out_unregister_driver; } cdns_uart_data->uartclk = devm_clk_get(&pdev->dev, "uart_clk"); @@ -1484,13 +1499,14 @@ static int cdns_uart_probe(struct platform_device *pdev) } if (IS_ERR(cdns_uart_data->uartclk)) { dev_err(&pdev->dev, "uart_clk clock not found.\n"); - return PTR_ERR(cdns_uart_data->uartclk); + rc = PTR_ERR(cdns_uart_data->uartclk); + goto err_out_unregister_driver; } rc = clk_prepare_enable(cdns_uart_data->pclk); if (rc) { dev_err(&pdev->dev, "Unable to enable pclk clock.\n"); - return rc; + goto err_out_unregister_driver; } rc = clk_prepare_enable(cdns_uart_data->uartclk); if (rc) { @@ -1525,7 +1541,6 @@ static int cdns_uart_probe(struct platform_device *pdev) port->flags = UPF_BOOT_AUTOCONF; port->ops = &cdns_uart_ops; port->fifosize = CDNS_UART_FIFO_SIZE; - port->line = id; /* * Register the port. @@ -1552,11 +1567,11 @@ static int cdns_uart_probe(struct platform_device *pdev) * If register_console() don't assign value, then console_port pointer * is cleanup. */ - if (cdns_uart_uart_driver.cons->index == -1) + if (cdns_uart_uart_driver->cons->index == -1) console_port = port; #endif - rc = uart_add_one_port(&cdns_uart_uart_driver, port); + rc = uart_add_one_port(cdns_uart_uart_driver, port); if (rc) { dev_err(&pdev->dev, "uart_add_one_port() failed; err=%i\n", rc); @@ -1565,7 +1580,7 @@ static int cdns_uart_probe(struct platform_device *pdev) #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE /* This is not port which is used for console that's why clean it up */ - if (cdns_uart_uart_driver.cons->index == -1) + if (cdns_uart_uart_driver->cons->index == -1) console_port = NULL; #endif @@ -1583,6 +1598,8 @@ static int cdns_uart_probe(struct platform_device *pdev) clk_disable_unprepare(cdns_uart_data->uartclk); err_out_clk_dis_pclk: clk_disable_unprepare(cdns_uart_data->pclk); +err_out_unregister_driver: + uart_unregister_driver(cdns_uart_data->cdns_uart_driver); return rc; } @@ -1611,6 +1628,7 @@ static int cdns_uart_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); pm_runtime_dont_use_autosuspend(&pdev->dev); + uart_unregister_driver(cdns_uart_data->cdns_uart_driver); return rc; }