* [PATCH v7 0/8] CPUs capacity information for heterogeneous systems
From: Juri Lelli @ 2016-09-19 11:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160912072424.GL10409@e106622-lin>
Hi,
On 12/09/16 08:24, Juri Lelli wrote:
> Hi,
>
> this is a ping for people interested in this series. Patches 2,4,7-8
> still needs ACKs.
>
Weekly ping. :-)
Best,
- Juri
> I know it's only been a week since I posted v7, but this series would
> pair nicely with asym cpu capacity support bits already sitting in
> tip/sched/core. I also know that it might be already late for 4.9 merge
> window; nevertheless, still hoping we can make it.
>
^ permalink raw reply
* [PATCH v4 0/7] ARM: dts: bcm283x: add and use pinctrl groups
From: Stefan Wahren @ 2016-09-19 11:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1474274603-24215-1-git-send-email-kraxel@redhat.com>
Am 19.09.2016 um 10:43 schrieb Gerd Hoffmann:
> Hi,
>
> New in v4: Patch #6 has been splitted into two: Patch 6 just moves
> pinctrl from &gpio to &sdhci. Removing the empty now alt3 group
> -- including all references as pointed out by Stefan Wahren in review --
> is done by the new patch 7. Patches 1-5 are unchanged.
Acked-by: Stefan Wahren <stefan.wahren@i2se.com>
for the whole series.
Thanks
Stefan
^ permalink raw reply
* [PATCH v2 5/5] clocks: exynos5433: add runtime pm support
From: Marek Szyprowski @ 2016-09-19 10:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1474282525-30441-1-git-send-email-m.szyprowski@samsung.com>
Add runtime pm support for all clock controller units (CMU), which belongs
to power domains and require special handling during on/off operations.
Typically special values has to be written to MUX registers to change
internal clocks parents to OSC clock before turning power off. During such
operation all clocks, which enters CMU has to be enabled to let MUX to
stabilize. Also for each CMU there is one special parent clock, which has
to be enabled all the time when any access to CMU registers is done.
This patch solves most of the mysterious external abort and freeze issues
caused by a lack of proper parent CMU clock enabled or incorrect turn off
procedure.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/clk/samsung/clk-exynos5433.c | 385 ++++++++++++++++++++++++++++-------
drivers/clk/samsung/clk.h | 6 +
2 files changed, 314 insertions(+), 77 deletions(-)
diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c
index ea1608682d7f..d507f2ace6c2 100644
--- a/drivers/clk/samsung/clk-exynos5433.c
+++ b/drivers/clk/samsung/clk-exynos5433.c
@@ -9,9 +9,14 @@
* Common Clock Framework support for Exynos5443 SoC.
*/
+#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
#include <dt-bindings/clock/exynos5433.h>
@@ -2333,6 +2338,10 @@ static const unsigned long g2d_clk_regs[] __initconst = {
DIV_ENABLE_IP_G2D_SECURE_SMMU_G2D,
};
+static const struct samsung_clk_reg_dump g2d_suspend_regs[] = {
+ { MUX_SEL_G2D0, 0 },
+};
+
/* list of all parent clock list */
PNAME(mout_aclk_g2d_266_user_p) = { "oscclk", "aclk_g2d_266", };
PNAME(mout_aclk_g2d_400_user_p) = { "oscclk", "aclk_g2d_400", };
@@ -2418,16 +2427,11 @@ static const struct samsung_cmu_info g2d_cmu_info __initconst = {
.nr_clk_ids = G2D_NR_CLK,
.clk_regs = g2d_clk_regs,
.nr_clk_regs = ARRAY_SIZE(g2d_clk_regs),
+ .suspend_regs = g2d_suspend_regs,
+ .nr_suspend_regs = ARRAY_SIZE(g2d_suspend_regs),
+ .clk_name = "aclk_g2d_400",
};
-static void __init exynos5433_cmu_g2d_init(struct device_node *np)
-{
- samsung_cmu_register_one(np, &g2d_cmu_info);
-}
-
-CLK_OF_DECLARE(exynos5433_cmu_g2d, "samsung,exynos5433-cmu-g2d",
- exynos5433_cmu_g2d_init);
-
/*
* Register offset definitions for CMU_DISP
*/
@@ -2492,6 +2496,14 @@ static const unsigned long disp_clk_regs[] __initconst = {
CLKOUT_CMU_DISP_DIV_STAT,
};
+static const struct samsung_clk_reg_dump disp_suspend_regs[] = {
+ { MUX_SEL_DISP0, 0 },
+ { MUX_SEL_DISP1, 0 },
+ { MUX_SEL_DISP2, 0 },
+ { MUX_SEL_DISP3, 0 },
+ { MUX_SEL_DISP4, 0 },
+};
+
/* list of all parent clock list */
PNAME(mout_disp_pll_p) = { "oscclk", "fout_disp_pll", };
PNAME(mout_sclk_dsim1_user_p) = { "oscclk", "sclk_dsim1_disp", };
@@ -2837,16 +2849,11 @@ static const struct samsung_cmu_info disp_cmu_info __initconst = {
.nr_clk_ids = DISP_NR_CLK,
.clk_regs = disp_clk_regs,
.nr_clk_regs = ARRAY_SIZE(disp_clk_regs),
+ .suspend_regs = disp_suspend_regs,
+ .nr_suspend_regs = ARRAY_SIZE(disp_suspend_regs),
+ .clk_name = "aclk_disp_333",
};
-static void __init exynos5433_cmu_disp_init(struct device_node *np)
-{
- samsung_cmu_register_one(np, &disp_cmu_info);
-}
-
-CLK_OF_DECLARE(exynos5433_cmu_disp, "samsung,exynos5433-cmu-disp",
- exynos5433_cmu_disp_init);
-
/*
* Register offset definitions for CMU_AUD
*/
@@ -2881,6 +2888,11 @@ static const unsigned long aud_clk_regs[] __initconst = {
ENABLE_IP_AUD1,
};
+static const struct samsung_clk_reg_dump aud_suspend_regs[] = {
+ { MUX_SEL_AUD0, 0 },
+ { MUX_SEL_AUD1, 0 },
+};
+
/* list of all parent clock list */
PNAME(mout_aud_pll_user_aud_p) = { "oscclk", "fout_aud_pll", };
PNAME(mout_sclk_aud_pcm_p) = { "mout_aud_pll_user", "ioclk_audiocdclk0",};
@@ -3007,16 +3019,10 @@ static const struct samsung_cmu_info aud_cmu_info __initconst = {
.nr_clk_ids = AUD_NR_CLK,
.clk_regs = aud_clk_regs,
.nr_clk_regs = ARRAY_SIZE(aud_clk_regs),
+ .suspend_regs = aud_suspend_regs,
+ .nr_suspend_regs = ARRAY_SIZE(aud_suspend_regs),
};
-static void __init exynos5433_cmu_aud_init(struct device_node *np)
-{
- samsung_cmu_register_one(np, &aud_cmu_info);
-}
-CLK_OF_DECLARE(exynos5433_cmu_aud, "samsung,exynos5433-cmu-aud",
- exynos5433_cmu_aud_init);
-
-
/*
* Register offset definitions for CMU_BUS{0|1|2}
*/
@@ -3218,6 +3224,10 @@ static const unsigned long g3d_clk_regs[] __initconst = {
CLK_STOPCTRL,
};
+static const struct samsung_clk_reg_dump g3d_suspend_regs[] = {
+ { MUX_SEL_G3D, 0 },
+};
+
/* list of all parent clock list */
PNAME(mout_aclk_g3d_400_p) = { "mout_g3d_pll", "aclk_g3d_400", };
PNAME(mout_g3d_pll_p) = { "oscclk", "fout_g3d_pll", };
@@ -3291,15 +3301,11 @@ static const struct samsung_cmu_info g3d_cmu_info __initconst = {
.nr_clk_ids = G3D_NR_CLK,
.clk_regs = g3d_clk_regs,
.nr_clk_regs = ARRAY_SIZE(g3d_clk_regs),
+ .suspend_regs = g3d_suspend_regs,
+ .nr_suspend_regs = ARRAY_SIZE(g3d_suspend_regs),
+ .clk_name = "aclk_g3d_400",
};
-static void __init exynos5433_cmu_g3d_init(struct device_node *np)
-{
- samsung_cmu_register_one(np, &g3d_cmu_info);
-}
-CLK_OF_DECLARE(exynos5433_cmu_g3d, "samsung,exynos5433-cmu-g3d",
- exynos5433_cmu_g3d_init);
-
/*
* Register offset definitions for CMU_GSCL
*/
@@ -3338,6 +3344,12 @@ static const unsigned long gscl_clk_regs[] __initconst = {
ENABLE_IP_GSCL_SECURE_SMMU_GSCL2,
};
+static const struct samsung_clk_reg_dump gscl_suspend_regs[] = {
+ { MUX_SEL_GSCL, 0 },
+ { ENABLE_ACLK_GSCL, 0xfff },
+ { ENABLE_PCLK_GSCL, 0xff },
+};
+
/* list of all parent clock list */
PNAME(aclk_gscl_111_user_p) = { "oscclk", "aclk_gscl_111", };
PNAME(aclk_gscl_333_user_p) = { "oscclk", "aclk_gscl_333", };
@@ -3432,15 +3444,11 @@ static const struct samsung_cmu_info gscl_cmu_info __initconst = {
.nr_clk_ids = GSCL_NR_CLK,
.clk_regs = gscl_clk_regs,
.nr_clk_regs = ARRAY_SIZE(gscl_clk_regs),
+ .suspend_regs = gscl_suspend_regs,
+ .nr_suspend_regs = ARRAY_SIZE(gscl_suspend_regs),
+ .clk_name = "aclk_gscl_111",
};
-static void __init exynos5433_cmu_gscl_init(struct device_node *np)
-{
- samsung_cmu_register_one(np, &gscl_cmu_info);
-}
-CLK_OF_DECLARE(exynos5433_cmu_gscl, "samsung,exynos5433-cmu-gscl",
- exynos5433_cmu_gscl_init);
-
/*
* Register offset definitions for CMU_APOLLO
*/
@@ -3966,6 +3974,11 @@ static const unsigned long mscl_clk_regs[] __initconst = {
ENABLE_IP_MSCL_SECURE_SMMU_JPEG,
};
+static const struct samsung_clk_reg_dump mscl_suspend_regs[] = {
+ { MUX_SEL_MSCL0, 0 },
+ { MUX_SEL_MSCL1, 0 },
+};
+
/* list of all parent clock list */
PNAME(mout_sclk_jpeg_user_p) = { "oscclk", "sclk_jpeg_mscl", };
PNAME(mout_aclk_mscl_400_user_p) = { "oscclk", "aclk_mscl_400", };
@@ -4078,15 +4091,11 @@ static const struct samsung_cmu_info mscl_cmu_info __initconst = {
.nr_clk_ids = MSCL_NR_CLK,
.clk_regs = mscl_clk_regs,
.nr_clk_regs = ARRAY_SIZE(mscl_clk_regs),
+ .suspend_regs = mscl_suspend_regs,
+ .nr_suspend_regs = ARRAY_SIZE(mscl_suspend_regs),
+ .clk_name = "aclk_mscl_400",
};
-static void __init exynos5433_cmu_mscl_init(struct device_node *np)
-{
- samsung_cmu_register_one(np, &mscl_cmu_info);
-}
-CLK_OF_DECLARE(exynos5433_cmu_mscl, "samsung,exynos5433-cmu-mscl",
- exynos5433_cmu_mscl_init);
-
/*
* Register offset definitions for CMU_MFC
*/
@@ -4116,6 +4125,10 @@ static const unsigned long mfc_clk_regs[] __initconst = {
ENABLE_IP_MFC_SECURE_SMMU_MFC,
};
+static const struct samsung_clk_reg_dump mfc_suspend_regs[] = {
+ { MUX_SEL_MFC, 0 },
+};
+
PNAME(mout_aclk_mfc_400_user_p) = { "oscclk", "aclk_mfc_400", };
static const struct samsung_mux_clock mfc_mux_clks[] __initconst = {
@@ -4186,15 +4199,11 @@ static const struct samsung_cmu_info mfc_cmu_info __initconst = {
.nr_clk_ids = MFC_NR_CLK,
.clk_regs = mfc_clk_regs,
.nr_clk_regs = ARRAY_SIZE(mfc_clk_regs),
+ .suspend_regs = mfc_suspend_regs,
+ .nr_suspend_regs = ARRAY_SIZE(mfc_suspend_regs),
+ .clk_name = "aclk_mfc_400",
};
-static void __init exynos5433_cmu_mfc_init(struct device_node *np)
-{
- samsung_cmu_register_one(np, &mfc_cmu_info);
-}
-CLK_OF_DECLARE(exynos5433_cmu_mfc, "samsung,exynos5433-cmu-mfc",
- exynos5433_cmu_mfc_init);
-
/*
* Register offset definitions for CMU_HEVC
*/
@@ -4224,6 +4233,10 @@ static const unsigned long hevc_clk_regs[] __initconst = {
ENABLE_IP_HEVC_SECURE_SMMU_HEVC,
};
+static const struct samsung_clk_reg_dump hevc_suspend_regs[] = {
+ { MUX_SEL_HEVC, 0 },
+};
+
PNAME(mout_aclk_hevc_400_user_p) = { "oscclk", "aclk_hevc_400", };
static const struct samsung_mux_clock hevc_mux_clks[] __initconst = {
@@ -4296,15 +4309,11 @@ static const struct samsung_cmu_info hevc_cmu_info __initconst = {
.nr_clk_ids = HEVC_NR_CLK,
.clk_regs = hevc_clk_regs,
.nr_clk_regs = ARRAY_SIZE(hevc_clk_regs),
+ .suspend_regs = hevc_suspend_regs,
+ .nr_suspend_regs = ARRAY_SIZE(hevc_suspend_regs),
+ .clk_name = "aclk_hevc_400",
};
-static void __init exynos5433_cmu_hevc_init(struct device_node *np)
-{
- samsung_cmu_register_one(np, &hevc_cmu_info);
-}
-CLK_OF_DECLARE(exynos5433_cmu_hevc, "samsung,exynos5433-cmu-hevc",
- exynos5433_cmu_hevc_init);
-
/*
* Register offset definitions for CMU_ISP
*/
@@ -4338,6 +4347,10 @@ static const unsigned long isp_clk_regs[] __initconst = {
ENABLE_IP_ISP3,
};
+static const struct samsung_clk_reg_dump isp_suspend_regs[] = {
+ { MUX_SEL_ISP, 0 },
+};
+
PNAME(mout_aclk_isp_dis_400_user_p) = { "oscclk", "aclk_isp_dis_400", };
PNAME(mout_aclk_isp_400_user_p) = { "oscclk", "aclk_isp_400", };
@@ -4549,15 +4562,11 @@ static const struct samsung_cmu_info isp_cmu_info __initconst = {
.nr_clk_ids = ISP_NR_CLK,
.clk_regs = isp_clk_regs,
.nr_clk_regs = ARRAY_SIZE(isp_clk_regs),
+ .suspend_regs = isp_suspend_regs,
+ .nr_suspend_regs = ARRAY_SIZE(isp_suspend_regs),
+ .clk_name = "aclk_isp_400",
};
-static void __init exynos5433_cmu_isp_init(struct device_node *np)
-{
- samsung_cmu_register_one(np, &isp_cmu_info);
-}
-CLK_OF_DECLARE(exynos5433_cmu_isp, "samsung,exynos5433-cmu-isp",
- exynos5433_cmu_isp_init);
-
/*
* Register offset definitions for CMU_CAM0
*/
@@ -4621,6 +4630,15 @@ static const unsigned long cam0_clk_regs[] __initconst = {
ENABLE_IP_CAM02,
ENABLE_IP_CAM03,
};
+
+static const struct samsung_clk_reg_dump cam0_suspend_regs[] = {
+ { MUX_SEL_CAM00, 0 },
+ { MUX_SEL_CAM01, 0 },
+ { MUX_SEL_CAM02, 0 },
+ { MUX_SEL_CAM03, 0 },
+ { MUX_SEL_CAM04, 0 },
+};
+
PNAME(mout_aclk_cam0_333_user_p) = { "oscclk", "aclk_cam0_333", };
PNAME(mout_aclk_cam0_400_user_p) = { "oscclk", "aclk_cam0_400", };
PNAME(mout_aclk_cam0_552_user_p) = { "oscclk", "aclk_cam0_552", };
@@ -5026,15 +5044,11 @@ static const struct samsung_cmu_info cam0_cmu_info __initconst = {
.nr_clk_ids = CAM0_NR_CLK,
.clk_regs = cam0_clk_regs,
.nr_clk_regs = ARRAY_SIZE(cam0_clk_regs),
+ .suspend_regs = cam0_suspend_regs,
+ .nr_suspend_regs = ARRAY_SIZE(cam0_suspend_regs),
+ .clk_name = "aclk_cam0_400",
};
-static void __init exynos5433_cmu_cam0_init(struct device_node *np)
-{
- samsung_cmu_register_one(np, &cam0_cmu_info);
-}
-CLK_OF_DECLARE(exynos5433_cmu_cam0, "samsung,exynos5433-cmu-cam0",
- exynos5433_cmu_cam0_init);
-
/*
* Register offset definitions for CMU_CAM1
*/
@@ -5081,6 +5095,12 @@ static const unsigned long cam1_clk_regs[] __initconst = {
ENABLE_IP_CAM12,
};
+static const struct samsung_clk_reg_dump cam1_suspend_regs[] = {
+ { MUX_SEL_CAM10, 0 },
+ { MUX_SEL_CAM11, 0 },
+ { MUX_SEL_CAM12, 0 },
+};
+
PNAME(mout_sclk_isp_uart_user_p) = { "oscclk", "sclk_isp_uart_cam1", };
PNAME(mout_sclk_isp_spi1_user_p) = { "oscclk", "sclk_isp_spi1_cam1", };
PNAME(mout_sclk_isp_spi0_user_p) = { "oscclk", "sclk_isp_spi0_cam1", };
@@ -5399,11 +5419,222 @@ static const struct samsung_cmu_info cam1_cmu_info __initconst = {
.nr_clk_ids = CAM1_NR_CLK,
.clk_regs = cam1_clk_regs,
.nr_clk_regs = ARRAY_SIZE(cam1_clk_regs),
+ .suspend_regs = cam1_suspend_regs,
+ .nr_suspend_regs = ARRAY_SIZE(cam1_suspend_regs),
+ .clk_name = "aclk_cam1_400",
+};
+
+
+struct exynos5433_cmu_data {
+ struct samsung_clk_provider ctx;
+
+ struct samsung_clk_reg_dump *clk_save;
+ unsigned int nr_clk_save;
+ const struct samsung_clk_reg_dump *clk_suspend;
+ unsigned int nr_clk_suspend;
+
+ struct clk *clk;
+ struct clk **pclks;
+ int nr_pclks;
+};
+
+static int exynos5433_cmu_suspend(struct device *dev)
+{
+ struct exynos5433_cmu_data *data = dev_get_drvdata(dev);
+ int i;
+
+ samsung_clk_save(data->ctx.reg_base, data->clk_save,
+ data->nr_clk_save);
+
+ for (i = 0; i < data->nr_pclks; i++)
+ clk_enable(data->pclks[i]);
+
+ samsung_clk_restore(data->ctx.reg_base, data->clk_suspend,
+ data->nr_clk_suspend);
+
+ for (i = 0; i < data->nr_pclks; i++)
+ clk_disable(data->pclks[i]);
+
+ clk_disable(data->clk);
+
+ return 0;
+}
+
+static int exynos5433_cmu_resume(struct device *dev)
+{
+ struct exynos5433_cmu_data *data = dev_get_drvdata(dev);
+ int i;
+
+ clk_enable(data->clk);
+
+ for (i = 0; i < data->nr_pclks; i++)
+ clk_enable(data->pclks[i]);
+
+ samsung_clk_restore(data->ctx.reg_base, data->clk_save,
+ data->nr_clk_save);
+
+ for (i = 0; i < data->nr_pclks; i++)
+ clk_disable(data->pclks[i]);
+
+ return 0;
+}
+
+static int __init exynos5433_cmu_probe(struct platform_device *pdev)
+{
+ const struct samsung_cmu_info *info;
+ struct exynos5433_cmu_data *data;
+ struct samsung_clk_provider *ctx;
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ void __iomem *reg_base;
+ struct clk **clk_table;
+ int i;
+
+ info = of_device_get_match_data(dev);
+
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+ ctx = &data->ctx;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ reg_base = devm_ioremap_resource(dev, res);
+ if (!reg_base) {
+ dev_err(dev, "failed to map registers\n");
+ return -ENOMEM;
+ }
+
+ clk_table = devm_kcalloc(dev, info->nr_clk_ids, sizeof(struct clk *),
+ GFP_KERNEL);
+ if (!clk_table)
+ return -ENOMEM;
+
+ for (i = 0; i < info->nr_clk_ids; ++i)
+ clk_table[i] = ERR_PTR(-ENOENT);
+
+ ctx->clk_data.clks = clk_table;
+ ctx->clk_data.clk_num = info->nr_clk_ids;
+ ctx->reg_base = reg_base;
+ ctx->dev = dev;
+ spin_lock_init(&ctx->lock);
+
+ data->clk_save = samsung_clk_alloc_reg_dump(info->clk_regs,
+ info->nr_clk_regs);
+ data->nr_clk_save = info->nr_clk_regs;
+ data->clk_suspend = info->suspend_regs;
+ data->nr_clk_suspend = info->nr_suspend_regs;
+ data->nr_pclks = of_count_phandle_with_args(dev->of_node, "clocks",
+ "#clock-cells");
+ if (data->nr_pclks > 0) {
+ data->pclks = devm_kcalloc(dev, sizeof(struct clk *),
+ data->nr_pclks, GFP_KERNEL);
+
+ for (i = 0; i < data->nr_pclks; i++) {
+ struct clk *clk = of_clk_get(dev->of_node, i);
+
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+ data->pclks[i] = clk;
+ }
+ }
+
+ /*
+ * Prepare all parent clocks here to avoid potential deadlock caused
+ * by global clock "prepare lock" grabbed by runtime pm callbacks
+ * from pm workers.
+ */
+ for (i = 0; i < data->nr_pclks; i++)
+ clk_prepare(data->pclks[i]);
+
+ if (info->pll_clks)
+ samsung_clk_register_pll(ctx, info->pll_clks, info->nr_pll_clks,
+ reg_base);
+ if (info->mux_clks)
+ samsung_clk_register_mux(ctx, info->mux_clks,
+ info->nr_mux_clks);
+ if (info->div_clks)
+ samsung_clk_register_div(ctx, info->div_clks,
+ info->nr_div_clks);
+ if (info->gate_clks)
+ samsung_clk_register_gate(ctx, info->gate_clks,
+ info->nr_gate_clks);
+ if (info->fixed_clks)
+ samsung_clk_register_fixed_rate(ctx, info->fixed_clks,
+ info->nr_fixed_clks);
+ if (info->fixed_factor_clks)
+ samsung_clk_register_fixed_factor(ctx, info->fixed_factor_clks,
+ info->nr_fixed_factor_clks);
+
+ if (info->clk_name)
+ data->clk = clk_get(dev, info->clk_name);
+ clk_prepare_enable(data->clk);
+
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+
+ platform_set_drvdata(pdev, data);
+ samsung_clk_of_add_provider(dev->of_node, ctx);
+
+ return 0;
+}
+
+static const struct of_device_id exynos5433_cmu_of_match[] = {
+ {
+ .compatible = "samsung,exynos5433-cmu-aud",
+ .data = &aud_cmu_info,
+ }, {
+ .compatible = "samsung,exynos5433-cmu-cam0",
+ .data = &cam0_cmu_info,
+ }, {
+ .compatible = "samsung,exynos5433-cmu-cam1",
+ .data = &cam1_cmu_info,
+ }, {
+ .compatible = "samsung,exynos5433-cmu-disp",
+ .data = &disp_cmu_info,
+ }, {
+ .compatible = "samsung,exynos5433-cmu-g2d",
+ .data = &g2d_cmu_info,
+ }, {
+ .compatible = "samsung,exynos5433-cmu-g3d",
+ .data = &g3d_cmu_info,
+ }, {
+ .compatible = "samsung,exynos5433-cmu-gscl",
+ .data = &gscl_cmu_info,
+ }, {
+ .compatible = "samsung,exynos5433-cmu-mfc",
+ .data = &mfc_cmu_info,
+ }, {
+ .compatible = "samsung,exynos5433-cmu-hevc",
+ .data = &hevc_cmu_info,
+ }, {
+ .compatible = "samsung,exynos5433-cmu-isp",
+ .data = &isp_cmu_info,
+ }, {
+ .compatible = "samsung,exynos5433-cmu-mscl",
+ .data = &mscl_cmu_info,
+ }, {
+ },
+};
+
+static const struct dev_pm_ops exynos5433_cmu_pm_ops = {
+ SET_RUNTIME_PM_OPS(exynos5433_cmu_suspend, exynos5433_cmu_resume,
+ NULL)
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
+};
+
+static struct platform_driver exynos5433_cmu_driver __refdata = {
+ .driver = {
+ .name = "exynos5433-cmu",
+ .of_match_table = exynos5433_cmu_of_match,
+ .suppress_bind_attrs = true,
+ .pm = &exynos5433_cmu_pm_ops,
+ },
+ .probe = exynos5433_cmu_probe,
};
-static void __init exynos5433_cmu_cam1_init(struct device_node *np)
+static int __init exynos5433_cmu_init(void)
{
- samsung_cmu_register_one(np, &cam1_cmu_info);
+ return platform_driver_register(&exynos5433_cmu_driver);
}
-CLK_OF_DECLARE(exynos5433_cmu_cam1, "samsung,exynos5433-cmu-cam1",
- exynos5433_cmu_cam1_init);
+core_initcall(exynos5433_cmu_init);
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index 9263d8a27c6b..664020cb4794 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -354,6 +354,12 @@ struct samsung_cmu_info {
/* list and number of clocks registers */
const unsigned long *clk_regs;
unsigned int nr_clk_regs;
+
+ /* list and number of clocks registers to set before suspend */
+ const struct samsung_clk_reg_dump *suspend_regs;
+ unsigned int nr_suspend_regs;
+ /* name of the parent clock needed for CMU register access */
+ const char *clk_name;
};
extern struct samsung_clk_provider *__init samsung_clk_init(
--
1.9.1
^ permalink raw reply related
* [PATCH 1/3] nvmem: add NXP LPC18xx OTP driver
From: Srinivas Kandagatla @ 2016-09-19 10:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160913161241.22492-2-manabian@gmail.com>
On 13/09/16 17:12, Joachim Eastwood wrote:
> Add simple read only driver for the internal OTP (One Time Programmable)
> memory found on all NXP LPC18xx and LPC43xx devices.
>
> The OTP memory is split into 4 banks each with 4 32-bits word. Some of
> the banks contain predefined data while others are for general purpose
> and user programmable via the OTP API in ROM. Note that writing to the
> OTP memory is not yet supported.
>
> Signed-off-by: Joachim Eastwood <manabian@gmail.com>
> ---
> drivers/nvmem/Kconfig | 10 ++++
> drivers/nvmem/Makefile | 2 +
> drivers/nvmem/lpc18xx_otp.c | 123 ++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 135 insertions(+)
> create mode 100644 drivers/nvmem/lpc18xx_otp.c
>
Patch looks good to me.
I will pick this patch + bindings patch once rc1 lands in.
Thanks,
srini
^ permalink raw reply
* [PATCH v2 4/5] ARM: dts: exynos: add support for ISP power domain to exynos4x12 clocks device
From: Marek Szyprowski @ 2016-09-19 10:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1474282525-30441-1-git-send-email-m.szyprowski@samsung.com>
Exynos4412 clock controller contains some additional clocks for FIMC-ISP
(Camera ISP) subsystem. Registers for those clocks are partially located
in the SOC area, which belongs to ISP power domain.
This patch implements integration of ISP clocks with ISP power domain.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
arch/arm/boot/dts/exynos4x12.dtsi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
index 3394bdcf10ae..4daea67546b9 100644
--- a/arch/arm/boot/dts/exynos4x12.dtsi
+++ b/arch/arm/boot/dts/exynos4x12.dtsi
@@ -74,6 +74,11 @@
compatible = "samsung,exynos4412-clock";
reg = <0x10030000 0x20000>;
#clock-cells = <1>;
+
+ isp-clock-controller {
+ compatible = "samsung,exynos4412-isp-clock";
+ power-domains = <&pd_isp>;
+ };
};
mct at 10050000 {
--
1.9.1
^ permalink raw reply related
* [PATCH v2 3/5] clocks: exynos4x12: add runtime pm support for ISP clocks
From: Marek Szyprowski @ 2016-09-19 10:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1474282525-30441-1-git-send-email-m.szyprowski@samsung.com>
Exynos4412 clock controller contains some additional clocks for FIMC-ISP
(Camera ISP) subsystem. Registers for those clocks are partially located
in the SOC area, which belongs to ISP power domain.
This patch implements integration of ISP clocks with ISP power domain
by using runtime pm feature of clocks core. This finally solves all the
mysterious freezes in accessing ISP clocks when ISP power domain is disabled.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
.../devicetree/bindings/clock/exynos4-clock.txt | 22 ++
drivers/clk/samsung/clk-exynos4.c | 227 +++++++++++++++------
2 files changed, 188 insertions(+), 61 deletions(-)
diff --git a/Documentation/devicetree/bindings/clock/exynos4-clock.txt b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
index f5a5b19ed3b2..429dd7e420e4 100644
--- a/Documentation/devicetree/bindings/clock/exynos4-clock.txt
+++ b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
@@ -41,3 +41,25 @@ Example 2: UART controller node that consumes the clock generated by the clock
clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
clock-names = "uart", "clk_uart_baud0";
};
+
+Exynos4412 clock controller contains some additional clocks for FIMC-ISP
+(Camera ISP) subsystem. Registers for those clocks are partially located
+in the SOC area, which belongs to ISP power domain. To properly handle
+additional ISP clocks and their integration with power domains, an
+additional subnode "isp-clock-controller" with "samsung,exynos4412-isp-clock"
+compatible has to be defined under the main Exynos4 clock node. This subnode
+can be then used for linking with respective ISP power domain (for more
+information, see Samsung Exynos power domains bindings).
+
+Example 3: An example of a clock controller for Exynos4412 with ISP clocks.
+
+ clock: clock-controller at 10030000 {
+ compatible = "samsung,exynos4412-clock";
+ reg = <0x10030000 0x20000>;
+ #clock-cells = <1>;
+
+ isp-clock-controller {
+ compatible = "samsung,exynos4412-isp-clock";
+ power-domains = <&pd_isp>;
+ };
+ };
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index faab9b31baf5..3d65e3f92f5a 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -16,7 +16,10 @@
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
+#include <linux/of_platform.h>
#include <linux/syscore_ops.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include "clk.h"
#include "clk-cpu.h"
@@ -123,6 +126,8 @@
#define CLKOUT_CMU_CPU 0x14a00
#define PWR_CTRL1 0x15020
#define E4X12_PWR_CTRL2 0x15024
+
+/* Exynos4x12 specific registers, which belong to ISP power domain */
#define E4X12_DIV_ISP0 0x18300
#define E4X12_DIV_ISP1 0x18304
#define E4X12_GATE_ISP0 0x18800
@@ -156,6 +161,8 @@ enum exynos4_plls {
static void __iomem *reg_base;
static enum exynos4_soc exynos4_soc;
+static struct samsung_clk_provider *exynos4412_ctx;
+static struct device_node *exynos4412_clk_node;
/*
* Support for CMU save/restore across system suspends
@@ -164,6 +171,7 @@ static enum exynos4_soc exynos4_soc;
static struct samsung_clk_reg_dump *exynos4_save_common;
static struct samsung_clk_reg_dump *exynos4_save_soc;
static struct samsung_clk_reg_dump *exynos4_save_pll;
+static struct samsung_clk_reg_dump *exynos4x12_save_isp;
/*
* list of controller registers to be saved and restored during a
@@ -192,6 +200,13 @@ static const unsigned long exynos4x12_clk_save[] __initconst = {
E4X12_PWR_CTRL2,
};
+static const unsigned long exynos4x12_clk_isp_save[] __initconst = {
+ E4X12_DIV_ISP0,
+ E4X12_DIV_ISP1,
+ E4X12_GATE_ISP0,
+ E4X12_GATE_ISP1,
+};
+
static const unsigned long exynos4_clk_pll_regs[] __initconst = {
EPLL_LOCK,
VPLL_LOCK,
@@ -822,20 +837,21 @@ static const struct samsung_div_clock exynos4x12_div_clks[] __initconst = {
DIV(0, "div_spi1_isp", "mout_spi1_isp", E4X12_DIV_ISP, 16, 4),
DIV(0, "div_spi1_isp_pre", "div_spi1_isp", E4X12_DIV_ISP, 20, 8),
DIV(0, "div_uart_isp", "mout_uart_isp", E4X12_DIV_ISP, 28, 4),
- DIV_F(CLK_DIV_ISP0, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3,
- CLK_GET_RATE_NOCACHE, 0),
- DIV_F(CLK_DIV_ISP1, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3,
- CLK_GET_RATE_NOCACHE, 0),
- DIV(0, "div_mpwm", "div_isp1", E4X12_DIV_ISP1, 0, 3),
- DIV_F(CLK_DIV_MCUISP0, "div_mcuisp0", "aclk400_mcuisp", E4X12_DIV_ISP1,
- 4, 3, CLK_GET_RATE_NOCACHE, 0),
- DIV_F(CLK_DIV_MCUISP1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1,
- 8, 3, CLK_GET_RATE_NOCACHE, 0),
DIV(CLK_SCLK_FIMG2D, "sclk_fimg2d", "mout_g2d", DIV_DMC1, 0, 4),
DIV(CLK_DIV_C2C, "div_c2c", "mout_c2c", DIV_DMC1, 4, 3),
DIV(0, "div_c2c_aclk", "div_c2c", DIV_DMC1, 12, 3),
};
+static struct samsung_div_clock exynos4x12_isp_div_clks[] = {
+ DIV_F(CLK_DIV_ISP0, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3, 0, 0),
+ DIV_F(CLK_DIV_ISP1, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3, 0, 0),
+ DIV_F(CLK_DIV_MCUISP0, "div_mcuisp0", "aclk400_mcuisp", E4X12_DIV_ISP1,
+ 4, 3, 0, 0),
+ DIV_F(CLK_DIV_MCUISP1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1,
+ 8, 3, 0, 0),
+ DIV_F(0, "div_mpwm", "div_isp1", E4X12_DIV_ISP1, 0, 3, 0, 0),
+};
+
/* list of gate clocks supported in all exynos4 soc's */
static const struct samsung_gate_clock exynos4_gate_clks[] __initconst = {
/*
@@ -1132,64 +1148,41 @@ static const struct samsung_gate_clock exynos4x12_gate_clks[] __initconst = {
0, 0),
GATE(CLK_I2S0, "i2s0", "aclk100", E4X12_GATE_IP_MAUDIO, 3,
0, 0),
- GATE(CLK_FIMC_ISP, "isp", "aclk200", E4X12_GATE_ISP0, 0,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_FIMC_DRC, "drc", "aclk200", E4X12_GATE_ISP0, 1,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_FIMC_FD, "fd", "aclk200", E4X12_GATE_ISP0, 2,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_FIMC_LITE0, "lite0", "aclk200", E4X12_GATE_ISP0, 3,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_FIMC_LITE1, "lite1", "aclk200", E4X12_GATE_ISP0, 4,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_MCUISP, "mcuisp", "aclk200", E4X12_GATE_ISP0, 5,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_GICISP, "gicisp", "aclk200", E4X12_GATE_ISP0, 7,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_SMMU_ISP, "smmu_isp", "aclk200", E4X12_GATE_ISP0, 8,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_SMMU_DRC, "smmu_drc", "aclk200", E4X12_GATE_ISP0, 9,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_SMMU_FD, "smmu_fd", "aclk200", E4X12_GATE_ISP0, 10,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_SMMU_LITE0, "smmu_lite0", "aclk200", E4X12_GATE_ISP0, 11,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_SMMU_LITE1, "smmu_lite1", "aclk200", E4X12_GATE_ISP0, 12,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_PPMUISPMX, "ppmuispmx", "aclk200", E4X12_GATE_ISP0, 20,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_PPMUISPX, "ppmuispx", "aclk200", E4X12_GATE_ISP0, 21,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_MCUCTL_ISP, "mcuctl_isp", "aclk200", E4X12_GATE_ISP0, 23,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_MPWM_ISP, "mpwm_isp", "aclk200", E4X12_GATE_ISP0, 24,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_I2C0_ISP, "i2c0_isp", "aclk200", E4X12_GATE_ISP0, 25,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_I2C1_ISP, "i2c1_isp", "aclk200", E4X12_GATE_ISP0, 26,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_MTCADC_ISP, "mtcadc_isp", "aclk200", E4X12_GATE_ISP0, 27,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_PWM_ISP, "pwm_isp", "aclk200", E4X12_GATE_ISP0, 28,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_WDT_ISP, "wdt_isp", "aclk200", E4X12_GATE_ISP0, 30,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_UART_ISP, "uart_isp", "aclk200", E4X12_GATE_ISP0, 31,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_ASYNCAXIM, "asyncaxim", "aclk200", E4X12_GATE_ISP1, 0,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_SMMU_ISPCX, "smmu_ispcx", "aclk200", E4X12_GATE_ISP1, 4,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_SPI0_ISP, "spi0_isp", "aclk200", E4X12_GATE_ISP1, 12,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_SPI1_ISP, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
GATE(CLK_G2D, "g2d", "aclk200", GATE_IP_DMC, 23, 0, 0),
GATE(CLK_SMMU_G2D, "smmu_g2d", "aclk200", GATE_IP_DMC, 24, 0, 0),
GATE(CLK_TMU_APBIF, "tmu_apbif", "aclk100", E4X12_GATE_IP_PERIR, 17, 0,
0),
};
+static struct samsung_gate_clock exynos4x12_isp_gate_clks[] = {
+ GATE(CLK_FIMC_ISP, "isp", "aclk200", E4X12_GATE_ISP0, 0, 0, 0),
+ GATE(CLK_FIMC_DRC, "drc", "aclk200", E4X12_GATE_ISP0, 1, 0, 0),
+ GATE(CLK_FIMC_FD, "fd", "aclk200", E4X12_GATE_ISP0, 2, 0, 0),
+ GATE(CLK_FIMC_LITE0, "lite0", "aclk200", E4X12_GATE_ISP0, 3, 0, 0),
+ GATE(CLK_FIMC_LITE1, "lite1", "aclk200", E4X12_GATE_ISP0, 4, 0, 0),
+ GATE(CLK_MCUISP, "mcuisp", "aclk200", E4X12_GATE_ISP0, 5, 0, 0),
+ GATE(CLK_GICISP, "gicisp", "aclk200", E4X12_GATE_ISP0, 7, 0, 0),
+ GATE(CLK_SMMU_ISP, "smmu_isp", "aclk200", E4X12_GATE_ISP0, 8, 0, 0),
+ GATE(CLK_SMMU_DRC, "smmu_drc", "aclk200", E4X12_GATE_ISP0, 9, 0, 0),
+ GATE(CLK_SMMU_FD, "smmu_fd", "aclk200", E4X12_GATE_ISP0, 10, 0, 0),
+ GATE(CLK_SMMU_LITE0, "smmu_lite0", "aclk200", E4X12_GATE_ISP0, 11, 0, 0),
+ GATE(CLK_SMMU_LITE1, "smmu_lite1", "aclk200", E4X12_GATE_ISP0, 12, 0, 0),
+ GATE(CLK_PPMUISPMX, "ppmuispmx", "aclk200", E4X12_GATE_ISP0, 20, 0, 0),
+ GATE(CLK_PPMUISPX, "ppmuispx", "aclk200", E4X12_GATE_ISP0, 21, 0, 0),
+ GATE(CLK_MCUCTL_ISP, "mcuctl_isp", "aclk200", E4X12_GATE_ISP0, 23, 0, 0),
+ GATE(CLK_MPWM_ISP, "mpwm_isp", "aclk200", E4X12_GATE_ISP0, 24, 0, 0),
+ GATE(CLK_I2C0_ISP, "i2c0_isp", "aclk200", E4X12_GATE_ISP0, 25, 0, 0),
+ GATE(CLK_I2C1_ISP, "i2c1_isp", "aclk200", E4X12_GATE_ISP0, 26, 0, 0),
+ GATE(CLK_MTCADC_ISP, "mtcadc_isp", "aclk200", E4X12_GATE_ISP0, 27, 0, 0),
+ GATE(CLK_PWM_ISP, "pwm_isp", "aclk200", E4X12_GATE_ISP0, 28, 0, 0),
+ GATE(CLK_WDT_ISP, "wdt_isp", "aclk200", E4X12_GATE_ISP0, 30, 0, 0),
+ GATE(CLK_UART_ISP, "uart_isp", "aclk200", E4X12_GATE_ISP0, 31, 0, 0),
+ GATE(CLK_ASYNCAXIM, "asyncaxim", "aclk200", E4X12_GATE_ISP1, 0, 0, 0),
+ GATE(CLK_SMMU_ISPCX, "smmu_ispcx", "aclk200", E4X12_GATE_ISP1, 4, 0, 0),
+ GATE(CLK_SPI0_ISP, "spi0_isp", "aclk200", E4X12_GATE_ISP1, 12, 0, 0),
+ GATE(CLK_SPI1_ISP, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13, 0, 0),
+};
+
static const struct samsung_clock_alias exynos4_aliases[] __initconst = {
ALIAS(CLK_MOUT_CORE, NULL, "moutcore"),
ALIAS(CLK_ARM_CLK, NULL, "armclk"),
@@ -1438,6 +1431,116 @@ static const struct exynos_cpuclk_cfg_data e4412_armclk_d[] __initconst = {
{ 0 },
};
+static int exynos4x12_isp_clk_suspend(struct device *dev)
+{
+ samsung_clk_save(reg_base, exynos4x12_save_isp,
+ ARRAY_SIZE(exynos4x12_clk_isp_save));
+ return 0;
+}
+
+static int exynos4x12_isp_clk_resume(struct device *dev)
+{
+ samsung_clk_restore(reg_base, exynos4x12_save_isp,
+ ARRAY_SIZE(exynos4x12_clk_isp_save));
+ return 0;
+}
+
+static int __init exynos4x12_isp_clk_probe(struct platform_device *pdev)
+{
+ struct samsung_clk_provider *ctx = exynos4412_ctx;
+
+ if (!ctx)
+ return -ENODEV;
+
+ dev_set_name(&pdev->dev, pdev->dev.of_node->name);
+
+ ctx->dev = &pdev->dev;
+ samsung_clk_register_div(ctx, exynos4x12_isp_div_clks,
+ ARRAY_SIZE(exynos4x12_isp_div_clks));
+
+ samsung_clk_register_gate(ctx, exynos4x12_isp_gate_clks,
+ ARRAY_SIZE(exynos4x12_isp_gate_clks));
+ ctx->dev = NULL;
+
+ exynos4x12_save_isp = samsung_clk_alloc_reg_dump(exynos4x12_clk_isp_save,
+ ARRAY_SIZE(exynos4x12_clk_isp_save));
+ if (!exynos4x12_save_isp)
+ dev_warn(&pdev->dev, "failed to allocate sleep save data, no sleep support!\n");
+ else {
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ }
+
+ return 0;
+}
+
+static const struct of_device_id exynos4x12_isp_clk_of_match[] = {
+ { .compatible = "samsung,exynos4412-isp-clock", },
+ { },
+};
+
+static const struct dev_pm_ops exynos4x12_isp_pm_ops = {
+ SET_RUNTIME_PM_OPS(exynos4x12_isp_clk_suspend,
+ exynos4x12_isp_clk_resume, NULL)
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
+};
+
+static struct platform_driver exynos4x12_isp_clk_driver __refdata = {
+ .driver = {
+ .name = "exynos-isp-clk",
+ .of_match_table = exynos4x12_isp_clk_of_match,
+ .suppress_bind_attrs = true,
+ .pm = &exynos4x12_isp_pm_ops,
+ },
+ .probe = exynos4x12_isp_clk_probe,
+};
+
+static int __init exynos4x12_isp_clk_init(void)
+{
+ struct platform_device *parent_pdev;
+ struct device *parent;
+ int ret;
+
+ if (!exynos4412_clk_node)
+ return 0;
+
+ parent_pdev = of_find_device_by_node(exynos4412_clk_node);
+ if (!parent_pdev)
+ return -ENODEV;
+
+ parent = &parent_pdev->dev;
+ ret = of_platform_populate(parent->of_node, NULL, NULL, parent);
+ if (ret)
+ return ret;
+
+ return platform_driver_register(&exynos4x12_isp_clk_driver);
+}
+arch_initcall_sync(exynos4x12_isp_clk_init);
+
+static void __init exynos4x12_isp_defer_clocks(struct samsung_clk_provider *ctx,
+ struct device_node *parent)
+{
+ struct device_node *np = of_get_next_available_child(parent, NULL);
+ if (!np)
+ return;
+
+ if (of_device_is_compatible(np,
+ exynos4x12_isp_clk_of_match[0].compatible)) {
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(exynos4x12_isp_div_clks); i++)
+ samsung_clk_add_lookup(ctx, ERR_PTR(-EPROBE_DEFER),
+ exynos4x12_isp_div_clks[i].id);
+ for (i = 0; i < ARRAY_SIZE(exynos4x12_isp_gate_clks); i++)
+ samsung_clk_add_lookup(ctx, ERR_PTR(-EPROBE_DEFER),
+ exynos4x12_isp_gate_clks[i].id);
+ exynos4412_ctx = ctx;
+ exynos4412_clk_node = parent;
+ }
+ of_node_put(np);
+}
+
/* register exynos4 clocks */
static void __init exynos4_clk_init(struct device_node *np,
enum exynos4_soc soc)
@@ -1529,6 +1632,8 @@ static void __init exynos4_clk_init(struct device_node *np,
samsung_clk_register_fixed_factor(ctx,
exynos4x12_fixed_factor_clks,
ARRAY_SIZE(exynos4x12_fixed_factor_clks));
+ exynos4x12_isp_defer_clocks(ctx, np);
+
if (of_machine_is_compatible("samsung,exynos4412")) {
exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
mout_core_p4x12[0], mout_core_p4x12[1], 0x14200,
--
1.9.1
^ permalink raw reply related
* [PATCH v2 2/5] clock: samsung: add support for runtime pm
From: Marek Szyprowski @ 2016-09-19 10:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1474282525-30441-1-git-send-email-m.szyprowski@samsung.com>
This patch adds struct device pointer to samsung_clk_provider and forwarding it
to clk_register_* functions, so drivers can register clocks, which use runtime
pm feature. It also adds CLK_RUNTIME_PM flag to all clocks for which such
device have been provided.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/clk/samsung/clk-pll.c | 4 ++--
drivers/clk/samsung/clk.c | 36 ++++++++++++++++++++++++------------
drivers/clk/samsung/clk.h | 1 +
3 files changed, 27 insertions(+), 14 deletions(-)
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 48139bd510f1..fa929ddf3551 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -1174,7 +1174,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
}
init.name = pll_clk->name;
- init.flags = pll_clk->flags;
+ init.flags = pll_clk->flags | (ctx->dev ? CLK_RUNTIME_PM : 0);
init.parent_names = &pll_clk->parent_name;
init.num_parents = 1;
@@ -1285,7 +1285,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
pll->lock_reg = base + pll_clk->lock_offset;
pll->con_reg = base + pll_clk->con_offset;
- clk = clk_register(NULL, &pll->hw);
+ clk = clk_register(ctx->dev, &pll->hw);
if (IS_ERR(clk)) {
pr_err("%s: failed to register pll clock %s : %ld\n",
__func__, pll_clk->name, PTR_ERR(clk));
diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
index b7d87d6db9dc..762019893383 100644
--- a/drivers/clk/samsung/clk.c
+++ b/drivers/clk/samsung/clk.c
@@ -143,8 +143,11 @@ void __init samsung_clk_register_fixed_rate(struct samsung_clk_provider *ctx,
unsigned int idx, ret;
for (idx = 0; idx < nr_clk; idx++, list++) {
- clk = clk_register_fixed_rate(NULL, list->name,
- list->parent_name, list->flags, list->fixed_rate);
+ unsigned int pm_flags = ctx->dev ? CLK_RUNTIME_PM : 0;
+
+ clk = clk_register_fixed_rate(ctx->dev, list->name,
+ list->parent_name, list->flags | pm_flags,
+ list->fixed_rate);
if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n", __func__,
list->name);
@@ -172,8 +175,11 @@ void __init samsung_clk_register_fixed_factor(struct samsung_clk_provider *ctx,
unsigned int idx;
for (idx = 0; idx < nr_clk; idx++, list++) {
- clk = clk_register_fixed_factor(NULL, list->name,
- list->parent_name, list->flags, list->mult, list->div);
+ unsigned int pm_flags = ctx->dev ? CLK_RUNTIME_PM : 0;
+
+ clk = clk_register_fixed_factor(ctx->dev, list->name,
+ list->parent_name, list->flags | pm_flags, list->mult,
+ list->div);
if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n", __func__,
list->name);
@@ -193,8 +199,10 @@ void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx,
unsigned int idx, ret;
for (idx = 0; idx < nr_clk; idx++, list++) {
- clk = clk_register_mux(NULL, list->name, list->parent_names,
- list->num_parents, list->flags,
+ unsigned int pm_flags = ctx->dev ? CLK_RUNTIME_PM : 0;
+
+ clk = clk_register_mux(ctx->dev, list->name, list->parent_names,
+ list->num_parents, list->flags | pm_flags,
ctx->reg_base + list->offset,
list->shift, list->width, list->mux_flags, &ctx->lock);
if (IS_ERR(clk)) {
@@ -225,15 +233,17 @@ void __init samsung_clk_register_div(struct samsung_clk_provider *ctx,
unsigned int idx, ret;
for (idx = 0; idx < nr_clk; idx++, list++) {
+ unsigned int pm_flags = ctx->dev ? CLK_RUNTIME_PM : 0;
+
if (list->table)
- clk = clk_register_divider_table(NULL, list->name,
- list->parent_name, list->flags,
+ clk = clk_register_divider_table(ctx->dev, list->name,
+ list->parent_name, list->flags | pm_flags,
ctx->reg_base + list->offset,
list->shift, list->width, list->div_flags,
list->table, &ctx->lock);
else
- clk = clk_register_divider(NULL, list->name,
- list->parent_name, list->flags,
+ clk = clk_register_divider(ctx->dev, list->name,
+ list->parent_name, list->flags | pm_flags,
ctx->reg_base + list->offset, list->shift,
list->width, list->div_flags, &ctx->lock);
if (IS_ERR(clk)) {
@@ -264,8 +274,10 @@ void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
unsigned int idx, ret;
for (idx = 0; idx < nr_clk; idx++, list++) {
- clk = clk_register_gate(NULL, list->name, list->parent_name,
- list->flags, ctx->reg_base + list->offset,
+ unsigned int pm_flags = ctx->dev ? CLK_RUNTIME_PM : 0;
+
+ clk = clk_register_gate(ctx->dev, list->name, list->parent_name,
+ list->flags | pm_flags, ctx->reg_base + list->offset,
list->bit_idx, list->gate_flags, &ctx->lock);
if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n", __func__,
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index da3bdebabf1e..9263d8a27c6b 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -26,6 +26,7 @@ struct clk;
*/
struct samsung_clk_provider {
void __iomem *reg_base;
+ struct device *dev;
struct clk_onecell_data clk_data;
spinlock_t lock;
};
--
1.9.1
^ permalink raw reply related
* [PATCH v2 1/5] clk: add support for runtime pm
From: Marek Szyprowski @ 2016-09-19 10:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1474282525-30441-1-git-send-email-m.szyprowski@samsung.com>
Registers for some clocks might be located in the SOC area, which are under the
power domain. To enable access to those registers respective domain has to be
turned on. Additionally, registers for such clocks will usually loose its
contents when power domain is turned off, so additional saving and restoring of
them might be needed in the clock controller driver.
This patch adds basic infrastructure in the clocks core to allow implementing
driver for such clocks under power domains. Clock provider can supply a
struct device pointer, which is the used by clock core for tracking and managing
clock's controller runtime pm state. Each clk_prepare() operation
will first call pm_runtime_get_sync() on the supplied device, while
clk_unprepare() will do pm_runtime_put() at the end.
Additional calls to pm_runtime_get/put functions are required to ensure that any
register access (like calculating/changing clock rates and unpreparing/disabling
unused clocks on boot) will be done with clock controller in runtime resumend
state.
When one wants to register clock controller, which make use of this feature, he
has to:
1. Provide a struct device to the core when registering the provider and set
CLK_RUNTIME_PM flags for its clocks.
2. It needs to enable runtime PM for that device.
3. It needs to make sure the runtime PM status of the controller device reflects
the HW state.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/clk/clk.c | 107 +++++++++++++++++++++++++++++++++++++++----
include/linux/clk-provider.h | 1 +
2 files changed, 98 insertions(+), 10 deletions(-)
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 820a939fb6bb..096a199b8e46 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -21,6 +21,7 @@
#include <linux/of.h>
#include <linux/device.h>
#include <linux/init.h>
+#include <linux/pm_runtime.h>
#include <linux/sched.h>
#include <linux/clkdev.h>
@@ -46,6 +47,7 @@ struct clk_core {
const struct clk_ops *ops;
struct clk_hw *hw;
struct module *owner;
+ struct device *dev;
struct clk_core *parent;
const char **parent_names;
struct clk_core **parents;
@@ -87,6 +89,26 @@ struct clk {
struct hlist_node clks_node;
};
+/*** runtime pm ***/
+static int clk_pm_runtime_get(struct clk_core *core)
+{
+ int ret = 0;
+
+ if (!core->dev)
+ return 0;
+
+ ret = pm_runtime_get_sync(core->dev);
+ return ret < 0 ? ret : 0;
+}
+
+static void clk_pm_runtime_put(struct clk_core *core)
+{
+ if (!core->dev)
+ return;
+
+ pm_runtime_put(core->dev);
+}
+
/*** locking ***/
static void clk_prepare_lock(void)
{
@@ -150,6 +172,8 @@ static void clk_enable_unlock(unsigned long flags)
static bool clk_core_is_prepared(struct clk_core *core)
{
+ bool status;
+
/*
* .is_prepared is optional for clocks that can prepare
* fall back to software usage counter if it is missing
@@ -157,11 +181,17 @@ static bool clk_core_is_prepared(struct clk_core *core)
if (!core->ops->is_prepared)
return core->prepare_count;
- return core->ops->is_prepared(core->hw);
+ clk_pm_runtime_get(core);
+ status = core->ops->is_prepared(core->hw);
+ clk_pm_runtime_put(core);
+
+ return status;
}
static bool clk_core_is_enabled(struct clk_core *core)
{
+ bool status;
+
/*
* .is_enabled is only mandatory for clocks that gate
* fall back to software usage counter if .is_enabled is missing
@@ -169,7 +199,29 @@ static bool clk_core_is_enabled(struct clk_core *core)
if (!core->ops->is_enabled)
return core->enable_count;
- return core->ops->is_enabled(core->hw);
+ /*
+ * Check if runtime pm is enabled before calling .is_enabled callback,
+ * if not assume that clock is disabled, because we might be called
+ * from atomic context, from which pm_runtime_get() is not allowed.
+ * This function is called mainly from clk_disable_unused_subtree,
+ * which ensures proper runtime pm activation of controller before
+ * taking enable spinlock, but the below check is needed if one tries
+ * to call it from other place.
+ */
+ if (core->dev) {
+ pm_runtime_get_noresume(core->dev);
+ if (pm_runtime_suspended(core->dev)) {
+ status = false;
+ goto done;
+ }
+ }
+
+ status = core->ops->is_enabled(core->hw);
+done:
+ if (core->dev)
+ pm_runtime_put(core->dev);
+
+ return status;
}
/*** helper functions ***/
@@ -489,6 +541,8 @@ static void clk_core_unprepare(struct clk_core *core)
if (core->ops->unprepare)
core->ops->unprepare(core->hw);
+ clk_pm_runtime_put(core);
+
trace_clk_unprepare_complete(core);
clk_core_unprepare(core->parent);
}
@@ -530,10 +584,14 @@ static int clk_core_prepare(struct clk_core *core)
return 0;
if (core->prepare_count == 0) {
- ret = clk_core_prepare(core->parent);
+ ret = clk_pm_runtime_get(core);
if (ret)
return ret;
+ ret = clk_core_prepare(core->parent);
+ if (ret)
+ goto runtime_put;
+
trace_clk_prepare(core);
if (core->ops->prepare)
@@ -541,15 +599,18 @@ static int clk_core_prepare(struct clk_core *core)
trace_clk_prepare_complete(core);
- if (ret) {
- clk_core_unprepare(core->parent);
- return ret;
- }
+ if (ret)
+ goto unprepare;
}
core->prepare_count++;
return 0;
+unprepare:
+ clk_core_unprepare(core->parent);
+runtime_put:
+ clk_pm_runtime_put(core);
+ return ret;
}
static int clk_core_prepare_lock(struct clk_core *core)
@@ -745,6 +806,9 @@ static void clk_unprepare_unused_subtree(struct clk_core *core)
if (core->flags & CLK_IGNORE_UNUSED)
return;
+ if (clk_pm_runtime_get(core) != 0)
+ return;
+
if (clk_core_is_prepared(core)) {
trace_clk_unprepare(core);
if (core->ops->unprepare_unused)
@@ -753,6 +817,8 @@ static void clk_unprepare_unused_subtree(struct clk_core *core)
core->ops->unprepare(core->hw);
trace_clk_unprepare_complete(core);
}
+
+ clk_pm_runtime_put(core);
}
static void clk_disable_unused_subtree(struct clk_core *core)
@@ -768,6 +834,9 @@ static void clk_disable_unused_subtree(struct clk_core *core)
if (core->flags & CLK_OPS_PARENT_ENABLE)
clk_core_prepare_enable(core->parent);
+ if (clk_pm_runtime_get(core) != 0)
+ return;
+
flags = clk_enable_lock();
if (core->enable_count)
@@ -794,6 +863,8 @@ unlock_out:
clk_enable_unlock(flags);
if (core->flags & CLK_OPS_PARENT_ENABLE)
clk_core_disable_unprepare(core->parent);
+
+ clk_pm_runtime_put(core);
}
static bool clk_ignore_unused;
@@ -1563,6 +1634,7 @@ static int clk_core_set_rate_nolock(struct clk_core *core,
{
struct clk_core *top, *fail_clk;
unsigned long rate = req_rate;
+ int ret = 0;
if (!core)
return 0;
@@ -1579,21 +1651,28 @@ static int clk_core_set_rate_nolock(struct clk_core *core,
if (!top)
return -EINVAL;
+ ret = clk_pm_runtime_get(core);
+ if (ret)
+ return ret;
+
/* notify that we are about to change rates */
fail_clk = clk_propagate_rate_change(top, PRE_RATE_CHANGE);
if (fail_clk) {
pr_debug("%s: failed to set %s rate\n", __func__,
fail_clk->name);
clk_propagate_rate_change(top, ABORT_RATE_CHANGE);
- return -EBUSY;
+ ret = -EBUSY;
+ goto err;
}
/* change the rates */
clk_change_rate(top);
core->req_rate = req_rate;
+err:
+ clk_pm_runtime_put(core);
- return 0;
+ return ret;
}
/**
@@ -1824,12 +1903,16 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent)
p_rate = parent->rate;
}
+ ret = clk_pm_runtime_get(core);
+ if (ret)
+ goto out;
+
/* propagate PRE_RATE_CHANGE notifications */
ret = __clk_speculate_rates(core, p_rate);
/* abort if a driver objects */
if (ret & NOTIFY_STOP_MASK)
- goto out;
+ goto runtime_put;
/* do the re-parent */
ret = __clk_set_parent(core, parent, p_index);
@@ -1842,6 +1925,8 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent)
__clk_recalc_accuracies(core);
}
+runtime_put:
+ clk_pm_runtime_put(core);
out:
clk_prepare_unlock();
@@ -2546,6 +2631,8 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
goto fail_name;
}
core->ops = hw->init->ops;
+ if (dev && (hw->init->flags & CLK_RUNTIME_PM))
+ core->dev = dev;
if (dev && dev->driver)
core->owner = dev->driver->owner;
core->hw = hw;
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index a39c0c530778..8a131eb71fdf 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -35,6 +35,7 @@
#define CLK_IS_CRITICAL BIT(11) /* do not gate, ever */
/* parents need enable during gate/ungate, set rate and re-parent */
#define CLK_OPS_PARENT_ENABLE BIT(12)
+#define CLK_RUNTIME_PM BIT(13)
struct clk;
struct clk_hw;
--
1.9.1
^ permalink raw reply related
* [PATCH v2 0/5] Add runtime PM support for clocks (on Exynos SoC example)
From: Marek Szyprowski @ 2016-09-19 10:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CGME20160919105545eucas1p1026e435bbaeb1f5c866a9abcdd051464@eucas1p1.samsung.com>
Dear All,
This patchset adds runtime PM support to common clock framework. This is an
attempt to implement support for clock controllers, which belongs to a power
domain. This approach works surprisingly well on Exynos 4412 and 5433 SoCs,
what allowed us to solve various freeze/crash issues related to power
management.
The main idea behind this patchset is to keep clock's controller power domain
enabled every time when at least one of its clock is enabled or access to its
registers is being made. Clock controller driver (clock provider) can
supply a struct device pointer, which is the used by clock core for tracking and
managing clock's controller runtime pm state. Each clk_prepare() operation will
first call pm_runtime_get_sync() on the supplied device, while clk_unprepare()
will do pm_runtime_put() at the end.
This runtime PM feature has been tested with Exynos4412 and Exynos5433 clocks
drivers. Both have some clocks, which belongs to respective power domains and
need special handling during power on/off procedures. Till now it wasn't handled
at all, what caused various problems.
Patches for exynos 4412 and 5433 clocks drivers change the way the clock
provider is initialized. Instead of CLK_OF_DECLARE based initialization, a
complete platform device driver infrastructure is being used. This is needed to
let driver to use runtime pm feature and integrate with generic power domains.
The side-effect of this change is a delay in clock provider registeration
during system boot, so early initialized drivers might get EPROBEDEFER error
when requesting their clocks. This is an issue for IOMMU drivers, so
this patchset will be fully functional once the deferred probe for IOMMU
will be merged.
The side-effect of this patchset is the one can finally read
/sys/kernel/debug/clk/clk_summary on all Exynos4412 boards without any freeze.
If one wants to test this patchset (on Exynos4412 Trats2 device with FIMC-IS
driver), I've provided a branch with all needed patches (fixes for Exynos,
FIMC-IS driver and IOMMU deferred probe):
https://git.linaro.org/people/marek.szyprowski/linux-srpol.git v4.8-clocks-pm-v2
Patches are based on vanilla v4.8-rc7 kernel.
Best regards
Marek Szyprowski
Samsung R&D Institute Poland
Changelog:
v2:
- Simplified clk_pm_runtime_get/put functions, removed workaround for devices
with disabled runtime pm. Such workaround is no longer needed since commit
4d23a5e84806b202d9231929c9507ef7cf7a0185 ("PM / Domains: Allow runtime PM
during system PM phases").
- Added CLK_RUNTIME_PM flag to indicate clocks, for which clock core should
call runtime pm functions. This solves problem with clocks, for which struct
device is already registered, but no runtime pm is enabled.
- Extended commit messages according to Ulf suggestions.
- Fixed some style issues pointed by Barlomiej.
v1: http://www.spinics.net/lists/arm-kernel/msg528128.html
- initial version
Marek Szyprowski (5):
clk: add support for runtime pm
clock: samsung: add support for runtime pm
clocks: exynos4x12: add runtime pm support for ISP clocks
ARM: dts: exynos: add support for ISP power domain to exynos4x12
clocks device
clocks: exynos5433: add runtime pm support
.../devicetree/bindings/clock/exynos4-clock.txt | 22 ++
arch/arm/boot/dts/exynos4x12.dtsi | 5 +
drivers/clk/clk.c | 107 +++++-
drivers/clk/samsung/clk-exynos4.c | 227 ++++++++----
drivers/clk/samsung/clk-exynos5433.c | 385 ++++++++++++++++-----
drivers/clk/samsung/clk-pll.c | 4 +-
drivers/clk/samsung/clk.c | 36 +-
drivers/clk/samsung/clk.h | 7 +
include/linux/clk-provider.h | 1 +
9 files changed, 632 insertions(+), 162 deletions(-)
--
1.9.1
^ permalink raw reply
* next-20160914 build: 2 failures 3 warnings (next-20160914)
From: Mark Brown @ 2016-09-19 10:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2300987.vYzazfRX5F@wuerfel>
On Mon, Sep 19, 2016 at 12:31:04PM +0200, Arnd Bergmann wrote:
> My guess is that this is indeed the correct fix, but I don't understand
> at all what the function does, and Marcin Niestroj said the same thing,
> he just copied the code from a driver that is always built-in.
Yes, most of the code is copied from regmap-irq. Setting the parent is
needed for edge triggered interrupts that don't latch state when
disabled but isn't needed in the general case.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160919/5befb5da/attachment.sig>
^ permalink raw reply
* [PATCH v3 0/2] KVM: ARM: Enable vtimers with user space gic
From: Alexander Graf @ 2016-09-19 10:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160916133027.GA27036@cbox>
On 16.09.16 15:30, Christoffer Dall wrote:
> On Fri, Sep 16, 2016 at 02:31:42PM +0200, Paolo Bonzini wrote:
>>
>>
>> On 16/09/2016 14:30, Christoffer Dall wrote:
>>>>>> This patch set allows user space to receive vtimer events as well as mask
>>>>>> them, so that we can handle all vtimer related interrupt injection from user
>>>>>> space, enabling us to use architected timer with user space gic emulation.
>>>>>
>>>>> I have already voiced my concerns in the past, including face to face,
>>>>> and I'm going to repeat it: I not keen at all on adding a new userspace
>>>>> interface that is going to bitrot extremely quickly.
>>>>
>>>> You don't have automated tests set up? It's not going to bitrot if you
>>>> test it, either with kvm-unit-tests or just by smoke-testing Linux.
>>>> It's _for_ the raspi, but it's not limited to it.
>>>
>>> Our automated testing situation is not great, no. Something we're
>>> looking at, but have resource problems with.
>>
>> But it's not a good reason to hold back a feature...
>>
>
> I didn't say that exactly, but choosing not to merge something we cannot
> maintain and which we're not paid to look after and where there's a
> minimal interest, is not entirely unreasonable.
>
> That being said, I'm not categorically against these patches, but I
> share Marc's view that we've already seen that non-vgic support had been
> broken for multiple versions without anyone complaining, and without
> automated testing or substantial interest in the work, the patches
> really are likely to bit-rot.
I know that it's very hard to grasp from an upstream maintainer
perspective, but keep in mind where the bulk of execution of kernel code
lies. The average life cycle of a "stable" Linux distribution's kernel
is a few years.
So far all regressions in the user space gic code have been found within
less than 1y of the respective code release. I'd say that counts for
quite a well used feature.
> But I haven't even looked at the patches in detail, I was just replying
> to the comment about testing.
Also keep in mind that without the architected timer support (and/or
without qemu patches than enable user space timers) the user space gic
support is pretty unusable to most people, so you obviously get less
reports.
Alex
^ permalink raw reply
* [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
From: Mark Rutland @ 2016-09-19 10:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CALCETrUDWiDmLbMqw9sQYEzvDuSVfmT_UscxQXfmf8YYyTOC=Q@mail.gmail.com>
[Adding Yosinori Sato for h8300]
On Fri, Sep 16, 2016 at 08:11:14AM -0700, Andy Lutomirski wrote:
> > On Thu, Sep 15, 2016 at 11:37:47AM -0700, Andy Lutomirski wrote:
> > > On Thu, Sep 15, 2016 at 6:49 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> > Just to check, what do you mean to happen with the flags field? Should
> > that always be in the generic thread_info? e.g.
> >
> > struct thread_info {
> > u32 flags;
> > #ifdef arch_thread_info
> > struct arch_thread_info arch_ti;
> > #endif
> > };
>
> Exactly. Possibly with a comment that using thread_struct should be
> preferred and that arch_thread_info should be used only if some header
> file requires access via current_thread_info() or task_thread_info().
Sure thing.
While looking at that, I spotted that would cause a circular include on
h8300, but that appears to be because of a larger bug anyhow. It seems
h8300 has thread_info::restart_block, and manipulates this in its signal
code, yet core code manipulates task_struct::restart_block.
I think we need something like the below (which is completely untested).
Thanks,
Mark.
---->8----
>From 4dfbdc7706bfb03a48999ff69e85e0c7361adffe Mon Sep 17 00:00:00 2001
From: Mark Rutland <mark.rutland@arm.com>
Date: Mon, 19 Sep 2016 11:33:42 +0100
Subject: [PATCH] h8300: fix syscall restarting
Back in commit f56141e3e2d9aabf ("all arches, signal: move restart_block
to struct task_struct"), all architectures and core code were changed to
use task_struct::restart_block. However, when h8300 support was
subsequently restored in v4.2, it was not updated to account for this,
and maintains thread_info::restart_block, which is not kept in sync.
This patch drops the redundant restart_block from thread_info, and moves
h8300 to the common one in task_struct, ensuring that syscall restarting
always works as expected.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: stable at vger.kernel.org # v4.2+
---
arch/h8300/include/asm/thread_info.h | 4 ----
arch/h8300/kernel/signal.c | 2 +-
2 files changed, 1 insertion(+), 5 deletions(-)
diff --git a/arch/h8300/include/asm/thread_info.h b/arch/h8300/include/asm/thread_info.h
index b408fe6..3cef068 100644
--- a/arch/h8300/include/asm/thread_info.h
+++ b/arch/h8300/include/asm/thread_info.h
@@ -31,7 +31,6 @@ struct thread_info {
int cpu; /* cpu we're on */
int preempt_count; /* 0 => preemptable, <0 => BUG */
mm_segment_t addr_limit;
- struct restart_block restart_block;
};
/*
@@ -44,9 +43,6 @@ struct thread_info {
.cpu = 0, \
.preempt_count = INIT_PREEMPT_COUNT, \
.addr_limit = KERNEL_DS, \
- .restart_block = { \
- .fn = do_no_restart_syscall, \
- }, \
}
#define init_thread_info (init_thread_union.thread_info)
diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c
index ad1f81f..7138303 100644
--- a/arch/h8300/kernel/signal.c
+++ b/arch/h8300/kernel/signal.c
@@ -79,7 +79,7 @@ restore_sigcontext(struct sigcontext *usc, int *pd0)
unsigned int er0;
/* Always make any pending restarted system calls return -EINTR */
- current_thread_info()->restart_block.fn = do_no_restart_syscall;
+ current->restart_block.fn = do_no_restart_syscall;
/* restore passed registers */
#define COPY(r) do { err |= get_user(regs->r, &usc->sc_##r); } while (0)
--
1.9.1
^ permalink raw reply related
* [PATCH] mtd: s3c2410: add device tree support
From: Sylwester Nawrocki @ 2016-09-19 10:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1474125760-28168-1-git-send-email-sergio.prado@e-labworks.com>
On 09/17/2016 05:22 PM, Sergio Prado wrote:
> +static int s3c24xx_nand_probe_dt(struct platform_device *pdev)
> +{
> + const struct s3c24XX_nand_devtype_data *devtype_data;
> + struct s3c2410_platform_nand *pdata;
> + struct s3c2410_nand_info *info = platform_get_drvdata(pdev);
> + struct device_node *np = pdev->dev.of_node, *child;
> + const struct of_device_id *of_id;
> + struct s3c2410_nand_set *sets;
> +
> + of_id = of_match_device(s3c24xx_nand_dt_ids, &pdev->dev);
> + if (!of_id)
> + return 1;
> +
> + devtype_data = of_id->data;
You could make it a bit simpler with of_device_get_match_data().
--
Thanks,
Sylwester
^ permalink raw reply
* [PATCH] ARM: dts: sun8i: Add accelerometer to polaroid-mid2407pxe03
From: Hans de Goede @ 2016-09-19 10:39 UTC (permalink / raw)
To: linux-arm-kernel
Add a dt node describing the mma7660 accelerometer on the
polaroid-mid2407pxe03 tablet.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
arch/arm/boot/dts/sun8i-a23-polaroid-mid2407pxe03.dts | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm/boot/dts/sun8i-a23-polaroid-mid2407pxe03.dts b/arch/arm/boot/dts/sun8i-a23-polaroid-mid2407pxe03.dts
index 6662127..a86cbed 100644
--- a/arch/arm/boot/dts/sun8i-a23-polaroid-mid2407pxe03.dts
+++ b/arch/arm/boot/dts/sun8i-a23-polaroid-mid2407pxe03.dts
@@ -62,6 +62,13 @@
};
};
+&i2c1 {
+ mma7660: accelerometer at 4c {
+ reg = <0x4c>;
+ compatible = "fsl,mma7660";
+ };
+};
+
&mmc1 {
pinctrl-names = "default";
pinctrl-0 = <&mmc1_pins_a>;
--
2.9.3
^ permalink raw reply related
* next-20160914 build: 2 failures 3 warnings (next-20160914)
From: Arnd Bergmann @ 2016-09-19 10:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919102150.GI10189@sirena.org.uk>
On Monday, September 19, 2016 11:21:50 AM CEST Mark Brown wrote:
> On Wed, Sep 14, 2016 at 06:11:37PM +0100, Mark Brown wrote:
> > On Wed, Sep 14, 2016 at 09:18:08AM +0100, Build bot for Mark Brown wrote:
>
> > Today's -next fails to build both arm and arm64 allmodconfig due to:
>
> > > arm64-allmodconfig
> > > ERROR: "irq_set_parent" [drivers/mfd/tps65217.ko] undefined!
>
> > > arm-allmodconfig
> > > ERROR: "irq_set_parent" [drivers/mfd/tps65217.ko] undefined!
>
> > due to 262d5cc6ceb293 (mfd: tps65217: Add support for IRQs) since
> > irq_set_parent() isn't exported.
>
> This is still breaking the build, do we have any ETA on getting the
> export added?
Thomas said he'd add it if the export is needed, but so far nobody
could tell if it is, or if the correct fix is something else, so
I have not sent a patch for inclusion.
My guess is that this is indeed the correct fix, but I don't understand
at all what the function does, and Marcin Niestroj said the same thing,
he just copied the code from a driver that is always built-in.
FWIW, the original function is
static int regmap_irq_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
struct regmap_irq_chip_data *data = h->host_data;
irq_set_chip_data(virq, data);
irq_set_chip(virq, &data->irq_chip);
irq_set_nested_thread(virq, 1);
irq_set_parent(virq, data->irq);
irq_set_noprobe(virq);
return 0;
}
and this is the new one:
static int tps65217_irq_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
struct tps65217 *tps = h->host_data;
irq_set_chip_data(virq, tps);
irq_set_chip_and_handler(virq, &tps65217_irq_chip, handle_edge_irq);
irq_set_nested_thread(virq, 1);
irq_set_parent(virq, tps->irq);
irq_set_noprobe(virq);
return 0;
}
twl6030_irq_map() has another almost identical copy, and the only
other caller of irq_set_parent() is gpiochip_set_chained_irqchip(),
which is completely different.
Arnd
^ permalink raw reply
* [PATCH v2 1/1] clk: imx53: Add clocks configuration
From: Fabien Lahoudere @ 2016-09-19 10:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160918002451.GE15478@tiger>
From: Kalle Kankare <kalle.kankare@vincit.fi>
Add clocks configuration for CSI, FIRI and IEEE1588.
Signed-off-by: Fabien Lahoudere <fabien.lahoudere@collabora.co.uk>
---
drivers/clk/imx/clk-imx51-imx53.c | 20 ++++++++++++++++++++
include/dt-bindings/clock/imx5-clock.h | 15 ++++++++++++++-
2 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/imx/clk-imx51-imx53.c b/drivers/clk/imx/clk-imx51-imx53.c
index 29d4c44..1e3c9ea 100644
--- a/drivers/clk/imx/clk-imx51-imx53.c
+++ b/drivers/clk/imx/clk-imx51-imx53.c
@@ -126,6 +126,7 @@ static const char *spdif0_com_sel[] = { "spdif0_podf", "ssi1_root_gate", };
static const char *mx51_spdif1_com_sel[] = { "spdif1_podf", "ssi2_root_gate", };
static const char *step_sels[] = { "lp_apm", };
static const char *cpu_podf_sels[] = { "pll1_sw", "step_sel" };
+static const char *ieee1588_sels[] = { "pll3_sw", "pll4_sw", "dummy" /* usbphy2_clk */, "dummy" /* fec_phy_clk */ };
static struct clk *clk[IMX5_CLK_END];
static struct clk_onecell_data clk_data;
@@ -543,6 +544,25 @@ static void __init mx53_clocks_init(struct device_node *np)
clk[IMX5_CLK_I2C3_GATE] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22);
clk[IMX5_CLK_SATA_GATE] = imx_clk_gate2("sata_gate", "ipg", MXC_CCM_CCGR4, 2);
+ clk[IMX5_CLK_FIRI_SEL] = imx_clk_mux("firi_sel", MXC_CCM_CSCMR2, 12, 2,
+ standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+ clk[IMX5_CLK_FIRI_PRED] = imx_clk_divider("firi_pred", "firi_sel", MXC_CCM_CSCDR3, 6, 3);
+ clk[IMX5_CLK_FIRI_PODF] = imx_clk_divider("firi_podf", "firi_pred", MXC_CCM_CSCDR3, 0, 6);
+ clk[IMX5_CLK_FIRI_SERIAL_GATE] = imx_clk_gate2("firi_serial_gate", "firi_podf", MXC_CCM_CCGR1, 28);
+ clk[IMX5_CLK_FIRI_IPG_GATE] = imx_clk_gate2("firi_ipg_gate", "ipg", MXC_CCM_CCGR1, 26);
+
+ clk[IMX5_CLK_CSI0_MCLK1_SEL] = imx_clk_mux("csi0_mclk1_sel", MXC_CCM_CSCMR2, 22, 2,
+ standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+ clk[IMX5_CLK_CSI0_MCLK1_PRED] = imx_clk_divider("csi0_mclk1_pred", "csi0_mclk1_sel", MXC_CCM_CSCDR4, 6, 3);
+ clk[IMX5_CLK_CSI0_MCLK1_PODF] = imx_clk_divider("csi0_mclk1_podf", "csi0_mclk1_pred", MXC_CCM_CSCDR4, 0, 6);
+ clk[IMX5_CLK_CSI0_MCLK1_GATE] = imx_clk_gate2("csi0_mclk1_serial_gate", "csi0_mclk1_podf", MXC_CCM_CCGR6, 4);
+
+ clk[IMX5_CLK_IEEE1588_SEL] = imx_clk_mux("ieee1588_sel", MXC_CCM_CSCMR2, 14, 2,
+ ieee1588_sels, ARRAY_SIZE(ieee1588_sels));
+ clk[IMX5_CLK_IEEE1588_PRED] = imx_clk_divider("ieee1588_pred", "ieee1588_sel", MXC_CCM_CSCDR2, 6, 3);
+ clk[IMX5_CLK_IEEE1588_PODF] = imx_clk_divider("ieee1588_podf", "ieee1588_pred", MXC_CCM_CSCDR2, 0, 6);
+ clk[IMX5_CLK_IEEE1588_GATE] = imx_clk_gate2("ieee1588_serial_gate", "ieee1588_podf", MXC_CCM_CCGR7, 6);
+
clk[IMX5_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4,
mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel));
clk[IMX5_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", MXC_CCM_CCOSR, 4, 3);
diff --git a/include/dt-bindings/clock/imx5-clock.h b/include/dt-bindings/clock/imx5-clock.h
index f4b7478..d382fc7 100644
--- a/include/dt-bindings/clock/imx5-clock.h
+++ b/include/dt-bindings/clock/imx5-clock.h
@@ -201,6 +201,19 @@
#define IMX5_CLK_STEP_SEL 189
#define IMX5_CLK_CPU_PODF_SEL 190
#define IMX5_CLK_ARM 191
-#define IMX5_CLK_END 192
+#define IMX5_CLK_FIRI_PRED 192
+#define IMX5_CLK_FIRI_SEL 193
+#define IMX5_CLK_FIRI_PODF 194
+#define IMX5_CLK_FIRI_SERIAL_GATE 195
+#define IMX5_CLK_FIRI_IPG_GATE 196
+#define IMX5_CLK_CSI0_MCLK1_PRED 197
+#define IMX5_CLK_CSI0_MCLK1_SEL 198
+#define IMX5_CLK_CSI0_MCLK1_PODF 199
+#define IMX5_CLK_CSI0_MCLK1_GATE 200
+#define IMX5_CLK_IEEE1588_PRED 201
+#define IMX5_CLK_IEEE1588_SEL 202
+#define IMX5_CLK_IEEE1588_PODF 203
+#define IMX5_CLK_IEEE1588_GATE 204
+#define IMX5_CLK_END 205
#endif /* __DT_BINDINGS_CLOCK_IMX5_H */
--
2.1.4
^ permalink raw reply related
* [PATCH] ASoC: samsung: make audio interface/controller explicitly
From: Mark Brown @ 2016-09-19 10:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1BBB8B7D-0C1B-48E0-A516-402515A04568@soulik.info>
On Mon, Sep 19, 2016 at 05:41:50PM +0800, Ayaka wrote:
> ??? iPad ??
Please fix your mail client to word wrap within paragraphs at something
substantially less than 80 columns. Doing this makes your messages much
easier to read and reply to.
> > Are you *sure* simple-card works for AC'97?
> Not sure. I could hardly find a AC97 device in embedded market. If it
> didn't I could disable it. I have only tested simple sound card for
> i2s and SPDIF.
I would be very surprised if it does and AC'97 is supposed to be
enumerable and not need a card binding anyway so best to remove this one
for the time being.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160919/c6b270fe/attachment.sig>
^ permalink raw reply
* next-20160914 build: 2 failures 3 warnings (next-20160914)
From: Mark Brown @ 2016-09-19 10:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160914171137.GF27974@sirena.org.uk>
On Wed, Sep 14, 2016 at 06:11:37PM +0100, Mark Brown wrote:
> On Wed, Sep 14, 2016 at 09:18:08AM +0100, Build bot for Mark Brown wrote:
> Today's -next fails to build both arm and arm64 allmodconfig due to:
> > arm64-allmodconfig
> > ERROR: "irq_set_parent" [drivers/mfd/tps65217.ko] undefined!
> > arm-allmodconfig
> > ERROR: "irq_set_parent" [drivers/mfd/tps65217.ko] undefined!
> due to 262d5cc6ceb293 (mfd: tps65217: Add support for IRQs) since
> irq_set_parent() isn't exported.
This is still breaking the build, do we have any ETA on getting the
export added?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160919/1958a83c/attachment.sig>
^ permalink raw reply
* [PATCH] spi: dw: use relaxed IO accessor
From: Arnd Bergmann @ 2016-09-19 10:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919090041.4024-1-jszhang@marvell.com>
On Monday, September 19, 2016 5:00:41 PM CEST Jisheng Zhang wrote:
> Using the __raw functions is discouraged. Update the driver to use the
> relaxed functions.
>
> Signed-off-by: Jisheng Zhang <jszhang@marvell.com>
This should mention that it fixes the driver for big-endian kernels.
However, it seems that the fix is only correct for the MMIO
registers, while the polled FIFO access is now wrong AFAICT,
both reader and writer:
static void dw_reader(struct dw_spi *dws)
{
u32 max = rx_max(dws);
u16 rxw;
while (max--) {
rxw = dw_read_io_reg(dws, DW_SPI_DR);
/* Care rx only if the transfer's original "rx" is not null */
if (dws->rx_end - dws->len) {
if (dws->n_bytes == 1)
*(u8 *)(dws->rx) = rxw;
else
*(u16 *)(dws->rx) = rxw;
}
dws->rx += dws->n_bytes;
}
}
As the FIFO is a byte stream, we have to use a non-swapping
accessor here, such as readsl() which would also take care of the
loop. The "n_bytes == 1" case probably should look like e.g.
*(u8 *)(dws->rx) = *(u8 *)&rxw;
so you are sure to get the first byte of the rxw variable
rather than the lower 8 bits.
> diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h
> index 61bc3cb..2cfdc4d 100644
> --- a/drivers/spi/spi-dw.h
> +++ b/drivers/spi/spi-dw.h
> @@ -143,22 +143,22 @@ struct dw_spi {
>
> static inline u32 dw_readl(struct dw_spi *dws, u32 offset)
> {
> - return __raw_readl(dws->regs + offset);
> + return readl_relaxed(dws->regs + offset);
> }
>
> static inline u16 dw_readw(struct dw_spi *dws, u32 offset)
> {
> - return __raw_readw(dws->regs + offset);
> + return readw_relaxed(dws->regs + offset);
> }
>
What is the reason for using readl_relaxed() rather than the
normal readl() here? In almost all instances that these are
called, you don't care about the added latency and should just
default to the normal I/O functions.
Arnd
^ permalink raw reply
* [PATCH v4 7/7] ARM: dts: bcm283x: drop alt3 from &gpio
From: Eric Anholt @ 2016-09-19 10:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1474274603-24215-8-git-send-email-kraxel@redhat.com>
Gerd Hoffmann <kraxel@redhat.com> writes:
> As the alt3 group has no pins left drop it from &gpio.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
If you end up spinning another version for some reason, I'd squash this
patch with the previous one. But regardless, 3-7 are:
Acked-by: Eric Anholt <eric@anholt.net>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 800 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160919/749771d8/attachment.sig>
^ permalink raw reply
* [RFC PATCH v2 11/11] irqchip: mbigen: promote mbigen init
From: Marc Zyngier @ 2016-09-19 10:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <3f9b5a3e-13f4-75a4-15bc-f55e26740205@linaro.org>
On 19/09/16 10:49, Hanjun Guo wrote:
> On 2016/9/15 23:24, Marc Zyngier wrote:
>> On 14/09/16 15:21, Hanjun Guo wrote:
>>> From: Hanjun Guo <hanjun.guo@linaro.org>
>>>
>>> mbigen is an irqchip and it needs to be probed before
>>> devices, same logic is used for SMMU and etc., let's
>>> use arch_initcall instead of platform init for mbigen.
>>>
>>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>> Cc: Ma Jun <majun258@huawei.com>
>>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>>> ---
>>> drivers/irqchip/irq-mbigen.c | 6 +++++-
>>> 1 file changed, 5 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
>>> index ca6add1..3a33de6 100644
>>> --- a/drivers/irqchip/irq-mbigen.c
>>> +++ b/drivers/irqchip/irq-mbigen.c
>>> @@ -374,7 +374,11 @@ static struct platform_driver mbigen_platform_driver = {
>>> .probe = mbigen_device_probe,
>>> };
>>>
>>> -module_platform_driver(mbigen_platform_driver);
>>> +static __init int mbigen_init(void)
>>> +{
>>> + return platform_driver_register(&mbigen_platform_driver);
>>> +}
>>> +arch_initcall(mbigen_init);
>>>
>>> MODULE_AUTHOR("Jun Ma <majun258@huawei.com>");
>>> MODULE_AUTHOR("Yun Wu <wuyun.wu@huawei.com>");
>>>
>>
>> I've already NACKed such a patch in the past, and I will carry on
>> NACKing it until all the other avenues (like properly tracking device
>> dependencies) have been explored and have been proven not to be fit for
>> purpose.
>
> I'd happy to work on this to make progress.
>
>>
>> Rafael had proposed something around this subject last year, and I've
>
> Sorry, obviously I missed something, could you give me the link about
> Rafael's patches? I will pull back and test it on our hardware.
Please see this discussion from almost a year ago:
https://patchwork.kernel.org/patch/7407401/
in which I give the existing pointers and explain why I'm pushing back
on things like this patch.
>
>> been repeatedly advising you to work with him and others to make it
>> happen. You can choose to ignore this advise, but that doesn't make this
>> patch an acceptable approach.
>
> OK, I will drop this patch in next version, and work on the generic
> solution instead.
That'd be the ideal thing, and that's what I suggested when we did meet
in BKK earlier this year. Obviously, I didn't convey my point clearly
enough.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH 5/6] arm/arm64: vgic-new: Implement VGICv3 CPU interface access
From: Peter Maydell @ 2016-09-19 10:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CALicx6s=FOVv8t-6s4VJYwqUGaCfqMxrjXuop=JX6UYrYVj7Fg@mail.gmail.com>
On 19 September 2016 at 08:36, Vijay Kilari <vijay.kilari@gmail.com> wrote:
> In order to track the PRI and ID bits written by guest,
> VGIC needs to store these values when ICC_CTRL_EL1 is updated.
> However, QEMU is reseting VGIC by writing 0's to all the
> registers after VGIC initialization and hence the back up values are
> always reset to 0 and hence when guest read back, VGIC returns wrong value.
>
> One option is to drop VGIC reset from QEMU which is not doing much.
No, if QEMU's reset is not resetting registers to the right value
the correct thing to do is fix the reset code. The way device
reset is supposed to work is that QEMU knows the right values
to use and it writes them to the kernel.
QEMU doesn't reset ICC_CTLR_EL1 to 0 for TCG:
cs->icc_ctlr_el1[GICV3_NS] = ICC_CTLR_EL1_A3V |
(1 << ICC_CTLR_EL1_IDBITS_SHIFT) |
(7 << ICC_CTLR_EL1_PRIBITS_SHIFT);
but I don't think that code gets run for the KVM VGIC.
thanks
-- PMM
^ permalink raw reply
* [PATCH 1/2] arm64: defconfig: enable I2C and DW MMC controller on rockchip platform
From: Andy Yan @ 2016-09-19 10:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1473248790-27101-1-git-send-email-andy.yan@rock-chips.com>
Hi :
Respected maintainers, is there some suggestions for this patch?
On 2016?09?07? 19:46, Andy Yan wrote:
> I2C and MMC are very basic modules for a board to bootup, as I2C always
> used to configure PMIC and MMC devices often used to store filesytem.
> So enable them here to let the rockchip based arm64 boards can bootup.
>
> Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
> ---
>
> arch/arm64/configs/defconfig | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index eadf485..427b6dc 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -222,6 +222,7 @@ CONFIG_I2C_QUP=y
> CONFIG_I2C_TEGRA=y
> CONFIG_I2C_UNIPHIER_F=y
> CONFIG_I2C_RCAR=y
> +CONFIG_I2C_RK3X=y
> CONFIG_I2C_CROS_EC_TUNNEL=y
> CONFIG_SPI=y
> CONFIG_SPI_ORION=y
> @@ -323,6 +324,7 @@ CONFIG_MMC_SPI=y
> CONFIG_MMC_DW=y
> CONFIG_MMC_DW_EXYNOS=y
> CONFIG_MMC_DW_K3=y
> +CONFIG_MMC_DW_ROCKCHIP=y
> CONFIG_MMC_SUNXI=y
> CONFIG_NEW_LEDS=y
> CONFIG_LEDS_CLASS=y
^ permalink raw reply
* [PATCH v4 1/7] pinctrl: bcm2835: add pull defines to dt bindings
From: Eric Anholt @ 2016-09-19 10:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1474274603-24215-2-git-send-email-kraxel@redhat.com>
Gerd Hoffmann <kraxel@redhat.com> writes:
> Also delete (unused) private enum from driver.
> The pull defines can be used instead if needed.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Eric Anholt <eric@anholt.net>
gpio maintainers, could I pull this through my dt tree? Or does this
need to be split in two?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 800 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160919/82c39ac2/attachment.sig>
^ permalink raw reply
* [RFC PATCH v2 11/11] irqchip: mbigen: promote mbigen init
From: Hanjun Guo @ 2016-09-19 9:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <57DABD2F.1030606@arm.com>
On 2016/9/15 23:24, Marc Zyngier wrote:
> On 14/09/16 15:21, Hanjun Guo wrote:
>> From: Hanjun Guo <hanjun.guo@linaro.org>
>>
>> mbigen is an irqchip and it needs to be probed before
>> devices, same logic is used for SMMU and etc., let's
>> use arch_initcall instead of platform init for mbigen.
>>
>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>> Cc: Thomas Gleixner <tglx@linutronix.de>
>> Cc: Ma Jun <majun258@huawei.com>
>> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
>> ---
>> drivers/irqchip/irq-mbigen.c | 6 +++++-
>> 1 file changed, 5 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
>> index ca6add1..3a33de6 100644
>> --- a/drivers/irqchip/irq-mbigen.c
>> +++ b/drivers/irqchip/irq-mbigen.c
>> @@ -374,7 +374,11 @@ static struct platform_driver mbigen_platform_driver = {
>> .probe = mbigen_device_probe,
>> };
>>
>> -module_platform_driver(mbigen_platform_driver);
>> +static __init int mbigen_init(void)
>> +{
>> + return platform_driver_register(&mbigen_platform_driver);
>> +}
>> +arch_initcall(mbigen_init);
>>
>> MODULE_AUTHOR("Jun Ma <majun258@huawei.com>");
>> MODULE_AUTHOR("Yun Wu <wuyun.wu@huawei.com>");
>>
>
> I've already NACKed such a patch in the past, and I will carry on
> NACKing it until all the other avenues (like properly tracking device
> dependencies) have been explored and have been proven not to be fit for
> purpose.
I'd happy to work on this to make progress.
>
> Rafael had proposed something around this subject last year, and I've
Sorry, obviously I missed something, could you give me the link about
Rafael's patches? I will pull back and test it on our hardware.
> been repeatedly advising you to work with him and others to make it
> happen. You can choose to ignore this advise, but that doesn't make this
> patch an acceptable approach.
OK, I will drop this patch in next version, and work on the generic
solution instead.
Thanks
Hanjun
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox