addressed runtime-PM functionality issues that arose from system integration testing.
changes include the following 1) ensure pm_runtime_put is called in case of SPI timeout 2) removed runtime-PM methods and initialization these methods are called by the subsystem PM and the SPI subsystem does not currenly support runtime-PM so providing these callbacks serves no useful purpose 3) changed pm_runtime_put/get to operate on parent device this links the 2 drivers so runtime-PM suspend/resume of controller driver is gated by the activity of both drivers. Signed-off-by: Russ Gorby <russ.go...@intel.com> --- drivers/serial/ifx6x60.c | 125 ++++++---------------------------------------- 1 files changed, 16 insertions(+), 109 deletions(-) diff --git a/drivers/serial/ifx6x60.c b/drivers/serial/ifx6x60.c index 18ba9ec..abffc86 100644 --- a/drivers/serial/ifx6x60.c +++ b/drivers/serial/ifx6x60.c @@ -134,6 +134,7 @@ static void ifx_spi_power_state_set(struct ifx_spi_device *ifx_dev, unsigned char val) { unsigned long flags; + int ret; spin_lock_irqsave(&ifx_dev->power_lock, flags); @@ -142,8 +143,9 @@ ifx_spi_power_state_set(struct ifx_spi_device *ifx_dev, unsigned char val) * tell power system */ if (!ifx_dev->power_status) { - dev_dbg(&ifx_dev->spi_dev->dev, "pm_runtime_get called"); - pm_runtime_get(&ifx_dev->spi_dev->dev); + ret = pm_runtime_get(ifx_dev->spi_dev->dev.parent); + if (ret < 0) + pr_warn("%s: rt_get failed: %d", DRVNAME, ret); } ifx_dev->power_status |= val; @@ -161,15 +163,16 @@ static void ifx_spi_power_state_clear(struct ifx_spi_device *ifx_dev, unsigned char val) { unsigned long flags; + int ret; spin_lock_irqsave(&ifx_dev->power_lock, flags); if (ifx_dev->power_status) { ifx_dev->power_status &= ~val; if (!ifx_dev->power_status) { - dev_dbg(&ifx_dev->spi_dev->dev, - "pm_runtime_put called"); - pm_runtime_put(&ifx_dev->spi_dev->dev); + ret = pm_runtime_put(ifx_dev->spi_dev->dev.parent); + if (ret < 0) + pr_warn("%s: rt_put failed: %d", DRVNAME, ret); } } @@ -273,6 +276,7 @@ static void ifx_spi_timeout(unsigned long arg) } dev_warn(&ifx_dev->spi_dev->dev, "*** SPI Timeout ***"); + ifx_spi_power_state_clear(ifx_dev, IFX_SPI_POWER_DATA_PENDING); ifx_spi_ttyhangup(ifx_dev); mrdy_set_low(ifx_dev); clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags); @@ -621,7 +625,6 @@ static int ifx_spi_write(struct tty_struct *tty, const unsigned char *buf, int srdy_value; dev_dbg(&ifx_dev->spi_dev->dev, "%s called", __func__); - tx_count = kfifo_in_locked(&port_data->tx_fifo, tmp_buf, count, &port_data->fifo_lock); ifx_ser->tty_write_cnt += tx_count; @@ -641,7 +644,7 @@ static int ifx_spi_write(struct tty_struct *tty, const unsigned char *buf, * @tty: our tty device * * Report how much data we can accept before we drop bytes. As we use - * a simple FIFO this is nice and easy. + * a simple FIFO this is nice and easy. */ static int ifx_spi_write_room(struct tty_struct *tty) { @@ -1148,7 +1151,12 @@ static void ifx_spi_io(unsigned long data) return; } } else { - /* print error if called in progress */ + /* + * ifx_spi_complete processing can extend beyond + * the point where the modem drops SRDY and so we can + * get a second SRDY interrupt for new I/O before + * completion processing is finished + */ dev_dbg(&ifx_dev->spi_dev->dev, "spi_io called while SPI in progress"); ifx_dev->write_pending = 1; @@ -1591,9 +1599,6 @@ static int ifx_spi_spi_probe(struct spi_device *spi) goto error_ret2; } - /* set pm runtime power state and register with power system */ - pm_runtime_set_active(&spi->dev); - pm_runtime_enable(&spi->dev); /* handle case that modem is already signaling SRDY */ /* no outgoing tty open at this point, this just satisfies the @@ -1680,103 +1685,6 @@ static int ifx_spi_spi_resume(struct spi_device *spi) return 0; } -/** - * ifx_spi_pm_suspend - suspend modem on system suspend - * @dev: device being suspended - * - * Suspend the modem. No action needed on Intel MID platforms, may - * need extending for other systems. - */ -static int ifx_spi_pm_suspend(struct device *dev) -{ - int retval = 0; - struct spi_device *spi = to_spi_device(dev); - - dev_dbg(&spi->dev, "pm suspend"); - - return retval; -} - -/** - * ifx_spi_pm_resume - resume modem on system resume - * @dev: device being suspended - * - * Allow the modem to resume. No action needed. - * - * FIXME: do we need to reset anything here ? - */ -static int ifx_spi_pm_resume(struct device *dev) -{ - int retval = 0; - struct spi_device *spi = to_spi_device(dev); - - dev_dbg(&spi->dev, "pm resume"); - - return retval; -} - -/** - * ifx_spi_pm_runtime_resume - suspend modem - * @dev: device being suspended - * - * Allow the modem to resume. No action needed. - */ -static int ifx_spi_pm_runtime_resume(struct device *dev) -{ - int retval = 0; - struct spi_device *spi = to_spi_device(dev); - - dev_dbg(&spi->dev, "pm runtime resume"); - - return retval; -} - -/** - * ifx_spi_pm_runtime_suspend - suspend modem - * @dev: device being suspended - * - * Allow the modem to suspend and thus suspend to continue up the - * device tree. - */ -static int ifx_spi_pm_runtime_suspend(struct device *dev) -{ - int retval = 0; - struct spi_device *spi = to_spi_device(dev); - - dev_dbg(&spi->dev, "pm runtime_suspend"); - - return retval; -} - -/** - * ifx_spi_pm_runtime_idle - check if modem idle - * @dev: our device - * - * Check conditions and queue runtime suspend if idle. - * FIXME: What locking/races are there on the power_status variable ? - */ -static int ifx_spi_pm_runtime_idle(struct device *dev) -{ - int retval = 0; - struct spi_device *spi = to_spi_device(dev); - struct ifx_spi_device *ifx_dev = spi_get_drvdata(spi); - - dev_dbg(&spi->dev, "pm runtime_idle"); - - if (!ifx_dev->power_status) - pm_runtime_suspend(dev); - - return retval; -} - -static const struct dev_pm_ops ifx_spi_pm = { - .resume = ifx_spi_pm_resume, - .suspend = ifx_spi_pm_suspend, - .runtime_resume = ifx_spi_pm_runtime_resume, - .runtime_suspend = ifx_spi_pm_runtime_suspend, - .runtime_idle = ifx_spi_pm_runtime_idle -}; - static const struct spi_device_id ifx_spi_device_ids[] = { { MODEMNAME_6160, IFX_6160 }, { MODEMNAME_6260, IFX_6260 }, @@ -1789,7 +1697,6 @@ static const struct spi_driver ifx_spi_driver = { .driver = { .name = DRVNAME, .bus = &spi_bus_type, - .pm = &ifx_spi_pm, .owner = THIS_MODULE}, .id_table = ifx_spi_device_ids, .probe = ifx_spi_spi_probe, -- 1.6.0.6 _______________________________________________ MeeGo-kernel mailing list MeeGo-kernel@lists.meego.com http://lists.meego.com/listinfo/meego-kernel