Re: [PATCH 2/2] gpio: omap: convert to use generic irq handler

2015-12-22 Thread Sebastian Andrzej Siewior
* Grygorii Strashko | 2015-12-12 10:30:10 [+0200]:

>git://git.ti.com/~gragst/ti-linux-kernel/gragsts-ti-linux-kernel.git

sucked in, thanks.

Sebastian
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] gpio: omap: convert to use generic irq handler

2015-12-11 Thread Sebastian Andrzej Siewior
* Grygorii Strashko | 2015-10-15 19:33:43 [+0300]:

>Hi Thomas,
>
>On 10/13/2015 09:33 PM, Thomas Gleixner wrote:
>>Grygorii,
>>
>>On Tue, 13 Oct 2015, Grygorii Strashko wrote:
>>>I'd very appreciate for any advice of how to better proceed with your 
>>>request.
>>>  - I can try to apply and re-send only patches marked by '*'
>>>  - I can prepare branch with all above patches
>>
>>Please provide a branch on top of 4.1.10 which contains the whole
>>lot. I have a look at it and decide then how to go from there.
>
>I've prepared branch linux-4.1.10-ti-gpio:
>in g...@git.ti.com:~gragst/ti-linux-kernel/gragsts-ti-linux-kernel.git

could you please provide a git URL for that?

>based on top of
> git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
> branch : linux-4.1.y
> commit : 27f1b7f Linux 4.1.10

Sebastian
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] PCI: dra7xx: mark dra7xx_pcie_msi irq as IRQF_NO_THREAD

2015-12-08 Thread Sebastian Andrzej Siewior
* Bjorn Helgaas | 2015-12-04 12:46:19 [-0600]:

>The backtrace might be OK (maybe slightly overkill), but all the
>stack addresses are certainly irrelevant and distracting.  We only
>need enough to recognize the problem.  I don't think the modules list
>is relevant either.

I would shorten it to the bare minimum. Also the patch description
itself could be truncated to the required bits…

>> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
>> index 8c36880..0415192 100644
>> --- a/drivers/pci/host/pci-dra7xx.c
>> +++ b/drivers/pci/host/pci-dra7xx.c
>> @@ -301,8 +301,19 @@ static int __init dra7xx_add_pcie_port(struct 
>> dra7xx_pcie *dra7xx,
>>  return -EINVAL;
>>  }
>>  
>> +/*
>> + * Mark dra7xx_pcie_msi IRQ as IRQF_NO_THREAD
>> + * On -RT and if kernel is booting with "threadirqs" cmd line parameter
>> + * the dra7xx_pcie_msi_irq_handler() will be forced threaded but,
>> + * in the same time, it's IRQ dispatcher and calls generic_handle_irq(),
>> + * which, in turn, will be resolved to handle_simple_irq() call.
>> + * The handle_simple_irq() expected to be called with IRQ disabled, as
>> + * result kernle will display warning:
>> + * "irq XXX handler YYY+0x0/0x14 enabled interrupts".
>> + */

…not to mention this piece. d7ce4377494a ("powerpc/fsl_msi: mark the msi
cascade handler IRQF_NO_THREAD") fixes the same bug in arch/ppc so they
bypassed you fixing it.

>>  ret = devm_request_irq(>dev, pp->irq,
>> -   dra7xx_pcie_msi_irq_handler, IRQF_SHARED,
>> +   dra7xx_pcie_msi_irq_handler,
>> +   IRQF_SHARED | IRQF_NO_THREAD,
>> "dra7-pcie-msi", pp);
>
>There's similar code in exynos_add_pcie_port(), imx6_add_pcie_port(),
>and spear13xx_add_pcie_port().  Do they need similar changes?  If not,
>why not?

You are right. The request for the handler exynos_pcie_msi_irq_handler(),
imx6_pcie_msi_handler() and spear13xx_pcie_irq_handler() needs same
treatment.
Additionally we have:

arch/mips/pci/msi-octeon.c: if (request_irq(OCTEON_IRQ_PCI_MSI0, 
octeon_msi_interrupt0,
arch/sparc/kernel/pci_msi.c:err = request_irq(irq, sparc64_msiq_interrupt, 
0,
drivers/pci/host/pci-tegra.c:   err = request_irq(msi->irq, tegra_pcie_msi_irq, 
0,
drivers/pci/host/pcie-rcar.c:   err = devm_request_irq(>dev, msi->irq1, 
rcar_pcie_msi_irq,
drivers/pci/host/pcie-rcar.c:   err = devm_request_irq(>dev, msi->irq2, 
rcar_pcie_msi_irq,
drivers/pci/host/pcie-xilinx.c: err = devm_request_irq(dev, port->irq, 
xilinx_pcie_intr_handler,

which require the same kind of fix…

>I see your discussion about DRA7 hardware design, but my impression is
>that this problem affects anybody who calls dw_handle_msi_irq() from a
>handler registered with IRQF_SHARED.

… brecause all of them invoke generic_handle_irq() from the requsted
handler. generic_handle_irq grabs raw_locks and this needs to run in
raw-irq context.
IRQF_SHARED could probably go away. The IRQ is mostlikely exclusive
assigned in each SoC for MSI interrupt demux.

>Bjorn

Sebastian
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] PCI: dra7xx: mark dra7xx_pcie_msi irq as IRQF_NO_THREAD

2015-11-12 Thread Sebastian Andrzej Siewior
On 11/06/2015 08:59 PM, Grygorii Strashko wrote:
> Hi Sebastian,

Hi Grygorii,

> - IRQF_NO_THREAD is the first considered option for such kind of issues.
>   But: Now in LKML there are ~60 occurrences of IRQF_NO_THREAD - most of
>   them are used by Arch code. And It's only used by 6 drivers (drivers/*) 
> [Addendum 2].
>   During past year, I've found only two threads related to IRQF_NO_THREAD
>   and, in both cases, IRQF_NO_THREAD was added for arch specific IRQs which
>   can't be threaded 
> (https://lists.ozlabs.org/pipermail/linuxppc-dev/2014-November/122659.html,
>   https://lkml.org/lkml/2015/4/21/404).

That powerpc patch you reference is doing the same thing you are doing
here.

> - ARM UP system: TI's am437xx SoCs for example.
>Here everything is started from /drivers/irqchip/irq-gic.c -> 
> gic_handle_irq()
> 

> GIC IRQ handler gic_handle_irq() may process more than one IRQ without 
> leaving HW IRQ mode
> (during my experiments I saw up to 6 IRQs processed in one cycle).

not only GIC. But then what good does it do if it leaves and returns
immediately back to the routine?

> As result, It was concluded, that having such current HW/SW and all IRQs 
> forced threaded [1],
> it will be potentially possible to predict system behavior, because 
> gic_handle_irq() will
> do the same things for most of processed IRQs.
> But, once there will be chained [2] or IRQF_NO_THREAD [3] IRQs - complete 
> unpredictability.

I would not go as far as "complete unpredictability". What you do (or
should do) is testing the system for longer period of time with
different behavior in order to estimate the worst case.
You can't predict the system anyway since it is way too complex. Just
try something that ensures that cyclictest is no longer cache hot and
see what happens then.

> So, It was selected as goal to have all PPI IRQs (forced) threaded. And if 
> someone
> will require faster IRQ handling - IRQF_NO_THREAD can be always added, but it 
> will
> be custom solution then. 
> 
> I'd be appreciated for your comments - if above problem is not a problem.
> Good - IRQF_NO_THREAD forever!

Yes, we try to avoid IRQF_NO_THREAD under all circumstances. However it
is required for low-level arch code. This includes basically
everything that is using raw-locks which includes interrupt controller
(the "real" ones like GIC or cascading like MSI or GPIO).
Here it is simple - you have a cascading MSI-interrupt controller and
as such it should be IRQF_NO_THREAD marked.
The latency spikes in worst case are not huge as explained earlier: The
only thing your cascading controller is allowed to do is to mark
interrupt as pending (which is with threaded interrupts just a task
wakeup).
And this is not a -RT only problem: it is broken in vanilla linux with
threaded interrupts as well.

Btw: There is an exception to this rule (as always): If you are on a
slow/blocking bus then you don't do IRQF_NO_THREAD. A slow bus would be
a GPIO controller behind an I2C/SPI controller which also acts as an
interrupt controller. Here you use a threaded-handler +
handle_nested_irq().

> Thanks.

Sebastian
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] PCI: dra7xx: mark dra7xx_pcie_msi irq as IRQF_NO_THREAD

2015-11-06 Thread Sebastian Andrzej Siewior
On 11/05/2015 07:43 PM, Grygorii Strashko wrote:
> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
> index 6589e7e..31460f4 100644
> --- a/drivers/pci/host/pci-dra7xx.c
> +++ b/drivers/pci/host/pci-dra7xx.c
> @@ -302,8 +302,30 @@ static int __init dra7xx_add_pcie_port(struct 
> dra7xx_pcie *dra7xx,
>   return -EINVAL;
>   }
>  
> + /*
> +  * Mark dra7xx_pcie_msi IRQ as IRQF_NO_THREAD
> +  * On -RT and if kernel is booting with "threadirqs" cmd line parameter
> +  * the dra7xx_pcie_msi_irq_handler() will be forced threaded but,
> +  * in the same time, it's IRQ dispatcher and calls generic_handle_irq(),
> +  * which, in turn, will be resolved to handle_simple_irq() call.
> +  * The handle_simple_irq() expected to be called with IRQ disabled, as
> +  * result kernle will display warning:
> +  * "irq XXX handler YYY+0x0/0x14 enabled interrupts".
> +  *
> +  * Current DRA7 PCIe hw configuration supports 32 interrupts,
> +  * which cannot change because it's hardwired in silicon, and can assume
> +  * that only a few (most of the time it will be exactly ONE) of those
> +  * interrupts are pending at the same time. So, It's sane way to dial
> +  * with above issue by marking dra7xx_pcie_msi IRQ as IRQF_NO_THREAD.
> +  * if some platform will utilize a lot of MSI IRQs and will suffer
> +  * form -RT latencies degradation because of that - IRQF_NO_THREAD can
> +  * be removed and "Warning Annihilation" W/A can be applied [1]
> +  *
> +  * [1] https://lkml.org/lkml/2015/11/2/578

I don't think this novel is required. Also a reference to a patch which
was not accepted is not a smart idea (since people might think they
will improve their -RT latency by applying it without thinking).

Do you have any *real* numbers where you can say this patch does
better/worse than what you suggester earlier? I'm simply asking because
each gpio-irq multiplexing driver does the same thing.

> +  */
>   ret = devm_request_irq(>dev, pp->irq,
> -dra7xx_pcie_msi_irq_handler, IRQF_SHARED,
> +dra7xx_pcie_msi_irq_handler,
> +IRQF_SHARED | IRQF_NO_THREAD,
>  "dra7-pcie-msi", pp);
>   if (ret) {
>   dev_err(>dev, "failed to request irq\n");
> 
Sebastian
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] tty: serial: 8250_omap: do not use RX DMA if pause is not supported

2015-08-14 Thread Sebastian Andrzej Siewior
The 8250-omap driver requires the DMA-engine driver to support the pause
command in order to properly turn off programmed RX transfer before the
driver stars manually reading from the FIFO.
The lacking support of the requirement has been discovered recently. In
order to stay safe here we disable RX-DMA completly on probe.
The rx_dma_broken assignment on probe could be removed once we working
pause function in omap-dma.

Cc: sta...@vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
v1…v2:
 - disable RX-DMA right on boot

 drivers/tty/serial/8250/8250_omap.c | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/8250/8250_omap.c 
b/drivers/tty/serial/8250/8250_omap.c
index d9a37191a1ae..2ac63c8bd946 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -112,6 +112,7 @@ struct omap8250_priv {
struct work_struct qos_work;
struct uart_8250_dma omap8250_dma;
spinlock_t rx_dma_lock;
+   bool rx_dma_broken;
 };
 
 static u32 uart_read(struct uart_8250_port *up, u32 reg)
@@ -773,6 +774,7 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p)
struct omap8250_priv*priv = p-port.private_data;
struct uart_8250_dma*dma = p-dma;
unsigned long   flags;
+   int ret;
 
spin_lock_irqsave(priv-rx_dma_lock, flags);
 
@@ -781,7 +783,9 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p)
return;
}
 
-   dmaengine_pause(dma-rxchan);
+   ret = dmaengine_pause(dma-rxchan);
+   if (WARN_ON_ONCE(ret))
+   priv-rx_dma_broken = true;
 
spin_unlock_irqrestore(priv-rx_dma_lock, flags);
 
@@ -825,6 +829,9 @@ static int omap_8250_rx_dma(struct uart_8250_port *p, 
unsigned int iir)
break;
}
 
+   if (priv-rx_dma_broken)
+   return -EINVAL;
+
spin_lock_irqsave(priv-rx_dma_lock, flags);
 
if (dma-rx_running)
@@ -1219,6 +1226,11 @@ static int omap8250_probe(struct platform_device *pdev)
 
if (of_machine_is_compatible(ti,am33xx))
priv-habit |= OMAP_DMA_TX_KICK;
+   /*
+* pause is currently not supported atleast on omap-sdma
+* and edma on most earlier kernels.
+*/
+   priv-rx_dma_broken = true;
}
}
 #endif
-- 
2.5.0

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] serial: 8250_omap: check how many bytes were injected

2015-08-14 Thread Sebastian Andrzej Siewior
The function tty_insert_flip_string() returns an int and as such it
might fail. So the result is that I kindly asked to insert 48 bytes and
the function only insterted 32.
I have no idea what to do with the remaining 16 so I think dropping them
is the only option. I also increase the buf_overrun counter so userpace
has a clue that we lost bytes.

Cc: Greg Kroah-Hartman gre...@linuxfoundation.org
Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/tty/serial/8250/8250_omap.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_omap.c 
b/drivers/tty/serial/8250/8250_omap.c
index 2ac63c8bd946..933f7ef2c004 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -738,6 +738,7 @@ static void __dma_rx_do_complete(struct uart_8250_port *p, 
bool error)
struct dma_tx_state state;
int count;
unsigned long   flags;
+   int ret;
 
dma_sync_single_for_cpu(dma-rxchan-device-dev, dma-rx_addr,
dma-rx_size, DMA_FROM_DEVICE);
@@ -753,8 +754,10 @@ static void __dma_rx_do_complete(struct uart_8250_port *p, 
bool error)
 
count = dma-rx_size - state.residue;
 
-   tty_insert_flip_string(tty_port, dma-rx_buf, count);
-   p-port.icount.rx += count;
+   ret = tty_insert_flip_string(tty_port, dma-rx_buf, count);
+
+   p-port.icount.rx += ret;
+   p-port.icount.buf_overrun += count - ret;
 unlock:
spin_unlock_irqrestore(priv-rx_dma_lock, flags);
 
-- 
2.5.0

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/3] serial: 8250: move rx_running out of the bitfield

2015-08-14 Thread Sebastian Andrzej Siewior
From: John Ogness john.ogn...@linutronix.de

That bitfield is modified by read + or + write operation. If someone
sets any of the other two bits it might render the lock useless.

While at it, remove other bitfields as well to avoid more such
errors.

Cc: Greg Kroah-Hartman gre...@linuxfoundation.org
Signed-off-by: John Ogness john.ogn...@linutronix.de
Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/tty/serial/8250/8250.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
index c43f74c53cd9..a407757dcecc 100644
--- a/drivers/tty/serial/8250/8250.h
+++ b/drivers/tty/serial/8250/8250.h
@@ -42,9 +42,9 @@ struct uart_8250_dma {
size_t  rx_size;
size_t  tx_size;
 
-   unsigned char   tx_running:1;
-   unsigned char   tx_err: 1;
-   unsigned char   rx_running:1;
+   unsigned char   tx_running;
+   unsigned char   tx_err;
+   unsigned char   rx_running;
 };
 
 struct old_serial_port {
-- 
2.5.0

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 3/3] serial: 8250_omap: try to avoid IER_RDI with DMA

2015-08-14 Thread Sebastian Andrzej Siewior
It has been observed on DRA7-evm that the UART triggers the interrupt and
reading IIR says IIR_NO_INT. It seems that we receive data via RX-DMA
but the interrupt is triggered anyway. I have hardly observed it on
AM335x and not in *that* quantity. On DRA7-evm with continuous transfers
at 3MBaud and CPU running at 1.5Ghz it is possible that the IRQ-core will
close the UART interrupt after some time with nobody cared.

I've seen that by not enabling IER_RDI those spurious interrupts are not
triggered. Also it seems that DMA and RDI cause the timeout interrupt
which does not allow RX-DMA to be scheduled even if the FIFO reached the
programmed RX threshold. However without RDI we don't get a notification
if we have less than RX threshold bytes in the FIFO.
This is where we have the rx_dma_wd timer. After programming the RX-DMA
transfer wait HZ / 4 or 250ms for it to complete. If it does not
complete in that time span we cancel the DMA transfer and enable RDI.
RDI will trigger an UART interrupt in case we have bytes in the FIFO.
Once we read bytes manually from the FIFO we enable RX-DMA again
(without RDI) with the same 250ms timeout.

One downside with this approach is that latency sensitive protocols that
transfer less than 48 bytes will have to wait 250ms to complete.

Is there maybe a user interface where one could set small or bulk transfers?

Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/tty/serial/8250/8250_omap.c | 33 -
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/8250/8250_omap.c 
b/drivers/tty/serial/8250/8250_omap.c
index 383f143b6b36..68d03553617b 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -113,6 +113,7 @@ struct omap8250_priv {
struct uart_8250_dma omap8250_dma;
spinlock_t rx_dma_lock;
bool rx_dma_broken;
+   struct timer_list rx_dma_wd;
 };
 
 static u32 uart_read(struct uart_8250_port *up, u32 reg)
@@ -599,6 +600,7 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id)
return IRQ_RETVAL(ret);
 }
 
+static void omap8250_rx_dma_wd(unsigned long data);
 static int omap_8250_startup(struct uart_port *port)
 {
struct uart_8250_port *up = up_to_u8250p(port);
@@ -627,6 +629,10 @@ static int omap_8250_startup(struct uart_port *port)
dev_warn_ratelimited(port-dev,
 failed to request DMA\n);
up-dma = NULL;
+   } else {
+   init_timer(priv-rx_dma_wd);
+   priv-rx_dma_wd.function = omap8250_rx_dma_wd;
+   priv-rx_dma_wd.data = (unsigned long) up;
}
}
 
@@ -635,7 +641,9 @@ static int omap_8250_startup(struct uart_port *port)
if (ret  0)
goto err;
 
-   up-ier = UART_IER_RLSI | UART_IER_RDI;
+   up-ier = UART_IER_RLSI;
+   if (!up-dma-rxchan)
+   up-ier |= UART_IER_RDI;
serial_out(up, UART_IER, up-ier);
 
 #ifdef CONFIG_PM
@@ -670,6 +678,8 @@ static void omap_8250_shutdown(struct uart_port *port)
if (up-dma)
up-dma-rx_dma(up, UART_IIR_RX_TIMEOUT);
 
+   del_timer_sync(priv-rx_dma_wd);
+
pm_runtime_get_sync(port-dev);
 
serial_out(up, UART_OMAP_WER, 0);
@@ -846,6 +856,9 @@ static int omap_8250_rx_dma(struct uart_8250_port *p, 
unsigned int iir)
if (dma-rx_running)
goto out;
 
+   if (p-ier  UART_IER_RDI)
+   goto out;
+
desc = dmaengine_prep_slave_single(dma-rxchan, dma-rx_addr,
   dma-rx_size, DMA_DEV_TO_MEM,
   DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
@@ -864,6 +877,7 @@ static int omap_8250_rx_dma(struct uart_8250_port *p, 
unsigned int iir)
   dma-rx_size, DMA_FROM_DEVICE);
 
dma_async_issue_pending(dma-rxchan);
+   mod_timer(priv-rx_dma_wd, jiffies + HZ / 4);
 out:
spin_unlock_irqrestore(priv-rx_dma_lock, flags);
return err;
@@ -1044,6 +1058,9 @@ static int omap_8250_dma_handle_irq(struct uart_port 
*port)
dma_err = omap_8250_rx_dma(up, iir);
if (dma_err) {
status = serial8250_rx_chars(up, status);
+
+   up-ier = ~UART_IER_RDI;
+   serial_port_out(port, UART_IER, up-ier);
omap_8250_rx_dma(up, 0);
}
}
@@ -1069,6 +1086,20 @@ static int omap_8250_dma_handle_irq(struct uart_port 
*port)
return 1;
 }
 
+static void omap8250_rx_dma_wd(unsigned long data)
+{
+   struct uart_8250_port   *up = (void *) data;
+   struct uart_port*port = up-port;
+   unsigned long flags;
+
+   spin_lock_irqsave(port-lock, flags);
+
+   omap_8250_rx_dma_flush(up);
+   up-ier |= UART_IER_RDI

Re: [PATCH 2/3] dma: add __must_check annotation for dmaengine_pause()

2015-08-11 Thread Sebastian Andrzej Siewior
On 08/11/2015 12:06 PM, Russell King - ARM Linux wrote:
 I think what people need to learn is that an API in the kernel which
 returns an int _can_ fail - it returns an int so it _can_ return an
 error code.  If it _can_ return an error code, there _will_ be
 implementations which _do_.
 
 If you don't check the return code, either your code doesn't care whether
 the function was successful or not, or you're playing with fire.  This is
 a prime example of playing with fire.
 
 Let's leave the crappy userspace laziness with regard to error checking
 to userspace, and keep it out of the kernel.
 
 Yes, the DMA engine capabilities may not be sufficient to describe every
 detail of DMA engines, but that's absolutely no reason to skimp on error
 checking.  Had there been some kind of error checking at the site, this
 problem would have been spotted before the 8250-omap driver was merged.

Let me disable RX-DMA in 8250-omap code and push that stable. Then we
won't need a special annotation for pause support because it remains
off and is currently about one user. I browsed each driver in
drivers/dma each one which does support pause supports it and all of
them implement it unconditionally (ipu_idmac grabs a mutex first but
this is another story).
Adding error checking to 8250-omap like I have it in #1 and disabling
RX-DMA in case pause fails looks be reasonable since there is nothing
else that can be done I guess.
Once we have the missing piece in omap-dma the RX-DMA can be enabled in
8250-omap.
Does this sound like a plan we can agree on?

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/3] tty: serial: 8250_omap: do not use RX DMA if pause is not supported

2015-08-10 Thread Sebastian Andrzej Siewior
On 08/10/2015 01:54 PM, Peter Ujfalusi wrote:
 diff --git a/drivers/tty/serial/8250/8250_omap.c 
 b/drivers/tty/serial/8250/8250_omap.c
 index 0340ee6ba970..07a11e0935e4 100644
 --- a/drivers/tty/serial/8250/8250_omap.c
 @@ -769,7 +771,9 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port 
 *p)
  return;
  }
  
 -dmaengine_pause(dma-rxchan);
 +ret = dmaengine_pause(dma-rxchan);
 +if (WARN_ON_ONCE(ret))
 +priv-rx_dma_broken = true;
 
 I don't think this is good thing for the stable _and_ for the mainline at the
 same time:
 in stable the rx DMA should not be allowed since the stable kernels does not
 allow pause/resume with omap-dma, so there the rx DMA should be just disabled
 for UART. This change will cause regression since it introduce a WARN_ON_ONCE,
 which will be printed if the user tries to use non working feature.

Okay. We do have pause support in mainline for edma since v4.2-rc1.
This driver can use edma or sdma depending on the configuration. But it
is not yet released. So you suggest remove RX-DMA support completely
from the 8250-omap, mark it stable, and revert that patch once we have
it fixed in sdma?

 In mainline you will eventually going to have pause/resume support so this
 patch will make no sense there.

The way this works is that it has to be fixed upstream before it can be
backported stable. Also Russell made clear (for a good reason) that the
RX problem has to be fixed upstream before he thinks about acking the
SDMA patch.
So if you prefer to instead remove RX-DMA until it is fixed, I am all
yours.


Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/3] tty: serial: 8250_omap: do not use RX DMA if pause is not supported

2015-08-08 Thread Sebastian Andrzej Siewior
On 08/08/2015 02:28 AM, Peter Hurley wrote:
 diff --git a/drivers/tty/serial/8250/8250_omap.c 
 b/drivers/tty/serial/8250/8250_omap.c
 index 0340ee6ba970..07a11e0935e4 100644
 --- a/drivers/tty/serial/8250/8250_omap.c
 +++ b/drivers/tty/serial/8250/8250_omap.c
 @@ -769,7 +771,9 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port 
 *p)
  return;
  }
  
 -dmaengine_pause(dma-rxchan);
 +ret = dmaengine_pause(dma-rxchan);
 +if (WARN_ON_ONCE(ret))
 +priv-rx_dma_broken = true;
 
 No offense, Sebastian, but it boggles my mind that anyone could defend this
 as solid api design. We're in the middle of an interrupt handler and the
 slave dma driver is /just/ telling us now that it doesn't implement this
 functionality?!!?

This is the best thing I could come up with. But to be fair: This
happens once _very_ early in the process and is 100% reproducible. The
WARN_ON should trigger user attention.

 The dmaengine api has _so much_ setup and none of it contemplates telling the
 consumer that critical functionality is missing?

Lets say it is a missing feature which was not noticed / required until
now. I have the missing functionality in patch #3. I don't see the
point in adding a lookup API for this feature which has to be
backported stable just to figure out that RX-DMA might not work.
Again: the WARN_ON triggers on the first short RX read _or_ on shutdown
of the port which is not after hours using the port.

 Even dma_get_slave_caps() returns _true_ for cmd_pause support; ok, that
 interface is pointless.
 
 Rather than losing /critical data/ here, the interrupt handler should just
 busy-wait until dmaengine_tx_status() returns DMA_COMPLETE for the rx_cookie.

This might not happen at all. At 115200 I *never* encouraged this. Once
the FIFO is filled with less than RX-trigger size than the UART sends
the time-out interrupt and the DMA *never* completes. Even if the FIFO
reaches trigger size later. So you have to abort the DMA transfer and
read data manually from the FIFO. That is why the omap enqueues the
RX-transfer upfront (while the FIFO is still empty).

It happens *sometimes* that the UART sends a timeout interrupt and the
DMA transfer just is started and it has been only observed at 3mbaud
(but there were no tests 115200  x  3mbaud that I know of).

Therefor I think this is a fair fix without hiding anything.

 Regards,
 Peter Hurley

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] dma: omap-dma: add support for pause of non-cyclic transfers

