Created
November 16, 2017 10:59
-
-
Save dsd/1f10c6c818569ceec11f910ad8a07228 to your computer and use it in GitHub Desktop.
intel-gpio base debug patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 70dde0c39f4923f453b8fac969fac8a1490e77db Mon Sep 17 00:00:00 2001 | |
From: Daniel Drake <drake@endlessm.com> | |
Date: Mon, 13 Nov 2017 09:27:30 +0800 | |
Subject: [PATCH] base debug patch | |
--- | |
drivers/hid/i2c-hid/i2c-hid.c | 7 +++- | |
drivers/pinctrl/intel/pinctrl-intel.c | 73 ++++++++++++++++++++++++++++++++++- | |
2 files changed, 76 insertions(+), 4 deletions(-) | |
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c | |
index 9145c2129a96..59c3762f741f 100644 | |
--- a/drivers/hid/i2c-hid/i2c-hid.c | |
+++ b/drivers/hid/i2c-hid/i2c-hid.c | |
@@ -493,12 +493,15 @@ static void i2c_hid_get_input(struct i2c_hid *ihid) | |
static irqreturn_t i2c_hid_irq(int irq, void *dev_id) | |
{ | |
struct i2c_hid *ihid = dev_id; | |
- | |
- if (test_bit(I2C_HID_READ_PENDING, &ihid->flags)) | |
+pr_err("i2c_hid_irq enter\n"); | |
+ if (test_bit(I2C_HID_READ_PENDING, &ihid->flags)) { | |
+pr_err("i2c_hid_irq exit - read pending\n"); | |
return IRQ_HANDLED; | |
+ } | |
i2c_hid_get_input(ihid); | |
+pr_err("i2c_hid_irq exit\n"); | |
return IRQ_HANDLED; | |
} | |
diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c | |
index 71df0f70b61f..42aede767b5a 100644 | |
--- a/drivers/pinctrl/intel/pinctrl-intel.c | |
+++ b/drivers/pinctrl/intel/pinctrl-intel.c | |
@@ -19,6 +19,7 @@ | |
#include <linux/pinctrl/pinmux.h> | |
#include <linux/pinctrl/pinconf.h> | |
#include <linux/pinctrl/pinconf-generic.h> | |
+#include <linux/timer.h> | |
#include "../core.h" | |
#include "pinctrl-intel.h" | |
@@ -114,6 +115,8 @@ struct intel_pinctrl { | |
size_t ncommunities; | |
struct intel_pinctrl_context context; | |
int irq; | |
+ struct timer_list debug_timer; | |
+ bool has_timer; | |
}; | |
#define pin_to_padno(c, p) ((p) - (c)->pin_base) | |
@@ -808,6 +811,37 @@ static const struct gpio_chip intel_gpio_chip = { | |
.set_config = gpiochip_generic_config, | |
}; | |
+static void log_regs(struct intel_pinctrl *pctrl, int pin, const char *msg) | |
+{ | |
+ const struct intel_padgroup *padgrp; | |
+ const struct intel_community *community; | |
+ unsigned gpp, gpp_offset; | |
+ unsigned long is, ie, padcfg; | |
+ void __iomem *reg; | |
+ | |
+ community = intel_get_community(pctrl, pin); | |
+ if (!community) | |
+ return; | |
+ | |
+ padgrp = intel_community_get_padgroup(community, pin); | |
+ if (!padgrp) | |
+ return; | |
+ | |
+ gpp = padgrp->reg_num; | |
+ gpp_offset = padgroup_offset(padgrp, pin); | |
+ | |
+ is = readl(community->regs + GPI_IS + gpp * 4); | |
+ ie = readl(community->regs + community->ie_offset + gpp * 4); | |
+ | |
+ reg = intel_get_padcfg(pctrl, pin, PADCFG0); | |
+ if (!reg) | |
+ return; | |
+ | |
+ padcfg = readl(reg); | |
+ | |
+ pr_err(" %s: pin=%d IS=%lx IE=%lx PADCFG0=%lx\n", msg, pin, is, ie, padcfg); | |
+} | |
+ | |
static void intel_gpio_irq_ack(struct irq_data *d) | |
{ | |
struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | |
@@ -820,6 +854,7 @@ static void intel_gpio_irq_ack(struct irq_data *d) | |
const struct intel_padgroup *padgrp; | |
unsigned gpp, gpp_offset; | |
+log_regs(pctrl, pin, "irq_ack before"); | |
padgrp = intel_community_get_padgroup(community, pin); | |
if (!padgrp) | |
return; | |
@@ -830,14 +865,16 @@ static void intel_gpio_irq_ack(struct irq_data *d) | |
raw_spin_lock(&pctrl->lock); | |
writel(BIT(gpp_offset), community->regs + GPI_IS + gpp * 4); | |
raw_spin_unlock(&pctrl->lock); | |
+log_regs(pctrl, pin, "irq_ack after"); | |
} | |
} | |
+static void timer_func(unsigned long arg); | |
static void intel_gpio_irq_enable(struct irq_data *d) | |
{ | |
struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | |
struct intel_pinctrl *pctrl = gpiochip_get_data(gc); | |
- const struct intel_community *community; | |
+ struct intel_community *community; | |
unsigned pin = irqd_to_hwirq(d); | |
community = intel_get_community(pctrl, pin); | |
@@ -846,6 +883,7 @@ static void intel_gpio_irq_enable(struct irq_data *d) | |
unsigned gpp, gpp_offset; | |
unsigned long flags; | |
u32 value; | |
+log_regs(pctrl, pin, "irq_enable before"); | |
padgrp = intel_community_get_padgroup(community, pin); | |
if (!padgrp) | |
@@ -862,6 +900,13 @@ static void intel_gpio_irq_enable(struct irq_data *d) | |
value |= BIT(gpp_offset); | |
writel(value, community->regs + community->ie_offset + gpp * 4); | |
raw_spin_unlock_irqrestore(&pctrl->lock, flags); | |
+log_regs(pctrl, pin, "irq_enable after"); | |
+ } | |
+ | |
+ if (!pctrl->has_timer) { | |
+ setup_timer(&pctrl->debug_timer, timer_func, (unsigned long) d); | |
+ mod_timer(&pctrl->debug_timer, jiffies + msecs_to_jiffies(1000)); | |
+ pctrl->has_timer = true; | |
} | |
} | |
@@ -872,6 +917,7 @@ static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask) | |
const struct intel_community *community; | |
unsigned pin = irqd_to_hwirq(d); | |
+pr_err("gpio_irq_mask_unmask: pin=%d mask=%d\n", pin, mask); | |
community = intel_get_community(pctrl, pin); | |
if (community) { | |
const struct intel_padgroup *padgrp; | |
@@ -879,6 +925,7 @@ static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask) | |
unsigned long flags; | |
void __iomem *reg; | |
u32 value; | |
+log_regs(pctrl, pin, "irq_mask_unmask before"); | |
padgrp = intel_community_get_padgroup(community, pin); | |
if (!padgrp) | |
@@ -896,7 +943,9 @@ static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask) | |
else | |
value |= BIT(gpp_offset); | |
writel(value, reg); | |
+ | |
raw_spin_unlock_irqrestore(&pctrl->lock, flags); | |
+log_regs(pctrl, pin, "irq_mask_unmask after"); | |
} | |
} | |
@@ -922,7 +971,9 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned type) | |
reg = intel_get_padcfg(pctrl, pin, PADCFG0); | |
if (!reg) | |
return -EINVAL; | |
+pr_err("gpio_irq_type: pin=%d type=%d\n", pin, type); | |
+log_regs(pctrl, pin, "irq_type before"); | |
/* | |
* If the pin is in ACPI mode it is still usable as a GPIO but it | |
* cannot be used as IRQ because GPI_IS status bit will not be | |
@@ -961,6 +1012,7 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned type) | |
irq_set_handler_locked(d, handle_level_irq); | |
raw_spin_unlock_irqrestore(&pctrl->lock, flags); | |
+log_regs(pctrl, pin, "irq_type after"); | |
return 0; | |
} | |
@@ -989,14 +1041,16 @@ static irqreturn_t intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl, | |
for (gpp = 0; gpp < community->ngpps; gpp++) { | |
const struct intel_padgroup *padgrp = &community->gpps[gpp]; | |
- unsigned long pending, enabled, gpp_offset; | |
+ unsigned long pending, p1, enabled, gpp_offset; | |
pending = readl(community->regs + GPI_IS + padgrp->reg_num * 4); | |
+ p1 = pending; | |
enabled = readl(community->regs + community->ie_offset + | |
padgrp->reg_num * 4); | |
/* Only interrupts that are enabled */ | |
pending &= enabled; | |
+pr_err("irq_handler: pending=%lx enabled=%lx so service %lx\n", p1, enabled, pending); | |
for_each_set_bit(gpp_offset, &pending, padgrp->size) { | |
unsigned padno, irq; | |
@@ -1005,6 +1059,8 @@ static irqreturn_t intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl, | |
if (padno >= community->npins) | |
break; | |
+log_regs(pctrl, community->pin_base + padno, "fire irq"); | |
+ | |
irq = irq_find_mapping(gc->irqdomain, | |
community->pin_base + padno); | |
generic_handle_irq(irq); | |
@@ -1023,15 +1079,28 @@ static irqreturn_t intel_gpio_irq(int irq, void *data) | |
irqreturn_t ret = IRQ_NONE; | |
int i; | |
+dev_err(pctrl->dev, "intel_gpio_irq enter\n"); | |
/* Need to check all communities for pending interrupts */ | |
for (i = 0; i < pctrl->ncommunities; i++) { | |
community = &pctrl->communities[i]; | |
ret |= intel_gpio_community_irq_handler(pctrl, community); | |
} | |
+dev_err(pctrl->dev, "intel_gpio_irq exit\n"); | |
return ret; | |
} | |
+static void timer_func(unsigned long arg) | |
+{ | |
+ struct irq_data *d = (struct irq_data *) arg; | |
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d); | |
+ struct intel_pinctrl *pctrl = gpiochip_get_data(gc); | |
+ unsigned pin = irqd_to_hwirq(d); | |
+ | |
+ log_regs(pctrl, pin, "debug timer"); | |
+ mod_timer(&pctrl->debug_timer, jiffies + msecs_to_jiffies(1000)); | |
+} | |
+ | |
static struct irq_chip intel_gpio_irqchip = { | |
.name = "intel-gpio", | |
.irq_enable = intel_gpio_irq_enable, | |
-- | |
2.14.1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment