Merge "slimbus: Specify number of channels for the group in group handle"
diff --git a/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt b/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
index 5d1fafb..b4093de 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
@@ -21,6 +21,13 @@
- qcom,limit-temp: Threshold temperature to start stepping CPU down, in degC.
- qcom,temp-hysteresis: Degrees below threshold temperature to step CPU up.
- qcom,freq-step: Number of frequency steps to take on each CPU mitigation.
+- qcom,core-limit-temp: Threshold temperature to start shutting down cores
+ in degC
+- qcom,core-temp-hysterisis: Degrees below core-limit-temp, the cores will be
+ brought online in sequence.
+- qcom,core-control-mask: The cpu mask that will be used to determine if a
+ core can be controlled or not. A mask of 0 indicates
+ the feature is disabled.
Example:
@@ -31,4 +38,7 @@
qcom,limit-temp = <60>;
qcom,temp-hysteresis = <10>;
qcom,freq-step = <2>;
+ qcom,core-limit-temp = <90>;
+ qcom,core-temp-hysterisis = <10>;
+ qcom,core-control-mask = <7>;
};
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 5003ee2..51228a0 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1876,6 +1876,9 @@
.limit_temp_degC = 60,
.temp_hysteresis_degC = 10,
.freq_step = 2,
+ .core_limit_temp_degC = 80,
+ .core_temp_hysteresis_degC = 10,
+ .core_control_mask = 0xe,
};
#define MSM_SHARED_RAM_PHYS 0x80000000
@@ -3223,6 +3226,16 @@
if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917)
apq8064_pm8917_pdata_fixup();
platform_device_register(&msm_gpio_device);
+ if (cpu_is_apq8064ab())
+ apq8064ab_update_krait_spm();
+ if (cpu_is_krait_v3()) {
+ msm_pm_set_tz_retention_flag(0);
+ apq8064ab_update_retention_spm();
+ } else {
+ msm_pm_set_tz_retention_flag(1);
+ }
+ msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
+ msm_spm_l2_init(msm_spm_l2_data);
msm_tsens_early_init(&apq_tsens_pdata);
msm_thermal_init(&msm_thermal_pdata);
if (socinfo_init() < 0)
@@ -3329,16 +3342,6 @@
apq8064_init_dsps();
platform_device_register(&msm_8960_riva);
}
- if (cpu_is_apq8064ab())
- apq8064ab_update_krait_spm();
- if (cpu_is_krait_v3()) {
- msm_pm_set_tz_retention_flag(0);
- apq8064ab_update_retention_spm();
- } else {
- msm_pm_set_tz_retention_flag(1);
- }
- msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
- msm_spm_l2_init(msm_spm_l2_data);
BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
apq8064_epm_adc_init();
}
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index 8136a42..c931ac7 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1114,18 +1114,11 @@
},
};
-static int __init msm_pm_init(void)
+static int __init msm_pm_setup_saved_state(void)
{
pgd_t *pc_pgd;
pmd_t *pmd;
unsigned long pmdval;
- enum msm_pm_time_stats_id enable_stats[] = {
- MSM_PM_STAT_IDLE_WFI,
- MSM_PM_STAT_RETENTION,
- MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE,
- MSM_PM_STAT_IDLE_POWER_COLLAPSE,
- MSM_PM_STAT_SUSPEND,
- };
unsigned long exit_phys;
/* Page table for cores to come back up safely. */
@@ -1166,6 +1159,20 @@
clean_caches((unsigned long)&msm_pm_pc_pgd, sizeof(msm_pm_pc_pgd),
virt_to_phys(&msm_pm_pc_pgd));
+ return 0;
+}
+core_initcall(msm_pm_setup_saved_state);
+
+static int __init msm_pm_init(void)
+{
+ enum msm_pm_time_stats_id enable_stats[] = {
+ MSM_PM_STAT_IDLE_WFI,
+ MSM_PM_STAT_RETENTION,
+ MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE,
+ MSM_PM_STAT_IDLE_POWER_COLLAPSE,
+ MSM_PM_STAT_SUSPEND,
+ };
+
msm_pm_mode_sysfs_add();
msm_pm_add_stats(enable_stats, ARRAY_SIZE(enable_stats));
diff --git a/arch/arm/mach-msm/pm-data.c b/arch/arm/mach-msm/pm-data.c
index 8fe2288..7fe7795 100644
--- a/arch/arm/mach-msm/pm-data.c
+++ b/arch/arm/mach-msm/pm-data.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -46,7 +46,7 @@
.idle_supported = 0,
.suspend_supported = 1,
.idle_enabled = 0,
- .suspend_enabled = 0,
+ .suspend_enabled = 1,
},
[MSM_PM_MODE(1, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE)] = {
@@ -74,7 +74,7 @@
.idle_supported = 0,
.suspend_supported = 1,
.idle_enabled = 0,
- .suspend_enabled = 0,
+ .suspend_enabled = 1,
},
[MSM_PM_MODE(2, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE)] = {
@@ -102,7 +102,7 @@
.idle_supported = 0,
.suspend_supported = 1,
.idle_enabled = 0,
- .suspend_enabled = 0,
+ .suspend_enabled = 1,
},
[MSM_PM_MODE(3, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE)] = {
diff --git a/block/blk-core.c b/block/blk-core.c
index 68d7158..fcb2a1b 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -29,6 +29,7 @@
#include <linux/fault-inject.h>
#include <linux/list_sort.h>
#include <linux/delay.h>
+#include <linux/ratelimit.h>
#define CREATE_TRACE_POINTS
#include <trace/events/block.h>
@@ -2141,9 +2142,11 @@
error_type = "I/O";
break;
}
- printk(KERN_ERR "end_request: %s error, dev %s, sector %llu\n",
- error_type, req->rq_disk ? req->rq_disk->disk_name : "?",
- (unsigned long long)blk_rq_pos(req));
+ printk_ratelimited(
+ KERN_ERR "end_request: %s error, dev %s, sector %llu\n",
+ error_type,
+ req->rq_disk ? req->rq_disk->disk_name : "?",
+ (unsigned long long)blk_rq_pos(req));
}
blk_account_io_completion(req, nr_bytes);
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index 68f4bdd..5136fdf 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -3142,6 +3142,9 @@
static void pm_batt_external_power_changed(struct power_supply *psy)
{
+ if (!the_chip)
+ return;
+
/* Only look for an external supply if it hasn't been registered */
if (!the_chip->ext_psy)
class_for_each_device(power_supply_class, NULL, psy,
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index 0e3daeb..177ebff 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -29,6 +29,9 @@
static struct msm_thermal_data msm_thermal_info;
static uint32_t limited_max_freq = MSM_CPUFREQ_NO_LIMIT;
static struct delayed_work check_temp_work;
+static bool core_control_enabled;
+static uint32_t cpus_offlined;
+static DEFINE_MUTEX(core_control_mutex);
static int limit_idx;
static int limit_idx_low;
@@ -42,7 +45,7 @@
table = cpufreq_frequency_get_table(0);
if (table == NULL) {
- pr_debug("%s: error reading cpufreq table\n", __func__);
+ pr_debug("%s: error reading cpufreq table\n", KBUILD_MODNAME);
ret = -EINVAL;
goto fail;
}
@@ -67,21 +70,82 @@
limited_max_freq = max_freq;
if (max_freq != MSM_CPUFREQ_NO_LIMIT)
- pr_info("msm_thermal: Limiting cpu%d max frequency to %d\n",
- cpu, max_freq);
+ pr_info("%s: Limiting cpu%d max frequency to %d\n",
+ KBUILD_MODNAME, cpu, max_freq);
else
- pr_info("msm_thermal: Max frequency reset for cpu%d\n", cpu);
+ pr_info("%s: Max frequency reset for cpu%d\n",
+ KBUILD_MODNAME, cpu);
ret = cpufreq_update_policy(cpu);
return ret;
}
-static void check_temp(struct work_struct *work)
+static void __cpuinit do_core_control(long temp)
+{
+ int i = 0;
+ int ret = 0;
+
+ if (!core_control_enabled)
+ return;
+
+ /**
+ * Offline cores starting from the max MPIDR to 1, when above limit,
+ * The core control mask is non zero and allows the core to be turned
+ * off.
+ * The core was not previously offlined by this module
+ * The core is the next in sequence.
+ * If the core was online for some reason, even after it was offlined
+ * by this module, offline it again.
+ * Online the back on if the temp is below the hysteresis and was
+ * offlined by this module and not already online.
+ */
+ mutex_lock(&core_control_mutex);
+ if (msm_thermal_info.core_control_mask &&
+ temp >= msm_thermal_info.core_limit_temp_degC) {
+ for (i = num_possible_cpus(); i > 0; i--) {
+ if (!(msm_thermal_info.core_control_mask & BIT(i)))
+ continue;
+ if (cpus_offlined & BIT(i) && !cpu_online(i))
+ continue;
+ pr_info("%s: Set Offline: CPU%d Temp: %ld\n",
+ KBUILD_MODNAME, i, temp);
+ ret = cpu_down(i);
+ if (ret)
+ pr_err("%s: Error %d offline core %d\n",
+ KBUILD_MODNAME, ret, i);
+ cpus_offlined |= BIT(i);
+ break;
+ }
+ } else if (msm_thermal_info.core_control_mask && cpus_offlined &&
+ temp <= (msm_thermal_info.core_limit_temp_degC -
+ msm_thermal_info.core_temp_hysteresis_degC)) {
+ for (i = 0; i < num_possible_cpus(); i++) {
+ if (!(cpus_offlined & BIT(i)))
+ continue;
+ cpus_offlined &= ~BIT(i);
+ pr_info("%s: Allow Online CPU%d Temp: %ld\n",
+ KBUILD_MODNAME, i, temp);
+ /* If this core is already online, then bring up the
+ * next offlined core.
+ */
+ if (cpu_online(i))
+ continue;
+ ret = cpu_up(i);
+ if (ret)
+ pr_err("%s: Error %d online core %d\n",
+ KBUILD_MODNAME, ret, i);
+ break;
+ }
+ }
+ mutex_unlock(&core_control_mutex);
+}
+
+static void __cpuinit check_temp(struct work_struct *work)
{
static int limit_init;
struct tsens_device tsens_dev;
- unsigned long temp = 0;
+ long temp = 0;
uint32_t max_freq = limited_max_freq;
int cpu = 0;
int ret = 0;
@@ -89,8 +153,8 @@
tsens_dev.sensor_num = msm_thermal_info.sensor_id;
ret = tsens_get_temp(&tsens_dev, &temp);
if (ret) {
- pr_debug("msm_thermal: Unable to read TSENS sensor %d\n",
- tsens_dev.sensor_num);
+ pr_debug("%s: Unable to read TSENS sensor %d\n",
+ KBUILD_MODNAME, tsens_dev.sensor_num);
goto reschedule;
}
@@ -102,6 +166,8 @@
limit_init = 1;
}
+ do_core_control(temp);
+
if (temp >= msm_thermal_info.limit_temp_degC) {
if (limit_idx == limit_idx_low)
goto reschedule;
@@ -129,8 +195,9 @@
for_each_possible_cpu(cpu) {
ret = update_cpu_max_freq(cpu, max_freq);
if (ret)
- pr_debug("Unable to limit cpu%d max freq to %d\n",
- cpu, max_freq);
+ pr_debug(
+ "%s: Unable to limit cpu%d max freq to %d\n",
+ KBUILD_MODNAME, cpu, max_freq);
}
reschedule:
@@ -139,7 +206,36 @@
msecs_to_jiffies(msm_thermal_info.poll_ms));
}
-static void disable_msm_thermal(void)
+static int __cpuinit msm_thermal_cpu_callback(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned long)hcpu;
+
+ if (action == CPU_UP_PREPARE || action == CPU_UP_PREPARE_FROZEN) {
+ if (core_control_enabled &&
+ (msm_thermal_info.core_control_mask & BIT(cpu)) &&
+ (cpus_offlined & BIT(cpu))) {
+ pr_info(
+ "%s: Preventing cpu%d from coming online.\n",
+ KBUILD_MODNAME, cpu);
+ return NOTIFY_BAD;
+ }
+ }
+
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block __refdata msm_thermal_cpu_notifier = {
+ .notifier_call = msm_thermal_cpu_callback,
+};
+
+/**
+ * We will reset the cpu frequencies limits here. The core online/offline
+ * status will be carried over to the process stopping the msm_thermal, as
+ * we dont want to online a core and bring in the thermal issues.
+ */
+static void __cpuinit disable_msm_thermal(void)
{
int cpu = 0;
@@ -155,7 +251,7 @@
}
}
-static int set_enabled(const char *val, const struct kernel_param *kp)
+static int __cpuinit set_enabled(const char *val, const struct kernel_param *kp)
{
int ret = 0;
@@ -163,9 +259,10 @@
if (!enabled)
disable_msm_thermal();
else
- pr_info("msm_thermal: no action for enabled = %d\n", enabled);
+ pr_info("%s: no action for enabled = %d\n",
+ KBUILD_MODNAME, enabled);
- pr_info("msm_thermal: enabled = %d\n", enabled);
+ pr_info("%s: enabled = %d\n", KBUILD_MODNAME, enabled);
return ret;
}
@@ -178,6 +275,153 @@
module_param_cb(enabled, &module_ops, &enabled, 0644);
MODULE_PARM_DESC(enabled, "enforce thermal limit on cpu");
+
+/* Call with core_control_mutex locked */
+static int __cpuinit update_offline_cores(int val)
+{
+ int cpu = 0;
+ int ret = 0;
+
+ cpus_offlined = msm_thermal_info.core_control_mask & val;
+ if (!core_control_enabled)
+ return 0;
+
+ for_each_possible_cpu(cpu) {
+ if (!(cpus_offlined & BIT(cpu)))
+ continue;
+ if (!cpu_online(cpu))
+ continue;
+ ret = cpu_down(cpu);
+ if (ret)
+ pr_err("%s: Unable to offline cpu%d\n",
+ KBUILD_MODNAME, cpu);
+ }
+ return ret;
+}
+
+static ssize_t show_cc_enabled(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%d\n", core_control_enabled);
+}
+
+static ssize_t __cpuinit store_cc_enabled(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ int ret = 0;
+ int val = 0;
+
+ mutex_lock(&core_control_mutex);
+ ret = kstrtoint(buf, 10, &val);
+ if (ret) {
+ pr_err("%s: Invalid input %s\n", KBUILD_MODNAME, buf);
+ goto done_store_cc;
+ }
+
+ if (core_control_enabled == !!val)
+ goto done_store_cc;
+
+ core_control_enabled = !!val;
+ if (core_control_enabled) {
+ pr_info("%s: Core control enabled\n", KBUILD_MODNAME);
+ register_cpu_notifier(&msm_thermal_cpu_notifier);
+ update_offline_cores(cpus_offlined);
+ } else {
+ pr_info("%s: Core control disabled\n", KBUILD_MODNAME);
+ unregister_cpu_notifier(&msm_thermal_cpu_notifier);
+ }
+
+done_store_cc:
+ mutex_unlock(&core_control_mutex);
+ return count;
+}
+
+static ssize_t show_cpus_offlined(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%d\n", cpus_offlined);
+}
+
+static ssize_t __cpuinit store_cpus_offlined(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ int ret = 0;
+ uint32_t val = 0;
+
+ mutex_lock(&core_control_mutex);
+ ret = kstrtouint(buf, 10, &val);
+ if (ret) {
+ pr_err("%s: Invalid input %s\n", KBUILD_MODNAME, buf);
+ goto done_cc;
+ }
+
+ if (enabled) {
+ pr_err("%s: Ignoring request; polling thread is enabled.\n",
+ KBUILD_MODNAME);
+ goto done_cc;
+ }
+
+ if (cpus_offlined == val)
+ goto done_cc;
+
+ update_offline_cores(val);
+done_cc:
+ mutex_unlock(&core_control_mutex);
+ return count;
+}
+
+static __cpuinitdata struct kobj_attribute cc_enabled_attr =
+__ATTR(enabled, 0644, show_cc_enabled, store_cc_enabled);
+
+static __cpuinitdata struct kobj_attribute cpus_offlined_attr =
+__ATTR(cpus_offlined, 0644, show_cpus_offlined, store_cpus_offlined);
+
+static __cpuinitdata struct attribute *cc_attrs[] = {
+ &cc_enabled_attr.attr,
+ &cpus_offlined_attr.attr,
+ NULL,
+};
+
+static __cpuinitdata struct attribute_group cc_attr_group = {
+ .attrs = cc_attrs,
+};
+
+static __init int msm_thermal_add_cc_nodes(void)
+{
+ struct kobject *module_kobj = NULL;
+ struct kobject *cc_kobj = NULL;
+ int ret = 0;
+
+ module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME);
+ if (!module_kobj) {
+ pr_err("%s: cannot find kobject for module\n",
+ KBUILD_MODNAME);
+ ret = -ENOENT;
+ goto done_cc_nodes;
+ }
+
+ cc_kobj = kobject_create_and_add("core_control", module_kobj);
+ if (!cc_kobj) {
+ pr_err("%s: cannot create core control kobj\n",
+ KBUILD_MODNAME);
+ ret = -ENOMEM;
+ goto done_cc_nodes;
+ }
+
+ ret = sysfs_create_group(cc_kobj, &cc_attr_group);
+ if (ret) {
+ pr_err("%s: cannot create group\n", KBUILD_MODNAME);
+ goto done_cc_nodes;
+ }
+
+ return 0;
+
+done_cc_nodes:
+ if (cc_kobj)
+ kobject_del(cc_kobj);
+ return ret;
+}
+
int __devinit msm_thermal_init(struct msm_thermal_data *pdata)
{
int ret = 0;
@@ -187,9 +431,12 @@
memcpy(&msm_thermal_info, pdata, sizeof(struct msm_thermal_data));
enabled = 1;
+ core_control_enabled = 1;
INIT_DELAYED_WORK(&check_temp_work, check_temp);
schedule_delayed_work(&check_temp_work, 0);
+ register_cpu_notifier(&msm_thermal_cpu_notifier);
+
return ret;
}
@@ -224,6 +471,23 @@
key = "qcom,freq-step";
ret = of_property_read_u32(node, key, &data.freq_step);
+ if (ret)
+ goto fail;
+
+ key = "qcom,core-limit-temp";
+ ret = of_property_read_u32(node, key, &data.core_limit_temp_degC);
+ if (ret)
+ goto fail;
+
+ key = "qcom,core-temp-hysteresis";
+ ret = of_property_read_u32(node, key, &data.core_temp_hysteresis_degC);
+ if (ret)
+ goto fail;
+
+ key = "qcom,core-control-mask";
+ ret = of_property_read_u32(node, key, &data.core_control_mask);
+ if (ret)
+ goto fail;
fail:
if (ret)
@@ -253,3 +517,9 @@
{
return platform_driver_register(&msm_thermal_device_driver);
}
+
+int __init msm_thermal_late_init(void)
+{
+ return msm_thermal_add_cc_nodes();
+}
+module_init(msm_thermal_late_init);
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 963cb26..f4d5426 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -322,14 +322,17 @@
*/
static int hw_device_reset(struct ci13xxx *udc)
{
+ int delay_count = 25; /* 250 usec */
+
/* should flush & stop before reset */
hw_cwrite(CAP_ENDPTFLUSH, ~0, ~0);
hw_cwrite(CAP_USBCMD, USBCMD_RS, 0);
hw_cwrite(CAP_USBCMD, USBCMD_RST, USBCMD_RST);
- while (hw_cread(CAP_USBCMD, USBCMD_RST))
- udelay(10); /* not RTOS friendly */
-
+ while (delay_count-- && hw_cread(CAP_USBCMD, USBCMD_RST))
+ udelay(10);
+ if (delay_count < 0)
+ pr_err("USB controller reset failed\n");
if (udc->udc_driver->notify_event)
udc->udc_driver->notify_event(udc,
@@ -792,6 +795,8 @@
*/
static int hw_usb_reset(void)
{
+ int delay_count = 10; /* 100 usec delay */
+
hw_usb_set_address(0);
/* ESS flushes only at end?!? */
@@ -804,8 +809,10 @@
hw_cwrite(CAP_ENDPTCOMPLETE, 0, 0); /* writes its content */
/* wait until all bits cleared */
- while (hw_cread(CAP_ENDPTPRIME, ~0))
- udelay(10); /* not RTOS friendly */
+ while (delay_count-- && hw_cread(CAP_ENDPTPRIME, ~0))
+ udelay(10);
+ if (delay_count < 0)
+ pr_err("ENDPTPRIME is not cleared during bus reset\n");
/* reset all endpoints ? */
diff --git a/drivers/usb/gadget/u_data_hsic.c b/drivers/usb/gadget/u_data_hsic.c
index 03433ce..752c476 100644
--- a/drivers/usb/gadget/u_data_hsic.c
+++ b/drivers/usb/gadget/u_data_hsic.c
@@ -643,6 +643,9 @@
if (ep_out)
usb_ep_fifo_flush(ep_out);
+ /* cancel pending writes to MDM */
+ cancel_work_sync(&port->write_tomdm_w);
+
ghsic_data_free_buffers(port);
cancel_work_sync(&port->connect_w);
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index 0d05e2f..ebe8c6e 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -379,7 +379,7 @@
list_add_tail(&urb->urb_list, &portdata->in_urb_list);
spin_unlock_irqrestore(&portdata->in_lock, flags);
- schedule_work(&portdata->in_work);
+ queue_work(system_nrt_wq, &portdata->in_work);
return;
}
@@ -498,7 +498,7 @@
port->throttle_req = false;
port->throttled = false;
- schedule_work(&portdata->in_work);
+ queue_work(system_nrt_wq, &portdata->in_work);
}
EXPORT_SYMBOL(usb_wwan_unthrottle);
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index f3302a53..e9d41d1 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -3278,9 +3278,10 @@
mdp4_overlay_mdp_pipe_req(pipe, mfd);
ret = mdp4_overlay_mdp_perf_req(mfd);
- if (ret)
+ if (ret) {
+ mdp4_overlay_pipe_free(pipe);
pr_err("%s: blt mode should not be enabled\n", __func__);
-
+ }
mutex_unlock(&mfd->dma->ov_mutex);
return ret;
diff --git a/include/linux/msm_thermal.h b/include/linux/msm_thermal.h
index 2c9a613..c89169c 100644
--- a/include/linux/msm_thermal.h
+++ b/include/linux/msm_thermal.h
@@ -20,6 +20,9 @@
uint32_t limit_temp_degC;
uint32_t temp_hysteresis_degC;
uint32_t freq_step;
+ uint32_t core_limit_temp_degC;
+ uint32_t core_temp_hysteresis_degC;
+ uint32_t core_control_mask;
};
#ifdef CONFIG_THERMAL_MONITOR