diff options
-rw-r--r-- | drivers/pnp/card.c | 25 | ||||
-rw-r--r-- | drivers/pnp/driver.c | 20 | ||||
-rw-r--r-- | include/linux/pnp.h | 5 |
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 | */ | ||
340 | static 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 | |||
349 | static 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 | ||
149 | static 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 | |||
159 | static 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 | ||
150 | struct bus_type pnp_bus_type = { | 168 | struct 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 | ||
167 | static inline void *pnp_get_card_drvdata (struct pnp_card_link *pcard) | 168 | static 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 | ||