* [PATCH] spi: refactor spi-coldfire-qspi to use SPI queue framework.
@ 2012-05-10 16:26 Steven King
2012-05-11 6:28 ` Greg Ungerer
[not found] ` <201205100926.55444.sfking-xS0NTnu2YfYAvxtiuMwx3w@public.gmane.org>
0 siblings, 2 replies; 7+ messages in thread
From: Steven King @ 2012-05-10 16:26 UTC (permalink / raw)
To: spi-devel-general; +Cc: Grant Likely, uClinux development list, gerg
Use the new SPI queue framework; remove use of workqueue, replace
mcfqspi_transfer with mcfqspi_transfer_one_message, add
mcfqspi_prepare_transfer_hw and mcfqspi_unprepare_transfer_hw, update power
management routines.
Signed-off-by: Steven King <sfking@fdwdc.com>
---
drivers/spi/spi-coldfire-qspi.c | 255 +++++++++++++++++---------------------
1 files changed, 114 insertions(+), 141 deletions(-)
diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c
index 6eee64a..b2d4b9e 100644
--- a/drivers/spi/spi-coldfire-qspi.c
+++ b/drivers/spi/spi-coldfire-qspi.c
@@ -25,12 +25,12 @@
#include <linux/errno.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
-#include <linux/workqueue.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/spi/spi.h>
+#include <linux/pm_runtime.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
@@ -78,10 +78,7 @@ struct mcfqspi {
wait_queue_head_t waitq;
- struct work_struct work;
- struct workqueue_struct *workq;
- spinlock_t lock;
- struct list_head msgq;
+ struct device *dev;
};
static void mcfqspi_wr_qmr(struct mcfqspi *mcfqspi, u16 val)
@@ -303,120 +300,80 @@ static void mcfqspi_transfer_msg16(struct mcfqspi *mcfqspi, unsigned count,
}
}
-static void mcfqspi_work(struct work_struct *work)
+static int mcfqspi_transfer_one_message(struct spi_master *master,
+ struct spi_message *msg)
{
- struct mcfqspi *mcfqspi = container_of(work, struct mcfqspi, work);
- unsigned long flags;
-
- spin_lock_irqsave(&mcfqspi->lock, flags);
- while (!list_empty(&mcfqspi->msgq)) {
- struct spi_message *msg;
- struct spi_device *spi;
- struct spi_transfer *xfer;
- int status = 0;
-
- msg = container_of(mcfqspi->msgq.next, struct spi_message,
- queue);
-
- list_del_init(&msg->queue);
- spin_unlock_irqrestore(&mcfqspi->lock, flags);
-
- spi = msg->spi;
-
- list_for_each_entry(xfer, &msg->transfers, transfer_list) {
- bool cs_high = spi->mode & SPI_CS_HIGH;
- u16 qmr = MCFQSPI_QMR_MSTR;
-
- if (xfer->bits_per_word)
- qmr |= xfer->bits_per_word << 10;
- else
- qmr |= spi->bits_per_word << 10;
- if (spi->mode & SPI_CPHA)
- qmr |= MCFQSPI_QMR_CPHA;
- if (spi->mode & SPI_CPOL)
- qmr |= MCFQSPI_QMR_CPOL;
- if (xfer->speed_hz)
- qmr |= mcfqspi_qmr_baud(xfer->speed_hz);
- else
- qmr |= mcfqspi_qmr_baud(spi->max_speed_hz);
- mcfqspi_wr_qmr(mcfqspi, qmr);
-
- mcfqspi_cs_select(mcfqspi, spi->chip_select, cs_high);
-
- mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE);
- if ((xfer->bits_per_word ? xfer->bits_per_word :
- spi->bits_per_word) == 8)
- mcfqspi_transfer_msg8(mcfqspi, xfer->len,
- xfer->tx_buf,
- xfer->rx_buf);
- else
- mcfqspi_transfer_msg16(mcfqspi, xfer->len / 2,
- xfer->tx_buf,
- xfer->rx_buf);
- mcfqspi_wr_qir(mcfqspi, 0);
-
- if (xfer->delay_usecs)
- udelay(xfer->delay_usecs);
- if (xfer->cs_change) {
- if (!list_is_last(&xfer->transfer_list,
- &msg->transfers))
- mcfqspi_cs_deselect(mcfqspi,
- spi->chip_select,
- cs_high);
- } else {
- if (list_is_last(&xfer->transfer_list,
- &msg->transfers))
- mcfqspi_cs_deselect(mcfqspi,
- spi->chip_select,
- cs_high);
- }
- msg->actual_length += xfer->len;
+ struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
+ struct spi_device *spi = msg->spi;
+ struct spi_transfer *t;
+ int status = 0;
+
+ list_for_each_entry(t, &msg->transfers, transfer_list) {
+ bool cs_high = spi->mode & SPI_CS_HIGH;
+ u16 qmr = MCFQSPI_QMR_MSTR;
+
+ if (t->bits_per_word)
+ qmr |= t->bits_per_word << 10;
+ else
+ qmr |= spi->bits_per_word << 10;
+ if (spi->mode & SPI_CPHA)
+ qmr |= MCFQSPI_QMR_CPHA;
+ if (spi->mode & SPI_CPOL)
+ qmr |= MCFQSPI_QMR_CPOL;
+ if (t->speed_hz)
+ qmr |= mcfqspi_qmr_baud(t->speed_hz);
+ else
+ qmr |= mcfqspi_qmr_baud(spi->max_speed_hz);
+ mcfqspi_wr_qmr(mcfqspi, qmr);
+
+ mcfqspi_cs_select(mcfqspi, spi->chip_select, cs_high);
+
+ mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE);
+ if ((t->bits_per_word ? t->bits_per_word :
+ spi->bits_per_word) == 8)
+ mcfqspi_transfer_msg8(mcfqspi, t->len, t->tx_buf,
+ t->rx_buf);
+ else
+ mcfqspi_transfer_msg16(mcfqspi, t->len / 2, t->tx_buf,
+ t->rx_buf);
+ mcfqspi_wr_qir(mcfqspi, 0);
+
+ if (t->delay_usecs)
+ udelay(t->delay_usecs);
+ if (t->cs_change) {
+ if (!list_is_last(&t->transfer_list, &msg->transfers))
+ mcfqspi_cs_deselect(mcfqspi, spi->chip_select,
+ cs_high);
+ } else {
+ if (list_is_last(&t->transfer_list, &msg->transfers))
+ mcfqspi_cs_deselect(mcfqspi, spi->chip_select,
+ cs_high);
}
- msg->status = status;
- msg->complete(msg->context);
-
- spin_lock_irqsave(&mcfqspi->lock, flags);
+ msg->actual_length += t->len;
}
- spin_unlock_irqrestore(&mcfqspi->lock, flags);
+ msg->status = status;
+ spi_finalize_current_message(master);
+
+ return status;
+
}
-static int mcfqspi_transfer(struct spi_device *spi, struct spi_message *msg)
+static int mcfqspi_prepare_transfer_hw(struct spi_master *master)
{
- struct mcfqspi *mcfqspi;
- struct spi_transfer *xfer;
- unsigned long flags;
-
- mcfqspi = spi_master_get_devdata(spi->master);
-
- list_for_each_entry(xfer, &msg->transfers, transfer_list) {
- if (xfer->bits_per_word && ((xfer->bits_per_word < 8)
- || (xfer->bits_per_word > 16))) {
- dev_dbg(&spi->dev,
- "%d bits per word is not supported\n",
- xfer->bits_per_word);
- goto fail;
- }
- if (xfer->speed_hz) {
- u32 real_speed = MCFQSPI_BUSCLK /
- mcfqspi_qmr_baud(xfer->speed_hz);
- if (real_speed != xfer->speed_hz)
- dev_dbg(&spi->dev,
- "using speed %d instead of %d\n",
- real_speed, xfer->speed_hz);
- }
- }
- msg->status = -EINPROGRESS;
- msg->actual_length = 0;
+ struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
- spin_lock_irqsave(&mcfqspi->lock, flags);
- list_add_tail(&msg->queue, &mcfqspi->msgq);
- queue_work(mcfqspi->workq, &mcfqspi->work);
- spin_unlock_irqrestore(&mcfqspi->lock, flags);
+ pm_runtime_get_sync(mcfqspi->dev);
+
+ return 0;
+}
+
+static int mcfqspi_unprepare_transfer_hw(struct spi_master *master)
+{
+ struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
+
+ pm_runtime_put_sync(mcfqspi->dev);
return 0;
-fail:
- msg->status = -EINVAL;
- return -EINVAL;
}
static int mcfqspi_setup(struct spi_device *spi)
@@ -502,21 +459,10 @@ static int __devinit mcfqspi_probe(struct platform_device *pdev)
}
clk_enable(mcfqspi->clk);
- mcfqspi->workq = create_singlethread_workqueue(dev_name(master->dev.parent));
- if (!mcfqspi->workq) {
- dev_dbg(&pdev->dev, "create_workqueue failed\n");
- status = -ENOMEM;
- goto fail4;
- }
- INIT_WORK(&mcfqspi->work, mcfqspi_work);
- spin_lock_init(&mcfqspi->lock);
- INIT_LIST_HEAD(&mcfqspi->msgq);
- init_waitqueue_head(&mcfqspi->waitq);
-
pdata = pdev->dev.platform_data;
if (!pdata) {
dev_dbg(&pdev->dev, "platform data is missing\n");
- goto fail5;
+ goto fail4;
}
master->bus_num = pdata->bus_num;
master->num_chipselect = pdata->num_chipselect;
@@ -525,28 +471,33 @@ static int __devinit mcfqspi_probe(struct platform_device *pdev)
status = mcfqspi_cs_setup(mcfqspi);
if (status) {
dev_dbg(&pdev->dev, "error initializing cs_control\n");
- goto fail5;
+ goto fail4;
}
+ init_waitqueue_head(&mcfqspi->waitq);
+ mcfqspi->dev = &pdev->dev;
+
master->mode_bits = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA;
master->setup = mcfqspi_setup;
- master->transfer = mcfqspi_transfer;
+ master->transfer_one_message = mcfqspi_transfer_one_message;
+ master->prepare_transfer_hardware = mcfqspi_prepare_transfer_hw;
+ master->unprepare_transfer_hardware = mcfqspi_unprepare_transfer_hw;
platform_set_drvdata(pdev, master);
status = spi_register_master(master);
if (status) {
dev_dbg(&pdev->dev, "spi_register_master failed\n");
- goto fail6;
+ goto fail5;
}
+ pm_runtime_enable(mcfqspi->dev);
+
dev_info(&pdev->dev, "Coldfire QSPI bus driver\n");
return 0;
-fail6:
- mcfqspi_cs_teardown(mcfqspi);
fail5:
- destroy_workqueue(mcfqspi->workq);
+ mcfqspi_cs_teardown(mcfqspi);
fail4:
clk_disable(mcfqspi->clk);
clk_put(mcfqspi->clk);
@@ -570,12 +521,12 @@ static int __devexit mcfqspi_remove(struct platform_device *pdev)
struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ pm_runtime_disable(mcfqspi->dev);
/* disable the hardware (set the baud rate to 0) */
mcfqspi_wr_qmr(mcfqspi, MCFQSPI_QMR_MSTR);
platform_set_drvdata(pdev, NULL);
mcfqspi_cs_teardown(mcfqspi);
- destroy_workqueue(mcfqspi->workq);
clk_disable(mcfqspi->clk);
clk_put(mcfqspi->clk);
free_irq(mcfqspi->irq, mcfqspi);
@@ -587,11 +538,13 @@ static int __devexit mcfqspi_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM
-
+#ifdef CONFIG_PM_SLEEP
static int mcfqspi_suspend(struct device *dev)
{
- struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev));
+ struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
+ struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
+
+ spi_master_suspend(master);
clk_disable(mcfqspi->clk);
@@ -600,27 +553,47 @@ static int mcfqspi_suspend(struct device *dev)
static int mcfqspi_resume(struct device *dev)
{
- struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev));
+ struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
+ struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
+
+ spi_master_resume(master);
clk_enable(mcfqspi->clk);
return 0;
}
+#endif
-static struct dev_pm_ops mcfqspi_dev_pm_ops = {
- .suspend = mcfqspi_suspend,
- .resume = mcfqspi_resume,
-};
+#ifdef CONFIG_PM_RUNTIME
+static int mcfqspi_runtime_suspend(struct device *dev)
+{
+ struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev));
-#define MCFQSPI_DEV_PM_OPS (&mcfqspi_dev_pm_ops)
-#else
-#define MCFQSPI_DEV_PM_OPS NULL
+ clk_disable(mcfqspi->clk);
+
+ return 0;
+}
+
+static int mcfqspi_runtime_resume(struct device *dev)
+{
+ struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev));
+
+ clk_enable(mcfqspi->clk);
+
+ return 0;
+}
#endif
+static const struct dev_pm_ops mcfqspi_pm = {
+ SET_SYSTEM_SLEEP_PM_OPS(mcfqspi_suspend, mcfqspi_resume)
+ SET_RUNTIME_PM_OPS(mcfqspi_runtime_suspend, mcfqspi_runtime_resume,
+ NULL)
+};
+
static struct platform_driver mcfqspi_driver = {
.driver.name = DRIVER_NAME,
.driver.owner = THIS_MODULE,
- .driver.pm = MCFQSPI_DEV_PM_OPS,
+ .driver.pm = &mcfqspi_pm,
.probe = mcfqspi_probe,
.remove = __devexit_p(mcfqspi_remove),
};
_______________________________________________
uClinux-dev mailing list
uClinux-dev@uclinux.org
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by uclinux-dev@uclinux.org
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] spi: refactor spi-coldfire-qspi to use SPI queue framework.
2012-05-10 16:26 [PATCH] spi: refactor spi-coldfire-qspi to use SPI queue framework Steven King
@ 2012-05-11 6:28 ` Greg Ungerer
[not found] ` <4FACB1A9.3060800-XXXsiaCtIV5Wk0Htik3J/w@public.gmane.org>
[not found] ` <201205100926.55444.sfking-xS0NTnu2YfYAvxtiuMwx3w@public.gmane.org>
1 sibling, 1 reply; 7+ messages in thread
From: Greg Ungerer @ 2012-05-11 6:28 UTC (permalink / raw)
To: Steven King
Cc: Grant Likely, spi-devel-general, uClinux development list, gerg
On 11/05/12 02:26, Steven King wrote:
> Use the new SPI queue framework; remove use of workqueue, replace
> mcfqspi_transfer with mcfqspi_transfer_one_message, add
> mcfqspi_prepare_transfer_hw and mcfqspi_unprepare_transfer_hw, update power
> management routines.
>
> Signed-off-by: Steven King<sfking@fdwdc.com>
I can't add much value reviewing this one, style wise it looks good.
Grant: if you don't want to take this through one of your trees
I can add it to the m68knommu git tree.
Regards
Greg
> drivers/spi/spi-coldfire-qspi.c | 255 +++++++++++++++++---------------------
> 1 files changed, 114 insertions(+), 141 deletions(-)
>
> diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c
> index 6eee64a..b2d4b9e 100644
> --- a/drivers/spi/spi-coldfire-qspi.c
> +++ b/drivers/spi/spi-coldfire-qspi.c
> @@ -25,12 +25,12 @@
> #include<linux/errno.h>
> #include<linux/platform_device.h>
> #include<linux/sched.h>
> -#include<linux/workqueue.h>
> #include<linux/delay.h>
> #include<linux/io.h>
> #include<linux/clk.h>
> #include<linux/err.h>
> #include<linux/spi/spi.h>
> +#include<linux/pm_runtime.h>
>
> #include<asm/coldfire.h>
> #include<asm/mcfsim.h>
> @@ -78,10 +78,7 @@ struct mcfqspi {
>
> wait_queue_head_t waitq;
>
> - struct work_struct work;
> - struct workqueue_struct *workq;
> - spinlock_t lock;
> - struct list_head msgq;
> + struct device *dev;
> };
>
> static void mcfqspi_wr_qmr(struct mcfqspi *mcfqspi, u16 val)
> @@ -303,120 +300,80 @@ static void mcfqspi_transfer_msg16(struct mcfqspi *mcfqspi, unsigned count,
> }
> }
>
> -static void mcfqspi_work(struct work_struct *work)
> +static int mcfqspi_transfer_one_message(struct spi_master *master,
> + struct spi_message *msg)
> {
> - struct mcfqspi *mcfqspi = container_of(work, struct mcfqspi, work);
> - unsigned long flags;
> -
> - spin_lock_irqsave(&mcfqspi->lock, flags);
> - while (!list_empty(&mcfqspi->msgq)) {
> - struct spi_message *msg;
> - struct spi_device *spi;
> - struct spi_transfer *xfer;
> - int status = 0;
> -
> - msg = container_of(mcfqspi->msgq.next, struct spi_message,
> - queue);
> -
> - list_del_init(&msg->queue);
> - spin_unlock_irqrestore(&mcfqspi->lock, flags);
> -
> - spi = msg->spi;
> -
> - list_for_each_entry(xfer,&msg->transfers, transfer_list) {
> - bool cs_high = spi->mode& SPI_CS_HIGH;
> - u16 qmr = MCFQSPI_QMR_MSTR;
> -
> - if (xfer->bits_per_word)
> - qmr |= xfer->bits_per_word<< 10;
> - else
> - qmr |= spi->bits_per_word<< 10;
> - if (spi->mode& SPI_CPHA)
> - qmr |= MCFQSPI_QMR_CPHA;
> - if (spi->mode& SPI_CPOL)
> - qmr |= MCFQSPI_QMR_CPOL;
> - if (xfer->speed_hz)
> - qmr |= mcfqspi_qmr_baud(xfer->speed_hz);
> - else
> - qmr |= mcfqspi_qmr_baud(spi->max_speed_hz);
> - mcfqspi_wr_qmr(mcfqspi, qmr);
> -
> - mcfqspi_cs_select(mcfqspi, spi->chip_select, cs_high);
> -
> - mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE);
> - if ((xfer->bits_per_word ? xfer->bits_per_word :
> - spi->bits_per_word) == 8)
> - mcfqspi_transfer_msg8(mcfqspi, xfer->len,
> - xfer->tx_buf,
> - xfer->rx_buf);
> - else
> - mcfqspi_transfer_msg16(mcfqspi, xfer->len / 2,
> - xfer->tx_buf,
> - xfer->rx_buf);
> - mcfqspi_wr_qir(mcfqspi, 0);
> -
> - if (xfer->delay_usecs)
> - udelay(xfer->delay_usecs);
> - if (xfer->cs_change) {
> - if (!list_is_last(&xfer->transfer_list,
> - &msg->transfers))
> - mcfqspi_cs_deselect(mcfqspi,
> - spi->chip_select,
> - cs_high);
> - } else {
> - if (list_is_last(&xfer->transfer_list,
> - &msg->transfers))
> - mcfqspi_cs_deselect(mcfqspi,
> - spi->chip_select,
> - cs_high);
> - }
> - msg->actual_length += xfer->len;
> + struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
> + struct spi_device *spi = msg->spi;
> + struct spi_transfer *t;
> + int status = 0;
> +
> + list_for_each_entry(t,&msg->transfers, transfer_list) {
> + bool cs_high = spi->mode& SPI_CS_HIGH;
> + u16 qmr = MCFQSPI_QMR_MSTR;
> +
> + if (t->bits_per_word)
> + qmr |= t->bits_per_word<< 10;
> + else
> + qmr |= spi->bits_per_word<< 10;
> + if (spi->mode& SPI_CPHA)
> + qmr |= MCFQSPI_QMR_CPHA;
> + if (spi->mode& SPI_CPOL)
> + qmr |= MCFQSPI_QMR_CPOL;
> + if (t->speed_hz)
> + qmr |= mcfqspi_qmr_baud(t->speed_hz);
> + else
> + qmr |= mcfqspi_qmr_baud(spi->max_speed_hz);
> + mcfqspi_wr_qmr(mcfqspi, qmr);
> +
> + mcfqspi_cs_select(mcfqspi, spi->chip_select, cs_high);
> +
> + mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE);
> + if ((t->bits_per_word ? t->bits_per_word :
> + spi->bits_per_word) == 8)
> + mcfqspi_transfer_msg8(mcfqspi, t->len, t->tx_buf,
> + t->rx_buf);
> + else
> + mcfqspi_transfer_msg16(mcfqspi, t->len / 2, t->tx_buf,
> + t->rx_buf);
> + mcfqspi_wr_qir(mcfqspi, 0);
> +
> + if (t->delay_usecs)
> + udelay(t->delay_usecs);
> + if (t->cs_change) {
> + if (!list_is_last(&t->transfer_list,&msg->transfers))
> + mcfqspi_cs_deselect(mcfqspi, spi->chip_select,
> + cs_high);
> + } else {
> + if (list_is_last(&t->transfer_list,&msg->transfers))
> + mcfqspi_cs_deselect(mcfqspi, spi->chip_select,
> + cs_high);
> }
> - msg->status = status;
> - msg->complete(msg->context);
> -
> - spin_lock_irqsave(&mcfqspi->lock, flags);
> + msg->actual_length += t->len;
> }
> - spin_unlock_irqrestore(&mcfqspi->lock, flags);
> + msg->status = status;
> + spi_finalize_current_message(master);
> +
> + return status;
> +
> }
>
> -static int mcfqspi_transfer(struct spi_device *spi, struct spi_message *msg)
> +static int mcfqspi_prepare_transfer_hw(struct spi_master *master)
> {
> - struct mcfqspi *mcfqspi;
> - struct spi_transfer *xfer;
> - unsigned long flags;
> -
> - mcfqspi = spi_master_get_devdata(spi->master);
> -
> - list_for_each_entry(xfer,&msg->transfers, transfer_list) {
> - if (xfer->bits_per_word&& ((xfer->bits_per_word< 8)
> - || (xfer->bits_per_word> 16))) {
> - dev_dbg(&spi->dev,
> - "%d bits per word is not supported\n",
> - xfer->bits_per_word);
> - goto fail;
> - }
> - if (xfer->speed_hz) {
> - u32 real_speed = MCFQSPI_BUSCLK /
> - mcfqspi_qmr_baud(xfer->speed_hz);
> - if (real_speed != xfer->speed_hz)
> - dev_dbg(&spi->dev,
> - "using speed %d instead of %d\n",
> - real_speed, xfer->speed_hz);
> - }
> - }
> - msg->status = -EINPROGRESS;
> - msg->actual_length = 0;
> + struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
>
> - spin_lock_irqsave(&mcfqspi->lock, flags);
> - list_add_tail(&msg->queue,&mcfqspi->msgq);
> - queue_work(mcfqspi->workq,&mcfqspi->work);
> - spin_unlock_irqrestore(&mcfqspi->lock, flags);
> + pm_runtime_get_sync(mcfqspi->dev);
> +
> + return 0;
> +}
> +
> +static int mcfqspi_unprepare_transfer_hw(struct spi_master *master)
> +{
> + struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
> +
> + pm_runtime_put_sync(mcfqspi->dev);
>
> return 0;
> -fail:
> - msg->status = -EINVAL;
> - return -EINVAL;
> }
>
> static int mcfqspi_setup(struct spi_device *spi)
> @@ -502,21 +459,10 @@ static int __devinit mcfqspi_probe(struct platform_device *pdev)
> }
> clk_enable(mcfqspi->clk);
>
> - mcfqspi->workq = create_singlethread_workqueue(dev_name(master->dev.parent));
> - if (!mcfqspi->workq) {
> - dev_dbg(&pdev->dev, "create_workqueue failed\n");
> - status = -ENOMEM;
> - goto fail4;
> - }
> - INIT_WORK(&mcfqspi->work, mcfqspi_work);
> - spin_lock_init(&mcfqspi->lock);
> - INIT_LIST_HEAD(&mcfqspi->msgq);
> - init_waitqueue_head(&mcfqspi->waitq);
> -
> pdata = pdev->dev.platform_data;
> if (!pdata) {
> dev_dbg(&pdev->dev, "platform data is missing\n");
> - goto fail5;
> + goto fail4;
> }
> master->bus_num = pdata->bus_num;
> master->num_chipselect = pdata->num_chipselect;
> @@ -525,28 +471,33 @@ static int __devinit mcfqspi_probe(struct platform_device *pdev)
> status = mcfqspi_cs_setup(mcfqspi);
> if (status) {
> dev_dbg(&pdev->dev, "error initializing cs_control\n");
> - goto fail5;
> + goto fail4;
> }
>
> + init_waitqueue_head(&mcfqspi->waitq);
> + mcfqspi->dev =&pdev->dev;
> +
> master->mode_bits = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA;
> master->setup = mcfqspi_setup;
> - master->transfer = mcfqspi_transfer;
> + master->transfer_one_message = mcfqspi_transfer_one_message;
> + master->prepare_transfer_hardware = mcfqspi_prepare_transfer_hw;
> + master->unprepare_transfer_hardware = mcfqspi_unprepare_transfer_hw;
>
> platform_set_drvdata(pdev, master);
>
> status = spi_register_master(master);
> if (status) {
> dev_dbg(&pdev->dev, "spi_register_master failed\n");
> - goto fail6;
> + goto fail5;
> }
> + pm_runtime_enable(mcfqspi->dev);
> +
> dev_info(&pdev->dev, "Coldfire QSPI bus driver\n");
>
> return 0;
>
> -fail6:
> - mcfqspi_cs_teardown(mcfqspi);
> fail5:
> - destroy_workqueue(mcfqspi->workq);
> + mcfqspi_cs_teardown(mcfqspi);
> fail4:
> clk_disable(mcfqspi->clk);
> clk_put(mcfqspi->clk);
> @@ -570,12 +521,12 @@ static int __devexit mcfqspi_remove(struct platform_device *pdev)
> struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
> struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>
> + pm_runtime_disable(mcfqspi->dev);
> /* disable the hardware (set the baud rate to 0) */
> mcfqspi_wr_qmr(mcfqspi, MCFQSPI_QMR_MSTR);
>
> platform_set_drvdata(pdev, NULL);
> mcfqspi_cs_teardown(mcfqspi);
> - destroy_workqueue(mcfqspi->workq);
> clk_disable(mcfqspi->clk);
> clk_put(mcfqspi->clk);
> free_irq(mcfqspi->irq, mcfqspi);
> @@ -587,11 +538,13 @@ static int __devexit mcfqspi_remove(struct platform_device *pdev)
> return 0;
> }
>
> -#ifdef CONFIG_PM
> -
> +#ifdef CONFIG_PM_SLEEP
> static int mcfqspi_suspend(struct device *dev)
> {
> - struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev));
> + struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
> + struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
> +
> + spi_master_suspend(master);
>
> clk_disable(mcfqspi->clk);
>
> @@ -600,27 +553,47 @@ static int mcfqspi_suspend(struct device *dev)
>
> static int mcfqspi_resume(struct device *dev)
> {
> - struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev));
> + struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
> + struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
> +
> + spi_master_resume(master);
>
> clk_enable(mcfqspi->clk);
>
> return 0;
> }
> +#endif
>
> -static struct dev_pm_ops mcfqspi_dev_pm_ops = {
> - .suspend = mcfqspi_suspend,
> - .resume = mcfqspi_resume,
> -};
> +#ifdef CONFIG_PM_RUNTIME
> +static int mcfqspi_runtime_suspend(struct device *dev)
> +{
> + struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev));
>
> -#define MCFQSPI_DEV_PM_OPS (&mcfqspi_dev_pm_ops)
> -#else
> -#define MCFQSPI_DEV_PM_OPS NULL
> + clk_disable(mcfqspi->clk);
> +
> + return 0;
> +}
> +
> +static int mcfqspi_runtime_resume(struct device *dev)
> +{
> + struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev));
> +
> + clk_enable(mcfqspi->clk);
> +
> + return 0;
> +}
> #endif
>
> +static const struct dev_pm_ops mcfqspi_pm = {
> + SET_SYSTEM_SLEEP_PM_OPS(mcfqspi_suspend, mcfqspi_resume)
> + SET_RUNTIME_PM_OPS(mcfqspi_runtime_suspend, mcfqspi_runtime_resume,
> + NULL)
> +};
> +
> static struct platform_driver mcfqspi_driver = {
> .driver.name = DRIVER_NAME,
> .driver.owner = THIS_MODULE,
> - .driver.pm = MCFQSPI_DEV_PM_OPS,
> + .driver.pm =&mcfqspi_pm,
> .probe = mcfqspi_probe,
> .remove = __devexit_p(mcfqspi_remove),
> };
>
>
>
--
------------------------------------------------------------------------
Greg Ungerer -- Principal Engineer EMAIL: gerg@snapgear.com
SnapGear Group, McAfee PHONE: +61 7 3435 2888
8 Gardner Close FAX: +61 7 3217 5323
Milton, QLD, 4064, Australia WEB: http://www.SnapGear.com
_______________________________________________
uClinux-dev mailing list
uClinux-dev@uclinux.org
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by uclinux-dev@uclinux.org
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] spi: refactor spi-coldfire-qspi to use SPI queue framework.
[not found] ` <201205100926.55444.sfking-xS0NTnu2YfYAvxtiuMwx3w@public.gmane.org>
@ 2012-05-11 8:33 ` Shubhrajyoti Datta
2012-05-11 10:33 ` Steven King
2012-05-14 19:50 ` Linus Walleij
1 sibling, 1 reply; 7+ messages in thread
From: Shubhrajyoti Datta @ 2012-05-11 8:33 UTC (permalink / raw)
To: Steven King
Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
uClinux development list, gerg-JBU5SbJe1FlAfugRpC6u6w
Hi Steven,
On Thu, May 10, 2012 at 9:56 PM, Steven King <sfking-xS0NTnu2YfYAvxtiuMwx3w@public.gmane.org> wrote:
> Use the new SPI queue framework; remove use of workqueue, replace
> mcfqspi_transfer with mcfqspi_transfer_one_message, add
> mcfqspi_prepare_transfer_hw and mcfqspi_unprepare_transfer_hw, update power
> management routines.
By update are you attempting to convert to runtime framework also?
>
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] spi: refactor spi-coldfire-qspi to use SPI queue framework.
2012-05-11 8:33 ` Shubhrajyoti Datta
@ 2012-05-11 10:33 ` Steven King
[not found] ` <201205110333.22096.sfking-xS0NTnu2YfYAvxtiuMwx3w@public.gmane.org>
0 siblings, 1 reply; 7+ messages in thread
From: Steven King @ 2012-05-11 10:33 UTC (permalink / raw)
To: Shubhrajyoti Datta; +Cc: spi-devel-general, uClinux development list, gerg
On Friday 11 May 2012 1:33:25 am Shubhrajyoti Datta wrote:
> Hi Steven,
>
> On Thu, May 10, 2012 at 9:56 PM, Steven King <sfking@fdwdc.com> wrote:
> > Use the new SPI queue framework; remove use of workqueue, replace
> > mcfqspi_transfer with mcfqspi_transfer_one_message, add
> > mcfqspi_prepare_transfer_hw and mcfqspi_unprepare_transfer_hw, update
> > power management routines.
>
> By update are you attempting to convert to runtime framework also?
laying the ground work for it; right now its mostly just a big nop as
currently on Coldfire there isnt any PM support. I suppose it would have
been better to have that as a separate patch, i can resubmit with that broken
out if people would prefer.
_______________________________________________
uClinux-dev mailing list
uClinux-dev@uclinux.org
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by uclinux-dev@uclinux.org
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] spi: refactor spi-coldfire-qspi to use SPI queue framework.
[not found] ` <201205110333.22096.sfking-xS0NTnu2YfYAvxtiuMwx3w@public.gmane.org>
@ 2012-05-11 13:21 ` Shubhrajyoti Datta
0 siblings, 0 replies; 7+ messages in thread
From: Shubhrajyoti Datta @ 2012-05-11 13:21 UTC (permalink / raw)
To: Steven King
Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
uClinux development list, gerg-JBU5SbJe1FlAfugRpC6u6w
On Fri, May 11, 2012 at 4:03 PM, Steven King <sfking-xS0NTnu2YfYAvxtiuMwx3w@public.gmane.org> wrote:
> On Friday 11 May 2012 1:33:25 am Shubhrajyoti Datta wrote:
>> Hi Steven,
>>
>> On Thu, May 10, 2012 at 9:56 PM, Steven King <sfking-xS0NTnu2YfYAvxtiuMwx3w@public.gmane.org> wrote:
>> > Use the new SPI queue framework; remove use of workqueue, replace
>> > mcfqspi_transfer with mcfqspi_transfer_one_message, add
>> > mcfqspi_prepare_transfer_hw and mcfqspi_unprepare_transfer_hw, update
>> > power management routines.
>>
>> By update are you attempting to convert to runtime framework also?
>
> laying the ground work for it; right now its mostly just a big nop as
> currently on Coldfire there isnt any PM support.
OK , BTW my concern was partly clock apis and partly runtime.
Anyways dont have any strong opinions.
> I suppose it would have
> been better to have that as a separate patch, i can resubmit with that broken
> out if people would prefer.
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] spi: refactor spi-coldfire-qspi to use SPI queue framework.
[not found] ` <201205100926.55444.sfking-xS0NTnu2YfYAvxtiuMwx3w@public.gmane.org>
2012-05-11 8:33 ` Shubhrajyoti Datta
@ 2012-05-14 19:50 ` Linus Walleij
1 sibling, 0 replies; 7+ messages in thread
From: Linus Walleij @ 2012-05-14 19:50 UTC (permalink / raw)
To: Steven King
Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
uClinux development list, gerg-JBU5SbJe1FlAfugRpC6u6w
On Thu, May 10, 2012 at 6:26 PM, Steven King <sfking-xS0NTnu2YfYAvxtiuMwx3w@public.gmane.org> wrote:
> Use the new SPI queue framework; remove use of workqueue, replace
> mcfqspi_transfer with mcfqspi_transfer_one_message, add
> mcfqspi_prepare_transfer_hw and mcfqspi_unprepare_transfer_hw, update power
> management routines.
>
> Signed-off-by: Steven King <sfking-xS0NTnu2YfYAvxtiuMwx3w@public.gmane.org>
Looks good to me, the PM runtime stuff could have been in a separate patch
but that's no big deal to me.
Acked-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Yours,
Linus Walleij
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] spi: refactor spi-coldfire-qspi to use SPI queue framework.
[not found] ` <4FACB1A9.3060800-XXXsiaCtIV5Wk0Htik3J/w@public.gmane.org>
@ 2012-05-20 4:57 ` Grant Likely
0 siblings, 0 replies; 7+ messages in thread
From: Grant Likely @ 2012-05-20 4:57 UTC (permalink / raw)
To: Greg Ungerer, Steven King
Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
uClinux development list, gerg-JBU5SbJe1FlAfugRpC6u6w
On Fri, 11 May 2012 16:28:57 +1000, Greg Ungerer <gerg-XXXsiaCtIV5Wk0Htik3J/w@public.gmane.org> wrote:
> On 11/05/12 02:26, Steven King wrote:
> > Use the new SPI queue framework; remove use of workqueue, replace
> > mcfqspi_transfer with mcfqspi_transfer_one_message, add
> > mcfqspi_prepare_transfer_hw and mcfqspi_unprepare_transfer_hw, update power
> > management routines.
> >
> > Signed-off-by: Steven King<sfking-xS0NTnu2YfYAvxtiuMwx3w@public.gmane.org>
>
> I can't add much value reviewing this one, style wise it looks good.
I'll take that as an ack.
>
> Grant: if you don't want to take this through one of your trees
> I can add it to the m68knommu git tree.
Merged, thanks.
g.
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2012-05-20 4:57 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-05-10 16:26 [PATCH] spi: refactor spi-coldfire-qspi to use SPI queue framework Steven King
2012-05-11 6:28 ` Greg Ungerer
[not found] ` <4FACB1A9.3060800-XXXsiaCtIV5Wk0Htik3J/w@public.gmane.org>
2012-05-20 4:57 ` Grant Likely
[not found] ` <201205100926.55444.sfking-xS0NTnu2YfYAvxtiuMwx3w@public.gmane.org>
2012-05-11 8:33 ` Shubhrajyoti Datta
2012-05-11 10:33 ` Steven King
[not found] ` <201205110333.22096.sfking-xS0NTnu2YfYAvxtiuMwx3w@public.gmane.org>
2012-05-11 13:21 ` Shubhrajyoti Datta
2012-05-14 19:50 ` Linus Walleij
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).