* [PATCH 1/2] tty: serial: provide devm_uart_add_one_port()
2022-12-09 14:07 [PATCH 0/2] tty: serial: add and use a managed variant of uart_add_one_port() Bartosz Golaszewski
@ 2022-12-09 14:07 ` Bartosz Golaszewski
2022-12-09 14:07 ` [PATCH 2/2] tty: serial: qcom-geni-serial: use devres for uart port management Bartosz Golaszewski
1 sibling, 0 replies; 3+ messages in thread
From: Bartosz Golaszewski @ 2022-12-09 14:07 UTC (permalink / raw)
To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman,
Jiri Slaby, Srinivas Kandagatla, Vinod Koul, Alex Elder,
Ilpo Järvinen
Cc: linux-kernel, linux-arm-msm, linux-serial, Bartosz Golaszewski
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Provide a devres variant of uart_add_one_port() that removes the managed
port at device detach.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
.../driver-api/driver-model/devres.rst | 3 ++
drivers/tty/serial/serial_core.c | 48 +++++++++++++++++++
include/linux/serial_core.h | 6 +++
3 files changed, 57 insertions(+)
diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst
index 56082265e8e5..5d07a8c1eadb 100644
--- a/Documentation/driver-api/driver-model/devres.rst
+++ b/Documentation/driver-api/driver-model/devres.rst
@@ -436,6 +436,9 @@ RTC
SERDEV
devm_serdev_device_open()
+SERIAL
+ devm_uart_add_one_port()
+
SLAVE DMA ENGINE
devm_acpi_dma_controller_register()
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 179ee199df34..44cdb8aa80a4 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -3217,6 +3217,54 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)
}
EXPORT_SYMBOL(uart_remove_one_port);
+struct uart_port_devres {
+ struct uart_driver *drv;
+ struct uart_port *port;
+};
+
+static void devm_uart_remove_one_port(struct device *dev, void *data)
+{
+ struct uart_port_devres *res = data;
+
+ uart_remove_one_port(res->drv, res->port);
+}
+
+/**
+ * devm_uart_add_one_port - managed variant of uart_register_driver()
+ * @dev: managed device
+ * @drv: pointer to the uart low level driver structure for this port
+ * @uport: uart port structure to use for this port.
+ *
+ * Context: task context, might sleep
+ *
+ * This is a devres wrapper around uart_add_one_port(). It allows the driver
+ * @drv to register its own uart_port structure with the core driver. The port
+ * will be unregistered on driver detach.
+ */
+int devm_uart_add_one_port(struct device *dev,
+ struct uart_driver *drv, struct uart_port *port)
+{
+ struct uart_port_devres *res;
+ int ret;
+
+ res = devres_alloc(devm_uart_remove_one_port, sizeof(*res), GFP_KERNEL);
+ if (!res)
+ return -1;
+
+ ret = uart_add_one_port(drv, port);
+ if (ret) {
+ devres_free(res);
+ return -1;
+ }
+
+ res->drv = drv;
+ res->port = port;
+ devres_add(dev, res);
+
+ return 0;
+}
+EXPORT_SYMBOL(devm_uart_add_one_port);
+
/**
* uart_match_port - are the two ports equivalent?
* @port1: first port
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index d657f2a42a7b..d0911f04706e 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -771,6 +771,12 @@ int uart_remove_one_port(struct uart_driver *reg, struct uart_port *port);
bool uart_match_port(const struct uart_port *port1,
const struct uart_port *port2);
+/*
+ * UART devres
+ */
+int devm_uart_add_one_port(struct device *dev,
+ struct uart_driver *drv, struct uart_port *port);
+
/*
* Power Management
*/
--
2.37.2
^ permalink raw reply related [flat|nested] 3+ messages in thread* [PATCH 2/2] tty: serial: qcom-geni-serial: use devres for uart port management
2022-12-09 14:07 [PATCH 0/2] tty: serial: add and use a managed variant of uart_add_one_port() Bartosz Golaszewski
2022-12-09 14:07 ` [PATCH 1/2] tty: serial: provide devm_uart_add_one_port() Bartosz Golaszewski
@ 2022-12-09 14:07 ` Bartosz Golaszewski
1 sibling, 0 replies; 3+ messages in thread
From: Bartosz Golaszewski @ 2022-12-09 14:07 UTC (permalink / raw)
To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman,
Jiri Slaby, Srinivas Kandagatla, Vinod Koul, Alex Elder,
Ilpo Järvinen
Cc: linux-kernel, linux-arm-msm, linux-serial, Bartosz Golaszewski
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Shrink and simplify the probe() and remove() code by using the managed
variant of uart_add_one_port().
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
drivers/tty/serial/qcom_geni_serial.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 83b66b73303a..16532cb64465 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -1469,7 +1469,7 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, port);
port->handle_rx = console ? handle_rx_console : handle_rx_uart;
- ret = uart_add_one_port(drv, uport);
+ ret = devm_uart_add_one_port(&pdev->dev, drv, uport);
if (ret)
return ret;
@@ -1478,7 +1478,6 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
IRQF_TRIGGER_HIGH, port->name, uport);
if (ret) {
dev_err(uport->dev, "Failed to get IRQ ret %d\n", ret);
- uart_remove_one_port(drv, uport);
return ret;
}
@@ -1495,7 +1494,6 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
port->wakeup_irq);
if (ret) {
device_init_wakeup(&pdev->dev, false);
- uart_remove_one_port(drv, uport);
return ret;
}
}
@@ -1505,12 +1503,8 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
static int qcom_geni_serial_remove(struct platform_device *pdev)
{
- struct qcom_geni_serial_port *port = platform_get_drvdata(pdev);
- struct uart_driver *drv = port->private_data.drv;
-
dev_pm_clear_wake_irq(&pdev->dev);
device_init_wakeup(&pdev->dev, false);
- uart_remove_one_port(drv, &port->uport);
return 0;
}
--
2.37.2
^ permalink raw reply related [flat|nested] 3+ messages in thread