From 38d19752a7807392e4517a14c21e7cf1cdddbd2d Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Mon, 16 Apr 2018 10:33:34 +0800 Subject: soc: mediatek: use of_device_get_match_data() The usage of of_device_get_match_data() reduce the code size a bit. Also, the only way to call pwrap_probe() is to match an entry in of_pwrap_match_tbl[], so of_id cannot be NULL. Signed-off-by: Ryder Lee Signed-off-by: Matthias Brugger --- drivers/soc/mediatek/mtk-pmic-wrap.c | 13 +++---------- drivers/soc/mediatek/mtk-scpsys.c | 4 +--- 2 files changed, 4 insertions(+), 13 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c index e9e054a15b7d..2afae64061d8 100644 --- a/drivers/soc/mediatek/mtk-pmic-wrap.c +++ b/drivers/soc/mediatek/mtk-pmic-wrap.c @@ -1458,19 +1458,12 @@ static int pwrap_probe(struct platform_device *pdev) int ret, irq; struct pmic_wrapper *wrp; struct device_node *np = pdev->dev.of_node; - const struct of_device_id *of_id = - of_match_device(of_pwrap_match_tbl, &pdev->dev); const struct of_device_id *of_slave_id = NULL; struct resource *res; - if (!of_id) { - dev_err(&pdev->dev, "Error: No device match found\n"); - return -ENODEV; - } + if (np->child) + of_slave_id = of_match_node(of_slave_match_tbl, np->child); - if (pdev->dev.of_node->child) - of_slave_id = of_match_node(of_slave_match_tbl, - pdev->dev.of_node->child); if (!of_slave_id) { dev_dbg(&pdev->dev, "slave pmic should be defined in dts\n"); return -EINVAL; @@ -1482,7 +1475,7 @@ static int pwrap_probe(struct platform_device *pdev) platform_set_drvdata(pdev, wrp); - wrp->master = of_id->data; + wrp->master = of_device_get_match_data(&pdev->dev); wrp->slave = of_slave_id->data; wrp->dev = &pdev->dev; diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c index d762a46d434f..a31ac4a4f859 100644 --- a/drivers/soc/mediatek/mtk-scpsys.c +++ b/drivers/soc/mediatek/mtk-scpsys.c @@ -1067,15 +1067,13 @@ static const struct of_device_id of_scpsys_match_tbl[] = { static int scpsys_probe(struct platform_device *pdev) { - const struct of_device_id *match; const struct scp_subdomain *sd; const struct scp_soc_data *soc; struct scp *scp; struct genpd_onecell_data *pd_data; int i, ret; - match = of_match_device(of_scpsys_match_tbl, &pdev->dev); - soc = (const struct scp_soc_data *)match->data; + soc = of_device_get_match_data(&pdev->dev); scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs, soc->bus_prot_reg_update); -- cgit v1.2.3 From b2b568c591ddbb20d597e256212579d70dbf3000 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 6 Mar 2018 15:33:11 +0100 Subject: soc: samsung: pm_domains: Deprecate support for clocks Handling of special clock operations on power domain on/off sequences has been moved to respective Exynos clock controller drivers, so there is no need to keep the duplicated (and conflicting) code in Exynos power domain driver. Mark clock related properties in Exynos power domain bindings as deprecated. This change has no inpact on backwards-compatibility, as the new drivers properly work with old DTBs (deprecated properties are ignored). Signed-off-by: Marek Szyprowski Signed-off-by: Krzysztof Kozlowski --- drivers/soc/samsung/pm_domains.c | 90 +--------------------------------------- 1 file changed, 1 insertion(+), 89 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/samsung/pm_domains.c b/drivers/soc/samsung/pm_domains.c index caf45cf7aa8e..ab8582971bfc 100644 --- a/drivers/soc/samsung/pm_domains.c +++ b/drivers/soc/samsung/pm_domains.c @@ -13,14 +13,11 @@ #include #include #include -#include #include #include #include #include -#define MAX_CLK_PER_DOMAIN 4 - struct exynos_pm_domain_config { /* Value for LOCAL_PWR_CFG and STATUS fields for each domain */ u32 local_pwr_cfg; @@ -33,10 +30,6 @@ struct exynos_pm_domain { void __iomem *base; bool is_off; struct generic_pm_domain pd; - struct clk *oscclk; - struct clk *clk[MAX_CLK_PER_DOMAIN]; - struct clk *pclk[MAX_CLK_PER_DOMAIN]; - struct clk *asb_clk[MAX_CLK_PER_DOMAIN]; u32 local_pwr_cfg; }; @@ -46,29 +39,10 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) void __iomem *base; u32 timeout, pwr; char *op; - int i; pd = container_of(domain, struct exynos_pm_domain, pd); base = pd->base; - for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) { - if (IS_ERR(pd->asb_clk[i])) - break; - clk_prepare_enable(pd->asb_clk[i]); - } - - /* Set oscclk before powering off a domain*/ - if (!power_on) { - for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) { - if (IS_ERR(pd->clk[i])) - break; - pd->pclk[i] = clk_get_parent(pd->clk[i]); - if (clk_set_parent(pd->clk[i], pd->oscclk)) - pr_err("%s: error setting oscclk as parent to clock %d\n", - domain->name, i); - } - } - pwr = power_on ? pd->local_pwr_cfg : 0; writel_relaxed(pwr, base); @@ -86,26 +60,6 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on) usleep_range(80, 100); } - /* Restore clocks after powering on a domain*/ - if (power_on) { - for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) { - if (IS_ERR(pd->clk[i])) - break; - - if (IS_ERR(pd->pclk[i])) - continue; /* Skip on first power up */ - if (clk_set_parent(pd->clk[i], pd->pclk[i])) - pr_err("%s: error setting parent to clock%d\n", - domain->name, i); - } - } - - for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) { - if (IS_ERR(pd->asb_clk[i])) - break; - clk_disable_unprepare(pd->asb_clk[i]); - } - return 0; } @@ -147,12 +101,6 @@ static __init const char *exynos_get_domain_name(struct device_node *node) return kstrdup_const(name, GFP_KERNEL); } -static const char *soc_force_no_clk[] = { - "samsung,exynos5250-clock", - "samsung,exynos5420-clock", - "samsung,exynos5800-clock", -}; - static __init int exynos4_pm_init_power_domain(void) { struct device_node *np; @@ -161,7 +109,7 @@ static __init int exynos4_pm_init_power_domain(void) for_each_matching_node_and_match(np, exynos_pm_domain_of_match, &match) { const struct exynos_pm_domain_config *pm_domain_cfg; struct exynos_pm_domain *pd; - int on, i; + int on; pm_domain_cfg = match->data; @@ -189,42 +137,6 @@ static __init int exynos4_pm_init_power_domain(void) pd->pd.power_on = exynos_pd_power_on; pd->local_pwr_cfg = pm_domain_cfg->local_pwr_cfg; - for (i = 0; i < ARRAY_SIZE(soc_force_no_clk); i++) - if (of_find_compatible_node(NULL, NULL, - soc_force_no_clk[i])) - goto no_clk; - - for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) { - char clk_name[8]; - - snprintf(clk_name, sizeof(clk_name), "asb%d", i); - pd->asb_clk[i] = of_clk_get_by_name(np, clk_name); - if (IS_ERR(pd->asb_clk[i])) - break; - } - - pd->oscclk = of_clk_get_by_name(np, "oscclk"); - if (IS_ERR(pd->oscclk)) - goto no_clk; - - for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) { - char clk_name[8]; - - snprintf(clk_name, sizeof(clk_name), "clk%d", i); - pd->clk[i] = of_clk_get_by_name(np, clk_name); - if (IS_ERR(pd->clk[i])) - break; - /* - * Skip setting parent on first power up. - * The parent at this time may not be useful at all. - */ - pd->pclk[i] = ERR_PTR(-EINVAL); - } - - if (IS_ERR(pd->clk[0])) - clk_put(pd->oscclk); - -no_clk: on = readl_relaxed(pd->base + 0x4) & pd->local_pwr_cfg; pm_genpd_init(&pd->pd, NULL, !on); -- cgit v1.2.3 From 4a58732c7c41c5a33b23556a2481d8a989060b4e Mon Sep 17 00:00:00 2001 From: Sean Wang Date: Tue, 3 Apr 2018 15:15:53 +0800 Subject: soc: mediatek: reuse read[l,x]_poll_timeout helpers Reuse the common helpers read[l,x]_poll_timeout provided by Linux core instead of an open-coded handling. The name of the local variable sram_pdn_ack in scpsys_power_on is renamed to pdn_ack in order to be consistent with the one used in scpsys_power_off. Signed-off-by: Sean Wang Cc: Matthias Brugger Cc: Ulf Hansson Cc: Weiyi Lu Signed-off-by: Matthias Brugger --- drivers/soc/mediatek/mtk-scpsys.c | 91 ++++++++++----------------------------- 1 file changed, 23 insertions(+), 68 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c index a31ac4a4f859..f140e71ec57b 100644 --- a/drivers/soc/mediatek/mtk-scpsys.c +++ b/drivers/soc/mediatek/mtk-scpsys.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,9 @@ #include #include +#define MTK_POLL_DELAY_US 10 +#define MTK_POLL_TIMEOUT (jiffies_to_usecs(HZ)) + #define SPM_VDE_PWR_CON 0x0210 #define SPM_MFG_PWR_CON 0x0214 #define SPM_VEN_PWR_CON 0x0230 @@ -184,12 +188,10 @@ static int scpsys_power_on(struct generic_pm_domain *genpd) { struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd); struct scp *scp = scpd->scp; - unsigned long timeout; - bool expired; void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs; - u32 sram_pdn_ack = scpd->data->sram_pdn_ack_bits; + u32 pdn_ack = scpd->data->sram_pdn_ack_bits; u32 val; - int ret; + int ret, tmp; int i; if (scpd->supply) { @@ -215,23 +217,10 @@ static int scpsys_power_on(struct generic_pm_domain *genpd) writel(val, ctl_addr); /* wait until PWR_ACK = 1 */ - timeout = jiffies + HZ; - expired = false; - while (1) { - ret = scpsys_domain_is_on(scpd); - if (ret > 0) - break; - - if (expired) { - ret = -ETIMEDOUT; - goto err_pwr_ack; - } - - cpu_relax(); - - if (time_after(jiffies, timeout)) - expired = true; - } + ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp > 0, + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); + if (ret < 0) + goto err_pwr_ack; val &= ~PWR_CLK_DIS_BIT; writel(val, ctl_addr); @@ -246,20 +235,10 @@ static int scpsys_power_on(struct generic_pm_domain *genpd) writel(val, ctl_addr); /* wait until SRAM_PDN_ACK all 0 */ - timeout = jiffies + HZ; - expired = false; - while (sram_pdn_ack && (readl(ctl_addr) & sram_pdn_ack)) { - - if (expired) { - ret = -ETIMEDOUT; - goto err_pwr_ack; - } - - cpu_relax(); - - if (time_after(jiffies, timeout)) - expired = true; - } + ret = readl_poll_timeout(ctl_addr, tmp, (tmp & pdn_ack) == 0, + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); + if (ret < 0) + goto err_pwr_ack; if (scpd->data->bus_prot_mask) { ret = mtk_infracfg_clear_bus_protection(scp->infracfg, @@ -289,12 +268,10 @@ static int scpsys_power_off(struct generic_pm_domain *genpd) { struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd); struct scp *scp = scpd->scp; - unsigned long timeout; - bool expired; void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs; u32 pdn_ack = scpd->data->sram_pdn_ack_bits; u32 val; - int ret; + int ret, tmp; int i; if (scpd->data->bus_prot_mask) { @@ -310,19 +287,10 @@ static int scpsys_power_off(struct generic_pm_domain *genpd) writel(val, ctl_addr); /* wait until SRAM_PDN_ACK all 1 */ - timeout = jiffies + HZ; - expired = false; - while (pdn_ack && (readl(ctl_addr) & pdn_ack) != pdn_ack) { - if (expired) { - ret = -ETIMEDOUT; - goto out; - } - - cpu_relax(); - - if (time_after(jiffies, timeout)) - expired = true; - } + ret = readl_poll_timeout(ctl_addr, tmp, (tmp & pdn_ack) == pdn_ack, + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); + if (ret < 0) + goto out; val |= PWR_ISO_BIT; writel(val, ctl_addr); @@ -340,23 +308,10 @@ static int scpsys_power_off(struct generic_pm_domain *genpd) writel(val, ctl_addr); /* wait until PWR_ACK = 0 */ - timeout = jiffies + HZ; - expired = false; - while (1) { - ret = scpsys_domain_is_on(scpd); - if (ret == 0) - break; - - if (expired) { - ret = -ETIMEDOUT; - goto out; - } - - cpu_relax(); - - if (time_after(jiffies, timeout)) - expired = true; - } + ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp == 0, + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); + if (ret < 0) + goto out; for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++) clk_disable_unprepare(scpd->clk[i]); -- cgit v1.2.3 From bc3acbb8752ee9d4b3bed091886511171bf6050f Mon Sep 17 00:00:00 2001 From: Vasyl Gomonovych Date: Fri, 20 Apr 2018 10:20:36 -0700 Subject: soc: ti: knav_qmss: Use percpu instead atomic for stats counter Hwqueue has collect statistics in heavy use queue_pop/queu_push functions for cache efficiency and make push/pop faster use percpu variables. For performance reasons, driver should keep descriptor in software handler as short as possible and quickly return it back to hardware queue. Descriptors coming into driver from hardware after pop and return back by push to reduce descriptor lifetime in driver collect statistics on percpu. Signed-off-by: Vasyl Gomonovych Signed-off-by: Santosh Shilimkar --- drivers/soc/ti/knav_qmss.h | 14 ++++++---- drivers/soc/ti/knav_qmss_queue.c | 60 ++++++++++++++++++++++++++-------------- 2 files changed, 48 insertions(+), 26 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/ti/knav_qmss.h b/drivers/soc/ti/knav_qmss.h index 905b974d1bdc..22f409b86107 100644 --- a/drivers/soc/ti/knav_qmss.h +++ b/drivers/soc/ti/knav_qmss.h @@ -19,6 +19,8 @@ #ifndef __KNAV_QMSS_H__ #define __KNAV_QMSS_H__ +#include + #define THRESH_GTE BIT(7) #define THRESH_LT 0 @@ -162,11 +164,11 @@ struct knav_qmgr_info { * notifies: notifier counts */ struct knav_queue_stats { - atomic_t pushes; - atomic_t pops; - atomic_t push_errors; - atomic_t pop_errors; - atomic_t notifies; + unsigned int pushes; + unsigned int pops; + unsigned int push_errors; + unsigned int pop_errors; + unsigned int notifies; }; /** @@ -283,7 +285,7 @@ struct knav_queue_inst { struct knav_queue { struct knav_reg_queue __iomem *reg_push, *reg_pop, *reg_peek; struct knav_queue_inst *inst; - struct knav_queue_stats stats; + struct knav_queue_stats __percpu *stats; knav_queue_notify_fn notifier_fn; void *notifier_fn_arg; atomic_t notifier_enabled; diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c index 77d6b5c03aae..384d70bd8605 100644 --- a/drivers/soc/ti/knav_qmss_queue.c +++ b/drivers/soc/ti/knav_qmss_queue.c @@ -83,7 +83,7 @@ void knav_queue_notify(struct knav_queue_inst *inst) continue; if (WARN_ON(!qh->notifier_fn)) continue; - atomic_inc(&qh->stats.notifies); + this_cpu_inc(qh->stats->notifies); qh->notifier_fn(qh->notifier_fn_arg); } rcu_read_unlock(); @@ -214,6 +214,12 @@ static struct knav_queue *__knav_queue_open(struct knav_queue_inst *inst, if (!qh) return ERR_PTR(-ENOMEM); + qh->stats = alloc_percpu(struct knav_queue_stats); + if (!qh->stats) { + ret = -ENOMEM; + goto err; + } + qh->flags = flags; qh->inst = inst; id = inst->id - inst->qmgr->start_queue; @@ -229,13 +235,17 @@ static struct knav_queue *__knav_queue_open(struct knav_queue_inst *inst, if (range->ops && range->ops->open_queue) ret = range->ops->open_queue(range, inst, flags); - if (ret) { - devm_kfree(inst->kdev->dev, qh); - return ERR_PTR(ret); - } + if (ret) + goto err; } list_add_tail_rcu(&qh->list, &inst->handles); return qh; + +err: + if (qh->stats) + free_percpu(qh->stats); + devm_kfree(inst->kdev->dev, qh); + return ERR_PTR(ret); } static struct knav_queue * @@ -411,6 +421,12 @@ static void knav_queue_debug_show_instance(struct seq_file *s, { struct knav_device *kdev = inst->kdev; struct knav_queue *qh; + int cpu = 0; + int pushes = 0; + int pops = 0; + int push_errors = 0; + int pop_errors = 0; + int notifies = 0; if (!knav_queue_is_busy(inst)) return; @@ -418,19 +434,22 @@ static void knav_queue_debug_show_instance(struct seq_file *s, seq_printf(s, "\tqueue id %d (%s)\n", kdev->base_id + inst->id, inst->name); for_each_handle_rcu(qh, inst) { - seq_printf(s, "\t\thandle %p: ", qh); - seq_printf(s, "pushes %8d, ", - atomic_read(&qh->stats.pushes)); - seq_printf(s, "pops %8d, ", - atomic_read(&qh->stats.pops)); - seq_printf(s, "count %8d, ", - knav_queue_get_count(qh)); - seq_printf(s, "notifies %8d, ", - atomic_read(&qh->stats.notifies)); - seq_printf(s, "push errors %8d, ", - atomic_read(&qh->stats.push_errors)); - seq_printf(s, "pop errors %8d\n", - atomic_read(&qh->stats.pop_errors)); + for_each_possible_cpu(cpu) { + pushes += per_cpu_ptr(qh->stats, cpu)->pushes; + pops += per_cpu_ptr(qh->stats, cpu)->pops; + push_errors += per_cpu_ptr(qh->stats, cpu)->push_errors; + pop_errors += per_cpu_ptr(qh->stats, cpu)->pop_errors; + notifies += per_cpu_ptr(qh->stats, cpu)->notifies; + } + + seq_printf(s, "\t\thandle %p: pushes %8d, pops %8d, count %8d, notifies %8d, push errors %8d, pop errors %8d\n", + qh, + pushes, + pops, + knav_queue_get_count(qh), + notifies, + push_errors, + pop_errors); } } @@ -547,6 +566,7 @@ void knav_queue_close(void *qhandle) if (range->ops && range->ops->close_queue) range->ops->close_queue(range, inst); } + free_percpu(qh->stats); devm_kfree(inst->kdev->dev, qh); } EXPORT_SYMBOL_GPL(knav_queue_close); @@ -620,7 +640,7 @@ int knav_queue_push(void *qhandle, dma_addr_t dma, val = (u32)dma | ((size / 16) - 1); writel_relaxed(val, &qh->reg_push[0].ptr_size_thresh); - atomic_inc(&qh->stats.pushes); + this_cpu_inc(qh->stats->pushes); return 0; } EXPORT_SYMBOL_GPL(knav_queue_push); @@ -658,7 +678,7 @@ dma_addr_t knav_queue_pop(void *qhandle, unsigned *size) if (size) *size = ((val & DESC_SIZE_MASK) + 1) * 16; - atomic_inc(&qh->stats.pops); + this_cpu_inc(qh->stats->pops); return dma; } EXPORT_SYMBOL_GPL(knav_queue_pop); -- cgit v1.2.3 From 050f810e238f268670f14a8f8b793ba2dbf2e92f Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Tue, 10 Apr 2018 11:32:09 -0700 Subject: soc: imx: gpcv2: Do not pass static memory as platform data Platform device core assumes the ownership of dev.platform_data as well as that it is dynamically allocated and it will try to kfree it as a part of platform_device_release(). Change the code to use platform_device_add_data() n instead of a pointer to a static memory to avoid causing a BUG() when calling platform_device_put(). The problem can be reproduced by artificially enabling the error path of platform_device_add() call (around line 357). Note that this change also allows us to constify imx7_pgc_domains, since we no longer need to be able to modify it. Cc: Stefan Agner Cc: Lucas Stach Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Andrey Smirnov Signed-off-by: Shawn Guo --- drivers/soc/imx/gpcv2.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c index afc7ecc3c187..f4e3bd40c72e 100644 --- a/drivers/soc/imx/gpcv2.c +++ b/drivers/soc/imx/gpcv2.c @@ -155,7 +155,7 @@ static int imx7_gpc_pu_pgc_sw_pdn_req(struct generic_pm_domain *genpd) return imx7_gpc_pu_pgc_sw_pxx_req(genpd, false); } -static struct imx7_pgc_domain imx7_pgc_domains[] = { +static const struct imx7_pgc_domain imx7_pgc_domains[] = { [IMX7_POWER_DOMAIN_MIPI_PHY] = { .genpd = { .name = "mipi-phy", @@ -321,11 +321,6 @@ static int imx_gpcv2_probe(struct platform_device *pdev) continue; } - domain = &imx7_pgc_domains[domain_index]; - domain->regmap = regmap; - domain->genpd.power_on = imx7_gpc_pu_pgc_sw_pup_req; - domain->genpd.power_off = imx7_gpc_pu_pgc_sw_pdn_req; - pd_pdev = platform_device_alloc("imx7-pgc-domain", domain_index); if (!pd_pdev) { @@ -334,7 +329,20 @@ static int imx_gpcv2_probe(struct platform_device *pdev) return -ENOMEM; } - pd_pdev->dev.platform_data = domain; + ret = platform_device_add_data(pd_pdev, + &imx7_pgc_domains[domain_index], + sizeof(imx7_pgc_domains[domain_index])); + if (ret) { + platform_device_put(pd_pdev); + of_node_put(np); + return ret; + } + + domain = pd_pdev->dev.platform_data; + domain->regmap = regmap; + domain->genpd.power_on = imx7_gpc_pu_pgc_sw_pup_req; + domain->genpd.power_off = imx7_gpc_pu_pgc_sw_pdn_req; + pd_pdev->dev.parent = dev; pd_pdev->dev.of_node = np; -- cgit v1.2.3 From f54e714cfc53b9164d1206f9ee49042195532a51 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Tue, 10 Apr 2018 11:32:10 -0700 Subject: soc: imx: gpc: Do not pass static memory as platform data Platform device core assumes the ownership of dev.platform_data as well as that it is dynamically allocated and it will try to kfree it as a part of platform_device_release(). Change the code to use platform_device_add_data() instead of a pointer to a static memory to avoid causing a BUG() when calling platform_device_put(). The problem can be reproduced by artificially enabling the error path of platform_device_add() call (around line 452). Cc: Stefan Agner Cc: Lucas Stach Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Andrey Smirnov Signed-off-by: Shawn Guo --- drivers/soc/imx/gpc.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/imx/gpc.c b/drivers/soc/imx/gpc.c index c4d35f32af8d..32f0748fd067 100644 --- a/drivers/soc/imx/gpc.c +++ b/drivers/soc/imx/gpc.c @@ -443,17 +443,25 @@ static int imx_gpc_probe(struct platform_device *pdev) if (domain_index >= of_id_data->num_domains) continue; - domain = &imx_gpc_domains[domain_index]; - domain->regmap = regmap; - domain->ipg_rate_mhz = ipg_rate_mhz; - pd_pdev = platform_device_alloc("imx-pgc-power-domain", domain_index); if (!pd_pdev) { of_node_put(np); return -ENOMEM; } - pd_pdev->dev.platform_data = domain; + + ret = platform_device_add_data(pd_pdev, + &imx_gpc_domains[domain_index], + sizeof(imx_gpc_domains[domain_index])); + if (ret) { + platform_device_put(pd_pdev); + of_node_put(np); + return ret; + } + domain = pd_pdev->dev.platform_data; + domain->regmap = regmap; + domain->ipg_rate_mhz = ipg_rate_mhz; + pd_pdev->dev.parent = &pdev->dev; pd_pdev->dev.of_node = np; -- cgit v1.2.3 From 9e59c5f66c624b43c766a9fe3b2430e0e976bf0e Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Mon, 14 May 2018 11:29:38 +0800 Subject: soc: rockchip: power-domain: Fix wrong value when power up pd with writemask Solve the pd could only ever turn off but never turn them on again, if the pd registers have the writemask bits. So far this affects the rk3328 only. Fixes: 79bb17ce8edb ("soc: rockchip: power-domain: Support domain control in hiword-registers") Cc: stable@vger.kernel.org Signed-off-by: Finley Xiao Signed-off-by: Elaine Zhang Reviewed-by: Ulf Hansson Signed-off-by: Heiko Stuebner --- drivers/soc/rockchip/pm_domains.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/soc') diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c index 53efc386b1ad..df7f30a425c6 100644 --- a/drivers/soc/rockchip/pm_domains.c +++ b/drivers/soc/rockchip/pm_domains.c @@ -255,7 +255,7 @@ static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd, return; else if (pd->info->pwr_w_mask) regmap_write(pmu->regmap, pmu->info->pwr_offset, - on ? pd->info->pwr_mask : + on ? pd->info->pwr_w_mask : (pd->info->pwr_mask | pd->info->pwr_w_mask)); else regmap_update_bits(pmu->regmap, pmu->info->pwr_offset, -- cgit v1.2.3 From 090c6243b14b909b2136fb40ee084faf842165d2 Mon Sep 17 00:00:00 2001 From: Sean Wang Date: Mon, 23 Apr 2018 14:42:45 +0800 Subject: soc: mediatek: reuse regmap_read_poll_timeout helpers Reuse the common helpers regmap_read_poll_timeout provided by Linux core instead of an open-coded handling. Signed-off-by: Sean Wang Cc: Matthias Brugger Cc: Ulf Hansson Cc: Weiyi Lu Signed-off-by: Matthias Brugger --- drivers/soc/mediatek/mtk-infracfg.c | 46 ++++++++++--------------------------- 1 file changed, 12 insertions(+), 34 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/mediatek/mtk-infracfg.c b/drivers/soc/mediatek/mtk-infracfg.c index 8c310de01e93..958861c9e6ee 100644 --- a/drivers/soc/mediatek/mtk-infracfg.c +++ b/drivers/soc/mediatek/mtk-infracfg.c @@ -17,6 +17,9 @@ #include #include +#define MTK_POLL_DELAY_US 10 +#define MTK_POLL_TIMEOUT (jiffies_to_usecs(HZ)) + #define INFRA_TOPAXI_PROTECTEN 0x0220 #define INFRA_TOPAXI_PROTECTSTA1 0x0228 #define INFRA_TOPAXI_PROTECTEN_SET 0x0260 @@ -37,7 +40,6 @@ int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask, bool reg_update) { - unsigned long expired; u32 val; int ret; @@ -47,22 +49,11 @@ int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask, else regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_SET, mask); - expired = jiffies + HZ; - - while (1) { - ret = regmap_read(infracfg, INFRA_TOPAXI_PROTECTSTA1, &val); - if (ret) - return ret; - - if ((val & mask) == mask) - break; + ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1, + val, (val & mask) == mask, + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); - cpu_relax(); - if (time_after(jiffies, expired)) - return -EIO; - } - - return 0; + return ret; } /** @@ -80,30 +71,17 @@ int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask, int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask, bool reg_update) { - unsigned long expired; int ret; + u32 val; if (reg_update) regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0); else regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_CLR, mask); - expired = jiffies + HZ; - - while (1) { - u32 val; - - ret = regmap_read(infracfg, INFRA_TOPAXI_PROTECTSTA1, &val); - if (ret) - return ret; - - if (!(val & mask)) - break; - - cpu_relax(); - if (time_after(jiffies, expired)) - return -EIO; - } + ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1, + val, !(val & mask), + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); - return 0; + return ret; } -- cgit v1.2.3 From ddf7aa996ca4cc095f3f24fe298ea044d304faa7 Mon Sep 17 00:00:00 2001 From: Sean Wang Date: Mon, 23 Apr 2018 16:36:21 +0800 Subject: soc: mediatek: introduce a CAPS flag for scp_domain_data Instead of adding more and more fields to scp_domain_data which get checked in the code flow, add a caps field used for an indication the characteristics for each SCP domain. At present, type u8 for the caps field is selected which can satisfy the current situation and doesn't take up extra space against type bool previously used. Suggested-by: Matthias Brugger Signed-off-by: Sean Wang Signed-off-by: Matthias Brugger --- drivers/soc/mediatek/mtk-scpsys.c | 65 ++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 31 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c index f140e71ec57b..b1b45e44c7ad 100644 --- a/drivers/soc/mediatek/mtk-scpsys.c +++ b/drivers/soc/mediatek/mtk-scpsys.c @@ -31,6 +31,9 @@ #define MTK_POLL_DELAY_US 10 #define MTK_POLL_TIMEOUT (jiffies_to_usecs(HZ)) +#define MTK_SCPD_ACTIVE_WAKEUP BIT(0) +#define MTK_SCPD_CAPS(_scpd, _x) ((_scpd)->data->caps & (_x)) + #define SPM_VDE_PWR_CON 0x0210 #define SPM_MFG_PWR_CON 0x0214 #define SPM_VEN_PWR_CON 0x0230 @@ -120,7 +123,7 @@ struct scp_domain_data { u32 sram_pdn_ack_bits; u32 bus_prot_mask; enum clk_id clk_id[MAX_CLKS]; - bool active_wakeup; + u8 caps; }; struct scp; @@ -424,7 +427,7 @@ static struct scp *init_scp(struct platform_device *pdev, genpd->name = data->name; genpd->power_off = scpsys_power_off; genpd->power_on = scpsys_power_on; - if (scpd->data->active_wakeup) + if (MTK_SCPD_CAPS(scpd, MTK_SCPD_ACTIVE_WAKEUP)) genpd->flags |= GENPD_FLAG_ACTIVE_WAKEUP; } @@ -477,7 +480,7 @@ static const struct scp_domain_data scp_domain_data_mt2701[] = { .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M | MT2701_TOP_AXI_PROT_EN_CONN_S, .clk_id = {CLK_NONE}, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT2701_POWER_DOMAIN_DISP] = { .name = "disp", @@ -486,7 +489,7 @@ static const struct scp_domain_data scp_domain_data_mt2701[] = { .sram_pdn_bits = GENMASK(11, 8), .clk_id = {CLK_MM}, .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_MM_M0, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT2701_POWER_DOMAIN_MFG] = { .name = "mfg", @@ -495,7 +498,7 @@ static const struct scp_domain_data scp_domain_data_mt2701[] = { .sram_pdn_bits = GENMASK(11, 8), .sram_pdn_ack_bits = GENMASK(12, 12), .clk_id = {CLK_MFG}, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT2701_POWER_DOMAIN_VDEC] = { .name = "vdec", @@ -504,7 +507,7 @@ static const struct scp_domain_data scp_domain_data_mt2701[] = { .sram_pdn_bits = GENMASK(11, 8), .sram_pdn_ack_bits = GENMASK(12, 12), .clk_id = {CLK_MM}, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT2701_POWER_DOMAIN_ISP] = { .name = "isp", @@ -513,7 +516,7 @@ static const struct scp_domain_data scp_domain_data_mt2701[] = { .sram_pdn_bits = GENMASK(11, 8), .sram_pdn_ack_bits = GENMASK(13, 12), .clk_id = {CLK_MM}, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT2701_POWER_DOMAIN_BDP] = { .name = "bdp", @@ -521,7 +524,7 @@ static const struct scp_domain_data scp_domain_data_mt2701[] = { .ctl_offs = SPM_BDP_PWR_CON, .sram_pdn_bits = GENMASK(11, 8), .clk_id = {CLK_NONE}, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT2701_POWER_DOMAIN_ETH] = { .name = "eth", @@ -530,7 +533,7 @@ static const struct scp_domain_data scp_domain_data_mt2701[] = { .sram_pdn_bits = GENMASK(11, 8), .sram_pdn_ack_bits = GENMASK(15, 12), .clk_id = {CLK_ETHIF}, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT2701_POWER_DOMAIN_HIF] = { .name = "hif", @@ -539,14 +542,14 @@ static const struct scp_domain_data scp_domain_data_mt2701[] = { .sram_pdn_bits = GENMASK(11, 8), .sram_pdn_ack_bits = GENMASK(15, 12), .clk_id = {CLK_ETHIF}, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT2701_POWER_DOMAIN_IFR_MSC] = { .name = "ifr_msc", .sta_mask = PWR_STATUS_IFR_MSC, .ctl_offs = SPM_IFR_MSC_PWR_CON, .clk_id = {CLK_NONE}, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, }; @@ -561,7 +564,7 @@ static const struct scp_domain_data scp_domain_data_mt2712[] = { .sram_pdn_bits = GENMASK(8, 8), .sram_pdn_ack_bits = GENMASK(12, 12), .clk_id = {CLK_MM}, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT2712_POWER_DOMAIN_VDEC] = { .name = "vdec", @@ -570,7 +573,7 @@ static const struct scp_domain_data scp_domain_data_mt2712[] = { .sram_pdn_bits = GENMASK(8, 8), .sram_pdn_ack_bits = GENMASK(12, 12), .clk_id = {CLK_MM, CLK_VDEC}, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT2712_POWER_DOMAIN_VENC] = { .name = "venc", @@ -579,7 +582,7 @@ static const struct scp_domain_data scp_domain_data_mt2712[] = { .sram_pdn_bits = GENMASK(11, 8), .sram_pdn_ack_bits = GENMASK(15, 12), .clk_id = {CLK_MM, CLK_VENC, CLK_JPGDEC}, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT2712_POWER_DOMAIN_ISP] = { .name = "isp", @@ -588,7 +591,7 @@ static const struct scp_domain_data scp_domain_data_mt2712[] = { .sram_pdn_bits = GENMASK(11, 8), .sram_pdn_ack_bits = GENMASK(13, 12), .clk_id = {CLK_MM}, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT2712_POWER_DOMAIN_AUDIO] = { .name = "audio", @@ -597,7 +600,7 @@ static const struct scp_domain_data scp_domain_data_mt2712[] = { .sram_pdn_bits = GENMASK(11, 8), .sram_pdn_ack_bits = GENMASK(15, 12), .clk_id = {CLK_AUDIO}, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT2712_POWER_DOMAIN_USB] = { .name = "usb", @@ -606,7 +609,7 @@ static const struct scp_domain_data scp_domain_data_mt2712[] = { .sram_pdn_bits = GENMASK(10, 8), .sram_pdn_ack_bits = GENMASK(14, 12), .clk_id = {CLK_NONE}, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT2712_POWER_DOMAIN_USB2] = { .name = "usb2", @@ -615,7 +618,7 @@ static const struct scp_domain_data scp_domain_data_mt2712[] = { .sram_pdn_bits = GENMASK(10, 8), .sram_pdn_ack_bits = GENMASK(14, 12), .clk_id = {CLK_NONE}, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT2712_POWER_DOMAIN_MFG] = { .name = "mfg", @@ -625,7 +628,7 @@ static const struct scp_domain_data scp_domain_data_mt2712[] = { .sram_pdn_ack_bits = GENMASK(16, 16), .clk_id = {CLK_MFG}, .bus_prot_mask = BIT(14) | BIT(21) | BIT(23), - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT2712_POWER_DOMAIN_MFG_SC1] = { .name = "mfg_sc1", @@ -634,7 +637,7 @@ static const struct scp_domain_data scp_domain_data_mt2712[] = { .sram_pdn_bits = GENMASK(8, 8), .sram_pdn_ack_bits = GENMASK(16, 16), .clk_id = {CLK_NONE}, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT2712_POWER_DOMAIN_MFG_SC2] = { .name = "mfg_sc2", @@ -643,7 +646,7 @@ static const struct scp_domain_data scp_domain_data_mt2712[] = { .sram_pdn_bits = GENMASK(8, 8), .sram_pdn_ack_bits = GENMASK(16, 16), .clk_id = {CLK_NONE}, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT2712_POWER_DOMAIN_MFG_SC3] = { .name = "mfg_sc3", @@ -652,7 +655,7 @@ static const struct scp_domain_data scp_domain_data_mt2712[] = { .sram_pdn_bits = GENMASK(8, 8), .sram_pdn_ack_bits = GENMASK(16, 16), .clk_id = {CLK_NONE}, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, }; @@ -752,7 +755,7 @@ static const struct scp_domain_data scp_domain_data_mt7622[] = { .sram_pdn_ack_bits = GENMASK(15, 12), .clk_id = {CLK_NONE}, .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_ETHSYS, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT7622_POWER_DOMAIN_HIF0] = { .name = "hif0", @@ -762,7 +765,7 @@ static const struct scp_domain_data scp_domain_data_mt7622[] = { .sram_pdn_ack_bits = GENMASK(15, 12), .clk_id = {CLK_HIFSEL}, .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF0, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT7622_POWER_DOMAIN_HIF1] = { .name = "hif1", @@ -772,7 +775,7 @@ static const struct scp_domain_data scp_domain_data_mt7622[] = { .sram_pdn_ack_bits = GENMASK(15, 12), .clk_id = {CLK_HIFSEL}, .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF1, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT7622_POWER_DOMAIN_WB] = { .name = "wb", @@ -782,7 +785,7 @@ static const struct scp_domain_data scp_domain_data_mt7622[] = { .sram_pdn_ack_bits = 0, .clk_id = {CLK_NONE}, .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_WB, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, }; @@ -798,7 +801,7 @@ static const struct scp_domain_data scp_domain_data_mt7623a[] = { .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M | MT2701_TOP_AXI_PROT_EN_CONN_S, .clk_id = {CLK_NONE}, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT7623A_POWER_DOMAIN_ETH] = { .name = "eth", @@ -807,7 +810,7 @@ static const struct scp_domain_data scp_domain_data_mt7623a[] = { .sram_pdn_bits = GENMASK(11, 8), .sram_pdn_ack_bits = GENMASK(15, 12), .clk_id = {CLK_ETHIF}, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT7623A_POWER_DOMAIN_HIF] = { .name = "hif", @@ -816,14 +819,14 @@ static const struct scp_domain_data scp_domain_data_mt7623a[] = { .sram_pdn_bits = GENMASK(11, 8), .sram_pdn_ack_bits = GENMASK(15, 12), .clk_id = {CLK_ETHIF}, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT7623A_POWER_DOMAIN_IFR_MSC] = { .name = "ifr_msc", .sta_mask = PWR_STATUS_IFR_MSC, .ctl_offs = SPM_IFR_MSC_PWR_CON, .clk_id = {CLK_NONE}, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, }; @@ -889,7 +892,7 @@ static const struct scp_domain_data scp_domain_data_mt8173[] = { .sram_pdn_bits = GENMASK(11, 8), .sram_pdn_ack_bits = GENMASK(15, 12), .clk_id = {CLK_NONE}, - .active_wakeup = true, + .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT8173_POWER_DOMAIN_MFG_ASYNC] = { .name = "mfg_async", -- cgit v1.2.3 From 1ba96062b59222c01cb6b4283451389012337b6e Mon Sep 17 00:00:00 2001 From: Sean Wang Date: Wed, 2 May 2018 12:03:29 +0800 Subject: soc: mediatek: add a fixed wait for SRAM stable MT7622_POWER_DOMAIN_WB doesn't send an ACK when its managed SRAM becomes stable, which is not like the behavior the other power domains should have. Therefore, it's necessary for such a power domain to have a fixed and well-predefined duration to wait until its managed SRAM can be allowed to access by all functions running on the top. Signed-off-by: Sean Wang Cc: Matthias Brugger Cc: Ulf Hansson Cc: Weiyi Lu Signed-off-by: Matthias Brugger --- drivers/soc/mediatek/mtk-scpsys.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c index b1b45e44c7ad..2080c8f3ea1e 100644 --- a/drivers/soc/mediatek/mtk-scpsys.c +++ b/drivers/soc/mediatek/mtk-scpsys.c @@ -32,6 +32,7 @@ #define MTK_POLL_TIMEOUT (jiffies_to_usecs(HZ)) #define MTK_SCPD_ACTIVE_WAKEUP BIT(0) +#define MTK_SCPD_FWAIT_SRAM BIT(1) #define MTK_SCPD_CAPS(_scpd, _x) ((_scpd)->data->caps & (_x)) #define SPM_VDE_PWR_CON 0x0210 @@ -237,11 +238,21 @@ static int scpsys_power_on(struct generic_pm_domain *genpd) val &= ~scpd->data->sram_pdn_bits; writel(val, ctl_addr); - /* wait until SRAM_PDN_ACK all 0 */ - ret = readl_poll_timeout(ctl_addr, tmp, (tmp & pdn_ack) == 0, - MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); - if (ret < 0) - goto err_pwr_ack; + /* Either wait until SRAM_PDN_ACK all 0 or have a force wait */ + if (MTK_SCPD_CAPS(scpd, MTK_SCPD_FWAIT_SRAM)) { + /* + * Currently, MTK_SCPD_FWAIT_SRAM is necessary only for + * MT7622_POWER_DOMAIN_WB and thus just a trivial setup is + * applied here. + */ + usleep_range(12000, 12100); + + } else { + ret = readl_poll_timeout(ctl_addr, tmp, (tmp & pdn_ack) == 0, + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); + if (ret < 0) + goto err_pwr_ack; + }; if (scpd->data->bus_prot_mask) { ret = mtk_infracfg_clear_bus_protection(scp->infracfg, @@ -785,7 +796,7 @@ static const struct scp_domain_data scp_domain_data_mt7622[] = { .sram_pdn_ack_bits = 0, .clk_id = {CLK_NONE}, .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_WB, - .caps = MTK_SCPD_ACTIVE_WAKEUP, + .caps = MTK_SCPD_ACTIVE_WAKEUP | MTK_SCPD_FWAIT_SRAM, }, }; -- cgit v1.2.3 From 5b70cba4079fdf4e281d27c2db66c13d8969f687 Mon Sep 17 00:00:00 2001 From: Sean Wang Date: Thu, 10 May 2018 10:57:40 +0800 Subject: soc: mediatek: remove unneeded semicolon Fix up drivers/soc/mediatek/mtk-scpsys.c:255:2-3: Unneeded semicolon accidently being added in commit f9e2f65dd561 ("soc: mediatek: add a fixed wait for SRAM stable"). Fixes: f9e2f65dd561 ("soc: mediatek: add a fixed wait for SRAM stable") Reported-by: kbuild test robot Signed-off-by: Sean Wang Signed-off-by: Matthias Brugger --- drivers/soc/mediatek/mtk-scpsys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/soc') diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c index 2080c8f3ea1e..128e3dd3186d 100644 --- a/drivers/soc/mediatek/mtk-scpsys.c +++ b/drivers/soc/mediatek/mtk-scpsys.c @@ -252,7 +252,7 @@ static int scpsys_power_on(struct generic_pm_domain *genpd) MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); if (ret < 0) goto err_pwr_ack; - }; + } if (scpd->data->bus_prot_mask) { ret = mtk_infracfg_clear_bus_protection(scp->infracfg, -- cgit v1.2.3 From 6f686e85eda6b03796cda4ea04fb8a429d69eb54 Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Wed, 23 May 2018 14:48:39 +0800 Subject: soc: rockchip: power-domain: add power domain support for rk3036 This driver is modified to support RK3036 SoC. Signed-off-by: Caesar Wang Signed-off-by: Elaine Zhang Reviewed-by: Ulf Hansson Signed-off-by: Heiko Stuebner --- drivers/soc/rockchip/pm_domains.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'drivers/soc') diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c index df7f30a425c6..4a764241b4da 100644 --- a/drivers/soc/rockchip/pm_domains.c +++ b/drivers/soc/rockchip/pm_domains.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -103,6 +104,15 @@ struct rockchip_pmu { .active_wakeup = wakeup, \ } +#define DOMAIN_RK3036(req, ack, idle, wakeup) \ +{ \ + .req_mask = (req >= 0) ? BIT(req) : 0, \ + .req_w_mask = (req >= 0) ? BIT(req + 16) : 0, \ + .ack_mask = (ack >= 0) ? BIT(ack) : 0, \ + .idle_mask = (idle >= 0) ? BIT(idle) : 0, \ + .active_wakeup = wakeup, \ +} + #define DOMAIN_RK3288(pwr, status, req, wakeup) \ DOMAIN(pwr, status, req, req, (req) + 16, wakeup) @@ -701,6 +711,16 @@ err_out: return error; } +static const struct rockchip_domain_info rk3036_pm_domains[] = { + [RK3036_PD_MSCH] = DOMAIN_RK3036(14, 23, 30, true), + [RK3036_PD_CORE] = DOMAIN_RK3036(13, 17, 24, false), + [RK3036_PD_PERI] = DOMAIN_RK3036(12, 18, 25, false), + [RK3036_PD_VIO] = DOMAIN_RK3036(11, 19, 26, false), + [RK3036_PD_VPU] = DOMAIN_RK3036(10, 20, 27, false), + [RK3036_PD_GPU] = DOMAIN_RK3036(9, 21, 28, false), + [RK3036_PD_SYS] = DOMAIN_RK3036(8, 22, 29, false), +}; + static const struct rockchip_domain_info rk3288_pm_domains[] = { [RK3288_PD_VIO] = DOMAIN_RK3288(7, 7, 4, false), [RK3288_PD_HEVC] = DOMAIN_RK3288(14, 10, 9, false), @@ -768,6 +788,15 @@ static const struct rockchip_domain_info rk3399_pm_domains[] = { [RK3399_PD_SDIOAUDIO] = DOMAIN_RK3399(31, 31, 29, true), }; +static const struct rockchip_pmu_info rk3036_pmu = { + .req_offset = 0x148, + .idle_offset = 0x14c, + .ack_offset = 0x14c, + + .num_domains = ARRAY_SIZE(rk3036_pm_domains), + .domain_info = rk3036_pm_domains, +}; + static const struct rockchip_pmu_info rk3288_pmu = { .pwr_offset = 0x08, .status_offset = 0x0c, @@ -842,6 +871,10 @@ static const struct rockchip_pmu_info rk3399_pmu = { }; static const struct of_device_id rockchip_pm_domain_dt_match[] = { + { + .compatible = "rockchip,rk3036-power-controller", + .data = (void *)&rk3036_pmu, + }, { .compatible = "rockchip,rk3288-power-controller", .data = (void *)&rk3288_pmu, -- cgit v1.2.3 From 277535f7b63291bff94747b65990222d78c7f271 Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Wed, 23 May 2018 14:51:10 +0800 Subject: soc: rockchip: power-domain: add power domain support for rk3128 This driver is modified to support RK3128 SoC. Signed-off-by: Elaine Zhang Reviewed-by: Ulf Hansson Signed-off-by: Heiko Stuebner --- drivers/soc/rockchip/pm_domains.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'drivers/soc') diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c index 4a764241b4da..d03468805c94 100644 --- a/drivers/soc/rockchip/pm_domains.c +++ b/drivers/soc/rockchip/pm_domains.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -721,6 +722,14 @@ static const struct rockchip_domain_info rk3036_pm_domains[] = { [RK3036_PD_SYS] = DOMAIN_RK3036(8, 22, 29, false), }; +static const struct rockchip_domain_info rk3128_pm_domains[] = { + [RK3128_PD_CORE] = DOMAIN_RK3288(0, 0, 4, false), + [RK3128_PD_MSCH] = DOMAIN_RK3288(-1, -1, 6, true), + [RK3128_PD_VIO] = DOMAIN_RK3288(3, 3, 2, false), + [RK3128_PD_VIDEO] = DOMAIN_RK3288(2, 2, 1, false), + [RK3128_PD_GPU] = DOMAIN_RK3288(1, 1, 3, false), +}; + static const struct rockchip_domain_info rk3288_pm_domains[] = { [RK3288_PD_VIO] = DOMAIN_RK3288(7, 7, 4, false), [RK3288_PD_HEVC] = DOMAIN_RK3288(14, 10, 9, false), @@ -797,6 +806,17 @@ static const struct rockchip_pmu_info rk3036_pmu = { .domain_info = rk3036_pm_domains, }; +static const struct rockchip_pmu_info rk3128_pmu = { + .pwr_offset = 0x04, + .status_offset = 0x08, + .req_offset = 0x0c, + .idle_offset = 0x10, + .ack_offset = 0x10, + + .num_domains = ARRAY_SIZE(rk3128_pm_domains), + .domain_info = rk3128_pm_domains, +}; + static const struct rockchip_pmu_info rk3288_pmu = { .pwr_offset = 0x08, .status_offset = 0x0c, @@ -875,6 +895,10 @@ static const struct of_device_id rockchip_pm_domain_dt_match[] = { .compatible = "rockchip,rk3036-power-controller", .data = (void *)&rk3036_pmu, }, + { + .compatible = "rockchip,rk3128-power-controller", + .data = (void *)&rk3128_pmu, + }, { .compatible = "rockchip,rk3288-power-controller", .data = (void *)&rk3288_pmu, -- cgit v1.2.3 From 2dacbd104636f3a864c4866067e555efb8ac8334 Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Wed, 23 May 2018 14:52:03 +0800 Subject: soc: rockchip: power-domain: add power domain support for rk3228 This driver is modified to support RK3228 SoC. Signed-off-by: Elaine Zhang Reviewed-by: Ulf Hansson Signed-off-by: Heiko Stuebner --- drivers/soc/rockchip/pm_domains.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'drivers/soc') diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c index d03468805c94..36ded8396bb5 100644 --- a/drivers/soc/rockchip/pm_domains.c +++ b/drivers/soc/rockchip/pm_domains.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -730,6 +731,20 @@ static const struct rockchip_domain_info rk3128_pm_domains[] = { [RK3128_PD_GPU] = DOMAIN_RK3288(1, 1, 3, false), }; +static const struct rockchip_domain_info rk3228_pm_domains[] = { + [RK3228_PD_CORE] = DOMAIN_RK3036(0, 0, 16, true), + [RK3228_PD_MSCH] = DOMAIN_RK3036(1, 1, 17, true), + [RK3228_PD_BUS] = DOMAIN_RK3036(2, 2, 18, true), + [RK3228_PD_SYS] = DOMAIN_RK3036(3, 3, 19, true), + [RK3228_PD_VIO] = DOMAIN_RK3036(4, 4, 20, false), + [RK3228_PD_VOP] = DOMAIN_RK3036(5, 5, 21, false), + [RK3228_PD_VPU] = DOMAIN_RK3036(6, 6, 22, false), + [RK3228_PD_RKVDEC] = DOMAIN_RK3036(7, 7, 23, false), + [RK3228_PD_GPU] = DOMAIN_RK3036(8, 8, 24, false), + [RK3228_PD_PERI] = DOMAIN_RK3036(9, 9, 25, true), + [RK3228_PD_GMAC] = DOMAIN_RK3036(10, 10, 26, false), +}; + static const struct rockchip_domain_info rk3288_pm_domains[] = { [RK3288_PD_VIO] = DOMAIN_RK3288(7, 7, 4, false), [RK3288_PD_HEVC] = DOMAIN_RK3288(14, 10, 9, false), @@ -817,6 +832,15 @@ static const struct rockchip_pmu_info rk3128_pmu = { .domain_info = rk3128_pm_domains, }; +static const struct rockchip_pmu_info rk3228_pmu = { + .req_offset = 0x40c, + .idle_offset = 0x488, + .ack_offset = 0x488, + + .num_domains = ARRAY_SIZE(rk3228_pm_domains), + .domain_info = rk3228_pm_domains, +}; + static const struct rockchip_pmu_info rk3288_pmu = { .pwr_offset = 0x08, .status_offset = 0x0c, @@ -899,6 +923,10 @@ static const struct of_device_id rockchip_pm_domain_dt_match[] = { .compatible = "rockchip,rk3128-power-controller", .data = (void *)&rk3128_pmu, }, + { + .compatible = "rockchip,rk3228-power-controller", + .data = (void *)&rk3228_pmu, + }, { .compatible = "rockchip,rk3288-power-controller", .data = (void *)&rk3288_pmu, -- cgit v1.2.3 From 9bdf401bf49eddba98ae36f7243b888d43496bd6 Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Wed, 23 May 2018 14:53:32 +0800 Subject: soc: rockchip: power-domain: add power domain support for px30 This driver is modified to support PX30 SoC. Signed-off-by: Finley Xiao Signed-off-by: Elaine Zhang Reviewed-by: Ulf Hansson Signed-off-by: Heiko Stuebner --- drivers/soc/rockchip/pm_domains.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'drivers/soc') diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c index 36ded8396bb5..09a34e3a9375 100644 --- a/drivers/soc/rockchip/pm_domains.c +++ b/drivers/soc/rockchip/pm_domains.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -115,6 +116,9 @@ struct rockchip_pmu { .active_wakeup = wakeup, \ } +#define DOMAIN_PX30(pwr, status, req, wakeup) \ + DOMAIN_M(pwr, status, req, (req) + 16, req, wakeup) + #define DOMAIN_RK3288(pwr, status, req, wakeup) \ DOMAIN(pwr, status, req, req, (req) + 16, wakeup) @@ -713,6 +717,17 @@ err_out: return error; } +static const struct rockchip_domain_info px30_pm_domains[] = { + [PX30_PD_USB] = DOMAIN_PX30(5, 5, 10, false), + [PX30_PD_SDCARD] = DOMAIN_PX30(8, 8, 9, false), + [PX30_PD_GMAC] = DOMAIN_PX30(10, 10, 6, false), + [PX30_PD_MMC_NAND] = DOMAIN_PX30(11, 11, 5, false), + [PX30_PD_VPU] = DOMAIN_PX30(12, 12, 14, false), + [PX30_PD_VO] = DOMAIN_PX30(13, 13, 7, false), + [PX30_PD_VI] = DOMAIN_PX30(14, 14, 8, false), + [PX30_PD_GPU] = DOMAIN_PX30(15, 15, 2, false), +}; + static const struct rockchip_domain_info rk3036_pm_domains[] = { [RK3036_PD_MSCH] = DOMAIN_RK3036(14, 23, 30, true), [RK3036_PD_CORE] = DOMAIN_RK3036(13, 17, 24, false), @@ -812,6 +827,17 @@ static const struct rockchip_domain_info rk3399_pm_domains[] = { [RK3399_PD_SDIOAUDIO] = DOMAIN_RK3399(31, 31, 29, true), }; +static const struct rockchip_pmu_info px30_pmu = { + .pwr_offset = 0x18, + .status_offset = 0x20, + .req_offset = 0x64, + .idle_offset = 0x6c, + .ack_offset = 0x6c, + + .num_domains = ARRAY_SIZE(px30_pm_domains), + .domain_info = px30_pm_domains, +}; + static const struct rockchip_pmu_info rk3036_pmu = { .req_offset = 0x148, .idle_offset = 0x14c, @@ -915,6 +941,10 @@ static const struct rockchip_pmu_info rk3399_pmu = { }; static const struct of_device_id rockchip_pm_domain_dt_match[] = { + { + .compatible = "rockchip,px30-power-controller", + .data = (void *)&px30_pmu, + }, { .compatible = "rockchip,rk3036-power-controller", .data = (void *)&rk3036_pmu, -- cgit v1.2.3