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 int btmrvl_open_generic(struct inode
*inode
, struct file
*file
)
50 file
->private_data
= inode
->i_private
;
54 static ssize_t
btmrvl_hscfgcmd_write(struct file
*file
,
55 const char __user
*ubuf
, size_t count
, loff_t
*ppos
)
57 struct btmrvl_private
*priv
= file
->private_data
;
61 memset(buf
, 0, sizeof(buf
));
63 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
66 ret
= strict_strtol(buf
, 10, &result
);
70 priv
->btmrvl_dev
.hscfgcmd
= result
;
72 if (priv
->btmrvl_dev
.hscfgcmd
) {
73 btmrvl_prepare_command(priv
);
74 wake_up_interruptible(&priv
->main_thread
.wait_q
);
80 static ssize_t
btmrvl_hscfgcmd_read(struct file
*file
, char __user
*userbuf
,
81 size_t count
, loff_t
*ppos
)
83 struct btmrvl_private
*priv
= file
->private_data
;
87 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n",
88 priv
->btmrvl_dev
.hscfgcmd
);
90 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
93 static const struct file_operations btmrvl_hscfgcmd_fops
= {
94 .read
= btmrvl_hscfgcmd_read
,
95 .write
= btmrvl_hscfgcmd_write
,
96 .open
= btmrvl_open_generic
,
97 .llseek
= default_llseek
,
100 static ssize_t
btmrvl_psmode_write(struct file
*file
, const char __user
*ubuf
,
101 size_t count
, loff_t
*ppos
)
103 struct btmrvl_private
*priv
= file
->private_data
;
107 memset(buf
, 0, sizeof(buf
));
109 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
112 ret
= strict_strtol(buf
, 10, &result
);
116 priv
->btmrvl_dev
.psmode
= result
;
121 static ssize_t
btmrvl_psmode_read(struct file
*file
, char __user
*userbuf
,
122 size_t count
, loff_t
*ppos
)
124 struct btmrvl_private
*priv
= file
->private_data
;
128 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n",
129 priv
->btmrvl_dev
.psmode
);
131 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
134 static const struct file_operations btmrvl_psmode_fops
= {
135 .read
= btmrvl_psmode_read
,
136 .write
= btmrvl_psmode_write
,
137 .open
= btmrvl_open_generic
,
138 .llseek
= default_llseek
,
141 static ssize_t
btmrvl_pscmd_write(struct file
*file
, const char __user
*ubuf
,
142 size_t count
, loff_t
*ppos
)
144 struct btmrvl_private
*priv
= file
->private_data
;
148 memset(buf
, 0, sizeof(buf
));
150 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
153 ret
= strict_strtol(buf
, 10, &result
);
157 priv
->btmrvl_dev
.pscmd
= result
;
159 if (priv
->btmrvl_dev
.pscmd
) {
160 btmrvl_prepare_command(priv
);
161 wake_up_interruptible(&priv
->main_thread
.wait_q
);
168 static ssize_t
btmrvl_pscmd_read(struct file
*file
, char __user
*userbuf
,
169 size_t count
, loff_t
*ppos
)
171 struct btmrvl_private
*priv
= file
->private_data
;
175 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->btmrvl_dev
.pscmd
);
177 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
180 static const struct file_operations btmrvl_pscmd_fops
= {
181 .read
= btmrvl_pscmd_read
,
182 .write
= btmrvl_pscmd_write
,
183 .open
= btmrvl_open_generic
,
184 .llseek
= default_llseek
,
187 static ssize_t
btmrvl_gpiogap_write(struct file
*file
, const char __user
*ubuf
,
188 size_t count
, loff_t
*ppos
)
190 struct btmrvl_private
*priv
= file
->private_data
;
194 memset(buf
, 0, sizeof(buf
));
196 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
199 ret
= strict_strtol(buf
, 16, &result
);
203 priv
->btmrvl_dev
.gpio_gap
= result
;
208 static ssize_t
btmrvl_gpiogap_read(struct file
*file
, char __user
*userbuf
,
209 size_t count
, loff_t
*ppos
)
211 struct btmrvl_private
*priv
= file
->private_data
;
215 ret
= snprintf(buf
, sizeof(buf
) - 1, "0x%x\n",
216 priv
->btmrvl_dev
.gpio_gap
);
218 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
221 static const struct file_operations btmrvl_gpiogap_fops
= {
222 .read
= btmrvl_gpiogap_read
,
223 .write
= btmrvl_gpiogap_write
,
224 .open
= btmrvl_open_generic
,
225 .llseek
= default_llseek
,
228 static ssize_t
btmrvl_hscmd_write(struct file
*file
, const char __user
*ubuf
,
229 size_t count
, loff_t
*ppos
)
231 struct btmrvl_private
*priv
= file
->private_data
;
235 memset(buf
, 0, sizeof(buf
));
237 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
240 ret
= strict_strtol(buf
, 10, &result
);
244 priv
->btmrvl_dev
.hscmd
= result
;
245 if (priv
->btmrvl_dev
.hscmd
) {
246 btmrvl_prepare_command(priv
);
247 wake_up_interruptible(&priv
->main_thread
.wait_q
);
253 static ssize_t
btmrvl_hscmd_read(struct file
*file
, char __user
*userbuf
,
254 size_t count
, loff_t
*ppos
)
256 struct btmrvl_private
*priv
= file
->private_data
;
260 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->btmrvl_dev
.hscmd
);
262 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
265 static const struct file_operations btmrvl_hscmd_fops
= {
266 .read
= btmrvl_hscmd_read
,
267 .write
= btmrvl_hscmd_write
,
268 .open
= btmrvl_open_generic
,
269 .llseek
= default_llseek
,
272 static ssize_t
btmrvl_hsmode_write(struct file
*file
, const char __user
*ubuf
,
273 size_t count
, loff_t
*ppos
)
275 struct btmrvl_private
*priv
= file
->private_data
;
279 memset(buf
, 0, sizeof(buf
));
281 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
284 ret
= strict_strtol(buf
, 10, &result
);
288 priv
->btmrvl_dev
.hsmode
= result
;
293 static ssize_t
btmrvl_hsmode_read(struct file
*file
, char __user
* userbuf
,
294 size_t count
, loff_t
*ppos
)
296 struct btmrvl_private
*priv
= file
->private_data
;
300 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->btmrvl_dev
.hsmode
);
302 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
305 static const struct file_operations btmrvl_hsmode_fops
= {
306 .read
= btmrvl_hsmode_read
,
307 .write
= btmrvl_hsmode_write
,
308 .open
= btmrvl_open_generic
,
309 .llseek
= default_llseek
,
312 static ssize_t
btmrvl_curpsmode_read(struct file
*file
, char __user
*userbuf
,
313 size_t count
, loff_t
*ppos
)
315 struct btmrvl_private
*priv
= file
->private_data
;
319 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->adapter
->psmode
);
321 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
324 static const struct file_operations btmrvl_curpsmode_fops
= {
325 .read
= btmrvl_curpsmode_read
,
326 .open
= btmrvl_open_generic
,
327 .llseek
= default_llseek
,
330 static ssize_t
btmrvl_psstate_read(struct file
*file
, char __user
* userbuf
,
331 size_t count
, loff_t
*ppos
)
333 struct btmrvl_private
*priv
= file
->private_data
;
337 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->adapter
->ps_state
);
339 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
342 static const struct file_operations btmrvl_psstate_fops
= {
343 .read
= btmrvl_psstate_read
,
344 .open
= btmrvl_open_generic
,
345 .llseek
= default_llseek
,
348 static ssize_t
btmrvl_hsstate_read(struct file
*file
, char __user
*userbuf
,
349 size_t count
, loff_t
*ppos
)
351 struct btmrvl_private
*priv
= file
->private_data
;
355 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->adapter
->hs_state
);
357 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
360 static const struct file_operations btmrvl_hsstate_fops
= {
361 .read
= btmrvl_hsstate_read
,
362 .open
= btmrvl_open_generic
,
363 .llseek
= default_llseek
,
366 static ssize_t
btmrvl_txdnldready_read(struct file
*file
, char __user
*userbuf
,
367 size_t count
, loff_t
*ppos
)
369 struct btmrvl_private
*priv
= file
->private_data
;
373 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n",
374 priv
->btmrvl_dev
.tx_dnld_rdy
);
376 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
379 static const struct file_operations btmrvl_txdnldready_fops
= {
380 .read
= btmrvl_txdnldready_read
,
381 .open
= btmrvl_open_generic
,
382 .llseek
= default_llseek
,
385 void btmrvl_debugfs_init(struct hci_dev
*hdev
)
387 struct btmrvl_private
*priv
= hdev
->driver_data
;
388 struct btmrvl_debugfs_data
*dbg
;
393 dbg
= kzalloc(sizeof(*dbg
), GFP_KERNEL
);
394 priv
->debugfs_data
= dbg
;
397 BT_ERR("Can not allocate memory for btmrvl_debugfs_data.");
401 dbg
->config_dir
= debugfs_create_dir("config", hdev
->debugfs
);
403 dbg
->psmode
= debugfs_create_file("psmode", 0644, dbg
->config_dir
,
404 hdev
->driver_data
, &btmrvl_psmode_fops
);
405 dbg
->pscmd
= debugfs_create_file("pscmd", 0644, dbg
->config_dir
,
406 hdev
->driver_data
, &btmrvl_pscmd_fops
);
407 dbg
->gpiogap
= debugfs_create_file("gpiogap", 0644, dbg
->config_dir
,
408 hdev
->driver_data
, &btmrvl_gpiogap_fops
);
409 dbg
->hsmode
= debugfs_create_file("hsmode", 0644, dbg
->config_dir
,
410 hdev
->driver_data
, &btmrvl_hsmode_fops
);
411 dbg
->hscmd
= debugfs_create_file("hscmd", 0644, dbg
->config_dir
,
412 hdev
->driver_data
, &btmrvl_hscmd_fops
);
413 dbg
->hscfgcmd
= debugfs_create_file("hscfgcmd", 0644, dbg
->config_dir
,
414 hdev
->driver_data
, &btmrvl_hscfgcmd_fops
);
416 dbg
->status_dir
= debugfs_create_dir("status", hdev
->debugfs
);
417 dbg
->curpsmode
= debugfs_create_file("curpsmode", 0444,
420 &btmrvl_curpsmode_fops
);
421 dbg
->psstate
= debugfs_create_file("psstate", 0444, dbg
->status_dir
,
422 hdev
->driver_data
, &btmrvl_psstate_fops
);
423 dbg
->hsstate
= debugfs_create_file("hsstate", 0444, dbg
->status_dir
,
424 hdev
->driver_data
, &btmrvl_hsstate_fops
);
425 dbg
->txdnldready
= debugfs_create_file("txdnldready", 0444,
428 &btmrvl_txdnldready_fops
);
431 void btmrvl_debugfs_remove(struct hci_dev
*hdev
)
433 struct btmrvl_private
*priv
= hdev
->driver_data
;
434 struct btmrvl_debugfs_data
*dbg
= priv
->debugfs_data
;
439 debugfs_remove(dbg
->psmode
);
440 debugfs_remove(dbg
->pscmd
);
441 debugfs_remove(dbg
->gpiogap
);
442 debugfs_remove(dbg
->hsmode
);
443 debugfs_remove(dbg
->hscmd
);
444 debugfs_remove(dbg
->hscfgcmd
);
445 debugfs_remove(dbg
->config_dir
);
447 debugfs_remove(dbg
->curpsmode
);
448 debugfs_remove(dbg
->psstate
);
449 debugfs_remove(dbg
->hsstate
);
450 debugfs_remove(dbg
->txdnldready
);
451 debugfs_remove(dbg
->status_dir
);