Merge tag 'LA.UM.9.12.r1-15200-SMxx50.QSSI13.0' of https://git.codelinaro.org/clo/la/kernel/msm-4.19 into android13-4.19-kona

"LA.UM.9.12.r1-15200-SMxx50.QSSI13.0"

* tag 'LA.UM.9.12.r1-15200-SMxx50.QSSI13.0' of https://git.codelinaro.org/clo/la/kernel/msm-4.19:
  sched: fixes sched_boost_disable
  net: qrtr: fifo: Add bounds check on tx path
  msm: synx: Remove synx handle status details from logging
  net: qrtr: fifo: Add bounds check in rx path
  icnss2: Add data length validation in cnss_wlfw_qdss_data_send_sync()
  cnss2: Validate maximum number of memory segments
  msm: synx: protect clean up with mutex lock
  cnss2: Unregister host driver during PCI remove
  soc: qcom: socinfo: Code clean-up
  net: usb: Get rid of inline before func definition
  memshare: Free QMI handle only if its valid
  msm: synx: Handling the base in idr_alloc
  msm: adsprpc: fix UAF process init_mem
  UPSTREAM: binderfs: use __u32 for device numbers
  phy: msm: qusb: Fix BC1.2 compliance failures
  dwc3: msm: Add module parameter to disable dp pulse

Change-Id: Ia55a1f598c8d6bd495644757ec5206ec691d538a
This commit is contained in:
Michael Bestas 2023-03-07 19:43:40 +02:00
commit 4e8eebe624
No known key found for this signature in database
GPG key ID: CC95044519BE6669
16 changed files with 154 additions and 111 deletions

View file

@ -484,7 +484,7 @@ struct fastrpc_file {
/* To indicate attempt has been made to allocate memory for debug_buf */ /* To indicate attempt has been made to allocate memory for debug_buf */
int debug_buf_alloced_attempted; int debug_buf_alloced_attempted;
/* Flag to indicate dynamic process creation status*/ /* Flag to indicate dynamic process creation status*/
bool in_process_create; enum fastrpc_process_create_state dsp_process_state;
struct completion shutdown; struct completion shutdown;
}; };
@ -2539,7 +2539,7 @@ static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl, int locked);
static int fastrpc_init_process(struct fastrpc_file *fl, static int fastrpc_init_process(struct fastrpc_file *fl,
struct fastrpc_ioctl_init_attrs *uproc) struct fastrpc_ioctl_init_attrs *uproc)
{ {
int err = 0, rh_hyp_done = 0; int err = 0, rh_hyp_done = 0, locked = 0;
struct fastrpc_apps *me = &gfa; struct fastrpc_apps *me = &gfa;
struct fastrpc_ioctl_invoke_crc ioctl; struct fastrpc_ioctl_invoke_crc ioctl;
struct fastrpc_ioctl_init *init = &uproc->init; struct fastrpc_ioctl_init *init = &uproc->init;
@ -2553,6 +2553,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl,
int unsigned_request = proc_attrs && init_flags; int unsigned_request = proc_attrs && init_flags;
int cid = fl->cid; int cid = fl->cid;
struct fastrpc_channel_ctx *chan = &me->channel[cid]; struct fastrpc_channel_ctx *chan = &me->channel[cid];
struct fastrpc_buf *init_mem;
if (chan->unsigned_support && if (chan->unsigned_support &&
fl->dev_minor == MINOR_NUM_DEV) { fl->dev_minor == MINOR_NUM_DEV) {
@ -2618,13 +2619,13 @@ static int fastrpc_init_process(struct fastrpc_file *fl,
} inbuf; } inbuf;
spin_lock(&fl->hlock); spin_lock(&fl->hlock);
if (fl->in_process_create) { if (fl->dsp_process_state) {
err = -EALREADY; err = -EALREADY;
pr_err("Already in create init process\n"); pr_err("Already in create init process\n");
spin_unlock(&fl->hlock); spin_unlock(&fl->hlock);
return err; return err;
} }
fl->in_process_create = true; fl->dsp_process_state = PROCESS_CREATE_IS_INPROGRESS;
spin_unlock(&fl->hlock); spin_unlock(&fl->hlock);
inbuf.pgid = fl->tgid; inbuf.pgid = fl->tgid;
inbuf.namelen = strlen(current->comm) + 1; inbuf.namelen = strlen(current->comm) + 1;
@ -2833,20 +2834,27 @@ bail:
fastrpc_mmap_free(mem, 0); fastrpc_mmap_free(mem, 0);
mutex_unlock(&fl->map_mutex); mutex_unlock(&fl->map_mutex);
} }
if (err) {
if (!IS_ERR_OR_NULL(fl->init_mem)) {
fastrpc_buf_free(fl->init_mem, 0);
fl->init_mem = NULL;
}
}
if (file) { if (file) {
mutex_lock(&fl->map_mutex); mutex_lock(&fl->map_mutex);
fastrpc_mmap_free(file, 0); fastrpc_mmap_free(file, 0);
mutex_unlock(&fl->map_mutex); mutex_unlock(&fl->map_mutex);
} }
if (init->flags == FASTRPC_INIT_CREATE) { spin_lock(&fl->hlock);
spin_lock(&fl->hlock); locked = 1;
fl->in_process_create = false; if (err) {
fl->dsp_process_state = PROCESS_CREATE_DEFAULT;
if (!IS_ERR_OR_NULL(fl->init_mem)) {
init_mem = fl->init_mem;
fl->init_mem = NULL;
locked = 0;
spin_unlock(&fl->hlock);
fastrpc_buf_free(init_mem, 0);
}
} else {
fl->dsp_process_state = PROCESS_CREATE_SUCCESS;
}
if (locked) {
locked = 0;
spin_unlock(&fl->hlock); spin_unlock(&fl->hlock);
} }
return err; return err;
@ -3812,7 +3820,7 @@ static int fastrpc_file_free(struct fastrpc_file *fl)
} }
spin_lock(&fl->hlock); spin_lock(&fl->hlock);
fl->file_close = 1; fl->file_close = 1;
fl->in_process_create = false; fl->dsp_process_state = PROCESS_CREATE_DEFAULT;
spin_unlock(&fl->hlock); spin_unlock(&fl->hlock);
if (!IS_ERR_OR_NULL(fl->init_mem)) if (!IS_ERR_OR_NULL(fl->init_mem))
fastrpc_buf_free(fl->init_mem, 0); fastrpc_buf_free(fl->init_mem, 0);
@ -4215,7 +4223,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
fl->cid = -1; fl->cid = -1;
fl->dev_minor = dev_minor; fl->dev_minor = dev_minor;
fl->init_mem = NULL; fl->init_mem = NULL;
fl->in_process_create = false; fl->dsp_process_state = PROCESS_CREATE_DEFAULT;
memset(&fl->perf, 0, sizeof(fl->perf)); memset(&fl->perf, 0, sizeof(fl->perf));
fl->qos_request = 0; fl->qos_request = 0;
fl->dsp_proc_init = 0; fl->dsp_proc_init = 0;

