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

Commit 990ef5ce authored by Eric Holmberg's avatar Eric Holmberg
Browse files

msm: smd_tty: add separate port locking



Currently a single mutex is used to lock access to opening and closing
SMD TTY ports.  This lock is held while waiting for the open timeout to
expire which unnecessarily delays ports that could be opened
immediately.

Add an individual lock for each port to enable each port to be opened
and closed independently.

CRs-Fixed: 541915
Change-Id: Ic698d9b6a1e5f6f4676a6530d3c7c0bc52ba35aa
Signed-off-by: default avatarEric Holmberg <eholmber@codeaurora.org>
parent 49ac45a4
Loading
Loading
Loading
Loading
+18 −8
Original line number Diff line number Diff line
@@ -59,7 +59,6 @@ do { \
} while (0)

static void *smd_tty_log_ctx;
static DEFINE_MUTEX(smd_tty_lock);

static struct delayed_work smd_tty_probe_work;
static int smd_tty_probe_done;
@@ -79,6 +78,8 @@ static int smd_tty_probe_done;
 * @edge:  SMD edge associated with port
 * @ch_name:  SMD channel name associated with port
 * @dev_name:  SMD platform device name associated with port
 *
 * @open_lock_lha1: open/close lock - used to serialize open/close operations
 * @open_wait:  Timeout in seconds to wait for SMD port to be created / opened
 *
 * @reset_lock_lha2: lock for reset and open state
@@ -104,6 +105,8 @@ struct smd_tty_info {
	uint32_t edge;
	char ch_name[SMD_MAX_CH_NAME_LEN];
	char dev_name[SMD_MAX_CH_NAME_LEN];

	struct mutex open_lock_lha1;
	unsigned int open_wait;

	spinlock_t reset_lock_lha2;
@@ -197,7 +200,9 @@ static ssize_t open_timeout_store(struct device *dev,
		return -EINVAL;
	}
	if (!kstrtoul(buf, 10, &wait)) {
		mutex_lock(&smd_tty[num_dev].open_lock_lha1);
		smd_tty[num_dev].open_wait = wait;
		mutex_unlock(&smd_tty[num_dev].open_lock_lha1);
		return n;
	} else {
		SMD_TTY_INFO("[%s]: Unable to convert %s to an int",
@@ -210,6 +215,7 @@ static ssize_t open_timeout_show(struct device *dev,
			struct device_attribute *attr, char *buf)
{
	unsigned int num_dev;
	unsigned int open_wait;

	if (dev == NULL) {
		SMD_TTY_INFO("%s: Invalid Device passed", __func__);
@@ -224,8 +230,11 @@ static ssize_t open_timeout_show(struct device *dev,
		return -EINVAL;
	}

	return snprintf(buf, PAGE_SIZE, "%d\n",
			smd_tty[num_dev].open_wait);
	mutex_lock(&smd_tty[num_dev].open_lock_lha1);
	open_wait = smd_tty[num_dev].open_wait;
	mutex_unlock(&smd_tty[num_dev].open_lock_lha1);

	return snprintf(buf, PAGE_SIZE, "%d\n", open_wait);
}

static DEVICE_ATTR
@@ -381,7 +390,7 @@ static int smd_tty_port_activate(struct tty_port *tport,

	info = smd_tty + n;

	mutex_lock(&smd_tty_lock);
	mutex_lock(&info->open_lock_lha1);
	tty->driver_data = info;

	peripheral = smd_edge_to_subsystem(smd_tty[n].edge);
@@ -469,7 +478,7 @@ static int smd_tty_port_activate(struct tty_port *tport,
	SMD_TTY_INFO("%s with PID %u opened port %s",
		      current->comm, current->pid, info->ch_name);
	smd_disable_read_intr(info->ch);
	mutex_unlock(&smd_tty_lock);
	mutex_unlock(&info->open_lock_lha1);
	return 0;

close_ch:
@@ -484,7 +493,7 @@ release_wl_tl:
release_pil:
	subsystem_put(info->pil);
out:
	mutex_unlock(&smd_tty_lock);
	mutex_unlock(&info->open_lock_lha1);

	return res;
}
@@ -501,7 +510,7 @@ static void smd_tty_port_shutdown(struct tty_port *tport)
		return;
	}

	mutex_lock(&smd_tty_lock);
	mutex_lock(&info->open_lock_lha1);

	spin_lock_irqsave(&info->reset_lock_lha2, flags);
	info->is_open = 0;
@@ -521,7 +530,7 @@ static void smd_tty_port_shutdown(struct tty_port *tport)
	info->ch = NULL;
	subsystem_put(info->pil);

	mutex_unlock(&smd_tty_lock);
	mutex_unlock(&info->open_lock_lha1);
	tty_kref_put(tty);
}

@@ -741,6 +750,7 @@ static int smd_tty_device_init(int idx)
	smd_tty[idx].device_ptr = tty_port_register_device(port, smd_tty_driver,
							   idx, NULL);
	init_completion(&smd_tty[idx].ch_allocated);
	mutex_init(&smd_tty[idx].open_lock_lha1);

	/* register platform device */
	smd_tty[idx].driver.probe = smd_tty_dummy_probe;