From patchwork Wed Mar 4 17:59:49 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 5938901 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 47671BF440 for ; Wed, 4 Mar 2015 18:07:55 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 5BA33202D1 for ; Wed, 4 Mar 2015 18:07:54 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6650920272 for ; Wed, 4 Mar 2015 18:07:53 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YTDej-0006pM-7a; Wed, 04 Mar 2015 18:04:25 +0000 Received: from cam-admin0.cambridge.arm.com ([217.140.96.50]) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YTDb0-0004IQ-R2 for linux-arm-kernel@lists.infradead.org; Wed, 04 Mar 2015 18:00:40 +0000 Received: from e106785-lin.cambridge.arm.com ([10.1.203.153]) by cam-admin0.cambridge.arm.com (8.12.6/8.12.6) with ESMTP id t24Hxtwt010579; Wed, 4 Mar 2015 17:59:56 GMT From: Andre Przywara To: linux@arm.linux.org.uk, gregkh@linuxfoundation.org, jslaby@suse.cz Subject: [PATCH v2 05/10] drivers: PL011: refactor pl011_probe() Date: Wed, 4 Mar 2015 17:59:49 +0000 Message-Id: <1425491994-23913-6-git-send-email-andre.przywara@arm.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1425491994-23913-1-git-send-email-andre.przywara@arm.com> References: <1425491994-23913-1-git-send-email-andre.przywara@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150304_100035_292666_D2A0F5C6 X-CRM114-Status: GOOD ( 15.48 ) X-Spam-Score: -5.0 (-----) Cc: linux-arm-kernel@lists.infradead.org, rob.herring@linaro.org, arnd@arndb.de, linux-serial@vger.kernel.org, Dave.Martin@arm.com X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Currently the pl011_probe() function is relying on some AMBA IDs and a device tree node to initialize the driver and a port. Both features are not necessarily required for the driver: - we lack AMBA IDs in the ARM SBSA generic UART and - we lack a DT node in ACPI systems. So lets refactor the function to ease later reuse. Signed-off-by: Andre Przywara --- drivers/tty/serial/amba-pl011.c | 89 ++++++++++++++++++++++++++------------- 1 file changed, 60 insertions(+), 29 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 37b55ee..4fe0a0a 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -2274,13 +2274,10 @@ static void pl011_unregister_port(struct uart_amba_port *uap) uart_unregister_driver(&amba_reg); } - -static int pl011_probe(struct amba_device *dev, const struct amba_id *id) +static int pl011_allocate_port(struct device *dev, struct uart_amba_port **_uap) { struct uart_amba_port *uap; - struct vendor_data *vendor = id->data; - void __iomem *base; - int i, ret; + int i; for (i = 0; i < ARRAY_SIZE(amba_ports); i++) if (amba_ports[i] == NULL) @@ -2289,48 +2286,50 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) if (i == ARRAY_SIZE(amba_ports)) return -EBUSY; - uap = devm_kzalloc(&dev->dev, sizeof(struct uart_amba_port), - GFP_KERNEL); + uap = devm_kzalloc(dev, sizeof(struct uart_amba_port), GFP_KERNEL); if (uap == NULL) return -ENOMEM; - i = pl011_probe_dt_alias(i, &dev->dev); + if (_uap) + *_uap = uap; + + return i; +} - base = devm_ioremap(&dev->dev, dev->res.start, - resource_size(&dev->res)); +static int pl011_setup_port(struct device *dev, struct uart_amba_port *uap, + struct resource *mmiobase, int index) +{ + void __iomem *base; + + base = devm_ioremap_resource(dev, mmiobase); if (!base) return -ENOMEM; - uap->clk = devm_clk_get(&dev->dev, NULL); - if (IS_ERR(uap->clk)) - return PTR_ERR(uap->clk); + index = pl011_probe_dt_alias(index, dev); - uap->vendor = vendor; - uap->lcrh_rx = vendor->lcrh_rx; - uap->lcrh_tx = vendor->lcrh_tx; uap->old_cr = 0; - uap->fifosize = vendor->get_fifosize(dev); - uap->port.dev = &dev->dev; - uap->port.mapbase = dev->res.start; + uap->port.dev = dev; + uap->port.mapbase = mmiobase->start; uap->port.membase = base; uap->port.iotype = UPIO_MEM; - uap->port.irq = dev->irq[0]; uap->port.fifosize = uap->fifosize; - uap->port.ops = &amba_pl011_pops; uap->port.flags = UPF_BOOT_AUTOCONF; - uap->port.line = i; + uap->port.line = index; INIT_DELAYED_WORK(&uap->tx_softirq_work, pl011_tx_softirq); - pl011_dma_probe(&dev->dev, uap); + pl011_dma_probe(dev, uap); - /* Ensure interrupts from this UART are masked and cleared */ - writew(0, uap->port.membase + UART011_IMSC); - writew(0xffff, uap->port.membase + UART011_ICR); + amba_ports[index] = uap; - snprintf(uap->type, sizeof(uap->type), "PL011 rev%u", amba_rev(dev)); + return 0; +} - amba_ports[i] = uap; +static int pl011_register_port(struct uart_amba_port *uap) +{ + int ret; - amba_set_drvdata(dev, uap); + /* Ensure interrupts from this UART are masked and cleared */ + writew(0, uap->port.membase + UART011_IMSC); + writew(0xffff, uap->port.membase + UART011_ICR); if (!amba_reg.state) { ret = uart_register_driver(&amba_reg); @@ -2347,6 +2346,38 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) return ret; } +static int pl011_probe(struct amba_device *dev, const struct amba_id *id) +{ + struct uart_amba_port *uap; + struct vendor_data *vendor = id->data; + int portnr, ret; + + portnr = pl011_allocate_port(&dev->dev, &uap); + if (portnr < 0) + return portnr; + + uap->clk = devm_clk_get(&dev->dev, NULL); + if (IS_ERR(uap->clk)) + return PTR_ERR(uap->clk); + + uap->vendor = vendor; + uap->lcrh_rx = vendor->lcrh_rx; + uap->lcrh_tx = vendor->lcrh_tx; + uap->fifosize = vendor->get_fifosize(dev); + uap->port.irq = dev->irq[0]; + uap->port.ops = &amba_pl011_pops; + + snprintf(uap->type, sizeof(uap->type), "PL011 rev%u", amba_rev(dev)); + + ret = pl011_setup_port(&dev->dev, uap, &dev->res, portnr); + if (ret) + return ret; + + amba_set_drvdata(dev, uap); + + return pl011_register_port(uap); +} + static int pl011_remove(struct amba_device *dev) { struct uart_amba_port *uap = amba_get_drvdata(dev);