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

Commit 70664942 authored by Runmin Wang's avatar Runmin Wang
Browse files

soc: qcom: pil: Update pil to use the new smp2p interface



Smp2p is no longer using the gpio controller interface any more.
So remove all the gpio related api and use irq interface directly.

Change-Id: I44a584e179d812238b4631b646fff8577cf1d5f9
Signed-off-by: default avatarRunmin Wang <runminw@codeaurora.org>
parent b2e799c3
Loading
Loading
Loading
Loading
+5 −12
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@
#include <linux/list_sort.h>
#include <linux/idr.h>
#include <linux/interrupt.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/of_address.h>
#include <linux/io.h>
#include <linux/dma-mapping.h>
@@ -739,25 +739,18 @@ static int pil_parse_devicetree(struct pil_desc *desc)
					desc->name);

	if (desc->ops->proxy_unvote && of_find_property(ofnode,
					"qcom,gpio-proxy-unvote",
					"qcom,proxy-unvote",
					NULL)) {
		clk_ready = of_get_named_gpio(ofnode,
				"qcom,gpio-proxy-unvote", 0);
		clk_ready = of_irq_get_byname(ofnode,
				"qcom,proxy-unvote");

		if (clk_ready < 0) {
			dev_dbg(desc->dev,
				"[%s]: Error getting proxy unvoting gpio\n",
				"[%s]: Error getting proxy unvoting irq\n",
				desc->name);
			return clk_ready;
		}

		clk_ready = gpio_to_irq(clk_ready);
		if (clk_ready < 0) {
			dev_err(desc->dev,
				"[%s]: Error getting proxy unvote IRQ\n",
				desc->name);
			return clk_ready;
		}
	}
	desc->proxy_unvote_irq = clk_ready;
	return 0;
+37 −11
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@
#include <linux/clk.h>
#include <linux/regulator/consumer.h>
#include <linux/interrupt.h>
#include <linux/of_gpio.h>
#include <linux/delay.h>

#include <linux/msm-bus-board.h>
@@ -31,6 +30,7 @@
#include <soc/qcom/scm.h>

#include <linux/soc/qcom/smem.h>
#include <linux/soc/qcom/smem_state.h>

#include "peripheral-loader.h"

