diff options
Diffstat (limited to 'drivers/gpu/drm/msm/msm_debugfs.c')
| -rw-r--r-- | drivers/gpu/drm/msm/msm_debugfs.c | 93 | 
1 files changed, 85 insertions, 8 deletions
diff --git a/drivers/gpu/drm/msm/msm_debugfs.c b/drivers/gpu/drm/msm/msm_debugfs.c index 1ff3fda245d1..f0da0d3c8a80 100644 --- a/drivers/gpu/drm/msm/msm_debugfs.c +++ b/drivers/gpu/drm/msm/msm_debugfs.c @@ -16,26 +16,101 @@   */  #ifdef CONFIG_DEBUG_FS +#include <linux/debugfs.h>  #include "msm_drv.h"  #include "msm_gpu.h"  #include "msm_kms.h"  #include "msm_debugfs.h" -static int msm_gpu_show(struct drm_device *dev, struct seq_file *m) +struct msm_gpu_show_priv { +	struct msm_gpu_state *state; +	struct drm_device *dev; +}; + +static int msm_gpu_show(struct seq_file *m, void *arg) +{ +	struct drm_printer p = drm_seq_file_printer(m); +	struct msm_gpu_show_priv *show_priv = m->private; +	struct msm_drm_private *priv = show_priv->dev->dev_private; +	struct msm_gpu *gpu = priv->gpu; +	int ret; + +	ret = mutex_lock_interruptible(&show_priv->dev->struct_mutex); +	if (ret) +		return ret; + +	drm_printf(&p, "%s Status:\n", gpu->name); +	gpu->funcs->show(gpu, show_priv->state, &p); + +	mutex_unlock(&show_priv->dev->struct_mutex); + +	return 0; +} + +static int msm_gpu_release(struct inode *inode, struct file *file)  { +	struct seq_file *m = file->private_data; +	struct msm_gpu_show_priv *show_priv = m->private; +	struct msm_drm_private *priv = show_priv->dev->dev_private; +	struct msm_gpu *gpu = priv->gpu; +	int ret; + +	ret = mutex_lock_interruptible(&show_priv->dev->struct_mutex); +	if (ret) +		return ret; + +	gpu->funcs->gpu_state_put(show_priv->state); +	mutex_unlock(&show_priv->dev->struct_mutex); + +	kfree(show_priv); + +	return single_release(inode, file); +} + +static int msm_gpu_open(struct inode *inode, struct file *file) +{ +	struct drm_device *dev = inode->i_private;  	struct msm_drm_private *priv = dev->dev_private;  	struct msm_gpu *gpu = priv->gpu; +	struct msm_gpu_show_priv *show_priv; +	int ret; -	if (gpu) { -		seq_printf(m, "%s Status:\n", gpu->name); -		pm_runtime_get_sync(&gpu->pdev->dev); -		gpu->funcs->show(gpu, m); -		pm_runtime_put_sync(&gpu->pdev->dev); +	if (!gpu) +		return -ENODEV; + +	show_priv = kmalloc(sizeof(*show_priv), GFP_KERNEL); +	if (!show_priv) +		return -ENOMEM; + +	ret = mutex_lock_interruptible(&dev->struct_mutex); +	if (ret) +		return ret; + +	pm_runtime_get_sync(&gpu->pdev->dev); +	show_priv->state = gpu->funcs->gpu_state_get(gpu); +	pm_runtime_put_sync(&gpu->pdev->dev); + +	mutex_unlock(&dev->struct_mutex); + +	if (IS_ERR(show_priv->state)) { +		ret = PTR_ERR(show_priv->state); +		kfree(show_priv); +		return ret;  	} -	return 0; +	show_priv->dev = dev; + +	return single_open(file, msm_gpu_show, show_priv);  } +static const struct file_operations msm_gpu_fops = { +	.owner = THIS_MODULE, +	.open = msm_gpu_open, +	.read = seq_read, +	.llseek = seq_lseek, +	.release = msm_gpu_release, +}; +  static int msm_gem_show(struct drm_device *dev, struct seq_file *m)  {  	struct msm_drm_private *priv = dev->dev_private; @@ -105,7 +180,6 @@ static int show_locked(struct seq_file *m, void *arg)  }  static struct drm_info_list msm_debugfs_list[] = { -		{"gpu", show_locked, 0, msm_gpu_show},  		{"gem", show_locked, 0, msm_gem_show},  		{ "mm", show_locked, 0, msm_mm_show },  		{ "fb", show_locked, 0, msm_fb_show }, @@ -158,6 +232,9 @@ int msm_debugfs_init(struct drm_minor *minor)  		return ret;  	} +	debugfs_create_file("gpu", S_IRUSR, minor->debugfs_root, +		dev, &msm_gpu_fops); +  	if (priv->kms->funcs->debugfs_init) {  		ret = priv->kms->funcs->debugfs_init(priv->kms, minor);  		if (ret)  |