From patchwork Thu May 28 13:32:47 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vaibhav Hiremath X-Patchwork-Id: 49115 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f198.google.com (mail-wi0-f198.google.com [209.85.212.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 663A8202A3 for ; Thu, 28 May 2015 13:35:29 +0000 (UTC) Received: by wifq9 with SMTP id q9sf13966598wif.3 for ; Thu, 28 May 2015 06:35:28 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=BsZSmdJ2AG3c/TVUr/rttsCV3AHN1+slWVUOYoKtcWs=; b=PYBt1KBQgvCisSyaIRgpKrfVr9mxNQb0SX6/YYE6iAxulDyrnxCSYiMIJ/76LqOoBa /ioZVc2W4EEguUVfxP2jIEVcR2CckGpaXxqbnp+kDDd/ZhBQJrDUR7eTlTZGmFBEcbaN TbKOaJPI6sZoK5NZKkmsyiGZk2ClsgraghkXj6yHtT83cQbHrQzlJuYoK5fL6xkaOdlF 9ESK8Sacoezs6980k+qatz02NzjgmRFKqnaqnj/jL4I3ndDK6zlawhdN8gm8WsOVRezD Va0XuaOqcfWcpEcfJuuMQfSfdr9qTyyF1JjXpEnpc55SUvS7uiPgsfK4j2uusgzKSSMl dGng== X-Gm-Message-State: ALoCoQmV1TaQiZ8sn1Cy2eDp1ycJ+UzETDNv0gctfBW19Uw5KP69U4SrR5YXBocg19vdr+9vtWqA X-Received: by 10.152.8.17 with SMTP id n17mr2760698laa.0.1432820128716; Thu, 28 May 2015 06:35:28 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.225.134 with SMTP id rk6ls192575lac.83.gmail; Thu, 28 May 2015 06:35:28 -0700 (PDT) X-Received: by 10.112.16.227 with SMTP id j3mr2843216lbd.43.1432820128566; Thu, 28 May 2015 06:35:28 -0700 (PDT) Received: from mail-la0-f42.google.com (mail-la0-f42.google.com. [209.85.215.42]) by mx.google.com with ESMTPS id w12si1945284lbf.159.2015.05.28.06.35.28 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 28 May 2015 06:35:28 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.42 as permitted sender) client-ip=209.85.215.42; Received: by labko7 with SMTP id ko7so28287822lab.2 for ; Thu, 28 May 2015 06:35:28 -0700 (PDT) X-Received: by 10.112.199.133 with SMTP id jk5mr2959571lbc.32.1432820128457; Thu, 28 May 2015 06:35:28 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.108.230 with SMTP id hn6csp1165347lbb; Thu, 28 May 2015 06:35:26 -0700 (PDT) X-Received: by 10.70.101.2 with SMTP id fc2mr5613374pdb.77.1432820125084; Thu, 28 May 2015 06:35:25 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z8si3682249pas.64.2015.05.28.06.35.24; Thu, 28 May 2015 06:35:25 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-i2c-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754008AbbE1NfR (ORCPT + 1 other); Thu, 28 May 2015 09:35:17 -0400 Received: from mail-pd0-f182.google.com ([209.85.192.182]:35795 "EHLO mail-pd0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753220AbbE1NfN (ORCPT ); Thu, 28 May 2015 09:35:13 -0400 Received: by pdea3 with SMTP id a3so41891063pde.2 for ; Thu, 28 May 2015 06:35:13 -0700 (PDT) X-Received: by 10.68.232.194 with SMTP id tq2mr5653612pbc.90.1432820112909; Thu, 28 May 2015 06:35:12 -0700 (PDT) Received: from localhost.localdomain ([202.62.77.106]) by mx.google.com with ESMTPSA id f1sm2473461pds.62.2015.05.28.06.35.09 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 28 May 2015 06:35:11 -0700 (PDT) From: Vaibhav Hiremath To: linux-i2c@vger.kernel.org Cc: Wolfram Sang , linux-arm-kernel@lists.infradead.org, Vaibhav Hiremath , Haojian Zhuang Subject: [PATCH 2/3] i2c: pxa: Add support for hardware lock Date: Thu, 28 May 2015 19:02:47 +0530 Message-Id: <1432819968-17515-3-git-send-email-vaibhav.hiremath@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1432819968-17515-1-git-send-email-vaibhav.hiremath@linaro.org> References: <1432819968-17515-1-git-send-email-vaibhav.hiremath@linaro.org> Sender: linux-i2c-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-i2c@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: vaibhav.hiremath@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.42 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , In case of PXA910 silicon, both AP and CP are present and these two ARM cores are sharing one pair of I2C pins. In order to keep I2C transaction operated with atomic, hardware lock (RIPC) is required. This patch extends support for atomic operation by adding hardware lock. Signed-off-by: Haojian Zhuang Signed-off-by: Vaibhav Hiremath --- drivers/i2c/busses/i2c-pxa.c | 75 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/i2c/pxa-i2c.h | 4 +++ 2 files changed, 79 insertions(+) diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index f51d512..eb26eb1 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -167,6 +167,7 @@ struct pxa_i2c { void __iomem *reg_isar; void __iomem *reg_ilcr; void __iomem *reg_iwcr; + void __iomem *hwlock_addr; unsigned long iobase; unsigned long iosize; @@ -368,6 +369,9 @@ static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why) static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret); static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id); +spinlock_t lock_for_ripc; +static int ripc_status; + /* enable/disable i2c unit */ static inline void i2c_pxa_enable(struct pxa_i2c *i2c, bool enable) { @@ -378,6 +382,57 @@ static inline void i2c_pxa_enable(struct pxa_i2c *i2c, bool enable) udelay(100); } +void mmp_hwlock_lock(struct i2c_adapter *adap) +{ + int cnt = 0; + unsigned long flags; + + struct pxa_i2c *i2c = adap->algo_data; + + spin_lock_irqsave(&lock_for_ripc, flags); + while(__raw_readl(i2c->hwlock_addr)) { + ripc_status = false; + spin_unlock_irqrestore(&lock_for_ripc, flags); + cpu_relax(); + udelay(50); + cnt++; + if (cnt >= 10000) { + pr_warn("AP: fail to lock ripc!\n"); + cnt = 0; + } + } + /* sure to hold ripc */ + ripc_status = true; + + spin_unlock_irqrestore(&lock_for_ripc, flags); +} + +void mmp_hwlock_unlock(struct i2c_adapter *adap) +{ + unsigned long flags; + + struct pxa_i2c *i2c = adap->algo_data; + + spin_lock_irqsave(&lock_for_ripc, flags); + __raw_writel(1, i2c->hwlock_addr); + ripc_status = false; + + spin_unlock_irqrestore(&lock_for_ripc, flags); +} + +int mmp_hwlock_trylock(struct i2c_adapter *adap) +{ + unsigned long flags; + + struct pxa_i2c *i2c = adap->algo_data; + + spin_lock_irqsave(&lock_for_ripc, flags); + ripc_status = !__raw_readl(i2c->hwlock_addr); + spin_unlock_irqrestore(&lock_for_ripc, flags); + + return ripc_status; +} + static inline int i2c_pxa_is_slavemode(struct pxa_i2c *i2c) { return !(readl(_ICR(i2c)) & ICR_SCLE); @@ -1347,6 +1402,14 @@ static int i2c_pxa_probe(struct platform_device *dev) i2c->iobase = res->start; i2c->iosize = resource_size(res); + res = platform_get_resource(dev, IORESOURCE_MEM, 1); + if (res) { + i2c->hwlock_addr = ioremap(res->start, resource_size(res)); + dev_info(&dev->dev, "hardware lock address: 0x%p\n", + i2c->hwlock_addr); + } else + dev_dbg(&dev->dev, "no hardware lock used\n"); + i2c->irq = irq; i2c->slave_addr = I2C_PXA_SLAVE_ADDR; @@ -1360,6 +1423,18 @@ static int i2c_pxa_probe(struct platform_device *dev) i2c->ilcr = plat->ilcr; i2c->iwcr = plat->iwcr; i2c->adap.class = plat->class; + + i2c->adap.hardware_lock = plat->hardware_lock; + i2c->adap.hardware_unlock = plat->hardware_unlock; + i2c->adap.hardware_trylock = plat->hardware_trylock; + } else { + if (i2c->hwlock_addr) { + spin_lock_init(&lock_for_ripc); + + i2c->adap.hardware_lock = mmp_hwlock_lock; + i2c->adap.hardware_unlock = mmp_hwlock_unlock; + i2c->adap.hardware_trylock = mmp_hwlock_trylock; + } } if (i2c->high_mode) { diff --git a/include/linux/i2c/pxa-i2c.h b/include/linux/i2c/pxa-i2c.h index d1a44e8..e6f5981 100644 --- a/include/linux/i2c/pxa-i2c.h +++ b/include/linux/i2c/pxa-i2c.h @@ -72,6 +72,10 @@ struct i2c_pxa_platform_data { unsigned long rate; unsigned int ilcr; unsigned int iwcr; + void (*hardware_lock)(struct i2c_adapter *); + void (*hardware_unlock)(struct i2c_adapter *); + int (*hardware_trylock)(struct i2c_adapter *); + }; extern void pxa_set_i2c_info(struct i2c_pxa_platform_data *info);