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

Commit 8071ebfc authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

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

parents f112feec 19901440
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -84,7 +84,7 @@
#define SMEM_GLOBAL_HOST	0xfffe

/* Max number of processors/hosts in a system */
#define SMEM_HOST_COUNT		10
#define SMEM_HOST_COUNT		11

/**
  * struct smem_proc_comm - proc_comm communication struct (legacy)
+17 −11
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * 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.
 */

#include <linux/interrupt.h>
@@ -97,6 +97,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);

@@ -137,6 +138,7 @@ struct qcom_smp2p {
	unsigned local_pid;
	unsigned remote_pid;

	int irq;
	struct regmap *ipc_regmap;
	int ipc_offset;
	int ipc_bit;
@@ -174,11 +176,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;
@@ -219,19 +221,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);
			}
		}
	}
@@ -293,6 +298,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;
}
@@ -444,7 +451,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);
@@ -473,10 +479,10 @@ static int qcom_smp2p_probe(struct platform_device *pdev)
	if (ret)
		goto report_read_failure;

	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;
	}

	smp2p->mbox_client.dev = &pdev->dev;
@@ -529,7 +535,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);