diff options
Diffstat (limited to 'drivers/net/phy')
-rw-r--r-- | drivers/net/phy/mdio-gpio.c | 13 | ||||
-rw-r--r-- | drivers/net/phy/mdio_bus.c | 56 | ||||
-rw-r--r-- | drivers/net/phy/phy.c | 41 |
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 | ||
290 | static 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 | */ |
292 | static int mdio_bus_suspend(struct device * dev, pm_message_t state) | 324 | static 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 | ||
305 | static int mdio_bus_resume(struct device * dev) | 334 | static 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 | ||
318 | struct bus_type mdio_bus_type = { | 344 | struct 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 | ||
415 | static void phy_change(struct work_struct *work); | 415 | static void phy_change(struct work_struct *work); |
416 | static void phy_state_machine(struct work_struct *work); | 416 | static void phy_state_machine(struct work_struct *work); |
417 | static 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 | */ |
452 | void phy_stop_machine(struct phy_device *phydev) | 448 | void 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 | */ |
768 | static void phy_state_machine(struct work_struct *work) | 758 | static 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 */ | ||
953 | static 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 | } |