blob: ab28c82d2a395a5d57a741207c005ee1dea6a7c4 [file] [log] [blame]
Pratik Patel74929432011-12-26 12:03:41 -08001/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/types.h>
17#include <linux/device.h>
18#include <linux/platform_device.h>
19#include <linux/io.h>
20#include <linux/err.h>
21#include <mach/rpm.h>
22
23#include "rpm_resources.h"
24#include "qdss.h"
25
26enum {
27 QDSS_CLK_OFF,
28 QDSS_CLK_ON_DBG,
29 QDSS_CLK_ON_HSDBG,
30};
31
Pratik Patel6630ebe2012-03-06 16:44:22 -080032struct qdss_ctx {
33 struct kobject *modulekobj;
34 uint8_t max_clk;
35};
36
37static struct qdss_ctx qdss;
38
39
40struct kobject *qdss_get_modulekobj(void)
41{
42 return qdss.modulekobj;
43}
Pratik Patel74929432011-12-26 12:03:41 -080044
45int qdss_clk_enable(void)
46{
47 int ret;
48
49 struct msm_rpm_iv_pair iv;
50 iv.id = MSM_RPM_ID_QDSS_CLK;
Pratik Patel6630ebe2012-03-06 16:44:22 -080051 if (qdss.max_clk)
52 iv.value = QDSS_CLK_ON_HSDBG;
53 else
54 iv.value = QDSS_CLK_ON_DBG;
Pratik Patel74929432011-12-26 12:03:41 -080055 ret = msm_rpmrs_set(MSM_RPM_CTX_SET_0, &iv, 1);
56 if (WARN(ret, "qdss clks not enabled (%d)\n", ret))
57 goto err_clk;
58
59 return 0;
Pratik Patel74929432011-12-26 12:03:41 -080060err_clk:
61 return ret;
62}
63
64void qdss_clk_disable(void)
65{
66 int ret;
67 struct msm_rpm_iv_pair iv;
68
69 iv.id = MSM_RPM_ID_QDSS_CLK;
70 iv.value = QDSS_CLK_OFF;
71 ret = msm_rpmrs_set(MSM_RPM_CTX_SET_0, &iv, 1);
72 WARN(ret, "qdss clks not disabled (%d)\n", ret);
73}
Pratik Patel59e29942011-12-27 10:31:33 -080074
Pratik Patel6630ebe2012-03-06 16:44:22 -080075#define QDSS_ATTR(name) \
76static struct kobj_attribute name##_attr = \
77 __ATTR(name, S_IRUGO | S_IWUSR, name##_show, name##_store)
78
79static ssize_t max_clk_store(struct kobject *kobj,
80 struct kobj_attribute *attr,
81 const char *buf, size_t n)
82{
83 unsigned long val;
84
85 if (sscanf(buf, "%lx", &val) != 1)
86 return -EINVAL;
87
88 qdss.max_clk = val;
89 return n;
90}
91static ssize_t max_clk_show(struct kobject *kobj,
92 struct kobj_attribute *attr,
93 char *buf)
94{
95 unsigned long val = qdss.max_clk;
96 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
97}
98QDSS_ATTR(max_clk);
99
100static int __init qdss_sysfs_init(void)
101{
102 int ret;
103
104 qdss.modulekobj = kset_find_obj(module_kset, KBUILD_MODNAME);
105 if (!qdss.modulekobj) {
106 pr_err("failed to find QDSS sysfs module kobject\n");
107 ret = -ENOENT;
108 goto err;
109 }
110
111 ret = sysfs_create_file(qdss.modulekobj, &max_clk_attr.attr);
112 if (ret) {
113 pr_err("failed to create QDSS sysfs max_clk attribute\n");
114 goto err;
115 }
116
117 return 0;
118err:
119 return ret;
120}
121
122static void qdss_sysfs_exit(void)
123{
124 sysfs_remove_file(qdss.modulekobj, &max_clk_attr.attr);
125}
126
Pratik Patel59e29942011-12-27 10:31:33 -0800127static int __init qdss_init(void)
128{
129 int ret;
130
Pratik Patel6630ebe2012-03-06 16:44:22 -0800131 ret = qdss_sysfs_init();
132 if (ret)
133 goto err_sysfs;
Pratik Patel59e29942011-12-27 10:31:33 -0800134 ret = etb_init();
135 if (ret)
136 goto err_etb;
137 ret = tpiu_init();
138 if (ret)
139 goto err_tpiu;
140 ret = funnel_init();
141 if (ret)
142 goto err_funnel;
Pratik Patel492b3012012-03-06 14:22:30 -0800143 ret = etm_init();
Pratik Patel59e29942011-12-27 10:31:33 -0800144 if (ret)
Pratik Patel492b3012012-03-06 14:22:30 -0800145 goto err_etm;
Pratik Patel59e29942011-12-27 10:31:33 -0800146
Pratik Patel61de7302012-03-07 12:06:10 -0800147 pr_info("QDSS initialized\n");
Pratik Patel59e29942011-12-27 10:31:33 -0800148 return 0;
Pratik Patel492b3012012-03-06 14:22:30 -0800149err_etm:
Pratik Patel59e29942011-12-27 10:31:33 -0800150 funnel_exit();
151err_funnel:
152 tpiu_exit();
153err_tpiu:
154 etb_exit();
155err_etb:
Pratik Patel6630ebe2012-03-06 16:44:22 -0800156 qdss_sysfs_exit();
157err_sysfs:
Pratik Patel61de7302012-03-07 12:06:10 -0800158 pr_err("QDSS init failed\n");
Pratik Patel59e29942011-12-27 10:31:33 -0800159 return ret;
160}
161module_init(qdss_init);
162
163static void __exit qdss_exit(void)
164{
Pratik Patel6630ebe2012-03-06 16:44:22 -0800165 qdss_sysfs_exit();
Pratik Patel492b3012012-03-06 14:22:30 -0800166 etm_exit();
Pratik Patel59e29942011-12-27 10:31:33 -0800167 funnel_exit();
168 tpiu_exit();
169 etb_exit();
170}
171module_exit(qdss_exit);
172
173MODULE_LICENSE("GPL v2");
174MODULE_DESCRIPTION("Qualcomm Debug SubSystem Driver");