Merge "msm: kgsl: Add kobject sysfs ops for the /sys/kernel/gpu directory"

This commit is contained in:
qctecmdr 2020-05-21 18:18:22 -07:00 • committed by Gerrit - the friendly Code Review server
commit 09fd506f88
5 changed files with 188 additions and 48 deletions

View file

@ -24,6 +24,7 @@
#include "kgsl_mmu.h"
#include "kgsl_pool.h"
#include "kgsl_sync.h"
#include "kgsl_sysfs.h"
#include "kgsl_trace.h"
#ifndef arch_mmap_check
@ -4733,6 +4734,50 @@ static void _unregister_device(struct kgsl_device *device)
mutex_unlock(&kgsl_driver.devlock);
}
/* sysfs_ops for the /sys/kernel/gpu kobject */
static ssize_t kgsl_gpu_sysfs_attr_show(struct kobject *kobj,
struct attribute *__attr, char *buf)
{
struct kgsl_gpu_sysfs_attr *attr = container_of(__attr,
struct kgsl_gpu_sysfs_attr, attr);
struct kgsl_device *device = container_of(kobj,
struct kgsl_device, gpu_sysfs_kobj);
if (attr->show)
return attr->show(device, buf);
return -EIO;
}
static ssize_t kgsl_gpu_sysfs_attr_store(struct kobject *kobj,
struct attribute *__attr, const char *buf, size_t count)
{
struct kgsl_gpu_sysfs_attr *attr = container_of(__attr,
struct kgsl_gpu_sysfs_attr, attr);
struct kgsl_device *device = container_of(kobj,
struct kgsl_device, gpu_sysfs_kobj);
if (attr->store)
return attr->store(device, buf, count);
return -EIO;
}
/* Dummy release function - we have nothing to do here */
static void kgsl_gpu_sysfs_release(struct kobject *kobj)
{
}
static const struct sysfs_ops kgsl_gpu_sysfs_ops = {
.show = kgsl_gpu_sysfs_attr_show,
.store = kgsl_gpu_sysfs_attr_store,
};
static struct kobj_type kgsl_gpu_sysfs_ktype = {
.sysfs_ops = &kgsl_gpu_sysfs_ops,
.release = kgsl_gpu_sysfs_release,
};
static int _register_device(struct kgsl_device *device)
{
static u64 dma_mask = DMA_BIT_MASK(64);
@ -4773,6 +4818,10 @@ static int _register_device(struct kgsl_device *device)
device->dev->dma_mask = &dma_mask;
set_dma_ops(device->dev, NULL);
kobject_init_and_add(&device->gpu_sysfs_kobj, &kgsl_gpu_sysfs_ktype,
kernel_kobj, "gpu");
return 0;
}
@ -4897,7 +4946,8 @@ void kgsl_device_platform_remove(struct kgsl_device *device)
kgsl_device_snapshot_close(device);
kobject_put(device->gpu_sysfs_kobj);
if (device->gpu_sysfs_kobj.state_initialized)
kobject_del(&device->gpu_sysfs_kobj);
idr_destroy(&device->context_idr);

View file

