aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2013-10-10 06:28:48 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-10-10 20:23:14 -0400
commit33cf00e5708290f7e57d949219ef443a2aef34e0 (patch)
tree9099e5cc31154c90472b2afbeaf72e3df786d309 /drivers/spi
parenta76e9bd89ae70fdfff5fd1ca47756a35d10c5f3f (diff)
spi: attach/detach SPI device to the ACPI power domain
If the SPI device is enumerated from ACPI namespace (it has an ACPI handle) it might have ACPI methods that needs to be called in order to transition the device to different power states (such as _PSx). We follow what has been done for platform and I2C buses here and attach the SPI device to the ACPI power domain if the device has an ACPI handle. This makes sure that the device is powered on when its ->probe() is called. For non-ACPI devices this patch is a no-op. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Acked-by: Mark Brown <broonie@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 9e039c60c068..740f9ddda227 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -240,15 +240,27 @@ EXPORT_SYMBOL_GPL(spi_bus_type);
240static int spi_drv_probe(struct device *dev) 240static int spi_drv_probe(struct device *dev)
241{ 241{
242 const struct spi_driver *sdrv = to_spi_driver(dev->driver); 242 const struct spi_driver *sdrv = to_spi_driver(dev->driver);
243 struct spi_device *spi = to_spi_device(dev);
244 int ret;
245
246 acpi_dev_pm_attach(&spi->dev, true);
247 ret = sdrv->probe(spi);
248 if (ret)
249 acpi_dev_pm_detach(&spi->dev, true);
243 250
244 return sdrv->probe(to_spi_device(dev)); 251 return ret;
245} 252}
246 253
247static int spi_drv_remove(struct device *dev) 254static int spi_drv_remove(struct device *dev)
248{ 255{
249 const struct spi_driver *sdrv = to_spi_driver(dev->driver); 256 const struct spi_driver *sdrv = to_spi_driver(dev->driver);
257 struct spi_device *spi = to_spi_device(dev);
258 int ret;
259
260 ret = sdrv->remove(spi);
261 acpi_dev_pm_detach(&spi->dev, true);
250 262
251 return sdrv->remove(to_spi_device(dev)); 263 return ret;
252} 264}
253 265
254static void spi_drv_shutdown(struct device *dev) 266static void spi_drv_shutdown(struct device *dev)
@@ -1025,8 +1037,10 @@ static acpi_status acpi_spi_add_device(acpi_handle handle, u32 level,
1025 return AE_OK; 1037 return AE_OK;
1026 } 1038 }
1027 1039
1040 adev->power.flags.ignore_parent = true;
1028 strlcpy(spi->modalias, dev_name(&adev->dev), sizeof(spi->modalias)); 1041 strlcpy(spi->modalias, dev_name(&adev->dev), sizeof(spi->modalias));
1029 if (spi_add_device(spi)) { 1042 if (spi_add_device(spi)) {
1043 adev->power.flags.ignore_parent = false;
1030 dev_err(&master->dev, "failed to add SPI device %s from ACPI\n", 1044 dev_err(&master->dev, "failed to add SPI device %s from ACPI\n",
1031 dev_name(&adev->dev)); 1045 dev_name(&adev->dev));
1032 spi_dev_put(spi); 1046 spi_dev_put(spi);