[PATCH 7/7 v2] OMAP: runtime: McSPI driver runtime conversion

Grant Likely grant.likely at secretlab.ca
Thu Dec 30 14:29:57 EST 2010


On Wed, Dec 01, 2010 at 07:32:11PM +0530, Govindraj.R wrote:
> McSPI runtime conversion.
> Changes involves:
> 1) remove clock framework apis to use runtime framework apis.
> 2) context restore from runtime resume which is a callback for get_sync.
> 3) Remove SYSCONFIG(sysc) register handling
>         (a) Remove context save and restore of sysc reg and remove soft reset
>             done from sysc reg as this will be done with hwmod framework.
>         (b) Also cleanup sysc reg bit macros.
> 4) Rename the omap2_mcspi_reset function to omap2_mcspi_master_setup
>    function as with hwmod changes soft reset will be done in
>    hwmod framework itself and use the return value from clock
>    enable function to return for failure scenarios.
> 
> Signed-off-by: Charulatha V <charu at ti.com>
> Signed-off-by: Govindraj.R <govindraj.raja at ti.com>
> Reviewed-by: Partha Basak <p-basak2 at ti.com>

One comment below, but otherwise looks good to me.  Since the majority
of the changes are in arch/arm, feel free to add my Acked-by for the
whole series and merge via the omap tree.  None of my comments are
showstoppers, so I'm even fine with merging them as-is as long as
followup patches are posted to address the comments.

In particular, I'd really like to see the data duplication issue from
the first 4 patches addressed.

Acked-by: Grant Likely <grant.likely at secretlab.ca>


