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
,
97 static ssize_t
btmrvl_psmode_write(struct file
*file
, const char __user
*ubuf
,
98 size_t count
, loff_t
*ppos
)
100 struct btmrvl_private
*priv
= file
->private_data
;
104 memset(buf
, 0, sizeof(buf
));
106 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
109 ret
= strict_strtol(buf
, 10, &result
);
111 priv
->btmrvl_dev
.psmode
= result
;
116 static ssize_t
btmrvl_psmode_read(struct file
*file
, char __user
*userbuf
,
117 size_t count
, loff_t
*ppos
)
119 struct btmrvl_private
*priv
= file
->private_data
;
123 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n",
124 priv
->btmrvl_dev
.psmode
);
126 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
129 static const struct file_operations btmrvl_psmode_fops
= {
130 .read
= btmrvl_psmode_read
,
131 .write
= btmrvl_psmode_write
,
132 .open
= btmrvl_open_generic
,
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
);
149 priv
->btmrvl_dev
.pscmd
= result
;
151 if (priv
->btmrvl_dev
.pscmd
) {
152 btmrvl_prepare_command(priv
);
153 wake_up_interruptible(&priv
->main_thread
.wait_q
);
160 static ssize_t
btmrvl_pscmd_read(struct file
*file
, char __user
*userbuf
,
161 size_t count
, loff_t
*ppos
)
163 struct btmrvl_private
*priv
= file
->private_data
;
167 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->btmrvl_dev
.pscmd
);
169 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
172 static const struct file_operations btmrvl_pscmd_fops
= {
173 .read
= btmrvl_pscmd_read
,
174 .write
= btmrvl_pscmd_write
,
175 .open
= btmrvl_open_generic
,
178 static ssize_t
btmrvl_gpiogap_write(struct file
*file
, const char __user
*ubuf
,
179 size_t count
, loff_t
*ppos
)
181 struct btmrvl_private
*priv
= file
->private_data
;
185 memset(buf
, 0, sizeof(buf
));
187 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
190 ret
= strict_strtol(buf
, 16, &result
);
192 priv
->btmrvl_dev
.gpio_gap
= result
;
197 static ssize_t
btmrvl_gpiogap_read(struct file
*file
, char __user
*userbuf
,
198 size_t count
, loff_t
*ppos
)
200 struct btmrvl_private
*priv
= file
->private_data
;
204 ret
= snprintf(buf
, sizeof(buf
) - 1, "0x%x\n",
205 priv
->btmrvl_dev
.gpio_gap
);
207 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
210 static const struct file_operations btmrvl_gpiogap_fops
= {
211 .read
= btmrvl_gpiogap_read
,
212 .write
= btmrvl_gpiogap_write
,
213 .open
= btmrvl_open_generic
,
216 static ssize_t
btmrvl_hscmd_write(struct file
*file
, const char __user
*ubuf
,
217 size_t count
, loff_t
*ppos
)
219 struct btmrvl_private
*priv
= file
->private_data
;
223 memset(buf
, 0, sizeof(buf
));
225 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
228 ret
= strict_strtol(buf
, 10, &result
);
230 priv
->btmrvl_dev
.hscmd
= result
;
231 if (priv
->btmrvl_dev
.hscmd
) {
232 btmrvl_prepare_command(priv
);
233 wake_up_interruptible(&priv
->main_thread
.wait_q
);
239 static ssize_t
btmrvl_hscmd_read(struct file
*file
, char __user
*userbuf
,
240 size_t count
, loff_t
*ppos
)
242 struct btmrvl_private
*priv
= file
->private_data
;
246 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->btmrvl_dev
.hscmd
);
248 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
251 static const struct file_operations btmrvl_hscmd_fops
= {
252 .read
= btmrvl_hscmd_read
,
253 .write
= btmrvl_hscmd_write
,
254 .open
= btmrvl_open_generic
,
257 static ssize_t
btmrvl_hsmode_write(struct file
*file
, const char __user
*ubuf
,
258 size_t count
, loff_t
*ppos
)
260 struct btmrvl_private
*priv
= file
->private_data
;
264 memset(buf
, 0, sizeof(buf
));
266 if (copy_from_user(&buf
, ubuf
, min_t(size_t, sizeof(buf
) - 1, count
)))
269 ret
= strict_strtol(buf
, 10, &result
);
271 priv
->btmrvl_dev
.hsmode
= result
;
276 static ssize_t
btmrvl_hsmode_read(struct file
*file
, char __user
* userbuf
,
277 size_t count
, loff_t
*ppos
)
279 struct btmrvl_private
*priv
= file
->private_data
;
283 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->btmrvl_dev
.hsmode
);
285 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
288 static const struct file_operations btmrvl_hsmode_fops
= {
289 .read
= btmrvl_hsmode_read
,
290 .write
= btmrvl_hsmode_write
,
291 .open
= btmrvl_open_generic
,
294 static ssize_t
btmrvl_curpsmode_read(struct file
*file
, char __user
*userbuf
,
295 size_t count
, loff_t
*ppos
)
297 struct btmrvl_private
*priv
= file
->private_data
;
301 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->adapter
->psmode
);
303 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
306 static const struct file_operations btmrvl_curpsmode_fops
= {
307 .read
= btmrvl_curpsmode_read
,
308 .open
= btmrvl_open_generic
,
311 static ssize_t
btmrvl_psstate_read(struct file
*file
, char __user
* userbuf
,
312 size_t count
, loff_t
*ppos
)
314 struct btmrvl_private
*priv
= file
->private_data
;
318 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->adapter
->ps_state
);
320 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
323 static const struct file_operations btmrvl_psstate_fops
= {
324 .read
= btmrvl_psstate_read
,
325 .open
= btmrvl_open_generic
,
328 static ssize_t
btmrvl_hsstate_read(struct file
*file
, char __user
*userbuf
,
329 size_t count
, loff_t
*ppos
)
331 struct btmrvl_private
*priv
= file
->private_data
;
335 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n", priv
->adapter
->hs_state
);
337 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
340 static const struct file_operations btmrvl_hsstate_fops
= {
341 .read
= btmrvl_hsstate_read
,
342 .open
= btmrvl_open_generic
,
345 static ssize_t
btmrvl_txdnldready_read(struct file
*file
, char __user
*userbuf
,
346 size_t count
, loff_t
*ppos
)
348 struct btmrvl_private
*priv
= file
->private_data
;
352 ret
= snprintf(buf
, sizeof(buf
) - 1, "%d\n",
353 priv
->btmrvl_dev
.tx_dnld_rdy
);
355 return simple_read_from_buffer(userbuf
, count
, ppos
, buf
, ret
);
358 static const struct file_operations btmrvl_txdnldready_fops
= {
359 .read
= btmrvl_txdnldready_read
,
360 .open
= btmrvl_open_generic
,
363 void btmrvl_debugfs_init(struct hci_dev
*hdev
)
365 struct btmrvl_private
*priv
= hdev
->driver_data
;
366 struct btmrvl_debugfs_data
*dbg
;
371 dbg
= kzalloc(sizeof(*dbg
), GFP_KERNEL
);
372 priv
->debugfs_data
= dbg
;
375 BT_ERR("Can not allocate memory for btmrvl_debugfs_data.");
379 dbg
->config_dir
= debugfs_create_dir("config", hdev
->debugfs
);
381 dbg
->psmode
= debugfs_create_file("psmode", 0644, dbg
->config_dir
,
382 hdev
->driver_data
, &btmrvl_psmode_fops
);
383 dbg
->pscmd
= debugfs_create_file("pscmd", 0644, dbg
->config_dir
,
384 hdev
->driver_data
, &btmrvl_pscmd_fops
);
385 dbg
->gpiogap
= debugfs_create_file("gpiogap", 0644, dbg
->config_dir
,
386 hdev
->driver_data
, &btmrvl_gpiogap_fops
);
387 dbg
->hsmode
= debugfs_create_file("hsmode", 0644, dbg
->config_dir
,
388 hdev
->driver_data
, &btmrvl_hsmode_fops
);
389 dbg
->hscmd
= debugfs_create_file("hscmd", 0644, dbg
->config_dir
,
390 hdev
->driver_data
, &btmrvl_hscmd_fops
);
391 dbg
->hscfgcmd
= debugfs_create_file("hscfgcmd", 0644, dbg
->config_dir
,
392 hdev
->driver_data
, &btmrvl_hscfgcmd_fops
);
394 dbg
->status_dir
= debugfs_create_dir("status", hdev
->debugfs
);
395 dbg
->curpsmode
= debugfs_create_file("curpsmode", 0444,
398 &btmrvl_curpsmode_fops
);
399 dbg
->psstate
= debugfs_create_file("psstate", 0444, dbg
->status_dir
,
400 hdev
->driver_data
, &btmrvl_psstate_fops
);
401 dbg
->hsstate
= debugfs_create_file("hsstate", 0444, dbg
->status_dir
,
402 hdev
->driver_data
, &btmrvl_hsstate_fops
);
403 dbg
->txdnldready
= debugfs_create_file("txdnldready", 0444,
406 &btmrvl_txdnldready_fops
);
409 void btmrvl_debugfs_remove(struct hci_dev
*hdev
)
411 struct btmrvl_private
*priv
= hdev
->driver_data
;
412 struct btmrvl_debugfs_data
*dbg
= priv
->debugfs_data
;
417 debugfs_remove(dbg
->psmode
);
418 debugfs_remove(dbg
->pscmd
);
419 debugfs_remove(dbg
->gpiogap
);
420 debugfs_remove(dbg
->hsmode
);
421 debugfs_remove(dbg
->hscmd
);
422 debugfs_remove(dbg
->hscfgcmd
);
423 debugfs_remove(dbg
->config_dir
);
425 debugfs_remove(dbg
->curpsmode
);
426 debugfs_remove(dbg
->psstate
);
427 debugfs_remove(dbg
->hsstate
);
428 debugfs_remove(dbg
->txdnldready
);
429 debugfs_remove(dbg
->status_dir
);