Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 278288
b: refs/heads/master
c: c7e963f
h: refs/heads/master
v: v3
  • Loading branch information
Robert Marklund authored and David S. Miller committed Nov 29, 2011
1 parent ed934bf commit 99ba645
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 12 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1839a6c6f1eb8c0e20dc87d57024a85707f1a2f8
refs/heads/master: c7e963f6888816f04d1f5da0e07bec4e0092f227
111 changes: 100 additions & 11 deletions trunk/drivers/net/ethernet/smsc/smsc911x.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -88,6 +89,8 @@ struct smsc911x_ops {
unsigned int *buf, unsigned int wordcount);
};

#define SMSC911X_NUM_SUPPLIES 2

struct smsc911x_data {
void __iomem *ioaddr;

Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -362,6 +368,76 @@ smsc911x_rx_readfifo_shift(struct smsc911x_data *pdata, unsigned int *buf,
spin_unlock_irqrestore(&pdata->dev_lock, flags);
}

/*
* enable resources, currently just regulators.
*/
static int smsc911x_enable_resources(struct platform_device *pdev)
{
struct net_device *ndev = platform_get_drvdata(pdev);
struct smsc911x_data *pdata = netdev_priv(ndev);
int ret = 0;

ret = regulator_bulk_enable(ARRAY_SIZE(pdata->supplies),
pdata->supplies);
if (ret)
netdev_err(ndev, "failed to enable regulators %d\n",
ret);
return ret;
}

/*
* disable resources, currently just regulators.
*/
static int smsc911x_disable_resources(struct platform_device *pdev)
{
struct net_device *ndev = platform_get_drvdata(pdev);
struct smsc911x_data *pdata = netdev_priv(ndev);
int ret = 0;

ret = regulator_bulk_disable(ARRAY_SIZE(pdata->supplies),
pdata->supplies);
return ret;
}

/*
* Request 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_resources(struct platform_device *pdev)
{
struct net_device *ndev = platform_get_drvdata(pdev);
struct smsc911x_data *pdata = netdev_priv(ndev);
int ret = 0;

/* Request regulators */
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);
return ret;
}

/*
* Free resources, currently just regulators.
*
*/
static void smsc911x_free_resources(struct platform_device *pdev)
{
struct net_device *ndev = platform_get_drvdata(pdev);
struct smsc911x_data *pdata = netdev_priv(ndev);

/* Free regulators */
regulator_bulk_free(ARRAY_SIZE(pdata->supplies),
pdata->supplies);
}

/* 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)
Expand Down Expand Up @@ -2092,6 +2168,9 @@ static int __devexit smsc911x_drv_remove(struct platform_device *pdev)

iounmap(pdata->ioaddr);

(void)smsc911x_disable_resources(pdev);
smsc911x_free_resources(pdev);

free_netdev(dev);

return 0;
Expand Down Expand Up @@ -2218,10 +2297,20 @@ 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_resources(pdev);
if (retval)
goto out_return_resources;

retval = smsc911x_enable_resources(pdev);
if (retval)
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);
Expand All @@ -2233,7 +2322,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 */
Expand All @@ -2244,7 +2333,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)
Expand All @@ -2264,15 +2353,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);
Expand Down Expand Up @@ -2321,12 +2408,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_disable_resources(pdev);
out_return_resources:
smsc911x_free_resources(pdev);
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));
Expand Down

0 comments on commit 99ba645

Please sign in to comment.