diff options
author | Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | 2015-03-19 06:30:47 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2015-03-27 04:35:08 -0400 |
commit | 12149a20b86330d6eac71edaad0357541abdcd05 (patch) | |
tree | 2e0d48e7233045c309cbbb7d11670516dc3c319e /drivers/pinctrl | |
parent | a8381faca5ec90b7eea94ce575e90af86e2c9a9e (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.c | 40 |
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 | ||
36 | static void __iomem *mpp_base; | 36 | static void __iomem *mpp_base; |
37 | static u32 *mpp_saved_regs; | ||
37 | 38 | ||
38 | static int armada_xp_mpp_ctrl_get(unsigned pid, unsigned long *config) | 39 | static 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 | ||
410 | static 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 | |||
425 | static 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 | |||
409 | static int armada_xp_pinctrl_probe(struct platform_device *pdev) | 439 | static 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 | ||
481 | module_platform_driver(armada_xp_pinctrl_driver); | 521 | module_platform_driver(armada_xp_pinctrl_driver); |