2015-08-07 Thread Sebastian Andrzej Siewior
On 08/07/2015 03:17 PM, Russell King - ARM Linux wrote:
 On Fri, Aug 07, 2015 at 02:35:45PM +0200, Sebastian Andrzej Siewior wrote:
 On 08/07/2015 12:55 PM, Russell King - ARM Linux wrote:
 On Fri, Aug 07, 2015 at 10:41:57AM +0200, Sebastian Andrzej Siewior wrote:
 This DMA driver is used by 8250-omap on DRA7-evm. There is one
 requirement that is to pause a transfer. This is currently used on the RX
 side. It is possible that the UART HW aborted the RX (UART's RX-timeout)
 but the DMA controller starts the transfer shortly after.
 Before we can manually purge the FIFO we need to pause the transfer,
 check how many bytes it already received and terminate the transfer
 without it making any progress.

 From testing on the TX side it seems that it is possible that we invoke
 pause once the transfer has completed which is indicated by the missing
 CCR_ENABLE bit but before the interrupt has been noticed. In that case the
 interrupt will come even after disabling it.

 How do you cope with the OMAP DMA hardware clearing its FIFO when you
 pause it?

 I don't
 
 ... and so you introduce a silent data loss bug into the driver.  That's
 not very clever.
 
 Right now the 820-omap (8250-dma in general, too but they don't use
 this driver) pause only the RX transfer in an error condition. This
 means it is only device-to-mem transfer. I only mentioned the TX
 transfer here since this was easier to test.
 
 That may be how 8250 works, but 8250 is not everything.  You can't ignore
 this problem.  You have to deal with it - either by not allowing a channel
 that would loose data to be paused, or by recovering from that condition.
 You're not doing either in your patch.
 
 Therefore, I have no other option but to NAK your change.  Sorry.
 
 Please fix this.

Would it be okay if I only allow pause for RX-transfers?
For TX-transfers, I would need to update the start-address so the
transfers begins where it stopped. However based on your concern I
can't really assume that the position reported by the HW is the correct
one.

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] dma: omap-dma: add support for pause of non-cyclic transfers

2015-08-07 Thread Sebastian Andrzej Siewior
On 08/07/2015 03:22 PM, Russell King - ARM Linux wrote:
 On Fri, Aug 07, 2015 at 12:36:14PM +0200, Sebastian Andrzej Siewior wrote:
 On 08/07/2015 11:44 AM, Peter Ujfalusi wrote:
 with a short testing audio did not broke (the only user of pause/resume)
 Some comments embedded.

 Cc: sta...@vger.kernel.org

 Why stable? This is not fixing any bugs since the PAUSE was not allowed for
 non cyclic transfers.

 Hmmm. The DRA7x was using pause before for UART. I just did not see it
 coming that it was not allowed here. John made a similar change to the
 edma driver and I assumed it went stable but now I see that it was just
 cherry-picked into the ti tree.
 
 This is *NOT* stable material.
 
 Pause of these channels is something that omap-dma has *never* supported.
 Therefore, it is *not* a regression.  What you are doing is *adding* a
 feature to the omap-dma driver.  That is not stable material in any sense.
 Stable is for bug fixes to existing code, not feature enhancements.

I didn't consider this as a feature.

 If something else has been converted to pause channels and that is causing
 a problem, then _that_ conversion is where the bug lies, not the lack of
 support in the omap-dma.

So we had the 8250-DMA doing pause and all its current users implement
it. We have a DMA driver tree which is not used and it not implementing
pause (not implementing pause at all). Later we get a combo of 8250-DMA
+ DMA driver that is broken because the lack of pause and this is
noticed a few kernel releases later.
The only way of fixing the bug is by implementing the pause feature.
Now you are saying that even if I implement this missing feature in a
newer kernel I am not allowed to mark it stable despite the fact that
it fixes an existing problem in older kernels because it is not a
regression.

 If it's a result of using some new driver with omap-dma, then the problem
 is with whatever introduced that new combination - it's not that omap-dma
 is buggy.
 
 Don't fix bugs in -stable by adding features.  That's _no_ way to fix bugs.
 
 NAK on this feature patch having any kind of stable tag.

I already accepted this.

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/3] tty: serial: 8250_omap: do not use RX DMA if pause is not supported

2015-08-07 Thread Sebastian Andrzej Siewior
The 8250-omap driver requires the DMA-engine driver to support the pause
command in order to properly turn off programmed RX transfer before the
driver stars manually reading from the FIFO.
The lacking support of the requirement has been discovered recently. In
order to stay safe here we disable support for RX-DMA as soon as we
notice that it does not work. This should happen very early.
If the user does not want to see this backtrace he can either disable
DMA support (completely or RX-only) or backport the required patches for
edma / omap-dma once they hit mainline.

Cc: sta...@vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/tty/serial/8250/8250_omap.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/8250/8250_omap.c 
b/drivers/tty/serial/8250/8250_omap.c
index 0340ee6ba970..07a11e0935e4 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -112,6 +112,7 @@ struct omap8250_priv {
struct work_struct qos_work;
struct uart_8250_dma omap8250_dma;
spinlock_t rx_dma_lock;
+   bool rx_dma_broken;
 };
 
 static u32 uart_read(struct uart_8250_port *up, u32 reg)
@@ -761,6 +762,7 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p)
struct omap8250_priv*priv = p-port.private_data;
struct uart_8250_dma*dma = p-dma;
unsigned long   flags;
+   int ret;
 
spin_lock_irqsave(priv-rx_dma_lock, flags);
 
@@ -769,7 +771,9 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p)
return;
}
 
-   dmaengine_pause(dma-rxchan);
+   ret = dmaengine_pause(dma-rxchan);
+   if (WARN_ON_ONCE(ret))
+   priv-rx_dma_broken = true;
 
spin_unlock_irqrestore(priv-rx_dma_lock, flags);
 
@@ -813,6 +817,9 @@ static int omap_8250_rx_dma(struct uart_8250_port *p, 
unsigned int iir)
break;
}
 
+   if (priv-rx_dma_broken)
+   return -EINVAL;
+
spin_lock_irqsave(priv-rx_dma_lock, flags);
 
if (dma-rx_running)
-- 
2.5.0

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] dma: omap-dma: add support for pause of non-cyclic transfers

2015-08-07 Thread Sebastian Andrzej Siewior
This DMA driver is used by 8250-omap on DRA7-evm. There is one
requirement that is to pause a transfer. This is currently used on the RX
side. It is possible that the UART HW aborted the RX (UART's RX-timeout)
but the DMA controller starts the transfer shortly after.
Before we can manually purge the FIFO we need to pause the transfer,
check how many bytes it already received and terminate the transfer
without it making any progress.

From testing on the TX side it seems that it is possible that we invoke
pause once the transfer has completed which is indicated by the missing
CCR_ENABLE bit but before the interrupt has been noticed. In that case the
interrupt will come even after disabling it.

The AM572x manual says that we have to wait for the CCR_RD_ACTIVE 
CCR_WR_ACTIVE bits to be gone before programming it again here is the
drain loop. Also it looks like without the drain the TX-transfer makes
sometimes progress.

One note: The pause + resume combo is broken because after resume the
the complete transfer will be programmed again. That means the already
transferred bytes (until the pause event) will be sent again. This is
currently not important for my UART user because it does only pause +
terminate.

Cc: sta...@vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/dma/omap-dma.c | 54 ++
 1 file changed, 41 insertions(+), 13 deletions(-)

diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 249445c8a4c6..6b8497203caf 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -299,7 +299,7 @@ static void omap_dma_start(struct omap_chan *c, struct 
omap_desc *d)
omap_dma_chan_write(c, CCR, d-ccr | CCR_ENABLE);
 }
 
-static void omap_dma_stop(struct omap_chan *c)
+static int omap_dma_stop(struct omap_chan *c)
 {
struct omap_dmadev *od = to_omap_dma_dev(c-vc.chan.device);
uint32_t val;
@@ -342,8 +342,26 @@ static void omap_dma_stop(struct omap_chan *c)
 
omap_dma_glbl_write(od, OCP_SYSCONFIG, sysconfig);
} else {
+   int i = 0;
+
+   if (!(val  CCR_ENABLE))
+   return -EINVAL;
+
val = ~CCR_ENABLE;
omap_dma_chan_write(c, CCR, val);
+   do {
+   val = omap_dma_chan_read(c, CCR);
+   if (!(val  (CCR_RD_ACTIVE | CCR_WR_ACTIVE)))
+   break;
+   if (i  100)
+   break;
+   udelay(5);
+   } while (1);
+
+   if (val  (CCR_RD_ACTIVE | CCR_WR_ACTIVE))
+   dev_err(c-vc.chan.device-dev,
+   DMA drain did not complete on lch %d\n,
+   c-dma_ch);
}
 
mb();
@@ -358,6 +376,7 @@ static void omap_dma_stop(struct omap_chan *c)
 
omap_dma_chan_write(c, CLNK_CTRL, val);
}
+   return 0;
 }
 
 static void omap_dma_start_sg(struct omap_chan *c, struct omap_desc *d,
@@ -728,6 +747,8 @@ static enum dma_status omap_dma_tx_status(struct dma_chan 
*chan,
} else {
txstate-residue = 0;
}
+   if (ret == DMA_IN_PROGRESS  c-paused)
+   ret = DMA_PAUSED;
spin_unlock_irqrestore(c-vc.lock, flags);
 
return ret;
@@ -1053,28 +1074,33 @@ static int omap_dma_terminate_all(struct dma_chan *chan)
 static int omap_dma_pause(struct dma_chan *chan)
 {
struct omap_chan *c = to_omap_dma_chan(chan);
+   struct omap_dmadev *od = to_omap_dma_dev(chan-device);
+   unsigned long flags;
+   int ret = -EINVAL;
 
-   /* Pause/Resume only allowed with cyclic mode */
-   if (!c-cyclic)
-   return -EINVAL;
+   spin_lock_irqsave(od-irq_lock, flags);
 
-   if (!c-paused) {
-   omap_dma_stop(c);
-   c-paused = true;
+   if (!c-paused  c-desc) {
+   ret = omap_dma_stop(c);
+   if (!ret)
+   c-paused = true;
}
 
-   return 0;
+   spin_unlock_irqrestore(od-irq_lock, flags);
+
+   return ret;
 }
 
 static int omap_dma_resume(struct dma_chan *chan)
 {
struct omap_chan *c = to_omap_dma_chan(chan);
+   struct omap_dmadev *od = to_omap_dma_dev(chan-device);
+   unsigned long flags;
+   int ret = -EINVAL;
 
-   /* Pause/Resume only allowed with cyclic mode */
-   if (!c-cyclic)
-   return -EINVAL;
+   spin_lock_irqsave(od-irq_lock, flags);
 
-   if (c-paused) {
+   if (c-paused  c-desc) {
mb();
 
/* Restore channel link register */
@@ -1082,9 +1108,11 @@ static int omap_dma_resume(struct dma_chan *chan)
 
omap_dma_start(c, c-desc);
c-paused = false;
+   ret = 0;
}
+   spin_unlock_irqrestore(od-irq_lock, flags

Re: [PATCH] dma: omap-dma: add support for pause of non-cyclic transfers

2015-08-07 Thread Sebastian Andrzej Siewior
On 08/07/2015 11:44 AM, Peter Ujfalusi wrote:
 On 08/07/2015 11:41 AM, Sebastian Andrzej Siewior wrote:
 This DMA driver is used by 8250-omap on DRA7-evm. There is one
 requirement that is to pause a transfer. This is currently used on the RX
 side. It is possible that the UART HW aborted the RX (UART's RX-timeout)
 but the DMA controller starts the transfer shortly after.
 Before we can manually purge the FIFO we need to pause the transfer,
 check how many bytes it already received and terminate the transfer
 without it making any progress.

 From testing on the TX side it seems that it is possible that we invoke
 pause once the transfer has completed which is indicated by the missing
 CCR_ENABLE bit but before the interrupt has been noticed. In that case the
 interrupt will come even after disabling it.

 The AM572x manual says that we have to wait for the CCR_RD_ACTIVE 
 CCR_WR_ACTIVE bits to be gone before programming it again here is the
 drain loop. Also it looks like without the drain the TX-transfer makes
 sometimes progress.

 One note: The pause + resume combo is broken because after resume the
 the complete transfer will be programmed again. That means the already
 transferred bytes (until the pause event) will be sent again. This is
 currently not important for my UART user because it does only pause +
 terminate.
 
 with a short testing audio did not broke (the only user of pause/resume)
 Some comments embedded.
 
 Cc: sta...@vger.kernel.org
 
 Why stable? This is not fixing any bugs since the PAUSE was not allowed for
 non cyclic transfers.

Hmmm. The DRA7x was using pause before for UART. I just did not see it
coming that it was not allowed here. John made a similar change to the
edma driver and I assumed it went stable but now I see that it was just
cherry-picked into the ti tree.
If you are not comfortable it being stable material I can drop it.

 Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
 ---
  drivers/dma/omap-dma.c | 54 
 ++
  1 file changed, 41 insertions(+), 13 deletions(-)

 diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
 index 249445c8a4c6..6b8497203caf 100644
 --- a/drivers/dma/omap-dma.c
 +++ b/drivers/dma/omap-dma.c
 @@ -299,7 +299,7 @@ static void omap_dma_start(struct omap_chan *c, struct 
 omap_desc *d)
  omap_dma_chan_write(c, CCR, d-ccr | CCR_ENABLE);
  }
  
 -static void omap_dma_stop(struct omap_chan *c)
 +static int omap_dma_stop(struct omap_chan *c)
  {
  struct omap_dmadev *od = to_omap_dma_dev(c-vc.chan.device);
  uint32_t val;
 @@ -342,8 +342,26 @@ static void omap_dma_stop(struct omap_chan *c)
  
  omap_dma_glbl_write(od, OCP_SYSCONFIG, sysconfig);
  } else {
 +int i = 0;
 +
 +if (!(val  CCR_ENABLE))
 +return -EINVAL;
 +
  val = ~CCR_ENABLE;
  omap_dma_chan_write(c, CCR, val);
 +do {
 +val = omap_dma_chan_read(c, CCR);
 +if (!(val  (CCR_RD_ACTIVE | CCR_WR_ACTIVE)))
 +break;
 +if (i  100)
 
 if (++i  100)
   break;
 to avoid infinite loop?

Ah. So I forgot to increment the counter. A few lines above there is
the same loop as a workaround for something. This is the same loop. I
could merge the loop + warning if you prefer. to have those things in
one place. I could also just increment i. Merging the two loops might
be better.

 +break;
 +udelay(5);
 +} while (1);
 +
 +if (val  (CCR_RD_ACTIVE | CCR_WR_ACTIVE))
 
 if (i  100) ?

While that would work, too I think it is more explicit to the reader if
you check for the condition that is important to you.

 +dev_err(c-vc.chan.device-dev,
 +DMA drain did not complete on lch %d\n,
 +c-dma_ch);
  }
  
  mb();

Sebastian

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] dma: omap-dma: add support for pause of non-cyclic transfers

2015-08-07 Thread Sebastian Andrzej Siewior
On 08/07/2015 06:07 PM, Peter Hurley wrote:
 If we look at what 8250-dma.c is doing:

 if (dma-rx_running) {
 dmaengine_pause(dma-rxchan);

 It's 8250-dma.c which is silently _ignoring_ the return code, failing
 to check that the operation it requested worked.  Maybe this should be
 WARN_ON(dmaengine_pause(dma-rxchan)) or at least it should print a
 message?
 
 Thanks for the suggestion; I'll hold on to that and push it after we add
 the 8250 omap dma pause in mainline.

I have a patch ready with WARN_ON_ONCE() for 8250-omap and 8250-dma.
This warning would trigger on am335x/edma until v4.2-rc1 and omap-dma
based version is open. I could post it if you want me to.
Besides that those two, there are four other drivers ignoring the
return code dmaengine_pause().

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] dma: omap-dma: add support for pause of non-cyclic transfers

2015-08-07 Thread Sebastian Andrzej Siewior
This DMA driver is used by 8250-omap on DRA7-evm. There is one
requirement that is to pause a transfer. This is currently used on the RX
side. It is possible that the UART HW aborted the RX (UART's RX-timeout)
but the DMA controller starts the transfer shortly after.
Before we can manually purge the FIFO we need to pause the transfer,
check how many bytes it already received and terminate the transfer
without it making any progress.

From testing on the TX side it seems that it is possible that we invoke
pause once the transfer has completed which is indicated by the missing
CCR_ENABLE bit but before the interrupt has been noticed. In that case the
interrupt will come even after disabling it.

The AM572x manual says that we have to wait for the CCR_RD_ACTIVE 
CCR_WR_ACTIVE bits to be gone before programming it again here is the
drain loop. Also it looks like without the drain the TX-transfer makes
sometimes progress.

One note: The pause + resume combo is broken because after resume the
the complete transfer will be programmed again. That means the already
transferred bytes (until the pause event) will be sent again. This is
currently not important for my UART user because it does only pause +
terminate.

v1…v2:
  - move the drain loop into omap_dma_drain_chan() instead of having it
twice.
  - allow pause only for DMA_DEV_TO_MEM transfers if non-cyclic. Add a
comment why DMA_MEM_TO_DEV not allowed.
  - clear pause on terminate_all. Otherwise pause() + terminate_all()
will keep the pause bit set and we can't pause the following
transfer.

Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/dma/omap-dma.c | 107 +
 1 file changed, 73 insertions(+), 34 deletions(-)

diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 249445c8a4c6..6bbf089d2d7f 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -299,7 +299,30 @@ static void omap_dma_start(struct omap_chan *c, struct 
omap_desc *d)
omap_dma_chan_write(c, CCR, d-ccr | CCR_ENABLE);
 }
 
-static void omap_dma_stop(struct omap_chan *c)
+static void omap_dma_drain_chan(struct omap_chan *c)
+{
+   int i;
+   uint32_t val;
+
+   /* Wait for sDMA FIFO to drain */
+   for (i = 0; ; i++) {
+   val = omap_dma_chan_read(c, CCR);
+   if (!(val  (CCR_RD_ACTIVE | CCR_WR_ACTIVE)))
+   break;
+
+   if (i  100)
+   break;
+
+   udelay(5);
+   }
+
+   if (val  (CCR_RD_ACTIVE | CCR_WR_ACTIVE))
+   dev_err(c-vc.chan.device-dev,
+   DMA drain did not complete on lch %d\n,
+   c-dma_ch);
+}
+
+static int omap_dma_stop(struct omap_chan *c)
 {
struct omap_dmadev *od = to_omap_dma_dev(c-vc.chan.device);
uint32_t val;
@@ -312,7 +335,6 @@ static void omap_dma_stop(struct omap_chan *c)
val = omap_dma_chan_read(c, CCR);
if (od-plat-errata  DMA_ERRATA_i541  val  CCR_TRIGGER_SRC) {
uint32_t sysconfig;
-   unsigned i;
 
sysconfig = omap_dma_glbl_read(od, OCP_SYSCONFIG);
val = sysconfig  ~DMA_SYSCONFIG_MIDLEMODE_MASK;
@@ -323,27 +345,18 @@ static void omap_dma_stop(struct omap_chan *c)
val = ~CCR_ENABLE;
omap_dma_chan_write(c, CCR, val);
 
-   /* Wait for sDMA FIFO to drain */
-   for (i = 0; ; i++) {
-   val = omap_dma_chan_read(c, CCR);
-   if (!(val  (CCR_RD_ACTIVE | CCR_WR_ACTIVE)))
-   break;
-
-   if (i  100)
-   break;
-
-   udelay(5);
-   }
-
-   if (val  (CCR_RD_ACTIVE | CCR_WR_ACTIVE))
-   dev_err(c-vc.chan.device-dev,
-   DMA drain did not complete on lch %d\n,
-   c-dma_ch);
+   omap_dma_drain_chan(c);
 
omap_dma_glbl_write(od, OCP_SYSCONFIG, sysconfig);
} else {
+
+   if (!(val  CCR_ENABLE))
+   return -EINVAL;
+
val = ~CCR_ENABLE;
omap_dma_chan_write(c, CCR, val);
+
+   omap_dma_drain_chan(c);
}
 
mb();
@@ -358,6 +371,7 @@ static void omap_dma_stop(struct omap_chan *c)
 
omap_dma_chan_write(c, CLNK_CTRL, val);
}
+   return 0;
 }
 
 static void omap_dma_start_sg(struct omap_chan *c, struct omap_desc *d,
@@ -728,6 +742,8 @@ static enum dma_status omap_dma_tx_status(struct dma_chan 
*chan,
} else {
txstate-residue = 0;
}
+   if (ret == DMA_IN_PROGRESS  c-paused)
+   ret = DMA_PAUSED;
spin_unlock_irqrestore(c-vc.lock, flags);
 
return ret;
@@ -1038,10 +1054,8 @@ static int omap_dma_terminate_all(struct

Re: [PATCH v2] dma: omap-dma: add support for pause of non-cyclic transfers

2015-08-07 Thread Sebastian Andrzej Siewior
* Russell King - ARM Linux | 2015-08-07 17:26:48 [+0100]:

On Fri, Aug 07, 2015 at 05:36:05PM +0200, Sebastian Andrzej Siewior wrote:
 +/*
 + * We do not allow DMA_MEM_TO_DEV transfers to be paused.
 + * According to RMK the OMAP hardware might prefetch bytes from
 + * memory into its FIFO and not send it to the device due to the
 + * pause. The bytes in the FIFO are cleared on pause. It is
 + * unspecified by how many bytes the source address is updated
 + * if at all.

Would you mind rewording the above.

Please take the time to read the manuals for the device you are playing
with.  It's mostly documented in there.  See the OMAP4430 ES2.x TRM,
16.4.18 and 16.4.19.

I didn't connect the dots that well. Thank you.

…

I updated the comment to:

/* 
 * We do not allow DMA_MEM_TO_DEV transfers to be paused.
 * From the AM572x TRM, 16.1.4.18 Disabling a Channel During Transfer:
 * When a channel is disabled during a transfer, the channel undergoes
 * an abort, unless it is hardware-source-synchronized ….
 * A source-synchronised channel is one where the fetching of data is
 * under control of the device. In other words, a device-to-memory
 * transfer. So, a destination-synchronised channel (which would be a
 * memory-to-device transfer) undergoes an abort if the the CCR_ENABLE
 * bit is cleared.
 * From 16.1.4.20.4.6.2 Abort: If an abort trigger occurs, the channel
 * aborts immediately after completion of current read/write
 * transactions and then the FIFO is cleaned up. The term cleaned up
 * is not defined. TI recommends to check that RD_ACTIVE and WR_ACTIVE
 * are both clear _before_ disabling the channel, otherwise data loss
 * will occur.
 * The problem is that if the channel is active, then device activity
 * can result in DMA activity starting between reading those as both
 * clear and the write to DMA_CCR to clear the enable bit hitting the
 * hardware. If the DMA hardware can't drain the data in its FIFO to the
 * destination, then data loss might occur (say if we write to an UART
 * and the UART is not accepting any further data).
 */

would that be okay?

Due to this, the OMAP DMA engine driver was submitted with this in the
cover note:

For the OMAP DMAengine driver, there's a few short-comings:

1. pause/resume support is not implemented; it's not clear whether the
   OMAP hardware is capable of supporting this sanely.

If I google for it, I find it. pause/resume support for cyclic was added
later without a note why it is only supported for cyclic.

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] dma: omap-dma: add support for pause of non-cyclic transfers

2015-08-07 Thread Sebastian Andrzej Siewior
On 08/07/2015 05:29 PM, Russell King - ARM Linux wrote:
 On Fri, Aug 07, 2015 at 11:08:48AM -0400, Peter Hurley wrote:
 [ + Greg KH ]

 On 08/07/2015 09:57 AM, Russell King - ARM Linux wrote:
 As it is something that the driver has _not_ supported, you are clearly
 adding a feature to an existing driver.  It's not a bug fix.

 If something else has been converted to pause channels and that is causing
 a problem, then _that_ conversion is where the bug lies, not the lack of
 support in the omap-dma.

 FWIW, the actual bug is the api that silently does nothing.
 
 Incorrect.
 
 static int omap_dma_pause(struct dma_chan *chan)
 {
 struct omap_chan *c = to_omap_dma_chan(chan);
 
 /* Pause/Resume only allowed with cyclic mode */
 if (!c-cyclic)
 return -EINVAL;
 
 Asking for the channel to be paused will return an error code indicating
 that the request failed.  That will be propagated back through to the
 return code of dmaengine_pause().
 
 If we look at what 8250-dma.c is doing:
 
 if (dma-rx_running) {
 dmaengine_pause(dma-rxchan);
 
 It's 8250-dma.c which is silently _ignoring_ the return code, failing
 to check that the operation it requested worked.  Maybe this should be
 WARN_ON(dmaengine_pause(dma-rxchan)) or at least it should print a
 message?

I think this is what Peter meant by saying silently does nothing.

 So, I guess that means that older kernels will just have to remain broken -
 all because the basic testing of the original code was never undertaken
 to ensure that basic stuff like reception of characters worked properly.

Hehe. I wouldn't describe testing at 3mbaud as basic. This reads as I
didn't do any kind of testing at all prior submitting the driver. This
was not the case.

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] dma: add __must_check annotation for dmaengine_pause()

2015-08-07 Thread Sebastian Andrzej Siewior
In 8250-omap I learned it the hard way that ignoring the return code
of dmaengine_pause() might be bad because the underlying DMA driver
might not support the function at all and so not doing what one is
expecting.
This patch adds the __must_check annotation as suggested by Russell King.

Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 include/linux/dmaengine.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 8ad9a4e839f6..4eac4716bded 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -825,7 +825,7 @@ static inline int dmaengine_terminate_all(struct dma_chan 
*chan)
return -ENOSYS;
 }
 
-static inline int dmaengine_pause(struct dma_chan *chan)
+static inline int __must_check dmaengine_pause(struct dma_chan *chan)
 {
if (chan-device-device_pause)
return chan-device-device_pause(chan);
-- 
2.5.0

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


omap-dma + 8250_omap: fix the dmaengine_pause()

2015-08-07 Thread Sebastian Andrzej Siewior
#1 is something that can go stable and disables RX-DMA should it
   notice that it does not work.
#2 adds the anotation as suggest by Russell.
#3 adds the missing feature to omap-dma so dmaengine_pause() works. Once
   this is merged, the warning from #1 disappears.

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 3/3] dma: omap-dma: add support for pause of non-cyclic transfers

2015-08-07 Thread Sebastian Andrzej Siewior
This DMA driver is used by 8250-omap on DRA7-evm. There is one
requirement that is to pause a transfer. This is currently used on the RX
side. It is possible that the UART HW aborted the RX (UART's RX-timeout)
but the DMA controller starts the transfer shortly after.
Before we can manually purge the FIFO we need to pause the transfer,
check how many bytes it already received and terminate the transfer
without it making any progress.

From testing on the TX side it seems that it is possible that we invoke
pause once the transfer has completed which is indicated by the missing
CCR_ENABLE bit but before the interrupt has been noticed. In that case the
interrupt will come even after disabling it.

The AM572x manual says that we have to wait for the CCR_RD_ACTIVE 
CCR_WR_ACTIVE bits to be gone before programming it again here is the
drain loop. Also it looks like without the drain the TX-transfer makes
sometimes progress.

One note: The pause + resume combo is broken because after resume the
the complete transfer will be programmed again. That means the already
transferred bytes (until the pause event) will be sent again. This is
currently not important for my UART user because it does only pause +
terminate.

v2…v3:
  - rephrase the comment based on Russell's information / feedback.

v1…v2:
  - move the drain loop into omap_dma_drain_chan() instead of having it
twice.
  - allow pause only for DMA_DEV_TO_MEM transfers if non-cyclic. Add a
comment why DMA_MEM_TO_DEV not allowed.
  - clear pause on terminate_all. Otherwise pause() + terminate_all()
will keep the pause bit set and we can't pause the following
transfer.

Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/dma/omap-dma.c | 122 +++--
 1 file changed, 88 insertions(+), 34 deletions(-)

diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 249445c8a4c6..cb217fab472e 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -299,7 +299,30 @@ static void omap_dma_start(struct omap_chan *c, struct 
omap_desc *d)
omap_dma_chan_write(c, CCR, d-ccr | CCR_ENABLE);
 }
 
-static void omap_dma_stop(struct omap_chan *c)
+static void omap_dma_drain_chan(struct omap_chan *c)
+{
+   int i;
+   uint32_t val;
+
+   /* Wait for sDMA FIFO to drain */
+   for (i = 0; ; i++) {
+   val = omap_dma_chan_read(c, CCR);
+   if (!(val  (CCR_RD_ACTIVE | CCR_WR_ACTIVE)))
+   break;
+
+   if (i  100)
+   break;
+
+   udelay(5);
+   }
+
+   if (val  (CCR_RD_ACTIVE | CCR_WR_ACTIVE))
+   dev_err(c-vc.chan.device-dev,
+   DMA drain did not complete on lch %d\n,
+   c-dma_ch);
+}
+
+static int omap_dma_stop(struct omap_chan *c)
 {
struct omap_dmadev *od = to_omap_dma_dev(c-vc.chan.device);
uint32_t val;
@@ -312,7 +335,6 @@ static void omap_dma_stop(struct omap_chan *c)
val = omap_dma_chan_read(c, CCR);
if (od-plat-errata  DMA_ERRATA_i541  val  CCR_TRIGGER_SRC) {
uint32_t sysconfig;
-   unsigned i;
 
sysconfig = omap_dma_glbl_read(od, OCP_SYSCONFIG);
val = sysconfig  ~DMA_SYSCONFIG_MIDLEMODE_MASK;
@@ -323,27 +345,18 @@ static void omap_dma_stop(struct omap_chan *c)
val = ~CCR_ENABLE;
omap_dma_chan_write(c, CCR, val);
 
-   /* Wait for sDMA FIFO to drain */
-   for (i = 0; ; i++) {
-   val = omap_dma_chan_read(c, CCR);
-   if (!(val  (CCR_RD_ACTIVE | CCR_WR_ACTIVE)))
-   break;
-
-   if (i  100)
-   break;
-
-   udelay(5);
-   }
-
-   if (val  (CCR_RD_ACTIVE | CCR_WR_ACTIVE))
-   dev_err(c-vc.chan.device-dev,
-   DMA drain did not complete on lch %d\n,
-   c-dma_ch);
+   omap_dma_drain_chan(c);
 
omap_dma_glbl_write(od, OCP_SYSCONFIG, sysconfig);
} else {
+
+   if (!(val  CCR_ENABLE))
+   return -EINVAL;
+
val = ~CCR_ENABLE;
omap_dma_chan_write(c, CCR, val);
+
+   omap_dma_drain_chan(c);
}
 
mb();
@@ -358,6 +371,7 @@ static void omap_dma_stop(struct omap_chan *c)
 
omap_dma_chan_write(c, CLNK_CTRL, val);
}
+   return 0;
 }
 
 static void omap_dma_start_sg(struct omap_chan *c, struct omap_desc *d,
@@ -728,6 +742,8 @@ static enum dma_status omap_dma_tx_status(struct dma_chan 
*chan,
} else {
txstate-residue = 0;
}
+   if (ret == DMA_IN_PROGRESS  c-paused)
+   ret = DMA_PAUSED;
spin_unlock_irqrestore(c-vc.lock, flags

Re: [PATCH] dma: omap-dma: add support for pause of non-cyclic transfers

2015-08-07 Thread Sebastian Andrzej Siewior
On 08/07/2015 01:44 PM, Peter Ujfalusi wrote:
 Cc: sta...@vger.kernel.org

 Why stable? This is not fixing any bugs since the PAUSE was not allowed for
 non cyclic transfers.

 Hmmm. The DRA7x was using pause before for UART. I just did not see it
 coming that it was not allowed here. John made a similar change to the
 edma driver and I assumed it went stable but now I see that it was just
 cherry-picked into the ti tree.
 If you are not comfortable it being stable material I can drop it.
 
 This change is needed for the UART DMA support if I'm not mistaken and this
 mode is not really supported by older kernels, so having this to implement
 something which is not going to be used in the stable kernels feels somehow 
 wrong.

We have the DT pieces since v3.19-rc1. And if I remember correctly I
tested this on am335x-evm and dra7-evm by I the time I posted the
patches. I agree that dra7 support was not the best back then but I am
almost sure that I had vanilla running for testing.
But I don't insist on the stable tag. Consider it dropped.

 Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
 ---
  drivers/dma/omap-dma.c | 54 
 ++
  1 file changed, 41 insertions(+), 13 deletions(-)

 diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
 index 249445c8a4c6..6b8497203caf 100644
 --- a/drivers/dma/omap-dma.c
 +++ b/drivers/dma/omap-dma.c
 @@ -299,7 +299,7 @@ static void omap_dma_start(struct omap_chan *c, struct 
 omap_desc *d)
omap_dma_chan_write(c, CCR, d-ccr | CCR_ENABLE);
  }
  
 -static void omap_dma_stop(struct omap_chan *c)
 +static int omap_dma_stop(struct omap_chan *c)
  {
struct omap_dmadev *od = to_omap_dma_dev(c-vc.chan.device);
uint32_t val;
 @@ -342,8 +342,26 @@ static void omap_dma_stop(struct omap_chan *c)
  
omap_dma_glbl_write(od, OCP_SYSCONFIG, sysconfig);
} else {
 +  int i = 0;
 +
 +  if (!(val  CCR_ENABLE))
 +  return -EINVAL;
 +
val = ~CCR_ENABLE;
omap_dma_chan_write(c, CCR, val);
 +  do {
 +  val = omap_dma_chan_read(c, CCR);
 +  if (!(val  (CCR_RD_ACTIVE | CCR_WR_ACTIVE)))
 +  break;
 +  if (i  100)

 if (++i  100)
 break;
 to avoid infinite loop?

 Ah. So I forgot to increment the counter. A few lines above there is
 the same loop as a workaround for something. This is the same loop. I
 could merge the loop + warning if you prefer. to have those things in
 one place. I could also just increment i. Merging the two loops might
 be better.
 
 The other loop is for handling the ERRATA i541 and the two loops can not be
 merged since the errata handling also require to change in SYSCONFIG register.

yes, but I had in mind is to put the loop into one function so we gain:

+static void omap_dma_drain_chan(struct omap_chan *c)
+{
+   int i;
+   uint32_t val;
+
+   /* Wait for sDMA FIFO to drain */
+   for (i = 0; ; i++) {
+   val = omap_dma_chan_read(c, CCR);
+   if (!(val  (CCR_RD_ACTIVE | CCR_WR_ACTIVE)))
+   break;
+
+   if (i  100)
+   break;
+
+   udelay(5);
+   }
+
+   if (val  (CCR_RD_ACTIVE | CCR_WR_ACTIVE))
+   dev_err(c-vc.chan.device-dev,
+   DMA drain did not complete on lch %d\n,
+   c-dma_ch);
+}

which is invoked by both parts of the if case (handling the errata not
not) instead of having the same loop twice.

 +  break;
 +  udelay(5);
 +  } while (1);
 +
 +  if (val  (CCR_RD_ACTIVE | CCR_WR_ACTIVE))

 if (i  100) ?

 While that would work, too I think it is more explicit to the reader if
 you check for the condition that is important to you.
 
 Yeah, I see that the errata handling is doing the same, fine by me.
good.

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] dma: omap-dma: add support for pause of non-cyclic transfers

2015-08-07 Thread Sebastian Andrzej Siewior
On 08/07/2015 12:55 PM, Russell King - ARM Linux wrote:
 On Fri, Aug 07, 2015 at 10:41:57AM +0200, Sebastian Andrzej Siewior wrote:
 This DMA driver is used by 8250-omap on DRA7-evm. There is one
 requirement that is to pause a transfer. This is currently used on the RX
 side. It is possible that the UART HW aborted the RX (UART's RX-timeout)
 but the DMA controller starts the transfer shortly after.
 Before we can manually purge the FIFO we need to pause the transfer,
 check how many bytes it already received and terminate the transfer
 without it making any progress.

 From testing on the TX side it seems that it is possible that we invoke
 pause once the transfer has completed which is indicated by the missing
 CCR_ENABLE bit but before the interrupt has been noticed. In that case the
 interrupt will come even after disabling it.
 
 How do you cope with the OMAP DMA hardware clearing its FIFO when you
 pause it?

I don't

 The problem is that on mem-to-device transfers, the DMA hardware can
 prefetch some data from memory into its FIFO before the device wants
 the data.  If you then disable the channel, the hardware clears the
 FIFO.
 
 It is unspecified whether the hardware updates the source address in
 this case, or by how much.  So it's pretty hard to undo the prefetching
 in software.
 
 The net result is: data loss.
 
 This is why I explicitly did not implement pause/resume for non-cyclic
 channels.

Right now the 820-omap (8250-dma in general, too but they don't use
this driver) pause only the RX transfer in an error condition. This
means it is only device-to-mem transfer. I only mentioned the TX
transfer here since this was easier to test.

When I first tested the 8250_omap + DMA on EDMA it seemed that once the
UART hardware triggered an time-out interrupt the DMA transfer _never_
started. Based on this I could just cancel the transfer since the
RX-DMA and assume zero bytes were transfer. Therefore I ignored the
lack of pause support in EDMA.
Things were fine until someone used 3mbaud instead 115200. Its been
observed that at this speed the UART triggers the time-out interrupt
and the DMA transfer just started. Without the support for pause
we lost some bytes here and once pause support was added the problem
was gone. Now I've been chasing another bug on Dra7 which uses this
driver and the lack of pause support is a candidate for my current
problem. So at this point, things can't get worse if we pause a
transfer and the hardware reported the wrong number of received bytes.
The situation can improve if we get the correct number :)
The 8250_omap does not pause the TX/RX transfer for the fun of it. As I
said, on the TX side we avoid it and on the RX side the transfer is only
paused if we receive an error interrupt (= no way out).

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] serial: 8250: omap: restore registers on shutdown

2015-08-06 Thread Sebastian Andrzej Siewior
On 08/06/2015 02:27 PM, Peter Hurley wrote:
 Hi Sebastian,

Hi Peter,

 On 08/04/2015 07:58 AM, Sebastian Andrzej Siewior wrote:
 On 08/03/2015 09:32 PM, Peter Hurley wrote:

 You mean a function in 8250-dma API which does what I did just here
 with the wait_event() and the wake_up in the callback? That way I could
 move the termios_wait into the dma struct instead of keeping in the
 omap specific part. I am also not sure if OMAP is the only one that may
 hang here or the other people just didn't notice it yet.

 Exactly; and we need to fix DMA wrt x_char anyway.

 Going back to the dmaengine api, I think something like this might work
 (as a first approximation):

 dma_sync_wait(dma-txchan, dma-tx_cookie);
 dmaengine_pause(dma-txchan);

 /* remainder of set_termios */

 dmaengine_resume(dma-txchan);

 We could require 8250 core dma to support pause/resume.

 I would prefer the waitqueue approach.
 You can't do this while holding the port lock. The lock is taken with
 irqs off so may not see the transfer completing.
 Why do you pause the channel? It may not work without an active
 descriptor and a start without resume should work. Also you must
 ensure that DMA's complete callback does not start another transfer if
 there is something queued up (that is why I had the tx_running dance).
 I am not sure if a transfer that is active and then paused will not
 trigger the hang bug if we change the termios in between.
 
 I'll look at/test this this weekend, ok?

Sure. I'm currently re-spinning the patches so have everything in
proper pieces. While at it I will take a look at x_char.

 Regards,
 Peter Hurley
 
Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] serial: 8250: omap: restore registers on shutdown

2015-08-06 Thread Sebastian Andrzej Siewior
On 08/06/2015 02:31 PM, Sebastian Andrzej Siewior wrote:

Hi Peter,

 I'll look at/test this this weekend, ok?
 
 Sure. I'm currently re-spinning the patches so have everything in
 proper pieces. While at it I will take a look at x_char.

So now that I actually look at it. If I read this right, we never send
the x_char if the TX-DMA never fails to do its job. The comment above
uart_send_xchar() says it is high priority. What do you suggest, wait
until the transfer completes, send the x_char _or_ pause the transfer
send that byte and then send the byte?
In both cases we have to wait until for the FIFO-empty interrupt to
make sure we don't overrun that TX-FIFO.

I *think* waiting until the transfer completes would be simpler but it
is not necessarily high priority.

 Regards,
 Peter Hurley

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] serial: 8250: omap: restore registers on shutdown

2015-08-04 Thread Sebastian Andrzej Siewior
On 08/03/2015 09:32 PM, Peter Hurley wrote:

 You mean a function in 8250-dma API which does what I did just here
 with the wait_event() and the wake_up in the callback? That way I could
 move the termios_wait into the dma struct instead of keeping in the
 omap specific part. I am also not sure if OMAP is the only one that may
 hang here or the other people just didn't notice it yet.
 
 Exactly; and we need to fix DMA wrt x_char anyway.
 
 Going back to the dmaengine api, I think something like this might work
 (as a first approximation):
 
   dma_sync_wait(dma-txchan, dma-tx_cookie);
   dmaengine_pause(dma-txchan);
 
   /* remainder of set_termios */
 
   dmaengine_resume(dma-txchan);
 
 We could require 8250 core dma to support pause/resume.

I would prefer the waitqueue approach.
You can't do this while holding the port lock. The lock is taken with
irqs off so may not see the transfer completing.
Why do you pause the channel? It may not work without an active
descriptor and a start without resume should work. Also you must
ensure that DMA's complete callback does not start another transfer if
there is something queued up (that is why I had the tx_running dance).
I am not sure if a transfer that is active and then paused will not
trigger the hang bug if we change the termios in between.

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] serial: 8250: omap: restore registers on shutdown

