[PATCH v2 2/3] serial: 8250_dma: Export serial8250_rx_dma_flush()

2016-06-14 Thread Chuah Kim Tatt
From: "Chuah, Kim Tatt" <kim.tatt.ch...@intel.com>

Export serial8250_rx_dma_flush() for use by SOC UART drivers.

Signed-off-by: Chuah, Kim Tatt <kim.tatt.ch...@intel.com>
---
 drivers/tty/serial/8250/8250_dma.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/tty/serial/8250/8250_dma.c 
b/drivers/tty/serial/8250/8250_dma.c
index 7f33d1c..3590d01 100644
--- a/drivers/tty/serial/8250/8250_dma.c
+++ b/drivers/tty/serial/8250/8250_dma.c
@@ -145,6 +145,7 @@ void serial8250_rx_dma_flush(struct uart_8250_port *p)
dmaengine_terminate_all(dma->rxchan);
}
 }
+EXPORT_SYMBOL_GPL(serial8250_rx_dma_flush);
 
 int serial8250_request_dma(struct uart_8250_port *p)
 {
-- 
1.9.1



[PATCH v2 1/3] dmaengine: hsu: Export hsu_dma_get_status()

2016-06-14 Thread Chuah Kim Tatt
From: "Chuah, Kim Tatt" <kim.tatt.ch...@intel.com>

To allow other code to safely read DMA Channel Status Register (where
the register attribute for Channel Error, Descriptor Time Out &
Descriptor Done fields are read-clear), export hsu_dma_get_status().
hsu_dma_irq() is renamed to hsu_dma_do_irq() and requires Status
Register value to be passed in.

Signed-off-by: Chuah, Kim Tatt <kim.tatt.ch...@intel.com>
---
 drivers/dma/hsu/hsu.c  | 90 +-
 drivers/dma/hsu/pci.c  | 11 -
 drivers/tty/serial/8250/8250_mid.c | 22 +++---
 include/linux/dma/hsu.h| 14 --
 4 files changed, 106 insertions(+), 31 deletions(-)

diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c
index f8c5cd5..c5f21ef 100644
--- a/drivers/dma/hsu/hsu.c
+++ b/drivers/dma/hsu/hsu.c
@@ -126,28 +126,33 @@ static void hsu_dma_start_transfer(struct hsu_dma_chan 
*hsuc)
hsu_dma_start_channel(hsuc);
 }
 
-static u32 hsu_dma_chan_get_sr(struct hsu_dma_chan *hsuc)
-{
-   unsigned long flags;
-   u32 sr;
-
-   spin_lock_irqsave(>vchan.lock, flags);
-   sr = hsu_chan_readl(hsuc, HSU_CH_SR);
-   spin_unlock_irqrestore(>vchan.lock, flags);
-
-   return sr & ~(HSU_CH_SR_DESCE_ANY | HSU_CH_SR_CDESC_ANY);
-}
-
-irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr)
+/*
+ *  hsu_dma_get_status() - get DMA channel status
+ *  @chip: HSUART DMA chip
+ *  @nr: DMA channel number
+ *  @status: pointer for DMA Channel Status Register value
+ *
+ *  Description:
+ *  The function reads and clears the DMA Channel Status Register, checks
+ *  if it was a timeout interrupt and returns a corresponding value.
+ *
+ *  Caller should provide a valid pointer for the DMA Channel Status
+ *  Register value that will be returned in @status.
+ *
+ *  Return:
+ *  1 for DMA timeout status, 0 for other DMA status, or error code for
+ *  invalid parameters or no interrupt pending.
+ */
+int hsu_dma_get_status(struct hsu_dma_chip *chip, unsigned short nr,
+  u32 *status)
 {
struct hsu_dma_chan *hsuc;
-   struct hsu_dma_desc *desc;
unsigned long flags;
u32 sr;
 
/* Sanity check */
if (nr >= chip->hsu->nr_channels)
-   return IRQ_NONE;
+   return -EINVAL;
 
hsuc = >hsu->chan[nr];
 
@@ -155,22 +160,65 @@ irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, 
unsigned short nr)
 * No matter what situation, need read clear the IRQ status
 * There is a bug, see Errata 5, HSD 2900918
 */
-   sr = hsu_dma_chan_get_sr(hsuc);
+   spin_lock_irqsave(>vchan.lock, flags);
+   sr = hsu_chan_readl(hsuc, HSU_CH_SR);
+   spin_unlock_irqrestore(>vchan.lock, flags);
+
+   /* Check if any interrupt is pending */
+   sr &= ~(HSU_CH_SR_DESCE_ANY | HSU_CH_SR_CDESC_ANY);
if (!sr)
-   return IRQ_NONE;
+   return -EIO;
 
/* Timeout IRQ, need wait some time, see Errata 2 */
if (sr & HSU_CH_SR_DESCTO_ANY)
udelay(2);
 
