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 <power-domain-uclass.h> 9 #include <asm/io.h> 10 11 #define MAX_DOMAINS 32 12 13 struct bcm6328_power_domain { 14 void __iomem *regs; 15 }; 16 17 static int bcm6328_power_domain_request(struct power_domain *power_domain) 18 { 19 if (power_domain->id >= MAX_DOMAINS) 20 return -EINVAL; 21 22 return 0; 23 } 24 25 static int bcm6328_power_domain_free(struct power_domain *power_domain) 26 { 27 return 0; 28 } 29 30 static int bcm6328_power_domain_on(struct power_domain *power_domain) 31 { 32 struct bcm6328_power_domain *priv = dev_get_priv(power_domain->dev); 33 34 clrbits_be32(priv->regs, BIT(power_domain->id)); 35 36 return 0; 37 } 38 39 static int bcm6328_power_domain_off(struct power_domain *power_domain) 40 { 41 struct bcm6328_power_domain *priv = dev_get_priv(power_domain->dev); 42 43 setbits_be32(priv->regs, BIT(power_domain->id)); 44 45 return 0; 46 } 47 48 static int bcm6328_power_domain_probe(struct udevice *dev) 49 { 50 struct bcm6328_power_domain *priv = dev_get_priv(dev); 51 fdt_addr_t addr; 52 fdt_size_t size; 53 54 addr = devfdt_get_addr_size_index(dev, 0, &size); 55 if (addr == FDT_ADDR_T_NONE) 56 return -EINVAL; 57 58 priv->regs = ioremap(addr, size); 59 60 return 0; 61 } 62 63 static const struct udevice_id bcm6328_power_domain_ids[] = { 64 { .compatible = "brcm,bcm6328-power-domain" }, 65 { /* sentinel */ } 66 }; 67 68 struct power_domain_ops bcm6328_power_domain_ops = { 69 .free = bcm6328_power_domain_free, 70 .off = bcm6328_power_domain_off, 71 .on = bcm6328_power_domain_on, 72 .request = bcm6328_power_domain_request, 73 }; 74 75 U_BOOT_DRIVER(bcm6328_power_domain) = { 76 .name = "bcm6328_power_domain", 77 .id = UCLASS_POWER_DOMAIN, 78 .of_match = bcm6328_power_domain_ids, 79 .ops = &bcm6328_power_domain_ops, 80 .priv_auto_alloc_size = sizeof(struct bcm6328_power_domain), 81 .probe = bcm6328_power_domain_probe, 82 }; 83