2015-08-03 Thread Sebastian Andrzej Siewior
* Peter Hurley | 2015-07-30 20:51:10 [-0400]:

Hi John,
Hi Peter,

I was never really a fan of the deferred set_termios();
I think it's more appropriate to wait for tx dma to
complete in omap_8250_set_termios().

So you want something like this? This was only compile + boot tested
(without triggering the corner case) and I know that 8250.h piece has to
go in a separated patch (as requested in 2/3 of this series). Just checking
if this is what you had in mind.

diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
index c43f74c53cd9..a407757dcecc 100644
--- a/drivers/tty/serial/8250/8250.h
+++ b/drivers/tty/serial/8250/8250.h
@@ -42,9 +42,9 @@ struct uart_8250_dma {
size_t  rx_size;
size_t  tx_size;
 
-   unsigned char   tx_running:1;
-   unsigned char   tx_err: 1;
-   unsigned char   rx_running:1;
+   unsigned char   tx_running;
+   unsigned char   tx_err;
+   unsigned char   rx_running;
 };
 
 struct old_serial_port {
diff --git a/drivers/tty/serial/8250/8250_omap.c 
b/drivers/tty/serial/8250/8250_omap.c
index d9a37191a1ae..12249125a218 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -100,9 +100,9 @@ struct omap8250_priv {
u8 wer;
u8 xon;
u8 xoff;
-   u8 delayed_restore;
u16 quot;
 
+   wait_queue_head_t termios_wait;
bool is_suspending;
int wakeirq;
int wakeups_enabled;
@@ -256,18 +256,6 @@ static void omap8250_update_mdr1(struct uart_8250_port *up,
 static void omap8250_restore_regs(struct uart_8250_port *up)
 {
struct omap8250_priv *priv = up-port.private_data;
-   struct uart_8250_dma*dma = up-dma;
-
-   if (dma  dma-tx_running) {
-   /*
-* TCSANOW requests the change to occur immediately however if
-* we have a TX-DMA operation in progress then it has been
-* observed that it might stall and never complete. Therefore we
-* delay DMA completes to prevent this hang from happen.
-*/
-   priv-delayed_restore = 1;
-   return;
-   }
 
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
serial_out(up, UART_EFR, UART_EFR_ECB);
@@ -309,6 +297,7 @@ static void omap8250_restore_regs(struct uart_8250_port *up)
up-port.ops-set_mctrl(up-port, up-port.mctrl);
 }
 
+static void omap_8250_dma_tx_complete(void *param);
 /*
  * OMAP can use CLK / (16 or 13) / div for baud rate. And then we have have
  * some differences in how we want to handle flow control.
@@ -322,6 +311,7 @@ static void omap_8250_set_termios(struct uart_port *port,
struct omap8250_priv *priv = up-port.private_data;
unsigned char cval = 0;
unsigned int baud;
+   unsigned int complete_dma = 0;
 
switch (termios-c_cflag  CSIZE) {
case CS5:
@@ -473,6 +463,25 @@ static void omap_8250_set_termios(struct uart_port *port,
if (termios-c_iflag  IXANY)
up-mcr |= UART_MCR_XONANY;
}
+
+   if (up-dma  up-dma-tx_running) {
+   struct uart_8250_dma*dma = up-dma;
+
+   /*
+* TCSANOW requests the change to occur immediately however if
+* we have a TX-DMA operation in progress then it has been
+* observed that it might stall and never complete. Therefore we
+* wait until DMA completes to prevent this hang from happen.
+*/
+
+   dma-tx_running = 2;
+
+   spin_unlock_irq(up-port.lock);
+   wait_event(priv-termios_wait,
+  dma-tx_running == 3);
+   spin_lock_irq(up-port.lock);
+   complete_dma = 1;
+   }
omap8250_restore_regs(up);
 
spin_unlock_irq(up-port.lock);
@@ -488,6 +497,8 @@ static void omap_8250_set_termios(struct uart_port *port,
/* Don't rewrite B0 */
if (tty_termios_baud_rate(termios))
tty_termios_encode_baud_rate(termios, baud, baud);
+   if (complete_dma)
+   omap_8250_dma_tx_complete(up);
 }
 
 /* same as 8250 except that we may have extra flow bits set in EFR */
@@ -869,17 +880,18 @@ static void omap_8250_dma_tx_complete(void *param)
 
spin_lock_irqsave(p-port.lock, flags);
 
+   if (dma-tx_running == 2) {
+   dma-tx_running = 3;
+   wake_up(priv-termios_wait);
+   goto out;
+   }
+
dma-tx_running = 0;
 
xmit-tail += dma-tx_size;
xmit-tail = UART_XMIT_SIZE - 1;
p-port.icount.tx += dma-tx_size;
 
-   if (priv-delayed_restore) {
-   priv-delayed_restore = 0;
-   omap8250_restore_regs(p);
-   }
-
if (uart_circ_chars_pending(xmit)  WAKEUP_CHARS)

Re: [PATCH 3/3] serial: 8250: omap: restore registers on shutdown

2015-08-03 Thread Sebastian Andrzej Siewior
On 08/03/2015 06:34 PM, Peter Hurley wrote:
 Hi Sebastian,

Hi Peter,

  struct old_serial_port {
 diff --git a/drivers/tty/serial/8250/8250_omap.c 
 b/drivers/tty/serial/8250/8250_omap.c
 index d9a37191a1ae..12249125a218 100644
 --- a/drivers/tty/serial/8250/8250_omap.c
 +++ b/drivers/tty/serial/8250/8250_omap.c
 @@ -100,9 +100,9 @@ struct omap8250_priv {
  u8 wer;
  u8 xon;
  u8 xoff;
 -u8 delayed_restore;
  u16 quot;
  
 +wait_queue_head_t termios_wait;
  bool is_suspending;
  int wakeirq;
  int wakeups_enabled;
 @@ -256,18 +256,6 @@ static void omap8250_update_mdr1(struct uart_8250_port 
 *up,
  static void omap8250_restore_regs(struct uart_8250_port *up)
  {
  struct omap8250_priv *priv = up-port.private_data;
 -struct uart_8250_dma*dma = up-dma;
 -
 -if (dma  dma-tx_running) {
 -/*
 - * TCSANOW requests the change to occur immediately however if
 - * we have a TX-DMA operation in progress then it has been
 - * observed that it might stall and never complete. Therefore we
 - * delay DMA completes to prevent this hang from happen.
 - */
 -priv-delayed_restore = 1;
 -return;
 -}
  
  serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
  serial_out(up, UART_EFR, UART_EFR_ECB);
 @@ -309,6 +297,7 @@ static void omap8250_restore_regs(struct uart_8250_port 
 *up)
  up-port.ops-set_mctrl(up-port, up-port.mctrl);
  }
  
 +static void omap_8250_dma_tx_complete(void *param);
  /*
   * OMAP can use CLK / (16 or 13) / div for baud rate. And then we have 
 have
   * some differences in how we want to handle flow control.
 @@ -322,6 +311,7 @@ static void omap_8250_set_termios(struct uart_port *port,
  struct omap8250_priv *priv = up-port.private_data;
  unsigned char cval = 0;
  unsigned int baud;
 +unsigned int complete_dma = 0;
  
  switch (termios-c_cflag  CSIZE) {
  case CS5:
 @@ -473,6 +463,25 @@ static void omap_8250_set_termios(struct uart_port 
 *port,
  if (termios-c_iflag  IXANY)
  up-mcr |= UART_MCR_XONANY;
  }
 +
 +if (up-dma  up-dma-tx_running) {
 +struct uart_8250_dma*dma = up-dma;
 +
 +/*
 + * TCSANOW requests the change to occur immediately however if
 + * we have a TX-DMA operation in progress then it has been
 + * observed that it might stall and never complete. Therefore we
 + * wait until DMA completes to prevent this hang from happen.
 + */
 +
 +dma-tx_running = 2;
 +
 +spin_unlock_irq(up-port.lock);
 +wait_event(priv-termios_wait,
 +   dma-tx_running == 3);
 
 Doesn't the dmaengine api offer a race-free way to wait for pending tx dma
 to complete?

Not that I know of. You still need to ensure that once that DMA
completed, nobody triggers another TX transfer before you do what you
planned. This is ensures by the tx_running != 0 and the spin lock.

 Maybe we could wrap that in the 8250 dma api?

You mean a function in 8250-dma API which does what I did just here
with the wait_event() and the wake_up in the callback? That way I could
move the termios_wait into the dma struct instead of keeping in the
omap specific part. I am also not sure if OMAP is the only one that may
hang here or the other people just didn't notice it yet.

 Regards,
 Peter Hurley
 
 +spin_lock_irq(up-port.lock);
 +complete_dma = 1;
 +}
  omap8250_restore_regs(up);
  
  spin_unlock_irq(up-port.lock);
 @@ -488,6 +497,8 @@ static void omap_8250_set_termios(struct uart_port *port,
  /* Don't rewrite B0 */
  if (tty_termios_baud_rate(termios))
  tty_termios_encode_baud_rate(termios, baud, baud);
 +if (complete_dma)
 +omap_8250_dma_tx_complete(up);
  }
  
  /* same as 8250 except that we may have extra flow bits set in EFR */
 @@ -869,17 +880,18 @@ static void omap_8250_dma_tx_complete(void *param)
  
  spin_lock_irqsave(p-port.lock, flags);
  
 +if (dma-tx_running == 2) {
 +dma-tx_running = 3;
 +wake_up(priv-termios_wait);
 +goto out;
 +}
 +
  dma-tx_running = 0;
  
  xmit-tail += dma-tx_size;
  xmit-tail = UART_XMIT_SIZE - 1;
  p-port.icount.tx += dma-tx_size;
  
 -if (priv-delayed_restore) {
 -priv-delayed_restore = 0;
 -omap8250_restore_regs(p);
 -}
 -
  if (uart_circ_chars_pending(xmit)  WAKEUP_CHARS)
  uart_write_wakeup(p-port);
  
 @@ -899,7 +911,7 @@ static void omap_8250_dma_tx_complete(void *param)
  p-ier |= UART_IER_THRI;
  serial_port_out(p-port, UART_IER, p-ier);
  }
 -
 +out:
  spin_unlock_irqrestore(p-port.lock, flags);
  }
  
 @@ -1216,6 +1228,7 @@ static int omap8250_probe(struct platform_device *pdev)
  

Re: [PATCH] gpio: omap: use raw locks for locking

2015-07-27 Thread Sebastian Andrzej Siewior
On 07/27/2015 02:50 PM, Linus Walleij wrote:
 Patch applied.
thanks.

 
 Now this question appear in my head:
 
 Is drivers/gpio full of stuff that will not work with the -RT kernel,
 and is this a change that should be done mutatis mutandis on
 all the GPIO drivers?

I described two call paths where you need a rawlock_t. If your gpio
driver uses irq_chip_generic then you a rawlock here and things should
be fine.

In general: If your gpio controller acts as an interrupts controller
(that is via chained handler) then you need the raw-locks if you need
any locking (if you have a write 1 to mask/unmask/enable/disable
register then you probably don't need any locking here at all). If the
gpio controller does not act as an interrupt controller than the
spinlock_t type should be enough.
If your gpio-interrupt controller requests its interrupt via
requested_threaded_irq() then it should do handle_nested_irq() and a
mutex is probably used for locking.

Using request_irq() with 0 flags is kind of broken. It works in
IRQ-context and delivers the interrupts with generic_handle_irq() and
this one passes it the handler (like handle_edge_irq() /
handle_level_irq()) which takes a raw_lock. Now, if you boot the
vanilla kernel with threadedirq then the irq-handler runs in threaded
context and you can't take a spinlock here anymore. So I think you
should use here IRQF_NO_THREAD here (and the raw lock type). I added
tglx on Cc: to back up because it is Monday.

 Yours,
 Linus Walleij
 

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] gpio: omap: use raw locks for locking

2015-07-21 Thread Sebastian Andrzej Siewior
This patch converts gpio_bank.lock from a spin_lock into a
raw_spin_lock. The call path is to access this lock is always under a
raw_spin_lock, for instance
- __setup_irq() holds desc-lock with irq off
  + __irq_set_trigger()
   + omap_gpio_irq_type()

- handle_level_irq() (runs with irqs off therefore raw locks)
  + mask_ack_irq()
   + omap_gpio_mask_irq()

This fixes the obvious backtrace on -RT. However the locking vs context
is not and this is not limited to -RT:
- omap_gpio_irq_type() is called with IRQ off and has an conditional
  call to pm_runtime_get_sync() which may sleep. Either it may happen or
  it may not happen but pm_runtime_get_sync() should not be called with
  irqs off.

- omap_gpio_debounce() is holding the lock with IRQs off.
  + omap2_set_gpio_debounce()
   + clk_prepare_enable()
+ clk_prepare() this one might sleep.
  The number of users of gpiod_set_debounce() / gpio_set_debounce()
  looks low but still this is not good.

Acked-by: Javier Martinez Canillas jav...@dowhile0.org
Acked-by: Santosh Shilimkar ssant...@kernel.org
Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/gpio/gpio-omap.c | 82 
 1 file changed, 41 insertions(+), 41 deletions(-)

diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 61a731ff9a07..f56de8de9c55 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -57,7 +57,7 @@ struct gpio_bank {
u32 saved_datain;
u32 level_mask;
u32 toggle_mask;
-   spinlock_t lock;
+   raw_spinlock_t lock;
struct gpio_chip chip;
struct clk *dbck;
u32 mod_usage;
@@ -498,19 +498,19 @@ static int omap_gpio_irq_type(struct irq_data *d, 
unsigned type)
if (!BANK_USED(bank))
pm_runtime_get_sync(bank-dev);
 
-   spin_lock_irqsave(bank-lock, flags);
+   raw_spin_lock_irqsave(bank-lock, flags);
retval = omap_set_gpio_triggering(bank, offset, type);
if (retval) {
-   spin_unlock_irqrestore(bank-lock, flags);
+   raw_spin_unlock_irqrestore(bank-lock, flags);
goto error;
}
omap_gpio_init_irq(bank, offset);
if (!omap_gpio_is_input(bank, offset)) {
-   spin_unlock_irqrestore(bank-lock, flags);
+   raw_spin_unlock_irqrestore(bank-lock, flags);
retval = -EINVAL;
goto error;
}
-   spin_unlock_irqrestore(bank-lock, flags);
+   raw_spin_unlock_irqrestore(bank-lock, flags);
 
if (type  (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
__irq_set_handler_locked(d-irq, handle_level_irq);
@@ -636,14 +636,14 @@ static int omap_set_gpio_wakeup(struct gpio_bank *bank, 
unsigned offset,
return -EINVAL;
}
 
-   spin_lock_irqsave(bank-lock, flags);
+   raw_spin_lock_irqsave(bank-lock, flags);
if (enable)
bank-context.wake_en |= gpio_bit;
else
bank-context.wake_en = ~gpio_bit;
 
writel_relaxed(bank-context.wake_en, bank-base + bank-regs-wkup_en);
-   spin_unlock_irqrestore(bank-lock, flags);
+   raw_spin_unlock_irqrestore(bank-lock, flags);
 
return 0;
 }
@@ -669,10 +669,10 @@ static int omap_gpio_request(struct gpio_chip *chip, 
unsigned offset)
if (!BANK_USED(bank))
pm_runtime_get_sync(bank-dev);
 
-   spin_lock_irqsave(bank-lock, flags);
+   raw_spin_lock_irqsave(bank-lock, flags);
omap_enable_gpio_module(bank, offset);
bank-mod_usage |= BIT(offset);
-   spin_unlock_irqrestore(bank-lock, flags);
+   raw_spin_unlock_irqrestore(bank-lock, flags);
 
return 0;
 }
@@ -682,14 +682,14 @@ static void omap_gpio_free(struct gpio_chip *chip, 
unsigned offset)
struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
unsigned long flags;
 
-   spin_lock_irqsave(bank-lock, flags);
+   raw_spin_lock_irqsave(bank-lock, flags);
bank-mod_usage = ~(BIT(offset));
if (!LINE_USED(bank-irq_usage, offset)) {
omap_set_gpio_direction(bank, offset, 1);
omap_clear_gpio_debounce(bank, offset);
}
omap_disable_gpio_module(bank, offset);
-   spin_unlock_irqrestore(bank-lock, flags);
+   raw_spin_unlock_irqrestore(bank-lock, flags);
 
/*
 * If this is the last gpio to be freed in the bank,
@@ -791,7 +791,7 @@ static unsigned int omap_gpio_irq_startup(struct irq_data 
*d)
if (!BANK_USED(bank))
pm_runtime_get_sync(bank-dev);
 
-   spin_lock_irqsave(bank-lock, flags);
+   raw_spin_lock_irqsave(bank-lock, flags);
 
if (!LINE_USED(bank-mod_usage, offset))
omap_set_gpio_direction(bank, offset, 1);
@@ -800,12 +800,12 @@ static unsigned int omap_gpio_irq_startup(struct irq_data 
*d)
omap_enable_gpio_module(bank, offset);
bank

Re: musb-hdrc: Vbus off, timeout 1100 msec message does not belong in sysfs

2015-07-10 Thread Sebastian Andrzej Siewior
On 07/09/2015 11:46 PM, Pavel Machek wrote:
 On Thu 2015-07-09 23:39:22, Pavel Machek wrote:
 Hi!

Hi,


 sysfs should contain one value per file. This one has at least two,
 with nice english sentence as a bonus.

 root@n900:/sys/devices/platform/6800.ocp/480ab000.usb_otg_hs/musb-hdrc.0.auto#
 cat vbus
 Vbus off, timeout 1100 msec

 :-(.
 
 Plus, documentation for this is nowhere to be seen:
 
 pavel@amd:/data/l/linux-n900$ grep -ri musb Documentation/ABI/
 pavel@amd:/data/l/linux-n900$

that is a shame indeed. It is part of the driver since TUSB support was
merged via commit 550a7375f (USB: Add MUSB and TUSB support) about 7
years ago.
The parameter expects the timeout values which is used to poll the port
for mode changes (host/device mode) since it can not be detected on its
own.
Felipe knows best if it is better to document it or remove it. I can't
remember that I needed it on am335x.

   Pavel
 
Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH REPOST] gpio: omap: use raw locks for locking

2015-06-30 Thread Sebastian Andrzej Siewior
On 06/30/2015 12:55 PM, Grygorii Strashko wrote:
 Hi Sebastian, All,
Hi Grygorii,

 The problem here is that OMAPs code implemented using PM runtime based
 approach and PM runtime is used everywhere. We don't see warnings form
 other drivers just because their HW IRQ handlers forced to be threaded, but
 that's not the case for OMAP GPIO :(

Only for the case where it is used as an interrupt controller. So the
primary interrupt controller is not using RPM then (or else you would
have the same problem).

 PM runtime for OMAP GPIO is implemented in irq_safe manner and it works for
 non-RT case, but the main question here - How can we proceed for -RT case?
 
 May be you have some thought?

If I remember it properly, you must not sleep but you do so on wakeup.
At least you take spinlocks (spinlocks not raw_spinlocks). One question
is why do you need (or why is it okay) to put a device to sleep (via
RPM) if the device is used as an interrupt controller? From what I
understand, if the GPIO controller is really sleeping you won't receive
any interrupts.

So I think you shouldn't put a GPIO controller to sleep if it is
active. If you avoid this, there should be nothing calling you from
IRQ-context on -RT.

From my side what I've tried or thought about:
 1) OMAP HW IRQ handler can be transformed to threaded IRQ on -RT.
Can it be acceptable?

It could. In theory. It would work, too. Not sure you really want this.
You lose the cascaded handler that you have now. The obvious change
would be that you see another IRQ used in /proc/interrupts. This is
harmless :) However each time an IRQ (on the GPIO side) arrives you
have a hardirq which is defered into thread context. Then it wakes
another thread (the GPIO-IRQ-handler). So this adds a little of
overhead on your call path. Since you won't have IRQF_NO_THREAD flag on
any user, this should remain the only price you pay.

Also I try not grow the -RT queue. I sent patches upstream where
possible. That means for this I would like to have this addressed
upstream as there is no joy carrying this patch (that means please
don't do a -RT only fix).

 2) I've tried to use irq_chip-irq_bus_lock/irq_bus_sync_unlock() callbacks.
It helps a bit, but there are two problems:
- These callbacks are not expected to fail;
- PM runtime calls are still present in omap_gpio_irq_handler().
Hypothetically, they can be removed, but we'd need to ensure that OMAP 
 GPIO HW
is powered and ready to process IRQs all the time while GPIO bank IRQ is 
 in use.
Not trivial thing to do taking into account multi-SoC support, suspend, 
 cpuidle :(

What I still don't understand how can a GPIO create an interrupt if it
is sleeping? I know CAN and a few others peripherals can do such
things. Is this also the case for the GPIO?

Or is the problem more that the CPU can't properly enter suspend/
cpuidle if the GPIO bank remains active?

   [code provided just to illustrate idea]
   static void omap_gpio_irq_bus_lock(struct irq_data *data)
   {
struct gpio_bank *bank = irq_data_get_irq_chip_data(data);
 
if (!BANK_USED(bank))
pm_runtime_get_sync(bank-dev);
   }

I don't really like the !BANK_USED(bank) check because it is either in
use or not. Things like that may hide the pm_runtime_get_sync() call and
explode with debug-off.

 I would be appreciated for any comments on this (1 or 2 or ..), thanks. 

Another way would be to turn the lock into a raw lock so it won't block
on -RT. However each time you hold the lock in process context you
block a possible -RT task from becoming run-able. Also this could
include larger hacker across the RPM code depending on how this lock
issue is solved.
Either way: the longer you hold the lock the longer you block the -RT
task and the important part is the worst-case scenario.

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] gpio: omap: use raw locks for locking

2015-06-30 Thread Sebastian Andrzej Siewior
On 06/30/2015 08:45 AM, Linus Walleij wrote:
 This doesn't apply to the current development tree.

it has been pointed out to me.

 Can you rebase this patch in Torvalds' HEAD, add Javier's ACK
 and resend?

I will do it once I'm done roasted :)

 Please put me on the To: line, I have no time to read all mail that
 I'm only CC on.
noted. This might been the problem while it hasn't been applied the
first time I posted it.

 Yours,
 Linus Walleij

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH REPOST] gpio: omap: use raw locks for locking

2015-06-19 Thread Sebastian Andrzej Siewior
This patch converts gpio_bank.lock from a spin_lock into a
raw_spin_lock. The call path is to access this lock is always under a
raw_spin_lock, for instance
- __setup_irq() holds desc-lock with irq off
  + __irq_set_trigger()
   + omap_gpio_irq_type()

- handle_level_irq() (runs with irqs off therefore raw locks)
  + mask_ack_irq()
   + omap_gpio_mask_irq()

This fixes the obvious backtrace on -RT. However the locking vs context
is not and this is not limited to -RT:
- omap_gpio_irq_type() is called with IRQ off and has an conditional
  call to pm_runtime_get_sync() which may sleep. Either it may happen or
  it may not happen but pm_runtime_get_sync() should not be called with
  irqs off.

- omap_gpio_debounce() is holding the lock with IRQs off.
  + omap2_set_gpio_debounce()
   + clk_prepare_enable()
+ clk_prepare() this one might sleep.
  The number of users of gpiod_set_debounce() / gpio_set_debounce()
  looks low but still this is not good.

Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/gpio/gpio-omap.c |   78 +++
 1 file changed, 39 insertions(+), 39 deletions(-)

--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -57,7 +57,7 @@ struct gpio_bank {
u32 saved_datain;
u32 level_mask;
u32 toggle_mask;
-   spinlock_t lock;
+   raw_spinlock_t lock;
struct gpio_chip chip;
struct clk *dbck;
u32 mod_usage;
@@ -498,14 +498,14 @@ static int omap_gpio_irq_type(struct irq
(type  (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)))
return -EINVAL;
 
-   spin_lock_irqsave(bank-lock, flags);
+   raw_spin_lock_irqsave(bank-lock, flags);
retval = omap_set_gpio_triggering(bank, offset, type);
omap_gpio_init_irq(bank, offset);
if (!omap_gpio_is_input(bank, offset)) {
-   spin_unlock_irqrestore(bank-lock, flags);
+   raw_spin_unlock_irqrestore(bank-lock, flags);
return -EINVAL;
}
-   spin_unlock_irqrestore(bank-lock, flags);
+   raw_spin_unlock_irqrestore(bank-lock, flags);
 
if (type  (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
__irq_set_handler_locked(d-irq, handle_level_irq);
@@ -626,14 +626,14 @@ static int omap_set_gpio_wakeup(struct g
return -EINVAL;
}
 
-   spin_lock_irqsave(bank-lock, flags);
+   raw_spin_lock_irqsave(bank-lock, flags);
if (enable)
bank-context.wake_en |= gpio_bit;
else
bank-context.wake_en = ~gpio_bit;
 
writel_relaxed(bank-context.wake_en, bank-base + bank-regs-wkup_en);
-   spin_unlock_irqrestore(bank-lock, flags);
+   raw_spin_unlock_irqrestore(bank-lock, flags);
 
return 0;
 }
@@ -668,7 +668,7 @@ static int omap_gpio_request(struct gpio
if (!BANK_USED(bank))
pm_runtime_get_sync(bank-dev);
 
-   spin_lock_irqsave(bank-lock, flags);
+   raw_spin_lock_irqsave(bank-lock, flags);
/* Set trigger to none. You need to enable the desired trigger with
 * request_irq() or set_irq_type(). Only do this if the IRQ line has
 * not already been requested.
@@ -678,7 +678,7 @@ static int omap_gpio_request(struct gpio
omap_enable_gpio_module(bank, offset);
}
bank-mod_usage |= BIT(offset);
-   spin_unlock_irqrestore(bank-lock, flags);
+   raw_spin_unlock_irqrestore(bank-lock, flags);
 
return 0;
 }
@@ -688,11 +688,11 @@ static void omap_gpio_free(struct gpio_c
struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
unsigned long flags;
 
-   spin_lock_irqsave(bank-lock, flags);
+   raw_spin_lock_irqsave(bank-lock, flags);
bank-mod_usage = ~(BIT(offset));
omap_disable_gpio_module(bank, offset);
omap_reset_gpio(bank, offset);
-   spin_unlock_irqrestore(bank-lock, flags);
+   raw_spin_unlock_irqrestore(bank-lock, flags);
 
/*
 * If this is the last gpio to be freed in the bank,
@@ -794,9 +794,9 @@ static unsigned int omap_gpio_irq_startu
if (!BANK_USED(bank))
pm_runtime_get_sync(bank-dev);
 
-   spin_lock_irqsave(bank-lock, flags);
+   raw_spin_lock_irqsave(bank-lock, flags);
omap_gpio_init_irq(bank, offset);
-   spin_unlock_irqrestore(bank-lock, flags);
+   raw_spin_unlock_irqrestore(bank-lock, flags);
omap_gpio_unmask_irq(d);
 
return 0;
@@ -808,11 +808,11 @@ static void omap_gpio_irq_shutdown(struc
unsigned long flags;
unsigned offset = d-hwirq;
 
-   spin_lock_irqsave(bank-lock, flags);
+   raw_spin_lock_irqsave(bank-lock, flags);
bank-irq_usage = ~(BIT(offset));
omap_disable_gpio_module(bank, offset);
omap_reset_gpio(bank, offset);
-   spin_unlock_irqrestore(bank-lock, flags);
+   raw_spin_unlock_irqrestore(bank-lock, flags

[PATCH] serial: 8250_omap: provide complete custom startup shutdown callbacks

2015-05-20 Thread Sebastian Andrzej Siewior
The currently in-use port-startup and port-shutdown are okay. The
startup part for instance does the tiny omap extra part and invokes
serial8250_do_startup() for the remaining pieces. The workflow in
serial8250_do_startup() is okay except for the part where UART_RX is
read without a check if there is something to read. I tried to
workaround it in commit 0aa525d11859 (tty: serial: 8250_core: read only
RX if there is something in the FIFO) but then reverted it later in
commit ca8bb4aefb9 (serial: 8250: Revert tty: serial: 8250_core: read
only RX if there is something in the FIFO).

This is the second attempt to get it to work on older OMAPs without
breaking other chips this time
Peter Hurley suggested to pull in the few needed lines from
serial8250_do_startup() and drop everything else that is not required
including making it simpler like using just request_irq() instead the
chain handler like it is doing now.
So lets try that.

Fixes: ca8bb4aefb93 (serial: 8250: Revert tty: serial: 8250_core:
   read only RX if there is something in the FIFO)
Tested-by: Tony Lindgren t...@atomide.com
Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/tty/serial/8250/8250_omap.c | 82 +
 1 file changed, 73 insertions(+), 9 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_omap.c 
b/drivers/tty/serial/8250/8250_omap.c
index 928cb7c6..dce1a23706e8 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -562,12 +562,36 @@ static irqreturn_t omap_wake_irq(int irq, void *dev_id)
return IRQ_NONE;
 }
 
+#ifdef CONFIG_SERIAL_8250_DMA
+static int omap_8250_dma_handle_irq(struct uart_port *port);
+#endif
+
+static irqreturn_t omap8250_irq(int irq, void *dev_id)
+{
+   struct uart_port *port = dev_id;
+   struct uart_8250_port *up = up_to_u8250p(port);
+   unsigned int iir;
+   int ret;
+
+#ifdef CONFIG_SERIAL_8250_DMA
+   if (up-dma) {
+   ret = omap_8250_dma_handle_irq(port);
+   return IRQ_RETVAL(ret);
+   }
+#endif
+
+   serial8250_rpm_get(up);
+   iir = serial_port_in(port, UART_IIR);
+   ret = serial8250_handle_irq(port, iir);
+   serial8250_rpm_put(up);
+
+   return IRQ_RETVAL(ret);
+}
+
 static int omap_8250_startup(struct uart_port *port)
 {
-   struct uart_8250_port *up =
-   container_of(port, struct uart_8250_port, port);
+   struct uart_8250_port *up = up_to_u8250p(port);
struct omap8250_priv *priv = port-private_data;
-
int ret;
 
if (priv-wakeirq) {
@@ -580,10 +604,31 @@ static int omap_8250_startup(struct uart_port *port)
 
pm_runtime_get_sync(port-dev);
 
-   ret = serial8250_do_startup(port);
-   if (ret)
+   up-mcr = 0;
+   serial_out(up, UART_FCR, UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+
+   serial_out(up, UART_LCR, UART_LCR_WLEN8);
+
+   up-lsr_saved_flags = 0;
+   up-msr_saved_flags = 0;
+
+   if (up-dma) {
+   ret = serial8250_request_dma(up);
+   if (ret) {
+   dev_warn_ratelimited(port-dev,
+failed to request DMA\n);
+   up-dma = NULL;
+   }
+   }
+
+   ret = request_irq(port-irq, omap8250_irq, IRQF_SHARED,
+ dev_name(port-dev), port);
+   if (ret  0)
goto err;
 
+   up-ier = UART_IER_RLSI | UART_IER_RDI;
+   serial_out(up, UART_IER, up-ier);
+
 #ifdef CONFIG_PM
up-capabilities |= UART_CAP_RPM;
 #endif
@@ -610,8 +655,7 @@ static int omap_8250_startup(struct uart_port *port)
 
 static void omap_8250_shutdown(struct uart_port *port)
 {
-   struct uart_8250_port *up =
-   container_of(port, struct uart_8250_port, port);
+   struct uart_8250_port *up = up_to_u8250p(port);
struct omap8250_priv *priv = port-private_data;
 
flush_work(priv-qos_work);
@@ -621,11 +665,24 @@ static void omap_8250_shutdown(struct uart_port *port)
pm_runtime_get_sync(port-dev);
 
serial_out(up, UART_OMAP_WER, 0);
-   serial8250_do_shutdown(port);
+
+   up-ier = 0;
+   serial_out(up, UART_IER, 0);
+
+   if (up-dma)
+   serial8250_release_dma(up);
+
+   /*
+* Disable break condition and FIFOs
+*/
+   if (up-lcr  UART_LCR_SBC)
+   serial_out(up, UART_LCR, up-lcr  ~UART_LCR_SBC);
+   serial_out(up, UART_FCR, UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
 
pm_runtime_mark_last_busy(port-dev);
pm_runtime_put_autosuspend(port-dev);
 
+   free_irq(port-irq, port);
if (priv-wakeirq)
free_irq(priv-wakeirq, port);
 }
@@ -974,6 +1031,13 @@ static inline int omap_8250_rx_dma(struct uart_8250_port 
*p, unsigned int iir)
 }
 #endif
 
+static int omap8250_no_handle_irq(struct uart_port *port)
+{
+   /* IRQ has not been requested

Re: [RFC PATCH] ARM: omap2plus_defconfig: Switch over to using 8250 driver

2015-04-13 Thread Sebastian Andrzej Siewior
On 04/12/2015 02:23 AM, Nishanth Menon wrote:
 I think for the moment we should just freeze omap-serial and let
 most of userspace catch up first; a lot of the official and
 unofficial vender support is still stuck in 3.14. By the time,
 3.19+ is de rigueur we'll hopefully have figured out the ttyS
 sharing and how to migrate without breaking userspace.

 
 How about the folks stuck on older distros like Maemo N900?

By the time I was thinking about this, I ended up with this:
a) replace ttyOx with ttySx for the kernel console we it does not end
   up dark and add a warning. This works right now however the warning
   might been longer but then if one does not read it it might not
   matter at all.
b) add symlink udev rule so ttySx nodes becomes ttyOx one, too

a) was mainly for people not aware of the defconfig change who end up
with the new driver without any knowledge.
b) was mainly for people for people using some kind of pre-created
image where you are not sure which kernel they have. They still could
use the old driver or they might have switched to the new one. This
udev rule should make sure there at least a getty on serial after the
complete boot.

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Cocci] [PATCH v13 3/6] clk: Make clk API return per-user struct clk instances

2015-03-13 Thread Sebastian Andrzej Siewior
Hi Shawn,

On Fri, Mar 13, 2015 at 11:29:32AM +0800, Shawn Guo wrote:

 We did not add a DT property for it, because there was already enough
 info (clock configuration) in DT for kernel to figure it out.
Correct. My understanding is whatever can be figured out without DT should
be done that way.

Is there a way to get this clock-select bit set without
enable_fec_anatop_clock() in u-boot? Because this one selects the clock and
frequency and also sets the proper bit in gpr1. My question is simply why do
we need to do this here as well.

 Shawn

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Cocci] [PATCH v13 3/6] clk: Make clk API return per-user struct clk instances

2015-03-12 Thread Sebastian Andrzej Siewior
On 2015-02-17 14:01:04 [-0800], Stephen Boyd wrote:
 diff = 
 --- arch/arm/mach-imx/mach-imx6q.c
 +++ /tmp/cocci-output-11792-b62223-mach-imx6q.c
 @@ -211,7 +211,6 @@ static void __init imx6q_1588_init(void)
* set bit IOMUXC_GPR1[21].  Or the PTP clock must be from pad
* (external OSC), and we need to clear the bit.
*/
 - clksel = ptp_clk == enet_ref ? IMX6Q_GPR1_ENET_CLK_SEL_ANATOP :
  IMX6Q_GPR1_ENET_CLK_SEL_PAD;
   gpr = syscon_regmap_lookup_by_compatible(fsl,imx6q-iomuxc-gpr);
   if (!IS_ERR(gpr))

Any idea how to do the comparison here? Or should we rely that the bootloader
sets this properly (it managed already to select a frequency)? The phy has no
clock node in current DT's so we can check this.

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] gpio: omap: use raw locks for locking

2015-02-25 Thread Sebastian Andrzej Siewior
On 02/16/2015 09:54 AM, Javier Martinez Canillas wrote:
 Hello Sebastian,

Hello Javier,

 Right, those are bugs regardless of PREEMPT_RT or not as you said.
 I'll add it to my TODO list, thanks for finding those.

Thanks.

 Acked-by: Javier Martinez Canillas jav...@dowhile0.org
 
 Best regards,
 Javier

Sebastian

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] serial: 8250: Revert tty: serial: 8250_core: read only RX if there is something in the FIFO

2015-02-15 Thread Sebastian Andrzej Siewior
This reverts commit 0aa525d11859c1a4d5b78fdc704148e2ae03ae13.

The conditional RX-FIFO read seems to cause spurious interrupts and we
see just:
|serial8250: too much work for irq29

The previous behaviour was default for decades and Marvell's 88f6282 SoC
might not be the only that relies on it. Therefore the Omap fix is
reverted for now.

Fixes: 0aa525d11859 (tty: serial: 8250_core: read only RX if there is
something in the FIFO)
Reported-By: Nicolas Schichan nschic...@freebox.fr
Debuged-By: Peter Hurley pe...@hurleysoftware.com
Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
* Russell King - ARM Linux | 2015-02-13 23:15:19 [+]:

On Fri, Feb 13, 2015 at 07:51:16PM +0100, Sebastian Andrzej Siewior wrote:
 Something like this maybe?

My personal feeling is that as 0aa525d11859 was wrong, it should be
reverted and this should be another attempt to fix the problem.  In
other words, there should be two patches, one a revert of the previously
known bad commit and this one having another go at it.

I feel that would be a better approach, since then we don't end up
with this change building on a previously know buggy change.  It
would also make the changes to this solution from the previous,
known-to-work-for-decades code more obvious.

Okay. So here is the revert.

 drivers/tty/serial/8250/8250_core.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_core.c 
b/drivers/tty/serial/8250/8250_core.c
index e3b9570a1eff..deae122c9c4b 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -2138,8 +2138,8 @@ int serial8250_do_startup(struct uart_port *port)
/*
 * Clear the interrupt registers.
 */
-   if (serial_port_in(port, UART_LSR)  UART_LSR_DR)
-   serial_port_in(port, UART_RX);
+   serial_port_in(port, UART_LSR);
+   serial_port_in(port, UART_RX);
serial_port_in(port, UART_IIR);
serial_port_in(port, UART_MSR);
 
@@ -2300,8 +2300,8 @@ int serial8250_do_startup(struct uart_port *port)
 * saved flags to avoid getting false values from polling
 * routines or the previous session.
 */
-   if (serial_port_in(port, UART_LSR)  UART_LSR_DR)
-   serial_port_in(port, UART_RX);
+   serial_port_in(port, UART_LSR);
+   serial_port_in(port, UART_RX);
serial_port_in(port, UART_IIR);
serial_port_in(port, UART_MSR);
up-lsr_saved_flags = 0;
@@ -2394,8 +2394,7 @@ void serial8250_do_shutdown(struct uart_port *port)
 * Read data port to reset things, and then unlink from
 * the IRQ chain.
 */
-   if (serial_port_in(port, UART_LSR)  UART_LSR_DR)
-   serial_port_in(port, UART_RX);
+   serial_port_in(port, UART_RX);
serial8250_rpm_put(up);
 
del_timer_sync(up-timer);
-- 
2.1.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 03/16] tty: serial: 8250_core: read only RX if there is something in the FIFO

