2 * Marvell Bluetooth driver: debugfs related functions
4 * Copyright (C) 2009, Marvell International Ltd.
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
15 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
17 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
18 * this warranty disclaimer.
21 #include <linux/debugfs.h>
22 #include <linux/slab.h>
24 #include <net/bluetooth/bluetooth.h>
25 #include <net/bluetooth/hci_core.h>
27 #include "btmrvl_drv.h"
29 struct btmrvl_debugfs_data
{
30 struct dentry
*config_dir
;
31 struct dentry
*status_dir
;
34 struct dentry
*psmode
;
36 struct dentry
*hsmode
;
38 struct dentry
*gpiogap
;
39 struct dentry
*hscfgcmd
;
42 struct dentry
*curpsmode
;
43 struct dentry
*hsstate
;
44 struct dentry
*psstate
;
45 struct dentry
*txdnldready
;
48 static ssize_t
btmrvl_hscfgcmd_write(struct file
*file
,
49 const char __user
*ubuf
, size_t count
, loff_t
*ppos
)
51 struct btmrvl_private
*priv
= file
->private_data
;
55 memset(buf
, 0, sizeof(buf
));
57 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
60 ret
= strict_strtol(buf
, 10, &result
);
64 priv
->btmrvl_dev
.hscfgcmd
= result
;
66 if (priv
->btmrvl_dev
.hscfgcmd
) {
67 btmrvl_prepare_command(priv
);
68 wake_up_interruptible(&priv
->main_thread
.wait_q
);
74 static ssize_t
btmrvl_hscfgcmd_read(struct file
*file
, char __user
*userbuf
,
75 size_t count
, loff_t
*ppos
)
77 struct btmrvl_private
*priv
= file
->private_data
;
81 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n",
82 priv
->btmrvl_dev
.hscfgcmd
);
84 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
87 static const struct file_operations btmrvl_hscfgcmd_fops
= {
88 .read
= btmrvl_hscfgcmd_read
,
89 .write
= btmrvl_hscfgcmd_write
,
91 .llseek
= default_llseek
,
94 static ssize_t
btmrvl_psmode_write(struct file
*file
, const char __user
*ubuf
,
95 size_t count
, loff_t
*ppos
)
97 struct btmrvl_private
*priv
= file
->private_data
;
101 memset(buf
, 0, sizeof(buf
));
103 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
106 ret
= strict_strtol(buf
, 10, &result
);
110 priv
->btmrvl_dev
.psmode
= result
;
115 static ssize_t
btmrvl_psmode_read(struct file
*file
, char __user
*userbuf
,
116 size_t count
, loff_t
*ppos
)
118 struct btmrvl_private
*priv
= file
->private_data
;
122 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n",
123 priv
->btmrvl_dev
.psmode
);
125 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
128 static const struct file_operations btmrvl_psmode_fops
= {
129 .read
= btmrvl_psmode_read
,
130 .write
= btmrvl_psmode_write
,
132 .llseek
= default_llseek
,
135 static ssize_t
btmrvl_pscmd_write(struct file
*file
, const char __user
*ubuf
,
136 size_t count
, loff_t
*ppos
)
138 struct btmrvl_private
*priv
= file
->private_data
;
142 memset(buf
, 0, sizeof(buf
));
144 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
147 ret
= strict_strtol(buf
, 10, &result
);
151 priv
->btmrvl_dev
.pscmd
= result
;
153 if (priv
->btmrvl_dev
.pscmd
) {
154 btmrvl_prepare_command(priv
);
155 wake_up_interruptible(&priv
->main_thread
.wait_q
);
162 static ssize_t
btmrvl_pscmd_read(struct file
*file
, char __user
*userbuf
,
163 size_t count
, loff_t
*ppos
)
165 struct btmrvl_private
*priv
= file
->private_data
;
169 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->btmrvl_dev
.pscmd
);
171 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
174 static const struct file_operations btmrvl_pscmd_fops
= {
175 .read
= btmrvl_pscmd_read
,
176 .write
= btmrvl_pscmd_write
,
178 .llseek
= default_llseek
,
181 static ssize_t
btmrvl_gpiogap_write(struct file
*file
, const char __user
*ubuf
,
182 size_t count
, loff_t
*ppos
)
184 struct btmrvl_private
*priv
= file
->private_data
;
188 memset(buf
, 0, sizeof(buf
));
190 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
193 ret
= strict_strtol(buf
, 16, &result
);
197 priv
->btmrvl_dev
.gpio_gap
= result
;
202 static ssize_t
btmrvl_gpiogap_read(struct file
*file
, char __user
*userbuf
,
203 size_t count
, loff_t
*ppos
)
205 struct btmrvl_private
*priv
= file
->private_data
;
209 ret
= snprintf(buf
, sizeof(buf
) - 1, "0x%x\n",
210 priv
->btmrvl_dev
.gpio_gap
);
212 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
215 static const struct file_operations btmrvl_gpiogap_fops
= {
216 .read
= btmrvl_gpiogap_read
,
217 .write
= btmrvl_gpiogap_write
,
219 .llseek
= default_llseek
,
222 static ssize_t
btmrvl_hscmd_write(struct file
*file
, const char __user
*ubuf
,
223 size_t count
, loff_t
*ppos
)
225 struct btmrvl_private
*priv
= file
->private_data
;
229 memset(buf
, 0, sizeof(buf
));
231 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
234 ret
= strict_strtol(buf
, 10, &result
);
238 priv
->btmrvl_dev
.hscmd
= result
;
239 if (priv
->btmrvl_dev
.hscmd
) {
240 btmrvl_prepare_command(priv
);
241 wake_up_interruptible(&priv
->main_thread
.wait_q
);
247 static ssize_t
btmrvl_hscmd_read(struct file
*file
, char __user
*userbuf
,
248 size_t count
, loff_t
*ppos
)
250 struct btmrvl_private
*priv
= file
->private_data
;
254 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->btmrvl_dev
.hscmd
);
256 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
259 static const struct file_operations btmrvl_hscmd_fops
= {
260 .read
= btmrvl_hscmd_read
,
261 .write
= btmrvl_hscmd_write
,
263 .llseek
= default_llseek
,
266 static ssize_t
btmrvl_hsmode_write(struct file
*file
, const char __user
*ubuf
,
267 size_t count
, loff_t
*ppos
)
269 struct btmrvl_private
*priv
= file
->private_data
;
273 memset(buf
, 0, sizeof(buf
));
275 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
278 ret
= strict_strtol(buf
, 10, &result
);
282 priv
->btmrvl_dev
.hsmode
= result
;
287 static ssize_t
btmrvl_hsmode_read(struct file
*file
, char __user
* userbuf
,
288 size_t count
, loff_t
*ppos
)
290 struct btmrvl_private
*priv
= file
->private_data
;
294 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->btmrvl_dev
.hsmode
);
296 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
299 static const struct file_operations btmrvl_hsmode_fops
= {
300 .read
= btmrvl_hsmode_read
,
301 .write
= btmrvl_hsmode_write
,
303 .llseek
= default_llseek
,
306 static ssize_t
btmrvl_curpsmode_read(struct file
*file
, char __user
*userbuf
,
307 size_t count
, loff_t
*ppos
)
309 struct btmrvl_private
*priv
= file
->private_data
;
313 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->adapter
->psmode
);
315 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
318 static const struct file_operations btmrvl_curpsmode_fops
= {
319 .read
= btmrvl_curpsmode_read
,
321 .llseek
= default_llseek
,
324 static ssize_t
btmrvl_psstate_read(struct file
*file
, char __user
* userbuf
,
325 size_t count
, loff_t
*ppos
)
327 struct btmrvl_private
*priv
= file
->private_data
;
331 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->adapter
->ps_state
);
333 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
336 static const struct file_operations btmrvl_psstate_fops
= {
337 .read
= btmrvl_psstate_read
,
339 .llseek
= default_llseek
,
342 static ssize_t
btmrvl_hsstate_read(struct file
*file
, char __user
*userbuf
,
343 size_t count
, loff_t
*ppos
)
345 struct btmrvl_private
*priv
= file
->private_data
;
349 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->adapter
->hs_state
);
351 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
354 static const struct file_operations btmrvl_hsstate_fops
= {
355 .read
= btmrvl_hsstate_read
,
357 .llseek
= default_llseek
,
360 static ssize_t
btmrvl_txdnldready_read(struct file
*file
, char __user
*userbuf
,
361 size_t count
, loff_t
*ppos
)
363 struct btmrvl_private
*priv
= file
->private_data
;
367 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n",
368 priv
->btmrvl_dev
.tx_dnld_rdy
);
370 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
373 static const struct file_operations btmrvl_txdnldready_fops
= {
374 .read
= btmrvl_txdnldready_read
,
376 .llseek
= default_llseek
,
379 void btmrvl_debugfs_init(struct hci_dev
*hdev
)
381 struct btmrvl_private
*priv
= hci_get_drvdata(hdev
);
382 struct btmrvl_debugfs_data
*dbg
;
387 dbg
= kzalloc(sizeof(*dbg
), GFP_KERNEL
);
388 priv
->debugfs_data
= dbg
;
391 BT_ERR("Can not allocate memory for btmrvl_debugfs_data.");
395 dbg
->config_dir
= debugfs_create_dir("config", hdev
->debugfs
);
397 dbg
->psmode
= debugfs_create_file("psmode", 0644, dbg
->config_dir
,
398 priv
, &btmrvl_psmode_fops
);
399 dbg
->pscmd
= debugfs_create_file("pscmd", 0644, dbg
->config_dir
,
400 priv
, &btmrvl_pscmd_fops
);
401 dbg
->gpiogap
= debugfs_create_file("gpiogap", 0644, dbg
->config_dir
,
402 priv
, &btmrvl_gpiogap_fops
);
403 dbg
->hsmode
= debugfs_create_file("hsmode", 0644, dbg
->config_dir
,
404 priv
, &btmrvl_hsmode_fops
);
405 dbg
->hscmd
= debugfs_create_file("hscmd", 0644, dbg
->config_dir
,
406 priv
, &btmrvl_hscmd_fops
);
407 dbg
->hscfgcmd
= debugfs_create_file("hscfgcmd", 0644, dbg
->config_dir
,
408 priv
, &btmrvl_hscfgcmd_fops
);
410 dbg
->status_dir
= debugfs_create_dir("status", hdev
->debugfs
);
411 dbg
->curpsmode
= debugfs_create_file("curpsmode", 0444,
412 dbg
->status_dir
, priv
,
413 &btmrvl_curpsmode_fops
);
414 dbg
->psstate
= debugfs_create_file("psstate", 0444, dbg
->status_dir
,
415 priv
, &btmrvl_psstate_fops
);
416 dbg
->hsstate
= debugfs_create_file("hsstate", 0444, dbg
->status_dir
,
417 priv
, &btmrvl_hsstate_fops
);
418 dbg
->txdnldready
= debugfs_create_file("txdnldready", 0444,
419 dbg
->status_dir
, priv
,
420 &btmrvl_txdnldready_fops
);
423 void btmrvl_debugfs_remove(struct hci_dev
*hdev
)
425 struct btmrvl_private
*priv
= hci_get_drvdata(hdev
);
426 struct btmrvl_debugfs_data
*dbg
= priv
->debugfs_data
;
431 debugfs_remove(dbg
->psmode
);
432 debugfs_remove(dbg
->pscmd
);
433 debugfs_remove(dbg
->gpiogap
);
434 debugfs_remove(dbg
->hsmode
);
435 debugfs_remove(dbg
->hscmd
);
436 debugfs_remove(dbg
->hscfgcmd
);
437 debugfs_remove(dbg
->config_dir
);
439 debugfs_remove(dbg
->curpsmode
);
440 debugfs_remove(dbg
->psstate
);
441 debugfs_remove(dbg
->hsstate
);
442 debugfs_remove(dbg
->txdnldready
);
443 debugfs_remove(dbg
->status_dir
);