diff --git a/scripts/coccinelle/platform_driver_remove.cocci b/scripts/coccinelle/platform_driver_remove.cocci new file mode 100644 index 00000000..07e9884d --- /dev/null +++ b/scripts/coccinelle/platform_driver_remove.cocci @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// Options: --no-includes --include-headers --smpl-spacing + +@match1@ +identifier p, removefn; +@@ +struct platform_driver p = { + .remove = removefn, +}; + +@match2@ +identifier p, removefn; +@@ +struct platform_driver p = { + .remove = __exit_p(removefn), +}; + +@match3@ +@@ +#include + +@fix1 depends on match1@ +identifier match1.p; +identifier match1.removefn; +fresh identifier removefn_wrapper = removefn ## "_wrapper"; +@@ ++#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */ ++static inline void removefn_wrapper(struct platform_device *pdev) ++{ ++ removefn(pdev); ++} ++#else ++static inline int removefn_wrapper(struct platform_device *pdev) ++{ ++ return removefn(pdev); ++} ++#endif ++ +struct platform_driver p = { +- .remove = removefn, ++ .remove = removefn_wrapper, +}; + +@fix2 depends on match2@ +identifier match2.p; +identifier match2.removefn; +fresh identifier removefn_wrapper = removefn ## "_wrapper"; +@@ ++#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */ ++static inline void removefn_wrapper(struct platform_device *pdev) ++{ ++ removefn(pdev); ++} ++#else ++static inline int removefn_wrapper(struct platform_device *pdev) ++{ ++ return removefn(pdev); ++} ++#endif ++ +struct platform_driver p = { +- .remove = __exit_p(removefn), ++ .remove = __exit_p(removefn_wrapper), +}; + +@fix3 depends on (match1 || match2) && !match3@ +@@ ++#include ++ +#include <...> + +@fix4 depends on (match1 || match2) && (!match3 && !fix3)@ +@@ ++#include ++ +#include "..." diff --git a/scripts/conftest/Makefile b/scripts/conftest/Makefile index f587a51d..5aa8520b 100644 --- a/scripts/conftest/Makefile +++ b/scripts/conftest/Makefile @@ -165,6 +165,7 @@ NV_CONFTEST_FUNCTION_COMPILE_TESTS += pci_epf_alloc_space_has_epc_features_arg NV_CONFTEST_FUNCTION_COMPILE_TESTS += pci_epf_driver_struct_probe_has_id_arg NV_CONFTEST_FUNCTION_COMPILE_TESTS += pci_epc_irq_type_enum_present NV_CONFTEST_FUNCTION_COMPILE_TESTS += pci_irq_intx +NV_CONFTEST_FUNCTION_COMPILE_TESTS += platform_driver_struct_remove_returns_void NV_CONFTEST_FUNCTION_COMPILE_TESTS += register_shrinker_has_fmt_arg NV_CONFTEST_FUNCTION_COMPILE_TESTS += shrinker_alloc NV_CONFTEST_FUNCTION_COMPILE_TESTS += slab_mem_spread diff --git a/scripts/conftest/conftest.sh b/scripts/conftest/conftest.sh index 6f2f6399..442c6917 100755 --- a/scripts/conftest/conftest.sh +++ b/scripts/conftest/conftest.sh @@ -7733,6 +7733,24 @@ compile_test() { compile_check_conftest "$CODE" "NV_PCI_IRQ_INTX" "" "types" ;; + platform_driver_struct_remove_returns_void) + # + # Determine if the 'platform_driver' structure 'remove' function + # pointer returns void. + # + # Commit 0edb555a65d1 ("platform: Make platform_driver::remove() + # return void") update the platform_driver structure 'remove' + # callback to return void instead of int. + # + CODE=" + #include + void conftest_platform_driver_struct_remove_returns_void(struct platform_driver *driver) { + void (*fn)(struct platform_device *) = driver->remove; + }" + + compile_check_conftest "$CODE" "NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID" "" "types" + ;; + register_shrinker_has_fmt_arg) # # Determine if the 'register_shrinker' function