1*f286066eSPranjal Ramajor Asha Kanojiya // SPDX-License-Identifier: GPL-2.0-only 2*f286066eSPranjal Ramajor Asha Kanojiya 3*f286066eSPranjal Ramajor Asha Kanojiya /* Copyright (c) 2020-2025, The Linux Foundation. All rights reserved. */ 4*f286066eSPranjal Ramajor Asha Kanojiya 5*f286066eSPranjal Ramajor Asha Kanojiya #include <drm/drm_file.h> 6*f286066eSPranjal Ramajor Asha Kanojiya #include <drm/drm_managed.h> 7*f286066eSPranjal Ramajor Asha Kanojiya #include <linux/device.h> 8*f286066eSPranjal Ramajor Asha Kanojiya #include <linux/kernel.h> 9*f286066eSPranjal Ramajor Asha Kanojiya #include <linux/kobject.h> 10*f286066eSPranjal Ramajor Asha Kanojiya #include <linux/mutex.h> 11*f286066eSPranjal Ramajor Asha Kanojiya #include <linux/sysfs.h> 12*f286066eSPranjal Ramajor Asha Kanojiya 13*f286066eSPranjal Ramajor Asha Kanojiya #include "qaic.h" 14*f286066eSPranjal Ramajor Asha Kanojiya 15*f286066eSPranjal Ramajor Asha Kanojiya #define NAME_LEN 14 16*f286066eSPranjal Ramajor Asha Kanojiya 17*f286066eSPranjal Ramajor Asha Kanojiya struct dbc_attribute { 18*f286066eSPranjal Ramajor Asha Kanojiya struct device_attribute dev_attr; 19*f286066eSPranjal Ramajor Asha Kanojiya u32 dbc_id; 20*f286066eSPranjal Ramajor Asha Kanojiya char name[NAME_LEN]; 21*f286066eSPranjal Ramajor Asha Kanojiya }; 22*f286066eSPranjal Ramajor Asha Kanojiya 23*f286066eSPranjal Ramajor Asha Kanojiya static ssize_t dbc_state_show(struct device *dev, struct device_attribute *a, char *buf) 24*f286066eSPranjal Ramajor Asha Kanojiya { 25*f286066eSPranjal Ramajor Asha Kanojiya struct dbc_attribute *dbc_attr = container_of(a, struct dbc_attribute, dev_attr); 26*f286066eSPranjal Ramajor Asha Kanojiya struct drm_minor *minor = dev_get_drvdata(dev); 27*f286066eSPranjal Ramajor Asha Kanojiya struct qaic_device *qdev; 28*f286066eSPranjal Ramajor Asha Kanojiya 29*f286066eSPranjal Ramajor Asha Kanojiya qdev = to_qaic_device(minor->dev); 30*f286066eSPranjal Ramajor Asha Kanojiya return sysfs_emit(buf, "%d\n", qdev->dbc[dbc_attr->dbc_id].state); 31*f286066eSPranjal Ramajor Asha Kanojiya } 32*f286066eSPranjal Ramajor Asha Kanojiya 33*f286066eSPranjal Ramajor Asha Kanojiya void set_dbc_state(struct qaic_device *qdev, u32 dbc_id, unsigned int state) 34*f286066eSPranjal Ramajor Asha Kanojiya { 35*f286066eSPranjal Ramajor Asha Kanojiya struct device *kdev = to_accel_kdev(qdev->qddev); 36*f286066eSPranjal Ramajor Asha Kanojiya char *envp[3] = {}; 37*f286066eSPranjal Ramajor Asha Kanojiya char state_str[16]; 38*f286066eSPranjal Ramajor Asha Kanojiya char id_str[12]; 39*f286066eSPranjal Ramajor Asha Kanojiya 40*f286066eSPranjal Ramajor Asha Kanojiya envp[0] = id_str; 41*f286066eSPranjal Ramajor Asha Kanojiya envp[1] = state_str; 42*f286066eSPranjal Ramajor Asha Kanojiya 43*f286066eSPranjal Ramajor Asha Kanojiya if (state >= DBC_STATE_MAX) 44*f286066eSPranjal Ramajor Asha Kanojiya return; 45*f286066eSPranjal Ramajor Asha Kanojiya if (dbc_id >= qdev->num_dbc) 46*f286066eSPranjal Ramajor Asha Kanojiya return; 47*f286066eSPranjal Ramajor Asha Kanojiya if (state == qdev->dbc[dbc_id].state) 48*f286066eSPranjal Ramajor Asha Kanojiya return; 49*f286066eSPranjal Ramajor Asha Kanojiya 50*f286066eSPranjal Ramajor Asha Kanojiya scnprintf(id_str, ARRAY_SIZE(id_str), "DBC_ID=%d", dbc_id); 51*f286066eSPranjal Ramajor Asha Kanojiya scnprintf(state_str, ARRAY_SIZE(state_str), "DBC_STATE=%d", state); 52*f286066eSPranjal Ramajor Asha Kanojiya 53*f286066eSPranjal Ramajor Asha Kanojiya qdev->dbc[dbc_id].state = state; 54*f286066eSPranjal Ramajor Asha Kanojiya kobject_uevent_env(&kdev->kobj, KOBJ_CHANGE, envp); 55*f286066eSPranjal Ramajor Asha Kanojiya } 56*f286066eSPranjal Ramajor Asha Kanojiya 57*f286066eSPranjal Ramajor Asha Kanojiya int qaic_sysfs_init(struct qaic_drm_device *qddev) 58*f286066eSPranjal Ramajor Asha Kanojiya { 59*f286066eSPranjal Ramajor Asha Kanojiya struct device *kdev = to_accel_kdev(qddev); 60*f286066eSPranjal Ramajor Asha Kanojiya struct drm_device *drm = to_drm(qddev); 61*f286066eSPranjal Ramajor Asha Kanojiya u32 num_dbc = qddev->qdev->num_dbc; 62*f286066eSPranjal Ramajor Asha Kanojiya struct dbc_attribute *dbc_attrs; 63*f286066eSPranjal Ramajor Asha Kanojiya int i, ret; 64*f286066eSPranjal Ramajor Asha Kanojiya 65*f286066eSPranjal Ramajor Asha Kanojiya dbc_attrs = drmm_kcalloc(drm, num_dbc, sizeof(*dbc_attrs), GFP_KERNEL); 66*f286066eSPranjal Ramajor Asha Kanojiya if (!dbc_attrs) 67*f286066eSPranjal Ramajor Asha Kanojiya return -ENOMEM; 68*f286066eSPranjal Ramajor Asha Kanojiya 69*f286066eSPranjal Ramajor Asha Kanojiya for (i = 0; i < num_dbc; ++i) { 70*f286066eSPranjal Ramajor Asha Kanojiya struct dbc_attribute *dbc_attr = &dbc_attrs[i]; 71*f286066eSPranjal Ramajor Asha Kanojiya 72*f286066eSPranjal Ramajor Asha Kanojiya sysfs_attr_init(&dbc_attr->dev_attr.attr); 73*f286066eSPranjal Ramajor Asha Kanojiya dbc_attr->dbc_id = i; 74*f286066eSPranjal Ramajor Asha Kanojiya scnprintf(dbc_attr->name, NAME_LEN, "dbc%d_state", i); 75*f286066eSPranjal Ramajor Asha Kanojiya dbc_attr->dev_attr.attr.name = dbc_attr->name; 76*f286066eSPranjal Ramajor Asha Kanojiya dbc_attr->dev_attr.attr.mode = 0444; 77*f286066eSPranjal Ramajor Asha Kanojiya dbc_attr->dev_attr.show = dbc_state_show; 78*f286066eSPranjal Ramajor Asha Kanojiya ret = sysfs_create_file(&kdev->kobj, &dbc_attr->dev_attr.attr); 79*f286066eSPranjal Ramajor Asha Kanojiya if (ret) { 80*f286066eSPranjal Ramajor Asha Kanojiya int j; 81*f286066eSPranjal Ramajor Asha Kanojiya 82*f286066eSPranjal Ramajor Asha Kanojiya for (j = 0; j < i; ++j) { 83*f286066eSPranjal Ramajor Asha Kanojiya dbc_attr = &dbc_attrs[j]; 84*f286066eSPranjal Ramajor Asha Kanojiya sysfs_remove_file(&kdev->kobj, &dbc_attr->dev_attr.attr); 85*f286066eSPranjal Ramajor Asha Kanojiya } 86*f286066eSPranjal Ramajor Asha Kanojiya drmm_kfree(drm, dbc_attrs); 87*f286066eSPranjal Ramajor Asha Kanojiya return ret; 88*f286066eSPranjal Ramajor Asha Kanojiya } 89*f286066eSPranjal Ramajor Asha Kanojiya } 90*f286066eSPranjal Ramajor Asha Kanojiya 91*f286066eSPranjal Ramajor Asha Kanojiya qddev->sysfs_attrs = dbc_attrs; 92*f286066eSPranjal Ramajor Asha Kanojiya return 0; 93*f286066eSPranjal Ramajor Asha Kanojiya } 94*f286066eSPranjal Ramajor Asha Kanojiya 95*f286066eSPranjal Ramajor Asha Kanojiya void qaic_sysfs_remove(struct qaic_drm_device *qddev) 96*f286066eSPranjal Ramajor Asha Kanojiya { 97*f286066eSPranjal Ramajor Asha Kanojiya struct dbc_attribute *dbc_attrs = qddev->sysfs_attrs; 98*f286066eSPranjal Ramajor Asha Kanojiya struct device *kdev = to_accel_kdev(qddev); 99*f286066eSPranjal Ramajor Asha Kanojiya u32 num_dbc = qddev->qdev->num_dbc; 100*f286066eSPranjal Ramajor Asha Kanojiya int i; 101*f286066eSPranjal Ramajor Asha Kanojiya 102*f286066eSPranjal Ramajor Asha Kanojiya if (!dbc_attrs) 103*f286066eSPranjal Ramajor Asha Kanojiya return; 104*f286066eSPranjal Ramajor Asha Kanojiya 105*f286066eSPranjal Ramajor Asha Kanojiya qddev->sysfs_attrs = NULL; 106*f286066eSPranjal Ramajor Asha Kanojiya for (i = 0; i < num_dbc; ++i) 107*f286066eSPranjal Ramajor Asha Kanojiya sysfs_remove_file(&kdev->kobj, &dbc_attrs[i].dev_attr.attr); 108*f286066eSPranjal Ramajor Asha Kanojiya drmm_kfree(to_drm(qddev), dbc_attrs); 109*f286066eSPranjal Ramajor Asha Kanojiya } 110