1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2017 ��lvaro Fern��ndez Rojas <noltari@gmail.com>
4 */
5
6#include <common.h>
7#include <dm.h>
8#include <malloc.h>
9#include <power-domain-uclass.h>
10#include <asm/io.h>
11#include <linux/bitops.h>
12
13#define MAX_DOMAINS	32
14
15struct bcm6328_power_domain {
16	void __iomem *regs;
17};
18
19static int bcm6328_power_domain_request(struct power_domain *power_domain)
20{
21	if (power_domain->id >= MAX_DOMAINS)
22		return -EINVAL;
23
24	return 0;
25}
26
27static int bcm6328_power_domain_on(struct power_domain *power_domain)
28{
29	struct bcm6328_power_domain *priv = dev_get_priv(power_domain->dev);
30
31	clrbits_be32(priv->regs, BIT(power_domain->id));
32
33	return 0;
34}
35
36static int bcm6328_power_domain_off(struct power_domain *power_domain)
37{
38	struct bcm6328_power_domain *priv = dev_get_priv(power_domain->dev);
39
40	setbits_be32(priv->regs, BIT(power_domain->id));
41
42	return 0;
43}
44
45static int bcm6328_power_domain_probe(struct udevice *dev)
46{
47	struct bcm6328_power_domain *priv = dev_get_priv(dev);
48
49	priv->regs = dev_remap_addr(dev);
50	if (!priv->regs)
51		return -EINVAL;
52
53	return 0;
54}
55
56static const struct udevice_id bcm6328_power_domain_ids[] = {
57	{ .compatible = "brcm,bcm6328-power-domain" },
58	{ /* sentinel */ }
59};
60
61struct power_domain_ops bcm6328_power_domain_ops = {
62	.off = bcm6328_power_domain_off,
63	.on = bcm6328_power_domain_on,
64	.request = bcm6328_power_domain_request,
65};
66
67U_BOOT_DRIVER(bcm6328_power_domain) = {
68	.name = "bcm6328_power_domain",
69	.id = UCLASS_POWER_DOMAIN,
70	.of_match = bcm6328_power_domain_ids,
71	.ops = &bcm6328_power_domain_ops,
72	.priv_auto	= sizeof(struct bcm6328_power_domain),
73	.probe = bcm6328_power_domain_probe,
74};
75