summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeYuan Wang <kamewang@google.com>2021-08-05 22:30:03 +0800
committerTeYuan Wang <kamewang@google.com>2021-08-09 15:42:43 +0800
commit2d0d4e612e61743598241837bbc7912bc8b94474 (patch)
treea63d817ea82a671f084f33f1127d32fa581064de
parent23e7c6f5bebb9f80ab97bec076ee9ae626620af7 (diff)
downloadedgetpu-2d0d4e612e61743598241837bbc7912bc8b94474.tar.gz
edgetpu: add user_vote for user space request TPU throttling
For the current upstream design, userspace can request cooling device via "cur_state" sysfs. However, the request will be overwritten by other kernel governor or it will overwrite other governor's request. So, create this user_vote sysfs for userspace to request cooling device and vote with other kernel governor's request. Bug: 188701596 Test: build Change-Id: I6ea5c1a5f5fdeb72f78f69fa7cc833f5f464d28e Signed-off-by: TeYuan Wang <kamewang@google.com>
-rw-r--r--drivers/edgetpu/abrolhos-thermal.c45
-rw-r--r--drivers/edgetpu/edgetpu-thermal.h1
2 files changed, 45 insertions, 1 deletions
diff --git a/drivers/edgetpu/abrolhos-thermal.c b/drivers/edgetpu/abrolhos-thermal.c
index a8a0016..6e7141f 100644
--- a/drivers/edgetpu/abrolhos-thermal.c
+++ b/drivers/edgetpu/abrolhos-thermal.c
@@ -78,6 +78,8 @@ static int edgetpu_set_cur_state(struct thermal_cooling_device *cdev,
return -EINVAL;
}
+ state_original = max(cooling->sysfs_req, state_original);
+
mutex_lock(&cooling->lock);
pwr_state = state_pwr_map[state_original].state;
if (state_original != cooling->cooling_state) {
@@ -281,6 +283,46 @@ error:
return -EINVAL;
}
+static ssize_t
+user_vote_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct thermal_cooling_device *cdev = container_of(dev, struct thermal_cooling_device, device);
+ struct edgetpu_thermal *cooling = cdev->devdata;
+
+ if (!cooling)
+ return -ENODEV;
+
+ return sysfs_emit(buf, "%lu\n", cooling->sysfs_req);
+}
+
+static ssize_t user_vote_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct thermal_cooling_device *cdev = container_of(dev, struct thermal_cooling_device, device);
+ struct edgetpu_thermal *cooling = cdev->devdata;
+ int ret;
+ unsigned long state;
+
+ if (!cooling)
+ return -ENODEV;
+
+ ret = kstrtoul(buf, 0, &state);
+ if (ret)
+ return ret;
+
+ if (state >= cooling->tpu_num_states)
+ return -EINVAL;
+
+ mutex_lock(&cdev->lock);
+ cooling->sysfs_req = state;
+ cdev->updated = false;
+ mutex_unlock(&cdev->lock);
+ thermal_cdev_update(cdev);
+ return count;
+}
+
+static DEVICE_ATTR_RW(user_vote);
+
static int
tpu_thermal_cooling_register(struct edgetpu_thermal *thermal, char *type)
{
@@ -304,7 +346,8 @@ tpu_thermal_cooling_register(struct edgetpu_thermal *thermal, char *type)
cooling_node, type, thermal, &edgetpu_cooling_ops);
if (IS_ERR(thermal->cdev))
return PTR_ERR(thermal->cdev);
- return 0;
+
+ return device_create_file(&thermal->cdev->device, &dev_attr_user_vote);
}
static int tpu_thermal_init(struct edgetpu_thermal *thermal, struct device *dev)
diff --git a/drivers/edgetpu/edgetpu-thermal.h b/drivers/edgetpu/edgetpu-thermal.h
index 8d4b23f..dbd283f 100644
--- a/drivers/edgetpu/edgetpu-thermal.h
+++ b/drivers/edgetpu/edgetpu-thermal.h
@@ -23,6 +23,7 @@ struct edgetpu_thermal {
struct mutex lock;
void *op_data;
unsigned long cooling_state;
+ unsigned long sysfs_req;
unsigned int tpu_num_states;
struct edgetpu_dev *etdev;
bool thermal_suspended; /* TPU thermal suspended state */