1. 28 11月, 2017 3 次提交
  2. 22 11月, 2017 1 次提交
    • K
      treewide: setup_timer() -> timer_setup() · e99e88a9
      Kees Cook 提交于
      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: NKees Cook <keescook@chromium.org>
      e99e88a9
  3. 08 11月, 2017 2 次提交
    • G
      tty: serial: Remove redundant license text · 4793f2eb
      Greg Kroah-Hartman 提交于
      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: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      4793f2eb
    • G
      tty: add SPDX identifiers to all remaining files in drivers/tty/ · e3b3d0f5
      Greg Kroah-Hartman 提交于
      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: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      e3b3d0f5
  4. 04 11月, 2017 3 次提交
  5. 20 10月, 2017 1 次提交
  6. 04 10月, 2017 6 次提交
  7. 19 9月, 2017 1 次提交
  8. 29 8月, 2017 2 次提交
  9. 30 7月, 2017 1 次提交
  10. 17 7月, 2017 2 次提交
  11. 29 6月, 2017 3 次提交
  12. 25 5月, 2017 1 次提交
  13. 18 5月, 2017 1 次提交
  14. 12 4月, 2017 1 次提交
  15. 09 4月, 2017 1 次提交
  16. 31 1月, 2017 2 次提交
    • F
      serial: imx: Fix the CTS_B polarity in RS485 mode · bc2be239
      Fabio Estevam 提交于
      When userspace passes the SER_RS485_RTS_ON_SEND flag it means that the
      CTS_B pin should go to logic level high before the transmission begins.
      
      CTS_B goes to logic level high when both CTSC and CTS bits are cleared.
      
      When userspace passes the SER_RS485_RTS_AFTER_SEND flag it means that the
      CTS_B pin should go to logic level low after the transmission finishes.
      
      CTS_B goes to logic level low when CTSC bit is cleared and CTS bit is set.
      
      So fix the CTS_B polarity logic.
      Signed-off-by: NFabio Estevam <fabio.estevam@nxp.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      bc2be239
    • F
      serial: imx: Fix the RTS GPIO polarity in RS485 mode · 1a613626
      Fabio Estevam 提交于
      On a board that needs to drive RTS GPIO high in order to enable the
      transmission of a RS485 transceiver the following description is
      passed in the devide tree:
      
      &uart4 {
              pinctrl-names = "default";
              pinctrl-0 = <&pinctrl_uart4>;
              rts-gpios = <&gpio6 2 GPIO_ACTIVE_HIGH>;
              status = "okay";
      };
      
      and userspace configures the uart port as follows:
      
      /* enable RS485 mode: */
      rs485conf.flags |= SER_RS485_ENABLED;
      
      /* set logical level for RTS pin equal to 1 when sending: */
      rs485conf.flags |= SER_RS485_RTS_ON_SEND;
      
      /* set logical level for RTS pin equal to 0 after sending: */
      rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);
      
      However the RTS GPIO polarity observed in the oscilloscope is inverted.
      
      When the SER_RS485_RTS_ON_SEND flag is set the imx_port_rts_active()
      function should be called and following the same logic when
      SER_RS485_RTS_AFTER_SEND flag is cleared the imx_port_rts_inactive()
      should be called.
      
      Do such logic change so that RS485 communication in half duplex can
      work successfully when the RTS GPIO pin is passed via device tree.
      Signed-off-by: NFabio Estevam <fabio.estevam@nxp.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      1a613626
  17. 12 1月, 2017 1 次提交
  18. 27 9月, 2016 1 次提交
  19. 15 9月, 2016 1 次提交
  20. 14 9月, 2016 1 次提交
  21. 02 9月, 2016 2 次提交
  22. 31 8月, 2016 2 次提交
    • N
      serial: imx-serial - update RX error counters when DMA is used · 41d98b5d
      Nandor Han 提交于
      Update error counters when DMA is used for receiving data. Do
      this by using DMA transaction error event instead error interrupts
      to reduce interrupt load.
      Tested-by: NPeter Senna Tschudin <peter.senna@collabora.com>
      Acked-by: NPeter Senna Tschudin <peter.senna@collabora.com>
      Signed-off-by: NNandor Han <nandor.han@ge.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      41d98b5d
    • N
      serial: imx-serial - update UART IMX driver to use cyclic DMA · 9d297239
      Nandor Han 提交于
      The IMX UART has a 32 bytes HW buffer which can be filled up in
      2777us at 115200 baud or 80us at 4Mbaud (supported by IMX53).
      Taking this in consideration there is a good probability to lose
      data because of the DMA startup latency.
      Our tests (explained below) indicates a latency up to 4400us when
      creating interrupt load and ~70us without. When creating interrupt
      load I was able to see continuous overrun errors by checking serial
      driver statistics using the command:
      `cat /proc/tty/driver/IMX-uart`.
      
      Replace manual restart of DMA with cyclic DMA to eliminate data loss
      due to DMA engine startup latency (similar approch to atmel_serial.c
      driver). As result the DMA engine will start on the first serial data
      transfer and stops only when serial port is closed.
      
      Tests environment:
       Using the m53evk board I have used a GPIO for profiling the IMX
       serial driver.
        - The RX line and GPIO were connected to oscilloscope.
        - Run a small test program on the m53evk board that will only open
          and read data from ttymxc2 port.
        - Connect the ttymxc2 port to my laptop using a USB serial converter
          where another test program is running, able to send configurable
          packet lengths and intervals.
        - Serial ports configured at 115200 8N1.
        - Interrupts load created by disconnecting/connecting (3s interval)
          a USB hub, using a digital switch, with 4 USB devices (USB-Serial
          converter, USB SD card, etc) connected.
          (around 160 interrupts/second generated)
        - The GPIO was toggled HI in the `imx_int` when USR1_RRDY or USR1_AGTIM
          events are received and toggled back, once the DMA configuration
          is finalized, at the end of `imx_dma_rxint`.
      
      Measurements:
      The measurements were done from the end of the last byte (RX line) until
      the GPIO was toggled back LOW.
      
      Note: The GPIO toggling was done using `gpiod_set_value` method.
      
      Tests performed:
         1. Sending 9 bytes packets at 8ms interval. Having the 9 bytes packets
            will activate the RRDY threshold event and IMX serial interrupt
            called.
            Results:
              - DMA start latency (interrupt start latency +
                 DMA configuration) consistently 70us when system not loaded.
              - DMA start latency up to 4400us when system loaded.
         2. Sending 40 bytes packet at 8mS interval.
            Results with load:
              - Able to observe overruns by running:
                 `watch -n1 cat /proc/tty/driver/IMX-uart`
      Tested-by: NPeter Senna Tschudin <peter.senna@collabora.com>
      Acked-by: NPeter Senna Tschudin <peter.senna@collabora.com>
      Signed-off-by: NNandor Han <nandor.han@ge.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      9d297239
  23. 01 5月, 2016 1 次提交