+   /*
+* At this point, at least one of Descriptor Time Out, Channel Error
+* or Descriptor Done bits must be set. Clear the Descriptor Time Out
+* bits and if sr is still non-zero, it must be channel error or
+* descriptor done which are higher priority than timeout and handled
+* in hsu_dma_do_irq(). Else, it must be a timeout.
+*/
sr &= ~HSU_CH_SR_DESCTO_ANY;
-   if (!sr)
-   return IRQ_HANDLED;
+
+   *status = sr;
+
+   return sr ? 0 : 1;
+}
+EXPORT_SYMBOL_GPL(hsu_dma_get_status);
+
+/*
+ *  hsu_dma_do_irq() - DMA interrupt handler
+ *  @chip: HSUART DMA chip
+ *  @nr: DMA channel number
+ *  @status: Channel Status Register value
+ *
+ *  Description:
+ *  This function handles Channel Error and Descriptor Done interrupts.
+ *  This function should be called after determining that the DMA interrupt
+ *  is not a normal timeout interrupt, ie. hsu_dma_get_status() returned 0.
+ *
+ *  Return:
+ *  IRQ_NONE for invalid channel number, IRQ_HANDLED otherwise.
+ */
+irqreturn_t hsu_dma_do_irq(struct hsu_dma_chip *chip, unsigned short nr,
+  u32 status)
+{
+   struct hsu_dma_chan *hsuc;
+   struct hsu_dma_desc *desc;
+   unsigned long flags;
+
+   /* Sanity check */
+   if (nr >= chip->hsu->nr_channels)
+   return IRQ_NONE;
+
+   hsuc = >hsu->chan[nr];
 
spin_lock_irqsave(>vchan.lock, flags);
desc = hsuc->desc;
if (desc) {
-   if (sr & HSU_CH_SR_CHE) {
+   if (status & HSU_CH_SR_CHE) {
desc->status = DMA_ERROR;
} else if (desc->active < desc

[PATCH v2 2/3] serial: 8250_dma: Export serial8250_rx_dma_flush()

2016-06-14 Thread Chuah Kim Tatt
From: "Chuah, Kim Tatt" 

Export serial8250_rx_dma_flush() for use by SOC UART drivers.

Signed-off-by: Chuah, Kim Tatt 
---
 drivers/tty/serial/8250/8250_dma.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/tty/serial/8250/8250_dma.c 
b/drivers/tty/serial/8250/8250_dma.c
index 7f33d1c..3590d01 100644
--- a/drivers/tty/serial/8250/8250_dma.c
+++ b/drivers/tty/serial/8250/8250_dma.c
@@ -145,6 +145,7 @@ void serial8250_rx_dma_flush(struct uart_8250_port *p)
dmaengine_terminate_all(dma->rxchan);
}
 }
+EXPORT_SYMBOL_GPL(serial8250_rx_dma_flush);
 
 int serial8250_request_dma(struct uart_8250_port *p)
 {
-- 
1.9.1



[PATCH v2 1/3] dmaengine: hsu: Export hsu_dma_get_status()

2016-06-14 Thread Chuah Kim Tatt
From: "Chuah, Kim Tatt" 

To allow other code to safely read DMA Channel Status Register (where
the register attribute for Channel Error, Descriptor Time Out &
Descriptor Done fields are read-clear), export hsu_dma_get_status().
hsu_dma_irq() is renamed to hsu_dma_do_irq() and requires Status
Register value to be passed in.

Signed-off-by: Chuah, Kim Tatt 
---
 drivers/dma/hsu/hsu.c  | 90 +-
 drivers/dma/hsu/pci.c  | 11 -
 drivers/tty/serial/8250/8250_mid.c | 22 +++---
 include/linux/dma/hsu.h| 14 --
 4 files changed, 106 insertions(+), 31 deletions(-)

diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c
index f8c5cd5..c5f21ef 100644
--- a/drivers/dma/hsu/hsu.c
+++ b/drivers/dma/hsu/hsu.c
@@ -126,28 +126,33 @@ static void hsu_dma_start_transfer(struct hsu_dma_chan 
*hsuc)
hsu_dma_start_channel(hsuc);
 }
 
-static u32 hsu_dma_chan_get_sr(struct hsu_dma_chan *hsuc)
-{
-   unsigned long flags;
-   u32 sr;
-
-   spin_lock_irqsave(>vchan.lock, flags);
-   sr = hsu_chan_readl(hsuc, HSU_CH_SR);
-   spin_unlock_irqrestore(>vchan.lock, flags);
-
-   return sr & ~(HSU_CH_SR_DESCE_ANY | HSU_CH_SR_CDESC_ANY);
-}
-
-irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr)
+/*
+ *  hsu_dma_get_status() - get DMA channel status
+ *  @chip: HSUART DMA chip
+ *  @nr: DMA channel number
+ *  @status: pointer for DMA Channel Status Register value
+ *
+ *  Description:
+ *  The function reads and clears the DMA Channel Status Register, checks
+ *  if it was a timeout interrupt and returns a corresponding value.
+ *
+ *  Caller should provide a valid pointer for the DMA Channel Status
+ *  Register value that will be returned in @status.
+ *
+ *  Return:
+ *  1 for DMA timeout status, 0 for other DMA status, or error code for
+ *  invalid parameters or no interrupt pending.
+ */
+int hsu_dma_get_status(struct hsu_dma_chip *chip, unsigned short nr,
+  u32 *status)
 {
struct hsu_dma_chan *hsuc;
-   struct hsu_dma_desc *desc;
unsigned long flags;
u32 sr;
 
/* Sanity check */
if (nr >= chip->hsu->nr_channels)
-   return IRQ_NONE;
+   return -EINVAL;
 
hsuc = >hsu->chan[nr];
 
@@ -155,22 +160,65 @@ irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, 
unsigned short nr)
 * No matter what situation, need read clear the IRQ status
 * There is a bug, see Errata 5, HSD 2900918
 */
-   sr = hsu_dma_chan_get_sr(hsuc);
+   spin_lock_irqsave(>vchan.lock, flags);
+   sr = hsu_chan_readl(hsuc, HSU_CH_SR);
+   spin_unlock_irqrestore(>vchan.lock, flags);
+
+   /* Check if any interrupt is pending */
+   sr &= ~(HSU_CH_SR_DESCE_ANY | HSU_CH_SR_CDESC_ANY);
if (!sr)
-   return IRQ_NONE;
+   return -EIO;
 
/* Timeout IRQ, need wait some time, see Errata 2 */
if (sr & HSU_CH_SR_DESCTO_ANY)
udelay(2);
 
+   /*
+* At this point, at least one of Descriptor Time Out, Channel Error
+* or Descriptor Done bits must be set. Clear the Descriptor Time Out
+* bits and if sr is still non-zero, it must be channel error or
+* descriptor done which are higher priority than timeout and handled
+* in hsu_dma_do_irq(). Else, it must be a timeout.
+*/
sr &= ~HSU_CH_SR_DESCTO_ANY;
-   if (!sr)
-   return IRQ_HANDLED;
+
+   *status = sr;
+
+   return sr ? 0 : 1;
+}
+EXPORT_SYMBOL_GPL(hsu_dma_get_status);
+
+/*
+ *  hsu_dma_do_irq() - DMA interrupt handler
+ *  @chip: HSUART DMA chip
+ *  @nr: DMA channel number
+ *  @status: Channel Status Register value
+ *
+ *  Description:
+ *  This function handles Channel Error and Descriptor Done interrupts.
+ *  This function should be called after determining that the DMA interrupt
+ *  is not a normal timeout interrupt, ie. hsu_dma_get_status() returned 0.
+ *
+ *  Return:
+ *  IRQ_NONE for invalid channel number, IRQ_HANDLED otherwise.
+ */
+irqreturn_t hsu_dma_do_irq(struct hsu_dma_chip *chip, unsigned short nr,
+  u32 status)
+{
+   struct hsu_dma_chan *hsuc;
+   struct hsu_dma_desc *desc;
+   unsigned long flags;
+
+   /* Sanity check */
+   if (nr >= chip->hsu->nr_channels)
+   return IRQ_NONE;
+
+   hsuc = >hsu->chan[nr];
 
spin_lock_irqsave(>vchan.lock, flags);
desc = hsuc->desc;
if (desc) {
-   if (sr & HSU_CH_SR_CHE) {
+   if (status & HSU_CH_SR_CHE) {
desc->status = DMA_ERROR;
} else if (desc->active < desc->nents) {
hsu_dma_start_channe

[PATCH v2 3/3] serial: 8250_mid: Read RX buffer on RX DMA timeout for DNV

2016-06-14 Thread Chuah Kim Tatt
From: "Chuah, Kim Tatt" <kim.tatt.ch...@intel.com>

In DNV, when RX DMA is used and number of bytes received is less than
transfer size, only RX DMA timeout interrupt is sent. When this happens,
read the RX buffer.

Signed-off-by: Chuah, Kim Tatt <kim.tatt.ch...@intel.com>
---
 drivers/tty/serial/8250/8250_mid.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_mid.c 
b/drivers/tty/serial/8250/8250_mid.c
index b218ff5..339de9c 100644
--- a/drivers/tty/serial/8250/8250_mid.c
+++ b/drivers/tty/serial/8250/8250_mid.c
@@ -96,6 +96,7 @@ static int tng_setup(struct mid8250 *mid, struct uart_port *p)
 static int dnv_handle_irq(struct uart_port *p)
 {
struct mid8250 *mid = p->private_data;
+   struct uart_8250_port *up = up_to_u8250p(p);
unsigned int fisr = serial_port_in(p, INTEL_MID_UART_DNV_FISR);
u32 status;
int ret = IRQ_NONE;
@@ -103,9 +104,10 @@ static int dnv_handle_irq(struct uart_port *p)
 
if (fisr & BIT(2)) {
err = hsu_dma_get_status(>dma_chip, 1, );
-   if (err > 0)
+   if (err > 0) {
+   serial8250_rx_dma_flush(up);
ret |= IRQ_HANDLED;
-   else if (err == 0)
+   } else if (err == 0)
ret |= hsu_dma_do_irq(>dma_chip, 1, status);
}
if (fisr & BIT(1)) {
-- 
1.9.1



[PATCH v2 0/3] Fix DNV HSUART RX DMA timeout interrupt issue

2016-06-14 Thread Chuah Kim Tatt
From: "Chuah, Kim Tatt" <kim.tatt.ch...@intel.com>

These patches fix a DNV HSUART DMA issue with timeout interrupts, where
RX data is stuck in buffer when RX DMA is used and the number of received
bytes is less than 4096.
These patches have been tested on Intel Denverton platform.

Changes from v1:
  - Added patch "serial: 8250_dma: Export serial8250_rx_dma_flush()" to solve
build error when CONFIG_SERIAL_8250_MID is set to "m".

Chuah, Kim Tatt (3):
  dmaengine: hsu: Export hsu_dma_get_status()
  serial: 8250_dma: Export serial8250_rx_dma_flush()
  serial: 8250_mid: Read RX buffer on RX DMA timeout for DNV

 drivers/dma/hsu/hsu.c  | 90 +-
 drivers/dma/hsu/pci.c  | 11 -
 drivers/tty/serial/8250/8250_dma.c |  1 +
 drivers/tty/serial/8250/8250_mid.c | 24 +++---
 include/linux/dma/hsu.h| 14 --
 5 files changed, 109 insertions(+), 31 deletions(-)

-- 
1.9.1



[PATCH v2 3/3] serial: 8250_mid: Read RX buffer on RX DMA timeout for DNV

2016-06-14 Thread Chuah Kim Tatt
From: "Chuah, Kim Tatt" 

In DNV, when RX DMA is used and number of bytes received is less than
transfer size, only RX DMA timeout interrupt is sent. When this happens,
read the RX buffer.

Signed-off-by: Chuah, Kim Tatt 
---
 drivers/tty/serial/8250/8250_mid.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_mid.c 
b/drivers/tty/serial/8250/8250_mid.c
index b218ff5..339de9c 100644
--- a/drivers/tty/serial/8250/8250_mid.c
+++ b/drivers/tty/serial/8250/8250_mid.c
@@ -96,6 +96,7 @@ static int tng_setup(struct mid8250 *mid, struct uart_port *p)
 static int dnv_handle_irq(struct uart_port *p)
 {
struct mid8250 *mid = p->private_data;
+   struct uart_8250_port *up = up_to_u8250p(p);
unsigned int fisr = serial_port_in(p, INTEL_MID_UART_DNV_FISR);
u32 status;
int ret = IRQ_NONE;
@@ -103,9 +104,10 @@ static int dnv_handle_irq(struct uart_port *p)
 
if (fisr & BIT(2)) {
err = hsu_dma_get_status(>dma_chip, 1, );
-   if (err > 0)
+   if (err > 0) {
+   serial8250_rx_dma_flush(up);
ret |= IRQ_HANDLED;
-   else if (err == 0)
+   } else if (err == 0)
ret |= hsu_dma_do_irq(>dma_chip, 1, status);
}
if (fisr & BIT(1)) {
-- 
1.9.1



[PATCH v2 0/3] Fix DNV HSUART RX DMA timeout interrupt issue

2016-06-14 Thread Chuah Kim Tatt
From: "Chuah, Kim Tatt" 

These patches fix a DNV HSUART DMA issue with timeout interrupts, where
RX data is stuck in buffer when RX DMA is used and the number of received
bytes is less than 4096.
These patches have been tested on Intel Denverton platform.

Changes from v1:
  - Added patch "serial: 8250_dma: Export serial8250_rx_dma_flush()" to solve
build error when CONFIG_SERIAL_8250_MID is set to "m".

Chuah, Kim Tatt (3):
  dmaengine: hsu: Export hsu_dma_get_status()
  serial: 8250_dma: Export serial8250_rx_dma_flush()
  serial: 8250_mid: Read RX buffer on RX DMA timeout for DNV

 drivers/dma/hsu/hsu.c  | 90 +-
 drivers/dma/hsu/pci.c  | 11 -
 drivers/tty/serial/8250/8250_dma.c |  1 +
 drivers/tty/serial/8250/8250_mid.c | 24 +++---
 include/linux/dma/hsu.h| 14 --
 5 files changed, 109 insertions(+), 31 deletions(-)

-- 
1.9.1



RE: [PATCH 2/2] serial: 8250_mid: Read RX buffer on RX DMA timeout for DNV

2016-05-15 Thread Chuah, Kim Tatt


>-Original Message-
>From: Andy Shevchenko [mailto:andriy.shevche...@linux.intel.com]
>Sent: Friday, May 13, 2016 7:28 PM
>To: lkp <l...@intel.com>; Chuah, Kim Tatt <kim.tatt.ch...@intel.com>; Peter
>Hurley <pe...@hurleysoftware.com>
>Cc: kbuild-...@01.org; gre...@linuxfoundation.org; Koul, Vinod
><vinod.k...@intel.com>; heikki.kroge...@linux.intel.com;
>mika.westerb...@linux.intel.com; linux-kernel@vger.kernel.org; Tan, Jui Nee
><jui.nee@intel.com>
>Subject: Re: [PATCH 2/2] serial: 8250_mid: Read RX buffer on RX DMA timeout for
>DNV
>
>On Fri, 2016-05-13 at 18:15 +0800, kbuild test robot wrote:
>> Hi,
>>
>> [auto build test ERROR on next-20160513] [cannot apply to
>> tty/tty-testing usb/usb-testing v4.6-rc7 v4.6-rc6
>> v4.6-rc5 v4.6-rc7]
>> [if your patch is applied to the wrong git tree, please drop us a note
>> to help improving the system]
>>
>> url:https://github.com/0day-ci/linux/commits/Chuah-Kim-Tatt/Fix-DN
>> V-HSUART-RX-DMA-timeout-interrupt-issue/20160513-162046
>> config: i386-randconfig-s0-201619 (attached as .config)
>> compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430
>> reproduce:
>> # save the attached .config to linux build tree
>> make ARCH=i386
>>
>> Note: the linux-review/Chuah-Kim-Tatt/Fix-DNV-HSUART-RX-DMA-timeout-
>> interrupt-issue/20160513-162046 HEAD
>> 0354112aa9821bec8d278ad06b3d543724f5291d builds fine.
>>   It only hurts bisectibility.
>>
>> All errors (new ones prefixed by >>):
>
>Peter, what happened to your DMA series in the linux-next? Did I miss any
>discussion related?
>
Hi Andy,
The error occurs when CONFIG_8250_MID is set to "m", because 
serial8250_rx_dma_flush() was not exported. Please advise.
>>
>> >
>> > >
>> > > ERROR: "serial8250_rx_dma_flush"
>> > > [drivers/tty/serial/8250/8250_mid.ko] undefined!
>> ---
>> 0-DAY kernel test infrastructureOpen Source Technology
>> Center https://lists.01.org/pipermail/kbuild-all
>> Intel Corporation
>
>--
>Andy Shevchenko <andriy.shevche...@linux.intel.com>
>Intel Finland Oy



RE: [PATCH 2/2] serial: 8250_mid: Read RX buffer on RX DMA timeout for DNV

2016-05-15 Thread Chuah, Kim Tatt


>-Original Message-
>From: Andy Shevchenko [mailto:andriy.shevche...@linux.intel.com]
>Sent: Friday, May 13, 2016 7:28 PM
>To: lkp ; Chuah, Kim Tatt ; Peter
>Hurley 
>Cc: kbuild-...@01.org; gre...@linuxfoundation.org; Koul, Vinod
>; heikki.kroge...@linux.intel.com;
>mika.westerb...@linux.intel.com; linux-kernel@vger.kernel.org; Tan, Jui Nee
>
>Subject: Re: [PATCH 2/2] serial: 8250_mid: Read RX buffer on RX DMA timeout for
>DNV
>
>On Fri, 2016-05-13 at 18:15 +0800, kbuild test robot wrote:
>> Hi,
>>
>> [auto build test ERROR on next-20160513] [cannot apply to
>> tty/tty-testing usb/usb-testing v4.6-rc7 v4.6-rc6
>> v4.6-rc5 v4.6-rc7]
>> [if your patch is applied to the wrong git tree, please drop us a note
>> to help improving the system]
>>
>> url:https://github.com/0day-ci/linux/commits/Chuah-Kim-Tatt/Fix-DN
>> V-HSUART-RX-DMA-timeout-interrupt-issue/20160513-162046
>> config: i386-randconfig-s0-201619 (attached as .config)
>> compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430
>> reproduce:
>>     # save the attached .config to linux build tree
>> make ARCH=i386
>>
>> Note: the linux-review/Chuah-Kim-Tatt/Fix-DNV-HSUART-RX-DMA-timeout-
>> interrupt-issue/20160513-162046 HEAD
>> 0354112aa9821bec8d278ad06b3d543724f5291d builds fine.
>>   It only hurts bisectibility.
>>
>> All errors (new ones prefixed by >>):
>
>Peter, what happened to your DMA series in the linux-next? Did I miss any
>discussion related?
>
Hi Andy,
The error occurs when CONFIG_8250_MID is set to "m", because 
serial8250_rx_dma_flush() was not exported. Please advise.
>>
>> >
>> > >
>> > > ERROR: "serial8250_rx_dma_flush"
>> > > [drivers/tty/serial/8250/8250_mid.ko] undefined!
>> ---
>> 0-DAY kernel test infrastructureOpen Source Technology
>> Center https://lists.01.org/pipermail/kbuild-all
>> Intel Corporation
>
>--
>Andy Shevchenko 
>Intel Finland Oy



[PATCH 1/2] dmaengine: hsu: Export hsu_dma_get_status()

2016-05-13 Thread Chuah Kim Tatt
From: "Chuah, Kim Tatt" <kim.tatt.ch...@intel.com>

To allow other code to safely read DMA Channel Status Register (where
the register attribute for Channel Error, Descriptor Time Out &
Descriptor Done fields are read-clear), export hsu_dma_get_status().
hsu_dma_irq() is renamed to hsu_dma_do_irq() and requires Status
Register value to be passed in.

Signed-off-by: Chuah, Kim Tatt <kim.tatt.ch...@intel.com>
---
 drivers/dma/hsu/hsu.c  | 90 +-
 drivers/dma/hsu/pci.c  | 11 -
 drivers/tty/serial/8250/8250_mid.c | 22 +++---
 include/linux/dma/hsu.h| 14 --
 4 files changed, 106 insertions(+), 31 deletions(-)

diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c
index f8c5cd5..c5f21ef 100644
--- a/drivers/dma/hsu/hsu.c
+++ b/drivers/dma/hsu/hsu.c
@@ -126,28 +126,33 @@ static void hsu_dma_start_transfer(struct hsu_dma_chan 
*hsuc)
hsu_dma_start_channel(hsuc);
 }
 
-static u32 hsu_dma_chan_get_sr(struct hsu_dma_chan *hsuc)
-{
-   unsigned long flags;
-   u32 sr;
-
-   spin_lock_irqsave(>vchan.lock, flags);
-   sr = hsu_chan_readl(hsuc, HSU_CH_SR);
-   spin_unlock_irqrestore(>vchan.lock, flags);
-
-   return sr & ~(HSU_CH_SR_DESCE_ANY | HSU_CH_SR_CDESC_ANY);
-}
-
-irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr)
+/*
+ *  hsu_dma_get_status() - get DMA channel status
+ *  @chip: HSUART DMA chip
+ *  @nr: DMA channel number
+ *  @status: pointer for DMA Channel Status Register value
+ *
+ *  Description:
+ *  The function reads and clears the DMA Channel Status Register, checks
+ *  if it was a timeout interrupt and returns a corresponding value.
+ *
+ *  Caller should provide a valid pointer for the DMA Channel Status
+ *  Register value that will be returned in @status.
+ *
+ *  Return:
+ *  1 for DMA timeout status, 0 for other DMA status, or error code for
+ *  invalid parameters or no interrupt pending.
+ */
+int hsu_dma_get_status(struct hsu_dma_chip *chip, unsigned short nr,
+  u32 *status)
 {
struct hsu_dma_chan *hsuc;
-   struct hsu_dma_desc *desc;
unsigned long flags;
u32 sr;
 
/* Sanity check */
if (nr >= chip->hsu->nr_channels)
-   return IRQ_NONE;
+   return -EINVAL;
 
hsuc = >hsu->chan[nr];
 
@@ -155,22 +160,65 @@ irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, 
unsigned short nr)
 * No matter what situation, need read clear the IRQ status
 * There is a bug, see Errata 5, HSD 2900918
 */
-   sr = hsu_dma_chan_get_sr(hsuc);
+   spin_lock_irqsave(>vchan.lock, flags);
+   sr = hsu_chan_readl(hsuc, HSU_CH_SR);
+   spin_unlock_irqrestore(>vchan.lock, flags);
+
+   /* Check if any interrupt is pending */
+   sr &= ~(HSU_CH_SR_DESCE_ANY | HSU_CH_SR_CDESC_ANY);
if (!sr)
-   return IRQ_NONE;
+   return -EIO;
 
/* Timeout IRQ, need wait some time, see Errata 2 */
if (sr & HSU_CH_SR_DESCTO_ANY)
udelay(2);
 
+   /*
+* At this point, at least one of Descriptor Time Out, Channel Error
+* or Descriptor Done bits must be set. Clear the Descriptor Time Out
+* bits and if sr is still non-zero, it must be channel error or
+* descriptor done which are higher priority than timeout and handled
+* in hsu_dma_do_irq(). Else, it must be a timeout.
+*/
sr &= ~HSU_CH_SR_DESCTO_ANY;
-   if (!sr)
-   return IRQ_HANDLED;
+
+   *status = sr;
+
+   return sr ? 0 : 1;
+}
+EXPORT_SYMBOL_GPL(hsu_dma_get_status);
+
+/*
+ *  hsu_dma_do_irq() - DMA interrupt handler
+ *  @chip: HSUART DMA chip
+ *  @nr: DMA channel number
+ *  @status: Channel Status Register value
+ *
+ *  Description:
+ *  This function handles Channel Error and Descriptor Done interrupts.
+ *  This function should be called after determining that the DMA interrupt
+ *  is not a normal timeout interrupt, ie. hsu_dma_get_status() returned 0.
+ *
+ *  Return:
+ *  IRQ_NONE for invalid channel number, IRQ_HANDLED otherwise.
+ */
+irqreturn_t hsu_dma_do_irq(struct hsu_dma_chip *chip, unsigned short nr,
+  u32 status)
+{
+   struct hsu_dma_chan *hsuc;
+   struct hsu_dma_desc *desc;
+   unsigned long flags;
+
+   /* Sanity check */
+   if (nr >= chip->hsu->nr_channels)
+   return IRQ_NONE;
+
+   hsuc = >hsu->chan[nr];
 
spin_lock_irqsave(>vchan.lock, flags);
desc = hsuc->desc;
if (desc) {
-   if (sr & HSU_CH_SR_CHE) {
+   if (status & HSU_CH_SR_CHE) {
desc->status = DMA_ERROR;
} else if (desc->active < desc

[PATCH 1/2] dmaengine: hsu: Export hsu_dma_get_status()

2016-05-13 Thread Chuah Kim Tatt
From: "Chuah, Kim Tatt" 

To allow other code to safely read DMA Channel Status Register (where
the register attribute for Channel Error, Descriptor Time Out &
Descriptor Done fields are read-clear), export hsu_dma_get_status().
hsu_dma_irq() is renamed to hsu_dma_do_irq() and requires Status
Register value to be passed in.

Signed-off-by: Chuah, Kim Tatt 
---
 drivers/dma/hsu/hsu.c  | 90 +-
 drivers/dma/hsu/pci.c  | 11 -
 drivers/tty/serial/8250/8250_mid.c | 22 +++---
 include/linux/dma/hsu.h| 14 --
 4 files changed, 106 insertions(+), 31 deletions(-)

diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c
index f8c5cd5..c5f21ef 100644
--- a/drivers/dma/hsu/hsu.c
+++ b/drivers/dma/hsu/hsu.c
@@ -126,28 +126,33 @@ static void hsu_dma_start_transfer(struct hsu_dma_chan 
*hsuc)
hsu_dma_start_channel(hsuc);
 }
 
-static u32 hsu_dma_chan_get_sr(struct hsu_dma_chan *hsuc)
-{
-   unsigned long flags;
-   u32 sr;
-
-   spin_lock_irqsave(>vchan.lock, flags);
-   sr = hsu_chan_readl(hsuc, HSU_CH_SR);
-   spin_unlock_irqrestore(>vchan.lock, flags);
-
-   return sr & ~(HSU_CH_SR_DESCE_ANY | HSU_CH_SR_CDESC_ANY);
-}
-
-irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr)
+/*
+ *  hsu_dma_get_status() - get DMA channel status
+ *  @chip: HSUART DMA chip
+ *  @nr: DMA channel number
+ *  @status: pointer for DMA Channel Status Register value
+ *
+ *  Description:
+ *  The function reads and clears the DMA Channel Status Register, checks
+ *  if it was a timeout interrupt and returns a corresponding value.
+ *
+ *  Caller should provide a valid pointer for the DMA Channel Status
+ *  Register value that will be returned in @status.
+ *
+ *  Return:
+ *  1 for DMA timeout status, 0 for other DMA status, or error code for
+ *  invalid parameters or no interrupt pending.
+ */
+int hsu_dma_get_status(struct hsu_dma_chip *chip, unsigned short nr,
+  u32 *status)
 {
struct hsu_dma_chan *hsuc;
-   struct hsu_dma_desc *desc;
unsigned long flags;
u32 sr;
 
/* Sanity check */
if (nr >= chip->hsu->nr_channels)
-   return IRQ_NONE;
+   return -EINVAL;
 
hsuc = >hsu->chan[nr];
 
@@ -155,22 +160,65 @@ irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, 
unsigned short nr)
 * No matter what situation, need read clear the IRQ status
 * There is a bug, see Errata 5, HSD 2900918
 */
-   sr = hsu_dma_chan_get_sr(hsuc);
+   spin_lock_irqsave(>vchan.lock, flags);
+   sr = hsu_chan_readl(hsuc, HSU_CH_SR);
+   spin_unlock_irqrestore(>vchan.lock, flags);
+
+   /* Check if any interrupt is pending */
+   sr &= ~(HSU_CH_SR_DESCE_ANY | HSU_CH_SR_CDESC_ANY);
if (!sr)
-   return IRQ_NONE;
+   return -EIO;
 
/* Timeout IRQ, need wait some time, see Errata 2 */
if (sr & HSU_CH_SR_DESCTO_ANY)
udelay(2);
 
+   /*
+* At this point, at least one of Descriptor Time Out, Channel Error
+* or Descriptor Done bits must be set. Clear the Descriptor Time Out
+* bits and if sr is still non-zero, it must be channel error or
+* descriptor done which are higher priority than timeout and handled
+* in hsu_dma_do_irq(). Else, it must be a timeout.
+*/
sr &= ~HSU_CH_SR_DESCTO_ANY;
-   if (!sr)
-   return IRQ_HANDLED;
+
+   *status = sr;
+
+   return sr ? 0 : 1;
+}
+EXPORT_SYMBOL_GPL(hsu_dma_get_status);
+
+/*
+ *  hsu_dma_do_irq() - DMA interrupt handler
+ *  @chip: HSUART DMA chip
+ *  @nr: DMA channel number
+ *  @status: Channel Status Register value
+ *
+ *  Description:
+ *  This function handles Channel Error and Descriptor Done interrupts.
+ *  This function should be called after determining that the DMA interrupt
+ *  is not a normal timeout interrupt, ie. hsu_dma_get_status() returned 0.
+ *
+ *  Return:
+ *  IRQ_NONE for invalid channel number, IRQ_HANDLED otherwise.
+ */
+irqreturn_t hsu_dma_do_irq(struct hsu_dma_chip *chip, unsigned short nr,
+  u32 status)
+{
+   struct hsu_dma_chan *hsuc;
+   struct hsu_dma_desc *desc;
+   unsigned long flags;
+
+   /* Sanity check */
+   if (nr >= chip->hsu->nr_channels)
+   return IRQ_NONE;
+
+   hsuc = >hsu->chan[nr];
 
spin_lock_irqsave(>vchan.lock, flags);
desc = hsuc->desc;
if (desc) {
-   if (sr & HSU_CH_SR_CHE) {
+   if (status & HSU_CH_SR_CHE) {
desc->status = DMA_ERROR;
} else if (desc->active < desc->nents) {
hsu_dma_start_channe

[PATCH 2/2] serial: 8250_mid: Read RX buffer on RX DMA timeout for DNV

2016-05-13 Thread Chuah Kim Tatt
From: "Chuah, Kim Tatt" <kim.tatt.ch...@intel.com>

In DNV, when RX DMA is used and number of bytes received is less than
transfer size, only RX DMA timeout interrupt is sent. When this happens,
read the RX buffer.

Signed-off-by: Chuah, Kim Tatt <kim.tatt.ch...@intel.com>
---
 drivers/tty/serial/8250/8250_mid.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_mid.c 
b/drivers/tty/serial/8250/8250_mid.c
index b218ff5..339de9c 100644
--- a/drivers/tty/serial/8250/8250_mid.c
+++ b/drivers/tty/serial/8250/8250_mid.c
@@ -96,6 +96,7 @@ static int tng_setup(struct mid8250 *mid, struct uart_port *p)
 static int dnv_handle_irq(struct uart_port *p)
 {
struct mid8250 *mid = p->private_data;
+   struct uart_8250_port *up = up_to_u8250p(p);
unsigned int fisr = serial_port_in(p, INTEL_MID_UART_DNV_FISR);
u32 status;
int ret = IRQ_NONE;
@@ -103,9 +104,10 @@ static int dnv_handle_irq(struct uart_port *p)
 
if (fisr & BIT(2)) {
err = hsu_dma_get_status(>dma_chip, 1, );
-   if (err > 0)
+   if (err > 0) {
+   serial8250_rx_dma_flush(up);
ret |= IRQ_HANDLED;
-   else if (err == 0)
+   } else if (err == 0)
ret |= hsu_dma_do_irq(>dma_chip, 1, status);
}
if (fisr & BIT(1)) {
-- 
1.9.1



[PATCH 2/2] serial: 8250_mid: Read RX buffer on RX DMA timeout for DNV

2016-05-13 Thread Chuah Kim Tatt
From: "Chuah, Kim Tatt" 

In DNV, when RX DMA is used and number of bytes received is less than
transfer size, only RX DMA timeout interrupt is sent. When this happens,
read the RX buffer.

Signed-off-by: Chuah, Kim Tatt 
---
 drivers/tty/serial/8250/8250_mid.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_mid.c 
b/drivers/tty/serial/8250/8250_mid.c
index b218ff5..339de9c 100644
--- a/drivers/tty/serial/8250/8250_mid.c
+++ b/drivers/tty/serial/8250/8250_mid.c
@@ -96,6 +96,7 @@ static int tng_setup(struct mid8250 *mid, struct uart_port *p)
 static int dnv_handle_irq(struct uart_port *p)
 {
struct mid8250 *mid = p->private_data;
+   struct uart_8250_port *up = up_to_u8250p(p);
unsigned int fisr = serial_port_in(p, INTEL_MID_UART_DNV_FISR);
u32 status;
int ret = IRQ_NONE;
@@ -103,9 +104,10 @@ static int dnv_handle_irq(struct uart_port *p)
 
if (fisr & BIT(2)) {
err = hsu_dma_get_status(>dma_chip, 1, );
-   if (err > 0)
+   if (err > 0) {
+   serial8250_rx_dma_flush(up);
ret |= IRQ_HANDLED;
-   else if (err == 0)
+   } else if (err == 0)
ret |= hsu_dma_do_irq(>dma_chip, 1, status);
}
if (fisr & BIT(1)) {
-- 
1.9.1



[PATCH 0/2] Fix DNV HSUART RX DMA timeout interrupt issue

2016-05-13 Thread Chuah Kim Tatt
From: "Chuah, Kim Tatt" <kim.tatt.ch...@intel.com>

These patches fix a DNV HSUART DMA issue with timeout interrupts which causes:
  - RX to be padded with zeros up to 4kB when <4kB should be received
  - RX to be truncated at 4kB when >4kB should be received.
These patches have been tested on Intel Denverton platform.


Chuah, Kim Tatt (2):
  dmaengine: hsu: Export hsu_dma_get_status()
  serial: 8250_mid: Read RX buffer on RX DMA timeout for DNV

 drivers/dma/hsu/hsu.c  | 90 +-
 drivers/dma/hsu/pci.c  | 11 -
 drivers/tty/serial/8250/8250_mid.c | 24 +++---
 include/linux/dma/hsu.h| 14 --
 4 files changed, 108 insertions(+), 31 deletions(-)

-- 
1.9.1



[PATCH 0/2] Fix DNV HSUART RX DMA timeout interrupt issue

2016-05-13 Thread Chuah Kim Tatt
From: "Chuah, Kim Tatt" 

These patches fix a DNV HSUART DMA issue with timeout interrupts which causes:
  - RX to be padded with zeros up to 4kB when <4kB should be received
  - RX to be truncated at 4kB when >4kB should be received.
These patches have been tested on Intel Denverton platform.


Chuah, Kim Tatt (2):
  dmaengine: hsu: Export hsu_dma_get_status()
  serial: 8250_mid: Read RX buffer on RX DMA timeout for DNV

 drivers/dma/hsu/hsu.c  | 90 +-
 drivers/dma/hsu/pci.c  | 11 -
 drivers/tty/serial/8250/8250_mid.c | 24 +++---
 include/linux/dma/hsu.h| 14 --
 4 files changed, 108 insertions(+), 31 deletions(-)

-- 
1.9.1