diff options
| author | Adrian Hunter <adrian.hunter@intel.com> | 2011-10-03 15:36:07 +0400 | 
|---|---|---|
| committer | Grant Likely <grant.likely@secretlab.ca> | 2011-10-06 14:14:52 +0400 | 
| commit | 8c0f7b10f1028d0bc78486affe2ccf39cdf45282 (patch) | |
| tree | 824ac3afe0678311c95f6cc09f45da8b63f331a9 /drivers/gpio/gpio-langwell.c | |
| parent | 38eb18a6f92da886fc1af509d25e8f7a49e23d9a (diff) | |
| download | linux-8c0f7b10f1028d0bc78486affe2ccf39cdf45282.tar.xz | |
gpio: langwell: ensure alternate function is cleared
Alternate function must be zero for the pin to act as
a GPIO.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
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; | 
