summaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-sch.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2014-08-07 08:36:12 +0200
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-08-07 08:36:12 +0200
commit5e2aa2ed08e2e280121dc7cf5609c87d464f12ef (patch)
treeca7d7b1480285e3b617fecc5b41f0ce150a82c32 /drivers/gpio/gpio-sch.c
parentInput: document INPUT_PROP_TOPBUTTONPAD (diff)
parentMerge branch 'wacom' into next (diff)
downloadlinux-5e2aa2ed08e2e280121dc7cf5609c87d464f12ef.tar.xz
linux-5e2aa2ed08e2e280121dc7cf5609c87d464f12ef.zip
Merge branch 'next' into for-linus
Prepare first round of input updates for 3.17.
Diffstat (limited to 'drivers/gpio/gpio-sch.c')
-rw-r--r--drivers/gpio/gpio-sch.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c
index 5af65719b95d..a9b1cd16c848 100644
--- a/drivers/gpio/gpio-sch.c
+++ b/drivers/gpio/gpio-sch.c
@@ -97,8 +97,6 @@ static int sch_gpio_core_direction_out(struct gpio_chip *gc,
u8 curr_dirs;
unsigned short offset, bit;
- sch_gpio_core_set(gc, gpio_num, val);
-
spin_lock(&gpio_lock);
offset = CGIO + gpio_num / 8;
@@ -109,6 +107,17 @@ static int sch_gpio_core_direction_out(struct gpio_chip *gc,
outb(curr_dirs & ~(1 << bit), gpio_ba + offset);
spin_unlock(&gpio_lock);
+
+ /*
+ * according to the datasheet, writing to the level register has no
+ * effect when GPIO is programmed as input.
+ * Actually the the level register is read-only when configured as input.
+ * Thus presetting the output level before switching to output is _NOT_ possible.
+ * Hence we set the level after configuring the GPIO as output.
+ * But we cannot prevent a short low pulse if direction is set to high
+ * and an external pull-up is connected.
+ */
+ sch_gpio_core_set(gc, gpio_num, val);
return 0;
}
@@ -178,8 +187,6 @@ static int sch_gpio_resume_direction_out(struct gpio_chip *gc,
u8 curr_dirs;
unsigned short offset, bit;
- sch_gpio_resume_set(gc, gpio_num, val);
-
offset = RGIO + gpio_num / 8;
bit = gpio_num % 8;
@@ -190,6 +197,17 @@ static int sch_gpio_resume_direction_out(struct gpio_chip *gc,
outb(curr_dirs & ~(1 << bit), gpio_ba + offset);
spin_unlock(&gpio_lock);
+
+ /*
+ * according to the datasheet, writing to the level register has no
+ * effect when GPIO is programmed as input.
+ * Actually the the level register is read-only when configured as input.
+ * Thus presetting the output level before switching to output is _NOT_ possible.
+ * Hence we set the level after configuring the GPIO as output.
+ * But we cannot prevent a short low pulse if direction is set to high
+ * and an external pull-up is connected.
+ */
+ sch_gpio_resume_set(gc, gpio_num, val);
return 0;
}