1*e2ad626fSUlf Hansson // SPDX-License-Identifier: GPL-2.0-or-later
2*e2ad626fSUlf Hansson /*
3*e2ad626fSUlf Hansson  * BCM63xx Power Domain Controller Driver
4*e2ad626fSUlf Hansson  *
5*e2ad626fSUlf Hansson  * Copyright (C) 2020 Álvaro Fernández Rojas <noltari@gmail.com>
6*e2ad626fSUlf Hansson  */
7*e2ad626fSUlf Hansson 
8*e2ad626fSUlf Hansson #include <dt-bindings/soc/bcm6318-pm.h>
9*e2ad626fSUlf Hansson #include <dt-bindings/soc/bcm6328-pm.h>
10*e2ad626fSUlf Hansson #include <dt-bindings/soc/bcm6362-pm.h>
11*e2ad626fSUlf Hansson #include <dt-bindings/soc/bcm63268-pm.h>
12*e2ad626fSUlf Hansson #include <linux/io.h>
13*e2ad626fSUlf Hansson #include <linux/module.h>
14*e2ad626fSUlf Hansson #include <linux/platform_device.h>
15*e2ad626fSUlf Hansson #include <linux/pm_domain.h>
16*e2ad626fSUlf Hansson #include <linux/of.h>
17*e2ad626fSUlf Hansson 
18*e2ad626fSUlf Hansson struct bcm63xx_power_dev {
19*e2ad626fSUlf Hansson 	struct generic_pm_domain genpd;
20*e2ad626fSUlf Hansson 	struct bcm63xx_power *power;
21*e2ad626fSUlf Hansson 	uint32_t mask;
22*e2ad626fSUlf Hansson };
23*e2ad626fSUlf Hansson 
24*e2ad626fSUlf Hansson struct bcm63xx_power {
25*e2ad626fSUlf Hansson 	void __iomem *base;
26*e2ad626fSUlf Hansson 	spinlock_t lock;
27*e2ad626fSUlf Hansson 	struct bcm63xx_power_dev *dev;
28*e2ad626fSUlf Hansson 	struct genpd_onecell_data genpd_data;
29*e2ad626fSUlf Hansson 	struct generic_pm_domain **genpd;
30*e2ad626fSUlf Hansson };
31*e2ad626fSUlf Hansson 
32*e2ad626fSUlf Hansson struct bcm63xx_power_data {
33*e2ad626fSUlf Hansson 	const char * const name;
34*e2ad626fSUlf Hansson 	uint8_t bit;
35*e2ad626fSUlf Hansson 	unsigned int flags;
36*e2ad626fSUlf Hansson };
37*e2ad626fSUlf Hansson 
bcm63xx_power_get_state(struct bcm63xx_power_dev * pmd,bool * is_on)38*e2ad626fSUlf Hansson static int bcm63xx_power_get_state(struct bcm63xx_power_dev *pmd, bool *is_on)
39*e2ad626fSUlf Hansson {
40*e2ad626fSUlf Hansson 	struct bcm63xx_power *power = pmd->power;
41*e2ad626fSUlf Hansson 
42*e2ad626fSUlf Hansson 	if (!pmd->mask) {
43*e2ad626fSUlf Hansson 		*is_on = false;
44*e2ad626fSUlf Hansson 		return -EINVAL;
45*e2ad626fSUlf Hansson 	}
46*e2ad626fSUlf Hansson 
47*e2ad626fSUlf Hansson 	*is_on = !(__raw_readl(power->base) & pmd->mask);
48*e2ad626fSUlf Hansson 
49*e2ad626fSUlf Hansson 	return 0;
50*e2ad626fSUlf Hansson }
51*e2ad626fSUlf Hansson 
bcm63xx_power_set_state(struct bcm63xx_power_dev * pmd,bool on)52*e2ad626fSUlf Hansson static int bcm63xx_power_set_state(struct bcm63xx_power_dev *pmd, bool on)
53*e2ad626fSUlf Hansson {
54*e2ad626fSUlf Hansson 	struct bcm63xx_power *power = pmd->power;
55*e2ad626fSUlf Hansson 	unsigned long flags;
56*e2ad626fSUlf Hansson 	uint32_t val;
57*e2ad626fSUlf Hansson 
58*e2ad626fSUlf Hansson 	if (!pmd->mask)
59*e2ad626fSUlf Hansson 		return -EINVAL;
60*e2ad626fSUlf Hansson 
61*e2ad626fSUlf Hansson 	spin_lock_irqsave(&power->lock, flags);
62*e2ad626fSUlf Hansson 	val = __raw_readl(power->base);
63*e2ad626fSUlf Hansson 	if (on)
64*e2ad626fSUlf Hansson 		val &= ~pmd->mask;
65*e2ad626fSUlf Hansson 	else
66*e2ad626fSUlf Hansson 		val |= pmd->mask;
67*e2ad626fSUlf Hansson 	__raw_writel(val, power->base);
68*e2ad626fSUlf Hansson 	spin_unlock_irqrestore(&power->lock, flags);
69*e2ad626fSUlf Hansson 
70*e2ad626fSUlf Hansson 	return 0;
71*e2ad626fSUlf Hansson }
72*e2ad626fSUlf Hansson 
bcm63xx_power_on(struct generic_pm_domain * genpd)73*e2ad626fSUlf Hansson static int bcm63xx_power_on(struct generic_pm_domain *genpd)
74*e2ad626fSUlf Hansson {
75*e2ad626fSUlf Hansson 	struct bcm63xx_power_dev *pmd = container_of(genpd,
76*e2ad626fSUlf Hansson 		struct bcm63xx_power_dev, genpd);
77*e2ad626fSUlf Hansson 
78*e2ad626fSUlf Hansson 	return bcm63xx_power_set_state(pmd, true);
79*e2ad626fSUlf Hansson }
80*e2ad626fSUlf Hansson 
bcm63xx_power_off(struct generic_pm_domain * genpd)81*e2ad626fSUlf Hansson static int bcm63xx_power_off(struct generic_pm_domain *genpd)
82*e2ad626fSUlf Hansson {
83*e2ad626fSUlf Hansson 	struct bcm63xx_power_dev *pmd = container_of(genpd,
84*e2ad626fSUlf Hansson 		struct bcm63xx_power_dev, genpd);
85*e2ad626fSUlf Hansson 
86*e2ad626fSUlf Hansson 	return bcm63xx_power_set_state(pmd, false);
87*e2ad626fSUlf Hansson }
88*e2ad626fSUlf Hansson 
bcm63xx_power_probe(struct platform_device * pdev)89*e2ad626fSUlf Hansson static int bcm63xx_power_probe(struct platform_device *pdev)
90*e2ad626fSUlf Hansson {
91*e2ad626fSUlf Hansson 	struct device *dev = &pdev->dev;
92*e2ad626fSUlf Hansson 	struct device_node *np = dev->of_node;
93*e2ad626fSUlf Hansson 	const struct bcm63xx_power_data *entry, *table;
94*e2ad626fSUlf Hansson 	struct bcm63xx_power *power;
95*e2ad626fSUlf Hansson 	unsigned int ndom;
96*e2ad626fSUlf Hansson 	uint8_t max_bit = 0;
97*e2ad626fSUlf Hansson 	int ret;
98*e2ad626fSUlf Hansson 
99*e2ad626fSUlf Hansson 	power = devm_kzalloc(dev, sizeof(*power), GFP_KERNEL);
100*e2ad626fSUlf Hansson 	if (!power)
101*e2ad626fSUlf Hansson 		return -ENOMEM;
102*e2ad626fSUlf Hansson 
103*e2ad626fSUlf Hansson 	power->base = devm_platform_ioremap_resource(pdev, 0);
104*e2ad626fSUlf Hansson 	if (IS_ERR(power->base))
105*e2ad626fSUlf Hansson 		return PTR_ERR(power->base);
106*e2ad626fSUlf Hansson 
107*e2ad626fSUlf Hansson 	table = of_device_get_match_data(dev);
108*e2ad626fSUlf Hansson 	if (!table)
109*e2ad626fSUlf Hansson 		return -EINVAL;
110*e2ad626fSUlf Hansson 
111*e2ad626fSUlf Hansson 	power->genpd_data.num_domains = 0;
112*e2ad626fSUlf Hansson 	ndom = 0;
113*e2ad626fSUlf Hansson 	for (entry = table; entry->name; entry++) {
114*e2ad626fSUlf Hansson 		max_bit = max(max_bit, entry->bit);
115*e2ad626fSUlf Hansson 		ndom++;
116*e2ad626fSUlf Hansson 	}
117*e2ad626fSUlf Hansson 
118*e2ad626fSUlf Hansson 	if (!ndom)
119*e2ad626fSUlf Hansson 		return -ENODEV;
120*e2ad626fSUlf Hansson 
121*e2ad626fSUlf Hansson 	power->genpd_data.num_domains = max_bit + 1;
122*e2ad626fSUlf Hansson 
123*e2ad626fSUlf Hansson 	power->dev = devm_kcalloc(dev, power->genpd_data.num_domains,
124*e2ad626fSUlf Hansson 				  sizeof(struct bcm63xx_power_dev),
125*e2ad626fSUlf Hansson 				  GFP_KERNEL);
126*e2ad626fSUlf Hansson 	if (!power->dev)
127*e2ad626fSUlf Hansson 		return -ENOMEM;
128*e2ad626fSUlf Hansson 
129*e2ad626fSUlf Hansson 	power->genpd = devm_kcalloc(dev, power->genpd_data.num_domains,
130*e2ad626fSUlf Hansson 				    sizeof(struct generic_pm_domain *),
131*e2ad626fSUlf Hansson 				    GFP_KERNEL);
132*e2ad626fSUlf Hansson 	if (!power->genpd)
133*e2ad626fSUlf Hansson 		return -ENOMEM;
134*e2ad626fSUlf Hansson 
135*e2ad626fSUlf Hansson 	power->genpd_data.domains = power->genpd;
136*e2ad626fSUlf Hansson 
137*e2ad626fSUlf Hansson 	ndom = 0;
138*e2ad626fSUlf Hansson 	for (entry = table; entry->name; entry++) {
139*e2ad626fSUlf Hansson 		struct bcm63xx_power_dev *pmd = &power->dev[ndom];
140*e2ad626fSUlf Hansson 		bool is_on;
141*e2ad626fSUlf Hansson 
142*e2ad626fSUlf Hansson 		pmd->power = power;
143*e2ad626fSUlf Hansson 		pmd->mask = BIT(entry->bit);
144*e2ad626fSUlf Hansson 		pmd->genpd.name = entry->name;
145*e2ad626fSUlf Hansson 		pmd->genpd.flags = entry->flags;
146*e2ad626fSUlf Hansson 
147*e2ad626fSUlf Hansson 		ret = bcm63xx_power_get_state(pmd, &is_on);
148*e2ad626fSUlf Hansson 		if (ret)
149*e2ad626fSUlf Hansson 			dev_warn(dev, "unable to get current state for %s\n",
150*e2ad626fSUlf Hansson 				 pmd->genpd.name);
151*e2ad626fSUlf Hansson 
152*e2ad626fSUlf Hansson 		pmd->genpd.power_on = bcm63xx_power_on;
153*e2ad626fSUlf Hansson 		pmd->genpd.power_off = bcm63xx_power_off;
154*e2ad626fSUlf Hansson 
155*e2ad626fSUlf Hansson 		pm_genpd_init(&pmd->genpd, NULL, !is_on);
156*e2ad626fSUlf Hansson 		power->genpd[entry->bit] = &pmd->genpd;
157*e2ad626fSUlf Hansson 
158*e2ad626fSUlf Hansson 		ndom++;
159*e2ad626fSUlf Hansson 	}
160*e2ad626fSUlf Hansson 
161*e2ad626fSUlf Hansson 	spin_lock_init(&power->lock);
162*e2ad626fSUlf Hansson 
163*e2ad626fSUlf Hansson 	ret = of_genpd_add_provider_onecell(np, &power->genpd_data);
164*e2ad626fSUlf Hansson 	if (ret) {
165*e2ad626fSUlf Hansson 		dev_err(dev, "failed to register genpd driver: %d\n", ret);
166*e2ad626fSUlf Hansson 		return ret;
167*e2ad626fSUlf Hansson 	}
168*e2ad626fSUlf Hansson 
169*e2ad626fSUlf Hansson 	dev_info(dev, "registered %u power domains\n", ndom);
170*e2ad626fSUlf Hansson 
171*e2ad626fSUlf Hansson 	return 0;
172*e2ad626fSUlf Hansson }
173*e2ad626fSUlf Hansson 
174*e2ad626fSUlf Hansson static const struct bcm63xx_power_data bcm6318_power_domains[] = {
175*e2ad626fSUlf Hansson 	{
176*e2ad626fSUlf Hansson 		.name = "pcie",
177*e2ad626fSUlf Hansson 		.bit = BCM6318_POWER_DOMAIN_PCIE,
178*e2ad626fSUlf Hansson 	}, {
179*e2ad626fSUlf Hansson 		.name = "usb",
180*e2ad626fSUlf Hansson 		.bit = BCM6318_POWER_DOMAIN_USB,
181*e2ad626fSUlf Hansson 	}, {
182*e2ad626fSUlf Hansson 		.name = "ephy0",
183*e2ad626fSUlf Hansson 		.bit = BCM6318_POWER_DOMAIN_EPHY0,
184*e2ad626fSUlf Hansson 	}, {
185*e2ad626fSUlf Hansson 		.name = "ephy1",
186*e2ad626fSUlf Hansson 		.bit = BCM6318_POWER_DOMAIN_EPHY1,
187*e2ad626fSUlf Hansson 	}, {
188*e2ad626fSUlf Hansson 		.name = "ephy2",
189*e2ad626fSUlf Hansson 		.bit = BCM6318_POWER_DOMAIN_EPHY2,
190*e2ad626fSUlf Hansson 	}, {
191*e2ad626fSUlf Hansson 		.name = "ephy3",
192*e2ad626fSUlf Hansson 		.bit = BCM6318_POWER_DOMAIN_EPHY3,
193*e2ad626fSUlf Hansson 	}, {
194*e2ad626fSUlf Hansson 		.name = "ldo2p5",
195*e2ad626fSUlf Hansson 		.bit = BCM6318_POWER_DOMAIN_LDO2P5,
196*e2ad626fSUlf Hansson 		.flags = GENPD_FLAG_ALWAYS_ON,
197*e2ad626fSUlf Hansson 	}, {
198*e2ad626fSUlf Hansson 		.name = "ldo2p9",
199*e2ad626fSUlf Hansson 		.bit = BCM6318_POWER_DOMAIN_LDO2P9,
200*e2ad626fSUlf Hansson 		.flags = GENPD_FLAG_ALWAYS_ON,
201*e2ad626fSUlf Hansson 	}, {
202*e2ad626fSUlf Hansson 		.name = "sw1p0",
203*e2ad626fSUlf Hansson 		.bit = BCM6318_POWER_DOMAIN_SW1P0,
204*e2ad626fSUlf Hansson 		.flags = GENPD_FLAG_ALWAYS_ON,
205*e2ad626fSUlf Hansson 	}, {
206*e2ad626fSUlf Hansson 		.name = "pad",
207*e2ad626fSUlf Hansson 		.bit = BCM6318_POWER_DOMAIN_PAD,
208*e2ad626fSUlf Hansson 		.flags = GENPD_FLAG_ALWAYS_ON,
209*e2ad626fSUlf Hansson 	}, {
210*e2ad626fSUlf Hansson 		/* sentinel */
211*e2ad626fSUlf Hansson 	},
212*e2ad626fSUlf Hansson };
213*e2ad626fSUlf Hansson 
214*e2ad626fSUlf Hansson static const struct bcm63xx_power_data bcm6328_power_domains[] = {
215*e2ad626fSUlf Hansson 	{
216*e2ad626fSUlf Hansson 		.name = "adsl2-mips",
217*e2ad626fSUlf Hansson 		.bit = BCM6328_POWER_DOMAIN_ADSL2_MIPS,
218*e2ad626fSUlf Hansson 	}, {
219*e2ad626fSUlf Hansson 		.name = "adsl2-phy",
220*e2ad626fSUlf Hansson 		.bit = BCM6328_POWER_DOMAIN_ADSL2_PHY,
221*e2ad626fSUlf Hansson 	}, {
222*e2ad626fSUlf Hansson 		.name = "adsl2-afe",
223*e2ad626fSUlf Hansson 		.bit = BCM6328_POWER_DOMAIN_ADSL2_AFE,
224*e2ad626fSUlf Hansson 	}, {
225*e2ad626fSUlf Hansson 		.name = "sar",
226*e2ad626fSUlf Hansson 		.bit = BCM6328_POWER_DOMAIN_SAR,
227*e2ad626fSUlf Hansson 	}, {
228*e2ad626fSUlf Hansson 		.name = "pcm",
229*e2ad626fSUlf Hansson 		.bit = BCM6328_POWER_DOMAIN_PCM,
230*e2ad626fSUlf Hansson 	}, {
231*e2ad626fSUlf Hansson 		.name = "usbd",
232*e2ad626fSUlf Hansson 		.bit = BCM6328_POWER_DOMAIN_USBD,
233*e2ad626fSUlf Hansson 	}, {
234*e2ad626fSUlf Hansson 		.name = "usbh",
235*e2ad626fSUlf Hansson 		.bit = BCM6328_POWER_DOMAIN_USBH,
236*e2ad626fSUlf Hansson 	}, {
237*e2ad626fSUlf Hansson 		.name = "pcie",
238*e2ad626fSUlf Hansson 		.bit = BCM6328_POWER_DOMAIN_PCIE,
239*e2ad626fSUlf Hansson 	}, {
240*e2ad626fSUlf Hansson 		.name = "robosw",
241*e2ad626fSUlf Hansson 		.bit = BCM6328_POWER_DOMAIN_ROBOSW,
242*e2ad626fSUlf Hansson 	}, {
243*e2ad626fSUlf Hansson 		.name = "ephy",
244*e2ad626fSUlf Hansson 		.bit = BCM6328_POWER_DOMAIN_EPHY,
245*e2ad626fSUlf Hansson 	}, {
246*e2ad626fSUlf Hansson 		/* sentinel */
247*e2ad626fSUlf Hansson 	},
248*e2ad626fSUlf Hansson };
249*e2ad626fSUlf Hansson 
250*e2ad626fSUlf Hansson static const struct bcm63xx_power_data bcm6362_power_domains[] = {
251*e2ad626fSUlf Hansson 	{
252*e2ad626fSUlf Hansson 		.name = "sar",
253*e2ad626fSUlf Hansson 		.bit = BCM6362_POWER_DOMAIN_SAR,
254*e2ad626fSUlf Hansson 	}, {
255*e2ad626fSUlf Hansson 		.name = "ipsec",
256*e2ad626fSUlf Hansson 		.bit = BCM6362_POWER_DOMAIN_IPSEC,
257*e2ad626fSUlf Hansson 	}, {
258*e2ad626fSUlf Hansson 		.name = "mips",
259*e2ad626fSUlf Hansson 		.bit = BCM6362_POWER_DOMAIN_MIPS,
260*e2ad626fSUlf Hansson 		.flags = GENPD_FLAG_ALWAYS_ON,
261*e2ad626fSUlf Hansson 	}, {
262*e2ad626fSUlf Hansson 		.name = "dect",
263*e2ad626fSUlf Hansson 		.bit = BCM6362_POWER_DOMAIN_DECT,
264*e2ad626fSUlf Hansson 	}, {
265*e2ad626fSUlf Hansson 		.name = "usbh",
266*e2ad626fSUlf Hansson 		.bit = BCM6362_POWER_DOMAIN_USBH,
267*e2ad626fSUlf Hansson 	}, {
268*e2ad626fSUlf Hansson 		.name = "usbd",
269*e2ad626fSUlf Hansson 		.bit = BCM6362_POWER_DOMAIN_USBD,
270*e2ad626fSUlf Hansson 	}, {
271*e2ad626fSUlf Hansson 		.name = "robosw",
272*e2ad626fSUlf Hansson 		.bit = BCM6362_POWER_DOMAIN_ROBOSW,
273*e2ad626fSUlf Hansson 	}, {
274*e2ad626fSUlf Hansson 		.name = "pcm",
275*e2ad626fSUlf Hansson 		.bit = BCM6362_POWER_DOMAIN_PCM,
276*e2ad626fSUlf Hansson 	}, {
277*e2ad626fSUlf Hansson 		.name = "periph",
278*e2ad626fSUlf Hansson 		.bit = BCM6362_POWER_DOMAIN_PERIPH,
279*e2ad626fSUlf Hansson 		.flags = GENPD_FLAG_ALWAYS_ON,
280*e2ad626fSUlf Hansson 	}, {
281*e2ad626fSUlf Hansson 		.name = "adsl-phy",
282*e2ad626fSUlf Hansson 		.bit = BCM6362_POWER_DOMAIN_ADSL_PHY,
283*e2ad626fSUlf Hansson 	}, {
284*e2ad626fSUlf Hansson 		.name = "gmii-pads",
285*e2ad626fSUlf Hansson 		.bit = BCM6362_POWER_DOMAIN_GMII_PADS,
286*e2ad626fSUlf Hansson 	}, {
287*e2ad626fSUlf Hansson 		.name = "fap",
288*e2ad626fSUlf Hansson 		.bit = BCM6362_POWER_DOMAIN_FAP,
289*e2ad626fSUlf Hansson 	}, {
290*e2ad626fSUlf Hansson 		.name = "pcie",
291*e2ad626fSUlf Hansson 		.bit = BCM6362_POWER_DOMAIN_PCIE,
292*e2ad626fSUlf Hansson 	}, {
293*e2ad626fSUlf Hansson 		.name = "wlan-pads",
294*e2ad626fSUlf Hansson 		.bit = BCM6362_POWER_DOMAIN_WLAN_PADS,
295*e2ad626fSUlf Hansson 	}, {
296*e2ad626fSUlf Hansson 		/* sentinel */
297*e2ad626fSUlf Hansson 	},
298*e2ad626fSUlf Hansson };
299*e2ad626fSUlf Hansson 
300*e2ad626fSUlf Hansson static const struct bcm63xx_power_data bcm63268_power_domains[] = {
301*e2ad626fSUlf Hansson 	{
302*e2ad626fSUlf Hansson 		.name = "sar",
303*e2ad626fSUlf Hansson 		.bit = BCM63268_POWER_DOMAIN_SAR,
304*e2ad626fSUlf Hansson 	}, {
305*e2ad626fSUlf Hansson 		.name = "ipsec",
306*e2ad626fSUlf Hansson 		.bit = BCM63268_POWER_DOMAIN_IPSEC,
307*e2ad626fSUlf Hansson 	}, {
308*e2ad626fSUlf Hansson 		.name = "mips",
309*e2ad626fSUlf Hansson 		.bit = BCM63268_POWER_DOMAIN_MIPS,
310*e2ad626fSUlf Hansson 		.flags = GENPD_FLAG_ALWAYS_ON,
311*e2ad626fSUlf Hansson 	}, {
312*e2ad626fSUlf Hansson 		.name = "dect",
313*e2ad626fSUlf Hansson 		.bit = BCM63268_POWER_DOMAIN_DECT,
314*e2ad626fSUlf Hansson 	}, {
315*e2ad626fSUlf Hansson 		.name = "usbh",
316*e2ad626fSUlf Hansson 		.bit = BCM63268_POWER_DOMAIN_USBH,
317*e2ad626fSUlf Hansson 	}, {
318*e2ad626fSUlf Hansson 		.name = "usbd",
319*e2ad626fSUlf Hansson 		.bit = BCM63268_POWER_DOMAIN_USBD,
320*e2ad626fSUlf Hansson 	}, {
321*e2ad626fSUlf Hansson 		.name = "robosw",
322*e2ad626fSUlf Hansson 		.bit = BCM63268_POWER_DOMAIN_ROBOSW,
323*e2ad626fSUlf Hansson 	}, {
324*e2ad626fSUlf Hansson 		.name = "pcm",
325*e2ad626fSUlf Hansson 		.bit = BCM63268_POWER_DOMAIN_PCM,
326*e2ad626fSUlf Hansson 	}, {
327*e2ad626fSUlf Hansson 		.name = "periph",
328*e2ad626fSUlf Hansson 		.bit = BCM63268_POWER_DOMAIN_PERIPH,
329*e2ad626fSUlf Hansson 		.flags = GENPD_FLAG_ALWAYS_ON,
330*e2ad626fSUlf Hansson 	}, {
331*e2ad626fSUlf Hansson 		.name = "vdsl-phy",
332*e2ad626fSUlf Hansson 		.bit = BCM63268_POWER_DOMAIN_VDSL_PHY,
333*e2ad626fSUlf Hansson 	}, {
334*e2ad626fSUlf Hansson 		.name = "vdsl-mips",
335*e2ad626fSUlf Hansson 		.bit = BCM63268_POWER_DOMAIN_VDSL_MIPS,
336*e2ad626fSUlf Hansson 	}, {
337*e2ad626fSUlf Hansson 		.name = "fap",
338*e2ad626fSUlf Hansson 		.bit = BCM63268_POWER_DOMAIN_FAP,
339*e2ad626fSUlf Hansson 	}, {
340*e2ad626fSUlf Hansson 		.name = "pcie",
341*e2ad626fSUlf Hansson 		.bit = BCM63268_POWER_DOMAIN_PCIE,
342*e2ad626fSUlf Hansson 	}, {
343*e2ad626fSUlf Hansson 		.name = "wlan-pads",
344*e2ad626fSUlf Hansson 		.bit = BCM63268_POWER_DOMAIN_WLAN_PADS,
345*e2ad626fSUlf Hansson 	}, {
346*e2ad626fSUlf Hansson 		/* sentinel */
347*e2ad626fSUlf Hansson 	},
348*e2ad626fSUlf Hansson };
349*e2ad626fSUlf Hansson 
350*e2ad626fSUlf Hansson static const struct of_device_id bcm63xx_power_of_match[] = {
351*e2ad626fSUlf Hansson 	{
352*e2ad626fSUlf Hansson 		.compatible = "brcm,bcm6318-power-controller",
353*e2ad626fSUlf Hansson 		.data = &bcm6318_power_domains,
354*e2ad626fSUlf Hansson 	}, {
355*e2ad626fSUlf Hansson 		.compatible = "brcm,bcm6328-power-controller",
356*e2ad626fSUlf Hansson 		.data = &bcm6328_power_domains,
357*e2ad626fSUlf Hansson 	}, {
358*e2ad626fSUlf Hansson 		.compatible = "brcm,bcm6362-power-controller",
359*e2ad626fSUlf Hansson 		.data = &bcm6362_power_domains,
360*e2ad626fSUlf Hansson 	}, {
361*e2ad626fSUlf Hansson 		.compatible = "brcm,bcm63268-power-controller",
362*e2ad626fSUlf Hansson 		.data = &bcm63268_power_domains,
363*e2ad626fSUlf Hansson 	}, {
364*e2ad626fSUlf Hansson 		/* sentinel */
365*e2ad626fSUlf Hansson 	}
366*e2ad626fSUlf Hansson };
367*e2ad626fSUlf Hansson 
368*e2ad626fSUlf Hansson static struct platform_driver bcm63xx_power_driver = {
369*e2ad626fSUlf Hansson 	.driver = {
370*e2ad626fSUlf Hansson 		.name = "bcm63xx-power-controller",
371*e2ad626fSUlf Hansson 		.of_match_table = bcm63xx_power_of_match,
372*e2ad626fSUlf Hansson 	},
373*e2ad626fSUlf Hansson 	.probe  = bcm63xx_power_probe,
374*e2ad626fSUlf Hansson };
375*e2ad626fSUlf Hansson builtin_platform_driver(bcm63xx_power_driver);
376