diff mbox series

[v5,3/3] serial: sc16is7xx: add support for EXAR XR20M1172 UART

Message ID 20240420182223.1153195-4-rilian.la.te@ya.ru
State Superseded
Headers show
Series [v5,1/3] serial: sc16is7xx: announce support of SER_RS485_RTS_ON_SEND | expand

Commit Message

Konstantin Pugin April 20, 2024, 6:22 p.m. UTC
From: Konstantin Pugin <ria.freelander@gmail.com>

XR20M1172 register set is mostly compatible with SC16IS762, but it has
a support for additional division rates of UART with special DLD register.
So, add handling this register by appropriate devicetree bindings.

Signed-off-by: Konstantin Pugin <ria.freelander@gmail.com>
---
 drivers/tty/serial/Kconfig         | 18 +++++----
 drivers/tty/serial/sc16is7xx.c     | 60 ++++++++++++++++++++++++++++--
 drivers/tty/serial/sc16is7xx.h     |  1 +
 drivers/tty/serial/sc16is7xx_i2c.c |  1 +
 drivers/tty/serial/sc16is7xx_spi.c |  1 +
 5 files changed, 69 insertions(+), 12 deletions(-)

Comments

Jiri Slaby (SUSE) April 22, 2024, 6:30 a.m. UTC | #1
On 20. 04. 24, 20:22, Konstantin Pugin wrote:
> From: Konstantin Pugin <ria.freelander@gmail.com>
> 
> XR20M1172 register set is mostly compatible with SC16IS762, but it has
> a support for additional division rates of UART with special DLD register.
> So, add handling this register by appropriate devicetree bindings.
...
> --- a/drivers/tty/serial/sc16is7xx.c
> +++ b/drivers/tty/serial/sc16is7xx.c
...
> @@ -555,18 +578,43 @@ static bool sc16is7xx_regmap_noinc(struct device *dev, unsigned int reg)
>   	return reg == SC16IS7XX_RHR_REG;
>   }
>   
> +static bool sc16is7xx_has_dld(struct device *dev)
> +{
> +		struct sc16is7xx_port *s = dev_get_drvdata(dev);
> +
> +		if (s->devtype == &xr20m1172_devtype)
> +			return true;
> +		return false;

:) so this should simply be:

return s->devtype == &xr20m1172_devtype;

...
> @@ -1002,6 +1052,7 @@ static void sc16is7xx_set_termios(struct uart_port *port,
>   				  const struct ktermios *old)
>   {
>   	struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
> +	bool has_dld = sc16is7xx_has_dld(port->dev);
>   	unsigned int lcr, flow = 0;
>   	int baud;
>   	unsigned long flags;
> @@ -1084,7 +1135,7 @@ static void sc16is7xx_set_termios(struct uart_port *port,
>   	/* Get baud rate generator configuration */
>   	baud = uart_get_baud_rate(port, termios, old,
>   				  port->uartclk / 16 / 4 / 0xffff,
> -				  port->uartclk / 16);
> +				  port->uartclk / (has_dld ? 4 : 16));

Could you do this instead:
unsigned int divisor = sc16is7xx_has_dld(port->dev) ? 4 : 16;

...

uart_get_baud_rate(..., port->uartclk / divisor);


I am not sure the above warrants for a new version. Just in case you are 
sending one.

thanks,
Konstantin P. April 22, 2024, 8:35 a.m. UTC | #2
I do not think this is a requirement for a new version. I need to
wait. Some folks want to test my patches with their hardware)))

