* [PATCH v1 1/3] mailbox: Provide devm variants for mbox_request_channel{,_byname}()
2026-08-12 15:25 [PATCH v1 0/3] mailbox: Provide devm variants for mbox_request_channel{,_byname}() Uwe Kleine-König
@ 2026-08-12 15:25 ` Uwe Kleine-König
2026-08-12 15:25 ` [PATCH v1 2/3] serial: tegra-tcu: Make use of dev_err_probe() in .probe() Uwe Kleine-König
2026-08-12 15:25 ` [PATCH v1 3/3] serial: tegra-tcu: Make use of devm_mbox_request_channel_byname() Uwe Kleine-König
2 siblings, 0 replies; 4+ messages in thread
From: Uwe Kleine-König @ 2026-08-12 15:25 UTC (permalink / raw)
To: Jassi Brar; +Cc: linux-kernel
The new functions devm_mbox_request_channel() and
devm_mbox_request_channel_byname() allow to simplify resource management
for callers in their .probe() and .remove() functions.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
---
drivers/mailbox/mailbox.c | 44 ++++++++++++++++++++++++++++++++++
include/linux/mailbox_client.h | 5 ++++
2 files changed, 49 insertions(+)
diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
index efacd24a085d..f51b4ca02041 100644
--- a/drivers/mailbox/mailbox.c
+++ b/drivers/mailbox/mailbox.c
@@ -490,6 +490,31 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)
}
EXPORT_SYMBOL_GPL(mbox_request_channel);
+static void devm_mbox_free_channel(void *data)
+{
+ struct mbox_chan *chan = data;
+
+ mbox_free_channel(chan);
+}
+
+struct mbox_chan *devm_mbox_request_channel(struct device *dev,
+ struct mbox_client *cl, int index)
+{
+ struct mbox_chan *chan;
+ int ret;
+
+ chan = mbox_request_channel(cl, index);
+ if (IS_ERR(chan))
+ return chan;
+
+ ret = devm_add_action_or_reset(dev, devm_mbox_free_channel, chan);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return chan;
+}
+EXPORT_SYMBOL_GPL(devm_mbox_request_channel);
+
struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl,
const char *name)
{
@@ -504,6 +529,25 @@ struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl,
}
EXPORT_SYMBOL_GPL(mbox_request_channel_byname);
+struct mbox_chan *devm_mbox_request_channel_byname(struct device *dev,
+ struct mbox_client *cl,
+ const char *name)
+{
+ struct mbox_chan *chan;
+ int ret;
+
+ chan = mbox_request_channel_byname(cl, name);
+ if (IS_ERR(chan))
+ return chan;
+
+ ret = devm_add_action_or_reset(dev, devm_mbox_free_channel, chan);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return chan;
+}
+EXPORT_SYMBOL_GPL(devm_mbox_request_channel_byname);
+
/**
* mbox_free_channel - The client relinquishes control of a mailbox
* channel by this call.
diff --git a/include/linux/mailbox_client.h b/include/linux/mailbox_client.h
index e5997120f45c..ce550a93bf61 100644
--- a/include/linux/mailbox_client.h
+++ b/include/linux/mailbox_client.h
@@ -40,7 +40,12 @@ struct mbox_client {
int mbox_bind_client(struct mbox_chan *chan, struct mbox_client *cl);
struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl,
const char *name);
+struct mbox_chan *devm_mbox_request_channel_byname(struct device *dev,
+ struct mbox_client *cl,
+ const char *name);
struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index);
+struct mbox_chan *devm_mbox_request_channel(struct device *dev,
+ struct mbox_client *cl, int index);
int mbox_send_message(struct mbox_chan *chan, void *mssg);
int mbox_flush(struct mbox_chan *chan, unsigned long timeout);
void mbox_client_txdone(struct mbox_chan *chan, int r); /* atomic */
--
2.47.3
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH v1 2/3] serial: tegra-tcu: Make use of dev_err_probe() in .probe()
2026-08-12 15:25 [PATCH v1 0/3] mailbox: Provide devm variants for mbox_request_channel{,_byname}() Uwe Kleine-König
2026-08-12 15:25 ` [PATCH v1 1/3] " Uwe Kleine-König
@ 2026-08-12 15:25 ` Uwe Kleine-König
2026-08-12 15:25 ` [PATCH v1 3/3] serial: tegra-tcu: Make use of devm_mbox_request_channel_byname() Uwe Kleine-König
2 siblings, 0 replies; 4+ messages in thread
From: Uwe Kleine-König @ 2026-08-12 15:25 UTC (permalink / raw)
To: Jassi Brar
Cc: Greg Kroah-Hartman, Jiri Slaby, Thierry Reding, Jonathan Hunter,
linux-kernel, linux-serial, linux-tegra
Usage of dev_err_probe() is (sometimes) a bit more compact than
dev_err(), it properly handles ENOMEM and EPROBE_DEFER and emits the
error code symbolically.
Also introduce a variable to hold &pdev->dev to reduce line length a
bit.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
---
drivers/tty/serial/tegra-tcu.c | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/drivers/tty/serial/tegra-tcu.c b/drivers/tty/serial/tegra-tcu.c
index 7033dbfe8ba1..077023ce1842 100644
--- a/drivers/tty/serial/tegra-tcu.c
+++ b/drivers/tty/serial/tegra-tcu.c
@@ -179,9 +179,10 @@ static int tegra_tcu_probe(struct platform_device *pdev)
{
struct uart_port *port;
struct tegra_tcu *tcu;
+ struct device *dev = &pdev->dev;
int err;
- tcu = devm_kzalloc(&pdev->dev, sizeof(*tcu), GFP_KERNEL);
+ tcu = devm_kzalloc(dev, sizeof(*tcu), GFP_KERNEL);
if (!tcu)
return -ENOMEM;
@@ -190,11 +191,9 @@ static int tegra_tcu_probe(struct platform_device *pdev)
tcu->rx_client.rx_callback = tegra_tcu_receive;
tcu->tx = mbox_request_channel_byname(&tcu->tx_client, "tx");
- if (IS_ERR(tcu->tx)) {
- err = PTR_ERR(tcu->tx);
- dev_err(&pdev->dev, "failed to get tx mailbox: %d\n", err);
- return err;
- }
+ if (IS_ERR(tcu->tx))
+ return dev_err_probe(dev, PTR_ERR(tcu->tx),
+ "failed to get tx mailbox\n");
#if IS_ENABLED(CONFIG_SERIAL_TEGRA_TCU_CONSOLE)
/* setup the console */
@@ -218,15 +217,14 @@ static int tegra_tcu_probe(struct platform_device *pdev)
err = uart_register_driver(&tcu->driver);
if (err) {
- dev_err(&pdev->dev, "failed to register UART driver: %d\n",
- err);
+ dev_err_probe(dev, err, "failed to register UART driver\n");
goto free_tx;
}
/* setup the port */
port = &tcu->port;
spin_lock_init(&port->lock);
- port->dev = &pdev->dev;
+ port->dev = dev;
port->type = PORT_TEGRA_TCU;
port->ops = &tegra_tcu_uart_ops;
port->fifosize = 1;
@@ -236,7 +234,7 @@ static int tegra_tcu_probe(struct platform_device *pdev)
err = uart_add_one_port(&tcu->driver, port);
if (err) {
- dev_err(&pdev->dev, "failed to add UART port: %d\n", err);
+ dev_err_probe(dev, err, "failed to add UART port\n");
goto unregister_uart;
}
@@ -246,8 +244,8 @@ static int tegra_tcu_probe(struct platform_device *pdev)
*/
tcu->rx = mbox_request_channel_byname(&tcu->rx_client, "rx");
if (IS_ERR(tcu->rx)) {
- err = PTR_ERR(tcu->rx);
- dev_err(&pdev->dev, "failed to get rx mailbox: %d\n", err);
+ err = dev_err_probe(dev, PTR_ERR(tcu->rx),
+ "failed to get rx mailbox\n");
goto remove_uart_port;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH v1 3/3] serial: tegra-tcu: Make use of devm_mbox_request_channel_byname()
2026-08-12 15:25 [PATCH v1 0/3] mailbox: Provide devm variants for mbox_request_channel{,_byname}() Uwe Kleine-König
2026-08-12 15:25 ` [PATCH v1 1/3] " Uwe Kleine-König
2026-08-12 15:25 ` [PATCH v1 2/3] serial: tegra-tcu: Make use of dev_err_probe() in .probe() Uwe Kleine-König
@ 2026-08-12 15:25 ` Uwe Kleine-König
2 siblings, 0 replies; 4+ messages in thread
From: Uwe Kleine-König @ 2026-08-12 15:25 UTC (permalink / raw)
To: Jassi Brar
Cc: Greg Kroah-Hartman, Jiri Slaby, Thierry Reding, Jonathan Hunter,
linux-kernel, linux-serial, linux-tegra
Simplify tegra_tcu_probe() a bit by using the devm managed variant of
mbox_request_channel_byname(). For the rx channel the function cannot be
used without confusing the order of resource freeing.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
---
drivers/tty/serial/tegra-tcu.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/drivers/tty/serial/tegra-tcu.c b/drivers/tty/serial/tegra-tcu.c
index 077023ce1842..a3596ec24d34 100644
--- a/drivers/tty/serial/tegra-tcu.c
+++ b/drivers/tty/serial/tegra-tcu.c
@@ -190,7 +190,7 @@ static int tegra_tcu_probe(struct platform_device *pdev)
tcu->rx_client.dev = &pdev->dev;
tcu->rx_client.rx_callback = tegra_tcu_receive;
- tcu->tx = mbox_request_channel_byname(&tcu->tx_client, "tx");
+ tcu->tx = devm_mbox_request_channel_byname(dev, &tcu->tx_client, "tx");
if (IS_ERR(tcu->tx))
return dev_err_probe(dev, PTR_ERR(tcu->tx),
"failed to get tx mailbox\n");
@@ -216,10 +216,9 @@ static int tegra_tcu_probe(struct platform_device *pdev)
tcu->driver.nr = 1;
err = uart_register_driver(&tcu->driver);
- if (err) {
- dev_err_probe(dev, err, "failed to register UART driver\n");
- goto free_tx;
- }
+ if (err)
+ return dev_err_probe(dev, err,
+ "failed to register UART driver\n");
/* setup the port */
port = &tcu->port;
@@ -260,8 +259,6 @@ static int tegra_tcu_probe(struct platform_device *pdev)
uart_remove_one_port(&tcu->driver, &tcu->port);
unregister_uart:
uart_unregister_driver(&tcu->driver);
-free_tx:
- mbox_free_channel(tcu->tx);
return err;
}
@@ -276,7 +273,6 @@ static void tegra_tcu_remove(struct platform_device *pdev)
mbox_free_channel(tcu->rx);
uart_remove_one_port(&tcu->driver, &tcu->port);
uart_unregister_driver(&tcu->driver);
- mbox_free_channel(tcu->tx);
}
static const struct of_device_id tegra_tcu_match[] = {
--
2.47.3
^ permalink raw reply related [flat|nested] 4+ messages in thread