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

Commit 8d007488 authored by Simon Guinot's avatar Simon Guinot Committed by Jason Cooper
Browse files

ARM: Orion: add dbg_show function to gpio-orion driver



This patch adds a dedicated dbg_show function to the gpio-mvebu driver.
In addition to the generic gpiolib informations, this function displays
informations related with the specific Marvell registers (blink enable,
data in polarity, interrupt masks and cause).

Signed-off-by: default avatarSimon Guinot <simon.guinot@sequanux.org>
Signed-off-by: default avatarJason Cooper <jason@lakedaemon.net>
parent 8bb96604
Loading
Loading
Loading
Loading
+59 −0
Original line number Diff line number Diff line
@@ -439,6 +439,64 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
	}
}

#ifdef CONFIG_DEBUG_FS
#include <linux/seq_file.h>

static void orion_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
{
	struct orion_gpio_chip *ochip =
		container_of(chip, struct orion_gpio_chip, chip);
	u32 out, io_conf, blink, in_pol, data_in, cause, edg_msk, lvl_msk;
	int i;

	out	= readl_relaxed(GPIO_OUT(ochip));
	io_conf	= readl_relaxed(GPIO_IO_CONF(ochip));
	blink	= readl_relaxed(GPIO_BLINK_EN(ochip));
	in_pol	= readl_relaxed(GPIO_IN_POL(ochip));
	data_in	= readl_relaxed(GPIO_DATA_IN(ochip));
	cause	= readl_relaxed(GPIO_EDGE_CAUSE(ochip));
	edg_msk	= readl_relaxed(GPIO_EDGE_MASK(ochip));
	lvl_msk	= readl_relaxed(GPIO_LEVEL_MASK(ochip));

	for (i = 0; i < chip->ngpio; i++) {
		const char *label;
		u32 msk;
		bool is_out;

		label = gpiochip_is_requested(chip, i);
		if (!label)
			continue;

		msk = 1 << i;
		is_out = !(io_conf & msk);

		seq_printf(s, " gpio-%-3d (%-20.20s)", chip->base + i, label);

		if (is_out) {
			seq_printf(s, " out %s %s\n",
				   out & msk ? "hi" : "lo",
				   blink & msk ? "(blink )" : "");
			continue;
		}

		seq_printf(s, " in  %s (act %s) - IRQ",
			   (data_in ^ in_pol) & msk  ? "hi" : "lo",
			   in_pol & msk ? "lo" : "hi");
		if (!((edg_msk | lvl_msk) & msk)) {
			seq_printf(s, " disabled\n");
			continue;
		}
		if (edg_msk & msk)
			seq_printf(s, " edge ");
		if (lvl_msk & msk)
			seq_printf(s, " level");
		seq_printf(s, " (%s)\n", cause & msk ? "pending" : "clear  ");
	}
}
#else
#define orion_gpio_dbg_show NULL
#endif

void __init orion_gpio_init(struct device_node *np,
			    int gpio_base, int ngpio,
			    void __iomem *base, int mask_offset,
@@ -471,6 +529,7 @@ void __init orion_gpio_init(struct device_node *np,
#ifdef CONFIG_OF
	ochip->chip.of_node = np;
#endif
	ochip->chip.dbg_show = orion_gpio_dbg_show;

	spin_lock_init(&ochip->lock);
	ochip->base = (void __iomem *)base;