xref: /linux/drivers/media/common/siano/smsdvb-debugfs.c (revision ca55b2fef3a9373fcfc30f82fd26bc7fccbda732)
1 /***********************************************************************
2  *
3  * Copyright(c) 2013 Mauro Carvalho Chehab
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 2 of the License, or
8  * (at your option) any later version.
9 
10  *  This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  ***********************************************************************/
19 
20 #include "smscoreapi.h"
21 
22 #include <linux/module.h>
23 #include <linux/slab.h>
24 #include <linux/init.h>
25 #include <linux/debugfs.h>
26 #include <linux/spinlock.h>
27 #include <linux/usb.h>
28 
29 #include "dmxdev.h"
30 #include "dvbdev.h"
31 #include "dvb_demux.h"
32 #include "dvb_frontend.h"
33 
34 #include "smsdvb.h"
35 
36 static struct dentry *smsdvb_debugfs_usb_root;
37 
38 struct smsdvb_debugfs {
39 	struct kref		refcount;
40 	spinlock_t		lock;
41 
42 	char			stats_data[PAGE_SIZE];
43 	unsigned		stats_count;
44 	bool			stats_was_read;
45 
46 	wait_queue_head_t	stats_queue;
47 };
48 
49 static void smsdvb_print_dvb_stats(struct smsdvb_debugfs *debug_data,
50 			    struct sms_stats *p)
51 {
52 	int n = 0;
53 	char *buf;
54 
55 	spin_lock(&debug_data->lock);
56 	if (debug_data->stats_count) {
57 		spin_unlock(&debug_data->lock);
58 		return;
59 	}
60 
61 	buf = debug_data->stats_data;
62 
63 	n += snprintf(&buf[n], PAGE_SIZE - n,
64 		      "is_rf_locked = %d\n", p->is_rf_locked);
65 	n += snprintf(&buf[n], PAGE_SIZE - n,
66 		      "is_demod_locked = %d\n", p->is_demod_locked);
67 	n += snprintf(&buf[n], PAGE_SIZE - n,
68 		      "is_external_lna_on = %d\n", p->is_external_lna_on);
69 	n += snprintf(&buf[n], PAGE_SIZE - n,
70 		      "SNR = %d\n", p->SNR);
71 	n += snprintf(&buf[n], PAGE_SIZE - n,
72 		      "ber = %d\n", p->ber);
73 	n += snprintf(&buf[n], PAGE_SIZE - n,
74 		      "FIB_CRC = %d\n", p->FIB_CRC);
75 	n += snprintf(&buf[n], PAGE_SIZE - n,
76 		      "ts_per = %d\n", p->ts_per);
77 	n += snprintf(&buf[n], PAGE_SIZE - n,
78 		      "MFER = %d\n", p->MFER);
79 	n += snprintf(&buf[n], PAGE_SIZE - n,
80 		      "RSSI = %d\n", p->RSSI);
81 	n += snprintf(&buf[n], PAGE_SIZE - n,
82 		      "in_band_pwr = %d\n", p->in_band_pwr);
83 	n += snprintf(&buf[n], PAGE_SIZE - n,
84 		      "carrier_offset = %d\n", p->carrier_offset);
85 	n += snprintf(&buf[n], PAGE_SIZE - n,
86 		      "modem_state = %d\n", p->modem_state);
87 	n += snprintf(&buf[n], PAGE_SIZE - n,
88 		      "frequency = %d\n", p->frequency);
89 	n += snprintf(&buf[n], PAGE_SIZE - n,
90 		      "bandwidth = %d\n", p->bandwidth);
91 	n += snprintf(&buf[n], PAGE_SIZE - n,
92 		      "transmission_mode = %d\n", p->transmission_mode);
93 	n += snprintf(&buf[n], PAGE_SIZE - n,
94 		      "modem_state = %d\n", p->modem_state);
95 	n += snprintf(&buf[n], PAGE_SIZE - n,
96 		      "guard_interval = %d\n", p->guard_interval);
97 	n += snprintf(&buf[n], PAGE_SIZE - n,
98 		      "code_rate = %d\n", p->code_rate);
99 	n += snprintf(&buf[n], PAGE_SIZE - n,
100 		      "lp_code_rate = %d\n", p->lp_code_rate);
101 	n += snprintf(&buf[n], PAGE_SIZE - n,
102 		      "hierarchy = %d\n", p->hierarchy);
103 	n += snprintf(&buf[n], PAGE_SIZE - n,
104 		      "constellation = %d\n", p->constellation);
105 	n += snprintf(&buf[n], PAGE_SIZE - n,
106 		      "burst_size = %d\n", p->burst_size);
107 	n += snprintf(&buf[n], PAGE_SIZE - n,
108 		      "burst_duration = %d\n", p->burst_duration);
109 	n += snprintf(&buf[n], PAGE_SIZE - n,
110 		      "burst_cycle_time = %d\n", p->burst_cycle_time);
111 	n += snprintf(&buf[n], PAGE_SIZE - n,
112 		      "calc_burst_cycle_time = %d\n",
113 		      p->calc_burst_cycle_time);
114 	n += snprintf(&buf[n], PAGE_SIZE - n,
115 		      "num_of_rows = %d\n", p->num_of_rows);
116 	n += snprintf(&buf[n], PAGE_SIZE - n,
117 		      "num_of_padd_cols = %d\n", p->num_of_padd_cols);
118 	n += snprintf(&buf[n], PAGE_SIZE - n,
119 		      "num_of_punct_cols = %d\n", p->num_of_punct_cols);
120 	n += snprintf(&buf[n], PAGE_SIZE - n,
121 		      "error_ts_packets = %d\n", p->error_ts_packets);
122 	n += snprintf(&buf[n], PAGE_SIZE - n,
123 		      "total_ts_packets = %d\n", p->total_ts_packets);
124 	n += snprintf(&buf[n], PAGE_SIZE - n,
125 		      "num_of_valid_mpe_tlbs = %d\n", p->num_of_valid_mpe_tlbs);
126 	n += snprintf(&buf[n], PAGE_SIZE - n,
127 		      "num_of_invalid_mpe_tlbs = %d\n", p->num_of_invalid_mpe_tlbs);
128 	n += snprintf(&buf[n], PAGE_SIZE - n,
129 		      "num_of_corrected_mpe_tlbs = %d\n", p->num_of_corrected_mpe_tlbs);
130 	n += snprintf(&buf[n], PAGE_SIZE - n,
131 		      "ber_error_count = %d\n", p->ber_error_count);
132 	n += snprintf(&buf[n], PAGE_SIZE - n,
133 		      "ber_bit_count = %d\n", p->ber_bit_count);
134 	n += snprintf(&buf[n], PAGE_SIZE - n,
135 		      "sms_to_host_tx_errors = %d\n", p->sms_to_host_tx_errors);
136 	n += snprintf(&buf[n], PAGE_SIZE - n,
137 		      "pre_ber = %d\n", p->pre_ber);
138 	n += snprintf(&buf[n], PAGE_SIZE - n,
139 		      "cell_id = %d\n", p->cell_id);
140 	n += snprintf(&buf[n], PAGE_SIZE - n,
141 		      "dvbh_srv_ind_hp = %d\n", p->dvbh_srv_ind_hp);
142 	n += snprintf(&buf[n], PAGE_SIZE - n,
143 		      "dvbh_srv_ind_lp = %d\n", p->dvbh_srv_ind_lp);
144 	n += snprintf(&buf[n], PAGE_SIZE - n,
145 		      "num_mpe_received = %d\n", p->num_mpe_received);
146 
147 	debug_data->stats_count = n;
148 	spin_unlock(&debug_data->lock);
149 	wake_up(&debug_data->stats_queue);
150 }
151 
152 static void smsdvb_print_isdb_stats(struct smsdvb_debugfs *debug_data,
153 			     struct sms_isdbt_stats *p)
154 {
155 	int i, n = 0;
156 	char *buf;
157 
158 	spin_lock(&debug_data->lock);
159 	if (debug_data->stats_count) {
160 		spin_unlock(&debug_data->lock);
161 		return;
162 	}
163 
164 	buf = debug_data->stats_data;
165 
166 	n += snprintf(&buf[n], PAGE_SIZE - n,
167 		      "statistics_type = %d\t", p->statistics_type);
168 	n += snprintf(&buf[n], PAGE_SIZE - n,
169 		      "full_size = %d\n", p->full_size);
170 
171 	n += snprintf(&buf[n], PAGE_SIZE - n,
172 		      "is_rf_locked = %d\t\t", p->is_rf_locked);
173 	n += snprintf(&buf[n], PAGE_SIZE - n,
174 		      "is_demod_locked = %d\t", p->is_demod_locked);
175 	n += snprintf(&buf[n], PAGE_SIZE - n,
176 		      "is_external_lna_on = %d\n", p->is_external_lna_on);
177 	n += snprintf(&buf[n], PAGE_SIZE - n,
178 		      "SNR = %d dB\t\t", p->SNR);
179 	n += snprintf(&buf[n], PAGE_SIZE - n,
180 		      "RSSI = %d dBm\t\t", p->RSSI);
181 	n += snprintf(&buf[n], PAGE_SIZE - n,
182 		      "in_band_pwr = %d dBm\n", p->in_band_pwr);
183 	n += snprintf(&buf[n], PAGE_SIZE - n,
184 		      "carrier_offset = %d\t", p->carrier_offset);
185 	n += snprintf(&buf[n], PAGE_SIZE - n,
186 		      "bandwidth = %d\t\t", p->bandwidth);
187 	n += snprintf(&buf[n], PAGE_SIZE - n,
188 		      "frequency = %d Hz\n", p->frequency);
189 	n += snprintf(&buf[n], PAGE_SIZE - n,
190 		      "transmission_mode = %d\t", p->transmission_mode);
191 	n += snprintf(&buf[n], PAGE_SIZE - n,
192 		      "modem_state = %d\t\t", p->modem_state);
193 	n += snprintf(&buf[n], PAGE_SIZE - n,
194 		      "guard_interval = %d\n", p->guard_interval);
195 	n += snprintf(&buf[n], PAGE_SIZE - n,
196 		      "system_type = %d\t\t", p->system_type);
197 	n += snprintf(&buf[n], PAGE_SIZE - n,
198 		      "partial_reception = %d\t", p->partial_reception);
199 	n += snprintf(&buf[n], PAGE_SIZE - n,
200 		      "num_of_layers = %d\n", p->num_of_layers);
201 	n += snprintf(&buf[n], PAGE_SIZE - n,
202 		      "sms_to_host_tx_errors = %d\n", p->sms_to_host_tx_errors);
203 
204 	for (i = 0; i < 3; i++) {
205 		if (p->layer_info[i].number_of_segments < 1 ||
206 		    p->layer_info[i].number_of_segments > 13)
207 			continue;
208 
209 		n += snprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i);
210 		n += snprintf(&buf[n], PAGE_SIZE - n, "\tcode_rate = %d\t",
211 			      p->layer_info[i].code_rate);
212 		n += snprintf(&buf[n], PAGE_SIZE - n, "constellation = %d\n",
213 			      p->layer_info[i].constellation);
214 		n += snprintf(&buf[n], PAGE_SIZE - n, "\tber = %-5d\t",
215 			      p->layer_info[i].ber);
216 		n += snprintf(&buf[n], PAGE_SIZE - n, "\tber_error_count = %-5d\t",
217 			      p->layer_info[i].ber_error_count);
218 		n += snprintf(&buf[n], PAGE_SIZE - n, "ber_bit_count = %-5d\n",
219 			      p->layer_info[i].ber_bit_count);
220 		n += snprintf(&buf[n], PAGE_SIZE - n, "\tpre_ber = %-5d\t",
221 			      p->layer_info[i].pre_ber);
222 		n += snprintf(&buf[n], PAGE_SIZE - n, "\tts_per = %-5d\n",
223 			      p->layer_info[i].ts_per);
224 		n += snprintf(&buf[n], PAGE_SIZE - n, "\terror_ts_packets = %-5d\t",
225 			      p->layer_info[i].error_ts_packets);
226 		n += snprintf(&buf[n], PAGE_SIZE - n, "total_ts_packets = %-5d\t",
227 			      p->layer_info[i].total_ts_packets);
228 		n += snprintf(&buf[n], PAGE_SIZE - n, "ti_ldepth_i = %d\n",
229 			      p->layer_info[i].ti_ldepth_i);
230 		n += snprintf(&buf[n], PAGE_SIZE - n,
231 			      "\tnumber_of_segments = %d\t",
232 			      p->layer_info[i].number_of_segments);
233 		n += snprintf(&buf[n], PAGE_SIZE - n, "tmcc_errors = %d\n",
234 			      p->layer_info[i].tmcc_errors);
235 	}
236 
237 	debug_data->stats_count = n;
238 	spin_unlock(&debug_data->lock);
239 	wake_up(&debug_data->stats_queue);
240 }
241 
242 static void smsdvb_print_isdb_stats_ex(struct smsdvb_debugfs *debug_data,
243 				struct sms_isdbt_stats_ex *p)
244 {
245 	int i, n = 0;
246 	char *buf;
247 
248 	spin_lock(&debug_data->lock);
249 	if (debug_data->stats_count) {
250 		spin_unlock(&debug_data->lock);
251 		return;
252 	}
253 
254 	buf = debug_data->stats_data;
255 
256 	n += snprintf(&buf[n], PAGE_SIZE - n,
257 		      "statistics_type = %d\t", p->statistics_type);
258 	n += snprintf(&buf[n], PAGE_SIZE - n,
259 		      "full_size = %d\n", p->full_size);
260 
261 	n += snprintf(&buf[n], PAGE_SIZE - n,
262 		      "is_rf_locked = %d\t\t", p->is_rf_locked);
263 	n += snprintf(&buf[n], PAGE_SIZE - n,
264 		      "is_demod_locked = %d\t", p->is_demod_locked);
265 	n += snprintf(&buf[n], PAGE_SIZE - n,
266 		      "is_external_lna_on = %d\n", p->is_external_lna_on);
267 	n += snprintf(&buf[n], PAGE_SIZE - n,
268 		      "SNR = %d dB\t\t", p->SNR);
269 	n += snprintf(&buf[n], PAGE_SIZE - n,
270 		      "RSSI = %d dBm\t\t", p->RSSI);
271 	n += snprintf(&buf[n], PAGE_SIZE - n,
272 		      "in_band_pwr = %d dBm\n", p->in_band_pwr);
273 	n += snprintf(&buf[n], PAGE_SIZE - n,
274 		      "carrier_offset = %d\t", p->carrier_offset);
275 	n += snprintf(&buf[n], PAGE_SIZE - n,
276 		      "bandwidth = %d\t\t", p->bandwidth);
277 	n += snprintf(&buf[n], PAGE_SIZE - n,
278 		      "frequency = %d Hz\n", p->frequency);
279 	n += snprintf(&buf[n], PAGE_SIZE - n,
280 		      "transmission_mode = %d\t", p->transmission_mode);
281 	n += snprintf(&buf[n], PAGE_SIZE - n,
282 		      "modem_state = %d\t\t", p->modem_state);
283 	n += snprintf(&buf[n], PAGE_SIZE - n,
284 		      "guard_interval = %d\n", p->guard_interval);
285 	n += snprintf(&buf[n], PAGE_SIZE - n,
286 		      "system_type = %d\t\t", p->system_type);
287 	n += snprintf(&buf[n], PAGE_SIZE - n,
288 		      "partial_reception = %d\t", p->partial_reception);
289 	n += snprintf(&buf[n], PAGE_SIZE - n,
290 		      "num_of_layers = %d\n", p->num_of_layers);
291 	n += snprintf(&buf[n], PAGE_SIZE - n, "segment_number = %d\t",
292 		      p->segment_number);
293 	n += snprintf(&buf[n], PAGE_SIZE - n, "tune_bw = %d\n",
294 		      p->tune_bw);
295 
296 	for (i = 0; i < 3; i++) {
297 		if (p->layer_info[i].number_of_segments < 1 ||
298 		    p->layer_info[i].number_of_segments > 13)
299 			continue;
300 
301 		n += snprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i);
302 		n += snprintf(&buf[n], PAGE_SIZE - n, "\tcode_rate = %d\t",
303 			      p->layer_info[i].code_rate);
304 		n += snprintf(&buf[n], PAGE_SIZE - n, "constellation = %d\n",
305 			      p->layer_info[i].constellation);
306 		n += snprintf(&buf[n], PAGE_SIZE - n, "\tber = %-5d\t",
307 			      p->layer_info[i].ber);
308 		n += snprintf(&buf[n], PAGE_SIZE - n, "\tber_error_count = %-5d\t",
309 			      p->layer_info[i].ber_error_count);
310 		n += snprintf(&buf[n], PAGE_SIZE - n, "ber_bit_count = %-5d\n",
311 			      p->layer_info[i].ber_bit_count);
312 		n += snprintf(&buf[n], PAGE_SIZE - n, "\tpre_ber = %-5d\t",
313 			      p->layer_info[i].pre_ber);
314 		n += snprintf(&buf[n], PAGE_SIZE - n, "\tts_per = %-5d\n",
315 			      p->layer_info[i].ts_per);
316 		n += snprintf(&buf[n], PAGE_SIZE - n, "\terror_ts_packets = %-5d\t",
317 			      p->layer_info[i].error_ts_packets);
318 		n += snprintf(&buf[n], PAGE_SIZE - n, "total_ts_packets = %-5d\t",
319 			      p->layer_info[i].total_ts_packets);
320 		n += snprintf(&buf[n], PAGE_SIZE - n, "ti_ldepth_i = %d\n",
321 			      p->layer_info[i].ti_ldepth_i);
322 		n += snprintf(&buf[n], PAGE_SIZE - n,
323 			      "\tnumber_of_segments = %d\t",
324 			      p->layer_info[i].number_of_segments);
325 		n += snprintf(&buf[n], PAGE_SIZE - n, "tmcc_errors = %d\n",
326 			      p->layer_info[i].tmcc_errors);
327 	}
328 
329 
330 	debug_data->stats_count = n;
331 	spin_unlock(&debug_data->lock);
332 
333 	wake_up(&debug_data->stats_queue);
334 }
335 
336 static int smsdvb_stats_open(struct inode *inode, struct file *file)
337 {
338 	struct smsdvb_client_t *client = inode->i_private;
339 	struct smsdvb_debugfs *debug_data = client->debug_data;
340 
341 	kref_get(&debug_data->refcount);
342 
343 	spin_lock(&debug_data->lock);
344 	debug_data->stats_count = 0;
345 	debug_data->stats_was_read = false;
346 	spin_unlock(&debug_data->lock);
347 
348 	file->private_data = debug_data;
349 
350 	return 0;
351 }
352 
353 static void smsdvb_debugfs_data_release(struct kref *ref)
354 {
355 	struct smsdvb_debugfs *debug_data;
356 
357 	debug_data = container_of(ref, struct smsdvb_debugfs, refcount);
358 	kfree(debug_data);
359 }
360 
361 static int smsdvb_stats_wait_read(struct smsdvb_debugfs *debug_data)
362 {
363 	int rc = 1;
364 
365 	spin_lock(&debug_data->lock);
366 
367 	if (debug_data->stats_was_read)
368 		goto exit;
369 
370 	rc = debug_data->stats_count;
371 
372 exit:
373 	spin_unlock(&debug_data->lock);
374 	return rc;
375 }
376 
377 static unsigned int smsdvb_stats_poll(struct file *file, poll_table *wait)
378 {
379 	struct smsdvb_debugfs *debug_data = file->private_data;
380 	int rc;
381 
382 	kref_get(&debug_data->refcount);
383 
384 	poll_wait(file, &debug_data->stats_queue, wait);
385 
386 	rc = smsdvb_stats_wait_read(debug_data);
387 	if (rc > 0)
388 		rc = POLLIN | POLLRDNORM;
389 
390 	kref_put(&debug_data->refcount, smsdvb_debugfs_data_release);
391 
392 	return rc;
393 }
394 
395 static ssize_t smsdvb_stats_read(struct file *file, char __user *user_buf,
396 				      size_t nbytes, loff_t *ppos)
397 {
398 	int rc = 0, len;
399 	struct smsdvb_debugfs *debug_data = file->private_data;
400 
401 	kref_get(&debug_data->refcount);
402 
403 	if (file->f_flags & O_NONBLOCK) {
404 		rc = smsdvb_stats_wait_read(debug_data);
405 		if (!rc) {
406 			rc = -EWOULDBLOCK;
407 			goto ret;
408 		}
409 	} else {
410 		rc = wait_event_interruptible(debug_data->stats_queue,
411 				      smsdvb_stats_wait_read(debug_data));
412 		if (rc < 0)
413 			goto ret;
414 	}
415 
416 	if (debug_data->stats_was_read) {
417 		rc = 0;	/* EOF */
418 		goto ret;
419 	}
420 
421 	len = debug_data->stats_count - *ppos;
422 	if (len >= 0)
423 		rc = simple_read_from_buffer(user_buf, nbytes, ppos,
424 					     debug_data->stats_data, len);
425 	else
426 		rc = 0;
427 
428 	if (*ppos >= debug_data->stats_count) {
429 		spin_lock(&debug_data->lock);
430 		debug_data->stats_was_read = true;
431 		spin_unlock(&debug_data->lock);
432 	}
433 ret:
434 	kref_put(&debug_data->refcount, smsdvb_debugfs_data_release);
435 	return rc;
436 }
437 
438 static int smsdvb_stats_release(struct inode *inode, struct file *file)
439 {
440 	struct smsdvb_debugfs *debug_data = file->private_data;
441 
442 	spin_lock(&debug_data->lock);
443 	debug_data->stats_was_read = true;	/* return EOF to read() */
444 	spin_unlock(&debug_data->lock);
445 	wake_up_interruptible_sync(&debug_data->stats_queue);
446 
447 	kref_put(&debug_data->refcount, smsdvb_debugfs_data_release);
448 	file->private_data = NULL;
449 
450 	return 0;
451 }
452 
453 static const struct file_operations debugfs_stats_ops = {
454 	.open = smsdvb_stats_open,
455 	.poll = smsdvb_stats_poll,
456 	.read = smsdvb_stats_read,
457 	.release = smsdvb_stats_release,
458 	.llseek = generic_file_llseek,
459 };
460 
461 /*
462  * Functions used by smsdvb, in order to create the interfaces
463  */
464 
465 int smsdvb_debugfs_create(struct smsdvb_client_t *client)
466 {
467 	struct smscore_device_t *coredev = client->coredev;
468 	struct dentry *d;
469 	struct smsdvb_debugfs *debug_data;
470 
471 	if (!smsdvb_debugfs_usb_root || !coredev->is_usb_device)
472 		return -ENODEV;
473 
474 	client->debugfs = debugfs_create_dir(coredev->devpath,
475 					     smsdvb_debugfs_usb_root);
476 	if (IS_ERR_OR_NULL(client->debugfs)) {
477 		pr_info("Unable to create debugfs %s directory.\n",
478 			coredev->devpath);
479 		return -ENODEV;
480 	}
481 
482 	d = debugfs_create_file("stats", S_IRUGO | S_IWUSR, client->debugfs,
483 				client, &debugfs_stats_ops);
484 	if (!d) {
485 		debugfs_remove(client->debugfs);
486 		return -ENOMEM;
487 	}
488 
489 	debug_data = kzalloc(sizeof(*client->debug_data), GFP_KERNEL);
490 	if (!debug_data)
491 		return -ENOMEM;
492 
493 	client->debug_data        = debug_data;
494 	client->prt_dvb_stats     = smsdvb_print_dvb_stats;
495 	client->prt_isdb_stats    = smsdvb_print_isdb_stats;
496 	client->prt_isdb_stats_ex = smsdvb_print_isdb_stats_ex;
497 
498 	init_waitqueue_head(&debug_data->stats_queue);
499 	spin_lock_init(&debug_data->lock);
500 	kref_init(&debug_data->refcount);
501 
502 	return 0;
503 }
504 
505 void smsdvb_debugfs_release(struct smsdvb_client_t *client)
506 {
507 	if (!client->debugfs)
508 		return;
509 
510 	client->prt_dvb_stats     = NULL;
511 	client->prt_isdb_stats    = NULL;
512 	client->prt_isdb_stats_ex = NULL;
513 
514 	debugfs_remove_recursive(client->debugfs);
515 	kref_put(&client->debug_data->refcount, smsdvb_debugfs_data_release);
516 
517 	client->debug_data = NULL;
518 	client->debugfs = NULL;
519 }
520 
521 int smsdvb_debugfs_register(void)
522 {
523 	struct dentry *d;
524 
525 	/*
526 	 * FIXME: This was written to debug Siano USB devices. So, it creates
527 	 * the debugfs node under <debugfs>/usb.
528 	 * A similar logic would be needed for Siano sdio devices, but, in that
529 	 * case, usb_debug_root is not a good choice.
530 	 *
531 	 * Perhaps the right fix here would be to create another sysfs root
532 	 * node for sdio-based boards, but this may need some logic at sdio
533 	 * subsystem.
534 	 */
535 	d = debugfs_create_dir("smsdvb", usb_debug_root);
536 	if (IS_ERR_OR_NULL(d)) {
537 		pr_err("Couldn't create sysfs node for smsdvb\n");
538 		return PTR_ERR(d);
539 	} else {
540 		smsdvb_debugfs_usb_root = d;
541 	}
542 	return 0;
543 }
544 
545 void smsdvb_debugfs_unregister(void)
546 {
547 	debugfs_remove_recursive(smsdvb_debugfs_usb_root);
548 	smsdvb_debugfs_usb_root = NULL;
549 }
550