mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 05:39:54 -04:00
msm: kgsl: Move preemption sysfs nodes to dispatcher
This paves the way to hook preemption sysfs nodes to hwscheduling which need to talk to GMU when changing preemption parameters via sysfs. Change-Id: I6940dbf294ad71a18b2dcded207cbacf18ba661d Signed-off-by: Harshdeep Dhatt <hdhatt@codeaurora.org>
This commit is contained in:
parent
c7fdd108da
commit
4f3a132f88
3 changed files with 204 additions and 165 deletions
|
|
@ -4,8 +4,10 @@
|
|||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <soc/qcom/msm_performance.h>
|
||||
#include "adreno.h"
|
||||
#include "adreno_sysfs.h"
|
||||
#include "adreno_trace.h"
|
||||
#include "kgsl_gmu_core.h"
|
||||
#include "kgsl_timeline.h"
|
||||
|
|
@ -2658,6 +2660,116 @@ void adreno_dispatcher_stop_fault_timer(struct kgsl_device *device)
|
|||
del_timer_sync(&dispatcher->fault_timer);
|
||||
}
|
||||
|
||||
static int _skipsaverestore_store(struct adreno_device *adreno_dev, bool val)
|
||||
{
|
||||
adreno_dev->preempt.skipsaverestore = val ? true : false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool _skipsaverestore_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return adreno_dev->preempt.skipsaverestore;
|
||||
}
|
||||
|
||||
static int _usesgmem_store(struct adreno_device *adreno_dev, bool val)
|
||||
{
|
||||
adreno_dev->preempt.usesgmem = val ? true : false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool _usesgmem_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return adreno_dev->preempt.usesgmem;
|
||||
}
|
||||
|
||||
static int _preempt_level_store(struct adreno_device *adreno_dev,
|
||||
unsigned int val)
|
||||
{
|
||||
adreno_dev->preempt.preempt_level = min_t(unsigned int, val, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int _preempt_level_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return adreno_dev->preempt.preempt_level;
|
||||
}
|
||||
|
||||
static void change_preemption(struct adreno_device *adreno_dev, void *priv)
|
||||
{
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
struct kgsl_context *context;
|
||||
struct adreno_context *drawctxt;
|
||||
struct adreno_ringbuffer *rb;
|
||||
int id, i, ret;
|
||||
|
||||
/* Make sure all ringbuffers are finished */
|
||||
FOR_EACH_RINGBUFFER(adreno_dev, rb, i) {
|
||||
ret = adreno_ringbuffer_waittimestamp(rb, rb->timestamp,
|
||||
2 * 1000);
|
||||
if (ret) {
|
||||
dev_err(device->dev,
|
||||
"Cannot disable preemption because couldn't idle ringbuffer[%d] ret: %d\n",
|
||||
rb->id, ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
change_bit(ADRENO_DEVICE_PREEMPTION, &adreno_dev->priv);
|
||||
adreno_dev->cur_rb = &adreno_dev->ringbuffers[0];
|
||||
adreno_dev->next_rb = NULL;
|
||||
adreno_dev->prev_rb = NULL;
|
||||
|
||||
/* Update the ringbuffer for each draw context */
|
||||
write_lock(&device->context_lock);
|
||||
idr_for_each_entry(&device->context_idr, context, id) {
|
||||
drawctxt = ADRENO_CONTEXT(context);
|
||||
drawctxt->rb = adreno_ctx_get_rb(adreno_dev, drawctxt);
|
||||
|
||||
/*
|
||||
* Make sure context destroy checks against the correct
|
||||
* ringbuffer's timestamp.
|
||||
*/
|
||||
adreno_rb_readtimestamp(adreno_dev, drawctxt->rb,
|
||||
KGSL_TIMESTAMP_RETIRED, &drawctxt->internal_timestamp);
|
||||
}
|
||||
write_unlock(&device->context_lock);
|
||||
}
|
||||
|
||||
static int _preemption_store(struct adreno_device *adreno_dev, bool val)
|
||||
{
|
||||
if (!(ADRENO_FEATURE(adreno_dev, ADRENO_PREEMPTION)) ||
|
||||
(test_bit(ADRENO_DEVICE_PREEMPTION,
|
||||
&adreno_dev->priv) == val))
|
||||
return 0;
|
||||
|
||||
return adreno_power_cycle(adreno_dev, change_preemption, NULL);
|
||||
}
|
||||
|
||||
static bool _preemption_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return adreno_is_preemption_enabled(adreno_dev);
|
||||
}
|
||||
|
||||
static unsigned int _preempt_count_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return adreno_dev->preempt.count;
|
||||
}
|
||||
|
||||
static ADRENO_SYSFS_BOOL(preemption);
|
||||
static ADRENO_SYSFS_U32(preempt_level);
|
||||
static ADRENO_SYSFS_BOOL(usesgmem);
|
||||
static ADRENO_SYSFS_BOOL(skipsaverestore);
|
||||
static ADRENO_SYSFS_RO_U32(preempt_count);
|
||||
|
||||
static const struct attribute *_preempt_attr_list[] = {
|
||||
&adreno_attr_preemption.attr.attr,
|
||||
&adreno_attr_preempt_level.attr.attr,
|
||||
&adreno_attr_usesgmem.attr.attr,
|
||||
&adreno_attr_skipsaverestore.attr.attr,
|
||||
&adreno_attr_preempt_count.attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/**
|
||||
* adreno_dispatcher_close() - close the dispatcher
|
||||
* @adreno_dev: pointer to the adreno device structure
|
||||
|
|
@ -2669,6 +2781,7 @@ void adreno_dispatcher_close(struct adreno_device *adreno_dev)
|
|||
struct adreno_dispatcher *dispatcher = &adreno_dev->dispatcher;
|
||||
int i;
|
||||
struct adreno_ringbuffer *rb;
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
|
||||
mutex_lock(&dispatcher->mutex);
|
||||
del_timer_sync(&dispatcher->timer);
|
||||
|
|
@ -2690,6 +2803,8 @@ void adreno_dispatcher_close(struct adreno_device *adreno_dev)
|
|||
kobject_put(&dispatcher->kobj);
|
||||
|
||||
kmem_cache_destroy(jobs_cache);
|
||||
|
||||
sysfs_remove_files(&device->dev->kobj, _preempt_attr_list);
|
||||
}
|
||||
|
||||
struct dispatcher_attribute {
|
||||
|
|
@ -2839,6 +2954,8 @@ int adreno_dispatcher_init(struct adreno_device *adreno_dev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
sysfs_create_files(&device->dev->kobj, _preempt_attr_list);
|
||||
|
||||
mutex_init(&dispatcher->mutex);
|
||||
|
||||
timer_setup(&dispatcher->timer, adreno_dispatcher_timer, 0);
|
||||
|
|
|
|||
|
|
@ -6,18 +6,7 @@
|
|||
#include <linux/sysfs.h>
|
||||
|
||||
#include "adreno.h"
|
||||
|
||||
struct adreno_sysfs_attribute_u32 {
|
||||
struct device_attribute attr;
|
||||
u32 (*show)(struct adreno_device *adreno_dev);
|
||||
int (*store)(struct adreno_device *adreno_dev, u32 val);
|
||||
};
|
||||
|
||||
struct adreno_sysfs_attribute_bool {
|
||||
struct device_attribute attr;
|
||||
bool (*show)(struct adreno_device *adreno_dev);
|
||||
int (*store)(struct adreno_device *adreno_dev, bool val);
|
||||
};
|
||||
#include "adreno_sysfs.h"
|
||||
|
||||
static int _ft_policy_store(struct adreno_device *adreno_dev,
|
||||
unsigned int val)
|
||||
|
|
@ -31,47 +20,6 @@ static unsigned int _ft_policy_show(struct adreno_device *adreno_dev)
|
|||
return adreno_dev->ft_policy;
|
||||
}
|
||||
|
||||
static int _preempt_level_store(struct adreno_device *adreno_dev,
|
||||
unsigned int val)
|
||||
{
|
||||
struct adreno_preemption *preempt = &adreno_dev->preempt;
|
||||
|
||||
if (val <= 2)
|
||||
preempt->preempt_level = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int _preempt_level_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return adreno_dev->preempt.preempt_level;
|
||||
}
|
||||
|
||||
static int _usesgmem_store(struct adreno_device *adreno_dev, bool val)
|
||||
{
|
||||
struct adreno_preemption *preempt = &adreno_dev->preempt;
|
||||
|
||||
preempt->usesgmem = val ? true : false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool _usesgmem_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return adreno_dev->preempt.usesgmem;
|
||||
}
|
||||
|
||||
static int _skipsaverestore_store(struct adreno_device *adreno_dev, bool val)
|
||||
{
|
||||
struct adreno_preemption *preempt = &adreno_dev->preempt;
|
||||
|
||||
preempt->skipsaverestore = val ? true : false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool _skipsaverestore_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return adreno_dev->preempt.skipsaverestore;
|
||||
}
|
||||
|
||||
static int _ft_pagefault_policy_store(struct adreno_device *adreno_dev,
|
||||
unsigned int val)
|
||||
{
|
||||
|
|
@ -139,62 +87,6 @@ static bool _ft_hang_intr_status_show(struct adreno_device *adreno_dev)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void change_preemption(struct adreno_device *adreno_dev, void *priv)
|
||||
{
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
struct kgsl_context *context;
|
||||
struct adreno_context *drawctxt;
|
||||
struct adreno_ringbuffer *rb;
|
||||
int id, i, ret;
|
||||
|
||||
/* Make sure all ringbuffers are finished */
|
||||
FOR_EACH_RINGBUFFER(adreno_dev, rb, i) {
|
||||
ret = adreno_ringbuffer_waittimestamp(rb, rb->timestamp,
|
||||
2 * 1000);
|
||||
if (ret) {
|
||||
dev_err(device->dev,
|
||||
"Cannot disable preemption because couldn't idle ringbuffer[%d] ret: %d\n",
|
||||
rb->id, ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
change_bit(ADRENO_DEVICE_PREEMPTION, &adreno_dev->priv);
|
||||
adreno_dev->cur_rb = &adreno_dev->ringbuffers[0];
|
||||
adreno_dev->next_rb = NULL;
|
||||
adreno_dev->prev_rb = NULL;
|
||||
|
||||
/* Update the ringbuffer for each draw context */
|
||||
write_lock(&device->context_lock);
|
||||
idr_for_each_entry(&device->context_idr, context, id) {
|
||||
drawctxt = ADRENO_CONTEXT(context);
|
||||
drawctxt->rb = adreno_ctx_get_rb(adreno_dev, drawctxt);
|
||||
|
||||
/*
|
||||
* Make sure context destroy checks against the correct
|
||||
* ringbuffer's timestamp.
|
||||
*/
|
||||
adreno_rb_readtimestamp(adreno_dev, drawctxt->rb,
|
||||
KGSL_TIMESTAMP_RETIRED, &drawctxt->internal_timestamp);
|
||||
}
|
||||
write_unlock(&device->context_lock);
|
||||
}
|
||||
|
||||
static int _preemption_store(struct adreno_device *adreno_dev, bool val)
|
||||
{
|
||||
if (!(ADRENO_FEATURE(adreno_dev, ADRENO_PREEMPTION)) ||
|
||||
(test_bit(ADRENO_DEVICE_PREEMPTION,
|
||||
&adreno_dev->priv) == val))
|
||||
return 0;
|
||||
|
||||
return adreno_power_cycle(adreno_dev, change_preemption, NULL);
|
||||
}
|
||||
|
||||
static bool _preemption_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return adreno_is_preemption_enabled(adreno_dev);
|
||||
}
|
||||
|
||||
static int _hwcg_store(struct adreno_device *adreno_dev, bool val)
|
||||
{
|
||||
if (adreno_dev->hwcg_enabled == val)
|
||||
|
|
@ -269,13 +161,6 @@ static unsigned int _ifpc_count_show(struct adreno_device *adreno_dev)
|
|||
return adreno_dev->ifpc_count;
|
||||
}
|
||||
|
||||
static unsigned int _preempt_count_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
struct adreno_preemption *preempt = &adreno_dev->preempt;
|
||||
|
||||
return preempt->count;
|
||||
}
|
||||
|
||||
static bool _acd_show(struct adreno_device *adreno_dev)
|
||||
{
|
||||
return adreno_dev->acd_enabled;
|
||||
|
|
@ -301,9 +186,8 @@ static int _bcl_store(struct adreno_device *adreno_dev, bool val)
|
|||
val);
|
||||
}
|
||||
|
||||
static ssize_t _sysfs_store_u32(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
ssize_t adreno_sysfs_store_u32(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
struct adreno_device *adreno_dev = ADRENO_DEVICE(dev_get_drvdata(dev));
|
||||
struct adreno_sysfs_attribute_u32 *_attr =
|
||||
|
|
@ -322,9 +206,8 @@ static ssize_t _sysfs_store_u32(struct device *dev,
|
|||
return count;
|
||||
}
|
||||
|
||||
static ssize_t _sysfs_show_u32(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
ssize_t adreno_sysfs_show_u32(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct adreno_device *adreno_dev = ADRENO_DEVICE(dev_get_drvdata(dev));
|
||||
struct adreno_sysfs_attribute_u32 *_attr =
|
||||
|
|
@ -333,9 +216,8 @@ static ssize_t _sysfs_show_u32(struct device *dev,
|
|||
return scnprintf(buf, PAGE_SIZE, "0x%X\n", _attr->show(adreno_dev));
|
||||
}
|
||||
|
||||
static ssize_t _sysfs_store_bool(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
ssize_t adreno_sysfs_store_bool(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
struct adreno_device *adreno_dev = ADRENO_DEVICE(dev_get_drvdata(dev));
|
||||
struct adreno_sysfs_attribute_bool *_attr =
|
||||
|
|
@ -354,9 +236,8 @@ static ssize_t _sysfs_store_bool(struct device *dev,
|
|||
return count;
|
||||
}
|
||||
|
||||
static ssize_t _sysfs_show_bool(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
ssize_t adreno_sysfs_show_bool(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct adreno_device *adreno_dev = ADRENO_DEVICE(dev_get_drvdata(dev));
|
||||
struct adreno_sysfs_attribute_bool *_attr =
|
||||
|
|
@ -364,39 +245,8 @@ static ssize_t _sysfs_show_bool(struct device *dev,
|
|||
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", _attr->show(adreno_dev));
|
||||
}
|
||||
|
||||
#define ADRENO_SYSFS_BOOL(_name) \
|
||||
struct adreno_sysfs_attribute_bool adreno_attr_##_name = { \
|
||||
.attr = __ATTR(_name, 0644, _sysfs_show_bool, _sysfs_store_bool), \
|
||||
.show = _ ## _name ## _show, \
|
||||
.store = _ ## _name ## _store, \
|
||||
}
|
||||
|
||||
#define ADRENO_SYSFS_RO_BOOL(_name) \
|
||||
struct adreno_sysfs_attribute_bool adreno_attr_##_name = { \
|
||||
.attr = __ATTR(_name, 0444, _sysfs_show_bool, NULL), \
|
||||
.show = _ ## _name ## _show, \
|
||||
}
|
||||
|
||||
#define ADRENO_SYSFS_U32(_name) \
|
||||
struct adreno_sysfs_attribute_u32 adreno_attr_##_name = { \
|
||||
.attr = __ATTR(_name, 0644, _sysfs_show_u32, _sysfs_store_u32), \
|
||||
.show = _ ## _name ## _show, \
|
||||
.store = _ ## _name ## _store, \
|
||||
}
|
||||
|
||||
#define ADRENO_SYSFS_RO_U32(_name) \
|
||||
struct adreno_sysfs_attribute_u32 adreno_attr_##_name = { \
|
||||
.attr = __ATTR(_name, 0444, _sysfs_show_u32, NULL), \
|
||||
.show = _ ## _name ## _show, \
|
||||
}
|
||||
|
||||
static ADRENO_SYSFS_U32(ft_policy);
|
||||
static ADRENO_SYSFS_U32(ft_pagefault_policy);
|
||||
static ADRENO_SYSFS_U32(preempt_level);
|
||||
static ADRENO_SYSFS_RO_U32(preempt_count);
|
||||
static ADRENO_SYSFS_BOOL(usesgmem);
|
||||
static ADRENO_SYSFS_BOOL(skipsaverestore);
|
||||
static ADRENO_SYSFS_BOOL(ft_long_ib_detect);
|
||||
static ADRENO_SYSFS_RO_BOOL(ft_hang_intr_status);
|
||||
static ADRENO_SYSFS_BOOL(gpu_llc_slice_enable);
|
||||
|
|
@ -407,7 +257,6 @@ static DEVICE_INT_ATTR(wake_timeout, 0644, adreno_wake_timeout);
|
|||
|
||||
static ADRENO_SYSFS_BOOL(sptp_pc);
|
||||
static ADRENO_SYSFS_BOOL(lm);
|
||||
static ADRENO_SYSFS_BOOL(preemption);
|
||||
static ADRENO_SYSFS_BOOL(hwcg);
|
||||
static ADRENO_SYSFS_BOOL(throttling);
|
||||
static ADRENO_SYSFS_BOOL(ifpc);
|
||||
|
|
@ -425,17 +274,12 @@ static const struct attribute *_attr_list[] = {
|
|||
&dev_attr_wake_timeout.attr.attr,
|
||||
&adreno_attr_sptp_pc.attr.attr,
|
||||
&adreno_attr_lm.attr.attr,
|
||||
&adreno_attr_preemption.attr.attr,
|
||||
&adreno_attr_hwcg.attr.attr,
|
||||
&adreno_attr_throttling.attr.attr,
|
||||
&adreno_attr_gpu_llc_slice_enable.attr.attr,
|
||||
&adreno_attr_gpuhtw_llc_slice_enable.attr.attr,
|
||||
&adreno_attr_preempt_level.attr.attr,
|
||||
&adreno_attr_usesgmem.attr.attr,
|
||||
&adreno_attr_skipsaverestore.attr.attr,
|
||||
&adreno_attr_ifpc.attr.attr,
|
||||
&adreno_attr_ifpc_count.attr.attr,
|
||||
&adreno_attr_preempt_count.attr.attr,
|
||||
&adreno_attr_acd.attr.attr,
|
||||
&adreno_attr_bcl.attr.attr,
|
||||
NULL,
|
||||
|
|
|
|||
78
drivers/gpu/msm/adreno_sysfs.h
Normal file
78
drivers/gpu/msm/adreno_sysfs.h
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _ADRENO_SYSFS_H_
|
||||
#define _ADRENO_SYSFS_H_
|
||||
|
||||
/*
|
||||
* struct adreno_sysfs_attribute_u32 - Container for accessing and modifying
|
||||
* integers in kgsl via sysfs
|
||||
*/
|
||||
struct adreno_sysfs_attribute_u32 {
|
||||
/** #attr: The device attribute corresponding to the sysfs node */
|
||||
struct device_attribute attr;
|
||||
/** @show: Function to show the value of the integer */
|
||||
u32 (*show)(struct adreno_device *adreno_dev);
|
||||
/** @store: Function to store the value of the integer */
|
||||
int (*store)(struct adreno_device *adreno_dev, u32 val);
|
||||
};
|
||||
|
||||
/*
|
||||
* struct adreno_sysfs_attribute_bool - Container for accessing and modifying
|
||||
* booleans in kgsl via sysfs
|
||||
*/
|
||||
struct adreno_sysfs_attribute_bool {
|
||||
/** #attr: The device attribute corresponding to the sysfs node */
|
||||
struct device_attribute attr;
|
||||
/** @show: Function to show the value of the boolean */
|
||||
bool (*show)(struct adreno_device *adreno_dev);
|
||||
/** @store: Function to store the value of the boolean */
|
||||
int (*store)(struct adreno_device *adreno_dev, bool val);
|
||||
};
|
||||
|
||||
/* Helper function to modify an integer in kgsl */
|
||||
ssize_t adreno_sysfs_store_u32(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count);
|
||||
|
||||
/* Helper function to read an integer in kgsl */
|
||||
ssize_t adreno_sysfs_show_u32(struct device *dev,
|
||||
struct device_attribute *attr, char *buf);
|
||||
|
||||
/* Helper function to modify a boolean in kgsl */
|
||||
ssize_t adreno_sysfs_store_bool(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count);
|
||||
|
||||
/* Helper function to read a boolean in kgsl */
|
||||
ssize_t adreno_sysfs_show_bool(struct device *dev,
|
||||
struct device_attribute *attr, char *buf);
|
||||
|
||||
#define ADRENO_SYSFS_BOOL(_name) \
|
||||
struct adreno_sysfs_attribute_bool adreno_attr_##_name = { \
|
||||
.attr = __ATTR(_name, 0644, adreno_sysfs_show_bool, \
|
||||
adreno_sysfs_store_bool), \
|
||||
.show = _ ## _name ## _show, \
|
||||
.store = _ ## _name ## _store, \
|
||||
}
|
||||
|
||||
#define ADRENO_SYSFS_RO_BOOL(_name) \
|
||||
struct adreno_sysfs_attribute_bool adreno_attr_##_name = { \
|
||||
.attr = __ATTR(_name, 0444, adreno_sysfs_show_bool, NULL), \
|
||||
.show = _ ## _name ## _show, \
|
||||
}
|
||||
|
||||
#define ADRENO_SYSFS_U32(_name) \
|
||||
struct adreno_sysfs_attribute_u32 adreno_attr_##_name = { \
|
||||
.attr = __ATTR(_name, 0644, adreno_sysfs_show_u32, \
|
||||
adreno_sysfs_store_u32), \
|
||||
.show = _ ## _name ## _show, \
|
||||
.store = _ ## _name ## _store, \
|
||||
}
|
||||
|
||||
#define ADRENO_SYSFS_RO_U32(_name) \
|
||||
struct adreno_sysfs_attribute_u32 adreno_attr_##_name = { \
|
||||
.attr = __ATTR(_name, 0444, adreno_sysfs_show_u32, NULL), \
|
||||
.show = _ ## _name ## _show, \
|
||||
}
|
||||
#endif
|
||||
Loading…
Reference in a new issue