@@ -101,6 +101,7 @@ struct pil_tz_data {
	bool enable_bus_scaling;
	bool keep_proxy_regs_on;
	struct completion stop_ack;
	struct completion shutdown_ack;
	struct pil_desc desc;
	struct subsys_device *subsys;
	struct subsys_desc subsys_desc;
@@ -796,8 +797,8 @@ static void log_failure_reason(const struct pil_tz_data *d)
		return;

	smem_reason = qcom_smem_get(QCOM_SMEM_HOST_ANY, d->smem_id, &size);
	if (!smem_reason || !size) {
		pr_err("%s SFR: (unknown, smem_get_entry_no_rlock failed).\n",
	if (IS_ERR(smem_reason) || !size) {
		pr_err("%s SFR: (unknown, qcom_smem_get failed).\n",
									name);
		return;
	}
@@ -819,14 +820,16 @@ static int subsys_shutdown(const struct subsys_desc *subsys, bool force_stop)
	int ret;

	if (!subsys_get_crash_status(d->subsys) && force_stop &&
						subsys->force_stop_gpio) {
		gpio_set_value(subsys->force_stop_gpio, 1);
						subsys->state) {
		qcom_smem_state_update_bits(subsys->state,
				subsys->force_stop_bit, 1);
		ret = wait_for_completion_timeout(&d->stop_ack,
				msecs_to_jiffies(STOP_ACK_TIMEOUT_MS));
		if (!ret)
			pr_warn("Timed out on stop ack from %s.\n",
							subsys->name);
		gpio_set_value(subsys->force_stop_gpio, 0);
		qcom_smem_state_update_bits(subsys->state,
				subsys->force_stop_bit, 0);
	}

	pil_shutdown(&d->desc);
@@ -868,9 +871,9 @@ static void subsys_crash_shutdown(const struct subsys_desc *subsys)
{
	struct pil_tz_data *d = subsys_to_data(subsys);

	if (subsys->force_stop_gpio > 0 &&
				!subsys_get_crash_status(d->subsys)) {
		gpio_set_value(subsys->force_stop_gpio, 1);
	if (subsys->state && !subsys_get_crash_status(d->subsys)) {
		qcom_smem_state_update_bits(subsys->state,
				subsys->force_stop_bit, 1);
		mdelay(CRASH_STOP_ACK_TO_MS);
	}
}
@@ -900,8 +903,7 @@ static irqreturn_t subsys_wdog_bite_irq_handler(int irq, void *dev_id)
		return IRQ_HANDLED;
	pr_err("Watchdog bite received from %s!\n", d->subsys_desc.name);

	if (d->subsys_desc.system_debug &&
			!gpio_get_value(d->subsys_desc.err_fatal_gpio))
	if (d->subsys_desc.system_debug)
		panic("%s: System ramdump requested. Triggering device restart!\n",
							__func__);
	subsys_set_crash_status(d->subsys, CRASH_STATUS_WDOG_BITE);
@@ -920,6 +922,26 @@ static irqreturn_t subsys_stop_ack_intr_handler(int irq, void *dev_id)
	return IRQ_HANDLED;
}

static irqreturn_t subsys_shutdown_ack_intr_handler(int irq, void *dev_id)
{
	struct pil_tz_data *d = subsys_to_data(dev_id);

	pr_info("Received stop shutdown interrupt from %s\n",
			d->subsys_desc.name);
	complete_shutdown_ack(d->subsys);
	return IRQ_HANDLED;
}

static irqreturn_t subsys_ramdump_disable_intr_handler(int irq, void *dev_id)
{
	struct pil_tz_data *d = subsys_to_data(dev_id);

	pr_info("Received ramdump disable interrupt from %s\n",
			d->subsys_desc.name);
	d->subsys_desc.ramdump_disable = 1;
	return IRQ_HANDLED;
}

static void clear_pbl_done(struct pil_tz_data *d)
{
	uint32_t err_value;
@@ -1104,6 +1126,10 @@ static int pil_tz_driver_probe(struct platform_device *pdev)
						subsys_err_fatal_intr_handler;
		d->subsys_desc.wdog_bite_handler = subsys_wdog_bite_irq_handler;
		d->subsys_desc.stop_ack_handler = subsys_stop_ack_intr_handler;
		d->subsys_desc.shutdown_ack_handler =
			subsys_shutdown_ack_intr_handler;
		d->subsys_desc.ramdump_disable_handler =
			subsys_ramdump_disable_intr_handler;
	}
	d->ramdump_dev = create_ramdump_device(d->subsys_desc.name,
								&pdev->dev);
+104 −65
Original line number Diff line number Diff line
@@ -29,14 +29,15 @@
#include <linux/device.h>
#include <linux/idr.h>
#include <linux/interrupt.h>
#include <linux/of_gpio.h>
#include <linux/cdev.h>
#include <linux/platform_device.h>
#include <soc/qcom/subsystem_restart.h>
#include <soc/qcom/subsystem_notif.h>
#include <soc/qcom/sysmon.h>
#include <trace/events/trace_msm_pil_event.h>

#include <linux/soc/qcom/smem_state.h>
#include <linux/of_irq.h>
#include <linux/of.h>
#include <asm/current.h>

#include "peripheral-loader.h"
@@ -174,6 +175,7 @@ struct subsys_device {
	struct cdev char_dev;
	dev_t dev_no;
	struct completion err_ready;
	struct completion shutdown_ack;
	enum crash_status crashed;
	int notif_state;
	struct list_head list;
@@ -189,6 +191,11 @@ void complete_err_ready(struct subsys_device *subsys)
	complete(&subsys->err_ready);
}

void complete_shutdown_ack(struct subsys_device *subsys)
{
	complete(&subsys->shutdown_ack);
}

static struct subsys_tracking *subsys_get_track(struct subsys_device *subsys)
{
	struct subsys_soc_restart_order *order = subsys->restart_order;
@@ -472,7 +479,7 @@ static void do_epoch_check(struct subsys_device *dev)

static int is_ramdump_enabled(struct subsys_device *dev)
{
	if (dev->desc->ramdump_disable_gpio)
	if (dev->desc->ramdump_disable_irq)
		return !dev->desc->ramdump_disable;

	return enable_ramdumps;
@@ -563,6 +570,11 @@ static void enable_all_irqs(struct subsys_device *dev)
		enable_irq(dev->desc->err_fatal_irq);
	if (dev->desc->stop_ack_irq && dev->desc->stop_ack_handler)
		enable_irq(dev->desc->stop_ack_irq);
	if (dev->desc->shutdown_ack_irq && dev->desc->shutdown_ack_handler)
		enable_irq(dev->desc->shutdown_ack_irq);
	if (dev->desc->ramdump_disable_irq &&
			dev->desc->ramdump_disable_handler)
		enable_irq(dev->desc->ramdump_disable_irq);
	if (dev->desc->generic_irq && dev->desc->generic_handler) {
		enable_irq(dev->desc->generic_irq);
		irq_set_irq_wake(dev->desc->generic_irq, 1);
@@ -581,6 +593,8 @@ static void disable_all_irqs(struct subsys_device *dev)
		disable_irq(dev->desc->err_fatal_irq);
	if (dev->desc->stop_ack_irq && dev->desc->stop_ack_handler)
		disable_irq(dev->desc->stop_ack_irq);
	if (dev->desc->shutdown_ack_irq && dev->desc->shutdown_ack_handler)
		disable_irq(dev->desc->shutdown_ack_irq);
	if (dev->desc->generic_irq && dev->desc->generic_handler) {
		disable_irq(dev->desc->generic_irq);
		irq_set_irq_wake(dev->desc->generic_irq, 0);
@@ -756,6 +770,7 @@ static void subsys_stop(struct subsys_device *subsys)
	if (!of_property_read_bool(subsys->desc->dev->of_node,
					"qcom,pil-force-shutdown")) {
		subsys_set_state(subsys, SUBSYS_OFFLINING);
		init_completion(&subsys->shutdown_ack);
		subsys->desc->sysmon_shutdown_ret =
				sysmon_send_shutdown(subsys->desc);
		if (subsys->desc->sysmon_shutdown_ret)
@@ -792,27 +807,25 @@ EXPORT_SYMBOL(subsystem_set_fwname);

int wait_for_shutdown_ack(struct subsys_desc *desc)
{
	int count;
	int ret;
	struct subsys_device *dev;

	if (!desc || !desc->shutdown_ack_gpio)
	if (!desc || !desc->shutdown_ack_irq)
		return 0;

	dev = find_subsys(desc->name);
	if (!dev)
		return 0;

	for (count = SHUTDOWN_ACK_MAX_LOOPS; count > 0; count--) {
		if (gpio_get_value(desc->shutdown_ack_gpio))
			return count;
		else if (subsys_get_crash_status(dev))
			break;
		msleep(SHUTDOWN_ACK_DELAY_MS);
	}

	pr_err("[%s]: Timed out waiting for shutdown ack\n", desc->name);
	ret = wait_for_completion_timeout(&dev->shutdown_ack,
						msecs_to_jiffies(10000));
	if (!ret) {
		pr_err("[%s]: Timed out waiting for shutdown ack\n",
				desc->name);
		return -ETIMEDOUT;
	}
	return ret;
}
EXPORT_SYMBOL(wait_for_shutdown_ack);

void *__subsystem_get(const char *name, const char *fw_name)
@@ -1431,86 +1444,76 @@ static struct subsys_soc_restart_order *ssr_parse_restart_orders(struct
	return tmp;
}

static int __get_gpio(struct subsys_desc *desc, const char *prop,
		int *gpio)
{
	struct device_node *dnode = desc->dev->of_node;
	int ret = -ENOENT;

	if (of_find_property(dnode, prop, NULL)) {
		*gpio = of_get_named_gpio(dnode, prop, 0);
		ret = *gpio < 0 ? *gpio : 0;
	}

	return ret;
}

static int __get_irq(struct subsys_desc *desc, const char *prop,
		unsigned int *irq, int *gpio)
		unsigned int *irq)
{
	int ret, gpiol, irql;

	ret = __get_gpio(desc, prop, &gpiol);
	if (ret)
		return ret;

	irql = gpio_to_irq(gpiol);
	int irql = 0;
	struct device_node *dnode = desc->dev->of_node;

	if (irql == -ENOENT)
		irql = -ENXIO;
	if (of_property_match_string(dnode, "interrupt-names", prop) < 0)
		return -ENOENT;

	irql = of_irq_get_byname(dnode, prop);
	if (irql < 0) {
		pr_err("[%s]: Error getting IRQ \"%s\"\n", desc->name,
		prop);
		return irql;
	}

	if (gpio)
		*gpio = gpiol;
	*irq = irql;
	return 0;
}

static int __get_smem_state(struct subsys_desc *desc, const char *prop,
		int *smem_bit)
{
	struct device_node *dnode = desc->dev->of_node;

	if (of_find_property(dnode, "qcom,smem-states", NULL)) {
		desc->state = qcom_smem_state_get(desc->dev, prop, smem_bit);
		if (IS_ERR_OR_NULL(desc->state)) {
			pr_err("Could not get smem-states %s\n", prop);
			return -ENXIO;
		}
		return 0;
	}
	return -ENOENT;
}

static int subsys_parse_devicetree(struct subsys_desc *desc)
{
	struct subsys_soc_restart_order *order;
	int ret;

	struct platform_device *pdev = container_of(desc->dev,
					struct platform_device, dev);

	ret = __get_irq(desc, "qcom,gpio-err-fatal", &desc->err_fatal_irq,
							&desc->err_fatal_gpio);
	ret = __get_irq(desc, "qcom,err-fatal", &desc->err_fatal_irq);
	if (ret && ret != -ENOENT)
		return ret;

	ret = __get_irq(desc, "qcom,gpio-err-ready", &desc->err_ready_irq,
							NULL);
	ret = __get_irq(desc, "qcom,err-ready", &desc->err_ready_irq);
	if (ret && ret != -ENOENT)
		return ret;

	ret = __get_irq(desc, "qcom,gpio-stop-ack", &desc->stop_ack_irq, NULL);
	ret = __get_irq(desc, "qcom,stop-ack", &desc->stop_ack_irq);
	if (ret && ret != -ENOENT)
		return ret;

	ret = __get_gpio(desc, "qcom,gpio-force-stop", &desc->force_stop_gpio);
	ret = __get_irq(desc, "qcom,ramdump-disabled",
			&desc->ramdump_disable_irq);
	if (ret && ret != -ENOENT)
		return ret;

	ret = __get_gpio(desc, "qcom,gpio-ramdump-disable",
			&desc->ramdump_disable_gpio);
	ret = __get_irq(desc, "qcom,shutdown-ack", &desc->shutdown_ack_irq);
	if (ret && ret != -ENOENT)
		return ret;

	ret = __get_gpio(desc, "qcom,gpio-shutdown-ack",
			&desc->shutdown_ack_gpio);
	ret = __get_irq(desc, "qcom,wdog", &desc->wdog_bite_irq);
	if (ret && ret != -ENOENT)
		return ret;

	ret = platform_get_irq(pdev, 0);
	if (ret > 0)
		desc->wdog_bite_irq = ret;
	ret = __get_smem_state(desc, "qcom,force-stop", &desc->force_stop_bit);
	if (ret && ret != -ENOENT)
		return ret;

	if (of_property_read_bool(pdev->dev.of_node,
					"qcom,pil-generic-irq-handler")) {
@@ -1538,23 +1541,25 @@ static int subsys_setup_irqs(struct subsys_device *subsys)
	int ret;

	if (desc->err_fatal_irq && desc->err_fatal_handler) {
		ret = devm_request_irq(desc->dev, desc->err_fatal_irq,
		ret = devm_request_threaded_irq(desc->dev, desc->err_fatal_irq,
				NULL,
				desc->err_fatal_handler,
				IRQF_TRIGGER_RISING, desc->name, desc);
		if (ret < 0) {
			dev_err(desc->dev, "[%s]: Unable to register error fatal IRQ handler!: %d\n",
				desc->name, ret);
			dev_err(desc->dev, "[%s]: Unable to register error fatal IRQ handler: %d, irq is %d\n",
				desc->name, ret, desc->err_fatal_irq);
			return ret;
		}
		disable_irq(desc->err_fatal_irq);
	}

	if (desc->stop_ack_irq && desc->stop_ack_handler) {
		ret = devm_request_irq(desc->dev, desc->stop_ack_irq,
		ret = devm_request_threaded_irq(desc->dev, desc->stop_ack_irq,
				NULL,
			desc->stop_ack_handler,
			IRQF_TRIGGER_RISING, desc->name, desc);
		if (ret < 0) {
			dev_err(desc->dev, "[%s]: Unable to register stop ack handler!: %d\n",
			dev_err(desc->dev, "[%s]: Unable to register stop ack handler: %d\n",
				desc->name, ret);
			return ret;
		}
@@ -1566,19 +1571,47 @@ static int subsys_setup_irqs(struct subsys_device *subsys)
			desc->wdog_bite_handler,
			IRQF_TRIGGER_RISING, desc->name, desc);
		if (ret < 0) {
			dev_err(desc->dev, "[%s]: Unable to register wdog bite handler!: %d\n",
			dev_err(desc->dev, "[%s]: Unable to register wdog bite handler: %d\n",
				desc->name, ret);
			return ret;
		}
		disable_irq(desc->wdog_bite_irq);
	}

	if (desc->shutdown_ack_irq && desc->shutdown_ack_handler) {
		ret = devm_request_threaded_irq(desc->dev,
				desc->shutdown_ack_irq,
				NULL,
			desc->shutdown_ack_handler,
			IRQF_TRIGGER_RISING, desc->name, desc);
		if (ret < 0) {
			dev_err(desc->dev, "[%s]: Unable to register shutdown ack handler: %d\n",
				desc->name, ret);
			return ret;
		}
		disable_irq(desc->shutdown_ack_irq);
	}

	if (desc->ramdump_disable_irq && desc->ramdump_disable_handler) {
		ret = devm_request_threaded_irq(desc->dev,
				desc->ramdump_disable_irq,
				NULL,
			desc->ramdump_disable_handler,
			IRQF_TRIGGER_RISING, desc->name, desc);
		if (ret < 0) {
			dev_err(desc->dev, "[%s]: Unable to register shutdown ack handler: %d\n",
				desc->name, ret);
			return ret;
		}
		disable_irq(desc->ramdump_disable_irq);
	}

	if (desc->generic_irq && desc->generic_handler) {
		ret = devm_request_irq(desc->dev, desc->generic_irq,
			desc->generic_handler,
			IRQF_TRIGGER_HIGH, desc->name, desc);
		if (ret < 0) {
			dev_err(desc->dev, "[%s]: Unable to register generic irq handler!: %d\n",
			dev_err(desc->dev, "[%s]: Unable to register generic irq handler: %d\n",
				desc->name, ret);
			return ret;
		}
@@ -1586,8 +1619,9 @@ static int subsys_setup_irqs(struct subsys_device *subsys)
	}

	if (desc->err_ready_irq) {
		ret = devm_request_irq(desc->dev,
		ret = devm_request_threaded_irq(desc->dev,
					desc->err_ready_irq,
					NULL,
					subsys_err_ready_intr_handler,
					IRQF_TRIGGER_RISING,
					"error_ready_interrupt", subsys);
@@ -1611,6 +1645,10 @@ static void subsys_free_irqs(struct subsys_device *subsys)
		devm_free_irq(desc->dev, desc->err_fatal_irq, desc);
	if (desc->stop_ack_irq && desc->stop_ack_handler)
		devm_free_irq(desc->dev, desc->stop_ack_irq, desc);
	if (desc->shutdown_ack_irq && desc->shutdown_ack_handler)
		devm_free_irq(desc->dev, desc->shutdown_ack_irq, desc);
	if (desc->ramdump_disable_irq && desc->ramdump_disable_handler)
		devm_free_irq(desc->dev, desc->ramdump_disable_irq, desc);
	if (desc->wdog_bite_irq && desc->wdog_bite_handler)
		devm_free_irq(desc->dev, desc->wdog_bite_irq, desc);
	if (desc->err_ready_irq)
@@ -1634,6 +1672,7 @@ struct subsys_device *subsys_register(struct subsys_desc *desc)
	subsys->dev.release = subsys_device_release;
	subsys->notif_state = -1;
	subsys->desc->sysmon_pid = -1;
	subsys->desc->state = NULL;
	strlcpy(subsys->desc->fw_name, desc->name,
			sizeof(subsys->desc->fw_name));

+7 −3
Original line number Diff line number Diff line
@@ -74,6 +74,8 @@ struct subsys_desc {
	void (*free_memory)(const struct subsys_desc *desc);
	irqreturn_t (*err_fatal_handler)(int irq, void *dev_id);
	irqreturn_t (*stop_ack_handler)(int irq, void *dev_id);
	irqreturn_t (*shutdown_ack_handler)(int irq, void *dev_id);
	irqreturn_t (*ramdump_disable_handler)(int irq, void *dev_id);
	irqreturn_t (*wdog_bite_handler)(int irq, void *dev_id);
	irqreturn_t (*generic_handler)(int irq, void *dev_id);
	int is_not_loadable;
@@ -83,9 +85,9 @@ struct subsys_desc {
	unsigned int stop_ack_irq;
	unsigned int wdog_bite_irq;
	unsigned int generic_irq;
	int force_stop_gpio;
	int ramdump_disable_gpio;
	int shutdown_ack_gpio;
	int force_stop_bit;
	int ramdump_disable_irq;
	int shutdown_ack_irq;
	int ramdump_disable;
	bool no_auth;
	bool pil_mss_memsetup;
@@ -95,6 +97,7 @@ struct subsys_desc {
	bool system_debug;
	bool ignore_ssr_failure;
	const char *edge;
	struct qcom_smem_state *state;
};

/**
@@ -136,6 +139,7 @@ extern enum crash_status subsys_get_crash_status(struct subsys_device *dev);
void notify_proxy_vote(struct device *device);
void notify_proxy_unvote(struct device *device);
void complete_err_ready(struct subsys_device *subsys);
void complete_shutdown_ack(struct subsys_device *subsys);
extern int wait_for_shutdown_ack(struct subsys_desc *desc);
#else