From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jiri Pirko Subject: Re: [RFC net-next 08/15] net: lora: sx1276: Add debugfs Date: Mon, 2 Jul 2018 18:26:49 +0200 Message-ID: <20180702162649.GC2737@nanopsycho.orion> References: <20180701110804.32415-1-afaerber@suse.de> <20180701110804.32415-9-afaerber@suse.de> Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit Cc: netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Jian-Hong Pan , Marcel Holtmann , "David S . Miller" , Matthias Brugger , Janus Piwek , Michael =?iso-8859-1?Q?R=F6der?= , Dollar Chen , Ken Yu To: Andreas =?iso-8859-1?Q?F=E4rber?= Return-path: Content-Disposition: inline In-Reply-To: <20180701110804.32415-9-afaerber@suse.de> Sender: linux-kernel-owner@vger.kernel.org List-Id: netdev.vger.kernel.org Sun, Jul 01, 2018 at 01:07:57PM CEST, afaerber@suse.de wrote: >Allow some interactive inspection at runtime via debugfs. > >Signed-off-by: Andreas Färber >--- > drivers/net/lora/sx1276.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 132 insertions(+) > >diff --git a/drivers/net/lora/sx1276.c b/drivers/net/lora/sx1276.c >index d6732111247a..1072019cfcc1 100644 >--- a/drivers/net/lora/sx1276.c >+++ b/drivers/net/lora/sx1276.c >@@ -5,6 +5,7 @@ > * Copyright (c) 2016-2018 Andreas Färber > */ > >+#include > #include > #include > #include >@@ -61,6 +62,8 @@ struct sx1276_priv { > > struct workqueue_struct *wq; > struct work_struct tx_work; >+ >+ struct dentry *debugfs; > }; > > static int sx1276_read_single(struct spi_device *spi, u8 reg, u8 *val) >@@ -416,6 +419,128 @@ static const struct net_device_ops sx1276_netdev_ops = { > .ndo_start_xmit = sx1276_loradev_start_xmit, > }; > >+static ssize_t sx1276_freq_read(struct file *file, char __user *user_buf, >+ size_t count, loff_t *ppos) >+{ >+ struct net_device *netdev = file->private_data; >+ struct sx1276_priv *priv = netdev_priv(netdev); >+ struct spi_device *spi = priv->spi; >+ ssize_t size; >+ char *buf; >+ int ret; >+ u8 msb, mid, lsb; >+ u32 freq_xosc; >+ unsigned long long frf; >+ >+ ret = of_property_read_u32(spi->dev.of_node, "clock-frequency", &freq_xosc); >+ if (ret) >+ return 0; >+ >+ mutex_lock(&priv->spi_lock); >+ >+ ret = sx1276_read_single(spi, REG_FRF_MSB, &msb); >+ if (!ret) >+ ret = sx1276_read_single(spi, REG_FRF_MID, &mid); >+ if (!ret) >+ ret = sx1276_read_single(spi, REG_FRF_LSB, &lsb); >+ >+ mutex_unlock(&priv->spi_lock); >+ >+ if (ret) >+ return 0; >+ >+ frf = freq_xosc; >+ frf *= ((ulong)msb << 16) | ((ulong)mid << 8) | lsb; >+ frf /= (1 << 19); >+ >+ buf = kasprintf(GFP_KERNEL, "%llu\n", frf); >+ if (!buf) >+ return 0; >+ >+ size = simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); >+ kfree(buf); >+ >+ return size; >+} >+ >+static const struct file_operations sx1276_freq_fops = { >+ .owner = THIS_MODULE, >+ .open = simple_open, >+ .read = sx1276_freq_read, >+}; >+ >+static ssize_t sx1276_state_read(struct file *file, char __user *user_buf, >+ size_t count, loff_t *ppos) >+{ >+ struct net_device *netdev = file->private_data; >+ struct sx1276_priv *priv = netdev_priv(netdev); >+ struct spi_device *spi = priv->spi; >+ ssize_t size; >+ char *buf; >+ int len = 0; >+ int ret; >+ u8 val; >+ bool lora_mode = true; >+ const int max_len = 4096; >+ >+ buf = kzalloc(max_len, GFP_KERNEL); >+ if (!buf) >+ return 0; >+ >+ mutex_lock(&priv->spi_lock); >+ >+ ret = sx1276_read_single(spi, REG_OPMODE, &val); >+ if (!ret) { >+ len += snprintf(buf + len, max_len - len, "RegOpMode = 0x%02x\n", val); >+ lora_mode = (val & REG_OPMODE_LONG_RANGE_MODE) != 0; >+ } >+ >+ ret = sx1276_read_single(spi, REG_FRF_MSB, &val); >+ if (!ret) >+ len += snprintf(buf + len, max_len - len, "RegFrMsb = 0x%02x\n", val); >+ ret = sx1276_read_single(spi, REG_FRF_MID, &val); >+ if (!ret) >+ len += snprintf(buf + len, max_len - len, "RegFrMid = 0x%02x\n", val); >+ ret = sx1276_read_single(spi, REG_FRF_LSB, &val); >+ if (!ret) >+ len += snprintf(buf + len, max_len - len, "RegFrLsb = 0x%02x\n", val); >+ >+ ret = sx1276_read_single(spi, REG_PA_CONFIG, &val); >+ if (!ret) >+ len += snprintf(buf + len, max_len - len, "RegPaConfig = 0x%02x\n", val); >+ >+ if (lora_mode) { >+ ret = sx1276_read_single(spi, LORA_REG_IRQ_FLAGS_MASK, &val); >+ if (!ret) >+ len += snprintf(buf + len, max_len - len, "RegIrqFlagsMask = 0x%02x\n", val); >+ >+ ret = sx1276_read_single(spi, LORA_REG_IRQ_FLAGS, &val); >+ if (!ret) >+ len += snprintf(buf + len, max_len - len, "RegIrqFlags = 0x%02x\n", val); >+ >+ ret = sx1276_read_single(spi, LORA_REG_SYNC_WORD, &val); >+ if (!ret) >+ len += snprintf(buf + len, max_len - len, "RegSyncWord = 0x%02x\n", val); >+ } >+ >+ ret = sx1276_read_single(spi, REG_PA_DAC, &val); >+ if (!ret) >+ len += snprintf(buf + len, max_len - len, "RegPaDac = 0x%02x\n", val); >+ >+ mutex_unlock(&priv->spi_lock); >+ >+ size = simple_read_from_buffer(user_buf, count, ppos, buf, len); >+ kfree(buf); >+ >+ return size; >+} >+ >+static const struct file_operations sx1276_state_fops = { >+ .owner = THIS_MODULE, >+ .open = simple_open, >+ .read = sx1276_state_read, >+}; >+ > static int sx1276_probe(struct spi_device *spi) > { > struct net_device *netdev; >@@ -566,6 +691,10 @@ static int sx1276_probe(struct spi_device *spi) > return ret; > } > >+ priv->debugfs = debugfs_create_dir(dev_name(&spi->dev), NULL); >+ debugfs_create_file("state", S_IRUGO, priv->debugfs, netdev, &sx1276_state_fops); >+ debugfs_create_file("frequency", S_IRUGO, priv->debugfs, netdev, &sx1276_freq_fops); Hmm. These look like useful information not only for debugging. I think it would be worth to expose these via some standard uapi. Like generic netlink, similar to nl80211 >+ > dev_info(&spi->dev, "SX1276 module probed (SX%d)", model); > > return 0; >@@ -574,6 +703,9 @@ static int sx1276_probe(struct spi_device *spi) > static int sx1276_remove(struct spi_device *spi) > { > struct net_device *netdev = spi_get_drvdata(spi); >+ struct sx1276_priv *priv = netdev_priv(netdev); >+ >+ debugfs_remove_recursive(priv->debugfs); > > unregister_loradev(netdev); > free_loradev(netdev); >-- >2.16.4 >