aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorAaron Lu <aaron.lu@intel.com>2014-09-24 22:57:26 -0400
committerLinus Walleij <linus.walleij@linaro.org>2014-09-25 09:15:30 -0400
commitdcdc3018d6357c35eae7d80b323e10bd72253cb7 (patch)
tree77de1277efd29dea50a6273df0473540cc1c91ed /drivers/gpio
parente4742d5769e7f502f1b928b759ddecabf03375d7 (diff)
gpio: crystalcove: support virtual GPIO
The virtual GPIO introduced in ACPI table of Baytrail-T based system is used to solve a problem under Windows. We do not have such problems under Linux so we do not actually need them. But we have to tell GPIO library that the Crystal Cove GPIO chip has this many GPIO pins or the common GPIO handler will refuse any access to those high number GPIO pins, which will resulted in a failure evaluation of every ACPI control method that is used to turn on/off power resource and/or report sensor temperatures. Signed-off-by: Aaron Lu <aaron.lu@intel.com> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com> [changed vgpio number from 0x5e to 94] Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-crystalcove.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c
index e3712f0e51ab..bbfe7f508502 100644
--- a/drivers/gpio/gpio-crystalcove.c
+++ b/drivers/gpio/gpio-crystalcove.c
@@ -24,6 +24,7 @@
24#include <linux/mfd/intel_soc_pmic.h> 24#include <linux/mfd/intel_soc_pmic.h>
25 25
26#define CRYSTALCOVE_GPIO_NUM 16 26#define CRYSTALCOVE_GPIO_NUM 16
27#define CRYSTALCOVE_VGPIO_NUM 94
27 28
28#define UPDATE_IRQ_TYPE BIT(0) 29#define UPDATE_IRQ_TYPE BIT(0)
29#define UPDATE_IRQ_MASK BIT(1) 30#define UPDATE_IRQ_MASK BIT(1)
@@ -130,6 +131,9 @@ static int crystalcove_gpio_dir_in(struct gpio_chip *chip, unsigned gpio)
130{ 131{
131 struct crystalcove_gpio *cg = to_cg(chip); 132 struct crystalcove_gpio *cg = to_cg(chip);
132 133
134 if (gpio > CRYSTALCOVE_VGPIO_NUM)
135 return 0;
136
133 return regmap_write(cg->regmap, to_reg(gpio, CTRL_OUT), 137 return regmap_write(cg->regmap, to_reg(gpio, CTRL_OUT),
134 CTLO_INPUT_SET); 138 CTLO_INPUT_SET);
135} 139}
@@ -139,6 +143,9 @@ static int crystalcove_gpio_dir_out(struct gpio_chip *chip, unsigned gpio,
139{ 143{
140 struct crystalcove_gpio *cg = to_cg(chip); 144 struct crystalcove_gpio *cg = to_cg(chip);
141 145
146 if (gpio > CRYSTALCOVE_VGPIO_NUM)
147 return 0;
148
142 return regmap_write(cg->regmap, to_reg(gpio, CTRL_OUT), 149 return regmap_write(cg->regmap, to_reg(gpio, CTRL_OUT),
143 CTLO_OUTPUT_SET | value); 150 CTLO_OUTPUT_SET | value);
144} 151}
@@ -149,6 +156,9 @@ static int crystalcove_gpio_get(struct gpio_chip *chip, unsigned gpio)
149 int ret; 156 int ret;
150 unsigned int val; 157 unsigned int val;
151 158
159 if (gpio > CRYSTALCOVE_VGPIO_NUM)
160 return 0;
161
152 ret = regmap_read(cg->regmap, to_reg(gpio, CTRL_IN), &val); 162 ret = regmap_read(cg->regmap, to_reg(gpio, CTRL_IN), &val);
153 if (ret) 163 if (ret)
154 return ret; 164 return ret;
@@ -161,6 +171,9 @@ static void crystalcove_gpio_set(struct gpio_chip *chip,
161{ 171{
162 struct crystalcove_gpio *cg = to_cg(chip); 172 struct crystalcove_gpio *cg = to_cg(chip);
163 173
174 if (gpio > CRYSTALCOVE_VGPIO_NUM)
175 return;
176
164 if (value) 177 if (value)
165 regmap_update_bits(cg->regmap, to_reg(gpio, CTRL_OUT), 1, 1); 178 regmap_update_bits(cg->regmap, to_reg(gpio, CTRL_OUT), 1, 1);
166 else 179 else
@@ -256,7 +269,7 @@ static irqreturn_t crystalcove_gpio_irq_handler(int irq, void *data)
256 269
257 pending = p0 | p1 << 8; 270 pending = p0 | p1 << 8;
258 271
259 for (gpio = 0; gpio < cg->chip.ngpio; gpio++) { 272 for (gpio = 0; gpio < CRYSTALCOVE_GPIO_NUM; gpio++) {
260 if (pending & BIT(gpio)) { 273 if (pending & BIT(gpio)) {
261 virq = irq_find_mapping(cg->chip.irqdomain, gpio); 274 virq = irq_find_mapping(cg->chip.irqdomain, gpio);
262 generic_handle_irq(virq); 275 generic_handle_irq(virq);
@@ -273,7 +286,7 @@ static void crystalcove_gpio_dbg_show(struct seq_file *s,
273 int gpio, offset; 286 int gpio, offset;
274 unsigned int ctlo, ctli, mirqs0, mirqsx, irq; 287 unsigned int ctlo, ctli, mirqs0, mirqsx, irq;
275 288
276 for (gpio = 0; gpio < cg->chip.ngpio; gpio++) { 289 for (gpio = 0; gpio < CRYSTALCOVE_GPIO_NUM; gpio++) {
277 regmap_read(cg->regmap, to_reg(gpio, CTRL_OUT), &ctlo); 290 regmap_read(cg->regmap, to_reg(gpio, CTRL_OUT), &ctlo);
278 regmap_read(cg->regmap, to_reg(gpio, CTRL_IN), &ctli); 291 regmap_read(cg->regmap, to_reg(gpio, CTRL_IN), &ctli);
279 regmap_read(cg->regmap, gpio < 8 ? MGPIO0IRQS0 : MGPIO1IRQS0, 292 regmap_read(cg->regmap, gpio < 8 ? MGPIO0IRQS0 : MGPIO1IRQS0,
@@ -320,7 +333,7 @@ static int crystalcove_gpio_probe(struct platform_device *pdev)
320 cg->chip.get = crystalcove_gpio_get; 333 cg->chip.get = crystalcove_gpio_get;
321 cg->chip.set = crystalcove_gpio_set; 334 cg->chip.set = crystalcove_gpio_set;
322 cg->chip.base = -1; 335 cg->chip.base = -1;
323 cg->chip.ngpio = CRYSTALCOVE_GPIO_NUM; 336 cg->chip.ngpio = CRYSTALCOVE_VGPIO_NUM;
324 cg->chip.can_sleep = true; 337 cg->chip.can_sleep = true;
325 cg->chip.dev = dev; 338 cg->chip.dev = dev;
326 cg->chip.dbg_show = crystalcove_gpio_dbg_show; 339 cg->chip.dbg_show = crystalcove_gpio_dbg_show;