xref: /openbmc/linux/drivers/bluetooth/btmrvl_debugfs.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1*99c926ceSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2a86974f7STedd Ho-Jeong An /*
3fb784f05SBing Zhao  * Marvell Bluetooth driver: debugfs related functions
4fb784f05SBing Zhao  *
5fb784f05SBing Zhao  * Copyright (C) 2009, Marvell International Ltd.
6fb784f05SBing Zhao  **/
7fb784f05SBing Zhao 
8fb784f05SBing Zhao #include <linux/debugfs.h>
95a0e3ad6STejun Heo #include <linux/slab.h>
10fb784f05SBing Zhao 
11fb784f05SBing Zhao #include <net/bluetooth/bluetooth.h>
12fb784f05SBing Zhao #include <net/bluetooth/hci_core.h>
13fb784f05SBing Zhao 
14fb784f05SBing Zhao #include "btmrvl_drv.h"
15fb784f05SBing Zhao 
16fb784f05SBing Zhao struct btmrvl_debugfs_data {
17b914a250SMarcel Holtmann 	struct dentry *config_dir;
18b914a250SMarcel Holtmann 	struct dentry *status_dir;
19fb784f05SBing Zhao };
20fb784f05SBing Zhao 
btmrvl_hscfgcmd_write(struct file * file,const char __user * ubuf,size_t count,loff_t * ppos)21fb784f05SBing Zhao static ssize_t btmrvl_hscfgcmd_write(struct file *file,
2254239903SMarcel Holtmann 			const char __user *ubuf, size_t count, loff_t *ppos)
23fb784f05SBing Zhao {
2454239903SMarcel Holtmann 	struct btmrvl_private *priv = file->private_data;
2554239903SMarcel Holtmann 	long result, ret;
26fb784f05SBing Zhao 
27c2e7f5deSAndy Shevchenko 	ret = kstrtol_from_user(ubuf, count, 10, &result);
2826e7acf3SDavid Miller 	if (ret)
2926e7acf3SDavid Miller 		return ret;
30fb784f05SBing Zhao 
31fb784f05SBing Zhao 	priv->btmrvl_dev.hscfgcmd = result;
32fb784f05SBing Zhao 
33fb784f05SBing Zhao 	if (priv->btmrvl_dev.hscfgcmd) {
34fb784f05SBing Zhao 		btmrvl_prepare_command(priv);
35fb784f05SBing Zhao 		wake_up_interruptible(&priv->main_thread.wait_q);
36fb784f05SBing Zhao 	}
37fb784f05SBing Zhao 
38fb784f05SBing Zhao 	return count;
39fb784f05SBing Zhao }
40fb784f05SBing Zhao 
btmrvl_hscfgcmd_read(struct file * file,char __user * userbuf,size_t count,loff_t * ppos)41fb784f05SBing Zhao static ssize_t btmrvl_hscfgcmd_read(struct file *file, char __user *userbuf,
42fb784f05SBing Zhao 						size_t count, loff_t *ppos)
43fb784f05SBing Zhao {
4454239903SMarcel Holtmann 	struct btmrvl_private *priv = file->private_data;
45fb784f05SBing Zhao 	char buf[16];
4654239903SMarcel Holtmann 	int ret;
47fb784f05SBing Zhao 
48fb784f05SBing Zhao 	ret = snprintf(buf, sizeof(buf) - 1, "%d\n",
49fb784f05SBing Zhao 						priv->btmrvl_dev.hscfgcmd);
50fb784f05SBing Zhao 
51fb784f05SBing Zhao 	return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
52fb784f05SBing Zhao }
53fb784f05SBing Zhao 
54fb784f05SBing Zhao static const struct file_operations btmrvl_hscfgcmd_fops = {
55fb784f05SBing Zhao 	.read	= btmrvl_hscfgcmd_read,
56fb784f05SBing Zhao 	.write	= btmrvl_hscfgcmd_write,
57234e3405SStephen Boyd 	.open	= simple_open,
586038f373SArnd Bergmann 	.llseek = default_llseek,
59fb784f05SBing Zhao };
60fb784f05SBing Zhao 
btmrvl_pscmd_write(struct file * file,const char __user * ubuf,size_t count,loff_t * ppos)61fb784f05SBing Zhao static ssize_t btmrvl_pscmd_write(struct file *file, const char __user *ubuf,
62fb784f05SBing Zhao 						size_t count, loff_t *ppos)
63fb784f05SBing Zhao {
6454239903SMarcel Holtmann 	struct btmrvl_private *priv = file->private_data;
6554239903SMarcel Holtmann 	long result, ret;
66fb784f05SBing Zhao 
67c2e7f5deSAndy Shevchenko 	ret = kstrtol_from_user(ubuf, count, 10, &result);
6826e7acf3SDavid Miller 	if (ret)
6926e7acf3SDavid Miller 		return ret;
70fb784f05SBing Zhao 
71fb784f05SBing Zhao 	priv->btmrvl_dev.pscmd = result;
72fb784f05SBing Zhao 
73fb784f05SBing Zhao 	if (priv->btmrvl_dev.pscmd) {
74fb784f05SBing Zhao 		btmrvl_prepare_command(priv);
75fb784f05SBing Zhao 		wake_up_interruptible(&priv->main_thread.wait_q);
76fb784f05SBing Zhao 	}
77fb784f05SBing Zhao 
78fb784f05SBing Zhao 	return count;
79fb784f05SBing Zhao 
80fb784f05SBing Zhao }
81fb784f05SBing Zhao 
btmrvl_pscmd_read(struct file * file,char __user * userbuf,size_t count,loff_t * ppos)82fb784f05SBing Zhao static ssize_t btmrvl_pscmd_read(struct file *file, char __user *userbuf,
83fb784f05SBing Zhao 						size_t count, loff_t *ppos)
84fb784f05SBing Zhao {
8554239903SMarcel Holtmann 	struct btmrvl_private *priv = file->private_data;
86fb784f05SBing Zhao 	char buf[16];
8754239903SMarcel Holtmann 	int ret;
88fb784f05SBing Zhao 
89fb784f05SBing Zhao 	ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->btmrvl_dev.pscmd);
90fb784f05SBing Zhao 
91fb784f05SBing Zhao 	return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
92fb784f05SBing Zhao }
93fb784f05SBing Zhao 
94fb784f05SBing Zhao static const struct file_operations btmrvl_pscmd_fops = {
95fb784f05SBing Zhao 	.read = btmrvl_pscmd_read,
96fb784f05SBing Zhao 	.write = btmrvl_pscmd_write,
97234e3405SStephen Boyd 	.open = simple_open,
986038f373SArnd Bergmann 	.llseek = default_llseek,
99fb784f05SBing Zhao };
100fb784f05SBing Zhao 
btmrvl_hscmd_write(struct file * file,const char __user * ubuf,size_t count,loff_t * ppos)101fb784f05SBing Zhao static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf,
102fb784f05SBing Zhao 						size_t count, loff_t *ppos)
103fb784f05SBing Zhao {
104be60b940SJoe Perches 	struct btmrvl_private *priv = file->private_data;
10554239903SMarcel Holtmann 	long result, ret;
106fb784f05SBing Zhao 
107c2e7f5deSAndy Shevchenko 	ret = kstrtol_from_user(ubuf, count, 10, &result);
10826e7acf3SDavid Miller 	if (ret)
10926e7acf3SDavid Miller 		return ret;
110fb784f05SBing Zhao 
111fb784f05SBing Zhao 	priv->btmrvl_dev.hscmd = result;
112fb784f05SBing Zhao 	if (priv->btmrvl_dev.hscmd) {
113fb784f05SBing Zhao 		btmrvl_prepare_command(priv);
114fb784f05SBing Zhao 		wake_up_interruptible(&priv->main_thread.wait_q);
115fb784f05SBing Zhao 	}
116fb784f05SBing Zhao 
117fb784f05SBing Zhao 	return count;
118fb784f05SBing Zhao }
119fb784f05SBing Zhao 
btmrvl_hscmd_read(struct file * file,char __user * userbuf,size_t count,loff_t * ppos)120fb784f05SBing Zhao static ssize_t btmrvl_hscmd_read(struct file *file, char __user *userbuf,
121fb784f05SBing Zhao 						size_t count, loff_t *ppos)
122fb784f05SBing Zhao {
12354239903SMarcel Holtmann 	struct btmrvl_private *priv = file->private_data;
124fb784f05SBing Zhao 	char buf[16];
12554239903SMarcel Holtmann 	int ret;
126fb784f05SBing Zhao 
127fb784f05SBing Zhao 	ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->btmrvl_dev.hscmd);
128fb784f05SBing Zhao 
129fb784f05SBing Zhao 	return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
130fb784f05SBing Zhao }
131fb784f05SBing Zhao 
132fb784f05SBing Zhao static const struct file_operations btmrvl_hscmd_fops = {
133fb784f05SBing Zhao 	.read	= btmrvl_hscmd_read,
134fb784f05SBing Zhao 	.write	= btmrvl_hscmd_write,
135234e3405SStephen Boyd 	.open	= simple_open,
1366038f373SArnd Bergmann 	.llseek = default_llseek,
137fb784f05SBing Zhao };
138fb784f05SBing Zhao 
btmrvl_debugfs_init(struct hci_dev * hdev)139fb784f05SBing Zhao void btmrvl_debugfs_init(struct hci_dev *hdev)
140fb784f05SBing Zhao {
141155961e8SDavid Herrmann 	struct btmrvl_private *priv = hci_get_drvdata(hdev);
142fb784f05SBing Zhao 	struct btmrvl_debugfs_data *dbg;
143fb784f05SBing Zhao 
144b914a250SMarcel Holtmann 	if (!hdev->debugfs)
145b914a250SMarcel Holtmann 		return;
146b914a250SMarcel Holtmann 
147fb784f05SBing Zhao 	dbg = kzalloc(sizeof(*dbg), GFP_KERNEL);
148fb784f05SBing Zhao 	priv->debugfs_data = dbg;
149fb784f05SBing Zhao 
150fb784f05SBing Zhao 	if (!dbg) {
151fb784f05SBing Zhao 		BT_ERR("Can not allocate memory for btmrvl_debugfs_data.");
152fb784f05SBing Zhao 		return;
153fb784f05SBing Zhao 	}
154fb784f05SBing Zhao 
155b914a250SMarcel Holtmann 	dbg->config_dir = debugfs_create_dir("config", hdev->debugfs);
156fb784f05SBing Zhao 
1579da226c7SAndy Shevchenko 	debugfs_create_u8("psmode", 0644, dbg->config_dir,
1589da226c7SAndy Shevchenko 			  &priv->btmrvl_dev.psmode);
1599da226c7SAndy Shevchenko 	debugfs_create_file("pscmd", 0644, dbg->config_dir,
160155961e8SDavid Herrmann 			    priv, &btmrvl_pscmd_fops);
1619da226c7SAndy Shevchenko 	debugfs_create_x16("gpiogap", 0644, dbg->config_dir,
1629da226c7SAndy Shevchenko 			   &priv->btmrvl_dev.gpio_gap);
1639da226c7SAndy Shevchenko 	debugfs_create_u8("hsmode", 0644, dbg->config_dir,
1649da226c7SAndy Shevchenko 			  &priv->btmrvl_dev.hsmode);
1659da226c7SAndy Shevchenko 	debugfs_create_file("hscmd", 0644, dbg->config_dir,
166155961e8SDavid Herrmann 			    priv, &btmrvl_hscmd_fops);
1679da226c7SAndy Shevchenko 	debugfs_create_file("hscfgcmd", 0644, dbg->config_dir,
168155961e8SDavid Herrmann 			    priv, &btmrvl_hscfgcmd_fops);
169fb784f05SBing Zhao 
170b914a250SMarcel Holtmann 	dbg->status_dir = debugfs_create_dir("status", hdev->debugfs);
1719da226c7SAndy Shevchenko 	debugfs_create_u8("curpsmode", 0444, dbg->status_dir,
1729da226c7SAndy Shevchenko 			  &priv->adapter->psmode);
1739da226c7SAndy Shevchenko 	debugfs_create_u8("psstate", 0444, dbg->status_dir,
1749da226c7SAndy Shevchenko 			  &priv->adapter->ps_state);
1759da226c7SAndy Shevchenko 	debugfs_create_u8("hsstate", 0444, dbg->status_dir,
1769da226c7SAndy Shevchenko 			  &priv->adapter->hs_state);
1779da226c7SAndy Shevchenko 	debugfs_create_u8("txdnldready", 0444, dbg->status_dir,
1789da226c7SAndy Shevchenko 			  &priv->btmrvl_dev.tx_dnld_rdy);
179fb784f05SBing Zhao }
180fb784f05SBing Zhao 
btmrvl_debugfs_remove(struct hci_dev * hdev)181fb784f05SBing Zhao void btmrvl_debugfs_remove(struct hci_dev *hdev)
182fb784f05SBing Zhao {
183155961e8SDavid Herrmann 	struct btmrvl_private *priv = hci_get_drvdata(hdev);
184fb784f05SBing Zhao 	struct btmrvl_debugfs_data *dbg = priv->debugfs_data;
185fb784f05SBing Zhao 
186fb784f05SBing Zhao 	if (!dbg)
187fb784f05SBing Zhao 		return;
188fb784f05SBing Zhao 
1899da226c7SAndy Shevchenko 	debugfs_remove_recursive(dbg->config_dir);
1909da226c7SAndy Shevchenko 	debugfs_remove_recursive(dbg->status_dir);
191fb784f05SBing Zhao 
192fb784f05SBing Zhao 	kfree(dbg);
193fb784f05SBing Zhao }
194