diff options
| -rw-r--r-- | arch/arm/boot/dts/qcom/sdm660.dtsi | 1 | ||||
| -rw-r--r-- | drivers/char/adsprpc.c | 1 | ||||
| -rw-r--r-- | drivers/char/diag/diagchar_core.c | 23 | ||||
| -rw-r--r-- | drivers/gpu/msm/kgsl_pwrctrl.c | 9 | ||||
| -rw-r--r-- | drivers/gpu/msm/kgsl_pwrscale.c | 6 | ||||
| -rw-r--r-- | drivers/iio/adc/qcom-rradc.c | 4 | ||||
| -rw-r--r-- | drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c | 2 | ||||
| -rw-r--r-- | drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c | 6 | ||||
| -rw-r--r-- | drivers/mmc/core/core.c | 6 | ||||
| -rw-r--r-- | drivers/net/wireless/cnss_utils/cnss_utils.c | 2 | ||||
| -rw-r--r-- | drivers/pwm/pwm-qpnp.c | 46 | ||||
| -rw-r--r-- | drivers/regulator/core.c | 12 | ||||
| -rw-r--r-- | drivers/soc/qcom/icnss.c | 83 | ||||
| -rw-r--r-- | drivers/soc/qcom/spcom.c | 10 | ||||
| -rw-r--r-- | kernel/irq/proc.c | 5 |
15 files changed, 183 insertions, 33 deletions
diff --git a/arch/arm/boot/dts/qcom/sdm660.dtsi b/arch/arm/boot/dts/qcom/sdm660.dtsi index 3debda8c084d..03537b113026 100644 --- a/arch/arm/boot/dts/qcom/sdm660.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660.dtsi @@ -2140,6 +2140,7 @@ qcom,qsee-ce-hw-instance = <0>; qcom,disk-encrypt-pipe-pair = <2>; qcom,support-fde; + qcom,fde-key-size; qcom,no-clock-support; qcom,msm-bus,name = "qseecom-noc"; qcom,msm-bus,num-cases = <4>; diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 0c89ab992012..13016f32b344 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -318,7 +318,6 @@ static struct fastrpc_channel_ctx gcinfo[NUM_CHANNELS] = { .channel = SMD_APPS_DSPS, .link.link_info.edge = "dsps", .link.link_info.transport = "smem", - .vmid = VMID_SSC_Q6, }, { .name = "cdsprpc-smd", diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c index 8ab22ee3bc3c..5ae3e4defd0d 100644 --- a/drivers/char/diag/diagchar_core.c +++ b/drivers/char/diag/diagchar_core.c @@ -1020,6 +1020,11 @@ static int diag_send_raw_data_remote(int proc, void *buf, int len, else hdlc_disabled = driver->hdlc_disabled; if (hdlc_disabled) { + if (len < 4) { + pr_err("diag: In %s, invalid len: %d of non_hdlc pkt", + __func__, len); + return -EBADMSG; + } payload = *(uint16_t *)(buf + 2); if (payload > DIAG_MAX_HDLC_BUF_SIZE) { pr_err("diag: Dropping packet, payload size is %d\n", @@ -1028,11 +1033,21 @@ static int diag_send_raw_data_remote(int proc, void *buf, int len, } driver->hdlc_encode_buf_len = payload; /* - * Adding 4 bytes for start (1 byte), version (1 byte) and - * payload (2 bytes) + * Adding 5 bytes for start (1 byte), version (1 byte), + * payload (2 bytes) and end (1 byte) */ - memcpy(driver->hdlc_encode_buf, buf + 4, payload); - goto send_data; + if (len == (payload + 5)) { + /* + * Adding 4 bytes for start (1 byte), version (1 byte) + * and payload (2 bytes) + */ + memcpy(driver->hdlc_encode_buf, buf + 4, payload); + goto send_data; + } else { + pr_err("diag: In %s, invalid len: %d of non_hdlc pkt", + __func__, len); + return -EBADMSG; + } } if (hdlc_flag) { diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c index 63315e86d172..ad8b0131bb46 100644 --- a/drivers/gpu/msm/kgsl_pwrctrl.c +++ b/drivers/gpu/msm/kgsl_pwrctrl.c @@ -1022,6 +1022,8 @@ static void __force_on(struct kgsl_device *device, int flag, int on) if (on) { switch (flag) { case KGSL_PWRFLAGS_CLK_ON: + /* make sure pwrrail is ON before enabling clocks */ + kgsl_pwrctrl_pwrrail(device, KGSL_PWRFLAGS_ON); kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_ON, KGSL_STATE_ACTIVE); break; @@ -1817,7 +1819,12 @@ static int kgsl_pwrctrl_pwrrail(struct kgsl_device *device, int state) struct kgsl_pwrctrl *pwr = &device->pwrctrl; int status = 0; - if (test_bit(KGSL_PWRFLAGS_POWER_ON, &pwr->ctrl_flags)) + /* + * Disabling the regulator means also disabling dependent clocks. + * Hence don't disable it if force clock ON is set. + */ + if (test_bit(KGSL_PWRFLAGS_POWER_ON, &pwr->ctrl_flags) || + test_bit(KGSL_PWRFLAGS_CLK_ON, &pwr->ctrl_flags)) return 0; if (state == KGSL_PWRFLAGS_OFF) { diff --git a/drivers/gpu/msm/kgsl_pwrscale.c b/drivers/gpu/msm/kgsl_pwrscale.c index 7f93ab8fa8d4..24a1a42af74e 100644 --- a/drivers/gpu/msm/kgsl_pwrscale.c +++ b/drivers/gpu/msm/kgsl_pwrscale.c @@ -550,7 +550,11 @@ int kgsl_devfreq_target(struct device *dev, unsigned long *freq, u32 flags) /* If the governor recommends a new frequency, update it here */ if (*freq != cur_freq) { level = pwr->max_pwrlevel; - for (i = pwr->min_pwrlevel; i >= pwr->max_pwrlevel; i--) + /* + * To avoid infinite loop issue type cast max_pwrlevel to + * signed integer type + */ + for (i = pwr->min_pwrlevel; i >= (int)pwr->max_pwrlevel; i--) if (*freq <= pwr->pwrlevels[i].gpu_freq) { if (pwr->thermal_cycle == CYCLE_ACTIVE) level = _thermal_adjust(pwr, i); diff --git a/drivers/iio/adc/qcom-rradc.c b/drivers/iio/adc/qcom-rradc.c index 537cca877f66..5c20970ccbbb 100644 --- a/drivers/iio/adc/qcom-rradc.c +++ b/drivers/iio/adc/qcom-rradc.c @@ -331,8 +331,8 @@ static int rradc_post_process_therm(struct rradc_chip *chip, int64_t temp; /* K = code/4 */ - temp = div64_s64(adc_code, FG_ADC_RR_BATT_THERM_LSB_K); - temp *= FG_ADC_SCALE_MILLI_FACTOR; + temp = ((int64_t)adc_code * FG_ADC_SCALE_MILLI_FACTOR); + temp = div64_s64(temp, FG_ADC_RR_BATT_THERM_LSB_K); *result_millidegc = temp - FG_ADC_KELVINMIL_CELSIUSMIL; return 0; diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c index ba9b4df6bf22..719b14226067 100644 --- a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c +++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c @@ -374,6 +374,7 @@ static int msm_vb2_put_buf(struct vb2_v4l2_buffer *vb, int session_id, pr_err("VB buffer is INVALID vb=%pK, ses_id=%d, str_id=%d\n", vb, session_id, stream_id); spin_unlock_irqrestore(&stream->stream_lock, flags); + read_unlock(&session->stream_rwlock); return -EINVAL; } msm_vb2 = @@ -428,6 +429,7 @@ static int msm_vb2_buf_done(struct vb2_v4l2_buffer *vb, int session_id, pr_err("VB buffer is INVALID ses_id=%d, str_id=%d, vb=%pK\n", session_id, stream_id, vb); spin_unlock_irqrestore(&stream->stream_lock, flags); + read_unlock(&session->stream_rwlock); return -EINVAL; } msm_vb2 = diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c index 491b8d31935a..cf7d1a8aa1f4 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c +++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c @@ -152,6 +152,12 @@ static int32_t msm_flash_i2c_write_table( conf_array.reg_setting = settings->reg_setting_a; conf_array.size = settings->size; + /* Validate the settings size */ + if ((!conf_array.size) || (conf_array.size > MAX_I2C_REG_SET)) { + pr_err("failed: invalid size %d", conf_array.size); + return -EINVAL; + } + return flash_ctrl->flash_i2c_client.i2c_func_tbl->i2c_write_table( &flash_ctrl->flash_i2c_client, &conf_array); } diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 79b5b3504ccd..0da9c5caea13 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -487,12 +487,17 @@ static int mmc_devfreq_set_target(struct device *dev, struct mmc_devfeq_clk_scaling *clk_scaling; int err = 0; int abort; + unsigned long pflags = current->flags; + + /* Ensure scaling would happen even in memory pressure conditions */ + current->flags |= PF_MEMALLOC; if (!(host && freq)) { pr_err("%s: unexpected host/freq parameter\n", __func__); err = -EINVAL; goto out; } + clk_scaling = &host->clk_scaling; if (!clk_scaling->enable) @@ -551,6 +556,7 @@ static int mmc_devfreq_set_target(struct device *dev, rel_host: mmc_release_host(host); out: + tsk_restore_flags(current, pflags, PF_MEMALLOC); return err; } diff --git a/drivers/net/wireless/cnss_utils/cnss_utils.c b/drivers/net/wireless/cnss_utils/cnss_utils.c index a452900868c4..d73846efbc4c 100644 --- a/drivers/net/wireless/cnss_utils/cnss_utils.c +++ b/drivers/net/wireless/cnss_utils/cnss_utils.c @@ -283,7 +283,7 @@ static int __init cnss_utils_init(void) { struct cnss_utils_priv *priv = NULL; - priv = kmalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; diff --git a/drivers/pwm/pwm-qpnp.c b/drivers/pwm/pwm-qpnp.c index d57bf2f3b80c..e46b1d583f40 100644 --- a/drivers/pwm/pwm-qpnp.c +++ b/drivers/pwm/pwm-qpnp.c @@ -317,6 +317,7 @@ struct _qpnp_pwm_config { struct pwm_period_config period; int supported_sizes; int force_pwm_size; + bool update_period; }; /* Public facing structure */ @@ -1211,28 +1212,32 @@ static int _pwm_config(struct qpnp_pwm_chip *chip, rc = qpnp_lpg_save_pwm_value(chip); if (rc) goto out; - rc = qpnp_lpg_configure_pwm(chip); - if (rc) - goto out; - rc = qpnp_configure_pwm_control(chip); - if (rc) - goto out; - if (!rc && chip->enabled) { - rc = qpnp_lpg_configure_pwm_state(chip, QPNP_PWM_ENABLE); - if (rc) { - pr_err("Error in configuring pwm state, rc=%d\n", rc); - return rc; - } + if (pwm_config->update_period) { + rc = qpnp_lpg_configure_pwm(chip); + if (rc) + goto out; + rc = qpnp_configure_pwm_control(chip); + if (rc) + goto out; + if (!rc && chip->enabled) { + rc = qpnp_lpg_configure_pwm_state(chip, + QPNP_PWM_ENABLE); + if (rc) { + pr_err("Error in configuring pwm state, rc=%d\n", + rc); + return rc; + } - /* Enable the glitch removal after PWM is enabled */ - rc = qpnp_lpg_glitch_removal(chip, true); - if (rc) { - pr_err("Error in enabling glitch control, rc=%d\n", rc); - return rc; + /* Enable the glitch removal after PWM is enabled */ + rc = qpnp_lpg_glitch_removal(chip, true); + if (rc) { + pr_err("Error in enabling glitch control, rc=%d\n", + rc); + return rc; + } } } - pr_debug("duty/period=%u/%u %s: pwm_value=%d (of %d)\n", (unsigned int)duty_value, (unsigned int)period_value, (tm_lvl == LVL_USEC) ? "usec" : "nsec", @@ -1375,12 +1380,14 @@ static int qpnp_pwm_config(struct pwm_chip *pwm_chip, spin_lock_irqsave(&chip->lpg_lock, flags); + chip->pwm_config.update_period = false; if (prev_period_us > INT_MAX / NSEC_PER_USEC || prev_period_us * NSEC_PER_USEC != period_ns) { qpnp_lpg_calc_period(LVL_NSEC, period_ns, chip); qpnp_lpg_save_period(chip); pwm->period = period_ns; chip->pwm_config.pwm_period = period_ns / NSEC_PER_USEC; + chip->pwm_config.update_period = true; } rc = _pwm_config(chip, LVL_NSEC, duty_ns, period_ns); @@ -1619,6 +1626,7 @@ int pwm_config_us(struct pwm_device *pwm, int duty_us, int period_us) spin_lock_irqsave(&chip->lpg_lock, flags); + chip->pwm_config.update_period = false; if (chip->pwm_config.pwm_period != period_us) { qpnp_lpg_calc_period(LVL_USEC, period_us, chip); qpnp_lpg_save_period(chip); @@ -1628,6 +1636,7 @@ int pwm_config_us(struct pwm_device *pwm, int duty_us, int period_us) pwm->period = 0; else pwm->period = (unsigned int)period_us * NSEC_PER_USEC; + chip->pwm_config.update_period = true; } rc = _pwm_config(chip, LVL_USEC, duty_us, period_us); @@ -1734,6 +1743,7 @@ static int qpnp_parse_pwm_dt_config(struct device_node *of_pwm_node, qpnp_lpg_calc_period(LVL_USEC, period, chip); qpnp_lpg_save_period(chip); chip->pwm_config.pwm_period = period; + chip->pwm_config.update_period = true; rc = _pwm_config(chip, LVL_USEC, chip->pwm_config.pwm_duty, period); diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index adf621430b41..188920367e84 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2361,6 +2361,14 @@ static void regulator_disable_work(struct work_struct *work) count = rdev->deferred_disables; rdev->deferred_disables = 0; + /* + * Workqueue functions queue the new work instance while the previous + * work instance is being processed. Cancel the queued work instance + * as the work instance under processing does the job of the queued + * work instance. + */ + cancel_delayed_work(&rdev->disable_work); + for (i = 0; i < count; i++) { ret = _regulator_disable(rdev); if (ret != 0) @@ -2404,10 +2412,10 @@ int regulator_disable_deferred(struct regulator *regulator, int ms) mutex_lock(&rdev->mutex); rdev->deferred_disables++; + mod_delayed_work(system_power_efficient_wq, &rdev->disable_work, + msecs_to_jiffies(ms)); mutex_unlock(&rdev->mutex); - queue_delayed_work(system_power_efficient_wq, &rdev->disable_work, - msecs_to_jiffies(ms)); return 0; } EXPORT_SYMBOL_GPL(regulator_disable_deferred); diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index 21be894414bc..07fe5720c4d8 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -365,6 +365,7 @@ struct icnss_stats { uint32_t vbatt_req; uint32_t vbatt_resp; uint32_t vbatt_req_err; + u32 rejuvenate_ind; uint32_t rejuvenate_ack_req; uint32_t rejuvenate_ack_resp; uint32_t rejuvenate_ack_err; @@ -456,6 +457,10 @@ static struct icnss_priv { struct icnss_wlan_mac_addr wlan_mac_addr; bool bypass_s1_smmu; struct mutex dev_lock; + u8 cause_for_rejuvenation; + u8 requesting_sub_system; + u16 line_number; + char function_name[QMI_WLFW_FUNCTION_NAME_LEN_V01 + 1]; } *penv; #ifdef CONFIG_ICNSS_DEBUG @@ -1691,6 +1696,60 @@ out: return ret; } +static int icnss_decode_rejuvenate_ind(void *msg, unsigned int msg_len) +{ + struct msg_desc ind_desc; + struct wlfw_rejuvenate_ind_msg_v01 ind_msg; + int ret = 0; + + if (!penv || !penv->wlfw_clnt) { + ret = -ENODEV; + goto out; + } + + memset(&ind_msg, 0, sizeof(ind_msg)); + + ind_desc.msg_id = QMI_WLFW_REJUVENATE_IND_V01; + ind_desc.max_msg_len = WLFW_REJUVENATE_IND_MSG_V01_MAX_MSG_LEN; + ind_desc.ei_array = wlfw_rejuvenate_ind_msg_v01_ei; + + ret = qmi_kernel_decode(&ind_desc, &ind_msg, msg, msg_len); + if (ret < 0) { + icnss_pr_err("Failed to decode rejuvenate ind message: ret %d, msg_len %u\n", + ret, msg_len); + goto out; + } + + if (ind_msg.cause_for_rejuvenation_valid) + penv->cause_for_rejuvenation = ind_msg.cause_for_rejuvenation; + else + penv->cause_for_rejuvenation = 0; + if (ind_msg.requesting_sub_system_valid) + penv->requesting_sub_system = ind_msg.requesting_sub_system; + else + penv->requesting_sub_system = 0; + if (ind_msg.line_number_valid) + penv->line_number = ind_msg.line_number; + else + penv->line_number = 0; + if (ind_msg.function_name_valid) + memcpy(penv->function_name, ind_msg.function_name, + QMI_WLFW_FUNCTION_NAME_LEN_V01 + 1); + else + memset(penv->function_name, 0, + QMI_WLFW_FUNCTION_NAME_LEN_V01 + 1); + + icnss_pr_info("Cause for rejuvenation: 0x%x, requesting sub-system: 0x%x, line number: %u, function name: %s\n", + penv->cause_for_rejuvenation, + penv->requesting_sub_system, + penv->line_number, + penv->function_name); + + penv->stats.rejuvenate_ind++; +out: + return ret; +} + static int wlfw_rejuvenate_ack_send_sync_msg(struct icnss_priv *priv) { int ret; @@ -1884,6 +1943,7 @@ static void icnss_qmi_wlfw_clnt_ind(struct qmi_handle *handle, msg_id, penv->state); icnss_ignore_qmi_timeout(true); + icnss_decode_rejuvenate_ind(msg, msg_len); event_data = kzalloc(sizeof(*event_data), GFP_KERNEL); if (event_data == NULL) return; @@ -3786,6 +3846,26 @@ static int icnss_stats_show_capability(struct seq_file *s, return 0; } +static int icnss_stats_show_rejuvenate_info(struct seq_file *s, + struct icnss_priv *priv) +{ + if (priv->stats.rejuvenate_ind) { + seq_puts(s, "\n<---------------- Rejuvenate Info ----------------->\n"); + seq_printf(s, "Number of Rejuvenations: %u\n", + priv->stats.rejuvenate_ind); + seq_printf(s, "Cause for Rejuvenation: 0x%x\n", + priv->cause_for_rejuvenation); + seq_printf(s, "Requesting Sub-System: 0x%x\n", + priv->requesting_sub_system); + seq_printf(s, "Line Number: %u\n", + priv->line_number); + seq_printf(s, "Function Name: %s\n", + priv->function_name); + } + + return 0; +} + static int icnss_stats_show_events(struct seq_file *s, struct icnss_priv *priv) { int i; @@ -3851,6 +3931,7 @@ static int icnss_stats_show(struct seq_file *s, void *data) ICNSS_STATS_DUMP(s, priv, vbatt_req); ICNSS_STATS_DUMP(s, priv, vbatt_resp); ICNSS_STATS_DUMP(s, priv, vbatt_req_err); + ICNSS_STATS_DUMP(s, priv, rejuvenate_ind); ICNSS_STATS_DUMP(s, priv, rejuvenate_ack_req); ICNSS_STATS_DUMP(s, priv, rejuvenate_ack_resp); ICNSS_STATS_DUMP(s, priv, rejuvenate_ack_err); @@ -3875,6 +3956,8 @@ static int icnss_stats_show(struct seq_file *s, void *data) icnss_stats_show_capability(s, priv); + icnss_stats_show_rejuvenate_info(s, priv); + icnss_stats_show_events(s, priv); icnss_stats_show_state(s, priv); diff --git a/drivers/soc/qcom/spcom.c b/drivers/soc/qcom/spcom.c index 7f03aabf415e..e4afce02afc7 100644 --- a/drivers/soc/qcom/spcom.c +++ b/drivers/soc/qcom/spcom.c @@ -245,7 +245,7 @@ struct spcom_device { int channel_count; /* private */ - struct mutex lock; + struct mutex cmd_lock; /* Link state */ struct completion link_state_changed; @@ -1952,6 +1952,8 @@ static int spcom_handle_write(struct spcom_channel *ch, swap_id = htonl(cmd->cmd_id); memcpy(cmd_name, &swap_id, sizeof(int)); + mutex_lock(&spcom_dev->cmd_lock); + pr_debug("cmd_id [0x%x] cmd_name [%s].\n", cmd_id, cmd_name); switch (cmd_id) { @@ -1972,9 +1974,11 @@ static int spcom_handle_write(struct spcom_channel *ch, break; default: pr_err("Invalid Command Id [0x%x].\n", (int) cmd->cmd_id); - return -EINVAL; + ret = -EINVAL; } + mutex_unlock(&spcom_dev->cmd_lock); + return ret; } @@ -2675,7 +2679,7 @@ static int spcom_probe(struct platform_device *pdev) return -ENOMEM; spcom_dev = dev; - mutex_init(&dev->lock); + mutex_init(&spcom_dev->cmd_lock); init_completion(&dev->link_state_changed); spcom_dev->link_state = GLINK_LINK_STATE_DOWN; diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index a24c5b909047..b05509af0352 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c @@ -114,6 +114,11 @@ static ssize_t write_irq_affinity(int type, struct file *file, goto free_cpumask; } + if (cpumask_subset(new_value, cpu_isolated_mask)) { + err = -EINVAL; + goto free_cpumask; + } + /* * Do not allow disabling IRQs completely - it's a too easy * way to make the system unusable accidentally :-) At least |