On Mon, Apr 22, 2024 at 9:30 AM Jiri Slaby <jirislaby@kernel.org> wrote:
>
> On 20. 04. 24, 20:22, Konstantin Pugin wrote:
> > From: Konstantin Pugin <ria.freelander@gmail.com>
> >
> > XR20M1172 register set is mostly compatible with SC16IS762, but it has
> > a support for additional division rates of UART with special DLD register.
> > So, add handling this register by appropriate devicetree bindings.
> ...
> > --- a/drivers/tty/serial/sc16is7xx.c
> > +++ b/drivers/tty/serial/sc16is7xx.c
> ...
> > @@ -555,18 +578,43 @@ static bool sc16is7xx_regmap_noinc(struct device *dev, unsigned int reg)
> >       return reg == SC16IS7XX_RHR_REG;
> >   }
> >
> > +static bool sc16is7xx_has_dld(struct device *dev)
> > +{
> > +             struct sc16is7xx_port *s = dev_get_drvdata(dev);
> > +
> > +             if (s->devtype == &xr20m1172_devtype)
> > +                     return true;
> > +             return false;
>
> :) so this should simply be:
>
> return s->devtype == &xr20m1172_devtype;
>
> ...
> > @@ -1002,6 +1052,7 @@ static void sc16is7xx_set_termios(struct uart_port *port,
> >                                 const struct ktermios *old)
> >   {
> >       struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
> > +     bool has_dld = sc16is7xx_has_dld(port->dev);
> >       unsigned int lcr, flow = 0;
> >       int baud;
> >       unsigned long flags;
> > @@ -1084,7 +1135,7 @@ static void sc16is7xx_set_termios(struct uart_port *port,
> >       /* Get baud rate generator configuration */
> >       baud = uart_get_baud_rate(port, termios, old,
> >                                 port->uartclk / 16 / 4 / 0xffff,
> > -                               port->uartclk / 16);
> > +                               port->uartclk / (has_dld ? 4 : 16));
>
> Could you do this instead:
> unsigned int divisor = sc16is7xx_has_dld(port->dev) ? 4 : 16;
>
> ...
>
> uart_get_baud_rate(..., port->uartclk / divisor);
>
>
> I am not sure the above warrants for a new version. Just in case you are
> sending one.
>
> thanks,
> --
> js
> suse labs
>
Andy Shevchenko April 22, 2024, 11:16 a.m. UTC | #3
On Mon, Apr 22, 2024 at 11:35:32AM +0300, Konstantin P. wrote:
> I do not think this is a requirement for a new version. I need to
> wait. Some folks want to test my patches with their hardware)))

You should not top-post!

...

Yes, it would be good them to provide a formal Tested-by tag, then you may send
a v6 with the tags and Jiri's comments being addressed. Btw, I prefer to have
them addressed now to eliminate unneeded churn in the future.

> On Mon, Apr 22, 2024 at 9:30 AM Jiri Slaby <jirislaby@kernel.org> wrote:
> > On 20. 04. 24, 20:22, Konstantin Pugin wrote:

> > I am not sure the above warrants for a new version. Just in case you are
> > sending one.
Andy Shevchenko April 22, 2024, 11:25 a.m. UTC | #4
On Sat, Apr 20, 2024 at 09:22:06PM +0300, Konstantin Pugin wrote:
> From: Konstantin Pugin <ria.freelander@gmail.com>
> 
> XR20M1172 register set is mostly compatible with SC16IS762, but it has
> a support for additional division rates of UART with special DLD register.
> So, add handling this register by appropriate devicetree bindings.

...

>  	help
> -	  Core driver for NXP SC16IS7xx UARTs.
> +	  Core driver for NXP SC16IS7xx-compatible UARTs.

'-compatible' --> ' and compatible'

>  	  Supported ICs are:
> -
> -	    SC16IS740
> -	    SC16IS741
> -	    SC16IS750
> -	    SC16IS752
> -	    SC16IS760
> -	    SC16IS762
> +		NXP:
> +	    	SC16IS740
> +	    	SC16IS741
> +	    	SC16IS750
> +	    	SC16IS752
> +	    	SC16IS760
> +	    	SC16IS762

You broke the indentation (as it has mixed TABs and spaces).

> +		EXAR:
> +			XR20M1172

No need to rewrite all of them, just add your line as

	    XR20M1172 (Exar)

>  	  The driver supports both I2C and SPI interfaces.

(Note, this needs to be fixed, hence it justifies a new version of the patch.)

...

> +/*
> + * Divisor Fractional Register bits (EXAR extension)

Missing period at the end of the line.

> + * EXAR hardware is mostly compatible with SC16IS7XX, but supports additional feature:
> + * 4x and 8x divisor, instead of default 16x. It has a special register to program it.
> + * Bits 0 to 3 is fractional divisor, it used to set value of last 16 bits of
> + * uartclk * (16 / divisor) / baud, in case of default it will be uartclk / baud.
> + * Bits 4 and 5 used as switches, and should not be set to 1 simultaneously.
> + */

...

