pmaports/device/.shared-patches/linux/qcom/msm8916/gpio-debug.patch
Minecrell aa1eefc44a
unmaintained/bq-paella-downstream: cleanup, add various debug patches (MR 2081)
These are various debugging related patches that I have used over the time
when attempting to get new features working for the mainline kernel.
Given that the downstream kernel is just intended for debugging in this case,
it seems convenient to add them to pmaports so I don't need to go search for
them in case I need them again in the future.

[ci:skip-build] Already built on CI
2021-03-31 23:49:26 +03:00

95 lines
2.8 KiB
Diff

This change allows dumping the state of all GPIOs via debugfs. This is useful
for debugging sometimes. The code is mostly copied from the mainline driver
to allow comparison: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/pinctrl/qcom/pinctrl-msm.c
diff --git a/drivers/pinctrl/pinctrl-msm-tlmm.c b/drivers/pinctrl/pinctrl-msm-tlmm.c
index fc8076162a0..fa628ca0dc1 100644
--- a/drivers/pinctrl/pinctrl-msm-tlmm.c
+++ b/drivers/pinctrl/pinctrl-msm-tlmm.c
@@ -671,6 +671,78 @@ static int msm_tlmm_gp_dir_out(struct gpio_chip *gc, unsigned offset, int val)
return 0;
}
+#ifdef CONFIG_DEBUG_FS
+#include <linux/seq_file.h>
+
+/* GP PIN TYPE REG MASKS */
+#define TLMM_GP_DRV_SHFT 6
+#define TLMM_GP_DRV_MASK 0x7
+#define TLMM_GP_PULL_SHFT 0
+#define TLMM_GP_PULL_MASK 0x3
+#define TLMM_GP_DIR_SHFT 9
+#define TLMM_GP_DIR_MASK 1
+#define TLMM_GP_FUNC_SHFT 2
+#define TLMM_GP_FUNC_MASK 0xF
+#define GPIO_OUT_BIT 1
+#define GPIO_IN_BIT 0
+#define GPIO_OE_BIT 9
+
+static void msm_gpio_dbg_show_one(struct seq_file *s,
+ struct gpio_chip *gc,
+ unsigned offset,
+ unsigned gpio)
+{
+ struct msm_pintype_info *pinfo = gc_to_pintype(gc);
+ void __iomem *cfg_regp = TLMM_GP_CFG(pinfo, offset);
+ void __iomem *inout_regp = TLMM_GP_INOUT(pinfo, offset);
+
+ unsigned func;
+ int is_out;
+ int drive;
+ int pull;
+ int val;
+ u32 ctl_reg, io_reg;
+
+ static const char * const pulls_keeper[] = {
+ "no pull",
+ "pull down",
+ "keeper",
+ "pull up"
+ };
+
+ ctl_reg = readl_relaxed(cfg_regp);
+ io_reg = readl_relaxed(inout_regp);
+
+ is_out = !!(ctl_reg & BIT(GPIO_OE_BIT));
+ func = (ctl_reg >> TLMM_GP_FUNC_SHFT) & TLMM_GP_FUNC_MASK;
+ drive = (ctl_reg >> TLMM_GP_DRV_SHFT) & TLMM_GP_DRV_SHFT;
+ pull = (ctl_reg >> TLMM_GP_PULL_SHFT) & TLMM_GP_PULL_MASK;
+
+ if (is_out)
+ val = !!(io_reg & BIT(GPIO_OUT_BIT));
+ else
+ val = !!(io_reg & BIT(GPIO_IN_BIT));
+
+ seq_printf(s, " gpio%d: %-3s", offset, is_out ? "out" : "in");
+ seq_printf(s, " %-4s func%d", val ? "high" : "low", func);
+ seq_printf(s, " %dmA", rval_to_drv_str(drive));
+ seq_printf(s, " %s", pulls_keeper[pull]);
+ seq_puts(s, "\n");
+}
+
+static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+ unsigned gpio = chip->base;
+ unsigned i;
+
+ for (i = 0; i < chip->ngpio; i++, gpio++)
+ msm_gpio_dbg_show_one(s, chip, i, gpio);
+}
+
+#else
+#define msm_gpio_dbg_show NULL
+#endif
+
static int msm_tlmm_gp_to_irq(struct gpio_chip *gc, unsigned offset)
{
struct msm_pintype_info *pinfo = gc_to_pintype(gc);
@@ -1073,6 +1145,7 @@ static struct msm_pintype_info tlmm_pininfo[] = {
.get = msm_tlmm_gp_get,
.set = msm_tlmm_gp_set,
.to_irq = msm_tlmm_gp_to_irq,
+ .dbg_show = msm_gpio_dbg_show,
},
.init_irq = msm_tlmm_gp_irq_init,
.irq_chip = &msm_tlmm_gp_irq,