Loading drivers/soc/qcom/smp2p.c +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 Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); } } } Loading Loading @@ -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; } Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading
drivers/soc/qcom/smp2p.c +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 Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); } } } Loading Loading @@ -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; } Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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); Loading