From patchwork Thu Oct 27 12:48:11 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 4860 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 4100923EF6 for ; Thu, 27 Oct 2011 12:49:36 +0000 (UTC) Received: from mail-fx0-f52.google.com (mail-fx0-f52.google.com [209.85.161.52]) by fiordland.canonical.com (Postfix) with ESMTP id 32289A1847E for ; Thu, 27 Oct 2011 12:49:36 +0000 (UTC) Received: by mail-fx0-f52.google.com with SMTP id n26so3746987faa.11 for ; Thu, 27 Oct 2011 05:49:36 -0700 (PDT) Received: by 10.223.36.193 with SMTP id u1mr15883532fad.27.1319719775938; Thu, 27 Oct 2011 05:49:35 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.152.1.71 with SMTP id 7cs44417lak; Thu, 27 Oct 2011 05:49:35 -0700 (PDT) Received: by 10.14.10.154 with SMTP id 26mr4576191eev.48.1319719775017; Thu, 27 Oct 2011 05:49:35 -0700 (PDT) Received: from eu1sys200aog118.obsmtp.com (eu1sys200aog118.obsmtp.com. [207.126.144.145]) by mx.google.com with SMTP id s51si1630442eef.171.2011.10.27.05.49.21 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 27 Oct 2011 05:49:35 -0700 (PDT) Received-SPF: neutral (google.com: 207.126.144.145 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) client-ip=207.126.144.145; Authentication-Results: mx.google.com; spf=neutral (google.com: 207.126.144.145 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) smtp.mail=linus.walleij@stericsson.com Received: from beta.dmz-ap.st.com ([138.198.100.35]) (using TLSv1) by eu1sys200aob118.postini.com ([207.126.147.11]) with SMTP; Thu, 27 Oct 2011 12:49:34 UTC Received: from zeta.dmz-ap.st.com (ns6.st.com [138.198.234.13]) by beta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 99EA3A7; Thu, 27 Oct 2011 12:39:53 +0000 (GMT) Received: from relay2.stm.gmessaging.net (unknown [10.230.100.18]) by zeta.dmz-ap.st.com (STMicroelectronics) with ESMTP id C605E720; Thu, 27 Oct 2011 12:48:19 +0000 (GMT) Received: from exdcvycastm004.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm004", Issuer "exdcvycastm004" (not verified)) by relay2.stm.gmessaging.net (Postfix) with ESMTPS id BDB0FA807B; Thu, 27 Oct 2011 14:48:13 +0200 (CEST) Received: from localhost.localdomain (10.230.100.153) by smtp.stericsson.com (10.230.100.2) with Microsoft SMTP Server (TLS) id 8.3.83.0; Thu, 27 Oct 2011 14:48:18 +0200 From: Linus Walleij To: , Steve Glendinning Cc: Mathieu Poirer , Robert Marklund , Paul Mundt , , Sascha Hauer , Tony Lindgren , , Mike Frysinger , , Linus Walleij Subject: [PATCH 2/2 v3] net/smsc911x: Add regulator support Date: Thu, 27 Oct 2011 14:48:11 +0200 Message-ID: <1319719691-15799-1-git-send-email-linus.walleij@stericsson.com> X-Mailer: git-send-email 1.7.3.2 MIME-Version: 1.0 From: Robert Marklund Add some basic regulator support for the power pins, as needed by the ST-Ericsson Snowball platform that powers up the SMSC911 chip using an external regulator. Platforms that use regulators and the smsc911x and have no defined regulator for the smsc911x and claim complete regulator constraints with no dummy regulators will need to provide it, for example using a fixed voltage regulator. It appears that this may affect (apart from Ux500 Snowball) possibly these archs/machines that from some grep:s appear to define both CONFIG_SMSC911X and CONFIG_REGULATOR: - ARM Freescale mx3 and OMAP 2 plus, Raumfeld machines - Blackfin - Super-H Cc: Paul Mundt Cc: linux-sh@vger.kernel.org Cc: Sascha Hauer Cc: Tony Lindgren Cc: linux-omap@vger.kernel.org Cc: Mike Frysinger Cc: uclinux-dist-devel@blackfin.uclinux.org Reviewed-by: Mark Brown Signed-off-by: Robert Marklund Signed-off-by: Linus Walleij --- ChangeLog v2->v3: - Use bulk regulators on Mark's request. - Add Cc-fileds to some possibly affected platforms. ChangeLog v1->v2: - Don't check for NULL regulators and error out properly if the regulators can't be found. All platforms using the smsc911x and the regulator framework simultaneously need to provide some kind of regulator for it. --- drivers/net/ethernet/smsc/smsc911x.c | 103 ++++++++++++++++++++++++++++++---- 1 files changed, 92 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 8843071..8ad15a6 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -88,6 +89,8 @@ struct smsc911x_ops { unsigned int *buf, unsigned int wordcount); }; +#define SMSC911X_NUM_SUPPLIES 2 + struct smsc911x_data { void __iomem *ioaddr; @@ -138,6 +141,9 @@ struct smsc911x_data { /* register access functions */ const struct smsc911x_ops *ops; + + /* regulators */ + struct regulator_bulk_data supplies[SMSC911X_NUM_SUPPLIES]; }; /* Easy access to information */ @@ -362,6 +368,60 @@ out: spin_unlock_irqrestore(&pdata->dev_lock, flags); } +/* + * Enable or disable resources, currently just regulators. + */ +static int smsc911x_enable_disable_resources(struct platform_device *pdev, + bool enable) +{ + struct net_device *ndev = platform_get_drvdata(pdev); + struct smsc911x_data *pdata = netdev_priv(ndev); + int ret = 0; + + /* enable/disable regulators */ + if (enable) { + ret = regulator_bulk_enable(ARRAY_SIZE(pdata->supplies), + pdata->supplies); + if (ret) + netdev_err(ndev, "failed to enable regulators %d\n", + ret); + } else + ret = regulator_bulk_disable(ARRAY_SIZE(pdata->supplies), + pdata->supplies); + return ret; +} + +/* + * Request or free resources, currently just regulators. + * + * The SMSC911x has two power pins: vddvario and vdd33a, in designs where + * these are not always-on we need to request regulators to be turned on + * before we can try to access the device registers. + */ +static int smsc911x_request_free_resources(struct platform_device *pdev, + bool request) +{ + struct net_device *ndev = platform_get_drvdata(pdev); + struct smsc911x_data *pdata = netdev_priv(ndev); + int ret = 0; + + /* Request regulators */ + if (request) { + pdata->supplies[0].supply = "vdd33a"; + pdata->supplies[1].supply = "vddvario"; + ret = regulator_bulk_get(&pdev->dev, + ARRAY_SIZE(pdata->supplies), + pdata->supplies); + if (ret) + netdev_err(ndev, "couldn't get regulators %d\n", + ret); + } else + regulator_bulk_free(ARRAY_SIZE(pdata->supplies), + pdata->supplies); + + return ret; +} + /* waits for MAC not busy, with timeout. Only called by smsc911x_mac_read * and smsc911x_mac_write, so assumes mac_lock is held */ static int smsc911x_mac_complete(struct smsc911x_data *pdata) @@ -2065,6 +2125,7 @@ static int __devexit smsc911x_drv_remove(struct platform_device *pdev) struct net_device *dev; struct smsc911x_data *pdata; struct resource *res; + int retval; dev = platform_get_drvdata(pdev); BUG_ON(!dev); @@ -2092,6 +2153,12 @@ static int __devexit smsc911x_drv_remove(struct platform_device *pdev) iounmap(pdata->ioaddr); + if (smsc911x_enable_disable_resources(pdev, false)) + pr_warn("Could not disable resource\n"); + + retval = smsc911x_request_free_resources(pdev, false); + /* ignore not all have regulators */ + free_netdev(dev); return 0; @@ -2218,10 +2285,24 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) pdata->dev = dev; pdata->msg_enable = ((1 << debug) - 1); + platform_set_drvdata(pdev, dev); + + retval = smsc911x_request_free_resources(pdev, true); + if (retval) { + pr_err("Could request regulators needed aborting\n"); + goto out_return_resources; + } + + retval = smsc911x_enable_disable_resources(pdev, true); + if (retval) { + pr_err("Could enable regulators needed aborting\n"); + goto out_disable_resources; + } + if (pdata->ioaddr == NULL) { SMSC_WARN(pdata, probe, "Error smsc911x base address invalid"); retval = -ENOMEM; - goto out_free_netdev_2; + goto out_disable_resources; } retval = smsc911x_probe_config_dt(&pdata->config, np); @@ -2233,7 +2314,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) if (retval) { SMSC_WARN(pdata, probe, "Error smsc911x config not found"); - goto out_unmap_io_3; + goto out_disable_resources; } /* assume standard, non-shifted, access to HW registers */ @@ -2244,7 +2325,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) retval = smsc911x_init(dev); if (retval < 0) - goto out_unmap_io_3; + goto out_disable_resources; /* configure irq polarity and type before connecting isr */ if (pdata->config.irq_polarity == SMSC911X_IRQ_POLARITY_ACTIVE_HIGH) @@ -2264,15 +2345,13 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) if (retval) { SMSC_WARN(pdata, probe, "Unable to claim requested irq: %d", dev->irq); - goto out_unmap_io_3; + goto out_free_irq; } - platform_set_drvdata(pdev, dev); - retval = register_netdev(dev); if (retval) { SMSC_WARN(pdata, probe, "Error %i registering device", retval); - goto out_unset_drvdata_4; + goto out_free_irq; } else { SMSC_TRACE(pdata, probe, "Network interface: \"%s\"", dev->name); @@ -2321,12 +2400,14 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) out_unregister_netdev_5: unregister_netdev(dev); -out_unset_drvdata_4: - platform_set_drvdata(pdev, NULL); +out_free_irq: free_irq(dev->irq, dev); -out_unmap_io_3: +out_disable_resources: + (void)smsc911x_enable_disable_resources(pdev, false); +out_return_resources: + (void)smsc911x_request_free_resources(pdev, false); + platform_set_drvdata(pdev, NULL); iounmap(pdata->ioaddr); -out_free_netdev_2: free_netdev(dev); out_release_io_1: release_mem_region(res->start, resource_size(res));