> +static bool sc16is7xx_has_dld(struct device *dev)
> +{
> +		struct sc16is7xx_port *s = dev_get_drvdata(dev);
> +
> +		if (s->devtype == &xr20m1172_devtype)
> +			return true;
> +		return false;

Besides what Jiri noticed, this has been indented one TAB too much.

> +}
Konstantin P. April 22, 2024, noon UTC | #5
On Mon, Apr 22, 2024 at 9:30 AM Jiri Slaby <jirislaby@kernel.org> wrote:
>
> On 20. 04. 24, 20:22, Konstantin Pugin wrote:
> > From: Konstantin Pugin <ria.freelander@gmail.com>
> >
> > XR20M1172 register set is mostly compatible with SC16IS762, but it has
> > a support for additional division rates of UART with special DLD register.
> > So, add handling this register by appropriate devicetree bindings.
> ...
> > --- a/drivers/tty/serial/sc16is7xx.c
> > +++ b/drivers/tty/serial/sc16is7xx.c
> ...
> > @@ -555,18 +578,43 @@ static bool sc16is7xx_regmap_noinc(struct device *dev, unsigned int reg)
> >       return reg == SC16IS7XX_RHR_REG;
> >   }
> >
> > +static bool sc16is7xx_has_dld(struct device *dev)
> > +{
> > +             struct sc16is7xx_port *s = dev_get_drvdata(dev);
> > +
> > +             if (s->devtype == &xr20m1172_devtype)
> > +                     return true;
> > +             return false;
>
> :) so this should simply be:
>
> return s->devtype == &xr20m1172_devtype;
>
I especially want to avoid this construction, because it will lead to
idea than we does not have other
DLD-capable UARTS, which is simply not true, there is, for example,
XR20M1280 UART, which has roughly the same register set
(https://www.alldatasheet.com/datasheet-pdf/pdf/445109/EXAR/XR20M1280.html).
I simply do not have other devices, so I do not
want to risk sending untested patches upstream.

> ...
> > @@ -1002,6 +1052,7 @@ static void sc16is7xx_set_termios(struct uart_port *port,
> >                                 const struct ktermios *old)
> >   {
> >       struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
> > +     bool has_dld = sc16is7xx_has_dld(port->dev);
> >       unsigned int lcr, flow = 0;
> >       int baud;
> >       unsigned long flags;
> > @@ -1084,7 +1135,7 @@ static void sc16is7xx_set_termios(struct uart_port *port,
> >       /* Get baud rate generator configuration */
> >       baud = uart_get_baud_rate(port, termios, old,
> >                                 port->uartclk / 16 / 4 / 0xffff,
> > -                               port->uartclk / 16);
> > +                               port->uartclk / (has_dld ? 4 : 16));
>
> Could you do this instead:
> unsigned int divisor = sc16is7xx_has_dld(port->dev) ? 4 : 16;
>
> ...
>
> uart_get_baud_rate(..., port->uartclk / divisor);
>
>
> I am not sure the above warrants for a new version. Just in case you are
> sending one.
>
> thanks,
> --
> js
> suse labs
>
Jiri Slaby (SUSE) April 22, 2024, 5:28 p.m. UTC | #6
On 22. 04. 24, 14:00, Konstantin P. wrote:
> On Mon, Apr 22, 2024 at 9:30 AM Jiri Slaby <jirislaby@kernel.org> wrote:
>>
>> On 20. 04. 24, 20:22, Konstantin Pugin wrote:
>>> From: Konstantin Pugin <ria.freelander@gmail.com>
>>>
>>> XR20M1172 register set is mostly compatible with SC16IS762, but it has
>>> a support for additional division rates of UART with special DLD register.
>>> So, add handling this register by appropriate devicetree bindings.
>> ...
>>> --- a/drivers/tty/serial/sc16is7xx.c
>>> +++ b/drivers/tty/serial/sc16is7xx.c
>> ...
>>> @@ -555,18 +578,43 @@ static bool sc16is7xx_regmap_noinc(struct device *dev, unsigned int reg)
>>>        return reg == SC16IS7XX_RHR_REG;
>>>    }
>>>
>>> +static bool sc16is7xx_has_dld(struct device *dev)
>>> +{
>>> +             struct sc16is7xx_port *s = dev_get_drvdata(dev);
>>> +
>>> +             if (s->devtype == &xr20m1172_devtype)
>>> +                     return true;
>>> +             return false;
>>
>> :) so this should simply be:
>>
>> return s->devtype == &xr20m1172_devtype;
>>
> I especially want to avoid this construction, because it will lead to
> idea than we does not have other
> DLD-capable UARTS, which is simply not true, there is, for example,
> XR20M1280 UART, which has roughly the same register set
> (https://www.alldatasheet.com/datasheet-pdf/pdf/445109/EXAR/XR20M1280.html).
> I simply do not have other devices, so I do not
> want to risk sending untested patches upstream.

Sorry, what?
Krzysztof Kozlowski April 22, 2024, 8:45 p.m. UTC | #7
On 22/04/2024 22:35, Konstantin P. wrote:
> On Mon, Apr 22, 2024, 23:11 Jiri Slaby <jirislaby@kernel.org> wrote:
> 
>> On 22. 04. 24, 14:00, Konstantin P. wrote:
>>> On Mon, Apr 22, 2024 at 9:30 AM Jiri Slaby <jirislaby@kernel.org> wrote:
>>>>
>>>> On 20. 04. 24, 20:22, Konstantin Pugin wrote:
>>>>> From: Konstantin Pugin <ria.freelander@gmail.com>
>>>>>
>>>>> XR20M1172 register set is mostly compatible with SC16IS762, but it has
>>>>> a support for additional division rates of UART with special DLD
>> register.
>>>>> So, add handling this register by appropriate devicetree bindings.
>>>> ...
>>>>> --- a/drivers/tty/serial/sc16is7xx.c
>>>>> +++ b/drivers/tty/serial/sc16is7xx.c
>>>> ...
>>>>> @@ -555,18 +578,43 @@ static bool sc16is7xx_regmap_noinc(struct device
>> *dev, unsigned int reg)
>>>>>        return reg == SC16IS7XX_RHR_REG;
>>>>>    }
>>>>>
>>>>> +static bool sc16is7xx_has_dld(struct device *dev)
>>>>> +{
>>>>> +             struct sc16is7xx_port *s = dev_get_drvdata(dev);
>>>>> +
>>>>> +             if (s->devtype == &xr20m1172_devtype)
>>>>> +                     return true;
>>>>> +             return false;
>>>>
>>>> :) so this should simply be:
>>>>
>>>> return s->devtype == &xr20m1172_devtype;
>>>>
>>> I especially want to avoid this construction, because it will lead to
>>> idea than we does not have other
>>> DLD-capable UARTS, which is simply not true, there is, for example,
>>> XR20M1280 UART, which has roughly the same register set
>>> (
>> https://www.alldatasheet.com/datasheet-pdf/pdf/445109/EXAR/XR20M1280.html
>> ).
>>> I simply do not have other devices, so I do not
>>> want to risk sending untested patches upstream.
>>
>> Sorry, what?
>>
>> --
>> js
>> suse labs
>>
> 
> I do not wish those function to be less generic than I did. If you think
> this change is required - I will change. But if it would be okay without a
> change - I prefer to stay as is.

The code does exactly the same, so what do you mean "less generic"? What
does it even mean?

Best regards,
Krzysztof
diff mbox series

Patch

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 4fdd7857ef4d..4380bfe7dfff 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1029,15 +1029,17 @@  config SERIAL_SC16IS7XX_CORE
 	select SERIAL_SC16IS7XX_SPI if SPI_MASTER
 	select SERIAL_SC16IS7XX_I2C if I2C
 	help
-	  Core driver for NXP SC16IS7xx UARTs.
+	  Core driver for NXP SC16IS7xx-compatible UARTs.
 	  Supported ICs are:
-
-	    SC16IS740
-	    SC16IS741
-	    SC16IS750
-	    SC16IS752
-	    SC16IS760
-	    SC16IS762
+		NXP:
+	    	SC16IS740
+	    	SC16IS741
+	    	SC16IS750
+	    	SC16IS752
+	    	SC16IS760
+	    	SC16IS762
+		EXAR:
+			XR20M1172
 
 	  The driver supports both I2C and SPI interfaces.
 
diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c
index dfcc804f558f..0f95d5aef71b 100644
--- a/drivers/tty/serial/sc16is7xx.c
+++ b/drivers/tty/serial/sc16is7xx.c
@@ -10,6 +10,7 @@ 
 #undef DEFAULT_SYMBOL_NAMESPACE
 #define DEFAULT_SYMBOL_NAMESPACE SERIAL_NXP_SC16IS7XX
 
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/device.h>
@@ -68,6 +69,7 @@ 
 /* Special Register set: Only if ((LCR[7] == 1) && (LCR != 0xBF)) */
 #define SC16IS7XX_DLL_REG		(0x00) /* Divisor Latch Low */
 #define SC16IS7XX_DLH_REG		(0x01) /* Divisor Latch High */
+#define XR20M117X_DLD_REG		(0x02) /* Divisor Fractional Register */
 
 /* Enhanced Register set: Only if (LCR == 0xBF) */
 #define SC16IS7XX_EFR_REG		(0x02) /* Enhanced Features */
@@ -221,6 +223,20 @@ 
 #define SC16IS7XX_TCR_RX_HALT(words)	((((words) / 4) & 0x0f) << 0)
 #define SC16IS7XX_TCR_RX_RESUME(words)	((((words) / 4) & 0x0f) << 4)
 
+/*
+ * Divisor Fractional Register bits (EXAR extension)
+ * EXAR hardware is mostly compatible with SC16IS7XX, but supports additional feature:
+ * 4x and 8x divisor, instead of default 16x. It has a special register to program it.
+ * Bits 0 to 3 is fractional divisor, it used to set value of last 16 bits of
+ * uartclk * (16 / divisor) / baud, in case of default it will be uartclk / baud.
+ * Bits 4 and 5 used as switches, and should not be set to 1 simultaneously.
+ */
+
+#define XR20M117X_DLD_16X			0
+#define XR20M117X_DLD_DIV_MASK		GENMASK(3, 0)
+#define XR20M117X_DLD_8X			BIT(4)
+#define XR20M117X_DLD_4X			BIT(5)
+
 /*
  * TLR register bits
  * If TLR[3:0] or TLR[7:4] are logical 0, the selectable trigger levels via the
@@ -523,6 +539,13 @@  const struct sc16is7xx_devtype sc16is762_devtype = {
 };
 EXPORT_SYMBOL_GPL(sc16is762_devtype);
 
+const struct sc16is7xx_devtype xr20m1172_devtype = {
+	.name		= "XR20M1172",
+	.nr_gpio	= 8,
+	.nr_uart	= 2,
+};
+EXPORT_SYMBOL_GPL(xr20m1172_devtype);
+
 static bool sc16is7xx_regmap_volatile(struct device *dev, unsigned int reg)
 {
 	switch (reg) {
@@ -555,18 +578,43 @@  static bool sc16is7xx_regmap_noinc(struct device *dev, unsigned int reg)
 	return reg == SC16IS7XX_RHR_REG;
 }
 
+static bool sc16is7xx_has_dld(struct device *dev)
+{
+		struct sc16is7xx_port *s = dev_get_drvdata(dev);
+
+		if (s->devtype == &xr20m1172_devtype)
+			return true;
+		return false;
+}
+
 static int sc16is7xx_set_baud(struct uart_port *port, int baud)
 {
 	struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
-	u8 lcr;
+	unsigned long clk = port->uartclk, div, div16;
+	bool has_dld = sc16is7xx_has_dld(port->dev);
+	u8 dld_mode = XR20M117X_DLD_16X;
 	u8 prescaler = 0;
-	unsigned long clk = port->uartclk, div = clk / 16 / baud;
+	u8 divisor = 16;
+	u8 lcr;
+
+	if (has_dld && DIV_ROUND_CLOSEST(clk, baud) < 16)
+		divisor = rounddown_pow_of_two(DIV_ROUND_CLOSEST(clk, baud));
+
+	div16 = (clk * 16) / divisor / baud;
+	div = div16 / 16;
 
 	if (div >= BIT(16)) {
 		prescaler = SC16IS7XX_MCR_CLKSEL_BIT;
 		div /= 4;
 	}
 
+	/* Count additional divisor for EXAR devices */
+	if (divisor == 8)
+		dld_mode = XR20M117X_DLD_8X;
+	if (divisor == 4)
+		dld_mode = XR20M117X_DLD_4X;
+	dld_mode |= FIELD_PREP(XR20M117X_DLD_DIV_MASK, div16);
+
 	/* Enable enhanced features */
 	sc16is7xx_efr_lock(port);
 	sc16is7xx_port_update(port, SC16IS7XX_EFR_REG,
@@ -587,12 +635,14 @@  static int sc16is7xx_set_baud(struct uart_port *port, int baud)
 	regcache_cache_bypass(one->regmap, true);
 	sc16is7xx_port_write(port, SC16IS7XX_DLH_REG, div / 256);
 	sc16is7xx_port_write(port, SC16IS7XX_DLL_REG, div % 256);
+	if (has_dld)
+		sc16is7xx_port_write(port, XR20M117X_DLD_REG, dld_mode);
 	regcache_cache_bypass(one->regmap, false);
 
 	/* Restore LCR and access to general register set */
 	sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr);
 
-	return DIV_ROUND_CLOSEST(clk / 16, div);
+	return DIV_ROUND_CLOSEST(clk / divisor, div);
 }
 
 static void sc16is7xx_handle_rx(struct uart_port *port, unsigned int rxlen,
@@ -1002,6 +1052,7 @@  static void sc16is7xx_set_termios(struct uart_port *port,
 				  const struct ktermios *old)
 {
 	struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
+	bool has_dld = sc16is7xx_has_dld(port->dev);
 	unsigned int lcr, flow = 0;
 	int baud;
 	unsigned long flags;
@@ -1084,7 +1135,7 @@  static void sc16is7xx_set_termios(struct uart_port *port,
 	/* Get baud rate generator configuration */
 	baud = uart_get_baud_rate(port, termios, old,
 				  port->uartclk / 16 / 4 / 0xffff,
-				  port->uartclk / 16);
+				  port->uartclk / (has_dld ? 4 : 16));
 
 	/* Setup baudrate generator */
 	baud = sc16is7xx_set_baud(port, baud);
@@ -1684,6 +1735,7 @@  void sc16is7xx_remove(struct device *dev)
 EXPORT_SYMBOL_GPL(sc16is7xx_remove);
 
 const struct of_device_id __maybe_unused sc16is7xx_dt_ids[] = {
+	{ .compatible = "exar,xr20m1172",	.data = &xr20m1172_devtype, },
 	{ .compatible = "nxp,sc16is740",	.data = &sc16is74x_devtype, },
 	{ .compatible = "nxp,sc16is741",	.data = &sc16is74x_devtype, },
 	{ .compatible = "nxp,sc16is750",	.data = &sc16is750_devtype, },
diff --git a/drivers/tty/serial/sc16is7xx.h b/drivers/tty/serial/sc16is7xx.h
index afb784eaee45..eb2e3bc86f15 100644
--- a/drivers/tty/serial/sc16is7xx.h
+++ b/drivers/tty/serial/sc16is7xx.h
@@ -28,6 +28,7 @@  extern const struct sc16is7xx_devtype sc16is750_devtype;
 extern const struct sc16is7xx_devtype sc16is752_devtype;
 extern const struct sc16is7xx_devtype sc16is760_devtype;
 extern const struct sc16is7xx_devtype sc16is762_devtype;
+extern const struct sc16is7xx_devtype xr20m1172_devtype;
 
 const char *sc16is7xx_regmap_name(u8 port_id);
 
diff --git a/drivers/tty/serial/sc16is7xx_i2c.c b/drivers/tty/serial/sc16is7xx_i2c.c
index 3ed47c306d85..839de902821b 100644
--- a/drivers/tty/serial/sc16is7xx_i2c.c
+++ b/drivers/tty/serial/sc16is7xx_i2c.c
@@ -46,6 +46,7 @@  static const struct i2c_device_id sc16is7xx_i2c_id_table[] = {
 	{ "sc16is752",	(kernel_ulong_t)&sc16is752_devtype, },
 	{ "sc16is760",	(kernel_ulong_t)&sc16is760_devtype, },
 	{ "sc16is762",	(kernel_ulong_t)&sc16is762_devtype, },
+	{ "xr20m1172",	(kernel_ulong_t)&xr20m1172_devtype, },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, sc16is7xx_i2c_id_table);
diff --git a/drivers/tty/serial/sc16is7xx_spi.c b/drivers/tty/serial/sc16is7xx_spi.c
index 73df36f8a7fd..2b278282dbd0 100644
--- a/drivers/tty/serial/sc16is7xx_spi.c
+++ b/drivers/tty/serial/sc16is7xx_spi.c
@@ -69,6 +69,7 @@  static const struct spi_device_id sc16is7xx_spi_id_table[] = {
 	{ "sc16is752",	(kernel_ulong_t)&sc16is752_devtype, },
 	{ "sc16is760",	(kernel_ulong_t)&sc16is760_devtype, },
 	{ "sc16is762",	(kernel_ulong_t)&sc16is762_devtype, },
+	{ "xr20m1172",	(kernel_ulong_t)&xr20m1172_devtype, },
 	{ }
 };
 MODULE_DEVICE_TABLE(spi, sc16is7xx_spi_id_table);