> ---
>  drivers/spi/omap2_mcspi.c |  120 +++++++++++++++++---------------------------
>  1 files changed, 46 insertions(+), 74 deletions(-)
> 
> diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c
> index ad3811e..a1b157f 100644
> --- a/drivers/spi/omap2_mcspi.c
> +++ b/drivers/spi/omap2_mcspi.c
> @@ -33,6 +33,7 @@
>  #include <linux/clk.h>
>  #include <linux/io.h>
>  #include <linux/slab.h>
> +#include <linux/pm_runtime.h>
> 
>  #include <linux/spi/spi.h>
> 
> @@ -46,7 +47,6 @@
>  #define OMAP2_MCSPI_MAX_CTRL 		4
> 
>  #define OMAP2_MCSPI_REVISION		0x00
> -#define OMAP2_MCSPI_SYSCONFIG		0x10
>  #define OMAP2_MCSPI_SYSSTATUS		0x14
>  #define OMAP2_MCSPI_IRQSTATUS		0x18
>  #define OMAP2_MCSPI_IRQENABLE		0x1c
> @@ -63,13 +63,6 @@
> 
>  /* per-register bitmasks: */
> 
> -#define OMAP2_MCSPI_SYSCONFIG_SMARTIDLE	BIT(4)
> -#define OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP	BIT(2)
> -#define OMAP2_MCSPI_SYSCONFIG_AUTOIDLE	BIT(0)
> -#define OMAP2_MCSPI_SYSCONFIG_SOFTRESET	BIT(1)
> -
> -#define OMAP2_MCSPI_SYSSTATUS_RESETDONE	BIT(0)
> -
>  #define OMAP2_MCSPI_MODULCTRL_SINGLE	BIT(0)
>  #define OMAP2_MCSPI_MODULCTRL_MS	BIT(2)
>  #define OMAP2_MCSPI_MODULCTRL_STEST	BIT(3)
> @@ -122,13 +115,12 @@ struct omap2_mcspi {
>  	spinlock_t		lock;
>  	struct list_head	msg_queue;
>  	struct spi_master	*master;
> -	struct clk		*ick;
> -	struct clk		*fck;
>  	/* Virtual base address of the controller */
>  	void __iomem		*base;
>  	unsigned long		phys;
>  	/* SPI1 has 4 channels, while SPI2 has 2 */
>  	struct omap2_mcspi_dma	*dma_channels;
> +	struct  device          *dev;

Inconsistent indentation with the rest of the structure (tabs vs. spaces).

>  };
> 
>  struct omap2_mcspi_cs {
> @@ -144,7 +136,6 @@ struct omap2_mcspi_cs {
>   * corresponding registers are modified.
>   */
>  struct omap2_mcspi_regs {
> -	u32 sysconfig;
>  	u32 modulctrl;
>  	u32 wakeupenable;
>  	struct list_head cs;
> @@ -268,9 +259,6 @@ static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi)
>  	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL,
>  			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].modulctrl);
> 
> -	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_SYSCONFIG,
> -			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].sysconfig);
> -
>  	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE,
>  			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].wakeupenable);
> 
> @@ -280,20 +268,12 @@ static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi)
>  }
>  static void omap2_mcspi_disable_clocks(struct omap2_mcspi *mcspi)
>  {
> -	clk_disable(mcspi->ick);
> -	clk_disable(mcspi->fck);
> +	pm_runtime_put_sync(mcspi->dev);
>  }
> 
>  static int omap2_mcspi_enable_clocks(struct omap2_mcspi *mcspi)
>  {
> -	if (clk_enable(mcspi->ick))
> -		return -ENODEV;
> -	if (clk_enable(mcspi->fck))
> -		return -ENODEV;
> -
> -	omap2_mcspi_restore_ctx(mcspi);
> -
> -	return 0;
> +	return pm_runtime_get_sync(mcspi->dev);
>  }
> 
>  static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit)
> @@ -819,8 +799,9 @@ static int omap2_mcspi_setup(struct spi_device *spi)
>  			return ret;
>  	}
> 
> -	if (omap2_mcspi_enable_clocks(mcspi))
> -		return -ENODEV;
> +	ret = omap2_mcspi_enable_clocks(mcspi);
> +	if (ret < 0)
> +		return ret;
> 
>  	ret = omap2_mcspi_setup_transfer(spi, NULL);
>  	omap2_mcspi_disable_clocks(mcspi);
> @@ -863,10 +844,11 @@ static void omap2_mcspi_work(struct work_struct *work)
>  	struct omap2_mcspi	*mcspi;
> 
>  	mcspi = container_of(work, struct omap2_mcspi, work);
> -	spin_lock_irq(&mcspi->lock);
> 
> -	if (omap2_mcspi_enable_clocks(mcspi))
> -		goto out;
> +	if (omap2_mcspi_enable_clocks(mcspi) < 0)
> +		return;
> +
> +	spin_lock_irq(&mcspi->lock);
> 
>  	/* We only enable one channel at a time -- the one whose message is
>  	 * at the head of the queue -- although this controller would gladly
> @@ -979,10 +961,9 @@ static void omap2_mcspi_work(struct work_struct *work)
>  		spin_lock_irq(&mcspi->lock);
>  	}
> 
> -	omap2_mcspi_disable_clocks(mcspi);
> -
> -out:
>  	spin_unlock_irq(&mcspi->lock);
> +
> +	omap2_mcspi_disable_clocks(mcspi);
>  }
> 
>  static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m)
> @@ -1063,25 +1044,15 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message
> *m)
>  	return 0;
>  }
> 
> -static int __init omap2_mcspi_reset(struct omap2_mcspi *mcspi)
> +static int __init omap2_mcspi_master_setup(struct omap2_mcspi *mcspi)
>  {
>  	struct spi_master	*master = mcspi->master;
>  	u32			tmp;
> +	int ret = 0;
> 
> -	if (omap2_mcspi_enable_clocks(mcspi))
> -		return -1;
> -
> -	mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG,
> -			OMAP2_MCSPI_SYSCONFIG_SOFTRESET);
> -	do {
> -		tmp = mcspi_read_reg(master, OMAP2_MCSPI_SYSSTATUS);
> -	} while (!(tmp & OMAP2_MCSPI_SYSSTATUS_RESETDONE));
> -
> -	tmp = OMAP2_MCSPI_SYSCONFIG_AUTOIDLE |
> -		OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP |
> -		OMAP2_MCSPI_SYSCONFIG_SMARTIDLE;
> -	mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG, tmp);
> -	omap2_mcspi_ctx[master->bus_num - 1].sysconfig = tmp;
> +	ret = omap2_mcspi_enable_clocks(mcspi);
> +	if (ret < 0)
> +		return ret;
> 
>  	tmp = OMAP2_MCSPI_WAKEUPENABLE_WKEN;
>  	mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, tmp);
> @@ -1092,6 +1063,18 @@ static int __init omap2_mcspi_reset(struct omap2_mcspi *mcspi)
>  	return 0;
>  }
> 
> +static int omap_mcspi_runtime_resume(struct device *dev)
> +{
> +	struct omap2_mcspi	*mcspi;
> +	struct spi_master	*master;
> +
> +	master = dev_get_drvdata(dev);
> +	mcspi = spi_master_get_devdata(master);
> +	omap2_mcspi_restore_ctx(mcspi);
> +
> +	return 0;
> +}
> +
> 
>  static int __init omap2_mcspi_probe(struct platform_device *pdev)
>  {
> @@ -1142,34 +1125,22 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)
>  	if (!mcspi->base) {
>  		dev_dbg(&pdev->dev, "can't ioremap MCSPI\n");
>  		status = -ENOMEM;
> -		goto err1aa;
> +		goto err2;
>  	}
> 
> +	mcspi->dev = &pdev->dev;
>  	INIT_WORK(&mcspi->work, omap2_mcspi_work);
> 
>  	spin_lock_init(&mcspi->lock);
>  	INIT_LIST_HEAD(&mcspi->msg_queue);
>  	INIT_LIST_HEAD(&omap2_mcspi_ctx[master->bus_num - 1].cs);
> 
> -	mcspi->ick = clk_get(&pdev->dev, "ick");
> -	if (IS_ERR(mcspi->ick)) {
> -		dev_dbg(&pdev->dev, "can't get mcspi_ick\n");
> -		status = PTR_ERR(mcspi->ick);
> -		goto err1a;
> -	}
> -	mcspi->fck = clk_get(&pdev->dev, "fck");
> -	if (IS_ERR(mcspi->fck)) {
> -		dev_dbg(&pdev->dev, "can't get mcspi_fck\n");
> -		status = PTR_ERR(mcspi->fck);
> -		goto err2;
> -	}
> -
>  	mcspi->dma_channels = kcalloc(master->num_chipselect,
>  			sizeof(struct omap2_mcspi_dma),
>  			GFP_KERNEL);
> 
>  	if (mcspi->dma_channels == NULL)
> -		goto err3;
> +		goto err2;
> 
>  	for (i = 0; i < master->num_chipselect; i++) {
>  		char dma_ch_name[14];
> @@ -1199,8 +1170,10 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)
>  		mcspi->dma_channels[i].dma_tx_sync_dev = dma_res->start;
>  	}
> 
> -	if (omap2_mcspi_reset(mcspi) < 0)
> -		goto err4;
> +	pm_runtime_enable(&pdev->dev);
> +
> +	if (status || omap2_mcspi_master_setup(mcspi) < 0)
> +		goto err3;
> 
>  	status = spi_register_master(master);
>  	if (status < 0)
> @@ -1209,17 +1182,13 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)
>  	return status;
> 
>  err4:
> -	kfree(mcspi->dma_channels);
> +	spi_master_put(master);
>  err3:
> -	clk_put(mcspi->fck);
> +	kfree(mcspi->dma_channels);
>  err2:
> -	clk_put(mcspi->ick);
> -err1a:
> -	iounmap(mcspi->base);
> -err1aa:
>  	release_mem_region(r->start, (r->end - r->start) + 1);
> +	iounmap(mcspi->base);
>  err1:
> -	spi_master_put(master);
>  	return status;
>  }
> 
> @@ -1235,9 +1204,7 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev)
>  	mcspi = spi_master_get_devdata(master);
>  	dma_channels = mcspi->dma_channels;
> 
> -	clk_put(mcspi->fck);
> -	clk_put(mcspi->ick);
> -
> +	omap2_mcspi_disable_clocks(mcspi);
>  	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	release_mem_region(r->start, (r->end - r->start) + 1);
> 
> @@ -1252,10 +1219,15 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev)
>  /* work with hotplug and coldplug */
>  MODULE_ALIAS("platform:omap2_mcspi");
> 
> +static const struct dev_pm_ops omap_mcspi_dev_pm_ops = {
> +	.runtime_resume	= omap_mcspi_runtime_resume,
> +};
> +
>  static struct platform_driver omap2_mcspi_driver = {
>  	.driver = {
>  		.name =		"omap2_mcspi",
>  		.owner =	THIS_MODULE,
> +		.pm = &omap_mcspi_dev_pm_ops,
>  	},
>  	.remove =	__exit_p(omap2_mcspi_remove),
>  };
> -- 
> 1.7.1
> 
> 



More information about the linux-arm-kernel mailing list