Merge tag 'LA.UM.9.14.r1-24700-LAHAINA.QSSI15.0' of https://git.codelinaro.org/clo/la/kernel/msm-5.4 into android13-5.4-lahaina

"LA.UM.9.14.r1-24700-LAHAINA.QSSI15.0"

* tag 'LA.UM.9.14.r1-24700-LAHAINA.QSSI15.0' of https://git.codelinaro.org/clo/la/kernel/msm-5.4:
  msm: npu v1: Fix OOB issue in IPC between driver and firmware
  mmc: sdhci-msm: Disable partial_init and clk-scaling to avoid RED error
  slimbus: qcom-ngd-ctrl: Avoid accessing deallocated stack
  msm_ipa: new structure for tunnel design for uC
  msm: ipa3: change variable name for indication of rx tlv format
  soc: qcom: llcc: Handle a second device without data corruption
  msm: eva: User after free fix in msm_cvp_mark_user_persist
  rpmsg: slatecom: out of bound read from process_cmd
  soc: qcom: msm_minidump: Configurable Encryption support
  defconfig: arm64: Disable trimming non-whitelisted symbols
  soc: qcom: add out of bound check for AON fifo
  rpmsg: slatecom: maintain rx_size to read
  Revert LLCC changes
  bus: mhi: Fix potential out-of-bound access

 Conflicts:
	arch/arm64/boot/dts/vendor/bindings/interrupt-controller/ti,sci-intr.txt
	drivers/soc/qcom/llcc-slice.c
	drivers/usb/dwc3/core.c
	kernel/events/core.c
	mm/memory-failure.c

Change-Id: Ie4d89454f0766d0a48ebd4f2e6facb6deca9ea57
This commit is contained in:
Michael Bestas 2024-05-29 02:59:55 +03:00
commit 71d8fed9fd
No known key found for this signature in database
GPG key ID: CC95044519BE6669
29 changed files with 3171 additions and 2824 deletions

View file

@ -1 +1 @@
LTS_5.4.259_70db018a109
LTS_5.4.268_66f4b04cb072

View file

@ -513,3 +513,4 @@ CONFIG_ANDROID_BINDERFS=y
CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder,vndbinder"
# CONFIG_ANDROID_BINDER_IPC_SELFTEST is not set
CONFIG_IPC_LOG_MINIDUMP_BUFFERS=16
# CONFIG_QCOM_MINIDUMP_ENCRYPT is not set

View file

@ -3,9 +3,6 @@ CONFIG_COMMON_CLK_QCOM=m
CONFIG_REGULATOR_FIXED_VOLTAGE=m
CONFIG_REGULATOR_PROXY_CONSUMER=m
CONFIG_REGULATOR_STUB=m
CONFIG_TRIM_UNUSED_KSYMS=y
CONFIG_UNUSED_KSYMS_WHITELIST="android/abi_gki_aarch64_qcom android/abi_gki_aarch64_qcom_internal"
CONFIG_UNUSED_KSYMS_WHITELIST_ONLY=y
CONFIG_PINCTRL_SM8150=m
CONFIG_PINCTRL_SDMSHRIKE=m
CONFIG_PINCTRL_SM6150=m

View file

@ -1,9 +1,6 @@
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_SCUBA=y
CONFIG_ARCH_BENGAL=y
CONFIG_TRIM_UNUSED_KSYMS=y
CONFIG_UNUSED_KSYMS_WHITELIST="android/abi_gki_aarch64_qcom android/abi_gki_aarch64_qcom_internal"
CONFIG_UNUSED_KSYMS_WHITELIST_ONLY=y
CONFIG_PINCTRL_SCUBA=m
CONFIG_QCOM_RPMH=m
CONFIG_QCOM_COMMAND_DB=m

View file

@ -9,9 +9,6 @@ CONFIG_REGULATOR_PROXY_CONSUMER=m
CONFIG_REGULATOR_REFGEN=m
CONFIG_REGULATOR_RPMH=m
CONFIG_REGULATOR_STUB=m
CONFIG_TRIM_UNUSED_KSYMS=y
CONFIG_UNUSED_KSYMS_WHITELIST="android/abi_gki_aarch64_qcom android/abi_gki_aarch64_qcom_internal"
CONFIG_UNUSED_KSYMS_WHITELIST_ONLY=y
CONFIG_PINCTRL_SM8150=m
CONFIG_PINCTRL_SDMSHRIKE=m
CONFIG_PINCTRL_SLPI=m
@ -140,3 +137,4 @@ CONFIG_CNSS_GENL=m
CONFIG_QRTR_MHI=m
CONFIG_UIO_MSM_SHAREDMEM=m
CONFIG_INCREMENTAL_FS=m
# CONFIG_TRIM_UNUSED_KSYMS is not set

View file

@ -1,8 +1,5 @@
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_HOLI=y
CONFIG_TRIM_UNUSED_KSYMS=y
CONFIG_UNUSED_KSYMS_WHITELIST="android/abi_gki_aarch64_qcom android/abi_gki_aarch64_qcom_internal"
CONFIG_UNUSED_KSYMS_WHITELIST_ONLY=y
CONFIG_QCOM_RPMH=m
CONFIG_QCOM_RPMHPD=m
CONFIG_QCOM_COMMAND_DB=m
@ -234,3 +231,4 @@ CONFIG_SM_DISPCC_BLAIR=m
CONFIG_SM_DEBUGCC_BLAIR=m
CONFIG_QCOM_CX_IPEAK=m
CONFIG_LEDS_AW2016=m
# CONFIG_TRIM_UNUSED_KSYMS is not set

View file

@ -1,9 +1,6 @@
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_LAHAINA=y
CONFIG_ARCH_SHIMA=y
CONFIG_TRIM_UNUSED_KSYMS=y
CONFIG_UNUSED_KSYMS_WHITELIST="android/abi_gki_aarch64_qcom android/abi_gki_aarch64_qcom_internal"
CONFIG_UNUSED_KSYMS_WHITELIST_ONLY=y
CONFIG_QCOM_RPMH=m
CONFIG_QCOM_RPMHPD=m
CONFIG_QCOM_COMMAND_DB=m
@ -252,3 +249,4 @@ CONFIG_REGULATOR_QPNP_LCDB=m
CONFIG_LEDS_QPNP_VIBRATOR_LDO=m
CONFIG_BACKLIGHT_QCOM_SPMI_WLED=m
# CONFIG_CFG80211_CRDA_SUPPORT is not set
# CONFIG_TRIM_UNUSED_KSYMS is not set

View file

@ -8,9 +8,6 @@ CONFIG_REGULATOR_PROXY_CONSUMER=m
CONFIG_REGULATOR_REFGEN=m
CONFIG_REGULATOR_RPMH=m
CONFIG_REGULATOR_STUB=m
CONFIG_TRIM_UNUSED_KSYMS=y
CONFIG_UNUSED_KSYMS_WHITELIST="android/abi_gki_aarch64_qcom android/abi_gki_aarch64_qcom_internal"
CONFIG_UNUSED_KSYMS_WHITELIST_ONLY=y
CONFIG_PINCTRL_SM6150=m
CONFIG_PINCTRL_SDMSHRIKE=m
CONFIG_HEADER_TEST=y

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "msm_cvp_common.h"
@ -643,9 +644,10 @@ int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst,
list_for_each_entry_safe(pbuf, dummy, &inst->persistbufs.list,
list) {
if (pbuf->ownership == CLIENT) {
if (pbuf->fd == buf->fd &&
pbuf->size == buf->size)
if (pbuf->fd == buf->fd && pbuf->size == buf->size) {
buf->fd = pbuf->smem->device_addr;
pbuf->ktid = ktid;
}
rc = 1;
break;
}
@ -657,7 +659,6 @@ int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst,
rc = -EFAULT;
break;
}
pbuf->ktid = ktid;
rc = 0;
}
return rc;

