Merge changes I3c3c58de,If73198f2 into msm-3.4
* changes:
cs: use device attributes instead of kobj attributes
cs: let each driver manage the clk for its device
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 481cd3d..fa91249 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -5069,8 +5069,12 @@
CLK_LOOKUP("mem_a_clk", ebi1_msmbus_a_clk.c, "msm_bus"),
CLK_LOOKUP("dfab_clk", dfab_msmbus_clk.c, "msm_bus"),
CLK_LOOKUP("dfab_a_clk", dfab_msmbus_a_clk.c, "msm_bus"),
- CLK_LOOKUP("core_clk", qdss_clk.c, "msm_qdss"),
- CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "msm_qdss"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, ""),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "msm_etb.0"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "msm_tpiu.0"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "msm_funnel.0"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "msm_stm.0"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "msm_etm.0"),
CLK_LOOKUP("ebi1_clk", ebi1_clk.c, ""),
CLK_LOOKUP("mmfpb_clk", mmfpb_clk.c, ""),
@@ -5395,8 +5399,12 @@
CLK_LOOKUP("mem_a_clk", ebi1_msmbus_a_clk.c, "msm_bus"),
CLK_LOOKUP("dfab_clk", dfab_msmbus_clk.c, "msm_bus"),
CLK_LOOKUP("dfab_a_clk", dfab_msmbus_a_clk.c, "msm_bus"),
- CLK_LOOKUP("core_clk", qdss_clk.c, "msm_qdss"),
- CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "msm_qdss"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, ""),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "msm_etb.0"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "msm_tpiu.0"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "msm_funnel.0"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "msm_stm.0"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "msm_etm.0"),
CLK_LOOKUP("ebi1_clk", ebi1_clk.c, NULL),
CLK_LOOKUP("mmfpb_clk", mmfpb_clk.c, NULL),
@@ -5713,8 +5721,12 @@
CLK_LOOKUP("mem_a_clk", ebi1_msmbus_a_clk.c, "msm_bus"),
CLK_LOOKUP("dfab_clk", dfab_msmbus_clk.c, "msm_bus"),
CLK_LOOKUP("dfab_a_clk", dfab_msmbus_a_clk.c, "msm_bus"),
- CLK_LOOKUP("core_clk", qdss_clk.c, "msm_qdss"),
- CLK_LOOKUP("core_a_clk", qdss_a_clk.c, "msm_qdss"),
+ CLK_LOOKUP("core_a_clk", qdss_a_clk.c, ""),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "msm_etb.0"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "msm_tpiu.0"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "msm_funnel.0"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "msm_stm.0"),
+ CLK_LOOKUP("core_clk", qdss_clk.c, "msm_etm.0"),
CLK_LOOKUP("ebi1_clk", ebi1_clk.c, NULL),
CLK_LOOKUP("mmfpb_clk", mmfpb_clk.c, NULL),
diff --git a/drivers/cs/cs-etb.c b/drivers/cs/cs-etb.c
index 84d8e72..c4cf19e 100644
--- a/drivers/cs/cs-etb.c
+++ b/drivers/cs/cs-etb.c
@@ -24,6 +24,7 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/mutex.h>
+#include <linux/clk.h>
#include <linux/cs.h>
#include "cs-priv.h"
@@ -74,6 +75,7 @@
atomic_t in_use;
struct device *dev;
struct kobject *kobj;
+ struct clk *clk;
uint32_t trigger_cntr;
};
@@ -99,15 +101,22 @@
ETB_LOCK();
}
-void etb_enable(void)
+int etb_enable(void)
{
+ int ret;
unsigned long flags;
+ ret = clk_prepare_enable(etb.clk);
+ if (ret)
+ return ret;
+
spin_lock_irqsave(&etb.spinlock, flags);
__etb_enable();
etb.enabled = true;
dev_info(etb.dev, "ETB enabled\n");
spin_unlock_irqrestore(&etb.spinlock, flags);
+
+ return 0;
}
static void __etb_disable(void)
@@ -147,6 +156,8 @@
etb.enabled = false;
dev_info(etb.dev, "ETB disabled\n");
spin_unlock_irqrestore(&etb.spinlock, flags);
+
+ clk_disable_unprepare(etb.clk);
}
static void __etb_dump(void)
@@ -275,13 +286,16 @@
.fops = &etb_fops,
};
-#define ETB_ATTR(__name) \
-static struct kobj_attribute __name##_attr = \
- __ATTR(__name, S_IRUGO | S_IWUSR, __name##_show, __name##_store)
+static ssize_t etb_show_trigger_cntr(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val = etb.trigger_cntr;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
-static ssize_t trigger_cntr_store(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf, size_t n)
+static ssize_t etb_store_trigger_cntr(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
unsigned long val;
@@ -289,16 +303,10 @@
return -EINVAL;
etb.trigger_cntr = val;
- return n;
+ return size;
}
-static ssize_t trigger_cntr_show(struct kobject *kobj,
- struct kobj_attribute *attr,
- char *buf)
-{
- unsigned long val = etb.trigger_cntr;
- return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
-}
-ETB_ATTR(trigger_cntr);
+static DEVICE_ATTR(trigger_cntr, S_IRUGO | S_IWUSR, etb_show_trigger_cntr,
+ etb_store_trigger_cntr);
static int __devinit etb_sysfs_init(void)
{
@@ -311,7 +319,7 @@
goto err_create;
}
- ret = sysfs_create_file(etb.kobj, &trigger_cntr_attr.attr);
+ ret = sysfs_create_file(etb.kobj, &dev_attr_trigger_cntr.attr);
if (ret) {
dev_err(etb.dev, "failed to create ETB sysfs trigger_cntr"
" attribute\n");
@@ -327,7 +335,7 @@
static void __devexit etb_sysfs_exit(void)
{
- sysfs_remove_file(etb.kobj, &trigger_cntr_attr.attr);
+ sysfs_remove_file(etb.kobj, &dev_attr_trigger_cntr.attr);
kobject_put(etb.kobj);
}
@@ -352,6 +360,16 @@
spin_lock_init(&etb.spinlock);
+ etb.clk = clk_get(etb.dev, "core_clk");
+ if (IS_ERR(etb.clk)) {
+ ret = PTR_ERR(etb.clk);
+ goto err_clk_get;
+ }
+
+ ret = clk_set_rate(etb.clk, CS_CLK_RATE_TRACE);
+ if (ret)
+ goto err_clk_rate;
+
ret = misc_register(&etb_misc);
if (ret)
goto err_misc;
@@ -370,6 +388,9 @@
err_alloc:
misc_deregister(&etb_misc);
err_misc:
+err_clk_rate:
+ clk_put(etb.clk);
+err_clk_get:
iounmap(etb.base);
err_ioremap:
err_res:
@@ -384,6 +405,7 @@
etb_sysfs_exit();
kfree(etb.buf);
misc_deregister(&etb_misc);
+ clk_put(etb.clk);
iounmap(etb.base);
return 0;
diff --git a/drivers/cs/cs-etm.c b/drivers/cs/cs-etm.c
index 724cc71..4e409cb 100644
--- a/drivers/cs/cs-etm.c
+++ b/drivers/cs/cs-etm.c
@@ -26,6 +26,7 @@
#include <linux/pm_qos.h>
#include <linux/sysfs.h>
#include <linux/stat.h>
+#include <linux/clk.h>
#include <linux/cs.h>
#include <asm/sections.h>
#include <mach/socinfo.h>
@@ -161,6 +162,7 @@
struct mutex mutex;
struct device *dev;
struct kobject *kobj;
+ struct clk *clk;
uint8_t arch;
uint8_t nr_addr_cmp;
uint8_t nr_cntr;
@@ -351,6 +353,10 @@
*/
pm_qos_update_request(&etm.qos_req, 0);
+ ret = clk_prepare_enable(etm.clk);
+ if (ret)
+ goto err_clk;
+
ret = qdss_enable(etm.src);
if (ret)
goto err_qdss;
@@ -367,6 +373,8 @@
return 0;
err_qdss:
+ clk_disable_unprepare(etm.clk);
+err_clk:
pm_qos_update_request(&etm.qos_req, PM_QOS_DEFAULT_VALUE);
wake_unlock(&etm.wake_lock);
err:
@@ -409,9 +417,11 @@
for_each_online_cpu(cpu)
__etm_disable(cpu);
+ etm.enabled = false;
+
qdss_disable(etm.src);
- etm.enabled = false;
+ clk_disable_unprepare(etm.clk);
pm_qos_update_request(&etm.qos_req, PM_QOS_DEFAULT_VALUE);
wake_unlock(&etm.wake_lock);
@@ -431,39 +441,16 @@
asm("isb\n\t");
}
-#define ETM_STORE(__name, mask) \
-static ssize_t __name##_store(struct kobject *kobj, \
- struct kobj_attribute *attr, \
- const char *buf, size_t n) \
-{ \
- unsigned long val; \
- \
- if (sscanf(buf, "%lx", &val) != 1) \
- return -EINVAL; \
- \
- etm.__name = val & mask; \
- return n; \
+static ssize_t etm_show_enabled(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val = etm.enabled;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
-#define ETM_SHOW(__name) \
-static ssize_t __name##_show(struct kobject *kobj, \
- struct kobj_attribute *attr, \
- char *buf) \
-{ \
- unsigned long val = etm.__name; \
- return scnprintf(buf, PAGE_SIZE, "%#lx\n", val); \
-}
-
-#define ETM_ATTR(__name) \
-static struct kobj_attribute __name##_attr = \
- __ATTR(__name, S_IRUGO | S_IWUSR, __name##_show, __name##_store)
-#define ETM_ATTR_RO(__name) \
-static struct kobj_attribute __name##_attr = \
- __ATTR(__name, S_IRUGO, __name##_show, NULL)
-
-static ssize_t enabled_store(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf, size_t n)
+static ssize_t etm_store_enabled(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
int ret = 0;
unsigned long val;
@@ -480,22 +467,46 @@
if (ret)
return ret;
- return n;
+ return size;
}
-ETM_SHOW(enabled);
-ETM_ATTR(enabled);
+static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, etm_show_enabled,
+ etm_store_enabled);
-ETM_SHOW(nr_addr_cmp);
-ETM_ATTR_RO(nr_addr_cmp);
-ETM_SHOW(nr_cntr);
-ETM_ATTR_RO(nr_cntr);
-ETM_SHOW(nr_ctxid_cmp);
-ETM_ATTR_RO(nr_ctxid_cmp);
+static ssize_t etm_show_nr_addr_cmp(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val = etm.nr_addr_cmp;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+static DEVICE_ATTR(nr_addr_cmp, S_IRUGO, etm_show_nr_addr_cmp, NULL);
+
+static ssize_t etm_show_nr_cntr(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val = etm.nr_cntr;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+static DEVICE_ATTR(nr_cntr, S_IRUGO, etm_show_nr_cntr, NULL);
+
+static ssize_t etm_show_nr_ctxid_cmp(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val = etm.nr_ctxid_cmp;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+static DEVICE_ATTR(nr_ctxid_cmp, S_IRUGO, etm_show_nr_ctxid_cmp, NULL);
+
+static ssize_t etm_show_reset(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val = etm.reset;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
/* Reset to trace everything i.e. exclude nothing. */
-static ssize_t reset_store(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf, size_t n)
+static ssize_t etm_store_reset(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t size)
{
int i;
unsigned long val;
@@ -544,14 +555,19 @@
etm.timestamp_event = 0x406F;
}
mutex_unlock(&etm.mutex);
- return n;
+ return size;
}
-ETM_SHOW(reset);
-ETM_ATTR(reset);
+static DEVICE_ATTR(reset, S_IRUGO | S_IWUSR, etm_show_reset, etm_store_reset);
-static ssize_t mode_store(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf, size_t n)
+static ssize_t etm_show_mode(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val = etm.mode;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_mode(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t size)
{
unsigned long val;
@@ -586,26 +602,86 @@
etm.ctrl &= ~(BIT(14) | BIT(15));
mutex_unlock(&etm.mutex);
- return n;
+ return size;
}
-ETM_SHOW(mode);
-ETM_ATTR(mode);
+static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, etm_show_mode, etm_store_mode);
-ETM_STORE(trigger_event, ETM_EVENT_MASK);
-ETM_SHOW(trigger_event);
-ETM_ATTR(trigger_event);
+static ssize_t etm_show_trigger_event(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val = etm.trigger_event;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
-ETM_STORE(enable_event, ETM_EVENT_MASK);
-ETM_SHOW(enable_event);
-ETM_ATTR(enable_event);
+static ssize_t etm_store_trigger_event(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
-ETM_STORE(fifofull_level, ETM_ALL_MASK);
-ETM_SHOW(fifofull_level);
-ETM_ATTR(fifofull_level);
+ if (sscanf(buf, "%lx", &val) != 1)
+ return -EINVAL;
-static ssize_t addr_idx_store(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf, size_t n)
+ etm.trigger_event = val & ETM_EVENT_MASK;
+ return size;
+}
+static DEVICE_ATTR(trigger_event, S_IRUGO | S_IWUSR, etm_show_trigger_event,
+ etm_store_trigger_event);
+
+static ssize_t etm_show_enable_event(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val = etm.enable_event;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_enable_event(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+
+ if (sscanf(buf, "%lx", &val) != 1)
+ return -EINVAL;
+
+ etm.enable_event = val & ETM_EVENT_MASK;
+ return size;
+}
+static DEVICE_ATTR(enable_event, S_IRUGO | S_IWUSR, etm_show_enable_event,
+ etm_store_enable_event);
+
+static ssize_t etm_show_fifofull_level(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val = etm.fifofull_level;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_fifofull_level(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+
+ if (sscanf(buf, "%lx", &val) != 1)
+ return -EINVAL;
+
+ etm.fifofull_level = val;
+ return size;
+}
+static DEVICE_ATTR(fifofull_level, S_IRUGO | S_IWUSR, etm_show_fifofull_level,
+ etm_store_fifofull_level);
+
+static ssize_t etm_show_addr_idx(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val = etm.addr_idx;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_addr_idx(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
unsigned long val;
@@ -620,14 +696,33 @@
mutex_lock(&etm.mutex);
etm.addr_idx = val;
mutex_unlock(&etm.mutex);
- return n;
+ return size;
}
-ETM_SHOW(addr_idx);
-ETM_ATTR(addr_idx);
+static DEVICE_ATTR(addr_idx, S_IRUGO | S_IWUSR, etm_show_addr_idx,
+ etm_store_addr_idx);
-static ssize_t addr_single_store(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf, size_t n)
+static ssize_t etm_show_addr_single(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val;
+ uint8_t idx;
+
+ mutex_lock(&etm.mutex);
+ idx = etm.addr_idx;
+ if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+ etm.addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
+ mutex_unlock(&etm.mutex);
+ return -EPERM;
+ }
+
+ val = etm.addr_val[idx];
+ mutex_unlock(&etm.mutex);
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_addr_single(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
unsigned long val;
uint8_t idx;
@@ -646,32 +741,40 @@
etm.addr_val[idx] = val;
etm.addr_type[idx] = ETM_ADDR_TYPE_SINGLE;
mutex_unlock(&etm.mutex);
- return n;
+ return size;
}
-static ssize_t addr_single_show(struct kobject *kobj,
- struct kobj_attribute *attr,
- char *buf)
+static DEVICE_ATTR(addr_single, S_IRUGO | S_IWUSR, etm_show_addr_single,
+ etm_store_addr_single);
+
+static ssize_t etm_show_addr_range(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- unsigned long val;
+ unsigned long val1, val2;
uint8_t idx;
mutex_lock(&etm.mutex);
idx = etm.addr_idx;
- if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
- etm.addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
+ if (idx % 2 != 0) {
+ mutex_unlock(&etm.mutex);
+ return -EPERM;
+ }
+ if (!((etm.addr_type[idx] == ETM_ADDR_TYPE_NONE &&
+ etm.addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
+ (etm.addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
+ etm.addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
mutex_unlock(&etm.mutex);
return -EPERM;
}
- val = etm.addr_val[idx];
+ val1 = etm.addr_val[idx];
+ val2 = etm.addr_val[idx + 1];
mutex_unlock(&etm.mutex);
- return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+ return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
}
-ETM_ATTR(addr_single);
-static ssize_t addr_range_store(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf, size_t n)
+static ssize_t etm_store_addr_range(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
unsigned long val1, val2;
uint8_t idx;
@@ -702,39 +805,33 @@
etm.addr_type[idx + 1] = ETM_ADDR_TYPE_RANGE;
etm.enable_ctrl1 |= (1 << (idx/2));
mutex_unlock(&etm.mutex);
- return n;
+ return size;
}
-static ssize_t addr_range_show(struct kobject *kobj,
- struct kobj_attribute *attr,
- char *buf)
+static DEVICE_ATTR(addr_range, S_IRUGO | S_IWUSR, etm_show_addr_range,
+ etm_store_addr_range);
+
+static ssize_t etm_show_addr_start(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- unsigned long val1, val2;
+ unsigned long val;
uint8_t idx;
mutex_lock(&etm.mutex);
idx = etm.addr_idx;
- if (idx % 2 != 0) {
- mutex_unlock(&etm.mutex);
- return -EPERM;
- }
- if (!((etm.addr_type[idx] == ETM_ADDR_TYPE_NONE &&
- etm.addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
- (etm.addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
- etm.addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
+ if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+ etm.addr_type[idx] == ETM_ADDR_TYPE_START)) {
mutex_unlock(&etm.mutex);
return -EPERM;
}
- val1 = etm.addr_val[idx];
- val2 = etm.addr_val[idx + 1];
+ val = etm.addr_val[idx];
mutex_unlock(&etm.mutex);
- return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
-ETM_ATTR(addr_range);
-static ssize_t addr_start_store(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf, size_t n)
+static ssize_t etm_store_addr_start(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
unsigned long val;
uint8_t idx;
@@ -755,11 +852,13 @@
etm.startstop_ctrl |= (1 << idx);
etm.enable_ctrl1 |= BIT(25);
mutex_unlock(&etm.mutex);
- return n;
+ return size;
}
-static ssize_t addr_start_show(struct kobject *kobj,
- struct kobj_attribute *attr,
- char *buf)
+static DEVICE_ATTR(addr_start, S_IRUGO | S_IWUSR, etm_show_addr_start,
+ etm_store_addr_start);
+
+static ssize_t etm_show_addr_stop(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
unsigned long val;
uint8_t idx;
@@ -767,7 +866,7 @@
mutex_lock(&etm.mutex);
idx = etm.addr_idx;
if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
- etm.addr_type[idx] == ETM_ADDR_TYPE_START)) {
+ etm.addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
mutex_unlock(&etm.mutex);
return -EPERM;
}
@@ -776,11 +875,10 @@
mutex_unlock(&etm.mutex);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
-ETM_ATTR(addr_start);
-static ssize_t addr_stop_store(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf, size_t n)
+static ssize_t etm_store_addr_stop(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
unsigned long val;
uint8_t idx;
@@ -801,32 +899,25 @@
etm.startstop_ctrl |= (1 << (idx + 16));
etm.enable_ctrl1 |= BIT(25);
mutex_unlock(&etm.mutex);
- return n;
+ return size;
}
-static ssize_t addr_stop_show(struct kobject *kobj,
- struct kobj_attribute *attr,
- char *buf)
+static DEVICE_ATTR(addr_stop, S_IRUGO | S_IWUSR, etm_show_addr_stop,
+ etm_store_addr_stop);
+
+static ssize_t etm_show_addr_acctype(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
unsigned long val;
- uint8_t idx;
mutex_lock(&etm.mutex);
- idx = etm.addr_idx;
- if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
- etm.addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
- mutex_unlock(&etm.mutex);
- return -EPERM;
- }
-
- val = etm.addr_val[idx];
+ val = etm.addr_acctype[etm.addr_idx];
mutex_unlock(&etm.mutex);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
-ETM_ATTR(addr_stop);
-static ssize_t addr_acctype_store(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf, size_t n)
+static ssize_t etm_store_addr_acctype(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
unsigned long val;
@@ -836,24 +927,21 @@
mutex_lock(&etm.mutex);
etm.addr_acctype[etm.addr_idx] = val;
mutex_unlock(&etm.mutex);
- return n;
+ return size;
}
-static ssize_t addr_acctype_show(struct kobject *kobj,
- struct kobj_attribute *attr,
- char *buf)
-{
- unsigned long val;
+static DEVICE_ATTR(addr_acctype, S_IRUGO | S_IWUSR, etm_show_addr_acctype,
+ etm_store_addr_acctype);
- mutex_lock(&etm.mutex);
- val = etm.addr_acctype[etm.addr_idx];
- mutex_unlock(&etm.mutex);
+static ssize_t etm_show_cntr_idx(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val = etm.addr_idx;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
-ETM_ATTR(addr_acctype);
-static ssize_t cntr_idx_store(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf, size_t n)
+static ssize_t etm_store_cntr_idx(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
unsigned long val;
@@ -868,14 +956,24 @@
mutex_lock(&etm.mutex);
etm.cntr_idx = val;
mutex_unlock(&etm.mutex);
- return n;
+ return size;
}
-ETM_SHOW(cntr_idx);
-ETM_ATTR(cntr_idx);
+static DEVICE_ATTR(cntr_idx, S_IRUGO | S_IWUSR, etm_show_cntr_idx,
+ etm_store_cntr_idx);
-static ssize_t cntr_rld_val_store(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf, size_t n)
+static ssize_t etm_show_cntr_rld_val(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val;
+ mutex_lock(&etm.mutex);
+ val = etm.cntr_rld_val[etm.cntr_idx];
+ mutex_unlock(&etm.mutex);
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_cntr_rld_val(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
unsigned long val;
@@ -885,23 +983,25 @@
mutex_lock(&etm.mutex);
etm.cntr_rld_val[etm.cntr_idx] = val;
mutex_unlock(&etm.mutex);
- return n;
+ return size;
}
-static ssize_t cntr_rld_val_show(struct kobject *kobj,
- struct kobj_attribute *attr,
- char *buf)
+static DEVICE_ATTR(cntr_rld_val, S_IRUGO | S_IWUSR, etm_show_cntr_rld_val,
+ etm_store_cntr_rld_val);
+
+static ssize_t etm_show_cntr_event(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
unsigned long val;
+
mutex_lock(&etm.mutex);
- val = etm.cntr_rld_val[etm.cntr_idx];
+ val = etm.cntr_event[etm.cntr_idx];
mutex_unlock(&etm.mutex);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
-ETM_ATTR(cntr_rld_val);
-static ssize_t cntr_event_store(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf, size_t n)
+static ssize_t etm_store_cntr_event(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
unsigned long val;
@@ -911,24 +1011,25 @@
mutex_lock(&etm.mutex);
etm.cntr_event[etm.cntr_idx] = val & ETM_EVENT_MASK;
mutex_unlock(&etm.mutex);
- return n;
+ return size;
}
-static ssize_t cntr_event_show(struct kobject *kobj,
- struct kobj_attribute *attr,
- char *buf)
+static DEVICE_ATTR(cntr_event, S_IRUGO | S_IWUSR, etm_show_cntr_event,
+ etm_store_cntr_event);
+
+static ssize_t etm_show_cntr_rld_event(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
unsigned long val;
mutex_lock(&etm.mutex);
- val = etm.cntr_event[etm.cntr_idx];
+ val = etm.cntr_rld_event[etm.cntr_idx];
mutex_unlock(&etm.mutex);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
-ETM_ATTR(cntr_event);
-static ssize_t cntr_rld_event_store(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf, size_t n)
+static ssize_t etm_store_cntr_rld_event(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
unsigned long val;
@@ -938,24 +1039,25 @@
mutex_lock(&etm.mutex);
etm.cntr_rld_event[etm.cntr_idx] = val & ETM_EVENT_MASK;
mutex_unlock(&etm.mutex);
- return n;
+ return size;
}
-static ssize_t cntr_rld_event_show(struct kobject *kobj,
- struct kobj_attribute *attr,
- char *buf)
+static DEVICE_ATTR(cntr_rld_event, S_IRUGO | S_IWUSR, etm_show_cntr_rld_event,
+ etm_store_cntr_rld_event);
+
+static ssize_t etm_show_cntr_val(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
unsigned long val;
mutex_lock(&etm.mutex);
- val = etm.cntr_rld_event[etm.cntr_idx];
+ val = etm.cntr_val[etm.cntr_idx];
mutex_unlock(&etm.mutex);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
-ETM_ATTR(cntr_rld_event);
-static ssize_t cntr_val_store(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf, size_t n)
+static ssize_t etm_store_cntr_val(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
unsigned long val;
@@ -965,48 +1067,153 @@
mutex_lock(&etm.mutex);
etm.cntr_val[etm.cntr_idx] = val;
mutex_unlock(&etm.mutex);
- return n;
+ return size;
}
-static ssize_t cntr_val_show(struct kobject *kobj,
- struct kobj_attribute *attr,
- char *buf)
+static DEVICE_ATTR(cntr_val, S_IRUGO | S_IWUSR, etm_show_cntr_val,
+ etm_store_cntr_val);
+
+static ssize_t etm_show_seq_12_event(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val = etm.seq_12_event;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_seq_12_event(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
unsigned long val;
- mutex_lock(&etm.mutex);
- val = etm.cntr_val[etm.cntr_idx];
- mutex_unlock(&etm.mutex);
+ if (sscanf(buf, "%lx", &val) != 1)
+ return -EINVAL;
+
+ etm.seq_12_event = val & ETM_EVENT_MASK;
+ return size;
+}
+static DEVICE_ATTR(seq_12_event, S_IRUGO | S_IWUSR, etm_show_seq_12_event,
+ etm_store_seq_12_event);
+
+static ssize_t etm_show_seq_21_event(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val = etm.seq_21_event;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
-ETM_ATTR(cntr_val);
-ETM_STORE(seq_12_event, ETM_EVENT_MASK);
-ETM_SHOW(seq_12_event);
-ETM_ATTR(seq_12_event);
+static ssize_t etm_store_seq_21_event(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
-ETM_STORE(seq_21_event, ETM_EVENT_MASK);
-ETM_SHOW(seq_21_event);
-ETM_ATTR(seq_21_event);
+ if (sscanf(buf, "%lx", &val) != 1)
+ return -EINVAL;
-ETM_STORE(seq_23_event, ETM_EVENT_MASK);
-ETM_SHOW(seq_23_event);
-ETM_ATTR(seq_23_event);
+ etm.seq_21_event = val & ETM_EVENT_MASK;
+ return size;
+}
+static DEVICE_ATTR(seq_21_event, S_IRUGO | S_IWUSR, etm_show_seq_21_event,
+ etm_store_seq_21_event);
-ETM_STORE(seq_31_event, ETM_EVENT_MASK);
-ETM_SHOW(seq_31_event);
-ETM_ATTR(seq_31_event);
+static ssize_t etm_show_seq_23_event(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val = etm.seq_23_event;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
-ETM_STORE(seq_32_event, ETM_EVENT_MASK);
-ETM_SHOW(seq_32_event);
-ETM_ATTR(seq_32_event);
+static ssize_t etm_store_seq_23_event(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
-ETM_STORE(seq_13_event, ETM_EVENT_MASK);
-ETM_SHOW(seq_13_event);
-ETM_ATTR(seq_13_event);
+ if (sscanf(buf, "%lx", &val) != 1)
+ return -EINVAL;
-static ssize_t seq_curr_state_store(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf, size_t n)
+ etm.seq_23_event = val & ETM_EVENT_MASK;
+ return size;
+}
+static DEVICE_ATTR(seq_23_event, S_IRUGO | S_IWUSR, etm_show_seq_23_event,
+ etm_store_seq_23_event);
+
+static ssize_t etm_show_seq_31_event(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val = etm.seq_31_event;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_seq_31_event(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+
+ if (sscanf(buf, "%lx", &val) != 1)
+ return -EINVAL;
+
+ etm.seq_31_event = val & ETM_EVENT_MASK;
+ return size;
+}
+static DEVICE_ATTR(seq_31_event, S_IRUGO | S_IWUSR, etm_show_seq_31_event,
+ etm_store_seq_31_event);
+
+static ssize_t etm_show_seq_32_event(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val = etm.seq_32_event;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_seq_32_event(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+
+ if (sscanf(buf, "%lx", &val) != 1)
+ return -EINVAL;
+
+ etm.seq_32_event = val & ETM_EVENT_MASK;
+ return size;
+}
+static DEVICE_ATTR(seq_32_event, S_IRUGO | S_IWUSR, etm_show_seq_32_event,
+ etm_store_seq_32_event);
+
+static ssize_t etm_show_seq_13_event(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val = etm.seq_13_event;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_seq_13_event(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+
+ if (sscanf(buf, "%lx", &val) != 1)
+ return -EINVAL;
+
+ etm.seq_13_event = val & ETM_EVENT_MASK;
+ return size;
+}
+static DEVICE_ATTR(seq_13_event, S_IRUGO | S_IWUSR, etm_show_seq_13_event,
+ etm_store_seq_13_event);
+
+static ssize_t etm_show_seq_curr_state(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val = etm.seq_curr_state;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_seq_curr_state(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
unsigned long val;
@@ -1016,14 +1223,21 @@
return -EINVAL;
etm.seq_curr_state = val;
- return n;
+ return size;
}
-ETM_SHOW(seq_curr_state);
-ETM_ATTR(seq_curr_state);
+static DEVICE_ATTR(seq_curr_state, S_IRUGO | S_IWUSR, etm_show_seq_curr_state,
+ etm_store_seq_curr_state);
-static ssize_t ctxid_idx_store(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf, size_t n)
+static ssize_t etm_show_ctxid_idx(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val = etm.ctxid_idx;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_ctxid_idx(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
unsigned long val;
@@ -1038,14 +1252,25 @@
mutex_lock(&etm.mutex);
etm.ctxid_idx = val;
mutex_unlock(&etm.mutex);
- return n;
+ return size;
}
-ETM_SHOW(ctxid_idx);
-ETM_ATTR(ctxid_idx);
+static DEVICE_ATTR(ctxid_idx, S_IRUGO | S_IWUSR, etm_show_ctxid_idx,
+ etm_store_ctxid_idx);
-static ssize_t ctxid_val_store(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf, size_t n)
+static ssize_t etm_show_ctxid_val(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val;
+
+ mutex_lock(&etm.mutex);
+ val = etm.ctxid_val[etm.ctxid_idx];
+ mutex_unlock(&etm.mutex);
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_ctxid_val(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
unsigned long val;
@@ -1055,65 +1280,110 @@
mutex_lock(&etm.mutex);
etm.ctxid_val[etm.ctxid_idx] = val;
mutex_unlock(&etm.mutex);
- return n;
+ return size;
}
-static ssize_t ctxid_val_show(struct kobject *kobj,
- struct kobj_attribute *attr,
- char *buf)
+static DEVICE_ATTR(ctxid_val, S_IRUGO | S_IWUSR, etm_show_ctxid_val,
+ etm_store_ctxid_val);
+
+static ssize_t etm_show_ctxid_mask(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val = etm.ctxid_mask;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_ctxid_mask(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
unsigned long val;
- mutex_lock(&etm.mutex);
- val = etm.ctxid_val[etm.ctxid_idx];
- mutex_unlock(&etm.mutex);
+ if (sscanf(buf, "%lx", &val) != 1)
+ return -EINVAL;
+
+ etm.ctxid_mask = val;
+ return size;
+}
+static DEVICE_ATTR(ctxid_mask, S_IRUGO | S_IWUSR, etm_show_ctxid_mask,
+ etm_store_ctxid_mask);
+
+static ssize_t etm_show_sync_freq(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val = etm.sync_freq;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
-ETM_ATTR(ctxid_val);
-ETM_STORE(ctxid_mask, ETM_ALL_MASK);
-ETM_SHOW(ctxid_mask);
-ETM_ATTR(ctxid_mask);
+static ssize_t etm_store_sync_freq(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
-ETM_STORE(sync_freq, ETM_SYNC_MASK);
-ETM_SHOW(sync_freq);
-ETM_ATTR(sync_freq);
+ if (sscanf(buf, "%lx", &val) != 1)
+ return -EINVAL;
-ETM_STORE(timestamp_event, ETM_EVENT_MASK);
-ETM_SHOW(timestamp_event);
-ETM_ATTR(timestamp_event);
+ etm.sync_freq = val & ETM_SYNC_MASK;
+ return size;
+}
+static DEVICE_ATTR(sync_freq, S_IRUGO | S_IWUSR, etm_show_sync_freq,
+ etm_store_sync_freq);
+
+static ssize_t etm_show_timestamp_event(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned long val = etm.timestamp_event;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_timestamp_event(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned long val;
+
+ if (sscanf(buf, "%lx", &val) != 1)
+ return -EINVAL;
+
+ etm.timestamp_event = val & ETM_EVENT_MASK;
+ return size;
+}
+static DEVICE_ATTR(timestamp_event, S_IRUGO | S_IWUSR, etm_show_timestamp_event,
+ etm_store_timestamp_event);
static struct attribute *etm_attrs[] = {
- &nr_addr_cmp_attr.attr,
- &nr_cntr_attr.attr,
- &nr_ctxid_cmp_attr.attr,
- &reset_attr.attr,
- &mode_attr.attr,
- &trigger_event_attr.attr,
- &enable_event_attr.attr,
- &fifofull_level_attr.attr,
- &addr_idx_attr.attr,
- &addr_single_attr.attr,
- &addr_range_attr.attr,
- &addr_start_attr.attr,
- &addr_stop_attr.attr,
- &addr_acctype_attr.attr,
- &cntr_idx_attr.attr,
- &cntr_rld_val_attr.attr,
- &cntr_event_attr.attr,
- &cntr_rld_event_attr.attr,
- &cntr_val_attr.attr,
- &seq_12_event_attr.attr,
- &seq_21_event_attr.attr,
- &seq_23_event_attr.attr,
- &seq_31_event_attr.attr,
- &seq_32_event_attr.attr,
- &seq_13_event_attr.attr,
- &seq_curr_state_attr.attr,
- &ctxid_idx_attr.attr,
- &ctxid_val_attr.attr,
- &ctxid_mask_attr.attr,
- &sync_freq_attr.attr,
- ×tamp_event_attr.attr,
+ &dev_attr_nr_addr_cmp.attr,
+ &dev_attr_nr_cntr.attr,
+ &dev_attr_nr_ctxid_cmp.attr,
+ &dev_attr_reset.attr,
+ &dev_attr_mode.attr,
+ &dev_attr_trigger_event.attr,
+ &dev_attr_enable_event.attr,
+ &dev_attr_fifofull_level.attr,
+ &dev_attr_addr_idx.attr,
+ &dev_attr_addr_single.attr,
+ &dev_attr_addr_range.attr,
+ &dev_attr_addr_start.attr,
+ &dev_attr_addr_stop.attr,
+ &dev_attr_addr_acctype.attr,
+ &dev_attr_cntr_idx.attr,
+ &dev_attr_cntr_rld_val.attr,
+ &dev_attr_cntr_event.attr,
+ &dev_attr_cntr_rld_event.attr,
+ &dev_attr_cntr_val.attr,
+ &dev_attr_seq_12_event.attr,
+ &dev_attr_seq_21_event.attr,
+ &dev_attr_seq_23_event.attr,
+ &dev_attr_seq_31_event.attr,
+ &dev_attr_seq_32_event.attr,
+ &dev_attr_seq_13_event.attr,
+ &dev_attr_seq_curr_state.attr,
+ &dev_attr_ctxid_idx.attr,
+ &dev_attr_ctxid_val.attr,
+ &dev_attr_ctxid_mask.attr,
+ &dev_attr_sync_freq.attr,
+ &dev_attr_timestamp_event.attr,
NULL,
};
@@ -1132,7 +1402,7 @@
goto err_create;
}
- ret = sysfs_create_file(etm.kobj, &enabled_attr.attr);
+ ret = sysfs_create_file(etm.kobj, &dev_attr_enabled.attr);
if (ret) {
dev_err(etm.dev, "failed to create ETM sysfs enabled"
" attribute\n");
@@ -1152,7 +1422,7 @@
static void __devexit etm_sysfs_exit(void)
{
sysfs_remove_group(etm.kobj, &etm_attr_grp);
- sysfs_remove_file(etm.kobj, &enabled_attr.attr);
+ sysfs_remove_file(etm.kobj, &dev_attr_enabled.attr);
kobject_put(etm.kobj);
}
@@ -1253,9 +1523,19 @@
goto err_qdssget;
}
- ret = qdss_clk_enable();
+ etm.clk = clk_get(etm.dev, "core_clk");
+ if (IS_ERR(etm.clk)) {
+ ret = PTR_ERR(etm.clk);
+ goto err_clk_get;
+ }
+
+ ret = clk_set_rate(etm.clk, CS_CLK_RATE_TRACE);
if (ret)
- goto err_clk;
+ goto err_clk_rate;
+
+ ret = clk_prepare_enable(etm.clk);
+ if (ret)
+ goto err_clk_enable;
ret = etm_arch_init();
if (ret)
@@ -1267,7 +1547,7 @@
etm.enabled = false;
- qdss_clk_disable();
+ clk_disable_unprepare(etm.clk);
dev_info(etm.dev, "ETM initialized\n");
@@ -1278,8 +1558,11 @@
err_sysfs:
err_arch:
- qdss_clk_disable();
-err_clk:
+ clk_disable_unprepare(etm.clk);
+err_clk_enable:
+err_clk_rate:
+ clk_put(etm.clk);
+err_clk_get:
qdss_put(etm.src);
err_qdssget:
pm_qos_remove_request(&etm.qos_req);
@@ -1297,6 +1580,7 @@
if (etm.enabled)
etm_disable();
etm_sysfs_exit();
+ clk_put(etm.clk);
qdss_put(etm.src);
pm_qos_remove_request(&etm.qos_req);
wake_lock_destroy(&etm.wake_lock);
diff --git a/drivers/cs/cs-funnel.c b/drivers/cs/cs-funnel.c
index 2ae8ac9..414023d 100644
--- a/drivers/cs/cs-funnel.c
+++ b/drivers/cs/cs-funnel.c
@@ -18,6 +18,7 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/err.h>
+#include <linux/clk.h>
#include <linux/cs.h>
#include "cs-priv.h"
@@ -56,6 +57,7 @@
struct mutex mutex;
struct device *dev;
struct kobject *kobj;
+ struct clk *clk;
uint32_t priority;
};
@@ -77,14 +79,22 @@
FUNNEL_LOCK(id);
}
-void funnel_enable(uint8_t id, uint32_t port_mask)
+int funnel_enable(uint8_t id, uint32_t port_mask)
{
+ int ret;
+
+ ret = clk_prepare_enable(funnel.clk);
+ if (ret)
+ return ret;
+
mutex_lock(&funnel.mutex);
__funnel_enable(id, port_mask);
funnel.enabled = true;
dev_info(funnel.dev, "FUNNEL port mask 0x%lx enabled\n",
(unsigned long) port_mask);
mutex_unlock(&funnel.mutex);
+
+ return 0;
}
static void __funnel_disable(uint8_t id, uint32_t port_mask)
@@ -108,15 +118,20 @@
dev_info(funnel.dev, "FUNNEL port mask 0x%lx disabled\n",
(unsigned long) port_mask);
mutex_unlock(&funnel.mutex);
+
+ clk_disable_unprepare(funnel.clk);
}
-#define FUNNEL_ATTR(__name) \
-static struct kobj_attribute __name##_attr = \
- __ATTR(__name, S_IRUGO | S_IWUSR, __name##_show, __name##_store)
+static ssize_t funnel_show_priority(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val = funnel.priority;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
-static ssize_t priority_store(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf, size_t n)
+static ssize_t funnel_store_priority(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
unsigned long val;
@@ -124,16 +139,10 @@
return -EINVAL;
funnel.priority = val;
- return n;
+ return size;
}
-static ssize_t priority_show(struct kobject *kobj,
- struct kobj_attribute *attr,
- char *buf)
-{
- unsigned long val = funnel.priority;
- return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
-}
-FUNNEL_ATTR(priority);
+static DEVICE_ATTR(priority, S_IRUGO | S_IWUSR, funnel_show_priority,
+ funnel_store_priority);
static int __devinit funnel_sysfs_init(void)
{
@@ -146,7 +155,7 @@
goto err_create;
}
- ret = sysfs_create_file(funnel.kobj, &priority_attr.attr);
+ ret = sysfs_create_file(funnel.kobj, &dev_attr_priority.attr);
if (ret) {
dev_err(funnel.dev, "failed to create FUNNEL sysfs priority"
" attribute\n");
@@ -162,7 +171,7 @@
static void __devexit funnel_sysfs_exit(void)
{
- sysfs_remove_file(funnel.kobj, &priority_attr.attr);
+ sysfs_remove_file(funnel.kobj, &dev_attr_priority.attr);
kobject_put(funnel.kobj);
}
@@ -187,11 +196,26 @@
mutex_init(&funnel.mutex);
+ funnel.clk = clk_get(funnel.dev, "core_clk");
+ if (IS_ERR(funnel.clk)) {
+ ret = PTR_ERR(funnel.clk);
+ goto err_clk_get;
+ }
+
+ ret = clk_set_rate(funnel.clk, CS_CLK_RATE_TRACE);
+ if (ret)
+ goto err_clk_rate;
+
funnel_sysfs_init();
dev_info(funnel.dev, "FUNNEL initialized\n");
return 0;
+err_clk_rate:
+ clk_put(funnel.clk);
+err_clk_get:
+ mutex_destroy(&funnel.mutex);
+ iounmap(funnel.base);
err_ioremap:
err_res:
dev_err(funnel.dev, "FUNNEL init failed\n");
@@ -203,6 +227,7 @@
if (funnel.enabled)
funnel_disable(0x0, 0xFF);
funnel_sysfs_exit();
+ clk_put(funnel.clk);
mutex_destroy(&funnel.mutex);
iounmap(funnel.base);
diff --git a/drivers/cs/cs-priv.h b/drivers/cs/cs-priv.h
index d89f461..a4028f5 100644
--- a/drivers/cs/cs-priv.h
+++ b/drivers/cs/cs-priv.h
@@ -36,11 +36,11 @@
#define BMVAL(val, lsb, msb) ((val & BM(lsb, msb)) >> lsb)
#define BVAL(val, n) ((val & BIT(n)) >> n)
-void etb_enable(void);
+int etb_enable(void);
void etb_disable(void);
void etb_dump(void);
void tpiu_disable(void);
-void funnel_enable(uint8_t id, uint32_t port_mask);
+int funnel_enable(uint8_t id, uint32_t port_mask);
void funnel_disable(uint8_t id, uint32_t port_mask);
struct kobject *qdss_get_modulekobj(void);
diff --git a/drivers/cs/cs-stm.c b/drivers/cs/cs-stm.c
index ddc22a3d..8f4b6f8 100644
--- a/drivers/cs/cs-stm.c
+++ b/drivers/cs/cs-stm.c
@@ -22,6 +22,7 @@
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
+#include <linux/clk.h>
#include <linux/cs.h>
#include <linux/cs-stm.h>
#include <asm/unaligned.h>
@@ -98,6 +99,7 @@
struct qdss_source *src;
struct device *dev;
struct kobject *kobj;
+ struct clk *clk;
uint32_t entity;
struct channel_space chs;
};
@@ -129,9 +131,13 @@
goto err;
}
+ ret = clk_prepare_enable(stm.clk);
+ if (ret)
+ goto err_clk;
+
ret = qdss_enable(stm.src);
if (ret)
- goto err;
+ goto err_qdss;
__stm_enable();
@@ -140,6 +146,9 @@
dev_info(stm.dev, "STM tracing enabled\n");
return 0;
+err_qdss:
+ clk_disable_unprepare(stm.clk);
+err_clk:
err:
return ret;
}
@@ -167,9 +176,11 @@
__stm_disable();
+ stm.enabled = false;
+
qdss_disable(stm.src);
- stm.enabled = false;
+ clk_disable_unprepare(stm.clk);
dev_info(stm.dev, "STM tracing disabled\n");
return 0;
@@ -386,13 +397,16 @@
.fops = &stm_fops,
};
-#define STM_ATTR(__name) \
-static struct kobj_attribute __name##_attr = \
- __ATTR(__name, S_IRUGO | S_IWUSR, __name##_show, __name##_store)
+static ssize_t stm_show_enabled(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long val = stm.enabled;
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
-static ssize_t enabled_store(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf, size_t n)
+static ssize_t stm_store_enabled(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
int ret = 0;
unsigned long val;
@@ -407,20 +421,21 @@
if (ret)
return ret;
- return n;
+ return size;
}
-static ssize_t enabled_show(struct kobject *kobj,
- struct kobj_attribute *attr,
- char *buf)
+static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, stm_show_enabled,
+ stm_store_enabled);
+
+static ssize_t stm_show_entity(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- unsigned long val = stm.enabled;
+ unsigned long val = stm.entity;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
-STM_ATTR(enabled);
-static ssize_t entity_store(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf, size_t n)
+static ssize_t stm_store_entity(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
unsigned long val;
@@ -428,16 +443,10 @@
return -EINVAL;
stm.entity = val;
- return n;
+ return size;
}
-static ssize_t entity_show(struct kobject *kobj,
- struct kobj_attribute *attr,
- char *buf)
-{
- unsigned long val = stm.entity;
- return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
-}
-STM_ATTR(entity);
+static DEVICE_ATTR(entity, S_IRUGO | S_IWUSR, stm_show_entity,
+ stm_store_entity);
static int __devinit stm_sysfs_init(void)
{
@@ -450,13 +459,13 @@
goto err_create;
}
- ret = sysfs_create_file(stm.kobj, &enabled_attr.attr);
+ ret = sysfs_create_file(stm.kobj, &dev_attr_enabled.attr);
if (ret) {
dev_err(stm.dev, "failed to create STM sysfs enabled attr\n");
goto err_file;
}
- if (sysfs_create_file(stm.kobj, &entity_attr.attr))
+ if (sysfs_create_file(stm.kobj, &dev_attr_entity.attr))
dev_err(stm.dev, "failed to create STM sysfs entity attr\n");
return 0;
@@ -468,8 +477,8 @@
static void __devexit stm_sysfs_exit(void)
{
- sysfs_remove_file(stm.kobj, &entity_attr.attr);
- sysfs_remove_file(stm.kobj, &enabled_attr.attr);
+ sysfs_remove_file(stm.kobj, &dev_attr_entity.attr);
+ sysfs_remove_file(stm.kobj, &dev_attr_enabled.attr);
kobject_put(stm.kobj);
}
@@ -531,6 +540,16 @@
goto err_qdssget;
}
+ stm.clk = clk_get(stm.dev, "core_clk");
+ if (IS_ERR(stm.clk)) {
+ ret = PTR_ERR(stm.clk);
+ goto err_clk_get;
+ }
+
+ ret = clk_set_rate(stm.clk, CS_CLK_RATE_TRACE);
+ if (ret)
+ goto err_clk_rate;
+
ret = stm_sysfs_init();
if (ret)
goto err_sysfs;
@@ -542,6 +561,9 @@
return 0;
err_sysfs:
+err_clk_rate:
+ clk_put(stm.clk);
+err_clk_get:
qdss_put(stm.src);
err_qdssget:
misc_deregister(&stm_misc);
@@ -563,6 +585,7 @@
if (stm.enabled)
stm_disable();
stm_sysfs_exit();
+ clk_put(stm.clk);
qdss_put(stm.src);
misc_deregister(&stm_misc);
iounmap(stm.chs.base);
diff --git a/drivers/cs/cs-tpiu.c b/drivers/cs/cs-tpiu.c
index c5e28eb..8191d2c 100644
--- a/drivers/cs/cs-tpiu.c
+++ b/drivers/cs/cs-tpiu.c
@@ -17,6 +17,7 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/err.h>
+#include <linux/clk.h>
#include <linux/cs.h>
#include "cs-priv.h"
@@ -60,6 +61,7 @@
void __iomem *base;
bool enabled;
struct device *dev;
+ struct clk *clk;
};
static struct tpiu_ctx tpiu;
@@ -100,9 +102,23 @@
tpiu.dev = &pdev->dev;
+ tpiu.clk = clk_get(tpiu.dev, "core_clk");
+ if (IS_ERR(tpiu.clk)) {
+ ret = PTR_ERR(tpiu.clk);
+ goto err_clk_get;
+ }
+
+ ret = clk_set_rate(tpiu.clk, CS_CLK_RATE_TRACE);
+ if (ret)
+ goto err_clk_rate;
+
dev_info(tpiu.dev, "TPIU initialized\n");
return 0;
+err_clk_rate:
+ clk_put(tpiu.clk);
+err_clk_get:
+ iounmap(tpiu.base);
err_ioremap:
err_res:
dev_err(tpiu.dev, "TPIU init failed\n");
@@ -113,6 +129,7 @@
{
if (tpiu.enabled)
tpiu_disable();
+ clk_put(tpiu.clk);
iounmap(tpiu.base);
return 0;
diff --git a/drivers/cs/cs.c b/drivers/cs/cs.c
index acc22a4..ee02f90 100644
--- a/drivers/cs/cs.c
+++ b/drivers/cs/cs.c
@@ -28,11 +28,6 @@
#define MAX_STR_LEN (65535)
-enum {
- QDSS_CLK_OFF,
- QDSS_CLK_ON_DBG,
- QDSS_CLK_ON_HSDBG,
-};
static LIST_HEAD(cs_orph_conns);
static DEFINE_MUTEX(cs_orph_conns_mutex);
@@ -387,19 +382,12 @@
*/
int qdss_enable(struct qdss_source *src)
{
- int ret;
-
if (!src)
return -EINVAL;
- ret = qdss_clk_enable();
- if (ret)
- goto err;
-
if (qdss.afamily) {
mutex_lock(&qdss.sink_mutex);
if (qdss.sink_count == 0) {
- etb_disable();
tpiu_disable();
/* enable ETB first to avoid losing any trace data */
etb_enable();
@@ -410,8 +398,6 @@
funnel_enable(0x0, src->fport_mask);
return 0;
-err:
- return ret;
}
EXPORT_SYMBOL(qdss_enable);
@@ -443,7 +429,6 @@
}
funnel_disable(0x0, src->fport_mask);
- qdss_clk_disable();
return;
out:
mutex_unlock(&qdss.sink_mutex);
@@ -470,37 +455,6 @@
}
EXPORT_SYMBOL(qdss_disable_sink);
-/**
- * qdss_clk_enable - enable qdss clocks
- *
- * Enables qdss clocks
- *
- * CONTEXT:
- * Might sleep. Should be called from a non-atomic context.
- *
- * RETURNS:
- * 0 on success, non-zero on failure
- */
-int qdss_clk_enable(void)
-{
- return clk_prepare_enable(qdss.clk);
-}
-EXPORT_SYMBOL(qdss_clk_enable);
-
-/**
- * qdss_clk_disable - disable qdss clocks
- *
- * Disables qdss clocks
- *
- * CONTEXT:
- * Might sleep. Should be called from a non-atomic context.
- */
-void qdss_clk_disable(void)
-{
- clk_disable_unprepare(qdss.clk);
-}
-EXPORT_SYMBOL(qdss_clk_disable);
-
struct kobject *qdss_get_modulekobj(void)
{
return qdss.modulekobj;
@@ -582,27 +536,11 @@
if (!pdata)
goto err_pdata;
- qdss.clk = clk_get(&pdev->dev, "core_clk");
- if (IS_ERR(qdss.clk)) {
- ret = PTR_ERR(qdss.clk);
- pr_info("clk get failed\n");
- goto err_clk_get;
- }
-
- ret = clk_set_rate(qdss.clk, QDSS_CLK_ON_DBG);
- if (ret) {
- pr_info("clk rate failed\n");
- goto err_clk_rate;
- }
-
qdss.afamily = pdata->afamily;
qdss_add_sources(pdata->src_table, pdata->size);
pr_info("QDSS arch initialized\n");
return 0;
-err_clk_rate:
- clk_put(qdss.clk);
-err_clk_get:
err_pdata:
mutex_destroy(&qdss.sink_mutex);
mutex_destroy(&qdss.sources_mutex);
@@ -613,7 +551,6 @@
static int __devexit qdss_remove(struct platform_device *pdev)
{
qdss_sysfs_exit();
- clk_put(qdss.clk);
mutex_destroy(&qdss.sink_mutex);
mutex_destroy(&qdss.sources_mutex);
diff --git a/include/linux/cs.h b/include/linux/cs.h
index 1a0094c..0e494b0 100644
--- a/include/linux/cs.h
+++ b/include/linux/cs.h
@@ -38,6 +38,12 @@
#define ETM_ARCH_V3_3 (0x23)
#define PFT_ARCH_V1_1 (0x31)
+enum cs_clk_rate {
+ CS_CLK_RATE_OFF,
+ CS_CLK_RATE_TRACE,
+ CS_CLK_RATE_HSTRACE,
+};
+
enum cs_device_type {
CS_DEVICE_TYPE_SOURCE,
CS_DEVICE_TYPE_LINK,
@@ -114,16 +120,12 @@
extern int qdss_enable(struct qdss_source *src);
extern void qdss_disable(struct qdss_source *src);
extern void qdss_disable_sink(void);
-extern int qdss_clk_enable(void);
-extern void qdss_clk_disable(void);
#else
static inline struct qdss_source *qdss_get(const char *name) { return NULL; }
static inline void qdss_put(struct qdss_source *src) {}
static inline int qdss_enable(struct qdss_source *src) { return -ENOSYS; }
static inline void qdss_disable(struct qdss_source *src) {}
static inline void qdss_disable_sink(void) {}
-static inline int qdss_clk_enable(void) { return -ENOSYS; }
-static inline void qdss_clk_disable(void) {}
#endif
#endif