From patchwork Wed Dec 29 12:28:08 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Felipe Balbi X-Patchwork-Id: 439271 X-Patchwork-Delegate: me@felipebalbi.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oBUMBEj4000490 for ; Thu, 30 Dec 2010 22:11:17 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752300Ab0L2M2O (ORCPT ); Wed, 29 Dec 2010 07:28:14 -0500 Received: from na3sys009aog108.obsmtp.com ([74.125.149.199]:45023 "EHLO na3sys009aog108.obsmtp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752096Ab0L2M2O (ORCPT ); Wed, 29 Dec 2010 07:28:14 -0500 Received: from source ([209.85.215.41]) by na3sys009aob108.postini.com ([74.125.148.12]) with SMTP ID DSNKTRspXKFkDGiifaQC87ZoHu9Io7AStzOM@postini.com; Wed, 29 Dec 2010 04:28:13 PST Received: by ewy27 with SMTP id 27so5667705ewy.0 for ; Wed, 29 Dec 2010 04:28:12 -0800 (PST) Received: by 10.213.17.197 with SMTP id t5mr428909eba.64.1293625691887; Wed, 29 Dec 2010 04:28:11 -0800 (PST) Received: from localhost (cs181221087.pp.htv.fi [82.181.221.87]) by mx.google.com with ESMTPS id t5sm10518528eeh.8.2010.12.29.04.28.09 (version=TLSv1/SSLv3 cipher=RC4-MD5); Wed, 29 Dec 2010 04:28:10 -0800 (PST) Date: Wed, 29 Dec 2010 14:28:08 +0200 From: Felipe Balbi To: Felipe Balbi Cc: Mark Brown , Felipe Balbi , Linux Kernel Mailing List , Linux OMAP Mailing List , Tony Lindgren , David Brownell , Thomas Gleixner Subject: Re: [RFC/PATCH 3/3] mfd: twl4030-irq: implement bus_*lock Message-ID: <20101229122808.GC2222@legolas.emea.dhcp.ti.com> Reply-To: balbi@ti.com References: <20101228161657.GF2239@legolas.emea.dhcp.ti.com> <1293556459-28613-1-git-send-email-balbi@ti.com> <1293556459-28613-4-git-send-email-balbi@ti.com> <20101228235836.GA2609@opensource.wolfsonmicro.com> <1293583108.1822.3.camel@eowin> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1293583108.1822.3.camel@eowin> User-Agent: Mutt/1.5.20 (2009-06-14) Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Thu, 30 Dec 2010 22:11:17 +0000 (UTC) diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index 298956d..84f6066 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c @@ -440,6 +440,7 @@ struct sih_agent { const struct sih *sih; u32 imr; + bool imr_change_pending; u32 edge_change; struct mutex irq_lock; @@ -450,64 +451,23 @@ struct sih_agent { static void twl4030_sih_mask(unsigned irq) { struct sih_agent *agent = get_irq_chip_data(irq); - const struct sih *sih = agent->sih; - - union { - u8 bytes[4]; - u32 word; - } imr; - - int status; agent->imr |= BIT(irq - agent->irq_base); - - mutex_lock(&agent->irq_lock); - - /* byte[0] gets overwritten as we write ... */ - imr.word = cpu_to_le32(agent->imr << 8); - - /* write the whole mask ... simpler than subsetting it */ - status = twl_i2c_write(sih->module, imr.bytes, - sih->mask[irq_line].imr_offset, sih->bytes_ixr); - if (status) - pr_err("twl4030: %s, %s --> %d\n", __func__, - "write", status); - mutex_unlock(&agent->irq_lock); + agent->imr_change_pending = true; } static void twl4030_sih_unmask(unsigned irq) { struct sih_agent *agent = get_irq_chip_data(irq); - const struct sih *sih = agent->sih; - union { - u8 bytes[4]; - u32 word; - } imr; - - int status; - - mutex_lock(&agent->irq_lock); agent->imr &= ~BIT(irq - agent->irq_base); - - /* byte[0] gets overwritten as we write ... */ - imr.word = cpu_to_le32(agent->imr << 8); - - /* write the whole mask ... simpler than subsetting it */ - status = twl_i2c_write(sih->module, imr.bytes, - sih->mask[irq_line].imr_offset, sih->bytes_ixr); - if (status) - pr_err("twl4030: %s, %s --> %d\n", __func__, - "write", status); - mutex_unlock(&agent->irq_lock); + agent->imr_change_pending = true; } static int twl4030_sih_set_type(unsigned irq, unsigned trigger) { struct sih_agent *agent = get_irq_chip_data(irq); - const struct sih *sih = agent->sih; struct irq_desc *desc = irq_to_desc(irq); - int status = 0; if (!desc) { pr_err("twl4030: Invalid IRQ: %d\n", irq); @@ -517,17 +477,57 @@ static int twl4030_sih_set_type(unsigned irq, unsigned trigger) if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) return -EINVAL; - mutex_lock(&agent->irq_lock); if ((desc->status & IRQ_TYPE_SENSE_MASK) != trigger) { - u8 bytes[6]; - u32 edge_change; + agent->edge_change |= BIT(irq - agent->irq_base); desc->status &= ~IRQ_TYPE_SENSE_MASK; desc->status |= trigger; - agent->edge_change |= BIT(irq - agent->irq_base); + } + + return 0; +} + +static void twl4030_sih_bus_lock(unsigned int irq) +{ + struct sih_agent *agent = get_irq_chip_data(irq); + + mutex_lock(&agent->irq_lock); +} + +static void twl4030_sih_bus_sync_unlock(unsigned int irq) +{ + struct sih_agent *agent = get_irq_chip_data(irq); + const struct sih *sih = agent->sih; + + int status; + + union { + u8 bytes[4]; + u32 word; + } imr; + + if (agent->imr_change_pending) { + /* byte[0] gets overwritten as we write ... */ + imr.word = cpu_to_le32(agent->imr << 8); + + /* write the whole mask ... simpler than subsetting it */ + status = twl_i2c_write(sih->module, imr.bytes, + sih->mask[irq_line].imr_offset, sih->bytes_ixr); + if (status) + pr_err("twl4030: %s, %s --> %d\n", __func__, + "write", status); + agent->imr_change_pending = false; + } + + if (agent->edge_change) { + u32 edge_change; + u8 bytes[6]; + edge_change = agent->edge_change; + agent->edge_change = 0; - /* Read, reserving first byte for write scratch. Yes, this + /* + * Read, reserving first byte for write scratch. Yes, this * could be cached for some speedup ... but be careful about * any processor on the other IRQ line, EDR registers are * shared. @@ -550,7 +550,6 @@ static int twl4030_sih_set_type(unsigned irq, unsigned trigger) if (!d) { pr_err("twl4030: Invalid IRQ: %d\n", i + agent->irq_base); - status = -ENODEV; goto out; } @@ -576,8 +575,6 @@ static int twl4030_sih_set_type(unsigned irq, unsigned trigger) out: mutex_unlock(&agent->irq_lock); - - return status; } static struct irq_chip twl4030_sih_irq_chip = { @@ -585,6 +582,8 @@ static struct irq_chip twl4030_sih_irq_chip = { .mask = twl4030_sih_mask, .unmask = twl4030_sih_unmask, .set_type = twl4030_sih_set_type, + .bus_lock = twl4030_sih_bus_lock, + .bus_sync_unlock = twl4030_sih_bus_sync_unlock, }; /*----------------------------------------------------------------------*/