2015-02-13 Thread Sebastian Andrzej Siewior
Something like this maybe?

Subject: [PATCH] serial: 8250: skip empty RX-read only on OMAP

The conditional RX-FIFO read seems to cause spurious interrupts and we
see just:
|serial8250: too much work for irq29

The previous behaviour was default for decades and Marvell's 88f6282 SoC
might not be the only that relies on it. Therefore this patch moves this
special OMAP3630 behaviour befind a BUG field.

Fixes: 0aa525d11859 (tty: serial: 8250_core: read only RX if there is
   something in the FIFO)

Reported-By: Nicolas Schichan nschic...@freebox.fr
Debuged-By: Peter Hurley pe...@hurleysoftware.com
Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/tty/serial/8250/8250.h  |  1 +
 drivers/tty/serial/8250/8250_core.c | 10 --
 drivers/tty/serial/8250/8250_omap.c |  1 +
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
index b00836851061..b6899fd69c7e 100644
--- a/drivers/tty/serial/8250/8250.h
+++ b/drivers/tty/serial/8250/8250.h
@@ -84,6 +84,7 @@ struct serial8250_config {
 #define UART_BUG_NOMSR (1  2)/* UART has buggy MSR status bits 
(Au1x00) */
 #define UART_BUG_THRE  (1  3)/* UART has buggy THRE reassertion */
 #define UART_BUG_PARITY(1  4)/* UART mishandles parity if 
FIFO enabled */
+#define UART_BUG_RXEMPT(1  5)/* UART can not read empty FIFO 
*/
 
 #define PROBE_RSA  (1  0)
 #define PROBE_ANY  (~0)
diff --git a/drivers/tty/serial/8250/8250_core.c 
b/drivers/tty/serial/8250/8250_core.c
index e3b9570a1eff..185386178023 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -2137,8 +2137,13 @@ int serial8250_do_startup(struct uart_port *port)
 
/*
 * Clear the interrupt registers.
+*
+* This (and later) unsolicied read of the RX FIFO seems to clear the
+* RX timeout condition which otherwise generates spurious interrupt.
+* This behaviour has been observed on Marvell's 88f6282 SoC.
 */
-   if (serial_port_in(port, UART_LSR)  UART_LSR_DR)
+   if (!(up-bugs  UART_BUG_RXEMPT) ||
+   (serial_port_in(port, UART_LSR)  UART_LSR_DR))
serial_port_in(port, UART_RX);
serial_port_in(port, UART_IIR);
serial_port_in(port, UART_MSR);
@@ -2300,7 +2305,8 @@ int serial8250_do_startup(struct uart_port *port)
 * saved flags to avoid getting false values from polling
 * routines or the previous session.
 */
-   if (serial_port_in(port, UART_LSR)  UART_LSR_DR)
+   if (!(up-bugs  UART_BUG_RXEMPT) ||
+   (serial_port_in(port, UART_LSR)  UART_LSR_DR))
serial_port_in(port, UART_RX);
serial_port_in(port, UART_IIR);
serial_port_in(port, UART_MSR);
diff --git a/drivers/tty/serial/8250/8250_omap.c 
b/drivers/tty/serial/8250/8250_omap.c
index fe6d2e51da09..a7ead2fa6a32 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -1021,6 +1021,7 @@ static int omap8250_probe(struct platform_device *pdev)
up.port.fifosize = 64;
up.tx_loadsz = 64;
up.capabilities = UART_CAP_FIFO;
+   up.bugs = UART_BUG_RXEMPT;
 #ifdef CONFIG_PM
/*
 * Runtime PM is mostly transparent. However to do it right we need to a
-- 
2.1.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 03/16] tty: serial: 8250_core: read only RX if there is something in the FIFO

2015-02-12 Thread Sebastian Andrzej Siewior
* Peter Hurley | 2015-02-12 11:32:04 [-0500]:

That said, I don't think serial8250_do_startup() is really doing that much
for OMAP h/w startup; open-coding what omap_8250 really needs is probably
 10 loc.

10 loc? I have a few more. serial8250_clear_fifos(),
serial_link_irq_chain() aren't exported. serial8250_set_mctrl() can
maybe accessed via uart_ops-set_mctrl(). Maybe I'm not removing the
obvious not required code but here it looks better to just a BUG flag for
the Omap.

--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -557,9 +557,74 @@ static int omap_8250_startup(struct uart_port *port)
 
pm_runtime_get_sync(port-dev);
 
-   ret = serial8250_do_startup(port);
-   if (ret)
-   goto err;
+   up-mcr = 0;
+
+   /*
+* Clear the FIFO buffers and disable them.
+* (they will be reenabled in set_termios())
+*/
+   serial8250_clear_fifos(up);
+
+   /*
+* Clear the interrupt registers.
+*/
+   if (serial_port_in(port, UART_LSR)  UART_LSR_DR)
+   serial_port_in(port, UART_RX);
+   serial_port_in(port, UART_IIR);
+   serial_port_in(port, UART_MSR);
+
+   retval = serial_link_irq_chain(up);
+   if (retval)
+   goto out;
+
+   /*
+* Now, initialize the UART
+*/
+   serial_port_out(port, UART_LCR, UART_LCR_WLEN8);
+
+   spin_lock_irqsave(port-lock, flags);
+   /*
+* Most PC uarts need OUT2 raised to enable interrupts.
+*/
+   if (port-irq)
+   up-port.mctrl |= TIOCM_OUT2;
+
+   serial8250_set_mctrl(port, port-mctrl);
+
+   spin_unlock_irqrestore(port-lock, flags);
+
+   /*
+* Clear the interrupt registers again for luck, and clear the
+* saved flags to avoid getting false values from polling
+* routines or the previous session.
+*/
+   if (serial_port_in(port, UART_LSR)  UART_LSR_DR)
+   serial_port_in(port, UART_RX);
+   serial_port_in(port, UART_IIR);
+   serial_port_in(port, UART_MSR);
+   up-lsr_saved_flags = 0;
+   up-msr_saved_flags = 0;
+
+   /*
+* Request DMA channels for both RX and TX.
+*/
+   if (up-dma) {
+   retval = serial8250_request_dma(up);
+   if (retval) {
+   pr_warn_ratelimited(ttyS%d - failed to request DMA\n,
+   serial_index(port));
+   up-dma = NULL;
+   }
+   }
+
+   /*
+* Finally, enable interrupts.  Note: Modem status interrupts
+* are set via set_termios(), which will be occurring imminently
+* anyway, so we don't enable them here.
+*/
+   up-ier = UART_IER_RLSI | UART_IER_RDI;
+   serial_port_out(port, UART_IER, up-ier);
+
 
 #ifdef CONFIG_PM
up-capabilities |= UART_CAP_RPM;

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 03/16] tty: serial: 8250_core: read only RX if there is something in the FIFO

