From 98e4c28b7ec390c2dad6a4c69d69629c0f7e8b10 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Mon, 14 Nov 2005 21:21:18 +0100 Subject: [PATCH] pcmcia: new suspend core Move the suspend and resume methods out of the event handler, and into special functions. Also use these functions for pre- and post-reset, as almost all drivers already do, and the remaining ones can easily be converted. Bugfix to include/pcmcia/ds.c Signed-off-by: Andrew Morton Signed-off-by: Dominik Brodowski --- drivers/isdn/hisax/sedlbauer_cs.c | 50 ++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 22 deletions(-) (limited to 'drivers/isdn/hisax/sedlbauer_cs.c') diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index dc334aa..27dce7c 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c @@ -553,6 +553,32 @@ static void sedlbauer_release(dev_link_t *link) } /* sedlbauer_release */ +static int sedlbauer_suspend(struct pcmcia_device *p_dev) +{ + dev_link_t *link = dev_to_instance(p_dev); + local_info_t *dev = link->priv; + + link->state |= DEV_SUSPEND; + dev->stop = 1; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); + + return 0; +} + +static int sedlbauer_resume(struct pcmcia_device *p_dev) +{ + dev_link_t *link = dev_to_instance(p_dev); + local_info_t *dev = link->priv; + + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_request_configuration(link->handle, &link->conf); + dev->stop = 0; + + return 0; +} + /*====================================================================== The card status event handler. Mostly, this schedules other @@ -569,7 +595,6 @@ static int sedlbauer_event(event_t event, int priority, event_callback_args_t *args) { dev_link_t *link = args->client_data; - local_info_t *dev = link->priv; DEBUG(1, "sedlbauer_event(0x%06x)\n", event); @@ -585,27 +610,6 @@ static int sedlbauer_event(event_t event, int priority, link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; sedlbauer_config(link); break; - case CS_EVENT_PM_SUSPEND: - link->state |= DEV_SUSPEND; - /* Fall through... */ - case CS_EVENT_RESET_PHYSICAL: - /* Mark the device as stopped, to block IO until later */ - dev->stop = 1; - if (link->state & DEV_CONFIG) - 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); - dev->stop = 0; - /* - In a normal driver, additional code may go here to restore - the device state and restart IO. - */ - break; } return 0; } /* sedlbauer_event */ @@ -631,6 +635,8 @@ static struct pcmcia_driver sedlbauer_driver = { .event = sedlbauer_event, .detach = sedlbauer_detach, .id_table = sedlbauer_ids, + .suspend = sedlbauer_suspend, + .resume = sedlbauer_resume, }; static int __init init_sedlbauer_cs(void) -- cgit v1.1 From cc3b4866bee996c922e875b8c8efe9f0d8803aae Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Mon, 14 Nov 2005 21:23:14 +0100 Subject: [PATCH] pcmcia: unify detach, REMOVAL_EVENT handlers into one remove callback Unify the "detach" and REMOVAL_EVENT handlers to one "remove" function. Old functionality is preserved, for the moment. Signed-off-by: Dominik Brodowski --- drivers/isdn/hisax/sedlbauer_cs.c | 38 +++++++------------------------------- 1 file changed, 7 insertions(+), 31 deletions(-) (limited to 'drivers/isdn/hisax/sedlbauer_cs.c') diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index 27dce7c..d2386f6 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c @@ -107,7 +107,7 @@ static int sedlbauer_event(event_t event, int priority, */ static dev_link_t *sedlbauer_attach(void); -static void sedlbauer_detach(dev_link_t *); +static void sedlbauer_detach(struct pcmcia_device *p_dev); /* You'll also need to prototype all the functions that will actually @@ -230,7 +230,7 @@ static dev_link_t *sedlbauer_attach(void) ret = pcmcia_register_client(&link->handle, &client_reg); if (ret != CS_SUCCESS) { cs_error(link->handle, RegisterClient, ret); - sedlbauer_detach(link); + sedlbauer_detach(link->handle); return NULL; } @@ -246,8 +246,9 @@ static dev_link_t *sedlbauer_attach(void) ======================================================================*/ -static void sedlbauer_detach(dev_link_t *link) +static void sedlbauer_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); dev_link_t **linkp; DEBUG(0, "sedlbauer_detach(0x%p)\n", link); @@ -258,25 +259,11 @@ static void sedlbauer_detach(dev_link_t *link) if (*linkp == NULL) return; - /* - If the device is currently configured and active, we won't - actually delete it yet. Instead, it is marked so that when - the release() function is called, that will trigger a proper - detach(). - */ if (link->state & DEV_CONFIG) { -#ifdef PCMCIA_DEBUG - printk(KERN_DEBUG "sedlbauer_cs: detach postponed, '%s' " - "still locked\n", link->dev->dev_name); -#endif - link->state |= DEV_STALE_LINK; - return; + ((local_info_t *)link->priv)->stop = 1; + sedlbauer_release(link); } - /* Break the link with Card Services */ - if (link->handle) - pcmcia_deregister_client(link->handle); - /* Unlink device structure, and free it */ *linkp = link->next; /* This points to the parent local_info_t struct */ @@ -547,10 +534,6 @@ static void sedlbauer_release(dev_link_t *link) if (link->irq.AssignedIRQ) pcmcia_release_irq(link->handle, &link->irq); link->state &= ~DEV_CONFIG; - - if (link->state & DEV_STALE_LINK) - sedlbauer_detach(link); - } /* sedlbauer_release */ static int sedlbauer_suspend(struct pcmcia_device *p_dev) @@ -599,13 +582,6 @@ static int sedlbauer_event(event_t event, int priority, DEBUG(1, "sedlbauer_event(0x%06x)\n", event); switch (event) { - case CS_EVENT_CARD_REMOVAL: - link->state &= ~DEV_PRESENT; - if (link->state & DEV_CONFIG) { - ((local_info_t *)link->priv)->stop = 1; - sedlbauer_release(link); - } - break; case CS_EVENT_CARD_INSERTION: link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; sedlbauer_config(link); @@ -633,7 +609,7 @@ static struct pcmcia_driver sedlbauer_driver = { }, .attach = sedlbauer_attach, .event = sedlbauer_event, - .detach = sedlbauer_detach, + .remove = sedlbauer_detach, .id_table = sedlbauer_ids, .suspend = sedlbauer_suspend, .resume = sedlbauer_resume, -- cgit v1.1 From b463581154f3f3eecda27cae60df813fefcd84d3 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Mon, 14 Nov 2005 21:25:35 +0100 Subject: [PATCH] pcmcia: remove dev_list from drivers The linked list of devices managed by each PCMCIA driver is, in very most cases, unused. Therefore, remove it from many drivers. Signed-off-by: Dominik Brodowski --- drivers/isdn/hisax/sedlbauer_cs.c | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) (limited to 'drivers/isdn/hisax/sedlbauer_cs.c') diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index d2386f6..814b32a 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c @@ -134,18 +134,7 @@ static dev_info_t dev_info = "sedlbauer_cs"; device numbers are used to derive the corresponding array index. */ -static dev_link_t *dev_list = NULL; - /* - A dev_link_t structure has fields for most things that are needed - to keep track of a socket, but there will usually be some device - specific information that also needs to be kept track of. The - 'priv' pointer in a dev_link_t structure can be used to point to - a device-specific private data structure, like this. - - To simplify the data structure handling, we actually include the - dev_link_t structure in the device's private data structure. - A driver needs to provide a dev_node_t structure for each device on a card. In some cases, there is only one device per card (for example, ethernet cards, modems). In other cases, there may be @@ -222,8 +211,7 @@ static dev_link_t *sedlbauer_attach(void) link->conf.IntType = INT_MEMORY_AND_IO; /* Register with Card Services */ - link->next = dev_list; - dev_list = link; + link->next = NULL; client_reg.dev_info = &dev_info; client_reg.Version = 0x0210; client_reg.event_callback_args.client_data = link; @@ -249,23 +237,14 @@ static dev_link_t *sedlbauer_attach(void) static void sedlbauer_detach(struct pcmcia_device *p_dev) { dev_link_t *link = dev_to_instance(p_dev); - dev_link_t **linkp; DEBUG(0, "sedlbauer_detach(0x%p)\n", link); - - /* Locate device structure */ - for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) - if (*linkp == link) break; - if (*linkp == NULL) - return; if (link->state & DEV_CONFIG) { - ((local_info_t *)link->priv)->stop = 1; - sedlbauer_release(link); + ((local_info_t *)link->priv)->stop = 1; + sedlbauer_release(link); } - /* Unlink device structure, and free it */ - *linkp = link->next; /* This points to the parent local_info_t struct */ kfree(link->priv); } /* sedlbauer_detach */ @@ -623,7 +602,6 @@ static int __init init_sedlbauer_cs(void) static void __exit exit_sedlbauer_cs(void) { pcmcia_unregister_driver(&sedlbauer_driver); - BUG_ON(dev_list != NULL); } module_init(init_sedlbauer_cs); -- cgit v1.1 From f8cfa618dccbdc6dab5297f75779566a388a98fd Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Mon, 14 Nov 2005 21:25:51 +0100 Subject: [PATCH] pcmcia: unify attach, EVENT_CARD_INSERTION handlers into one probe callback Unify the EVENT_CARD_INSERTION and "attach" callbacks to one unified probe() callback. As all in-kernel drivers are changed to this new callback, there will be no temporary backwards-compatibility. Inside a probe() function, each driver _must_ set struct pcmcia_device *p_dev->instance and instance->handle correctly. With these patches, the basic driver interface for 16-bit PCMCIA drivers now has the classic four callbacks known also from other buses: int (*probe) (struct pcmcia_device *dev); void (*remove) (struct pcmcia_device *dev); int (*suspend) (struct pcmcia_device *dev); int (*resume) (struct pcmcia_device *dev); Signed-off-by: Dominik Brodowski --- drivers/isdn/hisax/sedlbauer_cs.c | 75 +++++---------------------------------- 1 file changed, 9 insertions(+), 66 deletions(-) (limited to 'drivers/isdn/hisax/sedlbauer_cs.c') diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index 814b32a..6f5213a 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c @@ -97,8 +97,6 @@ module_param(protocol, int, 0); static void sedlbauer_config(dev_link_t *link); static void sedlbauer_release(dev_link_t *link); -static int sedlbauer_event(event_t event, int priority, - event_callback_args_t *args); /* The attach() and detach() entry points are used to create and destroy @@ -106,7 +104,6 @@ static int sedlbauer_event(event_t event, int priority, needed to manage one actual PCMCIA card. */ -static dev_link_t *sedlbauer_attach(void); static void sedlbauer_detach(struct pcmcia_device *p_dev); /* @@ -117,24 +114,6 @@ static void sedlbauer_detach(struct pcmcia_device *p_dev); */ /* - The dev_info variable is the "key" that is used to match up this - device driver with appropriate cards, through the card configuration - database. -*/ - -static dev_info_t dev_info = "sedlbauer_cs"; - -/* - A linked list of "instances" of the sedlbauer device. Each actual - PCMCIA card corresponds to one device instance, and is described - by one dev_link_t structure (defined in ds.h). - - You may not want to use a linked list for this -- for example, the - memory card driver uses an array of dev_link_t pointers, where minor - device numbers are used to derive the corresponding array index. -*/ - -/* A driver needs to provide a dev_node_t structure for each device on a card. In some cases, there is only one device per card (for example, ethernet cards, modems). In other cases, there may be @@ -169,18 +148,16 @@ typedef struct local_info_t { ======================================================================*/ -static dev_link_t *sedlbauer_attach(void) +static int sedlbauer_attach(struct pcmcia_device *p_dev) { local_info_t *local; dev_link_t *link; - client_reg_t client_reg; - int ret; DEBUG(0, "sedlbauer_attach()\n"); /* Allocate space for private device-specific data */ local = kmalloc(sizeof(local_info_t), GFP_KERNEL); - if (!local) return NULL; + if (!local) return -ENOMEM; memset(local, 0, sizeof(local_info_t)); local->cardnr = -1; link = &local->link; link->priv = local; @@ -210,19 +187,13 @@ static dev_link_t *sedlbauer_attach(void) link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - /* Register with Card Services */ - link->next = NULL; - client_reg.dev_info = &dev_info; - client_reg.Version = 0x0210; - client_reg.event_callback_args.client_data = link; - ret = pcmcia_register_client(&link->handle, &client_reg); - if (ret != CS_SUCCESS) { - cs_error(link->handle, RegisterClient, ret); - sedlbauer_detach(link->handle); - return NULL; - } + link->handle = p_dev; + p_dev->instance = link; - return link; + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + sedlbauer_config(link); + + return 0; } /* sedlbauer_attach */ /*====================================================================== @@ -541,33 +512,6 @@ static int sedlbauer_resume(struct pcmcia_device *p_dev) return 0; } -/*====================================================================== - - The card status event handler. Mostly, this schedules other - stuff to run after an event is received. - - When a CARD_REMOVAL event is received, we immediately set a - private flag to block future accesses to this device. All the - functions that actually access the device should check this flag - to make sure the card is still present. - -======================================================================*/ - -static int sedlbauer_event(event_t event, int priority, - event_callback_args_t *args) -{ - dev_link_t *link = args->client_data; - - DEBUG(1, "sedlbauer_event(0x%06x)\n", event); - - switch (event) { - case CS_EVENT_CARD_INSERTION: - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - sedlbauer_config(link); - break; - } - return 0; -} /* sedlbauer_event */ static struct pcmcia_device_id sedlbauer_ids[] = { PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "speed star II", "V 3.1", 0x81fb79f5, 0xf3612e1d, 0x6b95c78a), @@ -586,8 +530,7 @@ static struct pcmcia_driver sedlbauer_driver = { .drv = { .name = "sedlbauer_cs", }, - .attach = sedlbauer_attach, - .event = sedlbauer_event, + .probe = sedlbauer_attach, .remove = sedlbauer_detach, .id_table = sedlbauer_ids, .suspend = sedlbauer_suspend, -- cgit v1.1