2024-03-07 16:53:10

by Hugo Villeneuve

[permalink] [raw]
Subject: [PATCH v2 0/4] serial: sc16is7xx: split into core and I2C/SPI parts

From: Hugo Villeneuve <[email protected]>

Hello,
this patch series splits the SPI/I2C parts for the sc16is7xx driver into
separate source files (and separate I2C/SPI drivers).

These changes are based on suggestions made by Andy Shevchenko
following this discussion:

Link: https://lore.kernel.org/all/CAHp75VebCZckUrNraYQj9k=Mrn2kbYs1Lx26f5-8rKJ3RXeh-w@mail.gmail.com/

The patches are multiple, simply to facilitate the review process. In the end,
they could be merged into a single patch.

I have tested the changes on a custom board with two SC16IS752 DUART over
a SPI interface using a Variscite IMX8MN NANO SOM. The four UARTs are
configured in RS-485 mode.

I did not test the changes on a real SC16is7xx using the I2C interface. But
I slighly modified the driver to be able to simulate an I2C device using
i2c-stub. I was then able to instantiate a virtual I2C device without
disturbing existing connection/communication between real SPI devices on
/dev/ttySC0 and /dev/ttySC2 (using a loopback cable).

Thank you.

Link: [v1] https://lore.kernel.org/lkml/[email protected]

Changes for V2:
- Move port_registered[] init before the for loop to prevent bug if
aborting probe when i = 0
- Since patch f7b487648986 ("lib/find: add atomic find_bit() primitives") has
been dropped from linux-next/master, rework patch 2 (sc16is7xx_lines)
without find_and_set_bit.

Hugo Villeneuve (4):
serial: sc16is7xx: simplify and improve Kconfig help text
serial: sc16is7xx: split into core and I2C/SPI parts (core)
serial: sc16is7xx: split into core and I2C/SPI parts (sc16is7xx_lines)
serial: sc16is7xx: split into core and I2C/SPI parts
(sc16is7xx_regcfg)

drivers/tty/serial/Kconfig | 41 +++--
drivers/tty/serial/Makefile | 4 +-
drivers/tty/serial/sc16is7xx.c | 245 ++++++-----------------------
drivers/tty/serial/sc16is7xx.h | 41 +++++
drivers/tty/serial/sc16is7xx_i2c.c | 74 +++++++++
drivers/tty/serial/sc16is7xx_spi.c | 97 ++++++++++++
6 files changed, 284 insertions(+), 218 deletions(-)
create mode 100644 drivers/tty/serial/sc16is7xx.h
create mode 100644 drivers/tty/serial/sc16is7xx_i2c.c
create mode 100644 drivers/tty/serial/sc16is7xx_spi.c


base-commit: 801410b26a0e8b8a16f7915b2b55c9528b69ca87
--
2.39.2



2024-03-07 16:53:37

by Hugo Villeneuve

[permalink] [raw]
Subject: [PATCH v2 4/4] serial: sc16is7xx: split into core and I2C/SPI parts (sc16is7xx_regcfg)

From: Hugo Villeneuve <[email protected]>

Since each I2C/SPI probe function can modify sc16is7xx_regcfg at the same
time, change structure to be constant and do the required modifications on
a local copy.

