Received: by 2002:a25:86ce:0:0:0:0:0 with SMTP id y14csp199080ybm; Wed, 22 May 2019 01:28:05 -0700 (PDT) X-Google-Smtp-Source: APXvYqzN5P/rGQ/AOATHFtCIWwa/DcKY5SroVsYmBNaAn+/O4Oot2Tcg8q0yCD5vywHjyNAXK6Yu X-Received: by 2002:a65:6255:: with SMTP id q21mr77726921pgv.211.1558513685208; Wed, 22 May 2019 01:28:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1558513685; cv=none; d=google.com; s=arc-20160816; b=f4siyclIHUWwyv1pYV8n7GsmmIocxtoxPHGBOQ4rFcsWX+u1+C1qEQqxHjwxM5ytzQ tLU7Mo7zu4IplrYHA/CesstGjb/Yo5/UDJjEFlVuJXgQT8JIlXaZJ+0dNpwNtg4MSZxe 7feY9YJRKDTPFs54QI4qFdqMq7IFcfZvxlFspsck+h8sXXxv/JAG5X2N/ULYONCvbeTG 1TVCDsLrD+Vy+gGAFkAcCXG0gNX82T7A2CtkGXdlrs+QKZij7r5vU3yfP1Pho8gANR8E tiEi3a9/c9cXh8MiIcQNnUW0w+HNhfVu2vQoj1Gl38UCIM6FNkzKl/CNPIjWs5EL2Kbp e5Ag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:message-id:date:subject:cc :to:from:dkim-signature; bh=95DbXIJbPEyjb+3HhxJUM/8t0wqdd7pQtBu4/qr7Suc=; b=pvIx/Y6ChaAkPYGrmPg3oZuJpJNOg+CPaIWnG2guy7SwIAbWtVP9Ow64iZ6LsJiwuj ac/kskL0jJpyWLpvPld3j+Fj9oBHIb9T8OTPHt3nIpsyo0kcAtx6vfwSyrmGHCqQn/ND Mv5+UNhtednb9po0BA3T8xXYUPJpIKs35Eqx2w6mcMaDyHJFojnMxmV3AJbOxS96YSlU Cz6LKIlaL1HSl/9DR4XAa0wzUbh3RdrzVtLSeKd9QZUQztduj/n9ADLveb4A+dKTc/dS EZkkzkP+NubiFkNU36Mts1gRk/XiBzEEtvDP0pEUX8YwZmF1q6D78cGFhH4fprYLTBka afCA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@st.com header.s=STMicroelectronics header.b=EbGREjps; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r26si24485067pgb.32.2019.05.22.01.27.48; Wed, 22 May 2019 01:28:05 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@st.com header.s=STMicroelectronics header.b=EbGREjps; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728631AbfEVI0V (ORCPT + 99 others); Wed, 22 May 2019 04:26:21 -0400 Received: from mx07-00178001.pphosted.com ([62.209.51.94]:32826 "EHLO mx07-00178001.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728406AbfEVI0V (ORCPT ); Wed, 22 May 2019 04:26:21 -0400 Received: from pps.filterd (m0046668.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x4M8Gjp2016707; Wed, 22 May 2019 10:25:53 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=st.com; h=from : to : cc : subject : date : message-id : mime-version : content-type; s=STMicroelectronics; bh=95DbXIJbPEyjb+3HhxJUM/8t0wqdd7pQtBu4/qr7Suc=; b=EbGREjpsIjyrZeuzjob0mWdmoQyx1V90ZeDFkUVJYWBzW4r6trY/JeAB2UVddK76tWfA V1rLn3N2aIqoKvfym2FgaJ6Pnqf/CcUssjhLs/Wp7fWFwf4JDF7CrgnqmowLmGBFKYl2 dXSKYqlKgvD/rAq2Ue674LGcDPKDEk5orbg5SeK129nwRMgV5Ajg8i1AK2h6yAQmVgbk zEbdyi/3u7eDmSwA0sBsPbEPUwz/rEpEjnWjiEMWQ/OWUZnMolPP9Hg/qfw4Adrdqjf8 mioz04sXjFUGeZ4E9IB7NOf7KRl2lz/nvK0gu2ZepPrljD0vdib78NlVyYLlOXNMgEmZ QQ== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com with ESMTP id 2sj7h0y2bn-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Wed, 22 May 2019 10:25:53 +0200 Received: from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id F1C8D34; Wed, 22 May 2019 08:25:52 +0000 (GMT) Received: from Webmail-eu.st.com (Safex1hubcas23.st.com [10.75.90.46]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id D9A341E83; Wed, 22 May 2019 08:25:51 +0000 (GMT) Received: from SAFEX1HUBCAS21.st.com (10.75.90.44) by SAFEX1HUBCAS23.st.com (10.75.90.46) with Microsoft SMTP Server (TLS) id 14.3.439.0; Wed, 22 May 2019 10:25:51 +0200 Received: from localhost (10.48.0.131) by Webmail-ga.st.com (10.75.90.48) with Microsoft SMTP Server (TLS) id 14.3.439.0; Wed, 22 May 2019 10:25:51 +0200 From: Arnaud Pouliquen To: Jassi Brar , Fabien DESSENNE CC: , , , Subject: [PATCH] mailbox: stm32_ipcc: add spinlock to fix channels concurrent access Date: Wed, 22 May 2019 10:25:35 +0200 Message-ID: <1558513535-16736-1-git-send-email-arnaud.pouliquen@st.com> X-Mailer: git-send-email 2.7.4 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.48.0.131] X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2019-05-22_03:,, signatures=0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add spinlock protection on IPCC register update to avoid race condition. Without this fix, stm32_ipcc_set_bits and stm32_ipcc_clr_bits can be called in parallel for different channels. This results in register corruptions. Signed-off-by: Arnaud Pouliquen --- drivers/mailbox/stm32-ipcc.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/drivers/mailbox/stm32-ipcc.c b/drivers/mailbox/stm32-ipcc.c index f91dfb1327c7..5c2d1e1f988b 100644 --- a/drivers/mailbox/stm32-ipcc.c +++ b/drivers/mailbox/stm32-ipcc.c @@ -50,6 +50,7 @@ struct stm32_ipcc { void __iomem *reg_base; void __iomem *reg_proc; struct clk *clk; + spinlock_t lock; /* protect access to IPCC registers */ int irqs[IPCC_IRQ_NUM]; int wkp; u32 proc_id; @@ -58,14 +59,24 @@ struct stm32_ipcc { u32 xmr; }; -static inline void stm32_ipcc_set_bits(void __iomem *reg, u32 mask) +static inline void stm32_ipcc_set_bits(spinlock_t *lock, void __iomem *reg, + u32 mask) { + unsigned long flags; + + spin_lock_irqsave(lock, flags); writel_relaxed(readl_relaxed(reg) | mask, reg); + spin_unlock_irqrestore(lock, flags); } -static inline void stm32_ipcc_clr_bits(void __iomem *reg, u32 mask) +static inline void stm32_ipcc_clr_bits(spinlock_t *lock, void __iomem *reg, + u32 mask) { + unsigned long flags; + + spin_lock_irqsave(lock, flags); writel_relaxed(readl_relaxed(reg) & ~mask, reg); + spin_unlock_irqrestore(lock, flags); } static irqreturn_t stm32_ipcc_rx_irq(int irq, void *data) @@ -92,7 +103,7 @@ static irqreturn_t stm32_ipcc_rx_irq(int irq, void *data) mbox_chan_received_data(&ipcc->controller.chans[chan], NULL); - stm32_ipcc_set_bits(ipcc->reg_proc + IPCC_XSCR, + stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XSCR, RX_BIT_CHAN(chan)); ret = IRQ_HANDLED; @@ -121,7 +132,7 @@ static irqreturn_t stm32_ipcc_tx_irq(int irq, void *data) dev_dbg(dev, "%s: chan:%d tx\n", __func__, chan); /* mask 'tx channel free' interrupt */ - stm32_ipcc_set_bits(ipcc->reg_proc + IPCC_XMR, + stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XMR, TX_BIT_CHAN(chan)); mbox_chan_txdone(&ipcc->controller.chans[chan], 0); @@ -141,10 +152,12 @@ static int stm32_ipcc_send_data(struct mbox_chan *link, void *data) dev_dbg(ipcc->controller.dev, "%s: chan:%d\n", __func__, chan); /* set channel n occupied */ - stm32_ipcc_set_bits(ipcc->reg_proc + IPCC_XSCR, TX_BIT_CHAN(chan)); + stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XSCR, + TX_BIT_CHAN(chan)); /* unmask 'tx channel free' interrupt */ - stm32_ipcc_clr_bits(ipcc->reg_proc + IPCC_XMR, TX_BIT_CHAN(chan)); + stm32_ipcc_clr_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XMR, + TX_BIT_CHAN(chan)); return 0; } @@ -163,7 +176,8 @@ static int stm32_ipcc_startup(struct mbox_chan *link) } /* unmask 'rx channel occupied' interrupt */ - stm32_ipcc_clr_bits(ipcc->reg_proc + IPCC_XMR, RX_BIT_CHAN(chan)); + stm32_ipcc_clr_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XMR, + RX_BIT_CHAN(chan)); return 0; } @@ -175,7 +189,7 @@ static void stm32_ipcc_shutdown(struct mbox_chan *link) controller); /* mask rx/tx interrupt */ - stm32_ipcc_set_bits(ipcc->reg_proc + IPCC_XMR, + stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XMR, RX_BIT_CHAN(chan) | TX_BIT_CHAN(chan)); clk_disable_unprepare(ipcc->clk); @@ -208,6 +222,8 @@ static int stm32_ipcc_probe(struct platform_device *pdev) if (!ipcc) return -ENOMEM; + spin_lock_init(&ipcc->lock); + /* proc_id */ if (of_property_read_u32(np, "st,proc-id", &ipcc->proc_id)) { dev_err(dev, "Missing st,proc-id\n"); @@ -259,9 +275,10 @@ static int stm32_ipcc_probe(struct platform_device *pdev) } /* mask and enable rx/tx irq */ - stm32_ipcc_set_bits(ipcc->reg_proc + IPCC_XMR, + stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XMR, RX_BIT_MASK | TX_BIT_MASK); - stm32_ipcc_set_bits(ipcc->reg_proc + IPCC_XCR, XCR_RXOIE | XCR_TXOIE); + stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XCR, + XCR_RXOIE | XCR_TXOIE); /* wakeup */ if (of_property_read_bool(np, "wakeup-source")) { -- 2.7.4