From b99e9c096148fb8b0915da7506240aade4e863bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 5 Mar 2024 22:32:03 +0100 Subject: [PATCH 01/55] reset: meson-audio-arb: Convert to platform remove callback returning void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new(), which already returns void. Eventually after all drivers are converted, .remove_new() will be renamed to .remove(). Trivially convert this driver from always returning zero in the remove callback to the void returning variant. Signed-off-by: Uwe Kleine-König Reviewed-by: Philipp Zabel Link: https://lore.kernel.org/r/dbca07bad345abe7ca421515004987acf1cb41c2.1709674157.git.u.kleine-koenig@pengutronix.de Signed-off-by: Philipp Zabel --- drivers/reset/reset-meson-audio-arb.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/reset/reset-meson-audio-arb.c b/drivers/reset/reset-meson-audio-arb.c index 7891d52fa899..8740f5f6abf8 100644 --- a/drivers/reset/reset-meson-audio-arb.c +++ b/drivers/reset/reset-meson-audio-arb.c @@ -120,7 +120,7 @@ static const struct of_device_id meson_audio_arb_of_match[] = { }; MODULE_DEVICE_TABLE(of, meson_audio_arb_of_match); -static int meson_audio_arb_remove(struct platform_device *pdev) +static void meson_audio_arb_remove(struct platform_device *pdev) { struct meson_audio_arb_data *arb = platform_get_drvdata(pdev); @@ -130,8 +130,6 @@ static int meson_audio_arb_remove(struct platform_device *pdev) spin_unlock(&arb->lock); clk_disable_unprepare(arb->clk); - - return 0; } static int meson_audio_arb_probe(struct platform_device *pdev) @@ -189,7 +187,7 @@ static int meson_audio_arb_probe(struct platform_device *pdev) static struct platform_driver meson_audio_arb_pdrv = { .probe = meson_audio_arb_probe, - .remove = meson_audio_arb_remove, + .remove_new = meson_audio_arb_remove, .driver = { .name = "meson-audio-arb-reset", .of_match_table = meson_audio_arb_of_match, From 7f5aa02ad0c80fc841968cf9bbff36d845266683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 5 Mar 2024 22:32:04 +0100 Subject: [PATCH 02/55] reset: rzg2l-usbphy-ctrl: Convert to platform remove callback returning void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new(), which already returns void. Eventually after all drivers are converted, .remove_new() will be renamed to .remove(). Trivially convert this driver from always returning zero in the remove callback to the void returning variant. Signed-off-by: Uwe Kleine-König Reviewed-by: Philipp Zabel Link: https://lore.kernel.org/r/e75fb1af5c7df5fc4073a26a99ba88633503910d.1709674157.git.u.kleine-koenig@pengutronix.de Signed-off-by: Philipp Zabel --- drivers/reset/reset-rzg2l-usbphy-ctrl.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c index a8dde4606360..8f6fbd978591 100644 --- a/drivers/reset/reset-rzg2l-usbphy-ctrl.c +++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c @@ -156,15 +156,13 @@ static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev) return 0; } -static int rzg2l_usbphy_ctrl_remove(struct platform_device *pdev) +static void rzg2l_usbphy_ctrl_remove(struct platform_device *pdev) { struct rzg2l_usbphy_ctrl_priv *priv = dev_get_drvdata(&pdev->dev); pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); reset_control_assert(priv->rstc); - - return 0; } static struct platform_driver rzg2l_usbphy_ctrl_driver = { @@ -173,7 +171,7 @@ static struct platform_driver rzg2l_usbphy_ctrl_driver = { .of_match_table = rzg2l_usbphy_ctrl_match_table, }, .probe = rzg2l_usbphy_ctrl_probe, - .remove = rzg2l_usbphy_ctrl_remove, + .remove_new = rzg2l_usbphy_ctrl_remove, }; module_platform_driver(rzg2l_usbphy_ctrl_driver); From 6d89df61650d155b9033d9f507f3580f9177e623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 5 Mar 2024 22:32:05 +0100 Subject: [PATCH 03/55] reset: ti-sci: Convert to platform remove callback returning void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new(), which already returns void. Eventually after all drivers are converted, .remove_new() will be renamed to .remove(). Trivially convert this driver from always returning zero in the remove callback to the void returning variant. Signed-off-by: Uwe Kleine-König Reviewed-by: Nishanth Menon Reviewed-by: Philipp Zabel Link: https://lore.kernel.org/r/ab374da386cafd6748aac5bdf66e6be3e1860509.1709674157.git.u.kleine-koenig@pengutronix.de Signed-off-by: Philipp Zabel --- drivers/reset/reset-ti-sci.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/reset/reset-ti-sci.c b/drivers/reset/reset-ti-sci.c index cc01fa5b0bea..d384da0982fa 100644 --- a/drivers/reset/reset-ti-sci.c +++ b/drivers/reset/reset-ti-sci.c @@ -235,20 +235,18 @@ static int ti_sci_reset_probe(struct platform_device *pdev) return reset_controller_register(&data->rcdev); } -static int ti_sci_reset_remove(struct platform_device *pdev) +static void ti_sci_reset_remove(struct platform_device *pdev) { struct ti_sci_reset_data *data = platform_get_drvdata(pdev); reset_controller_unregister(&data->rcdev); idr_destroy(&data->idr); - - return 0; } static struct platform_driver ti_sci_reset_driver = { .probe = ti_sci_reset_probe, - .remove = ti_sci_reset_remove, + .remove_new = ti_sci_reset_remove, .driver = { .name = "ti-sci-reset", .of_match_table = ti_sci_reset_of_match, From 41929cce09f991992f16608fb5adfd3c2f809adb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 5 Mar 2024 22:20:57 +0100 Subject: [PATCH 04/55] fsi: master-aspeed: Convert to platform remove callback returning void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new(), which already returns void. Eventually after all drivers are converted, .remove_new() will be renamed to .remove(). Trivially convert this driver from always returning zero in the remove callback to the void returning variant. Acked-by: Jeremy Kerr Link: https://lore.kernel.org/r/de0f2d4cb529a433d4620ca0e8fda0dfb1e950db.1709673414.git.u.kleine-koenig@pengutronix.de Signed-off-by: Uwe Kleine-König --- drivers/fsi/fsi-master-aspeed.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/fsi/fsi-master-aspeed.c b/drivers/fsi/fsi-master-aspeed.c index f0a19cd451a0..b0b624c3717b 100644 --- a/drivers/fsi/fsi-master-aspeed.c +++ b/drivers/fsi/fsi-master-aspeed.c @@ -646,14 +646,12 @@ err_free_aspeed: return rc; } -static int fsi_master_aspeed_remove(struct platform_device *pdev) +static void fsi_master_aspeed_remove(struct platform_device *pdev) { struct fsi_master_aspeed *aspeed = platform_get_drvdata(pdev); fsi_master_unregister(&aspeed->master); clk_disable_unprepare(aspeed->clk); - - return 0; } static const struct of_device_id fsi_master_aspeed_match[] = { @@ -668,7 +666,7 @@ static struct platform_driver fsi_master_aspeed_driver = { .of_match_table = fsi_master_aspeed_match, }, .probe = fsi_master_aspeed_probe, - .remove = fsi_master_aspeed_remove, + .remove_new = fsi_master_aspeed_remove, }; module_platform_driver(fsi_master_aspeed_driver); From d1c9c5a03b6507e8dc8fe9656d5ab4b9582c3d1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 5 Mar 2024 22:20:58 +0100 Subject: [PATCH 05/55] fsi: master-ast-cf: Convert to platform remove callback returning void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new(), which already returns void. Eventually after all drivers are converted, .remove_new() will be renamed to .remove(). Trivially convert this driver from always returning zero in the remove callback to the void returning variant. Acked-by: Jeremy Kerr Link: https://lists.ozlabs.org/pipermail/linux-fsi/2024-March/000614.html Signed-off-by: Uwe Kleine-König --- drivers/fsi/fsi-master-ast-cf.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/fsi/fsi-master-ast-cf.c b/drivers/fsi/fsi-master-ast-cf.c index 812dfa9a9140..f8c776ce1b56 100644 --- a/drivers/fsi/fsi-master-ast-cf.c +++ b/drivers/fsi/fsi-master-ast-cf.c @@ -1412,15 +1412,13 @@ static int fsi_master_acf_probe(struct platform_device *pdev) } -static int fsi_master_acf_remove(struct platform_device *pdev) +static void fsi_master_acf_remove(struct platform_device *pdev) { struct fsi_master_acf *master = platform_get_drvdata(pdev); device_remove_file(master->dev, &dev_attr_external_mode); fsi_master_unregister(&master->master); - - return 0; } static const struct of_device_id fsi_master_acf_match[] = { @@ -1436,7 +1434,7 @@ static struct platform_driver fsi_master_acf = { .of_match_table = fsi_master_acf_match, }, .probe = fsi_master_acf_probe, - .remove = fsi_master_acf_remove, + .remove_new = fsi_master_acf_remove, }; module_platform_driver(fsi_master_acf); From 826788bbad497a65687ac32bb8468c4e25b7f702 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 5 Mar 2024 22:20:59 +0100 Subject: [PATCH 06/55] fsi: master-gpio: Convert to platform remove callback returning void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new(), which already returns void. Eventually after all drivers are converted, .remove_new() will be renamed to .remove(). Trivially convert this driver from always returning zero in the remove callback to the void returning variant. Acked-by: Jeremy Kerr Link: https://lists.ozlabs.org/pipermail/linux-fsi/2024-March/000612.html Signed-off-by: Uwe Kleine-König --- drivers/fsi/fsi-master-gpio.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c index ed03da4f2447..10fc344b6b22 100644 --- a/drivers/fsi/fsi-master-gpio.c +++ b/drivers/fsi/fsi-master-gpio.c @@ -867,15 +867,13 @@ static int fsi_master_gpio_probe(struct platform_device *pdev) -static int fsi_master_gpio_remove(struct platform_device *pdev) +static void fsi_master_gpio_remove(struct platform_device *pdev) { struct fsi_master_gpio *master = platform_get_drvdata(pdev); device_remove_file(&pdev->dev, &dev_attr_external_mode); fsi_master_unregister(&master->master); - - return 0; } static const struct of_device_id fsi_master_gpio_match[] = { @@ -890,7 +888,7 @@ static struct platform_driver fsi_master_gpio_driver = { .of_match_table = fsi_master_gpio_match, }, .probe = fsi_master_gpio_probe, - .remove = fsi_master_gpio_remove, + .remove_new = fsi_master_gpio_remove, }; module_platform_driver(fsi_master_gpio_driver); From 29f102dbb11fe1b2f4ea68e3a5721255f37f8bc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 5 Mar 2024 22:21:00 +0100 Subject: [PATCH 07/55] fsi: occ: Convert to platform remove callback returning void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new(), which already returns void. Eventually after all drivers are converted, .remove_new() will be renamed to .remove(). Trivially convert this driver from always returning zero in the remove callback to the void returning variant. Link: https://lists.ozlabs.org/pipermail/linux-fsi/2024-March/000613.html Acked-by: Jeremy Kerr Signed-off-by: Uwe Kleine-König --- drivers/fsi/fsi-occ.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/fsi/fsi-occ.c b/drivers/fsi/fsi-occ.c index da35ca9e84a6..21d2666c4195 100644 --- a/drivers/fsi/fsi-occ.c +++ b/drivers/fsi/fsi-occ.c @@ -703,7 +703,7 @@ static int occ_probe(struct platform_device *pdev) return 0; } -static int occ_remove(struct platform_device *pdev) +static void occ_remove(struct platform_device *pdev) { struct occ *occ = platform_get_drvdata(pdev); @@ -720,8 +720,6 @@ static int occ_remove(struct platform_device *pdev) device_for_each_child(&pdev->dev, NULL, occ_unregister_of_child); ida_simple_remove(&occ_ida, occ->idx); - - return 0; } static const struct of_device_id occ_match[] = { @@ -743,7 +741,7 @@ static struct platform_driver occ_driver = { .of_match_table = occ_match, }, .probe = occ_probe, - .remove = occ_remove, + .remove_new = occ_remove, }; static int occ_init(void) From 49fc3ffe9f7c239319f009ce3f5dd0cc5bfc64fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 8 Mar 2024 09:51:15 +0100 Subject: [PATCH 08/55] pps: clients: gpio: Convert to platform remove callback returning void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new(), which already returns void. Eventually after all drivers are converted, .remove_new() will be renamed to .remove(). Trivially convert this driver from always returning zero in the remove callback to the void returning variant. Acked-by: Rodolfo Giometti Link: https://lore.kernel.org/r/f4b9402af72e5f285c8b0f068076a76418f653f5.1709886922.git.u.kleine-koenig@pengutronix.de Signed-off-by: Uwe Kleine-König --- drivers/pps/clients/pps-gpio.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/pps/clients/pps-gpio.c b/drivers/pps/clients/pps-gpio.c index 2f4b11b4dfcd..791fdc9326dd 100644 --- a/drivers/pps/clients/pps-gpio.c +++ b/drivers/pps/clients/pps-gpio.c @@ -220,7 +220,7 @@ static int pps_gpio_probe(struct platform_device *pdev) return 0; } -static int pps_gpio_remove(struct platform_device *pdev) +static void pps_gpio_remove(struct platform_device *pdev) { struct pps_gpio_device_data *data = platform_get_drvdata(pdev); @@ -229,7 +229,6 @@ static int pps_gpio_remove(struct platform_device *pdev) /* reset echo pin in any case */ gpiod_set_value(data->echo_pin, 0); dev_info(&pdev->dev, "removed IRQ %d as PPS source\n", data->irq); - return 0; } static const struct of_device_id pps_gpio_dt_ids[] = { @@ -240,7 +239,7 @@ MODULE_DEVICE_TABLE(of, pps_gpio_dt_ids); static struct platform_driver pps_gpio_driver = { .probe = pps_gpio_probe, - .remove = pps_gpio_remove, + .remove_new = pps_gpio_remove, .driver = { .name = PPS_GPIO_NAME, .of_match_table = pps_gpio_dt_ids, From 1cb394e644a000aa6dbe92d1278c712ddc5bbcf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 9 Apr 2024 18:50:43 +0200 Subject: [PATCH 09/55] gpu: host1x: mipi: Benefit from devm_clk_get_prepared() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using devm_clk_get_prepared() instead of devm_clk_get() the clock is already returned prepared. So probe doesn't need to call clk_prepare() and at remove time the call to clk_unprepare() can be dropped. The latter makes the remove callback empty, so it can be dropped, too. Acked-by: Thierry Reding Link: https://lore.kernel.org/r/20240409165043.105137-2-u.kleine-koenig@pengutronix.de Signed-off-by: Uwe Kleine-König --- drivers/gpu/host1x/mipi.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/drivers/gpu/host1x/mipi.c b/drivers/gpu/host1x/mipi.c index 4dcec535ec21..e51b43dd15a3 100644 --- a/drivers/gpu/host1x/mipi.c +++ b/drivers/gpu/host1x/mipi.c @@ -501,7 +501,6 @@ static int tegra_mipi_probe(struct platform_device *pdev) { const struct of_device_id *match; struct tegra_mipi *mipi; - int err; match = of_match_node(tegra_mipi_of_match, pdev->dev.of_node); if (!match) @@ -520,35 +519,21 @@ static int tegra_mipi_probe(struct platform_device *pdev) mutex_init(&mipi->lock); - mipi->clk = devm_clk_get(&pdev->dev, NULL); + mipi->clk = devm_clk_get_prepared(&pdev->dev, NULL); if (IS_ERR(mipi->clk)) { dev_err(&pdev->dev, "failed to get clock\n"); return PTR_ERR(mipi->clk); } - err = clk_prepare(mipi->clk); - if (err < 0) - return err; - platform_set_drvdata(pdev, mipi); return 0; } -static int tegra_mipi_remove(struct platform_device *pdev) -{ - struct tegra_mipi *mipi = platform_get_drvdata(pdev); - - clk_unprepare(mipi->clk); - - return 0; -} - struct platform_driver tegra_mipi_driver = { .driver = { .name = "tegra-mipi", .of_match_table = tegra_mipi_of_match, }, .probe = tegra_mipi_probe, - .remove = tegra_mipi_remove, }; From bf9ca9f36975efc8306622d29e521cb5459bd168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 9 Apr 2024 19:02:48 +0200 Subject: [PATCH 10/55] drm/imagination: Convert to platform remove callback returning void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new(), which already returns void. Eventually after all drivers are converted, .remove_new() will be renamed to .remove(). Trivially convert this driver from always returning zero in the remove callback to the void returning variant. Reviewed-by: Matt Coster Acked-by: Matt Coster Reviewed-by: Thomas Zimmermann Link: https://lore.kernel.org/r/4cf10e420863f40a268f26b9bdb0c4b53dbf3406.1712681770.git.u.kleine-koenig@pengutronix.de Signed-off-by: Uwe Kleine-König --- drivers/gpu/drm/imagination/pvr_drv.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/imagination/pvr_drv.c b/drivers/gpu/drm/imagination/pvr_drv.c index 5c3b2d58d766..1a0cb7aa9cea 100644 --- a/drivers/gpu/drm/imagination/pvr_drv.c +++ b/drivers/gpu/drm/imagination/pvr_drv.c @@ -1451,8 +1451,7 @@ err_context_fini: return err; } -static int -pvr_remove(struct platform_device *plat_dev) +static void pvr_remove(struct platform_device *plat_dev) { struct drm_device *drm_dev = platform_get_drvdata(plat_dev); struct pvr_device *pvr_dev = to_pvr_device(drm_dev); @@ -1469,8 +1468,6 @@ pvr_remove(struct platform_device *plat_dev) pvr_watchdog_fini(pvr_dev); pvr_queue_device_fini(pvr_dev); pvr_context_device_fini(pvr_dev); - - return 0; } static const struct of_device_id dt_match[] = { @@ -1485,7 +1482,7 @@ static const struct dev_pm_ops pvr_pm_ops = { static struct platform_driver pvr_driver = { .probe = pvr_probe, - .remove = pvr_remove, + .remove_new = pvr_remove, .driver = { .name = PVR_DRIVER_NAME, .pm = &pvr_pm_ops, From 573a39d05053cb234a9ac3c7b0b359fb3258bd76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 9 Apr 2024 19:02:49 +0200 Subject: [PATCH 11/55] drm/mediatek: Convert to platform remove callback returning void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new(), which already returns void. Eventually after all drivers are converted, .remove_new() will be renamed to .remove(). Trivially convert this driver from always returning zero in the remove callback to the void returning variant. Reviewed-by: Thomas Zimmermann Link: https://lore.kernel.org/r/4a64dfbfbcfdf9b7cd46bc8026223e69a4b453b4.1712681770.git.u.kleine-koenig@pengutronix.de Signed-off-by: Uwe Kleine-König --- drivers/gpu/drm/mediatek/mtk_padding.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_padding.c b/drivers/gpu/drm/mediatek/mtk_padding.c index 85bc6768b6bc..5296d39d2f3a 100644 --- a/drivers/gpu/drm/mediatek/mtk_padding.c +++ b/drivers/gpu/drm/mediatek/mtk_padding.c @@ -137,10 +137,9 @@ static int mtk_padding_probe(struct platform_device *pdev) return 0; } -static int mtk_padding_remove(struct platform_device *pdev) +static void mtk_padding_remove(struct platform_device *pdev) { component_del(&pdev->dev, &mtk_padding_component_ops); - return 0; } static const struct of_device_id mtk_padding_driver_dt_match[] = { @@ -151,7 +150,7 @@ MODULE_DEVICE_TABLE(of, mtk_padding_driver_dt_match); struct platform_driver mtk_padding_driver = { .probe = mtk_padding_probe, - .remove = mtk_padding_remove, + .remove_new = mtk_padding_remove, .driver = { .name = "mediatek-disp-padding", .of_match_table = mtk_padding_driver_dt_match, From 17e1b2db37df9b06f586b960e2a30379d6bc1c1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 9 Apr 2024 19:02:50 +0200 Subject: [PATCH 12/55] gpu: host1x: Convert to platform remove callback returning void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new(), which already returns void. Eventually after all drivers are converted, .remove_new() will be renamed to .remove(). Trivially convert this driver from always returning zero in the remove callback to the void returning variant. Acked-by: Thierry Reding Reviewed-by: Thomas Zimmermann Link: https://lore.kernel.org/r/7e31909b1e536f0ddbb060b1aaa0a9e943687c8a.1712681770.git.u.kleine-koenig@pengutronix.de Signed-off-by: Uwe Kleine-König --- drivers/gpu/host1x/dev.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c index 3a0aaa68ac8d..f006bc931324 100644 --- a/drivers/gpu/host1x/dev.c +++ b/drivers/gpu/host1x/dev.c @@ -677,7 +677,7 @@ destroy_cache: return err; } -static int host1x_remove(struct platform_device *pdev) +static void host1x_remove(struct platform_device *pdev) { struct host1x *host = platform_get_drvdata(pdev); @@ -692,8 +692,6 @@ static int host1x_remove(struct platform_device *pdev) host1x_channel_list_free(&host->channel_list); host1x_iommu_exit(host); host1x_bo_cache_destroy(&host->cache); - - return 0; } static int __maybe_unused host1x_runtime_suspend(struct device *dev) @@ -778,7 +776,7 @@ static struct platform_driver tegra_host1x_driver = { .pm = &host1x_pm_ops, }, .probe = host1x_probe, - .remove = host1x_remove, + .remove_new = host1x_remove, }; static struct platform_driver * const drivers[] = { From 4402a5aa9732d870753ba7b945c812d9bd64f1c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 9 Apr 2024 19:02:51 +0200 Subject: [PATCH 13/55] gpu: ipu-v3: Convert to platform remove callback returning void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new(), which already returns void. Eventually after all drivers are converted, .remove_new() will be renamed to .remove(). Trivially convert the ipu-v3 platform drivers from always returning zero in the remove callback to the void returning variant. Reviewed-by: Philipp Zabel Reviewed-by: Thomas Zimmermann Link: https://lore.kernel.org/r/dee3c0e1c8c6bd1027a91c65be55ac1d6ba9e099.1712681770.git.u.kleine-koenig@pengutronix.de Signed-off-by: Uwe Kleine-König --- drivers/gpu/ipu-v3/ipu-common.c | 6 ++---- drivers/gpu/ipu-v3/ipu-pre.c | 5 ++--- drivers/gpu/ipu-v3/ipu-prg.c | 6 ++---- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index 71ec1e7f657a..3535be9daa1f 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c @@ -1450,7 +1450,7 @@ out_failed_reset: return ret; } -static int ipu_remove(struct platform_device *pdev) +static void ipu_remove(struct platform_device *pdev) { struct ipu_soc *ipu = platform_get_drvdata(pdev); @@ -1459,8 +1459,6 @@ static int ipu_remove(struct platform_device *pdev) ipu_irq_exit(ipu); clk_disable_unprepare(ipu->clk); - - return 0; } static struct platform_driver imx_ipu_driver = { @@ -1469,7 +1467,7 @@ static struct platform_driver imx_ipu_driver = { .of_match_table = imx_ipu_dt_ids, }, .probe = ipu_probe, - .remove = ipu_remove, + .remove_new = ipu_remove, }; static struct platform_driver * const drivers[] = { diff --git a/drivers/gpu/ipu-v3/ipu-pre.c b/drivers/gpu/ipu-v3/ipu-pre.c index aef984a43190..e469272d4f25 100644 --- a/drivers/gpu/ipu-v3/ipu-pre.c +++ b/drivers/gpu/ipu-v3/ipu-pre.c @@ -312,7 +312,7 @@ static int ipu_pre_probe(struct platform_device *pdev) return 0; } -static int ipu_pre_remove(struct platform_device *pdev) +static void ipu_pre_remove(struct platform_device *pdev) { struct ipu_pre *pre = platform_get_drvdata(pdev); @@ -326,7 +326,6 @@ static int ipu_pre_remove(struct platform_device *pdev) if (pre->buffer_virt) gen_pool_free(pre->iram, (unsigned long)pre->buffer_virt, IPU_PRE_MAX_WIDTH * IPU_PRE_NUM_SCANLINES * 4); - return 0; } static const struct of_device_id ipu_pre_dt_ids[] = { @@ -336,7 +335,7 @@ static const struct of_device_id ipu_pre_dt_ids[] = { struct platform_driver ipu_pre_drv = { .probe = ipu_pre_probe, - .remove = ipu_pre_remove, + .remove_new = ipu_pre_remove, .driver = { .name = "imx-ipu-pre", .of_match_table = ipu_pre_dt_ids, diff --git a/drivers/gpu/ipu-v3/ipu-prg.c b/drivers/gpu/ipu-v3/ipu-prg.c index 729605709955..4976ac0bb876 100644 --- a/drivers/gpu/ipu-v3/ipu-prg.c +++ b/drivers/gpu/ipu-v3/ipu-prg.c @@ -419,15 +419,13 @@ static int ipu_prg_probe(struct platform_device *pdev) return 0; } -static int ipu_prg_remove(struct platform_device *pdev) +static void ipu_prg_remove(struct platform_device *pdev) { struct ipu_prg *prg = platform_get_drvdata(pdev); mutex_lock(&ipu_prg_list_mutex); list_del(&prg->list); mutex_unlock(&ipu_prg_list_mutex); - - return 0; } #ifdef CONFIG_PM @@ -471,7 +469,7 @@ static const struct of_device_id ipu_prg_dt_ids[] = { struct platform_driver ipu_prg_drv = { .probe = ipu_prg_probe, - .remove = ipu_prg_remove, + .remove_new = ipu_prg_remove, .driver = { .name = "imx-ipu-prg", .pm = &prg_pm_ops, From 521558275731c040136ebdd6dfc84864ce9d9a96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 10 Apr 2024 15:47:33 +0200 Subject: [PATCH 14/55] nvdimm/e820: Convert to platform remove callback returning void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new(), which already returns void. Eventually after all drivers are converted, .remove_new() will be renamed to .remove(). Trivially convert this driver from always returning zero in the remove callback to the void returning variant. Reviewed-by: Dave Jiang Link: https://lore.kernel.org/r/fcb5545d45cf31caee31e0c66ed3521ead12c9b4.1712756722.git.u.kleine-koenig@pengutronix.de Signed-off-by: Uwe Kleine-König --- drivers/nvdimm/e820.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/nvdimm/e820.c b/drivers/nvdimm/e820.c index 4cd18be9d0e9..b84a1de7f23a 100644 --- a/drivers/nvdimm/e820.c +++ b/drivers/nvdimm/e820.c @@ -9,12 +9,11 @@ #include #include -static int e820_pmem_remove(struct platform_device *pdev) +static void e820_pmem_remove(struct platform_device *pdev) { struct nvdimm_bus *nvdimm_bus = platform_get_drvdata(pdev); nvdimm_bus_unregister(nvdimm_bus); - return 0; } static int e820_register_one(struct resource *res, void *data) @@ -60,7 +59,7 @@ err: static struct platform_driver e820_pmem_driver = { .probe = e820_pmem_probe, - .remove = e820_pmem_remove, + .remove_new = e820_pmem_remove, .driver = { .name = "e820_pmem", }, From 4998f389c981f092d2aceab5b47163c5ef7f4d0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 10 Apr 2024 15:47:34 +0200 Subject: [PATCH 15/55] nvdimm/of_pmem: Convert to platform remove callback returning void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new(), which already returns void. Eventually after all drivers are converted, .remove_new() will be renamed to .remove(). Trivially convert this driver from always returning zero in the remove callback to the void returning variant. Reviewed-by: Dave Jiang Link: https://lore.kernel.org/r/8de0900f8c9f40648295fd9e2f445c85b2593d26.1712756722.git.u.kleine-koenig@pengutronix.de Signed-off-by: Uwe Kleine-König --- drivers/nvdimm/of_pmem.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/nvdimm/of_pmem.c b/drivers/nvdimm/of_pmem.c index d3fca0ab6290..10230a2f6619 100644 --- a/drivers/nvdimm/of_pmem.c +++ b/drivers/nvdimm/of_pmem.c @@ -84,14 +84,12 @@ static int of_pmem_region_probe(struct platform_device *pdev) return 0; } -static int of_pmem_region_remove(struct platform_device *pdev) +static void of_pmem_region_remove(struct platform_device *pdev) { struct of_pmem_private *priv = platform_get_drvdata(pdev); nvdimm_bus_unregister(priv->bus); kfree(priv); - - return 0; } static const struct of_device_id of_pmem_region_match[] = { @@ -102,7 +100,7 @@ static const struct of_device_id of_pmem_region_match[] = { static struct platform_driver of_pmem_region_driver = { .probe = of_pmem_region_probe, - .remove = of_pmem_region_remove, + .remove_new = of_pmem_region_remove, .driver = { .name = "of_pmem", .of_match_table = of_pmem_region_match, From 45e7d78ef5e93520e574c05d27bcb3b69234486c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 8 Mar 2024 09:51:21 +0100 Subject: [PATCH 16/55] samples: qmi: Convert to platform remove callback returning void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new(), which already returns void. Eventually after all drivers are converted, .remove_new() will be renamed to .remove(). Trivially convert this driver from always returning zero in the remove callback to the void returning variant. Link: https://lore.kernel.org/r/d30beb557e0e97ea194028f62d3c4c10841d3e7c.1709886922.git.u.kleine-koenig@pengutronix.de Signed-off-by: Uwe Kleine-König --- samples/qmi/qmi_sample_client.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/samples/qmi/qmi_sample_client.c b/samples/qmi/qmi_sample_client.c index c045e3d24326..a42892523d3b 100644 --- a/samples/qmi/qmi_sample_client.c +++ b/samples/qmi/qmi_sample_client.c @@ -511,7 +511,7 @@ err_release_qmi_handle: return ret; } -static int qmi_sample_remove(struct platform_device *pdev) +static void qmi_sample_remove(struct platform_device *pdev) { struct qmi_sample *sample = platform_get_drvdata(pdev); @@ -520,13 +520,11 @@ static int qmi_sample_remove(struct platform_device *pdev) debugfs_remove(sample->de_dir); qmi_handle_release(&sample->qmi); - - return 0; } static struct platform_driver qmi_sample_driver = { .probe = qmi_sample_probe, - .remove = qmi_sample_remove, + .remove_new = qmi_sample_remove, .driver = { .name = "qmi_sample_client", }, From 0edb555a65d1ef047a9805051c36922b52a38a9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Mon, 9 Oct 2023 12:37:26 +0200 Subject: [PATCH 17/55] platform: Make platform_driver::remove() return void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit struct platform_driver::remove returning an integer made driver authors expect that returning an error code was proper error handling. However the driver core ignores the error and continues to remove the device because there is nothing the core could do anyhow and reentering the remove callback again is only calling for trouble. To prevent such wrong assumptions, change the return type of the remove callback to void. This was prepared by introducing an alternative remove callback returning void and converting all drivers to that. So .remove() can be changed without further changes in drivers. This corresponds to step b) of the plan outlined in commit 5c5a7680e67b ("platform: Provide a remove callback that returns no value"). Signed-off-by: Uwe Kleine-König --- drivers/base/platform.c | 10 ++-------- include/linux/platform_device.h | 15 +++++++-------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 10c577963418..c8aa1be70526 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -1420,14 +1420,8 @@ static void platform_remove(struct device *_dev) struct platform_driver *drv = to_platform_driver(_dev->driver); struct platform_device *dev = to_platform_device(_dev); - if (drv->remove_new) { - drv->remove_new(dev); - } else if (drv->remove) { - int ret = drv->remove(dev); - - if (ret) - dev_warn(_dev, "remove callback returned a non-zero value. This will be ignored.\n"); - } + if (drv->remove) + drv->remove(dev); dev_pm_domain_detach(_dev, true); } diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 7a41c72c1959..d422db6eec63 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -237,15 +237,14 @@ struct platform_driver { int (*probe)(struct platform_device *); /* - * Traditionally the remove callback returned an int which however is - * ignored by the driver core. This led to wrong expectations by driver - * authors who thought returning an error code was a valid error - * handling strategy. To convert to a callback returning void, new - * drivers should implement .remove_new() until the conversion it done - * that eventually makes .remove() return void. + * .remove_new() is a relic from a prototype conversion of .remove(). + * New drivers are supposed to implement .remove(). Once all drivers are + * converted to not use .remove_new any more, it will be dropped. */ - int (*remove)(struct platform_device *); - void (*remove_new)(struct platform_device *); + union { + void (*remove)(struct platform_device *); + void (*remove_new)(struct platform_device *); + }; void (*shutdown)(struct platform_device *); int (*suspend)(struct platform_device *, pm_message_t state); From 161364bdcfc4386652f26857c357982a6f517fd2 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Sat, 1 Jun 2024 18:18:48 -0700 Subject: [PATCH 18/55] samples/kobject: add missing MODULE_DESCRIPTION() macros make allmodconfig && make W=1 C=1 reports: WARNING: modpost: missing MODULE_DESCRIPTION() in samples/kobject/kobject-example.o WARNING: modpost: missing MODULE_DESCRIPTION() in samples/kobject/kset-example.o Add the missing invocations of the MODULE_DESCRIPTION() macro. Signed-off-by: Jeff Johnson Link: https://lore.kernel.org/r/20240601-md-samples-kobject-v1-1-f63b215d50cb@quicinc.com Signed-off-by: Greg Kroah-Hartman --- samples/kobject/kobject-example.c | 1 + samples/kobject/kset-example.c | 1 + 2 files changed, 2 insertions(+) diff --git a/samples/kobject/kobject-example.c b/samples/kobject/kobject-example.c index 96678ed73216..c9c3db19799a 100644 --- a/samples/kobject/kobject-example.c +++ b/samples/kobject/kobject-example.c @@ -140,5 +140,6 @@ static void __exit example_exit(void) module_init(example_init); module_exit(example_exit); +MODULE_DESCRIPTION("Sample kobject implementation"); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Greg Kroah-Hartman "); diff --git a/samples/kobject/kset-example.c b/samples/kobject/kset-example.c index 342452282719..552d7e363539 100644 --- a/samples/kobject/kset-example.c +++ b/samples/kobject/kset-example.c @@ -284,5 +284,6 @@ static void __exit example_exit(void) module_init(example_init); module_exit(example_exit); +MODULE_DESCRIPTION("Sample kset and ktype implementation"); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Greg Kroah-Hartman "); From 1968845d358e108cfbfba45538d64b3cbdf04ac2 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 31 May 2024 17:51:29 +0300 Subject: [PATCH 19/55] driver core: device.h: Group of_node handling declarations and definitions There are a few of_node related APIs defined in the driver core. Group the respective declarations and definitions in the header. There is no functional change. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20240531145129.1506733-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/include/linux/device.h b/include/linux/device.h index fc3bd7116ab9..56f266429229 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1031,13 +1031,6 @@ static inline void device_lock_assert(struct device *dev) lockdep_assert_held(&dev->mutex); } -static inline struct device_node *dev_of_node(struct device *dev) -{ - if (!IS_ENABLED(CONFIG_OF) || !dev) - return NULL; - return dev->of_node; -} - static inline bool dev_has_sync_state(struct device *dev) { if (!dev) @@ -1144,10 +1137,18 @@ void unlock_device_hotplug(void); int lock_device_hotplug_sysfs(void); int device_offline(struct device *dev); int device_online(struct device *dev); + void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode); void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode); -void device_set_of_node_from_dev(struct device *dev, const struct device *dev2); void device_set_node(struct device *dev, struct fwnode_handle *fwnode); +void device_set_of_node_from_dev(struct device *dev, const struct device *dev2); + +static inline struct device_node *dev_of_node(struct device *dev) +{ + if (!IS_ENABLED(CONFIG_OF) || !dev) + return NULL; + return dev->of_node; +} static inline int dev_num_vf(struct device *dev) { From d7d3ae441e29f0ca56c69cdd3a47769227b7be3d Mon Sep 17 00:00:00 2001 From: Ivan Orlov Date: Fri, 12 Apr 2024 16:17:26 +0100 Subject: [PATCH 20/55] dca: make dca_class a static const structure The driver core allows for struct class to be in read-only memory. Move the dca_class structure to be declared at build time placing it into read-only memory, instead of having to be dynamically allocated at boot time. Suggested-by: Greg Kroah-Hartman Signed-off-by: Ivan Orlov Link: https://lore.kernel.org/r/20240412151726.189030-1-ivan.orlov0322@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/dca/dca-sysfs.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/dca/dca-sysfs.c b/drivers/dca/dca-sysfs.c index fcc83ede0909..b915c2b4601e 100644 --- a/drivers/dca/dca-sysfs.c +++ b/drivers/dca/dca-sysfs.c @@ -13,7 +13,9 @@ #include #include -static struct class *dca_class; +static const struct class dca_class = { + .name = "dca", +}; static struct idr dca_idr; static spinlock_t dca_idr_lock; @@ -22,14 +24,14 @@ int dca_sysfs_add_req(struct dca_provider *dca, struct device *dev, int slot) struct device *cd; static int req_count; - cd = device_create(dca_class, dca->cd, MKDEV(0, slot + 1), NULL, + cd = device_create(&dca_class, dca->cd, MKDEV(0, slot + 1), NULL, "requester%d", req_count++); return PTR_ERR_OR_ZERO(cd); } void dca_sysfs_remove_req(struct dca_provider *dca, int slot) { - device_destroy(dca_class, MKDEV(0, slot + 1)); + device_destroy(&dca_class, MKDEV(0, slot + 1)); } int dca_sysfs_add_provider(struct dca_provider *dca, struct device *dev) @@ -49,7 +51,7 @@ int dca_sysfs_add_provider(struct dca_provider *dca, struct device *dev) if (ret < 0) return ret; - cd = device_create(dca_class, dev, MKDEV(0, 0), NULL, "dca%d", dca->id); + cd = device_create(&dca_class, dev, MKDEV(0, 0), NULL, "dca%d", dca->id); if (IS_ERR(cd)) { spin_lock(&dca_idr_lock); idr_remove(&dca_idr, dca->id); @@ -71,20 +73,22 @@ void dca_sysfs_remove_provider(struct dca_provider *dca) int __init dca_sysfs_init(void) { + int err; + idr_init(&dca_idr); spin_lock_init(&dca_idr_lock); - dca_class = class_create("dca"); - if (IS_ERR(dca_class)) { + err = class_register(&dca_class); + if (err) { idr_destroy(&dca_idr); - return PTR_ERR(dca_class); + return err; } return 0; } void __exit dca_sysfs_exit(void) { - class_destroy(dca_class); + class_unregister(&dca_class); idr_destroy(&dca_idr); } From 97b1974547c517d8b5cba1fa0cc7213399ff0d2c Mon Sep 17 00:00:00 2001 From: Vincenzo Mezzela Date: Fri, 7 Jun 2024 18:33:49 +0200 Subject: [PATCH 21/55] drivers: arch_topology: Refactor do-while loops Refactor do-while loops to move break condition within the loop's scope. This modification is in preparation to move the declaration of the device_node directly within the loop and take advantage of the automatic cleanup feature provided by the __free(device_node) attribute. Acked-by: Sudeep Holla Signed-off-by: Vincenzo Mezzela Link: https://lore.kernel.org/r/20240607163350.392971-2-vincenzo.mezzela@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/arch_topology.c | 107 ++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 52 deletions(-) diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index c66d070207a0..583f11bd4d2e 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -543,23 +543,24 @@ static int __init parse_core(struct device_node *core, int package_id, do { snprintf(name, sizeof(name), "thread%d", i); t = of_get_child_by_name(core, name); - if (t) { - leaf = false; - cpu = get_cpu_for_node(t); - if (cpu >= 0) { - cpu_topology[cpu].package_id = package_id; - cpu_topology[cpu].cluster_id = cluster_id; - cpu_topology[cpu].core_id = core_id; - cpu_topology[cpu].thread_id = i; - } else if (cpu != -ENODEV) { - pr_err("%pOF: Can't get CPU for thread\n", t); - of_node_put(t); - return -EINVAL; - } + if (!t) + break; + + leaf = false; + cpu = get_cpu_for_node(t); + if (cpu >= 0) { + cpu_topology[cpu].package_id = package_id; + cpu_topology[cpu].cluster_id = cluster_id; + cpu_topology[cpu].core_id = core_id; + cpu_topology[cpu].thread_id = i; + } else if (cpu != -ENODEV) { + pr_err("%pOF: Can't get CPU for thread\n", t); of_node_put(t); + return -EINVAL; } + of_node_put(t); i++; - } while (t); + } while (1); cpu = get_cpu_for_node(core); if (cpu >= 0) { @@ -599,48 +600,48 @@ static int __init parse_cluster(struct device_node *cluster, int package_id, do { snprintf(name, sizeof(name), "cluster%d", i); c = of_get_child_by_name(cluster, name); - if (c) { - leaf = false; - ret = parse_cluster(c, package_id, i, depth + 1); - if (depth > 0) - pr_warn("Topology for clusters of clusters not yet supported\n"); - of_node_put(c); - if (ret != 0) - return ret; - } + if (!c) + break; + + leaf = false; + ret = parse_cluster(c, package_id, i, depth + 1); + if (depth > 0) + pr_warn("Topology for clusters of clusters not yet supported\n"); + of_node_put(c); + if (ret != 0) + return ret; i++; - } while (c); + } while (1); /* Now check for cores */ i = 0; do { snprintf(name, sizeof(name), "core%d", i); c = of_get_child_by_name(cluster, name); - if (c) { - has_cores = true; + if (!c) + break; - if (depth == 0) { - pr_err("%pOF: cpu-map children should be clusters\n", - c); - of_node_put(c); - return -EINVAL; - } - - if (leaf) { - ret = parse_core(c, package_id, cluster_id, - core_id++); - } else { - pr_err("%pOF: Non-leaf cluster with core %s\n", - cluster, name); - ret = -EINVAL; - } + has_cores = true; + if (depth == 0) { + pr_err("%pOF: cpu-map children should be clusters\n", c); of_node_put(c); - if (ret != 0) - return ret; + return -EINVAL; } + + if (leaf) { + ret = parse_core(c, package_id, cluster_id, core_id++); + } else { + pr_err("%pOF: Non-leaf cluster with core %s\n", + cluster, name); + ret = -EINVAL; + } + + of_node_put(c); + if (ret != 0) + return ret; i++; - } while (c); + } while (1); if (leaf && !has_cores) pr_warn("%pOF: empty cluster\n", cluster); @@ -658,15 +659,17 @@ static int __init parse_socket(struct device_node *socket) do { snprintf(name, sizeof(name), "socket%d", package_id); c = of_get_child_by_name(socket, name); - if (c) { - has_socket = true; - ret = parse_cluster(c, package_id, -1, 0); - of_node_put(c); - if (ret != 0) - return ret; - } + if (!c) + break; + + has_socket = true; + ret = parse_cluster(c, package_id, -1, 0); + of_node_put(c); + if (ret != 0) + return ret; + package_id++; - } while (c); + } while (1); if (!has_socket) ret = parse_cluster(socket, 0, -1, 0); From 880f5f58fd1aa22540d7e24693f411f6416b86d3 Mon Sep 17 00:00:00 2001 From: Vincenzo Mezzela Date: Fri, 7 Jun 2024 18:33:50 +0200 Subject: [PATCH 22/55] drivers: arch_topology: use __free attribute instead of of_node_put() Introduce the __free attribute for scope-based resource management. Resources allocated with __free are automatically released at the end of the scope. This enhancement aims to mitigate memory management issues associated with forgetting to release resources by utilizing __free instead of of_node_put(). The declaration of the device_node used within the do-while loops is moved directly within the loop so that the resource is automatically freed at the end of each iteration. Acked-by: Sudeep Holla Suggested-by: Julia Lawall Signed-off-by: Vincenzo Mezzela Link: https://lore.kernel.org/r/20240607163350.392971-3-vincenzo.mezzela@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/arch_topology.c | 56 +++++++++++++++++------------------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index 583f11bd4d2e..75fcb75d5515 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -513,10 +514,10 @@ core_initcall(free_raw_capacity); */ static int __init get_cpu_for_node(struct device_node *node) { - struct device_node *cpu_node; int cpu; + struct device_node *cpu_node __free(device_node) = + of_parse_phandle(node, "cpu", 0); - cpu_node = of_parse_phandle(node, "cpu", 0); if (!cpu_node) return -1; @@ -527,7 +528,6 @@ static int __init get_cpu_for_node(struct device_node *node) pr_info("CPU node for %pOF exist but the possible cpu range is :%*pbl\n", cpu_node, cpumask_pr_args(cpu_possible_mask)); - of_node_put(cpu_node); return cpu; } @@ -538,11 +538,12 @@ static int __init parse_core(struct device_node *core, int package_id, bool leaf = true; int i = 0; int cpu; - struct device_node *t; do { snprintf(name, sizeof(name), "thread%d", i); - t = of_get_child_by_name(core, name); + struct device_node *t __free(device_node) = + of_get_child_by_name(core, name); + if (!t) break; @@ -555,10 +556,8 @@ static int __init parse_core(struct device_node *core, int package_id, cpu_topology[cpu].thread_id = i; } else if (cpu != -ENODEV) { pr_err("%pOF: Can't get CPU for thread\n", t); - of_node_put(t); return -EINVAL; } - of_node_put(t); i++; } while (1); @@ -587,7 +586,6 @@ static int __init parse_cluster(struct device_node *cluster, int package_id, char name[20]; bool leaf = true; bool has_cores = false; - struct device_node *c; int core_id = 0; int i, ret; @@ -599,7 +597,9 @@ static int __init parse_cluster(struct device_node *cluster, int package_id, i = 0; do { snprintf(name, sizeof(name), "cluster%d", i); - c = of_get_child_by_name(cluster, name); + struct device_node *c __free(device_node) = + of_get_child_by_name(cluster, name); + if (!c) break; @@ -607,7 +607,6 @@ static int __init parse_cluster(struct device_node *cluster, int package_id, ret = parse_cluster(c, package_id, i, depth + 1); if (depth > 0) pr_warn("Topology for clusters of clusters not yet supported\n"); - of_node_put(c); if (ret != 0) return ret; i++; @@ -617,7 +616,9 @@ static int __init parse_cluster(struct device_node *cluster, int package_id, i = 0; do { snprintf(name, sizeof(name), "core%d", i); - c = of_get_child_by_name(cluster, name); + struct device_node *c __free(device_node) = + of_get_child_by_name(cluster, name); + if (!c) break; @@ -625,21 +626,19 @@ static int __init parse_cluster(struct device_node *cluster, int package_id, if (depth == 0) { pr_err("%pOF: cpu-map children should be clusters\n", c); - of_node_put(c); return -EINVAL; } if (leaf) { ret = parse_core(c, package_id, cluster_id, core_id++); + if (ret != 0) + return ret; } else { pr_err("%pOF: Non-leaf cluster with core %s\n", cluster, name); - ret = -EINVAL; + return -EINVAL; } - of_node_put(c); - if (ret != 0) - return ret; i++; } while (1); @@ -652,19 +651,19 @@ static int __init parse_cluster(struct device_node *cluster, int package_id, static int __init parse_socket(struct device_node *socket) { char name[20]; - struct device_node *c; bool has_socket = false; int package_id = 0, ret; do { snprintf(name, sizeof(name), "socket%d", package_id); - c = of_get_child_by_name(socket, name); + struct device_node *c __free(device_node) = + of_get_child_by_name(socket, name); + if (!c) break; has_socket = true; ret = parse_cluster(c, package_id, -1, 0); - of_node_put(c); if (ret != 0) return ret; @@ -679,11 +678,11 @@ static int __init parse_socket(struct device_node *socket) static int __init parse_dt_topology(void) { - struct device_node *cn, *map; int ret = 0; int cpu; + struct device_node *cn __free(device_node) = + of_find_node_by_path("/cpus"); - cn = of_find_node_by_path("/cpus"); if (!cn) { pr_err("No CPU information found in DT\n"); return 0; @@ -693,13 +692,15 @@ static int __init parse_dt_topology(void) * When topology is provided cpu-map is essentially a root * cluster with restricted subnodes. */ - map = of_get_child_by_name(cn, "cpu-map"); + struct device_node *map __free(device_node) = + of_get_child_by_name(cn, "cpu-map"); + if (!map) - goto out; + return ret; ret = parse_socket(map); if (ret != 0) - goto out_map; + return ret; topology_normalize_cpu_scale(); @@ -709,14 +710,9 @@ static int __init parse_dt_topology(void) */ for_each_possible_cpu(cpu) if (cpu_topology[cpu].package_id < 0) { - ret = -EINVAL; - break; + return -EINVAL; } -out_map: - of_node_put(map); -out: - of_node_put(cn); return ret; } #endif From dd6e9894b451e7c85cceb8e9dc5432679a70e7dc Mon Sep 17 00:00:00 2001 From: Zijun Hu Date: Thu, 30 May 2024 21:14:37 +0800 Subject: [PATCH 23/55] kobject_uevent: Fix OOB access within zap_modalias_env() zap_modalias_env() wrongly calculates size of memory block to move, so will cause OOB memory access issue if variable MODALIAS is not the last one within its @env parameter, fixed by correcting size to memmove. Fixes: 9b3fa47d4a76 ("kobject: fix suppressing modalias in uevents delivered over netlink") Cc: stable@vger.kernel.org Signed-off-by: Zijun Hu Reviewed-by: Lk Sii Link: https://lore.kernel.org/r/1717074877-11352-1-git-send-email-quic_zijuhu@quicinc.com Signed-off-by: Greg Kroah-Hartman --- lib/kobject_uevent.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index 03b427e2707e..b7f2fa08d9c8 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c @@ -433,8 +433,23 @@ static void zap_modalias_env(struct kobj_uevent_env *env) len = strlen(env->envp[i]) + 1; if (i != env->envp_idx - 1) { + /* @env->envp[] contains pointers to @env->buf[] + * with @env->buflen chars, and we are removing + * variable MODALIAS here pointed by @env->envp[i] + * with length @len as shown below: + * + * 0 @env->buf[] @env->buflen + * --------------------------------------------- + * ^ ^ ^ ^ + * | |-> @len <-| target block | + * @env->envp[0] @env->envp[i] @env->envp[i + 1] + * + * so the "target block" indicated above is moved + * backward by @len, and its right size is + * @env->buflen - (@env->envp[i + 1] - @env->envp[0]). + */ memmove(env->envp[i], env->envp[i + 1], - env->buflen - len); + env->buflen - (env->envp[i + 1] - env->envp[0])); for (j = i; j < env->envp_idx - 1; j++) env->envp[j] = env->envp[j + 1] - len; From 477e36546e6fa79282427d5b82a9a9a67504de1a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 10 Jun 2024 10:19:42 +0200 Subject: [PATCH 24/55] nvdimm: make nd_class constant Now that the driver core allows for struct class to be in read-only memory, it is possible to make all 'class' structures be declared at build time. Move the class to a 'static const' declaration and register it rather than dynamically create it." Cc: Vishal Verma Cc: Dave Jiang Cc: nvdimm@lists.linux.dev Reviewed-by: Dan Williams Reviewed-by: Ira Weiny Link: https://lore.kernel.org/r/2024061041-grandkid-coherence-19b0@gregkh Signed-off-by: Greg Kroah-Hartman --- drivers/nvdimm/bus.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c index 508aed017ddc..101c425f3e8b 100644 --- a/drivers/nvdimm/bus.c +++ b/drivers/nvdimm/bus.c @@ -25,9 +25,12 @@ int nvdimm_major; static int nvdimm_bus_major; -static struct class *nd_class; static DEFINE_IDA(nd_ida); +static const struct class nd_class = { + .name = "nd", +}; + static int to_nd_device_type(const struct device *dev) { if (is_nvdimm(dev)) @@ -742,7 +745,7 @@ int nvdimm_bus_create_ndctl(struct nvdimm_bus *nvdimm_bus) device_initialize(dev); lockdep_set_class(&dev->mutex, &nvdimm_ndctl_key); device_set_pm_not_required(dev); - dev->class = nd_class; + dev->class = &nd_class; dev->parent = &nvdimm_bus->dev; dev->devt = devt; dev->release = ndctl_release; @@ -765,7 +768,7 @@ err: void nvdimm_bus_destroy_ndctl(struct nvdimm_bus *nvdimm_bus) { - device_destroy(nd_class, MKDEV(nvdimm_bus_major, nvdimm_bus->id)); + device_destroy(&nd_class, MKDEV(nvdimm_bus_major, nvdimm_bus->id)); } static const struct nd_cmd_desc __nd_cmd_dimm_descs[] = { @@ -1320,11 +1323,9 @@ int __init nvdimm_bus_init(void) goto err_dimm_chrdev; nvdimm_major = rc; - nd_class = class_create("nd"); - if (IS_ERR(nd_class)) { - rc = PTR_ERR(nd_class); + rc = class_register(&nd_class); + if (rc) goto err_class; - } rc = driver_register(&nd_bus_driver.drv); if (rc) @@ -1333,7 +1334,7 @@ int __init nvdimm_bus_init(void) return 0; err_nd_bus: - class_destroy(nd_class); + class_unregister(&nd_class); err_class: unregister_chrdev(nvdimm_major, "dimmctl"); err_dimm_chrdev: @@ -1347,7 +1348,7 @@ int __init nvdimm_bus_init(void) void nvdimm_bus_exit(void) { driver_unregister(&nd_bus_driver.drv); - class_destroy(nd_class); + class_unregister(&nd_class); unregister_chrdev(nvdimm_bus_major, "ndctl"); unregister_chrdev(nvdimm_major, "dimmctl"); bus_unregister(&nvdimm_bus_type); From ff985c759778986f55cbc557055fbeb84ee833eb Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 11 Jun 2024 15:01:04 +0200 Subject: [PATCH 25/55] auxbus: make to_auxiliary_drv accept and return a constant pointer In the quest to make struct device constant, start by making to_auxiliary_drv() return a constant pointer so that drivers that call this can be fixed up before the driver core changes. As the return type previously was not constant, also fix up all callers that were assuming that the pointer was not going to be a constant one in order to not break the build. Cc: Dave Ertman Cc: Ira Weiny Cc: Rafael J. Wysocki Cc: Bingbu Cao Cc: Tianshu Qiu Cc: Mauro Carvalho Chehab Cc: Michael Chan Cc: David S. Miller Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: Jesse Brandeburg Cc: Tony Nguyen Cc: Saeed Mahameed Cc: Leon Romanovsky Cc: Tariq Toukan Cc: Pierre-Louis Bossart Cc: Liam Girdwood Cc: Peter Ujfalusi Cc: Bard Liao Cc: Ranjani Sridharan Cc: Daniel Baluta Cc: Kai Vehmanen Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Richard Cochran Cc: linux-media@vger.kernel.org Cc: netdev@vger.kernel.org Cc: intel-wired-lan@lists.osuosl.org Cc: linux-rdma@vger.kernel.org Cc: sound-open-firmware@alsa-project.org Cc: linux-sound@vger.kernel.org Acked-by: Sakari Ailus # drivers/media/pci/intel/ipu6 Acked-by: Mark Brown Reviewed-by: Martin Habets Link: https://lore.kernel.org/r/20240611130103.3262749-7-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/auxiliary.c | 8 ++++---- drivers/media/pci/intel/ipu6/ipu6-bus.h | 2 +- drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c | 4 ++-- drivers/net/ethernet/intel/ice/ice_ptp.c | 2 +- drivers/net/ethernet/mellanox/mlx5/core/dev.c | 4 ++-- include/linux/auxiliary_bus.h | 2 +- sound/soc/sof/sof-client.c | 4 ++-- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c index d3a2c40c2f12..5832e31bb77b 100644 --- a/drivers/base/auxiliary.c +++ b/drivers/base/auxiliary.c @@ -180,7 +180,7 @@ static const struct auxiliary_device_id *auxiliary_match_id(const struct auxilia static int auxiliary_match(struct device *dev, struct device_driver *drv) { struct auxiliary_device *auxdev = to_auxiliary_dev(dev); - struct auxiliary_driver *auxdrv = to_auxiliary_drv(drv); + const struct auxiliary_driver *auxdrv = to_auxiliary_drv(drv); return !!auxiliary_match_id(auxdrv->id_table, auxdev); } @@ -203,7 +203,7 @@ static const struct dev_pm_ops auxiliary_dev_pm_ops = { static int auxiliary_bus_probe(struct device *dev) { - struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); + const struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); struct auxiliary_device *auxdev = to_auxiliary_dev(dev); int ret; @@ -222,7 +222,7 @@ static int auxiliary_bus_probe(struct device *dev) static void auxiliary_bus_remove(struct device *dev) { - struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); + const struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver); struct auxiliary_device *auxdev = to_auxiliary_dev(dev); if (auxdrv->remove) @@ -232,7 +232,7 @@ static void auxiliary_bus_remove(struct device *dev) static void auxiliary_bus_shutdown(struct device *dev) { - struct auxiliary_driver *auxdrv = NULL; + const struct auxiliary_driver *auxdrv = NULL; struct auxiliary_device *auxdev; if (dev->driver) { diff --git a/drivers/media/pci/intel/ipu6/ipu6-bus.h b/drivers/media/pci/intel/ipu6/ipu6-bus.h index b26c6aee1621..bb4926dfdf08 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-bus.h +++ b/drivers/media/pci/intel/ipu6/ipu6-bus.h @@ -21,7 +21,7 @@ struct ipu6_buttress_ctrl; struct ipu6_bus_device { struct auxiliary_device auxdev; - struct auxiliary_driver *auxdrv; + const struct auxiliary_driver *auxdrv; const struct ipu6_auxdrv_data *auxdrv_data; struct list_head list; void *pdata; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c index ba3fa1c2e5d9..b9e7d3e7b15d 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c @@ -239,7 +239,7 @@ void bnxt_ulp_stop(struct bnxt *bp) adev = &aux_priv->aux_dev; if (adev->dev.driver) { - struct auxiliary_driver *adrv; + const struct auxiliary_driver *adrv; pm_message_t pm = {}; adrv = to_auxiliary_drv(adev->dev.driver); @@ -277,7 +277,7 @@ void bnxt_ulp_start(struct bnxt *bp, int err) adev = &aux_priv->aux_dev; if (adev->dev.driver) { - struct auxiliary_driver *adrv; + const struct auxiliary_driver *adrv; adrv = to_auxiliary_drv(adev->dev.driver); edev->en_state = bp->state; diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c index 0f17fc1181d2..7341e7c4ef24 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp.c @@ -2784,7 +2784,7 @@ static struct ice_pf * ice_ptp_aux_dev_to_owner_pf(struct auxiliary_device *aux_dev) { struct ice_ptp_port_owner *ports_owner; - struct auxiliary_driver *aux_drv; + const struct auxiliary_driver *aux_drv; struct ice_ptp *owner_ptp; if (!aux_dev->dev.driver) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dev.c b/drivers/net/ethernet/mellanox/mlx5/core/dev.c index 47e7c2639774..9a79674d27f1 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/dev.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/dev.c @@ -349,7 +349,7 @@ int mlx5_attach_device(struct mlx5_core_dev *dev) { struct mlx5_priv *priv = &dev->priv; struct auxiliary_device *adev; - struct auxiliary_driver *adrv; + const struct auxiliary_driver *adrv; int ret = 0, i; devl_assert_locked(priv_to_devlink(dev)); @@ -406,7 +406,7 @@ void mlx5_detach_device(struct mlx5_core_dev *dev, bool suspend) { struct mlx5_priv *priv = &dev->priv; struct auxiliary_device *adev; - struct auxiliary_driver *adrv; + const struct auxiliary_driver *adrv; pm_message_t pm = {}; int i; diff --git a/include/linux/auxiliary_bus.h b/include/linux/auxiliary_bus.h index de21d9d24a95..bdff7b85f2ae 100644 --- a/include/linux/auxiliary_bus.h +++ b/include/linux/auxiliary_bus.h @@ -203,7 +203,7 @@ static inline struct auxiliary_device *to_auxiliary_dev(struct device *dev) return container_of(dev, struct auxiliary_device, dev); } -static inline struct auxiliary_driver *to_auxiliary_drv(struct device_driver *drv) +static inline const struct auxiliary_driver *to_auxiliary_drv(const struct device_driver *drv) { return container_of(drv, struct auxiliary_driver, driver); } diff --git a/sound/soc/sof/sof-client.c b/sound/soc/sof/sof-client.c index 99f74def4ab6..5d6005a88e79 100644 --- a/sound/soc/sof/sof-client.c +++ b/sound/soc/sof/sof-client.c @@ -357,7 +357,7 @@ EXPORT_SYMBOL_NS_GPL(sof_client_ipc4_find_module, SND_SOC_SOF_CLIENT); int sof_suspend_clients(struct snd_sof_dev *sdev, pm_message_t state) { - struct auxiliary_driver *adrv; + const struct auxiliary_driver *adrv; struct sof_client_dev *cdev; mutex_lock(&sdev->ipc_client_mutex); @@ -380,7 +380,7 @@ EXPORT_SYMBOL_NS_GPL(sof_suspend_clients, SND_SOC_SOF_CLIENT); int sof_resume_clients(struct snd_sof_dev *sdev) { - struct auxiliary_driver *adrv; + const struct auxiliary_driver *adrv; struct sof_client_dev *cdev; mutex_lock(&sdev->ipc_client_mutex); From 841b7ebf819491b4a7e701ee4d42a55810606c96 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 11 Jun 2024 15:01:05 +0200 Subject: [PATCH 26/55] driver core: platform: fix ups for constant struct device_driver Fix up a few places in the platform core code that can easily handle struct device_driver being constant. This is part of the work to make all struct device_driver pointers be constant. Cc: Rafael J. Wysocki Link: https://lore.kernel.org/r/20240611130103.3262749-8-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/platform.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index c8aa1be70526..a6884479f4ac 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -1122,7 +1122,7 @@ static int platform_legacy_resume(struct device *dev) int platform_pm_suspend(struct device *dev) { - struct device_driver *drv = dev->driver; + const struct device_driver *drv = dev->driver; int ret = 0; if (!drv) @@ -1140,7 +1140,7 @@ int platform_pm_suspend(struct device *dev) int platform_pm_resume(struct device *dev) { - struct device_driver *drv = dev->driver; + const struct device_driver *drv = dev->driver; int ret = 0; if (!drv) @@ -1162,7 +1162,7 @@ int platform_pm_resume(struct device *dev) int platform_pm_freeze(struct device *dev) { - struct device_driver *drv = dev->driver; + const struct device_driver *drv = dev->driver; int ret = 0; if (!drv) @@ -1180,7 +1180,7 @@ int platform_pm_freeze(struct device *dev) int platform_pm_thaw(struct device *dev) { - struct device_driver *drv = dev->driver; + const struct device_driver *drv = dev->driver; int ret = 0; if (!drv) @@ -1198,7 +1198,7 @@ int platform_pm_thaw(struct device *dev) int platform_pm_poweroff(struct device *dev) { - struct device_driver *drv = dev->driver; + const struct device_driver *drv = dev->driver; int ret = 0; if (!drv) @@ -1216,7 +1216,7 @@ int platform_pm_poweroff(struct device *dev) int platform_pm_restore(struct device *dev) { - struct device_driver *drv = dev->driver; + const struct device_driver *drv = dev->driver; int ret = 0; if (!drv) From 0725e8f9c442650924271a35017e6cce4315f3f1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 11 Jun 2024 15:01:06 +0200 Subject: [PATCH 27/55] driver core: driver: mark driver_add/remove_groups constant driver_add_groups() and driver_remove_groups should take a constant pointer as the structure is not modified, so make the change. Cc: Rafael J. Wysocki Link: https://lore.kernel.org/r/20240611130103.3262749-9-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/base.h | 4 ++-- drivers/base/driver.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/base/base.h b/drivers/base/base.h index db4f910e8e36..cba8307908c7 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -175,8 +175,8 @@ static inline void dev_sync_state(struct device *dev) dev->driver->sync_state(dev); } -int driver_add_groups(struct device_driver *drv, const struct attribute_group **groups); -void driver_remove_groups(struct device_driver *drv, const struct attribute_group **groups); +int driver_add_groups(const struct device_driver *drv, const struct attribute_group **groups); +void driver_remove_groups(const struct device_driver *drv, const struct attribute_group **groups); void device_driver_detach(struct device *dev); int devres_release_all(struct device *dev); diff --git a/drivers/base/driver.c b/drivers/base/driver.c index c8436c26ed6a..85b4c00df078 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -199,13 +199,13 @@ void driver_remove_file(struct device_driver *drv, } EXPORT_SYMBOL_GPL(driver_remove_file); -int driver_add_groups(struct device_driver *drv, +int driver_add_groups(const struct device_driver *drv, const struct attribute_group **groups) { return sysfs_create_groups(&drv->p->kobj, groups); } -void driver_remove_groups(struct device_driver *drv, +void driver_remove_groups(const struct device_driver *drv, const struct attribute_group **groups) { sysfs_remove_groups(&drv->p->kobj, groups); From 33ebea9bc0a36f62590d37d0a3c859759181573e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 11 Jun 2024 15:01:07 +0200 Subject: [PATCH 28/55] driver core: make device_release_driver_internal() take a const * Change device_release_driver_internal() to take a const struct device_driver * as it is not modifying it at all. Cc: Rafael J. Wysocki Link: https://lore.kernel.org/r/20240611130103.3262749-10-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/base.h | 2 +- drivers/base/dd.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/base/base.h b/drivers/base/base.h index cba8307908c7..d332b87cde9e 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -155,7 +155,7 @@ bool bus_is_registered(const struct bus_type *bus); int bus_add_driver(struct device_driver *drv); void bus_remove_driver(struct device_driver *drv); -void device_release_driver_internal(struct device *dev, struct device_driver *drv, +void device_release_driver_internal(struct device *dev, const struct device_driver *drv, struct device *parent); void driver_detach(struct device_driver *drv); diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 83d352394fdf..c24eca917d41 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -1284,7 +1284,7 @@ static void __device_release_driver(struct device *dev, struct device *parent) } void device_release_driver_internal(struct device *dev, - struct device_driver *drv, + const struct device_driver *drv, struct device *parent) { __device_driver_lock(dev, parent); From f6e98ef5f78a106821d451f9783dd96ba8551cb3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 11 Jun 2024 15:01:08 +0200 Subject: [PATCH 29/55] driver core: make driver_detach() take a const * driver_detach() does not modify the driver itself, so make the pointer constant. In doing so, the function driver_allows_async_probing() also needs to be changed so that the pointer type passes through to that function properly. Cc: Rafael J. Wysocki Link: https://lore.kernel.org/r/20240611130103.3262749-11-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/base.h | 2 +- drivers/base/dd.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/base/base.h b/drivers/base/base.h index d332b87cde9e..9df8028c3201 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -158,7 +158,7 @@ void bus_remove_driver(struct device_driver *drv); void device_release_driver_internal(struct device *dev, const struct device_driver *drv, struct device *parent); -void driver_detach(struct device_driver *drv); +void driver_detach(const struct device_driver *drv); void driver_deferred_probe_del(struct device *dev); void device_set_deferred_probe_reason(const struct device *dev, struct va_format *vaf); static inline int driver_match_device(struct device_driver *drv, diff --git a/drivers/base/dd.c b/drivers/base/dd.c index c24eca917d41..76b26096b033 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -863,7 +863,7 @@ static int __init save_async_options(char *buf) } __setup("driver_async_probe=", save_async_options); -static bool driver_allows_async_probing(struct device_driver *drv) +static bool driver_allows_async_probing(const struct device_driver *drv) { switch (drv->probe_type) { case PROBE_PREFER_ASYNCHRONOUS: @@ -1333,7 +1333,7 @@ void device_driver_detach(struct device *dev) * driver_detach - detach driver from all devices it controls. * @drv: driver. */ -void driver_detach(struct device_driver *drv) +void driver_detach(const struct device_driver *drv) { struct device_private *dev_prv; struct device *dev; From c6c631d2b72b9390587cd1ee5b7905f8ea5bb1ea Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 11 Jun 2024 15:01:09 +0200 Subject: [PATCH 30/55] driver core: mark async_driver as a const * Within struct device_private, mark the async_driver * as const as it is never modified. This requires some internal-to-the-driver-core functions to also have their parameters marked as constant, and there is one place where we cast _back_ from the const pointer to a real one, as the driver core still wants to modify the structure in a number of remaining places. Cc: Rafael J. Wysocki Link: https://lore.kernel.org/r/20240611130103.3262749-12-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/base.h | 2 +- drivers/base/dd.c | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/base/base.h b/drivers/base/base.h index 9df8028c3201..50151e7db796 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -112,7 +112,7 @@ struct device_private { struct klist_node knode_bus; struct klist_node knode_class; struct list_head deferred_probe; - struct device_driver *async_driver; + const struct device_driver *async_driver; char *deferred_probe_reason; struct device *device; u8 dead:1; diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 76b26096b033..8ec22229e259 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -568,7 +568,7 @@ static void device_remove(struct device *dev) dev->driver->remove(dev); } -static int call_driver_probe(struct device *dev, struct device_driver *drv) +static int call_driver_probe(struct device *dev, const struct device_driver *drv) { int ret = 0; @@ -599,7 +599,7 @@ static int call_driver_probe(struct device *dev, struct device_driver *drv) return ret; } -static int really_probe(struct device *dev, struct device_driver *drv) +static int really_probe(struct device *dev, const struct device_driver *drv) { bool test_remove = IS_ENABLED(CONFIG_DEBUG_TEST_DRIVER_REMOVE) && !drv->suppress_bind_attrs; @@ -628,7 +628,8 @@ static int really_probe(struct device *dev, struct device_driver *drv) } re_probe: - dev->driver = drv; + // FIXME - this cast should not be needed "soon" + dev->driver = (struct device_driver *)drv; /* If using pinctrl, bind pins now before probing */ ret = pinctrl_bind_pins(dev); @@ -727,7 +728,7 @@ done: /* * For initcall_debug, show the driver probe time. */ -static int really_probe_debug(struct device *dev, struct device_driver *drv) +static int really_probe_debug(struct device *dev, const struct device_driver *drv) { ktime_t calltime, rettime; int ret; @@ -774,7 +775,7 @@ void wait_for_device_probe(void) } EXPORT_SYMBOL_GPL(wait_for_device_probe); -static int __driver_probe_device(struct device_driver *drv, struct device *dev) +static int __driver_probe_device(const struct device_driver *drv, struct device *dev) { int ret = 0; @@ -819,7 +820,7 @@ static int __driver_probe_device(struct device_driver *drv, struct device *dev) * * If the device has a parent, runtime-resume the parent before driver probing. */ -static int driver_probe_device(struct device_driver *drv, struct device *dev) +static int driver_probe_device(const struct device_driver *drv, struct device *dev) { int trigger_count = atomic_read(&deferred_trigger_count); int ret; @@ -1137,7 +1138,7 @@ EXPORT_SYMBOL_GPL(device_driver_attach); static void __driver_attach_async_helper(void *_dev, async_cookie_t cookie) { struct device *dev = _dev; - struct device_driver *drv; + const struct device_driver *drv; int ret; __device_driver_lock(dev, dev->parent); From fca3eff7d36bcd1a51d2c256ccebbe3617d4fe3a Mon Sep 17 00:00:00 2001 From: "Ricardo B. Marliere" Date: Sun, 4 Feb 2024 17:25:51 -0300 Subject: [PATCH 31/55] parport: make parport_bus_type const Now that the driver core can properly handle constant struct bus_type, move the parport_bus_type variable to be a constant structure as well, placing it into read-only memory which can not be modified at runtime. Suggested-by: Greg Kroah-Hartman Signed-off-by: Ricardo B. Marliere Reviewed-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20240204-bus_cleanup-parport-v1-1-e6a0f756bbb8@marliere.net Signed-off-by: Greg Kroah-Hartman --- drivers/parport/share.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/parport/share.c b/drivers/parport/share.c index 49c74ded8a53..08dfa74be3c5 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c @@ -130,7 +130,7 @@ static int parport_probe(struct device *dev) return drv->probe(to_pardevice(dev)); } -static struct bus_type parport_bus_type = { +static const struct bus_type parport_bus_type = { .name = "parport", .probe = parport_probe, }; From a674fefd17324fc467f043568e738b80ca22f2b4 Mon Sep 17 00:00:00 2001 From: Danilo Krummrich Date: Tue, 18 Jun 2024 17:48:34 +0200 Subject: [PATCH 32/55] rust: add abstraction for struct device Add an (always) reference-counted abstraction for a generic C `struct device`. This abstraction encapsulates existing `struct device` instances and manages its reference count. Subsystems may use this abstraction as a base to abstract subsystem specific device instances based on a generic `struct device`, such as `struct pci_dev`. Co-developed-by: Wedson Almeida Filho Signed-off-by: Wedson Almeida Filho Signed-off-by: Danilo Krummrich Link: https://lore.kernel.org/r/20240618154841.6716-2-dakr@redhat.com Signed-off-by: Greg Kroah-Hartman --- rust/helpers.c | 1 + rust/kernel/device.rs | 102 ++++++++++++++++++++++++++++++++++++++++++ rust/kernel/lib.rs | 1 + 3 files changed, 104 insertions(+) create mode 100644 rust/kernel/device.rs diff --git a/rust/helpers.c b/rust/helpers.c index 2c37a0f5d7a8..0e02b2c64c72 100644 --- a/rust/helpers.c +++ b/rust/helpers.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs new file mode 100644 index 000000000000..e445e87fb7d7 --- /dev/null +++ b/rust/kernel/device.rs @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Generic devices that are part of the kernel's driver model. +//! +//! C header: [`include/linux/device.h`](srctree/include/linux/device.h) + +use crate::{ + bindings, + types::{ARef, Opaque}, +}; +use core::ptr; + +/// A reference-counted device. +/// +/// This structure represents the Rust abstraction for a C `struct device`. This implementation +/// abstracts the usage of an already existing C `struct device` within Rust code that we get +/// passed from the C side. +/// +/// An instance of this abstraction can be obtained temporarily or permanent. +/// +/// A temporary one is bound to the lifetime of the C `struct device` pointer used for creation. +/// A permanent instance is always reference-counted and hence not restricted by any lifetime +/// boundaries. +/// +/// For subsystems it is recommended to create a permanent instance to wrap into a subsystem +/// specific device structure (e.g. `pci::Device`). This is useful for passing it to drivers in +/// `T::probe()`, such that a driver can store the `ARef` (equivalent to storing a +/// `struct device` pointer in a C driver) for arbitrary purposes, e.g. allocating DMA coherent +/// memory. +/// +/// # Invariants +/// +/// The pointer stored in `Self` is non-null and valid for the lifetime of the `ARef` instance. In +/// particular, the `ARef` instance owns an increment on the underlying object’s reference count. +/// +/// `bindings::device::release` is valid to be called from any thread, hence `ARef` can be +/// dropped from any thread. +#[repr(transparent)] +pub struct Device(Opaque); + +impl Device { + /// Creates a new reference-counted abstraction instance of an existing `struct device` pointer. + /// + /// # Safety + /// + /// Callers must ensure that `ptr` is valid, non-null, and has a non-zero reference count, + /// i.e. it must be ensured that the reference count of the C `struct device` `ptr` points to + /// can't drop to zero, for the duration of this function call. + /// + /// It must also be ensured that `bindings::device::release` can be called from any thread. + /// While not officially documented, this should be the case for any `struct device`. + pub unsafe fn from_raw(ptr: *mut bindings::device) -> ARef { + // SAFETY: By the safety requirements, ptr is valid. + // Initially increase the reference count by one to compensate for the final decrement once + // this newly created `ARef` instance is dropped. + unsafe { bindings::get_device(ptr) }; + + // CAST: `Self` is a `repr(transparent)` wrapper around `bindings::device`. + let ptr = ptr.cast::(); + + // SAFETY: By the safety requirements, ptr is valid. + unsafe { ARef::from_raw(ptr::NonNull::new_unchecked(ptr)) } + } + + /// Obtain the raw `struct device *`. + pub(crate) fn as_raw(&self) -> *mut bindings::device { + self.0.get() + } + + /// Convert a raw C `struct device` pointer to a `&'a Device`. + /// + /// # Safety + /// + /// Callers must ensure that `ptr` is valid, non-null, and has a non-zero reference count, + /// i.e. it must be ensured that the reference count of the C `struct device` `ptr` points to + /// can't drop to zero, for the duration of this function call and the entire duration when the + /// returned reference exists. + pub unsafe fn as_ref<'a>(ptr: *mut bindings::device) -> &'a Self { + // SAFETY: Guaranteed by the safety requirements of the function. + unsafe { &*ptr.cast() } + } +} + +// SAFETY: Instances of `Device` are always reference-counted. +unsafe impl crate::types::AlwaysRefCounted for Device { + fn inc_ref(&self) { + // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero. + unsafe { bindings::get_device(self.as_raw()) }; + } + + unsafe fn dec_ref(obj: ptr::NonNull) { + // SAFETY: The safety requirements guarantee that the refcount is non-zero. + unsafe { bindings::put_device(obj.cast().as_ptr()) } + } +} + +// SAFETY: As by the type invariant `Device` can be sent to any thread. +unsafe impl Send for Device {} + +// SAFETY: `Device` can be shared among threads because all immutable methods are protected by the +// synchronization in `struct device`. +unsafe impl Sync for Device {} diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index fbd91a48ff8b..dd1207f1a873 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -28,6 +28,7 @@ extern crate self as kernel; pub mod alloc; mod build_assert; +pub mod device; pub mod error; pub mod init; pub mod ioctl; From de6582833db0e695ba0c548e3cc2ad7dbb6aa260 Mon Sep 17 00:00:00 2001 From: Danilo Krummrich Date: Tue, 18 Jun 2024 17:48:35 +0200 Subject: [PATCH 33/55] rust: add firmware abstractions Add an abstraction around the kernels firmware API to request firmware images. The abstraction provides functions to access the firmware's size and backing buffer. The firmware is released once the abstraction instance is dropped. Signed-off-by: Danilo Krummrich Acked-by: Boqun Feng Link: https://lore.kernel.org/r/20240618154841.6716-3-dakr@redhat.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_loader/Kconfig | 7 ++ rust/bindings/bindings_helper.h | 1 + rust/kernel/firmware.rs | 101 +++++++++++++++++++++++++++ rust/kernel/lib.rs | 2 + 4 files changed, 111 insertions(+) create mode 100644 rust/kernel/firmware.rs diff --git a/drivers/base/firmware_loader/Kconfig b/drivers/base/firmware_loader/Kconfig index 5ca00e02fe82..a03701674265 100644 --- a/drivers/base/firmware_loader/Kconfig +++ b/drivers/base/firmware_loader/Kconfig @@ -37,6 +37,13 @@ config FW_LOADER_DEBUG SHA256 checksums to the kernel log for each firmware file that is loaded. +config RUST_FW_LOADER_ABSTRACTIONS + bool "Rust Firmware Loader abstractions" + depends on RUST + depends on FW_LOADER=y + help + This enables the Rust abstractions for the firmware loader API. + if FW_LOADER config FW_LOADER_PAGED_BUF diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h index ddb5644d4fd9..18a3f05115cb 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/rust/kernel/firmware.rs b/rust/kernel/firmware.rs new file mode 100644 index 000000000000..b55ea1b45368 --- /dev/null +++ b/rust/kernel/firmware.rs @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Firmware abstraction +//! +//! C header: [`include/linux/firmware.h`](srctree/include/linux/firmware.h") + +use crate::{bindings, device::Device, error::Error, error::Result, str::CStr}; +use core::ptr::NonNull; + +// One of the following: `bindings::request_firmware`, `bindings::firmware_request_nowarn`, +// `firmware_request_platform`, `bindings::request_firmware_direct` +type FwFunc = + unsafe extern "C" fn(*mut *const bindings::firmware, *const i8, *mut bindings::device) -> i32; + +/// Abstraction around a C `struct firmware`. +/// +/// This is a simple abstraction around the C firmware API. Just like with the C API, firmware can +/// be requested. Once requested the abstraction provides direct access to the firmware buffer as +/// `&[u8]`. The firmware is released once [`Firmware`] is dropped. +/// +/// # Invariants +/// +/// The pointer is valid, and has ownership over the instance of `struct firmware`. +/// +/// Once requested, the `Firmware` backing buffer is not modified until it is freed when `Firmware` +/// is dropped. +/// +/// # Examples +/// +/// ``` +/// # use kernel::{c_str, device::Device, firmware::Firmware}; +/// +/// # // SAFETY: *NOT* safe, just for the example to get an `ARef` instance +/// # let dev = unsafe { Device::from_raw(core::ptr::null_mut()) }; +/// +/// let fw = Firmware::request(c_str!("path/to/firmware.bin"), &dev).unwrap(); +/// let blob = fw.data(); +/// ``` +pub struct Firmware(NonNull); + +impl Firmware { + fn request_internal(name: &CStr, dev: &Device, func: FwFunc) -> Result { + let mut fw: *mut bindings::firmware = core::ptr::null_mut(); + let pfw: *mut *mut bindings::firmware = &mut fw; + + // SAFETY: `pfw` is a valid pointer to a NULL initialized `bindings::firmware` pointer. + // `name` and `dev` are valid as by their type invariants. + let ret = unsafe { func(pfw as _, name.as_char_ptr(), dev.as_raw()) }; + if ret != 0 { + return Err(Error::from_errno(ret)); + } + + // SAFETY: `func` not bailing out with a non-zero error code, guarantees that `fw` is a + // valid pointer to `bindings::firmware`. + Ok(Firmware(unsafe { NonNull::new_unchecked(fw) })) + } + + /// Send a firmware request and wait for it. See also `bindings::request_firmware`. + pub fn request(name: &CStr, dev: &Device) -> Result { + Self::request_internal(name, dev, bindings::request_firmware) + } + + /// Send a request for an optional firmware module. See also + /// `bindings::firmware_request_nowarn`. + pub fn request_nowarn(name: &CStr, dev: &Device) -> Result { + Self::request_internal(name, dev, bindings::firmware_request_nowarn) + } + + fn as_raw(&self) -> *mut bindings::firmware { + self.0.as_ptr() + } + + /// Returns the size of the requested firmware in bytes. + pub fn size(&self) -> usize { + // SAFETY: Safe by the type invariant. + unsafe { (*self.as_raw()).size } + } + + /// Returns the requested firmware as `&[u8]`. + pub fn data(&self) -> &[u8] { + // SAFETY: Safe by the type invariant. Additionally, `bindings::firmware` guarantees, if + // successfully requested, that `bindings::firmware::data` has a size of + // `bindings::firmware::size` bytes. + unsafe { core::slice::from_raw_parts((*self.as_raw()).data, self.size()) } + } +} + +impl Drop for Firmware { + fn drop(&mut self) { + // SAFETY: Safe by the type invariant. + unsafe { bindings::release_firmware(self.as_raw()) }; + } +} + +// SAFETY: `Firmware` only holds a pointer to a C `struct firmware`, which is safe to be used from +// any thread. +unsafe impl Send for Firmware {} + +// SAFETY: `Firmware` only holds a pointer to a C `struct firmware`, references to which are safe to +// be used from any thread. +unsafe impl Sync for Firmware {} diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index dd1207f1a873..7707cb013ce9 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -30,6 +30,8 @@ pub mod alloc; mod build_assert; pub mod device; pub mod error; +#[cfg(CONFIG_RUST_FW_LOADER_ABSTRACTIONS)] +pub mod firmware; pub mod init; pub mod ioctl; #[cfg(CONFIG_KUNIT)] From 2f3cfd2f4b7cf3026fe6b9b2a5320cc18f4c184e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 13 Jun 2024 23:23:52 +0200 Subject: [PATCH 34/55] driver core: Make dev_err_probe() silent for -ENOMEM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For an out-of-memory error there should be no additional output. Adapt dev_err_probe() to not emit the error message when err is -ENOMEM. This simplifies handling errors that might among others be -ENOMEM. Signed-off-by: Uwe Kleine-König Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/3d1e308d45cddf67749522ca42d83f5b4f0b9634.1718311756.git.u.kleine-koenig@baylibre.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 2b4c0624b704..730cae66607c 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -5021,11 +5021,22 @@ int dev_err_probe(const struct device *dev, int err, const char *fmt, ...) vaf.fmt = fmt; vaf.va = &args; - if (err != -EPROBE_DEFER) { - dev_err(dev, "error %pe: %pV", ERR_PTR(err), &vaf); - } else { + switch (err) { + case -EPROBE_DEFER: device_set_deferred_probe_reason(dev, &vaf); dev_dbg(dev, "error %pe: %pV", ERR_PTR(err), &vaf); + break; + + case -ENOMEM: + /* + * We don't print anything on -ENOMEM, there is already enough + * output. + */ + break; + + default: + dev_err(dev, "error %pe: %pV", ERR_PTR(err), &vaf); + break; } va_end(args); From 269e974e664207cc45f83b579565ba73de1b75dc Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 14 Jun 2024 11:41:02 +0200 Subject: [PATCH 35/55] driver core: make [device_]driver_attach take a const * Change device_driver_attach() and driver_attach() to take a const * to struct device driver as neither of them modify the structure at all. Also, for some odd reason, drivers/dma/idxd/compat.c had a duplicate external reference to device_driver_attach(), so remove that to fix up the build, it should never have had that there in the first place. Cc: Rafael J. Wysocki Cc: Fenghua Yu Cc: Dave Jiang Cc: Vinod Koul Cc: Andy Shevchenko Cc: Petr Tesarik Cc: Alexander Lobakin Cc: dmaengine@vger.kernel.org Link: https://lore.kernel.org/r/2024061401-rasping-manger-c385@gregkh Signed-off-by: Greg Kroah-Hartman --- drivers/base/base.h | 5 +++-- drivers/base/dd.c | 9 +++++---- drivers/dma/idxd/compat.c | 1 - include/linux/device.h | 4 ++-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/base/base.h b/drivers/base/base.h index 50151e7db796..8bef47afa3a9 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -161,10 +161,11 @@ void device_release_driver_internal(struct device *dev, const struct device_driv void driver_detach(const struct device_driver *drv); void driver_deferred_probe_del(struct device *dev); void device_set_deferred_probe_reason(const struct device *dev, struct va_format *vaf); -static inline int driver_match_device(struct device_driver *drv, +static inline int driver_match_device(const struct device_driver *drv, struct device *dev) { - return drv->bus->match ? drv->bus->match(dev, drv) : 1; + /* cast will be removed in the future when match can handle a const pointer properly. */ + return drv->bus->match ? drv->bus->match(dev, (struct device_driver *)drv) : 1; } static inline void dev_sync_state(struct device *dev) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 8ec22229e259..9b745ba54de1 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -1118,7 +1118,7 @@ static void __device_driver_unlock(struct device *dev, struct device *parent) * Manually attach driver to a device. Will acquire both @dev lock and * @dev->parent lock if needed. Returns 0 on success, -ERR on failure. */ -int device_driver_attach(struct device_driver *drv, struct device *dev) +int device_driver_attach(const struct device_driver *drv, struct device *dev) { int ret; @@ -1154,7 +1154,7 @@ static void __driver_attach_async_helper(void *_dev, async_cookie_t cookie) static int __driver_attach(struct device *dev, void *data) { - struct device_driver *drv = data; + const struct device_driver *drv = data; bool async = false; int ret; @@ -1227,9 +1227,10 @@ static int __driver_attach(struct device *dev, void *data) * returns 0 and the @dev->driver is set, we've found a * compatible pair. */ -int driver_attach(struct device_driver *drv) +int driver_attach(const struct device_driver *drv) { - return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach); + /* The (void *) will be put back to const * in __driver_attach() */ + return bus_for_each_dev(drv->bus, NULL, (void *)drv, __driver_attach); } EXPORT_SYMBOL_GPL(driver_attach); diff --git a/drivers/dma/idxd/compat.c b/drivers/dma/idxd/compat.c index 5fd38d1b9d28..a4adb0c17995 100644 --- a/drivers/dma/idxd/compat.c +++ b/drivers/dma/idxd/compat.c @@ -7,7 +7,6 @@ #include #include "idxd.h" -extern int device_driver_attach(struct device_driver *drv, struct device *dev); extern void device_driver_detach(struct device *dev); #define DRIVER_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) \ diff --git a/include/linux/device.h b/include/linux/device.h index 3a630942f358..34eb20f5966f 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1177,12 +1177,12 @@ static inline void *dev_get_platdata(const struct device *dev) * Manual binding of a device to driver. See drivers/base/bus.c * for information on use. */ -int __must_check device_driver_attach(struct device_driver *drv, +int __must_check device_driver_attach(const struct device_driver *drv, struct device *dev); int __must_check device_bind_driver(struct device *dev); void device_release_driver(struct device *dev); int __must_check device_attach(struct device *dev); -int __must_check driver_attach(struct device_driver *drv); +int __must_check driver_attach(const struct device_driver *drv); void device_initial_probe(struct device *dev); int __must_check device_reprobe(struct device *dev); From bbe98f4fde5a52aa01a1e1d754e1398228815fb0 Mon Sep 17 00:00:00 2001 From: Danilo Krummrich Date: Wed, 19 Jun 2024 15:20:12 +0200 Subject: [PATCH 36/55] firmware: rust: improve safety comments Improve the wording of safety comments to be more explicit about what exactly is guaranteed to be valid. Suggested-by: Benno Lossin Signed-off-by: Danilo Krummrich Link: https://lore.kernel.org/r/20240619132029.59296-1-dakr@redhat.com Signed-off-by: Greg Kroah-Hartman --- rust/kernel/firmware.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/rust/kernel/firmware.rs b/rust/kernel/firmware.rs index b55ea1b45368..386c8fb44785 100644 --- a/rust/kernel/firmware.rs +++ b/rust/kernel/firmware.rs @@ -22,8 +22,7 @@ type FwFunc = /// /// The pointer is valid, and has ownership over the instance of `struct firmware`. /// -/// Once requested, the `Firmware` backing buffer is not modified until it is freed when `Firmware` -/// is dropped. +/// The `Firmware`'s backing buffer is not modified. /// /// # Examples /// @@ -72,22 +71,22 @@ impl Firmware { /// Returns the size of the requested firmware in bytes. pub fn size(&self) -> usize { - // SAFETY: Safe by the type invariant. + // SAFETY: `self.as_raw()` is valid by the type invariant. unsafe { (*self.as_raw()).size } } /// Returns the requested firmware as `&[u8]`. pub fn data(&self) -> &[u8] { - // SAFETY: Safe by the type invariant. Additionally, `bindings::firmware` guarantees, if - // successfully requested, that `bindings::firmware::data` has a size of - // `bindings::firmware::size` bytes. + // SAFETY: `self.as_raw()` is valid by the type invariant. Additionally, + // `bindings::firmware` guarantees, if successfully requested, that + // `bindings::firmware::data` has a size of `bindings::firmware::size` bytes. unsafe { core::slice::from_raw_parts((*self.as_raw()).data, self.size()) } } } impl Drop for Firmware { fn drop(&mut self) { - // SAFETY: Safe by the type invariant. + // SAFETY: `self.as_raw()` is valid by the type invariant. unsafe { bindings::release_firmware(self.as_raw()) }; } } From 7bd08093999898c0c35c4e90102cb2daebfadd9a Mon Sep 17 00:00:00 2001 From: Danilo Krummrich Date: Wed, 19 Jun 2024 15:20:13 +0200 Subject: [PATCH 37/55] MAINTAINERS: add Rust FW abstractions to FIRMWARE LOADER Add missing file path of the Rust abstractions to the maintainers entry, until we can move it to 'drivers/base/firmware_loader/'. CC: Luis Chamberlain CC: Russ Weight CC: Greg Kroah-Hartman Signed-off-by: Danilo Krummrich Link: https://lore.kernel.org/r/20240619132029.59296-2-dakr@redhat.com Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index cf9c9221c388..38e7e0edd9b8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8573,6 +8573,7 @@ L: linux-kernel@vger.kernel.org S: Maintained F: Documentation/firmware_class/ F: drivers/base/firmware_loader/ +F: rust/kernel/firmware.rs F: include/linux/firmware.h FLEXTIMER FTM-QUADDEC DRIVER From 892fb846d6a04ad95c22ae8c758fd8998a0d237c Mon Sep 17 00:00:00 2001 From: Danilo Krummrich Date: Wed, 19 Jun 2024 15:20:14 +0200 Subject: [PATCH 38/55] MAINTAINERS: add Danilo as FIRMWARE LOADER maintainer Add myself as firmware loader maintainer, as suggested by Luis in [1]. CC: Luis Chamberlain CC: Russ Weight CC: Greg Kroah-Hartman Link: https://lore.kernel.org/rust-for-linux/ZnHkQpyiX4UKdLEt@bombadil.infradead.org/ [1] Suggested-by: Luis Chamberlain Signed-off-by: Danilo Krummrich Link: https://lore.kernel.org/r/20240619132029.59296-3-dakr@redhat.com Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 38e7e0edd9b8..19e4a21e574e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8569,6 +8569,7 @@ F: include/linux/arm_ffa.h FIRMWARE LOADER (request_firmware) M: Luis Chamberlain M: Russ Weight +M: Danilo Krummrich L: linux-kernel@vger.kernel.org S: Maintained F: Documentation/firmware_class/ From 4ead6c37b04aa35943ea270f09db18ebb38e63ff Mon Sep 17 00:00:00 2001 From: Danilo Krummrich Date: Wed, 19 Jun 2024 15:39:17 +0200 Subject: [PATCH 39/55] device: rust: improve safety comments Improve the wording of safety comments to be more explicit about what exactly is guaranteed to be valid. Suggested-by: Benno Lossin Signed-off-by: Danilo Krummrich Link: https://lore.kernel.org/r/20240619133949.64638-1-dakr@redhat.com Signed-off-by: Greg Kroah-Hartman --- rust/kernel/device.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs index e445e87fb7d7..851018eef885 100644 --- a/rust/kernel/device.rs +++ b/rust/kernel/device.rs @@ -30,8 +30,10 @@ use core::ptr; /// /// # Invariants /// -/// The pointer stored in `Self` is non-null and valid for the lifetime of the `ARef` instance. In -/// particular, the `ARef` instance owns an increment on the underlying object’s reference count. +/// A `Device` instance represents a valid `struct device` created by the C portion of the kernel. +/// +/// Instances of this type are always reference-counted, that is, a call to `get_device` ensures +/// that the allocation remains valid at least until the matching call to `put_device`. /// /// `bindings::device::release` is valid to be called from any thread, hence `ARef` can be /// dropped from any thread. @@ -58,7 +60,8 @@ impl Device { // CAST: `Self` is a `repr(transparent)` wrapper around `bindings::device`. let ptr = ptr.cast::(); - // SAFETY: By the safety requirements, ptr is valid. + // SAFETY: `ptr` is valid by the safety requirements of this function. By the above call to + // `bindings::get_device` we also own a reference to the underlying `struct device`. unsafe { ARef::from_raw(ptr::NonNull::new_unchecked(ptr)) } } From 6b521fc111a2ad5ead39776960d3d2d289ce0722 Mon Sep 17 00:00:00 2001 From: Danilo Krummrich Date: Wed, 19 Jun 2024 15:39:18 +0200 Subject: [PATCH 40/55] MAINTAINERS: add Rust device abstractions to DRIVER CORE Add missing file path of the Rust abstractions to the maintainers entry, until we can move it to 'drivers/base/'. Signed-off-by: Danilo Krummrich Link: https://lore.kernel.org/r/20240619133949.64638-2-dakr@redhat.com Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 19e4a21e574e..82c7bc2f181c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6714,6 +6714,7 @@ F: include/linux/fwnode.h F: include/linux/kobj* F: include/linux/property.h F: lib/kobj* +F: rust/kernel/device.rs DRIVERS FOR OMAP ADAPTIVE VOLTAGE SCALING (AVS) M: Nishanth Menon From d69d804845985c29ab5be5a4b3b1f4787893daf8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 1 Jul 2024 14:07:37 +0200 Subject: [PATCH 41/55] driver core: have match() callback in struct bus_type take a const * In the match() callback, the struct device_driver * should not be changed, so change the function callback to be a const *. This is one step of many towards making the driver core safe to have struct device_driver in read-only memory. Because the match() callback is in all busses, all busses are modified to handle this properly. This does entail switching some container_of() calls to container_of_const() to properly handle the constant *. For some busses, like PCI and USB and HV, the const * is cast away in the match callback as those busses do want to modify those structures at this point in time (they have a local lock in the driver structure.) That will have to be changed in the future if they wish to have their struct device * in read-only-memory. Cc: Rafael J. Wysocki Reviewed-by: Alex Elder Acked-by: Sumit Garg Link: https://lore.kernel.org/r/2024070136-wrongdoer-busily-01e8@gregkh Signed-off-by: Greg Kroah-Hartman --- arch/arm/common/locomo.c | 4 ++-- arch/arm/include/asm/hardware/locomo.h | 2 +- arch/parisc/include/asm/parisc-device.h | 2 +- arch/parisc/kernel/drivers.c | 4 ++-- arch/powerpc/include/asm/ps3.h | 6 +----- arch/powerpc/include/asm/vio.h | 6 +----- arch/powerpc/platforms/ps3/system-bus.c | 4 ++-- arch/powerpc/platforms/pseries/ibmebus.c | 2 +- arch/powerpc/platforms/pseries/vio.c | 6 +++--- arch/s390/include/asm/ccwdev.h | 2 +- arch/sparc/include/asm/vio.h | 6 +----- arch/sparc/kernel/vio.c | 4 ++-- drivers/acpi/bus.c | 4 ++-- drivers/amba/bus.c | 6 +++--- drivers/base/auxiliary.c | 2 +- drivers/base/base.h | 3 +-- drivers/base/cpu.c | 2 +- drivers/base/isa.c | 2 +- drivers/base/platform.c | 2 +- drivers/bcma/main.c | 6 +++--- drivers/bus/fsl-mc/fsl-mc-bus.c | 4 ++-- drivers/bus/mhi/ep/main.c | 4 ++-- drivers/bus/mhi/host/init.c | 4 ++-- drivers/bus/mips_cdmm.c | 6 +++--- drivers/bus/moxtet.c | 4 ++-- drivers/bus/sunxi-rsb.c | 2 +- drivers/cdx/cdx.c | 4 ++-- drivers/cxl/core/port.c | 2 +- drivers/cxl/cxl.h | 5 +---- drivers/dax/bus.c | 17 +++++++---------- drivers/dma/idxd/bus.c | 6 +++--- drivers/eisa/eisa-bus.c | 4 ++-- drivers/firewire/core-device.c | 6 +++--- drivers/firmware/arm_ffa/bus.c | 2 +- drivers/firmware/arm_scmi/bus.c | 6 +++--- drivers/firmware/google/coreboot_table.c | 6 +++--- drivers/fpga/dfl.c | 4 ++-- drivers/fsi/fsi-core.c | 4 ++-- drivers/gpio/gpiolib.c | 2 +- drivers/gpu/drm/display/drm_dp_aux_bus.c | 2 +- drivers/gpu/drm/drm_mipi_dsi.c | 2 +- drivers/gpu/host1x/bus.c | 2 +- drivers/greybus/core.c | 4 ++-- drivers/hid/hid-core.c | 2 +- drivers/hid/intel-ish-hid/ishtp/bus.c | 2 +- drivers/hsi/hsi_core.c | 2 +- drivers/hv/vmbus_drv.c | 8 ++++---- drivers/hwtracing/intel_th/core.c | 4 ++-- drivers/hwtracing/intel_th/intel_th.h | 2 +- drivers/i2c/i2c-core-base.c | 4 ++-- drivers/i3c/master.c | 4 ++-- drivers/input/gameport/gameport.c | 4 ++-- drivers/input/rmi4/rmi_bus.c | 6 +++--- drivers/input/rmi4/rmi_bus.h | 2 +- drivers/input/rmi4/rmi_driver.c | 2 +- drivers/input/rmi4/rmi_driver.h | 2 +- drivers/input/serio/serio.c | 4 ++-- drivers/ipack/ipack.c | 6 +++--- drivers/macintosh/macio_asic.c | 2 +- drivers/mcb/mcb-core.c | 4 ++-- drivers/media/pci/bt8xx/bttv-gpio.c | 4 ++-- drivers/media/pci/bt8xx/bttv.h | 2 +- drivers/memstick/core/memstick.c | 7 +++---- drivers/mfd/mcp-core.c | 2 +- drivers/misc/mei/bus.c | 4 ++-- drivers/misc/tifm_core.c | 6 +++--- drivers/mmc/core/sdio_bus.c | 10 +++++----- drivers/most/core.c | 2 +- drivers/net/phy/mdio_bus.c | 4 ++-- drivers/net/phy/mdio_device.c | 4 ++-- drivers/net/phy/phy_device.c | 4 ++-- drivers/ntb/ntb_transport.c | 2 +- drivers/nvdimm/bus.c | 6 +++--- drivers/nvmem/layouts.c | 4 ++-- drivers/pci/endpoint/pci-epf-core.c | 4 ++-- drivers/pci/pci-driver.c | 8 ++++---- drivers/pcmcia/ds.c | 2 +- drivers/peci/core.c | 4 ++-- drivers/peci/internal.h | 5 +---- drivers/platform/surface/aggregator/bus.c | 4 ++-- drivers/platform/x86/wmi.c | 9 +++------ drivers/pnp/driver.c | 6 +++--- drivers/rapidio/rio-driver.c | 4 ++-- drivers/rpmsg/rpmsg_core.c | 4 ++-- drivers/rpmsg/rpmsg_internal.h | 2 +- drivers/s390/cio/css.c | 4 ++-- drivers/s390/cio/css.h | 2 +- drivers/s390/cio/device.c | 4 ++-- drivers/s390/crypto/ap_bus.c | 4 ++-- drivers/s390/crypto/ap_bus.h | 2 +- drivers/scsi/fcoe/fcoe_sysfs.c | 2 +- drivers/scsi/scsi_sysfs.c | 6 +++--- drivers/scsi/scsi_transport_iscsi.c | 2 +- drivers/sh/maple/maple.c | 4 ++-- drivers/siox/siox-core.c | 2 +- drivers/slimbus/core.c | 4 ++-- drivers/soc/qcom/apr.c | 4 ++-- drivers/soundwire/bus_type.c | 6 +++--- drivers/spi/spi.c | 2 +- drivers/spmi/spmi.c | 2 +- drivers/ssb/main.c | 4 ++-- .../staging/fieldbus/anybuss/anybuss-client.h | 6 +----- drivers/staging/fieldbus/anybuss/host.c | 4 ++-- drivers/staging/greybus/gbphy.c | 2 +- .../interface/vchiq_arm/vchiq_bus.c | 2 +- drivers/staging/vme_user/vme.c | 2 +- drivers/tc/tc-driver.c | 6 +++--- drivers/tee/tee_core.c | 2 +- drivers/thunderbolt/domain.c | 8 ++++---- drivers/tty/serdev/core.c | 2 +- drivers/tty/serial/serial_base_bus.c | 2 +- drivers/usb/common/ulpi.c | 2 +- drivers/usb/core/driver.c | 2 +- drivers/usb/gadget/udc/core.c | 2 +- drivers/usb/serial/bus.c | 2 +- drivers/usb/typec/bus.c | 2 +- drivers/vdpa/vdpa.c | 2 +- drivers/vfio/mdev/mdev_driver.c | 2 +- drivers/virtio/virtio.c | 2 +- drivers/xen/xenbus/xenbus.h | 2 +- drivers/xen/xenbus/xenbus_probe.c | 4 ++-- include/acpi/acpi_bus.h | 2 +- include/linux/arm_ffa.h | 2 +- include/linux/cdx/cdx_bus.h | 2 +- include/linux/device/bus.h | 2 +- include/linux/dfl.h | 2 +- include/linux/eisa.h | 2 +- include/linux/fsi.h | 2 +- include/linux/fsl/mc.h | 2 +- include/linux/gameport.h | 2 +- include/linux/greybus.h | 2 +- include/linux/hyperv.h | 6 +----- include/linux/i2c.h | 2 +- include/linux/i3c/device.h | 5 +---- include/linux/maple.h | 2 +- include/linux/mcb.h | 5 +---- include/linux/mdio.h | 19 ++++++------------- include/linux/mhi.h | 2 +- include/linux/mhi_ep.h | 2 +- include/linux/moxtet.h | 9 ++------- include/linux/nd.h | 6 +----- include/linux/pci-epf.h | 3 +-- include/linux/pci.h | 6 ++---- include/linux/phy.h | 2 +- include/linux/pnp.h | 2 +- include/linux/rio.h | 2 +- include/linux/scmi_protocol.h | 2 +- include/linux/serio.h | 2 +- include/linux/slimbus.h | 2 +- include/linux/soc/qcom/apr.h | 2 +- include/linux/soundwire/sdw_type.h | 2 +- include/linux/spi/spi.h | 6 ++---- include/linux/ssb/ssb.h | 2 +- include/linux/tc.h | 2 +- include/linux/tee_drv.h | 2 +- include/linux/virtio.h | 5 +---- include/scsi/scsi_transport_iscsi.h | 2 +- include/sound/ac97/codec.h | 5 +---- include/xen/xenbus.h | 5 +---- net/iucv/iucv.c | 2 +- sound/ac97/bus.c | 4 ++-- sound/core/seq_device.c | 4 ++-- sound/hda/hda_bus_type.c | 2 +- 163 files changed, 268 insertions(+), 338 deletions(-) diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index 6d0c9f7268ba..06b0e5fd54a6 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c @@ -816,10 +816,10 @@ EXPORT_SYMBOL(locomo_frontlight_set); * We model this as a regular bus type, and hang devices directly * off this. */ -static int locomo_match(struct device *_dev, struct device_driver *_drv) +static int locomo_match(struct device *_dev, const struct device_driver *_drv) { struct locomo_dev *dev = LOCOMO_DEV(_dev); - struct locomo_driver *drv = LOCOMO_DRV(_drv); + const struct locomo_driver *drv = LOCOMO_DRV(_drv); return dev->devid == drv->devid; } diff --git a/arch/arm/include/asm/hardware/locomo.h b/arch/arm/include/asm/hardware/locomo.h index 9fd9ad5d9202..3190e1e5067a 100644 --- a/arch/arm/include/asm/hardware/locomo.h +++ b/arch/arm/include/asm/hardware/locomo.h @@ -189,7 +189,7 @@ struct locomo_driver { void (*remove)(struct locomo_dev *); }; -#define LOCOMO_DRV(_d) container_of((_d), struct locomo_driver, drv) +#define LOCOMO_DRV(_d) container_of_const((_d), struct locomo_driver, drv) #define LOCOMO_DRIVER_NAME(_ldev) ((_ldev)->dev.driver->name) diff --git a/arch/parisc/include/asm/parisc-device.h b/arch/parisc/include/asm/parisc-device.h index 7ddd7f433367..9e74cef4d774 100644 --- a/arch/parisc/include/asm/parisc-device.h +++ b/arch/parisc/include/asm/parisc-device.h @@ -41,7 +41,7 @@ struct parisc_driver { #define to_parisc_device(d) container_of(d, struct parisc_device, dev) -#define to_parisc_driver(d) container_of(d, struct parisc_driver, drv) +#define to_parisc_driver(d) container_of_const(d, struct parisc_driver, drv) #define parisc_parent(d) to_parisc_device(d->dev.parent) static inline const char *parisc_pathname(struct parisc_device *d) diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c index ac19d685e4a5..1e793f770f71 100644 --- a/arch/parisc/kernel/drivers.c +++ b/arch/parisc/kernel/drivers.c @@ -97,7 +97,7 @@ static int for_each_padev(int (*fn)(struct device *, void *), void * data) * @driver: the PA-RISC driver to try * @dev: the PA-RISC device to try */ -static int match_device(struct parisc_driver *driver, struct parisc_device *dev) +static int match_device(const struct parisc_driver *driver, struct parisc_device *dev) { const struct parisc_device_id *ids; @@ -548,7 +548,7 @@ alloc_pa_dev(unsigned long hpa, struct hardware_path *mod_path) return dev; } -static int parisc_generic_match(struct device *dev, struct device_driver *drv) +static int parisc_generic_match(struct device *dev, const struct device_driver *drv) { return match_device(to_parisc_driver(drv), to_parisc_device(dev)); } diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h index d13d8fdc3411..987e23a2bd28 100644 --- a/arch/powerpc/include/asm/ps3.h +++ b/arch/powerpc/include/asm/ps3.h @@ -390,11 +390,7 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev); int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv); void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv); -static inline struct ps3_system_bus_driver *ps3_drv_to_system_bus_drv( - struct device_driver *_drv) -{ - return container_of(_drv, struct ps3_system_bus_driver, core); -} +#define ps3_drv_to_system_bus_drv(_drv) container_of_const(_drv, struct ps3_system_bus_driver, core) static inline struct ps3_system_bus_device *ps3_dev_to_system_bus_dev( const struct device *_dev) { diff --git a/arch/powerpc/include/asm/vio.h b/arch/powerpc/include/asm/vio.h index 6faf2a931755..7c444150c5ad 100644 --- a/arch/powerpc/include/asm/vio.h +++ b/arch/powerpc/include/asm/vio.h @@ -156,11 +156,7 @@ static inline int vio_enable_interrupts(struct vio_dev *dev) } #endif -static inline struct vio_driver *to_vio_driver(struct device_driver *drv) -{ - return container_of(drv, struct vio_driver, driver); -} - +#define to_vio_driver(__drv) container_of_const(__drv, struct vio_driver, driver) #define to_vio_dev(__dev) container_of_const(__dev, struct vio_dev, dev) #endif /* __KERNEL__ */ diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index 56dc6b29a3e7..b9a7d9bae687 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c @@ -333,10 +333,10 @@ int ps3_mmio_region_init(struct ps3_system_bus_device *dev, EXPORT_SYMBOL_GPL(ps3_mmio_region_init); static int ps3_system_bus_match(struct device *_dev, - struct device_driver *_drv) + const struct device_driver *_drv) { int result; - struct ps3_system_bus_driver *drv = ps3_drv_to_system_bus_drv(_drv); + const struct ps3_system_bus_driver *drv = ps3_drv_to_system_bus_drv(_drv); struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); if (!dev->match_sub_id) diff --git a/arch/powerpc/platforms/pseries/ibmebus.c b/arch/powerpc/platforms/pseries/ibmebus.c index b401282727a4..3436b0af795e 100644 --- a/arch/powerpc/platforms/pseries/ibmebus.c +++ b/arch/powerpc/platforms/pseries/ibmebus.c @@ -339,7 +339,7 @@ static struct attribute *ibmbus_bus_attrs[] = { }; ATTRIBUTE_GROUPS(ibmbus_bus); -static int ibmebus_bus_bus_match(struct device *dev, struct device_driver *drv) +static int ibmebus_bus_bus_match(struct device *dev, const struct device_driver *drv) { const struct of_device_id *matches = drv->of_match_table; diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c index 36d1c7d4156b..ac1d2d2c9a88 100644 --- a/arch/powerpc/platforms/pseries/vio.c +++ b/arch/powerpc/platforms/pseries/vio.c @@ -1576,10 +1576,10 @@ void vio_unregister_device(struct vio_dev *viodev) } EXPORT_SYMBOL(vio_unregister_device); -static int vio_bus_match(struct device *dev, struct device_driver *drv) +static int vio_bus_match(struct device *dev, const struct device_driver *drv) { const struct vio_dev *vio_dev = to_vio_dev(dev); - struct vio_driver *vio_drv = to_vio_driver(drv); + const struct vio_driver *vio_drv = to_vio_driver(drv); const struct vio_device_id *ids = vio_drv->id_table; return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL); @@ -1689,7 +1689,7 @@ struct vio_dev *vio_find_node(struct device_node *vnode) /* construct the kobject name from the device node */ if (of_node_is_type(vnode_parent, "vdevice")) { const __be32 *prop; - + prop = of_get_property(vnode, "reg", NULL); if (!prop) goto out; diff --git a/arch/s390/include/asm/ccwdev.h b/arch/s390/include/asm/ccwdev.h index 436365ff6c19..e3afcece375e 100644 --- a/arch/s390/include/asm/ccwdev.h +++ b/arch/s390/include/asm/ccwdev.h @@ -210,7 +210,7 @@ extern void ccw_device_get_id(struct ccw_device *, struct ccw_dev_id *); #define get_ccwdev_lock(x) (x)->ccwlock #define to_ccwdev(n) container_of(n, struct ccw_device, dev) -#define to_ccwdrv(n) container_of(n, struct ccw_driver, driver) +#define to_ccwdrv(n) container_of_const(n, struct ccw_driver, driver) extern struct ccw_device *ccw_device_create_console(struct ccw_driver *); extern void ccw_device_destroy_console(struct ccw_device *); diff --git a/arch/sparc/include/asm/vio.h b/arch/sparc/include/asm/vio.h index 587fb7841096..0ca8c3463166 100644 --- a/arch/sparc/include/asm/vio.h +++ b/arch/sparc/include/asm/vio.h @@ -483,11 +483,7 @@ int __vio_register_driver(struct vio_driver *drv, struct module *owner, __vio_register_driver(driver, THIS_MODULE, KBUILD_MODNAME) void vio_unregister_driver(struct vio_driver *drv); -static inline struct vio_driver *to_vio_driver(struct device_driver *drv) -{ - return container_of(drv, struct vio_driver, driver); -} - +#define to_vio_driver(__drv) container_of_const(__drv, struct vio_driver, driver) #define to_vio_dev(__dev) container_of_const(__dev, struct vio_dev, dev) int vio_ldc_send(struct vio_driver_state *vio, void *data, int len); diff --git a/arch/sparc/kernel/vio.c b/arch/sparc/kernel/vio.c index 846a55f942d4..07933d75ac81 100644 --- a/arch/sparc/kernel/vio.c +++ b/arch/sparc/kernel/vio.c @@ -54,10 +54,10 @@ static int vio_hotplug(const struct device *dev, struct kobj_uevent_env *env) return 0; } -static int vio_bus_match(struct device *dev, struct device_driver *drv) +static int vio_bus_match(struct device *dev, const struct device_driver *drv) { struct vio_dev *vio_dev = to_vio_dev(dev); - struct vio_driver *vio_drv = to_vio_driver(drv); + const struct vio_driver *vio_drv = to_vio_driver(drv); const struct vio_device_id *matches = vio_drv->id_table; if (!matches) diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 787eca838410..d3e1457cba17 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -1045,10 +1045,10 @@ EXPORT_SYMBOL(acpi_bus_unregister_driver); ACPI Bus operations -------------------------------------------------------------------------- */ -static int acpi_bus_match(struct device *dev, struct device_driver *drv) +static int acpi_bus_match(struct device *dev, const struct device_driver *drv) { struct acpi_device *acpi_dev = to_acpi_device(dev); - struct acpi_driver *acpi_drv = to_acpi_driver(drv); + const struct acpi_driver *acpi_drv = to_acpi_driver(drv); return acpi_dev->flags.match_driver && !acpi_match_device_ids(acpi_dev, acpi_drv->ids); diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index aba3aa95b224..34bc880ca20b 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -26,7 +26,7 @@ #include #include -#define to_amba_driver(d) container_of(d, struct amba_driver, drv) +#define to_amba_driver(d) container_of_const(d, struct amba_driver, drv) /* called on periphid match and class 0x9 coresight device. */ static int @@ -205,10 +205,10 @@ err_out: return ret; } -static int amba_match(struct device *dev, struct device_driver *drv) +static int amba_match(struct device *dev, const struct device_driver *drv) { struct amba_device *pcdev = to_amba_device(dev); - struct amba_driver *pcdrv = to_amba_driver(drv); + const struct amba_driver *pcdrv = to_amba_driver(drv); mutex_lock(&pcdev->periphid_lock); if (!pcdev->periphid) { diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c index 5832e31bb77b..95408b7594fc 100644 --- a/drivers/base/auxiliary.c +++ b/drivers/base/auxiliary.c @@ -177,7 +177,7 @@ static const struct auxiliary_device_id *auxiliary_match_id(const struct auxilia return NULL; } -static int auxiliary_match(struct device *dev, struct device_driver *drv) +static int auxiliary_match(struct device *dev, const struct device_driver *drv) { struct auxiliary_device *auxdev = to_auxiliary_dev(dev); const struct auxiliary_driver *auxdrv = to_auxiliary_drv(drv); diff --git a/drivers/base/base.h b/drivers/base/base.h index 8bef47afa3a9..0886f555d782 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -164,8 +164,7 @@ void device_set_deferred_probe_reason(const struct device *dev, struct va_format static inline int driver_match_device(const struct device_driver *drv, struct device *dev) { - /* cast will be removed in the future when match can handle a const pointer properly. */ - return drv->bus->match ? drv->bus->match(dev, (struct device_driver *)drv) : 1; + return drv->bus->match ? drv->bus->match(dev, drv) : 1; } static inline void dev_sync_state(struct device *dev) diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index c61ecb0c2ae2..4901fbfca326 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -26,7 +26,7 @@ static DEFINE_PER_CPU(struct device *, cpu_sys_devices); -static int cpu_subsys_match(struct device *dev, struct device_driver *drv) +static int cpu_subsys_match(struct device *dev, const struct device_driver *drv) { /* ACPI style match is the only one that may succeed. */ if (acpi_driver_match_device(dev, drv)) diff --git a/drivers/base/isa.c b/drivers/base/isa.c index e23d0b49a793..bfd9215c9070 100644 --- a/drivers/base/isa.c +++ b/drivers/base/isa.c @@ -23,7 +23,7 @@ struct isa_dev { #define to_isa_dev(x) container_of((x), struct isa_dev, dev) -static int isa_bus_match(struct device *dev, struct device_driver *driver) +static int isa_bus_match(struct device *dev, const struct device_driver *driver) { struct isa_driver *isa_driver = to_isa_driver(driver); diff --git a/drivers/base/platform.c b/drivers/base/platform.c index a6884479f4ac..8a511fe47bdb 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -1332,7 +1332,7 @@ __ATTRIBUTE_GROUPS(platform_dev); * and compare it against the name of the driver. Return whether they match * or not. */ -static int platform_match(struct device *dev, struct device_driver *drv) +static int platform_match(struct device *dev, const struct device_driver *drv) { struct platform_device *pdev = to_platform_device(dev); struct platform_driver *pdrv = to_platform_driver(drv); diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 6b5d34919c72..6ecfc821cf83 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -26,7 +26,7 @@ static unsigned int bcma_bus_next_num; /* bcma_buses_mutex locks the bcma_bus_next_num */ static DEFINE_MUTEX(bcma_buses_mutex); -static int bcma_bus_match(struct device *dev, struct device_driver *drv); +static int bcma_bus_match(struct device *dev, const struct device_driver *drv); static int bcma_device_probe(struct device *dev); static void bcma_device_remove(struct device *dev); static int bcma_device_uevent(const struct device *dev, struct kobj_uevent_env *env); @@ -584,10 +584,10 @@ void bcma_driver_unregister(struct bcma_driver *drv) } EXPORT_SYMBOL_GPL(bcma_driver_unregister); -static int bcma_bus_match(struct device *dev, struct device_driver *drv) +static int bcma_bus_match(struct device *dev, const struct device_driver *drv) { struct bcma_device *core = container_of(dev, struct bcma_device, dev); - struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv); + const struct bcma_driver *adrv = container_of_const(drv, struct bcma_driver, drv); const struct bcma_device_id *cid = &core->id; const struct bcma_device_id *did; diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index 78b96cd63de9..dd68b8191a0a 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -80,11 +80,11 @@ static phys_addr_t mc_portal_base_phys_addr; * * Returns 1 on success, 0 otherwise. */ -static int fsl_mc_bus_match(struct device *dev, struct device_driver *drv) +static int fsl_mc_bus_match(struct device *dev, const struct device_driver *drv) { const struct fsl_mc_device_id *id; struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); - struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(drv); + const struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(drv); bool found = false; /* When driver_override is set, only bind to the matching driver */ diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index f8f674adf1d4..b193c2d25621 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -1694,10 +1694,10 @@ static int mhi_ep_uevent(const struct device *dev, struct kobj_uevent_env *env) mhi_dev->name); } -static int mhi_ep_match(struct device *dev, struct device_driver *drv) +static int mhi_ep_match(struct device *dev, const struct device_driver *drv) { struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); - struct mhi_ep_driver *mhi_drv = to_mhi_ep_driver(drv); + const struct mhi_ep_driver *mhi_drv = to_mhi_ep_driver(drv); const struct mhi_device_id *id; /* diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c index 173f79918741..ce7d2e62c2f1 100644 --- a/drivers/bus/mhi/host/init.c +++ b/drivers/bus/mhi/host/init.c @@ -1442,10 +1442,10 @@ static int mhi_uevent(const struct device *dev, struct kobj_uevent_env *env) mhi_dev->name); } -static int mhi_match(struct device *dev, struct device_driver *drv) +static int mhi_match(struct device *dev, const struct device_driver *drv) { struct mhi_device *mhi_dev = to_mhi_device(dev); - struct mhi_driver *mhi_drv = to_mhi_driver(drv); + const struct mhi_driver *mhi_drv = to_mhi_driver(drv); const struct mhi_device_id *id; /* diff --git a/drivers/bus/mips_cdmm.c b/drivers/bus/mips_cdmm.c index 8baf14bd5eff..12dd32fd0b62 100644 --- a/drivers/bus/mips_cdmm.c +++ b/drivers/bus/mips_cdmm.c @@ -37,7 +37,7 @@ /* Each block of device registers is 64 bytes */ #define CDMM_DRB_SIZE 64 -#define to_mips_cdmm_driver(d) container_of(d, struct mips_cdmm_driver, drv) +#define to_mips_cdmm_driver(d) container_of_const(d, struct mips_cdmm_driver, drv) /* Default physical base address */ static phys_addr_t mips_cdmm_default_base; @@ -59,10 +59,10 @@ mips_cdmm_lookup(const struct mips_cdmm_device_id *table, return ret ? table : NULL; } -static int mips_cdmm_match(struct device *dev, struct device_driver *drv) +static int mips_cdmm_match(struct device *dev, const struct device_driver *drv) { struct mips_cdmm_device *cdev = to_mips_cdmm_device(dev); - struct mips_cdmm_driver *cdrv = to_mips_cdmm_driver(drv); + const struct mips_cdmm_driver *cdrv = to_mips_cdmm_driver(drv); return mips_cdmm_lookup(cdrv->id_table, cdev) != NULL; } diff --git a/drivers/bus/moxtet.c b/drivers/bus/moxtet.c index 641c1a6adc8a..8412406c4f1d 100644 --- a/drivers/bus/moxtet.c +++ b/drivers/bus/moxtet.c @@ -83,10 +83,10 @@ static const struct attribute_group *moxtet_dev_groups[] = { NULL, }; -static int moxtet_match(struct device *dev, struct device_driver *drv) +static int moxtet_match(struct device *dev, const struct device_driver *drv) { struct moxtet_device *mdev = to_moxtet_device(dev); - struct moxtet_driver *tdrv = to_moxtet_driver(drv); + const struct moxtet_driver *tdrv = to_moxtet_driver(drv); const enum turris_mox_module_id *t; if (of_driver_match_device(dev, drv)) diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c index 1e29ba76615d..a2a7576a33cc 100644 --- a/drivers/bus/sunxi-rsb.c +++ b/drivers/bus/sunxi-rsb.c @@ -130,7 +130,7 @@ struct sunxi_rsb { /* bus / slave device related functions */ static const struct bus_type sunxi_rsb_bus; -static int sunxi_rsb_device_match(struct device *dev, struct device_driver *drv) +static int sunxi_rsb_device_match(struct device *dev, const struct device_driver *drv) { return of_driver_match_device(dev, drv); } diff --git a/drivers/cdx/cdx.c b/drivers/cdx/cdx.c index 236d381dc5f7..07371cb653d3 100644 --- a/drivers/cdx/cdx.c +++ b/drivers/cdx/cdx.c @@ -262,10 +262,10 @@ EXPORT_SYMBOL_GPL(cdx_clear_master); * * Return: true on success, false otherwise. */ -static int cdx_bus_match(struct device *dev, struct device_driver *drv) +static int cdx_bus_match(struct device *dev, const struct device_driver *drv) { struct cdx_device *cdx_dev = to_cdx_device(dev); - struct cdx_driver *cdx_drv = to_cdx_driver(drv); + const struct cdx_driver *cdx_drv = to_cdx_driver(drv); const struct cdx_device_id *found_id = NULL; const struct cdx_device_id *ids; diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c index 887ed6e358fb..cb730050d3d4 100644 --- a/drivers/cxl/core/port.c +++ b/drivers/cxl/core/port.c @@ -2082,7 +2082,7 @@ static int cxl_bus_uevent(const struct device *dev, struct kobj_uevent_env *env) cxl_device_id(dev)); } -static int cxl_bus_match(struct device *dev, struct device_driver *drv) +static int cxl_bus_match(struct device *dev, const struct device_driver *drv) { return cxl_device_id(dev) == to_cxl_drv(drv)->id; } diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index 603c0120cff8..65c91e133e26 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -823,10 +823,7 @@ struct cxl_driver { int id; }; -static inline struct cxl_driver *to_cxl_drv(struct device_driver *drv) -{ - return container_of(drv, struct cxl_driver, drv); -} +#define to_cxl_drv(__drv) container_of_const(__drv, struct cxl_driver, drv) int __cxl_driver_register(struct cxl_driver *cxl_drv, struct module *owner, const char *modname); diff --git a/drivers/dax/bus.c b/drivers/dax/bus.c index 3ef9550bd2ca..fde29e0ad68b 100644 --- a/drivers/dax/bus.c +++ b/drivers/dax/bus.c @@ -39,12 +39,9 @@ static int dax_bus_uevent(const struct device *dev, struct kobj_uevent_env *env) return add_uevent_var(env, "MODALIAS=" DAX_DEVICE_MODALIAS_FMT, 0); } -static struct dax_device_driver *to_dax_drv(struct device_driver *drv) -{ - return container_of(drv, struct dax_device_driver, drv); -} +#define to_dax_drv(__drv) container_of_const(__drv, struct dax_device_driver, drv) -static struct dax_id *__dax_match_id(struct dax_device_driver *dax_drv, +static struct dax_id *__dax_match_id(const struct dax_device_driver *dax_drv, const char *dev_name) { struct dax_id *dax_id; @@ -57,7 +54,7 @@ static struct dax_id *__dax_match_id(struct dax_device_driver *dax_drv, return NULL; } -static int dax_match_id(struct dax_device_driver *dax_drv, struct device *dev) +static int dax_match_id(const struct dax_device_driver *dax_drv, struct device *dev) { int match; @@ -68,7 +65,7 @@ static int dax_match_id(struct dax_device_driver *dax_drv, struct device *dev) return match; } -static int dax_match_type(struct dax_device_driver *dax_drv, struct device *dev) +static int dax_match_type(const struct dax_device_driver *dax_drv, struct device *dev) { enum dax_driver_type type = DAXDRV_DEVICE_TYPE; struct dev_dax *dev_dax = to_dev_dax(dev); @@ -156,7 +153,7 @@ static struct attribute *dax_drv_attrs[] = { }; ATTRIBUTE_GROUPS(dax_drv); -static int dax_bus_match(struct device *dev, struct device_driver *drv); +static int dax_bus_match(struct device *dev, const struct device_driver *drv); /* * Static dax regions are regions created by an external subsystem @@ -250,9 +247,9 @@ static const struct bus_type dax_bus_type = { .drv_groups = dax_drv_groups, }; -static int dax_bus_match(struct device *dev, struct device_driver *drv) +static int dax_bus_match(struct device *dev, const struct device_driver *drv) { - struct dax_device_driver *dax_drv = to_dax_drv(drv); + const struct dax_device_driver *dax_drv = to_dax_drv(drv); if (dax_match_id(dax_drv, dev)) return 1; diff --git a/drivers/dma/idxd/bus.c b/drivers/dma/idxd/bus.c index b83b27e04f2a..e647a684485d 100644 --- a/drivers/dma/idxd/bus.c +++ b/drivers/dma/idxd/bus.c @@ -33,10 +33,10 @@ void idxd_driver_unregister(struct idxd_device_driver *idxd_drv) EXPORT_SYMBOL_GPL(idxd_driver_unregister); static int idxd_config_bus_match(struct device *dev, - struct device_driver *drv) + const struct device_driver *drv) { - struct idxd_device_driver *idxd_drv = - container_of(drv, struct idxd_device_driver, drv); + const struct idxd_device_driver *idxd_drv = + container_of_const(drv, struct idxd_device_driver, drv); struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); int i = 0; diff --git a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c index 33f0ba11c6ad..cb586a362944 100644 --- a/drivers/eisa/eisa-bus.c +++ b/drivers/eisa/eisa-bus.c @@ -105,10 +105,10 @@ static char __init *decode_eisa_sig(unsigned long addr) return sig_str; } -static int eisa_bus_match(struct device *dev, struct device_driver *drv) +static int eisa_bus_match(struct device *dev, const struct device_driver *drv) { struct eisa_device *edev = to_eisa_device(dev); - struct eisa_driver *edrv = to_eisa_driver(drv); + const struct eisa_driver *edrv = to_eisa_driver(drv); const struct eisa_device_id *eids = edrv->id_table; if (!eids) diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index e6cdb905eeac..00e9a13e6c45 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c @@ -190,10 +190,10 @@ static bool match_ids(const struct ieee1394_device_id *id_table, int *id) } static const struct ieee1394_device_id *unit_match(struct device *dev, - struct device_driver *drv) + const struct device_driver *drv) { const struct ieee1394_device_id *id_table = - container_of(drv, struct fw_driver, driver)->id_table; + container_of_const(drv, struct fw_driver, driver)->id_table; int id[] = {0, 0, 0, 0}; get_modalias_ids(fw_unit(dev), id); @@ -207,7 +207,7 @@ static const struct ieee1394_device_id *unit_match(struct device *dev, static bool is_fw_unit(const struct device *dev); -static int fw_unit_match(struct device *dev, struct device_driver *drv) +static int fw_unit_match(struct device *dev, const struct device_driver *drv) { /* We only allow binding to fw_units. */ return is_fw_unit(dev) && unit_match(dev, drv) != NULL; diff --git a/drivers/firmware/arm_ffa/bus.c b/drivers/firmware/arm_ffa/bus.c index 2f557e90f2eb..62b0b8b919aa 100644 --- a/drivers/firmware/arm_ffa/bus.c +++ b/drivers/firmware/arm_ffa/bus.c @@ -19,7 +19,7 @@ static DEFINE_IDA(ffa_bus_id); -static int ffa_device_match(struct device *dev, struct device_driver *drv) +static int ffa_device_match(struct device *dev, const struct device_driver *drv) { const struct ffa_device_id *id_table; struct ffa_device *ffa_dev; diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c index 77c78be6e79c..96b2e5f9a8ef 100644 --- a/drivers/firmware/arm_scmi/bus.c +++ b/drivers/firmware/arm_scmi/bus.c @@ -207,7 +207,7 @@ scmi_protocol_table_unregister(const struct scmi_device_id *id_table) } static const struct scmi_device_id * -scmi_dev_match_id(struct scmi_device *scmi_dev, struct scmi_driver *scmi_drv) +scmi_dev_match_id(struct scmi_device *scmi_dev, const struct scmi_driver *scmi_drv) { const struct scmi_device_id *id = scmi_drv->id_table; @@ -225,9 +225,9 @@ scmi_dev_match_id(struct scmi_device *scmi_dev, struct scmi_driver *scmi_drv) return NULL; } -static int scmi_dev_match(struct device *dev, struct device_driver *drv) +static int scmi_dev_match(struct device *dev, const struct device_driver *drv) { - struct scmi_driver *scmi_drv = to_scmi_driver(drv); + const struct scmi_driver *scmi_drv = to_scmi_driver(drv); struct scmi_device *scmi_dev = to_scmi_dev(dev); const struct scmi_device_id *id; diff --git a/drivers/firmware/google/coreboot_table.c b/drivers/firmware/google/coreboot_table.c index fa7752f6e89b..c179c4e85108 100644 --- a/drivers/firmware/google/coreboot_table.c +++ b/drivers/firmware/google/coreboot_table.c @@ -22,12 +22,12 @@ #include "coreboot_table.h" #define CB_DEV(d) container_of(d, struct coreboot_device, dev) -#define CB_DRV(d) container_of(d, struct coreboot_driver, drv) +#define CB_DRV(d) container_of_const(d, struct coreboot_driver, drv) -static int coreboot_bus_match(struct device *dev, struct device_driver *drv) +static int coreboot_bus_match(struct device *dev, const struct device_driver *drv) { struct coreboot_device *device = CB_DEV(dev); - struct coreboot_driver *driver = CB_DRV(drv); + const struct coreboot_driver *driver = CB_DRV(drv); const struct coreboot_device_id *id; if (!driver->id_table) diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c index 094ee97ea26c..c406b949026f 100644 --- a/drivers/fpga/dfl.c +++ b/drivers/fpga/dfl.c @@ -257,10 +257,10 @@ dfl_match_one_device(const struct dfl_device_id *id, struct dfl_device *ddev) return NULL; } -static int dfl_bus_match(struct device *dev, struct device_driver *drv) +static int dfl_bus_match(struct device *dev, const struct device_driver *drv) { struct dfl_device *ddev = to_dfl_dev(dev); - struct dfl_driver *ddrv = to_dfl_drv(drv); + const struct dfl_driver *ddrv = to_dfl_drv(drv); const struct dfl_device_id *id_entry; id_entry = ddrv->id_table; diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index 097d5a780264..46ac5a8beab7 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -1361,10 +1361,10 @@ EXPORT_SYMBOL_GPL(fsi_master_unregister); /* FSI core & Linux bus type definitions */ -static int fsi_bus_match(struct device *dev, struct device_driver *drv) +static int fsi_bus_match(struct device *dev, const struct device_driver *drv) { struct fsi_device *fsi_dev = to_fsi_dev(dev); - struct fsi_driver *fsi_drv = to_fsi_drv(drv); + const struct fsi_driver *fsi_drv = to_fsi_drv(drv); const struct fsi_device_id *id; if (!fsi_drv->id_table) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index fa62367ee929..8c1c7cd365c7 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -53,7 +53,7 @@ static DEFINE_IDA(gpio_ida); static dev_t gpio_devt; #define GPIO_DEV_MAX 256 /* 256 GPIO chip devices supported */ -static int gpio_bus_match(struct device *dev, struct device_driver *drv) +static int gpio_bus_match(struct device *dev, const struct device_driver *drv) { struct fwnode_handle *fwnode = dev_fwnode(dev); diff --git a/drivers/gpu/drm/display/drm_dp_aux_bus.c b/drivers/gpu/drm/display/drm_dp_aux_bus.c index 5afc26be9d2a..d810529ebfb6 100644 --- a/drivers/gpu/drm/display/drm_dp_aux_bus.c +++ b/drivers/gpu/drm/display/drm_dp_aux_bus.c @@ -36,7 +36,7 @@ struct dp_aux_ep_device_with_data { * * Return: True if this driver matches this device; false otherwise. */ -static int dp_aux_ep_match(struct device *dev, struct device_driver *drv) +static int dp_aux_ep_match(struct device *dev, const struct device_driver *drv) { return !!of_match_device(drv->of_match_table, dev); } diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 795001bb7ff1..ddd51279cc9a 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -48,7 +48,7 @@ * subset of the MIPI DCS command set. */ -static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv) +static int mipi_dsi_device_match(struct device *dev, const struct device_driver *drv) { struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c index 7c52757a89db..8e09d6d328d2 100644 --- a/drivers/gpu/host1x/bus.c +++ b/drivers/gpu/host1x/bus.c @@ -333,7 +333,7 @@ static int host1x_del_client(struct host1x *host1x, return -ENODEV; } -static int host1x_device_match(struct device *dev, struct device_driver *drv) +static int host1x_device_match(struct device *dev, const struct device_driver *drv) { return strcmp(dev_name(dev), drv->name) == 0; } diff --git a/drivers/greybus/core.c b/drivers/greybus/core.c index 95c09d4f3a86..c5569563bd03 100644 --- a/drivers/greybus/core.c +++ b/drivers/greybus/core.c @@ -90,9 +90,9 @@ greybus_match_id(struct gb_bundle *bundle, const struct greybus_bundle_id *id) return NULL; } -static int greybus_match_device(struct device *dev, struct device_driver *drv) +static int greybus_match_device(struct device *dev, const struct device_driver *drv) { - struct greybus_driver *driver = to_greybus_driver(drv); + const struct greybus_driver *driver = to_greybus_driver(drv); struct gb_bundle *bundle; const struct greybus_bundle_id *id; diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 74efda212c55..d7a1f8121006 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2562,7 +2562,7 @@ const struct hid_device_id *hid_match_device(struct hid_device *hdev, } EXPORT_SYMBOL_GPL(hid_match_device); -static int hid_bus_match(struct device *dev, struct device_driver *drv) +static int hid_bus_match(struct device *dev, const struct device_driver *drv) { struct hid_driver *hdrv = to_hid_driver(drv); struct hid_device *hdev = to_hid_device(dev); diff --git a/drivers/hid/intel-ish-hid/ishtp/bus.c b/drivers/hid/intel-ish-hid/ishtp/bus.c index 03d5601ce807..4a91577f6027 100644 --- a/drivers/hid/intel-ish-hid/ishtp/bus.c +++ b/drivers/hid/intel-ish-hid/ishtp/bus.c @@ -236,7 +236,7 @@ static int ishtp_cl_device_probe(struct device *dev) * * Return: 1 if dev & drv matches, 0 otherwise. */ -static int ishtp_cl_bus_match(struct device *dev, struct device_driver *drv) +static int ishtp_cl_bus_match(struct device *dev, const struct device_driver *drv) { struct ishtp_cl_device *device = to_ishtp_cl_device(dev); struct ishtp_cl_driver *driver = to_ishtp_cl_driver(drv); diff --git a/drivers/hsi/hsi_core.c b/drivers/hsi/hsi_core.c index e3beeac8aee5..8113cb9d4015 100644 --- a/drivers/hsi/hsi_core.c +++ b/drivers/hsi/hsi_core.c @@ -37,7 +37,7 @@ static int hsi_bus_uevent(const struct device *dev, struct kobj_uevent_env *env) return 0; } -static int hsi_bus_match(struct device *dev, struct device_driver *driver) +static int hsi_bus_match(struct device *dev, const struct device_driver *driver) { if (of_driver_match_device(dev, driver)) return true; diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 12a707ab73f8..c857dc3975be 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -685,7 +685,7 @@ static const struct hv_vmbus_device_id vmbus_device_null; * Return a matching hv_vmbus_device_id pointer. * If there is no match, return NULL. */ -static const struct hv_vmbus_device_id *hv_vmbus_get_id(struct hv_driver *drv, +static const struct hv_vmbus_device_id *hv_vmbus_get_id(const struct hv_driver *drv, struct hv_device *dev) { const guid_t *guid = &dev->dev_type; @@ -696,7 +696,7 @@ static const struct hv_vmbus_device_id *hv_vmbus_get_id(struct hv_driver *drv, return NULL; /* Look at the dynamic ids first, before the static ones */ - id = hv_vmbus_dynid_match(drv, guid); + id = hv_vmbus_dynid_match((struct hv_driver *)drv, guid); if (!id) id = hv_vmbus_dev_match(drv->id_table, guid); @@ -809,9 +809,9 @@ ATTRIBUTE_GROUPS(vmbus_drv); /* * vmbus_match - Attempt to match the specified device to the specified driver */ -static int vmbus_match(struct device *device, struct device_driver *driver) +static int vmbus_match(struct device *device, const struct device_driver *driver) { - struct hv_driver *drv = drv_to_hv_drv(driver); + const struct hv_driver *drv = drv_to_hv_drv(driver); struct hv_device *hv_dev = device_to_hv_device(device); /* The hv_sock driver handles all hv_sock offers. */ diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c index a121dc5cbd61..d72993355473 100644 --- a/drivers/hwtracing/intel_th/core.c +++ b/drivers/hwtracing/intel_th/core.c @@ -26,9 +26,9 @@ module_param(host_mode, bool, 0444); static DEFINE_IDA(intel_th_ida); -static int intel_th_match(struct device *dev, struct device_driver *driver) +static int intel_th_match(struct device *dev, const struct device_driver *driver) { - struct intel_th_driver *thdrv = to_intel_th_driver(driver); + const struct intel_th_driver *thdrv = to_intel_th_driver(driver); struct intel_th_device *thdev = to_intel_th_device(dev); if (thdev->type == INTEL_TH_SWITCH && diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h index 6cbba733f259..3b87cd542c1b 100644 --- a/drivers/hwtracing/intel_th/intel_th.h +++ b/drivers/hwtracing/intel_th/intel_th.h @@ -189,7 +189,7 @@ struct intel_th_driver { }; #define to_intel_th_driver(_d) \ - container_of((_d), struct intel_th_driver, driver) + container_of_const((_d), struct intel_th_driver, driver) #define to_intel_th_driver_or_null(_d) \ ((_d) ? to_intel_th_driver(_d) : NULL) diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index db0d1ac82910..0b1be9559d2d 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -136,10 +136,10 @@ const void *i2c_get_match_data(const struct i2c_client *client) } EXPORT_SYMBOL(i2c_get_match_data); -static int i2c_device_match(struct device *dev, struct device_driver *drv) +static int i2c_device_match(struct device *dev, const struct device_driver *drv) { struct i2c_client *client = i2c_verify_client(dev); - struct i2c_driver *driver; + const struct i2c_driver *driver; /* Attempt an OF style match */ diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c index 3b4d6a8edca3..00a3e9d01547 100644 --- a/drivers/i3c/master.c +++ b/drivers/i3c/master.c @@ -301,10 +301,10 @@ static const struct device_type i3c_device_type = { .uevent = i3c_device_uevent, }; -static int i3c_device_match(struct device *dev, struct device_driver *drv) +static int i3c_device_match(struct device *dev, const struct device_driver *drv) { struct i3c_device *i3cdev; - struct i3c_driver *i3cdrv; + const struct i3c_driver *i3cdrv; if (dev->type != &i3c_device_type) return 0; diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index cfcc81c47b50..e77dd0740d27 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c @@ -806,9 +806,9 @@ start_over: } EXPORT_SYMBOL(gameport_unregister_driver); -static int gameport_bus_match(struct device *dev, struct device_driver *drv) +static int gameport_bus_match(struct device *dev, const struct device_driver *drv) { - struct gameport_driver *gameport_drv = to_gameport_driver(drv); + const struct gameport_driver *gameport_drv = to_gameport_driver(drv); return !gameport_drv->ignore; } diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c index 343030290d78..3aee04837205 100644 --- a/drivers/input/rmi4/rmi_bus.c +++ b/drivers/input/rmi4/rmi_bus.c @@ -144,9 +144,9 @@ bool rmi_is_function_device(struct device *dev) return dev->type == &rmi_function_type; } -static int rmi_function_match(struct device *dev, struct device_driver *drv) +static int rmi_function_match(struct device *dev, const struct device_driver *drv) { - struct rmi_function_handler *handler = to_rmi_function_handler(drv); + const struct rmi_function_handler *handler = to_rmi_function_handler(drv); struct rmi_function *fn = to_rmi_function(dev); return fn->fd.function_number == handler->func; @@ -333,7 +333,7 @@ EXPORT_SYMBOL_GPL(rmi_unregister_function_handler); /* Bus specific stuff */ -static int rmi_bus_match(struct device *dev, struct device_driver *drv) +static int rmi_bus_match(struct device *dev, const struct device_driver *drv) { bool physical = rmi_is_physical_device(dev); diff --git a/drivers/input/rmi4/rmi_bus.h b/drivers/input/rmi4/rmi_bus.h index ea46ad9447ec..d4d0d82c69aa 100644 --- a/drivers/input/rmi4/rmi_bus.h +++ b/drivers/input/rmi4/rmi_bus.h @@ -87,7 +87,7 @@ struct rmi_function_handler { }; #define to_rmi_function_handler(d) \ - container_of(d, struct rmi_function_handler, driver) + container_of_const(d, struct rmi_function_handler, driver) int __must_check __rmi_register_function_handler(struct rmi_function_handler *, struct module *, const char *); diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c index ef9ea295f9e0..2168b6cd7167 100644 --- a/drivers/input/rmi4/rmi_driver.c +++ b/drivers/input/rmi4/rmi_driver.c @@ -1258,7 +1258,7 @@ static struct rmi_driver rmi_physical_driver = { .set_input_params = rmi_driver_set_input_params, }; -bool rmi_is_physical_driver(struct device_driver *drv) +bool rmi_is_physical_driver(const struct device_driver *drv) { return drv == &rmi_physical_driver.driver; } diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_driver.h index 1c6c6086c0e5..3bfe9013043e 100644 --- a/drivers/input/rmi4/rmi_driver.h +++ b/drivers/input/rmi4/rmi_driver.h @@ -84,7 +84,7 @@ int rmi_register_desc_calc_reg_offset( bool rmi_register_desc_has_subpacket(const struct rmi_register_desc_item *item, u8 subpacket); -bool rmi_is_physical_driver(struct device_driver *); +bool rmi_is_physical_driver(const struct device_driver *); int rmi_register_physical_driver(void); void rmi_unregister_physical_driver(void); void rmi_free_function_list(struct rmi_device *rmi_dev); diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index a8838b522627..36bf2c50d8e9 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -877,10 +877,10 @@ static void serio_set_drv(struct serio *serio, struct serio_driver *drv) serio_continue_rx(serio); } -static int serio_bus_match(struct device *dev, struct device_driver *drv) +static int serio_bus_match(struct device *dev, const struct device_driver *drv) { struct serio *serio = to_serio_port(dev); - struct serio_driver *serio_drv = to_serio_driver(drv); + const struct serio_driver *serio_drv = to_serio_driver(drv); if (serio->manual_bind || serio_drv->manual_bind) return 0; diff --git a/drivers/ipack/ipack.c b/drivers/ipack/ipack.c index 866bf48d803b..57d232c909f9 100644 --- a/drivers/ipack/ipack.c +++ b/drivers/ipack/ipack.c @@ -13,7 +13,7 @@ #include #define to_ipack_dev(device) container_of(device, struct ipack_device, dev) -#define to_ipack_driver(drv) container_of(drv, struct ipack_driver, driver) +#define to_ipack_driver(drv) container_of_const(drv, struct ipack_driver, driver) static DEFINE_IDA(ipack_ida); @@ -49,10 +49,10 @@ ipack_match_id(const struct ipack_device_id *ids, struct ipack_device *idev) return NULL; } -static int ipack_bus_match(struct device *dev, struct device_driver *drv) +static int ipack_bus_match(struct device *dev, const struct device_driver *drv) { struct ipack_device *idev = to_ipack_dev(dev); - struct ipack_driver *idrv = to_ipack_driver(drv); + const struct ipack_driver *idrv = to_ipack_driver(drv); const struct ipack_device_id *found_id; found_id = ipack_match_id(idrv->id_table, idev); diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 565f1e21ff7d..13626205530d 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -36,7 +36,7 @@ static struct macio_chip *macio_on_hold; -static int macio_bus_match(struct device *dev, struct device_driver *drv) +static int macio_bus_match(struct device *dev, const struct device_driver *drv) { const struct of_device_id * matches = drv->of_match_table; diff --git a/drivers/mcb/mcb-core.c b/drivers/mcb/mcb-core.c index 267045b76505..91bbd948ee93 100644 --- a/drivers/mcb/mcb-core.c +++ b/drivers/mcb/mcb-core.c @@ -28,9 +28,9 @@ static const struct mcb_device_id *mcb_match_id(const struct mcb_device_id *ids, return NULL; } -static int mcb_match(struct device *dev, struct device_driver *drv) +static int mcb_match(struct device *dev, const struct device_driver *drv) { - struct mcb_driver *mdrv = to_mcb_driver(drv); + const struct mcb_driver *mdrv = to_mcb_driver(drv); struct mcb_device *mdev = to_mcb_device(dev); const struct mcb_device_id *found_id; diff --git a/drivers/media/pci/bt8xx/bttv-gpio.c b/drivers/media/pci/bt8xx/bttv-gpio.c index 6b7fea50328c..59a6f160aac7 100644 --- a/drivers/media/pci/bt8xx/bttv-gpio.c +++ b/drivers/media/pci/bt8xx/bttv-gpio.c @@ -28,9 +28,9 @@ /* ----------------------------------------------------------------------- */ /* internal: the bttv "bus" */ -static int bttv_sub_bus_match(struct device *dev, struct device_driver *drv) +static int bttv_sub_bus_match(struct device *dev, const struct device_driver *drv) { - struct bttv_sub_driver *sub = to_bttv_sub_drv(drv); + const struct bttv_sub_driver *sub = to_bttv_sub_drv(drv); int len = strlen(sub->wanted); if (0 == strncmp(dev_name(dev), sub->wanted, len)) diff --git a/drivers/media/pci/bt8xx/bttv.h b/drivers/media/pci/bt8xx/bttv.h index eed7eeb3b963..97bbed980f98 100644 --- a/drivers/media/pci/bt8xx/bttv.h +++ b/drivers/media/pci/bt8xx/bttv.h @@ -341,7 +341,7 @@ struct bttv_sub_driver { int (*probe)(struct bttv_sub_device *sub); void (*remove)(struct bttv_sub_device *sub); }; -#define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv) +#define to_bttv_sub_drv(x) container_of_const((x), struct bttv_sub_driver, drv) int bttv_sub_register(struct bttv_sub_driver *drv, char *wanted); int bttv_sub_unregister(struct bttv_sub_driver *drv); diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c index 23fea51ecbdd..9a3a784054cc 100644 --- a/drivers/memstick/core/memstick.c +++ b/drivers/memstick/core/memstick.c @@ -38,13 +38,12 @@ static int memstick_dev_match(struct memstick_dev *card, return 0; } -static int memstick_bus_match(struct device *dev, struct device_driver *drv) +static int memstick_bus_match(struct device *dev, const struct device_driver *drv) { struct memstick_dev *card = container_of(dev, struct memstick_dev, dev); - struct memstick_driver *ms_drv = container_of(drv, - struct memstick_driver, - driver); + const struct memstick_driver *ms_drv = container_of_const(drv, struct memstick_driver, + driver); struct memstick_device_id *ids = ms_drv->id_table; if (ids) { diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c index 16ca23311cab..be08eaee0a90 100644 --- a/drivers/mfd/mcp-core.c +++ b/drivers/mfd/mcp-core.c @@ -20,7 +20,7 @@ #define to_mcp(d) container_of(d, struct mcp, attached_device) #define to_mcp_driver(d) container_of(d, struct mcp_driver, drv) -static int mcp_bus_match(struct device *dev, struct device_driver *drv) +static int mcp_bus_match(struct device *dev, const struct device_driver *drv) { return 1; } diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 99393f610cdf..5576146ab13b 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -19,7 +19,7 @@ #include "mei_dev.h" #include "client.h" -#define to_mei_cl_driver(d) container_of(d, struct mei_cl_driver, driver) +#define to_mei_cl_driver(d) container_of_const(d, struct mei_cl_driver, driver) /** * __mei_cl_send - internal client send (write) @@ -1124,7 +1124,7 @@ struct mei_cl_device_id *mei_cl_device_find(const struct mei_cl_device *cldev, * * Return: 1 if matching device was found 0 otherwise */ -static int mei_cl_device_match(struct device *dev, struct device_driver *drv) +static int mei_cl_device_match(struct device *dev, const struct device_driver *drv) { const struct mei_cl_device *cldev = to_mei_cl_device(dev); const struct mei_cl_driver *cldrv = to_mei_cl_driver(drv); diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c index fd9c3cbbc51e..12355d34e193 100644 --- a/drivers/misc/tifm_core.c +++ b/drivers/misc/tifm_core.c @@ -38,11 +38,11 @@ static int tifm_dev_match(struct tifm_dev *sock, struct tifm_device_id *id) return 0; } -static int tifm_bus_match(struct device *dev, struct device_driver *drv) +static int tifm_bus_match(struct device *dev, const struct device_driver *drv) { struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev); - struct tifm_driver *fm_drv = container_of(drv, struct tifm_driver, - driver); + const struct tifm_driver *fm_drv = container_of_const(drv, struct tifm_driver, + driver); struct tifm_device_id *ids = fm_drv->id_table; if (ids) { diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index c5fdfe2325f8..b66b637e2d57 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -26,7 +26,7 @@ #include "sdio_cis.h" #include "sdio_bus.h" -#define to_sdio_driver(d) container_of(d, struct sdio_driver, drv) +#define to_sdio_driver(d) container_of_const(d, struct sdio_driver, drv) /* show configuration fields */ #define sdio_config_attr(field, format_string, args...) \ @@ -91,7 +91,7 @@ static const struct sdio_device_id *sdio_match_one(struct sdio_func *func, } static const struct sdio_device_id *sdio_match_device(struct sdio_func *func, - struct sdio_driver *sdrv) + const struct sdio_driver *sdrv) { const struct sdio_device_id *ids; @@ -108,10 +108,10 @@ static const struct sdio_device_id *sdio_match_device(struct sdio_func *func, return NULL; } -static int sdio_bus_match(struct device *dev, struct device_driver *drv) +static int sdio_bus_match(struct device *dev, const struct device_driver *drv) { struct sdio_func *func = dev_to_sdio_func(dev); - struct sdio_driver *sdrv = to_sdio_driver(drv); + const struct sdio_driver *sdrv = to_sdio_driver(drv); if (sdio_match_device(func, sdrv)) return 1; @@ -129,7 +129,7 @@ sdio_bus_uevent(const struct device *dev, struct kobj_uevent_env *env) "SDIO_CLASS=%02X", func->class)) return -ENOMEM; - if (add_uevent_var(env, + if (add_uevent_var(env, "SDIO_ID=%04X:%04X", func->vendor, func->device)) return -ENOMEM; diff --git a/drivers/most/core.c b/drivers/most/core.c index f13d0e14a48b..304f0b457654 100644 --- a/drivers/most/core.c +++ b/drivers/most/core.c @@ -491,7 +491,7 @@ static int print_links(struct device *dev, void *data) return 0; } -static int most_match(struct device *dev, struct device_driver *drv) +static int most_match(struct device *dev, const struct device_driver *drv) { if (!strcmp(dev_name(dev), "most")) return 0; diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 8b9ead76e40e..7e2f10182c0c 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -1375,9 +1375,9 @@ EXPORT_SYMBOL_GPL(mdiobus_c45_modify_changed); * require calling the devices own match function, since different classes * of MDIO devices have different match criteria. */ -static int mdio_bus_match(struct device *dev, struct device_driver *drv) +static int mdio_bus_match(struct device *dev, const struct device_driver *drv) { - struct mdio_driver *mdiodrv = to_mdio_driver(drv); + const struct mdio_driver *mdiodrv = to_mdio_driver(drv); struct mdio_device *mdio = to_mdio_device(dev); /* Both the driver and device must type-match */ diff --git a/drivers/net/phy/mdio_device.c b/drivers/net/phy/mdio_device.c index 73f6539b9e50..e747ee63c665 100644 --- a/drivers/net/phy/mdio_device.c +++ b/drivers/net/phy/mdio_device.c @@ -35,10 +35,10 @@ static void mdio_device_release(struct device *dev) kfree(to_mdio_device(dev)); } -int mdio_device_bus_match(struct device *dev, struct device_driver *drv) +int mdio_device_bus_match(struct device *dev, const struct device_driver *drv) { struct mdio_device *mdiodev = to_mdio_device(dev); - struct mdio_driver *mdiodrv = to_mdio_driver(drv); + const struct mdio_driver *mdiodrv = to_mdio_driver(drv); if (mdiodrv->mdiodrv.flags & MDIO_DEVICE_IS_PHY) return 0; diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 6c6ec9475709..fc63299e4632 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -533,10 +533,10 @@ static int phy_scan_fixups(struct phy_device *phydev) return 0; } -static int phy_bus_match(struct device *dev, struct device_driver *drv) +static int phy_bus_match(struct device *dev, const struct device_driver *drv) { struct phy_device *phydev = to_phy_device(dev); - struct phy_driver *phydrv = to_phy_driver(drv); + const struct phy_driver *phydrv = to_phy_driver(drv); const int num_ids = ARRAY_SIZE(phydev->c45_ids.device_ids); int i; diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c index f9e7847a378e..77e55debeed6 100644 --- a/drivers/ntb/ntb_transport.c +++ b/drivers/ntb/ntb_transport.c @@ -284,7 +284,7 @@ static void ntb_memcpy_rx(struct ntb_queue_entry *entry, void *offset); static int ntb_transport_bus_match(struct device *dev, - struct device_driver *drv) + const struct device_driver *drv) { return !strncmp(dev_name(dev), drv->name, strlen(drv->name)); } diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c index 101c425f3e8b..2237715e42eb 100644 --- a/drivers/nvdimm/bus.c +++ b/drivers/nvdimm/bus.c @@ -272,7 +272,7 @@ long nvdimm_clear_poison(struct device *dev, phys_addr_t phys, } EXPORT_SYMBOL_GPL(nvdimm_clear_poison); -static int nvdimm_bus_match(struct device *dev, struct device_driver *drv); +static int nvdimm_bus_match(struct device *dev, const struct device_driver *drv); static const struct bus_type nvdimm_bus_type = { .name = "nd", @@ -468,9 +468,9 @@ static struct nd_device_driver nd_bus_driver = { }, }; -static int nvdimm_bus_match(struct device *dev, struct device_driver *drv) +static int nvdimm_bus_match(struct device *dev, const struct device_driver *drv) { - struct nd_device_driver *nd_drv = to_nd_device_driver(drv); + const struct nd_device_driver *nd_drv = to_nd_device_driver(drv); if (is_nvdimm_bus(dev) && nd_drv == &nd_bus_driver) return true; diff --git a/drivers/nvmem/layouts.c b/drivers/nvmem/layouts.c index 64dc7013a098..77a4119efea8 100644 --- a/drivers/nvmem/layouts.c +++ b/drivers/nvmem/layouts.c @@ -17,11 +17,11 @@ #include "internals.h" #define to_nvmem_layout_driver(drv) \ - (container_of((drv), struct nvmem_layout_driver, driver)) + (container_of_const((drv), struct nvmem_layout_driver, driver)) #define to_nvmem_layout_device(_dev) \ container_of((_dev), struct nvmem_layout, dev) -static int nvmem_layout_bus_match(struct device *dev, struct device_driver *drv) +static int nvmem_layout_bus_match(struct device *dev, const struct device_driver *drv) { return of_driver_match_device(dev, drv); } diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c index 323f2a60ab16..8fa2797d4169 100644 --- a/drivers/pci/endpoint/pci-epf-core.c +++ b/drivers/pci/endpoint/pci-epf-core.c @@ -488,10 +488,10 @@ pci_epf_match_id(const struct pci_epf_device_id *id, const struct pci_epf *epf) return NULL; } -static int pci_epf_device_match(struct device *dev, struct device_driver *drv) +static int pci_epf_device_match(struct device *dev, const struct device_driver *drv) { struct pci_epf *epf = to_pci_epf(dev); - struct pci_epf_driver *driver = to_pci_epf_driver(drv); + const struct pci_epf_driver *driver = to_pci_epf_driver(drv); if (driver->id_table) return !!pci_epf_match_id(driver->id_table, epf); diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index af2996d0d17f..f412ef73a6e4 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -1503,7 +1503,7 @@ EXPORT_SYMBOL(pci_dev_driver); * system is in its list of supported devices. Returns the matching * pci_device_id structure or %NULL if there is no match. */ -static int pci_bus_match(struct device *dev, struct device_driver *drv) +static int pci_bus_match(struct device *dev, const struct device_driver *drv) { struct pci_dev *pci_dev = to_pci_dev(dev); struct pci_driver *pci_drv; @@ -1512,7 +1512,7 @@ static int pci_bus_match(struct device *dev, struct device_driver *drv) if (!pci_dev->match_driver) return 0; - pci_drv = to_pci_driver(drv); + pci_drv = (struct pci_driver *)to_pci_driver(drv); found_id = pci_match_device(pci_drv, pci_dev); if (found_id) return 1; @@ -1688,10 +1688,10 @@ struct bus_type pci_bus_type = { EXPORT_SYMBOL(pci_bus_type); #ifdef CONFIG_PCIEPORTBUS -static int pcie_port_bus_match(struct device *dev, struct device_driver *drv) +static int pcie_port_bus_match(struct device *dev, const struct device_driver *drv) { struct pcie_device *pciedev; - struct pcie_port_service_driver *driver; + const struct pcie_port_service_driver *driver; if (drv->bus != &pcie_port_bus_type || dev->bus != &pcie_port_bus_type) return 0; diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index d3cfd353fb93..da6f66f357cc 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -900,7 +900,7 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, } -static int pcmcia_bus_match(struct device *dev, struct device_driver *drv) +static int pcmcia_bus_match(struct device *dev, const struct device_driver *drv) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); struct pcmcia_driver *p_drv = to_pcmcia_drv(drv); diff --git a/drivers/peci/core.c b/drivers/peci/core.c index 8f8bda2f2a62..289f0815a1c8 100644 --- a/drivers/peci/core.c +++ b/drivers/peci/core.c @@ -173,10 +173,10 @@ peci_bus_match_device_id(const struct peci_device_id *id, struct peci_device *de return NULL; } -static int peci_bus_device_match(struct device *dev, struct device_driver *drv) +static int peci_bus_device_match(struct device *dev, const struct device_driver *drv) { struct peci_device *device = to_peci_device(dev); - struct peci_driver *peci_drv = to_peci_driver(drv); + const struct peci_driver *peci_drv = to_peci_driver(drv); if (dev->type != &peci_device_type) return 0; diff --git a/drivers/peci/internal.h b/drivers/peci/internal.h index 506bafcccbbf..d388dfdeb48e 100644 --- a/drivers/peci/internal.h +++ b/drivers/peci/internal.h @@ -98,10 +98,7 @@ struct peci_driver { const struct peci_device_id *id_table; }; -static inline struct peci_driver *to_peci_driver(struct device_driver *d) -{ - return container_of(d, struct peci_driver, driver); -} +#define to_peci_driver(__drv) container_of_const(__drv, struct peci_driver, driver) int __peci_driver_register(struct peci_driver *driver, struct module *owner, const char *mod_name); diff --git a/drivers/platform/surface/aggregator/bus.c b/drivers/platform/surface/aggregator/bus.c index 118caa651bec..af8d573aae93 100644 --- a/drivers/platform/surface/aggregator/bus.c +++ b/drivers/platform/surface/aggregator/bus.c @@ -306,9 +306,9 @@ const void *ssam_device_get_match_data(const struct ssam_device *dev) } EXPORT_SYMBOL_GPL(ssam_device_get_match_data); -static int ssam_bus_match(struct device *dev, struct device_driver *drv) +static int ssam_bus_match(struct device *dev, const struct device_driver *drv) { - struct ssam_device_driver *sdrv = to_ssam_device_driver(drv); + const struct ssam_device_driver *sdrv = to_ssam_device_driver(drv); struct ssam_device *sdev = to_ssam_device(dev); if (!is_ssam_device(dev)) diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index d21f3fa25823..389e7878e937 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -727,10 +727,7 @@ char *wmi_get_acpi_device_uid(const char *guid_string) } EXPORT_SYMBOL_GPL(wmi_get_acpi_device_uid); -static inline struct wmi_driver *drv_to_wdrv(struct device_driver *drv) -{ - return container_of(drv, struct wmi_driver, driver); -} +#define drv_to_wdrv(__drv) container_of_const(__drv, struct wmi_driver, driver) /* * sysfs interface @@ -848,9 +845,9 @@ static void wmi_dev_release(struct device *dev) kfree(wblock); } -static int wmi_dev_match(struct device *dev, struct device_driver *driver) +static int wmi_dev_match(struct device *dev, const struct device_driver *driver) { - struct wmi_driver *wmi_driver = drv_to_wdrv(driver); + const struct wmi_driver *wmi_driver = drv_to_wdrv(driver); struct wmi_block *wblock = dev_to_wblock(dev); const struct wmi_device_id *id = wmi_driver->id_table; diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c index 3483e52e3a81..7de7aabb275e 100644 --- a/drivers/pnp/driver.c +++ b/drivers/pnp/driver.c @@ -41,7 +41,7 @@ int compare_pnp_id(struct pnp_id *pos, const char *id) return 0; } -static const struct pnp_device_id *match_device(struct pnp_driver *drv, +static const struct pnp_device_id *match_device(const struct pnp_driver *drv, struct pnp_dev *dev) { const struct pnp_device_id *drv_id = drv->id_table; @@ -150,10 +150,10 @@ static void pnp_device_shutdown(struct device *dev) drv->shutdown(pnp_dev); } -static int pnp_bus_match(struct device *dev, struct device_driver *drv) +static int pnp_bus_match(struct device *dev, const struct device_driver *drv) { struct pnp_dev *pnp_dev = to_pnp_dev(dev); - struct pnp_driver *pnp_drv = to_pnp_driver(drv); + const struct pnp_driver *pnp_drv = to_pnp_driver(drv); if (match_device(pnp_drv, pnp_dev) == NULL) return 0; diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c index 1b3b4c2e015d..238250e69005 100644 --- a/drivers/rapidio/rio-driver.c +++ b/drivers/rapidio/rio-driver.c @@ -186,10 +186,10 @@ EXPORT_SYMBOL_GPL(rio_attach_device); * there is a matching &struct rio_device_id or 0 if there is * no match. */ -static int rio_match_bus(struct device *dev, struct device_driver *drv) +static int rio_match_bus(struct device *dev, const struct device_driver *drv) { struct rio_dev *rdev = to_rio_dev(dev); - struct rio_driver *rdrv = to_rio_driver(drv); + const struct rio_driver *rdrv = to_rio_driver(drv); const struct rio_device_id *id = rdrv->id_table; const struct rio_device_id *found_id; diff --git a/drivers/rpmsg/rpmsg_core.c b/drivers/rpmsg/rpmsg_core.c index 0fa08266404d..712c06c02696 100644 --- a/drivers/rpmsg/rpmsg_core.c +++ b/drivers/rpmsg/rpmsg_core.c @@ -493,10 +493,10 @@ static inline int rpmsg_id_match(const struct rpmsg_device *rpdev, } /* match rpmsg channel and rpmsg driver */ -static int rpmsg_dev_match(struct device *dev, struct device_driver *drv) +static int rpmsg_dev_match(struct device *dev, const struct device_driver *drv) { struct rpmsg_device *rpdev = to_rpmsg_device(dev); - struct rpmsg_driver *rpdrv = to_rpmsg_driver(drv); + const struct rpmsg_driver *rpdrv = to_rpmsg_driver(drv); const struct rpmsg_device_id *ids = rpdrv->id_table; unsigned int i; diff --git a/drivers/rpmsg/rpmsg_internal.h b/drivers/rpmsg/rpmsg_internal.h index a3ba768138f1..42c7007be1b5 100644 --- a/drivers/rpmsg/rpmsg_internal.h +++ b/drivers/rpmsg/rpmsg_internal.h @@ -16,7 +16,7 @@ #include #define to_rpmsg_device(d) container_of(d, struct rpmsg_device, dev) -#define to_rpmsg_driver(d) container_of(d, struct rpmsg_driver, drv) +#define to_rpmsg_driver(d) container_of_const(d, struct rpmsg_driver, drv) extern const struct class rpmsg_class; diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 781f84901256..53b68f8c32f3 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -1354,10 +1354,10 @@ int sch_is_pseudo_sch(struct subchannel *sch) return sch == to_css(sch->dev.parent)->pseudo_subchannel; } -static int css_bus_match(struct device *dev, struct device_driver *drv) +static int css_bus_match(struct device *dev, const struct device_driver *drv) { struct subchannel *sch = to_subchannel(dev); - struct css_driver *driver = to_cssdriver(drv); + const struct css_driver *driver = to_cssdriver(drv); struct css_device_id *id; /* When driver_override is set, only bind to the matching driver */ diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h index c2b175592bb7..a65a27dc520c 100644 --- a/drivers/s390/cio/css.h +++ b/drivers/s390/cio/css.h @@ -103,7 +103,7 @@ struct css_driver { int (*settle)(void); }; -#define to_cssdriver(n) container_of(n, struct css_driver, drv) +#define to_cssdriver(n) container_of_const(n, struct css_driver, drv) extern int css_driver_register(struct css_driver *); extern void css_driver_unregister(struct css_driver *); diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 920f550bc313..b0f23242e171 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -58,10 +58,10 @@ static const struct bus_type ccw_bus_type; * subsystem driver and one channel system per machine, but * we still use the abstraction. T.R. says it's a good idea. */ static int -ccw_bus_match (struct device * dev, struct device_driver * drv) +ccw_bus_match (struct device * dev, const struct device_driver * drv) { struct ccw_device *cdev = to_ccwdev(dev); - struct ccw_driver *cdrv = to_ccwdrv(drv); + const struct ccw_driver *cdrv = to_ccwdrv(drv); const struct ccw_device_id *ids = cdrv->ids, *found; if (!ids) diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 898865be0dad..0998b17ecb37 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -552,9 +552,9 @@ static void ap_poll_thread_stop(void) * * AP bus driver registration/unregistration. */ -static int ap_bus_match(struct device *dev, struct device_driver *drv) +static int ap_bus_match(struct device *dev, const struct device_driver *drv) { - struct ap_driver *ap_drv = to_ap_drv(drv); + const struct ap_driver *ap_drv = to_ap_drv(drv); struct ap_device_id *id; /* diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index fdbc6fdfdf57..0b275c719319 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h @@ -158,7 +158,7 @@ struct ap_driver { struct ap_config_info *old_config_info); }; -#define to_ap_drv(x) container_of((x), struct ap_driver, driver) +#define to_ap_drv(x) container_of_const((x), struct ap_driver, driver) int ap_driver_register(struct ap_driver *, struct module *, char *); void ap_driver_unregister(struct ap_driver *); diff --git a/drivers/scsi/fcoe/fcoe_sysfs.c b/drivers/scsi/fcoe/fcoe_sysfs.c index 453665ac6020..7d3b904af9e8 100644 --- a/drivers/scsi/fcoe/fcoe_sysfs.c +++ b/drivers/scsi/fcoe/fcoe_sysfs.c @@ -600,7 +600,7 @@ static const struct attribute_group *fcoe_fcf_attr_groups[] = { static const struct bus_type fcoe_bus_type; static int fcoe_bus_match(struct device *dev, - struct device_driver *drv) + const struct device_driver *drv) { if (dev->bus == &fcoe_bus_type) return 1; diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index b5aae4e8ae33..32f94db6d6bf 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -528,7 +528,7 @@ static struct class sdev_class = { }; /* all probing is done in the individual ->probe routines */ -static int scsi_bus_match(struct device *dev, struct device_driver *gendrv) +static int scsi_bus_match(struct device *dev, const struct device_driver *gendrv) { struct scsi_device *sdp; @@ -661,7 +661,7 @@ static int scsi_sdev_check_buf_bit(const char *buf) return 1; else if (buf[0] == '0') return 0; - else + else return -EINVAL; } else return -EINVAL; @@ -886,7 +886,7 @@ store_queue_type_field(struct device *dev, struct device_attribute *attr, if (!sdev->tagged_supported) return -EINVAL; - + sdev_printk(KERN_INFO, sdev, "ignoring write to deprecated queue_type attribute"); return count; diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 93e1978ad564..fde7de3b1e55 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -1204,7 +1204,7 @@ static const struct device_type iscsi_flashnode_conn_dev_type = { static const struct bus_type iscsi_flashnode_bus; int iscsi_flashnode_bus_match(struct device *dev, - struct device_driver *drv) + const struct device_driver *drv) { if (dev->bus == &iscsi_flashnode_bus) return 1; diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c index 16018009a5a6..6dc0549f7900 100644 --- a/drivers/sh/maple/maple.c +++ b/drivers/sh/maple/maple.c @@ -747,9 +747,9 @@ static int maple_get_dma_buffer(void) } static int maple_match_bus_driver(struct device *devptr, - struct device_driver *drvptr) + const struct device_driver *drvptr) { - struct maple_driver *maple_drv = to_maple_driver(drvptr); + const struct maple_driver *maple_drv = to_maple_driver(drvptr); struct maple_device *maple_dev = to_maple_dev(devptr); /* Trap empty port case */ diff --git a/drivers/siox/siox-core.c b/drivers/siox/siox-core.c index 24a45920a240..f98f5a27e659 100644 --- a/drivers/siox/siox-core.c +++ b/drivers/siox/siox-core.c @@ -503,7 +503,7 @@ static const struct device_type siox_device_type = { .release = siox_device_release, }; -static int siox_match(struct device *dev, struct device_driver *drv) +static int siox_match(struct device *dev, const struct device_driver *drv) { if (dev->type != &siox_device_type) return 0; diff --git a/drivers/slimbus/core.c b/drivers/slimbus/core.c index 41e62de1f91f..65e5515f7555 100644 --- a/drivers/slimbus/core.c +++ b/drivers/slimbus/core.c @@ -30,10 +30,10 @@ static const struct slim_device_id *slim_match(const struct slim_device_id *id, return NULL; } -static int slim_device_match(struct device *dev, struct device_driver *drv) +static int slim_device_match(struct device *dev, const struct device_driver *drv) { struct slim_device *sbdev = to_slim_device(dev); - struct slim_driver *sbdrv = to_slim_driver(drv); + const struct slim_driver *sbdrv = to_slim_driver(drv); /* Attempt an OF style match first */ if (of_driver_match_device(dev, drv)) diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c index 50749e870efa..4fbff3a890e2 100644 --- a/drivers/soc/qcom/apr.c +++ b/drivers/soc/qcom/apr.c @@ -338,10 +338,10 @@ static void apr_rxwq(struct work_struct *work) } } -static int apr_device_match(struct device *dev, struct device_driver *drv) +static int apr_device_match(struct device *dev, const struct device_driver *drv) { struct apr_device *adev = to_apr_device(dev); - struct apr_driver *adrv = to_apr_driver(drv); + const struct apr_driver *adrv = to_apr_driver(drv); const struct apr_device_id *id = adrv->id_table; /* Attempt an OF style match first */ diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c index c32faace618f..d928258c6761 100644 --- a/drivers/soundwire/bus_type.c +++ b/drivers/soundwire/bus_type.c @@ -19,7 +19,7 @@ * struct sdw_device_id. */ static const struct sdw_device_id * -sdw_get_device_id(struct sdw_slave *slave, struct sdw_driver *drv) +sdw_get_device_id(struct sdw_slave *slave, const struct sdw_driver *drv) { const struct sdw_device_id *id; @@ -35,10 +35,10 @@ sdw_get_device_id(struct sdw_slave *slave, struct sdw_driver *drv) return NULL; } -static int sdw_bus_match(struct device *dev, struct device_driver *ddrv) +static int sdw_bus_match(struct device *dev, const struct device_driver *ddrv) { struct sdw_slave *slave; - struct sdw_driver *drv; + const struct sdw_driver *drv; int ret = 0; if (is_sdw_slave(dev)) { diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 9bc9fd10d538..38a857024333 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -371,7 +371,7 @@ const void *spi_get_device_match_data(const struct spi_device *sdev) } EXPORT_SYMBOL_GPL(spi_get_device_match_data); -static int spi_match_device(struct device *dev, struct device_driver *drv) +static int spi_match_device(struct device *dev, const struct device_driver *drv) { const struct spi_device *spi = to_spi_device(dev); const struct spi_driver *sdrv = to_spi_driver(drv); diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c index 667085cb199d..fb0101da1485 100644 --- a/drivers/spmi/spmi.c +++ b/drivers/spmi/spmi.c @@ -43,7 +43,7 @@ static const struct device_type spmi_ctrl_type = { .release = spmi_ctrl_release, }; -static int spmi_device_match(struct device *dev, struct device_driver *drv) +static int spmi_device_match(struct device *dev, const struct device_driver *drv) { if (of_driver_match_device(dev, drv)) return 1; diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 4da8848b3639..aa6165e3db4a 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -323,10 +323,10 @@ static int ssb_match_devid(const struct ssb_device_id *tabid, return 1; } -static int ssb_bus_match(struct device *dev, struct device_driver *drv) +static int ssb_bus_match(struct device *dev, const struct device_driver *drv) { struct ssb_device *ssb_dev = dev_to_ssb_dev(dev); - struct ssb_driver *ssb_drv = drv_to_ssb_drv(drv); + const struct ssb_driver *ssb_drv = drv_to_ssb_drv(drv); const struct ssb_device_id *id; for (id = ssb_drv->id_table; diff --git a/drivers/staging/fieldbus/anybuss/anybuss-client.h b/drivers/staging/fieldbus/anybuss/anybuss-client.h index a219688006fe..c21c4bebfb84 100644 --- a/drivers/staging/fieldbus/anybuss/anybuss-client.h +++ b/drivers/staging/fieldbus/anybuss/anybuss-client.h @@ -44,11 +44,7 @@ static inline struct anybuss_client *to_anybuss_client(struct device *dev) return container_of(dev, struct anybuss_client, dev); } -static inline struct anybuss_client_driver * -to_anybuss_client_driver(struct device_driver *drv) -{ - return container_of(drv, struct anybuss_client_driver, driver); -} +#define to_anybuss_client_driver(__drv) container_of_const(__drv, struct anybuss_client_driver, driver) static inline void * anybuss_get_drvdata(const struct anybuss_client *client) diff --git a/drivers/staging/fieldbus/anybuss/host.c b/drivers/staging/fieldbus/anybuss/host.c index 410e6f8073c0..4f2b2fce92ee 100644 --- a/drivers/staging/fieldbus/anybuss/host.c +++ b/drivers/staging/fieldbus/anybuss/host.c @@ -1166,9 +1166,9 @@ EXPORT_SYMBOL_GPL(anybuss_recv_msg); /* ------------------------ bus functions ------------------------ */ static int anybus_bus_match(struct device *dev, - struct device_driver *drv) + const struct device_driver *drv) { - struct anybuss_client_driver *adrv = + const struct anybuss_client_driver *adrv = to_anybuss_client_driver(drv); struct anybuss_client *adev = to_anybuss_client(dev); diff --git a/drivers/staging/greybus/gbphy.c b/drivers/staging/greybus/gbphy.c index d827f03f5253..fe4f76da7f9c 100644 --- a/drivers/staging/greybus/gbphy.c +++ b/drivers/staging/greybus/gbphy.c @@ -117,7 +117,7 @@ gbphy_dev_match_id(struct gbphy_device *gbphy_dev, return NULL; } -static int gbphy_dev_match(struct device *dev, struct device_driver *drv) +static int gbphy_dev_match(struct device *dev, const struct device_driver *drv) { struct gbphy_driver *gbphy_drv = to_gbphy_driver(drv); struct gbphy_device *gbphy_dev = to_gbphy_dev(dev); diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.c index 3f87b93c6537..41ece91ab88a 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.c @@ -14,7 +14,7 @@ #include "vchiq_arm.h" #include "vchiq_bus.h" -static int vchiq_bus_type_match(struct device *dev, struct device_driver *drv) +static int vchiq_bus_type_match(struct device *dev, const struct device_driver *drv) { if (dev->bus == &vchiq_bus_type && strcmp(dev_name(dev), drv->name) == 0) diff --git a/drivers/staging/vme_user/vme.c b/drivers/staging/vme_user/vme.c index 0cd370ab1008..9a091463656d 100644 --- a/drivers/staging/vme_user/vme.c +++ b/drivers/staging/vme_user/vme.c @@ -1931,7 +1931,7 @@ EXPORT_SYMBOL(vme_unregister_driver); /* - Bus Registration ------------------------------------------------------ */ -static int vme_bus_match(struct device *dev, struct device_driver *drv) +static int vme_bus_match(struct device *dev, const struct device_driver *drv) { struct vme_driver *vme_drv; diff --git a/drivers/tc/tc-driver.c b/drivers/tc/tc-driver.c index 1c9d983a5a1f..2f6d147594b0 100644 --- a/drivers/tc/tc-driver.c +++ b/drivers/tc/tc-driver.c @@ -56,7 +56,7 @@ EXPORT_SYMBOL(tc_unregister_driver); * system is in its list of supported devices. Returns the matching * tc_device_id structure or %NULL if there is no match. */ -static const struct tc_device_id *tc_match_device(struct tc_driver *tdrv, +static const struct tc_device_id *tc_match_device(const struct tc_driver *tdrv, struct tc_dev *tdev) { const struct tc_device_id *id = tdrv->id_table; @@ -82,10 +82,10 @@ static const struct tc_device_id *tc_match_device(struct tc_driver *tdrv, * system is in its list of supported devices. Returns 1 if there * is a match or 0 otherwise. */ -static int tc_bus_match(struct device *dev, struct device_driver *drv) +static int tc_bus_match(struct device *dev, const struct device_driver *drv) { struct tc_dev *tdev = to_tc_dev(dev); - struct tc_driver *tdrv = to_tc_driver(drv); + const struct tc_driver *tdrv = to_tc_driver(drv); const struct tc_device_id *id; id = tc_match_device(tdrv, tdev); diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index 82ad095d2b1c..d52e879b204e 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -1201,7 +1201,7 @@ int tee_client_cancel_req(struct tee_context *ctx, } static int tee_client_device_match(struct device *dev, - struct device_driver *drv) + const struct device_driver *drv) { const struct tee_client_device_id *id_table; struct tee_client_device *tee_device; diff --git a/drivers/thunderbolt/domain.c b/drivers/thunderbolt/domain.c index 0023017299f7..144d0232a70c 100644 --- a/drivers/thunderbolt/domain.c +++ b/drivers/thunderbolt/domain.c @@ -45,9 +45,9 @@ static bool match_service_id(const struct tb_service_id *id, } static const struct tb_service_id *__tb_service_match(struct device *dev, - struct device_driver *drv) + const struct device_driver *drv) { - struct tb_service_driver *driver; + const struct tb_service_driver *driver; const struct tb_service_id *ids; struct tb_service *svc; @@ -55,7 +55,7 @@ static const struct tb_service_id *__tb_service_match(struct device *dev, if (!svc) return NULL; - driver = container_of(drv, struct tb_service_driver, driver); + driver = container_of_const(drv, struct tb_service_driver, driver); if (!driver->id_table) return NULL; @@ -67,7 +67,7 @@ static const struct tb_service_id *__tb_service_match(struct device *dev, return NULL; } -static int tb_service_match(struct device *dev, struct device_driver *drv) +static int tb_service_match(struct device *dev, const struct device_driver *drv) { return !!__tb_service_match(dev, drv); } diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c index 613cb356b918..8913cdd675f6 100644 --- a/drivers/tty/serdev/core.c +++ b/drivers/tty/serdev/core.c @@ -85,7 +85,7 @@ static const struct device_type serdev_ctrl_type = { .release = serdev_ctrl_release, }; -static int serdev_device_match(struct device *dev, struct device_driver *drv) +static int serdev_device_match(struct device *dev, const struct device_driver *drv) { if (!is_serdev_device(dev)) return 0; diff --git a/drivers/tty/serial/serial_base_bus.c b/drivers/tty/serial/serial_base_bus.c index 73c6ee540c83..e0d15dac7b9b 100644 --- a/drivers/tty/serial/serial_base_bus.c +++ b/drivers/tty/serial/serial_base_bus.c @@ -29,7 +29,7 @@ static const struct device_type serial_port_type = { .name = "port", }; -static int serial_base_match(struct device *dev, struct device_driver *drv) +static int serial_base_match(struct device *dev, const struct device_driver *drv) { if (dev->type == &serial_ctrl_type && str_has_prefix(drv->name, serial_ctrl_type.name)) diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c index 0886b19d2e1c..4a2ee447b213 100644 --- a/drivers/usb/common/ulpi.c +++ b/drivers/usb/common/ulpi.c @@ -34,7 +34,7 @@ EXPORT_SYMBOL_GPL(ulpi_write); /* -------------------------------------------------------------------------- */ -static int ulpi_match(struct device *dev, struct device_driver *driver) +static int ulpi_match(struct device *dev, const struct device_driver *driver) { struct ulpi_driver *drv = to_ulpi_driver(driver); struct ulpi *ulpi = to_ulpi_dev(dev); diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index e02ba15f6e34..8e9bafcd62c6 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -855,7 +855,7 @@ bool usb_driver_applicable(struct usb_device *udev, return false; } -static int usb_device_match(struct device *dev, struct device_driver *drv) +static int usb_device_match(struct device *dev, const struct device_driver *drv) { /* devices and interfaces are handled separately */ if (is_usb_device(dev)) { diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 2dfae7a17b3f..b0a613758414 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -1568,7 +1568,7 @@ EXPORT_SYMBOL_GPL(usb_del_gadget_udc); /* ------------------------------------------------------------------------- */ -static int gadget_match_driver(struct device *dev, struct device_driver *drv) +static int gadget_match_driver(struct device *dev, const struct device_driver *drv) { struct usb_gadget *gadget = dev_to_usb_gadget(dev); struct usb_udc *udc = gadget->udc; diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index 6c812d01b37d..d200e2c29a8f 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c @@ -14,7 +14,7 @@ #include static int usb_serial_device_match(struct device *dev, - struct device_driver *drv) + const struct device_driver *drv) { const struct usb_serial_port *port = to_usb_serial_port(dev); struct usb_serial_driver *driver = to_usb_serial_driver(drv); diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c index 6ea103e1abae..aa879253d3b8 100644 --- a/drivers/usb/typec/bus.c +++ b/drivers/usb/typec/bus.c @@ -447,7 +447,7 @@ static struct attribute *typec_attrs[] = { }; ATTRIBUTE_GROUPS(typec); -static int typec_match(struct device *dev, struct device_driver *driver) +static int typec_match(struct device *dev, const struct device_driver *driver) { struct typec_altmode_driver *drv = to_altmode_driver(driver); struct typec_altmode *altmode = to_typec_altmode(dev); diff --git a/drivers/vdpa/vdpa.c b/drivers/vdpa/vdpa.c index 8d391947eb8d..3813ec493d9d 100644 --- a/drivers/vdpa/vdpa.c +++ b/drivers/vdpa/vdpa.c @@ -65,7 +65,7 @@ static void vdpa_dev_remove(struct device *d) drv->remove(vdev); } -static int vdpa_dev_match(struct device *dev, struct device_driver *drv) +static int vdpa_dev_match(struct device *dev, const struct device_driver *drv) { struct vdpa_device *vdev = dev_to_vdpa(dev); diff --git a/drivers/vfio/mdev/mdev_driver.c b/drivers/vfio/mdev/mdev_driver.c index b98322966b3e..ad5b834806ff 100644 --- a/drivers/vfio/mdev/mdev_driver.c +++ b/drivers/vfio/mdev/mdev_driver.c @@ -31,7 +31,7 @@ static void mdev_remove(struct device *dev) drv->remove(to_mdev_device(dev)); } -static int mdev_match(struct device *dev, struct device_driver *drv) +static int mdev_match(struct device *dev, const struct device_driver *drv) { /* * No drivers automatically match. Drivers are only bound by explicit diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index b968b2aa5f4d..bc0218f15a1e 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c @@ -82,7 +82,7 @@ static inline int virtio_id_match(const struct virtio_device *dev, /* This looks through all the IDs a driver claims to support. If any of them * match, we return 1 and the kernel will call virtio_dev_probe(). */ -static int virtio_dev_match(struct device *_dv, struct device_driver *_dr) +static int virtio_dev_match(struct device *_dv, const struct device_driver *_dr) { unsigned int i; struct virtio_device *dev = dev_to_virtio(_dv); diff --git a/drivers/xen/xenbus/xenbus.h b/drivers/xen/xenbus/xenbus.h index 2754bdfadcb8..13821e7e825e 100644 --- a/drivers/xen/xenbus/xenbus.h +++ b/drivers/xen/xenbus/xenbus.h @@ -104,7 +104,7 @@ void xb_deinit_comms(void); int xs_watch_msg(struct xs_watch_event *event); void xs_request_exit(struct xb_req_data *req); -int xenbus_match(struct device *_dev, struct device_driver *_drv); +int xenbus_match(struct device *_dev, const struct device_driver *_drv); int xenbus_dev_probe(struct device *_dev); void xenbus_dev_remove(struct device *_dev); int xenbus_register_driver_common(struct xenbus_driver *drv, diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index 1a9ded0cddcb..9f097f1f4a4c 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c @@ -94,9 +94,9 @@ match_device(const struct xenbus_device_id *arr, struct xenbus_device *dev) return NULL; } -int xenbus_match(struct device *_dev, struct device_driver *_drv) +int xenbus_match(struct device *_dev, const struct device_driver *_drv) { - struct xenbus_driver *drv = to_xenbus_driver(_drv); + const struct xenbus_driver *drv = to_xenbus_driver(_drv); if (!drv->ids) return 0; diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 1a4dfd7a1c4a..08d27a1a0072 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -562,7 +562,7 @@ static inline void *acpi_driver_data(struct acpi_device *d) } #define to_acpi_device(d) container_of(d, struct acpi_device, dev) -#define to_acpi_driver(d) container_of(d, struct acpi_driver, drv) +#define to_acpi_driver(d) container_of_const(d, struct acpi_driver, drv) static inline struct acpi_device *acpi_dev_parent(struct acpi_device *adev) { diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h index c82d56768101..ae70704bfa90 100644 --- a/include/linux/arm_ffa.h +++ b/include/linux/arm_ffa.h @@ -149,7 +149,7 @@ struct ffa_driver { struct device_driver driver; }; -#define to_ffa_driver(d) container_of(d, struct ffa_driver, driver) +#define to_ffa_driver(d) container_of_const(d, struct ffa_driver, driver) static inline void ffa_dev_set_drvdata(struct ffa_device *fdev, void *data) { diff --git a/include/linux/cdx/cdx_bus.h b/include/linux/cdx/cdx_bus.h index b57118aaa679..79bb80e56790 100644 --- a/include/linux/cdx/cdx_bus.h +++ b/include/linux/cdx/cdx_bus.h @@ -211,7 +211,7 @@ struct cdx_driver { }; #define to_cdx_driver(_drv) \ - container_of(_drv, struct cdx_driver, driver) + container_of_const(_drv, struct cdx_driver, driver) /* Macro to avoid include chaining to get THIS_MODULE */ #define cdx_driver_register(drv) \ diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h index 5ef4ec1c36c3..807831d6bf0f 100644 --- a/include/linux/device/bus.h +++ b/include/linux/device/bus.h @@ -81,7 +81,7 @@ struct bus_type { const struct attribute_group **dev_groups; const struct attribute_group **drv_groups; - int (*match)(struct device *dev, struct device_driver *drv); + int (*match)(struct device *dev, const struct device_driver *drv); int (*uevent)(const struct device *dev, struct kobj_uevent_env *env); int (*probe)(struct device *dev); void (*sync_state)(struct device *dev); diff --git a/include/linux/dfl.h b/include/linux/dfl.h index 0a7a00a0ee7f..1f02db0c1897 100644 --- a/include/linux/dfl.h +++ b/include/linux/dfl.h @@ -71,7 +71,7 @@ struct dfl_driver { }; #define to_dfl_dev(d) container_of(d, struct dfl_device, dev) -#define to_dfl_drv(d) container_of(d, struct dfl_driver, drv) +#define to_dfl_drv(d) container_of_const(d, struct dfl_driver, drv) /* * use a macro to avoid include chaining to get THIS_MODULE. diff --git a/include/linux/eisa.h b/include/linux/eisa.h index b012e30afebd..f98200cae637 100644 --- a/include/linux/eisa.h +++ b/include/linux/eisa.h @@ -60,7 +60,7 @@ struct eisa_driver { struct device_driver driver; }; -#define to_eisa_driver(drv) container_of(drv,struct eisa_driver, driver) +#define to_eisa_driver(drv) container_of_const(drv,struct eisa_driver, driver) /* These external functions are only available when EISA support is enabled. */ #ifdef CONFIG_EISA diff --git a/include/linux/fsi.h b/include/linux/fsi.h index 3df8c54868df..8c5eef808788 100644 --- a/include/linux/fsi.h +++ b/include/linux/fsi.h @@ -44,7 +44,7 @@ struct fsi_driver { }; #define to_fsi_dev(devp) container_of(devp, struct fsi_device, dev) -#define to_fsi_drv(drvp) container_of(drvp, struct fsi_driver, drv) +#define to_fsi_drv(drvp) container_of_const(drvp, struct fsi_driver, drv) extern int fsi_driver_register(struct fsi_driver *fsi_drv); extern void fsi_driver_unregister(struct fsi_driver *fsi_drv); diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h index a1b3de87a3d1..083c860fd28e 100644 --- a/include/linux/fsl/mc.h +++ b/include/linux/fsl/mc.h @@ -56,7 +56,7 @@ struct fsl_mc_driver { }; #define to_fsl_mc_driver(_drv) \ - container_of(_drv, struct fsl_mc_driver, driver) + container_of_const(_drv, struct fsl_mc_driver, driver) /** * enum fsl_mc_pool_type - Types of allocatable MC bus resources diff --git a/include/linux/gameport.h b/include/linux/gameport.h index 07e370113b2b..86d62fdafd7a 100644 --- a/include/linux/gameport.h +++ b/include/linux/gameport.h @@ -58,7 +58,7 @@ struct gameport_driver { bool ignore; }; -#define to_gameport_driver(d) container_of(d, struct gameport_driver, driver) +#define to_gameport_driver(d) container_of_const(d, struct gameport_driver, driver) int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mode); void gameport_close(struct gameport *gameport); diff --git a/include/linux/greybus.h b/include/linux/greybus.h index 634c9511cf78..4d58e27ceaf6 100644 --- a/include/linux/greybus.h +++ b/include/linux/greybus.h @@ -64,7 +64,7 @@ struct greybus_driver { struct device_driver driver; }; -#define to_greybus_driver(d) container_of(d, struct greybus_driver, driver) +#define to_greybus_driver(d) container_of_const(d, struct greybus_driver, driver) static inline void greybus_set_drvdata(struct gb_bundle *bundle, void *data) { diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 5e39baa7f6cb..22c22fb91042 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1330,11 +1330,7 @@ struct hv_device { #define device_to_hv_device(d) container_of_const(d, struct hv_device, device) - -static inline struct hv_driver *drv_to_hv_drv(struct device_driver *d) -{ - return container_of(d, struct hv_driver, driver); -} +#define drv_to_hv_drv(d) container_of_const(d, struct hv_driver, driver) static inline void hv_set_drvdata(struct hv_device *dev, void *data) { diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 9709537370ee..cde3de35a89f 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -304,7 +304,7 @@ struct i2c_driver { u32 flags; }; -#define to_i2c_driver(d) container_of(d, struct i2c_driver, driver) +#define to_i2c_driver(d) container_of_const(d, struct i2c_driver, driver) /** * struct i2c_client - represent an I2C slave device diff --git a/include/linux/i3c/device.h b/include/linux/i3c/device.h index e119f11948ef..0a8a44ac2f02 100644 --- a/include/linux/i3c/device.h +++ b/include/linux/i3c/device.h @@ -183,10 +183,7 @@ struct i3c_driver { const struct i3c_device_id *id_table; }; -static inline struct i3c_driver *drv_to_i3cdrv(struct device_driver *drv) -{ - return container_of(drv, struct i3c_driver, driver); -} +#define drv_to_i3cdrv(__drv) container_of_const(__drv, struct i3c_driver, driver) struct device *i3cdev_to_dev(struct i3c_device *i3cdev); diff --git a/include/linux/maple.h b/include/linux/maple.h index 9aae44efcfd4..3be4e567473c 100644 --- a/include/linux/maple.h +++ b/include/linux/maple.h @@ -97,7 +97,7 @@ int maple_add_packet(struct maple_device *mdev, u32 function, void maple_clear_dev(struct maple_device *mdev); #define to_maple_dev(n) container_of(n, struct maple_device, dev) -#define to_maple_driver(n) container_of(n, struct maple_driver, drv) +#define to_maple_driver(n) container_of_const(n, struct maple_driver, drv) #define maple_get_drvdata(d) dev_get_drvdata(&(d)->dev) #define maple_set_drvdata(d,p) dev_set_drvdata(&(d)->dev, (p)) diff --git a/include/linux/mcb.h b/include/linux/mcb.h index 0b971b24a804..4ab2691f51a6 100644 --- a/include/linux/mcb.h +++ b/include/linux/mcb.h @@ -94,10 +94,7 @@ struct mcb_driver { void (*shutdown)(struct mcb_device *mdev); }; -static inline struct mcb_driver *to_mcb_driver(struct device_driver *drv) -{ - return container_of(drv, struct mcb_driver, driver); -} +#define to_mcb_driver(__drv) container_of_const(__drv, struct mcb_driver, driver) static inline void *mcb_get_drvdata(struct mcb_device *dev) { diff --git a/include/linux/mdio.h b/include/linux/mdio.h index 68f8d2e970d4..efeca5bd7600 100644 --- a/include/linux/mdio.h +++ b/include/linux/mdio.h @@ -31,7 +31,7 @@ struct mdio_device { struct mii_bus *bus; char modalias[MDIO_NAME_SIZE]; - int (*bus_match)(struct device *dev, struct device_driver *drv); + int (*bus_match)(struct device *dev, const struct device_driver *drv); void (*device_free)(struct mdio_device *mdiodev); void (*device_remove)(struct mdio_device *mdiodev); @@ -57,11 +57,8 @@ struct mdio_driver_common { }; #define MDIO_DEVICE_FLAG_PHY 1 -static inline struct mdio_driver_common * -to_mdio_common_driver(const struct device_driver *driver) -{ - return container_of(driver, struct mdio_driver_common, driver); -} +#define to_mdio_common_driver(__drv_c) container_of_const(__drv_c, struct mdio_driver_common, \ + driver) /* struct mdio_driver: Generic MDIO driver */ struct mdio_driver { @@ -80,12 +77,8 @@ struct mdio_driver { void (*shutdown)(struct mdio_device *mdiodev); }; -static inline struct mdio_driver * -to_mdio_driver(const struct device_driver *driver) -{ - return container_of(to_mdio_common_driver(driver), struct mdio_driver, - mdiodrv); -} +#define to_mdio_driver(__drv_m) container_of_const(to_mdio_common_driver(__drv_m), \ + struct mdio_driver, mdiodrv) /* device driver data */ static inline void mdiodev_set_drvdata(struct mdio_device *mdio, void *data) @@ -105,7 +98,7 @@ void mdio_device_remove(struct mdio_device *mdiodev); void mdio_device_reset(struct mdio_device *mdiodev, int value); int mdio_driver_register(struct mdio_driver *drv); void mdio_driver_unregister(struct mdio_driver *drv); -int mdio_device_bus_match(struct device *dev, struct device_driver *drv); +int mdio_device_bus_match(struct device *dev, const struct device_driver *drv); static inline void mdio_device_get(struct mdio_device *mdiodev) { diff --git a/include/linux/mhi.h b/include/linux/mhi.h index b573f15762f8..ce1f9d737964 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -526,7 +526,7 @@ struct mhi_driver { struct device_driver driver; }; -#define to_mhi_driver(drv) container_of(drv, struct mhi_driver, driver) +#define to_mhi_driver(drv) container_of_const(drv, struct mhi_driver, driver) #define to_mhi_device(dev) container_of(dev, struct mhi_device, dev) /** diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 11bf3212f782..7b40fc8cbe77 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -221,7 +221,7 @@ struct mhi_ep_driver { }; #define to_mhi_ep_device(dev) container_of(dev, struct mhi_ep_device, dev) -#define to_mhi_ep_driver(drv) container_of(drv, struct mhi_ep_driver, driver) +#define to_mhi_ep_driver(drv) container_of_const(drv, struct mhi_ep_driver, driver) /* * module_mhi_ep_driver() - Helper macro for drivers that don't do diff --git a/include/linux/moxtet.h b/include/linux/moxtet.h index ac577699edfd..dfa4800306ee 100644 --- a/include/linux/moxtet.h +++ b/include/linux/moxtet.h @@ -61,13 +61,8 @@ struct moxtet_driver { struct device_driver driver; }; -static inline struct moxtet_driver * -to_moxtet_driver(struct device_driver *drv) -{ - if (!drv) - return NULL; - return container_of(drv, struct moxtet_driver, driver); -} +#define to_moxtet_driver(__drv) \ + ( __drv ? container_of_const(__drv, struct moxtet_driver, driver) : NULL ) extern int __moxtet_register_driver(struct module *owner, struct moxtet_driver *mdrv); diff --git a/include/linux/nd.h b/include/linux/nd.h index b9771ba1ef87..fa099e295f78 100644 --- a/include/linux/nd.h +++ b/include/linux/nd.h @@ -84,11 +84,7 @@ struct nd_device_driver { void (*notify)(struct device *dev, enum nvdimm_event event); }; -static inline struct nd_device_driver *to_nd_device_driver( - struct device_driver *drv) -{ - return container_of(drv, struct nd_device_driver, drv); -}; +#define to_nd_device_driver(__drv) container_of_const(__drv, struct nd_device_driver, drv) /** * struct nd_namespace_common - core infrastructure of a namespace diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h index adee6a1b35db..980a3c90a5ee 100644 --- a/include/linux/pci-epf.h +++ b/include/linux/pci-epf.h @@ -105,8 +105,7 @@ struct pci_epf_driver { const struct pci_epf_device_id *id_table; }; -#define to_pci_epf_driver(drv) (container_of((drv), struct pci_epf_driver, \ - driver)) +#define to_pci_epf_driver(drv) container_of_const((drv), struct pci_epf_driver, driver) /** * struct pci_epf_bar - represents the BAR of EPF device diff --git a/include/linux/pci.h b/include/linux/pci.h index cafc5ab1cbcb..aa1c3280b7d0 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -958,10 +958,8 @@ struct pci_driver { bool driver_managed_dma; }; -static inline struct pci_driver *to_pci_driver(struct device_driver *drv) -{ - return drv ? container_of(drv, struct pci_driver, driver) : NULL; -} +#define to_pci_driver(__drv) \ + ( __drv ? container_of_const(__drv, struct pci_driver, driver) : NULL ) /** * PCI_DEVICE - macro used to describe a specific PCI device diff --git a/include/linux/phy.h b/include/linux/phy.h index e6e83304558e..8237d5006a99 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -1179,7 +1179,7 @@ struct phy_driver { int (*led_polarity_set)(struct phy_device *dev, int index, unsigned long modes); }; -#define to_phy_driver(d) container_of(to_mdio_common_driver(d), \ +#define to_phy_driver(d) container_of_const(to_mdio_common_driver(d), \ struct phy_driver, mdiodrv) #define PHY_ANY_ID "MATCH ANY PHY" diff --git a/include/linux/pnp.h b/include/linux/pnp.h index 7f2ff95d2deb..b7a7158aaf65 100644 --- a/include/linux/pnp.h +++ b/include/linux/pnp.h @@ -383,7 +383,7 @@ struct pnp_driver { struct device_driver driver; }; -#define to_pnp_driver(drv) container_of(drv, struct pnp_driver, driver) +#define to_pnp_driver(drv) container_of_const(drv, struct pnp_driver, driver) struct pnp_card_driver { struct list_head global_list; diff --git a/include/linux/rio.h b/include/linux/rio.h index 2cd637268b4f..3c29f40f3c94 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h @@ -465,7 +465,7 @@ struct rio_driver { struct device_driver driver; }; -#define to_rio_driver(drv) container_of(drv,struct rio_driver, driver) +#define to_rio_driver(drv) container_of_const(drv,struct rio_driver, driver) union rio_pw_msg { struct { diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h index 3a9bb5b9a9e8..688466a0e816 100644 --- a/include/linux/scmi_protocol.h +++ b/include/linux/scmi_protocol.h @@ -945,7 +945,7 @@ struct scmi_device { struct scmi_handle *handle; }; -#define to_scmi_dev(d) container_of(d, struct scmi_device, dev) +#define to_scmi_dev(d) container_of_const(d, struct scmi_device, dev) struct scmi_device_id { u8 protocol_id; diff --git a/include/linux/serio.h b/include/linux/serio.h index 7ca41af93b37..bf2191f25350 100644 --- a/include/linux/serio.h +++ b/include/linux/serio.h @@ -80,7 +80,7 @@ struct serio_driver { struct device_driver driver; }; -#define to_serio_driver(d) container_of(d, struct serio_driver, driver) +#define to_serio_driver(d) container_of_const(d, struct serio_driver, driver) int serio_open(struct serio *serio, struct serio_driver *drv); void serio_close(struct serio *serio); diff --git a/include/linux/slimbus.h b/include/linux/slimbus.h index 3042385b7b40..a4608d9a9684 100644 --- a/include/linux/slimbus.h +++ b/include/linux/slimbus.h @@ -91,7 +91,7 @@ struct slim_driver { struct device_driver driver; const struct slim_device_id *id_table; }; -#define to_slim_driver(d) container_of(d, struct slim_driver, driver) +#define to_slim_driver(d) container_of_const(d, struct slim_driver, driver) /** * struct slim_val_inf - Slimbus value or information element diff --git a/include/linux/soc/qcom/apr.h b/include/linux/soc/qcom/apr.h index 7161a3183eda..a532d1e4b1f4 100644 --- a/include/linux/soc/qcom/apr.h +++ b/include/linux/soc/qcom/apr.h @@ -162,7 +162,7 @@ struct apr_driver { }; typedef struct apr_driver gpr_driver_t; -#define to_apr_driver(d) container_of(d, struct apr_driver, driver) +#define to_apr_driver(d) container_of_const(d, struct apr_driver, driver) /* * use a macro to avoid include chaining to get THIS_MODULE diff --git a/include/linux/soundwire/sdw_type.h b/include/linux/soundwire/sdw_type.h index 693320b4f5c2..d405935a45fe 100644 --- a/include/linux/soundwire/sdw_type.h +++ b/include/linux/soundwire/sdw_type.h @@ -13,7 +13,7 @@ static inline int is_sdw_slave(const struct device *dev) return dev->type == &sdw_slave_type; } -#define drv_to_sdw_driver(_drv) container_of(_drv, struct sdw_driver, driver) +#define drv_to_sdw_driver(_drv) container_of_const(_drv, struct sdw_driver, driver) #define sdw_register_driver(drv) \ __sdw_register_driver(drv, THIS_MODULE) diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index e8e1e798924f..3fc559686d38 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -351,10 +351,8 @@ struct spi_driver { struct device_driver driver; }; -static inline struct spi_driver *to_spi_driver(struct device_driver *drv) -{ - return drv ? container_of(drv, struct spi_driver, driver) : NULL; -} +#define to_spi_driver(__drv) \ + ( __drv ? container_of_const(__drv, struct spi_driver, driver) : NULL ) extern int __spi_register_driver(struct module *owner, struct spi_driver *sdrv); diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index a2257380c3f1..e1fb11e0f12c 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -325,7 +325,7 @@ struct ssb_driver { struct device_driver drv; }; -#define drv_to_ssb_drv(_drv) container_of(_drv, struct ssb_driver, drv) +#define drv_to_ssb_drv(_drv) container_of_const(_drv, struct ssb_driver, drv) extern int __ssb_driver_register(struct ssb_driver *drv, struct module *owner); #define ssb_driver_register(drv) \ diff --git a/include/linux/tc.h b/include/linux/tc.h index 1638660abf5e..8416bae9b126 100644 --- a/include/linux/tc.h +++ b/include/linux/tc.h @@ -108,7 +108,7 @@ struct tc_driver { struct device_driver driver; }; -#define to_tc_driver(drv) container_of(drv, struct tc_driver, driver) +#define to_tc_driver(drv) container_of_const(drv, struct tc_driver, driver) /* * Return TURBOchannel clock frequency in Hz. diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h index 786b9ae6cf4d..a54c203000ed 100644 --- a/include/linux/tee_drv.h +++ b/include/linux/tee_drv.h @@ -298,6 +298,6 @@ struct tee_client_driver { }; #define to_tee_client_driver(d) \ - container_of(d, struct tee_client_driver, driver) + container_of_const(d, struct tee_client_driver, driver) #endif /*__TEE_DRV_H*/ diff --git a/include/linux/virtio.h b/include/linux/virtio.h index 96fea920873b..ecc5cb7b8c91 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h @@ -209,10 +209,7 @@ struct virtio_driver { int (*restore)(struct virtio_device *dev); }; -static inline struct virtio_driver *drv_to_virtio(struct device_driver *drv) -{ - return container_of(drv, struct virtio_driver, driver); -} +#define drv_to_virtio(__drv) container_of_const(__drv, struct virtio_driver, driver) /* use a macro to avoid include chaining to get THIS_MODULE */ #define register_virtio_driver(drv) \ diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index fb3399e4cd29..bd1243657c01 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -495,7 +495,7 @@ iscsi_destroy_flashnode_sess(struct iscsi_bus_flash_session *fnode_sess); extern void iscsi_destroy_all_flashnode(struct Scsi_Host *shost); extern int iscsi_flashnode_bus_match(struct device *dev, - struct device_driver *drv); + const struct device_driver *drv); extern struct device * iscsi_find_flashnode_sess(struct Scsi_Host *shost, void *data, int (*fn)(struct device *dev, void *data)); diff --git a/include/sound/ac97/codec.h b/include/sound/ac97/codec.h index 2fc641cb1982..882b849b9255 100644 --- a/include/sound/ac97/codec.h +++ b/include/sound/ac97/codec.h @@ -73,10 +73,7 @@ static inline struct ac97_codec_device *to_ac97_device(struct device *d) return container_of(d, struct ac97_codec_device, dev); } -static inline struct ac97_codec_driver *to_ac97_driver(struct device_driver *d) -{ - return container_of(d, struct ac97_codec_driver, driver); -} +#define to_ac97_driver(__drv) container_of_const(__drv, struct ac97_codec_driver, driver) #if IS_ENABLED(CONFIG_AC97_BUS_NEW) int snd_ac97_codec_driver_register(struct ac97_codec_driver *drv); diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h index ac22cf08c09f..3f90bdd387b6 100644 --- a/include/xen/xenbus.h +++ b/include/xen/xenbus.h @@ -124,10 +124,7 @@ struct xenbus_driver { void (*reclaim_memory)(struct xenbus_device *dev); }; -static inline struct xenbus_driver *to_xenbus_driver(struct device_driver *drv) -{ - return container_of(drv, struct xenbus_driver, driver); -} +#define to_xenbus_driver(__drv) container_of_const(__drv, struct xenbus_driver, driver) int __must_check __xenbus_register_frontend(struct xenbus_driver *drv, struct module *owner, diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c index b7bf34a5eb37..1e42e13ad24e 100644 --- a/net/iucv/iucv.c +++ b/net/iucv/iucv.c @@ -62,7 +62,7 @@ #define IUCV_IPNORPY 0x10 #define IUCV_IPALL 0x80 -static int iucv_bus_match(struct device *dev, struct device_driver *drv) +static int iucv_bus_match(struct device *dev, const struct device_driver *drv) { return 0; } diff --git a/sound/ac97/bus.c b/sound/ac97/bus.c index 40e88d79c483..96d4d7eb879f 100644 --- a/sound/ac97/bus.c +++ b/sound/ac97/bus.c @@ -469,10 +469,10 @@ static struct attribute *ac97_dev_attrs[] = { }; ATTRIBUTE_GROUPS(ac97_dev); -static int ac97_bus_match(struct device *dev, struct device_driver *drv) +static int ac97_bus_match(struct device *dev, const struct device_driver *drv) { struct ac97_codec_device *adev = to_ac97_device(dev); - struct ac97_codec_driver *adrv = to_ac97_driver(drv); + const struct ac97_codec_driver *adrv = to_ac97_driver(drv); const struct ac97_id *id = adrv->id_table; int i = 0; diff --git a/sound/core/seq_device.c b/sound/core/seq_device.c index 654d620d0199..4492be5d2317 100644 --- a/sound/core/seq_device.c +++ b/sound/core/seq_device.c @@ -40,7 +40,7 @@ MODULE_LICENSE("GPL"); /* * bus definition */ -static int snd_seq_bus_match(struct device *dev, struct device_driver *drv) +static int snd_seq_bus_match(struct device *dev, const struct device_driver *drv) { struct snd_seq_device *sdev = to_seq_dev(dev); struct snd_seq_driver *sdrv = to_seq_drv(drv); @@ -234,7 +234,7 @@ int snd_seq_device_new(struct snd_card *card, int device, const char *id, put_device(&dev->dev); return err; } - + if (result) *result = dev; diff --git a/sound/hda/hda_bus_type.c b/sound/hda/hda_bus_type.c index cce2c30511a2..7545ace7b0ee 100644 --- a/sound/hda/hda_bus_type.c +++ b/sound/hda/hda_bus_type.c @@ -46,7 +46,7 @@ static int hdac_codec_match(struct hdac_device *dev, struct hdac_driver *drv) return 0; } -static int hda_bus_match(struct device *dev, struct device_driver *drv) +static int hda_bus_match(struct device *dev, const struct device_driver *drv) { struct hdac_device *hdev = dev_to_hdac_dev(dev); struct hdac_driver *hdrv = drv_to_hdac_driver(drv); From 23c6859677066fa3d6bb3672703636dd673cb5dd Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 6 Jun 2024 19:49:26 +0300 Subject: [PATCH 42/55] driver core: platform: Switch to use kmemdup_array() Let the kememdup_array() take care about multiplication and possible overflows. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20240606164926.3031358-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 8a511fe47bdb..4c3ee6521ba5 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -608,7 +608,7 @@ int platform_device_add_resources(struct platform_device *pdev, struct resource *r = NULL; if (res) { - r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL); + r = kmemdup_array(res, num, sizeof(*r), GFP_KERNEL); if (!r) return -ENOMEM; } From c884e3249f753dcef7a2b2023541ac1dc46b318e Mon Sep 17 00:00:00 2001 From: Zijun Hu Date: Tue, 2 Jul 2024 22:51:50 +0800 Subject: [PATCH 43/55] devres: Fix devm_krealloc() wasting memory Driver API devm_krealloc() calls alloc_dr() with wrong argument @total_new_size, so causes more memory to be allocated than required fix this memory waste by using @new_size as the argument for alloc_dr(). Fixes: f82485722e5d ("devres: provide devm_krealloc()") Cc: stable@vger.kernel.org Signed-off-by: Zijun Hu Link: https://lore.kernel.org/r/1719931914-19035-2-git-send-email-quic_zijuhu@quicinc.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/devres.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/base/devres.c b/drivers/base/devres.c index 3df0025d12aa..ff2247eec43c 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -896,9 +896,12 @@ void *devm_krealloc(struct device *dev, void *ptr, size_t new_size, gfp_t gfp) /* * Otherwise: allocate new, larger chunk. We need to allocate before * taking the lock as most probably the caller uses GFP_KERNEL. + * alloc_dr() will call check_dr_size() to reserve extra memory + * for struct devres automatically, so size @new_size user request + * is delivered to it directly as devm_kmalloc() does. */ new_dr = alloc_dr(devm_kmalloc_release, - total_new_size, gfp, dev_to_node(dev)); + new_size, gfp, dev_to_node(dev)); if (!new_dr) return NULL; From bd50a974097bb82d52a458bd3ee39fb723129a0c Mon Sep 17 00:00:00 2001 From: Zijun Hu Date: Tue, 2 Jul 2024 22:51:51 +0800 Subject: [PATCH 44/55] devres: Fix memory leakage caused by driver API devm_free_percpu() It will cause memory leakage when use driver API devm_free_percpu() to free memory allocated by devm_alloc_percpu(), fixed by using devres_release() instead of devres_destroy() within devm_free_percpu(). Fixes: ff86aae3b411 ("devres: add devm_alloc_percpu()") Cc: stable@vger.kernel.org Signed-off-by: Zijun Hu Link: https://lore.kernel.org/r/1719931914-19035-3-git-send-email-quic_zijuhu@quicinc.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/devres.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/base/devres.c b/drivers/base/devres.c index ff2247eec43c..8d709dbd4e0c 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -1225,7 +1225,11 @@ EXPORT_SYMBOL_GPL(__devm_alloc_percpu); */ void devm_free_percpu(struct device *dev, void __percpu *pdata) { - WARN_ON(devres_destroy(dev, devm_percpu_release, devm_percpu_match, + /* + * Use devres_release() to prevent memory leakage as + * devm_free_pages() does. + */ + WARN_ON(devres_release(dev, devm_percpu_release, devm_percpu_match, (__force void *)pdata)); } EXPORT_SYMBOL_GPL(devm_free_percpu); From 56a20ad349b5c51909cf8810f7c79b288864ad33 Mon Sep 17 00:00:00 2001 From: Zijun Hu Date: Tue, 2 Jul 2024 22:51:52 +0800 Subject: [PATCH 45/55] devres: Initialize an uninitialized struct member Initialize an uninitialized struct member for driver API devres_open_group(). Signed-off-by: Zijun Hu Link: https://lore.kernel.org/r/1719931914-19035-4-git-send-email-quic_zijuhu@quicinc.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/devres.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/base/devres.c b/drivers/base/devres.c index 8d709dbd4e0c..e9b0d94aeabd 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -567,6 +567,7 @@ void * devres_open_group(struct device *dev, void *id, gfp_t gfp) grp->id = grp; if (id) grp->id = id; + grp->color = 0; spin_lock_irqsave(&dev->devres_lock, flags); add_dr(dev, &grp->node[0]); From 997197b58bf6e22b8c6ef88a168d8292fa9acec9 Mon Sep 17 00:00:00 2001 From: Zijun Hu Date: Tue, 2 Jul 2024 22:51:54 +0800 Subject: [PATCH 46/55] devres: Correct code style for functions that return a pointer type Correct code style for several functions that return a pointer type. Signed-off-by: Zijun Hu Link: https://lore.kernel.org/r/1719931914-19035-6-git-send-email-quic_zijuhu@quicinc.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/devres.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/base/devres.c b/drivers/base/devres.c index e9b0d94aeabd..a2ce0ead06a6 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -85,7 +85,7 @@ static void group_close_release(struct device *dev, void *res) /* noop */ } -static struct devres_group * node_to_group(struct devres_node *node) +static struct devres_group *node_to_group(struct devres_node *node) { if (node->release == &group_open_release) return container_of(node, struct devres_group, node[0]); @@ -107,8 +107,8 @@ static bool check_dr_size(size_t size, size_t *tot_size) return true; } -static __always_inline struct devres * alloc_dr(dr_release_t release, - size_t size, gfp_t gfp, int nid) +static __always_inline struct devres *alloc_dr(dr_release_t release, + size_t size, gfp_t gfp, int nid) { size_t tot_size; struct devres *dr; @@ -283,8 +283,8 @@ static struct devres *find_dr(struct device *dev, dr_release_t release, * RETURNS: * Pointer to found devres, NULL if not found. */ -void * devres_find(struct device *dev, dr_release_t release, - dr_match_t match, void *match_data) +void *devres_find(struct device *dev, dr_release_t release, + dr_match_t match, void *match_data) { struct devres *dr; unsigned long flags; @@ -313,8 +313,8 @@ EXPORT_SYMBOL_GPL(devres_find); * RETURNS: * Pointer to found or added devres. */ -void * devres_get(struct device *dev, void *new_res, - dr_match_t match, void *match_data) +void *devres_get(struct device *dev, void *new_res, + dr_match_t match, void *match_data) { struct devres *new_dr = container_of(new_res, struct devres, data); struct devres *dr; @@ -349,8 +349,8 @@ EXPORT_SYMBOL_GPL(devres_get); * RETURNS: * Pointer to removed devres on success, NULL if not found. */ -void * devres_remove(struct device *dev, dr_release_t release, - dr_match_t match, void *match_data) +void *devres_remove(struct device *dev, dr_release_t release, + dr_match_t match, void *match_data) { struct devres *dr; unsigned long flags; @@ -549,7 +549,7 @@ int devres_release_all(struct device *dev) * RETURNS: * ID of the new group, NULL on failure. */ -void * devres_open_group(struct device *dev, void *id, gfp_t gfp) +void *devres_open_group(struct device *dev, void *id, gfp_t gfp) { struct devres_group *grp; unsigned long flags; @@ -577,7 +577,7 @@ void * devres_open_group(struct device *dev, void *id, gfp_t gfp) EXPORT_SYMBOL_GPL(devres_open_group); /* Find devres group with ID @id. If @id is NULL, look for the latest. */ -static struct devres_group * find_group(struct device *dev, void *id) +static struct devres_group *find_group(struct device *dev, void *id) { struct devres_node *node; From 2c61b8c51d21d1b10c2881aa9c9918ff49f6fb7d Mon Sep 17 00:00:00 2001 From: Danilo Krummrich Date: Mon, 8 Jul 2024 22:07:20 +0200 Subject: [PATCH 47/55] firmware_loader: annotate doctests as `no_run` The doctests of `Firmware` are compile-time only tests, since they require a proper `Device` and a valid path to a (firmware) blob in order to do something sane on runtime - we can't satisfy both of those requirements. Hence, configure the example as `no_run`. Unfortunately, the kernel's Rust build system can't consider the `no_run` attribute yet. Hence, for the meantime, wrap the example code into a new function and never actually call it. Fixes: de6582833db0 ("rust: add firmware abstractions") Signed-off-by: Danilo Krummrich Link: https://lore.kernel.org/r/20240708200724.3203-1-dakr@redhat.com Signed-off-by: Greg Kroah-Hartman --- rust/kernel/firmware.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/rust/kernel/firmware.rs b/rust/kernel/firmware.rs index 386c8fb44785..106a928a535e 100644 --- a/rust/kernel/firmware.rs +++ b/rust/kernel/firmware.rs @@ -26,14 +26,18 @@ type FwFunc = /// /// # Examples /// -/// ``` +/// ```no_run /// # use kernel::{c_str, device::Device, firmware::Firmware}; /// +/// # fn no_run() -> Result<(), Error> { /// # // SAFETY: *NOT* safe, just for the example to get an `ARef` instance /// # let dev = unsafe { Device::from_raw(core::ptr::null_mut()) }; /// -/// let fw = Firmware::request(c_str!("path/to/firmware.bin"), &dev).unwrap(); +/// let fw = Firmware::request(c_str!("path/to/firmware.bin"), &dev)?; /// let blob = fw.data(); +/// +/// # Ok(()) +/// # } /// ``` pub struct Firmware(NonNull); From a23b018c3bf646274f02edd46bf448c20c826d94 Mon Sep 17 00:00:00 2001 From: Danilo Krummrich Date: Mon, 8 Jul 2024 22:07:21 +0200 Subject: [PATCH 48/55] firmware_loader: fix soundness issue in `request_internal` `request_internal` must be called with one of the following function pointers: request_firmware(), firmware_request_nowarn(), firmware_request_platform() or request_firmware_direct(). The previous `FwFunc` alias did not guarantee this, which is unsound. In order to fix this up, implement `FwFunc` as new type with a corresponding type invariant. Reported-by: Gary Guo Closes: https://lore.kernel.org/lkml/20240620143611.7995e0bb@eugeo/ Signed-off-by: Danilo Krummrich Reviewed-by: Christian Schrefl Link: https://lore.kernel.org/r/20240708200724.3203-2-dakr@redhat.com Signed-off-by: Greg Kroah-Hartman --- rust/kernel/firmware.rs | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/rust/kernel/firmware.rs b/rust/kernel/firmware.rs index 106a928a535e..2ba03af9f036 100644 --- a/rust/kernel/firmware.rs +++ b/rust/kernel/firmware.rs @@ -7,10 +7,23 @@ use crate::{bindings, device::Device, error::Error, error::Result, str::CStr}; use core::ptr::NonNull; -// One of the following: `bindings::request_firmware`, `bindings::firmware_request_nowarn`, -// `firmware_request_platform`, `bindings::request_firmware_direct` -type FwFunc = - unsafe extern "C" fn(*mut *const bindings::firmware, *const i8, *mut bindings::device) -> i32; +/// # Invariants +/// +/// One of the following: `bindings::request_firmware`, `bindings::firmware_request_nowarn`, +/// `bindings::firmware_request_platform`, `bindings::request_firmware_direct`. +struct FwFunc( + unsafe extern "C" fn(*mut *const bindings::firmware, *const i8, *mut bindings::device) -> i32, +); + +impl FwFunc { + fn request() -> Self { + Self(bindings::request_firmware) + } + + fn request_nowarn() -> Self { + Self(bindings::firmware_request_nowarn) + } +} /// Abstraction around a C `struct firmware`. /// @@ -48,7 +61,7 @@ impl Firmware { // SAFETY: `pfw` is a valid pointer to a NULL initialized `bindings::firmware` pointer. // `name` and `dev` are valid as by their type invariants. - let ret = unsafe { func(pfw as _, name.as_char_ptr(), dev.as_raw()) }; + let ret = unsafe { func.0(pfw as _, name.as_char_ptr(), dev.as_raw()) }; if ret != 0 { return Err(Error::from_errno(ret)); } @@ -60,13 +73,13 @@ impl Firmware { /// Send a firmware request and wait for it. See also `bindings::request_firmware`. pub fn request(name: &CStr, dev: &Device) -> Result { - Self::request_internal(name, dev, bindings::request_firmware) + Self::request_internal(name, dev, FwFunc::request()) } /// Send a request for an optional firmware module. See also /// `bindings::firmware_request_nowarn`. pub fn request_nowarn(name: &CStr, dev: &Device) -> Result { - Self::request_internal(name, dev, bindings::firmware_request_nowarn) + Self::request_internal(name, dev, FwFunc::request_nowarn()) } fn as_raw(&self) -> *mut bindings::firmware { From ab7a880263c30b1675850a584c206770f5545c2f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 8 Jul 2024 10:15:45 +0200 Subject: [PATCH 49/55] driver core: make driver_[create|remove]_file take a const * The functions driver_create_file() and driver_remove_file() do not modify the struct device_driver structure directly, so they are safe to be marked as a constant pointer type. Cc: "Rafael J. Wysocki" Link: https://lore.kernel.org/r/2024070844-volley-hatchling-c812@gregkh Signed-off-by: Greg Kroah-Hartman --- drivers/base/driver.c | 4 ++-- include/linux/device/driver.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 85b4c00df078..3eeafdb79d0e 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -173,7 +173,7 @@ EXPORT_SYMBOL_GPL(driver_find_device); * @drv: driver. * @attr: driver attribute descriptor. */ -int driver_create_file(struct device_driver *drv, +int driver_create_file(const struct device_driver *drv, const struct driver_attribute *attr) { int error; @@ -191,7 +191,7 @@ EXPORT_SYMBOL_GPL(driver_create_file); * @drv: driver. * @attr: driver attribute descriptor. */ -void driver_remove_file(struct device_driver *drv, +void driver_remove_file(const struct device_driver *drv, const struct driver_attribute *attr) { if (drv) diff --git a/include/linux/device/driver.h b/include/linux/device/driver.h index 7738f458995f..dceb36f1c42c 100644 --- a/include/linux/device/driver.h +++ b/include/linux/device/driver.h @@ -146,9 +146,9 @@ struct driver_attribute { #define DRIVER_ATTR_WO(_name) \ struct driver_attribute driver_attr_##_name = __ATTR_WO(_name) -int __must_check driver_create_file(struct device_driver *driver, +int __must_check driver_create_file(const struct device_driver *driver, const struct driver_attribute *attr); -void driver_remove_file(struct device_driver *driver, +void driver_remove_file(const struct device_driver *driver, const struct driver_attribute *attr); int driver_set_override(struct device *dev, const char **override, From f8fb469147e7db57e3f78d46f3f427705b4a1935 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 8 Jul 2024 10:15:46 +0200 Subject: [PATCH 50/55] driver core: make driver_find_device() take a const * The function driver_find_device() does not modify the struct device_driver structure directly, so it is safe to be marked as a constant pointer type. As that is fixed up, also change the function signature on the inline functions that call this, which are: driver_find_device_by_name() driver_find_device_by_of_node() driver_find_device_by_devt() driver_find_next_device() driver_find_device_by_acpi_dev() Cc: "Rafael J. Wysocki" Link: https://lore.kernel.org/r/2024070849-broken-front-9eb5@gregkh Signed-off-by: Greg Kroah-Hartman --- drivers/base/driver.c | 2 +- include/linux/device/driver.h | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 3eeafdb79d0e..88c6fd1f1992 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -148,7 +148,7 @@ EXPORT_SYMBOL_GPL(driver_for_each_device); * if it does. If the callback returns non-zero, this function will * return to the caller and not iterate over any more devices. */ -struct device *driver_find_device(struct device_driver *drv, +struct device *driver_find_device(const struct device_driver *drv, struct device *start, const void *data, int (*match)(struct device *dev, const void *data)) { diff --git a/include/linux/device/driver.h b/include/linux/device/driver.h index dceb36f1c42c..1fc8b68786de 100644 --- a/include/linux/device/driver.h +++ b/include/linux/device/driver.h @@ -155,7 +155,7 @@ int driver_set_override(struct device *dev, const char **override, const char *s, size_t len); int __must_check driver_for_each_device(struct device_driver *drv, struct device *start, void *data, int (*fn)(struct device *dev, void *)); -struct device *driver_find_device(struct device_driver *drv, +struct device *driver_find_device(const struct device_driver *drv, struct device *start, const void *data, int (*match)(struct device *dev, const void *data)); @@ -165,7 +165,7 @@ struct device *driver_find_device(struct device_driver *drv, * @drv: the driver we're iterating * @name: name of the device to match */ -static inline struct device *driver_find_device_by_name(struct device_driver *drv, +static inline struct device *driver_find_device_by_name(const struct device_driver *drv, const char *name) { return driver_find_device(drv, NULL, name, device_match_name); @@ -178,7 +178,7 @@ static inline struct device *driver_find_device_by_name(struct device_driver *dr * @np: of_node pointer to match. */ static inline struct device * -driver_find_device_by_of_node(struct device_driver *drv, +driver_find_device_by_of_node(const struct device_driver *drv, const struct device_node *np) { return driver_find_device(drv, NULL, np, device_match_of_node); @@ -203,13 +203,13 @@ driver_find_device_by_fwnode(struct device_driver *drv, * @drv: the driver we're iterating * @devt: devt pointer to match. */ -static inline struct device *driver_find_device_by_devt(struct device_driver *drv, +static inline struct device *driver_find_device_by_devt(const struct device_driver *drv, dev_t devt) { return driver_find_device(drv, NULL, &devt, device_match_devt); } -static inline struct device *driver_find_next_device(struct device_driver *drv, +static inline struct device *driver_find_next_device(const struct device_driver *drv, struct device *start) { return driver_find_device(drv, start, NULL, device_match_any); @@ -223,14 +223,14 @@ static inline struct device *driver_find_next_device(struct device_driver *drv, * @adev: ACPI_COMPANION device to match. */ static inline struct device * -driver_find_device_by_acpi_dev(struct device_driver *drv, +driver_find_device_by_acpi_dev(const struct device_driver *drv, const struct acpi_device *adev) { return driver_find_device(drv, NULL, adev, device_match_acpi_dev); } #else static inline struct device * -driver_find_device_by_acpi_dev(struct device_driver *drv, const void *adev) +driver_find_device_by_acpi_dev(const struct device_driver *drv, const void *adev) { return NULL; } From 67c1ba551eed771d18c48b7bf7e97379ad8f616d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 8 Jul 2024 10:15:47 +0200 Subject: [PATCH 51/55] driver core: module: make module_[add|remove]_driver take a const * The functions module_add_driver() and module_remove_driver() do not modify the struct device_driver structure directly, so they are safe to be marked as a constant pointer type. Cc: "Rafael J. Wysocki" Link: https://lore.kernel.org/r/2024070850-entering-grandson-205e@gregkh Signed-off-by: Greg Kroah-Hartman --- drivers/base/base.h | 4 ++-- drivers/base/module.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/base/base.h b/drivers/base/base.h index 0886f555d782..0b53593372d7 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -192,8 +192,8 @@ extern struct kset *devices_kset; void devices_kset_move_last(struct device *dev); #if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS) -int module_add_driver(struct module *mod, struct device_driver *drv); -void module_remove_driver(struct device_driver *drv); +int module_add_driver(struct module *mod, const struct device_driver *drv); +void module_remove_driver(const struct device_driver *drv); #else static inline int module_add_driver(struct module *mod, struct device_driver *drv) diff --git a/drivers/base/module.c b/drivers/base/module.c index a1b55da07127..7af224e6914a 100644 --- a/drivers/base/module.c +++ b/drivers/base/module.c @@ -9,7 +9,7 @@ #include #include "base.h" -static char *make_driver_name(struct device_driver *drv) +static char *make_driver_name(const struct device_driver *drv) { char *driver_name; @@ -30,7 +30,7 @@ static void module_create_drivers_dir(struct module_kobject *mk) mutex_unlock(&drivers_dir_mutex); } -int module_add_driver(struct module *mod, struct device_driver *drv) +int module_add_driver(struct module *mod, const struct device_driver *drv) { char *driver_name; struct module_kobject *mk = NULL; @@ -89,7 +89,7 @@ out: return ret; } -void module_remove_driver(struct device_driver *drv) +void module_remove_driver(const struct device_driver *drv) { struct module_kobject *mk = NULL; char *driver_name; From c9add2e607a1ca63cc84bd1a7ab04d513096f37e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 10 Jul 2024 09:34:14 +0200 Subject: [PATCH 52/55] zorro: make match function take a const pointer In commit d69d80484598 ("driver core: have match() callback in struct bus_type take a const *"), the match callback for busses was changed to take a const pointer to struct device_driver. Unfortunately I missed fixing up the zorro code, and was only noticed after-the-fact by the kernel test robot. Resolve this issue by properly changing the zorro_bus_match() function. Cc: Geert Uytterhoeven Fixes: d69d80484598 ("driver core: have match() callback in struct bus_type take a const *") Reported-by: kernel test robot Reviewed-by: Geert Uytterhoeven Acked-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20240710073413.495541-2-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/zorro/zorro-driver.c | 4 ++-- include/linux/zorro.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/zorro/zorro-driver.c b/drivers/zorro/zorro-driver.c index f49d19977e82..e7d3af1a223f 100644 --- a/drivers/zorro/zorro-driver.c +++ b/drivers/zorro/zorro-driver.c @@ -118,10 +118,10 @@ EXPORT_SYMBOL(zorro_unregister_driver); * supported, and 0 if there is no match. */ -static int zorro_bus_match(struct device *dev, struct device_driver *drv) +static int zorro_bus_match(struct device *dev, const struct device_driver *drv) { struct zorro_dev *z = to_zorro_dev(dev); - struct zorro_driver *zorro_drv = to_zorro_driver(drv); + const struct zorro_driver *zorro_drv = to_zorro_driver(drv); const struct zorro_device_id *ids = zorro_drv->id_table; if (!ids) diff --git a/include/linux/zorro.h b/include/linux/zorro.h index db7416ed6057..f36c8d39553d 100644 --- a/include/linux/zorro.h +++ b/include/linux/zorro.h @@ -52,7 +52,7 @@ struct zorro_driver { struct device_driver driver; }; -#define to_zorro_driver(drv) container_of(drv, struct zorro_driver, driver) +#define to_zorro_driver(drv) container_of_const(drv, struct zorro_driver, driver) #define zorro_for_each_dev(dev) \ From af46fe8c41de5b79358c3007e3854dda9c61c7dc Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 10 Jul 2024 09:44:52 +0200 Subject: [PATCH 53/55] dio: Have dio_bus_match() callback take a const * MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/dio/dio-driver.c:128:11: error: initialization of ‘int (*)(struct device *, const struct device_driver *)’ from incompatible pointer type ‘int (*)(struct device *, struct device_driver *)’ [-Werror=incompatible-pointer-types] 128 | .match = dio_bus_match, | ^~~~~~~~~~~~~ drivers/dio/dio-driver.c:128:11: note: (near initialization for ‘dio_bus_type.match’) Reported-by: noreply@ellerman.id.au Fixes: d69d804845985c29 ("driver core: have match() callback in struct bus_type take a const *") Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20240710074452.2841173-1-geert@linux-m68k.org [ added dio.h change - gregkh ] Signed-off-by: Greg Kroah-Hartman --- drivers/dio/dio-driver.c | 4 ++-- include/linux/dio.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/dio/dio-driver.c b/drivers/dio/dio-driver.c index 2d9fa6011945..12fa2d209dab 100644 --- a/drivers/dio/dio-driver.c +++ b/drivers/dio/dio-driver.c @@ -110,10 +110,10 @@ void dio_unregister_driver(struct dio_driver *drv) * and 0 if there is no match. */ -static int dio_bus_match(struct device *dev, struct device_driver *drv) +static int dio_bus_match(struct device *dev, const struct device_driver *drv) { struct dio_dev *d = to_dio_dev(dev); - struct dio_driver *dio_drv = to_dio_driver(drv); + const struct dio_driver *dio_drv = to_dio_driver(drv); const struct dio_device_id *ids = dio_drv->id_table; if (!ids) diff --git a/include/linux/dio.h b/include/linux/dio.h index 2b5923909f96..464331c4c4a7 100644 --- a/include/linux/dio.h +++ b/include/linux/dio.h @@ -93,7 +93,7 @@ struct dio_driver { struct device_driver driver; }; -#define to_dio_driver(drv) container_of(drv, struct dio_driver, driver) +#define to_dio_driver(drv) container_of_const(drv, struct dio_driver, driver) /* DIO/DIO-II boards all have the following 8bit registers. * These are offsets from the base of the device. From e777798e67d9ba46cf56ad49919c1e86c5ee3213 Mon Sep 17 00:00:00 2001 From: Petr Tesarik Date: Thu, 11 Jul 2024 12:34:09 +0200 Subject: [PATCH 54/55] sysfs/cpu: Make crash_hotplug attribute world-readable There is no reason to restrict access to this attribute, as it merely reports whether crash elfcorehdr is automatically updated on CPU hot plug/unplug and/or online/offline events. Note that since commit 79365026f8694 ("crash: add a new kexec flag for hotplug support"), this maps to the same flag which is world-accessible through /sys/devices/system/memory/crash_hotplug. Signed-off-by: Petr Tesarik Acked-by: Baoquan He Acked-by: Sourabh Jain Link: https://lore.kernel.org/r/20240711103409.319673-1-petr.tesarik@suse.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 4901fbfca326..9a77301640b0 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -308,7 +308,7 @@ static ssize_t crash_hotplug_show(struct device *dev, { return sysfs_emit(buf, "%d\n", crash_check_hotplug_support()); } -static DEVICE_ATTR_ADMIN_RO(crash_hotplug); +static DEVICE_ATTR_RO(crash_hotplug); #endif static void cpu_device_release(struct device *dev) From b57d5ffc3ab507d0e19fc8b90b19c76af43fb790 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 12 Jul 2024 11:39:17 +0200 Subject: [PATCH 55/55] ARM: sa1100: make match function take a const pointer In commit d69d80484598 ("driver core: have match() callback in struct bus_type take a const *"), the match callback for busses was changed to take a const pointer to struct device_driver. Unfortunately I missed fixing up the sa1111 code, and was only noticed after-the-fact by the kernel test robot. Resolve this issue by properly changing the sa111_match() function. Cc: Russell King Fixes: d69d80484598 ("driver core: have match() callback in struct bus_type take a const *") Reported-by: kernel test robot Link: https://lore.kernel.org/r/20240712093916.2121096-2-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- arch/arm/common/sa1111.c | 4 ++-- arch/arm/include/asm/hardware/sa1111.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 1fbd7363cf11..550978dc3c50 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -1339,10 +1339,10 @@ EXPORT_SYMBOL_GPL(sa1111_get_irq); * We model this as a regular bus type, and hang devices directly * off this. */ -static int sa1111_match(struct device *_dev, struct device_driver *_drv) +static int sa1111_match(struct device *_dev, const struct device_driver *_drv) { struct sa1111_dev *dev = to_sa1111_device(_dev); - struct sa1111_driver *drv = SA1111_DRV(_drv); + const struct sa1111_driver *drv = SA1111_DRV(_drv); return !!(dev->devid & drv->devid); } diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h index d8c6f8a99dfa..a815f39b4243 100644 --- a/arch/arm/include/asm/hardware/sa1111.h +++ b/arch/arm/include/asm/hardware/sa1111.h @@ -404,7 +404,7 @@ struct sa1111_driver { void (*remove)(struct sa1111_dev *); }; -#define SA1111_DRV(_d) container_of((_d), struct sa1111_driver, drv) +#define SA1111_DRV(_d) container_of_const((_d), struct sa1111_driver, drv) #define SA1111_DRIVER_NAME(_sadev) ((_sadev)->dev.driver->name)