PM / devfreq: rockchip_dmc: pass a pointer to devfreq in bandwidth request/update actions

By passing a pointer to struct devfreq, we can fix global data abuse issue.

Change-Id: I17f6264b86549f67d61d03f38da0127e666eee3c
Signed-off-by: Rocky Hao <rocky.hao@rock-chips.com>
This commit is contained in:
Rocky Hao 2018-01-08 12:06:45 +08:00 committed by Tao Huang
parent 8228a831e1
commit 33b1e41afd
5 changed files with 72 additions and 14 deletions

View File

@ -643,8 +643,6 @@ struct rockchip_dmcfreq {
int (*set_auto_self_refresh)(u32 en);
};
static struct rockchip_dmcfreq *rk_dmcfreq;
/*
* function: packaging de-skew setting to rk3328_ddr_dts_config_timing,
* rk3328_ddr_dts_config_timing will pass to trust firmware, and
@ -2052,12 +2050,19 @@ static ssize_t rockchip_dmcfreq_status_store(struct device *dev,
static DEVICE_ATTR(system_status, 0644, rockchip_dmcfreq_status_show,
rockchip_dmcfreq_status_store);
void rockchip_dmcfreq_vop_bandwidth_update(unsigned int bw_mbyte)
void rockchip_dmcfreq_vop_bandwidth_update(struct devfreq *devfreq,
unsigned int bw_mbyte)
{
struct rockchip_dmcfreq *dmcfreq = rk_dmcfreq;
struct device *dev;
struct rockchip_dmcfreq *dmcfreq;
unsigned long vop_last_rate, target = 0;
int i;
if (!devfreq)
return;
dev = devfreq->dev.parent;
dmcfreq = dev_get_drvdata(dev);
if (!dmcfreq || !dmcfreq->auto_freq_en || !dmcfreq->vop_bw_tbl)
return;
@ -2078,12 +2083,20 @@ void rockchip_dmcfreq_vop_bandwidth_update(unsigned int bw_mbyte)
rockchip_dmcfreq_update_target(dmcfreq);
}
int rockchip_dmcfreq_vop_bandwidth_request(unsigned int bw_mbyte)
int rockchip_dmcfreq_vop_bandwidth_request(struct devfreq *devfreq,
unsigned int bw_mbyte)
{
struct rockchip_dmcfreq *dmcfreq = rk_dmcfreq;
struct device *dev;
struct rockchip_dmcfreq *dmcfreq;
unsigned long target = 0;
int i;
if (!devfreq)
return 0;
dev = devfreq->dev.parent;
dmcfreq = dev_get_drvdata(dev);
if (!dmcfreq || !dmcfreq->auto_freq_en || !dmcfreq->vop_bw_tbl)
return 0;
@ -2481,8 +2494,6 @@ static int rockchip_dmcfreq_probe(struct platform_device *pdev)
rockchip_set_system_status(SYS_STATUS_NORMAL);
rk_dmcfreq = data;
ret = ddr_power_model_simple_init(data);
if (!ret) {

View File

@ -20,6 +20,7 @@
#include <drm/drm_fb_helper.h>
#include <drm/drm_sync_helper.h>
#include <drm/rockchip_drm.h>
#include <linux/devfreq.h>
#include <linux/dma-mapping.h>
#include <linux/dma-iommu.h>
#include <linux/genalloc.h>
@ -1264,6 +1265,8 @@ static int rockchip_drm_bind(struct device *dev)
struct drm_device *drm_dev;
struct rockchip_drm_private *private;
int ret;
struct device_node *np = dev->of_node;
struct device_node *parent_np;
drm_dev = drm_dev_alloc(&rockchip_drm_driver, dev);
if (!drm_dev)
@ -1286,6 +1289,27 @@ static int rockchip_drm_bind(struct device *dev)
drm_dev->dev_private = private;
private->dmc_support = false;
private->devfreq = devfreq_get_devfreq_by_phandle(dev, 0);
if (IS_ERR(private->devfreq)) {
if (PTR_ERR(private->devfreq) == -EPROBE_DEFER) {
parent_np = of_parse_phandle(np, "devfreq", 0);
if (parent_np &&
of_device_is_available(parent_np)) {
private->dmc_support = true;
dev_warn(dev, "defer getting devfreq\n");
} else {
dev_info(dev, "dmc is disabled\n");
}
} else {
dev_info(dev, "devfreq is not set\n");
}
private->devfreq = NULL;
} else {
private->dmc_support = true;
dev_info(dev, "devfreq is ready\n");
}
private->hdmi_pll.pll = devm_clk_get(dev, "hdmi-tmds-pll");
if (PTR_ERR(private->hdmi_pll.pll) == -ENOENT) {
private->hdmi_pll.pll = NULL;

View File

@ -197,6 +197,8 @@ struct rockchip_drm_private {
struct drm_mm mm;
struct rockchip_dclk_pll default_pll;
struct rockchip_dclk_pll hdmi_pll;
struct devfreq *devfreq;
bool dmc_support;
};
#ifndef MODULE

View File

@ -234,7 +234,15 @@ static int rockchip_drm_bandwidth_atomic_check(struct drm_device *dev,
/*
* Check ddr frequency support here here.
*/
ret = rockchip_dmcfreq_vop_bandwidth_request(*bandwidth);
if (priv->dmc_support && !priv->devfreq) {
priv->devfreq = devfreq_get_devfreq_by_phandle(dev->dev, 0);
if (IS_ERR(priv->devfreq))
priv->devfreq = NULL;
}
if (priv->devfreq)
ret = rockchip_dmcfreq_vop_bandwidth_request(priv->devfreq,
*bandwidth);
return ret;
}
@ -244,6 +252,7 @@ rockchip_atomic_commit_complete(struct rockchip_atomic_commit *commit)
{
struct drm_atomic_state *state = commit->state;
struct drm_device *dev = commit->dev;
struct rockchip_drm_private *prv = dev->dev_private;
size_t bandwidth = commit->bandwidth;
/*
@ -273,7 +282,13 @@ rockchip_atomic_commit_complete(struct rockchip_atomic_commit *commit)
rockchip_drm_backlight_update(dev);
rockchip_dmcfreq_vop_bandwidth_update(bandwidth);
if (prv->dmc_support && !prv->devfreq) {
prv->devfreq = devfreq_get_devfreq_by_phandle(dev->dev, 0);
if (IS_ERR(prv->devfreq))
prv->devfreq = NULL;
}
if (prv->devfreq)
rockchip_dmcfreq_vop_bandwidth_update(prv->devfreq, bandwidth);
drm_atomic_helper_commit_planes(dev, state, true);

View File

@ -33,15 +33,21 @@ dma_addr_t rockchip_fb_get_dma_addr(struct drm_framebuffer *fb,
unsigned int plane);
#ifdef CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ
int rockchip_dmcfreq_vop_bandwidth_request(unsigned int bw_mbyte);
void rockchip_dmcfreq_vop_bandwidth_update(unsigned int bw_mbyte);
int rockchip_dmcfreq_vop_bandwidth_request(struct devfreq *devfreq,
unsigned int bw_mbyte);
void rockchip_dmcfreq_vop_bandwidth_update(struct devfreq *devfreq,
unsigned int bw_mbyte);
#else
static inline int rockchip_dmcfreq_vop_bandwidth_request(unsigned int bw_mbyte)
static inline int
rockchip_dmcfreq_vop_bandwidth_request(struct devfreq *devfreq,
unsigned int bw_mbyte)
{
return 0;
}
static inline void rockchip_dmcfreq_vop_bandwidth_update(unsigned int bw_mbyte)
static inline void
rockchip_dmcfreq_vop_bandwidth_update(struct devfreq *devfreq,
unsigned int bw_mbyte)
{
}
#endif