Merge "usb: phy: Add BIAS_CTRL2 register offset as mandatory"
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
index e1136da..12958b2 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
@@ -175,7 +175,7 @@
reg = <0x831000 0x200>;
interrupts = <0 26 0>;
status = "disabled";
- clocks = <&clock_gcc GCC_BLSP1_UART2_APPS_CLK>,
+ clocks = <&clock_gcc GCC_BLSP1_UART3_APPS_CLK>,
<&clock_gcc GCC_BLSP1_AHB_CLK>;
clock-names = "core", "iface";
};
diff --git a/arch/arm64/boot/dts/qcom/sda845-v2-hdk.dtsi b/arch/arm64/boot/dts/qcom/sda845-v2-hdk.dtsi
index 53617dc..d212554 100644
--- a/arch/arm64/boot/dts/qcom/sda845-v2-hdk.dtsi
+++ b/arch/arm64/boot/dts/qcom/sda845-v2-hdk.dtsi
@@ -18,3 +18,7 @@
#include "fg-gen3-batterydata-mlp356477-2800mah.dtsi"
};
};
+
+&sdhc_2 {
+ cd-gpios = <&tlmm 126 GPIO_ACTIVE_LOW>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index 30f0bb0..fa8a67d 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -1826,6 +1826,7 @@
reg = <0x0 0x200000>;
reg-names = "rmtfs";
qcom,client-id = <0x00000001>;
+ qcom,guard-memory;
};
qcom,msm_gsi {
@@ -2125,6 +2126,28 @@
status = "ok";
};
+ sdcc1_ice: sdcc1ice@7c8000 {
+ compatible = "qcom,ice";
+ reg = <0x7c8000 0x8000>;
+ qcom,enable-ice-clk;
+ clock-names = "ice_core_clk_src", "ice_core_clk",
+ "bus_clk", "iface_clk";
+ clocks = <&clock_gcc GCC_SDCC1_ICE_CORE_CLK_SRC>,
+ <&clock_gcc GCC_SDCC1_ICE_CORE_CLK>,
+ <&clock_gcc GCC_SDCC1_APPS_CLK>,
+ <&clock_gcc GCC_SDCC1_AHB_CLK>;
+ qcom,op-freq-hz = <300000000>, <0>, <0>, <0>;
+ qcom,msm-bus,name = "sdcc_ice_noc";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <150 512 0 0>, /* No vote */
+ <150 512 1000 0>; /* Max. bandwidth */
+ qcom,bus-vector-names = "MIN",
+ "MAX";
+ qcom,instance-type = "sdcc";
+ };
+
sdhc_1: sdhci@7c4000 {
compatible = "qcom,sdhci-msm-v5";
reg = <0x7C4000 0x1000>, <0x7C5000 0x1000>;
@@ -2135,6 +2158,7 @@
qcom,bus-width = <8>;
qcom,large-address-bus;
+ sdhc-msm-crypto = <&sdcc1_ice>;
qcom,clk-rates = <400000 20000000 25000000 50000000 100000000
192000000 384000000>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-qvr.dtsi b/arch/arm64/boot/dts/qcom/sdm845-qvr.dtsi
index 2d701a5..60e1cfc 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-qvr.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-qvr.dtsi
@@ -25,6 +25,10 @@
vbus-supply = <&smb2_vbus>;
};
+&qupv3_se6_4uart {
+ status = "ok";
+};
+
&pmi8998_fg {
qcom,battery-data = <&qvr_batterydata>;
qcom,fg-bmd-en-delay-ms = <300>;
diff --git a/arch/arm64/configs/sdm670-perf_defconfig b/arch/arm64/configs/sdm670-perf_defconfig
index 0228c36..97958e1 100644
--- a/arch/arm64/configs/sdm670-perf_defconfig
+++ b/arch/arm64/configs/sdm670-perf_defconfig
@@ -21,6 +21,7 @@
CONFIG_CPUSETS=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_SCHEDTUNE=y
+CONFIG_BLK_CGROUP=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_CGROUP_BPF=y
CONFIG_SCHED_CORE_CTL=y
@@ -52,6 +53,7 @@
CONFIG_MODULE_SIG_FORCE=y
CONFIG_MODULE_SIG_SHA512=y
CONFIG_PARTITION_ADVANCED=y
+CONFIG_CFQ_GROUP_IOSCHED=y
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_SDM670=y
CONFIG_PCI=y
diff --git a/arch/arm64/configs/sdm670_defconfig b/arch/arm64/configs/sdm670_defconfig
index 87f710e..e812f8e 100644
--- a/arch/arm64/configs/sdm670_defconfig
+++ b/arch/arm64/configs/sdm670_defconfig
@@ -22,6 +22,8 @@
CONFIG_CPUSETS=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_SCHEDTUNE=y
+CONFIG_BLK_CGROUP=y
+CONFIG_DEBUG_BLK_CGROUP=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_CGROUP_BPF=y
CONFIG_SCHED_CORE_CTL=y
@@ -54,6 +56,7 @@
# CONFIG_BLK_DEV_BSG is not set
CONFIG_PARTITION_ADVANCED=y
# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_CFQ_GROUP_IOSCHED=y
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_SDM670=y
CONFIG_PCI=y
@@ -264,6 +267,7 @@
CONFIG_MD=y
CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=y
+CONFIG_DM_REQ_CRYPT=y
CONFIG_DM_UEVENT=y
CONFIG_DM_VERITY=y
CONFIG_DM_VERITY_FEC=y
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index c9ae689..36f8546 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -33,7 +33,7 @@
#define DIAG_MAX_REQ_SIZE (16 * 1024)
#define DIAG_MAX_RSP_SIZE (16 * 1024)
-#define APF_DIAG_PADDING 256
+#define APF_DIAG_PADDING 0
/*
* In the worst case, the HDLC buffer can be atmost twice the size of the
* original packet. Add 3 bytes for 16 bit CRC (2 bytes) and a delimiter
diff --git a/drivers/devfreq/governor_bw_hwmon.c b/drivers/devfreq/governor_bw_hwmon.c
index a1d9b50..3026bc2 100644
--- a/drivers/devfreq/governor_bw_hwmon.c
+++ b/drivers/devfreq/governor_bw_hwmon.c
@@ -48,9 +48,6 @@
unsigned int hyst_trigger_count;
unsigned int hyst_length;
unsigned int idle_mbps;
- unsigned int low_power_ceil_mbps;
- unsigned int low_power_io_percent;
- unsigned int low_power_delay;
unsigned int mbps_zones[NUM_MBPS_ZONES];
unsigned long prev_ab;
@@ -65,7 +62,6 @@
unsigned long hyst_mbps;
unsigned long hyst_trig_win;
unsigned long hyst_en;
- unsigned long above_low_power;
unsigned long prev_req;
unsigned int wake;
unsigned int down_cnt;
@@ -317,7 +313,7 @@
unsigned long meas_mbps_zone;
unsigned long hist_lo_tol, hyst_lo_tol;
struct bw_hwmon *hw = node->hw;
- unsigned int new_bw, io_percent;
+ unsigned int new_bw, io_percent = node->io_percent;
ktime_t ts;
unsigned int ms = 0;
@@ -353,17 +349,6 @@
node->hist_mem--;
}
- /* Keep track of whether we are in low power mode consistently. */
- if (meas_mbps > node->low_power_ceil_mbps)
- node->above_low_power = node->low_power_delay;
- if (node->above_low_power)
- node->above_low_power--;
-
- if (node->above_low_power)
- io_percent = node->io_percent;
- else
- io_percent = node->low_power_io_percent;
-
/*
* The AB value that corresponds to the lowest mbps zone greater than
* or equal to the "frequency" the current measurement will pick.
@@ -785,9 +770,6 @@
gov_attr(hyst_trigger_count, 0U, 90U);
gov_attr(hyst_length, 0U, 90U);
gov_attr(idle_mbps, 0U, 2000U);
-gov_attr(low_power_ceil_mbps, 0U, 2500U);
-gov_attr(low_power_io_percent, 1U, 100U);
-gov_attr(low_power_delay, 1U, 60U);
gov_list_attr(mbps_zones, NUM_MBPS_ZONES, 0U, UINT_MAX);
static struct attribute *dev_attr[] = {
@@ -804,9 +786,6 @@
&dev_attr_hyst_trigger_count.attr,
&dev_attr_hyst_length.attr,
&dev_attr_idle_mbps.attr,
- &dev_attr_low_power_ceil_mbps.attr,
- &dev_attr_low_power_io_percent.attr,
- &dev_attr_low_power_delay.attr,
&dev_attr_mbps_zones.attr,
&dev_attr_throttle_adj.attr,
NULL,
@@ -940,9 +919,6 @@
node->guard_band_mbps = 100;
node->decay_rate = 90;
node->io_percent = 16;
- node->low_power_ceil_mbps = 0;
- node->low_power_io_percent = 16;
- node->low_power_delay = 60;
node->bw_step = 190;
node->sample_ms = 50;
node->up_scale = 0;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
index 2355444..dc9d7f4 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
@@ -259,7 +259,11 @@
lenp = config->status_valid_params ?: config->status_cmds_rlen;
count = config->status_cmd.count;
cmds = config->status_cmd.cmds;
- flags = (DSI_CTRL_CMD_FETCH_MEMORY | DSI_CTRL_CMD_READ);
+ if (cmds->last_command) {
+ cmds->msg.flags |= MIPI_DSI_MSG_LASTCOMMAND;
+ flags |= DSI_CTRL_CMD_LAST_COMMAND;
+ }
+ flags |= (DSI_CTRL_CMD_FETCH_MEMORY | DSI_CTRL_CMD_READ);
for (i = 0; i < count; ++i) {
memset(config->status_buf, 0x0, SZ_4K);
diff --git a/drivers/gpu/msm/adreno-gpulist.h b/drivers/gpu/msm/adreno-gpulist.h
index a56a593..d1dad8a 100644
--- a/drivers/gpu/msm/adreno-gpulist.h
+++ b/drivers/gpu/msm/adreno-gpulist.h
@@ -346,7 +346,7 @@
.major = 3,
.minor = 0,
.patchid = ANY_ID,
- .features = ADRENO_64BIT | ADRENO_RPMH |
+ .features = ADRENO_64BIT | ADRENO_RPMH | ADRENO_IFPC |
ADRENO_GPMU | ADRENO_CONTENT_PROTECTION | ADRENO_LM,
.sqefw_name = "a630_sqe.fw",
.zap_name = "a630_zap",
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index ae5a78d..ff8cb49 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -610,7 +610,7 @@
struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
struct adreno_irq *irq_params = gpudev->irq;
irqreturn_t ret = IRQ_NONE;
- unsigned int status = 0, fence = 0, tmp, int_bit;
+ unsigned int status = 0, fence = 0, fence_retries = 0, tmp, int_bit;
int i;
atomic_inc(&adreno_dev->pending_irq_refcnt);
@@ -627,13 +627,24 @@
/*
* If the AHB fence is not in ALLOW mode when we receive an RBBM
- * interrupt, something went wrong. Set a fault and change the
- * fence to ALLOW so we can clear the interrupt.
+ * interrupt, something went wrong. This means that we cannot proceed
+ * since the IRQ status and clear registers are not accessible.
+ * This is usually harmless because the GMU will abort power collapse
+ * and change the fence back to ALLOW. Poll so that this can happen.
*/
- adreno_readreg(adreno_dev, ADRENO_REG_GMU_AO_AHB_FENCE_CTRL, &fence);
- if (fence != 0) {
- KGSL_DRV_CRIT_RATELIMIT(device, "AHB fence is stuck in ISR\n");
- return ret;
+ if (kgsl_gmu_isenabled(device)) {
+ do {
+ adreno_readreg(adreno_dev,
+ ADRENO_REG_GMU_AO_AHB_FENCE_CTRL,
+ &fence);
+
+ if (fence_retries == FENCE_RETRY_MAX) {
+ KGSL_DRV_CRIT_RATELIMIT(device,
+ "AHB fence stuck in ISR\n");
+ return ret;
+ }
+ fence_retries++;
+ } while (fence != 0);
}
adreno_readreg(adreno_dev, ADRENO_REG_RBBM_INT_0_STATUS, &status);
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index d6cba9d..2bc0832 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -164,6 +164,9 @@
/* Number of times to try hard reset */
#define NUM_TIMES_RESET_RETRY 5
+/* Number of times to poll the AHB fence in ISR */
+#define FENCE_RETRY_MAX 100
+
/* One cannot wait forever for the core to idle, so set an upper limit to the
* amount of time to wait for the core to go idle
*/
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index 1adfeb2..70043db 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -537,6 +537,9 @@
total_sizedwords += 1;
}
+ if (gpudev->set_marker)
+ total_sizedwords += 4;
+
ringcmds = adreno_ringbuffer_allocspace(rb, total_sizedwords);
if (IS_ERR(ringcmds))
return PTR_ERR(ringcmds);
@@ -556,6 +559,9 @@
*ringcmds++ = KGSL_CMD_INTERNAL_IDENTIFIER;
}
+ if (gpudev->set_marker)
+ ringcmds += gpudev->set_marker(ringcmds, 1);
+
if (flags & KGSL_CMD_FLAGS_PWRON_FIXUP) {
/* Disable protected mode for the fixup */
*ringcmds++ = cp_packet(adreno_dev, CP_SET_PROTECTED_MODE, 1);
@@ -674,6 +680,9 @@
*ringcmds++ = timestamp;
}
+ if (gpudev->set_marker)
+ ringcmds += gpudev->set_marker(ringcmds, 0);
+
if (adreno_is_a3xx(adreno_dev)) {
/* Dummy set-constant to trigger context rollover */
*ringcmds++ = cp_packet(adreno_dev, CP_SET_CONSTANT, 2);
@@ -898,9 +907,6 @@
dwords += 8;
}
- if (gpudev->set_marker)
- dwords += 4;
-
if (gpudev->ccu_invalidate)
dwords += 4;
@@ -933,9 +939,6 @@
gpu_ticks_submitted));
}
- if (gpudev->set_marker)
- cmds += gpudev->set_marker(cmds, 1);
-
if (numibs) {
list_for_each_entry(ib, &cmdobj->cmdlist, node) {
/*
@@ -960,9 +963,6 @@
if (gpudev->ccu_invalidate)
cmds += gpudev->ccu_invalidate(adreno_dev, cmds);
- if (gpudev->set_marker)
- cmds += gpudev->set_marker(cmds, 0);
-
if (adreno_is_preemption_execution_enabled(adreno_dev)) {
if (gpudev->preemption_yield_enable)
cmds += gpudev->preemption_yield_enable(cmds);
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index 5061f6a..07a3f22 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -1057,7 +1057,7 @@
else if (type < ARRAY_SIZE(memtype_str) && memtype_str[type] != NULL)
strlcpy(name, memtype_str[type], name_size);
else
- snprintf(name, name_size, "unknown(%3d)", type);
+ snprintf(name, name_size, "VK/others(%3d)", type);
}
EXPORT_SYMBOL(kgsl_get_memory_usage);
diff --git a/drivers/irqchip/qcom/pdc-sdm670.c b/drivers/irqchip/qcom/pdc-sdm670.c
index 7bd6333..21bb58e 100644
--- a/drivers/irqchip/qcom/pdc-sdm670.c
+++ b/drivers/irqchip/qcom/pdc-sdm670.c
@@ -120,13 +120,13 @@
{106, 653}, /* core_bi_px_gpio_132 */
{107, 654}, /* core_bi_px_gpio_133 */
{108, 655}, /* core_bi_px_gpio_145 */
+ {115, 662}, /* core_bi_px_gpio_41 */
+ {116, 663}, /* core_bi_px_gpio_89 */
+ {117, 664}, /* core_bi_px_gpio_31 */
+ {118, 665}, /* core_bi_px_gpio_49 */
{119, 666}, /* core_bi_px_to_mpm[2] */
{120, 667}, /* core_bi_px_to_mpm[3] */
{121, 668}, /* core_bi_px_to_mpm[4] */
- {122, 669}, /* core_bi_px_gpio_41 */
- {123, 670}, /* core_bi_px_gpio_89 */
- {124, 671}, /* core_bi_px_gpio_31 */
- {125, 95}, /* core_bi_px_gpio_49 */
{-1}
};
diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
index 9f340bf..9dc85cd 100644
--- a/drivers/mailbox/mailbox.c
+++ b/drivers/mailbox/mailbox.c
@@ -63,7 +63,7 @@
again:
spin_lock_irqsave(&chan->lock, flags);
- if (!chan->msg_count || chan->active_req)
+ if (!chan->msg_count || (chan->active_req && err != -EAGAIN))
goto exit;
count = chan->msg_count;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 4e282c3..dabe667 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -605,8 +605,10 @@
mutex_lock(&q->lock);
rc = vb2_streamon(&q->vb2_bufq, i);
mutex_unlock(&q->lock);
- if (rc)
+ if (rc) {
dprintk(VIDC_ERR, "streamon failed on port: %d\n", i);
+ msm_comm_kill_session(inst);
+ }
return rc;
}
EXPORT_SYMBOL(msm_vidc_streamon);
@@ -1011,10 +1013,9 @@
}
fail_start:
- if (rc) {
- dprintk(VIDC_ERR, "%s: kill session %pK\n", __func__, inst);
- msm_comm_kill_session(inst);
- }
+ if (rc)
+ dprintk(VIDC_ERR, "%s: inst %pK session %x failed to start\n",
+ __func__, inst, hash32_ptr(inst->session));
return rc;
}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 03174c4..0a7175b 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -2108,7 +2108,8 @@
}
hdev = inst->core->device;
- dprintk(VIDC_WARN, "Session error received for session %pK\n", inst);
+ dprintk(VIDC_ERR, "Session error received for inst %pK session %x\n",
+ inst, hash32_ptr(inst->session));
if (response->status == VIDC_ERR_MAX_CLIENTS) {
dprintk(VIDC_WARN, "Too many clients, rejecting %pK", inst);
@@ -2131,6 +2132,8 @@
event = V4L2_EVENT_MSM_VIDC_SYS_ERROR;
}
+ /* change state before sending error to client */
+ change_inst_state(inst, MSM_VIDC_CORE_INVALID);
msm_vidc_queue_v4l2_event(inst, event);
put_inst(inst);
}
@@ -2794,7 +2797,8 @@
hdev = inst->core->device;
abort_completion = SESSION_MSG_INDEX(HAL_SESSION_ABORT_DONE);
- dprintk(VIDC_WARN, "%s: inst %pK\n", __func__, inst);
+ dprintk(VIDC_WARN, "%s: inst %pK session %x\n", __func__,
+ inst, hash32_ptr(inst->session));
rc = call_hfi_op(hdev, session_abort, (void *)inst->session);
if (rc) {
dprintk(VIDC_ERR,
@@ -2806,8 +2810,8 @@
msecs_to_jiffies(
inst->core->resources.msm_vidc_hw_rsp_timeout));
if (!rc) {
- dprintk(VIDC_ERR, "%s: inst %pK abort timed out\n",
- __func__, inst);
+ dprintk(VIDC_ERR, "%s: inst %pK session %x abort timed out\n",
+ __func__, inst, hash32_ptr(inst->session));
msm_comm_generate_sys_error(inst);
rc = -EBUSY;
} else {
@@ -3699,8 +3703,8 @@
if (inst->state == MSM_VIDC_CORE_INVALID) {
dprintk(VIDC_ERR, "%s: inst %pK is in invalid\n",
__func__, inst);
- mutex_unlock(&inst->sync_lock);
- return -EINVAL;
+ rc = -EINVAL;
+ goto exit;
}
flipped_state = get_flipped_state(inst->state, state);
@@ -3781,6 +3785,8 @@
rc = -EINVAL;
break;
}
+
+exit:
mutex_unlock(&inst->sync_lock);
if (rc) {
@@ -4174,6 +4180,19 @@
output_count = (batch_mode ? &count_single_batch : &count_buffers)
(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ if (!batch_mode && mbuf) {
+ /*
+ * don't queue output_mplane buffers if buffer queued
+ * by client is capture_mplane type and vice versa.
+ */
+ if (mbuf->vvb.vb2_buf.type ==
+ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ output_count = 0;
+ else if (mbuf->vvb.vb2_buf.type ==
+ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ capture_count = 0;
+ }
+
/*
* Somewhat complicated logic to prevent queuing the buffer to hardware.
* Don't queue if:
@@ -5026,6 +5045,9 @@
enum vidc_ports ports[] = {OUTPUT_PORT, CAPTURE_PORT};
int c = 0;
+ /* before flush ensure venus released all buffers */
+ msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
+
for (c = 0; c < ARRAY_SIZE(ports); ++c) {
enum vidc_ports port = ports[c];
@@ -5088,6 +5110,9 @@
return 0;
}
+ /* enable in flush */
+ inst->in_flush = true;
+
mutex_lock(&inst->registeredbufs.lock);
list_for_each_entry_safe(mbuf, next, &inst->registeredbufs.list, list) {
/* don't flush input buffers if input flush is not requested */
@@ -5128,9 +5153,6 @@
}
mutex_unlock(&inst->registeredbufs.lock);
- /* enable in flush */
- inst->in_flush = true;
-
hdev = inst->core->device;
if (ip_flush) {
dprintk(VIDC_DBG, "Send flush on all ports to firmware\n");
@@ -5574,8 +5596,8 @@
return 0;
}
- dprintk(VIDC_WARN, "%s: inst %pK, state %d\n", __func__,
- inst, inst->state);
+ dprintk(VIDC_WARN, "%s: inst %pK, session %x state %d\n", __func__,
+ inst, inst->state, hash32_ptr(inst->session));
/*
* We're internally forcibly killing the session, if fw is aware of
* the session send session_abort to firmware to clean up and release
@@ -5586,8 +5608,9 @@
inst->state == MSM_VIDC_CORE_INVALID) {
rc = msm_comm_session_abort(inst);
if (rc) {
- dprintk(VIDC_WARN, "%s: inst %pK abort failed\n",
- __func__, inst);
+ dprintk(VIDC_ERR,
+ "%s: inst %pK session %x abort failed\n",
+ __func__, inst, hash32_ptr(inst->session));
change_inst_state(inst, MSM_VIDC_CORE_INVALID);
}
}
@@ -5595,7 +5618,8 @@
change_inst_state(inst, MSM_VIDC_CLOSE_DONE);
msm_comm_session_clean(inst);
- dprintk(VIDC_WARN, "%s: inst %pK handled\n", __func__, inst);
+ dprintk(VIDC_WARN, "%s: inst %pK session %x handled\n", __func__,
+ inst, hash32_ptr(inst->session));
return rc;
}
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index 60169e9..7e7ed47 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -503,6 +503,11 @@
if (queue->qhdr_read_idx == queue->qhdr_write_idx) {
queue->qhdr_rx_req = receive_request;
+ /*
+ * mb() to ensure qhdr is updated in main memory
+ * so that venus reads the updated header values
+ */
+ mb();
*pb_tx_req_is_set = 0;
dprintk(VIDC_DBG,
"%s queue is empty, rx_req = %u, tx_req = %u, read_idx = %u\n",
@@ -550,6 +555,11 @@
queue->qhdr_rx_req = 0;
else
queue->qhdr_rx_req = receive_request;
+ /*
+ * mb() to ensure qhdr is updated in main memory
+ * so that venus reads the updated header values
+ */
+ mb();
*pb_tx_req_is_set = (queue->qhdr_tx_req == 1) ? 1 : 0;
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index edbf682..c98955f 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -4360,6 +4360,18 @@
}
EXPORT_SYMBOL(mmc_detect_card_removed);
+/*
+ * This should be called to make sure that detect work(mmc_rescan)
+ * is completed.Drivers may use this function from async schedule/probe
+ * contexts to make sure that the bootdevice detection is completed on
+ * completion of async_schedule.
+ */
+void mmc_flush_detect_work(struct mmc_host *host)
+{
+ flush_delayed_work(&host->detect);
+}
+EXPORT_SYMBOL(mmc_flush_detect_work);
+
void mmc_rescan(struct work_struct *work)
{
unsigned long flags;
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index c5469f1..e817a02 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -4948,6 +4948,9 @@
mmc_hostname(host->mmc), __func__, ret);
device_remove_file(&pdev->dev, &msm_host->auto_cmd21_attr);
}
+ if (sdhci_msm_is_bootdevice(&pdev->dev))
+ mmc_flush_detect_work(host->mmc);
+
/* Successful initialization */
goto out;
diff --git a/drivers/pinctrl/qcom/pinctrl-sdm670.c b/drivers/pinctrl/qcom/pinctrl-sdm670.c
index 8749653..6145c75 100644
--- a/drivers/pinctrl/qcom/pinctrl-sdm670.c
+++ b/drivers/pinctrl/qcom/pinctrl-sdm670.c
@@ -1596,7 +1596,7 @@
{24, 517},
{26, 518},
{30, 519},
- {31, 639},
+ {31, 632},
{32, 521},
{34, 522},
{36, 523},
@@ -1604,12 +1604,12 @@
{38, 525},
{39, 526},
{40, 527},
- {41, 637},
+ {41, 630},
{43, 529},
{44, 530},
{46, 531},
{48, 532},
- {49, 640},
+ {49, 633},
{52, 534},
{53, 535},
{54, 536},
@@ -1625,7 +1625,7 @@
{85, 555},
{86, 556},
{88, 557},
- {89, 638},
+ {89, 631},
{91, 559},
{92, 560},
{95, 561},
diff --git a/drivers/regulator/qpnp-labibb-regulator.c b/drivers/regulator/qpnp-labibb-regulator.c
index 6b1e480..d672d5f 100644
--- a/drivers/regulator/qpnp-labibb-regulator.c
+++ b/drivers/regulator/qpnp-labibb-regulator.c
@@ -65,6 +65,7 @@
#define REG_LAB_PRECHARGE_CTL 0x5E
#define REG_LAB_SOFT_START_CTL 0x5F
#define REG_LAB_SPARE_CTL 0x60
+#define REG_LAB_MISC_CTL 0x60 /* PMI8998/PM660A */
#define REG_LAB_PFM_CTL 0x62
/* LAB registers for PM660A */
@@ -137,6 +138,9 @@
#define LAB_SPARE_TOUCH_WAKE_BIT BIT(3)
#define LAB_SPARE_DISABLE_SCP_BIT BIT(0)
+/* REG_LAB_MISC_CTL */
+#define LAB_AUTO_GM_BIT BIT(4)
+
/* REG_LAB_PFM_CTL */
#define LAB_PFM_EN_BIT BIT(7)
@@ -1854,7 +1858,7 @@
static int qpnp_labibb_ttw_enter_ibb_common(struct qpnp_labibb *labibb)
{
int rc = 0;
- u8 val;
+ u8 val, mask;
val = 0;
rc = qpnp_labibb_write(labibb, labibb->ibb_base + REG_IBB_PD_CTL,
@@ -1874,10 +1878,16 @@
return rc;
}
- val = IBB_WAIT_MBG_OK;
+ if (labibb->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE) {
+ val = 0;
+ mask = IBB_DIS_DLY_MASK;
+ } else {
+ val = IBB_WAIT_MBG_OK;
+ mask = IBB_DIS_DLY_MASK | IBB_WAIT_MBG_OK;
+ }
+
rc = qpnp_labibb_sec_masked_write(labibb, labibb->ibb_base,
- REG_IBB_PWRUP_PWRDN_CTL_2,
- IBB_DIS_DLY_MASK | IBB_WAIT_MBG_OK, val);
+ REG_IBB_PWRUP_PWRDN_CTL_2, mask, val);
if (rc < 0) {
pr_err("write to register %x failed rc = %d\n",
REG_IBB_PWRUP_PWRDN_CTL_2, rc);
@@ -1953,7 +1963,7 @@
static int qpnp_labibb_regulator_ttw_mode_enter(struct qpnp_labibb *labibb)
{
int rc = 0;
- u8 val;
+ u8 val, reg;
/* Save the IBB settings before they get modified for TTW mode */
if (!labibb->ibb_settings_saved) {
@@ -2015,10 +2025,17 @@
}
val = LAB_SPARE_DISABLE_SCP_BIT;
+
if (labibb->pmic_rev_id->pmic_subtype != PMI8950_SUBTYPE)
val |= LAB_SPARE_TOUCH_WAKE_BIT;
- rc = qpnp_labibb_write(labibb, labibb->lab_base +
- REG_LAB_SPARE_CTL, &val, 1);
+
+ if (labibb->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE) {
+ reg = REG_LAB_MISC_CTL;
+ val |= LAB_AUTO_GM_BIT;
+ } else {
+ reg = REG_LAB_SPARE_CTL;
+ }
+ rc = qpnp_labibb_write(labibb, labibb->lab_base + reg, &val, 1);
if (rc < 0) {
pr_err("qpnp_labibb_write register %x failed rc = %d\n",
REG_LAB_SPARE_CTL, rc);
@@ -2048,7 +2065,15 @@
case PMI8950_SUBTYPE:
rc = qpnp_labibb_ttw_enter_ibb_pmi8950(labibb);
break;
+ case PMI8998_SUBTYPE:
+ rc = labibb->lab_ver_ops->ps_ctl(labibb, 70, true);
+ if (rc < 0)
+ break;
+
+ rc = qpnp_ibb_ps_config(labibb, true);
+ break;
}
+
if (rc < 0) {
pr_err("Failed to configure TTW-enter for IBB rc=%d\n", rc);
return rc;
@@ -2081,7 +2106,7 @@
static int qpnp_labibb_regulator_ttw_mode_exit(struct qpnp_labibb *labibb)
{
int rc = 0;
- u8 val;
+ u8 val, reg;
if (!labibb->ibb_settings_saved) {
pr_err("IBB settings are not saved!\n");
@@ -2115,8 +2140,14 @@
}
val = 0;
- rc = qpnp_labibb_write(labibb, labibb->lab_base +
- REG_LAB_SPARE_CTL, &val, 1);
+ if (labibb->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE) {
+ reg = REG_LAB_MISC_CTL;
+ val |= LAB_AUTO_GM_BIT;
+ } else {
+ reg = REG_LAB_SPARE_CTL;
+ }
+
+ rc = qpnp_labibb_write(labibb, labibb->lab_base + reg, &val, 1);
if (rc < 0) {
pr_err("qpnp_labibb_write register %x failed rc = %d\n",
REG_LAB_SPARE_CTL, rc);
@@ -3692,6 +3723,9 @@
case PMI8950_SUBTYPE:
/* TTW supported for all revisions */
break;
+ case PMI8998_SUBTYPE:
+ /* TTW supported for all revisions */
+ break;
default:
pr_info("TTW mode not supported for PMIC-subtype = %d\n",
labibb->pmic_rev_id->pmic_subtype);
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
index 09f7f20..f25bade 100644
--- a/drivers/thermal/cpu_cooling.c
+++ b/drivers/thermal/cpu_cooling.c
@@ -32,6 +32,7 @@
#include <linux/cpu_cooling.h>
#include <linux/sched.h>
#include <linux/of_device.h>
+#include <linux/suspend.h>
#include <trace/events/thermal.h>
@@ -117,10 +118,12 @@
static DEFINE_IDR(cpufreq_idr);
static DEFINE_MUTEX(cooling_cpufreq_lock);
+static atomic_t in_suspend;
static unsigned int cpufreq_dev_count;
static int8_t cpuhp_registered;
static struct work_struct cpuhp_register_work;
static struct cpumask cpus_pending_online;
+static struct cpumask cpus_isolated_by_thermal;
static DEFINE_MUTEX(core_isolate_lock);
static DEFINE_MUTEX(cooling_list_lock);
@@ -218,6 +221,51 @@
}
EXPORT_SYMBOL_GPL(cpufreq_cooling_get_level);
+static int cpufreq_cooling_pm_notify(struct notifier_block *nb,
+ unsigned long mode, void *_unused)
+{
+ struct cpufreq_cooling_device *cpufreq_dev;
+ unsigned int cpu;
+
+ switch (mode) {
+ case PM_HIBERNATION_PREPARE:
+ case PM_RESTORE_PREPARE:
+ case PM_SUSPEND_PREPARE:
+ atomic_set(&in_suspend, 1);
+ break;
+ case PM_POST_HIBERNATION:
+ case PM_POST_RESTORE:
+ case PM_POST_SUSPEND:
+ mutex_lock(&cooling_list_lock);
+ mutex_lock(&core_isolate_lock);
+ list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) {
+ if (cpufreq_dev->cpufreq_state ==
+ cpufreq_dev->max_level) {
+ cpu = cpumask_any(&cpufreq_dev->allowed_cpus);
+ if (cpu_online(cpu) &&
+ !cpumask_test_and_set_cpu(cpu,
+ &cpus_isolated_by_thermal)) {
+ if (sched_isolate_cpu(cpu))
+ cpumask_clear_cpu(cpu,
+ &cpus_isolated_by_thermal);
+ }
+ }
+ }
+ mutex_unlock(&core_isolate_lock);
+ mutex_unlock(&cooling_list_lock);
+
+ atomic_set(&in_suspend, 0);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static struct notifier_block cpufreq_cooling_pm_nb = {
+ .notifier_call = cpufreq_cooling_pm_notify,
+};
+
static int cpufreq_hp_offline(unsigned int offline_cpu)
{
struct cpufreq_cooling_device *cpufreq_dev;
@@ -228,7 +276,9 @@
continue;
mutex_lock(&core_isolate_lock);
- if (cpufreq_dev->cpufreq_state == cpufreq_dev->max_level)
+ if ((cpufreq_dev->cpufreq_state == cpufreq_dev->max_level) &&
+ (cpumask_test_and_clear_cpu(offline_cpu,
+ &cpus_isolated_by_thermal)))
sched_unisolate_cpu_unlocked(offline_cpu);
mutex_unlock(&core_isolate_lock);
break;
@@ -243,6 +293,9 @@
struct cpufreq_cooling_device *cpufreq_dev;
int ret = 0;
+ if (atomic_read(&in_suspend))
+ return 0;
+
mutex_lock(&cooling_list_lock);
list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) {
if (!cpumask_test_cpu(online_cpu, &cpufreq_dev->allowed_cpus))
@@ -677,8 +730,13 @@
cpufreq_device->cpufreq_state = state;
/* If state is the last, isolate the CPU */
if (state == cpufreq_device->max_level) {
- if (cpu_online(cpu))
- sched_isolate_cpu(cpu);
+ if (cpu_online(cpu) &&
+ (!cpumask_test_and_set_cpu(cpu,
+ &cpus_isolated_by_thermal))) {
+ if (sched_isolate_cpu(cpu))
+ cpumask_clear_cpu(cpu,
+ &cpus_isolated_by_thermal);
+ }
mutex_unlock(&core_isolate_lock);
return ret;
} else if ((prev_state == cpufreq_device->max_level)
@@ -695,8 +753,10 @@
if (ret)
pr_err("CPU:%d online error:%d\n", cpu, ret);
goto update_frequency;
- } else
+ } else if (cpumask_test_and_clear_cpu(cpu,
+ &cpus_isolated_by_thermal)) {
sched_unisolate_cpu(cpu);
+ }
}
mutex_unlock(&core_isolate_lock);
update_frequency:
@@ -1105,12 +1165,14 @@
mutex_unlock(&cooling_list_lock);
/* Register the notifier for first cpufreq cooling device */
- if (!cpufreq_dev_count++)
+ if (!cpufreq_dev_count++ && !cpufreq_dev->plat_ops)
cpufreq_register_notifier(&thermal_cpufreq_notifier_block,
CPUFREQ_POLICY_NOTIFIER);
if (!cpuhp_registered) {
cpuhp_registered = 1;
+ register_pm_notifier(&cpufreq_cooling_pm_nb);
cpumask_clear(&cpus_pending_online);
+ cpumask_clear(&cpus_isolated_by_thermal);
INIT_WORK(&cpuhp_register_work, register_cdev);
queue_work(system_wq, &cpuhp_register_work);
}
@@ -1285,9 +1347,13 @@
/* Unregister the notifier for the last cpufreq cooling device */
mutex_lock(&cooling_cpufreq_lock);
- if (!--cpufreq_dev_count)
- cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block,
- CPUFREQ_POLICY_NOTIFIER);
+ if (!--cpufreq_dev_count) {
+ unregister_pm_notifier(&cpufreq_cooling_pm_nb);
+ if (!cpufreq_dev->plat_ops)
+ cpufreq_unregister_notifier(
+ &thermal_cpufreq_notifier_block,
+ CPUFREQ_POLICY_NOTIFIER);
+ }
mutex_lock(&cooling_list_lock);
list_del(&cpufreq_dev->node);
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index d0fc511..19c79f2 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -266,6 +266,7 @@
struct pm_qos_request pm_qos_req_dma;
struct delayed_work perf_vote_work;
struct delayed_work sdp_check;
+ struct mutex suspend_resume_mutex;
};
#define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */
@@ -2157,8 +2158,10 @@
struct dwc3_event_buffer *evt;
struct usb_irq *uirq;
+ mutex_lock(&mdwc->suspend_resume_mutex);
if (atomic_read(&dwc->in_lpm)) {
dev_dbg(mdwc->dev, "%s: Already suspended\n", __func__);
+ mutex_unlock(&mdwc->suspend_resume_mutex);
return 0;
}
@@ -2171,6 +2174,7 @@
dev_dbg(mdwc->dev,
"%s: %d device events pending, abort suspend\n",
__func__, evt->count / 4);
+ mutex_unlock(&mdwc->suspend_resume_mutex);
return -EBUSY;
}
}
@@ -2189,6 +2193,7 @@
dev_dbg(mdwc->dev,
"%s: cable disconnected while not in idle otg state\n",
__func__);
+ mutex_unlock(&mdwc->suspend_resume_mutex);
return -EBUSY;
}
@@ -2202,12 +2207,15 @@
pr_err("%s(): Trying to go in LPM with state:%d\n",
__func__, dwc->gadget.state);
pr_err("%s(): LPM is not performed.\n", __func__);
+ mutex_unlock(&mdwc->suspend_resume_mutex);
return -EBUSY;
}
ret = dwc3_msm_prepare_suspend(mdwc);
- if (ret)
+ if (ret) {
+ mutex_unlock(&mdwc->suspend_resume_mutex);
return ret;
+ }
/* Disable core irq */
if (dwc->irq)
@@ -2315,6 +2323,7 @@
}
dev_info(mdwc->dev, "DWC3 in low power mode\n");
+ mutex_unlock(&mdwc->suspend_resume_mutex);
return 0;
}
@@ -2327,8 +2336,10 @@
dev_dbg(mdwc->dev, "%s: exiting lpm\n", __func__);
+ mutex_lock(&mdwc->suspend_resume_mutex);
if (!atomic_read(&dwc->in_lpm)) {
dev_dbg(mdwc->dev, "%s: Already resumed\n", __func__);
+ mutex_unlock(&mdwc->suspend_resume_mutex);
return 0;
}
@@ -2479,6 +2490,8 @@
msecs_to_jiffies(1000 * PM_QOS_SAMPLE_SEC));
dbg_event(0xFF, "Ctl Res", atomic_read(&dwc->in_lpm));
+ mutex_unlock(&mdwc->suspend_resume_mutex);
+
return 0;
}
@@ -3422,6 +3435,7 @@
POWER_SUPPLY_PROP_PRESENT, &pval);
}
+ mutex_init(&mdwc->suspend_resume_mutex);
/* Update initial VBUS/ID state from extcon */
if (mdwc->extcon_vbus && extcon_get_state(mdwc->extcon_vbus,
EXTCON_USB))
@@ -3897,6 +3911,8 @@
if (dwc->maximum_speed == usb_speed)
goto err;
+ dbg_event(0xFF, "fw_restarthost", 0);
+ flush_delayed_work(&mdwc->sm_work);
dbg_event(0xFF, "stop_host_mode", dwc->maximum_speed);
ret = dwc3_otg_start_host(mdwc, 0);
if (ret)
diff --git a/include/linux/alarmtimer.h b/include/linux/alarmtimer.h
index 8a30cb5..d4d098b 100644
--- a/include/linux/alarmtimer.h
+++ b/include/linux/alarmtimer.h
@@ -60,8 +60,5 @@
/* Provide way to access the rtc device being used by alarmtimers */
struct rtc_device *alarmtimer_get_rtcdev(void);
-#ifdef CONFIG_RTC_DRV_QPNP
-extern bool poweron_alarm;
-#endif
#endif
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index b718105..d6ff3ee 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -180,6 +180,7 @@
extern int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd);
extern int mmc_set_auto_bkops(struct mmc_card *card, bool enable);
extern int mmc_suspend_clk_scaling(struct mmc_host *host);
+extern void mmc_flush_detect_work(struct mmc_host *host);
#define MMC_ERASE_ARG 0x00000000
#define MMC_SECURE_ERASE_ARG 0x80000000
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 3d933a0..8cae0c4 100755
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -6975,7 +6975,7 @@
curr_util = boosted_task_util(cpu_rq(cpu)->curr);
- need_idle = wake_to_idle(p);
+ need_idle = wake_to_idle(p) || schedtune_prefer_idle(p);
grp = task_related_thread_group(p);
if (grp && grp->preferred_cluster)
diff --git a/kernel/sched/tune.h b/kernel/sched/tune.h
index 4f64417..d1b4c72 100644
--- a/kernel/sched/tune.h
+++ b/kernel/sched/tune.h
@@ -28,6 +28,7 @@
#define schedtune_cpu_boost(cpu) get_sysctl_sched_cfs_boost()
#define schedtune_task_boost(tsk) get_sysctl_sched_cfs_boost()
+#define schedtune_prefer_idle(tsk) 0
#define schedtune_exit_task(task) do { } while (0)
@@ -44,6 +45,7 @@
#define schedtune_cpu_boost(cpu) 0
#define schedtune_task_boost(tsk) 0
+#define schedtune_prefer_idle(tsk) 0
#define schedtune_exit_task(task) do { } while (0)
diff --git a/kernel/time/Makefile b/kernel/time/Makefile
index b9b881eb..7251e3c 100644
--- a/kernel/time/Makefile
+++ b/kernel/time/Makefile
@@ -11,5 +11,3 @@
obj-$(CONFIG_TICK_ONESHOT) += tick-oneshot.o tick-sched.o
obj-$(CONFIG_DEBUG_FS) += timekeeping_debug.o
obj-$(CONFIG_TEST_UDELAY) += test_udelay.o
-
-ccflags-y += -Idrivers/cpuidle
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index 842928a..f7a6750 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -25,10 +25,6 @@
#include <linux/posix-timers.h>
#include <linux/workqueue.h>
#include <linux/freezer.h>
-
-#ifdef CONFIG_MSM_PM
-#include "lpm-levels.h"
-#endif
#include <linux/workqueue.h>
/**
@@ -362,70 +358,6 @@
* set an rtc timer to fire that far into the future, which
* will wake us from suspend.
*/
-#if defined(CONFIG_RTC_DRV_QPNP) && defined(CONFIG_MSM_PM)
-static int alarmtimer_suspend(struct device *dev)
-{
- struct rtc_time tm;
- ktime_t min, now;
- unsigned long flags;
- struct rtc_device *rtc;
- int i;
- int ret = 0;
-
- spin_lock_irqsave(&freezer_delta_lock, flags);
- min = freezer_delta;
- freezer_delta = ktime_set(0, 0);
- spin_unlock_irqrestore(&freezer_delta_lock, flags);
-
- rtc = alarmtimer_get_rtcdev();
- /* If we have no rtcdev, just return */
- if (!rtc)
- return 0;
-
- /* Find the soonest timer to expire*/
- for (i = 0; i < ALARM_NUMTYPE; i++) {
- struct alarm_base *base = &alarm_bases[i];
- struct timerqueue_node *next;
- ktime_t delta;
-
- spin_lock_irqsave(&base->lock, flags);
- next = timerqueue_getnext(&base->timerqueue);
- spin_unlock_irqrestore(&base->lock, flags);
- if (!next)
- continue;
- delta = ktime_sub(next->expires, base->gettime());
- if (!min.tv64 || (delta.tv64 < min.tv64))
- min = delta;
- }
- if (min.tv64 == 0)
- return 0;
-
- if (ktime_to_ns(min) < 2 * NSEC_PER_SEC) {
- __pm_wakeup_event(ws, 2 * MSEC_PER_SEC);
- return -EBUSY;
- }
-
- /* Setup a timer to fire that far in the future */
- rtc_timer_cancel(rtc, &rtctimer);
- rtc_read_time(rtc, &tm);
- now = rtc_tm_to_ktime(tm);
- now = ktime_add(now, min);
- if (poweron_alarm) {
- struct rtc_time tm_val;
- unsigned long secs;
-
- tm_val = rtc_ktime_to_tm(min);
- rtc_tm_to_time(&tm_val, &secs);
- lpm_suspend_wake_time(secs);
- } else {
- /* Set alarm, if in the past reject suspend briefly to handle */
- ret = rtc_timer_start(rtc, &rtctimer, now, ktime_set(0, 0));
- if (ret < 0)
- __pm_wakeup_event(ws, MSEC_PER_SEC);
- }
- return ret;
-}
-#else
static int alarmtimer_suspend(struct device *dev)
{
struct rtc_time tm;
@@ -482,7 +414,7 @@
__pm_wakeup_event(ws, MSEC_PER_SEC);
return ret;
}
-#endif
+
static int alarmtimer_resume(struct device *dev)
{
struct rtc_device *rtc;