Re: SERIAL_IMX shutdown in RS485 mode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

added Linus Walleij and linux-gpio@vger.k.o to recipients.

On Tue, Sep 11, 2018 at 08:33:06AM +0200, Adam Rudziński wrote:
> W dniu 2018-09-11 o 07:54, Uwe Kleine-König pisze:
> > > I used those older kernels, because in this design I'm using a module, and
> > > the manufacturer provides their Linux distro based on 4.12.4. In particular,
> > > they provide a complete device tree, and that is something where I'm green.
> > > 
> > > However, in 4.19-rc3 the problem will be the same, because the shutdown
> > > function (there called imx_uart_shutdown) seems not to care about rs485, and
> > > does this near the end:
> > > 
> > >      ucr1 = imx_uart_readl(sport, UCR1);
> > >      ucr1 &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN |
> > > UCR1_RXDMAEN | UCR1_ATDMAEN);
> > > 
> > >      imx_uart_writel(sport, ucr1, UCR1);
> > > 
> > > so it just unconditionally disables the UART, like in the older kernels.
> > So disabling the UART results in the CTS output going inactive
> > (according to normal RS232 conventions)? That's independant of UCR2_CTSC
> > and UCR2_CTS? If so, you probably have a problem during power-on and/or
> > driver probe, too. As pinmuxing is set up before imx_uart_probe is
> > called there is a window where your transmitter is already active.
> > 
> > So I'd recommend to stick to the GPIO-variant (i.e. don't use CTS with
> > it's level being controlled by the UART) or at least change the polarity
> > of your transmit-enable such that the transmitter is off when the UART
> > is. (Note that this might enable your transmitter, too, depending on the
> > initial state of the GPIO. Usually it should be "input", so better make
> > sure to add a pull in the disable-direction in hardware.)
> 
> Yes. Actually, keeping control over CTS in IMX requires to keep UART
> enabled (bit 0 in UCR1) and the receiver enabled (bit 1 in UCR2).
> 
> Bullseye! There is a short moment on boot when Linux has already muxed
> the pin to CTS, but didn't configure the peripheral yet. Yesterday
> I've started to prepare a fix, and spent some time trying to
> understand what was happening, just to have come to the same
> conclusion, that it wouldn't work completely well.
> 
> Here, I would argue that it is fundamentally wrong in Linux. I think
> that the correct approach to pinmuxing would be if the driver did that
> when probed. Is there available any mechanism preventing Linux to do
> the pinmuxing but still starting the driver?

In general it's to late to setup pinmuxing only when probe is done. Look
at pinctrl_bind_pins(). That's the function that is called before probe.
It might be possible to hack something with an "init" pinctrl state.
This doesn't help though if the CTS function is already the default
being selected at powerup.

I remember a board with a similar problem which made me create
https://patchwork.kernel.org/patch/9227275/. This depends on hardware
support though.

> If not, then the solution with controlling the CTS field will always
> make a short glitch on startup. Then, I think, as you say, the best
> solution would be to just use a GPIO for that, so the device tree
> should configure UART_TX, UART_RX, and the respective GPIO with
> pull-down enabled. The downside is that this makes it inconsistent
> with non-RS485 use, which might be a problem if a device allowed to
> switch the UART to RS485 or RS232. A potential advantage is freedom of
> selection of the GPIO for control.
> 
> Is there a decent mechanism for a driver to tell
> - what pins are assigned fir this driver, and
> - that a pin is reserved or used by something else in Linux?

I guess you don't want to explore that to determine if it's safe to
disable the UART. IMHO that's too much.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |



[Index of Archives]     [Linux SPI]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux