diff options
Diffstat (limited to 'drivers/gpio/gpio-langwell.c')
| -rw-r--r-- | drivers/gpio/gpio-langwell.c | 27 | 
1 files changed, 27 insertions, 0 deletions
| diff --git a/drivers/gpio/gpio-langwell.c b/drivers/gpio/gpio-langwell.c index d2eb57c60e0e..00692e89ef87 100644 --- a/drivers/gpio/gpio-langwell.c +++ b/drivers/gpio/gpio-langwell.c @@ -59,6 +59,7 @@ enum GPIO_REG {  	GRER,		/* rising edge detect */  	GFER,		/* falling edge detect */  	GEDR,		/* edge detect result */ +	GAFR,		/* alt function */  };  struct lnw_gpio { @@ -81,6 +82,31 @@ static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset,  	return ptr;  } +static void __iomem *gpio_reg_2bit(struct gpio_chip *chip, unsigned offset, +				   enum GPIO_REG reg_type) +{ +	struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip); +	unsigned nreg = chip->ngpio / 32; +	u8 reg = offset / 16; +	void __iomem *ptr; + +	ptr = (void __iomem *)(lnw->reg_base + reg_type * nreg * 4 + reg * 4); +	return ptr; +} + +static int lnw_gpio_request(struct gpio_chip *chip, unsigned offset) +{ +	void __iomem *gafr = gpio_reg_2bit(chip, offset, GAFR); +	u32 value = readl(gafr); +	int shift = (offset % 16) << 1, af = (value >> shift) & 3; + +	if (af) { +		value &= ~(3 << shift); +		writel(value, gafr); +	} +	return 0; +} +  static int lnw_gpio_get(struct gpio_chip *chip, unsigned offset)  {  	void __iomem *gplr = gpio_reg(chip, offset, GPLR); @@ -321,6 +347,7 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev,  	lnw->reg_base = base;  	lnw->irq_base = irq_base;  	lnw->chip.label = dev_name(&pdev->dev); +	lnw->chip.request = lnw_gpio_request;  	lnw->chip.direction_input = lnw_gpio_direction_input;  	lnw->chip.direction_output = lnw_gpio_direction_output;  	lnw->chip.get = lnw_gpio_get; | 
