bcm2835-pm.c (2264B)
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 and power drivers. 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 20static const struct mfd_cell bcm2835_pm_devs[] = { 21 { .name = "bcm2835-wdt" }, 22}; 23 24static const struct mfd_cell bcm2835_power_devs[] = { 25 { .name = "bcm2835-power" }, 26}; 27 28static int bcm2835_pm_probe(struct platform_device *pdev) 29{ 30 struct resource *res; 31 struct device *dev = &pdev->dev; 32 struct bcm2835_pm *pm; 33 int ret; 34 35 pm = devm_kzalloc(dev, sizeof(*pm), GFP_KERNEL); 36 if (!pm) 37 return -ENOMEM; 38 platform_set_drvdata(pdev, pm); 39 40 pm->dev = dev; 41 42 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 43 pm->base = devm_ioremap_resource(dev, res); 44 if (IS_ERR(pm->base)) 45 return PTR_ERR(pm->base); 46 47 ret = devm_mfd_add_devices(dev, -1, 48 bcm2835_pm_devs, ARRAY_SIZE(bcm2835_pm_devs), 49 NULL, 0, NULL); 50 if (ret) 51 return ret; 52 53 /* We'll use the presence of the AXI ASB regs in the 54 * bcm2835-pm binding as the key for whether we can reference 55 * the full PM register range and support power domains. 56 */ 57 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 58 if (res) { 59 pm->asb = devm_ioremap_resource(dev, res); 60 if (IS_ERR(pm->asb)) 61 return PTR_ERR(pm->asb); 62 63 ret = devm_mfd_add_devices(dev, -1, 64 bcm2835_power_devs, 65 ARRAY_SIZE(bcm2835_power_devs), 66 NULL, 0, NULL); 67 if (ret) 68 return ret; 69 } 70 71 return 0; 72} 73 74static const struct of_device_id bcm2835_pm_of_match[] = { 75 { .compatible = "brcm,bcm2835-pm-wdt", }, 76 { .compatible = "brcm,bcm2835-pm", }, 77 {}, 78}; 79MODULE_DEVICE_TABLE(of, bcm2835_pm_of_match); 80 81static struct platform_driver bcm2835_pm_driver = { 82 .probe = bcm2835_pm_probe, 83 .driver = { 84 .name = "bcm2835-pm", 85 .of_match_table = bcm2835_pm_of_match, 86 }, 87}; 88module_platform_driver(bcm2835_pm_driver); 89 90MODULE_AUTHOR("Eric Anholt <eric@anholt.net>"); 91MODULE_DESCRIPTION("Driver for Broadcom BCM2835 PM MFD"); 92MODULE_LICENSE("GPL");