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

This commit is contained in:
qctecmdr 2019-08-16 20:10:02 -07:00 • committed by Gerrit - the friendly Code Review server
commit 8071ebfc9b
2 changed files with 18 additions and 12 deletions

View file

@ -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)

View file

@ -1,7 +1,7 @@
// 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);