* [PATCH 2/2 v2] net/smsc911x: Add regulator support
@ 2011-10-26 11:05 Linus Walleij
2011-10-26 13:36 ` Mark Brown
0 siblings, 1 reply; 2+ messages in thread
From: Linus Walleij @ 2011-10-26 11:05 UTC (permalink / raw)
To: netdev, Steve Glendinning
Cc: Mathieu Poirer, Robert Marklund, Mark Brown, Linus Walleij
From: Robert Marklund <robert.marklund@stericsson.com>
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.
Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Robert Marklund <robert.marklund@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
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 | 123 +++++++++++++++++++++++++++++++---
1 files changed, 112 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c
index 8843071..70fb695 100644
--- a/drivers/net/ethernet/smsc/smsc911x.c
+++ b/drivers/net/ethernet/smsc/smsc911x.c
@@ -44,6 +44,7 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/bug.h>
@@ -138,6 +139,10 @@ struct smsc911x_data {
/* register access functions */
const struct smsc911x_ops *ops;
+
+ /* regulators */
+ struct regulator *regulator_vddvario;
+ struct regulator *regulator_vdd33a;
};
/* Easy access to information */
@@ -362,6 +367,81 @@ 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 err = 0;
+
+ /* enable/disable regulator for vddvario */
+ if (enable) {
+ err = regulator_enable(pdata->regulator_vddvario);
+ if (err < 0) {
+ netdev_err(ndev, "regulator_enable failed for "
+ "vddvario");
+ }
+ } else
+ err = regulator_disable(pdata->regulator_vddvario);
+
+ /* enable/disable regulator for vdd33a */
+ if (enable) {
+ err = regulator_enable(pdata->regulator_vdd33a);
+ if (err < 0) {
+ netdev_err(ndev, "regulator_enable failed for "
+ "vdd33a");
+ }
+ } else
+ err = regulator_disable(pdata->regulator_vdd33a);
+
+ return err;
+}
+
+/*
+ * 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 err = 0;
+
+ /* Request regulator for vddvario */
+ if (request) {
+ pdata->regulator_vddvario = regulator_get(&pdev->dev,
+ "vddvario");
+ if (IS_ERR(pdata->regulator_vddvario)) {
+ netdev_err(ndev, "Failed to get regulator vddvario\n");
+ err = PTR_ERR(pdata->regulator_vddvario);
+ }
+ } else {
+ regulator_put(pdata->regulator_vddvario);
+ pdata->regulator_vddvario = NULL;
+ }
+
+ /* Request regulator for vdd33a */
+ if (request) {
+ pdata->regulator_vdd33a = regulator_get(&pdev->dev, "vdd33a");
+ if (IS_ERR(pdata->regulator_vdd33a)) {
+ netdev_err(ndev, "Failed to get regulator vdd33a\n");
+ err = PTR_ERR(pdata->regulator_vdd33a);
+ }
+ } else {
+ regulator_put(pdata->regulator_vdd33a);
+ pdata->regulator_vdd33a = NULL;
+ }
+
+ return err;
+}
+
/* 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 +2145,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 +2173,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 +2305,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 +2334,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 +2345,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 +2365,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 +2420,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));
--
1.7.3.2
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH 2/2 v2] net/smsc911x: Add regulator support
2011-10-26 11:05 [PATCH 2/2 v2] net/smsc911x: Add regulator support Linus Walleij
@ 2011-10-26 13:36 ` Mark Brown
0 siblings, 0 replies; 2+ messages in thread
From: Mark Brown @ 2011-10-26 13:36 UTC (permalink / raw)
To: Linus Walleij
Cc: netdev, Steve Glendinning, Mathieu Poirer, Robert Marklund,
Linus Walleij
On Wed, Oct 26, 2011 at 01:05:04PM +0200, Linus Walleij wrote:
> From: Robert Marklund <robert.marklund@stericsson.com>
>
> 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.
Reviewed-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
but it does look like the code could be simplified with the
regulator_bulk API - it'd mean you wouldn't need to do per regulator
API calls and would do all your unwinding if the second operation fails.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2011-10-26 13:36 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-10-26 11:05 [PATCH 2/2 v2] net/smsc911x: Add regulator support Linus Walleij
2011-10-26 13:36 ` Mark Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).