diff options
| author | Adrian Hunter <adrian.hunter@intel.com> | 2011-10-03 07:36:07 -0400 |
|---|---|---|
| committer | Grant Likely <grant.likely@secretlab.ca> | 2011-10-06 06:14:52 -0400 |
| commit | 8c0f7b10f1028d0bc78486affe2ccf39cdf45282 (patch) | |
| tree | 824ac3afe0678311c95f6cc09f45da8b63f331a9 | |
| parent | 38eb18a6f92da886fc1af509d25e8f7a49e23d9a (diff) | |
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>
| -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 { | |||
| 59 | GRER, /* rising edge detect */ | 59 | GRER, /* rising edge detect */ |
| 60 | GFER, /* falling edge detect */ | 60 | GFER, /* falling edge detect */ |
| 61 | GEDR, /* edge detect result */ | 61 | GEDR, /* edge detect result */ |
| 62 | GAFR, /* alt function */ | ||
| 62 | }; | 63 | }; |
| 63 | 64 | ||
| 64 | struct lnw_gpio { | 65 | struct lnw_gpio { |
| @@ -81,6 +82,31 @@ static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset, | |||
| 81 | return ptr; | 82 | return ptr; |
| 82 | } | 83 | } |
| 83 | 84 | ||
| 85 | static void __iomem *gpio_reg_2bit(struct gpio_chip *chip, unsigned offset, | ||
| 86 | enum GPIO_REG reg_type) | ||
| 87 | { | ||
| 88 | struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip); | ||
| 89 | unsigned nreg = chip->ngpio / 32; | ||
| 90 | u8 reg = offset / 16; | ||
| 91 | void __iomem *ptr; | ||
| 92 | |||
| 93 | ptr = (void __iomem *)(lnw->reg_base + reg_type * nreg * 4 + reg * 4); | ||
| 94 | return ptr; | ||
| 95 | } | ||
| 96 | |||
| 97 | static int lnw_gpio_request(struct gpio_chip *chip, unsigned offset) | ||
| 98 | { | ||
| 99 | void __iomem *gafr = gpio_reg_2bit(chip, offset, GAFR); | ||
| 100 | u32 value = readl(gafr); | ||
| 101 | int shift = (offset % 16) << 1, af = (value >> shift) & 3; | ||
| 102 | |||
| 103 | if (af) { | ||
| 104 | value &= ~(3 << shift); | ||
| 105 | writel(value, gafr); | ||
| 106 | } | ||
| 107 | return 0; | ||
| 108 | } | ||
| 109 | |||
| 84 | static int lnw_gpio_get(struct gpio_chip *chip, unsigned offset) | 110 | static int lnw_gpio_get(struct gpio_chip *chip, unsigned offset) |
| 85 | { | 111 | { |
| 86 | void __iomem *gplr = gpio_reg(chip, offset, GPLR); | 112 | void __iomem *gplr = gpio_reg(chip, offset, GPLR); |
| @@ -321,6 +347,7 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, | |||
| 321 | lnw->reg_base = base; | 347 | lnw->reg_base = base; |
| 322 | lnw->irq_base = irq_base; | 348 | lnw->irq_base = irq_base; |
| 323 | lnw->chip.label = dev_name(&pdev->dev); | 349 | lnw->chip.label = dev_name(&pdev->dev); |
| 350 | lnw->chip.request = lnw_gpio_request; | ||
| 324 | lnw->chip.direction_input = lnw_gpio_direction_input; | 351 | lnw->chip.direction_input = lnw_gpio_direction_input; |
| 325 | lnw->chip.direction_output = lnw_gpio_direction_output; | 352 | lnw->chip.direction_output = lnw_gpio_direction_output; |
| 326 | lnw->chip.get = lnw_gpio_get; | 353 | lnw->chip.get = lnw_gpio_get; |
