Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/bluetooth/btmrvl_debugfs.c
26378 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* Marvell Bluetooth driver: debugfs related functions
4
*
5
* Copyright (C) 2009, Marvell International Ltd.
6
**/
7
8
#include <linux/debugfs.h>
9
#include <linux/slab.h>
10
11
#include <net/bluetooth/bluetooth.h>
12
#include <net/bluetooth/hci_core.h>
13
14
#include "btmrvl_drv.h"
15
16
struct btmrvl_debugfs_data {
17
struct dentry *config_dir;
18
struct dentry *status_dir;
19
};
20
21
static ssize_t btmrvl_hscfgcmd_write(struct file *file,
22
const char __user *ubuf, size_t count, loff_t *ppos)
23
{
24
struct btmrvl_private *priv = file->private_data;
25
long result, ret;
26
27
ret = kstrtol_from_user(ubuf, count, 10, &result);
28
if (ret)
29
return ret;
30
31
priv->btmrvl_dev.hscfgcmd = result;
32
33
if (priv->btmrvl_dev.hscfgcmd) {
34
btmrvl_prepare_command(priv);
35
wake_up_interruptible(&priv->main_thread.wait_q);
36
}
37
38
return count;
39
}
40
41
static ssize_t btmrvl_hscfgcmd_read(struct file *file, char __user *userbuf,
42
size_t count, loff_t *ppos)
43
{
44
struct btmrvl_private *priv = file->private_data;
45
char buf[16];
46
int ret;
47
48
ret = snprintf(buf, sizeof(buf) - 1, "%d\n",
49
priv->btmrvl_dev.hscfgcmd);
50
51
return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
52
}
53
54
static const struct file_operations btmrvl_hscfgcmd_fops = {
55
.read = btmrvl_hscfgcmd_read,
56
.write = btmrvl_hscfgcmd_write,
57
.open = simple_open,
58
.llseek = default_llseek,
59
};
60
61
static ssize_t btmrvl_pscmd_write(struct file *file, const char __user *ubuf,
62
size_t count, loff_t *ppos)
63
{
64
struct btmrvl_private *priv = file->private_data;
65
long result, ret;
66
67
ret = kstrtol_from_user(ubuf, count, 10, &result);
68
if (ret)
69
return ret;
70
71
priv->btmrvl_dev.pscmd = result;
72
73
if (priv->btmrvl_dev.pscmd) {
74
btmrvl_prepare_command(priv);
75
wake_up_interruptible(&priv->main_thread.wait_q);
76
}
77
78
return count;
79
80
}
81
82
static ssize_t btmrvl_pscmd_read(struct file *file, char __user *userbuf,
83
size_t count, loff_t *ppos)
84
{
85
struct btmrvl_private *priv = file->private_data;
86
char buf[16];
87
int ret;
88
89
ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->btmrvl_dev.pscmd);
90
91
return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
92
}
93
94
static const struct file_operations btmrvl_pscmd_fops = {
95
.read = btmrvl_pscmd_read,
96
.write = btmrvl_pscmd_write,
97
.open = simple_open,
98
.llseek = default_llseek,
99
};
100
101
static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf,
102
size_t count, loff_t *ppos)
103
{
104
struct btmrvl_private *priv = file->private_data;
105
long result, ret;
106
107
ret = kstrtol_from_user(ubuf, count, 10, &result);
108
if (ret)
109
return ret;
110
111
priv->btmrvl_dev.hscmd = result;
112
if (priv->btmrvl_dev.hscmd) {
113
btmrvl_prepare_command(priv);
114
wake_up_interruptible(&priv->main_thread.wait_q);
115
}
116
117
return count;
118
}
119
120
static ssize_t btmrvl_hscmd_read(struct file *file, char __user *userbuf,
121
size_t count, loff_t *ppos)
122
{
123
struct btmrvl_private *priv = file->private_data;
124
char buf[16];
125
int ret;
126
127
ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->btmrvl_dev.hscmd);
128
129
return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
130
}
131
132
static const struct file_operations btmrvl_hscmd_fops = {
133
.read = btmrvl_hscmd_read,
134
.write = btmrvl_hscmd_write,
135
.open = simple_open,
136
.llseek = default_llseek,
137
};
138
139
void btmrvl_debugfs_init(struct hci_dev *hdev)
140
{
141
struct btmrvl_private *priv = hci_get_drvdata(hdev);
142
struct btmrvl_debugfs_data *dbg;
143
144
if (!hdev->debugfs)
145
return;
146
147
dbg = kzalloc(sizeof(*dbg), GFP_KERNEL);
148
priv->debugfs_data = dbg;
149
150
if (!dbg) {
151
BT_ERR("Can not allocate memory for btmrvl_debugfs_data.");
152
return;
153
}
154
155
dbg->config_dir = debugfs_create_dir("config", hdev->debugfs);
156
157
debugfs_create_u8("psmode", 0644, dbg->config_dir,
158
&priv->btmrvl_dev.psmode);
159
debugfs_create_file("pscmd", 0644, dbg->config_dir,
160
priv, &btmrvl_pscmd_fops);
161
debugfs_create_x16("gpiogap", 0644, dbg->config_dir,
162
&priv->btmrvl_dev.gpio_gap);
163
debugfs_create_u8("hsmode", 0644, dbg->config_dir,
164
&priv->btmrvl_dev.hsmode);
165
debugfs_create_file("hscmd", 0644, dbg->config_dir,
166
priv, &btmrvl_hscmd_fops);
167
debugfs_create_file("hscfgcmd", 0644, dbg->config_dir,
168
priv, &btmrvl_hscfgcmd_fops);
169
170
dbg->status_dir = debugfs_create_dir("status", hdev->debugfs);
171
debugfs_create_u8("curpsmode", 0444, dbg->status_dir,
172
&priv->adapter->psmode);
173
debugfs_create_u8("psstate", 0444, dbg->status_dir,
174
&priv->adapter->ps_state);
175
debugfs_create_u8("hsstate", 0444, dbg->status_dir,
176
&priv->adapter->hs_state);
177
debugfs_create_u8("txdnldready", 0444, dbg->status_dir,
178
&priv->btmrvl_dev.tx_dnld_rdy);
179
}
180
181
void btmrvl_debugfs_remove(struct hci_dev *hdev)
182
{
183
struct btmrvl_private *priv = hci_get_drvdata(hdev);
184
struct btmrvl_debugfs_data *dbg = priv->debugfs_data;
185
186
if (!dbg)
187
return;
188
189
debugfs_remove_recursive(dbg->config_dir);
190
debugfs_remove_recursive(dbg->status_dir);
191
192
kfree(dbg);
193
}
194
195