From: Matthew Howell <matthew.howell@sealevel.com>
To: "ilpo.jarvinen@linux.intel.com" <ilpo.jarvinen@linux.intel.com>
Cc: "linux-serial@vger.kernel.org" <linux-serial@vger.kernel.org>,
Darren Beeson <darren.beeson@sealevel.com>,
"gregkh@linuxfoundation.org" <gregkh@linuxfoundation.org>,
Jeff Baldwin <jeff.baldwin@sealevel.com>,
Ryan Wenglarz <ryan.wenglarz@sealevel.com>
Subject: Re: [PATCH V2] serial: exar: Preserve FCTR[5] bit in pci_xr17v35x_setup()
Date: Thu, 11 Apr 2024 17:01:08 +0000 [thread overview]
Message-ID: <3de81ecf80f1cf16d8040e60f4582ad581ecefde.camel@sealevel.com> (raw)
In-Reply-To: <da99e0fa-47a2-42e3-7b29-85dda41c3bbd@linux.intel.com>
On Thu, 2024-04-11 at 11:27 +0300, Ilpo Järvinen wrote:
> On Wed, 10 Apr 2024, Matthew Howell wrote:
> > On Wed, 2024-04-10 at 16:49 +0300, Ilpo Järvinen wrote:
> > > On Mon, 8 Apr 2024, Matthew Howell wrote:
> > > > On Mon, 2024-04-08 at 19:48 +0300, Ilpo Järvinen wrote:
> > > > > On Mon, 8 Apr 2024, Matthew Howell wrote:
> > > > >
> > > > > > On Wed, 2024-02-21 at 16:16 -0500, Matthew Howell wrote:
> > > > > > > Allows the use of the EN485 hardware pin by preserving the value of
> > > > > > > FCTR[5] in pci_xr17v35x_setup().
> > > > > > >
> > > > > > > Per the XR17V35X datasheet, the EN485 hardware pin works by setting
> > > > > > > FCTR[5] when the pin is active. pci_xr17v35x_setup() prevented the use
> > > > > > > of EN485 because it overwrote the FCTR register.
> > > > > > >
> > > > > > > Signed-off-by: Matthew Howell <matthew.howell@sealevel.com>
> > > > > > > ---
> > > > > > > V1 -> V2
> > > > > > > Fixed wordwrap in diff
> > > > > > >
> > > > > > > diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c
> > > > > > > index 23366f868..97711606f 100644
> > > > > > > --- a/drivers/tty/serial/8250/8250_exar.c
> > > > > > > +++ b/drivers/tty/serial/8250/8250_exar.c
> > > > > > > @@ -596,6 +596,7 @@ pci_xr17v35x_setup(struct exar8250 *priv, struct pci_dev *pcidev,
> > > > > > > unsigned int baud = 7812500;
> > > > > > > u8 __iomem *p;
> > > > > > > int ret;
> > > > > > > + u8 en485mask;
> > > > > > >
> > > > > > > port->port.uartclk = baud * 16;
> > > > > > > port->port.rs485_config = platform->rs485_config;
> > > > > > > @@ -618,7 +619,8 @@ pci_xr17v35x_setup(struct exar8250 *priv, struct pci_dev *pcidev,
> > > > > > > p = port->port.membase;
> > > > > > >
> > > > > > > writeb(0x00, p + UART_EXAR_8XMODE);
> > > > > > > - writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR);
> > > > > > > + en485mask = readb(p + UART_EXAR_FCTR) & UART_FCTR_EXAR_485;
> > > > > > > + writeb(UART_FCTR_EXAR_TRGD | en485mask, p + UART_EXAR_FCTR);
> > > > > > > writeb(128, p + UART_EXAR_TXTRG);
> > > > > > > writeb(128, p + UART_EXAR_RXTRG);
> > > > >
> > > > > Why you need to read rs485 state from the register? It should be available
> > > > > in ->rs485.flags & SER_RS485_ENABLED.
> > > > >
> > > >
> > > > Please correct me if I am wrong, but my understanding is that
> > > > SER_RS485_ENABLED is set from userspace using the TIOCRS485 IOCTL.
> > >
> > > Thought that and device_property_read_bool(dev,
> > > "linux,rs485-enabled-at-boot-time")
> > >
> >
> > I am not familiar with that property. Is that something that can be set
> > in userspace or via a kernel parameter? Or is it 'hard-coded' into the
> > device tree binding for a particular device?
>
> Through DT, yes (or ACPI equivalent).
>
> > > > However, this is not the only way that the FCTR register can be changed.
> > > > In particular, per XR17V35X datasheet, the EN485 pin is sampled on
> > > > power-on and transfers the logic state to FCTR[5]. Our card takes
> > > > advantage of this to allow users to configure RS485 in scenarios where
> > > > they cannot, or do not want to, modify their software to set
> > > > SER_RS485_ENABLED.
> > > >
> > > > However, this functionality of the UART does not currently work with
> > > > this driver because the entire FCTR register is being overwritten,
> > > > thereby erasing whatever value was written to FCTR[5] on UART power-up.
> > > >
> > > > The driver cannot know whether FCTR[5] was set on power-up without
> > > > reading the FCTR, therefore it must be read.
> > >
> > > ???
> > >
> > > Are you saying RS485 is enabled without kernel knowing about it? I don't
> > > think that's the correct way to do things.
> >
> > That is correct. However, I wouldn't say it is an incorrect way of doing
> > things. Some reasoning/justification below:
> >
> > * Kernel/Driver/Software independent RS485 Auto Enable is not new. I
> > can't speak for other vendors, but Sealevel has been creating products
> > with this functionality for several decades, dating back to at least
> > 1994.
> >
> > * In those products, the kernel was *necessarily* entirely unaware of
> > whether RS485 was in use because most OS's and applications did not
> > support RS485 at the time and as such was implement to be entirely
> > transparent to the OS and application.
> >
> > * Since then, many UARTs have integrated Auto RS485 Enable into a single
> > package and we have moved towards utilizing this integrated
> > functionality when it is available.
> >
> > * I say the above to point out that there is a long history of RS485
> > Auto Enable without kernel involvement, and therefore in my view it is
> > just as valid to have RS485 Auto Enabled set via hardware without the
> > kernel being aware as it is for the kernel to be aware.
>
> Is this "Auto" thing done with some dip switches/jumpers and is cast to
> stone after hw init? So driver's .probe() could just read that state
> and adjust kernel rs485 state based one it?
>
The behaviour of the patch at the moment is that changes to
SER_RS485_ENABLED can 'reset' the state of FCTR[5]. For example, if an
application sets SER_RS485_ENABLED to true, then back to false, the card
will lose the Auto-RS485 Enable setting.
On one hand, this provides users a method of 'resetting' FCTR[5] on a
channel that they do not want to be RS485 in order to work around that
limitation of the EN485 pin, but on the other it a little bit weird to
enabling and hen disabling SER_RS485_ENABLED does not leave you where
you in the state started if EN485 was asserted at boot.
> > * Finally, to the day many applications still do not support RS485.
> > Therefore, having the ability to set RS485 via hardware is still a
> > valuable feature for users, and one that Exar/Maxlinear seems to have
> > recognized, as I don't know why they would even have the EN485 pin if
> > not for this sort of use-case.
>
> Once the serial line has been transitioned into RS485 mode, userspace does
> not need to be aware of it (which can happen through DT so no userspace
> involvement). So this shouldn't be seen as a problem.
>
Ah, I had missed of_add_property() in the Device Tree kernel API.
Would it be appropriate to find and modify the device tree node from
exar_pci_probe()? I ask because it looks like all or most device tree
operations in the 8250 driver are confined to 8250_of.c, but I believe
the FCTR is specific to Exar so I think your suggestion of checking the
register value during probe makes sense.
> > Perhaps the optimal solution would be if there were a method for the
> > hardware to inform the kernel that it is configured for RS485 Auto
> > Enable via hardware, but I'm not aware of a supported way of doing this.
> > The only thing I can think of at the moment is just a check in the
> > init/setup that sets SER_RS485_ENABLED if FCTR[5] is enabled. I don't
> > know if this would be considered an improvement though.
>
> I don't think such mechanism exists beyond DT currently, but I don't see
> why it could be added.
> --
> i.
If DT already has a mechanism that can be used I would rather do that
than add additional mechanisms for the same thing.
--
Matthew H.
next prev parent reply other threads:[~2024-04-11 17:01 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-21 21:06 [PATCH V1] serial: exar: Preserve FCTR[5] bit in pci_xr17v35x_setup() Matthew Howell
2024-02-21 21:16 ` [PATCH V2] " Matthew Howell
2024-02-21 22:58 ` andy.shevchenko
2024-04-09 13:01 ` Matthew Howell
2024-04-08 13:11 ` Matthew Howell
2024-04-08 14:56 ` gregkh
2024-04-09 12:33 ` Matthew Howell
2024-04-08 16:48 ` Ilpo Järvinen
2024-04-08 17:25 ` Ilpo Järvinen
2024-04-08 20:27 ` Matthew Howell
2024-04-10 13:49 ` Ilpo Järvinen
2024-04-10 16:20 ` Matthew Howell
2024-04-11 8:27 ` Ilpo Järvinen
2024-04-11 17:01 ` Matthew Howell [this message]
2024-04-11 20:44 ` Matthew Howell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3de81ecf80f1cf16d8040e60f4582ad581ecefde.camel@sealevel.com \
--to=matthew.howell@sealevel.com \
--cc=darren.beeson@sealevel.com \
--cc=gregkh@linuxfoundation.org \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=jeff.baldwin@sealevel.com \
--cc=linux-serial@vger.kernel.org \
--cc=ryan.wenglarz@sealevel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox