Skip to content

Commit e17465f

Browse files
andy-shevbroonie
authored andcommitted
spi: pxa2xx: Move PM runtime handling to the glue drivers
PCI and platform buses have different defaults for runtime PM. In particular PCI probe is assumed to be called when PM runtime is enabled by the PCI core. In this case if we try enable it again the PM runtime complaints with pxa2xx_spi_pci 0000:00:07.0: Unbalanced pm_runtime_enable! Fix this by moving PM runtime handling from the SPI PXA2xx core to the glue drivers. Fixes: cc16069 ("spi: pxa2xx: Convert PCI driver to use spi-pxa2xx code directly") Fixes: 3d8f037 ("spi: pxa2xx: Move platform driver to a separate file") Fixes: 20ade9b ("spi: pxa2xx: Extract pxa2xx_spi_platform_*() callbacks") Signed-off-by: Andy Shevchenko <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 9a8fc29 commit e17465f

File tree

3 files changed

+35
-17
lines changed

3 files changed

+35
-17
lines changed

drivers/spi/spi-pxa2xx-pci.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/module.h>
1212
#include <linux/pci.h>
1313
#include <linux/pm.h>
14+
#include <linux/pm_runtime.h>
1415
#include <linux/sprintf.h>
1516
#include <linux/string.h>
1617
#include <linux/types.h>
@@ -297,11 +298,23 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev,
297298
return ret;
298299
ssp->irq = pci_irq_vector(dev, 0);
299300

300-
return pxa2xx_spi_probe(&dev->dev, ssp, pdata);
301+
ret = pxa2xx_spi_probe(&dev->dev, ssp, pdata);
302+
if (ret)
303+
return ret;
304+
305+
pm_runtime_set_autosuspend_delay(&dev->dev, 50);
306+
pm_runtime_use_autosuspend(&dev->dev);
307+
pm_runtime_put_autosuspend(&dev->dev);
308+
pm_runtime_allow(&dev->dev);
309+
310+
return 0;
301311
}
302312

303313
static void pxa2xx_spi_pci_remove(struct pci_dev *dev)
304314
{
315+
pm_runtime_forbid(&dev->dev);
316+
pm_runtime_get_noresume(&dev->dev);
317+
305318
pxa2xx_spi_remove(&dev->dev);
306319
}
307320

drivers/spi/spi-pxa2xx-platform.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <linux/init.h>
88
#include <linux/mod_devicetable.h>
99
#include <linux/platform_device.h>
10+
#include <linux/pm_runtime.h>
1011
#include <linux/property.h>
1112
#include <linux/types.h>
1213

@@ -142,6 +143,7 @@ static int pxa2xx_spi_platform_probe(struct platform_device *pdev)
142143
struct pxa2xx_spi_controller *platform_info;
143144
struct device *dev = &pdev->dev;
144145
struct ssp_device *ssp;
146+
int ret;
145147

146148
platform_info = dev_get_platdata(dev);
147149
if (!platform_info) {
@@ -156,12 +158,28 @@ static int pxa2xx_spi_platform_probe(struct platform_device *pdev)
156158
if (!ssp)
157159
ssp = &platform_info->ssp;
158160

159-
return pxa2xx_spi_probe(dev, ssp, platform_info);
161+
pm_runtime_set_autosuspend_delay(dev, 50);
162+
pm_runtime_use_autosuspend(dev);
163+
pm_runtime_set_active(dev);
164+
pm_runtime_enable(dev);
165+
166+
ret = pxa2xx_spi_probe(dev, ssp, platform_info);
167+
if (ret)
168+
pm_runtime_disable(dev);
169+
170+
return ret;
160171
}
161172

162173
static void pxa2xx_spi_platform_remove(struct platform_device *pdev)
163174
{
164-
pxa2xx_spi_remove(&pdev->dev);
175+
struct device *dev = &pdev->dev;
176+
177+
pm_runtime_get_sync(dev);
178+
179+
pxa2xx_spi_remove(dev);
180+
181+
pm_runtime_put_noidle(dev);
182+
pm_runtime_disable(dev);
165183
}
166184

167185
static const struct acpi_device_id pxa2xx_spi_acpi_match[] = {

drivers/spi/spi-pxa2xx.c

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,24 +1449,16 @@ int pxa2xx_spi_probe(struct device *dev, struct ssp_device *ssp,
14491449
}
14501450
}
14511451

1452-
pm_runtime_set_autosuspend_delay(dev, 50);
1453-
pm_runtime_use_autosuspend(dev);
1454-
pm_runtime_set_active(dev);
1455-
pm_runtime_enable(dev);
1456-
14571452
/* Register with the SPI framework */
14581453
dev_set_drvdata(dev, drv_data);
14591454
status = spi_register_controller(controller);
14601455
if (status) {
14611456
dev_err_probe(dev, status, "problem registering SPI controller\n");
1462-
goto out_error_pm_runtime_enabled;
1457+
goto out_error_clock_enabled;
14631458
}
14641459

14651460
return status;
14661461

1467-
out_error_pm_runtime_enabled:
1468-
pm_runtime_disable(dev);
1469-
14701462
out_error_clock_enabled:
14711463
clk_disable_unprepare(ssp->clk);
14721464

@@ -1483,8 +1475,6 @@ void pxa2xx_spi_remove(struct device *dev)
14831475
struct driver_data *drv_data = dev_get_drvdata(dev);
14841476
struct ssp_device *ssp = drv_data->ssp;
14851477

1486-
pm_runtime_get_sync(dev);
1487-
14881478
spi_unregister_controller(drv_data->controller);
14891479

14901480
/* Disable the SSP at the peripheral and SOC level */
@@ -1495,9 +1485,6 @@ void pxa2xx_spi_remove(struct device *dev)
14951485
if (drv_data->controller_info->enable_dma)
14961486
pxa2xx_spi_dma_release(drv_data);
14971487

1498-
pm_runtime_put_noidle(dev);
1499-
pm_runtime_disable(dev);
1500-
15011488
/* Release IRQ */
15021489
free_irq(ssp->irq, drv_data);
15031490
}

0 commit comments

Comments
 (0)