Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 167a60ca authored by Subbaraman Narayanamurthy's avatar Subbaraman Narayanamurthy
Browse files

soc: qcom: pmic_glink: add debugfs to filter logs



Add debugfs for pmic_glink device to filter out logs based on
filter and enable parameters. This is useful for debugging.

E.g. to filter out logs for PD Altmode driver whose message
owner id is 32780,

 echo 1 > /sys/kernel/debug/soc:qcom,pmic_glink/enable
 echo 32780 > /sys/kernel/debug/soc:qcom,pmic_glink/filter

E.g. to print out logs for all message owners,

 echo 1 > /sys/kernel/debug/soc:qcom,pmic_glink/enable
 echo 65535 > /sys/kernel/debug/soc:qcom,pmic_glink/filter

Please note that enabling these logs would print logs on both
Tx and Rx path from the clients of PMIC Glink device.

Change-Id: I63c1c90657b2044fe755cfd8fda73d5f942cad76
Signed-off-by: default avatarSubbaraman Narayanamurthy <subbaram@codeaurora.org>
parent fb60b1ec
Loading
Loading
Loading
Loading
+61 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@

#define pr_fmt(fmt)	"PMIC_GLINK: %s: " fmt, __func__

#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/idr.h>
#include <linux/list.h>
@@ -21,6 +22,7 @@
 * struct pmic_glink_dev - Top level data structure for pmic_glink device
 * @rpdev:		rpmsg device from rpmsg framework
 * @dev:		pmic_glink parent device for all child devices
 * @debugfs_dir:	Debugfs directory handle
 * @channel_name:	Glink channel name used by rpmsg device
 * @client_idr:		idr list for the clients
 * @client_lock:	mutex lock when idr APIs are used on client_idr
@@ -32,10 +34,13 @@
 * @dev_list:		list for pmic_glink_dev_list
 * @state:		indicates when remote subsystem is up/down
 * @child_probed:	indicates when the children are probed
 * @log_filter:		message owner filter for logging
 * @log_enable:		enables message logging
 */
struct pmic_glink_dev {
	struct rpmsg_device	*rpdev;
	struct device		*dev;
	struct dentry		*debugfs_dir;
	const char		*channel_name;
	struct idr		client_idr;
	struct mutex		client_lock;
@@ -47,6 +52,8 @@ struct pmic_glink_dev {
	struct list_head	dev_list;
	atomic_t		state;
	bool			child_probed;
	u32			log_filter;
	bool			log_enable;
};

/**
@@ -135,6 +142,15 @@ int pmic_glink_write(struct pmic_glink_client *client, void *data,
	rc = rpmsg_trysend(client->pgdev->rpdev->ept, data, len);
	mutex_unlock(&client->lock);

	if (!rc && client->pgdev->log_enable) {
		struct pmic_glink_hdr *hdr = data;

		if (client->pgdev->log_filter == hdr->owner)
			pr_info("Tx data: %*ph\n", len, data);
		else if (client->pgdev->log_filter == 65535)
			pr_info("[%u] Tx data: %*ph\n", hdr->owner, len, data);
	}

	return rc;
}
EXPORT_SYMBOL(pmic_glink_write);
@@ -252,6 +268,14 @@ static void pmic_glink_rx_callback(struct pmic_glink_dev *pgdev,
		return;
	}

	if (pgdev->log_enable) {
		if (pgdev->log_filter == hdr->owner)
			pr_info("Rx data: %*ph\n", pbuf->len, pbuf->buf);
		else if (pgdev->log_filter == 65535)
			pr_info("[%u] Rx data: %*ph\n", hdr->owner, pbuf->len,
				pbuf->buf);
	}

	client->callback(client->priv, pbuf->buf, pbuf->len);
}

@@ -345,6 +369,41 @@ static struct rpmsg_driver pmic_glink_rpmsg_driver = {
	},
};

#ifdef CONFIG_DEBUG_FS
static void pmic_glink_add_debugfs(struct pmic_glink_dev *pgdev)
{
	struct dentry *dir, *file;

	dir = debugfs_create_dir(dev_name(pgdev->dev), NULL);
	if (IS_ERR(dir)) {
		pr_err("Failed to create pmic_glink debugfs directory rc=%d\n",
			PTR_ERR(dir));
		return;
	}

	file = debugfs_create_u32("filter", 0600, dir, &pgdev->log_filter);
	if (IS_ERR(file)) {
		pr_err("Failed to create filter debugfs file rc=%d\n",
			PTR_ERR(file));
		debugfs_remove_recursive(dir);
		return;
	}

	file = debugfs_create_bool("enable", 0600, dir, &pgdev->log_enable);
	if (IS_ERR(file)) {
		pr_err("Failed to create enable debugfs file rc=%d\n",
			PTR_ERR(file));
		debugfs_remove_recursive(dir);
		return;
	}

	pgdev->debugfs_dir = dir;
}
#else
static inline void pmic_glink_add_debugfs(struct pmic_glink_dev *pgdev)
{ }
#endif

static void pmic_glink_init_work(struct work_struct *work)
{
	struct pmic_glink_dev *pgdev = container_of(work, struct pmic_glink_dev,
@@ -422,6 +481,7 @@ static int pmic_glink_probe(struct platform_device *pdev)
	pgdev->dev = dev;

	pmic_glink_dev_add(pgdev);
	pmic_glink_add_debugfs(pgdev);

	pr_debug("%s probed successfully\n", pgdev->channel_name);
	return 0;
@@ -431,6 +491,7 @@ static int pmic_glink_remove(struct platform_device *pdev)
{
	struct pmic_glink_dev *pgdev = dev_get_drvdata(&pdev->dev);

	debugfs_remove_recursive(pgdev->debugfs_dir);
	flush_workqueue(pgdev->rx_wq);
	destroy_workqueue(pgdev->rx_wq);
	idr_destroy(&pgdev->client_idr);