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

Commit 86e3ef81 authored by Cristina Ciocan's avatar Cristina Ciocan Committed by Linus Walleij
Browse files

pinctrl: baytrail: Update gpio chip operations



This patch updates the gpio chip implementation in order
to interact with the pin control model: the chip contains
reference to SOC data and pin/group/community information
is retrieved through the SOC reference.

Signed-off-by: default avatarCristina Ciocan <cristina.ciocan@intel.com>
Acked-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent c501d0b1
Loading
Loading
Loading
Loading
+68 −29
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@
#include <linux/types.h>
#include <linux/types.h>
#include <linux/bitops.h>
#include <linux/bitops.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/gpio/driver.h>
#include <linux/acpi.h>
#include <linux/acpi.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
@@ -1363,44 +1364,45 @@ static void byt_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
	unsigned long flags;
	unsigned long flags;
	u32 old_val;
	u32 old_val;


	raw_spin_lock_irqsave(&vg->lock, flags);
	if (!reg)
		return;


	raw_spin_lock_irqsave(&vg->lock, flags);
	old_val = readl(reg);
	old_val = readl(reg);

	if (value)
	if (value)
		writel(old_val | BYT_LEVEL, reg);
		writel(old_val | BYT_LEVEL, reg);
	else
	else
		writel(old_val & ~BYT_LEVEL, reg);
		writel(old_val & ~BYT_LEVEL, reg);

	raw_spin_unlock_irqrestore(&vg->lock, flags);
	raw_spin_unlock_irqrestore(&vg->lock, flags);
}
}


static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
{
{
	struct byt_gpio *vg = gpiochip_get_data(chip);
	struct byt_gpio *vg = gpiochip_get_data(chip);
	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
	unsigned long flags;
	unsigned long flags;
	u32 value;
	u32 value;


	raw_spin_lock_irqsave(&vg->lock, flags);
	if (!reg)

		return -EINVAL;
	value = readl(reg) | BYT_DIR_MASK;
	value &= ~BYT_INPUT_EN;		/* active low */
	writel(value, reg);


	raw_spin_lock_irqsave(&vg->lock, flags);
	value = readl(reg);
	raw_spin_unlock_irqrestore(&vg->lock, flags);
	raw_spin_unlock_irqrestore(&vg->lock, flags);


	return 0;
	if (!(value & BYT_OUTPUT_EN))
		return GPIOF_DIR_OUT;
	if (!(value & BYT_INPUT_EN))
		return GPIOF_DIR_IN;

	return -EINVAL;
}
}


static int byt_gpio_direction_output(struct gpio_chip *chip,
static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
				     unsigned gpio, int value)
{
{
	struct byt_gpio *vg = gpiochip_get_data(chip);
	struct byt_gpio *vg = gpiochip_get_data(chip);
	void __iomem *conf_reg = byt_gpio_reg(vg, gpio, BYT_CONF0_REG);
	void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
	void __iomem *reg = byt_gpio_reg(vg, gpio, BYT_VAL_REG);
	unsigned long flags;
	unsigned long flags;
	u32 reg_val;


	raw_spin_lock_irqsave(&vg->lock, flags);
	raw_spin_lock_irqsave(&vg->lock, flags);


@@ -1413,15 +1415,18 @@ static int byt_gpio_direction_output(struct gpio_chip *chip,
	WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN,
	WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN,
		"Potential Error: Setting GPIO with direct_irq_en to output");
		"Potential Error: Setting GPIO with direct_irq_en to output");


	reg_val = readl(reg) | BYT_DIR_MASK;
	return pinctrl_gpio_direction_input(chip->base + offset);
	reg_val &= ~(BYT_OUTPUT_EN | BYT_INPUT_EN);
}


	if (value)