View file

@ -94,12 +94,6 @@ struct npu_debugfs_ctx {
struct dentry *root;
uint32_t reg_off;
uint32_t reg_cnt;
uint8_t *log_buf;
struct mutex log_lock;
uint32_t log_num_bytes_buffered;
uint32_t log_read_index;
uint32_t log_write_index;
uint32_t log_buf_size;
};
struct npu_debugfs_reg_ctx {

View file

@ -27,8 +27,6 @@
*/
static int npu_debug_open(struct inode *inode, struct file *file);
static int npu_debug_release(struct inode *inode, struct file *file);
static ssize_t npu_debug_log_read(struct file *file,
char __user *user_buf, size_t count, loff_t *ppos);
static ssize_t npu_debug_ctrl_write(struct file *file,
const char __user *user_buf, size_t count, loff_t *ppos);
@ -38,13 +36,6 @@ static ssize_t npu_debug_ctrl_write(struct file *file,
*/
static struct npu_device *g_npu_dev;
static const struct file_operations npu_log_fops = {
.open = npu_debug_open,
.release = npu_debug_release,
.read = npu_debug_log_read,
.write = NULL,
};
static const struct file_operations npu_ctrl_fops = {
.open = npu_debug_open,
.release = npu_debug_release,
@ -69,47 +60,6 @@ static int npu_debug_release(struct inode *inode, struct file *file)
return 0;
}
/* -------------------------------------------------------------------------
* Function Implementations - DebugFS Log
* -------------------------------------------------------------------------
*/
static ssize_t npu_debug_log_read(struct file *file,
char __user *user_buf, size_t count, loff_t *ppos)
{
size_t len = 0;
struct npu_device *npu_dev = file->private_data;
struct npu_debugfs_ctx *debugfs;
pr_debug("npu_dev %pK %pK\n", npu_dev, g_npu_dev);
npu_dev = g_npu_dev;
debugfs = &npu_dev->debugfs_ctx;
/* mutex log lock */
mutex_lock(&debugfs->log_lock);
if (debugfs->log_num_bytes_buffered != 0) {
len = min(debugfs->log_num_bytes_buffered,
debugfs->log_buf_size - debugfs->log_read_index);
len = min(count, len);
if (copy_to_user(user_buf, (debugfs->log_buf +
debugfs->log_read_index), len)) {
pr_err("%s failed to copy to user\n", __func__);
mutex_unlock(&debugfs->log_lock);
return -EFAULT;
}
debugfs->log_read_index += len;
if (debugfs->log_read_index == debugfs->log_buf_size)
debugfs->log_read_index = 0;
debugfs->log_num_bytes_buffered -= len;
*ppos += len;
}
/* mutex log unlock */
mutex_unlock(&debugfs->log_lock);
return len;
}
/* -------------------------------------------------------------------------
* Function Implementations - DebugFS Control
@ -193,12 +143,6 @@ int npu_debugfs_init(struct npu_device *npu_dev)
return -ENODEV;
}
if (!debugfs_create_file("log", 0644, debugfs->root,
npu_dev, &npu_log_fops)) {
pr_err("debugfs_create_file log fail\n");
goto err;
}
if (!debugfs_create_file("ctrl", 0644, debugfs->root,
npu_dev, &npu_ctrl_fops)) {
pr_err("debugfs_create_file ctrl fail\n");
@ -235,14 +179,6 @@ int npu_debugfs_init(struct npu_device *npu_dev)
goto err;
}
debugfs->log_num_bytes_buffered = 0;
debugfs->log_read_index = 0;
debugfs->log_write_index = 0;
debugfs->log_buf_size = NPU_LOG_BUF_SIZE;
debugfs->log_buf = kzalloc(debugfs->log_buf_size, GFP_KERNEL);
if (!debugfs->log_buf)
goto err;
mutex_init(&debugfs->log_lock);
return 0;
@ -255,12 +191,6 @@ void npu_debugfs_deinit(struct npu_device *npu_dev)
{
struct npu_debugfs_ctx *debugfs = &npu_dev->debugfs_ctx;
debugfs->log_num_bytes_buffered = 0;
debugfs->log_read_index = 0;
debugfs->log_write_index = 0;
debugfs->log_buf_size = 0;
kfree(debugfs->log_buf);
if (!IS_ERR_OR_NULL(debugfs->root)) {
debugfs_remove_recursive(debugfs->root);
debugfs->root = NULL;

View file

@ -33,15 +33,16 @@
struct npu_queue_tuple {
uint32_t size;
uint32_t hdr;
uint32_t start_offset;
};
static const struct npu_queue_tuple npu_q_setup[6] = {
{ 1024, IPC_QUEUE_CMD_HIGH_PRIORITY | TX_HDR_TYPE | RX_HDR_TYPE },
{ 4096, IPC_QUEUE_APPS_EXEC | TX_HDR_TYPE | RX_HDR_TYPE },
{ 4096, IPC_QUEUE_DSP_EXEC | TX_HDR_TYPE | RX_HDR_TYPE },
{ 4096, IPC_QUEUE_APPS_RSP | TX_HDR_TYPE | RX_HDR_TYPE },
{ 4096, IPC_QUEUE_DSP_RSP | TX_HDR_TYPE | RX_HDR_TYPE },
{ 1024, IPC_QUEUE_LOG | TX_HDR_TYPE | RX_HDR_TYPE },
static struct npu_queue_tuple npu_q_setup[6] = {
{ 1024, IPC_QUEUE_CMD_HIGH_PRIORITY | TX_HDR_TYPE | RX_HDR_TYPE, 0},
{ 4096, IPC_QUEUE_APPS_EXEC | TX_HDR_TYPE | RX_HDR_TYPE, 0},
{ 4096, IPC_QUEUE_DSP_EXEC | TX_HDR_TYPE | RX_HDR_TYPE, 0},
{ 4096, IPC_QUEUE_APPS_RSP | TX_HDR_TYPE | RX_HDR_TYPE, 0},
{ 4096, IPC_QUEUE_DSP_RSP | TX_HDR_TYPE | RX_HDR_TYPE, 0},
{ 1024, IPC_QUEUE_LOG | TX_HDR_TYPE | RX_HDR_TYPE, 0},
};
/* -------------------------------------------------------------------------
@ -111,6 +112,7 @@ static int npu_host_ipc_init_hfi(struct npu_device *npu_dev)
/* queue is active */
q_hdr->qhdr_status = 0x01;
q_hdr->qhdr_start_offset = cur_start_offset;
npu_q_setup[q_idx].start_offset = cur_start_offset;
q_size = npu_q_setup[q_idx].size;
q_hdr->qhdr_type = npu_q_setup[q_idx].hdr;
/* in bytes */
@ -212,6 +214,18 @@ static int ipc_queue_read(struct npu_device *npu_dev,
/* Read the queue */
MEMR(npu_dev, (void *)((size_t)offset), (uint8_t *)&queue,
HFI_QUEUE_HEADER_SIZE);
if (queue.qhdr_type != npu_q_setup[target_que].hdr ||
queue.qhdr_q_size != npu_q_setup[target_que].size ||
queue.qhdr_read_idx >= queue.qhdr_q_size ||
queue.qhdr_write_idx >= queue.qhdr_q_size ||
queue.qhdr_start_offset !=
npu_q_setup[target_que].start_offset) {
pr_err("Invalid Queue header\n");
status = -EIO;
goto exit;
}
/* check if queue is empty */
if (queue.qhdr_read_idx == queue.qhdr_write_idx) {
/*
@ -235,8 +249,10 @@ static int ipc_queue_read(struct npu_device *npu_dev,
target_que,
packet_size);
if (packet_size == 0) {
status = -EPERM;
if ((packet_size == 0) ||
(packet_size > NPU_IPC_BUF_LENGTH)) {
pr_err("Invalid packet size %d\n", packet_size);
status = -EINVAL;
goto exit;
}
new_read_idx = queue.qhdr_read_idx + packet_size;
@ -306,6 +322,18 @@ static int ipc_queue_write(struct npu_device *npu_dev,
MEMR(npu_dev, (void *)((size_t)offset), (uint8_t *)&queue,
HFI_QUEUE_HEADER_SIZE);
if (queue.qhdr_type != npu_q_setup[target_que].hdr ||
queue.qhdr_q_size != npu_q_setup[target_que].size ||
queue.qhdr_read_idx >= queue.qhdr_q_size ||
queue.qhdr_write_idx >= queue.qhdr_q_size ||
queue.qhdr_start_offset !=
npu_q_setup[target_que].start_offset) {
pr_err("Invalid Queue header\n");
status = -EIO;
goto exit;
}
packet_size = (*(uint32_t *)packet);
if (packet_size == 0) {
/* assign failed status and return */

View file

@ -442,49 +442,3 @@ void subsystem_put_local(void *sub_system_handle)
return subsystem_put(sub_system_handle);
}
/* -------------------------------------------------------------------------
* Functions - Log
* -------------------------------------------------------------------------
*/
void npu_process_log_message(struct npu_device *npu_dev, uint32_t *message,
uint32_t size)
{
struct npu_debugfs_ctx *debugfs = &npu_dev->debugfs_ctx;
/* mutex log lock */
mutex_lock(&debugfs->log_lock);
if ((debugfs->log_num_bytes_buffered + size) >
debugfs->log_buf_size) {
/* No more space, invalidate it all and start over */
debugfs->log_read_index = 0;
debugfs->log_write_index = size;
debugfs->log_num_bytes_buffered = size;
memcpy(debugfs->log_buf, message, size);
} else {
if ((debugfs->log_write_index + size) >
debugfs->log_buf_size) {
/* Wrap around case */
uint8_t *src_addr = (uint8_t *)message;
uint8_t *dst_addr = NULL;
uint32_t remaining_to_end = debugfs->log_buf_size -
debugfs->log_write_index + 1;
dst_addr = debugfs->log_buf + debugfs->log_write_index;
memcpy(dst_addr, src_addr, remaining_to_end);
src_addr = &(src_addr[remaining_to_end]);
dst_addr = debugfs->log_buf;
memcpy(dst_addr, src_addr, size-remaining_to_end);
debugfs->log_write_index = size-remaining_to_end;
} else {
memcpy((debugfs->log_buf + debugfs->log_write_index),
message, size);
debugfs->log_write_index += size;
if (debugfs->log_write_index == debugfs->log_buf_size)
debugfs->log_write_index = 0;
}
debugfs->log_num_bytes_buffered += size;
}
/* mutex log unlock */
mutex_unlock(&debugfs->log_lock);
}

View file

@ -83,7 +83,4 @@ void npu_disable_sys_cache(struct npu_device *npu_dev);
void *subsystem_get_local(char *sub_system);
void subsystem_put_local(void *sub_system_handle);
void npu_process_log_message(struct npu_device *npu_dev, uint32_t *msg,
uint32_t size);
#endif /* _NPU_HW_ACCESS_H*/

View file

@ -20,11 +20,6 @@
* Defines
* -------------------------------------------------------------------------
*/
#define LOG_MSG_HEADER_SIZE 20
#define LOG_MSG_START_MSG_INDEX 5
#define LOG_MSG_TOTAL_SIZE_INDEX 0
#define LOG_MSG_MSG_ID_INDEX 1
#define NPU_FW_TIMEOUT_POLL_INTERVAL_MS 10
#define NPU_FW_TIMEOUT_MS 1000
@ -48,9 +43,7 @@ static void free_network(struct npu_host_ctx *ctx, struct npu_client *client,
static int network_get(struct npu_network *network);
static int network_put(struct npu_network *network);
static void app_msg_proc(struct npu_host_ctx *host_ctx, uint32_t *msg);
static void log_msg_proc(struct npu_device *npu_dev, uint32_t *msg);
static void host_session_msg_hdlr(struct npu_device *npu_dev);
static void host_session_log_hdlr(struct npu_device *npu_dev);
static int host_error_hdlr(struct npu_device *npu_dev, bool force);
static int npu_send_network_cmd(struct npu_device *npu_dev,
struct npu_network *network, void *cmd_ptr);
@ -391,7 +384,6 @@ static void host_irq_wq(struct work_struct *work)
if (host_error_hdlr(npu_dev, false))
return;
host_session_log_hdlr(npu_dev);
host_session_msg_hdlr(npu_dev);
}
@ -768,6 +760,12 @@ static void app_msg_proc(struct npu_host_ctx *host_ctx, uint32_t *msg)
}
pr_debug("network id : %llu\n", network->id);
if (exe_rsp_pkt->header.size < sizeof(*exe_rsp_pkt)) {
pr_err("invalid packet header size, header.size: %d\n",
exe_rsp_pkt->header.size);
network_put(network);
break;
}
stats_size = exe_rsp_pkt->header.size - sizeof(*exe_rsp_pkt);
pr_debug("stats_size %d:%d\n", exe_rsp_pkt->header.size,
stats_size);
@ -986,52 +984,6 @@ skip_read_msg:
kfree(msg);
}
static void log_msg_proc(struct npu_device *npu_dev, uint32_t *msg)
{
uint32_t msg_id;
uint32_t *log_msg;
uint32_t size;
msg_id = msg[LOG_MSG_MSG_ID_INDEX];
size = msg[LOG_MSG_TOTAL_SIZE_INDEX] - LOG_MSG_HEADER_SIZE;
switch (msg_id) {
case NPU_IPC_MSG_EVENT_NOTIFY:
/* Process the message */
log_msg = &(msg[LOG_MSG_START_MSG_INDEX]);
npu_process_log_message(npu_dev, log_msg, size);
break;
default:
pr_err("unsupported log response received %d\n", msg_id);
break;
}
}
static void host_session_log_hdlr(struct npu_device *npu_dev)
{
uint32_t *msg;
struct npu_host_ctx *host_ctx = &npu_dev->host_ctx;
msg = kzalloc(sizeof(uint32_t) * NPU_IPC_BUF_LENGTH, GFP_KERNEL);
if (!msg)
return;
mutex_lock(&host_ctx->lock);
if (host_ctx->fw_state == FW_DISABLED) {
pr_warn("handle npu session msg when FW is disabled\n");
goto skip_read_msg;
}
while (npu_host_ipc_read_msg(npu_dev, IPC_QUEUE_LOG, msg) == 0) {
pr_debug("received from log queue\n");
log_msg_proc(npu_dev, msg);
}
skip_read_msg:
mutex_unlock(&host_ctx->lock);
kfree(msg);
}
/* -------------------------------------------------------------------------
* Function Definitions - Functionality

View file

@ -2259,6 +2259,7 @@ static int mmc_cache_card_ext_csd(struct mmc_host *host)
return 0;
}
#if defined(CONFIG_SDC_QTI)
static int mmc_test_awake_ext_csd(struct mmc_host *host)
{
int err;
@ -2273,7 +2274,6 @@ static int mmc_test_awake_ext_csd(struct mmc_host *host)
}
/* only compare read/write fields that the sw changes */
#if defined(CONFIG_SDC_QTI)
pr_debug("%s: %s: type(cached:current) cmdq(%d:%d) cache_ctrl(%d:%d) bus_width (%d:%d) timing(%d:%d)\n",
mmc_hostname(host), __func__,
card->ext_csd.raw_ext_csd_cmdq,
@ -2292,12 +2292,12 @@ static int mmc_test_awake_ext_csd(struct mmc_host *host)
ext_csd[EXT_CSD_BUS_WIDTH]) &&
(card->ext_csd.raw_ext_csd_hs_timing ==
ext_csd[EXT_CSD_HS_TIMING]));
#endif
kfree(ext_csd);
return err;
}
#endif
static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
{
@ -2305,11 +2305,13 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
unsigned int notify_type = is_suspend ? EXT_CSD_POWER_OFF_SHORT :
EXT_CSD_POWER_OFF_LONG;
#if defined(CONFIG_SDC_QTI)
err = mmc_suspend_clk_scaling(host);
if (err) {
pr_err("%s: %s: fail to suspend clock scaling (%d)\n",
mmc_hostname(host), __func__, err);
return err;
if (!host->partial_init_broken) {
err = mmc_suspend_clk_scaling(host);
if (err) {
pr_err("%s: %s: fail to suspend clock scaling (%d)\n",
mmc_hostname(host), __func__, err);
return err;
}
}
#endif
mmc_log_string(host, "Enter\n");
@ -2328,8 +2330,9 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
if (mmc_can_sleep(host->card)) {
#if defined(CONFIG_SDC_QTI)
memcpy(&host->cached_ios, &host->ios, sizeof(host->cached_ios));
if (!host->partial_init_broken)
#endif
mmc_cache_card_ext_csd(host);
mmc_cache_card_ext_csd(host);
}
if (mmc_can_sleep(host->card))
err = mmc_sleepawake(host, true);
@ -2351,24 +2354,21 @@ out:
return err;
}
#if defined(CONFIG_SDC_QTI)
static int mmc_partial_init(struct mmc_host *host)
{
int err = 0;
struct mmc_card *card = host->card;
#if defined(CONFIG_SDC_QTI)
mmc_set_bus_width(host, host->cached_ios.bus_width);
mmc_set_timing(host, host->cached_ios.timing);
if (host->cached_ios.enhanced_strobe) {
#endif
host->ios.enhanced_strobe = true;
if (host->ops->hs400_enhanced_strobe)
host->ops->hs400_enhanced_strobe(host, &host->ios);
#if defined(CONFIG_SDC_QTI)
}
mmc_set_clock(host, host->cached_ios.clock);
mmc_set_bus_mode(host, host->cached_ios.bus_mode);
#endif
if (!mmc_card_hs400es(card) &&
(mmc_card_hs200(card) || mmc_card_hs400(card))) {
@ -2396,6 +2396,7 @@ static int mmc_partial_init(struct mmc_host *host)
out:
return err;
}
#endif
/*
* Suspend callback
@ -2440,14 +2441,23 @@ static int _mmc_resume(struct mmc_host *host)
if (mmc_can_sleep(host->card)) {
err = mmc_sleepawake(host, false);
if (!err)
err = mmc_partial_init(host);
#if defined(CONFIG_SDC_QTI)
if (!err) {
if (host->partial_init_broken)
err = mmc_init_card(host, host->card->ocr, host->card);
else
err = mmc_partial_init(host);
}
else
pr_err("%s: %s: awake failed (%d), fallback to full init\n",
mmc_hostname(host), __func__, err);
#endif
}
#if defined(CONFIG_SDC_QTI)
if (err)
#endif
err = mmc_init_card(host, host->card->ocr, host->card);
mmc_card_clr_suspended(host->card);
@ -2458,10 +2468,12 @@ out:
mmc_release_host(host);
#if defined(CONFIG_SDC_QTI)
err = mmc_resume_clk_scaling(host);
if (err)
pr_err("%s: %s: fail to resume clock scaling (%d)\n",
mmc_hostname(host), __func__, err);
if (!host->partial_init_broken) {
err = mmc_resume_clk_scaling(host);
if (err)
pr_err("%s: %s: fail to resume clock scaling (%d)\n",
mmc_hostname(host), __func__, err);
}
out:
#endif
mmc_log_string(host, "Exit err %d\n", err);

View file

@ -3,6 +3,7 @@
* drivers/mmc/host/sdhci-msm.c - Qualcomm SDHCI Platform driver
*
* Copyright (c) 2013-2014,2020. The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/module.h>
@ -1869,6 +1870,12 @@ static bool sdhci_msm_populate_pdata(struct device *dev,
if (sdhci_msm_dt_parse_hsr_info(dev, msm_host))
goto out;
#if defined(CONFIG_SDC_QTI)
msm_host->mmc->partial_init_broken =
of_property_read_bool(dev->of_node,
"qcom,partial_init_broken");
#endif
if (!sdhci_msm_dt_get_array(dev, "qcom,ice-clk-rates",
&ice_clk_table, &ice_clk_table_len, 0)) {
if (ice_clk_table && ice_clk_table_len) {
@ -4268,6 +4275,11 @@ static void sdhci_msm_set_caps(struct sdhci_msm_host *msm_host)
{
msm_host->mmc->caps |= MMC_CAP_AGGRESSIVE_PM;
msm_host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_NEED_RSP_BUSY;
#if defined(CONFIG_SDC_QTI)
if (!msm_host->mmc->partial_init_broken)
msm_host->mmc->caps2 |= MMC_CAP2_CLK_SCALE;
#endif
}
static int sdhci_msm_probe(struct platform_device *pdev)
@ -4546,8 +4558,8 @@ static int sdhci_msm_probe(struct platform_device *pdev)
#if defined(CONFIG_SDC_QTI)
host->timeout_clk_div = 4;
msm_host->mmc->caps2 |= MMC_CAP2_CLK_SCALE;
#endif
sdhci_msm_setup_pm(pdev, msm_host);
host->mmc_host_ops.execute_tuning = sdhci_msm_execute_tuning;

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
// Copyright (c) 2018, Linaro Limited
// Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
#include <linux/irq.h>
#include <linux/kernel.h>
@ -156,6 +157,8 @@ struct qcom_slim_ngd_ctrl {
struct completion reconf;
struct work_struct m_work;
struct workqueue_struct *mwq;
struct completion xfer_done;
struct completion sync_done;
spinlock_t tx_buf_lock;
enum qcom_slim_ngd_state state;
dma_addr_t rx_phys_base;
@ -768,7 +771,6 @@ static int qcom_slim_ngd_xfer_msg(struct slim_controller *sctrl,
{
struct qcom_slim_ngd_ctrl *ctrl = dev_get_drvdata(sctrl->dev);
DECLARE_COMPLETION_ONSTACK(tx_sent);
DECLARE_COMPLETION_ONSTACK(done);
int ret, timeout, i;
u8 wbuf[SLIM_MSGQ_BUF_LEN];
u8 rbuf[SLIM_MSGQ_BUF_LEN];
@ -777,6 +779,8 @@ static int qcom_slim_ngd_xfer_msg(struct slim_controller *sctrl,
u8 la = txn->la;
bool usr_msg = false;
reinit_completion(&ctrl->xfer_done);
if (txn->mt == SLIM_MSG_MT_CORE &&
(txn->mc >= SLIM_MSG_MC_BEGIN_RECONFIGURATION &&
txn->mc <= SLIM_MSG_MC_RECONFIGURE_NOW))
@ -824,7 +828,7 @@ static int qcom_slim_ngd_xfer_msg(struct slim_controller *sctrl,
if (txn->mc != SLIM_USR_MC_DISCONNECT_PORT)
wbuf[i++] = txn->msg->wbuf[1];
txn->comp = &done;
txn->comp = &ctrl->xfer_done;
ret = slim_alloc_txn_tid(sctrl, txn);
if (ret) {
dev_err(ctrl->dev, "Unable to allocate TID\n");
@ -876,7 +880,7 @@ static int qcom_slim_ngd_xfer_msg(struct slim_controller *sctrl,
}
if (usr_msg) {
timeout = wait_for_completion_timeout(&done, HZ);
timeout = wait_for_completion_timeout(&ctrl->xfer_done, HZ);
if (!timeout) {
dev_err(sctrl->dev, "TX timed out:MC:0x%x,mt:0x%x",
txn->mc, txn->mt);
@ -890,18 +894,21 @@ static int qcom_slim_ngd_xfer_msg(struct slim_controller *sctrl,
static int qcom_slim_ngd_xfer_msg_sync(struct slim_controller *ctrl,
struct slim_msg_txn *txn)
{
DECLARE_COMPLETION_ONSTACK(done);
struct qcom_slim_ngd_ctrl *dev =
container_of(ctrl, struct qcom_slim_ngd_ctrl, ctrl);
int ret, timeout;
reinit_completion(&dev->sync_done);
pm_runtime_get_sync(ctrl->dev);
txn->comp = &done;
txn->comp = &dev->sync_done;
ret = qcom_slim_ngd_xfer_msg(ctrl, txn);
if (ret)
return ret;
timeout = wait_for_completion_timeout(&done, HZ);
timeout = wait_for_completion_timeout(&dev->sync_done, HZ);
if (!timeout) {
dev_err(ctrl->dev, "TX timed out:MC:0x%x,mt:0x%x", txn->mc,
txn->mt);
@ -1460,6 +1467,9 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev)
init_completion(&ctrl->reconf);
init_completion(&ctrl->qmi.qmi_comp);
init_completion(&ctrl->xfer_done);
init_completion(&ctrl->sync_done);
platform_driver_register(&qcom_slim_ngd_driver);
return of_qcom_slim_ngd_register(dev, ctrl);
}

View file

@ -645,6 +645,16 @@ config MINIDUMP_MAX_ENTRIES
This defines maximum number of entries to be allocated for application
subsytem in Minidump table.
config QCOM_MINIDUMP_ENCRYPT
bool "QCOM Minidump Encryption Required"
depends on QCOM_MINIDUMP
default y
help
This adds a support to decide whether the regions in minidump
table should be encrypted or not. By default, encryption is done
by the boot firmware and the decision for encryption is taken by
the subsystems.
config QCOM_MICRODUMP
tristate "Qualcomm Technologies, Inc. Microdump Support"
depends on MSM_SUBSYSTEM_RESTART

View file

@ -1,532 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*
*/
#include <linux/bitmap.h>
#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/kernel.h>
#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>
#include <linux/soc/qcom/llcc-tcm.h>
#define ACTIVATE BIT(0)
#define DEACTIVATE BIT(1)
#define ACT_CTRL_OPCODE_ACTIVATE BIT(0)
#define ACT_CTRL_OPCODE_DEACTIVATE BIT(1)
#define ACT_CTRL_ACT_TRIG BIT(0)
#define ACT_CTRL_OPCODE_SHIFT 0x01
#define ATTR1_PROBE_TARGET_WAYS_SHIFT 0x02
#define ATTR1_FIXED_SIZE_SHIFT 0x03
#define ATTR1_PRIORITY_SHIFT 0x04
#define ATTR1_MAX_CAP_SHIFT 0x10
#define ATTR0_RES_WAYS_MASK GENMASK(11, 0)
#define ATTR0_BONUS_WAYS_MASK GENMASK(27, 16)
#define ATTR0_BONUS_WAYS_SHIFT 0x10
#define LLCC_STATUS_READ_DELAY 100
#define CACHE_LINE_SIZE_SHIFT 6
#define LLCC_COMMON_STATUS0 0x0003000c
#define LLCC_LB_CNT_MASK GENMASK(31, 28)
#define LLCC_LB_CNT_SHIFT 28
#define MAX_CAP_TO_BYTES(n) (n * SZ_1K)
#define LLCC_TRP_ACT_CTRLn(n) (n * SZ_4K)
#define LLCC_TRP_STATUSn(n) (4 + n * SZ_4K)
#define LLCC_TRP_ATTR0_CFGn(n) (0x21000 + SZ_8 * n)
#define LLCC_TRP_ATTR1_CFGn(n) (0x21004 + SZ_8 * n)
#define LLCC_TRP_C_AS_NC 0x22890
#define LLCC_TRP_NC_AS_C 0x22894
#define LLCC_FEAC_C_AS_NC 0x35030
#define LLCC_FEAC_NC_AS_C 0x35034
#define LLCC_TRP_WRSC_EN 0x21F20
#define LLCC_WRSC_SCID_EN(n) BIT(n)
#define LLCC_TRP_PCB_ACT 0x21F04
#define LLCC_TRP_SCID_DIS_CAP_ALLOC 0x21F00
#define BANK_OFFSET_STRIDE 0x80000
static struct llcc_slice_config sdm845_data[] = {
{ LLCC_CPUSS, 1, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 1 },
{ LLCC_VIDSC0, 2, 512, 2, 1, 0x0, 0x0f0, 0, 0, 1, 1, 0 },
{ LLCC_VIDSC1, 3, 512, 2, 1, 0x0, 0x0f0, 0, 0, 1, 1, 0 },
{ LLCC_ROTATOR, 4, 563, 2, 1, 0x0, 0x00e, 2, 0, 1, 1, 0 },
{ LLCC_VOICE, 5, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 },
{ LLCC_AUDIO, 6, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 },
{ LLCC_MDMHPGRW, 7, 1024, 2, 0, 0xfc, 0xf00, 0, 0, 1, 1, 0 },
{ LLCC_MDM, 8, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 },
{ LLCC_CMPT, 10, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 },
{ LLCC_GPUHTW, 11, 512, 1, 1, 0xc, 0x0, 0, 0, 1, 1, 0 },
{ LLCC_GPU, 12, 2304, 1, 0, 0xff0, 0x2, 0, 0, 1, 1, 0 },
{ LLCC_MMUHWT, 13, 256, 2, 0, 0x0, 0x1, 0, 0, 1, 0, 1 },
{ LLCC_CMPTDMA, 15, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 },
{ LLCC_DISP, 16, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 },
{ LLCC_VIDFW, 17, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 },
{ LLCC_MDMHPFX, 20, 1024, 2, 1, 0x0, 0xf00, 0, 0, 1, 1, 0 },
{ LLCC_MDMPNG, 21, 1024, 0, 1, 0x1e, 0x0, 0, 0, 1, 1, 0 },
{ LLCC_AUDHW, 22, 1024, 1, 1, 0xffc, 0x2, 0, 0, 1, 1, 0 },
};
static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER;
static struct regmap_config llcc_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
.fast_io = true,
};
/**
* llcc_slice_getd - get llcc slice descriptor
* @uid: usecase_id for the client
*
* A pointer to llcc slice descriptor will be returned on success and
* and error pointer is returned on failure
*/
struct llcc_slice_desc *llcc_slice_getd(u32 uid)
{
const struct llcc_slice_config *cfg;
struct llcc_slice_desc *desc;
u32 sz, count;
if (IS_ERR(drv_data))
return ERR_CAST(drv_data);
cfg = drv_data->cfg;
sz = drv_data->cfg_size;
for (count = 0; cfg && count < sz; count++, cfg++)
if (cfg->usecase_id == uid)
break;
if (count == sz || !cfg)
return ERR_PTR(-ENODEV);
desc = kzalloc(sizeof(*desc), GFP_KERNEL);
if (!desc)
return ERR_PTR(-ENOMEM);
desc->slice_id = cfg->slice_id;
desc->slice_size = cfg->max_cap;
return desc;
}
EXPORT_SYMBOL_GPL(llcc_slice_getd);
/**
* llcc_slice_putd - llcc slice descritpor
* @desc: Pointer to llcc slice descriptor
*/
void llcc_slice_putd(struct llcc_slice_desc *desc)
{
if (!IS_ERR_OR_NULL(desc))
kfree(desc);
}
EXPORT_SYMBOL_GPL(llcc_slice_putd);
static int llcc_update_act_ctrl(u32 sid,
u32 act_ctrl_reg_val, u32 status)
{
u32 act_ctrl_reg;
u32 status_reg;
u32 slice_status;
int ret;
if (IS_ERR(drv_data))
return PTR_ERR(drv_data);
act_ctrl_reg = LLCC_TRP_ACT_CTRLn(sid);
status_reg = LLCC_TRP_STATUSn(sid);
/* Set the ACTIVE trigger */
act_ctrl_reg_val |= ACT_CTRL_ACT_TRIG;
ret = regmap_write(drv_data->bcast_regmap, act_ctrl_reg,
act_ctrl_reg_val);
if (ret)
return ret;
/* Clear the ACTIVE trigger */
act_ctrl_reg_val &= ~ACT_CTRL_ACT_TRIG;
ret = regmap_write(drv_data->bcast_regmap, act_ctrl_reg,
act_ctrl_reg_val);
if (ret)
return ret;
ret = regmap_read_poll_timeout(drv_data->bcast_regmap, status_reg,
slice_status, !(slice_status & status),
0, LLCC_STATUS_READ_DELAY);
return ret;
}
/**
* llcc_slice_activate - Activate the llcc slice
* @desc: Pointer to llcc slice descriptor
*
* A value of zero will be returned on success and a negative errno will
* be returned in error cases
*/
int llcc_slice_activate(struct llcc_slice_desc *desc)
{
int ret;
u32 act_ctrl_val;
if (IS_ERR(drv_data))
return PTR_ERR(drv_data);
if (IS_ERR_OR_NULL(desc))
return -EINVAL;
mutex_lock(&drv_data->lock);
if (test_bit(desc->slice_id, drv_data->bitmap)) {
mutex_unlock(&drv_data->lock);
return 0;
}
act_ctrl_val = ACT_CTRL_OPCODE_ACTIVATE << ACT_CTRL_OPCODE_SHIFT;
ret = llcc_update_act_ctrl(desc->slice_id, act_ctrl_val,
DEACTIVATE);
if (ret) {
mutex_unlock(&drv_data->lock);
return ret;
}
__set_bit(desc->slice_id, drv_data->bitmap);
mutex_unlock(&drv_data->lock);
return ret;
}
EXPORT_SYMBOL_GPL(llcc_slice_activate);
/**
* llcc_slice_deactivate - Deactivate the llcc slice
* @desc: Pointer to llcc slice descriptor
*
* A value of zero will be returned on success and a negative errno will
* be returned in error cases
*/
int llcc_slice_deactivate(struct llcc_slice_desc *desc)
{
u32 act_ctrl_val;
int ret;
if (IS_ERR(drv_data))
return PTR_ERR(drv_data);
if (IS_ERR_OR_NULL(desc))
return -EINVAL;
mutex_lock(&drv_data->lock);
if (!test_bit(desc->slice_id, drv_data->bitmap)) {
mutex_unlock(&drv_data->lock);
return 0;
}
act_ctrl_val = ACT_CTRL_OPCODE_DEACTIVATE << ACT_CTRL_OPCODE_SHIFT;
ret = llcc_update_act_ctrl(desc->slice_id, act_ctrl_val,
ACTIVATE);
if (ret) {
mutex_unlock(&drv_data->lock);
return ret;
}
__clear_bit(desc->slice_id, drv_data->bitmap);
mutex_unlock(&drv_data->lock);
return ret;
}
EXPORT_SYMBOL_GPL(llcc_slice_deactivate);
/**
* llcc_get_slice_id - return the slice id
* @desc: Pointer to llcc slice descriptor
*/
int llcc_get_slice_id(struct llcc_slice_desc *desc)
{
if (IS_ERR_OR_NULL(desc))
return -EINVAL;
return desc->slice_id;
}
EXPORT_SYMBOL_GPL(llcc_get_slice_id);
/**
* llcc_get_slice_size - return the slice id
* @desc: Pointer to llcc slice descriptor
*/
size_t llcc_get_slice_size(struct llcc_slice_desc *desc)
{
if (IS_ERR_OR_NULL(desc))
return 0;
return desc->slice_size;
}
EXPORT_SYMBOL_GPL(llcc_get_slice_size);
static int qcom_llcc_cfg_program(struct platform_device *pdev)
{
int i;
u32 attr1_cfg;
u32 attr0_cfg;
u32 attr1_val;
u32 attr0_val;
u32 max_cap_cacheline;
u32 sz;
u32 pcb = 0;
u32 cad = 0;
u32 wren = 0;
int ret = 0;
const struct llcc_slice_config *llcc_table;
struct llcc_slice_desc desc;
bool cap_based_alloc_and_pwr_collapse =
drv_data->cap_based_alloc_and_pwr_collapse;
int v2_ver = of_device_is_compatible(pdev->dev.of_node,
"qcom,llcc-v2");
sz = drv_data->cfg_size;
llcc_table = drv_data->cfg;
for (i = 0; i < sz; i++) {
attr1_cfg = LLCC_TRP_ATTR1_CFGn(llcc_table[i].slice_id);
attr0_cfg = LLCC_TRP_ATTR0_CFGn(llcc_table[i].slice_id);
attr1_val = llcc_table[i].cache_mode;
attr1_val |= llcc_table[i].probe_target_ways <<
ATTR1_PROBE_TARGET_WAYS_SHIFT;
attr1_val |= llcc_table[i].fixed_size <<
ATTR1_FIXED_SIZE_SHIFT;
attr1_val |= llcc_table[i].priority <<
ATTR1_PRIORITY_SHIFT;
max_cap_cacheline = MAX_CAP_TO_BYTES(llcc_table[i].max_cap);
/* LLCC instances can vary for each target.
* The SW writes to broadcast register which gets propagated
* to each llcc instace (llcc0,.. llccN).
* Since the size of the memory is divided equally amongst the
* llcc instances, we need to configure the max cap accordingly.
*/
max_cap_cacheline = max_cap_cacheline / drv_data->num_banks;
max_cap_cacheline >>= CACHE_LINE_SIZE_SHIFT;
attr1_val |= max_cap_cacheline << ATTR1_MAX_CAP_SHIFT;
attr0_val = llcc_table[i].res_ways & ATTR0_RES_WAYS_MASK;
attr0_val |= llcc_table[i].bonus_ways << ATTR0_BONUS_WAYS_SHIFT;
ret = regmap_write(drv_data->bcast_regmap, attr1_cfg,
attr1_val);
if (ret)
return ret;
ret = regmap_write(drv_data->bcast_regmap, attr0_cfg,
attr0_val);
if (ret)
return ret;
if (v2_ver) {
wren |= llcc_table[i].write_scid_en <<
llcc_table[i].slice_id;
ret = regmap_write(drv_data->bcast_regmap,
LLCC_TRP_WRSC_EN, wren);
if (ret)
return ret;
}
if (cap_based_alloc_and_pwr_collapse) {
cad |= llcc_table[i].dis_cap_alloc <<
llcc_table[i].slice_id;
ret = regmap_write(drv_data->bcast_regmap,
LLCC_TRP_SCID_DIS_CAP_ALLOC, cad);
if (ret)
return ret;
pcb |= llcc_table[i].retain_on_pc <<
llcc_table[i].slice_id;
ret = regmap_write(drv_data->bcast_regmap,
LLCC_TRP_PCB_ACT, pcb);
if (ret)
return ret;
}
if (llcc_table[i].activate_on_init) {
desc.slice_id = llcc_table[i].slice_id;
ret = llcc_slice_activate(&desc);
}
}
return ret;
}
static int qcom_llcc_remove(struct platform_device *pdev)
{
/* Set the global pointer to a error code to avoid referencing it */
drv_data = ERR_PTR(-ENODEV);
return 0;
}
static struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev,
const char *name)
{
struct resource *res;
void __iomem *base;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
if (!res)
return ERR_PTR(-ENODEV);
base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base))
return ERR_CAST(base);
llcc_regmap_config.name = name;
return devm_regmap_init_mmio(&pdev->dev, base, &llcc_regmap_config);
}
static int qcom_llcc_probe(struct platform_device *pdev,
const struct llcc_slice_config *llcc_cfg, u32 sz)
{
u32 num_banks;
struct device *dev = &pdev->dev;
int ret, i;
struct platform_device *llcc_edac, *llcc_perfmon;
struct device_node *tcm_memory_node;
if (!IS_ERR(drv_data))
return -EBUSY;
drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL);
if (!drv_data) {
ret = -ENOMEM;
goto err;
}
drv_data->regmap = qcom_llcc_init_mmio(pdev, "llcc_base");
if (IS_ERR(drv_data->regmap)) {
ret = PTR_ERR(drv_data->regmap);
goto err;
}
drv_data->bcast_regmap =
qcom_llcc_init_mmio(pdev, "llcc_broadcast_base");
if (PTR_ERR(drv_data->bcast_regmap) == -ENODEV)
drv_data->bcast_regmap = drv_data->regmap;
else if (IS_ERR(drv_data->bcast_regmap)) {
ret = PTR_ERR(drv_data->bcast_regmap);
goto err;
}
ret = regmap_read(drv_data->regmap, LLCC_COMMON_STATUS0,
&num_banks);
if (ret)
goto err;
num_banks &= LLCC_LB_CNT_MASK;
num_banks >>= LLCC_LB_CNT_SHIFT;
drv_data->num_banks = num_banks;
for (i = 0; i < sz; i++)
if (llcc_cfg[i].slice_id > drv_data->max_slices)
drv_data->max_slices = llcc_cfg[i].slice_id;
drv_data->offsets = devm_kcalloc(dev, num_banks, sizeof(u32),
GFP_KERNEL);
if (!drv_data->offsets) {
ret = -ENOMEM;
goto err;
}
drv_data->cap_based_alloc_and_pwr_collapse =
of_property_read_bool(pdev->dev.of_node,
"cap-based-alloc-and-pwr-collapse");
for (i = 0; i < num_banks; i++)
drv_data->offsets[i] = i * BANK_OFFSET_STRIDE;
drv_data->bitmap = devm_kcalloc(dev,
BITS_TO_LONGS(drv_data->max_slices), sizeof(unsigned long),
GFP_KERNEL);
if (!drv_data->bitmap) {
ret = -ENOMEM;
goto err;
}
drv_data->cfg = llcc_cfg;
drv_data->cfg_size = sz;
mutex_init(&drv_data->lock);
platform_set_drvdata(pdev, drv_data);
ret = qcom_llcc_cfg_program(pdev);
if (ret) {
pr_err("llcc configuration failed!!\n");
goto err;
}
drv_data->ecc_irq = platform_get_irq(pdev, 0);
llcc_edac = platform_device_register_data(&pdev->dev,
"qcom_llcc_edac", -1, drv_data,
sizeof(*drv_data));
if (IS_ERR(llcc_edac))
dev_err(dev, "Failed to register llcc edac driver\n");
llcc_perfmon = platform_device_register_data(&pdev->dev,
"qcom_llcc_perfmon", -1,
drv_data, sizeof(*drv_data));
if (IS_ERR(llcc_perfmon))
dev_err(dev, "Failed to register llcc perfmon device\n");
tcm_memory_node = of_parse_phandle(dev->of_node, "memory-region", 0);
if (tcm_memory_node) {
ret = qcom_llcc_tcm_probe(pdev, llcc_cfg, sz, tcm_memory_node);
if (ret) {
dev_err(dev, "Failed to probe TCM manager\n");
goto err_dereg;
}
}
return 0;
err_dereg:
platform_device_unregister(llcc_edac);
platform_device_unregister(llcc_perfmon);
err:
drv_data = ERR_PTR(-ENODEV);
return ret;
}
static int sdm845_qcom_llcc_remove(struct platform_device *pdev)
{
return qcom_llcc_remove(pdev);
}
static int sdm845_qcom_llcc_probe(struct platform_device *pdev)
{
return qcom_llcc_probe(pdev, sdm845_data, ARRAY_SIZE(sdm845_data));
}
static const struct of_device_id sdm845_qcom_llcc_of_match[] = {
{ .compatible = "qcom,sdm845-llcc", },
{ }
};
static struct platform_driver sdm845_qcom_llcc_driver = {
.driver = {
.name = "sdm845-llcc",
.of_match_table = sdm845_qcom_llcc_of_match,
},
.probe = sdm845_qcom_llcc_probe,
.remove = sdm845_qcom_llcc_remove,
};
module_platform_driver(sdm845_qcom_llcc_driver);
MODULE_DESCRIPTION("QCOM sdm845 LLCC driver");
MODULE_LICENSE("GPL v2");

View file

@ -379,6 +379,9 @@ int qcom_llcc_probe(struct platform_device *pdev,
struct platform_device *llcc_edac, *llcc_perfmon;
struct device_node *tcm_memory_node;
if (!IS_ERR(drv_data))
return -EBUSY;
drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL);
if (!drv_data) {
ret = -ENOMEM;

View file

@ -570,8 +570,13 @@ static int __init msm_minidump_init(void)
minidump_table.revision = md_global_toc->md_revision;
md_ss_toc = &md_global_toc->md_ss_toc[MD_SS_HLOS_ID];
md_ss_toc->encryption_status = MD_SS_ENCR_NONE;
md_ss_toc->encryption_required = MD_SS_ENCR_REQ;
if (IS_ENABLED(CONFIG_QCOM_MINIDUMP_ENCRYPT)) {
md_ss_toc->encryption_status = MD_SS_ENCR_NONE;
md_ss_toc->encryption_required = MD_SS_ENCR_REQ;
} else {
md_ss_toc->encryption_status = MD_SS_ENCR_DONE;
md_ss_toc->encryption_required = MD_SS_ENCR_NOTREQ;
}
minidump_table.md_ss_toc = md_ss_toc;
minidump_table.md_regions = kzalloc((MAX_NUM_ENTRIES *

View file

@ -1780,9 +1780,6 @@ static int dwc3_probe(struct platform_device *pdev)
pm_runtime_allow(dev);
dwc3_debugfs_init(dwc);
dma_set_max_seg_size(dev, UINT_MAX);
return 0;
err3:

View file

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018 - 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 - 2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022 - 2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _IPA_WDI3_H_
@ -73,7 +73,7 @@ typedef void (*ipa_wdi_mesh_ast_notifier_cb)(void *priv, unsigned long data);
* @wdi_notify: bw notification cb
* inst_id: Instance ID
* @ast_update: AST update needed or not.
* @is_hsp: need to identify if attach is hsp/pine.
* @rx_tlv_format: need to identify rx tlv format hsp(1)/pine(0).
*/
struct ipa_wdi_init_in_params {
enum ipa_wdi_version wdi_version;
@ -85,6 +85,7 @@ struct ipa_wdi_init_in_params {
int inst_id;
bool ast_update;
bool is_hsp;
u8 rx_tlv_format;
};
/**

View file

@ -597,6 +597,7 @@ struct mmc_host {
bool hsq_enabled;
#if defined(CONFIG_SDC_QTI)
bool need_hw_reset;
bool partial_init_broken;
#endif
#if defined(CONFIG_SDC_QTI)

View file

@ -152,6 +152,8 @@
#define IPA_IOCTL_SET_EXT_ROUTER_MODE 95
#define IPA_IOCTL_ADD_DEL_DSCP_PCP_MAPPING 96
#define IPA_IOCTL_SEND_VLAN_MUXID_MAPPING 97
#define IPA_IOCTL_SEND_TUNNEL_TEMPLATE_INFO 98
#define IPA_IOCTL_QUERY_TUNNEL_FEATURE 99
/**
* max size of the header to be inserted
*/
@ -1776,6 +1778,104 @@ struct ipa_ioc_mux_mapping_table {
struct singletag_mux_map_entry map_entries[MAX_VLAN_CONFIGURE];
};
/* Feature Type Supported Design*/
/* Cache all Design Support with Regular HPS for both EoGRE and MPLSoGRE tunnel */
#define DEFAULT_FEATURE 0x00
/* EoGRE to support Single Tag packet with new HPS */
#define SINGLE_TAG_FEATURE 0x01
/* MPLSoGRE to support Double Tag packet with new HPS */
#define DOUBLE_TAG_FEATURE 0x02
/* EoGRE to support UnTag packet with new HPS */
#define UNTAG_FEATURE 0x03
/* l2 header is adjusted for every hwp_pkt_next_action */
/* uc evaluate l2 header length and send packet to exception */
#define SW_PATH_ADJ_L2_EXCEPTION 0x00
/* uc evaluate l2 header length and send packet to 2nd pass */
#define HW_PATH_ADJ_L2_RESUME_2ND_PASS 0x01
/* uc evaluate l2 header length, update the metadata and send packet to 2nd pass */
#define HW_PATH_ADJ_L2_METADATA_UPDATE_RESUME_2ND_PASS 0x02
/* uc evaluate l2 header length, add outer header and send packet to 2nd pass */
#define HW_PATH_ADJ_L2_ADD_TUNNEL_RESUME_2ND_PASS 0x03
/* uc evaluate l2 header, update metadata, add outer header and send packet to 2nd pass */
#define HW_PATH_ADJ_L2_ADD_TUNNEL_WITH_METADATA_UPDATE_RESUME_2ND_PASS 0x04
/* untagged packet configuration */
struct untag_pkt_config_t {
/* packet action that should follow untag packet */
uint32_t action_configured;
/* pdn from which untag packet should transfer */
uint8_t mux_id;
/* flag if 1=>pkt_with_option_hdr 0=>pkt_without_option_hdr */
uint8_t is_v6_options_hdr_present;
uint16_t pad0; /*for alignment*/
/* lower 32 bit of tunnel header address */
uint32_t *tunnel_template_addr;
uint32_t pad1; /*for alignment*/
} __packed;
/* vlanid - action - tunnel_id - mux_id */
struct singletag_mux_mapping_table_t {
/* multi tunnel purpose */
uint16_t vlan_id_start;
uint16_t vlan_id_end;
uint32_t action_configured;
/* pdn from which untag packet should transfer */
uint8_t mux_id;
/* flag if 1=>pkt_with_option_hdr 0=>pkt_without_option_hdr */
uint8_t is_v6_options_hdr_present;
uint16_t pad0; /*for alignment*/
uint32_t *tunnel_template_addr;
} __packed;
struct doubletag_mux_mapping_table_t {
/* multi tunnel purpose */
uint16_t stag_id_start;
uint16_t stag_id_end;
uint16_t ctag_id_start;
uint16_t ctag_id_end;
uint32_t action_configured;
/* pdn from which untag packet should transfer */
uint8_t mux_id;
/* flag if 1=>pkt_with_option_hdr 0=>pkt_without_option_hdr */
uint8_t is_v6_options_hdr_present;
uint16_t pad0; /*for alignment*/
uint32_t *tunnel_template_addr;
uint32_t pad1; /*for alignment*/
} __packed;
/* max template side pass to uc */
#define MAX_TEMPLATE_SIZE 64
/* max number of tunnel to support ie: per PDN two tunnel (2*8)*/
#define MAX_TUNNEL_SUPPORT 16
/* configuration table */
struct tunnel_protocols_config_table_t {
struct untag_pkt_config_t untagged_mapping_table;
uint8_t num_of_single_tag_configs;
uint8_t pad0; /*for alignment*/
uint16_t pad1; /*for alignment*/
uint32_t pad2; /*for alignment*/
/* table for single tag pkt */
struct singletag_mux_mapping_table_t singletag_mux_mapping_table[MAX_TUNNEL_SUPPORT];
uint8_t num_of_double_tag_configs;
uint8_t pad3; /*for alignment*/
uint16_t pad4; /*for alignment*/
uint32_t pad5; /*for alignment*/
/* table for double tag pkt */
struct doubletag_mux_mapping_table_t doubletag_mux_mapping_table[MAX_TUNNEL_SUPPORT];
};
/* ioctl tunnel configuration table */
struct ipa_ioc_tunnel_template_info {
uint8_t template_header[MAX_TEMPLATE_SIZE];
uint32_t template_len;
uint32_t template_type;
/*tunnel configuration table*/
struct tunnel_protocols_config_table_t tunnel_config;
};
/**
* struct ipa_exception
@ -4103,6 +4203,14 @@ struct ipa_ioc_dscp_pcp_map_info {
IPA_IOCTL_SEND_VLAN_MUXID_MAPPING, \
struct ipa_ioc_mux_mapping_table)
#define IPA_IOC_SEND_TUNNEL_TEMPLATE_INFO _IOW(IPA_IOC_MAGIC, \
IPA_IOCTL_SEND_TUNNEL_TEMPLATE_INFO, \
struct ipa_ioc_tunnel_template_info)
#define IPA_IOC_QUERY_TUNNEL_FEATURE _IOW(IPA_IOC_MAGIC, \
IPA_IOCTL_QUERY_TUNNEL_FEATURE, \
uint8_t)
/*
* unique magic number of the Tethering bridge ioctls

View file

@ -2041,11 +2041,11 @@ static void perf_group_detach(struct perf_event *event)
if (event->group_leader != event) {
list_del_init(&event->sibling_list);
event->group_leader->nr_siblings--;
event->group_leader->group_generation++;
#ifdef CONFIG_PERF_KERNEL_SHARE
if (event->shared)
event->group_leader = event;
#endif
event->group_leader->group_generation++;
goto out;
}

View file

@ -1030,7 +1030,7 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn,
if (kill)
collect_procs(hpage, &tokill, flags & MF_ACTION_REQUIRED);
unmap_success = try_to_unmap(p, ttu, NULL);
unmap_success = try_to_unmap(hpage, ttu, NULL);
if (!unmap_success)
pr_err("Memory failure: %#lx: failed to unmap page (mapcount=%d)\n",
pfn, page_mapcount(p));