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

Commit 074c4896 authored by Isaac J. Manjarres's avatar Isaac J. Manjarres
Browse files

soc: qcom: pil: Delay IRQ registration in subsys registration



When the request_irq functions and any of its variants
are invoked, it is possible to receive an IRQ from the
moment the IRQ line becomes active. This should only be
done when all other initialization routines have been
performed, to ensure proper behavior. Make IRQ registration
the last step in the subsystem registration process,
and initialize completion variables used in PIL IRQ handlers
to ensure that the completion variables used in these IRQ
handlers are not used prior to initialization.

Change-Id: I45286284d3c6d88c6b58dd4e2c2092f373b49fa1
Signed-off-by: default avatarIsaac J. Manjarres <isaacm@codeaurora.org>
parent b58cba17
Loading
Loading
Loading
Loading
+18 −10
Original line number Diff line number Diff line
@@ -672,7 +672,7 @@ static int subsystem_powerup(struct subsys_device *dev, void *data)
	int ret;

	pr_info("[%s:%d]: Powering up %s\n", current->comm, current->pid, name);
	init_completion(&dev->err_ready);
	reinit_completion(&dev->err_ready);

	ret = dev->desc->powerup(dev->desc);
	if (ret < 0) {
@@ -734,7 +734,7 @@ static int subsys_start(struct subsys_device *subsys)
	notify_each_subsys_device(&subsys, 1, SUBSYS_BEFORE_POWERUP,
								NULL);

	init_completion(&subsys->err_ready);
	reinit_completion(&subsys->err_ready);
	ret = subsys->desc->powerup(subsys->desc);
	if (ret) {
		notify_each_subsys_device(&subsys, 1, SUBSYS_POWERUP_FAILURE,
@@ -1660,6 +1660,12 @@ static void subsys_free_irqs(struct subsys_device *subsys)
		devm_free_irq(desc->dev, desc->err_ready_irq, subsys);
}

static void init_all_completions(struct subsys_device *subsys_dev)
{
	init_completion(&subsys_dev->err_ready);
	init_completion(&subsys_dev->shutdown_ack);
}

struct subsys_device *subsys_register(struct subsys_desc *desc)
{
	struct subsys_device *subsys;
@@ -1700,7 +1706,7 @@ struct subsys_device *subsys_register(struct subsys_desc *desc)
	dev_set_name(&subsys->dev, "subsys%d", subsys->id);

	mutex_init(&subsys->track.lock);
	init_completion(&subsys->shutdown_ack);
	init_all_completions(subsys);

	ret = device_register(&subsys->dev);
	if (ret) {
@@ -1719,10 +1725,6 @@ struct subsys_device *subsys_register(struct subsys_desc *desc)

		subsys->restart_order = update_restart_order(subsys);

		ret = subsys_setup_irqs(subsys);
		if (ret < 0)
			goto err_setup_irqs;

		if (of_property_read_u32(ofnode, "qcom,ssctl-instance-id",
					&desc->ssctl_instance_id))
			pr_debug("Reading instance-id for %s failed\n",
@@ -1754,13 +1756,19 @@ struct subsys_device *subsys_register(struct subsys_desc *desc)
	list_add_tail(&subsys->list, &subsys_list);
	mutex_unlock(&subsys_list_lock);

	if (ofnode) {
		ret = subsys_setup_irqs(subsys);
		if (ret < 0)
			goto err_setup_irqs;
	}

	return subsys;
err_setup_irqs:
	if (subsys->desc->edge)
		sysmon_glink_unregister(desc);
err_sysmon_glink_register:
	sysmon_notifier_unregister(subsys->desc);
err_sysmon_notifier:
	if (ofnode)
		subsys_free_irqs(subsys);
err_setup_irqs:
	if (ofnode)
		subsys_remove_restart_order(ofnode);
err_register: