diff options
author | Tony Lindgren <tony@atomide.com> | 2021-07-27 13:10:34 +0300 |
---|---|---|
committer | Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> | 2021-07-29 09:02:27 +0200 |
commit | 77ed5e9dec551765bde9f2e4b7ed9071ff03d61d (patch) | |
tree | 561fafbd569abf155f547e7f3b74624a640dee09 /drivers/memory | |
parent | 0f78964b523fe9920deae3455324060356ae53d0 (diff) | |
download | linux-77ed5e9dec551765bde9f2e4b7ed9071ff03d61d.tar.bz2 |
memory: omap-gpmc: Drop custom PM calls with cpu_pm notifier
We can now switch over to using cpu_pm instead of custom calls and make
the context save and restore functions static.
Let's also move the save and restore functions to avoid adding forward
declarations for them. And get rid of the static data pointer while at it.
Cc: Roger Quadros <rogerq@kernel.org>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Link: https://lore.kernel.org/r/20210727101034.32148-2-tony@atomide.com
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
Diffstat (limited to 'drivers/memory')
-rw-r--r-- | drivers/memory/omap-gpmc.c | 193 |
1 files changed, 118 insertions, 75 deletions
diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c index 55752c858f3e..be0858bff4d3 100644 --- a/drivers/memory/omap-gpmc.c +++ b/drivers/memory/omap-gpmc.c @@ -9,6 +9,7 @@ * Copyright (C) 2009 Texas Instruments * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> */ +#include <linux/cpu_pm.h> #include <linux/irq.h> #include <linux/kernel.h> #include <linux/init.h> @@ -232,7 +233,10 @@ struct gpmc_device { int irq; struct irq_chip irq_chip; struct gpio_chip gpio_chip; + struct notifier_block nb; + struct omap3_gpmc_regs context; int nirqs; + unsigned int is_suspended:1; }; static struct irq_domain *gpmc_irq_domain; @@ -2384,6 +2388,106 @@ static int gpmc_gpio_init(struct gpmc_device *gpmc) return 0; } +static void omap3_gpmc_save_context(struct gpmc_device *gpmc) +{ + struct omap3_gpmc_regs *gpmc_context; + int i; + + if (!gpmc || !gpmc_base) + return; + + gpmc_context = &gpmc->context; + + gpmc_context->sysconfig = gpmc_read_reg(GPMC_SYSCONFIG); + gpmc_context->irqenable = gpmc_read_reg(GPMC_IRQENABLE); + gpmc_context->timeout_ctrl = gpmc_read_reg(GPMC_TIMEOUT_CONTROL); + gpmc_context->config = gpmc_read_reg(GPMC_CONFIG); + gpmc_context->prefetch_config1 = gpmc_read_reg(GPMC_PREFETCH_CONFIG1); + gpmc_context->prefetch_config2 = gpmc_read_reg(GPMC_PREFETCH_CONFIG2); + gpmc_context->prefetch_control = gpmc_read_reg(GPMC_PREFETCH_CONTROL); + for (i = 0; i < gpmc_cs_num; i++) { + gpmc_context->cs_context[i].is_valid = gpmc_cs_mem_enabled(i); + if (gpmc_context->cs_context[i].is_valid) { + gpmc_context->cs_context[i].config1 = + gpmc_cs_read_reg(i, GPMC_CS_CONFIG1); + gpmc_context->cs_context[i].config2 = + gpmc_cs_read_reg(i, GPMC_CS_CONFIG2); + gpmc_context->cs_context[i].config3 = + gpmc_cs_read_reg(i, GPMC_CS_CONFIG3); + gpmc_context->cs_context[i].config4 = + gpmc_cs_read_reg(i, GPMC_CS_CONFIG4); + gpmc_context->cs_context[i].config5 = + gpmc_cs_read_reg(i, GPMC_CS_CONFIG5); + gpmc_context->cs_context[i].config6 = + gpmc_cs_read_reg(i, GPMC_CS_CONFIG6); + gpmc_context->cs_context[i].config7 = + gpmc_cs_read_reg(i, GPMC_CS_CONFIG7); + } + } +} + +static void omap3_gpmc_restore_context(struct gpmc_device *gpmc) +{ + struct omap3_gpmc_regs *gpmc_context; + int i; + + if (!gpmc || !gpmc_base) + return; + + gpmc_context = &gpmc->context; + + gpmc_write_reg(GPMC_SYSCONFIG, gpmc_context->sysconfig); + gpmc_write_reg(GPMC_IRQENABLE, gpmc_context->irqenable); + gpmc_write_reg(GPMC_TIMEOUT_CONTROL, gpmc_context->timeout_ctrl); + gpmc_write_reg(GPMC_CONFIG, gpmc_context->config); + gpmc_write_reg(GPMC_PREFETCH_CONFIG1, gpmc_context->prefetch_config1); + gpmc_write_reg(GPMC_PREFETCH_CONFIG2, gpmc_context->prefetch_config2); + gpmc_write_reg(GPMC_PREFETCH_CONTROL, gpmc_context->prefetch_control); + for (i = 0; i < gpmc_cs_num; i++) { + if (gpmc_context->cs_context[i].is_valid) { + gpmc_cs_write_reg(i, GPMC_CS_CONFIG1, + gpmc_context->cs_context[i].config1); + gpmc_cs_write_reg(i, GPMC_CS_CONFIG2, + gpmc_context->cs_context[i].config2); + gpmc_cs_write_reg(i, GPMC_CS_CONFIG3, + gpmc_context->cs_context[i].config3); + gpmc_cs_write_reg(i, GPMC_CS_CONFIG4, + gpmc_context->cs_context[i].config4); + gpmc_cs_write_reg(i, GPMC_CS_CONFIG5, + gpmc_context->cs_context[i].config5); + gpmc_cs_write_reg(i, GPMC_CS_CONFIG6, + gpmc_context->cs_context[i].config6); + gpmc_cs_write_reg(i, GPMC_CS_CONFIG7, + gpmc_context->cs_context[i].config7); + } else { + gpmc_cs_write_reg(i, GPMC_CS_CONFIG7, 0); + } + } +} + +static int omap_gpmc_context_notifier(struct notifier_block *nb, + unsigned long cmd, void *v) +{ + struct gpmc_device *gpmc; + + gpmc = container_of(nb, struct gpmc_device, nb); + if (gpmc->is_suspended || pm_runtime_suspended(gpmc->dev)) + return NOTIFY_OK; + + switch (cmd) { + case CPU_CLUSTER_PM_ENTER: + omap3_gpmc_save_context(gpmc); + break; + case CPU_CLUSTER_PM_ENTER_FAILED: /* No need to restore context */ + break; + case CPU_CLUSTER_PM_EXIT: + omap3_gpmc_restore_context(gpmc); + break; + } + + return NOTIFY_OK; +} + static int gpmc_probe(struct platform_device *pdev) { int rc; @@ -2472,6 +2576,9 @@ static int gpmc_probe(struct platform_device *pdev) gpmc_probe_dt_children(pdev); + gpmc->nb.notifier_call = omap_gpmc_context_notifier; + cpu_pm_register_notifier(&gpmc->nb); + return 0; gpio_init_failed: @@ -2486,6 +2593,7 @@ static int gpmc_remove(struct platform_device *pdev) { struct gpmc_device *gpmc = platform_get_drvdata(pdev); + cpu_pm_unregister_notifier(&gpmc->nb); gpmc_free_irq(gpmc); gpmc_mem_exit(); pm_runtime_put_sync(&pdev->dev); @@ -2497,15 +2605,23 @@ static int gpmc_remove(struct platform_device *pdev) #ifdef CONFIG_PM_SLEEP static int gpmc_suspend(struct device *dev) { - omap3_gpmc_save_context(); + struct gpmc_device *gpmc = dev_get_drvdata(dev); + + omap3_gpmc_save_context(gpmc); pm_runtime_put_sync(dev); + gpmc->is_suspended = 1; + return 0; } static int gpmc_resume(struct device *dev) { + struct gpmc_device *gpmc = dev_get_drvdata(dev); + pm_runtime_get_sync(dev); - omap3_gpmc_restore_context(); + omap3_gpmc_restore_context(gpmc); + gpmc->is_suspended = 0; + return 0; } #endif @@ -2527,76 +2643,3 @@ static __init int gpmc_init(void) return platform_driver_register(&gpmc_driver); } postcore_initcall(gpmc_init); - -static struct omap3_gpmc_regs gpmc_context; - -void omap3_gpmc_save_context(void) -{ - int i; - - if (!gpmc_base) - return; - - gpmc_context.sysconfig = gpmc_read_reg(GPMC_SYSCONFIG); - gpmc_context.irqenable = gpmc_read_reg(GPMC_IRQENABLE); - gpmc_context.timeout_ctrl = gpmc_read_reg(GPMC_TIMEOUT_CONTROL); - gpmc_context.config = gpmc_read_reg(GPMC_CONFIG); - gpmc_context.prefetch_config1 = gpmc_read_reg(GPMC_PREFETCH_CONFIG1); - gpmc_context.prefetch_config2 = gpmc_read_reg(GPMC_PREFETCH_CONFIG2); - gpmc_context.prefetch_control = gpmc_read_reg(GPMC_PREFETCH_CONTROL); - for (i = 0; i < gpmc_cs_num; i++) { - gpmc_context.cs_context[i].is_valid = gpmc_cs_mem_enabled(i); - if (gpmc_context.cs_context[i].is_valid) { - gpmc_context.cs_context[i].config1 = - gpmc_cs_read_reg(i, GPMC_CS_CONFIG1); - gpmc_context.cs_context[i].config2 = - gpmc_cs_read_reg(i, GPMC_CS_CONFIG2); - gpmc_context.cs_context[i].config3 = - gpmc_cs_read_reg(i, GPMC_CS_CONFIG3); - gpmc_context.cs_context[i].config4 = - gpmc_cs_read_reg(i, GPMC_CS_CONFIG4); - gpmc_context.cs_context[i].config5 = - gpmc_cs_read_reg(i, GPMC_CS_CONFIG5); - gpmc_context.cs_context[i].config6 = - gpmc_cs_read_reg(i, GPMC_CS_CONFIG6); - gpmc_context.cs_context[i].config7 = - gpmc_cs_read_reg(i, GPMC_CS_CONFIG7); - } - } -} - -void omap3_gpmc_restore_context(void) -{ - int i; - - if (!gpmc_base) - return; - - gpmc_write_reg(GPMC_SYSCONFIG, gpmc_context.sysconfig); - gpmc_write_reg(GPMC_IRQENABLE, gpmc_context.irqenable); - gpmc_write_reg(GPMC_TIMEOUT_CONTROL, gpmc_context.timeout_ctrl); - gpmc_write_reg(GPMC_CONFIG, gpmc_context.config); - gpmc_write_reg(GPMC_PREFETCH_CONFIG1, gpmc_context.prefetch_config1); - gpmc_write_reg(GPMC_PREFETCH_CONFIG2, gpmc_context.prefetch_config2); - gpmc_write_reg(GPMC_PREFETCH_CONTROL, gpmc_context.prefetch_control); - for (i = 0; i < gpmc_cs_num; i++) { - if (gpmc_context.cs_context[i].is_valid) { - gpmc_cs_write_reg(i, GPMC_CS_CONFIG1, - gpmc_context.cs_context[i].config1); - gpmc_cs_write_reg(i, GPMC_CS_CONFIG2, - gpmc_context.cs_context[i].config2); - gpmc_cs_write_reg(i, GPMC_CS_CONFIG3, - gpmc_context.cs_context[i].config3); - gpmc_cs_write_reg(i, GPMC_CS_CONFIG4, - gpmc_context.cs_context[i].config4); - gpmc_cs_write_reg(i, GPMC_CS_CONFIG5, - gpmc_context.cs_context[i].config5); - gpmc_cs_write_reg(i, GPMC_CS_CONFIG6, - gpmc_context.cs_context[i].config6); - gpmc_cs_write_reg(i, GPMC_CS_CONFIG7, - gpmc_context.cs_context[i].config7); - } else { - gpmc_cs_write_reg(i, GPMC_CS_CONFIG7, 0); - } - } -} |