aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/phy')
-rw-r--r--drivers/net/phy/mdio-gpio.c13
-rw-r--r--drivers/net/phy/mdio_bus.c56
-rw-r--r--drivers/net/phy/phy.c41
3 files changed, 61 insertions, 49 deletions
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c
index af28ff7ae176..33984b737233 100644
--- a/drivers/net/phy/mdio-gpio.c
+++ b/drivers/net/phy/mdio-gpio.c
@@ -202,16 +202,21 @@ static int __devinit mdio_ofgpio_probe(struct of_device *ofdev,
202{ 202{
203 struct device_node *np = NULL; 203 struct device_node *np = NULL;
204 struct mdio_gpio_platform_data *pdata; 204 struct mdio_gpio_platform_data *pdata;
205 int ret;
205 206
206 pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); 207 pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
207 if (!pdata) 208 if (!pdata)
208 return -ENOMEM; 209 return -ENOMEM;
209 210
210 pdata->mdc = of_get_gpio(ofdev->node, 0); 211 ret = of_get_gpio(ofdev->node, 0);
211 pdata->mdio = of_get_gpio(ofdev->node, 1); 212 if (ret < 0)
212
213 if (pdata->mdc < 0 || pdata->mdio < 0)
214 goto out_free; 213 goto out_free;
214 pdata->mdc = ret;
215
216 ret = of_get_gpio(ofdev->node, 1);
217 if (ret < 0)
218 goto out_free;
219 pdata->mdio = ret;
215 220
216 while ((np = of_get_next_child(ofdev->node, np))) 221 while ((np = of_get_next_child(ofdev->node, np)))
217 if (!strcmp(np->type, "ethernet-phy")) 222 if (!strcmp(np->type, "ethernet-phy"))
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 811a637695ca..b754020cbe75 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -21,6 +21,7 @@
21#include <linux/interrupt.h> 21#include <linux/interrupt.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/device.h>
24#include <linux/netdevice.h> 25#include <linux/netdevice.h>
25#include <linux/etherdevice.h> 26#include <linux/etherdevice.h>
26#include <linux/skbuff.h> 27#include <linux/skbuff.h>
@@ -98,7 +99,7 @@ int mdiobus_register(struct mii_bus *bus)
98 bus->dev.parent = bus->parent; 99 bus->dev.parent = bus->parent;
99 bus->dev.class = &mdio_bus_class; 100 bus->dev.class = &mdio_bus_class;
100 bus->dev.groups = NULL; 101 bus->dev.groups = NULL;
101 dev_set_name(&bus->dev, bus->id); 102 dev_set_name(&bus->dev, "%s", bus->id);
102 103
103 err = device_register(&bus->dev); 104 err = device_register(&bus->dev);
104 if (err) { 105 if (err) {
@@ -286,33 +287,58 @@ static int mdio_bus_match(struct device *dev, struct device_driver *drv)
286 (phydev->phy_id & phydrv->phy_id_mask)); 287 (phydev->phy_id & phydrv->phy_id_mask));
287} 288}
288 289
290static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
291{
292 struct device_driver *drv = phydev->dev.driver;
293 struct phy_driver *phydrv = to_phy_driver(drv);
294 struct net_device *netdev = phydev->attached_dev;
295
296 if (!drv || !phydrv->suspend)
297 return false;
298
299 /* PHY not attached? May suspend. */
300 if (!netdev)
301 return true;
302
303 /*
304 * Don't suspend PHY if the attched netdev parent may wakeup.
305 * The parent may point to a PCI device, as in tg3 driver.
306 */
307 if (netdev->dev.parent && device_may_wakeup(netdev->dev.parent))
308 return false;
309
310 /*
311 * Also don't suspend PHY if the netdev itself may wakeup. This
312 * is the case for devices w/o underlaying pwr. mgmt. aware bus,
313 * e.g. SoC devices.
314 */
315 if (device_may_wakeup(&netdev->dev))
316 return false;
317
318 return true;
319}
320
289/* Suspend and resume. Copied from platform_suspend and 321/* Suspend and resume. Copied from platform_suspend and
290 * platform_resume 322 * platform_resume
291 */ 323 */
292static int mdio_bus_suspend(struct device * dev, pm_message_t state) 324static int mdio_bus_suspend(struct device * dev, pm_message_t state)
293{ 325{
294 int ret = 0; 326 struct phy_driver *phydrv = to_phy_driver(dev->driver);
295 struct device_driver *drv = dev->driver;
296 struct phy_driver *phydrv = to_phy_driver(drv);
297 struct phy_device *phydev = to_phy_device(dev); 327 struct phy_device *phydev = to_phy_device(dev);
298 328
299 if (drv && phydrv->suspend && !device_may_wakeup(phydev->dev.parent)) 329 if (!mdio_bus_phy_may_suspend(phydev))
300 ret = phydrv->suspend(phydev); 330 return 0;
301 331 return phydrv->suspend(phydev);
302 return ret;
303} 332}
304 333
305static int mdio_bus_resume(struct device * dev) 334static int mdio_bus_resume(struct device * dev)
306{ 335{
307 int ret = 0; 336 struct phy_driver *phydrv = to_phy_driver(dev->driver);
308 struct device_driver *drv = dev->driver;
309 struct phy_driver *phydrv = to_phy_driver(drv);
310 struct phy_device *phydev = to_phy_device(dev); 337 struct phy_device *phydev = to_phy_device(dev);
311 338
312 if (drv && phydrv->resume && !device_may_wakeup(phydev->dev.parent)) 339 if (!mdio_bus_phy_may_suspend(phydev))
313 ret = phydrv->resume(phydev); 340 return 0;
314 341 return phydrv->resume(phydev);
315 return ret;
316} 342}
317 343
318struct bus_type mdio_bus_type = { 344struct bus_type mdio_bus_type = {
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index e4ede6080c9d..58b73b08dde0 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -414,7 +414,6 @@ EXPORT_SYMBOL(phy_start_aneg);
414 414
415static void phy_change(struct work_struct *work); 415static void phy_change(struct work_struct *work);
416static void phy_state_machine(struct work_struct *work); 416static void phy_state_machine(struct work_struct *work);
417static void phy_timer(unsigned long data);
418 417
419/** 418/**
420 * phy_start_machine - start PHY state machine tracking 419 * phy_start_machine - start PHY state machine tracking
@@ -434,11 +433,8 @@ void phy_start_machine(struct phy_device *phydev,
434{ 433{
435 phydev->adjust_state = handler; 434 phydev->adjust_state = handler;
436 435
437 INIT_WORK(&phydev->state_queue, phy_state_machine); 436 INIT_DELAYED_WORK(&phydev->state_queue, phy_state_machine);
438 init_timer(&phydev->phy_timer); 437 schedule_delayed_work(&phydev->state_queue, jiffies + HZ);
439 phydev->phy_timer.function = &phy_timer;
440 phydev->phy_timer.data = (unsigned long) phydev;
441 mod_timer(&phydev->phy_timer, jiffies + HZ);
442} 438}
443 439
444/** 440/**
@@ -451,8 +447,7 @@ void phy_start_machine(struct phy_device *phydev,
451 */ 447 */
452void phy_stop_machine(struct phy_device *phydev) 448void phy_stop_machine(struct phy_device *phydev)
453{ 449{
454 del_timer_sync(&phydev->phy_timer); 450 cancel_delayed_work_sync(&phydev->state_queue);
455 cancel_work_sync(&phydev->state_queue);
456 451
457 mutex_lock(&phydev->lock); 452 mutex_lock(&phydev->lock);
458 if (phydev->state > PHY_UP) 453 if (phydev->state > PHY_UP)
@@ -680,11 +675,9 @@ static void phy_change(struct work_struct *work)
680 if (err) 675 if (err)
681 goto irq_enable_err; 676 goto irq_enable_err;
682 677
683 /* Stop timer and run the state queue now. The work function for 678 /* reschedule state queue work to run as soon as possible */
684 * state_queue will start the timer up again. 679 cancel_delayed_work_sync(&phydev->state_queue);
685 */ 680 schedule_delayed_work(&phydev->state_queue, 0);
686 del_timer(&phydev->phy_timer);
687 schedule_work(&phydev->state_queue);
688 681
689 return; 682 return;
690 683
@@ -761,14 +754,13 @@ EXPORT_SYMBOL(phy_start);
761/** 754/**
762 * phy_state_machine - Handle the state machine 755 * phy_state_machine - Handle the state machine
763 * @work: work_struct that describes the work to be done 756 * @work: work_struct that describes the work to be done
764 *
765 * Description: Scheduled by the state_queue workqueue each time
766 * phy_timer is triggered.
767 */ 757 */
768static void phy_state_machine(struct work_struct *work) 758static void phy_state_machine(struct work_struct *work)
769{ 759{
760 struct delayed_work *dwork =
761 container_of(work, struct delayed_work, work);
770 struct phy_device *phydev = 762 struct phy_device *phydev =
771 container_of(work, struct phy_device, state_queue); 763 container_of(dwork, struct phy_device, state_queue);
772 int needs_aneg = 0; 764 int needs_aneg = 0;
773 int err = 0; 765 int err = 0;
774 766
@@ -946,17 +938,6 @@ static void phy_state_machine(struct work_struct *work)
946 if (err < 0) 938 if (err < 0)
947 phy_error(phydev); 939 phy_error(phydev);
948 940
949 mod_timer(&phydev->phy_timer, jiffies + PHY_STATE_TIME * HZ); 941 schedule_delayed_work(&phydev->state_queue,
950} 942 jiffies + PHY_STATE_TIME * HZ);
951
952/* PHY timer which schedules the state machine work */
953static void phy_timer(unsigned long data)
954{
955 struct phy_device *phydev = (struct phy_device *)data;
956
957 /*
958 * PHY I/O operations can potentially sleep so we ensure that
959 * it's done from a process context
960 */
961 schedule_work(&phydev->state_queue);
962} 943}