View file

@ -319,6 +319,15 @@ struct smq_invoke_rsp {
int retval; /* invoke return value */ int retval; /* invoke return value */
}; };
enum fastrpc_process_create_state {
/* Process is not created */
PROCESS_CREATE_DEFAULT = 0,
/* Process creation is in progress */
PROCESS_CREATE_IS_INPROGRESS = 1,
/* Process creation is successful */
PROCESS_CREATE_SUCCESS = 2,
};
enum fastrpc_response_flags { enum fastrpc_response_flags {
NORMAL_RESPONSE = 0, NORMAL_RESPONSE = 0,
EARLY_RESPONSE = 1, EARLY_RESPONSE = 1,

View file

@ -21,7 +21,7 @@
struct dentry *my_direc; struct dentry *my_direc;
const char delim[] = ","; const char delim[] = ",";
int columns = NAME_COLUMN | int columns = NAME_COLUMN |
BOUND_COLUMN | STATE_COLUMN | ERROR_CODES; BOUND_COLUMN | ERROR_CODES;
void populate_bound_rows( void populate_bound_rows(
struct synx_table_row *row, struct synx_table_row *row,
@ -29,14 +29,13 @@ void populate_bound_rows(
char *end) char *end)
{ {
int j; int j;
int state = SYNX_STATE_INVALID;
for (j = 0; j < row->num_bound_synxs; for (j = 0; j < row->num_bound_synxs;
j++) { j++) {
cur += scnprintf(cur, end - cur, cur += scnprintf(cur, end - cur,
"\n\tID: %d State: %s", "\n\tID: %d ",
row->bound_synxs[j].external_data->synx_obj, row->bound_synxs[j].external_data->synx_obj);
state);
} }
} }
static ssize_t synx_table_read(struct file *file, static ssize_t synx_table_read(struct file *file,
@ -51,7 +50,6 @@ static ssize_t synx_table_read(struct file *file,
char *dbuf, *cur, *end; char *dbuf, *cur, *end;
int i = 0; int i = 0;
int state = SYNX_STATE_INVALID;
ssize_t len = 0; ssize_t len = 0;
s32 index; s32 index;
@ -64,17 +62,15 @@ static ssize_t synx_table_read(struct file *file,
cur += scnprintf(cur, end - cur, "| Name |"); cur += scnprintf(cur, end - cur, "| Name |");
if (columns & BOUND_COLUMN) if (columns & BOUND_COLUMN)
cur += scnprintf(cur, end - cur, "| Bound |"); cur += scnprintf(cur, end - cur, "| Bound |");
if (columns & STATE_COLUMN)
cur += scnprintf(cur, end - cur, "| Status |");
cur += scnprintf(cur, end - cur, "\n"); cur += scnprintf(cur, end - cur, "\n");
for (i = 0; i < SYNX_MAX_OBJS; i++) { for (i = 1; i < SYNX_MAX_OBJS; i++) {
row = &dev->synx_table[i]; row = &dev->synx_table[i];
index = row->index; index = row->index;
mutex_lock(&dev->row_locks[index]); mutex_lock(&dev->row_locks[index]);
if (!row->index) { if (!row->index) {
mutex_unlock(&dev->row_locks[index]); mutex_unlock(&dev->row_locks[index]);
pr_warn("synx obj at %d invalid\n", index); pr_debug("synx obj at %d invalid\n", index);
continue; continue;
} }
@ -84,11 +80,6 @@ static ssize_t synx_table_read(struct file *file,
if (columns & BOUND_COLUMN) if (columns & BOUND_COLUMN)
cur += scnprintf(cur, end - cur, cur += scnprintf(cur, end - cur,
"|%11d|", row->num_bound_synxs); "|%11d|", row->num_bound_synxs);
if (columns & STATE_COLUMN) {
state = synx_status(row);
cur += scnprintf(cur, end - cur,
"|%10d|", state);
}
if ((columns & BOUND_COLUMN) && if ((columns & BOUND_COLUMN) &&
(row->num_bound_synxs > 0)) { (row->num_bound_synxs > 0)) {
cur += scnprintf( cur += scnprintf(

View file

@ -252,6 +252,7 @@ int synx_deinit_object(struct synx_table_row *row)
} }
} }
memset(row, 0, sizeof(*row)); memset(row, 0, sizeof(*row));
clear_bit(index, synx_dev->bitmap); clear_bit(index, synx_dev->bitmap);
@ -592,7 +593,7 @@ void *synx_from_handle(s32 synx_obj)
return NULL; return NULL;
} }
base = current->tgid << 16; base = (current->tgid << 16) & 0x7FFFFFFF;
if ((base >> 16) != (synx_obj >> 16)) { if ((base >> 16) != (synx_obj >> 16)) {
pr_err("current client: %d, base: %d, synx_obj: 0x%x\n", pr_err("current client: %d, base: %d, synx_obj: 0x%x\n",
@ -619,7 +620,7 @@ void synx_release_handle(void *pObj)
s32 synx_create_handle(void *pObj) s32 synx_create_handle(void *pObj)
{ {
s32 base = current->tgid << 16; s32 base = (current->tgid << 16) & 0x7FFFFFFF;
s32 id; s32 id;
struct synx_handle_entry *entry; struct synx_handle_entry *entry;
unsigned long flags; unsigned long flags;

View file

@ -529,9 +529,9 @@ int ax_check_ether_addr(struct ax_device *axdev);
int ax_get_mac_pass(struct ax_device *axdev, u8 *mac); int ax_get_mac_pass(struct ax_device *axdev, u8 *mac);
void ax_set_tx_qlen(struct ax_device *dev); void ax_set_tx_qlen(struct ax_device *dev);
inline void *__rx_buf_align(void *data); void *__rx_buf_align(void *data);
inline void *__tx_buf_align(void *data, u8 tx_align_len); void *__tx_buf_align(void *data, u8 tx_align_len);
inline struct net_device_stats *ax_get_stats(struct net_device *dev); struct net_device_stats *ax_get_stats(struct net_device *dev);
void ax_write_bulk_callback(struct urb *urb); void ax_write_bulk_callback(struct urb *urb);
void ax_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info); void ax_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info);

View file

@ -23,7 +23,6 @@
#define MAX_NO_OF_MAC_ADDR 4 #define MAX_NO_OF_MAC_ADDR 4
#define QMI_WLFW_MAX_TIMESTAMP_LEN 32 #define QMI_WLFW_MAX_TIMESTAMP_LEN 32
#define QMI_WLFW_MAX_NUM_MEM_SEG 32
#define QMI_WLFW_MAX_BUILD_ID_LEN 128 #define QMI_WLFW_MAX_BUILD_ID_LEN 128
#define CNSS_RDDM_TIMEOUT_MS 20000 #define CNSS_RDDM_TIMEOUT_MS 20000
#define RECOVERY_TIMEOUT 60000 #define RECOVERY_TIMEOUT 60000
@ -379,10 +378,10 @@ struct cnss_plat_data {
char fw_build_id[QMI_WLFW_MAX_BUILD_ID_LEN + 1]; char fw_build_id[QMI_WLFW_MAX_BUILD_ID_LEN + 1];
u32 otp_version; u32 otp_version;
u32 fw_mem_seg_len; u32 fw_mem_seg_len;
struct cnss_fw_mem fw_mem[QMI_WLFW_MAX_NUM_MEM_SEG]; struct cnss_fw_mem fw_mem[QMI_WLFW_MAX_NUM_MEM_SEG_V01];
struct cnss_fw_mem m3_mem; struct cnss_fw_mem m3_mem;
u32 qdss_mem_seg_len; u32 qdss_mem_seg_len;
struct cnss_fw_mem qdss_mem[QMI_WLFW_MAX_NUM_MEM_SEG]; struct cnss_fw_mem qdss_mem[QMI_WLFW_MAX_NUM_MEM_SEG_V01];
u32 *qdss_reg; u32 *qdss_reg;
struct cnss_pin_connect_result pin_result; struct cnss_pin_connect_result pin_result;
struct dentry *root_dentry; struct dentry *root_dentry;

View file

@ -2542,8 +2542,12 @@ int cnss_pci_register_driver_hdlr(struct cnss_pci_data *pci_priv,
int cnss_pci_unregister_driver_hdlr(struct cnss_pci_data *pci_priv) int cnss_pci_unregister_driver_hdlr(struct cnss_pci_data *pci_priv)
{ {
struct cnss_plat_data *plat_priv = pci_priv->plat_priv; struct cnss_plat_data *plat_priv;
if (!pci_priv)
return -EINVAL;
plat_priv = pci_priv->plat_priv;
set_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state); set_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state);
cnss_pci_dev_shutdown(pci_priv); cnss_pci_dev_shutdown(pci_priv);
pci_priv->driver_ops = NULL; pci_priv->driver_ops = NULL;
@ -4924,7 +4928,9 @@ static void cnss_pci_unregister_mhi(struct cnss_pci_data *pci_priv)
if (mhi_ctrl->cntrl_log_buf) if (mhi_ctrl->cntrl_log_buf)
ipc_log_context_destroy(mhi_ctrl->cntrl_log_buf); ipc_log_context_destroy(mhi_ctrl->cntrl_log_buf);
kfree(mhi_ctrl->irq); kfree(mhi_ctrl->irq);
mhi_ctrl->irq = NULL;
mhi_free_controller(mhi_ctrl); mhi_free_controller(mhi_ctrl);
pci_priv->mhi_ctrl = NULL;
} }
static void cnss_pci_config_regs(struct cnss_pci_data *pci_priv) static void cnss_pci_config_regs(struct cnss_pci_data *pci_priv)
@ -5079,6 +5085,7 @@ static void cnss_pci_remove(struct pci_dev *pci_dev)
struct cnss_plat_data *plat_priv = struct cnss_plat_data *plat_priv =
cnss_bus_dev_to_plat_priv(&pci_dev->dev); cnss_bus_dev_to_plat_priv(&pci_dev->dev);
cnss_pci_unregister_driver_hdlr(pci_priv);
cnss_pci_free_m3_mem(pci_priv); cnss_pci_free_m3_mem(pci_priv);
cnss_pci_free_fw_mem(pci_priv); cnss_pci_free_fw_mem(pci_priv);
cnss_pci_free_qdss_mem(pci_priv); cnss_pci_free_qdss_mem(pci_priv);

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#define pr_fmt(fmt) "icnss2_qmi: " fmt #define pr_fmt(fmt) "icnss2_qmi: " fmt
@ -968,11 +969,11 @@ int icnss_wlfw_qdss_data_send_sync(struct icnss_priv *priv, char *file_name,
__func__, resp->total_size, resp->data_len); __func__, resp->total_size, resp->data_len);
if ((resp->total_size_valid == 1 && if ((resp->total_size_valid == 1 &&
resp->total_size == total_size) resp->total_size == total_size)
&& (resp->seg_id_valid == 1 && resp->seg_id == req->seg_id) && (resp->seg_id_valid == 1 && resp->seg_id == req->seg_id)
&& (resp->data_valid == 1 && && (resp->data_valid == 1 &&
resp->data_len <= QMI_WLFW_MAX_DATA_SIZE_V01)) { resp->data_len <= QMI_WLFW_MAX_DATA_SIZE_V01)
&& resp->data_len <= remaining) {
memcpy(p_qdss_trace_data_temp, memcpy(p_qdss_trace_data_temp,
resp->data, resp->data_len); resp->data, resp->data_len);
} else { } else {

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/err.h> #include <linux/err.h>
@ -751,6 +752,7 @@ static void memshare_init_worker(struct work_struct *work)
dev_err(memsh_child->dev, dev_err(memsh_child->dev,
"memshare: Creating mem_share_svc qmi handle failed\n"); "memshare: Creating mem_share_svc qmi handle failed\n");
kfree(mem_share_svc_handle); kfree(mem_share_svc_handle);
mem_share_svc_handle = NULL;
destroy_workqueue(mem_share_svc_workqueue); destroy_workqueue(mem_share_svc_workqueue);
return; return;
} }
@ -759,8 +761,11 @@ static void memshare_init_worker(struct work_struct *work)
if (rc < 0) { if (rc < 0) {
dev_err(memsh_child->dev, dev_err(memsh_child->dev,
"memshare: Registering mem share svc failed %d\n", rc); "memshare: Registering mem share svc failed %d\n", rc);
qmi_handle_release(mem_share_svc_handle); if (mem_share_svc_handle) {
kfree(mem_share_svc_handle); qmi_handle_release(mem_share_svc_handle);
kfree(mem_share_svc_handle);
mem_share_svc_handle = NULL;
}
destroy_workqueue(mem_share_svc_workqueue); destroy_workqueue(mem_share_svc_workqueue);
return; return;
} }
@ -917,8 +922,11 @@ static int memshare_remove(struct platform_device *pdev)
return 0; return 0;
flush_workqueue(mem_share_svc_workqueue); flush_workqueue(mem_share_svc_workqueue);
qmi_handle_release(mem_share_svc_handle); if (mem_share_svc_handle) {
kfree(mem_share_svc_handle); qmi_handle_release(mem_share_svc_handle);
kfree(mem_share_svc_handle);
mem_share_svc_handle = NULL;
}
destroy_workqueue(mem_share_svc_workqueue); destroy_workqueue(mem_share_svc_workqueue);
return 0; return 0;
} }

View file

@ -200,8 +200,8 @@ struct socinfo_v0_14 {
struct socinfo_v0_13 v0_13; struct socinfo_v0_13 v0_13;
uint32_t num_clusters; uint32_t num_clusters;
uint32_t ncluster_array_offset; uint32_t ncluster_array_offset;
uint32_t num_defective_parts; uint32_t num_subset_parts;
uint32_t ndefective_parts_array_offset; uint32_t nsubset_parts_array_offset;
}; };
struct socinfo_v0_15 { struct socinfo_v0_15 {
@ -633,19 +633,19 @@ static uint32_t socinfo_get_ncluster_array_offset(void)
: 0; : 0;
} }
static uint32_t socinfo_get_num_defective_parts(void) static uint32_t socinfo_get_num_subset_parts(void)
{ {
return socinfo ? return socinfo ?
(socinfo_format >= SOCINFO_VERSION(0, 14) ? (socinfo_format >= SOCINFO_VERSION(0, 14) ?
socinfo->v0_14.num_defective_parts : 0) socinfo->v0_14.num_subset_parts : 0)
: 0; : 0;
} }
static uint32_t socinfo_get_ndefective_parts_array_offset(void) static uint32_t socinfo_get_nsubset_parts_array_offset(void)
{ {
return socinfo ? return socinfo ?
(socinfo_format >= SOCINFO_VERSION(0, 14) ? (socinfo_format >= SOCINFO_VERSION(0, 14) ?
socinfo->v0_14.ndefective_parts_array_offset : 0) socinfo->v0_14.nsubset_parts_array_offset : 0)
: 0; : 0;
} }
@ -872,9 +872,9 @@ msm_get_ncluster_array_offset(struct device *dev,
} }
uint32_t uint32_t
socinfo_get_cluster_info(enum defective_cluster_type cluster) socinfo_get_cluster_info(enum subset_cluster_type cluster)
{ {
uint32_t def_cluster, num_cluster, offset; uint32_t sub_cluster, num_cluster, offset;
void *cluster_val; void *cluster_val;
void *info = socinfo; void *info = socinfo;
@ -891,46 +891,46 @@ socinfo_get_cluster_info(enum defective_cluster_type cluster)
info += offset; info += offset;
cluster_val = info + (sizeof(uint32_t) * cluster); cluster_val = info + (sizeof(uint32_t) * cluster);
def_cluster = get_unaligned_le32(cluster_val); sub_cluster = get_unaligned_le32(cluster_val);
return def_cluster; return sub_cluster;
} }
EXPORT_SYMBOL(socinfo_get_cluster_info); EXPORT_SYMBOL(socinfo_get_cluster_info);
static ssize_t static ssize_t
msm_get_defective_cores(struct device *dev, msm_get_subset_cores(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
{ {
uint32_t def_cluster = socinfo_get_cluster_info(CLUSTER_CPUSS); uint32_t sub_cluster = socinfo_get_cluster_info(CLUSTER_CPUSS);
return scnprintf(buf, PAGE_SIZE, "%x\n", def_cluster); return scnprintf(buf, PAGE_SIZE, "%x\n", sub_cluster);
} }
static ssize_t static ssize_t
msm_get_num_defective_parts(struct device *dev, msm_get_num_subset_parts(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
{ {
return snprintf(buf, PAGE_SIZE, "0x%x\n", return snprintf(buf, PAGE_SIZE, "0x%x\n",
socinfo_get_num_defective_parts()); socinfo_get_num_subset_parts());
} }
static ssize_t static ssize_t
msm_get_ndefective_parts_array_offset(struct device *dev, msm_get_nsubset_parts_array_offset(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
{ {
return snprintf(buf, PAGE_SIZE, "0x%x\n", return snprintf(buf, PAGE_SIZE, "0x%x\n",
socinfo_get_ndefective_parts_array_offset()); socinfo_get_nsubset_parts_array_offset());
} }
static uint32_t static uint32_t
socinfo_get_defective_parts(void) socinfo_get_subset_parts(void)
{ {
uint32_t num_parts = socinfo_get_num_defective_parts(); uint32_t num_parts = socinfo_get_num_subset_parts();
uint32_t offset = socinfo_get_ndefective_parts_array_offset(); uint32_t offset = socinfo_get_nsubset_parts_array_offset();
uint32_t def_parts = 0; uint32_t sub_parts = 0;
void *info = socinfo; void *info = socinfo;
uint32_t part_entry; uint32_t part_entry;
int i; int i;
@ -942,15 +942,15 @@ socinfo_get_defective_parts(void)
for (i = 0; i < num_parts; i++) { for (i = 0; i < num_parts; i++) {
part_entry = get_unaligned_le32(info); part_entry = get_unaligned_le32(info);
if (part_entry) if (part_entry)
def_parts |= BIT(i); sub_parts |= BIT(i);
info += sizeof(uint32_t); info += sizeof(uint32_t);
} }
return def_parts; return sub_parts;
} }
bool bool
socinfo_get_part_info(enum defective_part_type part) socinfo_get_part_info(enum subset_part_type part)
{ {
uint32_t partinfo; uint32_t partinfo;
@ -959,7 +959,7 @@ socinfo_get_part_info(enum defective_part_type part)
return false; return false;
} }
partinfo = socinfo_get_defective_parts(); partinfo = socinfo_get_subset_parts();
if (partinfo < 0) { if (partinfo < 0) {
pr_err("Failed to get part information\n"); pr_err("Failed to get part information\n");
return false; return false;
@ -970,13 +970,13 @@ socinfo_get_part_info(enum defective_part_type part)
EXPORT_SYMBOL(socinfo_get_part_info); EXPORT_SYMBOL(socinfo_get_part_info);
static ssize_t static ssize_t
msm_get_defective_parts(struct device *dev, msm_get_subset_parts(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
{ {
uint32_t def_parts = socinfo_get_defective_parts(); uint32_t sub_parts = socinfo_get_subset_parts();
return scnprintf(buf, PAGE_SIZE, "%x\n", def_parts); return scnprintf(buf, PAGE_SIZE, "%x\n", sub_parts);
} }
static ssize_t static ssize_t
@ -1283,21 +1283,21 @@ static struct device_attribute msm_soc_attr_ncluster_array_offset =
__ATTR(ncluster_array_offset, 0444, __ATTR(ncluster_array_offset, 0444,
msm_get_ncluster_array_offset, NULL); msm_get_ncluster_array_offset, NULL);
static struct device_attribute msm_soc_attr_defective_cores = static struct device_attribute msm_soc_attr_subset_cores =
__ATTR(defective_cores, 0444, __ATTR(subset_cores, 0444,
msm_get_defective_cores, NULL); msm_get_subset_cores, NULL);
static struct device_attribute msm_soc_attr_num_defective_parts = static struct device_attribute msm_soc_attr_num_subset_parts =
__ATTR(num_defective_parts, 0444, __ATTR(num_subset_parts, 0444,
msm_get_num_defective_parts, NULL); msm_get_num_subset_parts, NULL);
static struct device_attribute msm_soc_attr_ndefective_parts_array_offset = static struct device_attribute msm_soc_attr_nsubset_parts_array_offset =
__ATTR(ndefective_parts_array_offset, 0444, __ATTR(nsubset_parts_array_offset, 0444,
msm_get_ndefective_parts_array_offset, NULL); msm_get_nsubset_parts_array_offset, NULL);
static struct device_attribute msm_soc_attr_defective_parts = static struct device_attribute msm_soc_attr_subset_parts =
__ATTR(defective_parts, 0444, __ATTR(subset_parts, 0444,
msm_get_defective_parts, NULL); msm_get_subset_parts, NULL);
static struct device_attribute msm_soc_attr_nmodem_supported = static struct device_attribute msm_soc_attr_nmodem_supported =
__ATTR(nmodem_supported, 0444, __ATTR(nmodem_supported, 0444,
@ -1498,13 +1498,13 @@ static void __init populate_soc_sysfs_files(struct device *msm_soc_device)
device_create_file(msm_soc_device, device_create_file(msm_soc_device,
&msm_soc_attr_ncluster_array_offset); &msm_soc_attr_ncluster_array_offset);
device_create_file(msm_soc_device, device_create_file(msm_soc_device,
&msm_soc_attr_defective_cores); &msm_soc_attr_subset_cores);
device_create_file(msm_soc_device, device_create_file(msm_soc_device,
&msm_soc_attr_num_defective_parts); &msm_soc_attr_num_subset_parts);
device_create_file(msm_soc_device, device_create_file(msm_soc_device,
&msm_soc_attr_ndefective_parts_array_offset); &msm_soc_attr_nsubset_parts_array_offset);
device_create_file(msm_soc_device, device_create_file(msm_soc_device,
&msm_soc_attr_defective_parts); &msm_soc_attr_subset_parts);
case SOCINFO_VERSION(0, 13): case SOCINFO_VERSION(0, 13):
device_create_file(msm_soc_device, device_create_file(msm_soc_device,
&msm_soc_attr_nproduct_id); &msm_soc_attr_nproduct_id);
@ -1741,7 +1741,7 @@ static void socinfo_print(void)
break; break;
case SOCINFO_VERSION(0, 14): case SOCINFO_VERSION(0, 14):
pr_info("v%u.%u, id=%u, ver=%u.%u, raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n accessory_chip=%u, hw_plat_subtype=%u, pmic_model=%u, pmic_die_revision=%u foundry_id=%u serial_number=%u num_pmics=%u chip_family=0x%x raw_device_family=0x%x raw_device_number=0x%x nproduct_id=0x%x num_clusters=0x%x ncluster_array_offset=0x%x num_defective_parts=0x%x ndefective_parts_array_offset=0x%x\n", pr_info("v%u.%u, id=%u, ver=%u.%u, raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n accessory_chip=%u, hw_plat_subtype=%u, pmic_model=%u, pmic_die_revision=%u foundry_id=%u serial_number=%u num_pmics=%u chip_family=0x%x raw_device_family=0x%x raw_device_number=0x%x nproduct_id=0x%x num_clusters=0x%x ncluster_array_offset=0x%x num_subset_parts=0x%x nsubset_parts_array_offset=0x%x\n",
f_maj, f_min, socinfo->v0_1.id, v_maj, v_min, f_maj, f_min, socinfo->v0_1.id, v_maj, v_min,
socinfo->v0_2.raw_id, socinfo->v0_2.raw_version, socinfo->v0_2.raw_id, socinfo->v0_2.raw_version,
socinfo->v0_3.hw_platform, socinfo->v0_3.hw_platform,
@ -1759,12 +1759,12 @@ static void socinfo_print(void)
socinfo->v0_13.nproduct_id, socinfo->v0_13.nproduct_id,
socinfo->v0_14.num_clusters, socinfo->v0_14.num_clusters,
socinfo->v0_14.ncluster_array_offset, socinfo->v0_14.ncluster_array_offset,
socinfo->v0_14.num_defective_parts, socinfo->v0_14.num_subset_parts,
socinfo->v0_14.ndefective_parts_array_offset); socinfo->v0_14.nsubset_parts_array_offset);
break; break;
case SOCINFO_VERSION(0, 15): case SOCINFO_VERSION(0, 15):
pr_info("v%u.%u, id=%u, ver=%u.%u, raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n accessory_chip=%u, hw_plat_subtype=%u, pmic_model=%u, pmic_die_revision=%u foundry_id=%u serial_number=%u num_pmics=%u chip_family=0x%x raw_device_family=0x%x raw_device_number=0x%x nproduct_id=0x%x num_clusters=0x%x ncluster_array_offset=0x%x num_defective_parts=0x%x ndefective_parts_array_offset=0x%x nmodem_supported=0x%x\n", pr_info("v%u.%u, id=%u, ver=%u.%u, raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n accessory_chip=%u, hw_plat_subtype=%u, pmic_model=%u, pmic_die_revision=%u foundry_id=%u serial_number=%u num_pmics=%u chip_family=0x%x raw_device_family=0x%x raw_device_number=0x%x nproduct_id=0x%x num_clusters=0x%x ncluster_array_offset=0x%x num_subset_parts=0x%x nsubset_parts_array_offset=0x%x nmodem_supported=0x%x\n",
f_maj, f_min, socinfo->v0_1.id, v_maj, v_min, f_maj, f_min, socinfo->v0_1.id, v_maj, v_min,
socinfo->v0_2.raw_id, socinfo->v0_2.raw_version, socinfo->v0_2.raw_id, socinfo->v0_2.raw_version,
socinfo->v0_3.hw_platform, socinfo->v0_3.hw_platform,
@ -1782,8 +1782,8 @@ static void socinfo_print(void)
socinfo->v0_13.nproduct_id, socinfo->v0_13.nproduct_id,
socinfo->v0_14.num_clusters, socinfo->v0_14.num_clusters,
socinfo->v0_14.ncluster_array_offset, socinfo->v0_14.ncluster_array_offset,
socinfo->v0_14.num_defective_parts, socinfo->v0_14.num_subset_parts,
socinfo->v0_14.ndefective_parts_array_offset, socinfo->v0_14.nsubset_parts_array_offset,
socinfo->v0_15.nmodem_supported); socinfo->v0_15.nmodem_supported);
break; break;

View file

@ -47,6 +47,10 @@
#include "debug.h" #include "debug.h"
#include "xhci.h" #include "xhci.h"
static bool bc12_compliance;
module_param(bc12_compliance, bool, 0644);
MODULE_PARM_DESC(bc12_compliance, "Disable sending dp pulse for CDP");
#define SDP_CONNETION_CHECK_TIME 10000 /* in ms */ #define SDP_CONNETION_CHECK_TIME 10000 /* in ms */
#define EXTCON_SYNC_EVENT_TIMEOUT_MS 1500 /* in ms */ #define EXTCON_SYNC_EVENT_TIMEOUT_MS 1500 /* in ms */
@ -3391,7 +3395,8 @@ static int dwc3_msm_vbus_notifier(struct notifier_block *nb,
* and only when the vbus connect event is a valid one. * and only when the vbus connect event is a valid one.
*/ */
if (get_psy_type(mdwc) == POWER_SUPPLY_TYPE_USB_CDP && if (get_psy_type(mdwc) == POWER_SUPPLY_TYPE_USB_CDP &&
mdwc->vbus_active && !mdwc->check_eud_state) { mdwc->vbus_active &&
!mdwc->check_eud_state && !bc12_compliance) {
dev_dbg(mdwc->dev, "Connected to CDP, pull DP up\n"); dev_dbg(mdwc->dev, "Connected to CDP, pull DP up\n");
usb_phy_drive_dp_pulse(mdwc->hs_phy, DP_PULSE_WIDTH_MSEC); usb_phy_drive_dp_pulse(mdwc->hs_phy, DP_PULSE_WIDTH_MSEC);
} }

View file

@ -195,6 +195,7 @@ struct qusb_phy {
bool is_gpio_active_low; bool is_gpio_active_low;
int notifier_irq; int notifier_irq;
bool is_port_valid; bool is_port_valid;
bool dcp_charger;
/* debugfs entries */ /* debugfs entries */
struct dentry *root; struct dentry *root;
@ -1514,13 +1515,14 @@ static void qusb_phy_port_state_work(struct work_struct *w)
if (status) { if (status) {
qusb_phy_notify_charger(qphy, qusb_phy_notify_charger(qphy,
POWER_SUPPLY_TYPE_USB_DCP); POWER_SUPPLY_TYPE_USB_DCP);
qphy->dcp_charger = true;
} else { } else {
qusb_phy_notify_charger(qphy, qusb_phy_notify_charger(qphy,
POWER_SUPPLY_TYPE_USB_CDP); POWER_SUPPLY_TYPE_USB_CDP);
qusb_phy_unprepare_chg_det(qphy);
qusb_phy_notify_extcon(qphy, EXTCON_USB, 1); qusb_phy_notify_extcon(qphy, EXTCON_USB, 1);
} }
qusb_phy_unprepare_chg_det(qphy);
qphy->port_state = PORT_CHG_DET_DONE; qphy->port_state = PORT_CHG_DET_DONE;
/* /*
* Fall through to check if cable got disconnected * Fall through to check if cable got disconnected
@ -1528,6 +1530,10 @@ static void qusb_phy_port_state_work(struct work_struct *w)
*/ */
case PORT_CHG_DET_DONE: case PORT_CHG_DET_DONE:
if (!vbus_active) { if (!vbus_active) {
if (qphy->dcp_charger) {
qphy->dcp_charger = false;
qusb_phy_unprepare_chg_det(qphy);
}
qphy->port_state = PORT_UNKNOWN; qphy->port_state = PORT_UNKNOWN;
qusb_phy_notify_extcon(qphy, EXTCON_USB, 0); qusb_phy_notify_extcon(qphy, EXTCON_USB, 0);
} }

View file

@ -233,7 +233,7 @@ enum pmic_model {
PMIC_MODEL_UNKNOWN = 0xFFFFFFFF PMIC_MODEL_UNKNOWN = 0xFFFFFFFF
}; };
enum defective_part_type { enum subset_part_type {
PART_UNKNOWN = 0, PART_UNKNOWN = 0,
PART_GPU = 1, PART_GPU = 1,
PART_VIDEO = 2, PART_VIDEO = 2,
@ -252,7 +252,7 @@ enum defective_part_type {
NUM_PARTS_MAX, NUM_PARTS_MAX,
}; };
enum defective_cluster_type { enum subset_cluster_type {
CLUSTER_CPUSS = 0, CLUSTER_CPUSS = 0,
NUM_CLUSTERS_MAX, NUM_CLUSTERS_MAX,
}; };
@ -267,8 +267,8 @@ uint32_t socinfo_get_platform_type(void);
uint32_t socinfo_get_platform_subtype(void); uint32_t socinfo_get_platform_subtype(void);
uint32_t socinfo_get_platform_version(void); uint32_t socinfo_get_platform_version(void);
uint32_t socinfo_get_serial_number(void); uint32_t socinfo_get_serial_number(void);
uint32_t socinfo_get_cluster_info(enum defective_cluster_type cluster); uint32_t socinfo_get_cluster_info(enum subset_cluster_type cluster);
bool socinfo_get_part_info(enum defective_part_type part); bool socinfo_get_part_info(enum subset_part_type part);
enum pmic_model socinfo_get_pmic_model(void); enum pmic_model socinfo_get_pmic_model(void);
uint32_t socinfo_get_pmic_die_revision(void); uint32_t socinfo_get_pmic_die_revision(void);
int __init socinfo_init(void) __must_check; int __init socinfo_init(void) __must_check;

View file

@ -146,7 +146,7 @@ static int sched_effective_boost(void)
static void sched_boost_disable(int type) static void sched_boost_disable(int type)
{ {
struct sched_boost_data *sb = &sched_boosts[type]; struct sched_boost_data *sb = &sched_boosts[type];
int next_boost; int next_boost, prev_boost = sched_boost_type;
if (sb->refcount <= 0) if (sb->refcount <= 0)
return; return;
@ -156,14 +156,15 @@ static void sched_boost_disable(int type)
if (sb->refcount) if (sb->refcount)
return; return;
next_boost = sched_effective_boost();
if (next_boost == prev_boost)
return;
/* /*
* This boost's refcount becomes zero, so it must * This boost's refcount becomes zero, so it must
* be disabled. Disable it first and then apply * be disabled. Disable it first and then apply
* the next boost. * the next boost.
*/ */
sb->exit(); sched_boosts[prev_boost].exit();
next_boost = sched_effective_boost();
sched_boosts[next_boost].enter(); sched_boosts[next_boost].enter();
} }

View file

@ -883,10 +883,9 @@ int core_ctl_set_boost(bool boost)
if (!cluster->boost) { if (!cluster->boost) {
ret = -EINVAL; ret = -EINVAL;
break; break;
} else {
--cluster->boost;
boost_state_changed = !cluster->boost;
} }
--cluster->boost;
boost_state_changed = !cluster->boost;
} }
} }
spin_unlock_irqrestore(&state_lock, flags); spin_unlock_irqrestore(&state_lock, flags);

View file

@ -82,6 +82,9 @@ static void fifo_rx_peak(struct fifo_pipe *pipe,
if (tail >= pipe->length) if (tail >= pipe->length)
tail -= pipe->length; tail -= pipe->length;
if (WARN_ON_ONCE(tail > pipe->length))
return;
len = min_t(size_t, count, pipe->length - tail); len = min_t(size_t, count, pipe->length - tail);
if (len) if (len)
memcpy_fromio(data, pipe->fifo + tail, len); memcpy_fromio(data, pipe->fifo + tail, len);
@ -117,6 +120,9 @@ static size_t fifo_tx_avail(struct fifo_pipe *pipe)
else else
avail = tail - head; avail = tail - head;
if (WARN_ON_ONCE(avail > pipe->length))
avail = 0;
return avail; return avail;
} }
@ -127,6 +133,8 @@ static void fifo_tx_write(struct fifo_pipe *pipe,
u32 head; u32 head;
head = le32_to_cpu(*pipe->head); head = le32_to_cpu(*pipe->head);
if (WARN_ON_ONCE(head > pipe->length))
return;
len = min_t(size_t, count, pipe->length - head); len = min_t(size_t, count, pipe->length - head);
if (len) if (len)