Skip to content

Commit

Permalink
pinctrl: qcom: Add support to log pin status before suspend for TLMM
Browse files Browse the repository at this point in the history
This change supports to print pin status before device suspend
to debug for TLMM. And expose 2 APIs to enable/disable this
functionality.

Signed-off-by: Minghao Zhang <quic_minghao@quicinc.com>
  • Loading branch information
Minghao Zhang authored and intel-lab-lkp committed Mar 28, 2023
1 parent 94df03a commit 5a98341
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 29 deletions.
133 changes: 104 additions & 29 deletions drivers/pinctrl/qcom/pinctrl-msm.c
Expand Up @@ -83,6 +83,21 @@ struct msm_pinctrl {
u32 phys_base[MAX_NR_TILES];
};

static bool pinctrl_msm_log_mask;

static const char * const pulls_keeper[] = {
"no pull",
"pull down",
"keeper",
"pull up"
};

static const char * const pulls_no_keeper[] = {
"no pull",
"pull down",
"pull up",
};

#define MSM_ACCESSOR(name) \
static u32 msm_readl_##name(struct msm_pinctrl *pctrl, \
const struct msm_pingroup *g) \
Expand Down Expand Up @@ -628,6 +643,29 @@ static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
}

static void msm_gpio_pin_status_get(struct msm_pinctrl *pctrl, const struct msm_pingroup *g,
unsigned int offset, int *is_out, unsigned int *func,
int *drive, int *pull, int *egpio_enable, int *val)
{
u32 ctl_reg, io_reg;

ctl_reg = msm_readl_ctl(pctrl, g);
io_reg = msm_readl_io(pctrl, g);

*is_out = !!(ctl_reg & BIT(g->oe_bit));
*func = (ctl_reg >> g->mux_bit) & 7;
*drive = (ctl_reg >> g->drv_bit) & 7;
*pull = (ctl_reg >> g->pull_bit) & 3;
*egpio_enable = 0;
if (pctrl->soc->egpio_func && ctl_reg & BIT(g->egpio_present))
*egpio_enable = !(ctl_reg & BIT(g->egpio_enable));

if (*is_out)
*val = !!(io_reg & BIT(g->out_bit));
else
*val = !!(io_reg & BIT(g->in_bit));
}

#ifdef CONFIG_DEBUG_FS

static void msm_gpio_dbg_show_one(struct seq_file *s,
Expand All @@ -644,40 +682,13 @@ static void msm_gpio_dbg_show_one(struct seq_file *s,
int pull;
int val;
int egpio_enable;
u32 ctl_reg, io_reg;

static const char * const pulls_keeper[] = {
"no pull",
"pull down",
"keeper",
"pull up"
};

static const char * const pulls_no_keeper[] = {
"no pull",
"pull down",
"pull up",
};

if (!gpiochip_line_is_valid(chip, offset))
return;

g = &pctrl->soc->groups[offset];
ctl_reg = msm_readl_ctl(pctrl, g);
io_reg = msm_readl_io(pctrl, g);

is_out = !!(ctl_reg & BIT(g->oe_bit));
func = (ctl_reg >> g->mux_bit) & 7;
drive = (ctl_reg >> g->drv_bit) & 7;
pull = (ctl_reg >> g->pull_bit) & 3;
egpio_enable = 0;
if (pctrl->soc->egpio_func && ctl_reg & BIT(g->egpio_present))
egpio_enable = !(ctl_reg & BIT(g->egpio_enable));

if (is_out)
val = !!(io_reg & BIT(g->out_bit));
else
val = !!(io_reg & BIT(g->in_bit));
msm_gpio_pin_status_get(pctrl, g, offset, &is_out, &func,
&drive, &pull, &egpio_enable, &val);

if (egpio_enable) {
seq_printf(s, " %-8s: egpio\n", g->name);
Expand Down Expand Up @@ -707,6 +718,39 @@ static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
#define msm_gpio_dbg_show NULL
#endif

static void msm_gpio_log_pin_status(struct gpio_chip *chip, unsigned int offset)
{
const struct msm_pingroup *g;
struct msm_pinctrl *pctrl = gpiochip_get_data(chip);
unsigned int func;
int is_out;
int drive;
int pull;
int val;
int egpio_enable;

if (!gpiochip_line_is_valid(chip, offset))
return;

g = &pctrl->soc->groups[offset];
msm_gpio_pin_status_get(pctrl, g, offset, &is_out, &func,
&drive, &pull, &egpio_enable, &val);

printk_deferred("%s: %s, %s, func%d, %dmA, %s\n",
g->name, is_out ? "out" : "in",
val ? "high" : "low", func,
msm_regval_to_drive(drive),
pctrl->soc->pull_no_keeper ? pulls_no_keeper[pull] : pulls_keeper[pull]);
}

static void msm_gpios_status(struct gpio_chip *chip)
{
unsigned int i;

for (i = 0; i < chip->ngpio; i++)
msm_gpio_log_pin_status(chip, i);
}

static int msm_gpio_init_valid_mask(struct gpio_chip *gc,
unsigned long *valid_mask,
unsigned int ngpios)
Expand Down Expand Up @@ -1450,6 +1494,35 @@ SIMPLE_DEV_PM_OPS(msm_pinctrl_dev_pm_ops, msm_pinctrl_suspend,

EXPORT_SYMBOL(msm_pinctrl_dev_pm_ops);

void debug_pintctrl_msm_enable(void)
{
pinctrl_msm_log_mask = true;
}
EXPORT_SYMBOL(debug_pintctrl_msm_enable);

void debug_pintctrl_msm_disable(void)
{
pinctrl_msm_log_mask = false;
}
EXPORT_SYMBOL(debug_pintctrl_msm_disable);

static __maybe_unused int noirq_msm_pinctrl_suspend(struct device *dev)
{
struct msm_pinctrl *pctrl = dev_get_drvdata(dev);

if (pinctrl_msm_log_mask) {
printk_deferred("%s\n", pctrl->chip.label);
msm_gpios_status(&pctrl->chip);
}

return 0;
}

const struct dev_pm_ops noirq_msm_pinctrl_dev_pm_ops = {
.suspend_noirq = noirq_msm_pinctrl_suspend,
};
EXPORT_SYMBOL(noirq_msm_pinctrl_dev_pm_ops);

int msm_pinctrl_probe(struct platform_device *pdev,
const struct msm_pinctrl_soc_data *soc_data)
{
Expand Down Expand Up @@ -1511,6 +1584,8 @@ int msm_pinctrl_probe(struct platform_device *pdev,
if (ret)
return ret;

pinctrl_msm_log_mask = false;

platform_set_drvdata(pdev, pctrl);

dev_dbg(&pdev->dev, "Probed Qualcomm pinctrl driver\n");
Expand Down
1 change: 1 addition & 0 deletions drivers/pinctrl/qcom/pinctrl-msm.h
Expand Up @@ -155,6 +155,7 @@ struct msm_pinctrl_soc_data {
};

extern const struct dev_pm_ops msm_pinctrl_dev_pm_ops;
extern const struct dev_pm_ops noirq_msm_pinctrl_dev_pm_ops;

int msm_pinctrl_probe(struct platform_device *pdev,
const struct msm_pinctrl_soc_data *soc_data);
Expand Down

0 comments on commit 5a98341

Please sign in to comment.