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

Commit 4b50acc1 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "soc: qcom: smp2p: Introduce pending state for virtual irq"

parents 572d72ce 031782d5
Loading
Loading
Loading
Loading
+17 −11
Original line number Diff line number Diff line
/*
 * Copyright (c) 2015, Sony Mobile Communications AB.
 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2013, 2018 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
@@ -104,6 +104,7 @@ struct smp2p_entry {

	struct irq_domain *domain;
	DECLARE_BITMAP(irq_enabled, 32);
	DECLARE_BITMAP(irq_pending, 32);
	DECLARE_BITMAP(irq_rising, 32);
	DECLARE_BITMAP(irq_falling, 32);

@@ -142,6 +143,7 @@ struct qcom_smp2p {
	unsigned local_pid;
	unsigned remote_pid;

	int irq;
	struct regmap *ipc_regmap;
	int ipc_offset;
	int ipc_bit;
@@ -170,11 +172,11 @@ static irqreturn_t qcom_smp2p_intr(int irq, void *data)
	struct smp2p_smem_item *in;
	struct smp2p_entry *entry;
	struct qcom_smp2p *smp2p = data;
	unsigned long status;
	unsigned smem_id = smp2p->smem_items[SMP2P_INBOUND];
	unsigned pid = smp2p->remote_pid;
	size_t size;
	int irq_pin;
	u32 status;
	char buf[SMP2P_MAX_ENTRY_NAME];
	u32 val;
	int i;
@@ -215,19 +217,22 @@ static irqreturn_t qcom_smp2p_intr(int irq, void *data)

		status = val ^ entry->last_value;
		entry->last_value = val;
		status |= *entry->irq_pending;

		/* No changes of this entry? */
		if (!status)
			continue;

		for_each_set_bit(i, entry->irq_enabled, 32) {
			if (!(status & BIT(i)))
				continue;

		for_each_set_bit(i, &status, 32) {
			if ((val & BIT(i) && test_bit(i, entry->irq_rising)) ||
			    (!(val & BIT(i)) && test_bit(i, entry->irq_falling))) {
				irq_pin = irq_find_mapping(entry->domain, i);
				handle_nested_irq(irq_pin);

				if (test_bit(i, entry->irq_enabled))
					clear_bit(i, entry->irq_pending);
				else
					set_bit(i, entry->irq_pending);
			}
		}
	}
@@ -289,6 +294,8 @@ static int smp2p_irq_map(struct irq_domain *d,
	irq_set_chip_data(irq, entry);
	irq_set_nested_thread(irq, 1);
	irq_set_noprobe(irq);
	irq_set_parent(irq, entry->smp2p->irq);
	irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY);

	return 0;
}
@@ -440,7 +447,6 @@ static int qcom_smp2p_probe(struct platform_device *pdev)
	struct device_node *node;
	struct qcom_smp2p *smp2p;
	const char *key;
	int irq;
	int ret;

	smp2p = devm_kzalloc(&pdev->dev, sizeof(*smp2p), GFP_KERNEL);
@@ -477,10 +483,10 @@ static int qcom_smp2p_probe(struct platform_device *pdev)
		return -EINVAL;
	}

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
	smp2p->irq = platform_get_irq(pdev, 0);
	if (smp2p->irq < 0) {
		dev_err(&pdev->dev, "unable to acquire smp2p interrupt\n");
		return irq;
		return smp2p->irq;
	}

	ret = qcom_smp2p_alloc_outbound_item(smp2p);
@@ -519,7 +525,7 @@ static int qcom_smp2p_probe(struct platform_device *pdev)
	/* Kick the outgoing edge after allocating entries */
	qcom_smp2p_kick(smp2p);

	ret = devm_request_threaded_irq(&pdev->dev, irq,
	ret = devm_request_threaded_irq(&pdev->dev, smp2p->irq,
					NULL, qcom_smp2p_intr,
					IRQF_ONESHOT,
					"smp2p", (void *)smp2p);