diff --git a/drivers/clk/sunxi/clk-mod0.c b/drivers/clk/sunxi/clk-mod0.c index ec8f5a1fca09..9d028aec58e5 100644 --- a/drivers/clk/sunxi/clk-mod0.c +++ b/drivers/clk/sunxi/clk-mod0.c @@ -128,7 +128,7 @@ static struct platform_driver sun4i_a10_mod0_clk_driver = { }, .probe = sun4i_a10_mod0_clk_probe, }; -module_platform_driver(sun4i_a10_mod0_clk_driver); +builtin_platform_driver(sun4i_a10_mod0_clk_driver); static const struct factors_data sun9i_a80_mod0_data __initconst = { .enable = 31, diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c index b0dac7d6ba31..9e231f52150c 100644 --- a/drivers/cpufreq/s5pv210-cpufreq.c +++ b/drivers/cpufreq/s5pv210-cpufreq.c @@ -659,4 +659,4 @@ static struct platform_driver s5pv210_cpufreq_platdrv = { }, .probe = s5pv210_cpufreq_probe, }; -module_platform_driver(s5pv210_cpufreq_platdrv); +builtin_platform_driver(s5pv210_cpufreq_platdrv); diff --git a/drivers/cpuidle/cpuidle-at91.c b/drivers/cpuidle/cpuidle-at91.c index f2446c78d87c..9c5853b6ca4a 100644 --- a/drivers/cpuidle/cpuidle-at91.c +++ b/drivers/cpuidle/cpuidle-at91.c @@ -62,5 +62,4 @@ static struct platform_driver at91_cpuidle_driver = { }, .probe = at91_cpuidle_probe, }; - -module_platform_driver(at91_cpuidle_driver); +builtin_platform_driver(at91_cpuidle_driver); diff --git a/drivers/cpuidle/cpuidle-calxeda.c b/drivers/cpuidle/cpuidle-calxeda.c index 9445e6cc02be..c13feec89ea1 100644 --- a/drivers/cpuidle/cpuidle-calxeda.c +++ b/drivers/cpuidle/cpuidle-calxeda.c @@ -75,5 +75,4 @@ static struct platform_driver calxeda_cpuidle_plat_driver = { }, .probe = calxeda_cpuidle_probe, }; - -module_platform_driver(calxeda_cpuidle_plat_driver); +builtin_platform_driver(calxeda_cpuidle_plat_driver); diff --git a/drivers/cpuidle/cpuidle-zynq.c b/drivers/cpuidle/cpuidle-zynq.c index 543292b1d38e..6f4257fc56e5 100644 --- a/drivers/cpuidle/cpuidle-zynq.c +++ b/drivers/cpuidle/cpuidle-zynq.c @@ -73,5 +73,4 @@ static struct platform_driver zynq_cpuidle_driver = { }, .probe = zynq_cpuidle_probe, }; - -module_platform_driver(zynq_cpuidle_driver); +builtin_platform_driver(zynq_cpuidle_driver); diff --git a/drivers/platform/goldfish/pdev_bus.c b/drivers/platform/goldfish/pdev_bus.c index 8c43589c3edb..1f52462f4cdd 100644 --- a/drivers/platform/goldfish/pdev_bus.c +++ b/drivers/platform/goldfish/pdev_bus.c @@ -220,20 +220,10 @@ static int goldfish_pdev_bus_probe(struct platform_device *pdev) return ret; } -static int goldfish_pdev_bus_remove(struct platform_device *pdev) -{ - iounmap(pdev_bus_base); - free_irq(pdev_bus_irq, pdev); - release_mem_region(pdev_bus_addr, pdev_bus_len); - return 0; -} - static struct platform_driver goldfish_pdev_bus_driver = { .probe = goldfish_pdev_bus_probe, - .remove = goldfish_pdev_bus_remove, .driver = { .name = "goldfish_pdev_bus" } }; - -module_platform_driver(goldfish_pdev_bus_driver); +builtin_platform_driver(goldfish_pdev_bus_driver); diff --git a/drivers/power/reset/syscon-reboot.c b/drivers/power/reset/syscon-reboot.c index d3c7d245ae63..7d0d269a0837 100644 --- a/drivers/power/reset/syscon-reboot.c +++ b/drivers/power/reset/syscon-reboot.c @@ -88,4 +88,4 @@ static struct platform_driver syscon_reboot_driver = { .of_match_table = syscon_reboot_of_match, }, }; -module_platform_driver(syscon_reboot_driver); +builtin_platform_driver(syscon_reboot_driver); diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index cc119d15dd16..75d0457a77b7 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -1021,7 +1021,7 @@ static struct platform_driver tegra_pmc_driver = { }, .probe = tegra_pmc_probe, }; -module_platform_driver(tegra_pmc_driver); +builtin_platform_driver(tegra_pmc_driver); /* * Early initialization to allow access to registers in the very early boot diff --git a/drivers/soc/versatile/soc-realview.c b/drivers/soc/versatile/soc-realview.c index 1a07bf540fec..e642c4540dda 100644 --- a/drivers/soc/versatile/soc-realview.c +++ b/drivers/soc/versatile/soc-realview.c @@ -142,4 +142,4 @@ static struct platform_driver realview_soc_driver = { .of_match_table = realview_soc_of_match, }, }; -module_platform_driver(realview_soc_driver); +builtin_platform_driver(realview_soc_driver); diff --git a/include/linux/device.h b/include/linux/device.h index 00ac57c26615..5a31bf3a4024 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1300,4 +1300,26 @@ static void __exit __driver##_exit(void) \ } \ module_exit(__driver##_exit); +/** + * builtin_driver() - Helper macro for drivers that don't do anything + * special in init and have no exit. This eliminates some boilerplate. + * Each driver may only use this macro once, and calling it replaces + * device_initcall (or in some cases, the legacy __initcall). This is + * meant to be a direct parallel of module_driver() above but without + * the __exit stuff that is not used for builtin cases. + * + * @__driver: driver name + * @__register: register function for this driver type + * @...: Additional arguments to be passed to __register + * + * Use this macro to construct bus specific macros for registering + * drivers, and do not use it on its own. + */ +#define builtin_driver(__driver, __register, ...) \ +static int __init __driver##_init(void) \ +{ \ + return __register(&(__driver) , ##__VA_ARGS__); \ +} \ +device_initcall(__driver##_init); + #endif /* _DEVICE_H_ */ diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 58f1e75ba105..bba08f44cc97 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -222,6 +222,15 @@ static inline void platform_set_drvdata(struct platform_device *pdev, module_driver(__platform_driver, platform_driver_register, \ platform_driver_unregister) +/* builtin_platform_driver() - Helper macro for builtin drivers that + * don't do anything special in driver init. This eliminates some + * boilerplate. Each driver may only use this macro once, and + * calling it replaces device_initcall(). Note this is meant to be + * a parallel of module_platform_driver() above, but w/o _exit stuff. + */ +#define builtin_platform_driver(__platform_driver) \ + builtin_driver(__platform_driver, platform_driver_register) + /* module_platform_driver_probe() - Helper macro for drivers that don't do * anything special in module init/exit. This eliminates a lot of * boilerplate. Each module may only use this macro once, and @@ -240,6 +249,20 @@ static void __exit __platform_driver##_exit(void) \ } \ module_exit(__platform_driver##_exit); +/* builtin_platform_driver_probe() - Helper macro for drivers that don't do + * anything special in device init. This eliminates some boilerplate. Each + * driver may only use this macro once, and using it replaces device_initcall. + * This is meant to be a parallel of module_platform_driver_probe above, but + * without the __exit parts. + */ +#define builtin_platform_driver_probe(__platform_driver, __platform_probe) \ +static int __init __platform_driver##_init(void) \ +{ \ + return platform_driver_probe(&(__platform_driver), \ + __platform_probe); \ +} \ +device_initcall(__platform_driver##_init); \ + #define platform_create_bundle(driver, probe, res, n_res, data, size) \ __platform_create_bundle(driver, probe, res, n_res, data, size, THIS_MODULE) extern struct platform_device *__platform_create_bundle(