2015-02-12 Thread Sebastian Andrzej Siewior
On 02/12/2015 08:55 PM, Peter Hurley wrote:
 On 02/12/2015 02:23 PM, Sebastian Andrzej Siewior wrote:
 * Peter Hurley | 2015-02-12 11:32:04 [-0500]:

 That said, I don't think serial8250_do_startup() is really doing that much
 for OMAP h/w startup; open-coding what omap_8250 really needs is probably
  10 loc.

 10 loc? I have a few more.
 
 :)
 
 serial8250_clear_fifos(),
 serial_link_irq_chain() aren't exported. serial8250_set_mctrl() can
 maybe accessed via uart_ops-set_mctrl(). Maybe I'm not removing the
 obvious not required code but here it looks better to just a BUG flag for
 the Omap.
 
 Ok.

Okay. I will try to post something tomorrow.

 --- a/drivers/tty/serial/8250/8250_omap.c
 +++ b/drivers/tty/serial/8250/8250_omap.c
 +
 +/*
 + * Clear the interrupt registers.
 + */
 +if (serial_port_in(port, UART_LSR)  UART_LSR_DR)
 +serial_port_in(port, UART_RX);
 +serial_port_in(port, UART_IIR);
 +serial_port_in(port, UART_MSR);
 +
 +retval = serial_link_irq_chain(up);
 +if (retval)
 +goto out;
 
 omap doesn't really need the legacy irq chain handling; this could just be
 request_irq().
 
 In the 8250 split I'll be posting soon, all the irq chaining and
 polling-via-timeout workarounds stays in the universal/legacy driver so
 other 8250 drivers can opt-out.

Ah. This sounds interesting.

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] gpio: omap: use raw locks for locking

2015-02-12 Thread Sebastian Andrzej Siewior
This patch converts gpio_bank.lock from a spin_lock into a
raw_spin_lock. The call path to access this lock is always under a
raw_spin_lock, for instance
- __setup_irq() holds desc-lock with irq off
  + __irq_set_trigger()
   + omap_gpio_irq_type()

- handle_level_irq() (runs with irqs off therefore raw locks)
  + mask_ack_irq()
   + omap_gpio_mask_irq()

This fixes the obvious backtrace on -RT. However I noticed two cases
where it looks wrong and this is not limited to -RT:
- omap_gpio_irq_type() is called with IRQ off and has an conditional
  call to pm_runtime_get_sync() which may sleep. Either it may happen or
  it may not happen but pm_runtime_get_sync() should not be called in an
  atomic section.

- omap_gpio_debounce() is holding the lock with IRQs off.
  + omap2_set_gpio_debounce()
   + clk_prepare_enable()
+ clk_prepare() this one might sleep.
  The number of users of gpiod_set_debounce() / gpio_set_debounce()
  looks low but still this is not good.

Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/gpio/gpio-omap.c | 78 
 1 file changed, 39 insertions(+), 39 deletions(-)

diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index f476ae2eb0b3..27e835f4c39d 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -57,7 +57,7 @@ struct gpio_bank {
u32 saved_datain;
u32 level_mask;
u32 toggle_mask;
-   spinlock_t lock;
+   raw_spinlock_t lock;
struct gpio_chip chip;
struct clk *dbck;
u32 mod_usage;
@@ -515,15 +515,15 @@ static int omap_gpio_irq_type(struct irq_data *d, 
unsigned type)
(type  (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)))
return -EINVAL;
 
-   spin_lock_irqsave(bank-lock, flags);
+   raw_spin_lock_irqsave(bank-lock, flags);
offset = GPIO_INDEX(bank, gpio);
retval = omap_set_gpio_triggering(bank, offset, type);
omap_gpio_init_irq(bank, gpio, offset);
if (!omap_gpio_is_input(bank, BIT(offset))) {
-   spin_unlock_irqrestore(bank-lock, flags);
+   raw_spin_unlock_irqrestore(bank-lock, flags);
return -EINVAL;
}
-   spin_unlock_irqrestore(bank-lock, flags);
+   raw_spin_unlock_irqrestore(bank-lock, flags);
 
if (type  (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
__irq_set_handler_locked(d-irq, handle_level_irq);
@@ -641,14 +641,14 @@ static int omap_set_gpio_wakeup(struct gpio_bank *bank, 
int gpio, int enable)
return -EINVAL;
}
 
-   spin_lock_irqsave(bank-lock, flags);
+   raw_spin_lock_irqsave(bank-lock, flags);
if (enable)
bank-context.wake_en |= gpio_bit;
else
bank-context.wake_en = ~gpio_bit;
 
writel_relaxed(bank-context.wake_en, bank-base + bank-regs-wkup_en);
-   spin_unlock_irqrestore(bank-lock, flags);
+   raw_spin_unlock_irqrestore(bank-lock, flags);
 
return 0;
 }
@@ -683,7 +683,7 @@ static int omap_gpio_request(struct gpio_chip *chip, 
unsigned offset)
if (!BANK_USED(bank))
pm_runtime_get_sync(bank-dev);
 
-   spin_lock_irqsave(bank-lock, flags);
+   raw_spin_lock_irqsave(bank-lock, flags);
/* Set trigger to none. You need to enable the desired trigger with
 * request_irq() or set_irq_type(). Only do this if the IRQ line has
 * not already been requested.
@@ -693,7 +693,7 @@ static int omap_gpio_request(struct gpio_chip *chip, 
unsigned offset)
omap_enable_gpio_module(bank, offset);
}
bank-mod_usage |= BIT(offset);
-   spin_unlock_irqrestore(bank-lock, flags);
+   raw_spin_unlock_irqrestore(bank-lock, flags);
 
return 0;
 }
@@ -703,11 +703,11 @@ static void omap_gpio_free(struct gpio_chip *chip, 
unsigned offset)
struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
unsigned long flags;
 
-   spin_lock_irqsave(bank-lock, flags);
+   raw_spin_lock_irqsave(bank-lock, flags);
bank-mod_usage = ~(BIT(offset));
omap_disable_gpio_module(bank, offset);
omap_reset_gpio(bank, bank-chip.base + offset);
-   spin_unlock_irqrestore(bank-lock, flags);
+   raw_spin_unlock_irqrestore(bank-lock, flags);
 
/*
 * If this is the last gpio to be freed in the bank,
@@ -810,9 +810,9 @@ static unsigned int omap_gpio_irq_startup(struct irq_data 
*d)
if (!BANK_USED(bank))
pm_runtime_get_sync(bank-dev);
 
-   spin_lock_irqsave(bank-lock, flags);
+   raw_spin_lock_irqsave(bank-lock, flags);
omap_gpio_init_irq(bank, gpio, offset);
-   spin_unlock_irqrestore(bank-lock, flags);
+   raw_spin_unlock_irqrestore(bank-lock, flags);
omap_gpio_unmask_irq(d);
 
return 0;
@@ -825,12 +825,12 @@ static void omap_gpio_irq_shutdown(struct irq_data *d

Re: [PATCH 03/16] tty: serial: 8250_core: read only RX if there is something in the FIFO

2015-02-12 Thread Sebastian Andrzej Siewior
On 02/11/2015 09:42 PM, Peter Hurley wrote:

 Reverting makes sense to me if it has caused a regression. Maybe Sebastian
 can update his patch to do this based on some quirk flag instead?
 
 That's fine with me. There's a 'bugs' field in struct 8250_uart_port and
 UART_BUG_* defines in 8250/8250.h for that purpose.

Makes sense. Reading an empty FIFO does not look right. Maybe we should
do the bug flag the other way around? But I can do what I am told to so
if there is more fallout than just this Marvell UART I could come
around with a patch to the bug field for the older OMAP.

 Regards,
 Peter Hurley

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 03/16] tty: serial: 8250_core: read only RX if there is something in the FIFO

2015-02-10 Thread Sebastian Andrzej Siewior
On 02/10/2015 12:34 AM, Peter Hurley wrote:
 The too much work message means serial8250_handle_irq() is returning 0,
 ie., not handled. Which in turn means IIR indicates no interrupt is pending
 (UART_IIR_NO_INT == 1).

The OMAP UART for instance have two possible TX-IRQ handling. The
default is to fire the interrupt once there is room for at least one
byte in the FIFO. I set the OMAP_UART_SCR_TX_EMPTY bit to get the same
behavior as the 8250 driver expects (interrupt while the FIFO is empty).
Without this bit set I've seen the message from time to time.

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] tty: serial: 8250: omap: add ttySx console if the user didn't

2014-12-18 Thread Sebastian Andrzej Siewior
This patch invokes add_preferred_console() with ttyS based on ttyO
arguments if the user didn't specify it on its own. This ensures that
the user will see the kernel booting on his serial console in case he
forgot to update the command line.

Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---

While trying to to make a proxy driver like Alan suggested I wasn't sure
how to obtain the ttyS console via official API. Then I stumbled upon
update_console_cmdline() and then add_preferred_console(). 

 drivers/tty/serial/8250/8250_omap.c | 40 +
 drivers/tty/serial/8250/Kconfig | 19 ++
 2 files changed, 59 insertions(+)

diff --git a/drivers/tty/serial/8250/8250_omap.c 
b/drivers/tty/serial/8250/8250_omap.c
index 336602eb453e..78401fbc823b 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -1248,6 +1248,46 @@ static int omap8250_runtime_resume(struct device *dev)
 }
 #endif
 
+#ifdef CONFIG_SERIAL_8250_OMAP_TTYO_FIXUP
+static int __init omap8250_console_fixup(void)
+{
+   char *omap_str;
+   char *options;
+   u8 idx;
+
+   if (strstr(boot_command_line, console=ttyS))
+   /* user set a ttyS based name for the console */
+   return 0;
+
+   omap_str = strstr(boot_command_line, console=ttyO);
+   if (!omap_str)
+   /* user did not set ttyO based console, so we don't care */
+   return 0;
+
+   omap_str += 12;
+   if ('0' = *omap_str  *omap_str = '9')
+   idx = *omap_str - '0';
+   else
+   return 0;
+
+   omap_str++;
+   if (omap_str[0] == ',') {
+   omap_str++;
+   options = omap_str;
+   } else {
+   options = NULL;
+   }
+
+   add_preferred_console(ttyS, idx, options);
+   pr_err(WARNING: Your 'console=ttyO%d' has been replaced by 'ttyS%d'\n,
+  idx, idx);
+   pr_err(This ensures that you still see kernel messages. Please\n);
+   pr_err(update your kernel commandline.\n);
+   return 0;
+}
+console_initcall(omap8250_console_fixup);
+#endif
+
 static const struct dev_pm_ops omap8250_dev_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(omap8250_suspend, omap8250_resume)
SET_RUNTIME_PM_OPS(omap8250_runtime_suspend,
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index 0fcbcd29502f..87adf08b9b6b 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -308,6 +308,25 @@ config SERIAL_8250_OMAP
 
  This driver uses ttyS instead of ttyO.
 
+config SERIAL_8250_OMAP_TTYO_FIXUP
+   bool Replace ttyO with ttyS
+   depends on SERIAL_8250_OMAP=y  SERIAL_8250_CONSOLE
+   default y
+   help
+ This option replaces the console=ttyO argument with the matching
+ ttyS argument if the user did not specified it on the command line.
+ This ensures that the user can see the kernel output during boot
+ which he wouldn't see otherwise. The getty has still to be configured
+ for ttyS instead of ttyO regardless of this option.
+ This option is intended for people who automatically enable this
+ driver without knowing that this driver requires a different console=
+ argument. If you read this, please keep this option disabled and
+ instead update your kernel command line. If you prepare a kernel for a
+ distribution or other kind of larger user base then you probably want
+ to keep this option enabled. Otherwise people might complain about a
+ not booting kernel because the serial console remains silent in case
+ they forgot to update the command line.
+
 config SERIAL_8250_FINTEK
tristate Support for Fintek F81216A LPC to 4 UART
depends on SERIAL_8250  PNP
-- 
2.1.3

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/6] Touchscreen performance related fixes

2014-12-11 Thread Sebastian Andrzej Siewior
On 12/11/2014 09:34 PM, Nicolae Rosia wrote:
 Hello,

Hi,

 Any updates on this series? I don't see it applied in [1] or [2].

I manage to freeze am335x-evm with those patches and I think Vignesh
is looking into this.

 Regards,
 Nicolae Rosia

Sebastian

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/6] Touchscreen performance related fixes

2014-12-01 Thread Sebastian Andrzej Siewior
On 12/01/2014 10:53 AM, Vignesh R wrote:
 Hi Sebastian,

Hi Vignesh,

 I fixed the issue that was triggering the WARN_ON(). I think it would be
 better if you tested these patches, before I posted them on the
 mainline. I don't want to clutter the list with too main versions. Here
 is the link to the tree with latest changes:

awesome, thank you.

 
 git clone -b tsc-devel git://git.ti.com/kernel/tsc-adc.git
 (tsc-devel branch)

I will and let you know.

 Please test the above tree and let me know the results.
 I will post new version(v5) if there are no issues wrt IIO and TSC
 working at the same time.

Cool. Were you able to get in touch with someone who has a 5-wire touch?

 Regards
 Vignesh
 

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] tty: serial: serial-omap: depend on !8250_omap

2014-12-01 Thread Sebastian Andrzej Siewior
On 12/01/2014 05:38 PM, Tony Lindgren wrote:
 * One Thousand Gnomes gno...@lxorguk.ukuu.org.uk [141201 06:11]:
 Well the nightmare userspace switch from ttyS to ttyO few years ago is
 something we want to avoid.. I think the best solution would be to make
 serial-omap.c transparently provide support for ttyO using the new 8250
 code so both ttyS and ttyO devices would just work. Otherwise it will
 be years of my serial port stopped working questions again.

 Thata a udev problem not a kernel one surely.
 
 How do you suggest we get people to update their kernel command line
 and inittab? Udev may not even be installed.

There are three use cases that I can think of right now:
- people that enable that new driver via oldconfig
  I would expect that they read the help message in Kconfig. No worry
  about them.

- people that get a complete system via magic_build_tool (may yocto or
  whatever)
  If $TOOL decides to use the new driver, then it should update
  commandline in bootloader. Those things create usually bootloader +
  kernel + rootfile system. If the commandline is saved on flash/mmc
  then it won't be reset from default. However udev should help here.
  So not a problem either (udev can't fix the kernel boot output but we
  should see atleast the login console).

- people that build omap2plus_defconfig and we switch to the new driver
  Those people get switched from one driver to the other without
  knowing. This is what I tried to bring to everyone's attention. The
  defconfig hasn't been changed yet so it is not problem for next
  release (yet).

I agree that this is a user problem. We agreed not to introduce a
console proxy in kernel _or_ hack the command line in kernel (to
replace O with S).
So I think the problem boils down to educate the user about this
change. Making the old driver disappear was one way of getting the
user's attention. Another idea would be to introduce a #warning which is
also activated by the defconfig and informs the user about the change.
Ideally this #warning could be switched off by Kconfig once the user
reads  deactivates it. This requires the pay attention to warnings
during build. #error would make sure he does but it breaks auto-builds
so it is not an option.

 Regards,
 
 Tony
 

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] tty: serial: serial-omap: depend on !8250_omap

2014-11-29 Thread Sebastian Andrzej Siewior
* Sebastian Andrzej Siewior | 2014-11-26 23:01:46 [+0100]:

Technically speaking this is not required. If both are enabled then the
Maikefile order says that 8250 one wins, the second is never probed.

If we choose to enable 8250_omap via defconfig then one might get supprised
that his console isn't working anymore since nothing says use ttySx
instead ttyOx.
This patch _tries_ to bring this to the users' attention by not showing
the serial-omap driver once the 8250 one is enabled. So the user might
choose to use the help text which says that this driver (8250_omap)
uses ttySx instead ttyOx.

Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
This is my attempt to warn the defconfig user of the defconfig change
(which did not yet happen). Any suggestions?

This is was Uwe Kleine-König suggested off-list:

|Currently there are two drivers for the serial device. Until the new one
|matured enough to drop the old one, let them conflict each other. They
|both handle the same devices, but only one can be responsible for a
|single device. There is no technical need, but having two drivers in the
|same kernel might result in surprises.

I personally don't mind having two drivers enabled since the makefile
order is always the same. My main concern is the ttyOx - ttySx switch
after the newer driver is enabled by default via defconfig (and the user
does not know it). make oldconfig is covered by default n.
Uwe's has a point about matured enough to drop the old one. It isn't
mentioned anywhere that the newer driver supports also DMA. Is this
something we want to add to the help text?
Could someone that will probably be dealling with possible fallout comment
on this? This patch shouldn't go in without an ACK.

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] tty: serial: serial-omap: depend on !8250_omap

2014-11-26 Thread Sebastian Andrzej Siewior
Technically speaking this is not required. If both are enabled then the
Maikefile order says that 8250 one wins, the second is never probed.

If we choose to enable 8250_omap via defconfig then one might get supprised
that his console isn't working anymore since nothing says use ttySx
instead ttyOx.
This patch _tries_ to bring this to the users' attention by not showing
the serial-omap driver once the 8250 one is enabled. So the user might
choose to use the help text which says that this driver (8250_omap)
uses ttySx instead ttyOx.

Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
This is my attempt to warn the defconfig user of the defconfig change
(which did not yet happen). Any suggestions?

 drivers/tty/serial/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index e71a28b4b94e..1b1bdf946fee 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1125,7 +1125,7 @@ config SERIAL_OF_PLATFORM
 
 config SERIAL_OMAP
tristate OMAP serial port support
-   depends on ARCH_OMAP2PLUS
+   depends on ARCH_OMAP2PLUS  !SERIAL_8250_OMAP
select SERIAL_CORE
help
  If you have a machine based on an Texas Instruments OMAP CPU you
-- 
2.1.3

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] tty: serial: 8250: omap: Add pinctrl support for suspend

2014-11-25 Thread Sebastian Andrzej Siewior
On 11/06/2014 09:35 PM, Tony Lindgren wrote:
 The pinctrl change in this patch and the wake-up events are a separate
 issue.

So this patch can go in and wake-up issue will be fixed once the
infrastructure is there. No misunderstanding here?

 Tony
 

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 3/6] mfd: ti_am335x_tscadc: Remove unwanted reg_se_cache save

2014-11-24 Thread Sebastian Andrzej Siewior
On 11/21/2014 02:10 PM, Richard Cochran wrote:

 On the BB white using the LCD4 cape and the shipped debian kernel, the
 cursor *does* jump away, but not as often or as far as on the custom
 design I was working with.

This sounds like the ADC is still sampling while the input data becomes
invalid. Usually there is a resistor on the wiper line and the
touchscreen manual says how much it should be at least. Could you
please check if this is properly installed?

 
 Thanks,
 Richard

Sebastian

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/6] Touchscreen performance related fixes

2014-11-24 Thread Sebastian Andrzej Siewior
* Vignesh R | 2014-11-14 10:37:25 [+0530]:

This series of patches fix TSC defects related to lag in touchscreen
performance and cursor jump at touch release. The lag was result of
udelay in TSC interrupt handler. Cursor jump due to false pen-up event.
The patches implement Advisory 1.0.31 in silicon errata of am335x-evm
am335x not -evm. The am335x-evm is a board (with its own advisory
document) built around the SoC.

Just testing the v4. I can use now IIO and touchscren at the same time.
back at v1 I reported that it does not work, this has been fixed now.
I had it running for a few minutes, now I see one of WARN_ON() beeing
triggered (I've cut a few numbers so don't wonder about PID 2 and so on):

|dmesg |grep WARNING | wc -l
|10
| dmesg |grep WARNING
|[306.257995] WARNING: CPU: 0 PID: 97 at mfd/ti_am335x_tscadc.c:94 
am335x_tsc_se_set_once+0xf8/0x104
|[365.469591] WARNING: CPU: 0 PID: 58 at mfd/ti_am335x_tscadc.c:94 
am335x_tsc_se_set_once+0xf8/0x104
|[379.255904] WARNING: CPU: 0 PID: 24 at mfd/ti_am335x_tscadc.c:94 
am335x_tsc_se_set_once+0xf8/0x104
|[426.230505] WARNING: CPU: 0 PID: 35 at mfd/ti_am335x_tscadc.c:94 
am335x_tsc_se_set_once+0xf8/0x104
|[435.654091] WARNING: CPU: 0 PID: 28 at mfd/ti_am335x_tscadc.c:94 
am335x_tsc_se_set_once+0xf8/0x104
|[438.897519] WARNING: CPU: 0 PID: 91 at mfd/ti_am335x_tscadc.c:94 
am335x_tsc_se_set_once+0xf8/0x104
|[525.720193] WARNING: CPU: 0 PID: 88 at mfd/ti_am335x_tscadc.c:94 
am335x_tsc_se_set_once+0xf8/0x104
|[527.644770] WARNING: CPU: 0 PID: 38 at mfd/ti_am335x_tscadc.c:94 
am335x_tsc_se_set_once+0xf8/0x104
|[557.218349] WARNING: CPU: 0 PID: 56 at mfd/ti_am335x_tscadc.c:94 
am335x_tsc_se_set_once+0xf8/0x104
|[610.077274] WARNING: CPU: 0 PID: 2 at mfd/ti_am335x_tscadc.c:94 
am335x_tsc_se_set_once+0xf8/0x104

The complete trace:

|[610.110692] CPU: 0 PID: 4422 Comm: cat Tainted: GW  3.18.0-rc6+ 
#1745
|[610.118577] [c00138ec] (unwind_backtrace) from [c0011544] 
(show_stack+0x10/0x14)
|[610.126772] [c0011544] (show_stack) from [c003c9b0] 
(warn_slowpath_common+0x68/0x88)
|[610.135313] [c003c9b0] (warn_slowpath_common) from [c003c9ec] 
(warn_slowpath_null+0x1c/0x24)
|[610.144586] [c003c9ec] (warn_slowpath_null) from [bf00569c] 
(am335x_tsc_se_set_once+0xf8/0x104 [ti_am335x_tscadc])
|[610.155886] [bf00569c] (am335x_tsc_se_set_once [ti_am335x_tscadc]) from 
[bf067494] (tiadc_read_raw+0xbc/0x190 [ti_am335x_adc])
|[610.168326] [bf067494] (tiadc_read_raw [ti_am335x_adc]) from [bf02dccc] 
(iio_read_channel_info+0x9c/0xa4 [industrialio])
|[610.180191] [bf02dccc] (iio_read_channel_info [industrialio]) from 
[c02a42d4] (dev_attr_show+0x1c/0x48)
|[610.190477] [c02a42d4] (dev_attr_show) from [c013d544] 
(sysfs_kf_seq_show+0x8c/0x110)
|[610.199108] [c013d544] (sysfs_kf_seq_show) from [c013c1c8] 
(kernfs_seq_show+0x24/0x28)
|[610.207833] [c013c1c8] (kernfs_seq_show) from [c0102658] 
(seq_read+0x1b4/0x47c)
|[610.215922] [c0102658] (seq_read) from [c00e6700] (vfs_read+0x8c/0x148)
|[610.223269] [c00e6700] (vfs_read) from [c00e67fc] (SyS_read+0x40/0x8c)
|[610.230525] [c00e67fc] (SyS_read) from [c000e640] 
(ret_fast_syscall+0x0/0x30)

