diff options
author | 2015-08-04 12:17:53 -0700 | |
---|---|---|
committer | 2015-08-04 15:44:42 -0700 | |
commit | 9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (patch) | |
tree | 1c9cafbcd35f783a87880a10f85d1a060db1a563 /kernel/drivers/gpu/drm/nouveau/nouveau_sysfs.c | |
parent | 98260f3884f4a202f9ca5eabed40b1354c489b29 (diff) |
Add the rt linux 4.1.3-rt3 as base
Import the rt linux 4.1.3-rt3 as OPNFV kvm base.
It's from git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git linux-4.1.y-rt and
the base is:
commit 0917f823c59692d751951bf5ea699a2d1e2f26a2
Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Date: Sat Jul 25 12:13:34 2015 +0200
Prepare v4.1.3-rt3
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
We lose all the git history this way and it's not good. We
should apply another opnfv project repo in future.
Change-Id: I87543d81c9df70d99c5001fbdf646b202c19f423
Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
Diffstat (limited to 'kernel/drivers/gpu/drm/nouveau/nouveau_sysfs.c')
-rw-r--r-- | kernel/drivers/gpu/drm/nouveau/nouveau_sysfs.c | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/kernel/drivers/gpu/drm/nouveau/nouveau_sysfs.c b/kernel/drivers/gpu/drm/nouveau/nouveau_sysfs.c new file mode 100644 index 000000000..1ec8f38ae --- /dev/null +++ b/kernel/drivers/gpu/drm/nouveau/nouveau_sysfs.c @@ -0,0 +1,198 @@ +/* + * Copyright 2013 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs <bskeggs@redhat.com> + */ + +#include <nvif/os.h> +#include <nvif/class.h> +#include <nvif/ioctl.h> + +#include "nouveau_sysfs.h" + +MODULE_PARM_DESC(pstate, "enable sysfs pstate file, which will be moved in the future"); +int nouveau_pstate; +module_param_named(pstate, nouveau_pstate, int, 0400); + +static inline struct drm_device * +drm_device(struct device *d) +{ + return dev_get_drvdata(d); +} + +#define snappendf(p,r,f,a...) do { \ + snprintf(p, r, f, ##a); \ + r -= strlen(p); \ + p += strlen(p); \ +} while(0) + +static ssize_t +nouveau_sysfs_pstate_get(struct device *d, struct device_attribute *a, char *b) +{ + struct nouveau_sysfs *sysfs = nouveau_sysfs(drm_device(d)); + struct nvif_control_pstate_info_v0 info = {}; + size_t cnt = PAGE_SIZE; + char *buf = b; + int ret, i; + + ret = nvif_mthd(&sysfs->ctrl, NVIF_CONTROL_PSTATE_INFO, + &info, sizeof(info)); + if (ret) + return ret; + + for (i = 0; i < info.count + 1; i++) { + const s32 state = i < info.count ? i : + NVIF_CONTROL_PSTATE_ATTR_V0_STATE_CURRENT; + struct nvif_control_pstate_attr_v0 attr = { + .state = state, + .index = 0, + }; + + ret = nvif_mthd(&sysfs->ctrl, NVIF_CONTROL_PSTATE_ATTR, + &attr, sizeof(attr)); + if (ret) + return ret; + + if (i < info.count) + snappendf(buf, cnt, "%02x:", attr.state); + else + snappendf(buf, cnt, "%s:", info.pwrsrc == 0 ? "DC" : + info.pwrsrc == 1 ? "AC" : + "--"); + + attr.index = 0; + do { + attr.state = state; + ret = nvif_mthd(&sysfs->ctrl, + NVIF_CONTROL_PSTATE_ATTR, + &attr, sizeof(attr)); + if (ret) + return ret; + + snappendf(buf, cnt, " %s %d", attr.name, attr.min); + if (attr.min != attr.max) + snappendf(buf, cnt, "-%d", attr.max); + snappendf(buf, cnt, " %s", attr.unit); + } while (attr.index); + + if (state >= 0) { + if (info.ustate_ac == state) + snappendf(buf, cnt, " AC"); + if (info.ustate_dc == state) + snappendf(buf, cnt, " DC"); + if (info.pstate == state) + snappendf(buf, cnt, " *"); + } else { + if (info.ustate_ac < -1) + snappendf(buf, cnt, " AC"); + if (info.ustate_dc < -1) + snappendf(buf, cnt, " DC"); + } + + snappendf(buf, cnt, "\n"); + } + + return strlen(b); +} + +static ssize_t +nouveau_sysfs_pstate_set(struct device *d, struct device_attribute *a, + const char *buf, size_t count) +{ + struct nouveau_sysfs *sysfs = nouveau_sysfs(drm_device(d)); + struct nvif_control_pstate_user_v0 args = { .pwrsrc = -EINVAL }; + long value, ret; + char *tmp; + + if ((tmp = strchr(buf, '\n'))) + *tmp = '\0'; + + if (!strncasecmp(buf, "dc:", 3)) { + args.pwrsrc = 0; + buf += 3; + } else + if (!strncasecmp(buf, "ac:", 3)) { + args.pwrsrc = 1; + buf += 3; + } + + if (!strcasecmp(buf, "none")) + args.ustate = NVIF_CONTROL_PSTATE_USER_V0_STATE_UNKNOWN; + else + if (!strcasecmp(buf, "auto")) + args.ustate = NVIF_CONTROL_PSTATE_USER_V0_STATE_PERFMON; + else { + ret = kstrtol(buf, 16, &value); + if (ret) + return ret; + args.ustate = value; + } + + ret = nvif_mthd(&sysfs->ctrl, NVIF_CONTROL_PSTATE_USER, + &args, sizeof(args)); + if (ret < 0) + return ret; + + return count; +} + +static DEVICE_ATTR(pstate, S_IRUGO | S_IWUSR, + nouveau_sysfs_pstate_get, nouveau_sysfs_pstate_set); + +void +nouveau_sysfs_fini(struct drm_device *dev) +{ + struct nouveau_sysfs *sysfs = nouveau_sysfs(dev); + struct nouveau_drm *drm = nouveau_drm(dev); + struct nvif_device *device = &drm->device; + + if (sysfs && sysfs->ctrl.priv) { + device_remove_file(nv_device_base(nvxx_device(device)), &dev_attr_pstate); + nvif_object_fini(&sysfs->ctrl); + } + + drm->sysfs = NULL; + kfree(sysfs); +} + +int +nouveau_sysfs_init(struct drm_device *dev) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + struct nvif_device *device = &drm->device; + struct nouveau_sysfs *sysfs; + int ret; + + if (!nouveau_pstate) + return 0; + + sysfs = drm->sysfs = kzalloc(sizeof(*sysfs), GFP_KERNEL); + if (!sysfs) + return -ENOMEM; + + ret = nvif_object_init(nvif_object(device), NULL, NVDRM_CONTROL, + NVIF_IOCTL_NEW_V0_CONTROL, NULL, 0, + &sysfs->ctrl); + if (ret == 0) + device_create_file(nv_device_base(nvxx_device(device)), &dev_attr_pstate); + + return 0; +} |