[PATCH V8 1/3] powernv: powercap: Add support for powercap framework
Adds a generic powercap framework to change the system powercap inband through OPAL-OCC command/response interface. Signed-off-by: Shilpasri G Bhat --- Changes from V7: - Replaced sscanf with kstrtoint arch/powerpc/include/asm/opal-api.h| 5 +- arch/powerpc/include/asm/opal.h| 4 + arch/powerpc/platforms/powernv/Makefile| 2 +- arch/powerpc/platforms/powernv/opal-powercap.c | 237 + arch/powerpc/platforms/powernv/opal-wrappers.S | 2 + arch/powerpc/platforms/powernv/opal.c | 4 + 6 files changed, 252 insertions(+), 2 deletions(-) create mode 100644 arch/powerpc/platforms/powernv/opal-powercap.c diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h index 3130a73..c3e0c4a 100644 --- a/arch/powerpc/include/asm/opal-api.h +++ b/arch/powerpc/include/asm/opal-api.h @@ -42,6 +42,7 @@ #define OPAL_I2C_STOP_ERR -24 #define OPAL_XIVE_PROVISIONING -31 #define OPAL_XIVE_FREE_ACTIVE -32 +#define OPAL_TIMEOUT -33 /* API Tokens (in r0) */ #define OPAL_INVALID_CALL -1 @@ -190,7 +191,9 @@ #define OPAL_NPU_INIT_CONTEXT 146 #define OPAL_NPU_DESTROY_CONTEXT 147 #define OPAL_NPU_MAP_LPAR 148 -#define OPAL_LAST 148 +#define OPAL_GET_POWERCAP 152 +#define OPAL_SET_POWERCAP 153 +#define OPAL_LAST 153 /* Device tree flags */ diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 588fb1c..ec2087c 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -267,6 +267,8 @@ int64_t opal_xive_set_vp_info(uint64_t vp, int64_t opal_xive_free_irq(uint32_t girq); int64_t opal_xive_sync(uint32_t type, uint32_t id); int64_t opal_xive_dump(uint32_t type, uint32_t id); +int opal_get_powercap(u32 handle, int token, u32 *pcap); +int opal_set_powercap(u32 handle, int token, u32 pcap); /* Internal functions */ extern int early_init_dt_scan_opal(unsigned long node, const char *uname, @@ -345,6 +347,8 @@ static inline int opal_get_async_rc(struct opal_msg msg) void opal_wake_poller(void); +void opal_powercap_init(void); + #endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_OPAL_H */ diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile index b5d98cb..e79f806 100644 --- a/arch/powerpc/platforms/powernv/Makefile +++ b/arch/powerpc/platforms/powernv/Makefile @@ -2,7 +2,7 @@ obj-y += setup.o opal-wrappers.o opal.o opal-async.o idle.o obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o obj-y += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o obj-y += opal-msglog.o opal-hmi.o opal-power.o opal-irqchip.o -obj-y += opal-kmsg.o +obj-y += opal-kmsg.o opal-powercap.o obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o obj-$(CONFIG_PCI) += pci.o pci-ioda.o npu-dma.o diff --git a/arch/powerpc/platforms/powernv/opal-powercap.c b/arch/powerpc/platforms/powernv/opal-powercap.c new file mode 100644 index 000..7c57f4b --- /dev/null +++ b/arch/powerpc/platforms/powernv/opal-powercap.c @@ -0,0 +1,237 @@ +/* + * PowerNV OPAL Powercap interface + * + * Copyright 2017 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#define pr_fmt(fmt) "opal-powercap: " fmt + +#include +#include +#include + +#include + +DEFINE_MUTEX(powercap_mutex); + +static struct kobject *powercap_kobj; + +struct powercap_attr { + u32 handle; + struct kobj_attribute attr; +}; + +static struct attribute_group *pattr_groups; +static struct powercap_attr *pcap_attrs; + +static ssize_t powercap_show(struct kobject *kobj, struct kobj_attribute *attr, +char *buf) +{ + struct powercap_attr *pcap_attr = container_of(attr, + struct powercap_attr, attr); + struct opal_msg msg; + u32 pcap; + int ret, token; + + token = opal_async_get_token_interruptible(); + if (token < 0) { + pr_devel("Failed to get token\n"); + return token; + } + + mutex_lock(&powercap_mutex); + ret = opal_get_powercap(pcap_attr->handle, token, &pcap); + switch (ret) { + case OPAL_ASYNC_COMPLETION: + ret = opal_async_wait_response(token, &msg); + if (ret) { + pr_devel("Failed to wait for the async response %d\n", +ret); + goto out; + } + r
Re: [PATCH V8 1/3] powernv: powercap: Add support for powercap framework
On Wed, 2017-07-26 at 10:35 +0530, Shilpasri G Bhat wrote: > Adds a generic powercap framework to change the system powercap > inband through OPAL-OCC command/response interface. > > Signed-off-by: Shilpasri G Bhat > --- > Changes from V7: > - Replaced sscanf with kstrtoint > > arch/powerpc/include/asm/opal-api.h| 5 +- > arch/powerpc/include/asm/opal.h| 4 + > arch/powerpc/platforms/powernv/Makefile| 2 +- > arch/powerpc/platforms/powernv/opal-powercap.c | 237 > + > arch/powerpc/platforms/powernv/opal-wrappers.S | 2 + > arch/powerpc/platforms/powernv/opal.c | 4 + > 6 files changed, 252 insertions(+), 2 deletions(-) > create mode 100644 arch/powerpc/platforms/powernv/opal-powercap.c > > diff --git a/arch/powerpc/include/asm/opal-api.h > b/arch/powerpc/include/asm/opal-api.h > index 3130a73..c3e0c4a 100644 > --- a/arch/powerpc/include/asm/opal-api.h > +++ b/arch/powerpc/include/asm/opal-api.h > @@ -42,6 +42,7 @@ > #define OPAL_I2C_STOP_ERR-24 > #define OPAL_XIVE_PROVISIONING -31 > #define OPAL_XIVE_FREE_ACTIVE-32 > +#define OPAL_TIMEOUT -33 > > /* API Tokens (in r0) */ > #define OPAL_INVALID_CALL -1 > @@ -190,7 +191,9 @@ > #define OPAL_NPU_INIT_CONTEXT146 > #define OPAL_NPU_DESTROY_CONTEXT 147 > #define OPAL_NPU_MAP_LPAR148 > -#define OPAL_LAST148 > +#define OPAL_GET_POWERCAP152 > +#define OPAL_SET_POWERCAP153 > +#define OPAL_LAST153 > > /* Device tree flags */ > > diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h > index 588fb1c..ec2087c 100644 > --- a/arch/powerpc/include/asm/opal.h > +++ b/arch/powerpc/include/asm/opal.h > @@ -267,6 +267,8 @@ int64_t opal_xive_set_vp_info(uint64_t vp, > int64_t opal_xive_free_irq(uint32_t girq); > int64_t opal_xive_sync(uint32_t type, uint32_t id); > int64_t opal_xive_dump(uint32_t type, uint32_t id); > +int opal_get_powercap(u32 handle, int token, u32 *pcap); > +int opal_set_powercap(u32 handle, int token, u32 pcap); > > /* Internal functions */ > extern int early_init_dt_scan_opal(unsigned long node, const char *uname, > @@ -345,6 +347,8 @@ static inline int opal_get_async_rc(struct opal_msg msg) > > void opal_wake_poller(void); > > +void opal_powercap_init(void); > + > #endif /* __ASSEMBLY__ */ > > #endif /* _ASM_POWERPC_OPAL_H */ > diff --git a/arch/powerpc/platforms/powernv/Makefile > b/arch/powerpc/platforms/powernv/Makefile > index b5d98cb..e79f806 100644 > --- a/arch/powerpc/platforms/powernv/Makefile > +++ b/arch/powerpc/platforms/powernv/Makefile > @@ -2,7 +2,7 @@ obj-y += setup.o opal-wrappers.o opal.o > opal-async.o idle.o > obj-y+= opal-rtc.o opal-nvram.o opal-lpc.o > opal-flash.o > obj-y+= rng.o opal-elog.o opal-dump.o > opal-sysparam.o opal-sensor.o > obj-y+= opal-msglog.o opal-hmi.o opal-power.o > opal-irqchip.o > -obj-y+= opal-kmsg.o > +obj-y+= opal-kmsg.o opal-powercap.o > > obj-$(CONFIG_SMP)+= smp.o subcore.o subcore-asm.o > obj-$(CONFIG_PCI)+= pci.o pci-ioda.o npu-dma.o > diff --git a/arch/powerpc/platforms/powernv/opal-powercap.c > b/arch/powerpc/platforms/powernv/opal-powercap.c > new file mode 100644 > index 000..7c57f4b > --- /dev/null > +++ b/arch/powerpc/platforms/powernv/opal-powercap.c > @@ -0,0 +1,237 @@ > +/* > + * PowerNV OPAL Powercap interface > + * > + * Copyright 2017 IBM Corp. > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version > + * 2 of the License, or (at your option) any later version. > + */ > + > +#define pr_fmt(fmt) "opal-powercap: " fmt > + > +#include > +#include > +#include > + > +#include > + > +DEFINE_MUTEX(powercap_mutex); > + > +static struct kobject *powercap_kobj; > + > +struct powercap_attr { > + u32 handle; > + struct kobj_attribute attr; > +}; > + > +static struct attribute_group *pattr_groups; > +static struct powercap_attr *pcap_attrs; > + > +static ssize_t powercap_show(struct kobject *kobj, struct kobj_attribute > *attr, > + char *buf) > +{ > + struct powercap_attr *pcap_attr = container_of(attr, > + struct powercap_attr, attr); > + struct opal_msg msg; > + u32 pcap; > + int ret, token; > + > + token = opal_async_get_token_interruptible(); > + if (token < 0) { > + pr_devel("Failed to get token\n"); > + return token; > + } > + > + mutex_lock(&powercap_mutex); If this is purely a userspace interface, shouldn't this be mutex_l
Re: [PATCH V8 1/3] powernv: powercap: Add support for powercap framework
Hi Cyril, On 07/28/2017 07:09 AM, Cyril Bur wrote: > Is there any reason that pcap_attrs needs to be contiguous? If not, I > feel like you could eliminate the entire loop below (and the last one > as well maybe) and just do the assignment of pattr_groups[].attrs[] up > there. > > In fact do you even need to store pcap_attrs? If you kcalloc them as > you need them (in the loop above), you can always free them again on > error by freeing pattr_groups[].attrs[] right? > > I'll admit I've become quite confused as to the layout of the sysfs dir > that you're creating here - would you mind showing what the expected > layout will be? > > I'll take more of a look once thats more clear in my head > > Thanks, > > Cyril The sysfs layout looks as below: # ls /sys/firmware/opal/powercap/ system-powercap # ls /sys/firmware/opal/powercap/system-powercap/ powercap-current powercap-max powercap-min # grep . /sys/firmware/opal/powercap/system-powercap/* /sys/firmware/opal/powercap/system-powercap/powercap-current:2375 /sys/firmware/opal/powercap/system-powercap/powercap-max:2375 /sys/firmware/opal/powercap/system-powercap/powercap-min:1945 Thanks and Regards, Shilpa
Re: [PATCH V8 1/3] powernv: powercap: Add support for powercap framework
Cyril Bur writes: > This is more for MPE and Stewart: > If there is some mutual exclusion that needs to happen, it should be > done in skiboot. We've had problems in the past with double entering > skiboot and hard to interpret errors ending up in userspace, this > solves that but it seems more like a coverup than an actual solution. Yeah, I'd like us to be in a position where we don't force mutual exclusion on such things out to the OS. The real issue this papers over is the async token stuff you're reworking. There's that, plus for this specific thing, you *could* go and set a differnt powercap 180 times concurrently and we should do the right thing in skiboot... but then you're sitting in skiboot rather than sitting in linux being able to go run some other task on the thread. -- Stewart Smith OPAL Architect, IBM.