All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tomasz Figa <t.figa@samsung.com>
To: Doug Anderson <dianders@chromium.org>
Cc: "Tomasz Figa" <tomasz.figa@gmail.com>,
	"Kukjin Kim" <kgene.kim@samsung.com>,
	"Heiko Stübner" <heiko@sntech.de>,
	"Olof Johansson" <olof@lixom.net>,
	"Stephen Warren" <swarren@wwwdotorg.org>,
	"Thomas Abraham" <thomas.abraham@linaro.org>,
	"Linus Walleij" <linus.walleij@linaro.org>,
	"Prathyush K" <prathyush.k@samsung.com>,
	linux-samsung-soc@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3] pinctrl: samsung: fix suspend/resume functionality
Date: Fri, 17 May 2013 16:38:10 +0200	[thread overview]
Message-ID: <1787926.aULH9sGxck@amdc1227> (raw)
In-Reply-To: <1368765198-25550-1-git-send-email-dianders@chromium.org>

Hi Doug,

On Thursday 16 of May 2013 21:33:18 Doug Anderson wrote:
> The GPIO states need to be restored after s2r and this is not currently
> supported in the pinctrl driver. This patch saves the gpio states before
> suspend and restores them after resume.
> 
> Saving and restoring is done very early using syscore_ops and must
> happen before pins are released from their powerdown state.
> 
> Patch originally from Prathyush K <prathyush.k@samsung.com> but
> rewritten by Doug Anderson <dianders@chromium.org>.
> 
> Signed-off-by: Prathyush K <prathyush.k@samsung.com>
> Signed-off-by: Doug Anderson <dianders@chromium.org>
> ---
> Changes in v3:
> - Skip save and restore for banks with no powerdown config.
> 
> Changes in v2:
> - Now uses sycore_ops to make sure we're early enough.
> - Try to handle two CON registers better.
> - Should handle s3c24xx better as per Heiko.
> - Simpler code; no longer tries to avoid glitching lines since
>   we _think_ all current SoCs should have pins in power down state
>   when the restore is called.
> - Dropped eint patch for now; Tomasz will post his version.
> 
>  drivers/pinctrl/pinctrl-samsung.c | 148
> ++++++++++++++++++++++++++++++++++++++ drivers/pinctrl/pinctrl-samsung.h | 
>  5 ++
>  2 files changed, 153 insertions(+)

On Exynos4210-based Trats board:

Tested-by: Tomasz Figa <t.figa@samsung.com>

Acked-by: Tomasz Figa <t.figa@samsung.com>

I will send several complementary patches in a while.

Best regards,
-- 
Tomasz Figa
Linux Kernel Developer
Samsung R&D Institute Poland
Samsung Electronics

