Skip to content

Instantly share code, notes, and snippets.

@dsd
Created November 16, 2017 10:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dsd/1f10c6c818569ceec11f910ad8a07228 to your computer and use it in GitHub Desktop.
Save dsd/1f10c6c818569ceec11f910ad8a07228 to your computer and use it in GitHub Desktop.
intel-gpio base debug patch
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