Commit b914a250e7b390c713b36a9405a39c4c11abad80
1 parent
ca325f6989
Exists in
master
and in
7 other branches
Bluetooth: Convert Marvell driver to use per adapter debugfs
The debugfs support of the Marvell driver is buggy. It is limited to one controller per system. Fix this by using the controller specific debugfs directory as parent. Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Showing 1 changed file with 7 additions and 7 deletions Inline Diff
drivers/bluetooth/btmrvl_debugfs.c
1 | /** | 1 | /** |
2 | * Marvell Bluetooth driver: debugfs related functions | 2 | * Marvell Bluetooth driver: debugfs related functions |
3 | * | 3 | * |
4 | * Copyright (C) 2009, Marvell International Ltd. | 4 | * Copyright (C) 2009, Marvell International Ltd. |
5 | * | 5 | * |
6 | * This software file (the "File") is distributed by Marvell International | 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 | 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 | 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 | 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., | 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 | 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. | 12 | * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. |
13 | * | 13 | * |
14 | * | 14 | * |
15 | * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE | 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 | 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE |
17 | * ARE EXPRESSLY DISCLAIMED. The License provides additional details about | 17 | * ARE EXPRESSLY DISCLAIMED. The License provides additional details about |
18 | * this warranty disclaimer. | 18 | * this warranty disclaimer. |
19 | **/ | 19 | **/ |
20 | 20 | ||
21 | #include <linux/debugfs.h> | 21 | #include <linux/debugfs.h> |
22 | 22 | ||
23 | #include <net/bluetooth/bluetooth.h> | 23 | #include <net/bluetooth/bluetooth.h> |
24 | #include <net/bluetooth/hci_core.h> | 24 | #include <net/bluetooth/hci_core.h> |
25 | 25 | ||
26 | #include "btmrvl_drv.h" | 26 | #include "btmrvl_drv.h" |
27 | 27 | ||
28 | struct btmrvl_debugfs_data { | 28 | struct btmrvl_debugfs_data { |
29 | struct dentry *root_dir, *config_dir, *status_dir; | 29 | struct dentry *config_dir; |
30 | struct dentry *status_dir; | ||
30 | 31 | ||
31 | /* config */ | 32 | /* config */ |
32 | struct dentry *psmode; | 33 | struct dentry *psmode; |
33 | struct dentry *pscmd; | 34 | struct dentry *pscmd; |
34 | struct dentry *hsmode; | 35 | struct dentry *hsmode; |
35 | struct dentry *hscmd; | 36 | struct dentry *hscmd; |
36 | struct dentry *gpiogap; | 37 | struct dentry *gpiogap; |
37 | struct dentry *hscfgcmd; | 38 | struct dentry *hscfgcmd; |
38 | 39 | ||
39 | /* status */ | 40 | /* status */ |
40 | struct dentry *curpsmode; | 41 | struct dentry *curpsmode; |
41 | struct dentry *hsstate; | 42 | struct dentry *hsstate; |
42 | struct dentry *psstate; | 43 | struct dentry *psstate; |
43 | struct dentry *txdnldready; | 44 | struct dentry *txdnldready; |
44 | }; | 45 | }; |
45 | 46 | ||
46 | static int btmrvl_open_generic(struct inode *inode, struct file *file) | 47 | static int btmrvl_open_generic(struct inode *inode, struct file *file) |
47 | { | 48 | { |
48 | file->private_data = inode->i_private; | 49 | file->private_data = inode->i_private; |
49 | return 0; | 50 | return 0; |
50 | } | 51 | } |
51 | 52 | ||
52 | static ssize_t btmrvl_hscfgcmd_write(struct file *file, | 53 | static ssize_t btmrvl_hscfgcmd_write(struct file *file, |
53 | const char __user *ubuf, size_t count, loff_t *ppos) | 54 | const char __user *ubuf, size_t count, loff_t *ppos) |
54 | { | 55 | { |
55 | struct btmrvl_private *priv = file->private_data; | 56 | struct btmrvl_private *priv = file->private_data; |
56 | char buf[16]; | 57 | char buf[16]; |
57 | long result, ret; | 58 | long result, ret; |
58 | 59 | ||
59 | memset(buf, 0, sizeof(buf)); | 60 | memset(buf, 0, sizeof(buf)); |
60 | 61 | ||
61 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | 62 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) |
62 | return -EFAULT; | 63 | return -EFAULT; |
63 | 64 | ||
64 | ret = strict_strtol(buf, 10, &result); | 65 | ret = strict_strtol(buf, 10, &result); |
65 | 66 | ||
66 | priv->btmrvl_dev.hscfgcmd = result; | 67 | priv->btmrvl_dev.hscfgcmd = result; |
67 | 68 | ||
68 | if (priv->btmrvl_dev.hscfgcmd) { | 69 | if (priv->btmrvl_dev.hscfgcmd) { |
69 | btmrvl_prepare_command(priv); | 70 | btmrvl_prepare_command(priv); |
70 | wake_up_interruptible(&priv->main_thread.wait_q); | 71 | wake_up_interruptible(&priv->main_thread.wait_q); |
71 | } | 72 | } |
72 | 73 | ||
73 | return count; | 74 | return count; |
74 | } | 75 | } |
75 | 76 | ||
76 | static ssize_t btmrvl_hscfgcmd_read(struct file *file, char __user *userbuf, | 77 | static ssize_t btmrvl_hscfgcmd_read(struct file *file, char __user *userbuf, |
77 | size_t count, loff_t *ppos) | 78 | size_t count, loff_t *ppos) |
78 | { | 79 | { |
79 | struct btmrvl_private *priv = file->private_data; | 80 | struct btmrvl_private *priv = file->private_data; |
80 | char buf[16]; | 81 | char buf[16]; |
81 | int ret; | 82 | int ret; |
82 | 83 | ||
83 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", | 84 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", |
84 | priv->btmrvl_dev.hscfgcmd); | 85 | priv->btmrvl_dev.hscfgcmd); |
85 | 86 | ||
86 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); | 87 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); |
87 | } | 88 | } |
88 | 89 | ||
89 | static const struct file_operations btmrvl_hscfgcmd_fops = { | 90 | static const struct file_operations btmrvl_hscfgcmd_fops = { |
90 | .read = btmrvl_hscfgcmd_read, | 91 | .read = btmrvl_hscfgcmd_read, |
91 | .write = btmrvl_hscfgcmd_write, | 92 | .write = btmrvl_hscfgcmd_write, |
92 | .open = btmrvl_open_generic, | 93 | .open = btmrvl_open_generic, |
93 | }; | 94 | }; |
94 | 95 | ||
95 | static ssize_t btmrvl_psmode_write(struct file *file, const char __user *ubuf, | 96 | static ssize_t btmrvl_psmode_write(struct file *file, const char __user *ubuf, |
96 | size_t count, loff_t *ppos) | 97 | size_t count, loff_t *ppos) |
97 | { | 98 | { |
98 | struct btmrvl_private *priv = file->private_data; | 99 | struct btmrvl_private *priv = file->private_data; |
99 | char buf[16]; | 100 | char buf[16]; |
100 | long result, ret; | 101 | long result, ret; |
101 | 102 | ||
102 | memset(buf, 0, sizeof(buf)); | 103 | memset(buf, 0, sizeof(buf)); |
103 | 104 | ||
104 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | 105 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) |
105 | return -EFAULT; | 106 | return -EFAULT; |
106 | 107 | ||
107 | ret = strict_strtol(buf, 10, &result); | 108 | ret = strict_strtol(buf, 10, &result); |
108 | 109 | ||
109 | priv->btmrvl_dev.psmode = result; | 110 | priv->btmrvl_dev.psmode = result; |
110 | 111 | ||
111 | return count; | 112 | return count; |
112 | } | 113 | } |
113 | 114 | ||
114 | static ssize_t btmrvl_psmode_read(struct file *file, char __user *userbuf, | 115 | static ssize_t btmrvl_psmode_read(struct file *file, char __user *userbuf, |
115 | size_t count, loff_t *ppos) | 116 | size_t count, loff_t *ppos) |
116 | { | 117 | { |
117 | struct btmrvl_private *priv = file->private_data; | 118 | struct btmrvl_private *priv = file->private_data; |
118 | char buf[16]; | 119 | char buf[16]; |
119 | int ret; | 120 | int ret; |
120 | 121 | ||
121 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", | 122 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", |
122 | priv->btmrvl_dev.psmode); | 123 | priv->btmrvl_dev.psmode); |
123 | 124 | ||
124 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); | 125 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); |
125 | } | 126 | } |
126 | 127 | ||
127 | static const struct file_operations btmrvl_psmode_fops = { | 128 | static const struct file_operations btmrvl_psmode_fops = { |
128 | .read = btmrvl_psmode_read, | 129 | .read = btmrvl_psmode_read, |
129 | .write = btmrvl_psmode_write, | 130 | .write = btmrvl_psmode_write, |
130 | .open = btmrvl_open_generic, | 131 | .open = btmrvl_open_generic, |
131 | }; | 132 | }; |
132 | 133 | ||
133 | static ssize_t btmrvl_pscmd_write(struct file *file, const char __user *ubuf, | 134 | static ssize_t btmrvl_pscmd_write(struct file *file, const char __user *ubuf, |
134 | size_t count, loff_t *ppos) | 135 | size_t count, loff_t *ppos) |
135 | { | 136 | { |
136 | struct btmrvl_private *priv = file->private_data; | 137 | struct btmrvl_private *priv = file->private_data; |
137 | char buf[16]; | 138 | char buf[16]; |
138 | long result, ret; | 139 | long result, ret; |
139 | 140 | ||
140 | memset(buf, 0, sizeof(buf)); | 141 | memset(buf, 0, sizeof(buf)); |
141 | 142 | ||
142 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | 143 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) |
143 | return -EFAULT; | 144 | return -EFAULT; |
144 | 145 | ||
145 | ret = strict_strtol(buf, 10, &result); | 146 | ret = strict_strtol(buf, 10, &result); |
146 | 147 | ||
147 | priv->btmrvl_dev.pscmd = result; | 148 | priv->btmrvl_dev.pscmd = result; |
148 | 149 | ||
149 | if (priv->btmrvl_dev.pscmd) { | 150 | if (priv->btmrvl_dev.pscmd) { |
150 | btmrvl_prepare_command(priv); | 151 | btmrvl_prepare_command(priv); |
151 | wake_up_interruptible(&priv->main_thread.wait_q); | 152 | wake_up_interruptible(&priv->main_thread.wait_q); |
152 | } | 153 | } |
153 | 154 | ||
154 | return count; | 155 | return count; |
155 | 156 | ||
156 | } | 157 | } |
157 | 158 | ||
158 | static ssize_t btmrvl_pscmd_read(struct file *file, char __user *userbuf, | 159 | static ssize_t btmrvl_pscmd_read(struct file *file, char __user *userbuf, |
159 | size_t count, loff_t *ppos) | 160 | size_t count, loff_t *ppos) |
160 | { | 161 | { |
161 | struct btmrvl_private *priv = file->private_data; | 162 | struct btmrvl_private *priv = file->private_data; |
162 | char buf[16]; | 163 | char buf[16]; |
163 | int ret; | 164 | int ret; |
164 | 165 | ||
165 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->btmrvl_dev.pscmd); | 166 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->btmrvl_dev.pscmd); |
166 | 167 | ||
167 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); | 168 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); |
168 | } | 169 | } |
169 | 170 | ||
170 | static const struct file_operations btmrvl_pscmd_fops = { | 171 | static const struct file_operations btmrvl_pscmd_fops = { |
171 | .read = btmrvl_pscmd_read, | 172 | .read = btmrvl_pscmd_read, |
172 | .write = btmrvl_pscmd_write, | 173 | .write = btmrvl_pscmd_write, |
173 | .open = btmrvl_open_generic, | 174 | .open = btmrvl_open_generic, |
174 | }; | 175 | }; |
175 | 176 | ||
176 | static ssize_t btmrvl_gpiogap_write(struct file *file, const char __user *ubuf, | 177 | static ssize_t btmrvl_gpiogap_write(struct file *file, const char __user *ubuf, |
177 | size_t count, loff_t *ppos) | 178 | size_t count, loff_t *ppos) |
178 | { | 179 | { |
179 | struct btmrvl_private *priv = file->private_data; | 180 | struct btmrvl_private *priv = file->private_data; |
180 | char buf[16]; | 181 | char buf[16]; |
181 | long result, ret; | 182 | long result, ret; |
182 | 183 | ||
183 | memset(buf, 0, sizeof(buf)); | 184 | memset(buf, 0, sizeof(buf)); |
184 | 185 | ||
185 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | 186 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) |
186 | return -EFAULT; | 187 | return -EFAULT; |
187 | 188 | ||
188 | ret = strict_strtol(buf, 16, &result); | 189 | ret = strict_strtol(buf, 16, &result); |
189 | 190 | ||
190 | priv->btmrvl_dev.gpio_gap = result; | 191 | priv->btmrvl_dev.gpio_gap = result; |
191 | 192 | ||
192 | return count; | 193 | return count; |
193 | } | 194 | } |
194 | 195 | ||
195 | static ssize_t btmrvl_gpiogap_read(struct file *file, char __user *userbuf, | 196 | static ssize_t btmrvl_gpiogap_read(struct file *file, char __user *userbuf, |
196 | size_t count, loff_t *ppos) | 197 | size_t count, loff_t *ppos) |
197 | { | 198 | { |
198 | struct btmrvl_private *priv = file->private_data; | 199 | struct btmrvl_private *priv = file->private_data; |
199 | char buf[16]; | 200 | char buf[16]; |
200 | int ret; | 201 | int ret; |
201 | 202 | ||
202 | ret = snprintf(buf, sizeof(buf) - 1, "0x%x\n", | 203 | ret = snprintf(buf, sizeof(buf) - 1, "0x%x\n", |
203 | priv->btmrvl_dev.gpio_gap); | 204 | priv->btmrvl_dev.gpio_gap); |
204 | 205 | ||
205 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); | 206 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); |
206 | } | 207 | } |
207 | 208 | ||
208 | static const struct file_operations btmrvl_gpiogap_fops = { | 209 | static const struct file_operations btmrvl_gpiogap_fops = { |
209 | .read = btmrvl_gpiogap_read, | 210 | .read = btmrvl_gpiogap_read, |
210 | .write = btmrvl_gpiogap_write, | 211 | .write = btmrvl_gpiogap_write, |
211 | .open = btmrvl_open_generic, | 212 | .open = btmrvl_open_generic, |
212 | }; | 213 | }; |
213 | 214 | ||
214 | static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf, | 215 | static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf, |
215 | size_t count, loff_t *ppos) | 216 | size_t count, loff_t *ppos) |
216 | { | 217 | { |
217 | struct btmrvl_private *priv = (struct btmrvl_private *) file->private_data; | 218 | struct btmrvl_private *priv = (struct btmrvl_private *) file->private_data; |
218 | char buf[16]; | 219 | char buf[16]; |
219 | long result, ret; | 220 | long result, ret; |
220 | 221 | ||
221 | memset(buf, 0, sizeof(buf)); | 222 | memset(buf, 0, sizeof(buf)); |
222 | 223 | ||
223 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | 224 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) |
224 | return -EFAULT; | 225 | return -EFAULT; |
225 | 226 | ||
226 | ret = strict_strtol(buf, 10, &result); | 227 | ret = strict_strtol(buf, 10, &result); |
227 | 228 | ||
228 | priv->btmrvl_dev.hscmd = result; | 229 | priv->btmrvl_dev.hscmd = result; |
229 | if (priv->btmrvl_dev.hscmd) { | 230 | if (priv->btmrvl_dev.hscmd) { |
230 | btmrvl_prepare_command(priv); | 231 | btmrvl_prepare_command(priv); |
231 | wake_up_interruptible(&priv->main_thread.wait_q); | 232 | wake_up_interruptible(&priv->main_thread.wait_q); |
232 | } | 233 | } |
233 | 234 | ||
234 | return count; | 235 | return count; |
235 | } | 236 | } |
236 | 237 | ||
237 | static ssize_t btmrvl_hscmd_read(struct file *file, char __user *userbuf, | 238 | static ssize_t btmrvl_hscmd_read(struct file *file, char __user *userbuf, |
238 | size_t count, loff_t *ppos) | 239 | size_t count, loff_t *ppos) |
239 | { | 240 | { |
240 | struct btmrvl_private *priv = file->private_data; | 241 | struct btmrvl_private *priv = file->private_data; |
241 | char buf[16]; | 242 | char buf[16]; |
242 | int ret; | 243 | int ret; |
243 | 244 | ||
244 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->btmrvl_dev.hscmd); | 245 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->btmrvl_dev.hscmd); |
245 | 246 | ||
246 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); | 247 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); |
247 | } | 248 | } |
248 | 249 | ||
249 | static const struct file_operations btmrvl_hscmd_fops = { | 250 | static const struct file_operations btmrvl_hscmd_fops = { |
250 | .read = btmrvl_hscmd_read, | 251 | .read = btmrvl_hscmd_read, |
251 | .write = btmrvl_hscmd_write, | 252 | .write = btmrvl_hscmd_write, |
252 | .open = btmrvl_open_generic, | 253 | .open = btmrvl_open_generic, |
253 | }; | 254 | }; |
254 | 255 | ||
255 | static ssize_t btmrvl_hsmode_write(struct file *file, const char __user *ubuf, | 256 | static ssize_t btmrvl_hsmode_write(struct file *file, const char __user *ubuf, |
256 | size_t count, loff_t *ppos) | 257 | size_t count, loff_t *ppos) |
257 | { | 258 | { |
258 | struct btmrvl_private *priv = file->private_data; | 259 | struct btmrvl_private *priv = file->private_data; |
259 | char buf[16]; | 260 | char buf[16]; |
260 | long result, ret; | 261 | long result, ret; |
261 | 262 | ||
262 | memset(buf, 0, sizeof(buf)); | 263 | memset(buf, 0, sizeof(buf)); |
263 | 264 | ||
264 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | 265 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) |
265 | return -EFAULT; | 266 | return -EFAULT; |
266 | 267 | ||
267 | ret = strict_strtol(buf, 10, &result); | 268 | ret = strict_strtol(buf, 10, &result); |
268 | 269 | ||
269 | priv->btmrvl_dev.hsmode = result; | 270 | priv->btmrvl_dev.hsmode = result; |
270 | 271 | ||
271 | return count; | 272 | return count; |
272 | } | 273 | } |
273 | 274 | ||
274 | static ssize_t btmrvl_hsmode_read(struct file *file, char __user * userbuf, | 275 | static ssize_t btmrvl_hsmode_read(struct file *file, char __user * userbuf, |
275 | size_t count, loff_t *ppos) | 276 | size_t count, loff_t *ppos) |
276 | { | 277 | { |
277 | struct btmrvl_private *priv = file->private_data; | 278 | struct btmrvl_private *priv = file->private_data; |
278 | char buf[16]; | 279 | char buf[16]; |
279 | int ret; | 280 | int ret; |
280 | 281 | ||
281 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->btmrvl_dev.hsmode); | 282 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->btmrvl_dev.hsmode); |
282 | 283 | ||
283 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); | 284 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); |
284 | } | 285 | } |
285 | 286 | ||
286 | static const struct file_operations btmrvl_hsmode_fops = { | 287 | static const struct file_operations btmrvl_hsmode_fops = { |
287 | .read = btmrvl_hsmode_read, | 288 | .read = btmrvl_hsmode_read, |
288 | .write = btmrvl_hsmode_write, | 289 | .write = btmrvl_hsmode_write, |
289 | .open = btmrvl_open_generic, | 290 | .open = btmrvl_open_generic, |
290 | }; | 291 | }; |
291 | 292 | ||
292 | static ssize_t btmrvl_curpsmode_read(struct file *file, char __user *userbuf, | 293 | static ssize_t btmrvl_curpsmode_read(struct file *file, char __user *userbuf, |
293 | size_t count, loff_t *ppos) | 294 | size_t count, loff_t *ppos) |
294 | { | 295 | { |
295 | struct btmrvl_private *priv = file->private_data; | 296 | struct btmrvl_private *priv = file->private_data; |
296 | char buf[16]; | 297 | char buf[16]; |
297 | int ret; | 298 | int ret; |
298 | 299 | ||
299 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->adapter->psmode); | 300 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->adapter->psmode); |
300 | 301 | ||
301 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); | 302 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); |
302 | } | 303 | } |
303 | 304 | ||
304 | static const struct file_operations btmrvl_curpsmode_fops = { | 305 | static const struct file_operations btmrvl_curpsmode_fops = { |
305 | .read = btmrvl_curpsmode_read, | 306 | .read = btmrvl_curpsmode_read, |
306 | .open = btmrvl_open_generic, | 307 | .open = btmrvl_open_generic, |
307 | }; | 308 | }; |
308 | 309 | ||
309 | static ssize_t btmrvl_psstate_read(struct file *file, char __user * userbuf, | 310 | static ssize_t btmrvl_psstate_read(struct file *file, char __user * userbuf, |
310 | size_t count, loff_t *ppos) | 311 | size_t count, loff_t *ppos) |
311 | { | 312 | { |
312 | struct btmrvl_private *priv = file->private_data; | 313 | struct btmrvl_private *priv = file->private_data; |
313 | char buf[16]; | 314 | char buf[16]; |
314 | int ret; | 315 | int ret; |
315 | 316 | ||
316 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->adapter->ps_state); | 317 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->adapter->ps_state); |
317 | 318 | ||
318 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); | 319 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); |
319 | } | 320 | } |
320 | 321 | ||
321 | static const struct file_operations btmrvl_psstate_fops = { | 322 | static const struct file_operations btmrvl_psstate_fops = { |
322 | .read = btmrvl_psstate_read, | 323 | .read = btmrvl_psstate_read, |
323 | .open = btmrvl_open_generic, | 324 | .open = btmrvl_open_generic, |
324 | }; | 325 | }; |
325 | 326 | ||
326 | static ssize_t btmrvl_hsstate_read(struct file *file, char __user *userbuf, | 327 | static ssize_t btmrvl_hsstate_read(struct file *file, char __user *userbuf, |
327 | size_t count, loff_t *ppos) | 328 | size_t count, loff_t *ppos) |
328 | { | 329 | { |
329 | struct btmrvl_private *priv = file->private_data; | 330 | struct btmrvl_private *priv = file->private_data; |
330 | char buf[16]; | 331 | char buf[16]; |
331 | int ret; | 332 | int ret; |
332 | 333 | ||
333 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->adapter->hs_state); | 334 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->adapter->hs_state); |
334 | 335 | ||
335 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); | 336 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); |
336 | } | 337 | } |
337 | 338 | ||
338 | static const struct file_operations btmrvl_hsstate_fops = { | 339 | static const struct file_operations btmrvl_hsstate_fops = { |
339 | .read = btmrvl_hsstate_read, | 340 | .read = btmrvl_hsstate_read, |
340 | .open = btmrvl_open_generic, | 341 | .open = btmrvl_open_generic, |
341 | }; | 342 | }; |
342 | 343 | ||
343 | static ssize_t btmrvl_txdnldready_read(struct file *file, char __user *userbuf, | 344 | static ssize_t btmrvl_txdnldready_read(struct file *file, char __user *userbuf, |
344 | size_t count, loff_t *ppos) | 345 | size_t count, loff_t *ppos) |
345 | { | 346 | { |
346 | struct btmrvl_private *priv = file->private_data; | 347 | struct btmrvl_private *priv = file->private_data; |
347 | char buf[16]; | 348 | char buf[16]; |
348 | int ret; | 349 | int ret; |
349 | 350 | ||
350 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", | 351 | ret = snprintf(buf, sizeof(buf) - 1, "%d\n", |
351 | priv->btmrvl_dev.tx_dnld_rdy); | 352 | priv->btmrvl_dev.tx_dnld_rdy); |
352 | 353 | ||
353 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); | 354 | return simple_read_from_buffer(userbuf, count, ppos, buf, ret); |
354 | } | 355 | } |
355 | 356 | ||
356 | static const struct file_operations btmrvl_txdnldready_fops = { | 357 | static const struct file_operations btmrvl_txdnldready_fops = { |
357 | .read = btmrvl_txdnldready_read, | 358 | .read = btmrvl_txdnldready_read, |
358 | .open = btmrvl_open_generic, | 359 | .open = btmrvl_open_generic, |
359 | }; | 360 | }; |
360 | 361 | ||
361 | void btmrvl_debugfs_init(struct hci_dev *hdev) | 362 | void btmrvl_debugfs_init(struct hci_dev *hdev) |
362 | { | 363 | { |
363 | struct btmrvl_private *priv = hdev->driver_data; | 364 | struct btmrvl_private *priv = hdev->driver_data; |
364 | struct btmrvl_debugfs_data *dbg; | 365 | struct btmrvl_debugfs_data *dbg; |
365 | 366 | ||
367 | if (!hdev->debugfs) | ||
368 | return; | ||
369 | |||
366 | dbg = kzalloc(sizeof(*dbg), GFP_KERNEL); | 370 | dbg = kzalloc(sizeof(*dbg), GFP_KERNEL); |
367 | priv->debugfs_data = dbg; | 371 | priv->debugfs_data = dbg; |
368 | 372 | ||
369 | if (!dbg) { | 373 | if (!dbg) { |
370 | BT_ERR("Can not allocate memory for btmrvl_debugfs_data."); | 374 | BT_ERR("Can not allocate memory for btmrvl_debugfs_data."); |
371 | return; | 375 | return; |
372 | } | 376 | } |
373 | 377 | ||
374 | dbg->root_dir = debugfs_create_dir("btmrvl", NULL); | 378 | dbg->config_dir = debugfs_create_dir("config", hdev->debugfs); |
375 | 379 | ||
376 | dbg->config_dir = debugfs_create_dir("config", dbg->root_dir); | ||
377 | |||
378 | dbg->psmode = debugfs_create_file("psmode", 0644, dbg->config_dir, | 380 | dbg->psmode = debugfs_create_file("psmode", 0644, dbg->config_dir, |
379 | hdev->driver_data, &btmrvl_psmode_fops); | 381 | hdev->driver_data, &btmrvl_psmode_fops); |
380 | dbg->pscmd = debugfs_create_file("pscmd", 0644, dbg->config_dir, | 382 | dbg->pscmd = debugfs_create_file("pscmd", 0644, dbg->config_dir, |
381 | hdev->driver_data, &btmrvl_pscmd_fops); | 383 | hdev->driver_data, &btmrvl_pscmd_fops); |
382 | dbg->gpiogap = debugfs_create_file("gpiogap", 0644, dbg->config_dir, | 384 | dbg->gpiogap = debugfs_create_file("gpiogap", 0644, dbg->config_dir, |
383 | hdev->driver_data, &btmrvl_gpiogap_fops); | 385 | hdev->driver_data, &btmrvl_gpiogap_fops); |
384 | dbg->hsmode = debugfs_create_file("hsmode", 0644, dbg->config_dir, | 386 | dbg->hsmode = debugfs_create_file("hsmode", 0644, dbg->config_dir, |
385 | hdev->driver_data, &btmrvl_hsmode_fops); | 387 | hdev->driver_data, &btmrvl_hsmode_fops); |
386 | dbg->hscmd = debugfs_create_file("hscmd", 0644, dbg->config_dir, | 388 | dbg->hscmd = debugfs_create_file("hscmd", 0644, dbg->config_dir, |
387 | hdev->driver_data, &btmrvl_hscmd_fops); | 389 | hdev->driver_data, &btmrvl_hscmd_fops); |
388 | dbg->hscfgcmd = debugfs_create_file("hscfgcmd", 0644, dbg->config_dir, | 390 | dbg->hscfgcmd = debugfs_create_file("hscfgcmd", 0644, dbg->config_dir, |
389 | hdev->driver_data, &btmrvl_hscfgcmd_fops); | 391 | hdev->driver_data, &btmrvl_hscfgcmd_fops); |
390 | 392 | ||
391 | dbg->status_dir = debugfs_create_dir("status", dbg->root_dir); | 393 | dbg->status_dir = debugfs_create_dir("status", hdev->debugfs); |
392 | dbg->curpsmode = debugfs_create_file("curpsmode", 0444, | 394 | dbg->curpsmode = debugfs_create_file("curpsmode", 0444, |
393 | dbg->status_dir, | 395 | dbg->status_dir, |
394 | hdev->driver_data, | 396 | hdev->driver_data, |
395 | &btmrvl_curpsmode_fops); | 397 | &btmrvl_curpsmode_fops); |
396 | dbg->psstate = debugfs_create_file("psstate", 0444, dbg->status_dir, | 398 | dbg->psstate = debugfs_create_file("psstate", 0444, dbg->status_dir, |
397 | hdev->driver_data, &btmrvl_psstate_fops); | 399 | hdev->driver_data, &btmrvl_psstate_fops); |
398 | dbg->hsstate = debugfs_create_file("hsstate", 0444, dbg->status_dir, | 400 | dbg->hsstate = debugfs_create_file("hsstate", 0444, dbg->status_dir, |
399 | hdev->driver_data, &btmrvl_hsstate_fops); | 401 | hdev->driver_data, &btmrvl_hsstate_fops); |
400 | dbg->txdnldready = debugfs_create_file("txdnldready", 0444, | 402 | dbg->txdnldready = debugfs_create_file("txdnldready", 0444, |
401 | dbg->status_dir, | 403 | dbg->status_dir, |
402 | hdev->driver_data, | 404 | hdev->driver_data, |
403 | &btmrvl_txdnldready_fops); | 405 | &btmrvl_txdnldready_fops); |
404 | } | 406 | } |
405 | 407 | ||
406 | void btmrvl_debugfs_remove(struct hci_dev *hdev) | 408 | void btmrvl_debugfs_remove(struct hci_dev *hdev) |
407 | { | 409 | { |
408 | struct btmrvl_private *priv = hdev->driver_data; | 410 | struct btmrvl_private *priv = hdev->driver_data; |
409 | struct btmrvl_debugfs_data *dbg = priv->debugfs_data; | 411 | struct btmrvl_debugfs_data *dbg = priv->debugfs_data; |
410 | 412 | ||
411 | if (!dbg) | 413 | if (!dbg) |
412 | return; | 414 | return; |
413 | 415 | ||
414 | debugfs_remove(dbg->psmode); | 416 | debugfs_remove(dbg->psmode); |
415 | debugfs_remove(dbg->pscmd); | 417 | debugfs_remove(dbg->pscmd); |
416 | debugfs_remove(dbg->gpiogap); | 418 | debugfs_remove(dbg->gpiogap); |
417 | debugfs_remove(dbg->hsmode); | 419 | debugfs_remove(dbg->hsmode); |
418 | debugfs_remove(dbg->hscmd); | 420 | debugfs_remove(dbg->hscmd); |
419 | debugfs_remove(dbg->hscfgcmd); | 421 | debugfs_remove(dbg->hscfgcmd); |
420 | debugfs_remove(dbg->config_dir); | 422 | debugfs_remove(dbg->config_dir); |
421 | 423 | ||
422 | debugfs_remove(dbg->curpsmode); | 424 | debugfs_remove(dbg->curpsmode); |
423 | debugfs_remove(dbg->psstate); | 425 | debugfs_remove(dbg->psstate); |
424 | debugfs_remove(dbg->hsstate); | 426 | debugfs_remove(dbg->hsstate); |
425 | debugfs_remove(dbg->txdnldready); | 427 | debugfs_remove(dbg->txdnldready); |
426 | debugfs_remove(dbg->status_dir); | 428 | debugfs_remove(dbg->status_dir); |
427 | |||
428 | debugfs_remove(dbg->root_dir); |