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
);
68 priv
->btmrvl_dev
.hscfgcmd
= result
;
70 if (priv
->btmrvl_dev
.hscfgcmd
) {
71 btmrvl_prepare_command(priv
);
72 wake_up_interruptible(&priv
->main_thread
.wait_q
);
78 static ssize_t
btmrvl_hscfgcmd_read(struct file
*file
, char __user
*userbuf
,
79 size_t count
, loff_t
*ppos
)
81 struct btmrvl_private
*priv
= file
->private_data
;
85 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n",
86 priv
->btmrvl_dev
.hscfgcmd
);
88 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
91 static const struct file_operations btmrvl_hscfgcmd_fops
= {
92 .read
= btmrvl_hscfgcmd_read
,
93 .write
= btmrvl_hscfgcmd_write
,
94 .open
= btmrvl_open_generic
,
95 .llseek
= default_llseek
,
98 static ssize_t
btmrvl_psmode_write(struct file
*file
, const char __user
*ubuf
,
99 size_t count
, loff_t
*ppos
)
101 struct btmrvl_private
*priv
= file
->private_data
;
105 memset(buf
, 0, sizeof(buf
));
107 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
110 ret
= strict_strtol(buf
, 10, &result
);
112 priv
->btmrvl_dev
.psmode
= result
;
117 static ssize_t
btmrvl_psmode_read(struct file
*file
, char __user
*userbuf
,
118 size_t count
, loff_t
*ppos
)
120 struct btmrvl_private
*priv
= file
->private_data
;
124 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n",
125 priv
->btmrvl_dev
.psmode
);
127 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
130 static const struct file_operations btmrvl_psmode_fops
= {
131 .read
= btmrvl_psmode_read
,
132 .write
= btmrvl_psmode_write
,
133 .open
= btmrvl_open_generic
,
134 .llseek
= default_llseek
,
137 static ssize_t
btmrvl_pscmd_write(struct file
*file
, const char __user
*ubuf
,
138 size_t count
, loff_t
*ppos
)
140 struct btmrvl_private
*priv
= file
->private_data
;
144 memset(buf
, 0, sizeof(buf
));
146 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
149 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
,
177 .open
= btmrvl_open_generic
,
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
);
195 priv
->btmrvl_dev
.gpio_gap
= result
;
200 static ssize_t
btmrvl_gpiogap_read(struct file
*file
, char __user
*userbuf
,
201 size_t count
, loff_t
*ppos
)
203 struct btmrvl_private
*priv
= file
->private_data
;
207 ret
= snprintf(buf
, sizeof(buf
) - 1, "0x%x\n",
208 priv
->btmrvl_dev
.gpio_gap
);
210 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
213 static const struct file_operations btmrvl_gpiogap_fops
= {
214 .read
= btmrvl_gpiogap_read
,
215 .write
= btmrvl_gpiogap_write
,
216 .open
= btmrvl_open_generic
,
217 .llseek
= default_llseek
,
220 static ssize_t
btmrvl_hscmd_write(struct file
*file
, const char __user
*ubuf
,
221 size_t count
, loff_t
*ppos
)
223 struct btmrvl_private
*priv
= file
->private_data
;
227 memset(buf
, 0, sizeof(buf
));
229 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
232 ret
= strict_strtol(buf
, 10, &result
);
234 priv
->btmrvl_dev
.hscmd
= result
;
235 if (priv
->btmrvl_dev
.hscmd
) {
236 btmrvl_prepare_command(priv
);
237 wake_up_interruptible(&priv
->main_thread
.wait_q
);
243 static ssize_t
btmrvl_hscmd_read(struct file
*file
, char __user
*userbuf
,
244 size_t count
, loff_t
*ppos
)
246 struct btmrvl_private
*priv
= file
->private_data
;
250 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->btmrvl_dev
.hscmd
);
252 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
255 static const struct file_operations btmrvl_hscmd_fops
= {
256 .read
= btmrvl_hscmd_read
,
257 .write
= btmrvl_hscmd_write
,
258 .open
= btmrvl_open_generic
,
259 .llseek
= default_llseek
,
262 static ssize_t
btmrvl_hsmode_write(struct file
*file
, const char __user
*ubuf
,
263 size_t count
, loff_t
*ppos
)
265 struct btmrvl_private
*priv
= file
->private_data
;
269 memset(buf
, 0, sizeof(buf
));
271 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
274 ret
= strict_strtol(buf
, 10, &result
);
276 priv
->btmrvl_dev
.hsmode
= result
;
281 static ssize_t
btmrvl_hsmode_read(struct file
*file
, char __user
* userbuf
,
282 size_t count
, loff_t
*ppos
)
284 struct btmrvl_private
*priv
= file
->private_data
;
288 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->btmrvl_dev
.hsmode
);
290 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
293 static const struct file_operations btmrvl_hsmode_fops
= {
294 .read
= btmrvl_hsmode_read
,
295 .write
= btmrvl_hsmode_write
,
296 .open
= btmrvl_open_generic
,
297 .llseek
= default_llseek
,
300 static ssize_t
btmrvl_curpsmode_read(struct file
*file
, char __user
*userbuf
,
301 size_t count
, loff_t
*ppos
)
303 struct btmrvl_private
*priv
= file
->private_data
;
307 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->adapter
->psmode
);
309 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
312 static const struct file_operations btmrvl_curpsmode_fops
= {
313 .read
= btmrvl_curpsmode_read
,
314 .open
= btmrvl_open_generic
,
315 .llseek
= default_llseek
,
318 static ssize_t
btmrvl_psstate_read(struct file
*file
, char __user
* userbuf
,
319 size_t count
, loff_t
*ppos
)
321 struct btmrvl_private
*priv
= file
->private_data
;
325 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->adapter
->ps_state
);
327 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
330 static const struct file_operations btmrvl_psstate_fops
= {
331 .read
= btmrvl_psstate_read
,
332 .open
= btmrvl_open_generic
,
333 .llseek
= default_llseek
,
336 static ssize_t
btmrvl_hsstate_read(struct file
*file
, char __user
*userbuf
,
337 size_t count
, loff_t
*ppos
)
339 struct btmrvl_private
*priv
= file
->private_data
;
343 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->adapter
->hs_state
);
345 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
348 static const struct file_operations btmrvl_hsstate_fops
= {
349 .read
= btmrvl_hsstate_read
,
350 .open
= btmrvl_open_generic
,
351 .llseek
= default_llseek
,
354 static ssize_t
btmrvl_txdnldready_read(struct file
*file
, char __user
*userbuf
,
355 size_t count
, loff_t
*ppos
)
357 struct btmrvl_private
*priv
= file
->private_data
;
361 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n",
362 priv
->btmrvl_dev
.tx_dnld_rdy
);
364 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
367 static const struct file_operations btmrvl_txdnldready_fops
= {
368 .read
= btmrvl_txdnldready_read
,
369 .open
= btmrvl_open_generic
,
370 .llseek
= default_llseek
,
373 void btmrvl_debugfs_init(struct hci_dev
*hdev
)
375 struct btmrvl_private
*priv
= hdev
->driver_data
;
376 struct btmrvl_debugfs_data
*dbg
;
381 dbg
= kzalloc(sizeof(*dbg
), GFP_KERNEL
);
382 priv
->debugfs_data
= dbg
;
385 BT_ERR("Can not allocate memory for btmrvl_debugfs_data.");
389 dbg
->config_dir
= debugfs_create_dir("config", hdev
->debugfs
);
391 dbg
->psmode
= debugfs_create_file("psmode", 0644, dbg
->config_dir
,
392 hdev
->driver_data
, &btmrvl_psmode_fops
);
393 dbg
->pscmd
= debugfs_create_file("pscmd", 0644, dbg
->config_dir
,
394 hdev
->driver_data
, &btmrvl_pscmd_fops
);
395 dbg
->gpiogap
= debugfs_create_file("gpiogap", 0644, dbg
->config_dir
,
396 hdev
->driver_data
, &btmrvl_gpiogap_fops
);
397 dbg
->hsmode
= debugfs_create_file("hsmode", 0644, dbg
->config_dir
,
398 hdev
->driver_data
, &btmrvl_hsmode_fops
);
399 dbg
->hscmd
= debugfs_create_file("hscmd", 0644, dbg
->config_dir
,
400 hdev
->driver_data
, &btmrvl_hscmd_fops
);
401 dbg
->hscfgcmd
= debugfs_create_file("hscfgcmd", 0644, dbg
->config_dir
,
402 hdev
->driver_data
, &btmrvl_hscfgcmd_fops
);
404 dbg
->status_dir
= debugfs_create_dir("status", hdev
->debugfs
);
405 dbg
->curpsmode
= debugfs_create_file("curpsmode", 0444,
408 &btmrvl_curpsmode_fops
);
409 dbg
->psstate
= debugfs_create_file("psstate", 0444, dbg
->status_dir
,
410 hdev
->driver_data
, &btmrvl_psstate_fops
);
411 dbg
->hsstate
= debugfs_create_file("hsstate", 0444, dbg
->status_dir
,
412 hdev
->driver_data
, &btmrvl_hsstate_fops
);
413 dbg
->txdnldready
= debugfs_create_file("txdnldready", 0444,
416 &btmrvl_txdnldready_fops
);
419 void btmrvl_debugfs_remove(struct hci_dev
*hdev
)
421 struct btmrvl_private
*priv
= hdev
->driver_data
;
422 struct btmrvl_debugfs_data
*dbg
= priv
->debugfs_data
;
427 debugfs_remove(dbg
->psmode
);
428 debugfs_remove(dbg
->pscmd
);
429 debugfs_remove(dbg
->gpiogap
);
430 debugfs_remove(dbg
->hsmode
);
431 debugfs_remove(dbg
->hscmd
);
432 debugfs_remove(dbg
->hscfgcmd
);
433 debugfs_remove(dbg
->config_dir
);
435 debugfs_remove(dbg
->curpsmode
);
436 debugfs_remove(dbg
->psstate
);
437 debugfs_remove(dbg
->hsstate
);
438 debugfs_remove(dbg
->txdnldready
);
439 debugfs_remove(dbg
->status_dir
);