Re: [PATCH] spi/s3c64xx: Convert to using core message queue

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 15 Feb 2012 14:48:32 -0800, Mark Brown <broonie@xxxxxxxxxxxxxxxxxxxxxxxxxxx> wrote:
> Convert the s3c64xx driver to using the new message queue factored out of
> the pl022 driver by Linus Walleij, saving us a nice block of code and
> getting the benefits of improvements implemented in the core.
> 
> Signed-off-by: Mark Brown <broonie@xxxxxxxxxxxxxxxxxxxxxxxxxxx>

Applied, thanks

g.

> ---
> 
> Only lightly tested thus far.  Linus, it'd be really nice if you could
> add this to your patch queue for this feature until it's merged by
> Grant.
> 
>  drivers/spi/spi-s3c64xx.c |  125 ++++++++-------------------------------------
>  1 files changed, 22 insertions(+), 103 deletions(-)
> 
> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
> index b899af66..1174d80 100644
> --- a/drivers/spi/spi-s3c64xx.c
> +++ b/drivers/spi/spi-s3c64xx.c
> @@ -128,8 +128,6 @@
>  
>  #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
>  
> -#define SUSPND    (1<<0)
> -#define SPIBUSY   (1<<1)
>  #define RXBUSY    (1<<2)
>  #define TXBUSY    (1<<3)
>  
> @@ -144,10 +142,8 @@ struct s3c64xx_spi_dma_data {
>   * @clk: Pointer to the spi clock.
>   * @src_clk: Pointer to the clock used to generate SPI signals.
>   * @master: Pointer to the SPI Protocol master.
> - * @workqueue: Work queue for the SPI xfer requests.
>   * @cntrlr_info: Platform specific data for the controller this driver manages.
>   * @tgl_spi: Pointer to the last CS left untoggled by the cs_change hint.
> - * @work: Work
>   * @queue: To log SPI xfer requests.
>   * @lock: Controller specific lock.
>   * @state: Set of FLAGS to indicate status.
> @@ -167,10 +163,8 @@ struct s3c64xx_spi_driver_data {
>  	struct clk                      *src_clk;
>  	struct platform_device          *pdev;
>  	struct spi_master               *master;
> -	struct workqueue_struct	        *workqueue;
>  	struct s3c64xx_spi_info  *cntrlr_info;
>  	struct spi_device               *tgl_spi;
> -	struct work_struct              work;
>  	struct list_head                queue;
>  	spinlock_t                      lock;
>  	unsigned long                   sfr_start;
> @@ -637,9 +631,10 @@ static void s3c64xx_spi_unmap_mssg(struct s3c64xx_spi_driver_data *sdd,
>  	}
>  }
>  
> -static void handle_msg(struct s3c64xx_spi_driver_data *sdd,
> -					struct spi_message *msg)
> +static int s3c64xx_spi_transfer_one_message(struct spi_master *master,
> +					    struct spi_message *msg)
>  {
> +	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
>  	struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
>  	struct spi_device *spi = msg->spi;
>  	struct s3c64xx_spi_csinfo *cs = spi->controller_data;
> @@ -771,13 +766,15 @@ out:
>  
>  	if (msg->complete)
>  		msg->complete(msg->context);
> +
> +	spi_finalize_current_message(master);
> +
> +	return 0;
>  }
>  
> -static void s3c64xx_spi_work(struct work_struct *work)
> +static int s3c64xx_spi_prepare_transfer(struct spi_master *spi)
>  {
> -	struct s3c64xx_spi_driver_data *sdd = container_of(work,
> -					struct s3c64xx_spi_driver_data, work);
> -	unsigned long flags;
> +	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi);
>  
>  	/* Acquire DMA channels */
>  	while (!acquire_dma(sdd))
> @@ -785,61 +782,18 @@ static void s3c64xx_spi_work(struct work_struct *work)
>  
>  	pm_runtime_get_sync(&sdd->pdev->dev);
>  
> -	spin_lock_irqsave(&sdd->lock, flags);
> -
> -	while (!list_empty(&sdd->queue)
> -				&& !(sdd->state & SUSPND)) {
> -
> -		struct spi_message *msg;
> -
> -		msg = container_of(sdd->queue.next, struct spi_message, queue);
> -
> -		list_del_init(&msg->queue);
> -
> -		/* Set Xfer busy flag */
> -		sdd->state |= SPIBUSY;
> -
> -		spin_unlock_irqrestore(&sdd->lock, flags);
> -
> -		handle_msg(sdd, msg);
> -
> -		spin_lock_irqsave(&sdd->lock, flags);
> -
> -		sdd->state &= ~SPIBUSY;
> -	}
> +	return 0;
> +}
>  
> -	spin_unlock_irqrestore(&sdd->lock, flags);
> +static int s3c64xx_spi_unprepare_transfer(struct spi_master *spi)
> +{
> +	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi);
>  
>  	/* Free DMA channels */
>  	sdd->ops->release(sdd->rx_dma.ch, &s3c64xx_spi_dma_client);
>  	sdd->ops->release(sdd->tx_dma.ch, &s3c64xx_spi_dma_client);
>  
>  	pm_runtime_put(&sdd->pdev->dev);
> -}
> -
> -static int s3c64xx_spi_transfer(struct spi_device *spi,
> -						struct spi_message *msg)
> -{
> -	struct s3c64xx_spi_driver_data *sdd;
> -	unsigned long flags;
> -
> -	sdd = spi_master_get_devdata(spi->master);
> -
> -	spin_lock_irqsave(&sdd->lock, flags);
> -
> -	if (sdd->state & SUSPND) {
> -		spin_unlock_irqrestore(&sdd->lock, flags);
> -		return -ESHUTDOWN;
> -	}
> -
> -	msg->status = -EINPROGRESS;
> -	msg->actual_length = 0;
> -
> -	list_add_tail(&msg->queue, &sdd->queue);
> -
> -	queue_work(sdd->workqueue, &sdd->work);
> -
> -	spin_unlock_irqrestore(&sdd->lock, flags);
>  
>  	return 0;
>  }
> @@ -879,13 +833,6 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
>  		}
>  	}
>  
> -	if (sdd->state & SUSPND) {
> -		spin_unlock_irqrestore(&sdd->lock, flags);
> -		dev_err(&spi->dev,
> -			"setup: SPI-%d not active!\n", spi->master->bus_num);
> -		return -ESHUTDOWN;
> -	}
> -
>  	spin_unlock_irqrestore(&sdd->lock, flags);
>  
>  	if (spi->bits_per_word != 8
> @@ -1073,7 +1020,9 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
>  
>  	master->bus_num = pdev->id;
>  	master->setup = s3c64xx_spi_setup;
> -	master->transfer = s3c64xx_spi_transfer;
> +	master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer;
> +	master->transfer_one_message = s3c64xx_spi_transfer_one_message;
> +	master->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer;
>  	master->num_chipselect = sci->num_cs;
>  	master->dma_alignment = 8;
>  	/* the spi->mode bits understood by this driver: */
> @@ -1128,27 +1077,18 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
>  		goto err6;
>  	}
>  
> -	sdd->workqueue = create_singlethread_workqueue(
> -						dev_name(master->dev.parent));
> -	if (sdd->workqueue == NULL) {
> -		dev_err(&pdev->dev, "Unable to create workqueue\n");
> -		ret = -ENOMEM;
> -		goto err7;
> -	}
> -
>  	/* Setup Deufult Mode */
>  	s3c64xx_spi_hwinit(sdd, pdev->id);
>  
>  	spin_lock_init(&sdd->lock);
>  	init_completion(&sdd->xfer_completion);
> -	INIT_WORK(&sdd->work, s3c64xx_spi_work);
>  	INIT_LIST_HEAD(&sdd->queue);
>  
>  	ret = request_irq(irq, s3c64xx_spi_irq, 0, "spi-s3c64xx", sdd);
>  	if (ret != 0) {
>  		dev_err(&pdev->dev, "Failed to request IRQ %d: %d\n",
>  			irq, ret);
> -		goto err8;
> +		goto err7;
>  	}
>  
>  	writel(S3C64XX_SPI_INT_RX_OVERRUN_EN | S3C64XX_SPI_INT_RX_UNDERRUN_EN |
> @@ -1158,7 +1098,7 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
>  	if (spi_register_master(master)) {
>  		dev_err(&pdev->dev, "cannot register SPI master\n");
>  		ret = -EBUSY;
> -		goto err9;
> +		goto err8;
>  	}
>  
>  	dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d "
> @@ -1172,10 +1112,8 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
>  
>  	return 0;
>  
> -err9:
> -	free_irq(irq, sdd);
>  err8:
> -	destroy_workqueue(sdd->workqueue);
> +	free_irq(irq, sdd);
>  err7:
>  	clk_disable(sdd->src_clk);
>  err6:
> @@ -1201,25 +1139,15 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)
>  	struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
>  	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
>  	struct resource	*mem_res;
> -	unsigned long flags;
>  
>  	pm_runtime_disable(&pdev->dev);
>  
> -	spin_lock_irqsave(&sdd->lock, flags);
> -	sdd->state |= SUSPND;
> -	spin_unlock_irqrestore(&sdd->lock, flags);
> -
> -	while (sdd->state & SPIBUSY)
> -		msleep(10);
> -
>  	spi_unregister_master(master);
>  
>  	writel(0, sdd->regs + S3C64XX_SPI_INT_EN);
>  
>  	free_irq(platform_get_irq(pdev, 0), sdd);
>  
> -	destroy_workqueue(sdd->workqueue);
> -
>  	clk_disable(sdd->src_clk);
>  	clk_put(sdd->src_clk);
>  
> @@ -1243,14 +1171,8 @@ static int s3c64xx_spi_suspend(struct device *dev)
>  {
>  	struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
>  	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
> -	unsigned long flags;
> -
> -	spin_lock_irqsave(&sdd->lock, flags);
> -	sdd->state |= SUSPND;
> -	spin_unlock_irqrestore(&sdd->lock, flags);
>  
> -	while (sdd->state & SPIBUSY)
> -		msleep(10);
> +	spi_master_suspend(master);
>  
>  	/* Disable the clock */
>  	clk_disable(sdd->src_clk);
> @@ -1267,7 +1189,6 @@ static int s3c64xx_spi_resume(struct device *dev)
>  	struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
>  	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
>  	struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
> -	unsigned long flags;
>  
>  	sci->cfg_gpio(pdev);
>  
> @@ -1277,9 +1198,7 @@ static int s3c64xx_spi_resume(struct device *dev)
>  
>  	s3c64xx_spi_hwinit(sdd, pdev->id);
>  
> -	spin_lock_irqsave(&sdd->lock, flags);
> -	sdd->state &= ~SUSPND;
> -	spin_unlock_irqrestore(&sdd->lock, flags);
> +	spi_master_resume(master);
>  
>  	return 0;
>  }
> -- 
> 1.7.9.rc1
> 

-- 
Grant Likely, B.Sc, P.Eng.
Secret Lab Technologies,Ltd.
--
To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux SoC Development]     [Linux Rockchip Development]     [Linux USB Development]     [Video for Linux]     [Linux Audio Users]     [Linux SCSI]     [Yosemite News]

  Powered by Linux