2 * driver/misc/clkmon/clk_mon.c
4 * Copyright (C) 2014 Samsung Electronics co. ltd
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
10 #include <linux/module.h>
11 #include <linux/kernel.h>
13 #include <linux/device.h>
14 #include <linux/miscdevice.h>
15 #include <linux/slab.h>
16 #include <linux/uaccess.h>
18 #include <linux/clk_mon.h>
19 #include <soc/sprd/pm_debug.h>
20 #include "clk_mon_ioctl.h"
21 #include "clk_mon_scx35.h"
22 /* SPRD is based on regulator framework and not Domain based framework
23 * hence, we need to get the status of the Parent regulators to check if
26 #include <linux/regulator/consumer.h>
29 #define CHECK_BIT_SET(var, pos) ((var) & (1<<(pos)))
33 /* SPRD is based on regulator concept and hence we get the list
34 * of regulators in the system. They are source of supply for
35 * the consumers that are under them.
38 struct power_domain_mask power_domain_masks[] = {
39 {"vdd18"}, {"vdd28"}, {"vdd25"}, {"vddcon"}, {"vdddcxo"}, {"vddmem"},
40 {"vddemmccore"}, {"vddrf0"}, {"vddcore"}, {"vddarm"}, {"vddgen"},
41 {"vddrf"},{"vddsdcore"}, {"vddsim0"}, {"vddsim1"}, {"vddsim2"}, {"vddcama"},
42 {"vddcamd"}, {"vddcamio"}, {"vddcammot"}, {"vddusb"}, {"vddwpa"},
43 {"vddgen1"}, {"vddgen0"}, {"vddwifipa"}, {"vddsdio"}, {"vddvibr"},
47 struct clk_gate_mask *clk_gate_masks = NULL;
49 static int clk_mon_ioc_check_reg(struct clk_mon_ioc_buf __user *uarg)
51 struct clk_mon_ioc_buf *karg = NULL;
52 void __iomem *v_addr = NULL;
53 int size = sizeof(struct clk_mon_ioc_buf);
57 if (!access_ok(VERIFY_WRITE, uarg, size))
60 karg = kzalloc(size, GFP_KERNEL);
65 if (copy_from_user(karg, uarg, size)) {
70 for (i = 0; i < karg->nr_addrs; i++) {
71 v_addr = ioremap((unsigned int)karg->reg[i].addr, SIZE_REG);
72 karg->reg[i].value = ioread32(v_addr);
76 if (copy_to_user(uarg, karg, size)) {
87 static int clk_mon_ioc_check_power_domain(struct clk_mon_ioc_buf __user *uarg)
89 struct clk_mon_ioc_buf *karg = NULL;
90 unsigned int dom_en = 0;
91 int size = sizeof(struct clk_mon_ioc_buf);
94 unsigned int num_domains = 0;
95 static struct regulator *regulator_pm;
97 if (!access_ok(VERIFY_WRITE, uarg, size))
100 karg = kzalloc(size, GFP_KERNEL);
105 num_domains = sizeof(power_domain_masks)/sizeof(power_domain_masks[0]);
107 for (i = 0; i < num_domains; i++) {
108 regulator_pm = regulator_get(NULL, power_domain_masks[i].name);
109 if (IS_ERR(regulator_pm)) {
110 pr_err("%s - Failed to get [%s] regulator\n",
111 __func__, power_domain_masks[i].name);
113 dom_en = regulator_is_enabled(regulator_pm);
115 strlcpy(karg->reg[i].name,
116 power_domain_masks[i].name,
117 sizeof(karg->reg[i].name));
118 karg->reg[i].value = dom_en;
119 /* Free the regulator from the consumer list
120 else suspend would be prevented */
121 regulator_put(regulator_pm);
127 if (copy_to_user(uarg, karg, size)) {
139 static int clk_mon_ioc_check_clock_gating(struct clk_mon_ioc_buf __user *uarg)
141 struct clk_mon_ioc_buf *karg = NULL;
142 unsigned int val = 0, value = 0;
143 int size = sizeof(struct clk_mon_ioc_buf);
146 void __iomem *v_addr = NULL;
148 if (!access_ok(VERIFY_WRITE, uarg, size))
151 karg = kzalloc(size, GFP_KERNEL);
156 for (i = 0; clk_gate_masks[i].addr != 0; i++) {
157 v_addr = ioremap((unsigned int)clk_gate_masks[i].addr,
159 value = ioread32(v_addr);
160 val = CHECK_BIT_SET((unsigned int) value, (unsigned int)clk_gate_masks[i].bit_number);
161 /* The output contains the register_name, address & value */
162 strlcpy(karg->reg[i].name,
163 clk_gate_masks[i].name,
164 sizeof(karg->reg[i].name));
165 karg->reg[i].addr = (void *) (&(clk_gate_masks[i].addr));
166 karg->reg[i].value = val;
170 if (copy_to_user(uarg, karg, size)) {
182 static int clk_mon_ioc_set_reg(struct clk_mon_reg_info __user *uarg)
184 struct clk_mon_reg_info *karg = NULL;
185 void __iomem *v_addr = NULL;
186 int size = sizeof(struct clk_mon_reg_info);
189 if (!access_ok(VERIFY_READ, uarg, size))
192 karg = kzalloc(size, GFP_KERNEL);
197 if (copy_from_user(karg, uarg, size)) {
202 v_addr = ioremap((unsigned int)karg->addr, SIZE_REG);
203 iowrite32(karg->value, v_addr);
213 static long clk_mon_ioctl(struct file *filep, unsigned int cmd,
216 struct clk_mon_ioc_buf __user *uarg = NULL;
219 pr_info("%s\n", __func__);
224 uarg = (struct clk_mon_ioc_buf __user *)arg;
227 case CLK_MON_IOC_CHECK_REG:
228 ret = clk_mon_ioc_check_reg(uarg);
230 case CLK_MON_IOC_CHECK_POWER_DOMAIN:
231 ret = clk_mon_ioc_check_power_domain(uarg);
233 case CLK_MON_IOC_CHECK_CLOCK_DOMAIN:
234 ret = clk_mon_ioc_check_clock_gating(uarg);
236 case CLK_MON_IOC_SET_REG:
237 ret = clk_mon_ioc_set_reg(
238 (struct clk_mon_reg_info __user *)arg);
241 pr_err("%s:Invalid ioctl\n", __func__);
248 static unsigned int g_reg_addr;
249 static unsigned int g_reg_value;
251 /* Useage - echo "Register_Address" "Value_to_be_set" > set_reg
252 Eg. Input - echo 0x40038814 0x1 > set_reg
253 >> Output - cat check_reg
254 >> [0x40038814] 0x00000001
257 static ssize_t clk_mon_store_check_reg(struct device *dev,
258 struct device_attribute *attr, const char *buf, size_t size)
260 unsigned int reg_addr = 0;
267 cur = strnstr(buf, "0x", sizeof(buf));
270 ret = sscanf(cur + 2, "%x", ®_addr);
275 g_reg_addr = reg_addr;
280 /* Useage - echo "Register_Address" > check_reg
281 Eg. Input - echo 0x40038814 > check_reg
282 >> Output - cat check_reg
283 >> [0x40038814] 0x80000000
286 static ssize_t clk_mon_show_check_reg(struct device *dev,
287 struct device_attribute *attr, char *buf)
289 void __iomem *v_addr = NULL;
290 unsigned int p_addr = 0;
291 unsigned int value = 0;
299 v_addr = ioremap(p_addr, SIZE_REG);
300 value = ioread32(v_addr);
303 size += snprintf(buf + size, CLK_MON_BUF_SIZE,
304 "[0x%x] 0x%x\n", p_addr, value) + 1;
309 static ssize_t clk_mon_store_set_reg(struct device *dev,
310 struct device_attribute *attr, const char *buf, size_t size)
312 unsigned int reg_addr = 0;
313 unsigned int reg_value = 0;
314 void __iomem *v_addr = NULL;
315 char tmp_addr[9] = {0};
321 cur = strnstr(buf, "0x", strlen(buf));
323 if (!cur || !(cur + 2))
326 strlcpy(tmp_addr, cur + 2, 8);
328 if (!sscanf(tmp_addr, "%x", ®_addr))
331 cur = strnstr(&cur[2], "0x", strlen(&cur[2]));
333 if (!cur || !(cur + 2))
336 if (!sscanf(cur + 2, "%x", ®_value))
339 g_reg_addr = reg_addr;
340 g_reg_value = reg_value;
342 v_addr = ioremap(g_reg_addr, SIZE_REG);
343 iowrite32(g_reg_value, v_addr);
349 static const int NR_BIT = 8 * sizeof(unsigned int);
350 static const int IDX_SHIFT = 5;
352 int clk_mon_power_domain(unsigned int *pm_status)
354 unsigned int dom_en = 0;
355 int i, bit_shift, idx;
356 unsigned int num_domains = 0;
357 static struct regulator *regulator_pm;
358 /* In total, 62+ regulators are present */
359 int bit_max = NR_BIT * PWR_DOMAINS_NUM;
361 num_domains = sizeof(power_domain_masks)/sizeof(power_domain_masks[0]);
363 /* Parse through the list of regulators & based on request from the
364 consumers of the regulator, it would be enabled/disabled i.e. ON/OFF
367 if (!pm_status || bit_max < 0 || num_domains <= 0)
370 memset(pm_status, 0, sizeof(unsigned int) * PWR_DOMAINS_NUM);
372 for (i = 0; i < num_domains; i++) {
374 pr_err("%s: Error Exceed storage size %d(%d)\n",
375 __func__, i, bit_max);
378 regulator_pm = regulator_get(NULL, power_domain_masks[i].name);
379 if (IS_ERR(regulator_pm)) {
380 pr_err("%s - Failed to get [%s] regulator\n",
381 __func__, power_domain_masks[i].name);
383 idx = (i >> IDX_SHIFT);
384 bit_shift = (i % NR_BIT);
385 /* Check the regulator status */
386 dom_en = regulator_is_enabled(regulator_pm);
389 pm_status[idx] |= (0x1 << bit_shift);
391 pm_status[idx] &= ~(0x1 << bit_shift);
392 regulator_put(regulator_pm);
399 int clk_mon_get_power_info(unsigned int *pm_status, char *buf)
401 int i, bit_shift, idx, size = 0;
402 unsigned int num_domains = 0, dom_en = 0;
403 int bit_max = NR_BIT * PWR_DOMAINS_NUM;
405 num_domains = sizeof(power_domain_masks)/sizeof(power_domain_masks[0]);
407 if ((!pm_status) || (!buf) || (num_domains <= 0))
410 for (i = 0; i < num_domains; i++) {
412 pr_err("%s: Error Exceed storage size %d(%d)\n",
413 __func__, i, NR_BIT);
417 bit_shift = i % NR_BIT;
418 idx = i >> IDX_SHIFT;
420 /* If the bit is set indicates that the regulator is enabled as
421 observed in the API clk_mon_power_domain.
423 dom_en = CHECK_BIT_SET(pm_status[idx], bit_shift);
425 size += snprintf(buf + size, CLK_MON_BUF_SIZE,
427 power_domain_masks[i].name,
428 (dom_en) ? "on" : "off");
433 int clk_mon_clock_gate(unsigned int *clk_status)
435 int bit_max = NR_BIT * CLK_GATES_NUM;
436 unsigned int val = 0;
437 volatile unsigned int value = 0;
438 unsigned long addr = 0;
439 unsigned int clk_en = 0;
440 int i, bit_shift, idx;
442 if (!clk_status || bit_max < 0)
445 memset(clk_status, 0, sizeof(unsigned int) * CLK_GATES_NUM);
447 for (i = 0; clk_gate_masks[i].addr != 0; i++) {
449 pr_err("%s: Error Exceed storage size %d(%d)\n",
450 __func__, i, bit_max);
454 if (addr != clk_gate_masks[i].addr) {
455 addr = clk_gate_masks[i].addr;
456 value = __raw_readl(clk_gate_masks[i].addr);
458 val = CHECK_BIT_SET(value,
459 (unsigned int) clk_gate_masks[i].bit_number);
462 idx = i >> IDX_SHIFT;
463 bit_shift = i % NR_BIT;
466 clk_status[idx] &= ~(BIT_ONE << bit_shift);
468 clk_status[idx] |= (BIT_ONE << bit_shift);
473 int clk_mon_get_clock_info(unsigned int *clk_status, char *buf)
475 unsigned long addr = 0;
476 int bit_max = NR_BIT * CLK_GATES_NUM;
480 void __iomem *v_addr = NULL;
481 unsigned int value = 0;
483 if (!clk_status || !buf)
486 for (i = 0; clk_gate_masks[i].addr != 0; i++) {
488 pr_err("%s: Error Exceed storage size %d(%d)\n",
489 __func__, i, bit_max);
493 if (addr != clk_gate_masks[i].addr) {
494 addr = clk_gate_masks[i].addr;
495 value = __raw_readl(clk_gate_masks[i].addr);
496 size += snprintf(buf + size, CLK_MON_BUF_SIZE,
498 ((unsigned int) clk_gate_masks[i].addr));
501 bit_shift = i % NR_BIT;
502 idx = i >> IDX_SHIFT;
503 /* If the bit is set indicates that the clock is enabled as
504 observed in the API clk_mon_clock_gate.
506 val = CHECK_BIT_SET(clk_status[idx], bit_shift);
507 size += snprintf(buf + size, CLK_MON_BUF_SIZE,
508 " %-20s\t: %s\n", clk_gate_masks[i].name,
509 (val !=0) ? "on" : "off");
514 static ssize_t clk_mon_show_power_domain(struct device *dev,
515 struct device_attribute *attr, char *buf)
517 unsigned int val = 0;
519 static struct regulator *regulator_pm;
520 unsigned int num_domains = 0;
523 num_domains = sizeof(power_domain_masks)/sizeof(power_domain_masks[0]);
525 memset(buf, 0, sizeof(buf));
527 /* Parse through the list of regulators & based on request from the
528 consumers of the regulator, it would be enabled/disabled i.e. ON/OFF
530 for (i = 0; i < num_domains; i++) {
531 regulator_pm = regulator_get(NULL, power_domain_masks[i].name);
532 if (IS_ERR(regulator_pm)) {
533 pr_err("Failed to get [%s] regulator\n",
534 power_domain_masks[i].name);
536 val = regulator_is_enabled(regulator_pm);
538 regulator_put(regulator_pm);
541 size += snprintf(buf + size, CLK_MON_BUF_SIZE,
543 power_domain_masks[i].name, (val) ? "on" : "off");
548 static ssize_t clk_mon_show_clock_gating(struct device *dev,
549 struct device_attribute *attr, char *buf)
551 unsigned int val = 0;
552 unsigned long addr=0;
553 volatile unsigned int value = 0;
557 for (i = 0; clk_gate_masks[i].addr != 0; i++) {
558 if(addr != clk_gate_masks[i].addr){
559 addr = clk_gate_masks[i].addr;
560 value = __raw_readl(clk_gate_masks[i].addr);
561 size += sprintf(buf + size, "\n[0x%x] 0x%x\n",
562 vaddr_to_paddr(addr, CLK_REG), value);
564 val = CHECK_BIT_SET( value,
565 (unsigned int)clk_gate_masks[i].bit_number);
566 size += snprintf(buf + size, CLK_MON_BUF_SIZE,
568 clk_gate_masks[i].name, (val) ? "on" : "off");
575 static DEVICE_ATTR(check_reg, S_IRUSR | S_IWUSR,
576 clk_mon_show_check_reg, clk_mon_store_check_reg);
577 static DEVICE_ATTR(set_reg, S_IWUSR, NULL, clk_mon_store_set_reg);
578 static DEVICE_ATTR(power_domain, S_IRUSR, clk_mon_show_power_domain, NULL);
579 static DEVICE_ATTR(clock_gating, S_IRUSR, clk_mon_show_clock_gating, NULL);
582 static struct attribute *clk_mon_attributes[] = {
583 &dev_attr_check_reg.attr,
584 &dev_attr_set_reg.attr,
585 &dev_attr_power_domain.attr,
586 &dev_attr_clock_gating.attr,
590 static struct attribute_group clk_mon_attr_group = {
591 .attrs = clk_mon_attributes,
595 static const struct file_operations clk_mon_fops = {
596 .owner = THIS_MODULE,
597 .unlocked_ioctl = clk_mon_ioctl,
600 static struct miscdevice clk_mon_device = {
601 .minor = MISC_DYNAMIC_MINOR,
603 .fops = &clk_mon_fops,
606 static int __init clk_mon_init(void)
610 pr_info("%s\n", __func__);
612 ret = misc_register(&clk_mon_device);
615 pr_err("%s: Unable to register clk_mon_device\n", __func__);
616 goto err_misc_register;
619 ret = sysfs_create_group(&clk_mon_device.this_device->kobj,
620 &clk_mon_attr_group);
623 pr_err("%s: Unable to Create sysfs node\n", __func__);
624 goto err_create_group;
627 /* Base addresses of the registers are located in include/soc/sprd/sci_glb_regs.h */
629 struct clk_gate_mask clk_gate_mask_temp[] = {
630 /* System Related Clocks, Start */
632 {"LVDS_EB", CLK_MON_AHB_EB, 22},
633 {"ZIPDEC_EB", CLK_MON_AHB_EB, 21},
634 {"ZIPENC_EB", CLK_MON_AHB_EB, 20},
635 {"NANDC_ECC_EB", CLK_MON_AHB_EB, 19},
636 {"NANDC_2X_EB", CLK_MON_AHB_EB, 18},
637 {"NANDC_EB", CLK_MON_AHB_EB, 17},
638 {"BUSMON2_EB", CLK_MON_AHB_EB, 16},
639 {"BUSMON1_EB", CLK_MON_AHB_EB, 15},
640 {"BUSMON0_EB", CLK_MON_AHB_EB, 14},
641 {"SPINLOCK_EB", CLK_MON_AHB_EB, 13},
642 {"GPS_EB", CLK_MON_AHB_EB, 12},
643 {"EMMC_EB", CLK_MON_AHB_EB, 11},
644 {"SDIO2_EB", CLK_MON_AHB_EB, 10},
645 {"SDIO1_EB", CLK_MON_AHB_EB, 9},
646 {"SDIO0_EB", CLK_MON_AHB_EB, 8},
647 {"DRM_EB", CLK_MON_AHB_EB, 7},
648 {"DMA_EB", CLK_MON_AHB_EB, 5},
649 {"USB_EB", CLK_MON_AHB_EB, 4},
650 {"GSP_EB", CLK_MON_AHB_EB, 3},
651 {"DISPC1_EB", CLK_MON_AHB_EB, 2},
652 {"DISPC2_EB", CLK_MON_AHB_EB, 1},
653 {"DSI_EB", CLK_MON_AHB_EB,0},
655 /* AP_AHB_AP_SYS_AUTO_SLEEP_CFG*/
656 {"GSP_CKG_FORCE_EN", CLK_MON_AP_SYS_AUTO_SLEEP_CFG, 9},
657 {"GSP_AUTO_GATE_EN", CLK_MON_AP_SYS_AUTO_SLEEP_CFG, 8},
658 {"AP_AHB_AUTO_GATE_EN", CLK_MON_AP_SYS_AUTO_SLEEP_CFG, 5},
659 {"CA7_DBG_FORCE_SLEEP", CLK_MON_AP_SYS_AUTO_SLEEP_CFG, 2},
660 {"CA7_DBG_AUTO_GATE_EN", CLK_MON_AP_SYS_AUTO_SLEEP_CFG, 1},
661 {"CA7_CORE_AUTO_GATE_EN", CLK_MON_AP_SYS_AUTO_SLEEP_CFG, 0},
664 {"INTC3_EB", CLK_MON_APB_EB, 22},
665 {"INTC2_EB", CLK_MON_APB_EB, 21},
666 {"INTC1_EB", CLK_MON_APB_EB, 20},
667 {"INTC0_EB", CLK_MON_APB_EB, 19},
668 {"CKG_EB", CLK_MON_APB_EB, 18},
669 {"UART4_EB", CLK_MON_APB_EB, 17},
670 {"UART3_EB", CLK_MON_APB_EB, 16},
671 {"UART2_EB", CLK_MON_APB_EB, 15},
672 {"UART1_EB", CLK_MON_APB_EB, 14},
673 {"UART0_EB", CLK_MON_APB_EB, 13},
674 {"I2C4_EB", CLK_MON_APB_EB, 12},
675 {"I2C3_EB", CLK_MON_APB_EB, 11},
676 {"I2C2_EB", CLK_MON_APB_EB, 10},
677 {"I2C1_EB", CLK_MON_APB_EB, 9},
678 {"I2C0_EB", CLK_MON_APB_EB, 8},
679 {"SPI2_EB", CLK_MON_APB_EB, 7},
680 {"SPI1_EB", CLK_MON_APB_EB, 6},
681 {"SPI0_EB", CLK_MON_APB_EB, 5},
682 {"IIS3_EB", CLK_MON_APB_EB, 4},
683 {"IIS2_EB", CLK_MON_APB_EB, 3},
684 {"IIS1_EB", CLK_MON_APB_EB, 2},
685 {"IIS0_EB", CLK_MON_APB_EB, 1},
686 {"SIM0_EB", CLK_MON_APB_EB, 0},
688 /* Always on APB EB0 */
689 {"I2C_EB", CLK_MON_AON_APB_EB0, 31},
690 {"CA7_DAP_EB", CLK_MON_AON_APB_EB0, 30},
691 {"CA7_TS1_EB", CLK_MON_AON_APB_EB0, 29},
692 {"CA7_TS0_EB", CLK_MON_AON_APB_EB0, 28},
693 {"GPU_EB", CLK_MON_AON_APB_EB0, 27},
694 {"CKG_EB", CLK_MON_AON_APB_EB0, 26},
695 {"MM_EB", CLK_MON_AON_APB_EB0, 25},
696 {"AP_WDG_EB", CLK_MON_AON_APB_EB0, 24},
697 {"MSPI_EB", CLK_MON_AON_APB_EB0, 23},
698 {"SPLK_EB", CLK_MON_AON_APB_EB0, 22},
699 {"IPII_EB", CLK_MON_AON_APB_EB0, 21},
700 {"PIN_EB", CLK_MON_AON_APB_EB0, 20},
701 {"VBC_EB", CLK_MON_AON_APB_EB0, 19},
702 {"AUD_EB", CLK_MON_AON_APB_EB0, 18},
703 {"AUDIF_EB", CLK_MON_AON_APB_EB0, 17},
704 {"ADI_EB", CLK_MON_AON_APB_EB0, 16},
705 {"INTC_EB", CLK_MON_AON_APB_EB0, 15},
706 {"EIC_EB", CLK_MON_AON_APB_EB0, 14},
707 {"EFUSE_EB", CLK_MON_AON_APB_EB0, 13},
708 {"AP_TMR0_EB", CLK_MON_AON_APB_EB0, 12},
709 {"AON_TMR_EB", CLK_MON_AON_APB_EB0, 11},
710 {"AP_SYST_EB", CLK_MON_AON_APB_EB0, 10},
711 {"AON_SYST_EB", CLK_MON_AON_APB_EB0, 9},
712 {"KPD_EB", CLK_MON_AON_APB_EB0, 8},
713 {"PWM3_EB", CLK_MON_AON_APB_EB0, 7},
714 {"PWM2_EB", CLK_MON_AON_APB_EB0, 6},
715 {"PWM1_EB", CLK_MON_AON_APB_EB0, 5},
716 {"PWM0_EB", CLK_MON_AON_APB_EB0, 4},
717 {"GPIO_EB", CLK_MON_AON_APB_EB0, 3},
718 {"TPC_EB", CLK_MON_AON_APB_EB0, 2},
719 {"FM_EB", CLK_MON_AON_APB_EB0, 1},
720 {"ADC_EB", CLK_MON_AON_APB_EB0, 0},
722 /* Always on APB EB1 */
723 {"CODEC_EB", CLK_MON_AON_APB_EB1, 14},
724 {"GSP_EMC_EB", CLK_MON_AON_APB_EB1, 13},
725 {"ZIP_EMC_EB", CLK_MON_AON_APB_EB1, 12},
726 {"DISP_EMC_EB", CLK_MON_AON_APB_EB1, 11},
727 {"AP_TMR2_EB", CLK_MON_AON_APB_EB1, 10},
728 {"AP_TMR1_EB", CLK_MON_AON_APB_EB1, 9},
729 {"CA7_WDG_EB", CLK_MON_AON_APB_EB1, 8},
730 {"AVS1_EB", CLK_MON_AON_APB_EB1, 7},
731 {"AVS0_EB", CLK_MON_AON_APB_EB1, 6},
732 {"PROBE_EB", CLK_MON_AON_APB_EB1, 5},
733 {"AUX2_EB", CLK_MON_AON_APB_EB1, 4},
734 {"AUX1_EB", CLK_MON_AON_APB_EB1, 3},
735 {"AUX0_EB", CLK_MON_AON_APB_EB1, 2},
736 {"THM_EB", CLK_MON_AON_APB_EB1, 1},
737 {"PMU_EB", CLK_MON_AON_APB_EB1, 0},
739 /* PMU_APB_PWR_STATUS0_DBG */
740 {"PD_MM_TOP_STATE", CLK_MON_PWR_STATUS0_DBG, 30},
741 {"PD_GPU_TOP_STATE", CLK_MON_PWR_STATUS0_DBG, 26},
742 {"PD_CA7_C3_STATE", CLK_MON_PWR_STATUS0_DBG, 18},
743 {"PD_CA7_C2_STATE", CLK_MON_PWR_STATUS0_DBG, 14},
744 {"PD_CA7_C1_STATE", CLK_MON_PWR_STATUS0_DBG, 10},
745 {"PD_CA7_C0_STATE", CLK_MON_PWR_STATUS0_DBG, 6},
746 {"PD_CA7_TOP_STATE", CLK_MON_PWR_STATUS0_DBG, 2},
748 /* PMU_APB_PWR_STATUS1_DBG */
749 {"PD_CP0_SYS_STATE", CLK_MON_PWR_STATUS1_DBG, 30},
750 {"PD_CP0_GSM_STATE", CLK_MON_PWR_STATUS1_DBG, 22},
751 {"PD_CP0_HU3GE_STATE", CLK_MON_PWR_STATUS1_DBG, 18},
752 {"PD_CP0_ARM9_2_STATE", CLK_MON_PWR_STATUS1_DBG, 14},
753 {"PD_CP0_ARM9_1_STATE", CLK_MON_PWR_STATUS1_DBG, 10},
754 {"PD_CP0_ARM9", CLK_MON_PWR_STATUS1_DBG, 6},
755 {"PD_AP_SYS_STATE", CLK_MON_PWR_STATUS1_DBG, 2},
757 /* PMU_APB_PWR_STATUS2_DBG */
758 {"PD_CP2_WIFI_STATE", CLK_MON_PWR_STATUS2_DBG, 26},
759 {"PD_CP2_ARM9_STATE", CLK_MON_PWR_STATUS2_DBG, 22},
760 {"PD_CP1_SYS_STATE", CLK_MON_PWR_STATUS2_DBG, 18},
761 {"PD_CP1_L1RAM_STATE", CLK_MON_PWR_STATUS2_DBG, 14},
762 {"PD_CP1_TD_STATE", CLK_MON_PWR_STATUS2_DBG, 10},
763 {"PD_CP1_GSM_STATE", CLK_MON_PWR_STATUS2_DBG, 6},
764 {"PD_CP1_ARM9_STATE", CLK_MON_PWR_STATUS2_DBG, 2},
766 /* PMU_APB_PWR_STATUS3_DBG */
767 {"PD_PUB_SYS_STATE", CLK_MON_PWR_STATUS3_DBG, 6},
768 {"PD_CP2_SYS_STATE", CLK_MON_PWR_STATUS3_DBG, 2},
770 /* PMU_APB_SLEEP_STATUS */
771 {"CP2_SLP_STATUS", CLK_MON_APB_SLEEP_STATUS, 14},
772 {"CP1_SLP_STATUS", CLK_MON_APB_SLEEP_STATUS, 10},
773 {"CP0_SLP_STATUS", CLK_MON_APB_SLEEP_STATUS, 6},
774 {"AP_SLP_STATUS", CLK_MON_APB_SLEEP_STATUS,2},
776 /* End [160+ clocks]*/
777 /* Any Missing Clocks to be added here */
782 clk_gate_masks = kmalloc(sizeof(clk_gate_mask_temp), GFP_KERNEL);
786 memcpy(clk_gate_masks, clk_gate_mask_temp, sizeof( clk_gate_mask_temp ));
791 misc_deregister(&clk_mon_device);
796 static void __exit clk_mon_exit(void)
799 kfree(clk_gate_masks);
800 misc_deregister(&clk_mon_device);
803 module_init(clk_mon_init);
804 module_exit(clk_mon_exit);
806 MODULE_AUTHOR("Himanshu Sheth <himanshu.s@samsung.com>");
807 MODULE_DESCRIPTION("Clock Gate Monitor");
808 MODULE_LICENSE("GPL");