#include <linux/pm_runtime.h>
#include "dmaengine.h"
+#include <soc/samsung/exynos-pm.h>
+
#define PL330_MAX_CHAN 8
#define PL330_MAX_IRQS 32
#define PL330_MAX_PERI 32
void __iomem *base;
/* Used the DMA wrapper */
bool wrapper;
+ /* Notifier block for powermode */
+ struct notifier_block lpa_nb;
void __iomem *inst_wrapper;
int usage_count;
/* Populated by the PL330 core driver during pl330_add */
return 0;
}
-static int __maybe_unused pl330_resume(struct device *dev)
+#ifdef CONFIG_CPU_IDLE
+static int pl330_notifier(struct notifier_block *nb,
+ unsigned long event, void *data)
{
- struct amba_device *pcdev = to_amba_device(dev);
- int ret;
+ struct pl330_dmac *pl330 =
+ container_of(nb, struct pl330_dmac, lpa_nb);
- ret = amba_pclk_prepare(pcdev);
- if (ret)
- return ret;
+ switch (event) {
+ case LPA_EXIT:
+ if (pl330->inst_wrapper)
+ __raw_writel((pl330->mcode_bus >> 32) & 0xf, pl330->inst_wrapper);
+ break;
+ }
- if (!pm_runtime_status_suspended(dev))
- ret = amba_pclk_enable(pcdev);
+ return NOTIFY_OK;
+}
+#endif /* CONFIG_CPU_IDLE */
- pm_runtime_enable(dev);
+#ifdef CONFIG_PM
+static int pl330_resume(struct device *dev)
+{
+ struct pl330_dmac *pl330;
- return ret;
+ pl330 = (struct pl330_dmac *)dev_get_drvdata(dev);
+
+ if (pl330->inst_wrapper)
+ __raw_writel((pl330->mcode_bus >> 32) & 0xf, pl330->inst_wrapper);
+
+ return 0;
}
+static const struct dev_pm_ops pl330_pm_ops = {
+ .resume = pl330_resume,
+};
+
static SIMPLE_DEV_PM_OPS(pl330_pm, pl330_suspend, pl330_resume);
+#define PL330_PM (&pl330_pm_ops)
+
+#else /* CONFIG_PM */
+
+#define PL330_PM NULL
+
+#endif /* !CONFIG_PM */
+
static int
pl330_probe(struct amba_device *adev, const struct amba_id *id)
{
pm_runtime_mark_last_busy(&adev->dev);
pm_runtime_put_autosuspend(&adev->dev);
+#ifdef CONFIG_CPU_IDLE
+ pl330->lpa_nb.notifier_call = pl330_notifier;
+ pl330->lpa_nb.next = NULL;
+ pl330->lpa_nb.priority = 0;
+
+ ret = exynos_pm_register_notifier(&pl330->lpa_nb);
+ if (ret) {
+ dev_err(&adev->dev, "failed to register pm notifier\n");
+ goto probe_err3;
+ }
+#endif
+
return 0;
probe_err3:
/* Idle the DMAC */
static struct amba_driver pl330_driver = {
.drv = {
.owner = THIS_MODULE,
+ .pm = PL330_PM,
.name = "dma-pl330",
- .pm = &pl330_pm,
},
.id_table = pl330_ids,
.probe = pl330_probe,