From 960ddf70cc11024e6e9dac206316d0160e00a77d Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Fri, 11 Dec 2020 13:58:46 +0000 Subject: drivers: soc: atmel: Avoid calling at91_soc_init on non AT91 SoCs Since at91_soc_init is called unconditionally from atmel_soc_device_init, we get the following warning on all non AT91 SoCs: " AT91: Could not find identification node" Fix the same by filtering with allowed AT91 SoC list. Cc: Nicolas Ferre Cc: Alexandre Belloni Cc: Ludovic Desroches Signed-off-by: Sudeep Holla Signed-off-by: Alexandre Belloni Link: https://lore.kernel.org/r/20201211135846.1334322-1-sudeep.holla@arm.com --- drivers/soc/atmel/soc.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers/soc') diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c index c4472b68b7c2..728d461ad6d6 100644 --- a/drivers/soc/atmel/soc.c +++ b/drivers/soc/atmel/soc.c @@ -271,8 +271,20 @@ struct soc_device * __init at91_soc_init(const struct at91_soc *socs) return soc_dev; } +static const struct of_device_id at91_soc_allowed_list[] __initconst = { + { .compatible = "atmel,at91rm9200", }, + { .compatible = "atmel,at91sam9", }, + { .compatible = "atmel,sama5", }, + { .compatible = "atmel,samv7", } +}; + static int __init atmel_soc_device_init(void) { + struct device_node *np = of_find_node_by_path("/"); + + if (!of_match_node(at91_soc_allowed_list, np)) + return 0; + at91_soc_init(socs); return 0; -- cgit v1.2.3 From 916c0c05521a52f13283ad3600793fc79516ff31 Mon Sep 17 00:00:00 2001 From: Sai Prakash Ranjan Date: Mon, 30 Nov 2020 15:09:23 +0530 Subject: soc: qcom: llcc-qcom: Extract major hardware version The major hardware version of the LLCC IP is encoded in its LLCC_COMMON_HW_INFO register. Extract the version and cache it in the driver data so that it can be used to implement version specific functionality like enabling Write sub cache for given SCID. Signed-off-by: Sai Prakash Ranjan [mani: splitted the version extract as a single patch and few cleanups] Signed-off-by: Manivannan Sadhasivam Link: https://lore.kernel.org/r/20201130093924.45057-4-manivannan.sadhasivam@linaro.org Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/llcc-qcom.c | 12 ++++++++++++ include/linux/soc/qcom/llcc-qcom.h | 2 ++ 2 files changed, 14 insertions(+) (limited to 'drivers/soc') diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c index 16b421608e9c..a559617ea7c0 100644 --- a/drivers/soc/qcom/llcc-qcom.c +++ b/drivers/soc/qcom/llcc-qcom.c @@ -4,6 +4,7 @@ * */ +#include #include #include #include @@ -35,6 +36,9 @@ #define CACHE_LINE_SIZE_SHIFT 6 +#define LLCC_COMMON_HW_INFO 0x00030000 +#define LLCC_MAJOR_VERSION_MASK GENMASK(31, 24) + #define LLCC_COMMON_STATUS0 0x0003000c #define LLCC_LB_CNT_MASK GENMASK(31, 28) #define LLCC_LB_CNT_SHIFT 28 @@ -476,6 +480,7 @@ static int qcom_llcc_probe(struct platform_device *pdev) const struct qcom_llcc_config *cfg; const struct llcc_slice_config *llcc_cfg; u32 sz; + u32 version; drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL); if (!drv_data) { @@ -496,6 +501,13 @@ static int qcom_llcc_probe(struct platform_device *pdev) goto err; } + /* Extract major version of the IP */ + ret = regmap_read(drv_data->bcast_regmap, LLCC_COMMON_HW_INFO, &version); + if (ret) + goto err; + + drv_data->major_version = FIELD_GET(LLCC_MAJOR_VERSION_MASK, version); + ret = regmap_read(drv_data->regmap, LLCC_COMMON_STATUS0, &num_banks); if (ret) diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h index 3db6797ba6ff..d17a3de80510 100644 --- a/include/linux/soc/qcom/llcc-qcom.h +++ b/include/linux/soc/qcom/llcc-qcom.h @@ -79,6 +79,7 @@ struct llcc_edac_reg_data { * @bitmap: Bit map to track the active slice ids * @offsets: Pointer to the bank offsets array * @ecc_irq: interrupt for llcc cache error detection and reporting + * @major_version: Indicates the LLCC major version */ struct llcc_drv_data { struct regmap *regmap; @@ -91,6 +92,7 @@ struct llcc_drv_data { unsigned long *bitmap; u32 *offsets; int ecc_irq; + u32 major_version; }; #if IS_ENABLED(CONFIG_QCOM_LLCC) -- cgit v1.2.3 From c4df37fe186de4df8895a7a4793f5221eda6e5ae Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Mon, 30 Nov 2020 15:09:24 +0530 Subject: soc: qcom: llcc-qcom: Add support for SM8250 SoC SM8250 SoC uses LLCC IP version 2. In this version, the WRSC_EN register needs to be written to enable the Write Sub Cache for each SCID. Hence, use a dedicated "write_scid_en" member with predefined values and write them for LLCC IP version 2. Reviewed-by: Sai Prakash Ranjan Signed-off-by: Manivannan Sadhasivam Link: https://lore.kernel.org/r/20201130093924.45057-5-manivannan.sadhasivam@linaro.org Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/llcc-qcom.c | 38 ++++++++++++++++++++++++++++++++++++++ include/linux/soc/qcom/llcc-qcom.h | 1 + 2 files changed, 39 insertions(+) (limited to 'drivers/soc') diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c index a559617ea7c0..8403a77b59fe 100644 --- a/drivers/soc/qcom/llcc-qcom.c +++ b/drivers/soc/qcom/llcc-qcom.c @@ -51,6 +51,7 @@ #define LLCC_TRP_SCID_DIS_CAP_ALLOC 0x21f00 #define LLCC_TRP_PCB_ACT 0x21f04 +#define LLCC_TRP_WRSC_EN 0x21f20 #define BANK_OFFSET_STRIDE 0x80000 @@ -77,6 +78,7 @@ * then the ways assigned to this client are not flushed on power * collapse. * @activate_on_init: Activate the slice immediately after it is programmed + * @write_scid_en: Bit enables write cache support for a given scid. */ struct llcc_slice_config { u32 usecase_id; @@ -91,6 +93,7 @@ struct llcc_slice_config { bool dis_cap_alloc; bool retain_on_pc; bool activate_on_init; + bool write_scid_en; }; struct qcom_llcc_config { @@ -151,6 +154,25 @@ static const struct llcc_slice_config sm8150_data[] = { { LLCC_WRCACHE, 31, 128, 1, 1, 0xFFF, 0x0, 0, 0, 0, 0, 0 }, }; +static const struct llcc_slice_config sm8250_data[] = { + { LLCC_CPUSS, 1, 3072, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 1, 0 }, + { LLCC_VIDSC0, 2, 512, 3, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, + { LLCC_AUDIO, 6, 1024, 1, 0, 0xfff, 0x0, 0, 0, 0, 0, 0, 0 }, + { LLCC_CMPT, 10, 1024, 1, 0, 0xfff, 0x0, 0, 0, 0, 0, 0, 0 }, + { LLCC_GPUHTW, 11, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, + { LLCC_GPU, 12, 1024, 1, 0, 0xfff, 0x0, 0, 0, 0, 1, 0, 1 }, + { LLCC_MMUHWT, 13, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 }, + { LLCC_CMPTDMA, 15, 1024, 1, 0, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, + { LLCC_DISP, 16, 3072, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, + { LLCC_VIDFW, 17, 512, 1, 0, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, + { LLCC_AUDHW, 22, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, + { LLCC_NPU, 23, 3072, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, + { LLCC_WLHW, 24, 1024, 1, 0, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, + { LLCC_CVP, 28, 256, 3, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 }, + { LLCC_APTCM, 30, 128, 3, 0, 0x0, 0x3, 1, 0, 0, 1, 0, 0 }, + { LLCC_WRCACHE, 31, 256, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 }, +}; + static const struct qcom_llcc_config sc7180_cfg = { .sct_data = sc7180_data, .size = ARRAY_SIZE(sc7180_data), @@ -168,6 +190,11 @@ static const struct qcom_llcc_config sm8150_cfg = { .size = ARRAY_SIZE(sm8150_data), }; +static const struct qcom_llcc_config sm8250_cfg = { + .sct_data = sm8250_data, + .size = ARRAY_SIZE(sm8250_data), +}; + static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER; /** @@ -417,6 +444,16 @@ static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config, return ret; } + if (drv_data->major_version == 2) { + u32 wren; + + wren = config->write_scid_en << config->slice_id; + ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_WRSC_EN, + BIT(config->slice_id), wren); + if (ret) + return ret; + } + if (config->activate_on_init) { desc.slice_id = config->slice_id; ret = llcc_slice_activate(&desc); @@ -571,6 +608,7 @@ static const struct of_device_id qcom_llcc_of_match[] = { { .compatible = "qcom,sc7180-llcc", .data = &sc7180_cfg }, { .compatible = "qcom,sdm845-llcc", .data = &sdm845_cfg }, { .compatible = "qcom,sm8150-llcc", .data = &sm8150_cfg }, + { .compatible = "qcom,sm8250-llcc", .data = &sm8250_cfg }, { } }; diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h index d17a3de80510..64fc582ae415 100644 --- a/include/linux/soc/qcom/llcc-qcom.h +++ b/include/linux/soc/qcom/llcc-qcom.h @@ -29,6 +29,7 @@ #define LLCC_AUDHW 22 #define LLCC_NPU 23 #define LLCC_WLHW 24 +#define LLCC_CVP 28 #define LLCC_MODPE 29 #define LLCC_APTCM 30 #define LLCC_WRCACHE 31 -- cgit v1.2.3 From e1d8008179fef782ecea4e7af1b9cd9891bd881e Mon Sep 17 00:00:00 2001 From: Lina Iyer Date: Tue, 24 Nov 2020 15:23:30 +0530 Subject: drivers: qcom: rpmh-rsc: Do not read back the register write on trigger When triggering a TCS to send its contents, reading back the trigger value may return an incorrect value. That is because, writing the trigger may raise an interrupt which could be handled immediately and the trigger value could be reset in the interrupt handler. A write_tcs_reg_sync() would read back the value that is written and try to match it to the value written to ensure that the value is written, but if that value is different, we may see false error for same. Reviewed-by: Douglas Anderson Signed-off-by: Lina Iyer Signed-off-by: Maulik Shah Link: https://lore.kernel.org/r/1606211610-15168-1-git-send-email-mkshah@codeaurora.org Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/rpmh-rsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/soc') diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index 37969dcbaf14..0b082ec894a1 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -364,7 +364,7 @@ static void __tcs_set_trigger(struct rsc_drv *drv, int tcs_id, bool trigger) enable = TCS_AMC_MODE_ENABLE; write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable); enable |= TCS_AMC_MODE_TRIGGER; - write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable); + write_tcs_reg(drv, RSC_DRV_CONTROL, tcs_id, enable); } } -- cgit v1.2.3 From 1b3df368914b5e1783a9192b32418b24b7a721e5 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 30 Jul 2020 18:32:20 +0300 Subject: soc: qcom: smem: use %*ph to print small buffer Use %*ph format to print small buffer as hex string. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20200730153220.39466-1-andriy.shevchenko@linux.intel.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/smem.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index 7251827bac88..cc4e0655a47b 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -732,9 +732,7 @@ qcom_smem_partition_header(struct qcom_smem *smem, header = smem->regions[0].virt_base + le32_to_cpu(entry->offset); if (memcmp(header->magic, SMEM_PART_MAGIC, sizeof(header->magic))) { - dev_err(smem->dev, "bad partition magic %02x %02x %02x %02x\n", - header->magic[0], header->magic[1], - header->magic[2], header->magic[3]); + dev_err(smem->dev, "bad partition magic %4ph\n", header->magic); return NULL; } -- cgit v1.2.3 From fef419c463d0dd95488a9750dc501ae43825e5d2 Mon Sep 17 00:00:00 2001 From: Lina Iyer Date: Thu, 7 Jan 2021 14:09:30 +0530 Subject: soc: qcom: rpmh: Remove serialization of TCS commands Requests sent to RPMH can be sent as fire-n-forget or response required, with the latter ensuring the command has been completed by the hardware accelerator. Commands in a request with tcs_cmd::wait set, would ensure that those select commands are sent as response required, even though the actual TCS request may be fire-n-forget. Also, commands with .wait flag were also guaranteed to be complete before the following command in the TCS is sent. This means that the next command of the same request blocked until the current request is completed. This could mean waiting for a voltage to settle or series of NOCs be configured before the next command is sent. But drivers using this feature have never cared about the serialization aspect. By not enforcing the serialization we can allow the hardware to run in parallel improving the performance. Let's clarify the usage of this member in the tcs_cmd structure to mean only completion and not serialization. This should also improve the performance of bus requests where changes could happen in parallel. Also, CPU resume from deep idle may see benefits from certain wake requests. Reviewed-by: Douglas Anderson Signed-off-by: Lina Iyer Signed-off-by: Maulik Shah Link: https://lore.kernel.org/r/1610008770-13891-1-git-send-email-mkshah@codeaurora.org Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/rpmh-rsc.c | 22 +++++++++------------- include/soc/qcom/tcs.h | 9 ++++++++- 2 files changed, 17 insertions(+), 14 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index 0b082ec894a1..a84ab0d6a9d4 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -231,10 +231,9 @@ static void tcs_invalidate(struct rsc_drv *drv, int type) if (bitmap_empty(tcs->slots, MAX_TCS_SLOTS)) return; - for (m = tcs->offset; m < tcs->offset + tcs->num_tcs; m++) { + for (m = tcs->offset; m < tcs->offset + tcs->num_tcs; m++) write_tcs_reg_sync(drv, RSC_DRV_CMD_ENABLE, m, 0); - write_tcs_reg_sync(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, m, 0); - } + bitmap_zero(tcs->slots, MAX_TCS_SLOTS); } @@ -443,7 +442,6 @@ static irqreturn_t tcs_tx_done(int irq, void *p) skip: /* Reclaim the TCS */ write_tcs_reg(drv, RSC_DRV_CMD_ENABLE, i, 0); - write_tcs_reg(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, i, 0); writel_relaxed(BIT(i), drv->tcs_base + RSC_DRV_IRQ_CLEAR); spin_lock(&drv->lock); clear_bit(i, drv->tcs_in_use); @@ -476,23 +474,23 @@ skip: static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id, const struct tcs_request *msg) { - u32 msgid, cmd_msgid; + u32 msgid; + u32 cmd_msgid = CMD_MSGID_LEN | CMD_MSGID_WRITE; u32 cmd_enable = 0; - u32 cmd_complete; struct tcs_cmd *cmd; int i, j; - cmd_msgid = CMD_MSGID_LEN; + /* Convert all commands to RR when the request has wait_for_compl set */ cmd_msgid |= msg->wait_for_compl ? CMD_MSGID_RESP_REQ : 0; - cmd_msgid |= CMD_MSGID_WRITE; - - cmd_complete = read_tcs_reg(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, tcs_id); for (i = 0, j = cmd_id; i < msg->num_cmds; i++, j++) { cmd = &msg->cmds[i]; cmd_enable |= BIT(j); - cmd_complete |= cmd->wait << j; msgid = cmd_msgid; + /* + * Additionally, if the cmd->wait is set, make the command + * response reqd even if the overall request was fire-n-forget. + */ msgid |= cmd->wait ? CMD_MSGID_RESP_REQ : 0; write_tcs_cmd(drv, RSC_DRV_CMD_MSGID, tcs_id, j, msgid); @@ -501,7 +499,6 @@ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id, trace_rpmh_send_msg(drv, tcs_id, j, msgid, cmd); } - write_tcs_reg(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, tcs_id, cmd_complete); cmd_enable |= read_tcs_reg(drv, RSC_DRV_CMD_ENABLE, tcs_id); write_tcs_reg(drv, RSC_DRV_CMD_ENABLE, tcs_id, cmd_enable); } @@ -652,7 +649,6 @@ int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg) * cleaned from rpmh_flush() by invoking rpmh_rsc_invalidate() */ write_tcs_reg_sync(drv, RSC_DRV_CMD_ENABLE, tcs_id, 0); - write_tcs_reg_sync(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, tcs_id, 0); enable_tcs_irq(drv, tcs_id, true); } spin_unlock_irqrestore(&drv->lock, flags); diff --git a/include/soc/qcom/tcs.h b/include/soc/qcom/tcs.h index 7a2a055ba6b0..3acca067c72b 100644 --- a/include/soc/qcom/tcs.h +++ b/include/soc/qcom/tcs.h @@ -30,7 +30,13 @@ enum rpmh_state { * * @addr: the address of the resource slv_id:18:16 | offset:0:15 * @data: the resource state request - * @wait: wait for this request to be complete before sending the next + * @wait: ensure that this command is complete before returning. + * Setting "wait" here only makes sense during rpmh_write_batch() for + * active-only transfers, this is because: + * rpmh_write() - Always waits. + * (DEFINE_RPMH_MSG_ONSTACK will set .wait_for_compl) + * rpmh_write_async() - Never waits. + * (There's no request completion callback) */ struct tcs_cmd { u32 addr; @@ -43,6 +49,7 @@ struct tcs_cmd { * * @state: state for the request. * @wait_for_compl: wait until we get a response from the h/w accelerator + * (same as setting cmd->wait for all commands in the request) * @num_cmds: the number of @cmds in this request * @cmds: an array of tcs_cmds */ -- cgit v1.2.3 From 7d981405d0fd3cfc0de052e4791f516235d8b858 Mon Sep 17 00:00:00 2001 From: Alice Guo Date: Mon, 4 Jan 2021 17:15:44 +0800 Subject: soc: imx8m: change to use platform driver Directly reading ocotp register depends on that bootloader enables ocotp clk, which is not always effective, so change to use nvmem API. Using nvmem API requires to support driver defer probe and thus change soc-imx8m.c to use platform driver. The other reason is that directly reading ocotp register causes kexec kernel hang because the 1st kernel running will disable unused clks after kernel boots up, and then ocotp clk will be disabled even if bootloader enables it. When kexec kernel, ocotp clk needs to be enabled before reading ocotp registers, and nvmem API with platform driver supported can accomplish this. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Alice Guo Signed-off-by: Shawn Guo --- drivers/soc/imx/soc-imx8m.c | 84 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 72 insertions(+), 12 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/imx/soc-imx8m.c b/drivers/soc/imx/soc-imx8m.c index cc57a384d74d..071e14496e4b 100644 --- a/drivers/soc/imx/soc-imx8m.c +++ b/drivers/soc/imx/soc-imx8m.c @@ -5,6 +5,8 @@ #include #include +#include +#include #include #include #include @@ -29,7 +31,7 @@ struct imx8_soc_data { char *name; - u32 (*soc_revision)(void); + u32 (*soc_revision)(struct device *dev); }; static u64 soc_uid; @@ -50,7 +52,7 @@ static u32 imx8mq_soc_revision_from_atf(void) static inline u32 imx8mq_soc_revision_from_atf(void) { return 0; }; #endif -static u32 __init imx8mq_soc_revision(void) +static u32 __init imx8mq_soc_revision(struct device *dev) { struct device_node *np; void __iomem *ocotp_base; @@ -75,9 +77,20 @@ static u32 __init imx8mq_soc_revision(void) rev = REV_B1; } - soc_uid = readl_relaxed(ocotp_base + OCOTP_UID_HIGH); - soc_uid <<= 32; - soc_uid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW); + if (dev) { + int ret; + + ret = nvmem_cell_read_u64(dev, "soc_unique_id", &soc_uid); + if (ret) { + iounmap(ocotp_base); + of_node_put(np); + return ret; + } + } else { + soc_uid = readl_relaxed(ocotp_base + OCOTP_UID_HIGH); + soc_uid <<= 32; + soc_uid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW); + } iounmap(ocotp_base); of_node_put(np); @@ -107,7 +120,7 @@ static void __init imx8mm_soc_uid(void) of_node_put(np); } -static u32 __init imx8mm_soc_revision(void) +static u32 __init imx8mm_soc_revision(struct device *dev) { struct device_node *np; void __iomem *anatop_base; @@ -125,7 +138,15 @@ static u32 __init imx8mm_soc_revision(void) iounmap(anatop_base); of_node_put(np); - imx8mm_soc_uid(); + if (dev) { + int ret; + + ret = nvmem_cell_read_u64(dev, "soc_unique_id", &soc_uid); + if (ret) + return ret; + } else { + imx8mm_soc_uid(); + } return rev; } @@ -150,7 +171,7 @@ static const struct imx8_soc_data imx8mp_soc_data = { .soc_revision = imx8mm_soc_revision, }; -static __maybe_unused const struct of_device_id imx8_soc_match[] = { +static __maybe_unused const struct of_device_id imx8_machine_match[] = { { .compatible = "fsl,imx8mq", .data = &imx8mq_soc_data, }, { .compatible = "fsl,imx8mm", .data = &imx8mm_soc_data, }, { .compatible = "fsl,imx8mn", .data = &imx8mn_soc_data, }, @@ -158,12 +179,20 @@ static __maybe_unused const struct of_device_id imx8_soc_match[] = { { } }; +static __maybe_unused const struct of_device_id imx8_soc_match[] = { + { .compatible = "fsl,imx8mq-soc", .data = &imx8mq_soc_data, }, + { .compatible = "fsl,imx8mm-soc", .data = &imx8mm_soc_data, }, + { .compatible = "fsl,imx8mn-soc", .data = &imx8mn_soc_data, }, + { .compatible = "fsl,imx8mp-soc", .data = &imx8mp_soc_data, }, + { } +}; + #define imx8_revision(soc_rev) \ soc_rev ? \ kasprintf(GFP_KERNEL, "%d.%d", (soc_rev >> 4) & 0xf, soc_rev & 0xf) : \ "unknown" -static int __init imx8_soc_init(void) +static int imx8_soc_info(struct platform_device *pdev) { struct soc_device_attribute *soc_dev_attr; struct soc_device *soc_dev; @@ -182,7 +211,10 @@ static int __init imx8_soc_init(void) if (ret) goto free_soc; - id = of_match_node(imx8_soc_match, of_root); + if (pdev) + id = of_match_node(imx8_soc_match, pdev->dev.of_node); + else + id = of_match_node(imx8_machine_match, of_root); if (!id) { ret = -ENODEV; goto free_soc; @@ -191,8 +223,16 @@ static int __init imx8_soc_init(void) data = id->data; if (data) { soc_dev_attr->soc_id = data->name; - if (data->soc_revision) - soc_rev = data->soc_revision(); + if (data->soc_revision) { + if (pdev) { + soc_rev = data->soc_revision(&pdev->dev); + ret = soc_rev; + if (ret < 0) + goto free_soc; + } else { + soc_rev = data->soc_revision(NULL); + } + } } soc_dev_attr->revision = imx8_revision(soc_rev); @@ -230,4 +270,24 @@ free_soc: kfree(soc_dev_attr); return ret; } + +/* Retain device_initcall is for backward compatibility with DTS. */ +static int __init imx8_soc_init(void) +{ + if (of_find_matching_node_and_match(NULL, imx8_soc_match, NULL)) + return 0; + + return imx8_soc_info(NULL); +} device_initcall(imx8_soc_init); + +static struct platform_driver imx8_soc_info_driver = { + .probe = imx8_soc_info, + .driver = { + .name = "imx8_soc_info", + .of_match_table = imx8_soc_match, + }, +}; + +module_platform_driver(imx8_soc_info_driver); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 8bcac4011ebe0dbdd46fd55b036ee855c95702d3 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 14 Dec 2020 19:07:43 +0100 Subject: soc: bcm: add PM driver for Broadcom's PMB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PMB originally comes from BCM63138 but can be also found on many other chipsets (e.g. BCM4908). It's needed to power on and off SoC blocks like PCIe, SATA, USB. Signed-off-by: Rafał Miłecki Acked-by: Ulf Hansson Signed-off-by: Florian Fainelli --- MAINTAINERS | 10 ++ drivers/soc/bcm/Makefile | 2 +- drivers/soc/bcm/bcm63xx/Kconfig | 9 ++ drivers/soc/bcm/bcm63xx/Makefile | 1 + drivers/soc/bcm/bcm63xx/bcm-pmb.c | 333 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 354 insertions(+), 1 deletion(-) create mode 100644 drivers/soc/bcm/bcm63xx/bcm-pmb.c (limited to 'drivers/soc') diff --git a/MAINTAINERS b/MAINTAINERS index 546aa66428c9..3bbb974bd11e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3683,6 +3683,16 @@ L: linux-mips@vger.kernel.org S: Maintained F: drivers/firmware/broadcom/* +BROADCOM PMB (POWER MANAGEMENT BUS) DRIVER +M: Rafał Miłecki +M: Florian Fainelli +M: bcm-kernel-feedback-list@broadcom.com +L: linux-pm@vger.kernel.org +S: Maintained +T: git git://github.com/broadcom/stblinux.git +F: drivers/soc/bcm/bcm-pmb.c +F: include/dt-bindings/soc/bcm-pmb.h + BROADCOM SPECIFIC AMBA DRIVER (BCMA) M: Rafał Miłecki L: linux-wireless@vger.kernel.org diff --git a/drivers/soc/bcm/Makefile b/drivers/soc/bcm/Makefile index 7bc90e0bd773..0f0efa28d92b 100644 --- a/drivers/soc/bcm/Makefile +++ b/drivers/soc/bcm/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_BCM2835_POWER) += bcm2835-power.o obj-$(CONFIG_RASPBERRYPI_POWER) += raspberrypi-power.o -obj-$(CONFIG_SOC_BCM63XX) += bcm63xx/ +obj-y += bcm63xx/ obj-$(CONFIG_SOC_BRCMSTB) += brcmstb/ diff --git a/drivers/soc/bcm/bcm63xx/Kconfig b/drivers/soc/bcm/bcm63xx/Kconfig index 16f648a6c70a..9e501c8ac5ce 100644 --- a/drivers/soc/bcm/bcm63xx/Kconfig +++ b/drivers/soc/bcm/bcm63xx/Kconfig @@ -10,3 +10,12 @@ config BCM63XX_POWER BCM6318, BCM6328, BCM6362 and BCM63268 SoCs. endif # SOC_BCM63XX + +config BCM_PMB + bool "Broadcom PMB (Power Management Bus) driver" + depends on ARCH_BCM4908 || (COMPILE_TEST && OF) + default ARCH_BCM4908 + select PM_GENERIC_DOMAINS if PM + help + This enables support for the Broadcom's PMB (Power Management Bus) that + is used for disabling and enabling SoC devices. diff --git a/drivers/soc/bcm/bcm63xx/Makefile b/drivers/soc/bcm/bcm63xx/Makefile index 0710d5e018cc..557eed3d67bd 100644 --- a/drivers/soc/bcm/bcm63xx/Makefile +++ b/drivers/soc/bcm/bcm63xx/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_BCM63XX_POWER) += bcm63xx-power.o +obj-$(CONFIG_BCM_PMB) += bcm-pmb.o diff --git a/drivers/soc/bcm/bcm63xx/bcm-pmb.c b/drivers/soc/bcm/bcm63xx/bcm-pmb.c new file mode 100644 index 000000000000..c223023dc64f --- /dev/null +++ b/drivers/soc/bcm/bcm63xx/bcm-pmb.c @@ -0,0 +1,333 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2013 Broadcom + * Copyright (C) 2020 Rafał Miłecki + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define BPCM_ID_REG 0x00 +#define BPCM_CAPABILITIES 0x04 +#define BPCM_CAP_NUM_ZONES 0x000000ff +#define BPCM_CAP_SR_REG_BITS 0x0000ff00 +#define BPCM_CAP_PLLTYPE 0x00030000 +#define BPCM_CAP_UBUS 0x00080000 +#define BPCM_CONTROL 0x08 +#define BPCM_STATUS 0x0c +#define BPCM_ROSC_CONTROL 0x10 +#define BPCM_ROSC_THRESH_H 0x14 +#define BPCM_ROSC_THRESHOLD_BCM6838 0x14 +#define BPCM_ROSC_THRESH_S 0x18 +#define BPCM_ROSC_COUNT_BCM6838 0x18 +#define BPCM_ROSC_COUNT 0x1c +#define BPCM_PWD_CONTROL_BCM6838 0x1c +#define BPCM_PWD_CONTROL 0x20 +#define BPCM_SR_CONTROL_BCM6838 0x20 +#define BPCM_PWD_ACCUM_CONTROL 0x24 +#define BPCM_SR_CONTROL 0x28 +#define BPCM_GLOBAL_CONTROL 0x2c +#define BPCM_MISC_CONTROL 0x30 +#define BPCM_MISC_CONTROL2 0x34 +#define BPCM_SGPHY_CNTL 0x38 +#define BPCM_SGPHY_STATUS 0x3c +#define BPCM_ZONE0 0x40 +#define BPCM_ZONE_CONTROL 0x00 +#define BPCM_ZONE_CONTROL_MANUAL_CLK_EN 0x00000001 +#define BPCM_ZONE_CONTROL_MANUAL_RESET_CTL 0x00000002 +#define BPCM_ZONE_CONTROL_FREQ_SCALE_USED 0x00000004 /* R/O */ +#define BPCM_ZONE_CONTROL_DPG_CAPABLE 0x00000008 /* R/O */ +#define BPCM_ZONE_CONTROL_MANUAL_MEM_PWR 0x00000030 +#define BPCM_ZONE_CONTROL_MANUAL_ISO_CTL 0x00000040 +#define BPCM_ZONE_CONTROL_MANUAL_CTL 0x00000080 +#define BPCM_ZONE_CONTROL_DPG_CTL_EN 0x00000100 +#define BPCM_ZONE_CONTROL_PWR_DN_REQ 0x00000200 +#define BPCM_ZONE_CONTROL_PWR_UP_REQ 0x00000400 +#define BPCM_ZONE_CONTROL_MEM_PWR_CTL_EN 0x00000800 +#define BPCM_ZONE_CONTROL_BLK_RESET_ASSERT 0x00001000 +#define BPCM_ZONE_CONTROL_MEM_STBY 0x00002000 +#define BPCM_ZONE_CONTROL_RESERVED 0x0007c000 +#define BPCM_ZONE_CONTROL_PWR_CNTL_STATE 0x00f80000 +#define BPCM_ZONE_CONTROL_FREQ_SCALAR_DYN_SEL 0x01000000 /* R/O */ +#define BPCM_ZONE_CONTROL_PWR_OFF_STATE 0x02000000 /* R/O */ +#define BPCM_ZONE_CONTROL_PWR_ON_STATE 0x04000000 /* R/O */ +#define BPCM_ZONE_CONTROL_PWR_GOOD 0x08000000 /* R/O */ +#define BPCM_ZONE_CONTROL_DPG_PWR_STATE 0x10000000 /* R/O */ +#define BPCM_ZONE_CONTROL_MEM_PWR_STATE 0x20000000 /* R/O */ +#define BPCM_ZONE_CONTROL_ISO_STATE 0x40000000 /* R/O */ +#define BPCM_ZONE_CONTROL_RESET_STATE 0x80000000 /* R/O */ +#define BPCM_ZONE_CONFIG1 0x04 +#define BPCM_ZONE_CONFIG2 0x08 +#define BPCM_ZONE_FREQ_SCALAR_CONTROL 0x0c +#define BPCM_ZONE_SIZE 0x10 + +struct bcm_pmb { + struct device *dev; + void __iomem *base; + spinlock_t lock; + bool little_endian; + struct genpd_onecell_data genpd_onecell_data; +}; + +struct bcm_pmb_pd_data { + const char * const name; + int id; + u8 bus; + u8 device; +}; + +struct bcm_pmb_pm_domain { + struct bcm_pmb *pmb; + const struct bcm_pmb_pd_data *data; + struct generic_pm_domain genpd; +}; + +static int bcm_pmb_bpcm_read(struct bcm_pmb *pmb, int bus, u8 device, + int offset, u32 *val) +{ + void __iomem *base = pmb->base + bus * 0x20; + unsigned long flags; + int err; + + spin_lock_irqsave(&pmb->lock, flags); + err = bpcm_rd(base, device, offset, val); + spin_unlock_irqrestore(&pmb->lock, flags); + + if (!err) + *val = pmb->little_endian ? le32_to_cpu(*val) : be32_to_cpu(*val); + + return err; +} + +static int bcm_pmb_bpcm_write(struct bcm_pmb *pmb, int bus, u8 device, + int offset, u32 val) +{ + void __iomem *base = pmb->base + bus * 0x20; + unsigned long flags; + int err; + + val = pmb->little_endian ? cpu_to_le32(val) : cpu_to_be32(val); + + spin_lock_irqsave(&pmb->lock, flags); + err = bpcm_wr(base, device, offset, val); + spin_unlock_irqrestore(&pmb->lock, flags); + + return err; +} + +static int bcm_pmb_power_off_zone(struct bcm_pmb *pmb, int bus, u8 device, + int zone) +{ + int offset; + u32 val; + int err; + + offset = BPCM_ZONE0 + zone * BPCM_ZONE_SIZE + BPCM_ZONE_CONTROL; + + err = bcm_pmb_bpcm_read(pmb, bus, device, offset, &val); + if (err) + return err; + + val |= BPCM_ZONE_CONTROL_PWR_DN_REQ; + val &= ~BPCM_ZONE_CONTROL_PWR_UP_REQ; + + err = bcm_pmb_bpcm_write(pmb, bus, device, offset, val); + + return err; +} + +static int bcm_pmb_power_on_zone(struct bcm_pmb *pmb, int bus, u8 device, + int zone) +{ + int offset; + u32 val; + int err; + + offset = BPCM_ZONE0 + zone * BPCM_ZONE_SIZE + BPCM_ZONE_CONTROL; + + err = bcm_pmb_bpcm_read(pmb, bus, device, offset, &val); + if (err) + return err; + + if (!(val & BPCM_ZONE_CONTROL_PWR_ON_STATE)) { + val &= ~BPCM_ZONE_CONTROL_PWR_DN_REQ; + val |= BPCM_ZONE_CONTROL_DPG_CTL_EN; + val |= BPCM_ZONE_CONTROL_PWR_UP_REQ; + val |= BPCM_ZONE_CONTROL_MEM_PWR_CTL_EN; + val |= BPCM_ZONE_CONTROL_BLK_RESET_ASSERT; + + err = bcm_pmb_bpcm_write(pmb, bus, device, offset, val); + } + + return err; +} + +static int bcm_pmb_power_off_device(struct bcm_pmb *pmb, int bus, u8 device) +{ + int offset; + u32 val; + int err; + + /* Entire device can be powered off by powering off the 0th zone */ + offset = BPCM_ZONE0 + BPCM_ZONE_CONTROL; + + err = bcm_pmb_bpcm_read(pmb, bus, device, offset, &val); + if (err) + return err; + + if (!(val & BPCM_ZONE_CONTROL_PWR_OFF_STATE)) { + val = BPCM_ZONE_CONTROL_PWR_DN_REQ; + + err = bcm_pmb_bpcm_write(pmb, bus, device, offset, val); + } + + return err; +} + +static int bcm_pmb_power_on_device(struct bcm_pmb *pmb, int bus, u8 device) +{ + u32 val; + int err; + int i; + + err = bcm_pmb_bpcm_read(pmb, bus, device, BPCM_CAPABILITIES, &val); + if (err) + return err; + + for (i = 0; i < (val & BPCM_CAP_NUM_ZONES); i++) { + err = bcm_pmb_power_on_zone(pmb, bus, device, i); + if (err) + return err; + } + + return err; +} + +static int bcm_pmb_power_on(struct generic_pm_domain *genpd) +{ + struct bcm_pmb_pm_domain *pd = container_of(genpd, struct bcm_pmb_pm_domain, genpd); + const struct bcm_pmb_pd_data *data = pd->data; + struct bcm_pmb *pmb = pd->pmb; + + switch (data->id) { + case BCM_PMB_PCIE0: + case BCM_PMB_PCIE1: + case BCM_PMB_PCIE2: + return bcm_pmb_power_on_zone(pmb, data->bus, data->device, 0); + case BCM_PMB_HOST_USB: + return bcm_pmb_power_on_device(pmb, data->bus, data->device); + default: + dev_err(pmb->dev, "unsupported device id: %d\n", data->id); + return -EINVAL; + } +} + +static int bcm_pmb_power_off(struct generic_pm_domain *genpd) +{ + struct bcm_pmb_pm_domain *pd = container_of(genpd, struct bcm_pmb_pm_domain, genpd); + const struct bcm_pmb_pd_data *data = pd->data; + struct bcm_pmb *pmb = pd->pmb; + + switch (data->id) { + case BCM_PMB_PCIE0: + case BCM_PMB_PCIE1: + case BCM_PMB_PCIE2: + return bcm_pmb_power_off_zone(pmb, data->bus, data->device, 0); + case BCM_PMB_HOST_USB: + return bcm_pmb_power_off_device(pmb, data->bus, data->device); + default: + dev_err(pmb->dev, "unsupported device id: %d\n", data->id); + return -EINVAL; + } +} + +static int bcm_pmb_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + const struct bcm_pmb_pd_data *table; + const struct bcm_pmb_pd_data *e; + struct resource *res; + struct bcm_pmb *pmb; + int max_id; + int err; + + pmb = devm_kzalloc(dev, sizeof(*pmb), GFP_KERNEL); + if (!pmb) + return -ENOMEM; + + pmb->dev = dev; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + pmb->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(pmb->base)) + return PTR_ERR(pmb->base); + + spin_lock_init(&pmb->lock); + + pmb->little_endian = !of_device_is_big_endian(dev->of_node); + + table = of_device_get_match_data(dev); + if (!table) + return -EINVAL; + + max_id = 0; + for (e = table; e->name; e++) + max_id = max(max_id, e->id); + + pmb->genpd_onecell_data.num_domains = max_id + 1; + pmb->genpd_onecell_data.domains = + devm_kcalloc(dev, pmb->genpd_onecell_data.num_domains, + sizeof(struct generic_pm_domain *), GFP_KERNEL); + if (!pmb->genpd_onecell_data.domains) + return -ENOMEM; + + for (e = table; e->name; e++) { + struct bcm_pmb_pm_domain *pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); + + pd->pmb = pmb; + pd->data = e; + pd->genpd.name = e->name; + pd->genpd.power_on = bcm_pmb_power_on; + pd->genpd.power_off = bcm_pmb_power_off; + + pm_genpd_init(&pd->genpd, NULL, true); + pmb->genpd_onecell_data.domains[e->id] = &pd->genpd; + } + + err = of_genpd_add_provider_onecell(dev->of_node, &pmb->genpd_onecell_data); + if (err) { + dev_err(dev, "failed to add genpd provider: %d\n", err); + return err; + } + + return 0; +} + +static const struct bcm_pmb_pd_data bcm_pmb_bcm4908_data[] = { + { .name = "pcie2", .id = BCM_PMB_PCIE2, .bus = 0, .device = 2, }, + { .name = "pcie0", .id = BCM_PMB_PCIE0, .bus = 1, .device = 14, }, + { .name = "pcie1", .id = BCM_PMB_PCIE1, .bus = 1, .device = 15, }, + { .name = "usb", .id = BCM_PMB_HOST_USB, .bus = 1, .device = 17, }, + { }, +}; + +static const struct of_device_id bcm_pmb_of_match[] = { + { .compatible = "brcm,bcm4908-pmb", .data = &bcm_pmb_bcm4908_data, }, + { }, +}; + +static struct platform_driver bcm_pmb_driver = { + .driver = { + .name = "bcm-pmb", + .of_match_table = bcm_pmb_of_match, + }, + .probe = bcm_pmb_probe, +}; + +builtin_platform_driver(bcm_pmb_driver); -- cgit v1.2.3 From 0c0d0e56e08ca3ae5f4a8922b6575bdf48b79974 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 22 Dec 2020 16:04:46 +0300 Subject: soc: qcom: socinfo: add qrb5165 SoC ID Signed-off-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20201222130448.4125297-1-dmitry.baryshkov@linaro.org Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/socinfo.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/soc') diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index d21530d24253..d4b0d6539df4 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -234,6 +234,7 @@ static const struct soc_id soc_id[] = { { 356, "SM8250" }, { 402, "IPQ6018" }, { 425, "SC7180" }, + { 455, "QRB5165" }, }; static const char *socinfo_machine(struct device *dev, unsigned int id) -- cgit v1.2.3 From 4305324208d8da4b4ce0efb20af9745effda3a2e Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 22 Dec 2020 16:04:47 +0300 Subject: soc: qcom: socinfo: add several PMIC IDs Add several PMIC IDs found on Qualcomm RB5 platform. Signed-off-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20201222130448.4125297-2-dmitry.baryshkov@linaro.org Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/socinfo.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/soc') diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index d4b0d6539df4..5536f1dd1d07 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -83,6 +83,11 @@ static const char *const pmic_models[] = { [23] = "PM8038", [24] = "PM8922", [25] = "PM8917", + [30] = "PM8150", + [31] = "PM8150L", + [32] = "PM8150B", + [33] = "PMK8002", + [36] = "PM8009", }; #endif /* CONFIG_DEBUG_FS */ -- cgit v1.2.3 From 734c78e7febf879a79e9b34e38df35cc63794350 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 22 Dec 2020 16:04:48 +0300 Subject: soc: qcom: socinfo: add info from PMIC models array Add debugfs file showing information from PMIC model array. Signed-off-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20201222130448.4125297-3-dmitry.baryshkov@linaro.org Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/socinfo.c | 42 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index 5536f1dd1d07..f5c190ceb667 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -15,6 +15,8 @@ #include #include +#include + /* * SoC version type with major number in the upper 16 bits and minor * number in the lower 16 bits. @@ -300,6 +302,32 @@ static int qcom_show_pmic_model(struct seq_file *seq, void *p) return 0; } +static int qcom_show_pmic_model_array(struct seq_file *seq, void *p) +{ + struct socinfo *socinfo = seq->private; + unsigned int num_pmics = le32_to_cpu(socinfo->num_pmics); + unsigned int pmic_array_offset = le32_to_cpu(socinfo->pmic_array_offset); + int i; + void *ptr = socinfo; + + ptr += pmic_array_offset; + + /* No need for bounds checking, it happened at socinfo_debugfs_init */ + for (i = 0; i < num_pmics; i++) { + unsigned int model = SOCINFO_MINOR(get_unaligned_le32(ptr + 2 * i * sizeof(u32))); + unsigned int die_rev = get_unaligned_le32(ptr + (2 * i + 1) * sizeof(u32)); + + if (model <= ARRAY_SIZE(pmic_models) && pmic_models[model]) + seq_printf(seq, "%s %u.%u\n", pmic_models[model], + SOCINFO_MAJOR(le32_to_cpu(die_rev)), + SOCINFO_MINOR(le32_to_cpu(die_rev))); + else + seq_printf(seq, "unknown (%d)\n", model); + } + + return 0; +} + static int qcom_show_pmic_die_revision(struct seq_file *seq, void *p) { struct socinfo *socinfo = seq->private; @@ -322,6 +350,7 @@ static int qcom_show_chip_id(struct seq_file *seq, void *p) QCOM_OPEN(build_id, qcom_show_build_id); QCOM_OPEN(pmic_model, qcom_show_pmic_model); +QCOM_OPEN(pmic_model_array, qcom_show_pmic_model_array); QCOM_OPEN(pmic_die_rev, qcom_show_pmic_die_revision); QCOM_OPEN(chip_id, qcom_show_chip_id); @@ -350,12 +379,14 @@ DEFINE_IMAGE_OPS(variant); DEFINE_IMAGE_OPS(oem); static void socinfo_debugfs_init(struct qcom_socinfo *qcom_socinfo, - struct socinfo *info) + struct socinfo *info, size_t info_size) { struct smem_image_version *versions; struct dentry *dentry; size_t size; int i; + unsigned int num_pmics; + unsigned int pmic_array_offset; qcom_socinfo->dbg_root = debugfs_create_dir("qcom_socinfo", NULL); @@ -411,6 +442,11 @@ static void socinfo_debugfs_init(struct qcom_socinfo *qcom_socinfo, &qcom_socinfo->info.raw_device_num); fallthrough; case SOCINFO_VERSION(0, 11): + num_pmics = le32_to_cpu(info->num_pmics); + pmic_array_offset = le32_to_cpu(info->pmic_array_offset); + if (pmic_array_offset + 2 * num_pmics * sizeof(u32) <= info_size) + DEBUGFS_ADD(info, pmic_model_array); + fallthrough; case SOCINFO_VERSION(0, 10): case SOCINFO_VERSION(0, 9): qcom_socinfo->info.foundry_id = __le32_to_cpu(info->foundry_id); @@ -488,7 +524,7 @@ static void socinfo_debugfs_exit(struct qcom_socinfo *qcom_socinfo) } #else static void socinfo_debugfs_init(struct qcom_socinfo *qcom_socinfo, - struct socinfo *info) + struct socinfo *info, size_t info_size) { } static void socinfo_debugfs_exit(struct qcom_socinfo *qcom_socinfo) { } @@ -528,7 +564,7 @@ static int qcom_socinfo_probe(struct platform_device *pdev) if (IS_ERR(qs->soc_dev)) return PTR_ERR(qs->soc_dev); - socinfo_debugfs_init(qs, info); + socinfo_debugfs_init(qs, info, item_size); /* Feed the soc specific unique data into entropy pool */ add_device_randomness(info, item_size); -- cgit v1.2.3 From 8333b2c26c2f38ed9510bce40e5a5c88d46c961e Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 15 Dec 2020 23:19:26 -0800 Subject: soc: qcom: socinfo: Open read access to all for debugfs There doesn't seem to be any reason to limit this to only root user readable. Let's make it readable by all so that random programs can read the debugfs files in here instead of just root. The information is just that, informational, so this is fine. Reviewed-by: Sai Prakash Ranjan Reviewed-by: Douglas Anderson Cc: Sai Prakash Ranjan Cc: Douglas Anderson Cc: Dmitry Baryshkov Signed-off-by: Stephen Boyd Link: https://lore.kernel.org/r/20201216071926.3147108-1-swboyd@chromium.org Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/socinfo.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index f5c190ceb667..c35e4c651602 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -272,7 +272,7 @@ static const struct file_operations qcom_ ##name## _ops = { \ } #define DEBUGFS_ADD(info, name) \ - debugfs_create_file(__stringify(name), 0400, \ + debugfs_create_file(__stringify(name), 0444, \ qcom_socinfo->dbg_root, \ info, &qcom_ ##name## _ops) @@ -392,14 +392,14 @@ static void socinfo_debugfs_init(struct qcom_socinfo *qcom_socinfo, qcom_socinfo->info.fmt = __le32_to_cpu(info->fmt); - debugfs_create_x32("info_fmt", 0400, qcom_socinfo->dbg_root, + debugfs_create_x32("info_fmt", 0444, qcom_socinfo->dbg_root, &qcom_socinfo->info.fmt); switch (qcom_socinfo->info.fmt) { case SOCINFO_VERSION(0, 15): qcom_socinfo->info.nmodem_supported = __le32_to_cpu(info->nmodem_supported); - debugfs_create_u32("nmodem_supported", 0400, qcom_socinfo->dbg_root, + debugfs_create_u32("nmodem_supported", 0444, qcom_socinfo->dbg_root, &qcom_socinfo->info.nmodem_supported); fallthrough; case SOCINFO_VERSION(0, 14): @@ -408,19 +408,19 @@ static void socinfo_debugfs_init(struct qcom_socinfo *qcom_socinfo, qcom_socinfo->info.num_defective_parts = __le32_to_cpu(info->num_defective_parts); qcom_socinfo->info.ndefective_parts_array_offset = __le32_to_cpu(info->ndefective_parts_array_offset); - debugfs_create_u32("num_clusters", 0400, qcom_socinfo->dbg_root, + debugfs_create_u32("num_clusters", 0444, qcom_socinfo->dbg_root, &qcom_socinfo->info.num_clusters); - debugfs_create_u32("ncluster_array_offset", 0400, qcom_socinfo->dbg_root, + debugfs_create_u32("ncluster_array_offset", 0444, qcom_socinfo->dbg_root, &qcom_socinfo->info.ncluster_array_offset); - debugfs_create_u32("num_defective_parts", 0400, qcom_socinfo->dbg_root, + debugfs_create_u32("num_defective_parts", 0444, qcom_socinfo->dbg_root, &qcom_socinfo->info.num_defective_parts); - debugfs_create_u32("ndefective_parts_array_offset", 0400, qcom_socinfo->dbg_root, + debugfs_create_u32("ndefective_parts_array_offset", 0444, qcom_socinfo->dbg_root, &qcom_socinfo->info.ndefective_parts_array_offset); fallthrough; case SOCINFO_VERSION(0, 13): qcom_socinfo->info.nproduct_id = __le32_to_cpu(info->nproduct_id); - debugfs_create_u32("nproduct_id", 0400, qcom_socinfo->dbg_root, + debugfs_create_u32("nproduct_id", 0444, qcom_socinfo->dbg_root, &qcom_socinfo->info.nproduct_id); DEBUGFS_ADD(info, chip_id); fallthrough; @@ -432,12 +432,12 @@ static void socinfo_debugfs_init(struct qcom_socinfo *qcom_socinfo, qcom_socinfo->info.raw_device_num = __le32_to_cpu(info->raw_device_num); - debugfs_create_x32("chip_family", 0400, qcom_socinfo->dbg_root, + debugfs_create_x32("chip_family", 0444, qcom_socinfo->dbg_root, &qcom_socinfo->info.chip_family); - debugfs_create_x32("raw_device_family", 0400, + debugfs_create_x32("raw_device_family", 0444, qcom_socinfo->dbg_root, &qcom_socinfo->info.raw_device_family); - debugfs_create_x32("raw_device_number", 0400, + debugfs_create_x32("raw_device_number", 0444, qcom_socinfo->dbg_root, &qcom_socinfo->info.raw_device_num); fallthrough; @@ -451,7 +451,7 @@ static void socinfo_debugfs_init(struct qcom_socinfo *qcom_socinfo, case SOCINFO_VERSION(0, 9): qcom_socinfo->info.foundry_id = __le32_to_cpu(info->foundry_id); - debugfs_create_u32("foundry_id", 0400, qcom_socinfo->dbg_root, + debugfs_create_u32("foundry_id", 0444, qcom_socinfo->dbg_root, &qcom_socinfo->info.foundry_id); fallthrough; case SOCINFO_VERSION(0, 8): @@ -463,7 +463,7 @@ static void socinfo_debugfs_init(struct qcom_socinfo *qcom_socinfo, qcom_socinfo->info.hw_plat_subtype = __le32_to_cpu(info->hw_plat_subtype); - debugfs_create_u32("hardware_platform_subtype", 0400, + debugfs_create_u32("hardware_platform_subtype", 0444, qcom_socinfo->dbg_root, &qcom_socinfo->info.hw_plat_subtype); fallthrough; @@ -471,28 +471,28 @@ static void socinfo_debugfs_init(struct qcom_socinfo *qcom_socinfo, qcom_socinfo->info.accessory_chip = __le32_to_cpu(info->accessory_chip); - debugfs_create_u32("accessory_chip", 0400, + debugfs_create_u32("accessory_chip", 0444, qcom_socinfo->dbg_root, &qcom_socinfo->info.accessory_chip); fallthrough; case SOCINFO_VERSION(0, 4): qcom_socinfo->info.plat_ver = __le32_to_cpu(info->plat_ver); - debugfs_create_u32("platform_version", 0400, + debugfs_create_u32("platform_version", 0444, qcom_socinfo->dbg_root, &qcom_socinfo->info.plat_ver); fallthrough; case SOCINFO_VERSION(0, 3): qcom_socinfo->info.hw_plat = __le32_to_cpu(info->hw_plat); - debugfs_create_u32("hardware_platform", 0400, + debugfs_create_u32("hardware_platform", 0444, qcom_socinfo->dbg_root, &qcom_socinfo->info.hw_plat); fallthrough; case SOCINFO_VERSION(0, 2): qcom_socinfo->info.raw_ver = __le32_to_cpu(info->raw_ver); - debugfs_create_u32("raw_version", 0400, qcom_socinfo->dbg_root, + debugfs_create_u32("raw_version", 0444, qcom_socinfo->dbg_root, &qcom_socinfo->info.raw_ver); fallthrough; case SOCINFO_VERSION(0, 1): @@ -509,11 +509,11 @@ static void socinfo_debugfs_init(struct qcom_socinfo *qcom_socinfo, dentry = debugfs_create_dir(socinfo_image_names[i], qcom_socinfo->dbg_root); - debugfs_create_file("name", 0400, dentry, &versions[i], + debugfs_create_file("name", 0444, dentry, &versions[i], &qcom_image_name_ops); - debugfs_create_file("variant", 0400, dentry, &versions[i], + debugfs_create_file("variant", 0444, dentry, &versions[i], &qcom_image_variant_ops); - debugfs_create_file("oem", 0400, dentry, &versions[i], + debugfs_create_file("oem", 0444, dentry, &versions[i], &qcom_image_oem_ops); } } -- cgit v1.2.3 From 0da78ae2e04c56f8f7ad9a28abdb5131b1bdf013 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Sat, 9 Jan 2021 17:31:22 +0100 Subject: soc: qcom: socinfo: Add SoC IDs for 630 family Add missing SoC IDs for Snapdragon 630-family platforms. Signed-off-by: Konrad Dybcio Tested-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20210109163123.147185-1-konrad.dybcio@somainline.org Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/socinfo.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/soc') diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index c35e4c651602..3b1afd3f3b16 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -231,10 +231,17 @@ static const struct soc_id soc_id[] = { { 310, "MSM8996AU" }, { 311, "APQ8096AU" }, { 312, "APQ8096SG" }, + { 317, "SDM660" }, { 318, "SDM630" }, { 321, "SDM845" }, + { 324, "SDA660" }, + { 325, "SDM658" }, + { 326, "SDA658" }, + { 327, "SDA630" }, { 338, "SDM450" }, { 341, "SDA845" }, + { 345, "SDM636" }, + { 346, "SDA636" }, { 349, "SDM632" }, { 350, "SDA632" }, { 351, "SDA450" }, -- cgit v1.2.3 From 407bdcf9beb3e96cca26abeec38955f4c320fa3d Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Sat, 9 Jan 2021 17:31:23 +0100 Subject: soc: qcom: socinfo: Add SoC IDs for APQ/MSM8998 Add missing SoC IDs for Snapdragon 835-family platforms. Signed-off-by: Konrad Dybcio Tested-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20210109163123.147185-2-konrad.dybcio@somainline.org Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/socinfo.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/soc') diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index 3b1afd3f3b16..bcf621e1db30 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -225,6 +225,7 @@ static const struct soc_id soc_id[] = { { 251, "MSM8992" }, { 253, "APQ8094" }, { 291, "APQ8096" }, + { 292, "MSM8998" }, { 293, "MSM8953" }, { 304, "APQ8053" }, { 305, "MSM8996SG" }, @@ -233,6 +234,7 @@ static const struct soc_id soc_id[] = { { 312, "APQ8096SG" }, { 317, "SDM660" }, { 318, "SDM630" }, + { 319, "APQ8098" }, { 321, "SDM845" }, { 324, "SDA660" }, { 325, "SDM658" }, -- cgit v1.2.3 From 3bc4bf77fa2adca8d6677461b6ec57505f1a3331 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 15 Jan 2021 17:27:28 +0100 Subject: soc: qcom: socinfo: Add MDM9607 IDs Along with IDs for its derivatives. Signed-off-by: Konrad Dybcio Link: https://lore.kernel.org/r/20210115162728.118249-1-konrad.dybcio@somainline.org Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/socinfo.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/soc') diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index bcf621e1db30..a985ed064669 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -224,9 +224,14 @@ static const struct soc_id soc_id[] = { { 250, "MSM8616" }, { 251, "MSM8992" }, { 253, "APQ8094" }, + { 290, "MDM9607" }, { 291, "APQ8096" }, { 292, "MSM8998" }, { 293, "MSM8953" }, + { 296, "MDM8207" }, + { 297, "MDM9207" }, + { 298, "MDM9307" }, + { 299, "MDM9628" }, { 304, "APQ8053" }, { 305, "MSM8996SG" }, { 310, "MSM8996AU" }, @@ -236,6 +241,7 @@ static const struct soc_id soc_id[] = { { 318, "SDM630" }, { 319, "APQ8098" }, { 321, "SDM845" }, + { 322, "MDM9206" }, { 324, "SDA660" }, { 325, "SDM658" }, { 326, "SDA658" }, -- cgit v1.2.3 From e6393818c8d13cb602af4850bcef47ead1455bbf Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 18 Jan 2021 11:36:51 +0000 Subject: soc: qcom: socinfo: Fix off-by-one array index bounds check There is an off-by-one array index bounds check on array pmic_models. Fix this by checking using < rather than <= on the array size. Addresses-Coverity: ("Out-of-bounds read") Fixes: 734c78e7febf ("soc: qcom: socinfo: add info from PMIC models array") Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20210118113651.71955-1-colin.king@canonical.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/socinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/soc') diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index a985ed064669..f449df560d93 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -332,7 +332,7 @@ static int qcom_show_pmic_model_array(struct seq_file *seq, void *p) unsigned int model = SOCINFO_MINOR(get_unaligned_le32(ptr + 2 * i * sizeof(u32))); unsigned int die_rev = get_unaligned_le32(ptr + (2 * i + 1) * sizeof(u32)); - if (model <= ARRAY_SIZE(pmic_models) && pmic_models[model]) + if (model < ARRAY_SIZE(pmic_models) && pmic_models[model]) seq_printf(seq, "%s %u.%u\n", pmic_models[model], SOCINFO_MAJOR(le32_to_cpu(die_rev)), SOCINFO_MINOR(le32_to_cpu(die_rev))); -- cgit v1.2.3 From 5fb33d8960dc7abdabc6fe599a30c2c99b082ef6 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 20 Jan 2021 12:57:55 +0300 Subject: soc: qcom: socinfo: Fix an off by one in qcom_show_pmic_model() These need to be < ARRAY_SIZE() instead of <= ARRAY_SIZE() to prevent accessing one element beyond the end of the array. Acked-by: Dmitry Baryshkov Reviewed-by: Douglas Anderson Reviewed-by: Stephen Boyd Fixes: e9247e2ce577 ("soc: qcom: socinfo: fix printing of pmic_model") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/YAf+o85Z9lgkq3Nw@mwanda Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/socinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/soc') diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index f449df560d93..5b4ad24a022b 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -309,7 +309,7 @@ static int qcom_show_pmic_model(struct seq_file *seq, void *p) if (model < 0) return -EINVAL; - if (model <= ARRAY_SIZE(pmic_models) && pmic_models[model]) + if (model < ARRAY_SIZE(pmic_models) && pmic_models[model]) seq_printf(seq, "%s\n", pmic_models[model]); else seq_printf(seq, "unknown (%d)\n", model); -- cgit v1.2.3 From a88f66d4a8668e66afa8eb4099b4515e0729b52a Mon Sep 17 00:00:00 2001 From: Vasyl Gomonovych Date: Sun, 24 Jan 2021 20:51:36 -0800 Subject: soc: ti: knav_qmss: Put refcount for dev node in failure case for_each_child_of_node increases refcount for each device_node and decreases previous one in a loop, but in case jump out of a loop current node refcount has no chnase for decreases so requires an of_node_put for jupm out cases. Fix based on raport from scripts/coccinelle/iterators/for_each_child.cocci Signed-off-by: Vasyl Gomonovych Signed-off-by: Santosh Shilimkar --- drivers/soc/ti/knav_dma.c | 1 + drivers/soc/ti/knav_qmss_queue.c | 3 +++ 2 files changed, 4 insertions(+) (limited to 'drivers/soc') diff --git a/drivers/soc/ti/knav_dma.c b/drivers/soc/ti/knav_dma.c index 7b5cb5d48f7d..591d14ebcb11 100644 --- a/drivers/soc/ti/knav_dma.c +++ b/drivers/soc/ti/knav_dma.c @@ -758,6 +758,7 @@ static int knav_dma_probe(struct platform_device *pdev) for_each_child_of_node(node, child) { ret = dma_init(node, child); if (ret) { + of_node_put(child); dev_err(&pdev->dev, "init failed with %d\n", ret); break; } diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c index 2e521f1eda96..2ac3856b8d42 100644 --- a/drivers/soc/ti/knav_qmss_queue.c +++ b/drivers/soc/ti/knav_qmss_queue.c @@ -1087,6 +1087,7 @@ static int knav_queue_setup_regions(struct knav_device *kdev, for_each_child_of_node(regions, child) { region = devm_kzalloc(dev, sizeof(*region), GFP_KERNEL); if (!region) { + of_node_put(child); dev_err(dev, "out of memory allocating region\n"); return -ENOMEM; } @@ -1399,6 +1400,7 @@ static int knav_queue_init_qmgrs(struct knav_device *kdev, for_each_child_of_node(qmgrs, child) { qmgr = devm_kzalloc(dev, sizeof(*qmgr), GFP_KERNEL); if (!qmgr) { + of_node_put(child); dev_err(dev, "out of memory allocating qmgr\n"); return -ENOMEM; } @@ -1498,6 +1500,7 @@ static int knav_queue_init_pdsps(struct knav_device *kdev, for_each_child_of_node(pdsps, child) { pdsp = devm_kzalloc(dev, sizeof(*pdsp), GFP_KERNEL); if (!pdsp) { + of_node_put(child); dev_err(dev, "out of memory allocating pdsp\n"); return -ENOMEM; } -- cgit v1.2.3 From 17ad4662595ea0c4fd7496b664523ef632e63349 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 24 Jan 2021 20:51:36 -0800 Subject: soc: ti: pm33xx: Fix some resource leak in the error handling paths of the probe function 'am33xx_pm_rtc_setup()' allocates some resources that must be freed on the error. Commit 2152fbbd47c0 ("soc: ti: pm33xx: Simplify RTC usage to prepare to drop platform data") has introduced the use of these resources but has only updated the remove function. Fix the error handling path of the probe function now. Fixes: 2152fbbd47c0 ("soc: ti: pm33xx: Simplify RTC usage to prepare to drop platform data") Signed-off-by: Christophe JAILLET Signed-off-by: Santosh Shilimkar --- drivers/soc/ti/pm33xx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/soc') diff --git a/drivers/soc/ti/pm33xx.c b/drivers/soc/ti/pm33xx.c index 64f3e3105540..7bab4bbaf02d 100644 --- a/drivers/soc/ti/pm33xx.c +++ b/drivers/soc/ti/pm33xx.c @@ -535,7 +535,7 @@ static int am33xx_pm_probe(struct platform_device *pdev) ret = am33xx_push_sram_idle(); if (ret) - goto err_free_sram; + goto err_unsetup_rtc; am33xx_pm_set_ipc_ops(); @@ -575,6 +575,9 @@ err_pm_runtime_put: err_pm_runtime_disable: pm_runtime_disable(dev); wkup_m3_ipc_put(m3_ipc); +err_unsetup_rtc: + iounmap(rtc_base_virt); + clk_put(rtc_fck); err_free_sram: am33xx_pm_free_sram(); pm33xx_dev = NULL; -- cgit v1.2.3 From f97a8a34353e993f7dc2c204faaa033955907bdc Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Sun, 24 Jan 2021 20:51:37 -0800 Subject: soc: ti: pruss: Correct the pruss_clk_init error trace text The pruss_clk_init() function can register more than one clock. Correct the existing misleading error trace upon a failure within this function. Signed-off-by: Suman Anna Signed-off-by: Santosh Shilimkar --- drivers/soc/ti/pruss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/soc') diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c index 5d6e7132a5c4..1d6890134312 100644 --- a/drivers/soc/ti/pruss.c +++ b/drivers/soc/ti/pruss.c @@ -273,7 +273,7 @@ static int pruss_probe(struct platform_device *pdev) ret = pruss_clk_init(pruss, child); if (ret) { - dev_err(dev, "failed to setup coreclk-mux\n"); + dev_err(dev, "pruss_clk_init failed, ret = %d\n", ret); goto node_put; } -- cgit v1.2.3 From 43eb76a2e56b94541293fc8192d6edf1d0ec8965 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Mon, 18 Jan 2021 17:19:41 +0100 Subject: drivers: soc: qcom: rpmpd: Add msm8994 RPM Power Domains MSM8994 uses similar to MSM8996, legacy-style voltage control, but does not include a VDD_SC_CX line. This setup is also correct for MSM8992. Do note that there exist some boards that use a tertiary PMIC (most likely pm8004), where SMPB on VDDGFX becomes SMPC. I cannot test this configuration though. Signed-off-by: Konrad Dybcio Link: https://lore.kernel.org/r/20210118161943.105733-1-konrad.dybcio@somainline.org Signed-off-by: Bjorn Andersson --- .../devicetree/bindings/power/qcom,rpmpd.yaml | 1 + drivers/soc/qcom/rpmpd.c | 28 ++++++++++++++++++++++ include/dt-bindings/power/qcom-rpmpd.h | 9 +++++++ 3 files changed, 38 insertions(+) (limited to 'drivers/soc') diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml index 64825128ee97..1ea21acbbd55 100644 --- a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml +++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml @@ -19,6 +19,7 @@ properties: - qcom,msm8916-rpmpd - qcom,msm8939-rpmpd - qcom,msm8976-rpmpd + - qcom,msm8994-rpmpd - qcom,msm8996-rpmpd - qcom,msm8998-rpmpd - qcom,qcs404-rpmpd diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c index 85d1207b72d7..27733b0e7fca 100644 --- a/drivers/soc/qcom/rpmpd.c +++ b/drivers/soc/qcom/rpmpd.c @@ -21,6 +21,8 @@ * RPMPD_X is X encoded as a little-endian, lower-case, ASCII string */ #define RPMPD_SMPA 0x61706d73 #define RPMPD_LDOA 0x616f646c +#define RPMPD_SMPB 0x62706d73 +#define RPMPD_LDOB 0x626f646c #define RPMPD_RWCX 0x78637772 #define RPMPD_RWMX 0x786d7772 #define RPMPD_RWLC 0x636c7772 @@ -184,6 +186,31 @@ static const struct rpmpd_desc msm8976_desc = { .max_state = RPM_SMD_LEVEL_TURBO_HIGH, }; +/* msm8994 RPM Power domains */ +DEFINE_RPMPD_PAIR(msm8994, vddcx, vddcx_ao, SMPA, CORNER, 1); +DEFINE_RPMPD_PAIR(msm8994, vddmx, vddmx_ao, SMPA, CORNER, 2); +/* Attention! *Some* 8994 boards with pm8004 may use SMPC here! */ +DEFINE_RPMPD_CORNER(msm8994, vddgfx, SMPB, 2); + +DEFINE_RPMPD_VFC(msm8994, vddcx_vfc, SMPA, 1); +DEFINE_RPMPD_VFC(msm8994, vddgfx_vfc, SMPB, 2); + +static struct rpmpd *msm8994_rpmpds[] = { + [MSM8994_VDDCX] = &msm8994_vddcx, + [MSM8994_VDDCX_AO] = &msm8994_vddcx_ao, + [MSM8994_VDDCX_VFC] = &msm8994_vddcx_vfc, + [MSM8994_VDDMX] = &msm8994_vddmx, + [MSM8994_VDDMX_AO] = &msm8994_vddmx_ao, + [MSM8994_VDDGFX] = &msm8994_vddgfx, + [MSM8994_VDDGFX_VFC] = &msm8994_vddgfx_vfc, +}; + +static const struct rpmpd_desc msm8994_desc = { + .rpmpds = msm8994_rpmpds, + .num_pds = ARRAY_SIZE(msm8994_rpmpds), + .max_state = MAX_CORNER_RPMPD_STATE, +}; + /* msm8996 RPM Power domains */ DEFINE_RPMPD_PAIR(msm8996, vddcx, vddcx_ao, SMPA, CORNER, 1); DEFINE_RPMPD_PAIR(msm8996, vddmx, vddmx_ao, SMPA, CORNER, 2); @@ -302,6 +329,7 @@ static const struct of_device_id rpmpd_match_table[] = { { .compatible = "qcom,msm8916-rpmpd", .data = &msm8916_desc }, { .compatible = "qcom,msm8939-rpmpd", .data = &msm8939_desc }, { .compatible = "qcom,msm8976-rpmpd", .data = &msm8976_desc }, + { .compatible = "qcom,msm8994-rpmpd", .data = &msm8994_desc }, { .compatible = "qcom,msm8996-rpmpd", .data = &msm8996_desc }, { .compatible = "qcom,msm8998-rpmpd", .data = &msm8998_desc }, { .compatible = "qcom,qcs404-rpmpd", .data = &qcs404_desc }, diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h index 7714487ac76b..d711e250cf2c 100644 --- a/include/dt-bindings/power/qcom-rpmpd.h +++ b/include/dt-bindings/power/qcom-rpmpd.h @@ -94,6 +94,15 @@ #define MSM8976_VDDMX_AO 4 #define MSM8976_VDDMX_VFL 5 +/* MSM8994 Power Domain Indexes */ +#define MSM8994_VDDCX 0 +#define MSM8994_VDDCX_AO 1 +#define MSM8994_VDDCX_VFC 2 +#define MSM8994_VDDMX 3 +#define MSM8994_VDDMX_AO 4 +#define MSM8994_VDDGFX 5 +#define MSM8994_VDDGFX_VFC 6 + /* MSM8996 Power Domain Indexes */ #define MSM8996_VDDCX 0 #define MSM8996_VDDCX_AO 1 -- cgit v1.2.3 From 975435132ecfef8de2118668c9f4f95086a0aae5 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Fri, 22 Jan 2021 14:21:34 +0200 Subject: drivers: soc: atmel: add null entry at the end of at91_soc_allowed_list[] of_match_node() calls __of_match_node() which loops though the entries of matches array. It stops when condition: (matches->name[0] || matches->type[0] || matches->compatible[0]) is false. Thus, add a null entry at the end of at91_soc_allowed_list[] array. Fixes: caab13b49604 ("drivers: soc: atmel: Avoid calling at91_soc_init on non AT91 SoCs") Cc: stable@vger.kernel.org #4.12+ Signed-off-by: Claudiu Beznea Signed-off-by: Arnd Bergmann Signed-off-by: Nicolas Ferre --- drivers/soc/atmel/soc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/soc') diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c index 728d461ad6d6..698d21f50516 100644 --- a/drivers/soc/atmel/soc.c +++ b/drivers/soc/atmel/soc.c @@ -275,7 +275,8 @@ static const struct of_device_id at91_soc_allowed_list[] __initconst = { { .compatible = "atmel,at91rm9200", }, { .compatible = "atmel,at91sam9", }, { .compatible = "atmel,sama5", }, - { .compatible = "atmel,samv7", } + { .compatible = "atmel,samv7", }, + { } }; static int __init atmel_soc_device_init(void) -- cgit v1.2.3 From 8eb2f88c6084b9dc69147abb3d24dafe36ecda8a Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Fri, 22 Jan 2021 14:21:32 +0200 Subject: drivers: soc: atmel: use GENMASK Use GENMASK() to define CIDR match mask. Signed-off-by: Claudiu Beznea Signed-off-by: Nicolas Ferre Link: https://lore.kernel.org/r/1611318097-8970-3-git-send-email-claudiu.beznea@microchip.com --- drivers/soc/atmel/soc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/soc') diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c index 698d21f50516..c3f920ee5c6f 100644 --- a/drivers/soc/atmel/soc.c +++ b/drivers/soc/atmel/soc.c @@ -27,7 +27,7 @@ #define AT91_CHIPID_EXID 0x04 #define AT91_CIDR_VERSION(x) ((x) & 0x1f) #define AT91_CIDR_EXT BIT(31) -#define AT91_CIDR_MATCH_MASK 0x7fffffe0 +#define AT91_CIDR_MATCH_MASK GENMASK(30, 5) static const struct at91_soc __initconst socs[] = { #ifdef CONFIG_SOC_AT91RM9200 -- cgit v1.2.3 From 11272a373c44a5bea3a1dd051a7e84e396926c14 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Fri, 22 Jan 2021 14:21:33 +0200 Subject: drivers: soc: atmel: fix "__initconst should be placed after socs[]" warning Fix checkpatch.pl warning: "__initconst should be placed after socs[]". Signed-off-by: Claudiu Beznea Signed-off-by: Nicolas Ferre Link: https://lore.kernel.org/r/1611318097-8970-4-git-send-email-claudiu.beznea@microchip.com --- drivers/soc/atmel/soc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/soc') diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c index c3f920ee5c6f..03f3c742716c 100644 --- a/drivers/soc/atmel/soc.c +++ b/drivers/soc/atmel/soc.c @@ -29,7 +29,7 @@ #define AT91_CIDR_EXT BIT(31) #define AT91_CIDR_MATCH_MASK GENMASK(30, 5) -static const struct at91_soc __initconst socs[] = { +static const struct at91_soc socs[] __initconst = { #ifdef CONFIG_SOC_AT91RM9200 AT91_SOC(AT91RM9200_CIDR_MATCH, 0, "at91rm9200 BGA", "at91rm9200"), #endif -- cgit v1.2.3 From af3a10513cd628269c3207bc50b8a5886c566ec4 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Fri, 22 Jan 2021 14:21:35 +0200 Subject: drivers: soc: atmel: add per soc id and version match masks SAMA7G5 has different masks for chip ID and chip version on CIDR register compared to previous AT91 SoCs. For this the commit adapts the code for SAMA7G5 addition by introducing 2 new members in struct at91_soc and fill them properly and also preparing the parsing of proper DT binding. Signed-off-by: Claudiu Beznea Signed-off-by: Nicolas Ferre Link: https://lore.kernel.org/r/1611318097-8970-6-git-send-email-claudiu.beznea@microchip.com --- drivers/soc/atmel/soc.c | 199 ++++++++++++++++++++++++++++++++---------------- drivers/soc/atmel/soc.h | 7 +- 2 files changed, 140 insertions(+), 66 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c index 03f3c742716c..f9052f45cb3e 100644 --- a/drivers/soc/atmel/soc.c +++ b/drivers/soc/atmel/soc.c @@ -25,135 +25,200 @@ #define AT91_DBGU_EXID 0x44 #define AT91_CHIPID_CIDR 0x00 #define AT91_CHIPID_EXID 0x04 -#define AT91_CIDR_VERSION(x) ((x) & 0x1f) +#define AT91_CIDR_VERSION(x, m) ((x) & (m)) +#define AT91_CIDR_VERSION_MASK GENMASK(4, 0) #define AT91_CIDR_EXT BIT(31) #define AT91_CIDR_MATCH_MASK GENMASK(30, 5) static const struct at91_soc socs[] __initconst = { #ifdef CONFIG_SOC_AT91RM9200 - AT91_SOC(AT91RM9200_CIDR_MATCH, 0, "at91rm9200 BGA", "at91rm9200"), + AT91_SOC(AT91RM9200_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, 0, "at91rm9200 BGA", "at91rm9200"), #endif #ifdef CONFIG_SOC_AT91SAM9 - AT91_SOC(AT91SAM9260_CIDR_MATCH, 0, "at91sam9260", NULL), - AT91_SOC(AT91SAM9261_CIDR_MATCH, 0, "at91sam9261", NULL), - AT91_SOC(AT91SAM9263_CIDR_MATCH, 0, "at91sam9263", NULL), - AT91_SOC(AT91SAM9G20_CIDR_MATCH, 0, "at91sam9g20", NULL), - AT91_SOC(AT91SAM9RL64_CIDR_MATCH, 0, "at91sam9rl64", NULL), - AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9M11_EXID_MATCH, + AT91_SOC(AT91SAM9260_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, 0, "at91sam9260", NULL), + AT91_SOC(AT91SAM9261_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, 0, "at91sam9261", NULL), + AT91_SOC(AT91SAM9263_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, 0, "at91sam9263", NULL), + AT91_SOC(AT91SAM9G20_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, 0, "at91sam9g20", NULL), + AT91_SOC(AT91SAM9RL64_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, 0, "at91sam9rl64", NULL), + AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, AT91SAM9M11_EXID_MATCH, "at91sam9m11", "at91sam9g45"), - AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9M10_EXID_MATCH, + AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, AT91SAM9M10_EXID_MATCH, "at91sam9m10", "at91sam9g45"), - AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9G46_EXID_MATCH, + AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, AT91SAM9G46_EXID_MATCH, "at91sam9g46", "at91sam9g45"), - AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9G45_EXID_MATCH, + AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, AT91SAM9G45_EXID_MATCH, "at91sam9g45", "at91sam9g45"), - AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9G15_EXID_MATCH, + AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, AT91SAM9G15_EXID_MATCH, "at91sam9g15", "at91sam9x5"), - AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9G35_EXID_MATCH, + AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, AT91SAM9G35_EXID_MATCH, "at91sam9g35", "at91sam9x5"), - AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9X35_EXID_MATCH, + AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, AT91SAM9X35_EXID_MATCH, "at91sam9x35", "at91sam9x5"), - AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9G25_EXID_MATCH, + AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, AT91SAM9G25_EXID_MATCH, "at91sam9g25", "at91sam9x5"), - AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9X25_EXID_MATCH, + AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, AT91SAM9X25_EXID_MATCH, "at91sam9x25", "at91sam9x5"), - AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91SAM9CN12_EXID_MATCH, + AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, AT91SAM9CN12_EXID_MATCH, "at91sam9cn12", "at91sam9n12"), - AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91SAM9N12_EXID_MATCH, + AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, AT91SAM9N12_EXID_MATCH, "at91sam9n12", "at91sam9n12"), - AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91SAM9CN11_EXID_MATCH, + AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, AT91SAM9CN11_EXID_MATCH, "at91sam9cn11", "at91sam9n12"), - AT91_SOC(AT91SAM9XE128_CIDR_MATCH, 0, "at91sam9xe128", "at91sam9xe128"), - AT91_SOC(AT91SAM9XE256_CIDR_MATCH, 0, "at91sam9xe256", "at91sam9xe256"), - AT91_SOC(AT91SAM9XE512_CIDR_MATCH, 0, "at91sam9xe512", "at91sam9xe512"), + AT91_SOC(AT91SAM9XE128_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, 0, "at91sam9xe128", "at91sam9xe128"), + AT91_SOC(AT91SAM9XE256_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, 0, "at91sam9xe256", "at91sam9xe256"), + AT91_SOC(AT91SAM9XE512_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, 0, "at91sam9xe512", "at91sam9xe512"), #endif #ifdef CONFIG_SOC_SAM9X60 - AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_EXID_MATCH, "sam9x60", "sam9x60"), + AT91_SOC(SAM9X60_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH, + "sam9x60", "sam9x60"), AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_D5M_EXID_MATCH, + AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH, "sam9x60 64MiB DDR2 SiP", "sam9x60"), AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_D1G_EXID_MATCH, + AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH, "sam9x60 128MiB DDR2 SiP", "sam9x60"), AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_D6K_EXID_MATCH, + AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH, "sam9x60 8MiB SDRAM SiP", "sam9x60"), #endif #ifdef CONFIG_SOC_SAMA5 - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D21CU_EXID_MATCH, + AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D21CU_EXID_MATCH, "sama5d21", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D22CU_EXID_MATCH, + AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D22CU_EXID_MATCH, "sama5d22", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D225C_D1M_EXID_MATCH, + AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D225C_D1M_EXID_MATCH, "sama5d225c 16MiB SiP", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D23CU_EXID_MATCH, + AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D23CU_EXID_MATCH, "sama5d23", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D24CX_EXID_MATCH, + AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D24CX_EXID_MATCH, "sama5d24", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D24CU_EXID_MATCH, + AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D24CU_EXID_MATCH, "sama5d24", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D26CU_EXID_MATCH, + AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D26CU_EXID_MATCH, "sama5d26", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27CU_EXID_MATCH, + AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D27CU_EXID_MATCH, "sama5d27", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27CN_EXID_MATCH, + AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D27CN_EXID_MATCH, "sama5d27", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27C_D1G_EXID_MATCH, + AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D27C_D1G_EXID_MATCH, "sama5d27c 128MiB SiP", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27C_D5M_EXID_MATCH, + AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D27C_D5M_EXID_MATCH, "sama5d27c 64MiB SiP", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27C_LD1G_EXID_MATCH, + AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D27C_LD1G_EXID_MATCH, "sama5d27c 128MiB LPDDR2 SiP", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27C_LD2G_EXID_MATCH, + AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D27C_LD2G_EXID_MATCH, "sama5d27c 256MiB LPDDR2 SiP", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28CU_EXID_MATCH, + AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D28CU_EXID_MATCH, "sama5d28", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28CN_EXID_MATCH, + AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D28CN_EXID_MATCH, "sama5d28", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28C_D1G_EXID_MATCH, + AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D28C_D1G_EXID_MATCH, "sama5d28c 128MiB SiP", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28C_LD1G_EXID_MATCH, + AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D28C_LD1G_EXID_MATCH, "sama5d28c 128MiB LPDDR2 SiP", "sama5d2"), - AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28C_LD2G_EXID_MATCH, + AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D28C_LD2G_EXID_MATCH, "sama5d28c 256MiB LPDDR2 SiP", "sama5d2"), - AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D31_EXID_MATCH, + AT91_SOC(SAMA5D3_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D31_EXID_MATCH, "sama5d31", "sama5d3"), - AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D33_EXID_MATCH, + AT91_SOC(SAMA5D3_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D33_EXID_MATCH, "sama5d33", "sama5d3"), - AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D34_EXID_MATCH, + AT91_SOC(SAMA5D3_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D34_EXID_MATCH, "sama5d34", "sama5d3"), - AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D35_EXID_MATCH, + AT91_SOC(SAMA5D3_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D35_EXID_MATCH, "sama5d35", "sama5d3"), - AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D36_EXID_MATCH, + AT91_SOC(SAMA5D3_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D36_EXID_MATCH, "sama5d36", "sama5d3"), - AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D41_EXID_MATCH, + AT91_SOC(SAMA5D4_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D41_EXID_MATCH, "sama5d41", "sama5d4"), - AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D42_EXID_MATCH, + AT91_SOC(SAMA5D4_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D42_EXID_MATCH, "sama5d42", "sama5d4"), - AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D43_EXID_MATCH, + AT91_SOC(SAMA5D4_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D43_EXID_MATCH, "sama5d43", "sama5d4"), - AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D44_EXID_MATCH, + AT91_SOC(SAMA5D4_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMA5D44_EXID_MATCH, "sama5d44", "sama5d4"), #endif #ifdef CONFIG_SOC_SAMV7 - AT91_SOC(SAME70Q21_CIDR_MATCH, SAME70Q21_EXID_MATCH, + AT91_SOC(SAME70Q21_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAME70Q21_EXID_MATCH, "same70q21", "same7"), - AT91_SOC(SAME70Q20_CIDR_MATCH, SAME70Q20_EXID_MATCH, + AT91_SOC(SAME70Q20_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAME70Q20_EXID_MATCH, "same70q20", "same7"), - AT91_SOC(SAME70Q19_CIDR_MATCH, SAME70Q19_EXID_MATCH, + AT91_SOC(SAME70Q19_CIDR_MATCH, AT91_CIDR_MATCH_MASK + AT91_CIDR_VERSION_MASK, SAME70Q19_EXID_MATCH, "same70q19", "same7"), - AT91_SOC(SAMS70Q21_CIDR_MATCH, SAMS70Q21_EXID_MATCH, + AT91_SOC(SAMS70Q21_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMS70Q21_EXID_MATCH, "sams70q21", "sams7"), - AT91_SOC(SAMS70Q20_CIDR_MATCH, SAMS70Q20_EXID_MATCH, + AT91_SOC(SAMS70Q20_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMS70Q20_EXID_MATCH, "sams70q20", "sams7"), - AT91_SOC(SAMS70Q19_CIDR_MATCH, SAMS70Q19_EXID_MATCH, + AT91_SOC(SAMS70Q19_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMS70Q19_EXID_MATCH, "sams70q19", "sams7"), - AT91_SOC(SAMV71Q21_CIDR_MATCH, SAMV71Q21_EXID_MATCH, + AT91_SOC(SAMV71Q21_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMV71Q21_EXID_MATCH, "samv71q21", "samv7"), - AT91_SOC(SAMV71Q20_CIDR_MATCH, SAMV71Q20_EXID_MATCH, + AT91_SOC(SAMV71Q20_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMV71Q20_EXID_MATCH, "samv71q20", "samv7"), - AT91_SOC(SAMV71Q19_CIDR_MATCH, SAMV71Q19_EXID_MATCH, + AT91_SOC(SAMV71Q19_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMV71Q19_EXID_MATCH, "samv71q19", "samv7"), - AT91_SOC(SAMV70Q20_CIDR_MATCH, SAMV70Q20_EXID_MATCH, + AT91_SOC(SAMV70Q20_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMV70Q20_EXID_MATCH, "samv70q20", "samv7"), - AT91_SOC(SAMV70Q19_CIDR_MATCH, SAMV70Q19_EXID_MATCH, + AT91_SOC(SAMV70Q19_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMV70Q19_EXID_MATCH, "samv70q19", "samv7"), #endif { /* sentinel */ }, @@ -191,8 +256,12 @@ static int __init at91_get_cidr_exid_from_chipid(u32 *cidr, u32 *exid) { struct device_node *np; void __iomem *regs; + static const struct of_device_id chipids[] = { + { .compatible = "atmel,sama5d2-chipid" }, + { }, + }; - np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-chipid"); + np = of_find_matching_node(NULL, chipids); if (!np) return -ENODEV; @@ -235,7 +304,7 @@ struct soc_device * __init at91_soc_init(const struct at91_soc *socs) } for (soc = socs; soc->name; soc++) { - if (soc->cidr_match != (cidr & AT91_CIDR_MATCH_MASK)) + if (soc->cidr_match != (cidr & soc->cidr_mask)) continue; if (!(cidr & AT91_CIDR_EXT) || soc->exid_match == exid) @@ -254,7 +323,7 @@ struct soc_device * __init at91_soc_init(const struct at91_soc *socs) soc_dev_attr->family = soc->family; soc_dev_attr->soc_id = soc->name; soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%X", - AT91_CIDR_VERSION(cidr)); + AT91_CIDR_VERSION(cidr, soc->version_mask)); soc_dev = soc_device_register(soc_dev_attr); if (IS_ERR(soc_dev)) { kfree(soc_dev_attr->revision); @@ -266,7 +335,7 @@ struct soc_device * __init at91_soc_init(const struct at91_soc *socs) if (soc->family) pr_info("Detected SoC family: %s\n", soc->family); pr_info("Detected SoC: %s, revision %X\n", soc->name, - AT91_CIDR_VERSION(cidr)); + AT91_CIDR_VERSION(cidr, soc->version_mask)); return soc_dev; } diff --git a/drivers/soc/atmel/soc.h b/drivers/soc/atmel/soc.h index 5849846a69d6..02198a4de22b 100644 --- a/drivers/soc/atmel/soc.h +++ b/drivers/soc/atmel/soc.h @@ -16,14 +16,19 @@ struct at91_soc { u32 cidr_match; + u32 cidr_mask; + u32 version_mask; u32 exid_match; const char *name; const char *family; }; -#define AT91_SOC(__cidr, __exid, __name, __family) \ +#define AT91_SOC(__cidr, __cidr_mask, __version_mask, __exid, \ + __name, __family) \ { \ .cidr_match = (__cidr), \ + .cidr_mask = (__cidr_mask), \ + .version_mask = (__version_mask), \ .exid_match = (__exid), \ .name = (__name), \ .family = (__family), \ -- cgit v1.2.3 From f12a29cb566699614266471342872193db1a1f52 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Fri, 22 Jan 2021 14:21:37 +0200 Subject: drivers: soc: atmel: add support for sama7g5 Add support for SAMA7G5 SoCs. Signed-off-by: Claudiu Beznea Signed-off-by: Nicolas Ferre Link: https://lore.kernel.org/r/1611318097-8970-8-git-send-email-claudiu.beznea@microchip.com --- drivers/soc/atmel/soc.c | 18 ++++++++++++++++++ drivers/soc/atmel/soc.h | 6 ++++++ 2 files changed, 24 insertions(+) (limited to 'drivers/soc') diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c index f9052f45cb3e..bc8e72fd431a 100644 --- a/drivers/soc/atmel/soc.c +++ b/drivers/soc/atmel/soc.c @@ -27,8 +27,10 @@ #define AT91_CHIPID_EXID 0x04 #define AT91_CIDR_VERSION(x, m) ((x) & (m)) #define AT91_CIDR_VERSION_MASK GENMASK(4, 0) +#define AT91_CIDR_VERSION_MASK_SAMA7G5 GENMASK(3, 0) #define AT91_CIDR_EXT BIT(31) #define AT91_CIDR_MATCH_MASK GENMASK(30, 5) +#define AT91_CIDR_MASK_SAMA7G5 GENMASK(27, 5) static const struct at91_soc socs[] __initconst = { #ifdef CONFIG_SOC_AT91RM9200 @@ -220,6 +222,20 @@ static const struct at91_soc socs[] __initconst = { AT91_SOC(SAMV70Q19_CIDR_MATCH, AT91_CIDR_MATCH_MASK, AT91_CIDR_VERSION_MASK, SAMV70Q19_EXID_MATCH, "samv70q19", "samv7"), +#endif +#ifdef CONFIG_SOC_SAMA7 + AT91_SOC(SAMA7G5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK_SAMA7G5, SAMA7G51_EXID_MATCH, + "sama7g51", "sama7g5"), + AT91_SOC(SAMA7G5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK_SAMA7G5, SAMA7G52_EXID_MATCH, + "sama7g52", "sama7g5"), + AT91_SOC(SAMA7G5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK_SAMA7G5, SAMA7G53_EXID_MATCH, + "sama7g53", "sama7g5"), + AT91_SOC(SAMA7G5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK_SAMA7G5, SAMA7G54_EXID_MATCH, + "sama7g54", "sama7g5"), #endif { /* sentinel */ }, }; @@ -258,6 +274,7 @@ static int __init at91_get_cidr_exid_from_chipid(u32 *cidr, u32 *exid) void __iomem *regs; static const struct of_device_id chipids[] = { { .compatible = "atmel,sama5d2-chipid" }, + { .compatible = "microchip,sama7g5-chipid" }, { }, }; @@ -345,6 +362,7 @@ static const struct of_device_id at91_soc_allowed_list[] __initconst = { { .compatible = "atmel,at91sam9", }, { .compatible = "atmel,sama5", }, { .compatible = "atmel,samv7", }, + { .compatible = "microchip,sama7g5", }, { } }; diff --git a/drivers/soc/atmel/soc.h b/drivers/soc/atmel/soc.h index 02198a4de22b..93c212533ff0 100644 --- a/drivers/soc/atmel/soc.h +++ b/drivers/soc/atmel/soc.h @@ -48,6 +48,7 @@ at91_soc_init(const struct at91_soc *socs); #define AT91SAM9X5_CIDR_MATCH 0x019a05a0 #define AT91SAM9N12_CIDR_MATCH 0x019a07a0 #define SAM9X60_CIDR_MATCH 0x019b35a0 +#define SAMA7G5_CIDR_MATCH 0x00162100 #define AT91SAM9M11_EXID_MATCH 0x00000001 #define AT91SAM9M10_EXID_MATCH 0x00000002 @@ -69,6 +70,11 @@ at91_soc_init(const struct at91_soc *socs); #define SAM9X60_D1G_EXID_MATCH 0x00000010 #define SAM9X60_D6K_EXID_MATCH 0x00000011 +#define SAMA7G51_EXID_MATCH 0x3 +#define SAMA7G52_EXID_MATCH 0x2 +#define SAMA7G53_EXID_MATCH 0x1 +#define SAMA7G54_EXID_MATCH 0x0 + #define AT91SAM9XE128_CIDR_MATCH 0x329973a0 #define AT91SAM9XE256_CIDR_MATCH 0x329a93a0 #define AT91SAM9XE512_CIDR_MATCH 0x329aa3a0 -- cgit v1.2.3 From cd9168b4377932a6494d464db1ddd3f63e41fce3 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Tue, 26 Jan 2021 11:29:30 +0200 Subject: drivers: soc: atmel: add spdx license identifier Add SPDX-License-Identifier. Signed-off-by: Claudiu Beznea [nicolas.ferre@microhcip.com: remove license boilerplate now it's useless] Signed-off-by: Nicolas Ferre Link: https://lore.kernel.org/r/1611653376-24168-2-git-send-email-claudiu.beznea@microchip.com --- drivers/soc/atmel/soc.c | 6 +----- drivers/soc/atmel/soc.h | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c index bc8e72fd431a..a2967846809f 100644 --- a/drivers/soc/atmel/soc.c +++ b/drivers/soc/atmel/soc.c @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2015 Atmel * * Alexandre Belloni Date: Wed, 27 Jan 2021 18:00:50 +0530 Subject: soc: qcom: aoss: Add SM8350 compatible Add SM8350 compatible to the qcom_aoss binding and driver. Acked-by: Rob Herring Signed-off-by: Vinod Koul Link: https://lore.kernel.org/r/20210127123054.263231-3-vkoul@kernel.org Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.txt | 1 + drivers/soc/qcom/qcom_aoss.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers/soc') diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.txt index 953add19e937..19c059e44681 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.txt +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.txt @@ -20,6 +20,7 @@ power-domains. "qcom,sdm845-aoss-qmp" "qcom,sm8150-aoss-qmp" "qcom,sm8250-aoss-qmp" + "qcom,sm8350-aoss-qmp" - reg: Usage: required diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c index b5840d624bc6..53acb9423bd6 100644 --- a/drivers/soc/qcom/qcom_aoss.c +++ b/drivers/soc/qcom/qcom_aoss.c @@ -600,6 +600,7 @@ static const struct of_device_id qmp_dt_match[] = { { .compatible = "qcom,sdm845-aoss-qmp", }, { .compatible = "qcom,sm8150-aoss-qmp", }, { .compatible = "qcom,sm8250-aoss-qmp", }, + { .compatible = "qcom,sm8350-aoss-qmp", }, {} }; MODULE_DEVICE_TABLE(of, qmp_dt_match); -- cgit v1.2.3 From 8b8f095b9076ca61107c0910c9273afd1dfa1f04 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 20 Jan 2021 11:34:07 -0800 Subject: soc: bcm: brcmstb: Remove soc_is_brcmstb() We have no in tree or out of tree users of this function, remove it and the header providing its prototype. Signed-off-by: Florian Fainelli --- drivers/soc/bcm/brcmstb/common.c | 17 ----------------- include/soc/brcmstb/common.h | 12 ------------ 2 files changed, 29 deletions(-) delete mode 100644 include/soc/brcmstb/common.h (limited to 'drivers/soc') diff --git a/drivers/soc/bcm/brcmstb/common.c b/drivers/soc/bcm/brcmstb/common.c index d33a383701dd..e87dfc6660f3 100644 --- a/drivers/soc/bcm/brcmstb/common.c +++ b/drivers/soc/bcm/brcmstb/common.c @@ -11,8 +11,6 @@ #include #include -#include - static u32 family_id; static u32 product_id; @@ -21,21 +19,6 @@ static const struct of_device_id brcmstb_machine_match[] = { { } }; -bool soc_is_brcmstb(void) -{ - const struct of_device_id *match; - struct device_node *root; - - root = of_find_node_by_path("/"); - if (!root) - return false; - - match = of_match_node(brcmstb_machine_match, root); - of_node_put(root); - - return match != NULL; -} - u32 brcmstb_get_family_id(void) { return family_id; diff --git a/include/soc/brcmstb/common.h b/include/soc/brcmstb/common.h deleted file mode 100644 index e4fe76856de9..000000000000 --- a/include/soc/brcmstb/common.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright © 2014 NVIDIA Corporation - * Copyright © 2015 Broadcom Corporation - */ - -#ifndef __SOC_BRCMSTB_COMMON_H__ -#define __SOC_BRCMSTB_COMMON_H__ - -bool soc_is_brcmstb(void); - -#endif /* __SOC_BRCMSTB_COMMON_H__ */ -- cgit v1.2.3 From aec8535edccb943adc067d184af1a3370f5b9568 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Mon, 18 Jan 2021 18:22:36 +0300 Subject: soc: qcom: socinfo: Remove unwanted le32_to_cpu() Remove extra le32_to_cpu() conversion, data is already converted from le32 to cpu endianness. This fixes two following warnings: drivers/soc/qcom/socinfo.c:322:36: sparse: sparse: cast to restricted __le32 drivers/soc/qcom/socinfo.c:323:36: sparse: sparse: cast to restricted __le32 Signed-off-by: Dmitry Baryshkov Fixes: 734c78e7febf ("soc: qcom: socinfo: add info from PMIC models array") Link: https://lore.kernel.org/r/20210118152236.514776-1-dmitry.baryshkov@linaro.org Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/socinfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index 5b4ad24a022b..f6cfb79338f0 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -334,8 +334,8 @@ static int qcom_show_pmic_model_array(struct seq_file *seq, void *p) if (model < ARRAY_SIZE(pmic_models) && pmic_models[model]) seq_printf(seq, "%s %u.%u\n", pmic_models[model], - SOCINFO_MAJOR(le32_to_cpu(die_rev)), - SOCINFO_MINOR(le32_to_cpu(die_rev))); + SOCINFO_MAJOR(die_rev), + SOCINFO_MINOR(die_rev)); else seq_printf(seq, "unknown (%d)\n", model); } -- cgit v1.2.3 From 9117d0c975b8e1596320c9f21f8ba9b9ecc79cbd Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 27 Jan 2021 17:24:48 +0000 Subject: soc: sunxi: sram: Add support for more than one EMAC clock The Allwinner H616 adds a second EMAC clock register at offset 0x34, for controlling the second EMAC in this chip. Allow to extend the regmap in this case, to cover more than the current 4 bytes exported. Signed-off-by: Andre Przywara Signed-off-by: Maxime Ripard Link: https://lore.kernel.org/r/20210127172500.13356-9-andre.przywara@arm.com --- drivers/soc/sunxi/sunxi_sram.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c index d4c7bd59429e..42833e33a96c 100644 --- a/drivers/soc/sunxi/sunxi_sram.c +++ b/drivers/soc/sunxi/sunxi_sram.c @@ -283,7 +283,7 @@ int sunxi_sram_release(struct device *dev) EXPORT_SYMBOL(sunxi_sram_release); struct sunxi_sramc_variant { - bool has_emac_clock; + int num_emac_clocks; }; static const struct sunxi_sramc_variant sun4i_a10_sramc_variant = { @@ -291,20 +291,31 @@ static const struct sunxi_sramc_variant sun4i_a10_sramc_variant = { }; static const struct sunxi_sramc_variant sun8i_h3_sramc_variant = { - .has_emac_clock = true, + .num_emac_clocks = 1, }; static const struct sunxi_sramc_variant sun50i_a64_sramc_variant = { - .has_emac_clock = true, + .num_emac_clocks = 1, +}; + +static const struct sunxi_sramc_variant sun50i_h616_sramc_variant = { + .num_emac_clocks = 2, }; #define SUNXI_SRAM_EMAC_CLOCK_REG 0x30 static bool sunxi_sram_regmap_accessible_reg(struct device *dev, unsigned int reg) { - if (reg == SUNXI_SRAM_EMAC_CLOCK_REG) - return true; - return false; + const struct sunxi_sramc_variant *variant; + + variant = of_device_get_match_data(dev); + + if (reg < SUNXI_SRAM_EMAC_CLOCK_REG) + return false; + if (reg > SUNXI_SRAM_EMAC_CLOCK_REG + variant->num_emac_clocks * 4) + return false; + + return true; } static struct regmap_config sunxi_sram_emac_clock_regmap = { @@ -312,7 +323,7 @@ static struct regmap_config sunxi_sram_emac_clock_regmap = { .val_bits = 32, .reg_stride = 4, /* last defined register */ - .max_register = SUNXI_SRAM_EMAC_CLOCK_REG, + .max_register = SUNXI_SRAM_EMAC_CLOCK_REG + 4, /* other devices have no business accessing other registers */ .readable_reg = sunxi_sram_regmap_accessible_reg, .writeable_reg = sunxi_sram_regmap_accessible_reg, @@ -343,7 +354,7 @@ static int sunxi_sram_probe(struct platform_device *pdev) if (!d) return -ENOMEM; - if (variant->has_emac_clock) { + if (variant->num_emac_clocks > 0) { emac_clock = devm_regmap_init_mmio(&pdev->dev, base, &sunxi_sram_emac_clock_regmap); @@ -387,6 +398,10 @@ static const struct of_device_id sunxi_sram_dt_match[] = { .compatible = "allwinner,sun50i-h5-system-control", .data = &sun50i_a64_sramc_variant, }, + { + .compatible = "allwinner,sun50i-h616-system-control", + .data = &sun50i_h616_sramc_variant, + }, { }, }; MODULE_DEVICE_TABLE(of, sunxi_sram_dt_match); -- cgit v1.2.3 From 207f13b419a60c56fb75baeb3d668de080514354 Mon Sep 17 00:00:00 2001 From: Fabien Parent Date: Wed, 9 Dec 2020 14:32:37 +0100 Subject: soc: mediatek: pm-domains: Add support for mt8167 Add the needed board data to support mt8167 SoC. Signed-off-by: Fabien Parent Reviewed-by: Enric Balletbo i Serra Link: https://lore.kernel.org/r/20201209133238.384030-2-fparent@baylibre.com Signed-off-by: Matthias Brugger --- drivers/soc/mediatek/mt8167-pm-domains.h | 86 ++++++++++++++++++++++++++++++++ drivers/soc/mediatek/mtk-pm-domains.c | 5 ++ drivers/soc/mediatek/mtk-pm-domains.h | 1 + include/linux/soc/mediatek/infracfg.h | 8 +++ 4 files changed, 100 insertions(+) create mode 100644 drivers/soc/mediatek/mt8167-pm-domains.h (limited to 'drivers/soc') diff --git a/drivers/soc/mediatek/mt8167-pm-domains.h b/drivers/soc/mediatek/mt8167-pm-domains.h new file mode 100644 index 000000000000..ad0b8dfa0527 --- /dev/null +++ b/drivers/soc/mediatek/mt8167-pm-domains.h @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_MEDIATEK_MT8167_PM_DOMAINS_H +#define __SOC_MEDIATEK_MT8167_PM_DOMAINS_H + +#include "mtk-pm-domains.h" +#include + +#define MT8167_PWR_STATUS_MFG_2D BIT(24) +#define MT8167_PWR_STATUS_MFG_ASYNC BIT(25) + +/* + * MT8167 power domain support + */ + +static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = { + [MT8167_POWER_DOMAIN_MM] = { + .sta_mask = PWR_STATUS_DISP, + .ctl_offs = SPM_DIS_PWR_CON, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(12, 12), + .bp_infracfg = { + BUS_PROT_UPDATE_TOPAXI(MT8167_TOP_AXI_PROT_EN_MM_EMI | + MT8167_TOP_AXI_PROT_EN_MCU_MM), + }, + .caps = MTK_SCPD_ACTIVE_WAKEUP, + }, + [MT8167_POWER_DOMAIN_VDEC] = { + .sta_mask = PWR_STATUS_VDEC, + .ctl_offs = SPM_VDE_PWR_CON, + .sram_pdn_bits = GENMASK(8, 8), + .sram_pdn_ack_bits = GENMASK(12, 12), + .caps = MTK_SCPD_ACTIVE_WAKEUP, + }, + [MT8167_POWER_DOMAIN_ISP] = { + .sta_mask = PWR_STATUS_ISP, + .ctl_offs = SPM_ISP_PWR_CON, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(13, 12), + .caps = MTK_SCPD_ACTIVE_WAKEUP, + }, + [MT8167_POWER_DOMAIN_MFG_ASYNC] = { + .sta_mask = MT8167_PWR_STATUS_MFG_ASYNC, + .ctl_offs = SPM_MFG_ASYNC_PWR_CON, + .sram_pdn_bits = 0, + .sram_pdn_ack_bits = 0, + .bp_infracfg = { + BUS_PROT_UPDATE_TOPAXI(MT8167_TOP_AXI_PROT_EN_MCU_MFG | + MT8167_TOP_AXI_PROT_EN_MFG_EMI), + }, + }, + [MT8167_POWER_DOMAIN_MFG_2D] = { + .sta_mask = MT8167_PWR_STATUS_MFG_2D, + .ctl_offs = SPM_MFG_2D_PWR_CON, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(15, 12), + }, + [MT8167_POWER_DOMAIN_MFG] = { + .sta_mask = PWR_STATUS_MFG, + .ctl_offs = SPM_MFG_PWR_CON, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(15, 12), + }, + [MT8167_POWER_DOMAIN_CONN] = { + .sta_mask = PWR_STATUS_CONN, + .ctl_offs = SPM_CONN_PWR_CON, + .sram_pdn_bits = GENMASK(8, 8), + .sram_pdn_ack_bits = 0, + .caps = MTK_SCPD_ACTIVE_WAKEUP, + .bp_infracfg = { + BUS_PROT_UPDATE_TOPAXI(MT8167_TOP_AXI_PROT_EN_CONN_EMI | + MT8167_TOP_AXI_PROT_EN_CONN_MCU | + MT8167_TOP_AXI_PROT_EN_MCU_CONN), + }, + }, +}; + +static const struct scpsys_soc_data mt8167_scpsys_data = { + .domains_data = scpsys_domain_data_mt8167, + .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8167), + .pwr_sta_offs = SPM_PWR_STATUS, + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, +}; + +#endif /* __SOC_MEDIATEK_MT8167_PM_DOMAINS_H */ + diff --git a/drivers/soc/mediatek/mtk-pm-domains.c b/drivers/soc/mediatek/mtk-pm-domains.c index fb70cb3b07b3..2d0d50ff35f0 100644 --- a/drivers/soc/mediatek/mtk-pm-domains.c +++ b/drivers/soc/mediatek/mtk-pm-domains.c @@ -15,6 +15,7 @@ #include #include +#include "mt8167-pm-domains.h" #include "mt8173-pm-domains.h" #include "mt8183-pm-domains.h" #include "mt8192-pm-domains.h" @@ -514,6 +515,10 @@ static void scpsys_domain_cleanup(struct scpsys *scpsys) } static const struct of_device_id scpsys_of_match[] = { + { + .compatible = "mediatek,mt8167-power-controller", + .data = &mt8167_scpsys_data, + }, { .compatible = "mediatek,mt8173-power-controller", .data = &mt8173_scpsys_data, diff --git a/drivers/soc/mediatek/mtk-pm-domains.h b/drivers/soc/mediatek/mtk-pm-domains.h index a2f4d8f97e05..88f5835e1648 100644 --- a/drivers/soc/mediatek/mtk-pm-domains.h +++ b/drivers/soc/mediatek/mtk-pm-domains.h @@ -14,6 +14,7 @@ #define SPM_VEN_PWR_CON 0x0230 #define SPM_ISP_PWR_CON 0x0238 #define SPM_DIS_PWR_CON 0x023c +#define SPM_CONN_PWR_CON 0x0280 #define SPM_VEN2_PWR_CON 0x0298 #define SPM_AUDIO_PWR_CON 0x029c #define SPM_MFG_2D_PWR_CON 0x02c0 diff --git a/include/linux/soc/mediatek/infracfg.h b/include/linux/soc/mediatek/infracfg.h index e7842debc05d..4615a228da51 100644 --- a/include/linux/soc/mediatek/infracfg.h +++ b/include/linux/soc/mediatek/infracfg.h @@ -123,6 +123,14 @@ #define MT8173_TOP_AXI_PROT_EN_MFG_M1 BIT(22) #define MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT BIT(23) +#define MT8167_TOP_AXI_PROT_EN_MM_EMI BIT(1) +#define MT8167_TOP_AXI_PROT_EN_MCU_MFG BIT(2) +#define MT8167_TOP_AXI_PROT_EN_CONN_EMI BIT(4) +#define MT8167_TOP_AXI_PROT_EN_MFG_EMI BIT(5) +#define MT8167_TOP_AXI_PROT_EN_CONN_MCU BIT(8) +#define MT8167_TOP_AXI_PROT_EN_MCU_CONN BIT(9) +#define MT8167_TOP_AXI_PROT_EN_MCU_MM BIT(11) + #define MT2701_TOP_AXI_PROT_EN_MM_M0 BIT(1) #define MT2701_TOP_AXI_PROT_EN_CONN_M BIT(2) #define MT2701_TOP_AXI_PROT_EN_CONN_S BIT(8) -- cgit v1.2.3 From 1570db1da9f57dfbe5dfa3010233c98947497466 Mon Sep 17 00:00:00 2001 From: Chun-Kuang Hu Date: Thu, 3 Dec 2020 07:58:55 +0800 Subject: soc: mediatek: cmdq: Remove cmdq_pkt_flush() rx_callback is a standard mailbox callback mechanism and could cover the function of proprietary cmdq_task_cb, so it is better to use the standard one instead of the proprietary one. But register rx_callback should before mbox_request_channel(), so remove cmdq_pkt_flush() and let client driver implement its own synchronous flush. Signed-off-by: Chun-Kuang Hu Link: https://lore.kernel.org/r/20201202235856.7652-1-chunkuang.hu@kernel.org Signed-off-by: Matthias Brugger --- drivers/soc/mediatek/mtk-cmdq-helper.c | 32 -------------------------------- include/linux/soc/mediatek/mtk-cmdq.h | 12 ------------ 2 files changed, 44 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c index 280d3bd9f675..3c8e4212d941 100644 --- a/drivers/soc/mediatek/mtk-cmdq-helper.c +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c @@ -463,36 +463,4 @@ int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, cmdq_async_flush_cb cb, } EXPORT_SYMBOL(cmdq_pkt_flush_async); -struct cmdq_flush_completion { - struct completion cmplt; - bool err; -}; - -static void cmdq_pkt_flush_cb(struct cmdq_cb_data data) -{ - struct cmdq_flush_completion *cmplt; - - cmplt = (struct cmdq_flush_completion *)data.data; - if (data.sta != CMDQ_CB_NORMAL) - cmplt->err = true; - else - cmplt->err = false; - complete(&cmplt->cmplt); -} - -int cmdq_pkt_flush(struct cmdq_pkt *pkt) -{ - struct cmdq_flush_completion cmplt; - int err; - - init_completion(&cmplt.cmplt); - err = cmdq_pkt_flush_async(pkt, cmdq_pkt_flush_cb, &cmplt); - if (err < 0) - return err; - wait_for_completion(&cmplt.cmplt); - - return cmplt.err ? -EFAULT : 0; -} -EXPORT_SYMBOL(cmdq_pkt_flush); - MODULE_LICENSE("GPL v2"); diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h index 8e9996610978..ac6b5f3cba95 100644 --- a/include/linux/soc/mediatek/mtk-cmdq.h +++ b/include/linux/soc/mediatek/mtk-cmdq.h @@ -280,16 +280,4 @@ int cmdq_pkt_finalize(struct cmdq_pkt *pkt); int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, cmdq_async_flush_cb cb, void *data); -/** - * cmdq_pkt_flush() - trigger CMDQ to execute the CMDQ packet - * @pkt: the CMDQ packet - * - * Return: 0 for success; else the error code is returned - * - * Trigger CMDQ to execute the CMDQ packet. Note that this is a - * synchronous flush function. When the function returned, the recorded - * commands have been done. - */ -int cmdq_pkt_flush(struct cmdq_pkt *pkt); - #endif /* __MTK_CMDQ_H__ */ -- cgit v1.2.3 From 1b18c0558d092b29b0d9ccdf14a6915156e6cf32 Mon Sep 17 00:00:00 2001 From: Hsin-Yi Wang Date: Fri, 29 Jan 2021 18:12:07 +0800 Subject: soc: mediatek: pm-domains: Add domain regulator supply Some power domains (eg. mfg) needs to turn on power supply before power on. Signed-off-by: Hsin-Yi Wang Reviewed-by: Nicolas Boichat Reviewed-by: Enric Balletbo i Serra Link: https://lore.kernel.org/r/20210129101208.2625249-3-hsinyi@chromium.org Signed-off-by: Matthias Brugger --- drivers/soc/mediatek/mt8183-pm-domains.h | 1 + drivers/soc/mediatek/mtk-pm-domains.c | 42 +++++++++++++++++++++++++++++++- drivers/soc/mediatek/mtk-pm-domains.h | 1 + 3 files changed, 43 insertions(+), 1 deletion(-) (limited to 'drivers/soc') diff --git a/drivers/soc/mediatek/mt8183-pm-domains.h b/drivers/soc/mediatek/mt8183-pm-domains.h index 8d996c5d2682..aa5230e6c12f 100644 --- a/drivers/soc/mediatek/mt8183-pm-domains.h +++ b/drivers/soc/mediatek/mt8183-pm-domains.h @@ -38,6 +38,7 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { .ctl_offs = 0x0338, .sram_pdn_bits = GENMASK(8, 8), .sram_pdn_ack_bits = GENMASK(12, 12), + .caps = MTK_SCPD_DOMAIN_SUPPLY, }, [MT8183_POWER_DOMAIN_MFG_CORE0] = { .sta_mask = BIT(7), diff --git a/drivers/soc/mediatek/mtk-pm-domains.c b/drivers/soc/mediatek/mtk-pm-domains.c index 2d0d50ff35f0..905ac8a0341a 100644 --- a/drivers/soc/mediatek/mtk-pm-domains.c +++ b/drivers/soc/mediatek/mtk-pm-domains.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "mt8167-pm-domains.h" @@ -41,6 +42,7 @@ struct scpsys_domain { struct clk_bulk_data *subsys_clks; struct regmap *infracfg; struct regmap *smi; + struct regulator *supply; }; struct scpsys { @@ -188,6 +190,16 @@ static int scpsys_bus_protect_disable(struct scpsys_domain *pd) return _scpsys_bus_protect_disable(pd->data->bp_infracfg, pd->infracfg); } +static int scpsys_regulator_enable(struct regulator *supply) +{ + return supply ? regulator_enable(supply) : 0; +} + +static int scpsys_regulator_disable(struct regulator *supply) +{ + return supply ? regulator_disable(supply) : 0; +} + static int scpsys_power_on(struct generic_pm_domain *genpd) { struct scpsys_domain *pd = container_of(genpd, struct scpsys_domain, genpd); @@ -195,10 +207,14 @@ static int scpsys_power_on(struct generic_pm_domain *genpd) bool tmp; int ret; - ret = clk_bulk_enable(pd->num_clks, pd->clks); + ret = scpsys_regulator_enable(pd->supply); if (ret) return ret; + ret = clk_bulk_enable(pd->num_clks, pd->clks); + if (ret) + goto err_reg; + /* subsys power on */ regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT); regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_2ND_BIT); @@ -233,6 +249,8 @@ err_disable_subsys_clks: clk_bulk_disable(pd->num_subsys_clks, pd->subsys_clks); err_pwr_ack: clk_bulk_disable(pd->num_clks, pd->clks); +err_reg: + scpsys_regulator_disable(pd->supply); return ret; } @@ -268,6 +286,8 @@ static int scpsys_power_off(struct generic_pm_domain *genpd) clk_bulk_disable(pd->num_clks, pd->clks); + scpsys_regulator_disable(pd->supply); + return 0; } @@ -276,6 +296,7 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no { const struct scpsys_domain_data *domain_data; struct scpsys_domain *pd; + struct device_node *root_node = scpsys->dev->of_node; struct property *prop; const char *clk_name; int i, ret, num_clks; @@ -308,6 +329,25 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no pd->data = domain_data; pd->scpsys = scpsys; + if (MTK_SCPD_CAPS(pd, MTK_SCPD_DOMAIN_SUPPLY)) { + /* + * Find regulator in current power domain node. + * devm_regulator_get() finds regulator in a node and its child + * node, so set of_node to current power domain node then change + * back to original node after regulator is found for current + * power domain node. + */ + scpsys->dev->of_node = node; + pd->supply = devm_regulator_get(scpsys->dev, "domain"); + scpsys->dev->of_node = root_node; + if (IS_ERR(pd->supply)) { + dev_err_probe(scpsys->dev, PTR_ERR(pd->supply), + "%pOF: failed to get power supply.\n", + node); + return ERR_CAST(pd->supply); + } + } + pd->infracfg = syscon_regmap_lookup_by_phandle_optional(node, "mediatek,infracfg"); if (IS_ERR(pd->infracfg)) return ERR_CAST(pd->infracfg); diff --git a/drivers/soc/mediatek/mtk-pm-domains.h b/drivers/soc/mediatek/mtk-pm-domains.h index 88f5835e1648..141dc76054e6 100644 --- a/drivers/soc/mediatek/mtk-pm-domains.h +++ b/drivers/soc/mediatek/mtk-pm-domains.h @@ -7,6 +7,7 @@ #define MTK_SCPD_FWAIT_SRAM BIT(1) #define MTK_SCPD_SRAM_ISO BIT(2) #define MTK_SCPD_KEEP_DEFAULT_OFF BIT(3) +#define MTK_SCPD_DOMAIN_SUPPLY BIT(4) #define MTK_SCPD_CAPS(_scpd, _x) ((_scpd)->data->caps & (_x)) #define SPM_VDE_PWR_CON 0x0210 -- cgit v1.2.3 From dd65030295e20338bbb8238454c2e9546b6e5e17 Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Wed, 13 Jan 2021 22:30:12 +0100 Subject: soc: mediatek: pm-domains: Don't print an error if child domain is deferred Child domains can be deferred by the core because one of its resources is not available yet, in such case, it will print an error, but later it will succeed to probe. Fix that using the dev_err_probe() function so it only prints an error on a real error. Signed-off-by: Enric Balletbo i Serra Reviewed-by: Hsin-Yi Wang Link: https://lore.kernel.org/r/20210113213012.67643-1-enric.balletbo@collabora.com Signed-off-by: Matthias Brugger --- drivers/soc/mediatek/mtk-pm-domains.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/mediatek/mtk-pm-domains.c b/drivers/soc/mediatek/mtk-pm-domains.c index 905ac8a0341a..b7f697666bdd 100644 --- a/drivers/soc/mediatek/mtk-pm-domains.c +++ b/drivers/soc/mediatek/mtk-pm-domains.c @@ -487,8 +487,8 @@ static int scpsys_add_subdomain(struct scpsys *scpsys, struct device_node *paren child_pd = scpsys_add_one_domain(scpsys, child); if (IS_ERR(child_pd)) { - ret = PTR_ERR(child_pd); - dev_err(scpsys->dev, "%pOF: failed to get child domain id\n", child); + dev_err_probe(scpsys->dev, PTR_ERR(child_pd), + "%pOF: failed to get child domain id\n", child); goto err_put_node; } -- cgit v1.2.3 From ea797f699440d85489dc839b28845434e350c917 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Sun, 31 Jan 2021 20:53:43 -0800 Subject: soc: ti: pruss: Refactor the CFG sub-module init The CFG sub-module is not present on some earlier SoCs like the DA850/OMAPL-138 in the TI Davinci family. Refactor out the CFG sub-module parse and initialization logic into a separate function to make it easier to add logic for the PRUSS IP on the above legacy SoC families. Signed-off-by: Suman Anna Signed-off-by: Santosh Shilimkar --- drivers/soc/ti/pruss.c | 91 +++++++++++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 41 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c index 1d6890134312..f22ac1edbdd0 100644 --- a/drivers/soc/ti/pruss.c +++ b/drivers/soc/ti/pruss.c @@ -161,6 +161,53 @@ static struct regmap_config regmap_conf = { .reg_stride = 4, }; +static int pruss_cfg_of_init(struct device *dev, struct pruss *pruss) +{ + struct device_node *np = dev_of_node(dev); + struct device_node *child; + struct resource res; + int ret; + + child = of_get_child_by_name(np, "cfg"); + if (!child) { + dev_err(dev, "%pOF is missing its 'cfg' node\n", child); + return -ENODEV; + } + + if (of_address_to_resource(child, 0, &res)) { + ret = -ENOMEM; + goto node_put; + } + + pruss->cfg_base = devm_ioremap(dev, res.start, resource_size(&res)); + if (!pruss->cfg_base) { + ret = -ENOMEM; + goto node_put; + } + + regmap_conf.name = kasprintf(GFP_KERNEL, "%pOFn@%llx", child, + (u64)res.start); + regmap_conf.max_register = resource_size(&res) - 4; + + pruss->cfg_regmap = devm_regmap_init_mmio(dev, pruss->cfg_base, + ®map_conf); + kfree(regmap_conf.name); + if (IS_ERR(pruss->cfg_regmap)) { + dev_err(dev, "regmap_init_mmio failed for cfg, ret = %ld\n", + PTR_ERR(pruss->cfg_regmap)); + ret = PTR_ERR(pruss->cfg_regmap); + goto node_put; + } + + ret = pruss_clk_init(pruss, child); + if (ret) + dev_err(dev, "pruss_clk_init failed, ret = %d\n", ret); + +node_put: + of_node_put(child); + return ret; +} + static int pruss_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -239,56 +286,18 @@ static int pruss_probe(struct platform_device *pdev) goto rpm_disable; } - child = of_get_child_by_name(np, "cfg"); - if (!child) { - dev_err(dev, "%pOF is missing its 'cfg' node\n", child); - ret = -ENODEV; + ret = pruss_cfg_of_init(dev, pruss); + if (ret < 0) goto rpm_put; - } - - if (of_address_to_resource(child, 0, &res)) { - ret = -ENOMEM; - goto node_put; - } - - pruss->cfg_base = devm_ioremap(dev, res.start, resource_size(&res)); - if (!pruss->cfg_base) { - ret = -ENOMEM; - goto node_put; - } - - regmap_conf.name = kasprintf(GFP_KERNEL, "%pOFn@%llx", child, - (u64)res.start); - regmap_conf.max_register = resource_size(&res) - 4; - - pruss->cfg_regmap = devm_regmap_init_mmio(dev, pruss->cfg_base, - ®map_conf); - kfree(regmap_conf.name); - if (IS_ERR(pruss->cfg_regmap)) { - dev_err(dev, "regmap_init_mmio failed for cfg, ret = %ld\n", - PTR_ERR(pruss->cfg_regmap)); - ret = PTR_ERR(pruss->cfg_regmap); - goto node_put; - } - - ret = pruss_clk_init(pruss, child); - if (ret) { - dev_err(dev, "pruss_clk_init failed, ret = %d\n", ret); - goto node_put; - } ret = devm_of_platform_populate(dev); if (ret) { dev_err(dev, "failed to register child devices\n"); - goto node_put; + goto rpm_put; } - of_node_put(child); - return 0; -node_put: - of_node_put(child); rpm_put: pm_runtime_put_sync(dev); rpm_disable: -- cgit v1.2.3 From a8fc8e5b8e42c4401d009143a5fd822ef3d0c9df Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Sun, 31 Jan 2021 20:58:49 -0800 Subject: soc: ti: k3-ringacc: Use of_device_get_match_data() Simplify the retrieval of getting the match data in the probe function by directly using of_device_get_match_data() instead of using of_match_node() and getting data. Signed-off-by: Suman Anna Signed-off-by: Santosh Shilimkar --- drivers/soc/ti/k3-ringacc.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/ti/k3-ringacc.c b/drivers/soc/ti/k3-ringacc.c index b495b0d5d0fa..312ba0f98ad7 100644 --- a/drivers/soc/ti/k3-ringacc.c +++ b/drivers/soc/ti/k3-ringacc.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -1517,15 +1518,13 @@ EXPORT_SYMBOL_GPL(k3_ringacc_dmarings_init); static int k3_ringacc_probe(struct platform_device *pdev) { const struct ringacc_match_data *match_data; - const struct of_device_id *match; struct device *dev = &pdev->dev; struct k3_ringacc *ringacc; int ret; - match = of_match_node(k3_ringacc_of_match, dev->of_node); - if (!match) + match_data = of_device_get_match_data(&pdev->dev); + if (!match_data) return -ENODEV; - match_data = match->data; ringacc = devm_kzalloc(dev, sizeof(*ringacc), GFP_KERNEL); if (!ringacc) -- cgit v1.2.3 From 01f937ffc4686837d6c43dea80c6ade6cbd2940a Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Sat, 30 Jan 2021 15:23:49 +0100 Subject: soc: qcom: ocmem: don't return NULL in of_get_ocmem If ocmem probe fails for whatever reason, of_get_ocmem returned NULL. Without this, users must check for both NULL and IS_ERR on the returned pointer - which didn't happen in drivers/gpu/drm/msm/adreno/adreno_gpu.c leading to a NULL pointer dereference. Reviewed-by: Brian Masney Fixes: 88c1e9404f1d ("soc: qcom: add OCMEM driver") Signed-off-by: Luca Weiss Link: https://lore.kernel.org/r/20210130142349.53335-1-luca@z3ntu.xyz Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/ocmem.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/soc') diff --git a/drivers/soc/qcom/ocmem.c b/drivers/soc/qcom/ocmem.c index 7f9e9944d1ea..f1875dc31ae2 100644 --- a/drivers/soc/qcom/ocmem.c +++ b/drivers/soc/qcom/ocmem.c @@ -189,6 +189,7 @@ struct ocmem *of_get_ocmem(struct device *dev) { struct platform_device *pdev; struct device_node *devnode; + struct ocmem *ocmem; devnode = of_parse_phandle(dev->of_node, "sram", 0); if (!devnode || !devnode->parent) { @@ -202,7 +203,12 @@ struct ocmem *of_get_ocmem(struct device *dev) return ERR_PTR(-EPROBE_DEFER); } - return platform_get_drvdata(pdev); + ocmem = platform_get_drvdata(pdev); + if (!ocmem) { + dev_err(dev, "Cannot get ocmem\n"); + return ERR_PTR(-ENODEV); + } + return ocmem; } EXPORT_SYMBOL(of_get_ocmem); -- cgit v1.2.3 From 7deff441f53cc148cbf18381bd252a754b0d7d4e Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 4 Feb 2021 16:49:25 +0100 Subject: drivers: soc: atmel: fix type for same7 A missing comma caused a build failure: drivers/soc/atmel/soc.c:196:24: error: too few arguments provided to function-like macro invocation Fixes: af3a10513cd6 ("drivers: soc: atmel: add per soc id and version match masks") Signed-off-by: Arnd Bergmann Acked-by: Alexandre Belloni Signed-off-by: Arnd Bergmann --- drivers/soc/atmel/soc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/soc') diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c index a2967846809f..a490ad7e090f 100644 --- a/drivers/soc/atmel/soc.c +++ b/drivers/soc/atmel/soc.c @@ -191,7 +191,7 @@ static const struct at91_soc socs[] __initconst = { AT91_SOC(SAME70Q20_CIDR_MATCH, AT91_CIDR_MATCH_MASK, AT91_CIDR_VERSION_MASK, SAME70Q20_EXID_MATCH, "same70q20", "same7"), - AT91_SOC(SAME70Q19_CIDR_MATCH, AT91_CIDR_MATCH_MASK + AT91_SOC(SAME70Q19_CIDR_MATCH, AT91_CIDR_MATCH_MASK, AT91_CIDR_VERSION_MASK, SAME70Q19_EXID_MATCH, "same70q19", "same7"), AT91_SOC(SAMS70Q21_CIDR_MATCH, AT91_CIDR_MATCH_MASK, -- cgit v1.2.3 From 3f94cf15583be554df7aaa651b8ff8e1b68fbe51 Mon Sep 17 00:00:00 2001 From: Jae Hyun Yoo Date: Tue, 8 Dec 2020 17:17:47 +0800 Subject: soc: aspeed: snoop: Add clock control logic If LPC SNOOP driver is registered ahead of lpc-ctrl module, LPC SNOOP block will be enabled without heart beating of LCLK until lpc-ctrl enables the LCLK. This issue causes improper handling on host interrupts when the host sends interrupt in that time frame. Then kernel eventually forcibly disables the interrupt with dumping stack and printing a 'nobody cared this irq' message out. To prevent this issue, all LPC sub-nodes should enable LCLK individually so this patch adds clock control logic into the LPC SNOOP driver. Fixes: 3772e5da4454 ("drivers/misc: Aspeed LPC snoop output using misc chardev") Signed-off-by: Jae Hyun Yoo Signed-off-by: Vernon Mauery Signed-off-by: John Wang Reviewed-by: Joel Stanley Link: https://lore.kernel.org/r/20201208091748.1920-1-wangzhiqiang.bj@bytedance.com Signed-off-by: Joel Stanley --- drivers/soc/aspeed/aspeed-lpc-snoop.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/aspeed/aspeed-lpc-snoop.c b/drivers/soc/aspeed/aspeed-lpc-snoop.c index 682ba0eb4eba..20acac6342ef 100644 --- a/drivers/soc/aspeed/aspeed-lpc-snoop.c +++ b/drivers/soc/aspeed/aspeed-lpc-snoop.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -67,6 +68,7 @@ struct aspeed_lpc_snoop_channel { struct aspeed_lpc_snoop { struct regmap *regmap; int irq; + struct clk *clk; struct aspeed_lpc_snoop_channel chan[NUM_SNOOP_CHANNELS]; }; @@ -282,22 +284,42 @@ static int aspeed_lpc_snoop_probe(struct platform_device *pdev) return -ENODEV; } + lpc_snoop->clk = devm_clk_get(dev, NULL); + if (IS_ERR(lpc_snoop->clk)) { + rc = PTR_ERR(lpc_snoop->clk); + if (rc != -EPROBE_DEFER) + dev_err(dev, "couldn't get clock\n"); + return rc; + } + rc = clk_prepare_enable(lpc_snoop->clk); + if (rc) { + dev_err(dev, "couldn't enable clock\n"); + return rc; + } + rc = aspeed_lpc_snoop_config_irq(lpc_snoop, pdev); if (rc) - return rc; + goto err; rc = aspeed_lpc_enable_snoop(lpc_snoop, dev, 0, port); if (rc) - return rc; + goto err; /* Configuration of 2nd snoop channel port is optional */ if (of_property_read_u32_index(dev->of_node, "snoop-ports", 1, &port) == 0) { rc = aspeed_lpc_enable_snoop(lpc_snoop, dev, 1, port); - if (rc) + if (rc) { aspeed_lpc_disable_snoop(lpc_snoop, 0); + goto err; + } } + return 0; + +err: + clk_disable_unprepare(lpc_snoop->clk); + return rc; } @@ -309,6 +331,8 @@ static int aspeed_lpc_snoop_remove(struct platform_device *pdev) aspeed_lpc_disable_snoop(lpc_snoop, 0); aspeed_lpc_disable_snoop(lpc_snoop, 1); + clk_disable_unprepare(lpc_snoop->clk); + return 0; } -- cgit v1.2.3 From d0e72be77e7995923fac73f27cf7a75d3d1a4dec Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Wed, 10 Feb 2021 22:16:51 +1030 Subject: soc: aspeed: socinfo: Add new systems Aspeed's u-boot sdk has been updated with the SoC IDs for the AST2605 variant, as well as A2 and A3 variants of the 2600 family. >From u-boot's arch/arm/mach-aspeed/ast2600/scu_info.c: SOC_ID("AST2600-A0", 0x0500030305000303), SOC_ID("AST2600-A1", 0x0501030305010303), SOC_ID("AST2620-A1", 0x0501020305010203), SOC_ID("AST2600-A2", 0x0502030305010303), SOC_ID("AST2620-A2", 0x0502020305010203), SOC_ID("AST2605-A2", 0x0502010305010103), SOC_ID("AST2600-A3", 0x0503030305030303), SOC_ID("AST2620-A3", 0x0503020305030203), SOC_ID("AST2605-A3", 0x0503010305030103), Fixes: e0218dca5787 ("soc: aspeed: Add soc info driver") Link: https://lore.kernel.org/r/20210210114651.334324-1-joel@jms.id.au Signed-off-by: Joel Stanley --- drivers/soc/aspeed/aspeed-socinfo.c | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/aspeed/aspeed-socinfo.c b/drivers/soc/aspeed/aspeed-socinfo.c index 773930e0cb10..e3215f826d17 100644 --- a/drivers/soc/aspeed/aspeed-socinfo.c +++ b/drivers/soc/aspeed/aspeed-socinfo.c @@ -25,6 +25,7 @@ static struct { /* AST2600 */ { "AST2600", 0x05000303 }, { "AST2620", 0x05010203 }, + { "AST2605", 0x05030103 }, }; static const char *siliconid_to_name(u32 siliconid) @@ -43,14 +44,30 @@ static const char *siliconid_to_name(u32 siliconid) static const char *siliconid_to_rev(u32 siliconid) { unsigned int rev = (siliconid >> 16) & 0xff; - - switch (rev) { - case 0: - return "A0"; - case 1: - return "A1"; - case 3: - return "A2"; + unsigned int gen = (siliconid >> 24) & 0xff; + + if (gen < 0x5) { + /* AST2500 and below */ + switch (rev) { + case 0: + return "A0"; + case 1: + return "A1"; + case 3: + return "A2"; + } + } else { + /* AST2600 */ + switch (rev) { + case 0: + return "A0"; + case 1: + return "A1"; + case 2: + return "A2"; + case 3: + return "A3"; + } } return "??"; -- cgit v1.2.3