From patchwork Wed Aug 27 17:46:27 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Chen, Alvin" X-Patchwork-Id: 383407 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 507A71400B7 for ; Wed, 27 Aug 2014 19:56:16 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933457AbaH0Jyz (ORCPT ); Wed, 27 Aug 2014 05:54:55 -0400 Received: from mga03.intel.com ([143.182.124.21]:3195 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755826AbaH0Jya (ORCPT ); Wed, 27 Aug 2014 05:54:30 -0400 Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga101.ch.intel.com with ESMTP; 27 Aug 2014 02:54:29 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.04,409,1406617200"; d="scan'208";a="473110642" Received: from quark.bj.intel.com ([172.16.182.163]) by azsmga001.ch.intel.com with ESMTP; 27 Aug 2014 02:54:22 -0700 From: Weike Chen To: Linus Walleij , Alexandre Courbot , Grant Likely , Rob Herring Cc: linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Boon Leong Ong , Andriy Shevchenko , Mika Westerberg , Hock Leong Kweh , Darren Hart , Alvin Chen Subject: [PATCH 2/3] GPIO: gpio-dwapb: Support Debounce Date: Wed, 27 Aug 2014 10:46:27 -0700 Message-Id: <1409161588-19417-3-git-send-email-alvin.chen@intel.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1409161588-19417-1-git-send-email-alvin.chen@intel.com> References: <1409161588-19417-1-git-send-email-alvin.chen@intel.com> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org This patch enables 'debounce' for the designware GPIO, and it is based on Josef Ahmad's previous work. Reviewed-by: Hock Leong Kweh Reviewed-by: Shevchenko, Andriy Signed-off-by: Weike Chen --- drivers/gpio/gpio-dwapb.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c index 155a64b..e0ab988 100644 --- a/drivers/gpio/gpio-dwapb.c +++ b/drivers/gpio/gpio-dwapb.c @@ -36,6 +36,7 @@ #define GPIO_INTTYPE_LEVEL 0x38 #define GPIO_INT_POLARITY 0x3c #define GPIO_INTSTATUS 0x40 +#define GPIO_PORTA_DEBOUNCE 0x48 #define GPIO_PORTA_EOI 0x4c #define GPIO_EXT_PORTA 0x50 #define GPIO_EXT_PORTB 0x54 @@ -64,6 +65,23 @@ struct dwapb_gpio { const struct dwapb_gpio_platform_data *pdata; }; +static inline u32 dwapb_read(struct dwapb_gpio *gpio, unsigned int offset) +{ + struct bgpio_chip *bgc = &gpio->ports[0].bgc; + void __iomem *reg_base = gpio->regs; + + return bgc->read_reg(reg_base + offset); +} + +static inline void dwapb_write(struct dwapb_gpio *gpio, unsigned int offset, + u32 val) +{ + struct bgpio_chip *bgc = &gpio->ports[0].bgc; + void __iomem *reg_base = gpio->regs; + + bgc->write_reg(reg_base + offset, val); +} + static int dwapb_gpio_to_irq(struct gpio_chip *gc, unsigned offset) { struct bgpio_chip *bgc = to_bgpio_chip(gc); @@ -209,6 +227,29 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type) return 0; } +static int dwapb_gpio_set_debounce(struct gpio_chip *gc, + unsigned offset, unsigned debounce) +{ + struct bgpio_chip *bgc = to_bgpio_chip(gc); + struct dwapb_gpio_port *port = + container_of(bgc, struct dwapb_gpio_port, bgc); + struct dwapb_gpio *gpio = port->gpio; + unsigned long flags, val_deb; + unsigned long mask = bgc->pin2mask(bgc, offset); + + spin_lock_irqsave(&bgc->lock, flags); + + val_deb = dwapb_read(gpio, GPIO_PORTA_DEBOUNCE); + if (debounce) + dwapb_write(gpio, GPIO_PORTA_DEBOUNCE, mask | val_deb); + else + dwapb_write(gpio, GPIO_PORTA_DEBOUNCE, ~mask & val_deb); + + spin_unlock_irqrestore(&bgc->lock, flags); + + return 0; +} + static irqreturn_t dwapb_irq_handler_mfd(int irq, void *dev_id) { struct irq_desc *desc = irq_to_desc(irq); @@ -342,6 +383,7 @@ static int dwapb_gpio_add_port(struct dwapb_gpio *gpio, port->bgc.gc.ngpio = pp->ngpio; port->bgc.gc.base = pp->gpio_base; + port->bgc.gc.set_debounce = dwapb_gpio_set_debounce; /* * Only port A can provide interrupts in all configurations of the IP.