Squashed backup commit (no shallow-clone history issues) of xiaomi-mt6833-dev/kernel_xiaomi_mt6833 (lineage-23.2 branch, upstream commit 9eece662e) plus all fixes applied to get everpal_defconfig building clean against a modern (GCC 15.2.0) toolchain -- see the previous commit message on the lineage-23.2 branch (also in this repo history is not available here since this is a squashed snapshot; full incremental history lives in the local DL380 checkout and the upstream GitHub remote). Upstream: https://github.com/xiaomi-mt6833-dev/kernel_xiaomi_mt6833 (lineage-23.2)
249 lines
4.8 KiB
C
249 lines
4.8 KiB
C
/*
|
|
* Copyright (C) 2020 MediaTek Inc.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#include <linux/types.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/list.h>
|
|
#include <linux/slab.h>
|
|
|
|
#include <linux/rbtree.h>
|
|
#include <linux/debugfs.h>
|
|
#include <apusys_device.h>
|
|
#include <linux/ktime.h>
|
|
|
|
#include "mdw_cmn.h"
|
|
#include "mdw_cmd.h"
|
|
#include "mdw_rsc.h"
|
|
#include "mdw_queue.h"
|
|
|
|
#define MAX_BOOST (100)
|
|
|
|
static struct mdw_cmd_parser *cmd_parser;
|
|
|
|
//--------------------------------------
|
|
int mdw_queue_task_start(struct mdw_apu_sc *sc)
|
|
{
|
|
struct mdw_queue *mq = NULL;
|
|
int ret = 0;
|
|
|
|
mdw_flw_debug("\n");
|
|
|
|
/* get queue */
|
|
mq = mdw_rsc_get_queue(sc->type);
|
|
if (!mq)
|
|
return -ENODEV;
|
|
|
|
/* normal task*/
|
|
if (sc->period == 0) {
|
|
struct deadline_root *rt_root;
|
|
struct mdw_rsc_tab *rt_tab;
|
|
|
|
if (sc->type < APUSYS_DEVICE_RT) {
|
|
rt_tab = mdw_rsc_get_tab(sc->type + APUSYS_DEVICE_RT);
|
|
rt_root = &rt_tab->q.deadline;
|
|
if (rt_tab != NULL && rt_root->need_timer)
|
|
sc->cluster_size = INT_MAX;
|
|
}
|
|
}
|
|
|
|
if (cmd_parser->is_deadline(sc)) {
|
|
ret = mq->deadline.ops.task_start(sc, &mq->deadline);
|
|
if (!ret) {
|
|
mutex_lock(&mq->mtx);
|
|
mq->deadline_task_num++;
|
|
mutex_unlock(&mq->mtx);
|
|
}
|
|
} else {
|
|
ret = mq->norm.ops.task_start(sc, &mq->norm);
|
|
if (!ret) {
|
|
mutex_lock(&mq->mtx);
|
|
mq->normal_task_num++;
|
|
mutex_unlock(&mq->mtx);
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int mdw_queue_task_end(struct mdw_apu_sc *sc)
|
|
{
|
|
struct mdw_queue *mq = NULL;
|
|
int ret = 0;
|
|
|
|
mdw_flw_debug("\n");
|
|
|
|
/* get queue */
|
|
mq = mdw_rsc_get_queue(sc->type);
|
|
if (!mq)
|
|
return -ENODEV;
|
|
|
|
if (cmd_parser->is_deadline(sc)) {
|
|
ret = mq->deadline.ops.task_end(sc, &mq->deadline);
|
|
if (!ret) {
|
|
mutex_lock(&mq->mtx);
|
|
mq->deadline_task_num--;
|
|
mutex_unlock(&mq->mtx);
|
|
}
|
|
} else {
|
|
ret = mq->norm.ops.task_end(sc, &mq->norm);
|
|
mutex_lock(&mq->mtx);
|
|
mq->normal_task_num--;
|
|
mutex_unlock(&mq->mtx);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
struct mdw_apu_sc *mdw_queue_pop(int type)
|
|
{
|
|
struct mdw_apu_sc *sc = NULL;
|
|
struct mdw_queue *mq = NULL;
|
|
|
|
mdw_flw_debug("\n");
|
|
|
|
/* get queue */
|
|
mq = mdw_rsc_get_queue(type);
|
|
if (!mq)
|
|
return NULL;
|
|
|
|
/* get sc */
|
|
if (mq->deadline.ops.len(&mq->deadline))
|
|
sc = mq->deadline.ops.pop(&mq->deadline);
|
|
else
|
|
sc = mq->norm.ops.pop(&mq->norm);
|
|
|
|
if (sc)
|
|
getnstimeofday(&sc->ts_deque);
|
|
|
|
return sc;
|
|
}
|
|
|
|
int mdw_queue_insert(struct mdw_apu_sc *sc, int is_front)
|
|
{
|
|
struct mdw_queue *mq = NULL;
|
|
|
|
mdw_flw_debug("\n");
|
|
getnstimeofday(&sc->ts_enque);
|
|
|
|
/* get queue */
|
|
mq = mdw_rsc_get_queue(sc->type);
|
|
if (!mq)
|
|
return -ENODEV;
|
|
|
|
if (cmd_parser->is_deadline(sc))
|
|
return mq->deadline.ops.insert(sc, &mq->deadline, is_front);
|
|
|
|
return mq->norm.ops.insert(sc, &mq->norm, is_front);
|
|
}
|
|
|
|
int mdw_queue_len(int type, int is_deadline)
|
|
{
|
|
struct mdw_queue *mq = NULL;
|
|
|
|
mdw_flw_debug("\n");
|
|
|
|
/* get queue */
|
|
mq = mdw_rsc_get_queue(type);
|
|
if (!mq)
|
|
return 0;
|
|
|
|
if (is_deadline)
|
|
return mq->deadline.ops.len(&mq->deadline);
|
|
|
|
return mq->norm.ops.len(&mq->norm);
|
|
}
|
|
|
|
int mdw_queue_delete(struct mdw_apu_sc *sc)
|
|
{
|
|
struct mdw_queue *mq = NULL;
|
|
|
|
mdw_flw_debug("\n");
|
|
|
|
/* get queue */
|
|
mq = mdw_rsc_get_queue(sc->type);
|
|
if (!mq)
|
|
return -ENODEV;
|
|
|
|
if (cmd_parser->is_deadline(sc))
|
|
return mq->deadline.ops.delete(sc, &mq->deadline);
|
|
|
|
return mq->norm.ops.delete(sc, &mq->norm);
|
|
}
|
|
|
|
int mdw_queue_boost(struct mdw_apu_sc *sc)
|
|
{
|
|
struct mdw_rsc_tab *tab = NULL;
|
|
struct deadline_root *root;
|
|
unsigned int suggest_time;
|
|
|
|
if (sc == NULL)
|
|
return 0;
|
|
|
|
suggest_time = sc->hdr->suggest_time * 1000;
|
|
|
|
tab = mdw_rsc_get_tab(sc->type);
|
|
root = &tab->q.deadline;
|
|
|
|
if (sc->hdr->suggest_time != 0) {
|
|
if (sc->hdr->driver_time < suggest_time)
|
|
sc->boost -= 10;
|
|
else if (sc->hdr->driver_time > suggest_time)
|
|
sc->boost += 10;
|
|
|
|
if (sc->boost > 100)
|
|
sc->boost = 100;
|
|
if (sc->boost < 0)
|
|
sc->boost = 0;
|
|
}
|
|
|
|
if (root->load_boost || root->trace_boost)
|
|
return MAX_BOOST;
|
|
else
|
|
return sc->boost;
|
|
}
|
|
|
|
void mdw_queue_destroy(struct mdw_queue *mq)
|
|
{
|
|
mdw_flw_debug("\n");
|
|
mq->deadline.ops.destroy(&mq->deadline);
|
|
mq->norm.ops.destroy(&mq->norm);
|
|
}
|
|
|
|
int mdw_queue_init(struct mdw_queue *mq)
|
|
{
|
|
int ret = 0;
|
|
|
|
mdw_flw_debug("\n");
|
|
|
|
cmd_parser = mdw_cmd_get_parser();
|
|
if (!cmd_parser)
|
|
return -ENODEV;
|
|
|
|
memset(mq, 0, sizeof(struct mdw_queue));
|
|
|
|
mutex_init(&mq->mtx);
|
|
|
|
ret = mdw_queue_deadline_init(&mq->deadline);
|
|
if (ret)
|
|
goto out;
|
|
|
|
ret = mdw_queue_norm_init(&mq->norm);
|
|
if (ret)
|
|
goto fail_init_norm;
|
|
|
|
fail_init_norm:
|
|
mq->deadline.ops.destroy(&mq->deadline);
|
|
out:
|
|
return ret;
|
|
}
|