Signed-off-by: Hugo Villeneuve <[email protected]>
---
drivers/tty/serial/sc16is7xx.c | 2 +-
drivers/tty/serial/sc16is7xx.h | 2 +-
drivers/tty/serial/sc16is7xx_i2c.c | 11 +++++++----
drivers/tty/serial/sc16is7xx_spi.c | 11 +++++++----
4 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c
index d81aad1b201d..2cde4d6abac0 100644
--- a/drivers/tty/serial/sc16is7xx.c
+++ b/drivers/tty/serial/sc16is7xx.c
@@ -1703,7 +1703,7 @@ const struct of_device_id __maybe_unused sc16is7xx_dt_ids[] = {
EXPORT_SYMBOL_GPL(sc16is7xx_dt_ids);
MODULE_DEVICE_TABLE(of, sc16is7xx_dt_ids);

-struct regmap_config sc16is7xx_regcfg = {
+const struct regmap_config sc16is7xx_regcfg = {
.reg_bits = 5,
.pad_bits = 3,
.val_bits = 8,
diff --git a/drivers/tty/serial/sc16is7xx.h b/drivers/tty/serial/sc16is7xx.h
index 410f34b1005c..8d03357e35c7 100644
--- a/drivers/tty/serial/sc16is7xx.h
+++ b/drivers/tty/serial/sc16is7xx.h
@@ -19,7 +19,7 @@ struct sc16is7xx_devtype {
int nr_uart;
};

-extern struct regmap_config sc16is7xx_regcfg;
+extern const struct regmap_config sc16is7xx_regcfg;

extern const struct of_device_id __maybe_unused sc16is7xx_dt_ids[];

diff --git a/drivers/tty/serial/sc16is7xx_i2c.c b/drivers/tty/serial/sc16is7xx_i2c.c
index 70f0c329cc13..5667c56cf2aa 100644
--- a/drivers/tty/serial/sc16is7xx_i2c.c
+++ b/drivers/tty/serial/sc16is7xx_i2c.c
@@ -12,17 +12,20 @@ static int sc16is7xx_i2c_probe(struct i2c_client *i2c)
{
const struct sc16is7xx_devtype *devtype;
struct regmap *regmaps[SC16IS7XX_MAX_PORTS];
+ struct regmap_config regcfg;
unsigned int i;

devtype = i2c_get_match_data(i2c);
if (!devtype)
return dev_err_probe(&i2c->dev, -ENODEV, "Failed to match device\n");

+ memcpy(&regcfg, &sc16is7xx_regcfg, sizeof(struct regmap_config));
+
for (i = 0; i < devtype->nr_uart; i++) {
- sc16is7xx_regcfg.name = sc16is7xx_regmap_name(i);
- sc16is7xx_regcfg.read_flag_mask = sc16is7xx_regmap_port_mask(i);
- sc16is7xx_regcfg.write_flag_mask = sc16is7xx_regmap_port_mask(i);
- regmaps[i] = devm_regmap_init_i2c(i2c, &sc16is7xx_regcfg);
+ regcfg.name = sc16is7xx_regmap_name(i);
+ regcfg.read_flag_mask = sc16is7xx_regmap_port_mask(i);
+ regcfg.write_flag_mask = sc16is7xx_regmap_port_mask(i);
+ regmaps[i] = devm_regmap_init_i2c(i2c, &regcfg);
}

return sc16is7xx_probe(&i2c->dev, devtype, regmaps, i2c->irq);
diff --git a/drivers/tty/serial/sc16is7xx_spi.c b/drivers/tty/serial/sc16is7xx_spi.c
index 3942fc1b7455..55c1d4ad83f5 100644
--- a/drivers/tty/serial/sc16is7xx_spi.c
+++ b/drivers/tty/serial/sc16is7xx_spi.c
@@ -16,6 +16,7 @@ static int sc16is7xx_spi_probe(struct spi_device *spi)
{
const struct sc16is7xx_devtype *devtype;
struct regmap *regmaps[SC16IS7XX_MAX_PORTS];
+ struct regmap_config regcfg;
unsigned int i;
int ret;

@@ -35,17 +36,19 @@ static int sc16is7xx_spi_probe(struct spi_device *spi)
if (!devtype)
return dev_err_probe(&spi->dev, -ENODEV, "Failed to match device\n");

+ memcpy(&regcfg, &sc16is7xx_regcfg, sizeof(struct regmap_config));
+
for (i = 0; i < devtype->nr_uart; i++) {
- sc16is7xx_regcfg.name = sc16is7xx_regmap_name(i);
+ regcfg.name = sc16is7xx_regmap_name(i);
/*
* If read_flag_mask is 0, the regmap code sets it to a default
* of 0x80. Since we specify our own mask, we must add the READ
* bit ourselves:
*/
- sc16is7xx_regcfg.read_flag_mask = sc16is7xx_regmap_port_mask(i) |
+ regcfg.read_flag_mask = sc16is7xx_regmap_port_mask(i) |
SC16IS7XX_SPI_READ_BIT;
- sc16is7xx_regcfg.write_flag_mask = sc16is7xx_regmap_port_mask(i);
- regmaps[i] = devm_regmap_init_spi(spi, &sc16is7xx_regcfg);
+ regcfg.write_flag_mask = sc16is7xx_regmap_port_mask(i);
+ regmaps[i] = devm_regmap_init_spi(spi, &regcfg);
}

return sc16is7xx_probe(&spi->dev, devtype, regmaps, spi->irq);
--
2.39.2