aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl
diff options
context:
space:
mode:
authorThomas Petazzoni <thomas.petazzoni@free-electrons.com>2015-03-19 06:30:47 -0400
committerLinus Walleij <linus.walleij@linaro.org>2015-03-27 04:35:08 -0400
commit12149a20b86330d6eac71edaad0357541abdcd05 (patch)
tree2e0d48e7233045c309cbbb7d11670516dc3c319e /drivers/pinctrl
parenta8381faca5ec90b7eea94ce575e90af86e2c9a9e (diff)
pinctrl: mvebu: add suspend/resume support to Armada XP pinctrl driver
This commit adds suspend/resume support to the Armada XP pinctrl driver, by simply saving and restoring the MPP registers. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r--drivers/pinctrl/mvebu/pinctrl-armada-xp.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-xp.c b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c
index fc3376147c18..d191c3a24885 100644
--- a/drivers/pinctrl/mvebu/pinctrl-armada-xp.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c
@@ -34,6 +34,7 @@
34#include "pinctrl-mvebu.h" 34#include "pinctrl-mvebu.h"
35 35
36static void __iomem *mpp_base; 36static void __iomem *mpp_base;
37static u32 *mpp_saved_regs;
37 38
38static int armada_xp_mpp_ctrl_get(unsigned pid, unsigned long *config) 39static int armada_xp_mpp_ctrl_get(unsigned pid, unsigned long *config)
39{ 40{
@@ -406,12 +407,42 @@ static struct pinctrl_gpio_range mv78460_mpp_gpio_ranges[] = {
406 MPP_GPIO_RANGE(2, 64, 64, 3), 407 MPP_GPIO_RANGE(2, 64, 64, 3),
407}; 408};
408 409
410static int armada_xp_pinctrl_suspend(struct platform_device *pdev,
411 pm_message_t state)
412{
413 struct mvebu_pinctrl_soc_info *soc =
414 platform_get_drvdata(pdev);
415 int i, nregs;
416
417 nregs = DIV_ROUND_UP(soc->nmodes, MVEBU_MPPS_PER_REG);
418
419 for (i = 0; i < nregs; i++)
420 mpp_saved_regs[i] = readl(mpp_base + i * 4);
421
422 return 0;
423}
424
425static int armada_xp_pinctrl_resume(struct platform_device *pdev)
426{
427 struct mvebu_pinctrl_soc_info *soc =
428 platform_get_drvdata(pdev);
429 int i, nregs;
430
431 nregs = DIV_ROUND_UP(soc->nmodes, MVEBU_MPPS_PER_REG);
432
433 for (i = 0; i < nregs; i++)
434 writel(mpp_saved_regs[i], mpp_base + i * 4);
435
436 return 0;
437}
438
409static int armada_xp_pinctrl_probe(struct platform_device *pdev) 439static int armada_xp_pinctrl_probe(struct platform_device *pdev)
410{ 440{
411 struct mvebu_pinctrl_soc_info *soc = &armada_xp_pinctrl_info; 441 struct mvebu_pinctrl_soc_info *soc = &armada_xp_pinctrl_info;
412 const struct of_device_id *match = 442 const struct of_device_id *match =
413 of_match_device(armada_xp_pinctrl_of_match, &pdev->dev); 443 of_match_device(armada_xp_pinctrl_of_match, &pdev->dev);
414 struct resource *res; 444 struct resource *res;
445 int nregs;
415 446
416 if (!match) 447 if (!match)
417 return -ENODEV; 448 return -ENODEV;
@@ -459,6 +490,13 @@ static int armada_xp_pinctrl_probe(struct platform_device *pdev)
459 break; 490 break;
460 } 491 }
461 492
493 nregs = DIV_ROUND_UP(soc->nmodes, MVEBU_MPPS_PER_REG);
494
495 mpp_saved_regs = devm_kmalloc(&pdev->dev, nregs * sizeof(u32),
496 GFP_KERNEL);
497 if (!mpp_saved_regs)
498 return -ENOMEM;
499
462 pdev->dev.platform_data = soc; 500 pdev->dev.platform_data = soc;
463 501
464 return mvebu_pinctrl_probe(pdev); 502 return mvebu_pinctrl_probe(pdev);
@@ -476,6 +514,8 @@ static struct platform_driver armada_xp_pinctrl_driver = {
476 }, 514 },
477 .probe = armada_xp_pinctrl_probe, 515 .probe = armada_xp_pinctrl_probe,
478 .remove = armada_xp_pinctrl_remove, 516 .remove = armada_xp_pinctrl_remove,
517 .suspend = armada_xp_pinctrl_suspend,
518 .resume = armada_xp_pinctrl_resume,
479}; 519};
480 520
481module_platform_driver(armada_xp_pinctrl_driver); 521module_platform_driver(armada_xp_pinctrl_driver);