diff options
Diffstat (limited to 'drivers/pnp/driver.c')
| -rw-r--r-- | drivers/pnp/driver.c | 53 | 
1 files changed, 47 insertions, 6 deletions
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c index d1dbb9df53f..f748cc8cbb0 100644 --- a/drivers/pnp/driver.c +++ b/drivers/pnp/driver.c @@ -154,7 +154,7 @@ static int pnp_bus_match(struct device *dev, struct device_driver *drv)  	return 1;  } -static int pnp_bus_suspend(struct device *dev, pm_message_t state) +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; @@ -163,6 +163,13 @@ static int pnp_bus_suspend(struct device *dev, pm_message_t state)  	if (!pnp_drv)  		return 0; +	if (pnp_drv->driver.pm && pnp_drv->driver.pm->suspend) { +		error = pnp_drv->driver.pm->suspend(dev); +		suspend_report_result(pnp_drv->driver.pm->suspend, error); +		if (error) +			return error; +	} +  	if (pnp_drv->suspend) {  		error = pnp_drv->suspend(pnp_dev, state);  		if (error) @@ -180,6 +187,21 @@ static int pnp_bus_suspend(struct device *dev, pm_message_t state)  	return 0;  } +static int pnp_bus_suspend(struct device *dev) +{ +	return __pnp_bus_suspend(dev, PMSG_SUSPEND); +} + +static int pnp_bus_freeze(struct device *dev) +{ +	return __pnp_bus_suspend(dev, PMSG_FREEZE); +} + +static int pnp_bus_poweroff(struct device *dev) +{ +	return __pnp_bus_suspend(dev, PMSG_HIBERNATE); +} +  static int pnp_bus_resume(struct device *dev)  {  	struct pnp_dev *pnp_dev = to_pnp_dev(dev); @@ -189,8 +211,11 @@ static int pnp_bus_resume(struct device *dev)  	if (!pnp_drv)  		return 0; -	if (pnp_dev->protocol->resume) -		pnp_dev->protocol->resume(pnp_dev); +	if (pnp_dev->protocol->resume) { +		error = pnp_dev->protocol->resume(pnp_dev); +		if (error) +			return error; +	}  	if (pnp_can_write(pnp_dev)) {  		error = pnp_start_dev(pnp_dev); @@ -198,6 +223,12 @@ static int pnp_bus_resume(struct device *dev)  			return error;  	} +	if (pnp_drv->driver.pm && pnp_drv->driver.pm->resume) { +		error = pnp_drv->driver.pm->resume(dev); +		if (error) +			return error; +	} +  	if (pnp_drv->resume) {  		error = pnp_drv->resume(pnp_dev);  		if (error) @@ -207,15 +238,25 @@ static int pnp_bus_resume(struct device *dev)  	return 0;  } +static const struct dev_pm_ops pnp_bus_dev_pm_ops = { +	/* Suspend callbacks */ +	.suspend = pnp_bus_suspend, +	.resume = pnp_bus_resume, +	/* Hibernate callbacks */ +	.freeze = pnp_bus_freeze, +	.thaw = pnp_bus_resume, +	.poweroff = pnp_bus_poweroff, +	.restore = pnp_bus_resume, +}; +  struct bus_type pnp_bus_type = {  	.name    = "pnp",  	.match   = pnp_bus_match,  	.probe   = pnp_device_probe,  	.remove  = pnp_device_remove,  	.shutdown = pnp_device_shutdown, -	.suspend = pnp_bus_suspend, -	.resume  = pnp_bus_resume, -	.dev_attrs = pnp_interface_attrs, +	.pm	 = &pnp_bus_dev_pm_ops, +	.dev_groups = pnp_dev_groups,  };  int pnp_register_driver(struct pnp_driver *drv)  | 