> diff --git a/drivers/pinctrl/pinctrl-samsung.c
> b/drivers/pinctrl/pinctrl-samsung.c index 9763668..d45e36f 100644
> --- a/drivers/pinctrl/pinctrl-samsung.c
> +++ b/drivers/pinctrl/pinctrl-samsung.c
> @@ -28,6 +28,7 @@
>  #include <linux/gpio.h>
>  #include <linux/irqdomain.h>
>  #include <linux/spinlock.h>
> +#include <linux/syscore_ops.h>
> 
>  #include "core.h"
>  #include "pinctrl-samsung.h"
> @@ -48,6 +49,9 @@ static struct pin_config {
>  	{ "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN },
>  };
> 
> +/* Global list of devices (struct samsung_pinctrl_drv_data) */
> +LIST_HEAD(drvdata_list);
> +
>  static unsigned int pin_base;
> 
>  static inline struct samsung_pin_bank *gc_to_pin_bank(struct gpio_chip *gc)
> @@ -961,9 +965,145 @@ static int samsung_pinctrl_probe(struct
> platform_device *pdev) ctrl->eint_wkup_init(drvdata);
> 
>  	platform_set_drvdata(pdev, drvdata);
> +
> +	/* Add to the global list */
> +	list_add_tail(&drvdata->node, &drvdata_list);
> +
>  	return 0;
>  }
> 
> +#ifdef CONFIG_PM
> +
> +/**
> + * samsung_pinctrl_suspend_dev - save pinctrl state for suspend for a
> device + *
> + * Save data for all banks handled by this device.
> + */
> +static void samsung_pinctrl_suspend_dev(
> +	struct samsung_pinctrl_drv_data *drvdata)
> +{
> +	struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
> +	void __iomem *virt_base = drvdata->virt_base;
> +	int i;
> +
> +	for (i = 0; i < ctrl->nr_banks; i++) {
> +		struct samsung_pin_bank *bank = &ctrl->pin_banks[i];
> +		void __iomem *reg = virt_base + bank->pctl_offset;
> +
> +		u8 *offs = bank->type->reg_offset;
> +		u8 *widths = bank->type->fld_width;
> +		enum pincfg_type type;
> +
> +		/* Registers without a powerdown config aren't lost */
> +		if (!widths[PINCFG_TYPE_CON_PDN])
> +			continue;
> +
> +		for (type = 0; type < PINCFG_TYPE_NUM; type++)
> +			if (widths[type])
> +				bank->pm_save[type] = readl(reg + offs[type]);
> +
> +		if (widths[PINCFG_TYPE_FUNC] * bank->nr_pins > 32) {
> +			/* Some banks have two config registers */
> +			bank->pm_save[PINCFG_TYPE_NUM] =
> +				readl(reg + offs[PINCFG_TYPE_FUNC] + 4);
> +			pr_debug("Save %s @ %p (con %#010x %08x)\n",
> +				 bank->name, reg,
> +				 bank->pm_save[PINCFG_TYPE_FUNC],
> +				 bank->pm_save[PINCFG_TYPE_NUM]);
> +		} else {
> +			pr_debug("Save %s @ %p (con %#010x)\n", bank->name,
> +				 reg, bank->pm_save[PINCFG_TYPE_FUNC]);
> +		}
> +	}
> +}
> +
> +/**
> + * samsung_pinctrl_resume_dev - restore pinctrl state from suspend for a
> device + *
> + * Restore one of the banks that was saved during suspend.
> + *
> + * We don't bother doing anything complicated to avoid glitching lines
> since + * we're called before pad retention is turned off.
> + */
> +static void samsung_pinctrl_resume_dev(struct samsung_pinctrl_drv_data
> *drvdata) +{
> +	struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
> +	void __iomem *virt_base = drvdata->virt_base;
> +	int i;
> +
> +	for (i = 0; i < ctrl->nr_banks; i++) {
> +		struct samsung_pin_bank *bank = &ctrl->pin_banks[i];
> +		void __iomem *reg = virt_base + bank->pctl_offset;
> +
> +		u8 *offs = bank->type->reg_offset;
> +		u8 *widths = bank->type->fld_width;
> +		enum pincfg_type type;
> +
> +		/* Registers without a powerdown config aren't lost */
> +		if (!widths[PINCFG_TYPE_CON_PDN])
> +			continue;
> +
> +		if (widths[PINCFG_TYPE_FUNC] * bank->nr_pins > 32) {
> +			/* Some banks have two config registers */
> +			pr_debug("%s @ %p (con %#010x %08x => %#010x %08x)\n",
> +				 bank->name, reg,
> +				 readl(reg + offs[PINCFG_TYPE_FUNC]),
> +				 readl(reg + offs[PINCFG_TYPE_FUNC] + 4),
> +				 bank->pm_save[PINCFG_TYPE_FUNC],
> +				 bank->pm_save[PINCFG_TYPE_NUM]);
> +			writel(bank->pm_save[PINCFG_TYPE_NUM],
> +			       reg + offs[PINCFG_TYPE_FUNC] + 4);
> +		} else {
> +			pr_debug("%s @ %p (con %#010x => %#010x)\n", bank->name,
> +				 reg, readl(reg + offs[PINCFG_TYPE_FUNC]),
> +				 bank->pm_save[PINCFG_TYPE_FUNC]);
> +		}
> +		for (type = 0; type < PINCFG_TYPE_NUM; type++)
> +			if (widths[type])
> +				writel(bank->pm_save[type], reg + offs[type]);
> +	}
> +}
> +
> +/**
> + * samsung_pinctrl_suspend - save pinctrl state for suspend
> + *
> + * Save data for all banks across all devices.
> + */
> +static int samsung_pinctrl_suspend(void)
> +{
> +	struct samsung_pinctrl_drv_data *drvdata;
> +
> +	list_for_each_entry(drvdata, &drvdata_list, node) {
> +		samsung_pinctrl_suspend_dev(drvdata);
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * samsung_pinctrl_resume - restore pinctrl state for suspend
> + *
> + * Restore data for all banks across all devices.
> + */
> +static void samsung_pinctrl_resume(void)
> +{
> +	struct samsung_pinctrl_drv_data *drvdata;
> +
> +	list_for_each_entry_reverse(drvdata, &drvdata_list, node) {
> +		samsung_pinctrl_resume_dev(drvdata);
> +	}
> +}
> +
> +#else
> +#define samsung_pinctrl_suspend		NULL
> +#define samsung_pinctrl_resume		NULL
> +#endif
> +
> +static struct syscore_ops samsung_pinctrl_syscore_ops = {
> +	.suspend	= samsung_pinctrl_suspend,
> +	.resume		= samsung_pinctrl_resume,
> +};
> +
>  static const struct of_device_id samsung_pinctrl_dt_match[] = {
>  #ifdef CONFIG_PINCTRL_EXYNOS
>  	{ .compatible = "samsung,exynos4210-pinctrl",
> @@ -992,6 +1132,14 @@ static struct platform_driver samsung_pinctrl_driver =
> {
> 
>  static int __init samsung_pinctrl_drv_register(void)
>  {
> +	/*
> +	 * Register syscore ops for save/restore of registers across suspend.
> +	 * It's important to ensure that this driver is running at an earlier
> +	 * initcall level than any arch-specific init calls that install syscore
> +	 * ops that turn off pad retention (like exynos_pm_resume).
> +	 */
> +	register_syscore_ops(&samsung_pinctrl_syscore_ops);
> +
>  	return platform_driver_register(&samsung_pinctrl_driver);
>  }
>  postcore_initcall(samsung_pinctrl_drv_register);
> diff --git a/drivers/pinctrl/pinctrl-samsung.h
> b/drivers/pinctrl/pinctrl-samsung.h index 7c7f9eb..9f5cc81 100644
> --- a/drivers/pinctrl/pinctrl-samsung.h
> +++ b/drivers/pinctrl/pinctrl-samsung.h
> @@ -127,6 +127,7 @@ struct samsung_pin_bank_type {
>   * @gpio_chip: GPIO chip of the bank.
>   * @grange: linux gpio pin range supported by this bank.
>   * @slock: spinlock protecting bank registers
> + * @pm_save: saved register values during suspend
>   */
>  struct samsung_pin_bank {
>  	struct samsung_pin_bank_type *type;
> @@ -144,6 +145,8 @@ struct samsung_pin_bank {
>  	struct gpio_chip gpio_chip;
>  	struct pinctrl_gpio_range grange;
>  	spinlock_t slock;
> +
> +	u32 pm_save[PINCFG_TYPE_NUM + 1]; /* +1 to handle double CON registers*/
>  };
> 
>  /**
> @@ -189,6 +192,7 @@ struct samsung_pin_ctrl {
> 
>  /**
>   * struct samsung_pinctrl_drv_data: wrapper for holding driver data
> together. + * @node: global list node
>   * @virt_base: register base address of the controller.
>   * @dev: device instance representing the controller.
>   * @irq: interrpt number used by the controller to notify gpio interrupts.
> @@ -201,6 +205,7 @@ struct samsung_pin_ctrl {
>   * @nr_function: number of such pin functions.
>   */
>  struct samsung_pinctrl_drv_data {
> +	struct list_head		node;
>  	void __iomem			*virt_base;
>  	struct device			*dev;
>  	int				irq;

  reply	other threads:[~2013-05-17 14:38 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-05-16 17:12 [PATCH 0/2] Fix suspend/resume issues created by pinmux on exynos Doug Anderson
2013-05-16 17:12 ` [PATCH 1/2] pinctrl: samsung: fix suspend/resume functionality Doug Anderson
2013-05-16 19:19   ` Tomasz Figa
2013-05-16 20:32     ` Doug Anderson
2013-05-16 21:27       ` Tomasz Figa
2013-05-16 21:51         ` Doug Anderson
2013-05-16 22:08           ` Tomasz Figa
2013-05-16 22:30             ` Heiko Stübner
2013-05-16 22:56               ` Tomasz Figa
2013-05-16 23:10                 ` Doug Anderson
2013-05-16 23:55                   ` Doug Anderson
2013-05-16 21:19     ` Heiko Stübner
2013-05-16 17:12 ` [PATCH 2/2] pinctrl: exynos: fix eint wakeup by using irq_set_wake() Doug Anderson
2013-05-16 19:26   ` Tomasz Figa
2013-05-16 22:25     ` Doug Anderson
2013-05-16 22:37       ` Tomasz Figa
2013-05-16 23:49         ` Doug Anderson
2013-05-16 23:19 ` [PATCH v2] pinctrl: samsung: fix suspend/resume functionality Doug Anderson
2013-05-17  4:33   ` [PATCH v3] " Doug Anderson
2013-05-17 14:38     ` Tomasz Figa [this message]
2013-05-20 11:47     ` Linus Walleij
2013-05-20 14:59       ` Doug Anderson
2013-05-20 16:16         ` Kukjin Kim
2013-05-21  6:26         ` Olof Johansson
2013-05-21 11:21     ` Linus Walleij

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1787926.aULH9sGxck@amdc1227 \
    --to=t.figa@samsung.com \
    --cc=dianders@chromium.org \
    --cc=heiko@sntech.de \
    --cc=kgene.kim@samsung.com \
    --cc=linus.walleij@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=olof@lixom.net \
    --cc=prathyush.k@samsung.com \
    --cc=swarren@wwwdotorg.org \
    --cc=thomas.abraham@linaro.org \
    --cc=tomasz.figa@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.