#include #include #include #include #include #include #include "cmucal.h" #include "vclk.h" #include "ra.h" /*** debugfs support ***/ #ifdef CONFIG_DEBUG_FS #define MAX_NAME_SIZE 50 #define INFO_SIZE (SZ_64K) enum clk_info_type { NONE_INFO, CLK_INFO, BLK_CMU_INFO, TOP_CMU_INFO, }; static struct dentry *rootdir; static struct cmucal_clk *clk_info; static struct vclk *dvfs_domain; static u32 cmu_id; static enum clk_info_type cur_info_type = NONE_INFO; static void *(*cal_pd_lookup_cmu_id)(u32 cmu_id); static unsigned int margin; static unsigned int debug_freq; extern unsigned int dbg_offset; static unsigned int cmu_top_base = 0x0; static unsigned int cmu_aud_base = 0x0; void __iomem *cmu_aud; static unsigned int cmu_nocl0_base = 0x0; void __iomem *cmu_nocl0; static unsigned int cmu_cpucl0_base = 0x0; void __iomem *cmu_cpucl0; static unsigned int cmu_cpucl1_base = 0x0; void __iomem *cmu_cpucl1; static unsigned int cmu_cpucl2_base = 0x0; void __iomem *cmu_cpucl2; static unsigned int cmu_dsu_base = 0x0; void __iomem *cmu_dsu; static unsigned int cmu_peris_base = 0x0; void __iomem *cmu_peris; extern bool is_ignore_cmu_dbg(u32 addr); static int clk_store(char *buf, int r, struct cmucal_clk *clk, u32 val, bool state) { struct cmucal_clk *p_clk = ra_get_parent(clk->id); r += scnprintf(buf + r, INFO_SIZE - r, "%-64s : [0x%02x] %6s, %12ld Hz, <- %s\n", clk->name, val, state ? "active" : "idle", vclk_debug_clk_get_rate(clk->id), p_clk ? p_clk->name : "none"); return r; } static bool cal_cmublk_acquire(unsigned int cmu_id, struct exynos_pm_domain **p_pd) { struct exynos_pm_domain *pd = NULL; if (!cal_pd_lookup_cmu_id) return true; pd = (struct exynos_pm_domain *)cal_pd_lookup_cmu_id(cmu_id & 0xFFFF0000); if (pd) { *p_pd = pd; mutex_lock(&pd->access_lock); if (!cal_pd_status(pd->cal_pdid)) return false; } return true; } static void cal_cmublk_release(struct exynos_pm_domain *pd) { if (pd) mutex_unlock(&pd->access_lock); } /* * blk_cmu_info : It will print all the gate clocks of the specified block. */ static int blk_cmu_info(char *buf) { struct cmucal_clk *clk; struct exynos_pm_domain *pd = NULL; int size, reg; int r = 0; int i; if (cal_cmublk_acquire(cmu_id, &pd) == false) { if (pd) { r = scnprintf(buf, INFO_SIZE, " - %s[%x] is off.\n", pd->name, cmu_id); } goto blk_unlock; } r = scnprintf(buf, INFO_SIZE, " - [%x] BLK info\n", cmu_id); size = cmucal_get_list_size(GATE_TYPE); for (i = 0; i < size ; i++) { clk = cmucal_get_node(i | GATE_TYPE); if (clk && ((clk->paddr & 0xFFFF0000) == cmu_id)) { reg = readl(clk->offset + dbg_offset); r = clk_store(buf, r, clk, reg, (reg & 0x70) != 0x30); } } blk_unlock: cal_cmublk_release(pd); return r; } /* * top_cmu_info : It will print all the pll/mux/divider/gate clocks of the top */ static int top_cmu_info(char *buf) { struct cmucal_clk *clk; int size, reg; int i; int r = 0; if (cmu_top_base == 0x0) return scnprintf(buf, INFO_SIZE, "cmu_top_base is NULL\n"); r = scnprintf(buf, INFO_SIZE, " - CMU_TOP PLL info!\n"); size = cmucal_get_list_size(PLL_TYPE); for (i = 0; i < size ; i++) { clk = cmucal_get_node(i | PLL_TYPE); if (!clk || (clk->paddr & 0xFFFF0000) != cmu_top_base) continue; if (is_ignore_cmu_dbg(clk->paddr)) continue; reg = readl(clk->pll_con0); r = clk_store(buf, r, clk, reg, (reg >> 29) & 0x1); } r += scnprintf(buf + r, INFO_SIZE - r, "\n - CMU_TOP MUX info\n"); size = cmucal_get_list_size(MUX_TYPE); for (i = 0; i < size ; i++) { clk = cmucal_get_node(i | MUX_TYPE); if (!clk || (clk->paddr & 0xFFFF0000) != cmu_top_base) continue; if (is_ignore_cmu_dbg(clk->paddr)) continue; reg = readl(clk->offset + dbg_offset); r = clk_store(buf, r, clk, reg, (reg & 0x70) != 0x30); } r += scnprintf(buf + r, INFO_SIZE - r, "\n - CMU_TOP GATE info\n"); size = cmucal_get_list_size(GATE_TYPE); for (i = 0; i < size ; i++) { clk = cmucal_get_node(i | GATE_TYPE); if (!clk || (clk->paddr & 0xFFFF0000) != cmu_top_base) continue; if (is_ignore_cmu_dbg(clk->paddr)) continue; reg = readl(clk->offset + dbg_offset); r = clk_store(buf, r, clk, reg, (reg & 0x70) != 0x30); } r += scnprintf(buf + r, INFO_SIZE - r, "\n - CMU_TOP DIV info\n"); size = cmucal_get_list_size(DIV_TYPE); for (i = 0; i < size ; i++) { clk = cmucal_get_node(i | DIV_TYPE); if (!clk || (clk->paddr & 0xFFFF0000) != cmu_top_base) continue; if (is_ignore_cmu_dbg(clk->paddr)) continue; reg = readl(clk->offset + dbg_offset); r = clk_store(buf, r, clk, reg, (reg & 0x70) != 0x30); } return r; } /* * clk_node_info : It will print all information of the clk node */ static int clk_node_info(struct cmucal_clk *clk, char *buf) { struct cmucal_clk *parent; struct exynos_pm_domain *pd = NULL; int r = 0; if (clk == NULL) { r = scnprintf(buf, INFO_SIZE, "#echo \"clk_name\" > clk_info\n"); return r; } if (cal_cmublk_acquire(clk->paddr, &pd) == false) { if (pd) r = scnprintf(buf, INFO_SIZE, "%s is off.\n", pd->name); goto blk_unlock; } r = scnprintf(buf, INFO_SIZE, "clk name : %s\n" " id : 0x%x\n" " rate : %u\n" " value : %lu\n" " path :\n", clk->name, clk->id, vclk_debug_clk_get_rate(clk->id), ra_get_value(clk->id)); parent = ra_get_parent(clk->id); while (parent != NULL) { r += scnprintf(buf + r, INFO_SIZE - r, "<- %s ", parent->name); parent = ra_get_parent(parent->id); } r += scnprintf(buf + r, INFO_SIZE - r, "\n"); blk_unlock: cal_cmublk_release(pd); return r; } static int vclk_table_dump(struct seq_file *s, void *p) { struct vclk *vclk = s->private; struct cmucal_clk *clk; struct exynos_pm_domain *pd = NULL; int i, j; seq_puts(s, "-----------------------------------------------------\n"); seq_printf(s, "%s <%x>\n", vclk->name, vclk->id); for (i = 0; i < vclk->num_list; i++) { clk = cmucal_get_node(vclk->list[i]); if (!clk) continue; pd = NULL; if (cal_cmublk_acquire(clk->paddr, &pd) == false) { if (pd) { seq_printf(s, "[%s] %s is off.\n", clk->name, pd->name); } } else { seq_printf(s, " [%s] value : %lu rate : %u\n", clk->name, ra_get_value(clk->id), vclk_debug_clk_get_rate(clk->id)); } cal_cmublk_release(pd); } if (!vclk->lut) return 0; for (i = 0; i < vclk->num_rates; i++) { seq_printf(s, "[%2d]%7d :", i + 1, vclk->lut[i].rate); for (j = 0; j < vclk->num_list; j++) seq_printf(s, "%7d ", vclk->lut[i].params[j]); seq_puts(s, "\n"); } return 0; } static int vclk_table_open(struct inode *inode, struct file *file) { return single_open(file, vclk_table_dump, inode->i_private); } static const struct file_operations vclk_table_fops = { .open = vclk_table_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; static int vclk_clk_info(struct seq_file *s, void *p) { return 0; } static int vclk_clk_info_open(struct inode *inode, struct file *file) { return single_open_size(file, vclk_clk_info, inode->i_private, INFO_SIZE); } static ssize_t vclk_read_clk_info(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) { char *buf; int r = 0; buf = kmalloc(INFO_SIZE, GFP_KERNEL); if (!buf) return -ENOMEM; switch (cur_info_type) { case NONE_INFO: r = scnprintf( buf, INFO_SIZE, "CLK_NODE_INFO: echo \"clk_name\" > clk_info\n" "BLK_CMU_INFO: echo blk_hwacg #cmu_blk_id > clk_info\n" "TOP_CMU_INFO: echo hwacg > clk_info\n"); break; case CLK_INFO: r = clk_node_info(clk_info, buf); break; case BLK_CMU_INFO: r = blk_cmu_info(buf); break; case TOP_CMU_INFO: r = top_cmu_info(buf); break; } r = simple_read_from_buffer(ubuf, cnt, ppos, buf, r); kfree(buf); return r; } static ssize_t vclk_write_clk_info(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) { char buf[MAX_NAME_SIZE + 1]; char *c_buf, *tmp; unsigned int id; unsigned long c_addr; size_t ret; c_buf = buf; ret = cnt; if (cnt == 0) return cnt; if (cnt > MAX_NAME_SIZE) cnt = MAX_NAME_SIZE; if (copy_from_user(buf, ubuf, cnt)) return -EVCLKFAULT; if (buf[cnt-1] == '\n') buf[cnt-1] = 0; else buf[cnt] = 0; if (!strcmp(buf, "hwacg")) { cur_info_type = TOP_CMU_INFO; } else if (!strcmp(strsep(&c_buf," "), "blk_hwacg")) { cur_info_type = NONE_INFO; tmp = strsep(&c_buf, " "); if (tmp && kstrtol(tmp, 16, &c_addr) == 0) { cmu_id = c_addr & 0xFFFF0000; cur_info_type = BLK_CMU_INFO; } pr_info("%x, id = %x\n", cur_info_type, cmu_id); } else { id = cmucal_get_id(buf); clk_info = cmucal_get_node(id); if (clk_info) cur_info_type = CLK_INFO; else cur_info_type = NONE_INFO; } *ppos += ret; return cnt; } static ssize_t vclk_read_dvfs_domain(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) { struct vclk *vclk; char buf[1024]; int i, size; int r; vclk = dvfs_domain; if (vclk == NULL) r = sprintf(buf, "echo id > dvfs_domain\n"); else r = sprintf(buf, "%s : 0x%x\n", dvfs_domain->name, dvfs_domain->id); r += sprintf(buf + r, "- dvfs list\n"); size = cmucal_get_list_size(ACPM_VCLK_TYPE); for (i = 0; i < size ; i++) { vclk = cmucal_get_node(ACPM_VCLK_TYPE | i); if (vclk == NULL) continue; r += sprintf(buf + r, " %s : 0x%x\n", vclk->name, vclk->id); } return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); } static ssize_t vclk_write_dvfs_domain(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) { char buf[16]; ssize_t len; u32 id; len = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, cnt); if (len < 0) return len; buf[len] = '\0'; if (!kstrtouint(buf, 0, &id)) { dvfs_domain = cmucal_get_node(id); if (!dvfs_domain || !IS_ACPM_VCLK(dvfs_domain->id)) dvfs_domain = NULL; } return len; } static ssize_t vclk_read_set_margin(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) { char buf[512]; int r; r = sprintf(buf, "margin : %u\n", margin); return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); } static ssize_t vclk_write_set_margin(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) { char buf[16]; ssize_t len; u32 volt; len = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, cnt); if (len < 0) return len; buf[len] = '\0'; if (dvfs_domain && !kstrtoint(buf, 0, &volt)) { margin = volt; cal_dfs_set_volt_margin(dvfs_domain->id, volt); } return len; } static ssize_t vclk_read_set_freq(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) { char buf[512]; int r; r = sprintf(buf, "freq : %u\n", debug_freq); return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); } static ssize_t vclk_write_set_freq(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) { char buf[16]; ssize_t len; u32 freq; len = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, cnt); if (len < 0) return len; buf[len] = '\0'; if (dvfs_domain && !kstrtoint(buf, 0, &freq)) { debug_freq = freq; cal_dfs_set_rate(dvfs_domain->id, freq); } return len; } /////////////////////////////////////////////////////////////////////////////////////////////////////////// #define BASE_MOVE (0x100) #if 0 #define CLKDIVSTEP_STAT (0x83c) #define CLK_CON_MUX_MUX_CLK (0x1000) #define STRMUX (0x870) static ssize_t cpucl0_stepup_run_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) { char buf[512] = {0,}; int r; if (cmu_cpucl0) { unsigned int reg = __raw_readl(cmu_cpucl0 - BASE_MOVE + CLKDIVSTEP_STAT); r = sprintf(buf, "CLKDIVSTEP_STAT : 0x%x\n", reg); reg = __raw_readl(cmu_cpucl0 - BASE_MOVE + CLK_CON_MUX_MUX_CLK); r = sprintf(buf, "%sCLK_CON_MUX_MUX_CLK_ : 0x%x\n", buf, reg); reg = __raw_readl(cmu_cpucl0 - BASE_MOVE + STRMUX); r = sprintf(buf, "%s_STRMUX_CORE : 0x%x\n", buf, reg); } else { r = sprintf(buf, "empty base\n"); } return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); } static ssize_t cpucl1_stepup_run_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) { char buf[512] = {0,}; int r; if (cmu_cpucl1) { unsigned int reg = __raw_readl(cmu_cpucl1 - BASE_MOVE + CLKDIVSTEP_STAT); r = sprintf(buf, "CLKDIVSTEP_STAT : 0x%x\n", reg); reg = __raw_readl(cmu_cpucl1 - BASE_MOVE + CLK_CON_MUX_MUX_CLK); r = sprintf(buf, "%sCLK_CON_MUX_MUX_CLK_ : 0x%x\n", buf, reg); reg = __raw_readl(cmu_cpucl1 - BASE_MOVE + STRMUX); r = sprintf(buf, "%s_STRMUX_CORE : 0x%x\n", buf, reg); } else { r = sprintf(buf, "empty base\n"); } return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); } static ssize_t cpucl2_stepup_run_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) { char buf[512] = {0,}; int r; if (cmu_cpucl2) { unsigned int reg = __raw_readl(cmu_cpucl2 - BASE_MOVE + CLKDIVSTEP_STAT); r = sprintf(buf, "CLKDIVSTEP_STAT : 0x%x\n", reg); reg = __raw_readl(cmu_cpucl2 - BASE_MOVE + CLK_CON_MUX_MUX_CLK); r = sprintf(buf, "%sCLK_CON_MUX_MUX_CLK_ : 0x%x\n", buf, reg); reg = __raw_readl(cmu_cpucl2 - BASE_MOVE + STRMUX); r = sprintf(buf, "%s_STRMUX_CORE : 0x%x\n", buf, reg); } else { r = sprintf(buf, "empty base\n"); } return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); } static ssize_t dsu_stepup_run_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) { char buf[512] = {0,}; int r; if (cmu_dsu) { unsigned int reg = __raw_readl(cmu_dsu - BASE_MOVE + CLKDIVSTEP_STAT); r = sprintf(buf, "CLKDIVSTEP_STAT : 0x%x\n", reg); reg = __raw_readl(cmu_dsu - BASE_MOVE + CLK_CON_MUX_MUX_CLK); r = sprintf(buf, "%s CLK_CON_MUX_MUX_CLK_ : 0x%x\n", buf, reg); reg = __raw_readl(cmu_dsu - BASE_MOVE + STRMUX); r = sprintf(buf, "%s_STRMUX_CORE : 0x%x\n", buf, reg); } else { r = sprintf(buf, "empty base\n"); } return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); } #endif static const struct file_operations clk_info_fops = { .open = vclk_clk_info_open, .read = vclk_read_clk_info, .write = vclk_write_clk_info, .llseek = seq_lseek, .release = single_release, }; static const struct file_operations dvfs_domain_fops = { .open = simple_open, .read = vclk_read_dvfs_domain, .write = vclk_write_dvfs_domain, .llseek = seq_lseek, }; static const struct file_operations set_margin_fops = { .open = simple_open, .read = vclk_read_set_margin, .write = vclk_write_set_margin, .llseek = seq_lseek, }; static const struct file_operations set_freq_fops = { .open = simple_open, .read = vclk_read_set_freq, .write = vclk_write_set_freq, .llseek = seq_lseek, }; #if 0 static const struct file_operations cpucl0_stepup_run_fops = { .open = simple_open, .read = cpucl0_stepup_run_read, .llseek = seq_lseek, }; static const struct file_operations cpucl1_stepup_run_fops = { .open = simple_open, .read = cpucl1_stepup_run_read, .llseek = seq_lseek, }; static const struct file_operations cpucl2_stepup_run_fops = { .open = simple_open, .read = cpucl2_stepup_run_read, .llseek = seq_lseek, }; static const struct file_operations dsu_stepup_run_fops = { .open = simple_open, .read = dsu_stepup_run_read, .llseek = seq_lseek, }; #endif /* caller must hold prepare_lock */ static int vclk_debug_create_one(struct vclk *vclk, struct dentry *pdentry) { struct dentry *d; int ret = -ENOMEM; if (!vclk || !pdentry) { ret = -EINVAL; goto out; } d = debugfs_create_dir(vclk->name, pdentry); if (!d) goto out; vclk->dentry = d; debugfs_create_x32("vclk_id", 0400, vclk->dentry, (u32 *)&vclk->id); debugfs_create_u32("vclk_rate", 0400, vclk->dentry, (u32 *)&vclk->vrate); debugfs_create_u32("vclk_num_rates", 0400, vclk->dentry, (u32 *)&vclk->num_rates); debugfs_create_u32("vclk_num_list", 0400, vclk->dentry, (u32 *)&vclk->num_list); d = debugfs_create_file("vclk_table", 0400, vclk->dentry, vclk, &vclk_table_fops); if (!d) return -ENOMEM; ret = 0; goto out; out: return ret; } unsigned int vclk_debug_clk_get_rate(unsigned int id) { unsigned long rate; rate = ra_recalc_rate(id); return rate; } EXPORT_SYMBOL_GPL(vclk_debug_clk_get_rate); unsigned long vclk_debug_clk_get_value(unsigned int id) { unsigned long val; val = ra_get_value(id); return val; } EXPORT_SYMBOL_GPL(vclk_debug_clk_get_value); int vclk_debug_clk_set_value(unsigned int id, unsigned int params) { int ret; ret = ra_set_value(id, params); return ret; } EXPORT_SYMBOL_GPL(vclk_debug_clk_set_value); void cmucal_dbg_set_cmu_top_base(u32 base_addr) { cmu_top_base = base_addr; pr_info("cmu_top_base : 0x%x\n", base_addr); } EXPORT_SYMBOL_GPL(cmucal_dbg_set_cmu_top_base); void cmucal_dbg_set_cmu_aud_base(u32 base_addr) { cmu_aud_base = base_addr + BASE_MOVE; pr_info("cmu_aud_base : 0x%x\n", base_addr); cmu_aud = ioremap(cmu_aud_base, SZ_4K); if (!cmu_aud) pr_err("%s: cmu_aud ioremap failed\n", __func__); } EXPORT_SYMBOL_GPL(cmucal_dbg_set_cmu_aud_base); void cmucal_dbg_set_cmu_nocl0_base(u32 base_addr) { cmu_nocl0_base = base_addr + BASE_MOVE; pr_info("cmu_nocl0_base : 0x%x\n", base_addr); cmu_nocl0 = ioremap(cmu_nocl0_base, SZ_4K); if (!cmu_nocl0) pr_err("%s: cmu_nocl0 ioremap failed\n", __func__); } EXPORT_SYMBOL_GPL(cmucal_dbg_set_cmu_nocl0_base); void cmucal_dbg_set_cmu_cpucl0_base(u32 base_addr) { cmu_cpucl0_base = base_addr + BASE_MOVE; pr_info("cmu_cpucl0_base : 0x%x\n", base_addr); cmu_cpucl0 = ioremap(cmu_cpucl0_base, SZ_4K); if (!cmu_cpucl0) pr_err("%s: cmu_cpucl0 ioremap failed\n", __func__); } EXPORT_SYMBOL_GPL(cmucal_dbg_set_cmu_cpucl0_base); void cmucal_dbg_set_cmu_cpucl1_base(u32 base_addr) { cmu_cpucl1_base = base_addr + BASE_MOVE; pr_info("cmu_cpucl1_base : 0x%x\n", base_addr); cmu_cpucl1 = ioremap(cmu_cpucl1_base, SZ_4K); if (!cmu_cpucl1) pr_err("%s: cmu_cpucl1 ioremap failed\n", __func__); } EXPORT_SYMBOL_GPL(cmucal_dbg_set_cmu_cpucl1_base); void cmucal_dbg_set_cmu_cpucl2_base(u32 base_addr) { cmu_cpucl2_base = base_addr + BASE_MOVE; pr_info("cmu_cpucl2_base : 0x%x\n", base_addr); cmu_cpucl2 = ioremap(cmu_cpucl2_base, SZ_4K); if (!cmu_cpucl2) pr_err("%s: cmu_cpucl2 ioremap failed\n", __func__); } EXPORT_SYMBOL_GPL(cmucal_dbg_set_cmu_cpucl2_base); void cmucal_dbg_set_cmu_dsu_base(u32 base_addr) { cmu_dsu_base = base_addr + BASE_MOVE; pr_info("cmu_dsu_base : 0x%x\n", base_addr); cmu_dsu = ioremap(cmu_dsu_base, SZ_4K); if (!cmu_dsu) pr_err("%s: cmu_dsu ioremap failed\n", __func__); } EXPORT_SYMBOL_GPL(cmucal_dbg_set_cmu_dsu_base); void cmucal_dbg_set_cmu_peris_base(u32 base_addr) { cmu_peris_base = base_addr + BASE_MOVE; pr_info("cmu_peris_base : 0x%x\n", base_addr); cmu_peris = ioremap(cmu_peris_base, SZ_4K); if (!cmu_peris) pr_err("%s: cmu_peris ioremap failed\n", __func__); } EXPORT_SYMBOL_GPL(cmucal_dbg_set_cmu_peris_base); void cal_register_pd_lookup_cmu_id(void *(*func)(u32 cmu_id)) { cal_pd_lookup_cmu_id = func; } EXPORT_SYMBOL_GPL(cal_register_pd_lookup_cmu_id); /** * vclk_debug_init - lazily create the debugfs clk tree visualization */ int vclk_debug_init(void) { struct vclk *vclk; struct dentry *d; int i; rootdir = debugfs_create_dir("vclk", NULL); if (!rootdir) return -ENOMEM; for (i = 0; i < cmucal_get_list_size(VCLK_TYPE); i++) { vclk = cmucal_get_node(i | VCLK_TYPE); if (!vclk) continue; vclk_debug_create_one(vclk, rootdir); } for (i = 0; i < cmucal_get_list_size(ACPM_VCLK_TYPE); i++) { vclk = cmucal_get_node(i | ACPM_VCLK_TYPE); if (!vclk) continue; vclk_debug_create_one(vclk, rootdir); } d = debugfs_create_file("clk_info", 0600, rootdir, NULL, &clk_info_fops); if (!d) return -ENOMEM; d = debugfs_create_file("dvfs_domain", 0600, rootdir, NULL, &dvfs_domain_fops); if (!d) return -ENOMEM; d = debugfs_create_file("set_margin", 0600, rootdir, NULL, &set_margin_fops); if (!d) return -ENOMEM; d = debugfs_create_file("set_freq", 0600, rootdir, NULL, &set_freq_fops); if (!d) return -ENOMEM; #if 0 d = debugfs_create_file("cpucl0_stepup_run", 0400, rootdir, NULL, &cpucl0_stepup_run_fops); if (!d) return -ENOMEM; d = debugfs_create_file("cpucl1_stepup_run", 0400, rootdir, NULL, &cpucl1_stepup_run_fops); if (!d) return -ENOMEM; d = debugfs_create_file("cpucl2_stepup_run", 0400, rootdir, NULL, &cpucl2_stepup_run_fops); if (!d) return -ENOMEM; d = debugfs_create_file("dsu_stepup_run", 0400, rootdir, NULL, &dsu_stepup_run_fops); if (!d) return -ENOMEM; #endif return 0; } EXPORT_SYMBOL_GPL(vclk_debug_init); #endif MODULE_LICENSE("GPL");