diff options
Diffstat (limited to 'drivers/memory/samsung')
-rw-r--r-- | drivers/memory/samsung/Kconfig | 7 | ||||
-rw-r--r-- | drivers/memory/samsung/exynos-srom.c | 22 | ||||
-rw-r--r-- | drivers/memory/samsung/exynos5422-dmc.c | 15 |
3 files changed, 28 insertions, 16 deletions
diff --git a/drivers/memory/samsung/Kconfig b/drivers/memory/samsung/Kconfig index 20a8406ce786..8e240f078afc 100644 --- a/drivers/memory/samsung/Kconfig +++ b/drivers/memory/samsung/Kconfig @@ -23,5 +23,12 @@ config EXYNOS5422_DMC config EXYNOS_SROM bool "Exynos SROM controller driver" if COMPILE_TEST depends on (ARM && ARCH_EXYNOS) || (COMPILE_TEST && HAS_IOMEM) + help + This adds driver for Samsung Exynos SoC SROM controller. The driver + in basic operation mode only saves and restores SROM registers + during suspend. If however appropriate device tree configuration + is provided, the driver enables support for external memory + or external devices. + If unsure, say Y on devices with Samsung Exynos SocS. endif diff --git a/drivers/memory/samsung/exynos-srom.c b/drivers/memory/samsung/exynos-srom.c index 6510d7bab217..e73dd330af47 100644 --- a/drivers/memory/samsung/exynos-srom.c +++ b/drivers/memory/samsung/exynos-srom.c @@ -47,9 +47,9 @@ struct exynos_srom { struct exynos_srom_reg_dump *reg_offset; }; -static struct exynos_srom_reg_dump *exynos_srom_alloc_reg_dump( - const unsigned long *rdump, - unsigned long nr_rdump) +static struct exynos_srom_reg_dump * +exynos_srom_alloc_reg_dump(const unsigned long *rdump, + unsigned long nr_rdump) { struct exynos_srom_reg_dump *rd; unsigned int i; @@ -116,7 +116,7 @@ static int exynos_srom_probe(struct platform_device *pdev) } srom = devm_kzalloc(&pdev->dev, - sizeof(struct exynos_srom), GFP_KERNEL); + sizeof(struct exynos_srom), GFP_KERNEL); if (!srom) return -ENOMEM; @@ -130,7 +130,7 @@ static int exynos_srom_probe(struct platform_device *pdev) platform_set_drvdata(pdev, srom); srom->reg_offset = exynos_srom_alloc_reg_dump(exynos_srom_offsets, - ARRAY_SIZE(exynos_srom_offsets)); + ARRAY_SIZE(exynos_srom_offsets)); if (!srom->reg_offset) { iounmap(srom->reg_base); return -ENOMEM; @@ -157,16 +157,16 @@ static int exynos_srom_probe(struct platform_device *pdev) #ifdef CONFIG_PM_SLEEP static void exynos_srom_save(void __iomem *base, - struct exynos_srom_reg_dump *rd, - unsigned int num_regs) + struct exynos_srom_reg_dump *rd, + unsigned int num_regs) { for (; num_regs > 0; --num_regs, ++rd) rd->value = readl(base + rd->offset); } static void exynos_srom_restore(void __iomem *base, - const struct exynos_srom_reg_dump *rd, - unsigned int num_regs) + const struct exynos_srom_reg_dump *rd, + unsigned int num_regs) { for (; num_regs > 0; --num_regs, ++rd) writel(rd->value, base + rd->offset); @@ -177,7 +177,7 @@ static int exynos_srom_suspend(struct device *dev) struct exynos_srom *srom = dev_get_drvdata(dev); exynos_srom_save(srom->reg_base, srom->reg_offset, - ARRAY_SIZE(exynos_srom_offsets)); + ARRAY_SIZE(exynos_srom_offsets)); return 0; } @@ -186,7 +186,7 @@ static int exynos_srom_resume(struct device *dev) struct exynos_srom *srom = dev_get_drvdata(dev); exynos_srom_restore(srom->reg_base, srom->reg_offset, - ARRAY_SIZE(exynos_srom_offsets)); + ARRAY_SIZE(exynos_srom_offsets)); return 0; } #endif diff --git a/drivers/memory/samsung/exynos5422-dmc.c b/drivers/memory/samsung/exynos5422-dmc.c index 25196d6268e2..4312233e8e0a 100644 --- a/drivers/memory/samsung/exynos5422-dmc.c +++ b/drivers/memory/samsung/exynos5422-dmc.c @@ -270,12 +270,14 @@ static int find_target_freq_idx(struct exynos5_dmc *dmc, * This function switches between these banks according to the * currently used clock source. */ -static void exynos5_switch_timing_regs(struct exynos5_dmc *dmc, bool set) +static int exynos5_switch_timing_regs(struct exynos5_dmc *dmc, bool set) { unsigned int reg; int ret; ret = regmap_read(dmc->clk_regmap, CDREX_LPDDR3PHY_CON3, ®); + if (ret) + return ret; if (set) reg |= EXYNOS5_TIMING_SET_SWI; @@ -283,6 +285,8 @@ static void exynos5_switch_timing_regs(struct exynos5_dmc *dmc, bool set) reg &= ~EXYNOS5_TIMING_SET_SWI; regmap_write(dmc->clk_regmap, CDREX_LPDDR3PHY_CON3, reg); + + return 0; } /** @@ -516,7 +520,7 @@ exynos5_dmc_switch_to_bypass_configuration(struct exynos5_dmc *dmc, /* * Delays are long enough, so use them for the new coming clock. */ - exynos5_switch_timing_regs(dmc, USE_MX_MSPLL_TIMINGS); + ret = exynos5_switch_timing_regs(dmc, USE_MX_MSPLL_TIMINGS); return ret; } @@ -577,7 +581,9 @@ exynos5_dmc_change_freq_and_volt(struct exynos5_dmc *dmc, clk_set_rate(dmc->fout_bpll, target_rate); - exynos5_switch_timing_regs(dmc, USE_BPLL_TIMINGS); + ret = exynos5_switch_timing_regs(dmc, USE_BPLL_TIMINGS); + if (ret) + goto disable_clocks; ret = clk_set_parent(dmc->mout_mclk_cdrex, dmc->mout_bpll); if (ret) @@ -1392,7 +1398,7 @@ static int exynos5_dmc_probe(struct platform_device *pdev) return PTR_ERR(dmc->base_drexi1); dmc->clk_regmap = syscon_regmap_lookup_by_phandle(np, - "samsung,syscon-clk"); + "samsung,syscon-clk"); if (IS_ERR(dmc->clk_regmap)) return PTR_ERR(dmc->clk_regmap); @@ -1471,7 +1477,6 @@ static int exynos5_dmc_probe(struct platform_device *pdev) exynos5_dmc_df_profile.polling_ms = 500; } - dmc->df = devm_devfreq_add_device(dev, &exynos5_dmc_df_profile, DEVFREQ_GOV_SIMPLE_ONDEMAND, &dmc->gov_data); |