Could you please look at that one? (I tested it on am335x-evm btw).

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 0/6] Touchscreen performance related fixes

2014-11-24 Thread Sebastian Andrzej Siewior
On 11/24/2014 01:16 PM, Vignesh R wrote:

 I have tried running both IIO and TSC at the same time. But I have never
 seen WARN_ON() even after running for close to 30 min. Can you send me
 the exact script, so that it will be easy to reproduce?

Sure thing.
- one shell
evtest /dev/input/event2
- second shell
./iio-test.sh
  with:

|#!/bin/sh
|
|while [ 1 = 1 ]
|do
|cat /sys/bus/iio/devices/iio\:device0/in_voltage4_raw
|done


the kernel config: https://breakpoint.cc/am335x-config

 
 Regards
 Vignesh

Sebastian

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 11/13] arm: dts: dra7: add DMA properties for UART

2014-11-13 Thread Sebastian Andrzej Siewior
On 11/05/2014 08:43 PM, Lennart Sorensen wrote:
 I managed to get something dma related on uart3.  But it isn't happy:
 
 [   95.577401] DMA misaligned error with device 53
 repeated many times.
 
 I wonder if the dma support isn't quite working for the omap572x yet in
 this tree (ti's 3.12.y tree), or maybe it is picky and the driver still
 needs a bit of work.

misaligned dma? I haven't seen any alignment requirement for SDMA/EDMA
and I haven't seen this error on beagle board, am335x-evm or dra7-evm.

 I have had no issues on uart7 and 8 without dma.

So basically what you are saying is that DMA (no matter which channel)
gives you this error and without DMA it works fine?

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 00/13 v10] omap 8250 based UART + DMA

2014-11-06 Thread Sebastian Andrzej Siewior
On 11/06/2014 04:14 AM, Greg KH wrote:
 I've now applied the patches here that I could, if I have missed any,
 please let me know and resend.

Thank you Greg. I pulled your tty-testing and it seems to work on
am335x-evm/dra7-evm.

Tony, if you could please take the two .dts files then the series would
be complete (that one dma patch was applied by Vinod during the merge
window).

 
 thanks,
 
 greg k-h
 
Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] tty: serial: 8250: omap: Add pinctrl support for suspend

2014-11-06 Thread Sebastian Andrzej Siewior
This is mostly an equivalent for the 8250-omap driver based on a patch
of Dave Gerlach for the omap-serial driver (which is not yet merged).

From his changelog:
|By optionally putting the pins into sleep state in the suspend callback
|we can accomplish two things.
|- minimize current leakage from pins and thus save power,
|- prevent the IP from driving pins output in an uncontrolled manner,
|  which may happen if the power domain drops the domain regulator.

The pinctlr change is put before enable_wakeup logic as per Nishanth
Menon (slightly reworded):
|When wakeup is enabled, I/O daisy chain based wakeup is used by
|reconfiguring the padconfig register. However, this gets overriden by
|sleep/wakeup configuration. Therefore we need first to allow pinctrl to
|play with the wakeup bits as needed beyond the sleep configuration.

Cc: Dave Gerlach d-gerl...@ti.com
Cc: Nishanth Menon n...@ti.com
Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/tty/serial/8250/8250_omap.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/tty/serial/8250/8250_omap.c 
b/drivers/tty/serial/8250/8250_omap.c
index 57a8b1241b85..1681875f2996 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -1156,6 +1156,7 @@ static int omap8250_suspend(struct device *dev)
serial8250_suspend_port(priv-line);
flush_work(priv-qos_work);
 
+   pinctrl_pm_select_sleep_state(dev);
if (device_may_wakeup(dev))
omap8250_enable_wakeup(priv, true);
else
@@ -1167,6 +1168,7 @@ static int omap8250_resume(struct device *dev)
 {
struct omap8250_priv *priv = dev_get_drvdata(dev);
 
+   pinctrl_pm_select_default_state(dev);
if (device_may_wakeup(dev))
omap8250_enable_wakeup(priv, false);
 
-- 
2.1.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] tty: serial: 8250: omap: Add pinctrl support for suspend

2014-11-06 Thread Sebastian Andrzej Siewior
On 11/06/2014 08:15 PM, Nishanth Menon wrote:
 sounds good to me *IF* omap8250_enable_wakeup (wakeirq handling) is
 the way we want to continue doing things for daisychain? - Tony, can
 you comment?
 http://marc.info/?l=linux-omapm=141222144402707w=2
 
 I wonder if wakeirq explicit handling is valid anymore and something
 given the potential race and alternate approach proposed?

The wakeirq logic is already in the driver. So if we go for the
alternate approach, the pinctrl patch is obsolete? Or does it mean we
get rid of the map8250_enable_wakeup() including the second irq we have
now (and keep the pinctl change)?

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 11/13] arm: dts: dra7: add DMA properties for UART

2014-11-05 Thread Sebastian Andrzej Siewior
On 11/05/2014 02:15 AM, Lennart Sorensen wrote:
 Well 4 hours running with multiple reboots (our testsuite reboots every
 30 minutes to test the watchdog).  So far it has only lost 70 bytes out
 of 40MB of data sent between uart7 and uart8 (and we are pretty sure
 the serial test has a small bug that causes a few bytes to be lost right
 after a reboot sometimes).
 
 The reason I am even trying the new driver today is that we were seeing
 soft lockups on the CPU whenever the serial ports were being tested,
 usually in less than 5 minutes, so 4 hours without a lockup is a good
 sign.  No idea what might be wrong with the old omap serial driver, but
 it seems something is (unless of course we managed to break it somehow
 when we tried to solve its habit of dropping characters).

Okay. No DMA but the basic part seems to work for you. Thanks for
testing.

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 11/13] arm: dts: dra7: add DMA properties for UART

2014-11-05 Thread Sebastian Andrzej Siewior
On 11/05/2014 05:20 PM, Lennart Sorensen wrote:
 On Wed, Nov 05, 2014 at 10:33:15AM -0500, Lennart Sorensen wrote:
 Two systems ran 16 hours each so far with no issues.  Pushed 170MB of
 data through the pair of serial ports on one system at 230400.
 
 The console on uart3 doesn't appear to be using the dma assuming the
 values in /sys for the dma controller and bytes transferred mean anything.
 It does mention in dmesg that it allocated dma channels for uart3 though.

Then it should use it :)

 How do you tell if it is using dma?

There is omap_8250_tx_dma() and omap_8250_rx_dma(). Both setup
callbacks (the rx+tx _complete). Upon successful DMA transfer you
should see them invoked with bytes transfered (0).
For RX transfer you need at least trigger bytes in the FIFO within a
given time frame (I think it was 46 bytes and the delay may be up to 2
bytes). If you miss this then DMA for RX won't wire and you purge the
FIFO manually via timeout-interrupt (the callback will be invoked
with an error condition and 0 bytes).

Assuming this works for you then one should figure out why the counters
in /sys are not updated…

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/4] Touchscreen performance related fixes

2014-11-04 Thread Sebastian Andrzej Siewior
On 11/04/2014 12:44 PM, Vignesh R wrote:

 I ran following commands
 $ evtest /dev/input/touchscreen0 
 (with heavy item on touchscreen)
  and
 $ cat /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage4_en
 (in a busy loop)
 I tried above experiment on my board but I didn't hit any problem even
 after running for close to 30 minutes. I was unable to reproduce failure

Just to make sure: You had the touchscreen and iio command running in
parallel and you saw evtest output while there was iio operation?

 The problem may be in configuring correct charge-delay value. Please run:
 $ ts_test  /dev/null
 and let me know if pen events are being detected properly.

Well I get the touch events but not while busy loop on iio interface is
running (I get maybe one event every 5 seconds or so).
After all, it is the same HW you have.

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 11/13] arm: dts: dra7: add DMA properties for UART

2014-11-04 Thread Sebastian Andrzej Siewior
On 11/04/2014 06:02 PM, Lennart Sorensen wrote:
 
 According to the manual the DMA channels for UART7 to 10 are:
 
 uart7:  144 145
 uart8:  146 147
 uart9:  148 149
 uart10: 150 151
 
 Might as well add those too.  We have uart 7 and 8 in use on our board
 so I am about to go test it.

Mind sharing the manual with me? Mine does not mention DMA channels for
UART7-10. If you are able to test 7+8 (and it works) could you please
make patch which with for the remaining four devices?

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/4] Touchscreen performance related fixes

2014-11-03 Thread Sebastian Andrzej Siewior
On 10/27/2014 08:02 PM, Griffis, Brad wrote:
 On 10/27/2014 12:34 PM, Sebastian Andrzej Siewior wrote:
 Do we really need #3 (and then #4)? Given the complexity we have already, is 
 there any benefit by decreasing this value? 
 
 I specifically requested we add ti,charge-delay to the device tree because it 
 is THE critical value to tune for a given design.  Although I think the 
 current value of 0xB000 will be suitable for a great many designs, I expect 
 that many users will need to adjust this value for their hardware.  Details 
 such as which touchscreen vendor is being used and how the touchscreen is 
 connected (header vs cable) have an effect on what's appropriate here.

Oh. That is one knob I hoped we could avoid since I haven't seen it
before on other TSCs. But okay. Please make sure that there is a
message printed if the default value is used. And lets hope the user
will do something about his.

 Would  someone want to increase it? Can we safely determine a value which 
 works for everyone?
 
 This value represents a hardware delay before checking for the pen-up event.  
 So in the scenario where someone is seeing excessive false pen-up events they 
 will want to increase this parameter.  The downsize of making this larger is 
 that it decreases the overall sampling speed of both the touchscreen as well 
 as the standalone ADC samples.  At one point I tried making it huge, but that 
 made the touchscreen overly sluggish because the sampling became too slow.  
 So there is a definite trade-off that if you make it too large the 
 touchscreen becomes sluggish, and if you make it too small then you may see 
 false pen-up events.  The optimal value will need to be tuned for a given 
 design.

I applied the patches from this series and did the following test on my
am335x-evm: A mug on the touchscreen (to make sure the events are
coming), evtest on the event node to see that the events and loop of

cat /sys/bus/iio/devices/iio\:device0/in_voltage4_raw

In the past I was able lock up the TSC/ADC HW that way (see commit
7ca6740cd1 (mfd: input: iio: ti_amm335x: Rework TSC/ADC
synchronization)) for details.
With this patches applied I don't seen any TSC events once the IIO
interface is (heavily) used. Can this be fixed?

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/4] Touchscreen performance related fixes

2014-10-27 Thread Sebastian Andrzej Siewior
On 10/27/2014 12:08 PM, Vignesh R wrote:
 This series of patches fix TSC defects related to lag in touchscreen

I will try to look this in the next few days. Do we really need #3 (and
then #4)? Given the complexity we have already, is there any benefit by
decreasing this value? Would  someone want to increase it? Can we safely
determine a value which works for everyone?

Sebastian

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V2] tty: serial: omap: Increase max consoles and add check to prevent crash

2014-10-23 Thread Sebastian Andrzej Siewior
On 10/22/2014 02:46 PM, Nishanth Menon wrote:
 Increase the maximum number of consoles possible to 10 since DRA7 now
 has the maximum number of consoles possible. without doing this, for
 example, enabling DRA7 UART10 results in internal data structures and
 console cannot match up and we endup with a crash as follows:

good, Thanks.
Acked-by: Sebastian Andrzej Siewior bige...@linutronix.de

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] tty: serial: omap: increase max consoles to 10

2014-10-22 Thread Sebastian Andrzej Siewior
On 10/21/2014 06:23 PM, Nishanth Menon wrote:
 
 The final solution is to transition off to use 8250 driver and no
 dependency on console structures and move away from omap-serial driver,
 hence no major cleanups are done for this driver.

So the shiny new driver works for you, is this what you are saying?

 diff --git a/drivers/tty/serial/omap-serial.c 
 b/drivers/tty/serial/omap-serial.c
 index 18c30ca..4f9cbb6 100644
 --- a/drivers/tty/serial/omap-serial.c
 +++ b/drivers/tty/serial/omap-serial.c
 @@ -46,7 +46,7 @@
  
  #include dt-bindings/gpio/gpio.h
  
 -#define OMAP_MAX_HSUART_PORTS6
 +#define OMAP_MAX_HSUART_PORTS10
  
  #define UART_BUILD_REVISION(x, y)(((x)  8) | (y))

Please also add a check in the probe code that up-port.line does not
exceed OMAP_MAX_HSUART_PORTS again. So we leave the probe function with
an error code instead.

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 09/16] tty: serial: 8250_dma: Add a TX trigger workaround for AM33xx

2014-10-02 Thread Sebastian Andrzej Siewior
* Frans Klaver | 2014-09-30 10:44:16 [+0200]:

On Mon, Sep 29, 2014 at 12:30:43PM +0200, Frans Klaver wrote:
 On Mon, Sep 29, 2014 at 11:54:40AM +0200, Sebastian Andrzej Siewior wrote:
  For your too much work for irq problem: Could you add trace_printk()
  in tx/rx dma start/complete, and irq routine? The interresting part is
  what is the irq routine doing once entered. It might be a condition that
  is ignored at first and acked later while serving another event. Or it
  is really doing something and this is more or less legal.
 

Here's some trace output I get. I hope branches become clear by the
calls they do.

   uart_test-482   [000] .ns.17.860139: __dma_rx_do_complete: error: 
 0, uart_bug_dma: 32
   uart_test-482   [000] .ns.17.860141: __dma_rx_do_complete: 
 rx_dma(p, 0)

these two happen outside the IRQ routine for every 48 bytes.
…
   uart_test-483   [000] dnh.17.861018: serial8250_interrupt: irq 89
   uart_test-483   [000] dnh.17.861026: serial8250_interrupt: 89 e
e? Did was the routine invoked 0xe times or this a register?

   uart_test-483   [000] .ns.17.861045: __dma_rx_do_complete: error: 
 0, uart_bug_dma: 32
   uart_test-483   [000] .ns.17.861047: __dma_rx_do_complete: 
 rx_dma(p, 0)
another 48bytes

   uart_test-479   [000] d.H.17.861124: serial8250_interrupt: irq 89
   uart_test-479   [000] d.H.17.861133: serial8250_handle_irq: l1 IIR 
 cc LSR 61
   uart_test-479   [000] d.H.17.861135: serial8250_handle_irq: 
 rx_dma(up, iir)
   uart_test-479   [000] d.H.17.861139: serial8250_rx_dma: l1, 
 UART_IIR_RX_TIMEOUT
   uart_test-479   [000] d.H.17.861147: __dma_rx_do_complete: error: 
 1, uart_bug_dma: 32
   uart_test-479   [000] d.H.17.861150: serial8250_handle_irq: 
 rx_chars(up, status)
   uart_test-479   [000] d.H.17.861190: serial8250_handle_irq: 
 rx_dma(up, 0)
timeout, manual purge. Do you have an idea how many bytes were manually
received?

   uart_test-479   [000] d.H.17.861205: serial8250_interrupt: 89 e
 kworker/0:1-10[000] dnH.17.864949: serial8250_interrupt: irq 89

So far so good. We're just entered interrupt where stuff goes awry. The
following pattern repeats over 600 times:

 kworker/0:1-10[000] dnH.17.865198: serial8250_handle_irq: l1 IIR 
 cc LSR 61
 kworker/0:1-10[000] dnH.17.865254: serial8250_handle_irq: 
 rx_dma(up, iir)
 kworker/0:1-10[000] dnH.17.865333: serial8250_rx_dma: l1, 
 UART_IIR_RX_TIMEOUT
 kworker/0:1-10[000] dnH.17.865626: __dma_rx_do_complete: error: 
 1, uart_bug_dma: 32
 kworker/0:1-10[000] dnH.17.865747: serial8250_handle_irq: 
 rx_chars(up, status)
 kworker/0:1-10[000] dnH.17.868797: serial8250_handle_irq: 
 rx_dma(up, 0)

ending with:

 kworker/0:1-10[000] dnH.20.027093: serial8250_interrupt: 
 serial8250: too much work for irq89
 kworker/0:1-10[000] dnH.20.027181: serial8250_interrupt: 89 e

This clogs the entire system until I disconnect the communication lines.

So we get an RX timeout. The receiver fifo trigger level was not reached
and 8250_core is left to copy the remaining data. I would expect that if
the trigger level wasn't reached, we wouldn't need to be doing this that
often. On the other hand, could we be trapped reading data from rx
without dma helping us? And how could we resolve this?

So if I understand you correct, then you enter serial8250_interrupt()
and then you enter multiple times omap_8250_dma_handle_irq() and
you always get a TIMEOUT event and fetch byte(s) manualy via
serial8250_rx_chars(). And after one iteration UART_IIR_NO_INT is not
set and you do it again, right?

I have no idea when exactly the timeout-interrupt fires. The manual
says: … the count is reset when there is activity on uarti_rx … but it
does not say how often it increments before the level is reached.
It also might be that you have a small gap between two bytes and this
high baud rate the gap is considered as a timeout event.

Another thing could be that if the we enqueue a RX transfer from the
dma_completion callback then we have too many bytes in the FIFO already
becahse the callback is invoked from softirq. What happens if we cut the
middle man via


diff --git a/drivers/dma/virt-dma.c b/drivers/dma/virt-dma.c
index 6f80432..21b04bd 100644
--- a/drivers/dma/virt-dma.c
+++ b/drivers/dma/virt-dma.c
@@ -63,8 +63,9 @@ static void vchan_complete(unsigned long arg)
dma_async_tx_callback cb = NULL;
void *cb_data = NULL;
LIST_HEAD(head);
+   unsigned long flags;
 
-   spin_lock_irq(vc-lock);
+   spin_lock_irqsave(vc-lock, flags);
list_splice_tail_init(vc-desc_completed, head);
vd = vc-cyclic;
if (vd) {
@@ -72,7 +73,7 @@ static void vchan_complete(unsigned long arg)
cb = vd-tx.callback;
cb_data = vd-tx.callback_param;
}
-   spin_unlock_irq(vc

Re: [PATCH 00/13 v10] omap 8250 based UART + DMA

2014-10-02 Thread Sebastian Andrzej Siewior
* Tony Lindgren | 2014-10-02 09:43:39 [-0700]:

Looks good to me. For the patches that do not yet have my acks, please
feel free to add:

Reviewed-by: Tony Lindgren t...@atomide.com
Tested-by: Tony Lindgren t...@atomide.com
Thanks.

It's probably best that I queue the .dts changes separately though
to avoid pointless merge conflicts.

Yeah. There is no real dependency on them except that you need them at
some point :)

Regards,

Tony

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 09/16] tty: serial: 8250_dma: Add a TX trigger workaround for AM33xx

2014-09-29 Thread Sebastian Andrzej Siewior
* Frans Klaver | 2014-09-29 10:50:42 [+0200]:

This version fixes the console things for us. It also increases the
amount of data we can push over the serial port. If I push the data
towards our requirements, we're not there yet. I get the too much work
for irq notice still. However, I don't think you'd need to be fixing
that in this series (or at all). We had similar issues there with
omap-serial as well.

As far as I'm concerned, this is

Tested-by: Frans Klaver frans.kla...@xsens.com

Thanks a lot.
There is a patch named ARM: edma: unconditionally ack the error
interrupt. I have the feeling that this is not really required once we
delay set_termios. I couldn't reproduce the bug with beagleblack with my
usual test case.

For your too much work for irq problem: Could you add trace_printk()
in tx/rx dma start/complete, and irq routine? The interresting part is
what is the irq routine doing once entered. It might be a condition that
is ignored at first and acked later while serving another event. Or it
is really doing something and this is more or less legal.

Thanks,
Frans

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 13/16] tty: serial: 8250_dma: add pm runtime

2014-09-29 Thread Sebastian Andrzej Siewior
* Frans Klaver | 2014-09-29 11:26:06 [+0200]:

On Wed, Sep 10, 2014 at 09:30:08PM +0200, Sebastian Andrzej Siewior wrote:
 There is nothing to do for RPM in the RX path. If the HW goes off then it
 won't assert the DMA line and the transfer won't happen. So we hope that
 the HW does not go off for RX to work (DMA or PIO makes no difference
 here).
 
 For TX the situation is slightly different. RPM is enabled on
 start_tx(). We can't disable RPM on DMA complete callback because there
 is still data in the FIFO which is being sent. We have to wait until
 the FIFO is empty before we disable it.
 For this to happen we fake a TX sent error and enable THRI. Once the
 FIFO is empty we receive an interrupt and since the TTY-buffer is still
 empty we put RPM via __stop_tx(). Should it been filed then in the
 start_tx() path we should program the DMA transfer and remove the error
 flag and the THRI bit.

That last sentence starts out a bit messy.

This got mered so there is nothing I can do about it anymore. But I will
try to fix comments in code where and in patches that are not yet merged
(what you report :))

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 06/16] tty: serial: Add 8250-core based omap driver

2014-09-29 Thread Sebastian Andrzej Siewior
* Frans Klaver | 2014-09-29 11:38:23 [+0200]:

threshold
fixed

 +/*
 + * It claims to be 16C750 compatible however it is a little different.
 + * It has EFR and has no FCR7_64byte bit. The AFE (which it claims to
 + * have) is enabled via EFR instead of MCR. The type is set here 8250
 + * just to get things going. UNKNOWN does not work for a few reasons and
 + * we don't need our own type since we don't use 8250's set_termios()
 + * and our bugs are handeld via the bug member.

handled
replaced that last line with 
or pm callback.

since there no bugs member anymore.


 + */
 +up.port.type = PORT_8250;
 +up.port.iotype = UPIO_MEM;
 +up.port.flags = UPF_FIXED_PORT | UPF_FIXED_TYPE | UPF_SOFT_FLOW |
 +UPF_HARD_FLOW;
 +up.port.private_data = priv;
 +
 +up.port.regshift = 2;
 +up.port.fifosize = 64;
 +up.tx_loadsz = 64;
 +up.capabilities = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP;
 +#ifdef CONFIG_PM_RUNTIME
 +/*
 + * PM_RUNTIME is mostly transparent. However to do it right we need to a

need to _do_ a ...?
I think dropping that 'to' should fix it.

 + * TX empty interrupt before we can put the device to auto idle. So if
 + * PM_RUNTIME is not enabled we don't add that flag and can spare that
 + * one extra interrupt in the TX path.
 + */

snip

 +config SERIAL_8250_OMAP
 +tristate Support for OMAP internal UART (8250 based driver)
 +depends on SERIAL_8250  ARCH_OMAP2PLUS
 +help
 +  If you have a machine based on an Texas Instruments OMAP CPU you
 +  can enable its onboard serial ports by enabling this option.
 +
 +  This driver is in early stage and uses ttyS instead of ttyO.
 +

I just wondered if this driver should be marked experimental?
What did you have in mind? CONFIG_EXPERIMENTAL is gone. After all that
debuging that I had in the meantime I was thinking about dropping that
early stage.

Thanks,
Frans

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 02/16] tty: serial: 8250_core: add run time pm

2014-09-29 Thread Sebastian Andrzej Siewior
* Frans Klaver | 2014-09-29 11:46:20 [+0200]:

On Wed, Sep 10, 2014 at 09:29:57PM +0200, Sebastian Andrzej Siewior wrote:
 +/*
 + * This two wrapper ensure, that enable_runtime_pm_tx() can be called more 
 than

These two wrappers ensure that enable_runtime_pm_tx() ...
fixed

 @@ -1469,7 +1531,12 @@ void serial8250_tx_chars(struct uart_8250_port *up)
  
  DEBUG_INTR(THRE...);
  
 -if (uart_circ_empty(xmit))
 +/*
 + * With RPM enabled, we have to wait once the FIFO is empty before the

s,once,until,? Or do I not understand the sentence correctly?
No, you understand it correct. until is the better word here.

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 09/16] tty: serial: 8250_dma: Add a TX trigger workaround for AM33xx

2014-09-29 Thread Sebastian Andrzej Siewior
* Peter Hurley | 2014-09-17 08:20:41 [-0400]:

 So I connected my am335x-evm
 with beagle board xm because both of them have an old fashion UART
 connector (instead those uart-to-usb). Both configured with HW-Flow and
 I haven't seen the function invoked but I saw port-icount.overrun
 being incremented. This shouldn't happen. So I am a little puzzled here…

Yeah, that's weird. Do you have a break-out box to confirm that RTS/CTS are
being driven?

=
- beagle board
  According to schematics the board has only RX and TX connected. No
  RTS/CTS

- am335x-evm
  The schematics say DNI next to a resistor on RTS/CTS. DNI stands
  most likely for Do Not Install. With a scope it looks like the the
  wire behind the MAX is open.

- beagle bone black
  Only RX and TX are wired towards the USB2serial device.

In short: each device I have has RTS/CTS not working/connected and I
can't test HW handshake with HW available.

Regards,
Peter Hurley

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 00/13 v10] omap 8250 based UART + DMA

2014-09-29 Thread Sebastian Andrzej Siewior
The queue is getting smaller. The highlights of v9…v10
- the DMA stall Frans Klaver reported which popped up in yocto is gone. It
  also seems that the ack the err-irq even if nothing happened in EDMA
  can be dropped.
- the RX- and TX-DMA callbacks are now OMAP-only and no bugs flags are
  introduced into the generic DMA code. This also means that there is
  custom IRQ routine in case of DMA.

Sebastian

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 09/13] dmaengine: edma: check for echan-edesc = NULL in edma_dma_pause()

2014-09-29 Thread Sebastian Andrzej Siewior
I added book keeping of whether or not the 8250-dma driver has an RX
transfer pending or not so we don't BUG here if it calls
dmaengine_pause() on a channel which has not a pending transfer. Guess
what, this is not enough.
The following can be triggered with a busy RX channel and hackbench in
background:
- DMA transfer completes. The callback is delayed via
  vchan_cookie_complete() into a tasklet so it das not happen asap.
- hackbench keeps the system busy so the tasklet does not run soon.
- the UART collected enough data and generates an timeout-interrupt.
  Since 8250-dma *thinks* the DMA-transfer is still pending it tries to
  cancel it via invoking dmaengine_pause() first. This causes the segfault
  because echan-edesc is NULL now that the transfer completed (however
  the callback did not run yet).

With this patch we don't BUG in the scenario described.

Cc: vinod.k...@intel.com
Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/dma/edma.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index 7b65633f495e..123f578d6dd3 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -288,7 +288,7 @@ static int edma_slave_config(struct edma_chan *echan,
 static int edma_dma_pause(struct edma_chan *echan)
 {
/* Pause/Resume only allowed with cyclic mode */
-   if (!echan-edesc-cyclic)
+   if (!echan-edesc || !echan-edesc-cyclic)
return -EINVAL;
 
edma_pause(echan-ch_num);
-- 
2.1.0

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 08/13] tty: serial: 8250_omap: add custom DMA-RX callback