static int byt_gpio_direction_output(struct gpio_chip *chip,
		writel(reg_val | BYT_LEVEL, reg);
				     unsigned int offset, int value)
	else
{
		writel(reg_val & ~BYT_LEVEL, reg);
	int ret = pinctrl_gpio_direction_output(chip->base + offset);


	raw_spin_unlock_irqrestore(&vg->lock, flags);
	if (ret)
		return ret;

	byt_gpio_set(chip, offset, value);


	return 0;
	return 0;
}
}
@@ -1430,20 +1435,42 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
{
{
	struct byt_gpio *vg = gpiochip_get_data(chip);
	struct byt_gpio *vg = gpiochip_get_data(chip);
	int i;
	int i;
	u32 conf0, val, offs;
	u32 conf0, val;


	for (i = 0; i < vg->chip.ngpio; i++) {
	for (i = 0; i < vg->soc_data->npins; i++) {
		const struct byt_community *comm;
		const char *pull_str = NULL;
		const char *pull_str = NULL;
		const char *pull = NULL;
		const char *pull = NULL;
		void __iomem *reg;
		unsigned long flags;
		unsigned long flags;
		const char *label;
		const char *label;
		offs = vg->range->pins[i] * 16;
		unsigned int pin;


		raw_spin_lock_irqsave(&vg->lock, flags);
		raw_spin_lock_irqsave(&vg->lock, flags);
		conf0 = readl(vg->reg_base + offs + BYT_CONF0_REG);
		pin = vg->soc_data->pins[i].number;
		val = readl(vg->reg_base + offs + BYT_VAL_REG);
		reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
		if (!reg) {
			seq_printf(s,
				   "Could not retrieve pin %i conf0 reg\n",
				   pin);
			continue;
		}
		conf0 = readl(reg);

		reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
		if (!reg) {
			seq_printf(s,
				   "Could not retrieve pin %i val reg\n", pin);
		}
		val = readl(reg);
		raw_spin_unlock_irqrestore(&vg->lock, flags);
		raw_spin_unlock_irqrestore(&vg->lock, flags);


		comm = byt_get_community(vg, pin);
		if (!comm) {
			seq_printf(s,
				   "Could not get community for pin %i\n", pin);
			continue;
		}
		label = gpiochip_is_requested(chip, i);
		label = gpiochip_is_requested(chip, i);
		if (!label)
		if (!label)
			label = "Unrequested";
			label = "Unrequested";
@@ -1474,12 +1501,12 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)


		seq_printf(s,
		seq_printf(s,
			   " gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s",
			   " gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s",
			   i,
			   pin,
			   label,
			   label,
			   val & BYT_INPUT_EN ? "  " : "in",
			   val & BYT_INPUT_EN ? "  " : "in",
			   val & BYT_OUTPUT_EN ? "   " : "out",
			   val & BYT_OUTPUT_EN ? "   " : "out",
			   val & BYT_LEVEL ? "hi" : "lo",
			   val & BYT_LEVEL ? "hi" : "lo",
			   vg->range->pins[i], offs,
			   comm->pad_map[i], comm->pad_map[i] * 32,
			   conf0 & 0x7,
			   conf0 & 0x7,
			   conf0 & BYT_TRIG_NEG ? " fall" : "     ",
			   conf0 & BYT_TRIG_NEG ? " fall" : "     ",
			   conf0 & BYT_TRIG_POS ? " rise" : "     ",
			   conf0 & BYT_TRIG_POS ? " rise" : "     ",
@@ -1519,6 +1546,18 @@ static void byt_gpio_irq_handler(struct irq_desc *desc)
	chip->irq_eoi(data);
	chip->irq_eoi(data);
}
}


static const struct gpio_chip byt_gpio_chip = {
	.owner			= THIS_MODULE,
	.request		= gpiochip_generic_request,
	.free			= gpiochip_generic_free,
	.get_direction		= byt_gpio_get_direction,
	.direction_input	= byt_gpio_direction_input,
	.direction_output	= byt_gpio_direction_output,
	.get			= byt_gpio_get,
	.set			= byt_gpio_set,
	.dbg_show		= byt_gpio_dbg_show,
};

static void byt_irq_ack(struct irq_data *d)
static void byt_irq_ack(struct irq_data *d)
{
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);