From 269e4a4122685d0739f0e8e53b440111bf8a03f9 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Wed, 4 Sep 2013 13:37:43 +0300 Subject: spi/pxa2xx: check status register as well to determine if the device is off The current interrupt handler calls pm_runtime_suspended() to check if the device is suspended or not. However, runtime PM status of the device is only set to suspended once all PM runtime suspend hooks have executed. In case of Intel Lynxpoint we have the device bound to the ACPI power domain and its runtime suspend hook will put the device to D3hot (or D3cold if possible). This means that the device is powered off before its state is set to runtime suspended. While in this state the device might get an interrupt that is meant for another device (as the interrupt line is shared), and because the device is powered off accessing its registers will return 0xffffffff that the driver misinterprets as an invalid state. When this happens user will see messages like below on the console: pxa2xx-spi INT33C0:00: bad message state in interrupt handler Fix this by checking the status register for ~0 and returning IRQ_NONE in that case. Signed-off-by: Mika Westerberg Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers/spi/spi-pxa2xx.c') diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 2eb06ee0b32..c1a50674c1e 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -546,8 +546,17 @@ static irqreturn_t ssp_int(int irq, void *dev_id) if (pm_runtime_suspended(&drv_data->pdev->dev)) return IRQ_NONE; - sccr1_reg = read_SSCR1(reg); + /* + * If the device is not yet in RPM suspended state and we get an + * interrupt that is meant for another device, check if status bits + * are all set to one. That means that the device is already + * powered off. + */ status = read_SSSR(reg); + if (status == ~0) + return IRQ_NONE; + + sccr1_reg = read_SSCR1(reg); /* Ignore possible writes if we don't need to write */ if (!(sccr1_reg & SSCR1_TIE)) -- cgit v1.2.3-70-g09d2