2014-09-29 Thread Sebastian Andrzej Siewior
The omap needs a DMA request pending right away. If it is
enqueued once the bytes are in the FIFO then nothing will happen
and the FIFO will be later purged via RX-timeout interrupt.
This patch enqueues RX-DMA request on completion but not if it
was aborted on error. The first enqueue will happen in the driver
in startup.

Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/tty/serial/8250/8250_omap.c | 96 +
 1 file changed, 96 insertions(+)

diff --git a/drivers/tty/serial/8250/8250_omap.c 
b/drivers/tty/serial/8250/8250_omap.c
index 5f183d197dfa..1659858e595a 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -619,6 +619,102 @@ static void omap_8250_unthrottle(struct uart_port *port)
 }
 
 #ifdef CONFIG_SERIAL_8250_DMA
+static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir);
+
+static void __dma_rx_do_complete(struct uart_8250_port *p, bool error)
+{
+   struct uart_8250_dma*dma = p-dma;
+   struct tty_port *tty_port = p-port.state-port;
+   struct dma_tx_state state;
+   int count;
+
+   dma_sync_single_for_cpu(dma-rxchan-device-dev, dma-rx_addr,
+   dma-rx_size, DMA_FROM_DEVICE);
+
+   dma-rx_running = 0;
+   dmaengine_tx_status(dma-rxchan, dma-rx_cookie, state);
+   dmaengine_terminate_all(dma-rxchan);
+
+   count = dma-rx_size - state.residue;
+
+   tty_insert_flip_string(tty_port, dma-rx_buf, count);
+   p-port.icount.rx += count;
+   if (!error)
+   omap_8250_rx_dma(p, 0);
+
+   tty_flip_buffer_push(tty_port);
+}
+
+static void __dma_rx_complete(void *param)
+{
+   __dma_rx_do_complete(param, false);
+}
+
+static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir)
+{
+   struct uart_8250_dma*dma = p-dma;
+   struct dma_async_tx_descriptor  *desc;
+
+   switch (iir  0x3f) {
+   case UART_IIR_RLSI:
+   /* 8250_core handles errors and break interrupts */
+   if (dma-rx_running) {
+   dmaengine_pause(dma-rxchan);
+   __dma_rx_do_complete(p, true);
+   }
+   return -EIO;
+   case UART_IIR_RX_TIMEOUT:
+   /*
+* If RCVR FIFO trigger level was not reached, complete the
+* transfer and let 8250_core copy the remaining data.
+*/
+   if (dma-rx_running) {
+   dmaengine_pause(dma-rxchan);
+   __dma_rx_do_complete(p, true);
+   }
+   return -ETIMEDOUT;
+   case UART_IIR_RDI:
+   /*
+* The OMAP UART is a special BEAST. If we receive RDI we _have_
+* a DMA transfer programmed but it didn't work. One reason is
+* that we were too slow and there were too many bytes in the
+* FIFO, the UART counted wrong and never kicked the DMA engine
+* to do anything. That means once we receive RDI on OMAP then
+* the DMA won't do anything soon so we have to cancel the DMA
+* transfer and purge the FIFO manually.
+*/
+   if (dma-rx_running) {
+   dmaengine_pause(dma-rxchan);
+   __dma_rx_do_complete(p, true);
+   }
+   return -ETIMEDOUT;
+
+   default:
+   break;
+   }
+
+   if (dma-rx_running)
+   return 0;
+
+   desc = dmaengine_prep_slave_single(dma-rxchan, dma-rx_addr,
+  dma-rx_size, DMA_DEV_TO_MEM,
+  DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+   if (!desc)
+   return -EBUSY;
+
+   dma-rx_running = 1;
+   desc-callback = __dma_rx_complete;
+   desc-callback_param = p;
+
+   dma-rx_cookie = dmaengine_submit(desc);
+
+   dma_sync_single_for_device(dma-rxchan-device-dev, dma-rx_addr,
+  dma-rx_size, DMA_FROM_DEVICE);
+
+   dma_async_issue_pending(dma-rxchan);
+   return 0;
+}
+
 static int omap_8250_tx_dma(struct uart_8250_port *p);
 
 static void omap_8250_dma_tx_complete(void *param)
-- 
2.1.0

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 05/13] tty: serial: 8250_dma: keep own book keeping about RX transfers

2014-09-29 Thread Sebastian Andrzej Siewior
After dmaengine_terminate_all() has been invoked then both DMA drivers
(edma and omap-dma) do not invoke dma_cookie_complete() to mark the
transfer as complete. This dma_cookie_complete() is performed by the
Synopsys DesignWare driver which is probably the only one that is used
by omap8250-dma and hence don't see following problem…
…which is that once a RX transfer has been terminated then following
query of channel status reports DMA_IN_PROGRESS (again: the actual
transfer has been canceled, there is nothing going on anymore).

This means that serial8250_rx_dma() never enqueues another DMA transfer
because it (wrongly) assumes that there is a transer already pending.

Vinod Koul refuses to accept a patch which adds this
dma_cookie_complete() to both drivers and so dmaengine_tx_status() would
report DMA_COMPLETE instead (and behave like the Synopsys DesignWare
driver already does). He argues that I am not allowed to use the cookie
to query the status and that the driver already cleaned everything up after
the invokation of dmaengine_terminate_all().

To end this I add a bookkeeping whether or not a RX-transfer has been
started to the 8250-dma code. It has already been done for the TX side.
*Now* we learn about the RX status based on our bookkeeping and don't
need dmaengine_tx_status() for this anymore.

Cc: vinod.k...@intel.com
Reviewed-by: Tony Lindgren t...@atomide.com
Tested-by: Tony Lindgren t...@atomide.com
Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/tty/serial/8250/8250.h |  1 +
 drivers/tty/serial/8250/8250_dma.c | 10 --
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
index a63d198f8d03..ebab625179d4 100644
--- a/drivers/tty/serial/8250/8250.h
+++ b/drivers/tty/serial/8250/8250.h
@@ -42,6 +42,7 @@ struct uart_8250_dma {
 
unsigned char   tx_running:1;
unsigned char   tx_err: 1;
+   unsigned char   rx_running:1;
 };
 
 struct old_serial_port {
diff --git a/drivers/tty/serial/8250/8250_dma.c 
b/drivers/tty/serial/8250/8250_dma.c
index 69e54abb6e71..db9eda3c12d6 100644
--- a/drivers/tty/serial/8250/8250_dma.c
+++ b/drivers/tty/serial/8250/8250_dma.c
@@ -61,6 +61,7 @@ static void __dma_rx_complete(void *param)
dma_sync_single_for_cpu(dma-rxchan-device-dev, dma-rx_addr,
dma-rx_size, DMA_FROM_DEVICE);
 
+   dma-rx_running = 0;
dmaengine_tx_status(dma-rxchan, dma-rx_cookie, state);
dmaengine_terminate_all(dma-rxchan);
 
@@ -123,10 +124,6 @@ int serial8250_rx_dma(struct uart_8250_port *p, unsigned 
int iir)
 {
struct uart_8250_dma*dma = p-dma;
struct dma_async_tx_descriptor  *desc;
-   struct dma_tx_state state;
-   int dma_status;
-
-   dma_status = dmaengine_tx_status(dma-rxchan, dma-rx_cookie, state);
 
switch (iir  0x3f) {
case UART_IIR_RLSI:
@@ -137,7 +134,7 @@ int serial8250_rx_dma(struct uart_8250_port *p, unsigned 
int iir)
 * If RCVR FIFO trigger level was not reached, complete the
 * transfer and let 8250_core copy the remaining data.
 */
-   if (dma_status == DMA_IN_PROGRESS) {
+   if (dma-rx_running) {
dmaengine_pause(dma-rxchan);
__dma_rx_complete(p);
}
@@ -146,7 +143,7 @@ int serial8250_rx_dma(struct uart_8250_port *p, unsigned 
int iir)
break;
}
 
-   if (dma_status)
+   if (dma-rx_running)
return 0;
 
desc = dmaengine_prep_slave_single(dma-rxchan, dma-rx_addr,
@@ -155,6 +152,7 @@ int serial8250_rx_dma(struct uart_8250_port *p, unsigned 
int iir)
if (!desc)
return -EBUSY;
 
+   dma-rx_running = 1;
desc-callback = __dma_rx_complete;
desc-callback_param = p;
 
-- 
2.1.0

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 07/13] tty: serial: 8250_omap: add custom DMA-TX callback

2014-09-29 Thread Sebastian Andrzej Siewior
This patch provides mostly a copy of serial8250_tx_dma() +
__dma_tx_complete() with the following extensions:

- DMA bug
  At least on AM335x the following problem exists: Even if the TX FIFO is
  empty and a TX transfer is programmed (and started) the UART does not
  trigger the DMA transfer.
  After $TRESHOLD number of bytes have been written to the FIFO manually the
  UART reevaluates the whole situation and decides that now there is enough
  room in the FIFO and so the transfer begins.
  This problem has not been seen on DRA7 or beagle board xm (OMAP3). I am not
  sure if this is UART-IP core specific or DMA engine.

  The workaround is to use a threshold of one byte, program the DMA
  transfer minus one byte and then to put the first byte into the FIFO to
  kick start the transfer.

- support for runtime PM
  RPM is enabled on start_tx(). We can't disable RPM on DMA complete callback
  because there is still data in the FIFO which is being sent. We have to wait
  until the FIFO is empty before we disable it.
  For this to happen we fake a TX sent error and enable THRI. Once the
  FIFO is empty we receive an interrupt and since the TTY-buffer is still
  empty we put RPM via __stop_tx(). Should it been filed then in the
  start_tx() path we should program the DMA transfer and remove the error
  flag and the THRI bit.

Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/tty/serial/8250/8250_omap.c | 144 
 include/uapi/linux/serial_reg.h |   1 +
 2 files changed, 145 insertions(+)

diff --git a/drivers/tty/serial/8250/8250_omap.c 
b/drivers/tty/serial/8250/8250_omap.c
index 2f653c48639d..5f183d197dfa 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -22,6 +22,7 @@
 #include linux/pm_runtime.h
 #include linux/console.h
 #include linux/pm_qos.h
+#include linux/dma-mapping.h
 
 #include 8250.h
 
@@ -29,6 +30,7 @@
 
 #define UART_ERRATA_i202_MDR1_ACCESS   (1  0)
 #define OMAP_UART_WER_HAS_TX_WAKEUP(1  1)
+#define OMAP_DMA_TX_KICK   (1  2)
 
 #define OMAP_UART_FCR_RX_TRIG  6
 #define OMAP_UART_FCR_TX_TRIG  4
@@ -616,6 +618,148 @@ static void omap_8250_unthrottle(struct uart_port *port)
pm_runtime_put_autosuspend(port-dev);
 }
 
+#ifdef CONFIG_SERIAL_8250_DMA
+static int omap_8250_tx_dma(struct uart_8250_port *p);
+
+static void omap_8250_dma_tx_complete(void *param)
+{
+   struct uart_8250_port   *p = param;
+   struct uart_8250_dma*dma = p-dma;
+   struct circ_buf *xmit = p-port.state-xmit;
+   unsigned long   flags;
+   boolen_thri = false;
+
+   dma_sync_single_for_cpu(dma-txchan-device-dev, dma-tx_addr,
+   UART_XMIT_SIZE, DMA_TO_DEVICE);
+
+   spin_lock_irqsave(p-port.lock, flags);
+
+   dma-tx_running = 0;
+
+   xmit-tail += dma-tx_size;
+   xmit-tail = UART_XMIT_SIZE - 1;
+   p-port.icount.tx += dma-tx_size;
+
+   if (uart_circ_chars_pending(xmit)  WAKEUP_CHARS)
+   uart_write_wakeup(p-port);
+
+   if (!uart_circ_empty(xmit)  !uart_tx_stopped(p-port)) {
+   int ret;
+
+   ret = omap_8250_tx_dma(p);
+   if (ret)
+   en_thri = true;
+
+   } else if (p-capabilities  UART_CAP_RPM) {
+   en_thri = true;
+   }
+
+   if (en_thri) {
+   dma-tx_err = 1;
+   p-ier |= UART_IER_THRI;
+   serial_port_out(p-port, UART_IER, p-ier);
+   }
+
+   spin_unlock_irqrestore(p-port.lock, flags);
+}
+
+static int omap_8250_tx_dma(struct uart_8250_port *p)
+{
+   struct uart_8250_dma*dma = p-dma;
+   struct omap8250_priv*priv = p-port.private_data;
+   struct circ_buf *xmit = p-port.state-xmit;
+   struct dma_async_tx_descriptor  *desc;
+   unsigned intskip_byte = 0;
+   int ret;
+
+   if (dma-tx_running)
+   return 0;
+   if (uart_tx_stopped(p-port) || uart_circ_empty(xmit)) {
+
+   /*
+* Even if no data, we need to return an error for the two cases
+* below so serial8250_tx_chars() is invoked and properly clears
+* THRI and/or runtime suspend.
+*/
+   if (dma-tx_err || p-capabilities  UART_CAP_RPM) {
+   ret = -EBUSY;
+   goto err;
+   }
+   if (p-ier  UART_IER_THRI) {
+   p-ier = ~UART_IER_THRI;
+   serial_out(p, UART_IER, p-ier);
+   }
+   return 0;
+   }
+
+   dma-tx_size = CIRC_CNT_TO_END(xmit-head, xmit-tail, UART_XMIT_SIZE);
+   if (priv-habit  OMAP_DMA_TX_KICK) {
+   u8 tx_lvl;
+
+   /*
+* We need to put the first byte into the FIFO in order to start

[PATCH 06/13] tty: serial: 8250: allow to use custom DMA implementation

2014-09-29 Thread Sebastian Andrzej Siewior
The OMAP has a few corner cases where it needs a share of kindness of
affection to do the right thing. Heikki Krogerus suggested that instead
adding the quirks into the default DMA implementation, OMAP could get
its own copy of the function. And Alan suggested the same thing so here
we go.

This patch provides callbacks for custom TX/RX DMA implementation. If
there are not setup / used, then the default (current) implementation is
used.

Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/tty/serial/8250/8250.h  |  3 +++
 drivers/tty/serial/8250/8250_core.c | 11 ---
 drivers/tty/serial/8250/8250_dma.c  |  2 --
 3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
index ebab625179d4..4bb831ab5db0 100644
--- a/drivers/tty/serial/8250/8250.h
+++ b/drivers/tty/serial/8250/8250.h
@@ -16,6 +16,9 @@
 #include linux/dmaengine.h
 
 struct uart_8250_dma {
+   int (*tx_dma)(struct uart_8250_port *p);
+   int (*rx_dma)(struct uart_8250_port *p, unsigned int iir);
+
dma_filter_fn   fn;
void*rx_param;
void*tx_param;
diff --git a/drivers/tty/serial/8250/8250_core.c 
b/drivers/tty/serial/8250/8250_core.c
index ea57c87f8528..93b0799936fd 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -1350,7 +1350,7 @@ static void serial8250_start_tx(struct uart_port *port)
struct uart_8250_port *up = up_to_u8250p(port);
 
serial8250_rpm_get_tx(up);
-   if (up-dma  !serial8250_tx_dma(up)) {
+   if (up-dma  !up-dma-tx_dma(up)) {
return;
} else if (!(up-ier  UART_IER_THRI)) {
up-ier |= UART_IER_THRI;
@@ -1588,7 +1588,7 @@ int serial8250_handle_irq(struct uart_port *port, 
unsigned int iir)
 
if (status  (UART_LSR_DR | UART_LSR_BI)) {
if (up-dma)
-   dma_err = serial8250_rx_dma(up, iir);
+   dma_err = up-dma-rx_dma(up, iir);
 
if (!up-dma || dma_err)
status = serial8250_rx_chars(up, status);
@@ -3624,8 +3624,13 @@ int serial8250_register_8250_port(struct uart_8250_port 
*up)
uart-dl_read = up-dl_read;
if (up-dl_write)
uart-dl_write = up-dl_write;
-   if (up-dma)
+   if (up-dma) {
uart-dma = up-dma;
+   if (!uart-dma-tx_dma)
+   uart-dma-tx_dma = serial8250_tx_dma;
+   if (!uart-dma-rx_dma)
+   uart-dma-rx_dma = serial8250_rx_dma;
+   }
 
if (serial8250_isa_config != NULL)
serial8250_isa_config(0, uart-port,
diff --git a/drivers/tty/serial/8250/8250_dma.c 
b/drivers/tty/serial/8250/8250_dma.c
index db9eda3c12d6..258430b72039 100644
--- a/drivers/tty/serial/8250/8250_dma.c
+++ b/drivers/tty/serial/8250/8250_dma.c
@@ -118,7 +118,6 @@ int serial8250_tx_dma(struct uart_8250_port *p)
dma-tx_err = 1;
return ret;
 }
-EXPORT_SYMBOL_GPL(serial8250_tx_dma);
 
 int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir)
 {
@@ -165,7 +164,6 @@ int serial8250_rx_dma(struct uart_8250_port *p, unsigned 
int iir)
 
return 0;
 }
-EXPORT_SYMBOL_GPL(serial8250_rx_dma);
 
 int serial8250_request_dma(struct uart_8250_port *p)
 {
-- 
2.1.0

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 01/13] tty: serial: 8250: Fix wording in runtime-PM comments

2014-09-29 Thread Sebastian Andrzej Siewior
Frans reworded the two comments with better English for better
understanding. His review hit the mailing list after the patch got
applied so here is an incremental update.

Reported-by: Frans Klaver frans.kla...@xsens.com
Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/tty/serial/8250/8250_core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_core.c 
b/drivers/tty/serial/8250/8250_core.c
index 139f3d2b8aa9..a1904628a2a1 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -557,7 +557,7 @@ static void serial8250_rpm_put(struct uart_8250_port *p)
 }
 
 /*
- * This two wrapper ensure, that enable_runtime_pm_tx() can be called more than
+ * These two wrappers ensure that enable_runtime_pm_tx() can be called more 
than
  * once and disable_runtime_pm_tx() will still disable RPM because the fifo is
  * empty and the HW can idle again.
  */
@@ -1532,7 +1532,7 @@ void serial8250_tx_chars(struct uart_8250_port *up)
DEBUG_INTR(THRE...);
 
/*
-* With RPM enabled, we have to wait once the FIFO is empty before the
+* With RPM enabled, we have to wait until the FIFO is empty before the
 * HW can go idle. So we get here once again with empty FIFO and disable
 * the interrupt and RPM in __stop_tx()
 */
-- 
2.1.0

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 04/13] tty: serial: 8250_dma: handle error on TX submit

2014-09-29 Thread Sebastian Andrzej Siewior
Right now it is possible that serial8250_tx_dma() fails and returns
-EBUSY. The caller (serial8250_start_tx()) will then enable
UART_IER_THRI which will generate an interrupt once the TX FIFO is
empty.
In serial8250_handle_irq() nothing will happen because up-dma is set
and so serial8250_tx_chars() won't be invoked. We end up with plenty of
interrupts and some too much work for irq output.

This patch introduces dma_tx_err in struct uart_8250_port to signal that
the last invocation of serial8250_tx_dma() failed so we can fill the TX
FIFO manually. Should the next invocation of serial8250_start_tx()
succeed then the dma_tx_err flag along with the THRI bit is removed and
DMA only usage may continue.

Reviewed-by: Tony Lindgren t...@atomide.com
Tested-by: Tony Lindgren t...@atomide.com
Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/tty/serial/8250/8250.h  |  1 +
 drivers/tty/serial/8250/8250_core.c |  3 ++-
 drivers/tty/serial/8250/8250_dma.c  | 30 +-
 3 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
index 1bcb4b2141a6..a63d198f8d03 100644
--- a/drivers/tty/serial/8250/8250.h
+++ b/drivers/tty/serial/8250/8250.h
@@ -41,6 +41,7 @@ struct uart_8250_dma {
size_t  tx_size;
 
unsigned char   tx_running:1;
+   unsigned char   tx_err: 1;
 };
 
 struct old_serial_port {
diff --git a/drivers/tty/serial/8250/8250_core.c 
b/drivers/tty/serial/8250/8250_core.c
index 159b72471622..ea57c87f8528 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -1594,7 +1594,8 @@ int serial8250_handle_irq(struct uart_port *port, 
unsigned int iir)
status = serial8250_rx_chars(up, status);
}
serial8250_modem_status(up);
-   if (!up-dma  (status  UART_LSR_THRE))
+   if ((!up-dma || (up-dma  up-dma-tx_err)) 
+   (status  UART_LSR_THRE))
serial8250_tx_chars(up);
 
spin_unlock_irqrestore(port-lock, flags);
diff --git a/drivers/tty/serial/8250/8250_dma.c 
b/drivers/tty/serial/8250/8250_dma.c
index 148ffe4c232f..69e54abb6e71 100644
--- a/drivers/tty/serial/8250/8250_dma.c
+++ b/drivers/tty/serial/8250/8250_dma.c
@@ -36,8 +36,16 @@ static void __dma_tx_complete(void *param)
if (uart_circ_chars_pending(xmit)  WAKEUP_CHARS)
uart_write_wakeup(p-port);
 
-   if (!uart_circ_empty(xmit)  !uart_tx_stopped(p-port))
-   serial8250_tx_dma(p);
+   if (!uart_circ_empty(xmit)  !uart_tx_stopped(p-port)) {
+   int ret;
+
+   ret = serial8250_tx_dma(p);
+   if (ret) {
+   dma-tx_err = 1;
+   p-ier |= UART_IER_THRI;
+   serial_port_out(p-port, UART_IER, p-ier);
+   }
+   }
 
spin_unlock_irqrestore(p-port.lock, flags);
 }
@@ -69,6 +77,7 @@ int serial8250_tx_dma(struct uart_8250_port *p)
struct uart_8250_dma*dma = p-dma;
struct circ_buf *xmit = p-port.state-xmit;
struct dma_async_tx_descriptor  *desc;
+   int ret;
 
if (uart_tx_stopped(p-port) || dma-tx_running ||
uart_circ_empty(xmit))
@@ -80,8 +89,10 @@ int serial8250_tx_dma(struct uart_8250_port *p)
   dma-tx_addr + xmit-tail,
   dma-tx_size, DMA_MEM_TO_DEV,
   DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-   if (!desc)
-   return -EBUSY;
+   if (!desc) {
+   ret = -EBUSY;
+   goto err;
+   }
 
dma-tx_running = 1;
 
@@ -94,8 +105,17 @@ int serial8250_tx_dma(struct uart_8250_port *p)
   UART_XMIT_SIZE, DMA_TO_DEVICE);
 
dma_async_issue_pending(dma-txchan);
-
+   if (dma-tx_err) {
+   dma-tx_err = 0;
+   if (p-ier  UART_IER_THRI) {
+   p-ier = ~UART_IER_THRI;
+   serial_out(p, UART_IER, p-ier);
+   }
+   }
return 0;
+err:
+   dma-tx_err = 1;
+   return ret;
 }
 EXPORT_SYMBOL_GPL(serial8250_tx_dma);
 
-- 
2.1.0

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 03/13] tty: serial: Add 8250-core based omap driver

2014-09-29 Thread Sebastian Andrzej Siewior
This patch provides a 8250-core based UART driver for the internal OMAP
UART. The long term goal is to provide the same functionality as the
current OMAP uart driver and DMA support.
I tried to merge omap-serial code together with the 8250-core code.
There should should be hardly a noticable difference. The trigger levels
are different compared to omap-serial:
- omap serial
  TX: Interrupt comes after TX FIFO has room for 16 bytes.
  TX of 4096 bytes in one go results in 256 interrupts

  RX: Interrupt comes after there is on byte in the FIFO.
  RX of 4096 bytes results in 4096 interrupts.

- this driver
  TX: Interrupt comes once the TX FIFO is empty.
  TX of 4096 bytes results in 65 interrupts. That means there will
  be gaps on the line while the driver reloads the FIFO.

  RX: Interrupt comes once there are 48 bytes in the FIFO or less over
  longer time frame. We have
  1 / 11520 * 10^3 * 16 = 1.38… ms
  1.38ms to react and purge the FIFO on 115200,8N1. Since the other
  driver fired after each byte it had ~5.47ms time to react. This
  _may_ cause problems if one relies on no missing bytes and has no
  flow control. On the other hand we get only 85 interrupts for the
  same amount of data.

It has been only tested as console UART on am335x-evm, dra7-evm and
beagle bone. I also did some longer raw-transfers to meassure the load.

The device name is ttyS based instead of ttyO. If a ttyO based node name
is required please ask udev for it. If both driver are activated (this
and omap-serial) then this serial driver will take control over the
device due to the link order

v9…v10:
- Tony noticed that omap3 won't show anything after waking up
  from core off. In v9 I reworked the register restore and set
  IER to 0 by accident. This went unnoticed because start_tx
  usually sets ier (either due to DMA bug or due to TX-complete
  IRQ).
- dropped EFR and SLEEP from capabilities. We do have both but
  nobody should touch it. We already handle SLEEP ourself.
- make the private copy of the registers (like EFR) u8 instead
  u32
- drop MDR1  DL[ML] reset in restore registers. Does not look
  required it is set to the required value later.
- update MDR1  SCR only if changed.
- set MDR1 as the last thing. The errata says that we should
  setup everything before MDR1 set.
- avoid div by 0 in omap_8250_get_divisor() if baud rate gets
  very large (Frans Klaver fixed the same thing omap-serial)
- drop is in early stage from Kconfig.
v8…v9:
- less on a file seems to hang the am335x after a while. I
  believe I introduce this bug a while ago since I can reproduce
  this prior to v8. Fixed by redoing the omap8250_restore_regs()
v7…v8:
- redo the register write. There is now one function for that
  which is used from set_termios() and runtime-resume.
- drop PORT_OMAP_16750 and move the setup to the omap file. We
  have our own set termios function anyway (Heikki Krogerus)
- use MEM instead of MEM32. TRM of AM/DM37x says that 32bit
  access on THR might result in data abort. We only need 32bit
  access in the errata function which is before we use 8250's
  read function so it doesn't matter.
v4…v7:
- change trigger levels after some tests with raw transfers.
v3…v4:
- drop RS485 support
- wire up -throttle / -unthrottle
v2…v3:
- wire up startup  shutdown for wakeup-irq handling.
- RS485 handling (well the core does).

v1…v2:
- added runtime PM. Could somebody could please double check
  this?
- added omap_8250_set_termios()

Reviewed-by: Tony Lindgren t...@atomide.com
Tested-by: Tony Lindgren t...@atomide.com
Tested-by: Frans Klaver frans.kla...@xsens.com
Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/tty/serial/8250/8250_omap.c | 914 
 drivers/tty/serial/8250/Kconfig |   9 +
 drivers/tty/serial/8250/Makefile|   1 +
 3 files changed, 924 insertions(+)
 create mode 100644 drivers/tty/serial/8250/8250_omap.c

diff --git a/drivers/tty/serial/8250/8250_omap.c 
b/drivers/tty/serial/8250/8250_omap.c
new file mode 100644
index ..2f653c48639d
--- /dev/null
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -0,0 +1,914 @@
+/*
+ * 8250-core based driver for the OMAP internal UART
+ *
+ * based on omap-serial.c, Copyright (C) 2010 Texas Instruments.
+ *
+ * Copyright (C) 2014 Sebastian Andrzej Siewior
+ *
+ */
+
+#include linux/device.h
+#include linux/io.h
+#include linux/module.h
+#include linux/serial_8250.h
+#include linux/serial_core.h
+#include linux/serial_reg.h
+#include linux/platform_device.h
+#include linux/slab.h
+#include linux/of.h
+#include linux/of_gpio.h
+#include linux/of_irq.h
+#include linux/delay.h
+#include

