aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pnp/card.c25
-rw-r--r--drivers/pnp/driver.c20
-rw-r--r--include/linux/pnp.h5
3 files changed, 50 insertions, 0 deletions
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c
index bd7c966ea2d7..0ecbe4edbec1 100644
--- a/drivers/pnp/card.c
+++ b/drivers/pnp/card.c
@@ -69,6 +69,7 @@ static int card_probe(struct pnp_card * card, struct pnp_card_driver * drv)
69 return 0; 69 return 0;
70 clink->card = card; 70 clink->card = card;
71 clink->driver = drv; 71 clink->driver = drv;
72 clink->pm_state = PMSG_ON;
72 if (drv->probe) { 73 if (drv->probe) {
73 if (drv->probe(clink, id)>=0) 74 if (drv->probe(clink, id)>=0)
74 return 1; 75 return 1;
@@ -333,6 +334,28 @@ void pnp_release_card_device(struct pnp_dev * dev)
333 up_write(&dev->dev.bus->subsys.rwsem); 334 up_write(&dev->dev.bus->subsys.rwsem);
334} 335}
335 336
337/*
338 * suspend/resume callbacks
339 */
340static int card_suspend(struct pnp_dev *dev, pm_message_t state)
341{
342 struct pnp_card_link *link = dev->card_link;
343 if (link->pm_state.event == state.event)
344 return 0;
345 link->pm_state = state;
346 return link->driver->suspend(link, state);
347}
348
349static int card_resume(struct pnp_dev *dev)
350{
351 struct pnp_card_link *link = dev->card_link;
352 if (link->pm_state.event == PM_EVENT_ON)
353 return 0;
354 link->pm_state = PMSG_ON;
355 link->driver->resume(link);
356 return 0;
357}
358
336/** 359/**
337 * pnp_register_card_driver - registers a PnP card driver with the PnP Layer 360 * pnp_register_card_driver - registers a PnP card driver with the PnP Layer
338 * @drv: pointer to the driver to register 361 * @drv: pointer to the driver to register
@@ -348,6 +371,8 @@ int pnp_register_card_driver(struct pnp_card_driver * drv)
348 drv->link.flags = drv->flags; 371 drv->link.flags = drv->flags;
349 drv->link.probe = NULL; 372 drv->link.probe = NULL;
350 drv->link.remove = &card_remove_first; 373 drv->link.remove = &card_remove_first;
374 drv->link.suspend = drv->suspend ? card_suspend : NULL;
375 drv->link.resume = drv->resume ? card_resume : NULL;
351 376
352 spin_lock(&pnp_lock); 377 spin_lock(&pnp_lock);
353 list_add_tail(&drv->global_list, &pnp_card_drivers); 378 list_add_tail(&drv->global_list, &pnp_card_drivers);
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c
index d3ccce706ab4..ea2cb9a8b21d 100644
--- a/drivers/pnp/driver.c
+++ b/drivers/pnp/driver.c
@@ -146,10 +146,30 @@ static int pnp_bus_match(struct device *dev, struct device_driver *drv)
146 return 1; 146 return 1;
147} 147}
148 148
149static int pnp_bus_suspend(struct device *dev, pm_message_t state)
150{
151 struct pnp_dev * pnp_dev = to_pnp_dev(dev);
152 struct pnp_driver * pnp_drv = pnp_dev->driver;
153
154 if (pnp_drv && pnp_drv->suspend)
155 return pnp_drv->suspend(pnp_dev, state);
156 return 0;
157}
158
159static void pnp_bus_resume(struct device *dev)
160{
161 struct pnp_dev * pnp_dev = to_pnp_dev(dev);
162 struct pnp_driver * pnp_drv = pnp_dev->driver;
163
164 if (pnp_drv && pnp_drv->resume)
165 pnp_drv->resume(pnp_dev);
166}
149 167
150struct bus_type pnp_bus_type = { 168struct bus_type pnp_bus_type = {
151 .name = "pnp", 169 .name = "pnp",
152 .match = pnp_bus_match, 170 .match = pnp_bus_match,
171 .suspend = pnp_bus_suspend,
172 .resume = pnp_bus_resume,
153}; 173};
154 174
155 175
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index 584d57cb393a..472319fcf631 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -162,6 +162,7 @@ struct pnp_card_link {
162 struct pnp_card * card; 162 struct pnp_card * card;
163 struct pnp_card_driver * driver; 163 struct pnp_card_driver * driver;
164 void * driver_data; 164 void * driver_data;
165 pm_message_t pm_state;
165}; 166};
166 167
167static inline void *pnp_get_card_drvdata (struct pnp_card_link *pcard) 168static inline void *pnp_get_card_drvdata (struct pnp_card_link *pcard)
@@ -294,6 +295,8 @@ struct pnp_driver {
294 unsigned int flags; 295 unsigned int flags;
295 int (*probe) (struct pnp_dev *dev, const struct pnp_device_id *dev_id); 296 int (*probe) (struct pnp_dev *dev, const struct pnp_device_id *dev_id);
296 void (*remove) (struct pnp_dev *dev); 297 void (*remove) (struct pnp_dev *dev);
298 int (*suspend) (struct pnp_dev *dev, pm_message_t state);
299 int (*resume) (struct pnp_dev *dev);
297 struct device_driver driver; 300 struct device_driver driver;
298}; 301};
299 302
@@ -306,6 +309,8 @@ struct pnp_card_driver {
306 unsigned int flags; 309 unsigned int flags;
307 int (*probe) (struct pnp_card_link *card, const struct pnp_card_device_id *card_id); 310 int (*probe) (struct pnp_card_link *card, const struct pnp_card_device_id *card_id);
308 void (*remove) (struct pnp_card_link *card); 311 void (*remove) (struct pnp_card_link *card);
312 int (*suspend) (struct pnp_card_link *card, pm_message_t state);
313 int (*resume) (struct pnp_card_link *card);
309 struct pnp_driver link; 314 struct pnp_driver link;
310}; 315};
311 316