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

Commit 8bc7bdcf 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: pil: Update pil to use the new smp2p interface" into msm-next

parents 605d1391 70664942
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