[PATCH 4/13] pcmcia: new suspend core
Dominik Brodowski
linux at dominikbrodowski.net
Wed Sep 7 17:36:56 EDT 2005
Add support to the PCMCIA core to move the supend and resume methods out
of the event handler. Also use these functions for pre- and post-reset,
as almost all drivers do it this way anyway. Convert pcnet_cs as an
example.
Signed-off-by: Dominik Brodowski <linux at dominikbrodoswki.net>
---
Documentation/pcmcia/driver-changes.txt | 6 +++
drivers/net/pcmcia/pcnet_cs.c | 58 +++++++++++++++++++-------------
drivers/pcmcia/ds.c | 10 +++++
include/pcmcia/ds.h | 6 +++
4 files changed, 57 insertions(+), 23 deletions(-)
Index: 2.6.13-rc4-git1/drivers/net/pcmcia/pcnet_cs.c
===================================================================
--- 2.6.13-rc4-git1.orig/drivers/net/pcmcia/pcnet_cs.c
+++ 2.6.13-rc4-git1/drivers/net/pcmcia/pcnet_cs.c
@@ -780,6 +780,39 @@ static void pcnet_release(dev_link_t *li
======================================================================*/
+static int pcnet_suspend(struct pcmcia_device *p_dev)
+{
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
+
+ link->state |= DEV_SUSPEND;
+ if (link->state & DEV_CONFIG) {
+ if (link->open)
+ netif_device_detach(dev);
+ pcmcia_release_configuration(link->handle);
+ }
+
+ return 0;
+}
+
+static int pcnet_resume(struct pcmcia_device *p_dev)
+{
+ dev_link_t *link = dev_to_instance(p_dev);
+ struct net_device *dev = link->priv;
+
+ link->state &= ~DEV_SUSPEND;
+ if (link->state & DEV_CONFIG) {
+ pcmcia_request_configuration(link->handle, &link->conf);
+ if (link->open) {
+ pcnet_reset_8390(dev);
+ NS8390_init(dev, 1);
+ netif_device_attach(dev);
+ }
+ }
+
+ return 0;
+}
+
static int pcnet_event(event_t event, int priority,
event_callback_args_t *args)
{
@@ -798,29 +831,6 @@ static int pcnet_event(event_t event, in
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
pcnet_config(link);
break;
- case CS_EVENT_PM_SUSPEND:
- link->state |= DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_RESET_PHYSICAL:
- if (link->state & DEV_CONFIG) {
- if (link->open)
- netif_device_detach(dev);
- pcmcia_release_configuration(link->handle);
- }
- break;
- case CS_EVENT_PM_RESUME:
- link->state &= ~DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_CARD_RESET:
- if (link->state & DEV_CONFIG) {
- pcmcia_request_configuration(link->handle, &link->conf);
- if (link->open) {
- pcnet_reset_8390(dev);
- NS8390_init(dev, 1);
- netif_device_attach(dev);
- }
- }
- break;
}
return 0;
} /* pcnet_event */
@@ -1843,6 +1853,8 @@ static struct pcmcia_driver pcnet_driver
.detach = pcnet_detach,
.owner = THIS_MODULE,
.id_table = pcnet_ids,
+ .suspend = pcnet_suspend,
+ .resume = pcnet_resume,
};
static int __init init_pcnet_cs(void)
Index: 2.6.13-rc4-git1/include/pcmcia/ds.h
===================================================================
--- 2.6.13-rc4-git1.orig/include/pcmcia/ds.h
+++ 2.6.13-rc4-git1/include/pcmcia/ds.h
@@ -137,6 +137,10 @@ struct pcmcia_driver {
int (*event) (event_t event, int priority,
event_callback_args_t *);
void (*detach)(dev_link_t *);
+
+ int (*suspend) (struct pcmcia_device *dev);
+ int (*resume) (struct pcmcia_device *dev);
+
struct module *owner;
struct pcmcia_device_id *id_table;
struct device_driver drv;
@@ -193,6 +197,8 @@ struct pcmcia_device {
#define handle_to_pdev(handle) (handle)
#define handle_to_dev(handle) (handle->dev)
+#define dev_to_instance(dev) (dev->instance);
+
/* error reporting */
void cs_error(client_handle_t handle, int func, int ret);
Index: 2.6.13-rc4-git1/drivers/pcmcia/ds.c
===================================================================
--- 2.6.13-rc4-git1.orig/drivers/pcmcia/ds.c
+++ 2.6.13-rc4-git1/drivers/pcmcia/ds.c
@@ -946,6 +946,16 @@ static int send_event_callback(struct de
if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE))
return 0;
+ if ((data->event == CS_EVENT_PM_SUSPEND) ||
+ (data->event == CS_EVENT_RESET_PHYSICAL)) {
+ if (p_drv->suspend)
+ return p_drv->suspend(p_dev);
+ } else if ((data->event == CS_EVENT_PM_RESUME) ||
+ (data->event == CS_EVENT_CARD_RESET)) {
+ if (p_drv->resume)
+ return p_drv->resume(p_dev);
+ }
+
if (p_drv->event)
return p_drv->event(data->event, data->priority,
&p_dev->event_callback_args);
Index: 2.6.13-rc4-git1/Documentation/pcmcia/driver-changes.txt
===================================================================
--- 2.6.13-rc4-git1.orig/Documentation/pcmcia/driver-changes.txt
+++ 2.6.13-rc4-git1/Documentation/pcmcia/driver-changes.txt
@@ -1,5 +1,11 @@
This file details changes in 2.6 which affect PCMCIA card driver authors:
+* Move suspend, resume and reset out of event handler (as of 2.6.14)
+ int (*suspend) (struct pcmcia_device *dev);
+ int (*resume) (struct pcmcia_device *dev);
+ should be initialized in struct pcmcia_driver, and handle
+ (SUSPEND == RESET_PHYSICAL) and (RESUME == CARD_RESET) events
+
* event handler initialization in struct pcmcia_driver (as of 2.6.13)
The event handler is notified of all events, and must be initialized
as the event() callback in the driver's struct pcmcia_driver.
More information about the linux-pcmcia
mailing list