net: smsc911x: Add GPIO functions to the driver
Add hooks to control the relevant Gpio pin from the Ethernet driver. This allows the driver to drive the GPIO line low or high during suspend and resume for power management. Change-Id: Idfcf547501198d155d314a30923fd4de440840a9 Signed-off-by: Rohit Vaswani <rvaswani@codeaurora.org>
This commit is contained in:
committed by
Stephen Boyd
parent
e61d2b7e6e
commit
66e014b30f
@@ -44,6 +44,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/timer.h>
|
||||
@@ -954,7 +955,7 @@ static void smsc911x_phy_adjust_link(struct net_device *dev)
|
||||
(!pdata->using_extphy)) {
|
||||
/* Restore original GPIO configuration */
|
||||
pdata->gpio_setting = pdata->gpio_orig_setting;
|
||||
smsc911x_reg_write(pdata, GPIO_CFG,
|
||||
smsc911x_reg_write(pdata, SMSC_GPIO_CFG,
|
||||
pdata->gpio_setting);
|
||||
}
|
||||
} else {
|
||||
@@ -962,7 +963,7 @@ static void smsc911x_phy_adjust_link(struct net_device *dev)
|
||||
/* Check global setting that LED1
|
||||
* usage is 10/100 indicator */
|
||||
pdata->gpio_setting = smsc911x_reg_read(pdata,
|
||||
GPIO_CFG);
|
||||
SMSC_GPIO_CFG);
|
||||
if ((pdata->gpio_setting & GPIO_CFG_LED1_EN_) &&
|
||||
(!pdata->using_extphy)) {
|
||||
/* Force 10/100 LED off, after saving
|
||||
@@ -973,7 +974,7 @@ static void smsc911x_phy_adjust_link(struct net_device *dev)
|
||||
pdata->gpio_setting |= (GPIO_CFG_GPIOBUF0_
|
||||
| GPIO_CFG_GPIODIR0_
|
||||
| GPIO_CFG_GPIOD0_);
|
||||
smsc911x_reg_write(pdata, GPIO_CFG,
|
||||
smsc911x_reg_write(pdata, SMSC_GPIO_CFG,
|
||||
pdata->gpio_setting);
|
||||
}
|
||||
}
|
||||
@@ -1485,7 +1486,7 @@ static int smsc911x_open(struct net_device *dev)
|
||||
SMSC_WARN(pdata, ifup,
|
||||
"Timed out waiting for EEPROM busy bit to clear");
|
||||
|
||||
smsc911x_reg_write(pdata, GPIO_CFG, 0x70070000);
|
||||
smsc911x_reg_write(pdata, SMSC_GPIO_CFG, 0x70070000);
|
||||
|
||||
/* The soft reset above cleared the device's MAC address,
|
||||
* restore it from local copy (set in probe) */
|
||||
@@ -1931,9 +1932,9 @@ smsc911x_ethtool_getregs(struct net_device *dev, struct ethtool_regs *regs,
|
||||
|
||||
static void smsc911x_eeprom_enable_access(struct smsc911x_data *pdata)
|
||||
{
|
||||
unsigned int temp = smsc911x_reg_read(pdata, GPIO_CFG);
|
||||
unsigned int temp = smsc911x_reg_read(pdata, SMSC_GPIO_CFG);
|
||||
temp &= ~GPIO_CFG_EEPR_EN_;
|
||||
smsc911x_reg_write(pdata, GPIO_CFG, temp);
|
||||
smsc911x_reg_write(pdata, SMSC_GPIO_CFG, temp);
|
||||
msleep(1);
|
||||
}
|
||||
|
||||
@@ -2241,6 +2242,12 @@ static int __devexit smsc911x_drv_remove(struct platform_device *pdev)
|
||||
|
||||
SMSC_TRACE(pdata, ifdown, "Stopping driver");
|
||||
|
||||
if (pdata->config.has_reset_gpio) {
|
||||
gpio_set_value_cansleep(pdata->config.reset_gpio, 0);
|
||||
gpio_free(pdata->config.reset_gpio);
|
||||
}
|
||||
|
||||
|
||||
phy_disconnect(pdata->phy_dev);
|
||||
pdata->phy_dev = NULL;
|
||||
mdiobus_unregister(pdata->mii_bus);
|
||||
@@ -2528,6 +2535,10 @@ static int smsc911x_suspend(struct device *dev)
|
||||
PMT_CTRL_PM_MODE_D1_ | PMT_CTRL_WOL_EN_ |
|
||||
PMT_CTRL_ED_EN_ | PMT_CTRL_PME_EN_);
|
||||
|
||||
/* Drive the GPIO Ethernet_Reset Line low to Suspend */
|
||||
if (pdata->config.has_reset_gpio)
|
||||
gpio_set_value_cansleep(pdata->config.reset_gpio, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2537,6 +2548,10 @@ static int smsc911x_resume(struct device *dev)
|
||||
struct smsc911x_data *pdata = netdev_priv(ndev);
|
||||
unsigned int to = 100;
|
||||
|
||||
if (pdata->config.has_reset_gpio)
|
||||
gpio_set_value_cansleep(pdata->config.reset_gpio, 1);
|
||||
|
||||
|
||||
/* Note 3.11 from the datasheet:
|
||||
* "When the LAN9220 is in a power saving state, a write of any
|
||||
* data to the BYTE_TEST register will wake-up the device."
|
||||
|
||||
@@ -236,7 +236,7 @@
|
||||
#define PMT_CTRL_PME_EN_ 0x00000002
|
||||
#define PMT_CTRL_READY_ 0x00000001
|
||||
|
||||
#define GPIO_CFG 0x88
|
||||
#define SMSC_GPIO_CFG 0x88
|
||||
#define GPIO_CFG_LED3_EN_ 0x40000000
|
||||
#define GPIO_CFG_LED2_EN_ 0x20000000
|
||||
#define GPIO_CFG_LED1_EN_ 0x10000000
|
||||
|
||||
@@ -24,7 +24,14 @@
|
||||
#include <linux/phy.h>
|
||||
|
||||
/* platform_device configuration data, should be assigned to
|
||||
* the platform_device's dev.platform_data */
|
||||
* the platform_device's dev.platform_data
|
||||
* Provides 2 GPIO-related fields
|
||||
* reset_gpio to map the ETHERNET_RESET GPIO pin
|
||||
* has_reset_gpio - to indicate if the GPIO is being set(1) or not(0)
|
||||
* and remain compatible with architectures not using GPIOs
|
||||
* Default would be zero if its not being assigned any value.
|
||||
* Both values would need to set in the appropriate board file
|
||||
*/
|
||||
struct smsc911x_platform_config {
|
||||
unsigned int irq_polarity;
|
||||
unsigned int irq_type;
|
||||
@@ -32,6 +39,8 @@ struct smsc911x_platform_config {
|
||||
unsigned int shift;
|
||||
phy_interface_t phy_interface;
|
||||
unsigned char mac[6];
|
||||
unsigned char has_reset_gpio;
|
||||
unsigned int reset_gpio;
|
||||
};
|
||||
|
||||
/* Constants for platform_device irq polarity configuration */
|
||||
|
||||
Reference in New Issue
Block a user