mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-21 18:19:03 +07:00
drm/panfrost: use spinlock instead of atomic
Convert busy_count to a simple int protected by spinlock. Reviewed-by: Steven Price <steven.price@arm.com> Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> Signed-off-by: Clément Péron <peron.clem@gmail.com> Signed-off-by: Rob Herring <robh@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20200710095409.407087-6-peron.clem@gmail.com
This commit is contained in:
parent
9bfacfc82f
commit
ed85df3f60
@ -12,16 +12,12 @@
|
||||
|
||||
static void panfrost_devfreq_update_utilization(struct panfrost_devfreq *pfdevfreq)
|
||||
{
|
||||
ktime_t now;
|
||||
ktime_t last;
|
||||
|
||||
if (!pfdevfreq->devfreq)
|
||||
return;
|
||||
ktime_t now, last;
|
||||
|
||||
now = ktime_get();
|
||||
last = pfdevfreq->time_last_update;
|
||||
|
||||
if (atomic_read(&pfdevfreq->busy_count) > 0)
|
||||
if (pfdevfreq->busy_count > 0)
|
||||
pfdevfreq->busy_time += ktime_sub(now, last);
|
||||
else
|
||||
pfdevfreq->idle_time += ktime_sub(now, last);
|
||||
@ -59,10 +55,14 @@ static int panfrost_devfreq_get_dev_status(struct device *dev,
|
||||
{
|
||||
struct panfrost_device *pfdev = dev_get_drvdata(dev);
|
||||
struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
|
||||
unsigned long irqflags;
|
||||
|
||||
status->current_frequency = clk_get_rate(pfdev->clock);
|
||||
|
||||
spin_lock_irqsave(&pfdevfreq->lock, irqflags);
|
||||
|
||||
panfrost_devfreq_update_utilization(pfdevfreq);
|
||||
|
||||
status->current_frequency = clk_get_rate(pfdev->clock);
|
||||
status->total_time = ktime_to_ns(ktime_add(pfdevfreq->busy_time,
|
||||
pfdevfreq->idle_time));
|
||||
|
||||
@ -70,6 +70,8 @@ static int panfrost_devfreq_get_dev_status(struct device *dev,
|
||||
|
||||
panfrost_devfreq_reset(pfdevfreq);
|
||||
|
||||
spin_unlock_irqrestore(&pfdevfreq->lock, irqflags);
|
||||
|
||||
dev_dbg(pfdev->dev, "busy %lu total %lu %lu %% freq %lu MHz\n",
|
||||
status->busy_time, status->total_time,
|
||||
status->busy_time / (status->total_time / 100),
|
||||
@ -100,6 +102,8 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
|
||||
else if (ret)
|
||||
return ret;
|
||||
|
||||
spin_lock_init(&pfdevfreq->lock);
|
||||
|
||||
panfrost_devfreq_reset(pfdevfreq);
|
||||
|
||||
cur_freq = clk_get_rate(pfdev->clock);
|
||||
@ -162,15 +166,32 @@ void panfrost_devfreq_suspend(struct panfrost_device *pfdev)
|
||||
|
||||
void panfrost_devfreq_record_busy(struct panfrost_devfreq *pfdevfreq)
|
||||
{
|
||||
unsigned long irqflags;
|
||||
|
||||
if (!pfdevfreq->devfreq)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&pfdevfreq->lock, irqflags);
|
||||
|
||||
panfrost_devfreq_update_utilization(pfdevfreq);
|
||||
atomic_inc(&pfdevfreq->busy_count);
|
||||
|
||||
pfdevfreq->busy_count++;
|
||||
|
||||
spin_unlock_irqrestore(&pfdevfreq->lock, irqflags);
|
||||
}
|
||||
|
||||
void panfrost_devfreq_record_idle(struct panfrost_devfreq *pfdevfreq)
|
||||
{
|
||||
int count;
|
||||
unsigned long irqflags;
|
||||
|
||||
if (!pfdevfreq->devfreq)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&pfdevfreq->lock, irqflags);
|
||||
|
||||
panfrost_devfreq_update_utilization(pfdevfreq);
|
||||
count = atomic_dec_if_positive(&pfdevfreq->busy_count);
|
||||
WARN_ON(count < 0);
|
||||
|
||||
WARN_ON(--pfdevfreq->busy_count < 0);
|
||||
|
||||
spin_unlock_irqrestore(&pfdevfreq->lock, irqflags);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
#ifndef __PANFROST_DEVFREQ_H__
|
||||
#define __PANFROST_DEVFREQ_H__
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/ktime.h>
|
||||
|
||||
struct devfreq;
|
||||
@ -14,10 +15,16 @@ struct panfrost_device;
|
||||
struct panfrost_devfreq {
|
||||
struct devfreq *devfreq;
|
||||
struct thermal_cooling_device *cooling;
|
||||
|
||||
ktime_t busy_time;
|
||||
ktime_t idle_time;
|
||||
ktime_t time_last_update;
|
||||
atomic_t busy_count;
|
||||
int busy_count;
|
||||
/*
|
||||
* Protect busy_time, idle_time, time_last_update and busy_count
|
||||
* because these can be updated concurrently between multiple jobs.
|
||||
*/
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
int panfrost_devfreq_init(struct panfrost_device *pfdev);
|
||||
|
Loading…
Reference in New Issue
Block a user