blob: f3a9cb4413937fbdecafd4522a7eacc5ae4fa558 [file] [log] [blame] [edit]
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
*/
//#define DEBUG
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/debugfs.h>
#include "host.h"
#include "sysfs.h"
#define PWR_OFF 0
#define PWR_ON 1
struct dentry *debug_dir;
static int gethost_clkrate(struct seq_file *s, void *what)
{
struct host_module *host = s->private;
seq_printf(s, "%u\n", host->clk_rate);
return 0;
}
static ssize_t host_clkrate_write(struct file *file, const char __user *userbuf,
size_t count, loff_t *ppos)
{
struct seq_file *sf = file->private_data;
struct host_module *host = sf->private;
char buffer[15] = {0};
count = min_t(size_t, count, sizeof(buffer) - 1);
if (copy_from_user(buffer, userbuf, count))
return -EFAULT;
if (kstrtouint(buffer, 0, &host->clk_rate))
return -EINVAL;
return count;
}
static int host_clkrate_open(struct inode *inode, struct file *file)
{
return single_open(file, gethost_clkrate, inode->i_private);
}
static const struct file_operations clkrate_fops = {
.open = host_clkrate_open,
.read = seq_read,
.write = host_clkrate_write,
.llseek = seq_lseek,
.release = single_release,
};
static int health_cnt_show(struct seq_file *s, void *data)
{
struct host_module *host = s->private;
if (host->health_reg)
seq_printf(s, "[%u %u]\n", host->pre_cnt, host->cur_cnt);
else
seq_puts(s, "not support health monitor\n");
return 0;
}
DEFINE_SHOW_ATTRIBUTE(health_cnt);
void host_create_debugfs_files(struct host_module *host)
{
struct dentry *freq_file;
struct host_data *host_data = host->host_data;
debug_dir = debugfs_create_dir(host_data->name, NULL);
if (!debug_dir) {
pr_err("[%s]debugfs_create_dir %s failed..\n", __func__, host_data->name);
return;
}
freq_file = debugfs_create_file("clk_rate", S_IFREG | 0440,
debug_dir, host, &clkrate_fops);
if (!freq_file)
pr_err("[%s]debugfs_create_file failed..\n", __func__);
debugfs_create_file("health_cnt", 0444, debug_dir, host,
&health_cnt_fops);
}
void host_destroy_debugfs_files(struct host_module *host)
{
debugfs_remove_recursive(debug_dir);
}
static ssize_t pwron_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int ret = 0;
unsigned int pwr_on = 0;
ret = kstrtouint(buf, 0, &pwr_on);
if (ret)
return -EINVAL;
switch (pwr_on) {
case PWR_ON:
pm_runtime_get_sync(dev);
break;
case PWR_OFF:
pm_runtime_put_sync(dev);
break;
default:
break;
};
return count;
}
static DEVICE_ATTR_WO(pwron);
void host_create_device_files(struct device *dev)
{
WARN_ON(device_create_file(dev, &dev_attr_pwron));
}
void host_destroy_device_files(struct device *dev)
{
device_remove_file(dev, &dev_attr_pwron);
}