diff options
Diffstat (limited to 'drivers/net/ucc_geth.c')
-rw-r--r-- | drivers/net/ucc_geth.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index d2ca61d3dffc..7fb96f33bade 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c | |||
@@ -3497,6 +3497,10 @@ static int ucc_geth_open(struct net_device *dev) | |||
3497 | napi_enable(&ugeth->napi); | 3497 | napi_enable(&ugeth->napi); |
3498 | netif_start_queue(dev); | 3498 | netif_start_queue(dev); |
3499 | 3499 | ||
3500 | device_set_wakeup_capable(&dev->dev, | ||
3501 | qe_alive_during_sleep() || ugeth->phydev->irq); | ||
3502 | device_set_wakeup_enable(&dev->dev, ugeth->wol_en); | ||
3503 | |||
3500 | return err; | 3504 | return err; |
3501 | 3505 | ||
3502 | err: | 3506 | err: |
@@ -3561,6 +3565,85 @@ static void ucc_geth_timeout(struct net_device *dev) | |||
3561 | schedule_work(&ugeth->timeout_work); | 3565 | schedule_work(&ugeth->timeout_work); |
3562 | } | 3566 | } |
3563 | 3567 | ||
3568 | |||
3569 | #ifdef CONFIG_PM | ||
3570 | |||
3571 | static int ucc_geth_suspend(struct of_device *ofdev, pm_message_t state) | ||
3572 | { | ||
3573 | struct net_device *ndev = dev_get_drvdata(&ofdev->dev); | ||
3574 | struct ucc_geth_private *ugeth = netdev_priv(ndev); | ||
3575 | |||
3576 | if (!netif_running(ndev)) | ||
3577 | return 0; | ||
3578 | |||
3579 | napi_disable(&ugeth->napi); | ||
3580 | |||
3581 | /* | ||
3582 | * Disable the controller, otherwise we'll wakeup on any network | ||
3583 | * activity. | ||
3584 | */ | ||
3585 | ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); | ||
3586 | |||
3587 | if (ugeth->wol_en & WAKE_MAGIC) { | ||
3588 | setbits32(ugeth->uccf->p_uccm, UCC_GETH_UCCE_MPD); | ||
3589 | setbits32(&ugeth->ug_regs->maccfg2, MACCFG2_MPE); | ||
3590 | ucc_fast_enable(ugeth->uccf, COMM_DIR_RX_AND_TX); | ||
3591 | } else if (!(ugeth->wol_en & WAKE_PHY)) { | ||
3592 | phy_stop(ugeth->phydev); | ||
3593 | } | ||
3594 | |||
3595 | return 0; | ||
3596 | } | ||
3597 | |||
3598 | static int ucc_geth_resume(struct of_device *ofdev) | ||
3599 | { | ||
3600 | struct net_device *ndev = dev_get_drvdata(&ofdev->dev); | ||
3601 | struct ucc_geth_private *ugeth = netdev_priv(ndev); | ||
3602 | int err; | ||
3603 | |||
3604 | if (!netif_running(ndev)) | ||
3605 | return 0; | ||
3606 | |||
3607 | if (qe_alive_during_sleep()) { | ||
3608 | if (ugeth->wol_en & WAKE_MAGIC) { | ||
3609 | ucc_fast_disable(ugeth->uccf, COMM_DIR_RX_AND_TX); | ||
3610 | clrbits32(&ugeth->ug_regs->maccfg2, MACCFG2_MPE); | ||
3611 | clrbits32(ugeth->uccf->p_uccm, UCC_GETH_UCCE_MPD); | ||
3612 | } | ||
3613 | ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); | ||
3614 | } else { | ||
3615 | /* | ||
3616 | * Full reinitialization is required if QE shuts down | ||
3617 | * during sleep. | ||
3618 | */ | ||
3619 | ucc_geth_memclean(ugeth); | ||
3620 | |||
3621 | err = ucc_geth_init_mac(ugeth); | ||
3622 | if (err) { | ||
3623 | ugeth_err("%s: Cannot initialize MAC, aborting.", | ||
3624 | ndev->name); | ||
3625 | return err; | ||
3626 | } | ||
3627 | } | ||
3628 | |||
3629 | ugeth->oldlink = 0; | ||
3630 | ugeth->oldspeed = 0; | ||
3631 | ugeth->oldduplex = -1; | ||
3632 | |||
3633 | phy_stop(ugeth->phydev); | ||
3634 | phy_start(ugeth->phydev); | ||
3635 | |||
3636 | napi_enable(&ugeth->napi); | ||
3637 | netif_start_queue(ndev); | ||
3638 | |||
3639 | return 0; | ||
3640 | } | ||
3641 | |||
3642 | #else | ||
3643 | #define ucc_geth_suspend NULL | ||
3644 | #define ucc_geth_resume NULL | ||
3645 | #endif | ||
3646 | |||
3564 | static phy_interface_t to_phy_interface(const char *phy_connection_type) | 3647 | static phy_interface_t to_phy_interface(const char *phy_connection_type) |
3565 | { | 3648 | { |
3566 | if (strcasecmp(phy_connection_type, "mii") == 0) | 3649 | if (strcasecmp(phy_connection_type, "mii") == 0) |
@@ -3852,6 +3935,8 @@ static struct of_platform_driver ucc_geth_driver = { | |||
3852 | .match_table = ucc_geth_match, | 3935 | .match_table = ucc_geth_match, |
3853 | .probe = ucc_geth_probe, | 3936 | .probe = ucc_geth_probe, |
3854 | .remove = ucc_geth_remove, | 3937 | .remove = ucc_geth_remove, |
3938 | .suspend = ucc_geth_suspend, | ||
3939 | .resume = ucc_geth_resume, | ||
3855 | }; | 3940 | }; |
3856 | 3941 | ||
3857 | static int __init ucc_geth_init(void) | 3942 | static int __init ucc_geth_init(void) |