diff options
Diffstat (limited to 'drivers/soc')
-rw-r--r-- | drivers/soc/qcom/Kconfig | 1 | ||||
-rw-r--r-- | drivers/soc/qcom/Makefile | 2 | ||||
-rw-r--r-- | drivers/soc/qcom/cmd-db.c | 2 | ||||
-rw-r--r-- | drivers/soc/qcom/icc-bwmon.c | 30 | ||||
-rw-r--r-- | drivers/soc/qcom/ice.c | 2 | ||||
-rw-r--r-- | drivers/soc/qcom/llcc-qcom.c | 1 | ||||
-rw-r--r-- | drivers/soc/qcom/ocmem.c | 68 | ||||
-rw-r--r-- | drivers/soc/qcom/pmic_glink.c | 8 | ||||
-rw-r--r-- | drivers/soc/qcom/pmic_glink_altmode.c | 62 | ||||
-rw-r--r-- | drivers/soc/qcom/qcom_aoss.c | 49 | ||||
-rw-r--r-- | drivers/soc/qcom/qcom_gsbi.c | 11 | ||||
-rw-r--r-- | drivers/soc/qcom/qmi_encdec.c | 4 | ||||
-rw-r--r-- | drivers/soc/qcom/rpm-proc.c | 77 | ||||
-rw-r--r-- | drivers/soc/qcom/rpmh-rsc.c | 2 | ||||
-rw-r--r-- | drivers/soc/qcom/smd-rpm.c | 35 | ||||
-rw-r--r-- | drivers/soc/qcom/smem.c | 18 | ||||
-rw-r--r-- | drivers/soc/qcom/socinfo.c | 3 | ||||
-rw-r--r-- | drivers/soc/qcom/spm.c | 6 | ||||
-rw-r--r-- | drivers/soc/qcom/trace-rpmh.h | 16 | ||||
-rw-r--r-- | drivers/soc/qcom/wcnss_ctrl.c | 1 |
20 files changed, 260 insertions, 138 deletions
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index e597799e8121..715348869d04 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -191,6 +191,7 @@ config QCOM_SMD_RPM tristate "Qualcomm Resource Power Manager (RPM) over SMD" depends on ARCH_QCOM || COMPILE_TEST depends on RPMSG + depends on RPMSG_QCOM_SMD || RPMSG_QCOM_SMD=n help If you say yes to this option, support will be included for the Resource Power Manager system found in the Qualcomm 8974 based diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index f548a7150bb2..bbca2e1e55bb 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -17,7 +17,7 @@ obj-$(CONFIG_QCOM_RPM_MASTER_STATS) += rpm_master_stats.o obj-$(CONFIG_QCOM_RPMH) += qcom_rpmh.o qcom_rpmh-y += rpmh-rsc.o qcom_rpmh-y += rpmh.o -obj-$(CONFIG_QCOM_SMD_RPM) += smd-rpm.o +obj-$(CONFIG_QCOM_SMD_RPM) += rpm-proc.o smd-rpm.o obj-$(CONFIG_QCOM_SMEM) += smem.o obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o obj-$(CONFIG_QCOM_SMP2P) += smp2p.o diff --git a/drivers/soc/qcom/cmd-db.c b/drivers/soc/qcom/cmd-db.c index 33856abd560c..34c40368d5b5 100644 --- a/drivers/soc/qcom/cmd-db.c +++ b/drivers/soc/qcom/cmd-db.c @@ -284,7 +284,7 @@ static int cmd_db_debugfs_dump(struct seq_file *seq, void *p) ent = rsc_to_entry_header(rsc); for (j = 0; j < le16_to_cpu(rsc->cnt); j++, ent++) { seq_printf(seq, "0x%05x: %*pEp", le32_to_cpu(ent->addr), - (int)sizeof(ent->id), ent->id); + (int)strnlen(ent->id, sizeof(ent->id)), ent->id); len = le16_to_cpu(ent->len); if (len) { diff --git a/drivers/soc/qcom/icc-bwmon.c b/drivers/soc/qcom/icc-bwmon.c index 40068a285913..adf2d523f103 100644 --- a/drivers/soc/qcom/icc-bwmon.c +++ b/drivers/soc/qcom/icc-bwmon.c @@ -12,7 +12,7 @@ #include <linux/io.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm_opp.h> #include <linux/regmap.h> @@ -165,9 +165,6 @@ enum bwmon_fields { struct icc_bwmon_data { unsigned int sample_ms; unsigned int count_unit_kb; /* kbytes */ - unsigned int default_highbw_kbps; - unsigned int default_medbw_kbps; - unsigned int default_lowbw_kbps; u8 zone1_thres_count; u8 zone3_thres_count; unsigned int quirks; @@ -564,20 +561,21 @@ static void bwmon_set_threshold(struct icc_bwmon *bwmon, static void bwmon_start(struct icc_bwmon *bwmon) { const struct icc_bwmon_data *data = bwmon->data; + u32 bw_low = 0; int window; + /* No need to check for errors, as this must have succeeded before. */ + dev_pm_opp_find_bw_ceil(bwmon->dev, &bw_low, 0); + bwmon_clear_counters(bwmon, true); window = mult_frac(bwmon->data->sample_ms, HW_TIMER_HZ, MSEC_PER_SEC); /* Maximum sampling window: 0xffffff for v4 and 0xfffff for v5 */ regmap_field_write(bwmon->regs[F_SAMPLE_WINDOW], window); - bwmon_set_threshold(bwmon, bwmon->regs[F_THRESHOLD_HIGH], - data->default_highbw_kbps); - bwmon_set_threshold(bwmon, bwmon->regs[F_THRESHOLD_MED], - data->default_medbw_kbps); - bwmon_set_threshold(bwmon, bwmon->regs[F_THRESHOLD_LOW], - data->default_lowbw_kbps); + bwmon_set_threshold(bwmon, bwmon->regs[F_THRESHOLD_HIGH], bw_low); + bwmon_set_threshold(bwmon, bwmon->regs[F_THRESHOLD_MED], bw_low); + bwmon_set_threshold(bwmon, bwmon->regs[F_THRESHOLD_LOW], 0); regmap_field_write(bwmon->regs[F_THRESHOLD_COUNT_ZONE0], BWMON_THRESHOLD_COUNT_ZONE0_DEFAULT); @@ -807,9 +805,6 @@ static int bwmon_remove(struct platform_device *pdev) static const struct icc_bwmon_data msm8998_bwmon_data = { .sample_ms = 4, .count_unit_kb = 1024, - .default_highbw_kbps = 4800 * 1024, /* 4.8 GBps */ - .default_medbw_kbps = 512 * 1024, /* 512 MBps */ - .default_lowbw_kbps = 0, .zone1_thres_count = 16, .zone3_thres_count = 1, .quirks = BWMON_HAS_GLOBAL_IRQ, @@ -822,9 +817,6 @@ static const struct icc_bwmon_data msm8998_bwmon_data = { static const struct icc_bwmon_data sdm845_cpu_bwmon_data = { .sample_ms = 4, .count_unit_kb = 64, - .default_highbw_kbps = 4800 * 1024, /* 4.8 GBps */ - .default_medbw_kbps = 512 * 1024, /* 512 MBps */ - .default_lowbw_kbps = 0, .zone1_thres_count = 16, .zone3_thres_count = 1, .quirks = BWMON_HAS_GLOBAL_IRQ, @@ -835,9 +827,6 @@ static const struct icc_bwmon_data sdm845_cpu_bwmon_data = { static const struct icc_bwmon_data sdm845_llcc_bwmon_data = { .sample_ms = 4, .count_unit_kb = 1024, - .default_highbw_kbps = 800 * 1024, /* 800 MBps */ - .default_medbw_kbps = 256 * 1024, /* 256 MBps */ - .default_lowbw_kbps = 0, .zone1_thres_count = 16, .zone3_thres_count = 1, .regmap_fields = sdm845_llcc_bwmon_reg_fields, @@ -847,9 +836,6 @@ static const struct icc_bwmon_data sdm845_llcc_bwmon_data = { static const struct icc_bwmon_data sc7280_llcc_bwmon_data = { .sample_ms = 4, .count_unit_kb = 64, - .default_highbw_kbps = 800 * 1024, /* 800 MBps */ - .default_medbw_kbps = 256 * 1024, /* 256 MBps */ - .default_lowbw_kbps = 0, .zone1_thres_count = 16, .zone3_thres_count = 1, .quirks = BWMON_NEEDS_FORCE_CLEAR, diff --git a/drivers/soc/qcom/ice.c b/drivers/soc/qcom/ice.c index a6123ea96272..fbab7fe5c652 100644 --- a/drivers/soc/qcom/ice.c +++ b/drivers/soc/qcom/ice.c @@ -11,7 +11,9 @@ #include <linux/clk.h> #include <linux/delay.h> #include <linux/iopoll.h> +#include <linux/of.h> #include <linux/of_platform.h> +#include <linux/platform_device.h> #include <linux/firmware/qcom/qcom_scm.h> diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c index 67c19ed2219a..e32a4161a8d0 100644 --- a/drivers/soc/qcom/llcc-qcom.c +++ b/drivers/soc/qcom/llcc-qcom.c @@ -13,7 +13,6 @@ #include <linux/module.h> #include <linux/mutex.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/regmap.h> #include <linux/sizes.h> #include <linux/slab.h> diff --git a/drivers/soc/qcom/ocmem.c b/drivers/soc/qcom/ocmem.c index aaddc3cc53b7..20f5461d46b9 100644 --- a/drivers/soc/qcom/ocmem.c +++ b/drivers/soc/qcom/ocmem.c @@ -14,7 +14,8 @@ #include <linux/io.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> +#include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/firmware/qcom/qcom_scm.h> #include <linux/sizes.h> @@ -54,6 +55,8 @@ struct ocmem { const struct ocmem_config *config; struct resource *memory; void __iomem *mmio; + struct clk *core_clk; + struct clk *iface_clk; unsigned int num_ports; unsigned int num_macros; bool interleaved; @@ -80,8 +83,8 @@ struct ocmem { #define OCMEM_HW_VERSION_MINOR(val) FIELD_GET(GENMASK(27, 16), val) #define OCMEM_HW_VERSION_STEP(val) FIELD_GET(GENMASK(15, 0), val) -#define OCMEM_HW_PROFILE_NUM_PORTS(val) FIELD_PREP(0x0000000f, (val)) -#define OCMEM_HW_PROFILE_NUM_MACROS(val) FIELD_PREP(0x00003f00, (val)) +#define OCMEM_HW_PROFILE_NUM_PORTS(val) FIELD_GET(0x0000000f, (val)) +#define OCMEM_HW_PROFILE_NUM_MACROS(val) FIELD_GET(0x00003f00, (val)) #define OCMEM_HW_PROFILE_LAST_REGN_HALFSIZE 0x00010000 #define OCMEM_HW_PROFILE_INTERLEAVING 0x00020000 @@ -95,16 +98,6 @@ struct ocmem { #define OCMEM_PSGSC_CTL_MACRO2_MODE(val) FIELD_PREP(0x00000700, (val)) #define OCMEM_PSGSC_CTL_MACRO3_MODE(val) FIELD_PREP(0x00007000, (val)) -#define OCMEM_CLK_CORE_IDX 0 -static struct clk_bulk_data ocmem_clks[] = { - { - .id = "core", - }, - { - .id = "iface", - }, -}; - static inline void ocmem_write(struct ocmem *ocmem, u32 reg, u32 data) { writel(data, ocmem->mmio + reg); @@ -320,19 +313,20 @@ static int ocmem_dev_probe(struct platform_device *pdev) ocmem->dev = dev; ocmem->config = device_get_match_data(dev); - ret = devm_clk_bulk_get(dev, ARRAY_SIZE(ocmem_clks), ocmem_clks); - if (ret) { - if (ret != -EPROBE_DEFER) - dev_err(dev, "Unable to get clocks\n"); + ocmem->core_clk = devm_clk_get(dev, "core"); + if (IS_ERR(ocmem->core_clk)) + return dev_err_probe(dev, PTR_ERR(ocmem->core_clk), + "Unable to get core clock\n"); - return ret; - } + ocmem->iface_clk = devm_clk_get_optional(dev, "iface"); + if (IS_ERR(ocmem->iface_clk)) + return dev_err_probe(dev, PTR_ERR(ocmem->iface_clk), + "Unable to get iface clock\n"); ocmem->mmio = devm_platform_ioremap_resource_byname(pdev, "ctrl"); - if (IS_ERR(ocmem->mmio)) { - dev_err(&pdev->dev, "Failed to ioremap ocmem_ctrl resource\n"); - return PTR_ERR(ocmem->mmio); - } + if (IS_ERR(ocmem->mmio)) + return dev_err_probe(&pdev->dev, PTR_ERR(ocmem->mmio), + "Failed to ioremap ocmem_ctrl resource\n"); ocmem->memory = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem"); @@ -342,19 +336,23 @@ static int ocmem_dev_probe(struct platform_device *pdev) } /* The core clock is synchronous with graphics */ - WARN_ON(clk_set_rate(ocmem_clks[OCMEM_CLK_CORE_IDX].clk, 1000) < 0); + WARN_ON(clk_set_rate(ocmem->core_clk, 1000) < 0); + + ret = clk_prepare_enable(ocmem->core_clk); + if (ret) + return dev_err_probe(ocmem->dev, ret, "Failed to enable core clock\n"); - ret = clk_bulk_prepare_enable(ARRAY_SIZE(ocmem_clks), ocmem_clks); + ret = clk_prepare_enable(ocmem->iface_clk); if (ret) { - dev_info(ocmem->dev, "Failed to enable clocks\n"); - return ret; + clk_disable_unprepare(ocmem->core_clk); + return dev_err_probe(ocmem->dev, ret, "Failed to enable iface clock\n"); } if (qcom_scm_restore_sec_cfg_available()) { dev_dbg(dev, "configuring scm\n"); ret = qcom_scm_restore_sec_cfg(QCOM_SCM_OCMEM_DEV_ID, 0); if (ret) { - dev_err(dev, "Could not enable secure configuration\n"); + dev_err_probe(dev, ret, "Could not enable secure configuration\n"); goto err_clk_disable; } } @@ -413,23 +411,33 @@ static int ocmem_dev_probe(struct platform_device *pdev) return 0; err_clk_disable: - clk_bulk_disable_unprepare(ARRAY_SIZE(ocmem_clks), ocmem_clks); + clk_disable_unprepare(ocmem->core_clk); + clk_disable_unprepare(ocmem->iface_clk); return ret; } static int ocmem_dev_remove(struct platform_device *pdev) { - clk_bulk_disable_unprepare(ARRAY_SIZE(ocmem_clks), ocmem_clks); + struct ocmem *ocmem = platform_get_drvdata(pdev); + + clk_disable_unprepare(ocmem->core_clk); + clk_disable_unprepare(ocmem->iface_clk); return 0; } +static const struct ocmem_config ocmem_8226_config = { + .num_regions = 1, + .macro_size = SZ_128K, +}; + static const struct ocmem_config ocmem_8974_config = { .num_regions = 3, .macro_size = SZ_128K, }; static const struct of_device_id ocmem_of_match[] = { + { .compatible = "qcom,msm8226-ocmem", .data = &ocmem_8226_config }, { .compatible = "qcom,msm8974-ocmem", .data = &ocmem_8974_config }, { } }; diff --git a/drivers/soc/qcom/pmic_glink.c b/drivers/soc/qcom/pmic_glink.c index c87056769ebd..61c89ddfc75b 100644 --- a/drivers/soc/qcom/pmic_glink.c +++ b/drivers/soc/qcom/pmic_glink.c @@ -4,8 +4,8 @@ * Copyright (c) 2022, Linaro Ltd */ #include <linux/auxiliary_bus.h> -#include <linux/of_device.h> #include <linux/module.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/rpmsg.h> #include <linux/slab.h> @@ -342,13 +342,9 @@ static const unsigned long pmic_glink_sm8450_client_mask = BIT(PMIC_GLINK_CLIENT BIT(PMIC_GLINK_CLIENT_ALTMODE) | BIT(PMIC_GLINK_CLIENT_UCSI); -/* Do not handle altmode for now on those platforms */ -static const unsigned long pmic_glink_sm8550_client_mask = BIT(PMIC_GLINK_CLIENT_BATT) | - BIT(PMIC_GLINK_CLIENT_UCSI); - static const struct of_device_id pmic_glink_of_match[] = { { .compatible = "qcom,sm8450-pmic-glink", .data = &pmic_glink_sm8450_client_mask }, - { .compatible = "qcom,sm8550-pmic-glink", .data = &pmic_glink_sm8550_client_mask }, + { .compatible = "qcom,sm8550-pmic-glink", .data = &pmic_glink_sm8450_client_mask }, { .compatible = "qcom,pmic-glink" }, {} }; diff --git a/drivers/soc/qcom/pmic_glink_altmode.c b/drivers/soc/qcom/pmic_glink_altmode.c index df48fbea4b68..d05e0d6edf49 100644 --- a/drivers/soc/qcom/pmic_glink_altmode.c +++ b/drivers/soc/qcom/pmic_glink_altmode.c @@ -6,6 +6,7 @@ #include <linux/auxiliary_bus.h> #include <linux/bitfield.h> #include <linux/module.h> +#include <linux/of.h> #include <linux/of_device.h> #include <linux/mutex.h> #include <linux/property.h> @@ -15,6 +16,7 @@ #include <linux/usb/typec_altmode.h> #include <linux/usb/typec_dp.h> #include <linux/usb/typec_mux.h> +#include <linux/usb/typec_retimer.h> #include <linux/soc/qcom/pmic_glink.h> @@ -68,6 +70,8 @@ struct pmic_glink_altmode_port { struct typec_switch *typec_switch; struct typec_mux *typec_mux; struct typec_mux_state state; + struct typec_retimer *typec_retimer; + struct typec_retimer_state retimer_state; struct typec_altmode dp_alt; struct work_struct work; @@ -157,6 +161,14 @@ static void pmic_glink_altmode_enable_dp(struct pmic_glink_altmode *altmode, ret = typec_mux_set(port->typec_mux, &port->state); if (ret) dev_err(altmode->dev, "failed to switch mux to DP\n"); + + port->retimer_state.alt = &port->dp_alt; + port->retimer_state.data = &dp_data; + port->retimer_state.mode = TYPEC_MODAL_STATE(mode); + + ret = typec_retimer_set(port->typec_retimer, &port->retimer_state); + if (ret) + dev_err(altmode->dev, "failed to setup retimer to DP\n"); } static void pmic_glink_altmode_enable_usb(struct pmic_glink_altmode *altmode, @@ -171,6 +183,36 @@ static void pmic_glink_altmode_enable_usb(struct pmic_glink_altmode *altmode, ret = typec_mux_set(port->typec_mux, &port->state); if (ret) dev_err(altmode->dev, "failed to switch mux to USB\n"); + + port->retimer_state.alt = NULL; + port->retimer_state.data = NULL; + port->retimer_state.mode = TYPEC_STATE_USB; + + ret = typec_retimer_set(port->typec_retimer, &port->retimer_state); + if (ret) + dev_err(altmode->dev, "failed to setup retimer to USB\n"); +} + +static void pmic_glink_altmode_safe(struct pmic_glink_altmode *altmode, + struct pmic_glink_altmode_port *port) +{ + int ret; + + port->state.alt = NULL; + port->state.data = NULL; + port->state.mode = TYPEC_STATE_SAFE; + + ret = typec_mux_set(port->typec_mux, &port->state); + if (ret) + dev_err(altmode->dev, "failed to switch mux to safe mode\n"); + + port->retimer_state.alt = NULL; + port->retimer_state.data = NULL; + port->retimer_state.mode = TYPEC_STATE_SAFE; + + ret = typec_retimer_set(port->typec_retimer, &port->retimer_state); + if (ret) + dev_err(altmode->dev, "failed to setup retimer to USB\n"); } static void pmic_glink_altmode_worker(struct work_struct *work) @@ -180,7 +222,9 @@ static void pmic_glink_altmode_worker(struct work_struct *work) typec_switch_set(alt_port->typec_switch, alt_port->orientation); - if (alt_port->svid == USB_TYPEC_DP_SID) + if (alt_port->svid == USB_TYPEC_DP_SID && alt_port->mode == 0xff) + pmic_glink_altmode_safe(altmode, alt_port); + else if (alt_port->svid == USB_TYPEC_DP_SID) pmic_glink_altmode_enable_dp(altmode, alt_port, alt_port->mode, alt_port->hpd_state, alt_port->hpd_irq); else @@ -331,6 +375,11 @@ static const struct drm_bridge_funcs pmic_glink_altmode_bridge_funcs = { .attach = pmic_glink_altmode_attach, }; +static void pmic_glink_altmode_put_retimer(void *data) +{ + typec_retimer_put(data); +} + static void pmic_glink_altmode_put_mux(void *data) { typec_mux_put(data); @@ -437,6 +486,17 @@ static int pmic_glink_altmode_probe(struct auxiliary_device *adev, if (ret) return ret; + alt_port->typec_retimer = fwnode_typec_retimer_get(fwnode); + if (IS_ERR(alt_port->typec_retimer)) + return dev_err_probe(dev, PTR_ERR(alt_port->typec_retimer), + "failed to acquire retimer-switch for port: %d\n", + port); + + ret = devm_add_action_or_reset(dev, pmic_glink_altmode_put_retimer, + alt_port->typec_retimer); + if (ret) + return ret; + alt_port->typec_switch = fwnode_typec_switch_get(fwnode); if (IS_ERR(alt_port->typec_switch)) return dev_err_probe(dev, PTR_ERR(alt_port->typec_switch), diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c index e376c32cc16e..77f0cf126629 100644 --- a/drivers/soc/qcom/qcom_aoss.c +++ b/drivers/soc/qcom/qcom_aoss.c @@ -205,37 +205,42 @@ static bool qmp_message_empty(struct qmp *qmp) /** * qmp_send() - send a message to the AOSS * @qmp: qmp context - * @data: message to be sent - * @len: length of the message + * @fmt: format string for message to be sent + * @...: arguments for the format string * - * Transmit @data to AOSS and wait for the AOSS to acknowledge the message. - * @len must be a multiple of 4 and not longer than the mailbox size. Access is - * synchronized by this implementation. + * Transmit message to AOSS and wait for the AOSS to acknowledge the message. + * data must not be longer than the mailbox size. Access is synchronized by + * this implementation. * * Return: 0 on success, negative errno on failure */ -int qmp_send(struct qmp *qmp, const void *data, size_t len) +int qmp_send(struct qmp *qmp, const char *fmt, ...) { + char buf[QMP_MSG_LEN]; long time_left; + va_list args; + int len; int ret; - if (WARN_ON(IS_ERR_OR_NULL(qmp) || !data)) + if (WARN_ON(IS_ERR_OR_NULL(qmp) || !fmt)) return -EINVAL; - if (WARN_ON(len + sizeof(u32) > qmp->size)) - return -EINVAL; + memset(buf, 0, sizeof(buf)); + va_start(args, fmt); + len = vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); - if (WARN_ON(len % sizeof(u32))) + if (WARN_ON(len >= sizeof(buf))) return -EINVAL; mutex_lock(&qmp->tx_lock); /* The message RAM only implements 32-bit accesses */ __iowrite32_copy(qmp->msgram + qmp->offset + sizeof(u32), - data, len / sizeof(u32)); - writel(len, qmp->msgram + qmp->offset); + buf, sizeof(buf) / sizeof(u32)); + writel(sizeof(buf), qmp->msgram + qmp->offset); - /* Read back len to confirm data written in message RAM */ + /* Read back length to confirm data written in message RAM */ readl(qmp->msgram + qmp->offset); qmp_kick(qmp); @@ -259,18 +264,18 @@ EXPORT_SYMBOL(qmp_send); static int qmp_qdss_clk_prepare(struct clk_hw *hw) { - static const char buf[QMP_MSG_LEN] = "{class: clock, res: qdss, val: 1}"; + static const char *buf = "{class: clock, res: qdss, val: 1}"; struct qmp *qmp = container_of(hw, struct qmp, qdss_clk); - return qmp_send(qmp, buf, sizeof(buf)); + return qmp_send(qmp, buf); } static void qmp_qdss_clk_unprepare(struct clk_hw *hw) { - static const char buf[QMP_MSG_LEN] = "{class: clock, res: qdss, val: 0}"; + static const char *buf = "{class: clock, res: qdss, val: 0}"; struct qmp *qmp = container_of(hw, struct qmp, qdss_clk); - qmp_send(qmp, buf, sizeof(buf)); + qmp_send(qmp, buf); } static const struct clk_ops qmp_qdss_clk_ops = { @@ -329,7 +334,6 @@ static int qmp_cdev_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state) { struct qmp_cooling_device *qmp_cdev = cdev->devdata; - char buf[QMP_MSG_LEN] = {}; bool cdev_state; int ret; @@ -339,13 +343,8 @@ static int qmp_cdev_set_cur_state(struct thermal_cooling_device *cdev, if (qmp_cdev->state == state) return 0; - snprintf(buf, sizeof(buf), - "{class: volt_flr, event:zero_temp, res:%s, value:%s}", - qmp_cdev->name, - cdev_state ? "on" : "off"); - - ret = qmp_send(qmp_cdev->qmp, buf, sizeof(buf)); - + ret = qmp_send(qmp_cdev->qmp, "{class: volt_flr, event:zero_temp, res:%s, value:%s}", + qmp_cdev->name, cdev_state ? "on" : "off"); if (!ret) qmp_cdev->state = cdev_state; diff --git a/drivers/soc/qcom/qcom_gsbi.c b/drivers/soc/qcom/qcom_gsbi.c index f1742e5bddb9..df7907a83aa8 100644 --- a/drivers/soc/qcom/qcom_gsbi.c +++ b/drivers/soc/qcom/qcom_gsbi.c @@ -129,7 +129,7 @@ static int gsbi_probe(struct platform_device *pdev) const struct of_device_id *match; void __iomem *base; struct gsbi_info *gsbi; - int i, ret; + int i; u32 mask, gsbi_num; const struct crci_config *config = NULL; @@ -178,12 +178,10 @@ static int gsbi_probe(struct platform_device *pdev) dev_info(&pdev->dev, "GSBI port protocol: %d crci: %d\n", gsbi->mode, gsbi->crci); - gsbi->hclk = devm_clk_get(&pdev->dev, "iface"); + gsbi->hclk = devm_clk_get_enabled(&pdev->dev, "iface"); if (IS_ERR(gsbi->hclk)) return PTR_ERR(gsbi->hclk); - clk_prepare_enable(gsbi->hclk); - writel_relaxed((gsbi->mode << GSBI_PROTOCOL_SHIFT) | gsbi->crci, base + GSBI_CTRL_REG); @@ -211,10 +209,7 @@ static int gsbi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, gsbi); - ret = of_platform_populate(node, NULL, NULL, &pdev->dev); - if (ret) - clk_disable_unprepare(gsbi->hclk); - return ret; + return of_platform_populate(node, NULL, NULL, &pdev->dev); } static int gsbi_remove(struct platform_device *pdev) diff --git a/drivers/soc/qcom/qmi_encdec.c b/drivers/soc/qcom/qmi_encdec.c index b7158e3c3a0b..5c7161b18b72 100644 --- a/drivers/soc/qcom/qmi_encdec.c +++ b/drivers/soc/qcom/qmi_encdec.c @@ -534,8 +534,8 @@ static int qmi_decode_string_elem(const struct qmi_elem_info *ei_array, decoded_bytes += rc; } - if (string_len > temp_ei->elem_len) { - pr_err("%s: String len %d > Max Len %d\n", + if (string_len >= temp_ei->elem_len) { + pr_err("%s: String len %d >= Max Len %d\n", __func__, string_len, temp_ei->elem_len); return -ETOOSMALL; } else if (string_len > tlv_len) { diff --git a/drivers/soc/qcom/rpm-proc.c b/drivers/soc/qcom/rpm-proc.c new file mode 100644 index 000000000000..2995d9b90190 --- /dev/null +++ b/drivers/soc/qcom/rpm-proc.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright (c) 2021-2023, Stephan Gerhold <stephan@gerhold.net> */ + +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> +#include <linux/rpmsg/qcom_smd.h> + +static int rpm_proc_probe(struct platform_device *pdev) +{ + struct qcom_smd_edge *edge = NULL; + struct device *dev = &pdev->dev; + struct device_node *edge_node; + int ret; + + edge_node = of_get_child_by_name(dev->of_node, "smd-edge"); + if (edge_node) { + edge = qcom_smd_register_edge(dev, edge_node); + of_node_put(edge_node); + if (IS_ERR(edge)) + return dev_err_probe(dev, PTR_ERR(edge), + "Failed to register smd-edge\n"); + } + + ret = devm_of_platform_populate(dev); + if (ret) { + dev_err(dev, "Failed to populate child devices: %d\n", ret); + goto err; + } + + platform_set_drvdata(pdev, edge); + return 0; +err: + if (edge) + qcom_smd_unregister_edge(edge); + return ret; +} + +static void rpm_proc_remove(struct platform_device *pdev) +{ + struct qcom_smd_edge *edge = platform_get_drvdata(pdev); + + if (edge) + qcom_smd_unregister_edge(edge); +} + +static const struct of_device_id rpm_proc_of_match[] = { + { .compatible = "qcom,rpm-proc", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, rpm_proc_of_match); + +static struct platform_driver rpm_proc_driver = { + .probe = rpm_proc_probe, + .remove_new = rpm_proc_remove, + .driver = { + .name = "qcom-rpm-proc", + .of_match_table = rpm_proc_of_match, + }, +}; + +static int __init rpm_proc_init(void) +{ + return platform_driver_register(&rpm_proc_driver); +} +arch_initcall(rpm_proc_init); + +static void __exit rpm_proc_exit(void) +{ + platform_driver_unregister(&rpm_proc_driver); +} +module_exit(rpm_proc_exit); + +MODULE_DESCRIPTION("Qualcomm RPM processor/subsystem driver"); +MODULE_AUTHOR("Stephan Gerhold <stephan@gerhold.net>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index 0dd4363ebac8..a021dc71807b 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -516,7 +516,7 @@ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id, write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_MSGID], tcs_id, j, msgid); write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_ADDR], tcs_id, j, cmd->addr); write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_DATA], tcs_id, j, cmd->data); - trace_rpmh_send_msg(drv, tcs_id, j, msgid, cmd); + trace_rpmh_send_msg(drv, tcs_id, msg->state, j, msgid, cmd); } cmd_enable |= read_tcs_reg(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id); diff --git a/drivers/soc/qcom/smd-rpm.c b/drivers/soc/qcom/smd-rpm.c index 0c1aa809cc4e..13d8c52330d0 100644 --- a/drivers/soc/qcom/smd-rpm.c +++ b/drivers/soc/qcom/smd-rpm.c @@ -199,6 +199,9 @@ static int qcom_smd_rpm_probe(struct rpmsg_device *rpdev) struct qcom_smd_rpm *rpm; int ret; + if (!rpdev->dev.of_node) + return -EINVAL; + rpm = devm_kzalloc(&rpdev->dev, sizeof(*rpm), GFP_KERNEL); if (!rpm) return -ENOMEM; @@ -230,38 +233,18 @@ static void qcom_smd_rpm_remove(struct rpmsg_device *rpdev) of_platform_depopulate(&rpdev->dev); } -static const struct of_device_id qcom_smd_rpm_of_match[] = { - { .compatible = "qcom,rpm-apq8084" }, - { .compatible = "qcom,rpm-ipq6018" }, - { .compatible = "qcom,rpm-ipq9574" }, - { .compatible = "qcom,rpm-msm8226" }, - { .compatible = "qcom,rpm-msm8909" }, - { .compatible = "qcom,rpm-msm8916" }, - { .compatible = "qcom,rpm-msm8936" }, - { .compatible = "qcom,rpm-msm8953" }, - { .compatible = "qcom,rpm-msm8974" }, - { .compatible = "qcom,rpm-msm8976" }, - { .compatible = "qcom,rpm-msm8994" }, - { .compatible = "qcom,rpm-msm8996" }, - { .compatible = "qcom,rpm-msm8998" }, - { .compatible = "qcom,rpm-sdm660" }, - { .compatible = "qcom,rpm-sm6115" }, - { .compatible = "qcom,rpm-sm6125" }, - { .compatible = "qcom,rpm-sm6375" }, - { .compatible = "qcom,rpm-qcm2290" }, - { .compatible = "qcom,rpm-qcs404" }, - {} +static const struct rpmsg_device_id qcom_smd_rpm_id_table[] = { + { .name = "rpm_requests", }, + { /* sentinel */ } }; -MODULE_DEVICE_TABLE(of, qcom_smd_rpm_of_match); +MODULE_DEVICE_TABLE(rpmsg, qcom_smd_rpm_id_table); static struct rpmsg_driver qcom_smd_rpm_driver = { .probe = qcom_smd_rpm_probe, .remove = qcom_smd_rpm_remove, .callback = qcom_smd_rpm_callback, - .drv = { - .name = "qcom_smd_rpm", - .of_match_table = qcom_smd_rpm_of_match, - }, + .id_table = qcom_smd_rpm_id_table, + .drv.name = "qcom_smd_rpm", }; static int __init qcom_smd_rpm_init(void) diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index b0d59e815c3b..d4a89d2bb43b 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -359,6 +359,17 @@ static struct qcom_smem *__smem; /* Timeout (ms) for the trylock of remote spinlocks */ #define HWSPINLOCK_TIMEOUT 1000 +/** + * qcom_smem_is_available() - Check if SMEM is available + * + * Return: true if SMEM is available, false otherwise. + */ +bool qcom_smem_is_available(void) +{ + return !!__smem; +} +EXPORT_SYMBOL(qcom_smem_is_available); + static int qcom_smem_alloc_private(struct qcom_smem *smem, struct smem_partition *part, unsigned item, @@ -724,7 +735,7 @@ EXPORT_SYMBOL_GPL(qcom_smem_get_free_space); static bool addr_in_range(void __iomem *base, size_t size, void *addr) { - return base && (addr >= base && addr < base + size); + return base && ((void __iomem *)addr >= base && (void __iomem *)addr < base + size); } /** @@ -1059,7 +1070,6 @@ static int qcom_smem_probe(struct platform_device *pdev) struct reserved_mem *rmem; struct qcom_smem *smem; unsigned long flags; - size_t array_size; int num_regions; int hwlock_id; u32 version; @@ -1071,8 +1081,8 @@ static int qcom_smem_probe(struct platform_device *pdev) if (of_property_present(pdev->dev.of_node, "qcom,rpm-msg-ram")) num_regions++; - array_size = num_regions * sizeof(struct smem_region); - smem = devm_kzalloc(&pdev->dev, sizeof(*smem) + array_size, GFP_KERNEL); + smem = devm_kzalloc(&pdev->dev, struct_size(smem, regions, num_regions), + GFP_KERNEL); if (!smem) return -ENOMEM; diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index 4d49945b3a35..497cfb720fcb 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -371,6 +371,7 @@ static const struct soc_id soc_id[] = { { qcom_board_id(SDA429W) }, { qcom_board_id(SM8350) }, { qcom_board_id(QCM2290) }, + { qcom_board_id(SM7125) }, { qcom_board_id(SM6115) }, { qcom_board_id(IPQ5010) }, { qcom_board_id(IPQ5018) }, @@ -405,8 +406,8 @@ static const struct soc_id soc_id[] = { { qcom_board_id(SA8775P) }, { qcom_board_id(QRU1000) }, { qcom_board_id(QDU1000) }, + { qcom_board_id(SM4450) }, { qcom_board_id(QDU1010) }, - { qcom_board_id(IPQ5019) }, { qcom_board_id(QRU1032) }, { qcom_board_id(QRU1052) }, { qcom_board_id(QRU1062) }, diff --git a/drivers/soc/qcom/spm.c b/drivers/soc/qcom/spm.c index a6cbeb40831b..2f0b1bfe7658 100644 --- a/drivers/soc/qcom/spm.c +++ b/drivers/soc/qcom/spm.c @@ -12,8 +12,6 @@ #include <linux/module.h> #include <linux/slab.h> #include <linux/of.h> -#include <linux/of_address.h> -#include <linux/of_device.h> #include <linux/err.h> #include <linux/platform_device.h> #include <soc/qcom/spm.h> @@ -275,15 +273,13 @@ static int spm_dev_probe(struct platform_device *pdev) { const struct of_device_id *match_id; struct spm_driver_data *drv; - struct resource *res; void __iomem *addr; drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL); if (!drv) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - drv->reg_base = devm_ioremap_resource(&pdev->dev, res); + drv->reg_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(drv->reg_base)) return PTR_ERR(drv->reg_base); diff --git a/drivers/soc/qcom/trace-rpmh.h b/drivers/soc/qcom/trace-rpmh.h index 12b676b20cb2..be6b42ecc1f8 100644 --- a/drivers/soc/qcom/trace-rpmh.h +++ b/drivers/soc/qcom/trace-rpmh.h @@ -38,14 +38,15 @@ TRACE_EVENT(rpmh_tx_done, TRACE_EVENT(rpmh_send_msg, - TP_PROTO(struct rsc_drv *d, int m, int n, u32 h, + TP_PROTO(struct rsc_drv *d, int m, enum rpmh_state state, int n, u32 h, const struct tcs_cmd *c), - TP_ARGS(d, m, n, h, c), + TP_ARGS(d, m, state, n, h, c), TP_STRUCT__entry( __string(name, d->name) __field(int, m) + __field(u32, state) __field(int, n) __field(u32, hdr) __field(u32, addr) @@ -56,6 +57,7 @@ TRACE_EVENT(rpmh_send_msg, TP_fast_assign( __assign_str(name, d->name); __entry->m = m; + __entry->state = state; __entry->n = n; __entry->hdr = h; __entry->addr = c->addr; @@ -63,8 +65,14 @@ TRACE_EVENT(rpmh_send_msg, __entry->wait = c->wait; ), - TP_printk("%s: send-msg: tcs(m): %d cmd(n): %d msgid: %#x addr: %#x data: %#x complete: %d", - __get_str(name), __entry->m, __entry->n, __entry->hdr, + TP_printk("%s: tcs(m): %d [%s] cmd(n): %d msgid: %#x addr: %#x data: %#x complete: %d", + __get_str(name), __entry->m, + __print_symbolic(__entry->state, + { RPMH_SLEEP_STATE, "sleep" }, + { RPMH_WAKE_ONLY_STATE, "wake" }, + { RPMH_ACTIVE_ONLY_STATE, "active" }), + __entry->n, + __entry->hdr, __entry->addr, __entry->data, __entry->wait) ); diff --git a/drivers/soc/qcom/wcnss_ctrl.c b/drivers/soc/qcom/wcnss_ctrl.c index 2a06d631e415..ad9942412c58 100644 --- a/drivers/soc/qcom/wcnss_ctrl.c +++ b/drivers/soc/qcom/wcnss_ctrl.c @@ -7,6 +7,7 @@ #include <linux/module.h> #include <linux/slab.h> #include <linux/io.h> +#include <linux/of.h> #include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/rpmsg.h> |