Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bcm2835-pm: Move bcm2835-watchdog's DT probe to an MFD.

The PM block that the wdt driver was binding to actually has multiple
features we want to expose (power domains, reset, watchdog). Move the
DT attachment to a MFD driver and make WDT probe against MFD.

Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Acked-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>

authored by

Eric Anholt and committed by
Stefan Wahren
5e6acc3e fbeab182

+88 -17
+1
arch/arm/mach-bcm/Kconfig
··· 167 167 select BCM2835_TIMER 168 168 select PINCTRL 169 169 select PINCTRL_BCM2835 170 + select MFD_CORE 170 171 help 171 172 This enables support for the Broadcom BCM2835 and BCM2836 SoCs. 172 173 This SoC is used in the Raspberry Pi and Roku 2 devices.
+1
drivers/mfd/Makefile
··· 10 10 obj-$(CONFIG_MFD_ACT8945A) += act8945a.o 11 11 obj-$(CONFIG_MFD_SM501) += sm501.o 12 12 obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o 13 + obj-$(CONFIG_ARCH_BCM2835) += bcm2835-pm.o 13 14 obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o 14 15 obj-$(CONFIG_MFD_BD9571MWV) += bd9571mwv.o 15 16 cros_ec_core-objs := cros_ec.o
+64
drivers/mfd/bcm2835-pm.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * PM MFD driver for Broadcom BCM2835 4 + * 5 + * This driver binds to the PM block and creates the MFD device for 6 + * the WDT driver. 7 + */ 8 + 9 + #include <linux/delay.h> 10 + #include <linux/io.h> 11 + #include <linux/mfd/bcm2835-pm.h> 12 + #include <linux/mfd/core.h> 13 + #include <linux/module.h> 14 + #include <linux/of_address.h> 15 + #include <linux/of_platform.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/types.h> 18 + #include <linux/watchdog.h> 19 + 20 + static const struct mfd_cell bcm2835_pm_devs[] = { 21 + { .name = "bcm2835-wdt" }, 22 + }; 23 + 24 + static int bcm2835_pm_probe(struct platform_device *pdev) 25 + { 26 + struct resource *res; 27 + struct device *dev = &pdev->dev; 28 + struct bcm2835_pm *pm; 29 + 30 + pm = devm_kzalloc(dev, sizeof(*pm), GFP_KERNEL); 31 + if (!pm) 32 + return -ENOMEM; 33 + platform_set_drvdata(pdev, pm); 34 + 35 + pm->dev = dev; 36 + 37 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 38 + pm->base = devm_ioremap_resource(dev, res); 39 + if (IS_ERR(pm->base)) 40 + return PTR_ERR(pm->base); 41 + 42 + return devm_mfd_add_devices(dev, -1, 43 + bcm2835_pm_devs, ARRAY_SIZE(bcm2835_pm_devs), 44 + NULL, 0, NULL); 45 + } 46 + 47 + static const struct of_device_id bcm2835_pm_of_match[] = { 48 + { .compatible = "brcm,bcm2835-pm-wdt", }, 49 + {}, 50 + }; 51 + MODULE_DEVICE_TABLE(of, bcm2835_pm_of_match); 52 + 53 + static struct platform_driver bcm2835_pm_driver = { 54 + .probe = bcm2835_pm_probe, 55 + .driver = { 56 + .name = "bcm2835-pm", 57 + .of_match_table = bcm2835_pm_of_match, 58 + }, 59 + }; 60 + module_platform_driver(bcm2835_pm_driver); 61 + 62 + MODULE_AUTHOR("Eric Anholt <eric@anholt.net>"); 63 + MODULE_DESCRIPTION("Driver for Broadcom BCM2835 PM MFD"); 64 + MODULE_LICENSE("GPL");
+9 -17
drivers/watchdog/bcm2835_wdt.c
··· 12 12 13 13 #include <linux/delay.h> 14 14 #include <linux/types.h> 15 + #include <linux/mfd/bcm2835-pm.h> 15 16 #include <linux/module.h> 16 17 #include <linux/io.h> 17 18 #include <linux/watchdog.h> ··· 47 46 void __iomem *base; 48 47 spinlock_t lock; 49 48 }; 49 + 50 + static struct bcm2835_wdt *bcm2835_power_off_wdt; 50 51 51 52 static unsigned int heartbeat; 52 53 static bool nowayout = WATCHDOG_NOWAYOUT; ··· 151 148 */ 152 149 static void bcm2835_power_off(void) 153 150 { 154 - struct device_node *np = 155 - of_find_compatible_node(NULL, NULL, "brcm,bcm2835-pm-wdt"); 156 - struct platform_device *pdev = of_find_device_by_node(np); 157 - struct bcm2835_wdt *wdt = platform_get_drvdata(pdev); 151 + struct bcm2835_wdt *wdt = bcm2835_power_off_wdt; 158 152 u32 val; 159 153 160 154 /* ··· 169 169 170 170 static int bcm2835_wdt_probe(struct platform_device *pdev) 171 171 { 172 - struct resource *res; 172 + struct bcm2835_pm *pm = dev_get_drvdata(pdev->dev.parent); 173 173 struct device *dev = &pdev->dev; 174 174 struct bcm2835_wdt *wdt; 175 175 int err; ··· 181 181 182 182 spin_lock_init(&wdt->lock); 183 183 184 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 185 - wdt->base = devm_ioremap_resource(dev, res); 186 - if (IS_ERR(wdt->base)) 187 - return PTR_ERR(wdt->base); 184 + wdt->base = pm->base; 188 185 189 186 watchdog_set_drvdata(&bcm2835_wdt_wdd, wdt); 190 187 watchdog_init_timeout(&bcm2835_wdt_wdd, heartbeat, dev); ··· 208 211 return err; 209 212 } 210 213 211 - if (pm_power_off == NULL) 214 + if (pm_power_off == NULL) { 212 215 pm_power_off = bcm2835_power_off; 216 + bcm2835_power_off_wdt = wdt; 217 + } 213 218 214 219 dev_info(dev, "Broadcom BCM2835 watchdog timer"); 215 220 return 0; ··· 225 226 return 0; 226 227 } 227 228 228 - static const struct of_device_id bcm2835_wdt_of_match[] = { 229 - { .compatible = "brcm,bcm2835-pm-wdt", }, 230 - {}, 231 - }; 232 - MODULE_DEVICE_TABLE(of, bcm2835_wdt_of_match); 233 - 234 229 static struct platform_driver bcm2835_wdt_driver = { 235 230 .probe = bcm2835_wdt_probe, 236 231 .remove = bcm2835_wdt_remove, 237 232 .driver = { 238 233 .name = "bcm2835-wdt", 239 - .of_match_table = bcm2835_wdt_of_match, 240 234 }, 241 235 }; 242 236 module_platform_driver(bcm2835_wdt_driver);
+13
include/linux/mfd/bcm2835-pm.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + 3 + #ifndef BCM2835_MFD_PM_H 4 + #define BCM2835_MFD_PM_H 5 + 6 + #include <linux/regmap.h> 7 + 8 + struct bcm2835_pm { 9 + struct device *dev; 10 + void __iomem *base; 11 + }; 12 + 13 + #endif /* BCM2835_MFD_PM_H */