From patchwork Thu Jan 18 12:31:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcin Wojtas X-Patchwork-Id: 10173099 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 4AF6C6055D for ; Thu, 18 Jan 2018 12:34:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3961E2013C for ; Thu, 18 Jan 2018 12:34:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2D90A27C2D; Thu, 18 Jan 2018 12:34:10 +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=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.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 824A72013C for ; Thu, 18 Jan 2018 12:34:09 +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=RuMefJ1IJLmV0FxFPM2edAoz/WyD8AhqSfU/mJwvT+Q=; b=PBFpAo8TJTD2iqduNEaqCwpKCv I+RNauML301LlkLJniCg5qxAukHW8Ju+RPcDuaEPlm+T4fiNmBW2c+WIWAslRTF0nZScfp4I530e1 q0BGBkRsyALGbOrWt/rpQPTLeCdnK3psXZsoFfSEvsYPBfJXOvurxPxHbaAJ7+6Ib5kqrvc1pXJ6R XW3wnr6eEJotqB4Tz5Ih8mE+u3cAPAU9X/dYcdfkBL4txhgYP9UD8QvVIR5lnKq9TDeZJkmWJa4Vz sScbZeKpwk/8CXPLUToCGvkgqfRhFAuzgjPidZoQFlpDcSNL1SZqF9fluuUqkwuqApcOBAIG2pt0s 6/iD+A5g==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.89 #1 (Red Hat Linux)) id 1ec9OP-0002vA-21; Thu, 18 Jan 2018 12:34:05 +0000 Received: from mail-lf0-x243.google.com ([2a00:1450:4010:c07::243]) by bombadil.infradead.org with esmtps (Exim 4.89 #1 (Red Hat Linux)) id 1ec9Mc-0000o7-Bx for linux-arm-kernel@lists.infradead.org; Thu, 18 Jan 2018 12:32:22 +0000 Received: by mail-lf0-x243.google.com with SMTP id q17so16231054lfa.9 for ; Thu, 18 Jan 2018 04:32:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=xupd2XgD2fi/cidWbvOSziGDKyKkE3Rycry1jJHel1o=; b=YleqWpK1qACWnqxv3ypGgbq3jAoEqcHKtUKwW9VqgBVDK88kU/PVSWnucv235jTA1t nhrFftngIn7UhgCQhZIs9iekxqiiZ6cSjLaWHlb10S+oNE8oZt+V+QQR6hrht+PNPdP3 zetc3oyINnWSoRAKqCkFYEMYcwVmv/STUH87mAoTqTY6pixyBiDufQKIS2QqaDMu1an5 wn+tWNRdhRna7oZzkmCn7OiINYuMgNabH38RloDeTK6YZnn8b0MS7VKmxtJJKJhslmuy ctsuSomss6m0BHV6t2iiXrEf8ZCMnI+qz/3HbqrUgvg8wpC2hpzuX/Ml0ff7y1Om0Mpu My1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=xupd2XgD2fi/cidWbvOSziGDKyKkE3Rycry1jJHel1o=; b=WseKWCB43fKJaPNCxdLlTAAfFBhdmTO8JkcW6lKV7hNJvXV2e7JhkwuF7Kk4TF8oMX gYYF+9MxJijoRLXOX85hIHxPiJkR4G7wW+qorZzBP6uIfnYAXs8wGsfmx8x2HTFg3JZW 1jfR+cEQe66v1SXMhmz3EEn7j0iuTCfsZnD59EU5ssDDmBIvP/9HT45WJOluM/AuTdv4 n58AKVYDZSZn7OGHFa4lu4npCfNmD6p9m2Nnbs3K8kk+fiSQx0NKnnXqBtkJd5sPB2FX DSComTqwSnyCrYqmIA4L1ptwxyiL6xQ4rxIcp0q/2C25p87mZ1JkhgwHH34JxkQTzGsk GviQ== X-Gm-Message-State: AKwxytdV5LQFN02ePgIrzLF1JfqxSD8c6gcWah8zSb7dTsRo5JmpkmGx /bSg5rCxxErulxVHpWE2hW5lrA== X-Google-Smtp-Source: ACJfBosqLe6u8pvNC+TSsJBjAIM9M3evQwNkKXK7TurL+CBnLd9bduhFctpawVPyP5Me7FtH1K/+0A== X-Received: by 10.25.28.142 with SMTP id c136mr24566484lfc.38.1516278729359; Thu, 18 Jan 2018 04:32:09 -0800 (PST) Received: from gilgamesh.semihalf.com (31-172-191-173.noc.fibertech.net.pl. [31.172.191.173]) by smtp.gmail.com with ESMTPSA id s23sm1303906ljs.1.2018.01.18.04.32.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 18 Jan 2018 04:32:08 -0800 (PST) From: Marcin Wojtas To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, netdev@vger.kernel.org, linux-acpi@vger.kernel.org Subject: [net-next: PATCH v4 7/7] net: mvpp2: enable ACPI support in the driver Date: Thu, 18 Jan 2018 13:31:44 +0100 Message-Id: <1516278704-17141-8-git-send-email-mw@semihalf.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1516278704-17141-1-git-send-email-mw@semihalf.com> References: <1516278704-17141-1-git-send-email-mw@semihalf.com> 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: thomas.petazzoni@free-electrons.com, andrew@lunn.ch, f.fainelli@gmail.com, graeme.gregory@linaro.org, ard.biesheuvel@linaro.org, jaz@semihalf.com, antoine.tenart@free-electrons.com, rafael.j.wysocki@intel.com, linux@armlinux.org.uk, nadavh@marvell.com, neta@marvell.com, tn@semihalf.com, gregory.clement@free-electrons.com, stefanc@marvell.com, mw@semihalf.com, davem@davemloft.net 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 introduces an alternative way of obtaining resources - via ACPI tables provided by firmware. Enabling coexistence with the DT support, in addition to the OF_*->device_*/fwnode_* API replacement, required following steps to be taken: * Add mvpp2_acpi_match table * Omit clock configuration and obtain tclk from the property - in ACPI world, the firmware is responsible for clock maintenance. * Disable comphy and syscon handling as they are not available for ACPI. * Modify way of obtaining interrupts - use newly introduced fwnode_irq_get() routine * Until proper MDIO bus and PHY handling with ACPI is established in the kernel, use only link interrupts feature in the driver. For the RGMII port it results in depending on GMAC settings done during firmware stage. * When booting with ACPI MVPP2_QDIST_MULTI_MODE is picked by default, as there is no need to keep any kind of the backward compatibility. Moreover, a memory region used by mvmdio driver is usually placed in the middle of the address space of the PP2 network controller. The MDIO base address is obtained without requesting memory region (by devm_ioremap() call) in mvmdio.c, later overlapping resources are requested by the network driver, which is responsible for avoiding a concurrent access. In case the MDIO memory region is declared in the ACPI, it can already appear as 'in-use' in the OS. Because it is overlapped by second region of the network controller, make sure it is released, before requesting it again. The care is taken by mvpp2 driver to avoid concurrent access to this memory region. Signed-off-by: Marcin Wojtas --- drivers/net/ethernet/marvell/mvpp2.c | 133 ++++++++++++++------ 1 file changed, 94 insertions(+), 39 deletions(-) diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index f16448e..a1d7b88 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c @@ -10,6 +10,7 @@ * warranty of any kind, whether express or implied. */ +#include #include #include #include @@ -7502,7 +7503,10 @@ static int mvpp2_multi_queue_vectors_init(struct mvpp2_port *port, strncpy(irqname, "rx-shared", sizeof(irqname)); } - v->irq = of_irq_get_byname(port_node, irqname); + if (port_node) + v->irq = of_irq_get_byname(port_node, irqname); + else + v->irq = fwnode_irq_get(port->fwnode, i); if (v->irq <= 0) { ret = -EINVAL; goto err; @@ -7746,7 +7750,7 @@ static int mvpp2_port_probe(struct platform_device *pdev, struct mvpp2 *priv) { struct device_node *phy_node; - struct phy *comphy; + struct phy *comphy = NULL; struct mvpp2_port *port; struct mvpp2_port_pcpu *port_pcpu; struct device_node *port_node = to_of_node(port_fwnode); @@ -7760,7 +7764,12 @@ static int mvpp2_port_probe(struct platform_device *pdev, int phy_mode; int err, i, cpu; - has_tx_irqs = mvpp2_port_has_tx_irqs(priv, port_node); + if (port_node) { + has_tx_irqs = mvpp2_port_has_tx_irqs(priv, port_node); + } else { + has_tx_irqs = true; + queue_mode = MVPP2_QDIST_MULTI_MODE; + } if (!has_tx_irqs) queue_mode = MVPP2_QDIST_SINGLE_MODE; @@ -7775,7 +7784,11 @@ static int mvpp2_port_probe(struct platform_device *pdev, if (!dev) return -ENOMEM; - phy_node = of_parse_phandle(port_node, "phy", 0); + if (port_node) + phy_node = of_parse_phandle(port_node, "phy", 0); + else + phy_node = NULL; + phy_mode = fwnode_get_phy_mode(port_fwnode); if (phy_mode < 0) { dev_err(&pdev->dev, "incorrect phy mode\n"); @@ -7783,13 +7796,15 @@ static int mvpp2_port_probe(struct platform_device *pdev, goto err_free_netdev; } - comphy = devm_of_phy_get(&pdev->dev, port_node, NULL); - if (IS_ERR(comphy)) { - if (PTR_ERR(comphy) == -EPROBE_DEFER) { - err = -EPROBE_DEFER; - goto err_free_netdev; + if (port_node) { + comphy = devm_of_phy_get(&pdev->dev, port_node, NULL); + if (IS_ERR(comphy)) { + if (PTR_ERR(comphy) == -EPROBE_DEFER) { + err = -EPROBE_DEFER; + goto err_free_netdev; + } + comphy = NULL; } - comphy = NULL; } if (fwnode_property_read_u32(port_fwnode, "port-id", &id)) { @@ -7805,6 +7820,7 @@ static int mvpp2_port_probe(struct platform_device *pdev, port = netdev_priv(dev); port->dev = dev; + port->fwnode = port_fwnode; port->ntxqs = ntxqs; port->nrxqs = nrxqs; port->priv = priv; @@ -7814,7 +7830,10 @@ static int mvpp2_port_probe(struct platform_device *pdev, if (err) goto err_free_netdev; - port->link_irq = of_irq_get_byname(port_node, "link"); + if (port_node) + port->link_irq = of_irq_get_byname(port_node, "link"); + else + port->link_irq = fwnode_irq_get(port_fwnode, port->nqvecs + 1); if (port->link_irq == -EPROBE_DEFER) { err = -EPROBE_DEFER; goto err_deinit_qvecs; @@ -8197,6 +8216,7 @@ static int mvpp2_init(struct platform_device *pdev, struct mvpp2 *priv) static int mvpp2_probe(struct platform_device *pdev) { + const struct acpi_device_id *acpi_id; struct fwnode_handle *fwnode = pdev->dev.fwnode; struct fwnode_handle *port_fwnode; struct mvpp2 *priv; @@ -8209,8 +8229,14 @@ static int mvpp2_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; - priv->hw_version = - (unsigned long)of_device_get_match_data(&pdev->dev); + if (has_acpi_companion(&pdev->dev)) { + acpi_id = acpi_match_device(pdev->dev.driver->acpi_match_table, + &pdev->dev); + priv->hw_version = (unsigned long)acpi_id->driver_data; + } else { + priv->hw_version = + (unsigned long)of_device_get_match_data(&pdev->dev); + } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(&pdev->dev, res); @@ -8224,10 +8250,23 @@ static int mvpp2_probe(struct platform_device *pdev) return PTR_ERR(priv->lms_base); } else { res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (has_acpi_companion(&pdev->dev)) { + /* In case the MDIO memory region is declared in + * the ACPI, it can already appear as 'in-use' + * in the OS. Because it is overlapped by second + * region of the network controller, make + * sure it is released, before requesting it again. + * The care is taken by mvpp2 driver to avoid + * concurrent access to this memory region. + */ + release_resource(res); + } priv->iface_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->iface_base)) return PTR_ERR(priv->iface_base); + } + if (priv->hw_version == MVPP22 && dev_of_node(&pdev->dev)) { priv->sysctrl_base = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "marvell,system-controller"); @@ -8253,32 +8292,34 @@ static int mvpp2_probe(struct platform_device *pdev) else priv->max_port_rxqs = 32; - priv->pp_clk = devm_clk_get(&pdev->dev, "pp_clk"); - if (IS_ERR(priv->pp_clk)) - return PTR_ERR(priv->pp_clk); - err = clk_prepare_enable(priv->pp_clk); - if (err < 0) - return err; - - priv->gop_clk = devm_clk_get(&pdev->dev, "gop_clk"); - if (IS_ERR(priv->gop_clk)) { - err = PTR_ERR(priv->gop_clk); - goto err_pp_clk; - } - err = clk_prepare_enable(priv->gop_clk); - if (err < 0) - goto err_pp_clk; + if (dev_of_node(&pdev->dev)) { + priv->pp_clk = devm_clk_get(&pdev->dev, "pp_clk"); + if (IS_ERR(priv->pp_clk)) + return PTR_ERR(priv->pp_clk); + err = clk_prepare_enable(priv->pp_clk); + if (err < 0) + return err; - if (priv->hw_version == MVPP22) { - priv->mg_clk = devm_clk_get(&pdev->dev, "mg_clk"); - if (IS_ERR(priv->mg_clk)) { - err = PTR_ERR(priv->mg_clk); - goto err_gop_clk; + priv->gop_clk = devm_clk_get(&pdev->dev, "gop_clk"); + if (IS_ERR(priv->gop_clk)) { + err = PTR_ERR(priv->gop_clk); + goto err_pp_clk; } - - err = clk_prepare_enable(priv->mg_clk); + err = clk_prepare_enable(priv->gop_clk); if (err < 0) - goto err_gop_clk; + goto err_pp_clk; + + if (priv->hw_version == MVPP22) { + priv->mg_clk = devm_clk_get(&pdev->dev, "mg_clk"); + if (IS_ERR(priv->mg_clk)) { + err = PTR_ERR(priv->mg_clk); + goto err_gop_clk; + } + + err = clk_prepare_enable(priv->mg_clk); + if (err < 0) + goto err_gop_clk; + } priv->axi_clk = devm_clk_get(&pdev->dev, "axi_clk"); if (IS_ERR(priv->axi_clk)) { @@ -8291,10 +8332,14 @@ static int mvpp2_probe(struct platform_device *pdev) if (err < 0) goto err_gop_clk; } - } - /* Get system's tclk rate */ - priv->tclk = clk_get_rate(priv->pp_clk); + /* Get system's tclk rate */ + priv->tclk = clk_get_rate(priv->pp_clk); + } else if (device_property_read_u32(&pdev->dev, "clock-frequency", + &priv->tclk)) { + dev_err(&pdev->dev, "missing clock-frequency value\n"); + return -EINVAL; + } if (priv->hw_version == MVPP22) { err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(40)); @@ -8399,6 +8444,9 @@ static int mvpp2_remove(struct platform_device *pdev) aggr_txq->descs_dma); } + if (is_acpi_node(port_fwnode)) + return 0; + clk_disable_unprepare(priv->axi_clk); clk_disable_unprepare(priv->mg_clk); clk_disable_unprepare(priv->pp_clk); @@ -8420,12 +8468,19 @@ static const struct of_device_id mvpp2_match[] = { }; MODULE_DEVICE_TABLE(of, mvpp2_match); +static const struct acpi_device_id mvpp2_acpi_match[] = { + { "MRVL0110", MVPP22 }, + { }, +}; +MODULE_DEVICE_TABLE(acpi, mvpp2_acpi_match); + static struct platform_driver mvpp2_driver = { .probe = mvpp2_probe, .remove = mvpp2_remove, .driver = { .name = MVPP2_DRIVER_NAME, .of_match_table = mvpp2_match, + .acpi_match_table = ACPI_PTR(mvpp2_acpi_match), }, };