18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * BCM63xx Power Domain Controller Driver
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2020 Álvaro Fernández Rojas <noltari@gmail.com>
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <dt-bindings/soc/bcm6318-pm.h>
98c2ecf20Sopenharmony_ci#include <dt-bindings/soc/bcm6328-pm.h>
108c2ecf20Sopenharmony_ci#include <dt-bindings/soc/bcm6362-pm.h>
118c2ecf20Sopenharmony_ci#include <dt-bindings/soc/bcm63268-pm.h>
128c2ecf20Sopenharmony_ci#include <linux/io.h>
138c2ecf20Sopenharmony_ci#include <linux/module.h>
148c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
158c2ecf20Sopenharmony_ci#include <linux/pm_domain.h>
168c2ecf20Sopenharmony_ci#include <linux/of.h>
178c2ecf20Sopenharmony_ci#include <linux/of_device.h>
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_cistruct bcm63xx_power_dev {
208c2ecf20Sopenharmony_ci	struct generic_pm_domain genpd;
218c2ecf20Sopenharmony_ci	struct bcm63xx_power *power;
228c2ecf20Sopenharmony_ci	uint32_t mask;
238c2ecf20Sopenharmony_ci};
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_cistruct bcm63xx_power {
268c2ecf20Sopenharmony_ci	void __iomem *base;
278c2ecf20Sopenharmony_ci	spinlock_t lock;
288c2ecf20Sopenharmony_ci	struct bcm63xx_power_dev *dev;
298c2ecf20Sopenharmony_ci	struct genpd_onecell_data genpd_data;
308c2ecf20Sopenharmony_ci	struct generic_pm_domain **genpd;
318c2ecf20Sopenharmony_ci};
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_cistruct bcm63xx_power_data {
348c2ecf20Sopenharmony_ci	const char * const name;
358c2ecf20Sopenharmony_ci	uint8_t bit;
368c2ecf20Sopenharmony_ci	unsigned int flags;
378c2ecf20Sopenharmony_ci};
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_cistatic int bcm63xx_power_get_state(struct bcm63xx_power_dev *pmd, bool *is_on)
408c2ecf20Sopenharmony_ci{
418c2ecf20Sopenharmony_ci	struct bcm63xx_power *power = pmd->power;
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci	if (!pmd->mask) {
448c2ecf20Sopenharmony_ci		*is_on = false;
458c2ecf20Sopenharmony_ci		return -EINVAL;
468c2ecf20Sopenharmony_ci	}
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci	*is_on = !(__raw_readl(power->base) & pmd->mask);
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci	return 0;
518c2ecf20Sopenharmony_ci}
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_cistatic int bcm63xx_power_set_state(struct bcm63xx_power_dev *pmd, bool on)
548c2ecf20Sopenharmony_ci{
558c2ecf20Sopenharmony_ci	struct bcm63xx_power *power = pmd->power;
568c2ecf20Sopenharmony_ci	unsigned long flags;
578c2ecf20Sopenharmony_ci	uint32_t val;
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	if (!pmd->mask)
608c2ecf20Sopenharmony_ci		return -EINVAL;
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	spin_lock_irqsave(&power->lock, flags);
638c2ecf20Sopenharmony_ci	val = __raw_readl(power->base);
648c2ecf20Sopenharmony_ci	if (on)
658c2ecf20Sopenharmony_ci		val &= ~pmd->mask;
668c2ecf20Sopenharmony_ci	else
678c2ecf20Sopenharmony_ci		val |= pmd->mask;
688c2ecf20Sopenharmony_ci	__raw_writel(val, power->base);
698c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&power->lock, flags);
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	return 0;
728c2ecf20Sopenharmony_ci}
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_cistatic int bcm63xx_power_on(struct generic_pm_domain *genpd)
758c2ecf20Sopenharmony_ci{
768c2ecf20Sopenharmony_ci	struct bcm63xx_power_dev *pmd = container_of(genpd,
778c2ecf20Sopenharmony_ci		struct bcm63xx_power_dev, genpd);
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ci	return bcm63xx_power_set_state(pmd, true);
808c2ecf20Sopenharmony_ci}
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_cistatic int bcm63xx_power_off(struct generic_pm_domain *genpd)
838c2ecf20Sopenharmony_ci{
848c2ecf20Sopenharmony_ci	struct bcm63xx_power_dev *pmd = container_of(genpd,
858c2ecf20Sopenharmony_ci		struct bcm63xx_power_dev, genpd);
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci	return bcm63xx_power_set_state(pmd, false);
888c2ecf20Sopenharmony_ci}
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_cistatic int bcm63xx_power_probe(struct platform_device *pdev)
918c2ecf20Sopenharmony_ci{
928c2ecf20Sopenharmony_ci	struct device *dev = &pdev->dev;
938c2ecf20Sopenharmony_ci	struct device_node *np = dev->of_node;
948c2ecf20Sopenharmony_ci	struct resource *res;
958c2ecf20Sopenharmony_ci	const struct bcm63xx_power_data *entry, *table;
968c2ecf20Sopenharmony_ci	struct bcm63xx_power *power;
978c2ecf20Sopenharmony_ci	unsigned int ndom;
988c2ecf20Sopenharmony_ci	uint8_t max_bit = 0;
998c2ecf20Sopenharmony_ci	int ret;
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci	power = devm_kzalloc(dev, sizeof(*power), GFP_KERNEL);
1028c2ecf20Sopenharmony_ci	if (!power)
1038c2ecf20Sopenharmony_ci		return -ENOMEM;
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1068c2ecf20Sopenharmony_ci	power->base = devm_ioremap_resource(&pdev->dev, res);
1078c2ecf20Sopenharmony_ci	if (IS_ERR(power->base))
1088c2ecf20Sopenharmony_ci		return PTR_ERR(power->base);
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci	table = of_device_get_match_data(dev);
1118c2ecf20Sopenharmony_ci	if (!table)
1128c2ecf20Sopenharmony_ci		return -EINVAL;
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci	power->genpd_data.num_domains = 0;
1158c2ecf20Sopenharmony_ci	ndom = 0;
1168c2ecf20Sopenharmony_ci	for (entry = table; entry->name; entry++) {
1178c2ecf20Sopenharmony_ci		max_bit = max(max_bit, entry->bit);
1188c2ecf20Sopenharmony_ci		ndom++;
1198c2ecf20Sopenharmony_ci	}
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ci	if (!ndom)
1228c2ecf20Sopenharmony_ci		return -ENODEV;
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci	power->genpd_data.num_domains = max_bit + 1;
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci	power->dev = devm_kcalloc(dev, power->genpd_data.num_domains,
1278c2ecf20Sopenharmony_ci				  sizeof(struct bcm63xx_power_dev),
1288c2ecf20Sopenharmony_ci				  GFP_KERNEL);
1298c2ecf20Sopenharmony_ci	if (!power->dev)
1308c2ecf20Sopenharmony_ci		return -ENOMEM;
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ci	power->genpd = devm_kcalloc(dev, power->genpd_data.num_domains,
1338c2ecf20Sopenharmony_ci				    sizeof(struct generic_pm_domain *),
1348c2ecf20Sopenharmony_ci				    GFP_KERNEL);
1358c2ecf20Sopenharmony_ci	if (!power->genpd)
1368c2ecf20Sopenharmony_ci		return -ENOMEM;
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci	power->genpd_data.domains = power->genpd;
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci	ndom = 0;
1418c2ecf20Sopenharmony_ci	for (entry = table; entry->name; entry++) {
1428c2ecf20Sopenharmony_ci		struct bcm63xx_power_dev *pmd = &power->dev[ndom];
1438c2ecf20Sopenharmony_ci		bool is_on;
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci		pmd->power = power;
1468c2ecf20Sopenharmony_ci		pmd->mask = BIT(entry->bit);
1478c2ecf20Sopenharmony_ci		pmd->genpd.name = entry->name;
1488c2ecf20Sopenharmony_ci		pmd->genpd.flags = entry->flags;
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci		ret = bcm63xx_power_get_state(pmd, &is_on);
1518c2ecf20Sopenharmony_ci		if (ret)
1528c2ecf20Sopenharmony_ci			dev_warn(dev, "unable to get current state for %s\n",
1538c2ecf20Sopenharmony_ci				 pmd->genpd.name);
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_ci		pmd->genpd.power_on = bcm63xx_power_on;
1568c2ecf20Sopenharmony_ci		pmd->genpd.power_off = bcm63xx_power_off;
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci		pm_genpd_init(&pmd->genpd, NULL, !is_on);
1598c2ecf20Sopenharmony_ci		power->genpd[entry->bit] = &pmd->genpd;
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci		ndom++;
1628c2ecf20Sopenharmony_ci	}
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ci	spin_lock_init(&power->lock);
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci	ret = of_genpd_add_provider_onecell(np, &power->genpd_data);
1678c2ecf20Sopenharmony_ci	if (ret) {
1688c2ecf20Sopenharmony_ci		dev_err(dev, "failed to register genpd driver: %d\n", ret);
1698c2ecf20Sopenharmony_ci		return ret;
1708c2ecf20Sopenharmony_ci	}
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci	dev_info(dev, "registered %u power domains\n", ndom);
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci	return 0;
1758c2ecf20Sopenharmony_ci}
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_cistatic const struct bcm63xx_power_data bcm6318_power_domains[] = {
1788c2ecf20Sopenharmony_ci	{
1798c2ecf20Sopenharmony_ci		.name = "pcie",
1808c2ecf20Sopenharmony_ci		.bit = BCM6318_POWER_DOMAIN_PCIE,
1818c2ecf20Sopenharmony_ci	}, {
1828c2ecf20Sopenharmony_ci		.name = "usb",
1838c2ecf20Sopenharmony_ci		.bit = BCM6318_POWER_DOMAIN_USB,
1848c2ecf20Sopenharmony_ci	}, {
1858c2ecf20Sopenharmony_ci		.name = "ephy0",
1868c2ecf20Sopenharmony_ci		.bit = BCM6318_POWER_DOMAIN_EPHY0,
1878c2ecf20Sopenharmony_ci	}, {
1888c2ecf20Sopenharmony_ci		.name = "ephy1",
1898c2ecf20Sopenharmony_ci		.bit = BCM6318_POWER_DOMAIN_EPHY1,
1908c2ecf20Sopenharmony_ci	}, {
1918c2ecf20Sopenharmony_ci		.name = "ephy2",
1928c2ecf20Sopenharmony_ci		.bit = BCM6318_POWER_DOMAIN_EPHY2,
1938c2ecf20Sopenharmony_ci	}, {
1948c2ecf20Sopenharmony_ci		.name = "ephy3",
1958c2ecf20Sopenharmony_ci		.bit = BCM6318_POWER_DOMAIN_EPHY3,
1968c2ecf20Sopenharmony_ci	}, {
1978c2ecf20Sopenharmony_ci		.name = "ldo2p5",
1988c2ecf20Sopenharmony_ci		.bit = BCM6318_POWER_DOMAIN_LDO2P5,
1998c2ecf20Sopenharmony_ci		.flags = GENPD_FLAG_ALWAYS_ON,
2008c2ecf20Sopenharmony_ci	}, {
2018c2ecf20Sopenharmony_ci		.name = "ldo2p9",
2028c2ecf20Sopenharmony_ci		.bit = BCM6318_POWER_DOMAIN_LDO2P9,
2038c2ecf20Sopenharmony_ci		.flags = GENPD_FLAG_ALWAYS_ON,
2048c2ecf20Sopenharmony_ci	}, {
2058c2ecf20Sopenharmony_ci		.name = "sw1p0",
2068c2ecf20Sopenharmony_ci		.bit = BCM6318_POWER_DOMAIN_SW1P0,
2078c2ecf20Sopenharmony_ci		.flags = GENPD_FLAG_ALWAYS_ON,
2088c2ecf20Sopenharmony_ci	}, {
2098c2ecf20Sopenharmony_ci		.name = "pad",
2108c2ecf20Sopenharmony_ci		.bit = BCM6318_POWER_DOMAIN_PAD,
2118c2ecf20Sopenharmony_ci		.flags = GENPD_FLAG_ALWAYS_ON,
2128c2ecf20Sopenharmony_ci	}, {
2138c2ecf20Sopenharmony_ci		/* sentinel */
2148c2ecf20Sopenharmony_ci	},
2158c2ecf20Sopenharmony_ci};
2168c2ecf20Sopenharmony_ci
2178c2ecf20Sopenharmony_cistatic const struct bcm63xx_power_data bcm6328_power_domains[] = {
2188c2ecf20Sopenharmony_ci	{
2198c2ecf20Sopenharmony_ci		.name = "adsl2-mips",
2208c2ecf20Sopenharmony_ci		.bit = BCM6328_POWER_DOMAIN_ADSL2_MIPS,
2218c2ecf20Sopenharmony_ci	}, {
2228c2ecf20Sopenharmony_ci		.name = "adsl2-phy",
2238c2ecf20Sopenharmony_ci		.bit = BCM6328_POWER_DOMAIN_ADSL2_PHY,
2248c2ecf20Sopenharmony_ci	}, {
2258c2ecf20Sopenharmony_ci		.name = "adsl2-afe",
2268c2ecf20Sopenharmony_ci		.bit = BCM6328_POWER_DOMAIN_ADSL2_AFE,
2278c2ecf20Sopenharmony_ci	}, {
2288c2ecf20Sopenharmony_ci		.name = "sar",
2298c2ecf20Sopenharmony_ci		.bit = BCM6328_POWER_DOMAIN_SAR,
2308c2ecf20Sopenharmony_ci	}, {
2318c2ecf20Sopenharmony_ci		.name = "pcm",
2328c2ecf20Sopenharmony_ci		.bit = BCM6328_POWER_DOMAIN_PCM,
2338c2ecf20Sopenharmony_ci	}, {
2348c2ecf20Sopenharmony_ci		.name = "usbd",
2358c2ecf20Sopenharmony_ci		.bit = BCM6328_POWER_DOMAIN_USBD,
2368c2ecf20Sopenharmony_ci	}, {
2378c2ecf20Sopenharmony_ci		.name = "usbh",
2388c2ecf20Sopenharmony_ci		.bit = BCM6328_POWER_DOMAIN_USBH,
2398c2ecf20Sopenharmony_ci	}, {
2408c2ecf20Sopenharmony_ci		.name = "pcie",
2418c2ecf20Sopenharmony_ci		.bit = BCM6328_POWER_DOMAIN_PCIE,
2428c2ecf20Sopenharmony_ci	}, {
2438c2ecf20Sopenharmony_ci		.name = "robosw",
2448c2ecf20Sopenharmony_ci		.bit = BCM6328_POWER_DOMAIN_ROBOSW,
2458c2ecf20Sopenharmony_ci	}, {
2468c2ecf20Sopenharmony_ci		.name = "ephy",
2478c2ecf20Sopenharmony_ci		.bit = BCM6328_POWER_DOMAIN_EPHY,
2488c2ecf20Sopenharmony_ci	}, {
2498c2ecf20Sopenharmony_ci		/* sentinel */
2508c2ecf20Sopenharmony_ci	},
2518c2ecf20Sopenharmony_ci};
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_cistatic const struct bcm63xx_power_data bcm6362_power_domains[] = {
2548c2ecf20Sopenharmony_ci	{
2558c2ecf20Sopenharmony_ci		.name = "sar",
2568c2ecf20Sopenharmony_ci		.bit = BCM6362_POWER_DOMAIN_SAR,
2578c2ecf20Sopenharmony_ci	}, {
2588c2ecf20Sopenharmony_ci		.name = "ipsec",
2598c2ecf20Sopenharmony_ci		.bit = BCM6362_POWER_DOMAIN_IPSEC,
2608c2ecf20Sopenharmony_ci	}, {
2618c2ecf20Sopenharmony_ci		.name = "mips",
2628c2ecf20Sopenharmony_ci		.bit = BCM6362_POWER_DOMAIN_MIPS,
2638c2ecf20Sopenharmony_ci		.flags = GENPD_FLAG_ALWAYS_ON,
2648c2ecf20Sopenharmony_ci	}, {
2658c2ecf20Sopenharmony_ci		.name = "dect",
2668c2ecf20Sopenharmony_ci		.bit = BCM6362_POWER_DOMAIN_DECT,
2678c2ecf20Sopenharmony_ci	}, {
2688c2ecf20Sopenharmony_ci		.name = "usbh",
2698c2ecf20Sopenharmony_ci		.bit = BCM6362_POWER_DOMAIN_USBH,
2708c2ecf20Sopenharmony_ci	}, {
2718c2ecf20Sopenharmony_ci		.name = "usbd",
2728c2ecf20Sopenharmony_ci		.bit = BCM6362_POWER_DOMAIN_USBD,
2738c2ecf20Sopenharmony_ci	}, {
2748c2ecf20Sopenharmony_ci		.name = "robosw",
2758c2ecf20Sopenharmony_ci		.bit = BCM6362_POWER_DOMAIN_ROBOSW,
2768c2ecf20Sopenharmony_ci	}, {
2778c2ecf20Sopenharmony_ci		.name = "pcm",
2788c2ecf20Sopenharmony_ci		.bit = BCM6362_POWER_DOMAIN_PCM,
2798c2ecf20Sopenharmony_ci	}, {
2808c2ecf20Sopenharmony_ci		.name = "periph",
2818c2ecf20Sopenharmony_ci		.bit = BCM6362_POWER_DOMAIN_PERIPH,
2828c2ecf20Sopenharmony_ci		.flags = GENPD_FLAG_ALWAYS_ON,
2838c2ecf20Sopenharmony_ci	}, {
2848c2ecf20Sopenharmony_ci		.name = "adsl-phy",
2858c2ecf20Sopenharmony_ci		.bit = BCM6362_POWER_DOMAIN_ADSL_PHY,
2868c2ecf20Sopenharmony_ci	}, {
2878c2ecf20Sopenharmony_ci		.name = "gmii-pads",
2888c2ecf20Sopenharmony_ci		.bit = BCM6362_POWER_DOMAIN_GMII_PADS,
2898c2ecf20Sopenharmony_ci	}, {
2908c2ecf20Sopenharmony_ci		.name = "fap",
2918c2ecf20Sopenharmony_ci		.bit = BCM6362_POWER_DOMAIN_FAP,
2928c2ecf20Sopenharmony_ci	}, {
2938c2ecf20Sopenharmony_ci		.name = "pcie",
2948c2ecf20Sopenharmony_ci		.bit = BCM6362_POWER_DOMAIN_PCIE,
2958c2ecf20Sopenharmony_ci	}, {
2968c2ecf20Sopenharmony_ci		.name = "wlan-pads",
2978c2ecf20Sopenharmony_ci		.bit = BCM6362_POWER_DOMAIN_WLAN_PADS,
2988c2ecf20Sopenharmony_ci	}, {
2998c2ecf20Sopenharmony_ci		/* sentinel */
3008c2ecf20Sopenharmony_ci	},
3018c2ecf20Sopenharmony_ci};
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_cistatic const struct bcm63xx_power_data bcm63268_power_domains[] = {
3048c2ecf20Sopenharmony_ci	{
3058c2ecf20Sopenharmony_ci		.name = "sar",
3068c2ecf20Sopenharmony_ci		.bit = BCM63268_POWER_DOMAIN_SAR,
3078c2ecf20Sopenharmony_ci	}, {
3088c2ecf20Sopenharmony_ci		.name = "ipsec",
3098c2ecf20Sopenharmony_ci		.bit = BCM63268_POWER_DOMAIN_IPSEC,
3108c2ecf20Sopenharmony_ci	}, {
3118c2ecf20Sopenharmony_ci		.name = "mips",
3128c2ecf20Sopenharmony_ci		.bit = BCM63268_POWER_DOMAIN_MIPS,
3138c2ecf20Sopenharmony_ci		.flags = GENPD_FLAG_ALWAYS_ON,
3148c2ecf20Sopenharmony_ci	}, {
3158c2ecf20Sopenharmony_ci		.name = "dect",
3168c2ecf20Sopenharmony_ci		.bit = BCM63268_POWER_DOMAIN_DECT,
3178c2ecf20Sopenharmony_ci	}, {
3188c2ecf20Sopenharmony_ci		.name = "usbh",
3198c2ecf20Sopenharmony_ci		.bit = BCM63268_POWER_DOMAIN_USBH,
3208c2ecf20Sopenharmony_ci	}, {
3218c2ecf20Sopenharmony_ci		.name = "usbd",
3228c2ecf20Sopenharmony_ci		.bit = BCM63268_POWER_DOMAIN_USBD,
3238c2ecf20Sopenharmony_ci	}, {
3248c2ecf20Sopenharmony_ci		.name = "robosw",
3258c2ecf20Sopenharmony_ci		.bit = BCM63268_POWER_DOMAIN_ROBOSW,
3268c2ecf20Sopenharmony_ci	}, {
3278c2ecf20Sopenharmony_ci		.name = "pcm",
3288c2ecf20Sopenharmony_ci		.bit = BCM63268_POWER_DOMAIN_PCM,
3298c2ecf20Sopenharmony_ci	}, {
3308c2ecf20Sopenharmony_ci		.name = "periph",
3318c2ecf20Sopenharmony_ci		.bit = BCM63268_POWER_DOMAIN_PERIPH,
3328c2ecf20Sopenharmony_ci		.flags = GENPD_FLAG_ALWAYS_ON,
3338c2ecf20Sopenharmony_ci	}, {
3348c2ecf20Sopenharmony_ci		.name = "vdsl-phy",
3358c2ecf20Sopenharmony_ci		.bit = BCM63268_POWER_DOMAIN_VDSL_PHY,
3368c2ecf20Sopenharmony_ci	}, {
3378c2ecf20Sopenharmony_ci		.name = "vdsl-mips",
3388c2ecf20Sopenharmony_ci		.bit = BCM63268_POWER_DOMAIN_VDSL_MIPS,
3398c2ecf20Sopenharmony_ci	}, {
3408c2ecf20Sopenharmony_ci		.name = "fap",
3418c2ecf20Sopenharmony_ci		.bit = BCM63268_POWER_DOMAIN_FAP,
3428c2ecf20Sopenharmony_ci	}, {
3438c2ecf20Sopenharmony_ci		.name = "pcie",
3448c2ecf20Sopenharmony_ci		.bit = BCM63268_POWER_DOMAIN_PCIE,
3458c2ecf20Sopenharmony_ci	}, {
3468c2ecf20Sopenharmony_ci		.name = "wlan-pads",
3478c2ecf20Sopenharmony_ci		.bit = BCM63268_POWER_DOMAIN_WLAN_PADS,
3488c2ecf20Sopenharmony_ci	}, {
3498c2ecf20Sopenharmony_ci		/* sentinel */
3508c2ecf20Sopenharmony_ci	},
3518c2ecf20Sopenharmony_ci};
3528c2ecf20Sopenharmony_ci
3538c2ecf20Sopenharmony_cistatic const struct of_device_id bcm63xx_power_of_match[] = {
3548c2ecf20Sopenharmony_ci	{
3558c2ecf20Sopenharmony_ci		.compatible = "brcm,bcm6318-power-controller",
3568c2ecf20Sopenharmony_ci		.data = &bcm6318_power_domains,
3578c2ecf20Sopenharmony_ci	}, {
3588c2ecf20Sopenharmony_ci		.compatible = "brcm,bcm6328-power-controller",
3598c2ecf20Sopenharmony_ci		.data = &bcm6328_power_domains,
3608c2ecf20Sopenharmony_ci	}, {
3618c2ecf20Sopenharmony_ci		.compatible = "brcm,bcm6362-power-controller",
3628c2ecf20Sopenharmony_ci		.data = &bcm6362_power_domains,
3638c2ecf20Sopenharmony_ci	}, {
3648c2ecf20Sopenharmony_ci		.compatible = "brcm,bcm63268-power-controller",
3658c2ecf20Sopenharmony_ci		.data = &bcm63268_power_domains,
3668c2ecf20Sopenharmony_ci	}, {
3678c2ecf20Sopenharmony_ci		/* sentinel */
3688c2ecf20Sopenharmony_ci	}
3698c2ecf20Sopenharmony_ci};
3708c2ecf20Sopenharmony_ci
3718c2ecf20Sopenharmony_cistatic struct platform_driver bcm63xx_power_driver = {
3728c2ecf20Sopenharmony_ci	.driver = {
3738c2ecf20Sopenharmony_ci		.name = "bcm63xx-power-controller",
3748c2ecf20Sopenharmony_ci		.of_match_table = bcm63xx_power_of_match,
3758c2ecf20Sopenharmony_ci	},
3768c2ecf20Sopenharmony_ci	.probe  = bcm63xx_power_probe,
3778c2ecf20Sopenharmony_ci};
3788c2ecf20Sopenharmony_cibuiltin_platform_driver(bcm63xx_power_driver);
379