* [PATCH 0/4] pinctrl: baytrail: Assorted fixes
@ 2015-02-23 12:53 Mika Westerberg
2015-02-23 12:53 ` [PATCH 1/4] pinctrl: baytrail: Relax GPIO request rules Mika Westerberg
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Mika Westerberg @ 2015-02-23 12:53 UTC (permalink / raw)
To: Linus Walleij
Cc: Heikki Krogerus, Mathias Nyman, Hans Holmberg, Benjamin Adler,
Mika Westerberg, linux-gpio, linux-kernel
Hi,
This series contains set of fixes that are necessary in order to get some
new Intel Baytrail based devices, in particular the GPIO part of those,
working.
The first patch fixes GPIO request problem that was found on Zotac ZBOX
pico 320.
Second and third patch deal with Lenovo Thinkpad 10 digitizer problem.
In addition to that we now save and restore pin context over system sleep
as was observed on Minnowboard MAX (but applies to other Baytrail based
devices which support S3).
Mika Westerberg (4):
pinctrl: baytrail: Relax GPIO request rules
pinctrl: baytrail: Clear interrupt triggering from pins that are in GPIO mode
pinctrl: baytrail: Rework interrupt handling
pinctrl: baytrail: Save pin context over system sleep
drivers/pinctrl/intel/pinctrl-baytrail.c | 254 +++++++++++++++++++++++--------
1 file changed, 188 insertions(+), 66 deletions(-)
--
2.1.4
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/4] pinctrl: baytrail: Relax GPIO request rules
2015-02-23 12:53 [PATCH 0/4] pinctrl: baytrail: Assorted fixes Mika Westerberg
@ 2015-02-23 12:53 ` Mika Westerberg
2015-03-06 11:20 ` Linus Walleij
2015-02-23 12:53 ` [PATCH 2/4] pinctrl: baytrail: Clear interrupt triggering from pins that are in GPIO mode Mika Westerberg
` (2 subsequent siblings)
3 siblings, 1 reply; 8+ messages in thread
From: Mika Westerberg @ 2015-02-23 12:53 UTC (permalink / raw)
To: Linus Walleij
Cc: Heikki Krogerus, Mathias Nyman, Hans Holmberg, Benjamin Adler,
Mika Westerberg, linux-gpio, linux-kernel
Zotac ZBOX PI320, a Baytrail based mini-PC, has power button connected to a
GPIO pin and it is exposed to the operating system as Windows 8 button
array. This is implemented in Linux as a driver using gpio_keys.
However, BIOS on this particula machine forgot to mux the pin to be a GPIO
instead of native function, which results following message to be seen on
the console:
byt_gpio INT33FC:02: pin 16 cannot be used as GPIO.
This causes power button to not work as the driver was not able to request
the GPIO it needs.
So instead of completely preventing this we allow turning the pin as GPIO
but issue warning that something might be wrong.
Reported-by: Benjamin Adler <benadler@gmx.net>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/pinctrl/intel/pinctrl-baytrail.c | 35 ++++++++++++++++++++------------
1 file changed, 22 insertions(+), 13 deletions(-)
diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c
index 5afe03e28b91..e44f2fd6753f 100644
--- a/drivers/pinctrl/intel/pinctrl-baytrail.c
+++ b/drivers/pinctrl/intel/pinctrl-baytrail.c
@@ -158,40 +158,49 @@ static void __iomem *byt_gpio_reg(struct gpio_chip *chip, unsigned offset,
return vg->reg_base + reg_offset + reg;
}
-static bool is_special_pin(struct byt_gpio *vg, unsigned offset)
+static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned offset)
{
/* SCORE pin 92-93 */
if (!strcmp(vg->range->name, BYT_SCORE_ACPI_UID) &&
offset >= 92 && offset <= 93)
- return true;
+ return 1;
/* SUS pin 11-21 */
if (!strcmp(vg->range->name, BYT_SUS_ACPI_UID) &&
offset >= 11 && offset <= 21)
- return true;
+ return 1;
- return false;
+ return 0;
}
static int byt_gpio_request(struct gpio_chip *chip, unsigned offset)
{
struct byt_gpio *vg = to_byt_gpio(chip);
void __iomem *reg = byt_gpio_reg(chip, offset, BYT_CONF0_REG);
- u32 value;
- bool special;
+ u32 value, gpio_mux;
/*
* In most cases, func pin mux 000 means GPIO function.
* But, some pins may have func pin mux 001 represents
- * GPIO function. Only allow user to export pin with
- * func pin mux preset as GPIO function by BIOS/FW.
+ * GPIO function.
+ *
+ * Because there are devices out there where some pins were not
+ * configured correctly we allow changing the mux value from
+ * request (but print out warning about that).
*/
value = readl(reg) & BYT_PIN_MUX;
- special = is_special_pin(vg, offset);
- if ((special && value != 1) || (!special && value)) {
- dev_err(&vg->pdev->dev,
- "pin %u cannot be used as GPIO.\n", offset);
- return -EINVAL;
+ gpio_mux = byt_get_gpio_mux(vg, offset);
+ if (WARN_ON(gpio_mux != value)) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&vg->lock, flags);
+ value = readl(reg) & ~BYT_PIN_MUX;
+ value |= gpio_mux;
+ writel(value, reg);
+ spin_unlock_irqrestore(&vg->lock, flags);
+
+ dev_warn(&vg->pdev->dev,
+ "pin %u forcibly re-configured as GPIO\n", offset);
}
pm_runtime_get(&vg->pdev->dev);
--
2.1.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/4] pinctrl: baytrail: Clear interrupt triggering from pins that are in GPIO mode
2015-02-23 12:53 [PATCH 0/4] pinctrl: baytrail: Assorted fixes Mika Westerberg
2015-02-23 12:53 ` [PATCH 1/4] pinctrl: baytrail: Relax GPIO request rules Mika Westerberg
@ 2015-02-23 12:53 ` Mika Westerberg
2015-03-06 11:21 ` Linus Walleij
2015-02-23 12:53 ` [PATCH 3/4] pinctrl: baytrail: Rework interrupt handling Mika Westerberg
2015-02-23 12:53 ` [PATCH 4/4] pinctrl: baytrail: Save pin context over system sleep Mika Westerberg
3 siblings, 1 reply; 8+ messages in thread
From: Mika Westerberg @ 2015-02-23 12:53 UTC (permalink / raw)
To: Linus Walleij
Cc: Heikki Krogerus, Mathias Nyman, Hans Holmberg, Benjamin Adler,
Mika Westerberg, linux-gpio, linux-kernel
If the pin is already configured as GPIO and it has any of the triggering
flags set, we may get spurious interrupts depending on the state of the
pin.
Prevent this by clearing the triggering flags on such pins. However, if the
pin is also configured as "direct IRQ" we leave the flags as is. Otherwise
it will prevent interrupts that are routed directly to IO-APIC.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/pinctrl/intel/pinctrl-baytrail.c | 36 +++++++++++++++++++++++++-------
1 file changed, 29 insertions(+), 7 deletions(-)
diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c
index e44f2fd6753f..d264b099182d 100644
--- a/drivers/pinctrl/intel/pinctrl-baytrail.c
+++ b/drivers/pinctrl/intel/pinctrl-baytrail.c
@@ -158,6 +158,19 @@ static void __iomem *byt_gpio_reg(struct gpio_chip *chip, unsigned offset,
return vg->reg_base + reg_offset + reg;
}
+static void byt_gpio_clear_triggering(struct byt_gpio *vg, unsigned offset)
+{
+ void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG);
+ unsigned long flags;
+ u32 value;
+
+ spin_lock_irqsave(&vg->lock, flags);
+ value = readl(reg);
+ value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
+ writel(value, reg);
+ spin_unlock_irqrestore(&vg->lock, flags);
+}
+
static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned offset)
{
/* SCORE pin 92-93 */
@@ -211,14 +224,8 @@ static int byt_gpio_request(struct gpio_chip *chip, unsigned offset)
static void byt_gpio_free(struct gpio_chip *chip, unsigned offset)
{
struct byt_gpio *vg = to_byt_gpio(chip);
- void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG);
- u32 value;
-
- /* clear interrupt triggering */
- value = readl(reg);
- value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
- writel(value, reg);
+ byt_gpio_clear_triggering(vg, offset);
pm_runtime_put(&vg->pdev->dev);
}
@@ -481,6 +488,21 @@ static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
{
void __iomem *reg;
u32 base, value;
+ int i;
+
+ /*
+ * Clear interrupt triggers for all pins that are GPIOs and
+ * do not use direct IRQ mode. This will prevent spurious
+ * interrupts from misconfigured pins.
+ */
+ for (i = 0; i < vg->chip.ngpio; i++) {
+ value = readl(byt_gpio_reg(&vg->chip, i, BYT_CONF0_REG));
+ if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i) &&
+ !(value & BYT_DIRECT_IRQ_EN)) {
+ byt_gpio_clear_triggering(vg, i);
+ dev_dbg(&vg->pdev->dev, "disabling GPIO %d\n", i);
+ }
+ }
/* clear interrupt status trigger registers */
for (base = 0; base < vg->chip.ngpio; base += 32) {
--
2.1.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/4] pinctrl: baytrail: Rework interrupt handling
2015-02-23 12:53 [PATCH 0/4] pinctrl: baytrail: Assorted fixes Mika Westerberg
2015-02-23 12:53 ` [PATCH 1/4] pinctrl: baytrail: Relax GPIO request rules Mika Westerberg
2015-02-23 12:53 ` [PATCH 2/4] pinctrl: baytrail: Clear interrupt triggering from pins that are in GPIO mode Mika Westerberg
@ 2015-02-23 12:53 ` Mika Westerberg
2015-03-06 11:23 ` Linus Walleij
2015-02-23 12:53 ` [PATCH 4/4] pinctrl: baytrail: Save pin context over system sleep Mika Westerberg
3 siblings, 1 reply; 8+ messages in thread
From: Mika Westerberg @ 2015-02-23 12:53 UTC (permalink / raw)
To: Linus Walleij
Cc: Heikki Krogerus, Mathias Nyman, Hans Holmberg, Benjamin Adler,
Mika Westerberg, linux-gpio, linux-kernel
Instead of handling everything in the driver's first level interrupt
handler, we can take advantage of already existing flow handlers that are
provided by the IRQ core.
This changes the functionality a bit also. Previously the driver looped
over pending interrupts in a single loop, restarting the loop if some
interrupt changed state. This caused problem with Lenovo Thinkpad 10
digitizer that it was not able to deassert the interrupt before the driver
disabled the interrupt for good (looplimit was exhausted).
Rework the interrupt handling logic a bit so that we provide proper mask,
ack and unmask operations in terms of Baytrail GPIO hardware and loop over
pending interrupts only once. If the interrupt remains asserted the first
level handler will be re-triggered automatically.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/pinctrl/intel/pinctrl-baytrail.c | 100 +++++++++++++++++--------------
1 file changed, 56 insertions(+), 44 deletions(-)
diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c
index d264b099182d..2318057a309b 100644
--- a/drivers/pinctrl/intel/pinctrl-baytrail.c
+++ b/drivers/pinctrl/intel/pinctrl-baytrail.c
@@ -252,23 +252,13 @@ static int byt_irq_type(struct irq_data *d, unsigned type)
value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG |
BYT_TRIG_LVL);
- switch (type) {
- case IRQ_TYPE_LEVEL_HIGH:
- value |= BYT_TRIG_LVL;
- case IRQ_TYPE_EDGE_RISING:
- value |= BYT_TRIG_POS;
- break;
- case IRQ_TYPE_LEVEL_LOW:
- value |= BYT_TRIG_LVL;
- case IRQ_TYPE_EDGE_FALLING:
- value |= BYT_TRIG_NEG;
- break;
- case IRQ_TYPE_EDGE_BOTH:
- value |= (BYT_TRIG_NEG | BYT_TRIG_POS);
- break;
- }
writel(value, reg);
+ if (type & IRQ_TYPE_EDGE_BOTH)
+ __irq_set_handler_locked(d->irq, handle_edge_irq);
+ else if (type & IRQ_TYPE_LEVEL_MASK)
+ __irq_set_handler_locked(d->irq, handle_level_irq);
+
spin_unlock_irqrestore(&vg->lock, flags);
return 0;
@@ -426,58 +416,80 @@ static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
struct irq_data *data = irq_desc_get_irq_data(desc);
struct byt_gpio *vg = to_byt_gpio(irq_desc_get_handler_data(desc));
struct irq_chip *chip = irq_data_get_irq_chip(data);
- u32 base, pin, mask;
+ u32 base, pin;
void __iomem *reg;
- u32 pending;
+ unsigned long pending;
unsigned virq;
- int looplimit = 0;
/* check from GPIO controller which pin triggered the interrupt */
for (base = 0; base < vg->chip.ngpio; base += 32) {
-
reg = byt_gpio_reg(&vg->chip, base, BYT_INT_STAT_REG);
-
- while ((pending = readl(reg))) {
- pin = __ffs(pending);
- mask = BIT(pin);
- /* Clear before handling so we can't lose an edge */
- writel(mask, reg);
-
+ pending = readl(reg);
+ for_each_set_bit(pin, &pending, 32) {
virq = irq_find_mapping(vg->chip.irqdomain, base + pin);
generic_handle_irq(virq);
-
- /* In case bios or user sets triggering incorretly a pin
- * might remain in "interrupt triggered" state.
- */
- if (looplimit++ > 32) {
- dev_err(&vg->pdev->dev,
- "Gpio %d interrupt flood, disabling\n",
- base + pin);
-
- reg = byt_gpio_reg(&vg->chip, base + pin,
- BYT_CONF0_REG);
- mask = readl(reg);
- mask &= ~(BYT_TRIG_NEG | BYT_TRIG_POS |
- BYT_TRIG_LVL);
- writel(mask, reg);
- mask = readl(reg); /* flush */
- break;
- }
}
}
chip->irq_eoi(data);
}
+static void byt_irq_ack(struct irq_data *d)
+{
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ struct byt_gpio *vg = to_byt_gpio(gc);
+ unsigned offset = irqd_to_hwirq(d);
+ void __iomem *reg;
+
+ reg = byt_gpio_reg(&vg->chip, offset, BYT_INT_STAT_REG);
+ writel(BIT(offset % 32), reg);
+}
+
static void byt_irq_unmask(struct irq_data *d)
{
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ struct byt_gpio *vg = to_byt_gpio(gc);
+ unsigned offset = irqd_to_hwirq(d);
+ unsigned long flags;
+ void __iomem *reg;
+ u32 value;
+
+ spin_lock_irqsave(&vg->lock, flags);
+
+ reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG);
+ value = readl(reg);
+
+ switch (irqd_get_trigger_type(d)) {
+ case IRQ_TYPE_LEVEL_HIGH:
+ value |= BYT_TRIG_LVL;
+ case IRQ_TYPE_EDGE_RISING:
+ value |= BYT_TRIG_POS;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ value |= BYT_TRIG_LVL;
+ case IRQ_TYPE_EDGE_FALLING:
+ value |= BYT_TRIG_NEG;
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ value |= (BYT_TRIG_NEG | BYT_TRIG_POS);
+ break;
+ }
+
+ writel(value, reg);
+
+ spin_unlock_irqrestore(&vg->lock, flags);
}
static void byt_irq_mask(struct irq_data *d)
{
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ struct byt_gpio *vg = to_byt_gpio(gc);
+
+ byt_gpio_clear_triggering(vg, irqd_to_hwirq(d));
}
static struct irq_chip byt_irqchip = {
.name = "BYT-GPIO",
+ .irq_ack = byt_irq_ack,
.irq_mask = byt_irq_mask,
.irq_unmask = byt_irq_unmask,
.irq_set_type = byt_irq_type,
--
2.1.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 4/4] pinctrl: baytrail: Save pin context over system sleep
2015-02-23 12:53 [PATCH 0/4] pinctrl: baytrail: Assorted fixes Mika Westerberg
` (2 preceding siblings ...)
2015-02-23 12:53 ` [PATCH 3/4] pinctrl: baytrail: Rework interrupt handling Mika Westerberg
@ 2015-02-23 12:53 ` Mika Westerberg
3 siblings, 0 replies; 8+ messages in thread
From: Mika Westerberg @ 2015-02-23 12:53 UTC (permalink / raw)
To: Linus Walleij
Cc: Heikki Krogerus, Mathias Nyman, Hans Holmberg, Benjamin Adler,
Mika Westerberg, linux-gpio, linux-kernel
The BIOS might reconfigure pins as it needs when S3 is entered. This might
cause drivers using the GPIOs to fail because the state was wrong or
interrupts stopped working.
Fix this by saving and restoring enough pin context over system sleep.
Reported-by: Hans Holmberg <hans.holmberg@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/pinctrl/intel/pinctrl-baytrail.c | 83 +++++++++++++++++++++++++++++++-
1 file changed, 81 insertions(+), 2 deletions(-)
diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c
index 2318057a309b..2062c224e32f 100644
--- a/drivers/pinctrl/intel/pinctrl-baytrail.c
+++ b/drivers/pinctrl/intel/pinctrl-baytrail.c
@@ -66,6 +66,10 @@
#define BYT_DIR_MASK (BIT(1) | BIT(2))
#define BYT_TRIG_MASK (BIT(26) | BIT(25) | BIT(24))
+#define BYT_CONF0_RESTORE_MASK (BYT_DIRECT_IRQ_EN | BYT_TRIG_MASK | \
+ BYT_PIN_MUX)
+#define BYT_VAL_RESTORE_MASK (BYT_DIR_MASK | BYT_LEVEL)
+
#define BYT_NGPIO_SCORE 102
#define BYT_NGPIO_NCORE 28
#define BYT_NGPIO_SUS 44
@@ -134,12 +138,18 @@ static struct pinctrl_gpio_range byt_ranges[] = {
},
};
+struct byt_gpio_pin_context {
+ u32 conf0;
+ u32 val;
+};
+
struct byt_gpio {
struct gpio_chip chip;
struct platform_device *pdev;
spinlock_t lock;
void __iomem *reg_base;
struct pinctrl_gpio_range *range;
+ struct byt_gpio_pin_context *saved_context;
};
#define to_byt_gpio(c) container_of(c, struct byt_gpio, chip)
@@ -584,6 +594,11 @@ static int byt_gpio_probe(struct platform_device *pdev)
gc->can_sleep = false;
gc->dev = dev;
+#ifdef CONFIG_PM_SLEEP
+ vg->saved_context = devm_kcalloc(&pdev->dev, gc->ngpio,
+ sizeof(*vg->saved_context), GFP_KERNEL);
+#endif
+
ret = gpiochip_add(gc);
if (ret) {
dev_err(&pdev->dev, "failed adding byt-gpio chip\n");
@@ -612,6 +627,69 @@ static int byt_gpio_probe(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_PM_SLEEP
+static int byt_gpio_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct byt_gpio *vg = platform_get_drvdata(pdev);
+ int i;
+
+ for (i = 0; i < vg->chip.ngpio; i++) {
+ void __iomem *reg;
+ u32 value;
+
+ reg = byt_gpio_reg(&vg->chip, i, BYT_CONF0_REG);
+ value = readl(reg) & BYT_CONF0_RESTORE_MASK;
+ vg->saved_context[i].conf0 = value;
+
+ reg = byt_gpio_reg(&vg->chip, i, BYT_VAL_REG);
+ value = readl(reg) & BYT_VAL_RESTORE_MASK;
+ vg->saved_context[i].val = value;
+ }
+
+ return 0;
+}
+
+static int byt_gpio_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct byt_gpio *vg = platform_get_drvdata(pdev);
+ int i;
+
+ for (i = 0; i < vg->chip.ngpio; i++) {
+ void __iomem *reg;
+ u32 value;
+
+ reg = byt_gpio_reg(&vg->chip, i, BYT_CONF0_REG);
+ value = readl(reg);
+ if ((value & BYT_CONF0_RESTORE_MASK) !=
+ vg->saved_context[i].conf0) {
+ value &= ~BYT_CONF0_RESTORE_MASK;
+ value |= vg->saved_context[i].conf0;
+ writel(value, reg);
+ dev_info(dev, "restored pin %d conf0 %#08x", i, value);
+ }
+
+ reg = byt_gpio_reg(&vg->chip, i, BYT_VAL_REG);
+ value = readl(reg);
+ if ((value & BYT_VAL_RESTORE_MASK) !=
+ vg->saved_context[i].val) {
+ u32 v;
+
+ v = value & ~BYT_VAL_RESTORE_MASK;
+ v |= vg->saved_context[i].val;
+ if (v != value) {
+ writel(v, reg);
+ dev_dbg(dev, "restored pin %d val %#08x\n",
+ i, v);
+ }
+ }
+ }
+
+ return 0;
+}
+#endif
+
static int byt_gpio_runtime_suspend(struct device *dev)
{
return 0;
@@ -623,8 +701,9 @@ static int byt_gpio_runtime_resume(struct device *dev)
}
static const struct dev_pm_ops byt_gpio_pm_ops = {
- .runtime_suspend = byt_gpio_runtime_suspend,
- .runtime_resume = byt_gpio_runtime_resume,
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(byt_gpio_suspend, byt_gpio_resume)
+ SET_RUNTIME_PM_OPS(byt_gpio_runtime_suspend, byt_gpio_runtime_resume,
+ NULL)
};
static const struct acpi_device_id byt_gpio_acpi_match[] = {
--
2.1.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 1/4] pinctrl: baytrail: Relax GPIO request rules
2015-02-23 12:53 ` [PATCH 1/4] pinctrl: baytrail: Relax GPIO request rules Mika Westerberg
@ 2015-03-06 11:20 ` Linus Walleij
0 siblings, 0 replies; 8+ messages in thread
From: Linus Walleij @ 2015-03-06 11:20 UTC (permalink / raw)
To: Mika Westerberg
Cc: Heikki Krogerus, Mathias Nyman, Hans Holmberg, Benjamin Adler,
linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org
On Mon, Feb 23, 2015 at 1:53 PM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> Zotac ZBOX PI320, a Baytrail based mini-PC, has power button connected to a
> GPIO pin and it is exposed to the operating system as Windows 8 button
> array. This is implemented in Linux as a driver using gpio_keys.
>
> However, BIOS on this particula machine forgot to mux the pin to be a GPIO
> instead of native function, which results following message to be seen on
> the console:
>
> byt_gpio INT33FC:02: pin 16 cannot be used as GPIO.
>
> This causes power button to not work as the driver was not able to request
> the GPIO it needs.
>
> So instead of completely preventing this we allow turning the pin as GPIO
> but issue warning that something might be wrong.
>
> Reported-by: Benjamin Adler <benadler@gmx.net>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Patch applied for fixes.
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/4] pinctrl: baytrail: Clear interrupt triggering from pins that are in GPIO mode
2015-02-23 12:53 ` [PATCH 2/4] pinctrl: baytrail: Clear interrupt triggering from pins that are in GPIO mode Mika Westerberg
@ 2015-03-06 11:21 ` Linus Walleij
0 siblings, 0 replies; 8+ messages in thread
From: Linus Walleij @ 2015-03-06 11:21 UTC (permalink / raw)
To: Mika Westerberg
Cc: Heikki Krogerus, Mathias Nyman, Hans Holmberg, Benjamin Adler,
linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org
On Mon, Feb 23, 2015 at 1:53 PM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> If the pin is already configured as GPIO and it has any of the triggering
> flags set, we may get spurious interrupts depending on the state of the
> pin.
>
> Prevent this by clearing the triggering flags on such pins. However, if the
> pin is also configured as "direct IRQ" we leave the flags as is. Otherwise
> it will prevent interrupts that are routed directly to IO-APIC.
>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Patch applied for fixes.
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 3/4] pinctrl: baytrail: Rework interrupt handling
2015-02-23 12:53 ` [PATCH 3/4] pinctrl: baytrail: Rework interrupt handling Mika Westerberg
@ 2015-03-06 11:23 ` Linus Walleij
0 siblings, 0 replies; 8+ messages in thread
From: Linus Walleij @ 2015-03-06 11:23 UTC (permalink / raw)
To: Mika Westerberg
Cc: Heikki Krogerus, Mathias Nyman, Hans Holmberg, Benjamin Adler,
linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org
On Mon, Feb 23, 2015 at 1:53 PM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> Instead of handling everything in the driver's first level interrupt
> handler, we can take advantage of already existing flow handlers that are
> provided by the IRQ core.
>
> This changes the functionality a bit also. Previously the driver looped
> over pending interrupts in a single loop, restarting the loop if some
> interrupt changed state. This caused problem with Lenovo Thinkpad 10
> digitizer that it was not able to deassert the interrupt before the driver
> disabled the interrupt for good (looplimit was exhausted).
>
> Rework the interrupt handling logic a bit so that we provide proper mask,
> ack and unmask operations in terms of Baytrail GPIO hardware and loop over
> pending interrupts only once. If the interrupt remains asserted the first
> level handler will be re-triggered automatically.
>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Patch applied for fixes.
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2015-03-06 11:23 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-02-23 12:53 [PATCH 0/4] pinctrl: baytrail: Assorted fixes Mika Westerberg
2015-02-23 12:53 ` [PATCH 1/4] pinctrl: baytrail: Relax GPIO request rules Mika Westerberg
2015-03-06 11:20 ` Linus Walleij
2015-02-23 12:53 ` [PATCH 2/4] pinctrl: baytrail: Clear interrupt triggering from pins that are in GPIO mode Mika Westerberg
2015-03-06 11:21 ` Linus Walleij
2015-02-23 12:53 ` [PATCH 3/4] pinctrl: baytrail: Rework interrupt handling Mika Westerberg
2015-03-06 11:23 ` Linus Walleij
2015-02-23 12:53 ` [PATCH 4/4] pinctrl: baytrail: Save pin context over system sleep Mika Westerberg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).