@ -296,7 +296,7 @@ struct kgsl_device {
/* Number of active contexts seen globally for this device */
int active_context_count;
struct kobject *gpu_sysfs_kobj;
struct kobject gpu_sysfs_kobj;
struct clk *l3_clk;
unsigned int l3_freq[MAX_L3_LEVELS];
unsigned int num_l3_pwrlevels;

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2010-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2010-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/of_device.h>
@ -12,6 +12,7 @@
#include "kgsl_device.h"
#include "kgsl_bus.h"
#include "kgsl_pwrscale.h"
#include "kgsl_sysfs.h"
#include "kgsl_trace.h"
#define UPDATE_BUSY_VAL 1000000
@ -824,10 +825,8 @@ static ssize_t popp_show(struct device *dev,
return scnprintf(buf, PAGE_SIZE, "0\n");
}
static ssize_t gpu_model_show(struct device *dev,
struct device_attribute *attr, char *buf)
static ssize_t _gpu_model_show(struct kgsl_device *device, char *buf)
{
struct kgsl_device *device = dev_get_drvdata(dev);
char model_str[32] = {0};
device->ftbl->gpu_model(device, model_str, sizeof(model_str));
@ -835,12 +834,18 @@ static ssize_t gpu_model_show(struct device *dev,
return scnprintf(buf, PAGE_SIZE, "%s\n", model_str);
}
static ssize_t gpu_busy_percentage_show(struct device *dev,
struct device_attribute *attr,
static ssize_t gpu_model_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct kgsl_device *device = dev_get_drvdata(dev);
return _gpu_model_show(device, buf);
}
static ssize_t _gpu_busy_show(struct kgsl_device *device,
char *buf)
{
int ret;
struct kgsl_device *device = dev_get_drvdata(dev);
struct kgsl_clk_stats *stats = &device->pwrctrl.clk_stats;
unsigned int busy_percent = 0;
@ -857,22 +862,37 @@ static ssize_t gpu_busy_percentage_show(struct device *dev,
return ret;
}
static ssize_t min_clock_mhz_show(struct device *dev,
static ssize_t gpu_busy_percentage_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct kgsl_device *device = dev_get_drvdata(dev);
return _gpu_busy_show(device, buf);
}
static ssize_t _min_clock_mhz_show(struct kgsl_device *device,
char *buf)
{
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
return scnprintf(buf, PAGE_SIZE, "%d\n",
pwr->pwrlevels[pwr->min_pwrlevel].gpu_freq / 1000000);
}
static ssize_t min_clock_mhz_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
static ssize_t min_clock_mhz_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct kgsl_device *device = dev_get_drvdata(dev);
return _min_clock_mhz_show(device, buf);
}
static ssize_t _min_clock_mhz_store(struct kgsl_device *device,
const char *buf, size_t count)
{
int level, ret;
unsigned int freq;
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
@ -890,21 +910,34 @@ static ssize_t min_clock_mhz_store(struct device *dev,
return count;
}
static ssize_t max_clock_mhz_show(struct device *dev,
struct device_attribute *attr, char *buf)
static ssize_t min_clock_mhz_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct kgsl_device *device = dev_get_drvdata(dev);
return _min_clock_mhz_store(device, buf, count);
}
static ssize_t _max_clock_mhz_show(struct kgsl_device *device, char *buf)
{
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
return scnprintf(buf, PAGE_SIZE, "%d\n",
pwr->pwrlevels[pwr->thermal_pwrlevel].gpu_freq / 1000000);
}
static ssize_t max_clock_mhz_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
static ssize_t max_clock_mhz_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct kgsl_device *device = dev_get_drvdata(dev);
return _max_clock_mhz_show(device, buf);
}
static ssize_t _max_clock_mhz_store(struct kgsl_device *device,
const char *buf, size_t count)
{
u32 freq;
int ret, level;
@ -924,20 +957,32 @@ static ssize_t max_clock_mhz_store(struct device *dev,
return count;
}
static ssize_t max_clock_mhz_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct kgsl_device *device = dev_get_drvdata(dev);
return _max_clock_mhz_store(device, buf, count);
}
static ssize_t _clock_mhz_show(struct kgsl_device *device, char *buf)
{
return scnprintf(buf, PAGE_SIZE, "%ld\n",
kgsl_pwrctrl_active_freq(&device->pwrctrl) / 1000000);
}
static ssize_t clock_mhz_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct kgsl_device *device = dev_get_drvdata(dev);
return scnprintf(buf, PAGE_SIZE, "%ld\n",
kgsl_pwrctrl_active_freq(&device->pwrctrl) / 1000000);
return _clock_mhz_show(device, buf);
}
static ssize_t freq_table_mhz_show(struct device *dev,
struct device_attribute *attr,
static ssize_t _freq_table_mhz_show(struct kgsl_device *device,
char *buf)
{
struct kgsl_device *device = dev_get_drvdata(dev);
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
int index, num_chars = 0;
@ -955,11 +1000,18 @@ static ssize_t freq_table_mhz_show(struct device *dev,
return num_chars;
}
static ssize_t temp_show(struct device *dev,
static ssize_t freq_table_mhz_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct kgsl_device *device = dev_get_drvdata(dev);
return _freq_table_mhz_show(device, buf);
}
static ssize_t _gpu_tmu_show(struct kgsl_device *device,
char *buf)
{
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
struct thermal_zone_device *thermal_dev;
int ret, temperature = 0;
@ -979,6 +1031,15 @@ static ssize_t temp_show(struct device *dev,
temperature);
}
static ssize_t temp_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct kgsl_device *device = dev_get_drvdata(dev);
return _gpu_tmu_show(device, buf);
}
static ssize_t pwrscale_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
@ -1069,23 +1130,24 @@ static const struct attribute *pwrctrl_attr_list[] = {
NULL,
};
static DEVICE_ATTR(gpu_busy, 0200, gpu_busy_percentage_show, NULL);
static DEVICE_ATTR(gpu_min_clock, 0644, min_clock_mhz_show,
min_clock_mhz_store);
static DEVICE_ATTR(gpu_max_clock, 0644, max_clock_mhz_show,
max_clock_mhz_store);
static DEVICE_ATTR(gpu_clock, 0200, clock_mhz_show, NULL);
static DEVICE_ATTR(gpu_freq_table, 0200, freq_table_mhz_show, NULL);
static DEVICE_ATTR(gpu_tmu, 0200, temp_show, NULL);
static GPU_SYSFS_ATTR(gpu_model, 0200, _gpu_model_show, NULL);
static GPU_SYSFS_ATTR(gpu_busy, 0200, _gpu_busy_show, NULL);
static GPU_SYSFS_ATTR(gpu_min_clock, 0644, _min_clock_mhz_show,
_min_clock_mhz_store);
static GPU_SYSFS_ATTR(gpu_max_clock, 0644, _max_clock_mhz_show,
_max_clock_mhz_store);
static GPU_SYSFS_ATTR(gpu_clock, 0200, _clock_mhz_show, NULL);
static GPU_SYSFS_ATTR(gpu_freq_table, 0200, _freq_table_mhz_show, NULL);
static GPU_SYSFS_ATTR(gpu_tmu, 0200, _gpu_tmu_show, NULL);
static const struct attribute *pwrctrl_gpu_attr_list[] = {
&dev_attr_gpu_model.attr,
&dev_attr_gpu_busy.attr,
&dev_attr_gpu_min_clock.attr,
&dev_attr_gpu_max_clock.attr,
&dev_attr_gpu_clock.attr,
&dev_attr_gpu_freq_table.attr,
&dev_attr_gpu_tmu.attr,
static const struct attribute *gpu_sysfs_attr_list[] = {
&gpu_sysfs_attr_gpu_model.attr,
&gpu_sysfs_attr_gpu_busy.attr,
&gpu_sysfs_attr_gpu_min_clock.attr,
&gpu_sysfs_attr_gpu_max_clock.attr,
&gpu_sysfs_attr_gpu_clock.attr,
&gpu_sysfs_attr_gpu_freq_table.attr,
&gpu_sysfs_attr_gpu_tmu.attr,
NULL,
};
@ -1097,13 +1159,10 @@ int kgsl_pwrctrl_init_sysfs(struct kgsl_device *device)
if (ret)
return ret;
device->gpu_sysfs_kobj = kobject_create_and_add("gpu", kernel_kobj);
if (!device->gpu_sysfs_kobj)
if (!device->gpu_sysfs_kobj.state_in_sysfs)
return 0;
return sysfs_create_files(device->gpu_sysfs_kobj,
pwrctrl_gpu_attr_list);
return sysfs_create_files(&device->gpu_sysfs_kobj, gpu_sysfs_attr_list);
}
/*

View file

@ -886,10 +886,10 @@ int kgsl_pwrscale_init(struct kgsl_device *device, struct platform_device *pdev,
KGSL_GOVERNOR_CALL_INTERVAL);
/* Add links to the devfreq sysfs nodes */
kgsl_gpu_sysfs_add_link(device->gpu_sysfs_kobj,
kgsl_gpu_sysfs_add_link(&device->gpu_sysfs_kobj,
&pwrscale->devfreqptr->dev.kobj, "governor",
"gpu_governor");
kgsl_gpu_sysfs_add_link(device->gpu_sysfs_kobj,
kgsl_gpu_sysfs_add_link(&device->gpu_sysfs_kobj,
&pwrscale->devfreqptr->dev.kobj,
"available_governors", "gpu_available_governor");

View file

@ -0,0 +1,31 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*/
#ifndef _KGSL_SYSFS_H_
#define _KGSL_SYSFS_H_
struct kgsl_device;
/**
* struct kgsl_gpu_sysfs_attr - Attribute definition for sysfs objects in the
* /sys/kernel/gpu kobject
*/
struct kgsl_gpu_sysfs_attr {
/** @attr: Attribute for the sysfs node */
struct attribute attr;
/** @show: Show function for the node */
ssize_t (*show)(struct kgsl_device *device, char *buf);
/** @store: Store function for the node */
ssize_t (*store)(struct kgsl_device *device, const char *buf,
size_t count);
};
#define GPU_SYSFS_ATTR(_name, _mode, _show, _store) \
struct kgsl_gpu_sysfs_attr gpu_sysfs_attr_##_name = { \
.attr = { .name = __stringify(_name), .mode = _mode }, \
.show = _show, \
.store = _store, \
}
#endif