[ALSA] PATCH] Add PM support to PnP drivers
Add suspend/resume callback to pnp_driver and pnp_card_driver. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
0ba656d0b2
commit
4c98cfef2e
3 changed files with 50 additions and 0 deletions
|
@ -69,6 +69,7 @@ static int card_probe(struct pnp_card * card, struct pnp_card_driver * drv)
|
||||||
return 0;
|
return 0;
|
||||||
clink->card = card;
|
clink->card = card;
|
||||||
clink->driver = drv;
|
clink->driver = drv;
|
||||||
|
clink->pm_state = PMSG_ON;
|
||||||
if (drv->probe) {
|
if (drv->probe) {
|
||||||
if (drv->probe(clink, id)>=0)
|
if (drv->probe(clink, id)>=0)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -333,6 +334,28 @@ void pnp_release_card_device(struct pnp_dev * dev)
|
||||||
up_write(&dev->dev.bus->subsys.rwsem);
|
up_write(&dev->dev.bus->subsys.rwsem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* suspend/resume callbacks
|
||||||
|
*/
|
||||||
|
static int card_suspend(struct pnp_dev *dev, pm_message_t state)
|
||||||
|
{
|
||||||
|
struct pnp_card_link *link = dev->card_link;
|
||||||
|
if (link->pm_state.event == state.event)
|
||||||
|
return 0;
|
||||||
|
link->pm_state = state;
|
||||||
|
return link->driver->suspend(link, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int card_resume(struct pnp_dev *dev)
|
||||||
|
{
|
||||||
|
struct pnp_card_link *link = dev->card_link;
|
||||||
|
if (link->pm_state.event == PM_EVENT_ON)
|
||||||
|
return 0;
|
||||||
|
link->pm_state = PMSG_ON;
|
||||||
|
link->driver->resume(link);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pnp_register_card_driver - registers a PnP card driver with the PnP Layer
|
* pnp_register_card_driver - registers a PnP card driver with the PnP Layer
|
||||||
* @drv: pointer to the driver to register
|
* @drv: pointer to the driver to register
|
||||||
|
@ -348,6 +371,8 @@ int pnp_register_card_driver(struct pnp_card_driver * drv)
|
||||||
drv->link.flags = drv->flags;
|
drv->link.flags = drv->flags;
|
||||||
drv->link.probe = NULL;
|
drv->link.probe = NULL;
|
||||||
drv->link.remove = &card_remove_first;
|
drv->link.remove = &card_remove_first;
|
||||||
|
drv->link.suspend = drv->suspend ? card_suspend : NULL;
|
||||||
|
drv->link.resume = drv->resume ? card_resume : NULL;
|
||||||
|
|
||||||
spin_lock(&pnp_lock);
|
spin_lock(&pnp_lock);
|
||||||
list_add_tail(&drv->global_list, &pnp_card_drivers);
|
list_add_tail(&drv->global_list, &pnp_card_drivers);
|
||||||
|
|
|
@ -146,10 +146,30 @@ static int pnp_bus_match(struct device *dev, struct device_driver *drv)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int pnp_bus_suspend(struct device *dev, pm_message_t state)
|
||||||
|
{
|
||||||
|
struct pnp_dev * pnp_dev = to_pnp_dev(dev);
|
||||||
|
struct pnp_driver * pnp_drv = pnp_dev->driver;
|
||||||
|
|
||||||
|
if (pnp_drv && pnp_drv->suspend)
|
||||||
|
return pnp_drv->suspend(pnp_dev, state);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pnp_bus_resume(struct device *dev)
|
||||||
|
{
|
||||||
|
struct pnp_dev * pnp_dev = to_pnp_dev(dev);
|
||||||
|
struct pnp_driver * pnp_drv = pnp_dev->driver;
|
||||||
|
|
||||||
|
if (pnp_drv && pnp_drv->resume)
|
||||||
|
pnp_drv->resume(pnp_dev);
|
||||||
|
}
|
||||||
|
|
||||||
struct bus_type pnp_bus_type = {
|
struct bus_type pnp_bus_type = {
|
||||||
.name = "pnp",
|
.name = "pnp",
|
||||||
.match = pnp_bus_match,
|
.match = pnp_bus_match,
|
||||||
|
.suspend = pnp_bus_suspend,
|
||||||
|
.resume = pnp_bus_resume,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -162,6 +162,7 @@ struct pnp_card_link {
|
||||||
struct pnp_card * card;
|
struct pnp_card * card;
|
||||||
struct pnp_card_driver * driver;
|
struct pnp_card_driver * driver;
|
||||||
void * driver_data;
|
void * driver_data;
|
||||||
|
pm_message_t pm_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void *pnp_get_card_drvdata (struct pnp_card_link *pcard)
|
static inline void *pnp_get_card_drvdata (struct pnp_card_link *pcard)
|
||||||
|
@ -294,6 +295,8 @@ struct pnp_driver {
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
int (*probe) (struct pnp_dev *dev, const struct pnp_device_id *dev_id);
|
int (*probe) (struct pnp_dev *dev, const struct pnp_device_id *dev_id);
|
||||||
void (*remove) (struct pnp_dev *dev);
|
void (*remove) (struct pnp_dev *dev);
|
||||||
|
int (*suspend) (struct pnp_dev *dev, pm_message_t state);
|
||||||
|
int (*resume) (struct pnp_dev *dev);
|
||||||
struct device_driver driver;
|
struct device_driver driver;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -306,6 +309,8 @@ struct pnp_card_driver {
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
int (*probe) (struct pnp_card_link *card, const struct pnp_card_device_id *card_id);
|
int (*probe) (struct pnp_card_link *card, const struct pnp_card_device_id *card_id);
|
||||||
void (*remove) (struct pnp_card_link *card);
|
void (*remove) (struct pnp_card_link *card);
|
||||||
|
int (*suspend) (struct pnp_card_link *card, pm_message_t state);
|
||||||
|
int (*resume) (struct pnp_card_link *card);
|
||||||
struct pnp_driver link;
|
struct pnp_driver link;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue