Commit Graph

63 Commits

Author SHA1 Message Date
Geert Uytterhoeven
ffab87fdec serial: fsl_lpuart: Fix out-of-bounds access through DT alias
The lpuart_ports[] array is indexed using a value derived from the
"serialN" alias in DT, which may lead to an out-of-bounds access.

Fix this by adding a range check.

Fixes: c9e2e946fb ("tty: serial: add Freescale lpuart driver support")
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-02-28 15:29:59 +01:00
Lukas Wunner
01d845352a serial: fsl_lpuart: Support common rs485 binding for RTS polarity
Invoke the ->rs485_config callback on probe to set UARTMODEM_TXRTSPOL
appropriately based on the UART's device properties.

This implicitly sets UARTMODEM_TXRTSE if rs485 was enabled in the device
properties, so drop the identical code from lpuart_probe().

It also fixes a bug:  If an unsupported rs485 property was specified
(rs485-rx-during-tx or rs485-rts-delay), the driver returns -ENOSYS
without performing any cleanup, in particular without calling
uart_remove_one_port() or clk_disable_unprepare(), thus leaking the
uart_port. But with the invocation of ->rs485_config, the unsupported
properties are now cleared in struct serial_rs485 and thus ignored.
It therefore seems sufficient to just log an error instead of bailing
out.

Cc: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-11-28 16:05:20 +01:00
Lukas Wunner
743f93f822 serial: Make retrieval of rs485 properties platform-agnostic
Commit ef838a81dd ("serial: Add common rs485 device tree parsing
function") consolidated retrieval of rs485 OF properties in a common
helper function but did not #ifdef it to CONFIG_OF.  The function is
therefore included on ACPI platforms as well even though it's not used.

On the other hand ACPI platforms with rs485 do exist (e.g. Siemens
IOT2040) and they may leverage _DSD to store rs485 properties.  Likewise,
UART platform devices instantiated from an MFD should be able to specify
rs485 properties.  In fact, the tty subsystem maintainer had asked for
a "generic" function during review of commit ef838a81dd:
https://marc.info/?l=linux-serial&m=150143441725194&w=4

Thus, instead of constraining the helper to OF platforms, make it
platform-agnostic by converting it to device_property_*() functions
and renaming it accordingly.

In imx.c, move the invocation of uart_get_rs485_mode() from
serial_imx_probe_dt() to serial_imx_probe() so that it also gets called
for non-OF devices.

In omap-serial.c, move its invocation further up within
serial_omap_probe_rs485() so that the RTS polarity can be overridden
with the driver-specific "rs485-rts-active-high" property once we
introduce a generic "rs485-rts-active-low" property.

Cc: Jan Kiszka <jan.kiszka@siemens.com>
Cc: Richard Genoud <richard.genoud@gmail.com>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-11-28 16:04:57 +01:00
Kees Cook
e99e88a9d2 treewide: setup_timer() -> timer_setup()
This converts all remaining cases of the old setup_timer() API into using
timer_setup(), where the callback argument is the structure already
holding the struct timer_list. These should have no behavioral changes,
since they just change which pointer is passed into the callback with
the same available pointers after conversion. It handles the following
examples, in addition to some other variations.

Casting from unsigned long:

    void my_callback(unsigned long data)
    {
        struct something *ptr = (struct something *)data;
    ...
    }
    ...
    setup_timer(&ptr->my_timer, my_callback, ptr);

and forced object casts:

    void my_callback(struct something *ptr)
    {
    ...
    }
    ...
    setup_timer(&ptr->my_timer, my_callback, (unsigned long)ptr);

become:

    void my_callback(struct timer_list *t)
    {
        struct something *ptr = from_timer(ptr, t, my_timer);
    ...
    }
    ...
    timer_setup(&ptr->my_timer, my_callback, 0);

Direct function assignments:

    void my_callback(unsigned long data)
    {
        struct something *ptr = (struct something *)data;
    ...
    }
    ...
    ptr->my_timer.function = my_callback;

have a temporary cast added, along with converting the args:

    void my_callback(struct timer_list *t)
    {
        struct something *ptr = from_timer(ptr, t, my_timer);
    ...
    }
    ...
    ptr->my_timer.function = (TIMER_FUNC_TYPE)my_callback;

And finally, callbacks without a data assignment:

    void my_callback(unsigned long data)
    {
    ...
    }
    ...
    setup_timer(&ptr->my_timer, my_callback, 0);

have their argument renamed to verify they're unused during conversion:

    void my_callback(struct timer_list *unused)
    {
    ...
    }
    ...
    timer_setup(&ptr->my_timer, my_callback, 0);

The conversion is done with the following Coccinelle script:

spatch --very-quiet --all-includes --include-headers \
	-I ./arch/x86/include -I ./arch/x86/include/generated \
	-I ./include -I ./arch/x86/include/uapi \
	-I ./arch/x86/include/generated/uapi -I ./include/uapi \
	-I ./include/generated/uapi --include ./include/linux/kconfig.h \
	--dir . \
	--cocci-file ~/src/data/timer_setup.cocci

@fix_address_of@
expression e;
@@

 setup_timer(
-&(e)
+&e
 , ...)

// Update any raw setup_timer() usages that have a NULL callback, but
// would otherwise match change_timer_function_usage, since the latter
// will update all function assignments done in the face of a NULL
// function initialization in setup_timer().
@change_timer_function_usage_NULL@
expression _E;
identifier _timer;
type _cast_data;
@@

(
-setup_timer(&_E->_timer, NULL, _E);
+timer_setup(&_E->_timer, NULL, 0);
|
-setup_timer(&_E->_timer, NULL, (_cast_data)_E);
+timer_setup(&_E->_timer, NULL, 0);
|
-setup_timer(&_E._timer, NULL, &_E);
+timer_setup(&_E._timer, NULL, 0);
|
-setup_timer(&_E._timer, NULL, (_cast_data)&_E);
+timer_setup(&_E._timer, NULL, 0);
)

@change_timer_function_usage@
expression _E;
identifier _timer;
struct timer_list _stl;
identifier _callback;
type _cast_func, _cast_data;
@@

(
-setup_timer(&_E->_timer, _callback, _E);
+timer_setup(&_E->_timer, _callback, 0);
|
-setup_timer(&_E->_timer, &_callback, _E);
+timer_setup(&_E->_timer, _callback, 0);
|
-setup_timer(&_E->_timer, _callback, (_cast_data)_E);
+timer_setup(&_E->_timer, _callback, 0);
|
-setup_timer(&_E->_timer, &_callback, (_cast_data)_E);
+timer_setup(&_E->_timer, _callback, 0);
|
-setup_timer(&_E->_timer, (_cast_func)_callback, _E);
+timer_setup(&_E->_timer, _callback, 0);
|
-setup_timer(&_E->_timer, (_cast_func)&_callback, _E);
+timer_setup(&_E->_timer, _callback, 0);
|
-setup_timer(&_E->_timer, (_cast_func)_callback, (_cast_data)_E);
+timer_setup(&_E->_timer, _callback, 0);
|
-setup_timer(&_E->_timer, (_cast_func)&_callback, (_cast_data)_E);
+timer_setup(&_E->_timer, _callback, 0);
|
-setup_timer(&_E._timer, _callback, (_cast_data)_E);
+timer_setup(&_E._timer, _callback, 0);
|
-setup_timer(&_E._timer, _callback, (_cast_data)&_E);
+timer_setup(&_E._timer, _callback, 0);
|
-setup_timer(&_E._timer, &_callback, (_cast_data)_E);
+timer_setup(&_E._timer, _callback, 0);
|
-setup_timer(&_E._timer, &_callback, (_cast_data)&_E);
+timer_setup(&_E._timer, _callback, 0);
|
-setup_timer(&_E._timer, (_cast_func)_callback, (_cast_data)_E);
+timer_setup(&_E._timer, _callback, 0);
|
-setup_timer(&_E._timer, (_cast_func)_callback, (_cast_data)&_E);
+timer_setup(&_E._timer, _callback, 0);
|
-setup_timer(&_E._timer, (_cast_func)&_callback, (_cast_data)_E);
+timer_setup(&_E._timer, _callback, 0);
|
-setup_timer(&_E._timer, (_cast_func)&_callback, (_cast_data)&_E);
+timer_setup(&_E._timer, _callback, 0);
|
 _E->_timer@_stl.function = _callback;
|
 _E->_timer@_stl.function = &_callback;
|
 _E->_timer@_stl.function = (_cast_func)_callback;
|
 _E->_timer@_stl.function = (_cast_func)&_callback;
|
 _E._timer@_stl.function = _callback;
|
 _E._timer@_stl.function = &_callback;
|
 _E._timer@_stl.function = (_cast_func)_callback;
|
 _E._timer@_stl.function = (_cast_func)&_callback;
)

// callback(unsigned long arg)
@change_callback_handle_cast
 depends on change_timer_function_usage@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._timer;
type _origtype;
identifier _origarg;
type _handletype;
identifier _handle;
@@

 void _callback(
-_origtype _origarg
+struct timer_list *t
 )
 {
(
	... when != _origarg
	_handletype *_handle =
-(_handletype *)_origarg;
+from_timer(_handle, t, _timer);
	... when != _origarg
|
	... when != _origarg
	_handletype *_handle =
-(void *)_origarg;
+from_timer(_handle, t, _timer);
	... when != _origarg
|
	... when != _origarg
	_handletype *_handle;
	... when != _handle
	_handle =
-(_handletype *)_origarg;
+from_timer(_handle, t, _timer);
	... when != _origarg
|
	... when != _origarg
	_handletype *_handle;
	... when != _handle
	_handle =
-(void *)_origarg;
+from_timer(_handle, t, _timer);
	... when != _origarg
)
 }

// callback(unsigned long arg) without existing variable
@change_callback_handle_cast_no_arg
 depends on change_timer_function_usage &&
                     !change_callback_handle_cast@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._timer;
type _origtype;
identifier _origarg;
type _handletype;
@@

 void _callback(
-_origtype _origarg
+struct timer_list *t
 )
 {
+	_handletype *_origarg = from_timer(_origarg, t, _timer);
+
	... when != _origarg
-	(_handletype *)_origarg
+	_origarg
	... when != _origarg
 }

// Avoid already converted callbacks.
@match_callback_converted
 depends on change_timer_function_usage &&
            !change_callback_handle_cast &&
	    !change_callback_handle_cast_no_arg@
identifier change_timer_function_usage._callback;
identifier t;
@@

 void _callback(struct timer_list *t)
 { ... }

// callback(struct something *handle)
@change_callback_handle_arg
 depends on change_timer_function_usage &&
	    !match_callback_converted &&
            !change_callback_handle_cast &&
            !change_callback_handle_cast_no_arg@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._timer;
type _handletype;
identifier _handle;
@@

 void _callback(
-_handletype *_handle
+struct timer_list *t
 )
 {
+	_handletype *_handle = from_timer(_handle, t, _timer);
	...
 }

// If change_callback_handle_arg ran on an empty function, remove
// the added handler.
@unchange_callback_handle_arg
 depends on change_timer_function_usage &&
	    change_callback_handle_arg@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._timer;
type _handletype;
identifier _handle;
identifier t;
@@

 void _callback(struct timer_list *t)
 {
-	_handletype *_handle = from_timer(_handle, t, _timer);
 }

// We only want to refactor the setup_timer() data argument if we've found
// the matching callback. This undoes changes in change_timer_function_usage.
@unchange_timer_function_usage
 depends on change_timer_function_usage &&
            !change_callback_handle_cast &&
            !change_callback_handle_cast_no_arg &&
	    !change_callback_handle_arg@
expression change_timer_function_usage._E;
identifier change_timer_function_usage._timer;
identifier change_timer_function_usage._callback;
type change_timer_function_usage._cast_data;
@@

(
-timer_setup(&_E->_timer, _callback, 0);
+setup_timer(&_E->_timer, _callback, (_cast_data)_E);
|
-timer_setup(&_E._timer, _callback, 0);
+setup_timer(&_E._timer, _callback, (_cast_data)&_E);
)

// If we fixed a callback from a .function assignment, fix the
// assignment cast now.
@change_timer_function_assignment
 depends on change_timer_function_usage &&
            (change_callback_handle_cast ||
             change_callback_handle_cast_no_arg ||
             change_callback_handle_arg)@
expression change_timer_function_usage._E;
identifier change_timer_function_usage._timer;
identifier change_timer_function_usage._callback;
type _cast_func;
typedef TIMER_FUNC_TYPE;
@@

(
 _E->_timer.function =
-_callback
+(TIMER_FUNC_TYPE)_callback
 ;
|
 _E->_timer.function =
-&_callback
+(TIMER_FUNC_TYPE)_callback
 ;
|
 _E->_timer.function =
-(_cast_func)_callback;
+(TIMER_FUNC_TYPE)_callback
 ;
|
 _E->_timer.function =
-(_cast_func)&_callback
+(TIMER_FUNC_TYPE)_callback
 ;
|
 _E._timer.function =
-_callback
+(TIMER_FUNC_TYPE)_callback
 ;
|
 _E._timer.function =
-&_callback;
+(TIMER_FUNC_TYPE)_callback
 ;
|
 _E._timer.function =
-(_cast_func)_callback
+(TIMER_FUNC_TYPE)_callback
 ;
|
 _E._timer.function =
-(_cast_func)&_callback
+(TIMER_FUNC_TYPE)_callback
 ;
)

// Sometimes timer functions are called directly. Replace matched args.
@change_timer_function_calls
 depends on change_timer_function_usage &&
            (change_callback_handle_cast ||
             change_callback_handle_cast_no_arg ||
             change_callback_handle_arg)@
expression _E;
identifier change_timer_function_usage._timer;
identifier change_timer_function_usage._callback;
type _cast_data;
@@

 _callback(
(
-(_cast_data)_E
+&_E->_timer
|
-(_cast_data)&_E
+&_E._timer
|
-_E
+&_E->_timer
)
 )

// If a timer has been configured without a data argument, it can be
// converted without regard to the callback argument, since it is unused.
@match_timer_function_unused_data@
expression _E;
identifier _timer;
identifier _callback;
@@

(
-setup_timer(&_E->_timer, _callback, 0);
+timer_setup(&_E->_timer, _callback, 0);
|
-setup_timer(&_E->_timer, _callback, 0L);
+timer_setup(&_E->_timer, _callback, 0);
|
-setup_timer(&_E->_timer, _callback, 0UL);
+timer_setup(&_E->_timer, _callback, 0);
|
-setup_timer(&_E._timer, _callback, 0);
+timer_setup(&_E._timer, _callback, 0);
|
-setup_timer(&_E._timer, _callback, 0L);
+timer_setup(&_E._timer, _callback, 0);
|
-setup_timer(&_E._timer, _callback, 0UL);
+timer_setup(&_E._timer, _callback, 0);
|
-setup_timer(&_timer, _callback, 0);
+timer_setup(&_timer, _callback, 0);
|
-setup_timer(&_timer, _callback, 0L);
+timer_setup(&_timer, _callback, 0);
|
-setup_timer(&_timer, _callback, 0UL);
+timer_setup(&_timer, _callback, 0);
|
-setup_timer(_timer, _callback, 0);
+timer_setup(_timer, _callback, 0);
|
-setup_timer(_timer, _callback, 0L);
+timer_setup(_timer, _callback, 0);
|
-setup_timer(_timer, _callback, 0UL);
+timer_setup(_timer, _callback, 0);
)

@change_callback_unused_data
 depends on match_timer_function_unused_data@
identifier match_timer_function_unused_data._callback;
type _origtype;
identifier _origarg;
@@

 void _callback(
-_origtype _origarg
+struct timer_list *unused
 )
 {
	... when != _origarg
 }

Signed-off-by: Kees Cook <keescook@chromium.org>
2017-11-21 15:57:07 -08:00
Greg Kroah-Hartman
4793f2ebff tty: serial: Remove redundant license text
Now that the SPDX tag is in all tty files, that identifies the license
in a specific and legally-defined manner.  So the extra GPL text wording
can be removed as it is no longer needed at all.

This is done on a quest to remove the 700+ different ways that files in
the kernel describe the GPL license text.  And there's unneeded stuff
like the address (sometimes incorrect) for the FSF which is never
needed.

No copyright headers or other non-license-description text was removed.

Cc: Jiri Slaby <jslaby@suse.com>
Cc: Eric Anholt <eric@anholt.net>
Cc: Stefan Wahren <stefan.wahren@i2se.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: Ray Jui <rjui@broadcom.com>
Cc: Scott Branden <sbranden@broadcom.com>
Cc: bcm-kernel-feedback-list@broadcom.com
Cc: "James E.J. Bottomley" <jejb@parisc-linux.org>
Cc: Helge Deller <deller@gmx.de>
Cc: Joachim Eastwood <manabian@gmail.com>
Cc: Matthias Brugger <matthias.bgg@gmail.com>
Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: Tobias Klauser <tklauser@distanz.ch>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Vineet Gupta <vgupta@synopsys.com>
Cc: Richard Genoud <richard.genoud@gmail.com>
Cc: Alexander Shiyan <shc_work@mail.ru>
Cc: Baruch Siach <baruch@tkos.co.il>
Cc: Pat Gefre <pfg@sgi.com>
Cc: "Guilherme G. Piccoli" <gpiccoli@linux.vnet.ibm.com>
Cc: Jason Wessel <jason.wessel@windriver.com>
Cc: Vladimir Zapolskiy <vz@mleia.com>
Cc: Sylvain Lemieux <slemieux.tyco@gmail.com>
Cc: Carlo Caione <carlo@caione.org>
Cc: Kevin Hilman <khilman@baylibre.com>
Cc: Liviu Dudau <liviu.dudau@arm.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Andy Gross <andy.gross@linaro.org>
Cc: David Brown <david.brown@linaro.org>
Cc: "Andreas Färber" <afaerber@suse.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Kevin Cernekee <cernekee@gmail.com>
Cc: Laxman Dewangan <ldewangan@nvidia.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: Barry Song <baohua@kernel.org>
Cc: Patrice Chotard <patrice.chotard@st.com>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>
Cc: Chris Metcalf <cmetcalf@mellanox.com>
Cc: Peter Korsgaard <jacmet@sunsite.dk>
Cc: Timur Tabi <timur@tabi.org>
Cc: Tony Prisk <linux@prisktech.co.nz>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: "Sören Brinkmann" <soren.brinkmann@xilinx.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-11-08 13:08:12 +01:00
Greg Kroah-Hartman
e3b3d0f549 tty: add SPDX identifiers to all remaining files in drivers/tty/
It's good to have SPDX identifiers in all files to make it easier to
audit the kernel tree for correct licenses.

Update the drivers/tty files files with the correct SPDX license
identifier based on the license text in the file itself.  The SPDX
identifier is a legally binding shorthand, which can be used instead of
the full boiler plate text.

This work is based on a script and data from Thomas Gleixner, Philippe
Ombredanne, and Kate Stewart.

Cc: Jiri Slaby <jslaby@suse.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Chris Metcalf <cmetcalf@mellanox.com>
Cc: Jiri Kosina <jikos@kernel.org>
Cc: David Sterba <dsterba@suse.com>
Cc: James Hogan <jhogan@kernel.org>
Cc: Rob Herring <robh@kernel.org>
Cc: Eric Anholt <eric@anholt.net>
Cc: Stefan Wahren <stefan.wahren@i2se.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: Ray Jui <rjui@broadcom.com>
Cc: Scott Branden <sbranden@broadcom.com>
Cc: bcm-kernel-feedback-list@broadcom.com
Cc: "James E.J. Bottomley" <jejb@parisc-linux.org>
Cc: Helge Deller <deller@gmx.de>
Cc: Joachim Eastwood <manabian@gmail.com>
Cc: Matthias Brugger <matthias.bgg@gmail.com>
Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: Tobias Klauser <tklauser@distanz.ch>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Vineet Gupta <vgupta@synopsys.com>
Cc: Richard Genoud <richard.genoud@gmail.com>
Cc: Alexander Shiyan <shc_work@mail.ru>
Cc: Baruch Siach <baruch@tkos.co.il>
Cc: "Maciej W. Rozycki" <macro@linux-mips.org>
Cc: "Uwe Kleine-König" <kernel@pengutronix.de>
Cc: Pat Gefre <pfg@sgi.com>
Cc: "Guilherme G. Piccoli" <gpiccoli@linux.vnet.ibm.com>
Cc: Jason Wessel <jason.wessel@windriver.com>
Cc: Vladimir Zapolskiy <vz@mleia.com>
Cc: Sylvain Lemieux <slemieux.tyco@gmail.com>
Cc: Carlo Caione <carlo@caione.org>
Cc: Kevin Hilman <khilman@baylibre.com>
Cc: Liviu Dudau <liviu.dudau@arm.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Andy Gross <andy.gross@linaro.org>
Cc: David Brown <david.brown@linaro.org>
Cc: "Andreas Färber" <afaerber@suse.de>
Cc: Kevin Cernekee <cernekee@gmail.com>
Cc: Laxman Dewangan <ldewangan@nvidia.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: Barry Song <baohua@kernel.org>
Cc: Patrice Chotard <patrice.chotard@st.com>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Peter Korsgaard <jacmet@sunsite.dk>
Cc: Timur Tabi <timur@tabi.org>
Cc: Tony Prisk <linux@prisktech.co.nz>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: "Sören Brinkmann" <soren.brinkmann@xilinx.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Kate Stewart <kstewart@linuxfoundation.org>
Cc: Philippe Ombredanne <pombredanne@nexb.com>
Cc: Jiri Slaby <jslaby@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-11-08 13:08:12 +01:00
Greg Kroah-Hartman
9424e8b1fe Merge 4.14-rc4 into tty-next
We want the tty/serial fixes in here as well.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-10-09 09:05:05 +02:00
Sascha Hauer
dde18d53d7 serial: fsl_lpuart: Use common rs485 device tree parsing function
We just got a common helper for parsing the rs485 specific
device tree properties. Use it and drop the open coded parser.

As a side effect this adds support for parsing rs485-rts-delay and
rs485-rx-during-tx. As the driver doesn't support this though, probing
fails if these are defined.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-09-18 18:36:25 +02:00
Fabio Estevam
c45e2d2547 serial: fsl_lpuart: Remove unused 'bd' variable
Since commit a6d7514b14 ("tty: serial: lpuart: add a more accurate baud
rate calculation method") the baud rate is now calculated inside the
lpuart32_serial_setbrg() function, so we no longer need to read the
UARTBAUD register inside lpuart32_set_termios().

The 'bd' variable can be simply removed.

This fixes the following build warning with W=1:

drivers/tty/serial/fsl_lpuart.c: In function 'lpuart32_set_termios':
drivers/tty/serial/fsl_lpuart.c:1652:32: warning: variable 'bd' set but not used [-Wunused-but-set-variable]

Fixes: a6d7514b14 ("tty: serial: lpuart: add a more accurate baud rate calculation method")
Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-09-18 18:31:49 +02:00
Fugang Duan
9d7ee0e28d tty: serial: lpuart: avoid report NULL interrupt
The current driver register irq in .startup() and free the irq in
.shutdown(), then user will see the NULL interrupt output from
'cat /proc/interrupts' after the uart port test completed:
...
 41:        515          0          0          0     GICv3 257 Level     fsl-lpuart
 42:          2          0          0          0     GICv3 258 Level
...

It is better to register all the irqs during probe function via devm_request_irq()
to avoid to call free_irq().

Signed-off-by: Fugang Duan <fugang.duan@nxp.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-09-18 18:19:21 +02:00
Andy Shevchenko
3d6bcddf54 serial: fsl_lpuart: Avoid using irq_wake flag
There is no need to duplicate a flag which IRQ core takes care of.

Replace custom flag by IRQ core API that retrieves its state.

Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Dong Aisheng <aisheng.dong@nxp.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-08-28 20:51:19 +02:00
Uwe Kleine-König
68c338eaa0 serial: fsl_lpuart: clear unsupported options in .rs485_config()
The struct serial_rs485 parameter is both input and output and is
supposed to hold the actually used configuration on return. So clear
unsupported settings.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-07-30 07:46:06 -07:00
Greg Kroah-Hartman
329f0a8a35 Merge 4.13-rc2 into tty-next
We want the tty/serial fixes in here as well.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-07-23 20:04:33 -07:00
Marius Vlad
a5fa2660d7 tty/serial/fsl_lpuart: Add CONSOLE_POLL support for lpuart32.
This mirrors commit 2a41bc2a2b but for 32-bit register definitions.

Fix a minor typo while at it.

Signed-off-by: Marius Vlad <marius.vlad0@gmail.com>
CC: Nicolae Rosia <nicolae_rosia@mentor.com>
CC: Stefan Golinschi <stefan.golinschi@gmail.com>
CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-07-18 09:28:29 +02:00
Fabio Estevam
3ee5447e8c tty: serial: lpuart: Fix the logic for detecting the 32-bit type UART
Commit 0d6fce9044 ("tty: serial: lpuart: introduce lpuart_soc_data to
represent SoC property") introduced a buggy logic for detecting the 32-bit
type UART since the condition: "if (sport->port.iotype & UPIO_MEM32BE)"
is always true.

Performing such bitfield AND operation is not correct, because in the
case of Vybrid UART iotype is UPIO_MEM (2), so:

UPIO_MEM & UPIO_MEM32BE = 010 & 110 = 010, which is true.

Such logic tells the driver to always treat the UART operations as 32-bit,
leading to the driver misbehavior on Vybrid.

Fix the 32-bit type detection logic to avoid UART breakage on Vybrid.

While at it, introduce a lpuart_is_32() function to help readability.

Fixes: 0d6fce9044 ("tty: serial: lpuart: introduce lpuart_soc_data to represent SoC property")
Reported-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com>
Reviewed-by: Dong Aisheng <aisheng.dong@nxp.com>
Tested-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-07-17 14:14:24 +02:00
Dong Aisheng
a6d7514b14 tty: serial: lpuart: add a more accurate baud rate calculation method
On new LPUART versions, the oversampling ratio for the receiver can be
changed from 4x (00011) to 32x (11111) which could help us get a more
accurate baud rate divider.

The idea is to use the best OSR (over-sampling rate) possible.
Note, OSR is typically hard-set to 16 in other LPUART instantiations.
Loop to find the best OSR value possible, one that generates minimum
baud diff iterate through the rest of the supported values of OSR.

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Mingkai Hu <Mingkai.Hu@nxp.com>
Cc: Yangbo Lu <yangbo.lu@nxp.com>
Acked-by: Fugang Duan <fugang.duan@nxp.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-06-29 17:12:34 +02:00
Dong Aisheng
97d6f353da tty: serial: lpuart: add earlycon support for imx7ulp
earlycon is executed quite early before the device tree probe,
so we need correctly initialize the port membase and iotype for
imx7ulp during early console setup before using.

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Mingkai Hu <Mingkai.Hu@nxp.com>
Cc: Yangbo Lu <yangbo.lu@nxp.com>
Acked-by: Fugang Duan <fugang.duan@nxp.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-06-29 17:12:34 +02:00
Dong Aisheng
24b1e5f0e8 tty: serial: lpuart: add imx7ulp support
The lpuart of imx7ulp is basically the same as ls1021a. It's also
32 bit width register, but unlike ls1021a, it's little endian.
Besides that, imx7ulp lpuart has a minor different register layout
from ls1021a that it has four extra registers (verid, param, global,
pincfg) located at the beginning of register map, which are currently
not used by the driver and less to be used later.

To ease the register difference handling, we add a reg_off member
in lpuart_soc_data structure to represent if the normal
lpuart32_{read|write} requires plus a offset to hide the issue.

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Mingkai Hu <Mingkai.Hu@nxp.com>
Cc: Yangbo Lu <yangbo.lu@nxp.com>
Cc: Fugang Duan <fugang.duan@nxp.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-06-29 17:12:34 +02:00
Dong Aisheng
f98e1fcd96 tty: serial: lpuart: add little endian 32 bit register support
Use standard port->iotype to distinguish endian difference. Note as we
read/write register by checking iotype dynamically, we need to initialize
the iotype correctly for earlycon as well to avoid a break.

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com> (supporter:TTY LAYER)
Cc: Stefan Agner <stefan@agner.ch>
Cc: Mingkai Hu <Mingkai.Hu@nxp.com>
Cc: Yangbo Lu <yangbo.lu@nxp.com>
Cc: Fugang Duan <fugang.duan@nxp.com>
Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
Cc: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>

ChangeLog:
v3->v4:
 * Removed unneeded semicolon catched by 0day Robot.
v2->v3:
 * Instead of using global var, use standard port->iotype to distinguish
   endian difference.
v1->v2:
 * No changes
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-06-29 17:12:33 +02:00
Dong Aisheng
a0204f25e1 tty: serial: lpuart: refactor lpuart32_{read|write} prototype
Due to the original lpuart32_read/write takes no port specific
information arguments, it's hard to distinguish port difference
within the API. Although it works before, but not suitable anymore
when adding more new chips support.

So let's convert it to accept a new struct uart_port argument
to make it be able to retrieve more port specific information.
This is a preparation for the later adding new chips support
more easily. No functions changes.

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Mingkai Hu <Mingkai.Hu@nxp.com>
Cc: Yangbo Lu <yangbo.lu@nxp.com>
Cc: Fugang Duan <fugang.duan@nxp.com>
Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
Cc: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-06-29 17:12:33 +02:00
Dong Aisheng
0d6fce9044 tty: serial: lpuart: introduce lpuart_soc_data to represent SoC property
This is used to dynamically check the SoC specific lpuart properies.
Currently only the iotype is added, it functions the same as before.
With this, new chips with different iotype will be more easily added.

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Mingkai Hu <Mingkai.Hu@nxp.com>
Cc: Yangbo Lu <yangbo.lu@nxp.com>
Cc: Fugang Duan <fugang.duan@nxp.com>
Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
Cc: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-06-29 17:12:33 +02:00
Stefan Agner
abf1e0a980 tty: serial: fsl_lpuart: lock port on console write
The console write code is not entirely race free (e.g. the operations
to disabling the UART interrupts are not atomic) hence locking is
required. This has been become apparent with the PREEMPT RT patchset
applied: With the fully preemptible kernel configuration the system
often ended up in a freeze already at startup.

Disable interrupts and lock using read_lock_irqsave. Try to lock in
the sysrq/oops case, but don't bother if locking fails.

Signed-off-by: Stefan Agner <stefan@agner.ch>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-03-31 16:56:10 +02:00
Nikita Yushchenko
54a44d54be tty: serial: fsl_lpuart: fix del_timer_sync() vs timer routine deadlock
Problem found via lockdep:

- lpuart_set_termios() calls del_timer_sync(&sport->lpuart_timer) while
  holding sport->port.lock

- sport->lpuart_timer routine is lpuart_timer_func() that calls
  lpuart_copy_rx_to_tty() that acquires same lock.

To fix, move Rx DMA stopping out of lock, as it already is in other places
in the same file.

While at it, also make Rx DMA start/stop code to look the same is in
other places in the same file.

Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Tested-by: Stefan Agner <stefan@agner.ch>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-01-12 11:51:24 +01:00
Greg Kroah-Hartman
5131dcd781 Merge 4.9-rc3 into tty-next
We want the serial/tty fixes in here as well.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-10-30 06:42:10 -04:00
Greg Kroah-Hartman
463e2a2b89 serial: fsl_lpuart: remove build warning
commit 2a41bc2a2b ("tty: serial: fsl_lpuart: add polled console
functions") caused a build warning about an unused variable, so fix it.

Reported-by: kbuild test robot <fengguang.wu@intel.com>
Cc: Nicolae Rosia <nicolae_rosia@mentor.com>
Cc: Stefan Golinschi <stefan.golinschi@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-10-28 02:47:35 -04:00
Aaron Brice
d704b2d32c tty: serial: fsl_lpuart: Fix Tx DMA edge case
In the case where head == 0 on the circular buffer, there should be one
DMA buffer, not two.  The second zero-length buffer would break the
lpuart driver, transfer would never complete.

Signed-off-by: Aaron Brice <aaron.brice@datasoft.com>
Acked-by: Stefan Agner <stefan@agner.ch>
Tested-by: Stefan Agner <stefan@agner.ch>
Tested-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-10-27 16:41:56 +02:00
Nicolae Rosia
2a41bc2a2b tty: serial: fsl_lpuart: add polled console functions
This adds polling functions as used by kgdb.

Signed-off-by: Nicolae Rosia <nicolae_rosia@mentor.com>
Signed-off-by: Stefan Golinschi <stefan.golinschi@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-10-27 16:27:24 +02:00
Wei Yongjun
33ddca08bf tty: serial: fsl_lpuart: use GFP_ATOMIC under spin lock
The function lpuart_start_rx_dma() is called from several
places, in some of which, such as lpuart_startup(), a lock
be held here, so we should use GFP_ATOMIC when a lock is held.

Fixes: 5887ad43ee ("tty: serial: fsl_lpuart: Use cyclic DMA for Rx")
Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-09-15 12:35:49 +02:00
Julia Lawall
069a47e5ad tty: serial: constify uart_ops structures
Check for uart_ops structures that are only stored in the ops field of a
uart_port structure.  This field is declared const, so uart_ops structures
that have this property can be declared as const also.

The semantic patch that makes this change is as follows:
(http://coccinelle.lip6.fr/)

// <smpl>
@r disable optional_qualifier@
identifier i;
position p;
@@
static struct uart_ops i@p = { ... };

@ok@
identifier r.i;
struct uart_port e;
position p;
@@
e.ops = &i@p;

@bad@
position p != {r.p,ok.p};
identifier r.i;
struct uart_ops e;
@@
e@i@p

@depends on !bad disable optional_qualifier@
identifier r.i;
@@
static
+const
 struct uart_ops i = { ... };
// </smpl>

Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-09-02 15:01:16 +02:00
Bhuvanchandra DV
03895cf41d tty: serial: fsl_lpuart: Add support for RS-485
Enable Vybrid's build-in support for RS-485 auto RTS for controlling line
direction of RS-485 transceiver driver.

Enable RS485 feature by either using ioctrl 'TIOCSRS485' or enable it in the
device tree by setting 'linux,rs485-enabled-at-boot-time' property.

Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-08-31 15:48:29 +02:00
Bhuvanchandra DV
c05efd692f tty: serial: fsl_lpuart: Update suspend/resume for DMA mode
When DMA mode is enabled one need to make sure the DMA channels are idle before
entering suspend mode especially when UART ports which are set as wakeup source
and console port with no_console_suspend is set. This patch takes care of
gracefully releasing DMA channels for the above two cases and start the DMA at
resume.

Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-08-31 15:48:29 +02:00
Bhuvanchandra DV
6250cc30c4 tty: serial: fsl_lpuart: Use scatter/gather DMA for Tx
Drop PIO to DMA switching and use scatter/gather DMA for Tx path to improve
performance.

Some part of the code is borrowed from imx serial driver.

Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-08-31 15:48:29 +02:00
Bhuvanchandra DV
5887ad43ee tty: serial: fsl_lpuart: Use cyclic DMA for Rx
The initial approach of DMA implementatin for RX is inefficient due to switching
from PIO to DMA, this leads to overruns especially on instances with the smaller
FIFO. To address these issues this patch uses a cyclic DMA for receiver path.

Some part of the code is borrowed from atmel serial driver.

Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-08-31 15:48:29 +02:00
Bhuvanchandra DV
aa9e7d7803 tty: serial: fsl_lpuart: Fix broken 8m/s1 support
By default the driver always configure the mode as 8s1 even when 8m1 mode is
selected. Fix this by adding support to control the space/mark bit.

Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-08-31 15:48:28 +02:00
Stefan Agner
d68827c62a tty: serial: fsl_lpuart: fix clearing of receive flag
Commit 8e4934c6d6 ("tty: serial: fsl_lpuart: clear receive flag on FIFO
flush") implemented clearing of the receive flag by reading the status register
only. It turned out that even though we flush the FIFO afterwards, a explicit
read of the data register is still required.

This leads to a FIFO underrun. To avoid this, follow the advice in the overrun
"Operation section": Unconditionally clear RXUF after using RXFLUSH.

Signed-off-by: Stefan Agner <stefan@agner.ch>
Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-08-31 15:48:28 +02:00
Stefan Agner
d6b0d2f243 tty: serial: fsl_lpuart: support suspend/resume
Add suspend/resume support.

Signed-off-by: Stefan Agner <stefan@agner.ch>
Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-08-31 15:48:28 +02:00
Stefan Agner
b70b636186 tty: serial: fsl_lpuart: consider TX FIFO too in tx_empty
Currently the tx_empty callback only considers the Transmit Complete Flag (TC).
The reference manual is not quite clear if the TC flag covers the TX FIFO too.
Debug prints on real hardware have shown that from time to time the TC flag is
asserted (indicating Transmitter idle) while there are still data in the
TX FIFO. Hence, in this case the serial core will call the shutdown callback
even though there are data remaining in the TX FIFO buffers.

Avoid early shutdowns by considering the TX FIFO empty flag too. Also avoid
theoretical race conditions between DMA and the driver by checking whether the
TX DMA is in progress too.

Signed-off-by: Stefan Agner <stefan@agner.ch>
Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-08-31 15:48:28 +02:00
Jiri Slaby
394a9e2ca2 TTY: serial, handle platform_get_irq retval properly
platform_get_irq can fail, so we should handle negative value when
returned.

[v2]

platform_get_irq can actually return zero on some platforms. So do not
remove checks for irq == 0 there.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: "Uwe Kleine-König" <kernel@pengutronix.de>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Laxman Dewangan <ldewangan@nvidia.com>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Alexandre Courbot <gnurou@gmail.com>
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-tegra@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-06-25 09:01:52 -07:00
Stefan Agner
1d59b382f1 serial: fsl_lpuart: add earlycon support
Add support for DT and command line based earlycon support for
lpuart and lpuart32 used on Freescale Vybrid and and QorIQ LS1021A
processors.

Signed-off-by: Stefan Agner <stefan@agner.ch>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-17 21:18:30 -07:00
Greg Kroah-Hartman
b3e3bf2ef2 Merge 4.0-rc7 into tty-next
We want the fixes in here as well, also to help out with merge issues.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-04-07 11:07:20 +02:00
Stefan Agner
8e4934c6d6 tty: serial: fsl_lpuart: clear receive flag on FIFO flush
When the receiver was enabled during startup, a character could
have been in the FIFO when the UART get initially used. The
driver configures the (receive) watermark level, and flushes the
FIFO. However, the receive flag (RDRF) could still be set at that
stage (as mentioned in the register description of UARTx_RWFIFO).
This leads to an interrupt which won't be handled properly in
interrupt mode: The receive interrupt function lpuart_rxint checks
the FIFO count, which is 0 at that point (due to the flush
during initialization). The problem does not manifest when using
DMA to receive characters.

Fix this situation by explicitly read the status register, which
leads to clearing of the RDRF flag. Due to the flush just after
the status flag read, a explicit data read is not to required.

Signed-off-by: Stefan Agner <stefan@agner.ch>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-03-26 23:13:14 +01:00
Stefan Agner
4e8f245937 tty: serial: fsl_lpuart: specify transmit FIFO size
Specify transmit FIFO size which might be different depending on
LPUART instance. This makes sure uart_wait_until_sent in serial
core getting called, which in turn waits and checks if the FIFO
is really empty on shutdown by using the tx_empty callback.
Without the call of this callback, the last several characters
might not yet be transmitted when closing the serial port. This
can be reproduced by simply using echo and redirect the output to
a ttyLP device.

Signed-off-by: Stefan Agner <stefan@agner.ch>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-03-26 23:13:14 +01:00
Fabian Frederick
ed0bb2323c tty: constify of_device_id array
of_device_id is always used as const.
(See driver.of_match_table and open firmware functions)

Signed-off-by: Fabian Frederick <fabf@skynet.be>
Acked-by: Peter Korsgaard <peter@korsgaard.com>
Acked-by: Timur Tabi <timur@tabi.org>
Acked-by: Patrice Chotard <patrice.chotard@st.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-03-26 22:49:10 +01:00
Stefan Agner
bfc2e07f91 tty: serial: fsl_lpuart: terminate DMA on buffer flush
On uart buffer flush, serial core resets the circular buffer.
If a DMA transfer is in progress at that time, the callback
lpuart_dma_tx_complete will move buffer's tail unconditionally,
hence tail moves beyond head. Use the flush_buffer hook to
terminate the DMA imeaditely and avoid lpuart_dma_tx_complete
being called in this situation.

This bug often showed up while shutdown and lead to duplicate
serial console output.

Signed-off-by: Stefan Agner <stefan@agner.ch>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-02-02 10:09:55 -08:00
Yuan Yao
2fe605df32 serial: fsl-lpuart: disable interrupt when suspend
For power management support, we should disable TX and
TX interrupt so that kernel can prepare for deep sleep.

Retain RX and RX interrupt for wakeup the kernel when
receive the input character.

Signed-off-by: Yuan Yao <yao.yuan@freescale.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-02-02 10:09:55 -08:00
Stefan Agner
011f5bde62 serial: fsl_lpuart: update RX timer on successful DMA transfer
To end a DMA transfer which did not consume a whole buffer (e.g. one
character only), a RX timer is used. When lots of data are received
the DMA transfer will complete and setup another DMA transfer, which
in turn might complete again. In this cases, it is not necessary to
abort the DMA transfers using the RX timer. This change pushes the
RX timer timeout into the future each time a DMA transfer completed.

Aborting the DMA was not very harmful, since the next received
character lead to setup of another RX DMA.

Signed-off-by: Stefan Agner <stefan@agner.ch>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-02-02 10:09:55 -08:00
Stefan Agner
4a818c4396 serial: fsl_lpuart: move DMA channel request to probe
Move the DMA channel request to probe to avoid requesting the DMA
channel on each opening of the ttyLPx device. This also fixes a
potential issue that TX channel is not freed when only RX channel
allocation fails. The DMA channels are now handled independently,
so one could use UART with DMA only in TX direction for instance.

Signed-off-by: Stefan Agner <stefan@agner.ch>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-02-02 10:09:55 -08:00
Stefan Agner
5f1437f61a serial: fsl_lpuart: avoid new transfer while DMA is running
When the UART is in DMA receive mode (RDMAS set) and one character
just arrived while another interrupt is handled (e.g. TX), the RDRF
(receiver data register full flag) is set due to the water level of
1. But since the DMA will take care of this character, there is no
need to handle it by calling lpuart_prepare_rx. Handling it leads to
adding the RX timeout timer twice:

[   74.336698] Kernel BUG at 80053070 [verbose debug info unavailable]
[   74.342999] Internal error: Oops - BUG: 0 [#1] ARM0:00.00 khungtaskd
[   74.347817] Modules linked in:    0 S  0.0  0.0   0:00.00 writeback
[   74.350926] CPU: 0 PID: 0 Comm: swapper Not tainted 3.19.0-rc3-00001-g39d78e2 #1788
[   74.358617] Hardware name: Freescale Vybrid VF610 (Device Tree)t
[   74.364563] task: 807a7678 ti: 8079c000 task.ti: 8079c000 kblockd
[   74.370002] PC is at add_timer+0x24/0x28.0  0.0   0:00.09 kworker/u2:1
[   74.373960] LR is at lpuart_int+0x15c/0x3d8
[   74.378171] pc : [<80053070>]    lr : [<802e0d88>]    psr: a0010193
[   74.378171] sp : 8079de10  ip : 8079de20  fp : 8079de1c
[   74.389694] r10: 807d44c0  r9 : 8688c300  r8 : 00000013
[   74.394943] r7 : 20010193  r6 : 00000000  r5 : 000000a0  r4 : 86997210
[   74.401498] r3 : ffffa7da  r2 : 80817868  r1 : 86997210  r0 : 86997344
[   74.408052] Flags: NzCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
[   74.415489] Control: 10c5387d  Table: 8611c059  DAC: 00000015
[   74.421265] Process swapper (pid: 0, stack limit = 0x8079c230)
...

Solve this by only execute the receiver path (lpuart_prepare_rx) if
the DMA receive mode (RDMAS) is not set. Also, make sure the flag is
cleared on initialization, in case it has been left set.

This can be best reproduced using UART as a serial console, then
running top while dd'ing data into the terminal.

Signed-off-by: Stefan Agner <stefan@agner.ch>
Cc: stable <stable@vger.kernel.org> # 3.14
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-02-02 10:09:55 -08:00
Stefan Agner
4a8588a1cf serial: fsl_lpuart: delete timer on shutdown
If the serial port gets closed while a RX transfer is in progress,
the timer might fire after the serial port shutdown finished. This
leads in a NULL pointer dereference:

[    7.508324] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[    7.516590] pgd = 86348000
[    7.519445] [00000000] *pgd=86179831, *pte=00000000, *ppte=00000000
[    7.526145] Internal error: Oops: 17 [#1] ARM
[    7.530611] Modules linked in:
[    7.533876] CPU: 0 PID: 123 Comm: systemd Not tainted 3.19.0-rc3-00004-g5b11ea7 #1778
[    7.541827] Hardware name: Freescale Vybrid VF610 (Device Tree)
[    7.547862] task: 861c3400 ti: 86ac8000 task.ti: 86ac8000
[    7.553392] PC is at lpuart_timer_func+0x24/0xf8
[    7.558127] LR is at lpuart_timer_func+0x20/0xf8
[    7.562857] pc : [<802df99c>]    lr : [<802df998>]    psr: 600b0113
[    7.562857] sp : 86ac9b90  ip : 86ac9b90  fp : 86ac9bbc
[    7.574467] r10: 80817180  r9 : 80817b98  r8 : 80817998
[    7.579803] r7 : 807acee0  r6 : 86989000  r5 : 00000100  r4 : 86997210
[    7.586444] r3 : 86ac8000  r2 : 86ac9bc0  r1 : 86997210  r0 : 00000000
[    7.593085] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
[    7.600341] Control: 10c5387d  Table: 86348059  DAC: 00000015
[    7.606203] Process systemd (pid: 123, stack limit = 0x86ac8230)

Setup the timer on UART startup which allows to delete the timer
unconditionally on shutdown. This also saves the initialization
on each transfer.

Signed-off-by: Stefan Agner <stefan@agner.ch>
Cc: stable <stable@vger.kernel.org> # 3.14
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-02-02 10:09:54 -08:00
Linus Torvalds
e6b5be2be4 Driver core patches for 3.19-rc1
Here's the set of driver core patches for 3.19-rc1.
 
 They are dominated by the removal of the .owner field in platform
 drivers.  They touch a lot of files, but they are "simple" changes, just
 removing a line in a structure.
 
 Other than that, a few minor driver core and debugfs changes.  There are
 some ath9k patches coming in through this tree that have been acked by
 the wireless maintainers as they relied on the debugfs changes.
 
 Everything has been in linux-next for a while.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iEYEABECAAYFAlSOD20ACgkQMUfUDdst+ylLPACg2QrW1oHhdTMT9WI8jihlHVRM
 53kAoLeteByQ3iVwWurwwseRPiWa8+MI
 =OVRS
 -----END PGP SIGNATURE-----

Merge tag 'driver-core-3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core

Pull driver core update from Greg KH:
 "Here's the set of driver core patches for 3.19-rc1.

  They are dominated by the removal of the .owner field in platform
  drivers.  They touch a lot of files, but they are "simple" changes,
  just removing a line in a structure.

  Other than that, a few minor driver core and debugfs changes.  There
  are some ath9k patches coming in through this tree that have been
  acked by the wireless maintainers as they relied on the debugfs
  changes.

  Everything has been in linux-next for a while"

* tag 'driver-core-3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (324 commits)
  Revert "ath: ath9k: use debugfs_create_devm_seqfile() helper for seq_file entries"
  fs: debugfs: add forward declaration for struct device type
  firmware class: Deletion of an unnecessary check before the function call "vunmap"
  firmware loader: fix hung task warning dump
  devcoredump: provide a one-way disable function
  device: Add dev_<level>_once variants
  ath: ath9k: use debugfs_create_devm_seqfile() helper for seq_file entries
  ath: use seq_file api for ath9k debugfs files
  debugfs: add helper function to create device related seq_file
  drivers/base: cacheinfo: remove noisy error boot message
  Revert "core: platform: add warning if driver has no owner"
  drivers: base: support cpu cache information interface to userspace via sysfs
  drivers: base: add cpu_device_create to support per-cpu devices
  topology: replace custom attribute macros with standard DEVICE_ATTR*
  cpumask: factor out show_cpumap into separate helper function
  driver core: Fix unbalanced device reference in drivers_probe
  driver core: fix race with userland in device_add()
  sysfs/kernfs: make read requests on pre-alloc files use the buffer.
  sysfs/kernfs: allow attributes to request write buffer be pre-allocated.
  fs: sysfs: return EGBIG on write if offset is larger than file size
  ...
2014-12-14 16:10:09 -08:00