Commit 5e6acc3e authored by Eric Anholt's avatar Eric Anholt Committed by Stefan Wahren

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: default avatarEric Anholt <eric@anholt.net>
Reviewed-by: default avatarGuenter Roeck <linux@roeck-us.net>
Acked-by: default avatarStefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: default avatarStefan Wahren <stefan.wahren@i2se.com>
parent fbeab182
...@@ -167,6 +167,7 @@ config ARCH_BCM2835 ...@@ -167,6 +167,7 @@ config ARCH_BCM2835
select BCM2835_TIMER select BCM2835_TIMER
select PINCTRL select PINCTRL
select PINCTRL_BCM2835 select PINCTRL_BCM2835
select MFD_CORE
help help
This enables support for the Broadcom BCM2835 and BCM2836 SoCs. This enables support for the Broadcom BCM2835 and BCM2836 SoCs.
This SoC is used in the Raspberry Pi and Roku 2 devices. This SoC is used in the Raspberry Pi and Roku 2 devices.
......
...@@ -10,6 +10,7 @@ obj-$(CONFIG_MFD_88PM805) += 88pm805.o 88pm80x.o ...@@ -10,6 +10,7 @@ obj-$(CONFIG_MFD_88PM805) += 88pm805.o 88pm80x.o
obj-$(CONFIG_MFD_ACT8945A) += act8945a.o obj-$(CONFIG_MFD_ACT8945A) += act8945a.o
obj-$(CONFIG_MFD_SM501) += sm501.o obj-$(CONFIG_MFD_SM501) += sm501.o
obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o
obj-$(CONFIG_ARCH_BCM2835) += bcm2835-pm.o
obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o
obj-$(CONFIG_MFD_BD9571MWV) += bd9571mwv.o obj-$(CONFIG_MFD_BD9571MWV) += bd9571mwv.o
cros_ec_core-objs := cros_ec.o cros_ec_core-objs := cros_ec.o
......
// SPDX-License-Identifier: GPL-2.0+
/*
* PM MFD driver for Broadcom BCM2835
*
* This driver binds to the PM block and creates the MFD device for
* the WDT driver.
*/
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/mfd/bcm2835-pm.h>
#include <linux/mfd/core.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/watchdog.h>
static const struct mfd_cell bcm2835_pm_devs[] = {
{ .name = "bcm2835-wdt" },
};
static int bcm2835_pm_probe(struct platform_device *pdev)
{
struct resource *res;
struct device *dev = &pdev->dev;
struct bcm2835_pm *pm;
pm = devm_kzalloc(dev, sizeof(*pm), GFP_KERNEL);
if (!pm)
return -ENOMEM;
platform_set_drvdata(pdev, pm);
pm->dev = dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pm->base = devm_ioremap_resource(dev, res);
if (IS_ERR(pm->base))
return PTR_ERR(pm->base);
return devm_mfd_add_devices(dev, -1,
bcm2835_pm_devs, ARRAY_SIZE(bcm2835_pm_devs),
NULL, 0, NULL);
}
static const struct of_device_id bcm2835_pm_of_match[] = {
{ .compatible = "brcm,bcm2835-pm-wdt", },
{},
};
MODULE_DEVICE_TABLE(of, bcm2835_pm_of_match);
static struct platform_driver bcm2835_pm_driver = {
.probe = bcm2835_pm_probe,
.driver = {
.name = "bcm2835-pm",
.of_match_table = bcm2835_pm_of_match,
},
};
module_platform_driver(bcm2835_pm_driver);
MODULE_AUTHOR("Eric Anholt <eric@anholt.net>");
MODULE_DESCRIPTION("Driver for Broadcom BCM2835 PM MFD");
MODULE_LICENSE("GPL");
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/mfd/bcm2835-pm.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/watchdog.h> #include <linux/watchdog.h>
...@@ -47,6 +48,8 @@ struct bcm2835_wdt { ...@@ -47,6 +48,8 @@ struct bcm2835_wdt {
spinlock_t lock; spinlock_t lock;
}; };
static struct bcm2835_wdt *bcm2835_power_off_wdt;
static unsigned int heartbeat; static unsigned int heartbeat;
static bool nowayout = WATCHDOG_NOWAYOUT; static bool nowayout = WATCHDOG_NOWAYOUT;
...@@ -148,10 +151,7 @@ static struct watchdog_device bcm2835_wdt_wdd = { ...@@ -148,10 +151,7 @@ static struct watchdog_device bcm2835_wdt_wdd = {
*/ */
static void bcm2835_power_off(void) static void bcm2835_power_off(void)
{ {
struct device_node *np = struct bcm2835_wdt *wdt = bcm2835_power_off_wdt;
of_find_compatible_node(NULL, NULL, "brcm,bcm2835-pm-wdt");
struct platform_device *pdev = of_find_device_by_node(np);
struct bcm2835_wdt *wdt = platform_get_drvdata(pdev);
u32 val; u32 val;
/* /*
...@@ -169,7 +169,7 @@ static void bcm2835_power_off(void) ...@@ -169,7 +169,7 @@ static void bcm2835_power_off(void)
static int bcm2835_wdt_probe(struct platform_device *pdev) static int bcm2835_wdt_probe(struct platform_device *pdev)
{ {
struct resource *res; struct bcm2835_pm *pm = dev_get_drvdata(pdev->dev.parent);
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct bcm2835_wdt *wdt; struct bcm2835_wdt *wdt;
int err; int err;
...@@ -181,10 +181,7 @@ static int bcm2835_wdt_probe(struct platform_device *pdev) ...@@ -181,10 +181,7 @@ static int bcm2835_wdt_probe(struct platform_device *pdev)
spin_lock_init(&wdt->lock); spin_lock_init(&wdt->lock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdt->base = pm->base;
wdt->base = devm_ioremap_resource(dev, res);
if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base);
watchdog_set_drvdata(&bcm2835_wdt_wdd, wdt); watchdog_set_drvdata(&bcm2835_wdt_wdd, wdt);
watchdog_init_timeout(&bcm2835_wdt_wdd, heartbeat, dev); watchdog_init_timeout(&bcm2835_wdt_wdd, heartbeat, dev);
...@@ -211,8 +208,10 @@ static int bcm2835_wdt_probe(struct platform_device *pdev) ...@@ -211,8 +208,10 @@ static int bcm2835_wdt_probe(struct platform_device *pdev)
return err; return err;
} }
if (pm_power_off == NULL) if (pm_power_off == NULL) {
pm_power_off = bcm2835_power_off; pm_power_off = bcm2835_power_off;
bcm2835_power_off_wdt = wdt;
}
dev_info(dev, "Broadcom BCM2835 watchdog timer"); dev_info(dev, "Broadcom BCM2835 watchdog timer");
return 0; return 0;
...@@ -226,18 +225,11 @@ static int bcm2835_wdt_remove(struct platform_device *pdev) ...@@ -226,18 +225,11 @@ static int bcm2835_wdt_remove(struct platform_device *pdev)
return 0; return 0;
} }
static const struct of_device_id bcm2835_wdt_of_match[] = {
{ .compatible = "brcm,bcm2835-pm-wdt", },
{},
};
MODULE_DEVICE_TABLE(of, bcm2835_wdt_of_match);
static struct platform_driver bcm2835_wdt_driver = { static struct platform_driver bcm2835_wdt_driver = {
.probe = bcm2835_wdt_probe, .probe = bcm2835_wdt_probe,
.remove = bcm2835_wdt_remove, .remove = bcm2835_wdt_remove,
.driver = { .driver = {
.name = "bcm2835-wdt", .name = "bcm2835-wdt",
.of_match_table = bcm2835_wdt_of_match,
}, },
}; };
module_platform_driver(bcm2835_wdt_driver); module_platform_driver(bcm2835_wdt_driver);
......
/* SPDX-License-Identifier: GPL-2.0+ */
#ifndef BCM2835_MFD_PM_H
#define BCM2835_MFD_PM_H
#include <linux/regmap.h>
struct bcm2835_pm {
struct device *dev;
void __iomem *base;
};
#endif /* BCM2835_MFD_PM_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment