1 /* 2 * Copyright (c) 2016, NVIDIA CORPORATION. 3 * 4 * SPDX-License-Identifier: GPL-2.0 5 */ 6 7 #include <common.h> 8 #include <dm.h> 9 #include <power-domain.h> 10 #include <power-domain-uclass.h> 11 12 DECLARE_GLOBAL_DATA_PTR; 13 14 static inline struct power_domain_ops *power_domain_dev_ops(struct udevice *dev) 15 { 16 return (struct power_domain_ops *)dev->driver->ops; 17 } 18 19 static int power_domain_of_xlate_default(struct power_domain *power_domain, 20 struct ofnode_phandle_args *args) 21 { 22 debug("%s(power_domain=%p)\n", __func__, power_domain); 23 24 if (args->args_count != 1) { 25 debug("Invalid args_count: %d\n", args->args_count); 26 return -EINVAL; 27 } 28 29 power_domain->id = args->args[0]; 30 31 return 0; 32 } 33 34 int power_domain_get(struct udevice *dev, struct power_domain *power_domain) 35 { 36 struct ofnode_phandle_args args; 37 int ret; 38 struct udevice *dev_power_domain; 39 struct power_domain_ops *ops; 40 41 debug("%s(dev=%p, power_domain=%p)\n", __func__, dev, power_domain); 42 43 ret = dev_read_phandle_with_args(dev, "power-domains", 44 "#power-domain-cells", 0, 0, &args); 45 if (ret) { 46 debug("%s: dev_read_phandle_with_args failed: %d\n", 47 __func__, ret); 48 return ret; 49 } 50 51 ret = uclass_get_device_by_ofnode(UCLASS_POWER_DOMAIN, args.node, 52 &dev_power_domain); 53 if (ret) { 54 debug("%s: uclass_get_device_by_ofnode failed: %d\n", 55 __func__, ret); 56 return ret; 57 } 58 ops = power_domain_dev_ops(dev_power_domain); 59 60 power_domain->dev = dev_power_domain; 61 if (ops->of_xlate) 62 ret = ops->of_xlate(power_domain, &args); 63 else 64 ret = power_domain_of_xlate_default(power_domain, &args); 65 if (ret) { 66 debug("of_xlate() failed: %d\n", ret); 67 return ret; 68 } 69 70 ret = ops->request(power_domain); 71 if (ret) { 72 debug("ops->request() failed: %d\n", ret); 73 return ret; 74 } 75 76 return 0; 77 } 78 79 int power_domain_free(struct power_domain *power_domain) 80 { 81 struct power_domain_ops *ops = power_domain_dev_ops(power_domain->dev); 82 83 debug("%s(power_domain=%p)\n", __func__, power_domain); 84 85 return ops->free(power_domain); 86 } 87 88 int power_domain_on(struct power_domain *power_domain) 89 { 90 struct power_domain_ops *ops = power_domain_dev_ops(power_domain->dev); 91 92 debug("%s(power_domain=%p)\n", __func__, power_domain); 93 94 return ops->on(power_domain); 95 } 96 97 int power_domain_off(struct power_domain *power_domain) 98 { 99 struct power_domain_ops *ops = power_domain_dev_ops(power_domain->dev); 100 101 debug("%s(power_domain=%p)\n", __func__, power_domain); 102 103 return ops->off(power_domain); 104 } 105 106 UCLASS_DRIVER(power_domain) = { 107 .id = UCLASS_POWER_DOMAIN, 108 .name = "power_domain", 109 }; 110