* Re: New serial card development
From: Matt Schulte @ 2012-10-23 16:31 UTC (permalink / raw)
To: Theodore Ts'o; +Cc: Alan Cox, linux-serial
In-Reply-To: <CAJp1Oe6ekkaZ29iwJ91VXwM_CSL6Z0_KEaqVQTa1XMzTB5niEQ@mail.gmail.com>
On Tue, Oct 23, 2012 at 11:27 AM, Matt Schulte
<matts@commtech-fastcom.com> wrote:
> On Fri, Oct 19, 2012 at 4:21 PM, Theodore Ts'o <tytso@mit.edu> wrote:
>> Alan's advice to get your card working as a basic serial card is very
>> good one. Get basic functionality working, and then you can add the
>> support for the extra bits later....
>
> I can see the logic in getting it working as a basic serial card
> first. I think at minimum I would still need to implement the extra
> divisor calculations to get accurate bit rates.
>
> So when it works as a basic serial card, I assume you would want me to
> use the default PCI IDs to keep it more generic. Then would I add my
> own PCI IDs and refer them back to the generic port?
>
As more of a procedural question, when I go to make the patch(es) to
submit which, kernel repo do I start with? Do I start with Greg KH's
tty repo and then generate the patches and submit them here?
Matt
^ permalink raw reply
* Re: New serial card development
From: Grant Edwards @ 2012-10-23 18:06 UTC (permalink / raw)
To: linux-serial
In-Reply-To: <CAJp1Oe6ekkaZ29iwJ91VXwM_CSL6Z0_KEaqVQTa1XMzTB5niEQ@mail.gmail.com>
On 2012-10-23, Matt Schulte <matts@commtech-fastcom.com> wrote:
> On Fri, Oct 19, 2012 at 4:21 PM, Theodore Ts'o <tytso@mit.edu> wrote:
>> On Wed, Oct 17, 2012 at 03:24:06PM -0500, Matt Schulte wrote:
>>>
>>> What I would need to have happen is for a flag to be set that says
>>> "enable 9-bit mode transmit" or something. When set, the first byte
>>> of data of a given write will go out with mark parity, then the rest
>>> of the bytes will have space parity. The one byte with mark is the
>>> address byte.
>
>> Why not just have a userspace library routine which simply uses
>> tcgetattr/tcsetattr to toggle a bit (probably a new bit in c_cflag) in
>> struct termios, issue the single byte write, and then toggle the bit
>> back?
Can it be guaranteed that it's going to be fast enough at high
baud-rates to prevent any gap between the first byte and subsequent
bytes?
>> In Linux, system calls are fast, so using some extra ioctl's to toggle
>> the termios structure is probably the way to go. It's also much more
>> general since it doesn't presume a very specific protocol (i.e., your
>> magic multi-drop protocol).
>
> Also this isn't a magic protocol, it is a very old protocol that is
> apparently still in use today because I have several customers still
> asking for it.
It's been pretty much a standard in the microctroller world for a
_long_ time. I remember 9-bit HW support with special interrupt on
the "address" byte from almost 30 years ago: when I first worked with
the Intel 8051 in 1983, it had 9-bit support in it's UART (and we used
it).
I now work for a company that has manufactured PC serial boards for
25+ years, and we still get regular requests for that feature (and our
boards do support it -- though our Linux driver does not).
--
Grant Edwards grant.b.edwards Yow! I guess you guys got
at BIG MUSCLES from doing too
gmail.com much STUDYING!
^ permalink raw reply
* Re: New serial card development
From: Alan Cox @ 2012-10-23 18:26 UTC (permalink / raw)
To: Grant Edwards; +Cc: linux-serial
In-Reply-To: <k66mc1$cml$1@ger.gmane.org>
> Can it be guaranteed that it's going to be fast enough at high
> baud-rates to prevent any gap between the first byte and subsequent
> bytes?
Possibly not for some protocols (or worse yet 'almost always' for some
protocols).
It's something to look at once the basic bits are in.
> I now work for a company that has manufactured PC serial boards for
> 25+ years, and we still get regular requests for that feature (and our
> boards do support it -- though our Linux driver does not).
In which case when we get to addressing this it will be good to make
sure we cover your needs as well.
Alan
^ permalink raw reply
* Re: [PATCH 0/1] staging: Add firewire-serial driver
From: Stefan Richter @ 2012-10-23 18:41 UTC (permalink / raw)
To: Peter Hurley
Cc: devel, Greg Kroah-Hartman, linux-kernel, linux-serial,
linux1394-devel, Alan Cox
In-Reply-To: <1351009822.2621.158.camel@thor>
On Oct 23 Peter Hurley wrote:
> most controllers allow spillover into
> the portion of bus cycle assigned for sync tx (which is another 4Kbytes
> per 125us).
All controllers do so and are expected to do so. Asynchronous traffic is
not supposed to depend on a cycle master being active.
> (Technical note: the actual total max for combined async
> and sync tx is 6144 bytes per 125us clock)
It depends on bus topology, transaction types, and more. For a single-hop
S400 1394a bus (vulgo FireWire 400) I once calculated 44 MB/s bandwidth of
asynchronous unified write transactions:
http://marc.info/?l=linux1394-devel&m=109128028930225
That's at the physical layer; link layer and application layer performances
are less than that of course.
--
Stefan Richter
-=====-===-- =-=- =-===
http://arcgraph.de/sr/
------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_sfd2d_oct
^ permalink raw reply
* Re: New serial card development
From: Greg KH @ 2012-10-23 18:38 UTC (permalink / raw)
To: Matt Schulte; +Cc: Theodore Ts'o, Alan Cox, linux-serial
In-Reply-To: <CAJp1Oe67Jd+FaaDPosexrVrrUFS=c-0FUZx_JHTbpTN5RCCcUw@mail.gmail.com>
On Tue, Oct 23, 2012 at 11:31:41AM -0500, Matt Schulte wrote:
> On Tue, Oct 23, 2012 at 11:27 AM, Matt Schulte
> <matts@commtech-fastcom.com> wrote:
> > On Fri, Oct 19, 2012 at 4:21 PM, Theodore Ts'o <tytso@mit.edu> wrote:
> >> Alan's advice to get your card working as a basic serial card is very
> >> good one. Get basic functionality working, and then you can add the
> >> support for the extra bits later....
> >
> > I can see the logic in getting it working as a basic serial card
> > first. I think at minimum I would still need to implement the extra
> > divisor calculations to get accurate bit rates.
> >
> > So when it works as a basic serial card, I assume you would want me to
> > use the default PCI IDs to keep it more generic. Then would I add my
> > own PCI IDs and refer them back to the generic port?
> >
>
> As more of a procedural question, when I go to make the patch(es) to
> submit which, kernel repo do I start with? Do I start with Greg KH's
> tty repo and then generate the patches and submit them here?
That would be a great place to work off of, use the tty-next branch
please.
thanks,
greg k-h
^ permalink raw reply
* Re: New serial card development
From: Grant Edwards @ 2012-10-23 18:45 UTC (permalink / raw)
To: linux-serial
In-Reply-To: <20121023192633.18849645@pyramind.ukuu.org.uk>
On 2012-10-23, Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:
>> Can it be guaranteed that it's going to be fast enough at high
>> baud-rates to prevent any gap between the first byte and subsequent
>> bytes?
>
> Possibly not for some protocols (or worse yet 'almost always' for
> some protocols).
>
> It's something to look at once the basic bits are in.
>
>> I now work for a company that has manufactured PC serial boards for
>> 25+ years, and we still get regular requests for that feature (and our
>> boards do support it -- though our Linux driver does not).
>
> In which case when we get to addressing this it will be good to make
> sure we cover your needs as well.
FWIW, in some products we're planning that will require support for
various industrial serial protocols, I'm leaning towards abandoning
the tty driver approach and writing a stand-alone character device
driver. The byte-stream oriented tty/line-discipline layer just
doesn't fit well when dealing with frame-oriented industrial protocols
that depend on things like 9th bit addressing and detecting
sub-millisecond inter-byte timeouts. When I add in the lack of
long-term stability in the tty API it seems like it might not be such
a bad idea to give up trying to make the tty abstraction fit a use
case that's just nothing like a teletype.
--
Grant Edwards grant.b.edwards Yow! Gibble, Gobble, we
at ACCEPT YOU ...
gmail.com
^ permalink raw reply
* Re: New serial card development
From: Greg KH @ 2012-10-23 19:16 UTC (permalink / raw)
To: Grant Edwards; +Cc: linux-serial
In-Reply-To: <k66okv$811$1@ger.gmane.org>
On Tue, Oct 23, 2012 at 06:45:51PM +0000, Grant Edwards wrote:
> On 2012-10-23, Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:
> >> Can it be guaranteed that it's going to be fast enough at high
> >> baud-rates to prevent any gap between the first byte and subsequent
> >> bytes?
> >
> > Possibly not for some protocols (or worse yet 'almost always' for
> > some protocols).
> >
> > It's something to look at once the basic bits are in.
> >
> >> I now work for a company that has manufactured PC serial boards for
> >> 25+ years, and we still get regular requests for that feature (and our
> >> boards do support it -- though our Linux driver does not).
> >
> > In which case when we get to addressing this it will be good to make
> > sure we cover your needs as well.
>
> FWIW, in some products we're planning that will require support for
> various industrial serial protocols, I'm leaning towards abandoning
> the tty driver approach and writing a stand-alone character device
> driver. The byte-stream oriented tty/line-discipline layer just
> doesn't fit well when dealing with frame-oriented industrial protocols
> that depend on things like 9th bit addressing and detecting
> sub-millisecond inter-byte timeouts. When I add in the lack of
> long-term stability in the tty API it seems like it might not be such
> a bad idea to give up trying to make the tty abstraction fit a use
> case that's just nothing like a teletype.
What do you mean "lack of long-term stability"? The userspace tty api
hasn't ever changed or broken. Don't focus on in-kernel api, that's
always going to change, no matter what interface you choose to use in
the kernel.
Just get your drivers merged into the tree and you will not have to
worry about it.
thanks,
greg k-h
^ permalink raw reply
* Re: New serial card development
From: Alan Cox @ 2012-10-23 19:24 UTC (permalink / raw)
To: Grant Edwards; +Cc: linux-serial
In-Reply-To: <k66okv$811$1@ger.gmane.org>
> FWIW, in some products we're planning that will require support for
> various industrial serial protocols, I'm leaning towards abandoning
> the tty driver approach and writing a stand-alone character device
> driver. The byte-stream oriented tty/line-discipline layer just
> doesn't fit well when dealing with frame-oriented industrial protocols
> that depend on things like 9th bit addressing and detecting
> sub-millisecond inter-byte timeouts. When I add in the lack of
> long-term stability in the tty API it seems like it might not be such
> a bad idea to give up trying to make the tty abstraction fit a use
> case that's just nothing like a teletype.
Not unreasonable but we do need to cover it to some extent because there
are a lot of 'multi-use' port types where you need to share the hardware
or switch modes.
Although we don't use it that way its not entirely accidental that the
tty buffer code supports chains of buffers with lengths 8)
Alan
^ permalink raw reply
* Re: New serial card development
From: Grant Edwards @ 2012-10-23 19:42 UTC (permalink / raw)
To: linux-serial
In-Reply-To: <20121023191604.GA1942@kroah.com>
On 2012-10-23, Greg KH <greg@kroah.com> wrote:
> On Tue, Oct 23, 2012 at 06:45:51PM +0000, Grant Edwards wrote:
>
>> FWIW, in some products we're planning that will require support for
>> various industrial serial protocols, I'm leaning towards abandoning
>> the tty driver approach and writing a stand-alone character device
>> driver. The byte-stream oriented tty/line-discipline layer just
>> doesn't fit well when dealing with frame-oriented industrial protocols
>> that depend on things like 9th bit addressing and detecting
>> sub-millisecond inter-byte timeouts. When I add in the lack of
>> long-term stability in the tty API it seems like it might not be such
>> a bad idea to give up trying to make the tty abstraction fit a use
>> case that's just nothing like a teletype.
>
> What do you mean "lack of long-term stability"? The userspace tty api
> hasn't ever changed or broken.
I meant the in-kernel api.
> Don't focus on in-kernel api,
It's my job to focus on the in-kernel api.
> that's always going to change, no matter what interface you choose to
> use in the kernel.
Maybe it's just my perception, but the the tty API seems to change a
more than the plain character-device API.
--
Grant Edwards grant.b.edwards Yow! I wish I was on a
at Cincinnati street corner
gmail.com holding a clean dog!
^ permalink raw reply
* Re: [PATCH] serial: 8250 check iir rdi in interrupt
From: Min Zhang @ 2012-10-23 19:43 UTC (permalink / raw)
To: Alan Cox; +Cc: gregkh, linux-serial, linux-kernel
In-Reply-To: <20121023110133.62bed522@pyramind.ukuu.org.uk>
On Tue, Oct 23, 2012 at 3:01 AM, Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:
>
> > Added module parameter skip_rdi_check to opt out this workaround.
>
> NAK. Anything like this should be runtime.
One can echo 1 (or 0) > /sys/modules/8250/parameters/skip_rdi_check
during run time to turn it off (or on) dynamically. Does it count as
runtime?
> > Tested on Radisys ATCA 46XX which uses FPGA 16550-compatible and
> > other generic 16550 UART. It takes from an hour to days to reproduce by
> > pumping inputs to serial console continously using TeraTerm script:
>
> You turn this on by default but it's a nasty IRQ latency penalty
> on a lot of x86 platforms with the uarts on the lpc bus.
I agree. Will this patch be more acceptable if default is off? I can't
narrow it hardware down since it is all generic UART.,
> What I am not clear on from this is
>
> - do you see it on both the ports (the bug that is)
No, each hardware only has one serial console port that has traffic,
and only one of the two symptom occur on one type of hardware. That is
hardware 1 ttyS0 has "too much work for irq", and hardware 2 ttyS0 has
console freeze under a separate test. I group them together since they
occur using the same console flooding test script and under similar
RDI root cause.
> - if you do see it on both are you sure its not in reality a symptom of
> some other console/irq handling race ?
It is racing. For "too much work for irq", here is sequence events
analyzed by a Motorola engineer:
1) Data arrives in the FIFO, but not enough to cause an
interrupt
2) The transmitter is started.
3) A transmit needs data interrupt occurs (0xC2 in the
IIR)
4) The processing function is called and it reads the
LSR
5) The LSR indicates that the transmitter needs data,
but also indicates the presence of data in the FIFO (0x61 in the LSR)
6) The processing function receives the characters, and
outputs data to the FIFO
7) At the exact time (very very small window) that the
character is read from the FIFO, the FIFO timeout occurs locking in an
interrupt cause
8) The next loop through the interrupt code begins
9) The IIR now indicates the data timeout interrupt
(0xCC in the IIR)
10) The processing function is called and it reads the
LSR
11) The LSR is 0 indicating nothing to do
12) The interrupt loop continues (the IIR won't clear
until a character is pulled) until it reaches its max count and
displays the error.
The other console freeze symptom is caused by similar sequence. The
last interrupt before interrupt stops always shows IIR=0xC2 and
LSR=0x21, which means has transmit interrupt but both transmit and
receive status.
After interrupt stops, i insmod a module to force read: IIR=0xC6,
IER=0x0F, still no interrupt. Then I read LSR=0xE3., which is what the
next interrupt would have done, makes interrupt resume again. Instead
of force reading LSR, I can also resume interrupt by forcing a printk,
which triggers a new transmit interrupt that reads LSR anyway.
>
> Alan
^ permalink raw reply
* Re: New serial card development
From: Grant Edwards @ 2012-10-23 19:48 UTC (permalink / raw)
To: linux-serial
In-Reply-To: <20121023202404.7e916cca@pyramind.ukuu.org.uk>
On 2012-10-23, Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:
>> FWIW, in some products we're planning that will require support for
>> various industrial serial protocols, I'm leaning towards abandoning
>> the tty driver approach and writing a stand-alone character device
>> driver. The byte-stream oriented tty/line-discipline layer just
>> doesn't fit well when dealing with frame-oriented industrial protocols
>> that depend on things like 9th bit addressing and detecting
>> sub-millisecond inter-byte timeouts. When I add in the lack of
>> long-term stability in the tty API it seems like it might not be such
>> a bad idea to give up trying to make the tty abstraction fit a use
>> case that's just nothing like a teletype.
>
> Not unreasonable but we do need to cover it to some extent because there
> are a lot of 'multi-use' port types where you need to share the hardware
> or switch modes.
Agreed. Providing support for things like 9 bit mode, inter-byte
timeouts, arbitrary baud rates, half-duplex mode, and user-selectable
electrical interfaces (232/422/485/etc.) in the standard tty API would
be a good thing. Half-duplex mode (sometimes called RS485 mode) and
arbitrary baud rate are great recent additions.
> Although we don't use it that way its not entirely accidental that the
> tty buffer code supports chains of buffers with lengths 8)
Thanks, that's good to know.
--
Grant Edwards grant.b.edwards Yow! I can't decide which
at WRONG TURN to make first!!
gmail.com I wonder if BOB GUCCIONE
has these problems!
^ permalink raw reply
* Re: New serial card development
From: Greg KH @ 2012-10-23 20:10 UTC (permalink / raw)
To: Grant Edwards; +Cc: linux-serial
In-Reply-To: <k66rv4$4ir$1@ger.gmane.org>
On Tue, Oct 23, 2012 at 07:42:28PM +0000, Grant Edwards wrote:
> On 2012-10-23, Greg KH <greg@kroah.com> wrote:
> > On Tue, Oct 23, 2012 at 06:45:51PM +0000, Grant Edwards wrote:
> >
> >> FWIW, in some products we're planning that will require support for
> >> various industrial serial protocols, I'm leaning towards abandoning
> >> the tty driver approach and writing a stand-alone character device
> >> driver. The byte-stream oriented tty/line-discipline layer just
> >> doesn't fit well when dealing with frame-oriented industrial protocols
> >> that depend on things like 9th bit addressing and detecting
> >> sub-millisecond inter-byte timeouts. When I add in the lack of
> >> long-term stability in the tty API it seems like it might not be such
> >> a bad idea to give up trying to make the tty abstraction fit a use
> >> case that's just nothing like a teletype.
> >
> > What do you mean "lack of long-term stability"? The userspace tty api
> > hasn't ever changed or broken.
>
> I meant the in-kernel api.
>
> > Don't focus on in-kernel api,
>
> It's my job to focus on the in-kernel api.
It's my job to ensure that you don't have to. Why are you caring? Are
you trying to keep drivers outside of the kernel tree? If so, there's
nothing we can do, except point out what a bad idea that really is to
try to do.
> > that's always going to change, no matter what interface you choose to
> > use in the kernel.
>
> Maybe it's just my perception, but the the tty API seems to change a
> more than the plain character-device API.
Recently, yes. But, once that churn is over, it should settle down.
Oh, and watch out, the "plain" character-device api is going to change
in the next year or so, I've been working on lots of fixups in that
area, and hope to publish something in a month or so if I get it cleaned
up.
My point is, all of the kernel changes, all the time, so don't use the
lack of change, or the rate of change, for a specific api, as any
indication that it will not change again in the future, possibly in very
drastic ways.
thanks,
greg k-h
^ permalink raw reply
* Re: New serial card development
From: Theodore Ts'o @ 2012-10-23 20:31 UTC (permalink / raw)
To: Grant Edwards; +Cc: linux-serial
In-Reply-To: <k66okv$811$1@ger.gmane.org>
On Tue, Oct 23, 2012 at 06:45:51PM +0000, Grant Edwards wrote:
> FWIW, in some products we're planning that will require support for
> various industrial serial protocols, I'm leaning towards abandoning
> the tty driver approach and writing a stand-alone character device
> driver. The byte-stream oriented tty/line-discipline layer just
> doesn't fit well when dealing with frame-oriented industrial protocols
> that depend on things like 9th bit addressing and detecting
> sub-millisecond inter-byte timeouts.
You might want to take a look at how the ppp line discipline (which is
obviously highly packet oriented) works. One advantage of doing
things that way is if you have a multiport serial card, where some
ports want to play this packet-oriented approach, and other cards
might be connected to a traditional modem or terminal sort of device,
you won't have to figure out how to share a PCI board between two
different drivers, allocating one port to the traditional tty/serial
driver, and another one to your new driver, etc.
Regards,
- Ted
^ permalink raw reply
* Re: New serial card development
From: Grant Edwards @ 2012-10-23 20:41 UTC (permalink / raw)
To: linux-serial
In-Reply-To: <20121023203102.GA28626@thunk.org>
On 2012-10-23, Theodore Ts'o <tytso@mit.edu> wrote:
> On Tue, Oct 23, 2012 at 06:45:51PM +0000, Grant Edwards wrote:
>> FWIW, in some products we're planning that will require support for
>> various industrial serial protocols, I'm leaning towards abandoning
>> the tty driver approach and writing a stand-alone character device
>> driver. The byte-stream oriented tty/line-discipline layer just
>> doesn't fit well when dealing with frame-oriented industrial protocols
>> that depend on things like 9th bit addressing and detecting
>> sub-millisecond inter-byte timeouts.
>
> You might want to take a look at how the ppp line discipline (which
> is obviously highly packet oriented) works. One advantage of doing
> things that way is if you have a multiport serial card, where some
> ports want to play this packet-oriented approach, and other cards
> might be connected to a traditional modem or terminal sort of device,
> you won't have to figure out how to share a PCI board between two
> different drivers, allocating one port to the traditional tty/serial
> driver, and another one to your new driver, etc.
Thanks for the suggestion. I did look into line-disciplines briefly
quite a while back. Most of the information I found implied that
adding a line disciplilne wasn't something you could do at run-time by
loading a user-built module -- it would require recompiling parts of
the kernel. Articles made statements about having to modify kernel
include files like tty.h. If that's wrong, then a line discipline
might be a good option.
--
Grant Edwards grant.b.edwards Yow! I'm having a
at quadrophonic sensation
gmail.com of two winos alone in a
steel mill!
^ permalink raw reply
* [PATCH] serial:ifx6x60:different SPI word width configure requires different swap process
From: chao bi @ 2012-10-24 6:48 UTC (permalink / raw)
To: alan; +Cc: linux-serial, richardx.r.gorby, chuansheng.liu, jun.d.chen
SPI protocol driver only provide one function (swap_buf()) to swap SPI data
into big endian format, which is only available when SPI controller's word width
is 16 bits. But word width could be configured as 8/16/32 bits, different word
width configure should be mapped to different swap methods.This patch is to make
SPI protocol driver choose the right swap function corresponding to SPI word
width configuration.
cc: liu chuansheng <chuansheng.liu@intel.com>
cc: Chen Jun <jun.d.chen@intel.com>
Signed-off-by: channing <chao.bi@intel.com>
---
drivers/tty/serial/ifx6x60.c | 70 ++++++++++++++++++++++++++++++++++++------
drivers/tty/serial/ifx6x60.h | 1 +
2 files changed, 61 insertions(+), 10 deletions(-)
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c
index 5b9bc19..c52b4b0 100644
--- a/drivers/tty/serial/ifx6x60.c
+++ b/drivers/tty/serial/ifx6x60.c
@@ -152,26 +152,67 @@ ifx_spi_power_state_clear(struct ifx_spi_device *ifx_dev, unsigned char val)
}
/**
- * swap_buf
+ * swap_buf_8
* @buf: our buffer
* @len : number of bytes (not words) in the buffer
* @end: end of buffer
*
* Swap the contents of a buffer into big endian format
*/
-static inline void swap_buf(u16 *buf, int len, void *end)
+static inline void swap_buf_8(unsigned char *buf, int len, void *end)
+{
+ /* don't swap buffer if SPI word width is 8 bits */
+ return;
+}
+
+/**
+ * swap_buf_16
+ * @buf: our buffer
+ * @len : number of bytes (not words) in the buffer
+ * @end: end of buffer
+ *
+ * Swap the contents of a buffer into big endian format
+ */
+static inline void swap_buf_16(unsigned char *buf, int len, void *end)
{
int n;
+ u16 *buf_16 = (u16 *)buf;
len = ((len + 1) >> 1);
- if ((void *)&buf[len] > end) {
- pr_err("swap_buf: swap exceeds boundary (%p > %p)!",
- &buf[len], end);
+ if ((void *)&buf_16[len] > end) {
+ pr_err("swap_buf_16: swap exceeds boundary (%p > %p)!",
+ &buf_16[len], end);
return;
}
for (n = 0; n < len; n++) {
- *buf = cpu_to_be16(*buf);
- buf++;
+ *buf_16 = cpu_to_be16(*buf_16);
+ buf_16++;
+ }
+}
+
+/**
+ * swap_buf_32
+ * @buf: our buffer
+ * @len : number of bytes (not words) in the buffer
+ * @end: end of buffer
+ *
+ * Swap the contents of a buffer into big endian format
+ */
+static inline void swap_buf_32(unsigned char *buf, int len, void *end)
+{
+ int n;
+
+ u32 *buf_32 = (u32 *)buf;
+ len = (0 == (len&0x03)) ? (len >> 2) : ((len >> 2) + 1);
+
+ if ((void *)&buf_32[len] > end) {
+ pr_err("swap_buf_32: swap exceeds boundary (%p > %p)!\n",
+ &buf_32[len], end);
+ return;
+ }
+ for (n = 0; n < len; n++) {
+ *buf_32 = cpu_to_be32(*buf_32);
+ buf_32++;
}
}
@@ -449,7 +490,7 @@ static int ifx_spi_prepare_tx_buffer(struct ifx_spi_device *ifx_dev)
tx_count-IFX_SPI_HEADER_OVERHEAD,
ifx_dev->spi_more);
/* swap actual data in the buffer */
- swap_buf((u16 *)(ifx_dev->tx_buffer), tx_count,
+ ifx_dev->swap_buf((ifx_dev->tx_buffer), tx_count,
&ifx_dev->tx_buffer[IFX_SPI_TRANSFER_SIZE]);
return tx_count;
}
@@ -617,7 +658,7 @@ static void ifx_spi_complete(void *ctx)
if (!ifx_dev->spi_msg.status) {
/* check header validity, get comm flags */
- swap_buf((u16 *)ifx_dev->rx_buffer, IFX_SPI_HEADER_OVERHEAD,
+ ifx_dev->swap_buf(ifx_dev->rx_buffer, IFX_SPI_HEADER_OVERHEAD,
&ifx_dev->rx_buffer[IFX_SPI_HEADER_OVERHEAD]);
decode_result = ifx_spi_decode_spi_header(ifx_dev->rx_buffer,
&length, &more, &cts);
@@ -636,7 +677,8 @@ static void ifx_spi_complete(void *ctx)
actual_length = min((unsigned int)length,
ifx_dev->spi_msg.actual_length);
- swap_buf((u16 *)(ifx_dev->rx_buffer + IFX_SPI_HEADER_OVERHEAD),
+ ifx_dev->swap_buf(
+ (ifx_dev->rx_buffer + IFX_SPI_HEADER_OVERHEAD),
actual_length,
&ifx_dev->rx_buffer[IFX_SPI_TRANSFER_SIZE]);
ifx_spi_insert_flip_string(
@@ -1001,6 +1043,14 @@ static int ifx_spi_spi_probe(struct spi_device *spi)
return -ENODEV;
}
+ /* init swap_buf function according to word width configuration */
+ if (spi->bits_per_word == 32)
+ ifx_dev->swap_buf = swap_buf_32;
+ else if (spi->bits_per_word == 16)
+ ifx_dev->swap_buf = swap_buf_16;
+ else
+ ifx_dev->swap_buf = swap_buf_8;
+
/* ensure SPI protocol flags are initialized to enable transfer */
ifx_dev->spi_more = 0;
ifx_dev->spi_slave_cts = 0;
diff --git a/drivers/tty/serial/ifx6x60.h b/drivers/tty/serial/ifx6x60.h
index e8464ba..d8869f5 100644
--- a/drivers/tty/serial/ifx6x60.h
+++ b/drivers/tty/serial/ifx6x60.h
@@ -124,6 +124,7 @@ struct ifx_spi_device {
#define MR_INPROGRESS 1
#define MR_COMPLETE 2
wait_queue_head_t mdm_reset_wait;
+ void (*swap_buf)(unsigned char *buf, int len, void *end);
};
#endif /* _IFX6X60_H */
--
1.7.1
^ permalink raw reply related
* RE: Subject: [PATCH] serial:ifx6x60:add swap_buf_32 function in case SPI word width is 32 bits
From: Bi, Chao @ 2012-10-24 6:43 UTC (permalink / raw)
To: Alan Cox
Cc: alan@linux.intel.com, linux-serial@vger.kernel.org, Gorby, Russ,
Chen, Jun D, Liu, Chuansheng
In-Reply-To: <20121023103920.3bcb9159@pyramind.ukuu.org.uk>
Hi Alan,
Yes, you're right.
SPI word width is configured by Protocol driver in ifx_spi_spi_probe(), it could be 8/16/32 bits, so Protocol driver should choose diff swap method according to the configuration.
I've update the patch as your suggestion, please check another PATCH mail.
Thanks!
Chao
-----Original Message-----
From: Alan Cox [mailto:alan@lxorguk.ukuu.org.uk]
Sent: Tuesday, October 23, 2012 5:39 PM
To: Bi, Chao
Cc: alan@linux.intel.com; linux-serial@vger.kernel.org; Gorby, Russ; Chen, Jun D; Liu, Chuansheng
Subject: Re: Subject: [PATCH] serial:ifx6x60:add swap_buf_32 function in case SPI word width is 32 bits
> is 16 bits. But per our experiment and validation on medfield
> platform, 16 bit word width cannot cover all scenarioes, 32 bits word
> width is a better choice to avoid SPI FIFO overrun. Therefore, SPI
> controller is likely to configure its word width as either 16 bits or
> 32 bits. This patch is to implement 2 functions
> (swap_buf_16() and swap_buf_32()) to adapt the two configurations.
And how will you get both to work with the same kernel, which is the way Linux wants to work (and avoids the nasty mess some other embedded platforms have gotten themselves into).
What you probably want to do is is put a 16/32bit flag into the platform data and then in ifx_spi_spi_probe() just do
if (pl_data->spi_32)
ifx_dev->swap = swap_buf_32;
else
ifx_dev->swap = swap_buf;
then call
ifx_dev->swap_buf()
Alan
^ permalink raw reply
* [PATCH v2 0/3] serial: mxs-auart: add DMA support for auart in mx28
From: Huang Shijie @ 2012-10-24 10:27 UTC (permalink / raw)
To: gregkh
Cc: alan, linux-serial, linux-arm-kernel, shawn.guo, linux,
lauri.hintsala, vinod.koul, Huang Shijie
This patch set adds the DMA support for auart in mx28.
patch 1:
In mx23, the DMA has a bug(see errata:2836). We can not add the
DMA support in mx23, but we can add DMA support to auart in mx28.
So in order to add the DMA support for the auart in mx28, we should add
the platform_device_id to distinguish the distinguish SOCs.
patch 2: add the DMA support for mx28
Only we meet the following conditions, we can enable the DMA support
for auart:
(1) We enable the DMA support in the dts file, such as
arch/arm/boot/dts/imx28.dtsi.
(2) We enable the hardware flow control.
(3) We use the mx28, not the mx23. Due to hardware bug(see errata: 2836),
we can not add the DMA support to mx23.
patch 3: enable the DMA support in dts for mx28
You can use the /ttyAPP0 to test this patch set.
I tested this patch in mx28-evk board.
v1 --> v2:
[1] use the inline function, not a macro, to distinguish the SOCs.
[2] remove the "inline" for mxs_auart_tx_chars().
[3] use the `pio`, not the `pio[1]` to fill the DMA descriptor.
[4] use bit operation to serialize the DMA TX.
[5] use the RX/TX DMA channel to enable the DMA support, remove the
"fsl,auart-enable-dma".
Huang Shijie (3):
serial: mxs-auart: distinguish the different SOCs
serial: mxs-auart: add the DMA support for mx28
ARM: dts: enable dma support for auart0 in mx28
.../bindings/tty/serial/fsl-mxs-auart.txt | 8 +
arch/arm/boot/dts/imx28.dtsi | 1 +
drivers/tty/serial/mxs-auart.c | 360 +++++++++++++++++++-
3 files changed, 358 insertions(+), 11 deletions(-)
^ permalink raw reply
* [PATCH v2 1/3] serial: mxs-auart: distinguish the different SOCs
From: Huang Shijie @ 2012-10-24 10:27 UTC (permalink / raw)
To: gregkh
Cc: alan, linux-serial, linux-arm-kernel, shawn.guo, linux,
lauri.hintsala, vinod.koul, Huang Shijie
In-Reply-To: <1351074456-25863-1-git-send-email-b32955@freescale.com>
The current mxs-auart driver is used for both mx23 and mx28.
But in mx23, the DMA has a bug(see errata:2836). We can not add the
DMA support in mx23, but we can add DMA support to auart in mx28.
So in order to add the DMA support for the auart in mx28, we should
distinguish the distinguish SOCs.
This patch adds a new platform_device_id table and a inline function
is_imx28_auart() to distinguish the mx23 and mx28.
Signed-off-by: Huang Shijie <b32955@freescale.com>
---
drivers/tty/serial/mxs-auart.c | 42 ++++++++++++++++++++++++++++++++++-----
1 files changed, 36 insertions(+), 6 deletions(-)
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
index 6db3baa..06d7271 100644
--- a/drivers/tty/serial/mxs-auart.c
+++ b/drivers/tty/serial/mxs-auart.c
@@ -114,11 +114,17 @@
static struct uart_driver auart_driver;
+enum mxs_auart_type {
+ IMX23_AUART,
+ IMX28_AUART,
+};
+
struct mxs_auart_port {
struct uart_port port;
unsigned int flags;
unsigned int ctrl;
+ enum mxs_auart_type devtype;
unsigned int irq;
@@ -126,6 +132,29 @@ struct mxs_auart_port {
struct device *dev;
};
+static struct platform_device_id mxs_auart_devtype[] = {
+ { .name = "mxs-auart-imx23", .driver_data = IMX23_AUART },
+ { .name = "mxs-auart-imx28", .driver_data = IMX28_AUART },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, mxs_auart_devtype);
+
+static struct of_device_id mxs_auart_dt_ids[] = {
+ {
+ .compatible = "fsl,imx28-auart",
+ .data = &mxs_auart_devtype[IMX28_AUART]
+ }, {
+ .compatible = "fsl,imx23-auart",
+ .data = &mxs_auart_devtype[IMX23_AUART]
+ }, { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mxs_auart_dt_ids);
+
+static inline int is_imx28_auart(struct mxs_auart_port *s)
+{
+ return s->devtype == IMX28_AUART;
+}
+
static void mxs_auart_stop_tx(struct uart_port *u);
#define to_auart_port(u) container_of(u, struct mxs_auart_port, port)
@@ -706,6 +735,8 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s,
static int __devinit mxs_auart_probe(struct platform_device *pdev)
{
+ const struct of_device_id *of_id =
+ of_match_device(mxs_auart_dt_ids, &pdev->dev);
struct mxs_auart_port *s;
u32 version;
int ret = 0;
@@ -730,6 +761,11 @@ static int __devinit mxs_auart_probe(struct platform_device *pdev)
goto out_free;
}
+ if (of_id) {
+ pdev->id_entry = of_id->data;
+ s->devtype = pdev->id_entry->driver_data;
+ }
+
s->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(s->clk)) {
ret = PTR_ERR(s->clk);
@@ -805,12 +841,6 @@ static int __devexit mxs_auart_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id mxs_auart_dt_ids[] = {
- { .compatible = "fsl,imx23-auart", },
- { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, mxs_auart_dt_ids);
-
static struct platform_driver mxs_auart_driver = {
.probe = mxs_auart_probe,
.remove = __devexit_p(mxs_auart_remove),
--
1.7.0.4
^ permalink raw reply related
* [PATCH v2 2/3] serial: mxs-auart: add the DMA support for mx28
From: Huang Shijie @ 2012-10-24 10:27 UTC (permalink / raw)
To: gregkh
Cc: alan, linux-serial, linux-arm-kernel, shawn.guo, linux,
lauri.hintsala, vinod.koul, Huang Shijie
In-Reply-To: <1351074456-25863-1-git-send-email-b32955@freescale.com>
Only we meet the following conditions, we can enable the DMA support for
auart:
(1) We enable the DMA support in the dts file, such as
arch/arm/boot/dts/imx28.dtsi.
(2) We enable the hardware flow control.
(3) We use the mx28, not the mx23. Due to hardware bug(see errata: 2836),
we can not add the DMA support to mx23.
Signed-off-by: Huang Shijie <b32955@freescale.com>
---
.../bindings/tty/serial/fsl-mxs-auart.txt | 8 +
drivers/tty/serial/mxs-auart.c | 318 +++++++++++++++++++-
2 files changed, 321 insertions(+), 5 deletions(-)
diff --git a/Documentation/devicetree/bindings/tty/serial/fsl-mxs-auart.txt b/Documentation/devicetree/bindings/tty/serial/fsl-mxs-auart.txt
index 2ee903f..273a8d5 100644
--- a/Documentation/devicetree/bindings/tty/serial/fsl-mxs-auart.txt
+++ b/Documentation/devicetree/bindings/tty/serial/fsl-mxs-auart.txt
@@ -6,11 +6,19 @@ Required properties:
- reg : Address and length of the register set for the device
- interrupts : Should contain the auart interrupt numbers
+Optional properties:
+- fsl,auart-dma-channel : The DMA channels, the first is for RX, the other
+ is for TX. If you add this property, it also means that you
+ will enable the DMA support for the auart.
+ Note: due to the hardware bug in imx23(see errata : 2836),
+ only the imx28 can enable the DMA support for the auart.
+
Example:
auart0: serial@8006a000 {
compatible = "fsl,imx28-auart", "fsl,imx23-auart";
reg = <0x8006a000 0x2000>;
interrupts = <112 70 71>;
+ fsl,auart-dma-channel = <8 9>;
};
Note: Each auart port should have an alias correctly numbered in "aliases"
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
index 06d7271..d593e0a 100644
--- a/drivers/tty/serial/mxs-auart.c
+++ b/drivers/tty/serial/mxs-auart.c
@@ -34,6 +34,8 @@
#include <linux/io.h>
#include <linux/pinctrl/consumer.h>
#include <linux/of_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/fsl/mxs-dma.h>
#include <asm/cacheflush.h>
@@ -71,6 +73,15 @@
#define AUART_CTRL0_SFTRST (1 << 31)
#define AUART_CTRL0_CLKGATE (1 << 30)
+#define AUART_CTRL0_RXTO_ENABLE (1 << 27)
+#define AUART_CTRL0_RXTIMEOUT(v) (((v) & 0x7ff) << 16)
+#define AUART_CTRL0_XFER_COUNT(v) ((v) & 0xffff)
+
+#define AUART_CTRL1_XFER_COUNT(v) ((v) & 0xffff)
+
+#define AUART_CTRL2_DMAONERR (1 << 26)
+#define AUART_CTRL2_TXDMAE (1 << 25)
+#define AUART_CTRL2_RXDMAE (1 << 24)
#define AUART_CTRL2_CTSEN (1 << 15)
#define AUART_CTRL2_RTSEN (1 << 14)
@@ -111,6 +122,7 @@
#define AUART_STAT_BERR (1 << 18)
#define AUART_STAT_PERR (1 << 17)
#define AUART_STAT_FERR (1 << 16)
+#define AUART_STAT_RXCOUNT_MASK 0xffff
static struct uart_driver auart_driver;
@@ -122,7 +134,10 @@ enum mxs_auart_type {
struct mxs_auart_port {
struct uart_port port;
- unsigned int flags;
+#define MXS_AUART_DMA_CONFIG 0x1
+#define MXS_AUART_DMA_ENABLED 0x2
+#define MXS_AUART_DMA_TX_SYNC 2 /* bit 2 */
+ unsigned long flags;
unsigned int ctrl;
enum mxs_auart_type devtype;
@@ -130,6 +145,20 @@ struct mxs_auart_port {
struct clk *clk;
struct device *dev;
+
+ /* for DMA */
+ struct mxs_dma_data dma_data;
+ int dma_channel_rx, dma_channel_tx;
+ int dma_irq_rx, dma_irq_tx;
+ int dma_channel;
+
+ struct scatterlist tx_sgl;
+ struct dma_chan *tx_dma_chan;
+ void *tx_dma_buf;
+
+ struct scatterlist rx_sgl;
+ struct dma_chan *rx_dma_chan;
+ void *rx_dma_buf;
};
static struct platform_device_id mxs_auart_devtype[] = {
@@ -155,14 +184,107 @@ static inline int is_imx28_auart(struct mxs_auart_port *s)
return s->devtype == IMX28_AUART;
}
+static inline bool auart_dma_enabled(struct mxs_auart_port *s)
+{
+ return s->flags & MXS_AUART_DMA_ENABLED;
+}
+
static void mxs_auart_stop_tx(struct uart_port *u);
#define to_auart_port(u) container_of(u, struct mxs_auart_port, port)
-static inline void mxs_auart_tx_chars(struct mxs_auart_port *s)
+static void mxs_auart_tx_chars(struct mxs_auart_port *s);
+
+static void dma_tx_callback(void *param)
{
+ struct mxs_auart_port *s = param;
struct circ_buf *xmit = &s->port.state->xmit;
+ dma_unmap_sg(s->dev, &s->tx_sgl, 1, DMA_TO_DEVICE);
+
+ /* clear the bit used to serialize the DMA tx. */
+ clear_bit(MXS_AUART_DMA_TX_SYNC, &s->flags);
+ smp_mb__after_clear_bit();
+
+ /* wake up the possible processes. */
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(&s->port);
+
+ mxs_auart_tx_chars(s);
+}
+
+static int mxs_auart_dma_tx(struct mxs_auart_port *s, int size)
+{
+ struct dma_async_tx_descriptor *desc;
+ struct scatterlist *sgl = &s->tx_sgl;
+ struct dma_chan *channel = s->tx_dma_chan;
+ u32 pio;
+
+ /* [1] : send PIO. Note, the first pio word is CTRL1. */
+ pio = AUART_CTRL1_XFER_COUNT(size);
+ desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)&pio,
+ 1, DMA_TRANS_NONE, 0);
+ if (!desc) {
+ dev_err(s->dev, "step 1 error\n");
+ return -EINVAL;
+ }
+
+ /* [2] : set DMA buffer. */
+ sg_init_one(sgl, s->tx_dma_buf, size);
+ dma_map_sg(s->dev, sgl, 1, DMA_TO_DEVICE);
+ desc = dmaengine_prep_slave_sg(channel, sgl,
+ 1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!desc) {
+ dev_err(s->dev, "step 2 error\n");
+ return -EINVAL;
+ }
+
+ /* [3] : submit the DMA */
+ desc->callback = dma_tx_callback;
+ desc->callback_param = s;
+ dmaengine_submit(desc);
+ dma_async_issue_pending(channel);
+ return 0;
+}
+
+static void mxs_auart_tx_chars(struct mxs_auart_port *s)
+{
+ struct circ_buf *xmit = &s->port.state->xmit;
+
+ if (auart_dma_enabled(s)) {
+ int i = 0;
+ int size;
+ void *buffer = s->tx_dma_buf;
+
+ if (test_and_set_bit(MXS_AUART_DMA_TX_SYNC, &s->flags))
+ return;
+
+ while (!uart_circ_empty(xmit) && !uart_tx_stopped(&s->port)) {
+ size = min_t(u32, UART_XMIT_SIZE - i,
+ CIRC_CNT_TO_END(xmit->head,
+ xmit->tail,
+ UART_XMIT_SIZE));
+ memcpy(buffer + i, xmit->buf + xmit->tail, size);
+ xmit->tail = (xmit->tail + size) & (UART_XMIT_SIZE - 1);
+
+ i += size;
+ if (i >= UART_XMIT_SIZE)
+ break;
+ }
+
+ if (uart_tx_stopped(&s->port))
+ mxs_auart_stop_tx(&s->port);
+
+ if (i) {
+ mxs_auart_dma_tx(s, i);
+ } else {
+ clear_bit(MXS_AUART_DMA_TX_SYNC, &s->flags);
+ smp_mb__after_clear_bit();
+ }
+ return;
+ }
+
+
while (!(readl(s->port.membase + AUART_STAT) &
AUART_STAT_TXFF)) {
if (s->port.x_char) {
@@ -316,10 +438,155 @@ static u32 mxs_auart_get_mctrl(struct uart_port *u)
return mctrl;
}
+static bool mxs_auart_dma_filter(struct dma_chan *chan, void *param)
+{
+ struct mxs_auart_port *s = param;
+
+ if (!mxs_dma_is_apbx(chan))
+ return false;
+
+ if (s->dma_channel == chan->chan_id) {
+ chan->private = &s->dma_data;
+ return true;
+ }
+ return false;
+}
+
+static int mxs_auart_dma_prep_rx(struct mxs_auart_port *s);
+static void dma_rx_callback(void *arg)
+{
+ struct mxs_auart_port *s = (struct mxs_auart_port *) arg;
+ struct tty_struct *tty = s->port.state->port.tty;
+ int count;
+ u32 stat;
+
+ stat = readl(s->port.membase + AUART_STAT);
+ stat &= ~(AUART_STAT_OERR | AUART_STAT_BERR |
+ AUART_STAT_PERR | AUART_STAT_FERR);
+
+ count = stat & AUART_STAT_RXCOUNT_MASK;
+ tty_insert_flip_string(tty, s->rx_dma_buf, count);
+
+ writel(stat, s->port.membase + AUART_STAT);
+ tty_flip_buffer_push(tty);
+
+ /* start the next DMA for RX. */
+ mxs_auart_dma_prep_rx(s);
+}
+
+static int mxs_auart_dma_prep_rx(struct mxs_auart_port *s)
+{
+ struct dma_async_tx_descriptor *desc;
+ struct scatterlist *sgl = &s->rx_sgl;
+ struct dma_chan *channel = s->rx_dma_chan;
+ u32 pio[1];
+
+ /* [1] : send PIO */
+ pio[0] = AUART_CTRL0_RXTO_ENABLE
+ | AUART_CTRL0_RXTIMEOUT(0x80)
+ | AUART_CTRL0_XFER_COUNT(UART_XMIT_SIZE);
+ desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)pio,
+ 1, DMA_TRANS_NONE, 0);
+ if (!desc) {
+ dev_err(s->dev, "step 1 error\n");
+ return -EINVAL;
+ }
+
+ /* [2] : send DMA request */
+ sg_init_one(sgl, s->rx_dma_buf, UART_XMIT_SIZE);
+ dma_map_sg(s->dev, sgl, 1, DMA_FROM_DEVICE);
+ desc = dmaengine_prep_slave_sg(channel, sgl, 1, DMA_DEV_TO_MEM,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!desc) {
+ dev_err(s->dev, "step 2 error\n");
+ return -1;
+ }
+
+ /* [3] : submit the DMA, but do not issue it. */
+ desc->callback = dma_rx_callback;
+ desc->callback_param = s;
+ dmaengine_submit(desc);
+ dma_async_issue_pending(channel);
+ return 0;
+}
+
+static void mxs_auart_dma_exit_channel(struct mxs_auart_port *s)
+{
+ if (s->tx_dma_chan) {
+ dma_release_channel(s->tx_dma_chan);
+ s->tx_dma_chan = NULL;
+ }
+ if (s->rx_dma_chan) {
+ dma_release_channel(s->rx_dma_chan);
+ s->rx_dma_chan = NULL;
+ }
+
+ kfree(s->tx_dma_buf);
+ kfree(s->rx_dma_buf);
+ s->tx_dma_buf = NULL;
+ s->rx_dma_buf = NULL;
+}
+
+static void mxs_auart_dma_exit(struct mxs_auart_port *s)
+{
+
+ writel(AUART_CTRL2_TXDMAE | AUART_CTRL2_RXDMAE | AUART_CTRL2_DMAONERR,
+ s->port.membase + AUART_CTRL2_CLR);
+
+ mxs_auart_dma_exit_channel(s);
+ s->flags &= ~MXS_AUART_DMA_ENABLED;
+}
+
+static int mxs_auart_dma_init(struct mxs_auart_port *s)
+{
+ dma_cap_mask_t mask;
+
+ if (auart_dma_enabled(s))
+ return 0;
+
+ /* We do not get the right DMA channels. */
+ if (s->dma_channel_rx == -1 || s->dma_channel_rx == -1)
+ return -EINVAL;
+
+ /* init for RX */
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+ s->dma_channel = s->dma_channel_rx;
+ s->dma_data.chan_irq = s->dma_irq_rx;
+ s->rx_dma_chan = dma_request_channel(mask, mxs_auart_dma_filter, s);
+ if (!s->rx_dma_chan)
+ goto err_out;
+ s->rx_dma_buf = kzalloc(UART_XMIT_SIZE, GFP_KERNEL | GFP_DMA);
+ if (!s->rx_dma_buf)
+ goto err_out;
+
+ /* init for TX */
+ s->dma_channel = s->dma_channel_tx;
+ s->dma_data.chan_irq = s->dma_irq_tx;
+ s->tx_dma_chan = dma_request_channel(mask, mxs_auart_dma_filter, s);
+ if (!s->tx_dma_chan)
+ goto err_out;
+ s->tx_dma_buf = kzalloc(UART_XMIT_SIZE, GFP_KERNEL | GFP_DMA);
+ if (!s->tx_dma_buf)
+ goto err_out;
+
+ /* set the flags */
+ s->flags |= MXS_AUART_DMA_ENABLED;
+ dev_dbg(s->dev, "enabled the DMA support.");
+
+ return 0;
+
+err_out:
+ mxs_auart_dma_exit_channel(s);
+ return -EINVAL;
+
+}
+
static void mxs_auart_settermios(struct uart_port *u,
struct ktermios *termios,
struct ktermios *old)
{
+ struct mxs_auart_port *s = to_auart_port(u);
u32 bm, ctrl, ctrl2, div;
unsigned int cflag, baud;
@@ -391,10 +658,23 @@ static void mxs_auart_settermios(struct uart_port *u,
ctrl |= AUART_LINECTRL_STP2;
/* figure out the hardware flow control settings */
- if (cflag & CRTSCTS)
+ if (cflag & CRTSCTS) {
+ /*
+ * The DMA has a bug(see errata:2836) in mx23.
+ * So we can not implement the DMA for auart in mx23,
+ * we can only implement the DMA support for auart
+ * in mx28.
+ */
+ if (is_imx28_auart(s) && (s->flags & MXS_AUART_DMA_CONFIG)) {
+ if (!mxs_auart_dma_init(s))
+ /* enable DMA tranfer */
+ ctrl2 |= AUART_CTRL2_TXDMAE | AUART_CTRL2_RXDMAE
+ | AUART_CTRL2_DMAONERR;
+ }
ctrl2 |= AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN;
- else
+ } else {
ctrl2 &= ~(AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN);
+ }
/* set baud rate */
baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk);
@@ -406,6 +686,17 @@ static void mxs_auart_settermios(struct uart_port *u,
writel(ctrl2, u->membase + AUART_CTRL2);
uart_update_timeout(u, termios->c_cflag, baud);
+
+ /* prepare for the DMA RX. */
+ if (auart_dma_enabled(s)) {
+ if (!mxs_auart_dma_prep_rx(s)) {
+ /* Disable the normal RX interrupt. */
+ writel(AUART_INTR_RXIEN, u->membase + AUART_INTR_CLR);
+ } else {
+ mxs_auart_dma_exit(s);
+ dev_err(s->dev, "We can not start up the DMA.\n");
+ }
+ }
}
static irqreturn_t mxs_auart_irq_handle(int irq, void *context)
@@ -484,6 +775,9 @@ static void mxs_auart_shutdown(struct uart_port *u)
{
struct mxs_auart_port *s = to_auart_port(u);
+ if (auart_dma_enabled(s))
+ mxs_auart_dma_exit(s);
+
writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR);
writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN,
@@ -717,6 +1011,7 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s,
struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
+ u32 dma_channel[2];
int ret;
if (!np)
@@ -730,6 +1025,20 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s,
}
s->port.line = ret;
+ s->dma_irq_rx = platform_get_irq(pdev, 1);
+ s->dma_irq_tx = platform_get_irq(pdev, 2);
+
+ ret = of_property_read_u32_array(np, "fsl,auart-dma-channel",
+ dma_channel, 2);
+ if (ret == 0) {
+ s->dma_channel_rx = dma_channel[0];
+ s->dma_channel_tx = dma_channel[1];
+
+ s->flags |= MXS_AUART_DMA_CONFIG;
+ } else {
+ s->dma_channel_rx = -1;
+ s->dma_channel_tx = -1;
+ }
return 0;
}
@@ -787,7 +1096,6 @@ static int __devinit mxs_auart_probe(struct platform_device *pdev)
s->port.type = PORT_IMX;
s->port.dev = s->dev = get_device(&pdev->dev);
- s->flags = 0;
s->ctrl = 0;
s->irq = platform_get_irq(pdev, 0);
--
1.7.0.4
^ permalink raw reply related
* [PATCH v2 3/3] ARM: dts: enable dma support for auart0 in mx28
From: Huang Shijie @ 2012-10-24 10:27 UTC (permalink / raw)
To: gregkh
Cc: alan, linux-serial, linux-arm-kernel, shawn.guo, linux,
lauri.hintsala, vinod.koul, Huang Shijie
In-Reply-To: <1351074456-25863-1-git-send-email-b32955@freescale.com>
enable the dma support for auart0 in mx28.
Signed-off-by: Huang Shijie <b32955@freescale.com>
---
arch/arm/boot/dts/imx28.dtsi | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index e16d631..73d1a9f 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -798,6 +798,7 @@
compatible = "fsl,imx28-auart", "fsl,imx23-auart";
reg = <0x8006a000 0x2000>;
interrupts = <112 70 71>;
+ fsl,auart-dma-channel = <8 9>;
clocks = <&clks 45>;
status = "disabled";
};
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH] serial:ifx6x60:different SPI word width configure requires different swap process
From: Alan Cox @ 2012-10-24 12:31 UTC (permalink / raw)
To: chao bi; +Cc: alan, linux-serial, richardx.r.gorby, chuansheng.liu, jun.d.chen
In-Reply-To: <1351061328.18855.95.camel@bichao>
On Wed, 24 Oct 2012 14:48:48 +0800
chao bi <chao.bi@intel.com> wrote:
>
> SPI protocol driver only provide one function (swap_buf()) to swap SPI data
> into big endian format, which is only available when SPI controller's word width
> is 16 bits. But word width could be configured as 8/16/32 bits, different word
> width configure should be mapped to different swap methods.This patch is to make
> SPI protocol driver choose the right swap function corresponding to SPI word
> width configuration.
>
> cc: liu chuansheng <chuansheng.liu@intel.com>
> cc: Chen Jun <jun.d.chen@intel.com>
> Signed-off-by: channing <chao.bi@intel.com>
> + len = (0 == (len&0x03)) ? (len >> 2) : ((len >> 2) + 1);
Minor question - is that not just (len + 3) >> 2 ?
The SPI swapping stuff at runtime looks right so.
Acked-by: Alan Cox <alan@linux.intel.com>
^ permalink raw reply
* [PATCH] [tty]: Report warning when low_latency flag is wrongly used
From: Ivo Sieben @ 2012-10-24 12:35 UTC (permalink / raw)
To: Greg KH, linux-serial, RT; +Cc: Ivo Sieben
In-Reply-To: <20121023111659.6f4427c7@bob.linux.org.uk>
When a driver has the low_latency flag set and uses the schedule_flip()
function to initiate copying data to the line discipline, a workqueue is
scheduled in but never actually flushed. This is incorrect use of the
low_latency flag (driver should not support the low_latency flag, or use
the tty_flip_buffer_push() function instead). Make sure a warning is
reported to catch incorrect use of the low_latency flag.
This patch goes with: cee4ad1ed90a0959fc29f9d30a2526e5e9522cfa
Signed-off-by: Ivo Sieben <meltedpianoman@gmail.com>
---
drivers/tty/tty_buffer.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index 06725f5..6cf87d7 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -365,6 +365,7 @@ void tty_schedule_flip(struct tty_struct *tty)
{
struct tty_bufhead *buf = &tty->port->buf;
unsigned long flags;
+ WARN_ON(tty->low_latency);
spin_lock_irqsave(&buf->lock, flags);
if (buf->tail != NULL)
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH 0/1] staging: Add firewire-serial driver
From: Stefan Richter @ 2012-10-24 13:41 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Peter Hurley, devel, linux1394-devel, linux-kernel, linux-serial
In-Reply-To: <20121022224505.GD24489@kroah.com>
On Oct 22 Greg Kroah-Hartman wrote:
> On Thu, Oct 18, 2012 at 08:56:55AM -0400, Peter Hurley wrote:
> > Please consider this serial driver for review for submission to staging.
> > The firewire-serial driver implements TTY over IEEE 1394. In its default
> > configuration, it creates 4 TTY devices and one loopback device per
> > firewire card (respectively, named fwtty<n>~fwtty<n+3> and fwloop<n>).
> >
> > Currently, the TTY devices auto-connect to every cabled peer (the TODO
> > list includes plans for providing a sysfs interface to control virtual
> > cabling with whitelist/blacklist support per GUID).
> >
> > Efforts are still ongoing for a companion console driver, with plans to
> > eventually add early_printk & kgdb support (via additional drivers).
> >
> > Some issues did arise with both the TTY and Firewire subsystems which
> > are noted in the TODO file. Please review these workarounds.
> >
> > Peter Hurley (1):
> > staging: fwserial: Add TTY-over-Firewire serial driver
>
> I'd like to get an Ack from Stefan here, before I'll add this to the
> staging tree.
I have not formed an opinion yet, and have not taken the time to look over
the code yet. Personally, I am entirely unfamiliar with the application
domain of tty drivers in general and with the tty-over-"high"speed-bus
application domain in particular. IOW, I don't know who is going to use
this for which purposes.
On the FireWire side, this driver implements an own transport protocol.
AFAIK a standardized serial-over-1394 does not exist. This means that
interoperability of this driver will initially be limited to
Linux-to-Linux. Devices or other operating systems which implement this
do not exist.
Apart from that aspect, the proposed fwserial driver looks to have
requirements similar to the existing IPv4-over-1394 and SBP target-mode
drivers (drivers/firewire/net.* and drivers/target/sbp/*). This means that
(a) fw-serial motivated changes to the firewire subsystem and (b) firewire
subsystem motivated changes to fwserial could quite possibly also be
interesting for or required by those other drivers as well, meaning that
maintenance overhead should not increase much.
> > drivers/staging/fwserial/dma_fifo.c | 310 ++++
> > drivers/staging/fwserial/dma_fifo.h | 130 ++
> > drivers/staging/fwserial/fwserial.c | 2885 +++++++++++++++++++++++++++++++++++
> > drivers/staging/fwserial/fwserial.h | 355 +++++
drivers/firewire/net.c is 1721 lines, sbp_target is 2868 lines.
Why is fwserial bigger?
--
Stefan Richter
-=====-===-- =-=- ==---
http://arcgraph.de/sr/
^ permalink raw reply
* Re: [PATCH] [tty]: Report warning when low_latency flag is wrongly used
From: Paul Gortmaker @ 2012-10-24 14:32 UTC (permalink / raw)
To: Ivo Sieben; +Cc: Greg KH, linux-serial, RT
In-Reply-To: <1351082142-28633-1-git-send-email-meltedpianoman@gmail.com>
On 12-10-24 08:35 AM, Ivo Sieben wrote:
> When a driver has the low_latency flag set and uses the schedule_flip()
> function to initiate copying data to the line discipline, a workqueue is
> scheduled in but never actually flushed. This is incorrect use of the
> low_latency flag (driver should not support the low_latency flag, or use
> the tty_flip_buffer_push() function instead). Make sure a warning is
> reported to catch incorrect use of the low_latency flag.
>
> This patch goes with: cee4ad1ed90a0959fc29f9d30a2526e5e9522cfa
Ideally you shouldn't put commit IDs in the commit log when they
are not "permanent" (i.e. already part of mainline). For example,
I have no idea what cee4ad1e contains, or what tree it lives in,
and I can't even search for it, since you've not also included
the short log.
Paul.
--
>
> Signed-off-by: Ivo Sieben <meltedpianoman@gmail.com>
>
> ---
> drivers/tty/tty_buffer.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
> index 06725f5..6cf87d7 100644
> --- a/drivers/tty/tty_buffer.c
> +++ b/drivers/tty/tty_buffer.c
> @@ -365,6 +365,7 @@ void tty_schedule_flip(struct tty_struct *tty)
> {
> struct tty_bufhead *buf = &tty->port->buf;
> unsigned long flags;
> + WARN_ON(tty->low_latency);
>
> spin_lock_irqsave(&buf->lock, flags);
> if (buf->tail != NULL)
>
^ permalink raw reply
* Re: [PATCH 0/1] staging: Add firewire-serial driver
From: Peter Hurley @ 2012-10-24 15:56 UTC (permalink / raw)
To: Stefan Richter
Cc: Greg Kroah-Hartman, devel, linux1394-devel, linux-kernel,
linux-serial
In-Reply-To: <20121024154141.3029ad92@stein>
> > > drivers/staging/fwserial/dma_fifo.c | 310 ++++
> > > drivers/staging/fwserial/dma_fifo.h | 130 ++
> > > drivers/staging/fwserial/fwserial.c | 2885 +++++++++++++++++++++++++++++++++++
> > > drivers/staging/fwserial/fwserial.h | 355 +++++
>
> drivers/firewire/net.c is 1721 lines, sbp_target is 2868 lines.
> Why is fwserial bigger?
1) Exclude the dma_fifo* files in the comparison, because block & net
devices get dma-able memory management from their subsystems.
2) Certain tty concepts don't map well to an automated bus, so these are
simulated (eg, break handling)
3) fwserial has to implement a protocol to virtually cable peers
4) sbp_target only supports 1 target.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox