Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a170f6e3 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "soc: qcom: bam_dmux: Fix race condition between power up and power down"

parents 116e0f7f 03ccabc7
Loading
Loading
Loading
Loading
+17 −3
Original line number Diff line number Diff line
/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2016, 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
@@ -917,14 +917,17 @@ int msm_bam_dmux_write(uint32_t id, struct sk_buff *skb)

	read_lock(&ul_wakeup_lock);
	if (!bam_is_connected) {
		atomic_inc(&ul_ondemand_vote);
		read_unlock(&ul_wakeup_lock);
		ul_wakeup();
		if (unlikely(in_global_reset == 1)) {
			srcu_read_unlock(&bam_dmux_srcu, rcu_id);
			atomic_dec(&ul_ondemand_vote);
			return -EFAULT;
		}
		read_lock(&ul_wakeup_lock);
		notify_all(BAM_DMUX_UL_CONNECTED, (unsigned long)(NULL));
		atomic_dec(&ul_ondemand_vote);
	}

	/* if skb do not have any tailroom for padding,
@@ -1124,14 +1127,17 @@ int msm_bam_dmux_open(uint32_t id, void *priv,

	read_lock(&ul_wakeup_lock);
	if (!bam_is_connected) {
		atomic_inc(&ul_ondemand_vote);
		read_unlock(&ul_wakeup_lock);
		ul_wakeup();
		if (unlikely(in_global_reset == 1)) {
			atomic_dec(&ul_ondemand_vote);
			kfree(hdr);
			return -EFAULT;
		}
		read_lock(&ul_wakeup_lock);
		notify_all(BAM_DMUX_UL_CONNECTED, (unsigned long)(NULL));
		atomic_dec(&ul_ondemand_vote);
	}

	hdr->magic_num = BAM_MUX_HDR_MAGIC_NO;
@@ -1163,12 +1169,16 @@ int msm_bam_dmux_close(uint32_t id)

	read_lock(&ul_wakeup_lock);
	if (!bam_is_connected && !bam_ch_is_in_reset(id)) {
		atomic_inc(&ul_ondemand_vote);
		read_unlock(&ul_wakeup_lock);
		ul_wakeup();
		if (unlikely(in_global_reset == 1))
		if (unlikely(in_global_reset == 1)) {
			atomic_dec(&ul_ondemand_vote);
			return -EFAULT;
		}
		read_lock(&ul_wakeup_lock);
		notify_all(BAM_DMUX_UL_CONNECTED, (unsigned long)(NULL));
		atomic_dec(&ul_ondemand_vote);
	}

	spin_lock_irqsave(&bam_ch[id].lock, flags);
@@ -1675,13 +1685,17 @@ static void kickoff_ul_wakeup_func(struct work_struct *work)
{
	read_lock(&ul_wakeup_lock);
	if (!bam_is_connected) {
		atomic_inc(&ul_ondemand_vote);
		read_unlock(&ul_wakeup_lock);
		ul_wakeup();
		if (unlikely(in_global_reset == 1))
		if (unlikely(in_global_reset == 1)) {
			atomic_dec(&ul_ondemand_vote);
			return;
		}
		read_lock(&ul_wakeup_lock);
		ul_packet_written = 1;
		notify_all(BAM_DMUX_UL_CONNECTED, (unsigned long)(NULL));
		atomic_dec(&ul_ondemand_vote);
	}
	read_unlock(&ul_wakeup_lock);
}