* [PATCH] spi/s3c64xx: Log error interrupts
@ 2011-11-10 11:11 Mark Brown
0 siblings, 0 replies; 5+ messages in thread
From: Mark Brown @ 2011-11-10 11:11 UTC (permalink / raw)
To: Grant Likely, Kukjin Kim
Cc: spi-devel-general, patches, linux-arm-kernel, Mark Brown
Although the hardware supports interrupts we're not currently using them
at all since for small transfers the overhead is greater than that for
busy waiting and for large transfers we have interrupts from the DMA.
This means that if the hardware reports an error (especially one which
might not stall transfer) we might miss it.
Take a first pass at dealing with such errors by enabling the interrupt
if we can and logging the errors if they happen. Ideally we'd report the
error via the affected transfer but since we're in master mode it's very
difficult to trigger errors at present and this code is much simpler.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
drivers/spi/spi-s3c64xx.c | 57 +++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index dcf7e10..8172173 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -20,6 +20,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/workqueue.h>
+#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/dma-mapping.h>
@@ -153,6 +154,7 @@ struct s3c64xx_spi_dma_data {
* @tx_dmach: Controller's DMA channel for Tx.
* @sfr_start: BUS address of SPI controller regs.
* @regs: Pointer to ioremap'ed controller registers.
+ * @irq: interrupt
* @xfer_completion: To indicate completion of xfer task.
* @cur_mode: Stores the active configuration of the controller.
* @cur_bpw: Stores the active bits per word settings.
@@ -171,6 +173,7 @@ struct s3c64xx_spi_driver_data {
struct list_head queue;
spinlock_t lock;
unsigned long sfr_start;
+ int irq;
struct completion xfer_completion;
unsigned state;
unsigned cur_mode, cur_bpw;
@@ -930,6 +933,33 @@ setup_exit:
return err;
}
+static irqreturn_t s3c64xx_spi_irq(int irq, void *data)
+{
+ struct s3c64xx_spi_driver_data *sdd = data;
+ struct spi_master *spi = sdd->master;
+ unsigned int val;
+
+ val = readl(sdd->regs + S3C64XX_SPI_PENDING_CLR);
+
+ val &= S3C64XX_SPI_PND_RX_OVERRUN_CLR |
+ S3C64XX_SPI_PND_RX_UNDERRUN_CLR |
+ S3C64XX_SPI_PND_TX_OVERRUN_CLR |
+ S3C64XX_SPI_PND_TX_UNDERRUN_CLR;
+
+ writel(val, sdd->regs + S3C64XX_SPI_PENDING_CLR);
+
+ if (val & S3C64XX_SPI_PND_RX_OVERRUN_CLR)
+ dev_err(&spi->dev, "RX overrun\n");
+ if (val & S3C64XX_SPI_PND_RX_UNDERRUN_CLR)
+ dev_err(&spi->dev, "RX underrun\n");
+ if (val & S3C64XX_SPI_PND_TX_OVERRUN_CLR)
+ dev_err(&spi->dev, "TX overrun\n");
+ if (val & S3C64XX_SPI_PND_TX_UNDERRUN_CLR)
+ dev_err(&spi->dev, "TX underrun\n");
+
+ return IRQ_HANDLED;
+}
+
static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel)
{
struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
@@ -970,7 +1000,7 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
struct s3c64xx_spi_driver_data *sdd;
struct s3c64xx_spi_info *sci;
struct spi_master *master;
- int ret;
+ int ret, irq;
char clk_name[16];
if (pdev->id < 0) {
@@ -1006,6 +1036,12 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
return -ENXIO;
}
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_warn(&pdev->dev, "Failed to get IRQ: %d\n", irq);
+ return irq;
+ }
+
master = spi_alloc_master(&pdev->dev,
sizeof(struct s3c64xx_spi_driver_data));
if (master == NULL) {
@@ -1100,10 +1136,21 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
INIT_WORK(&sdd->work, s3c64xx_spi_work);
INIT_LIST_HEAD(&sdd->queue);
+ ret = request_irq(sdd->irq, s3c64xx_spi_irq, 0, "spi-s3c64xx", sdd);
+ if (ret != 0) {
+ dev_err(&pdev->dev, "Failed to request IRQ: %d\n",
+ ret);
+ goto err8;
+ }
+
+ writel(S3C64XX_SPI_INT_RX_OVERRUN_EN | S3C64XX_SPI_INT_RX_UNDERRUN_EN |
+ S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN,
+ sdd->regs + S3C64XX_SPI_INT_EN);
+
if (spi_register_master(master)) {
dev_err(&pdev->dev, "cannot register SPI master\n");
ret = -EBUSY;
- goto err8;
+ goto err9;
}
dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d "
@@ -1115,6 +1162,8 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
return 0;
+err9:
+ free_irq(sdd->irq, sdd);
err8:
destroy_workqueue(sdd->workqueue);
err7:
@@ -1153,6 +1202,10 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)
spi_unregister_master(master);
+ writel(0, sdd->regs + S3C64XX_SPI_INT_EN);
+
+ free_irq(sdd->irq, sdd);
+
destroy_workqueue(sdd->workqueue);
clk_disable(sdd->src_clk);
--
1.7.7.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH] spi/s3c64xx: Log error interrupts
@ 2011-11-28 11:31 Mark Brown
[not found] ` <1322479918-7818-1-git-send-email-broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
0 siblings, 1 reply; 5+ messages in thread
From: Mark Brown @ 2011-11-28 11:31 UTC (permalink / raw)
To: Kukjin Kim, Wolfram Sang
Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, Mark Brown
Although the hardware supports interrupts we're not currently using them
at all since for small transfers the overhead is greater than that for
busy waiting and for large transfers we have interrupts from the DMA.
This means that if the hardware reports an error (especially one which
might not stall transfer) we might miss it.
Take a first pass at dealing with such errors by enabling the interrupt
if we can and logging the errors if they happen. Ideally we'd report the
error via the affected transfer but since we're in master mode it's very
difficult to trigger errors at present and this code is much simpler.
Signed-off-by: Mark Brown <broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
---
drivers/spi/spi-s3c64xx.c | 56 +++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 54 insertions(+), 2 deletions(-)
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index dcf7e10..9b16406 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -20,6 +20,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/workqueue.h>
+#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/dma-mapping.h>
@@ -153,6 +154,7 @@ struct s3c64xx_spi_dma_data {
* @tx_dmach: Controller's DMA channel for Tx.
* @sfr_start: BUS address of SPI controller regs.
* @regs: Pointer to ioremap'ed controller registers.
+ * @irq: interrupt
* @xfer_completion: To indicate completion of xfer task.
* @cur_mode: Stores the active configuration of the controller.
* @cur_bpw: Stores the active bits per word settings.
@@ -930,6 +932,33 @@ setup_exit:
return err;
}
+static irqreturn_t s3c64xx_spi_irq(int irq, void *data)
+{
+ struct s3c64xx_spi_driver_data *sdd = data;
+ struct spi_master *spi = sdd->master;
+ unsigned int val;
+
+ val = readl(sdd->regs + S3C64XX_SPI_PENDING_CLR);
+
+ val &= S3C64XX_SPI_PND_RX_OVERRUN_CLR |
+ S3C64XX_SPI_PND_RX_UNDERRUN_CLR |
+ S3C64XX_SPI_PND_TX_OVERRUN_CLR |
+ S3C64XX_SPI_PND_TX_UNDERRUN_CLR;
+
+ writel(val, sdd->regs + S3C64XX_SPI_PENDING_CLR);
+
+ if (val & S3C64XX_SPI_PND_RX_OVERRUN_CLR)
+ dev_err(&spi->dev, "RX overrun\n");
+ if (val & S3C64XX_SPI_PND_RX_UNDERRUN_CLR)
+ dev_err(&spi->dev, "RX underrun\n");
+ if (val & S3C64XX_SPI_PND_TX_OVERRUN_CLR)
+ dev_err(&spi->dev, "TX overrun\n");
+ if (val & S3C64XX_SPI_PND_TX_UNDERRUN_CLR)
+ dev_err(&spi->dev, "TX underrun\n");
+
+ return IRQ_HANDLED;
+}
+
static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel)
{
struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
@@ -970,7 +999,7 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
struct s3c64xx_spi_driver_data *sdd;
struct s3c64xx_spi_info *sci;
struct spi_master *master;
- int ret;
+ int ret, irq;
char clk_name[16];
if (pdev->id < 0) {
@@ -1006,6 +1035,12 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
return -ENXIO;
}
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_warn(&pdev->dev, "Failed to get IRQ: %d\n", irq);
+ return irq;
+ }
+
master = spi_alloc_master(&pdev->dev,
sizeof(struct s3c64xx_spi_driver_data));
if (master == NULL) {
@@ -1100,10 +1135,21 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
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;
+ }
+
+ writel(S3C64XX_SPI_INT_RX_OVERRUN_EN | S3C64XX_SPI_INT_RX_UNDERRUN_EN |
+ S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN,
+ sdd->regs + S3C64XX_SPI_INT_EN);
+
if (spi_register_master(master)) {
dev_err(&pdev->dev, "cannot register SPI master\n");
ret = -EBUSY;
- goto err8;
+ goto err9;
}
dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d "
@@ -1115,6 +1161,8 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
return 0;
+err9:
+ free_irq(irq, sdd);
err8:
destroy_workqueue(sdd->workqueue);
err7:
@@ -1153,6 +1201,10 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)
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);
--
1.7.7.3
------------------------------------------------------------------------------
All the data continuously generated in your IT infrastructure
contains a definitive record of customers, application performance,
security threats, fraudulent activity, and more. Splunk takes this
data and makes sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-novd2d
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] spi/s3c64xx: Log error interrupts
[not found] ` <1322479918-7818-1-git-send-email-broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
@ 2011-12-02 11:46 ` Linus Walleij
[not found] ` <CACRpkdaKJk_NLisVUFihdyMi9fT5fQnOSWErxTUgd4nUcMm-CA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 5+ messages in thread
From: Linus Walleij @ 2011-12-02 11:46 UTC (permalink / raw)
To: Mark Brown
Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, Kukjin Kim,
Jassi Brar
On Mon, Nov 28, 2011 at 12:31 PM, Mark Brown
<broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org> wrote:
> Although the hardware supports interrupts we're not currently using them
> at all since for small transfers the overhead is greater than that for
> busy waiting and for large transfers we have interrupts from the DMA.
> This means that if the hardware reports an error (especially one which
> might not stall transfer) we might miss it.
>
> Take a first pass at dealing with such errors by enabling the interrupt
> if we can and logging the errors if they happen. Ideally we'd report the
> error via the affected transfer but since we're in master mode it's very
> difficult to trigger errors at present and this code is much simpler.
>
> Signed-off-by: Mark Brown <broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
Looks good to me:
Acked-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
(Cc:ing Jassi so he doesn't miss this.)
Yours,
Linus Walleij
------------------------------------------------------------------------------
All the data continuously generated in your IT infrastructure
contains a definitive record of customers, application performance,
security threats, fraudulent activity, and more. Splunk takes this
data and makes sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-novd2d
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] spi/s3c64xx: Log error interrupts
[not found] ` <CACRpkdaKJk_NLisVUFihdyMi9fT5fQnOSWErxTUgd4nUcMm-CA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2011-12-02 14:13 ` Jassi Brar
[not found] ` <CABb+yY0KBX9J+0zjkkU5O-NoiRNkZY1TrbPfc8ak65hWWSFwhQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 5+ messages in thread
From: Jassi Brar @ 2011-12-02 14:13 UTC (permalink / raw)
To: Linus Walleij
Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, Mark Brown,
Kukjin Kim, Jassi Brar
On Fri, Dec 2, 2011 at 5:16 PM, Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> On Mon, Nov 28, 2011 at 12:31 PM, Mark Brown
> <broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org> wrote:
>
>> Although the hardware supports interrupts we're not currently using them
>> at all since for small transfers the overhead is greater than that for
>> busy waiting and for large transfers we have interrupts from the DMA.
>> This means that if the hardware reports an error (especially one which
>> might not stall transfer) we might miss it.
>>
>> Take a first pass at dealing with such errors by enabling the interrupt
>> if we can and logging the errors if they happen. Ideally we'd report the
>> error via the affected transfer but since we're in master mode it's very
>> difficult to trigger errors at present and this code is much simpler.
>>
>> Signed-off-by: Mark Brown <broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
>
> Looks good to me:
> Acked-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>
> (Cc:ing Jassi so he doesn't miss this.)
>
Linus, thanks for looping me in.
Though due to my changed priorities, I wouldn't mind me being kept out
of Samsung matters.
Cheers,
-Jassi
------------------------------------------------------------------------------
All the data continuously generated in your IT infrastructure
contains a definitive record of customers, application performance,
security threats, fraudulent activity, and more. Splunk takes this
data and makes sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-novd2d
^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: [PATCH] spi/s3c64xx: Log error interrupts
[not found] ` <CABb+yY0KBX9J+0zjkkU5O-NoiRNkZY1TrbPfc8ak65hWWSFwhQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2011-12-06 10:38 ` Kukjin Kim
0 siblings, 0 replies; 5+ messages in thread
From: Kukjin Kim @ 2011-12-06 10:38 UTC (permalink / raw)
To: 'Jassi Brar', 'Linus Walleij'
Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
'Mark Brown', 'Jassi Brar'
Jassi Brar wrote:
>
> On Fri, Dec 2, 2011 at 5:16 PM, Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> wrote:
> > On Mon, Nov 28, 2011 at 12:31 PM, Mark Brown
> > <broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org> wrote:
> >
> >> Although the hardware supports interrupts we're not currently using
> them
> >> at all since for small transfers the overhead is greater than that for
> >> busy waiting and for large transfers we have interrupts from the DMA.
> >> This means that if the hardware reports an error (especially one which
> >> might not stall transfer) we might miss it.
> >>
> >> Take a first pass at dealing with such errors by enabling the interrupt
> >> if we can and logging the errors if they happen. Ideally we'd report
> the
> >> error via the affected transfer but since we're in master mode it's
> very
> >> difficult to trigger errors at present and this code is much simpler.
> >>
> >> Signed-off-by: Mark Brown <broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
> >
> > Looks good to me:
> > Acked-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> >
Looks ok to me, too.
Acked-by: Kukjin Kim <kgene.kim-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
(Cc'ed Grant Likely)
As I know, Grant will pick this up in his spi tree with our ack after his backing.
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <kgene.kim-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
> > (Cc:ing Jassi so he doesn't miss this.)
> >
> Linus, thanks for looping me in.
> Though due to my changed priorities, I wouldn't mind me being kept out
> of Samsung matters.
>
> Cheers,
> -Jassi
------------------------------------------------------------------------------
Cloud Services Checklist: Pricing and Packaging Optimization
This white paper is intended to serve as a reference, checklist and point of
discussion for anyone considering optimizing the pricing and packaging model
of a cloud services business. Read Now!
http://www.accelacomm.com/jaw/sfnl/114/51491232/
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-12-06 10:38 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-28 11:31 [PATCH] spi/s3c64xx: Log error interrupts Mark Brown
[not found] ` <1322479918-7818-1-git-send-email-broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
2011-12-02 11:46 ` Linus Walleij
[not found] ` <CACRpkdaKJk_NLisVUFihdyMi9fT5fQnOSWErxTUgd4nUcMm-CA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-12-02 14:13 ` Jassi Brar
[not found] ` <CABb+yY0KBX9J+0zjkkU5O-NoiRNkZY1TrbPfc8ak65hWWSFwhQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-12-06 10:38 ` Kukjin Kim
-- strict thread matches above, loose matches on Subject: below --
2011-11-10 11:11 Mark Brown
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).