Linux MIPS Architecture development
 help / color / mirror / Atom feed
From: Rodolfo Giometti <giometti@linux.it>
To: Linux MIPS <linux-mips@linux-mips.org>
Cc: ppopov@mvista.com
Subject: Power management for au1000_eth.c
Date: Wed, 5 Apr 2006 17:47:11 +0200	[thread overview]
Message-ID: <20060405154711.GL7029@enneenne.com> (raw)

Hello,

I'm trying to add power management support to au1000_eth.c driver.

In order to to it I 've added these two functions:

   static int au1000_eth_suspend(struct device *dev, pm_message_t state, u32 level)
   {
   	struct net_device *ndev = dev_get_drvdata(dev);
   	struct au1000_private *aup = (struct au1000_private *) ndev->priv;

   	if (!ndev)
   		return 0;

   	switch (level) {
   	case SUSPEND_DISABLE :
   		if (netif_running(ndev))
   			netif_device_detach(ndev);

   		break;
   	
   	case SUSPEND_SAVE_STATE :
   		/* bring the device out of reset, otherwise accessing to mii
   	 	 * will hang */
   		*aup->enable = MAC_EN_CLOCK_ENABLE;
   		au_sync_delay(2);
   		*aup->enable = MAC_EN_RESET0 | MAC_EN_RESET1 | 
   				MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE;
   		au_sync_delay(2);

   		if (aup->phy_ops->phy_suspend)
   			aup->phy_ops->phy_suspend(ndev, aup->phy_addr, level);

   		del_timer_sync(&aup->timer); /* FIXME: REMOVED??? */
   		reset_mac(ndev);

   		netif_stop_queue(ndev);

   		free_irq(ndev->irq, dev);

   		break;

   	case SUSPEND_POWER_DOWN :

   		break;
   	}

   	return 0;
   }

   static int au1000_eth_resume(struct device *dev, u32 level)
   {
   	struct net_device *ndev = dev_get_drvdata(dev);
   	struct au1000_private *aup = (struct au1000_private *) ndev->priv;
           u32 flags;
   	int ret;

   	if (!ndev)
   		return 0;

   	switch (level) {
   	case RESUME_RESTORE_STATE :
   		/* bring the device out of reset, otherwise accessing to mii
   	 	 * will hang */
   		*aup->enable = MAC_EN_CLOCK_ENABLE;
   		au_sync_delay(2);
   		*aup->enable = MAC_EN_RESET0 | MAC_EN_RESET1 | 
   				MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE;
   		au_sync_delay(2);

   		if (aup->phy_ops->phy_resume)
   			aup->phy_ops->phy_resume(ndev, aup->phy_addr, level);
   		aup->phy_ops->phy_init(ndev, aup->phy_addr);

   		/* au1000_init() expects that the device is in reset state.
   		 */
   		reset_mac(ndev); /* au1000_init() expects the device in reset */
   		au1000_init(ndev);

   	        ret = request_irq(ndev->irq, &au1000_interrupt, 0, ndev->name, ndev);
   	        if (ret) {
   			printk(KERN_ERR "%s: unable to get IRQ %d\n",
   	                                 ndev->name, ndev->irq);
   			return ret; //FIXME
   		}

   		init_timer(&aup->timer); /* used in ioctl() */
   		aup->timer.expires = RUN_AT((3*HZ));
   		aup->timer.data = (unsigned long) ndev;
   		aup->timer.function = &au1000_timer; /* timer handler */
   		add_timer(&aup->timer);

   		break;

   	case RESUME_ENABLE :
   		if (netif_running(ndev))
   			netif_device_attach(ndev);

   		break;
   	}

   	return 0;
   }

The problem is that after wakeup the system hangs or returns lots of
errors like:

   Reserved instruction in kernel code in arch/mips/kernel/traps.c::do_ri, line 706[#169]:

Note that if I compile the driver as a module and removing it before
sleeping and reinstalling it after wake up the system (and the
ethernet) works correctly...

Suggestions? :)

Thanks in advance,

Rodolfo

-- 

GNU/Linux Solutions                  e-mail:    giometti@enneenne.com
Linux Device Driver                             giometti@gnudd.com
Embedded Systems                     		giometti@linux.it
UNIX programming                     phone:     +39 349 2432127

             reply	other threads:[~2006-04-05 15:35 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-04-05 15:47 Rodolfo Giometti [this message]
2006-04-05 22:23 ` Power management for au1000_eth.c Rodolfo Giometti
2006-04-05 22:26   ` [PATCH] Oops! - " Rodolfo Giometti
2006-04-06 14:43     ` Sergei Shtylyov
2006-04-06 15:50       ` Rodolfo Giometti
2006-04-19 18:46         ` [PATCH] au1000_eth.c probe code straightened up Sergei Shtylyov
2006-05-02 15:09           ` [PATCH] au1000_eth.c Power Management, driver registration and module support Rodolfo Giometti
2006-05-03  7:47             ` Rodolfo Giometti
2006-05-31 15:01             ` Sergei Shtylyov
2006-05-31 15:21               ` Rodolfo Giometti
2006-04-06 17:10       ` Oops! - Re: Power management for au1000_eth.c Jordan Crouse

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20060405154711.GL7029@enneenne.com \
    --to=giometti@linux.it \
    --cc=linux-mips@linux-mips.org \
    --cc=ppopov@mvista.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox