~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/powerpc/platforms/powernv/opal-psr.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * PowerNV OPAL Power-Shift-Ratio interface
  4  *
  5  * Copyright 2017 IBM Corp.
  6  */
  7 
  8 #define pr_fmt(fmt)     "opal-psr: " fmt
  9 
 10 #include <linux/of.h>
 11 #include <linux/kobject.h>
 12 #include <linux/slab.h>
 13 
 14 #include <asm/opal.h>
 15 
 16 static DEFINE_MUTEX(psr_mutex);
 17 
 18 static struct kobject *psr_kobj;
 19 
 20 static struct psr_attr {
 21         u32 handle;
 22         struct kobj_attribute attr;
 23 } *psr_attrs;
 24 
 25 static ssize_t psr_show(struct kobject *kobj, struct kobj_attribute *attr,
 26                         char *buf)
 27 {
 28         struct psr_attr *psr_attr = container_of(attr, struct psr_attr, attr);
 29         struct opal_msg msg;
 30         int psr, ret, token;
 31 
 32         token = opal_async_get_token_interruptible();
 33         if (token < 0) {
 34                 pr_devel("Failed to get token\n");
 35                 return token;
 36         }
 37 
 38         ret = mutex_lock_interruptible(&psr_mutex);
 39         if (ret)
 40                 goto out_token;
 41 
 42         ret = opal_get_power_shift_ratio(psr_attr->handle, token,
 43                                             (u32 *)__pa(&psr));
 44         switch (ret) {
 45         case OPAL_ASYNC_COMPLETION:
 46                 ret = opal_async_wait_response(token, &msg);
 47                 if (ret) {
 48                         pr_devel("Failed to wait for the async response\n");
 49                         ret = -EIO;
 50                         goto out;
 51                 }
 52                 ret = opal_error_code(opal_get_async_rc(msg));
 53                 if (!ret) {
 54                         ret = sprintf(buf, "%u\n", be32_to_cpu(psr));
 55                         if (ret < 0)
 56                                 ret = -EIO;
 57                 }
 58                 break;
 59         case OPAL_SUCCESS:
 60                 ret = sprintf(buf, "%u\n", be32_to_cpu(psr));
 61                 if (ret < 0)
 62                         ret = -EIO;
 63                 break;
 64         default:
 65                 ret = opal_error_code(ret);
 66         }
 67 
 68 out:
 69         mutex_unlock(&psr_mutex);
 70 out_token:
 71         opal_async_release_token(token);
 72         return ret;
 73 }
 74 
 75 static ssize_t psr_store(struct kobject *kobj, struct kobj_attribute *attr,
 76                          const char *buf, size_t count)
 77 {
 78         struct psr_attr *psr_attr = container_of(attr, struct psr_attr, attr);
 79         struct opal_msg msg;
 80         int psr, ret, token;
 81 
 82         ret = kstrtoint(buf, 0, &psr);
 83         if (ret)
 84                 return ret;
 85 
 86         token = opal_async_get_token_interruptible();
 87         if (token < 0) {
 88                 pr_devel("Failed to get token\n");
 89                 return token;
 90         }
 91 
 92         ret = mutex_lock_interruptible(&psr_mutex);
 93         if (ret)
 94                 goto out_token;
 95 
 96         ret = opal_set_power_shift_ratio(psr_attr->handle, token, psr);
 97         switch (ret) {
 98         case OPAL_ASYNC_COMPLETION:
 99                 ret = opal_async_wait_response(token, &msg);
100                 if (ret) {
101                         pr_devel("Failed to wait for the async response\n");
102                         ret = -EIO;
103                         goto out;
104                 }
105                 ret = opal_error_code(opal_get_async_rc(msg));
106                 if (!ret)
107                         ret = count;
108                 break;
109         case OPAL_SUCCESS:
110                 ret = count;
111                 break;
112         default:
113                 ret = opal_error_code(ret);
114         }
115 
116 out:
117         mutex_unlock(&psr_mutex);
118 out_token:
119         opal_async_release_token(token);
120         return ret;
121 }
122 
123 void __init opal_psr_init(void)
124 {
125         struct device_node *psr, *node;
126         int i = 0;
127 
128         psr = of_find_compatible_node(NULL, NULL,
129                                       "ibm,opal-power-shift-ratio");
130         if (!psr) {
131                 pr_devel("Power-shift-ratio node not found\n");
132                 return;
133         }
134 
135         psr_attrs = kcalloc(of_get_child_count(psr), sizeof(*psr_attrs),
136                             GFP_KERNEL);
137         if (!psr_attrs)
138                 goto out_put_psr;
139 
140         psr_kobj = kobject_create_and_add("psr", opal_kobj);
141         if (!psr_kobj) {
142                 pr_warn("Failed to create psr kobject\n");
143                 goto out;
144         }
145 
146         for_each_child_of_node(psr, node) {
147                 if (of_property_read_u32(node, "handle",
148                                          &psr_attrs[i].handle))
149                         goto out_kobj;
150 
151                 sysfs_attr_init(&psr_attrs[i].attr.attr);
152                 if (of_property_read_string(node, "label",
153                                             &psr_attrs[i].attr.attr.name))
154                         goto out_kobj;
155                 psr_attrs[i].attr.attr.mode = 0664;
156                 psr_attrs[i].attr.show = psr_show;
157                 psr_attrs[i].attr.store = psr_store;
158                 if (sysfs_create_file(psr_kobj, &psr_attrs[i].attr.attr)) {
159                         pr_devel("Failed to create psr sysfs file %s\n",
160                                  psr_attrs[i].attr.attr.name);
161                         goto out_kobj;
162                 }
163                 i++;
164         }
165         of_node_put(psr);
166 
167         return;
168 out_kobj:
169         of_node_put(node);
170         kobject_put(psr_kobj);
171 out:
172         kfree(psr_attrs);
173 out_put_psr:
174         of_node_put(psr);
175 }
176 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php