summaryrefslogtreecommitdiff
path: root/drivers/staging/fsl_qbman/bman_config.c
diff options
context:
space:
mode:
authorJeffrey Ladouceur <Jeffrey.Ladouceur@freescale.com>2014-04-04 19:05:46 (GMT)
committerJose Rivera <German.Rivera@freescale.com>2014-04-07 13:19:23 (GMT)
commitfb7f27080adc65cd5f341bdf56a1d0c14f316c1b (patch)
tree4e829d81a2615d0b9e69a463ba2b961bd3106390 /drivers/staging/fsl_qbman/bman_config.c
parent20ba3f28e926a9fbf0acf56df26a2ce2e9aaf235 (diff)
downloadlinux-fsl-qoriq-fb7f27080adc65cd5f341bdf56a1d0c14f316c1b.tar.xz
fsl_qbman: Add support for deepsleep
In order for supported SoCs to enter deepsleep the QBMan ip blocks must not have any pending interrupt status bits set in the Portals. Therefore, in the pm callbacks for each portal, save the isdr, and clear the isr. On the resume side, reset the save isdr. Also fix the buffer pool depletion notification in all bman portals. The default value is to notify them. This is an issue for unused portals, as the portal will have the corresponding isr bit set and will prevent deepsleep for occuring. The unused portals need to have their ISDR and ISR cleared in order for the qman block to enter idle state. Also re-added the setting of ISDR clear ISR for the qbman ccsr block. Signed-off-by: Jeffrey Ladouceur <Jeffrey.Ladouceur@freescale.com> Change-Id: Icd908215ed10d39e3f112b939c4d6b2758a97a76 Reviewed-on: http://git.am.freescale.net:8181/10717 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Haiying Wang <Haiying.Wang@freescale.com> Reviewed-by: Roy Pledge <roy.pledge@freescale.com> Reviewed-by: Jose Rivera <German.Rivera@freescale.com>
Diffstat (limited to 'drivers/staging/fsl_qbman/bman_config.c')
-rw-r--r--drivers/staging/fsl_qbman/bman_config.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/staging/fsl_qbman/bman_config.c b/drivers/staging/fsl_qbman/bman_config.c
index a00b3d4..efba359 100644
--- a/drivers/staging/fsl_qbman/bman_config.c
+++ b/drivers/staging/fsl_qbman/bman_config.c
@@ -43,6 +43,8 @@ struct bman;
#define REG_POOL_HWDXT(n) (0x0300 + ((n) * 0x04))
#define REG_POOL_CONTENT(n) (0x0600 + ((n) * 0x04))
#define REG_FBPR_FPC 0x0800
+#define REG_STATE_IDLE 0x960
+#define REG_STATE_STOP 0x964
#define REG_ECSR 0x0a00
#define REG_ECIR 0x0a04
#define REG_EADR 0x0a08
@@ -663,11 +665,46 @@ static struct of_device_id of_fsl_bman_ids[] = {
};
MODULE_DEVICE_TABLE(of, of_fsl_bman_ids);
+#ifdef CONFIG_SUSPEND
+static u32 saved_isdr;
+
+static int bman_pm_suspend_noirq(struct device *dev)
+{
+ suspend_unused_bportal();
+ /* save isdr, disable all, clear isr */
+ saved_isdr = bm_err_isr_disable_read(bm);
+ bm_err_isr_disable_write(bm, 0xffffffff);
+ bm_err_isr_status_clear(bm, 0xffffffff);
+ /* should be idle, otherwise abort ? */
+#ifdef CONFIG_PM_DEBUG
+ pr_info("Bman suspend code, IDLE_STAT = 0x%x\n", bm_in(STATE_IDLE));
+#endif
+ return 0;
+}
+
+static int bman_pm_resume_noirq(struct device *dev)
+{
+ /* restore isdr */
+ bm_err_isr_disable_write(bm, saved_isdr);
+ resume_unused_bportal();
+ return 0;
+}
+#else
+#define bman_pm_suspend_noirq NULL
+#define bman_pm_resume_noirq NULL
+#endif
+
+static const struct dev_pm_ops bman_pm_ops = {
+ .suspend_noirq = bman_pm_suspend_noirq,
+ .resume_noirq = bman_pm_resume_noirq,
+};
+
static struct platform_driver of_fsl_bman_driver = {
.driver = {
.owner = THIS_MODULE,
.name = DRV_NAME,
.of_match_table = of_fsl_bman_ids,
+ .pm = &bman_pm_ops,
},
.probe = of_fsl_bman_probe,
.remove = of_fsl_bman_remove,