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 /drivers/gpio | |
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>
Diffstat (limited to 'drivers/gpio')
-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; |