[PATCH 02/13] tty: serial: 8250: make serial8250_console_setup() non _init

2014-09-29 Thread Sebastian Andrzej Siewior
if I boot with console=ttyS0 and the omap driver is module I end up with

| console [ttyS0] disabled
| omap8250 44e09000.serial: ttyS0 at MMIO 0x44e09000 (irq = 88, base_baud = 
300) is a 8250
| Unable to handle kernel paging request at virtual address c07a9de0
| Modules linked in: 8250_omap(+)
| CPU: 0 PID: 908 Comm: modprobe Not tainted 3.17.0-rc5+ #1593
| PC is at serial8250_console_setup+0x0/0xc8
| LR is at register_console+0x13c/0x3a4
| [c0078788] (register_console) from [c02d0340] 
(uart_add_one_port+0x3cc/0x420)
| [c02d0340] (uart_add_one_port) from [c02d38a4] 
(serial8250_register_8250_port+0x298/0x39c)
| [c02d38a4] (serial8250_register_8250_port) from [bf006274] 
(omap8250_probe+0x218/0x3dc [8250_omap])
| [bf006274] (omap8250_probe [8250_omap]) from [c02e3424] 
(platform_drv_probe+0x2c/0x5c)
| [c02e3424] (platform_drv_probe) from [c02e1eac] 
(driver_probe_device+0x104/0x228)
…
| [c009fa48] (SyS_init_module) from [c000e6e0] (ret_fast_syscall+0x0/0x30)
| Code: 7823603b f8314620 051b3013 491ed416 (44792204)

because serial8250_console_setup() is already gone.

Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/tty/serial/8250/8250_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/8250/8250_core.c 
b/drivers/tty/serial/8250/8250_core.c
index a1904628a2a1..159b72471622 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -3237,7 +3237,7 @@ serial8250_console_write(struct console *co, const char 
*s, unsigned int count)
serial8250_rpm_put(up);
 }
 
-static int __init serial8250_console_setup(struct console *co, char *options)
+static int serial8250_console_setup(struct console *co, char *options)
 {
struct uart_port *port;
int baud = 9600;
-- 
2.1.0

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 11/13] arm: dts: dra7: add DMA properties for UART

2014-09-29 Thread Sebastian Andrzej Siewior
Cc: devicet...@vger.kernel.org
Reviewed-by: Tony Lindgren t...@atomide.com
Tested-by: Tony Lindgren t...@atomide.com
Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 arch/arm/boot/dts/dra7.dtsi | 12 
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index d678152db4cb..f273e3811f75 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -332,6 +332,8 @@
ti,hwmods = uart1;
clock-frequency = 4800;
status = disabled;
+   dmas = sdma 49, sdma 50;
+   dma-names = tx, rx;
};
 
uart2: serial@4806c000 {
@@ -341,6 +343,8 @@
ti,hwmods = uart2;
clock-frequency = 4800;
status = disabled;
+   dmas = sdma 51, sdma 52;
+   dma-names = tx, rx;
};
 
uart3: serial@4802 {
@@ -350,6 +354,8 @@
ti,hwmods = uart3;
clock-frequency = 4800;
status = disabled;
+   dmas = sdma 53, sdma 54;
+   dma-names = tx, rx;
};
 
uart4: serial@4806e000 {
@@ -359,6 +365,8 @@
ti,hwmods = uart4;
clock-frequency = 4800;
 status = disabled;
+   dmas = sdma 55, sdma 56;
+   dma-names = tx, rx;
};
 
uart5: serial@48066000 {
@@ -368,6 +376,8 @@
ti,hwmods = uart5;
clock-frequency = 4800;
status = disabled;
+   dmas = sdma 63, sdma 64;
+   dma-names = tx, rx;
};
 
uart6: serial@48068000 {
@@ -377,6 +387,8 @@
ti,hwmods = uart6;
clock-frequency = 4800;
status = disabled;
+   dmas = sdma 79, sdma 80;
+   dma-names = tx, rx;
};
 
uart7: serial@4842 {
-- 
2.1.0

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 12/13] tty: serial: 8250: omap: add custom irq handling

2014-09-29 Thread Sebastian Andrzej Siewior
We have (or will have) custom DMA callbacks in the omap driver due to
the different behaviour in the RX and TX case. To make this work
we need a few changes in the IRQ handler to invoke the rx_handler again
after the manual mode or retry the tx_handler again before falling
back to the manual mode.

Heikki didn't want to see the extra hacks in the generic / default irq
handler and Peter wasn't too happy about an OMAP-only IRQ handler. The
way I planned it is to use this extra IRQ routine only in DMA case. If
Peter dislike this approach then I hope Heikki doesn't block changes in
the default IRQ handler :)

Cc: Heikki Krogerus heikki.kroge...@linux.intel.com
Cc: Peter Hurley pe...@hurleysoftware.com
Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/tty/serial/8250/8250.h  |  2 ++
 drivers/tty/serial/8250/8250_core.c |  6 ++--
 drivers/tty/serial/8250/8250_omap.c | 55 +
 3 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
index 4bb831ab5db0..28097a912c10 100644
--- a/drivers/tty/serial/8250/8250.h
+++ b/drivers/tty/serial/8250/8250.h
@@ -119,6 +119,8 @@ static inline void serial_dl_write(struct uart_8250_port 
*up, int value)
 }
 
 struct uart_8250_port *serial8250_get_port(int line);
+void serial8250_rpm_get(struct uart_8250_port *p);
+void serial8250_rpm_put(struct uart_8250_port *p);
 
 #if defined(__alpha__)  !defined(CONFIG_PCI)
 /*
diff --git a/drivers/tty/serial/8250/8250_core.c 
b/drivers/tty/serial/8250/8250_core.c
index 93b0799936fd..6a3b4399bf3c 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -541,20 +541,22 @@ void serial8250_clear_and_reinit_fifos(struct 
uart_8250_port *p)
 }
 EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos);
 
-static void serial8250_rpm_get(struct uart_8250_port *p)
+void serial8250_rpm_get(struct uart_8250_port *p)
 {
if (!(p-capabilities  UART_CAP_RPM))
return;
pm_runtime_get_sync(p-port.dev);
 }
+EXPORT_SYMBOL_GPL(serial8250_rpm_get);
 
-static void serial8250_rpm_put(struct uart_8250_port *p)
+void serial8250_rpm_put(struct uart_8250_port *p)
 {
if (!(p-capabilities  UART_CAP_RPM))
return;
pm_runtime_mark_last_busy(p-port.dev);
pm_runtime_put_autosuspend(p-port.dev);
 }
+EXPORT_SYMBOL_GPL(serial8250_rpm_put);
 
 /*
  * These two wrappers ensure that enable_runtime_pm_tx() can be called more 
than
diff --git a/drivers/tty/serial/8250/8250_omap.c 
b/drivers/tty/serial/8250/8250_omap.c
index 1659858e595a..6500547f8fda 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -13,6 +13,7 @@
 #include linux/serial_8250.h
 #include linux/serial_core.h
 #include linux/serial_reg.h
+#include linux/tty_flip.h
 #include linux/platform_device.h
 #include linux/slab.h
 #include linux/of.h
@@ -854,6 +855,60 @@ static int omap_8250_tx_dma(struct uart_8250_port *p)
return ret;
 }
 
+/*
+ * This is mostly serial8250_handle_irq(). We have a slightly different DMA
+ * hoook for RX/TX and need different logic for them in the ISR. Therefore we
+ * use the default routine in the non-DMA case and this one for with DMA.
+ */
+static int omap_8250_dma_handle_irq(struct uart_port *port)
+{
+   struct uart_8250_port *up = up_to_u8250p(port);
+   unsigned char status;
+   unsigned long flags;
+   u8 iir;
+   int dma_err = 0;
+
+   serial8250_rpm_get(up);
+
+   iir = serial_port_in(port, UART_IIR);
+   if (iir  UART_IIR_NO_INT) {
+   serial8250_rpm_put(up);
+   return 0;
+   }
+
+   spin_lock_irqsave(port-lock, flags);
+
+   status = serial_port_in(port, UART_LSR);
+
+   if (status  (UART_LSR_DR | UART_LSR_BI)) {
+
+   dma_err = omap_8250_rx_dma(up, iir);
+   if (dma_err) {
+   status = serial8250_rx_chars(up, status);
+   omap_8250_rx_dma(up, 0);
+   }
+   }
+   serial8250_modem_status(up);
+   if (status  UART_LSR_THRE  up-dma-tx_err) {
+   if (uart_tx_stopped(up-port) ||
+   uart_circ_empty(up-port.state-xmit)) {
+   up-dma-tx_err = 0;
+   serial8250_tx_chars(up);
+   } else  {
+   /*
+* try again due to an earlier failer which
+* might have been resolved by now.
+*/
+   dma_err = omap_8250_tx_dma(up);
+   if (dma_err)
+   serial8250_tx_chars(up);
+   }
+   }
+
+   spin_unlock_irqrestore(port-lock, flags);
+   serial8250_rpm_put(up);
+   return 1;
+}
 #endif
 
 static int omap8250_probe(struct platform_device *pdev)
-- 
2.1.0

--
To unsubscribe from this list: send the line

[PATCH 13/13] tty: serial: 8250: omap: add dma support

2014-09-29 Thread Sebastian Andrzej Siewior
This patch adds the required pieces to 8250-OMAP UART driver for DMA
support. The TX burst size is set to 1 so we can send an arbitrary
amount of bytes.

The RX burst is currently set to 48 which means we receive an DMA
interrupt every 48 bytes and have to reprogram everything. Less bytes in
the RX-FIFO mean that no DMA transfer will happen and the UART will send a
RX-timeout _or_ RDI event at which point the FIFO will be manually purged.
There is a workaround for TX-DMA on AM33xx where we put the first byte
into the FIFO to kick start the DMA process. Haven't seen this problem on
OMAP36xx (beagle board xm) or DRA7xx.

On AM375x there is Usage Note 2.7: UART: Cannot Acknowledge Idle
Requests in Smartidle Mode When Configured for DMA Operations in the
errata document. This problem persists even after disabling DMA in the
UART and will be addressed in the HWMOD.

v10:
- delay update_registers() from set_termios() until TX-DMA is
  done. It has been reported / proved that invoking
  update_registers() while TX-DMA is in progress may stall the
  DMA operation and it won't finish.
- use the new omap DMA-TX-RX hooks and DMA only interrupt
  routine.

Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 drivers/tty/serial/8250/8250_omap.c | 71 +
 1 file changed, 71 insertions(+)

diff --git a/drivers/tty/serial/8250/8250_omap.c 
b/drivers/tty/serial/8250/8250_omap.c
index 6500547f8fda..57a8b1241b85 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -88,6 +88,7 @@ struct omap8250_priv {
u8 wer;
u8 xon;
u8 xoff;
+   u8 delayed_restore;
u16 quot;
 
bool is_suspending;
@@ -211,6 +212,18 @@ static void omap8250_update_scr(struct uart_8250_port *up,
 static void omap8250_restore_regs(struct uart_8250_port *up)
 {
struct omap8250_priv *priv = up-port.private_data;
+   struct uart_8250_dma*dma = up-dma;
+
+   if (dma  dma-tx_running) {
+   /*
+* TCSANOW requests the change to occur immediately however if
+* we have a TX-DMA operation in progress then it has been
+* observed that it might stall and never complete. Therefore we
+* delay DMA completes to prevent this hang from happen.
+*/
+   priv-delayed_restore = 1;
+   return;
+   }
 
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
serial_out(up, UART_EFR, UART_EFR_ECB);
@@ -375,6 +388,10 @@ static void omap_8250_set_termios(struct uart_port *port,
priv-scr = OMAP_UART_SCR_RX_TRIG_GRANU1_MASK | OMAP_UART_SCR_TX_EMPTY |
OMAP_UART_SCR_TX_TRIG_GRANU1_MASK;
 
+   if (up-dma)
+   priv-scr |= OMAP_UART_SCR_DMAMODE_1 |
+   OMAP_UART_SCR_DMAMODE_CTL;
+
priv-xon = termios-c_cc[VSTART];
priv-xoff = termios-c_cc[VSTOP];
 
@@ -554,6 +571,9 @@ static int omap_8250_startup(struct uart_port *port)
priv-wer |= OMAP_UART_TX_WAKEUP_EN;
serial_out(up, UART_OMAP_WER, priv-wer);
 
+   if (up-dma)
+   up-dma-rx_dma(up, 0);
+
pm_runtime_mark_last_busy(port-dev);
pm_runtime_put_autosuspend(port-dev);
return 0;
@@ -572,6 +592,8 @@ static void omap_8250_shutdown(struct uart_port *port)
struct omap8250_priv *priv = port-private_data;
 
flush_work(priv-qos_work);
+   if (up-dma)
+   up-dma-rx_dma(up, UART_IIR_RX_TIMEOUT);
 
pm_runtime_get_sync(port-dev);
 
@@ -725,6 +747,7 @@ static void omap_8250_dma_tx_complete(void *param)
struct circ_buf *xmit = p-port.state-xmit;
unsigned long   flags;
boolen_thri = false;
+   struct omap8250_priv*priv = p-port.private_data;
 
dma_sync_single_for_cpu(dma-txchan-device-dev, dma-tx_addr,
UART_XMIT_SIZE, DMA_TO_DEVICE);
@@ -737,6 +760,11 @@ static void omap_8250_dma_tx_complete(void *param)
xmit-tail = UART_XMIT_SIZE - 1;
p-port.icount.tx += dma-tx_size;
 
+   if (priv-delayed_restore) {
+   priv-delayed_restore = 0;
+   omap8250_restore_regs(p);
+   }
+
if (uart_circ_chars_pending(xmit)  WAKEUP_CHARS)
uart_write_wakeup(p-port);
 
@@ -909,6 +937,18 @@ static int omap_8250_dma_handle_irq(struct uart_port *port)
serial8250_rpm_put(up);
return 1;
 }
+
+static bool the_no_dma_filter_fn(struct dma_chan *chan, void *param)
+{
+   return false;
+}
+
+#else
+
+static inline int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir)
+{
+   return -EINVAL;
+}
 #endif
 
 static int omap8250_probe(struct platform_device *pdev)
@@ -1010,6 +1050,32 @@ static int omap8250_probe(struct platform_device *pdev)
pm_runtime_get_sync(pdev-dev

[PATCH 10/13] arm: dts: am33xx: add DMA properties for UART

2014-09-29 Thread Sebastian Andrzej Siewior
Cc: devicet...@vger.kernel.org
Reviewed-by: Tony Lindgren t...@atomide.com
Tested-by: Tony Lindgren t...@atomide.com
Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de
---
 arch/arm/boot/dts/am33xx.dtsi | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index 3a0a161342ba..078a760a4a21 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -200,6 +200,8 @@
reg = 0x44e09000 0x2000;
interrupts = 72;
status = disabled;
+   dmas = edma 26, edma 27;
+   dma-names = tx, rx;
};
 
uart1: serial@48022000 {
@@ -209,6 +211,8 @@
reg = 0x48022000 0x2000;
interrupts = 73;
status = disabled;
+   dmas = edma 28, edma 29;
+   dma-names = tx, rx;
};
 
uart2: serial@48024000 {
@@ -218,6 +222,8 @@
reg = 0x48024000 0x2000;
interrupts = 74;
status = disabled;
+   dmas = edma 30, edma 31;
+   dma-names = tx, rx;
};
 
uart3: serial@481a6000 {
-- 
2.1.0

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 09/16] tty: serial: 8250_dma: Add a TX trigger workaround for AM33xx

2014-09-25 Thread Sebastian Andrzej Siewior
* Heikki Krogerus | 2014-09-22 10:46:05 [+0300]:

Well, there are no other SoCs at the moment that would need it, and
it's actually possible that there never will be. So yes, just handle
that also in the omap specific code.

Okay. So let me move the irq routine and the workarounds into omap then.

Thanks,


Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 09/16] tty: serial: 8250_dma: Add a TX trigger workaround for AM33xx

2014-09-25 Thread Sebastian Andrzej Siewior
* Sebastian Andrzej Siewior | 2014-09-24 09:53:46 [+0200]:

* Peter Hurley | 2014-09-23 13:03:51 [-0400]:

But DMA is cheating if the UART driver's tx_empty() method is saying the
transmitter is empty while TX DMA is still running.
This shouldn't be the case. But I will check this once I able to.

I added 

|#define BOTH_EMPTY  (UART_LSR_TEMT | UART_LSR_THRE)
|trace_printk(delay %d\n, (lsr  BOTH_EMPTY) == BOTH_EMPTY ? 1 : 0);

in my set_termios() and the trace shows
|  vi-949   [000] d...70.477002: omap8250_restore_regs: delay 
0

so no, it does not wait until TX FIFO is empty. It looks like it uses
TCSANOW instead of TCSADRAIN. And since this looks legal I will delay
it until TX-DMA is complete because it is known to stall the DMA operation.

Regards,
Peter Hurley

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 09/16] tty: serial: 8250_dma: Add a TX trigger workaround for AM33xx

2014-09-25 Thread Sebastian Andrzej Siewior
* Peter Hurley | 2014-09-25 07:31:32 [-0400]:

I just verified that GNU readline6 uses ioctl(TCSETSW, ...) to do the 
set_termios
(which is the ioctl that libc should use for tcsetattr(TCSADRAIN)).

Maybe this userspace is using a readline()-alike that has a bug by not using 
the
correct tcsetattr() action?

set_termios() has an opt argument. While doing :n in vi I see two invocations
with opt == 8 which stands for TCSETS.
browsing through vi's code I stumbled upon 

|static void rawmode(void)
|{
…
|tcsetattr_stdin_TCSANOW(term_vi);
|}
|int FAST_FUNC tcsetattr_stdin_TCSANOW(const struct termios *tp)
|{
|return tcsetattr(STDIN_FILENO, TCSANOW, tp);
|}

and this is probably what you meant. There is also
| static void cookmode(void)
| {
| fflush_all();
| tcsetattr_stdin_TCSANOW(term_orig);
| }

However I don't see __tty_perform_flush() in kernel invoked.

Or maybe the glibc-equivalent has the bug, and tcsetattr(TCSADRAIN) is not 
using
ioctl(TCSETSW)?

libc is GNU C Library 2.20. 

Regards,
Peter Hurley

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 09/16] tty: serial: 8250_dma: Add a TX trigger workaround for AM33xx

2014-09-25 Thread Sebastian Andrzej Siewior
* Frans Klaver | 2014-09-22 11:28:54 [+0200]:

I guess then we'd still have to answer the question why the yocto build
calls set_termios() so often, but that's not on you then. Did you notice
it even changing settings? We might want to fix this even if the kernel
should be able to cope.

could you please test uart_v10_pre3? I dropped a few register sets and
delayed the register update until TX-DMA is complete. I am traveling
currently and have only my boneblack and it passes my limited testing.
If it solves your problems, too then I would address Heikki's latest
comments and prepare the final v10 (and I hope I didn't break beagle
board in between).

Thanks again,
Frans

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] ARM: edma: unconditionally ack the error interrupt

2014-09-25 Thread Sebastian Andrzej Siewior
* Peter Ujfalusi | 2014-09-20 00:29:01 [+0300]:

mask 800 means URXEVT0 (UART0 rx), 400 is UTXEVT0 (UART0 tx) events.
But it is clear that my theory was not even close to what's going on.
Do you have some tool which can be used to reproduce this issue?

The latest uart patch set is at
git://git.breakpoint.cc/bigeasy/linux.git uart_v10_pre3

and the latest one I tested and saw the issue was uart_v9.
The test case is, boot, login via serial, do less file and press space
for a while to get less to scroll the file.
The error counter increment after a while.

 Fun fact: If I remove the write access to EDMA_EMCR register (the write
 access after the read out) then I haven't seen [1] a single error interrupt
 beeing unhandled out of 9. The former has three out of eight.

Hrm, this is interesting. Am I interpret it right:
if you clear the event missed register's bit for the event, you will receive
the interrupt, but there if you read the EMR bits, they are all 0.
usually yes. Sometimes the EMR bits are set.

if you do not clear the bit in the event missed register (even if it is not
set) you will not receive the error interrupt. Right?
no, the error interrupt comes but the EMR is always non-zero.

I think this can be due to the fact how edma (if I read the TRM right) works:
the error irq will be asserted if there is a transition from 0 to 1 in one of
the error registers. If you had error and you did not cleared the error bit,
the next error will not going to cause another transition so no interrupt will
be triggered. Having said that, there should be at least one error interrupt
coming since at some point we should have had 0 - 1 transition...

Can you print out also the EDMA_EMR at places you were printing EDMA_EMCR?

So I had a bug where I changed the baud + DMA bits in the UART while
there was a DMA-TX in progress. Now I dropped this in v10_pre3 and it
seems not to trigger anymore.

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 09/16] tty: serial: 8250_dma: Add a TX trigger workaround for AM33xx

2014-09-24 Thread Sebastian Andrzej Siewior
* Peter Hurley | 2014-09-23 13:03:51 [-0400]:

readline() does this; it 'saves' the caller's termios, sets termios
for non-canonical reads, reads one char, and 'restores' the caller's
termios.

interresting, thanks. I guess I would need to opimize this a little so
the baudrate isn't going to 0 and back to the requested baudrate.

The tty core calls the driver's wait_until_sent() method before changing
the termios (if TCSADRAIN is used for tcsetattr(), which I think for readline()
it does).

The interresting difference is that when I take the yocto RFS and chroot
into from Debian then I don't this problem. Not sure if this is really
readline or something else…

But DMA is cheating if the UART driver's tx_empty() method is saying the
transmitter is empty while TX DMA is still running.
This shouldn't be the case. But I will check this once I able to.
After TX-DMA is done, xmit-tail is updated and port.icount.tx is
incremented. At this time the TX FIFO is still full (up to 64 bytes) and
I set UART_IER_THRI to wait until TX FIFO is empty so I can disable
runtime-pm. Therefore I would assume LSR does not say BOTH_EMPTY until
the FIFO is empty.

Regards,
Peter Hurley

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 09/16] tty: serial: 8250_dma: Add a TX trigger workaround for AM33xx

2014-09-24 Thread Sebastian Andrzej Siewior
* Frans Klaver | 2014-09-22 11:28:54 [+0200]:


Wow, thanks for your work here. This does indeed sound hard to trap.

I guess then we'd still have to answer the question why the yocto build
calls set_termios() so often, but that's not on you then. Did you notice
it even changing settings? We might want to fix this even if the kernel
should be able to cope.

Yeah. I don't care if this is yocto's fault or not. If it is possible to
stop the DMA transfer from userland with whatever method then it needs to
be fixed in kernel so that this does happen.

Thanks again,
Frans

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 09/16] tty: serial: 8250_dma: Add a TX trigger workaround for AM33xx

2014-09-21 Thread Sebastian Andrzej Siewior
* Frans Klaver | 2014-09-17 12:28:12 [+0200]:

- Bone Black: Yocto poky, core-image-minimal
  Login, less file locks up, doesn't show anything. I can exit using
  Ctrl-C.

So I have the same with my and the serial-omap driver. No difference
here. The trace looks like this:
|   idle-0 [000] d.h.   444.393585: serial8250_handle_irq: iir cc 
lsr 61
|   idle-0 [000] d.h.   444.393605: serial8250_rx_chars: get 0d
received the enter key

|   idle-0 [000] d.h.   444.393609: serial8250_rx_chars: insert d 
lsr 61
|   idle-0 [000] d.h.   444.393614: uart_insert_char: 1
|   idle-0 [000] d.h.   444.393617: uart_insert_char: 2
|   idle-0 [000] dnh.   444.393636: serial8250_tx_chars: empty
|  kworker/0:2-753   [000] d...   444.393686: serial8250_start_tx: empty?1
|  kworker/0:2-753   [000] d.h.   444.393699: serial8250_handle_irq: iir c2 
lsr 60
|  kworker/0:2-753   [000] d.h.   444.393705: serial8250_tx_chars: empty
|   sh-1042  [000] d...   444.393822: serial8250_start_tx: empty?1
|   sh-1042  [000] d.h.   444.393836: serial8250_handle_irq: iir c2 
lsr 60
|   sh-1042  [000] d.h.   444.393842: serial8250_tx_chars: empty
|   sh-1042  [000] d...   444.393855: serial8250_start_tx: empty?0
|   sh-1042  [000] d.h.   444.393863: serial8250_handle_irq: iir c2 
lsr 60
|   sh-1042  [000] d.h.   444.393867: serial8250_tx_chars: put 0d
|   sh-1042  [000] d.h.   444.393871: serial8250_tx_chars: put 0a

shell responded with \r\n which I see and then

|   sh-1042  [000] d.h.   444.394057: serial8250_handle_irq: iir c2 
lsr 60
|   sh-1042  [000] d.h.   444.394065: serial8250_tx_chars: empty

nothing more. less isn't sending data for some reason. Exactly the same
thing happens in a Debian environment except that it continues:
…
| bash-2468  [000] d.h.99.657899: serial8250_tx_chars: put 0a
| bash-2468  [000] d.h.99.658089: serial8250_handle_irq: iir c2 
lsr 60
| bash-2468  [000] d.h.99.658095: serial8250_tx_chars: empty
=
| less-2474  [000] d...99.696038: serial8250_start_tx: empty?0
| less-2474  [000] d.h.99.696069: serial8250_handle_irq: iir c2 
lsr 60
| less-2474  [000] d.h.99.696078: serial8250_tx_chars: put 1b
| less-2474  [000] d.h.99.696082: serial8250_tx_chars: put 5b
| less-2474  [000] d.h.99.696085: serial8250_tx_chars: put 3f
| less-2474  [000] d.h.99.696087: serial8250_tx_chars: put 31

It has to be something about the environment. Booting Debian and chroot
into this RFS and less works perfectly. But since it behaves like that
with both drivers, I guess the problem is somewhere else…

  vi runs normally, only occupies part of the total screen estate in
  minicom. After quitting, a weird character shows up (typically I see
  ÿ there), but minicom can use the rest of the screen estate again.
  If we disregard the odd character, this is much like the behavior we
  have on the omap-serial driver.
- Custom board: Yocto poky, custom image
  Login, less file locks up, showing only ÿ in the top left corner
  of the screen. Can get out of there by having something dumped through
  /dev/kmsg.

I managed to run into something like that with vi on dra7 and with
little more patience on am335x as well by vi * and then :n.

This gets fixed indeed by writing. Hours of debugging and a lot of hair
less later: the yocto RFS calls set_termios quite a lot. This includes
changing the baudrate (not by yocto but the driver sets it to 0 and then
to the requested one) and this seems to be responsible for the bad
bytes. I haven't figured out yet I don't see this with omap-serial.
Even worse: If this (set_termios()) happens while the DMA is still
active then it might stall it. A write into the FIFO seems to fix it and
this is where your echo /dev/kmsg fixes things.
If I delay the restore_registers part of set_termios() until TX-DMA is
complete then it seems that the TX-DMA stall does not tall anymore.

Having it summed up like this, I think we're back at ncurses and its
interaction with the serial driver.

Hope this helps. Thanks for your effort so far,
Frans

Sebastian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


  1   2   3   4   5   >