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>
23 #include <net/bluetooth/bluetooth.h>
24 #include <net/bluetooth/hci_core.h>
26 #include "btmrvl_drv.h"
28 struct btmrvl_debugfs_data
{
29 struct dentry
*root_dir
, *config_dir
, *status_dir
;
32 struct dentry
*drvdbg
;
33 struct dentry
*psmode
;
35 struct dentry
*hsmode
;
37 struct dentry
*gpiogap
;
38 struct dentry
*hscfgcmd
;
41 struct dentry
*curpsmode
;
42 struct dentry
*hsstate
;
43 struct dentry
*psstate
;
44 struct dentry
*txdnldready
;
47 static int btmrvl_open_generic(struct inode
*inode
, struct file
*file
)
49 file
->private_data
= inode
->i_private
;
53 static ssize_t
btmrvl_hscfgcmd_write(struct file
*file
,
54 const char __user
*ubuf
, size_t count
, loff_t
*ppos
)
56 struct btmrvl_private
*priv
= file
->private_data
;
60 memset(buf
, 0, sizeof(buf
));
62 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
65 ret
= strict_strtol(buf
, 10, &result
);
67 priv
->btmrvl_dev
.hscfgcmd
= result
;
69 if (priv
->btmrvl_dev
.hscfgcmd
) {
70 btmrvl_prepare_command(priv
);
71 wake_up_interruptible(&priv
->main_thread
.wait_q
);
77 static ssize_t
btmrvl_hscfgcmd_read(struct file
*file
, char __user
*userbuf
,
78 size_t count
, loff_t
*ppos
)
80 struct btmrvl_private
*priv
= file
->private_data
;
84 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n",
85 priv
->btmrvl_dev
.hscfgcmd
);
87 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
90 static const struct file_operations btmrvl_hscfgcmd_fops
= {
91 .read
= btmrvl_hscfgcmd_read
,
92 .write
= btmrvl_hscfgcmd_write
,
93 .open
= btmrvl_open_generic
,
96 static ssize_t
btmrvl_psmode_write(struct file
*file
, const char __user
*ubuf
,
97 size_t count
, loff_t
*ppos
)
99 struct btmrvl_private
*priv
= file
->private_data
;
103 memset(buf
, 0, sizeof(buf
));
105 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
108 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
,
131 .open
= btmrvl_open_generic
,
134 static ssize_t
btmrvl_pscmd_write(struct file
*file
, const char __user
*ubuf
,
135 size_t count
, loff_t
*ppos
)
137 struct btmrvl_private
*priv
= file
->private_data
;
141 memset(buf
, 0, sizeof(buf
));
143 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
146 ret
= strict_strtol(buf
, 10, &result
);
148 priv
->btmrvl_dev
.pscmd
= result
;
150 if (priv
->btmrvl_dev
.pscmd
) {
151 btmrvl_prepare_command(priv
);
152 wake_up_interruptible(&priv
->main_thread
.wait_q
);
159 static ssize_t
btmrvl_pscmd_read(struct file
*file
, char __user
*userbuf
,
160 size_t count
, loff_t
*ppos
)
162 struct btmrvl_private
*priv
= file
->private_data
;
166 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->btmrvl_dev
.pscmd
);
168 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
171 static const struct file_operations btmrvl_pscmd_fops
= {
172 .read
= btmrvl_pscmd_read
,
173 .write
= btmrvl_pscmd_write
,
174 .open
= btmrvl_open_generic
,
177 static ssize_t
btmrvl_gpiogap_write(struct file
*file
, const char __user
*ubuf
,
178 size_t count
, loff_t
*ppos
)
180 struct btmrvl_private
*priv
= file
->private_data
;
184 memset(buf
, 0, sizeof(buf
));
186 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
189 ret
= strict_strtol(buf
, 16, &result
);
191 priv
->btmrvl_dev
.gpio_gap
= result
;
196 static ssize_t
btmrvl_gpiogap_read(struct file
*file
, char __user
*userbuf
,
197 size_t count
, loff_t
*ppos
)
199 struct btmrvl_private
*priv
= file
->private_data
;
203 ret
= snprintf(buf
, sizeof(buf
) - 1, "0x%x\n",
204 priv
->btmrvl_dev
.gpio_gap
);
206 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
209 static const struct file_operations btmrvl_gpiogap_fops
= {
210 .read
= btmrvl_gpiogap_read
,
211 .write
= btmrvl_gpiogap_write
,
212 .open
= btmrvl_open_generic
,
215 static ssize_t
btmrvl_hscmd_write(struct file
*file
, const char __user
*ubuf
,
216 size_t count
, loff_t
*ppos
)
218 struct btmrvl_private
*priv
= (struct btmrvl_private
*) file
->private_data
;
222 memset(buf
, 0, sizeof(buf
));
224 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
227 ret
= strict_strtol(buf
, 10, &result
);
229 priv
->btmrvl_dev
.hscmd
= result
;
230 if (priv
->btmrvl_dev
.hscmd
) {
231 btmrvl_prepare_command(priv
);
232 wake_up_interruptible(&priv
->main_thread
.wait_q
);
238 static ssize_t
btmrvl_hscmd_read(struct file
*file
, char __user
*userbuf
,
239 size_t count
, loff_t
*ppos
)
241 struct btmrvl_private
*priv
= file
->private_data
;
245 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->btmrvl_dev
.hscmd
);
247 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
250 static const struct file_operations btmrvl_hscmd_fops
= {
251 .read
= btmrvl_hscmd_read
,
252 .write
= btmrvl_hscmd_write
,
253 .open
= btmrvl_open_generic
,
256 static ssize_t
btmrvl_hsmode_write(struct file
*file
, const char __user
*ubuf
,
257 size_t count
, loff_t
*ppos
)
259 struct btmrvl_private
*priv
= file
->private_data
;
263 memset(buf
, 0, sizeof(buf
));
265 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
268 ret
= strict_strtol(buf
, 10, &result
);
270 priv
->btmrvl_dev
.hsmode
= result
;
275 static ssize_t
btmrvl_hsmode_read(struct file
*file
, char __user
* userbuf
,
276 size_t count
, loff_t
*ppos
)
278 struct btmrvl_private
*priv
= file
->private_data
;
282 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->btmrvl_dev
.hsmode
);
284 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
287 static const struct file_operations btmrvl_hsmode_fops
= {
288 .read
= btmrvl_hsmode_read
,
289 .write
= btmrvl_hsmode_write
,
290 .open
= btmrvl_open_generic
,
293 static ssize_t
btmrvl_curpsmode_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
->adapter
->psmode
);
302 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
305 static const struct file_operations btmrvl_curpsmode_fops
= {
306 .read
= btmrvl_curpsmode_read
,
307 .open
= btmrvl_open_generic
,
310 static ssize_t
btmrvl_psstate_read(struct file
*file
, char __user
* userbuf
,
311 size_t count
, loff_t
*ppos
)
313 struct btmrvl_private
*priv
= file
->private_data
;
317 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->adapter
->ps_state
);
319 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
322 static const struct file_operations btmrvl_psstate_fops
= {
323 .read
= btmrvl_psstate_read
,
324 .open
= btmrvl_open_generic
,
327 static ssize_t
btmrvl_hsstate_read(struct file
*file
, char __user
*userbuf
,
328 size_t count
, loff_t
*ppos
)
330 struct btmrvl_private
*priv
= file
->private_data
;
334 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->adapter
->hs_state
);
336 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
339 static const struct file_operations btmrvl_hsstate_fops
= {
340 .read
= btmrvl_hsstate_read
,
341 .open
= btmrvl_open_generic
,
344 static ssize_t
btmrvl_txdnldready_read(struct file
*file
, char __user
*userbuf
,
345 size_t count
, loff_t
*ppos
)
347 struct btmrvl_private
*priv
= file
->private_data
;
351 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n",
352 priv
->btmrvl_dev
.tx_dnld_rdy
);
354 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
357 static const struct file_operations btmrvl_txdnldready_fops
= {
358 .read
= btmrvl_txdnldready_read
,
359 .open
= btmrvl_open_generic
,
362 void btmrvl_debugfs_init(struct hci_dev
*hdev
)
364 struct btmrvl_private
*priv
= hdev
->driver_data
;
365 struct btmrvl_debugfs_data
*dbg
;
367 dbg
= kzalloc(sizeof(*dbg
), GFP_KERNEL
);
368 priv
->debugfs_data
= dbg
;
371 BT_ERR("Can not allocate memory for btmrvl_debugfs_data.");
375 dbg
->root_dir
= debugfs_create_dir("btmrvl", NULL
);
377 dbg
->config_dir
= debugfs_create_dir("config", dbg
->root_dir
);
379 dbg
->psmode
= debugfs_create_file("psmode", 0644, dbg
->config_dir
,
380 hdev
->driver_data
, &btmrvl_psmode_fops
);
381 dbg
->pscmd
= debugfs_create_file("pscmd", 0644, dbg
->config_dir
,
382 hdev
->driver_data
, &btmrvl_pscmd_fops
);
383 dbg
->gpiogap
= debugfs_create_file("gpiogap", 0644, dbg
->config_dir
,
384 hdev
->driver_data
, &btmrvl_gpiogap_fops
);
385 dbg
->hsmode
= debugfs_create_file("hsmode", 0644, dbg
->config_dir
,
386 hdev
->driver_data
, &btmrvl_hsmode_fops
);
387 dbg
->hscmd
= debugfs_create_file("hscmd", 0644, dbg
->config_dir
,
388 hdev
->driver_data
, &btmrvl_hscmd_fops
);
389 dbg
->hscfgcmd
= debugfs_create_file("hscfgcmd", 0644, dbg
->config_dir
,
390 hdev
->driver_data
, &btmrvl_hscfgcmd_fops
);
392 dbg
->status_dir
= debugfs_create_dir("status", dbg
->root_dir
);
393 dbg
->curpsmode
= debugfs_create_file("curpsmode", 0444,
396 &btmrvl_curpsmode_fops
);
397 dbg
->psstate
= debugfs_create_file("psstate", 0444, dbg
->status_dir
,
398 hdev
->driver_data
, &btmrvl_psstate_fops
);
399 dbg
->hsstate
= debugfs_create_file("hsstate", 0444, dbg
->status_dir
,
400 hdev
->driver_data
, &btmrvl_hsstate_fops
);
401 dbg
->txdnldready
= debugfs_create_file("txdnldready", 0444,
404 &btmrvl_txdnldready_fops
);
407 void btmrvl_debugfs_remove(struct hci_dev
*hdev
)
409 struct btmrvl_private
*priv
= hdev
->driver_data
;
410 struct btmrvl_debugfs_data
*dbg
= priv
->debugfs_data
;
415 debugfs_remove(dbg
->psmode
);
416 debugfs_remove(dbg
->pscmd
);
417 debugfs_remove(dbg
->gpiogap
);
418 debugfs_remove(dbg
->hsmode
);
419 debugfs_remove(dbg
->hscmd
);
420 debugfs_remove(dbg
->hscfgcmd
);
421 debugfs_remove(dbg
->config_dir
);
423 debugfs_remove(dbg
->curpsmode
);
424 debugfs_remove(dbg
->psstate
);
425 debugfs_remove(dbg
->hsstate
);
426 debugfs_remove(dbg
->txdnldready
);
427 debugfs_remove(dbg
->status_dir
);
429 debugfs_remove(dbg
->root_dir
);