From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755527Ab1JCLgV (ORCPT ); Mon, 3 Oct 2011 07:36:21 -0400 Received: from mga09.intel.com ([134.134.136.24]:14967 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752520Ab1JCLgS (ORCPT ); Mon, 3 Oct 2011 07:36:18 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.67,352,1309762800"; d="scan'208";a="58411631" From: Adrian Hunter To: grant.likely@secretlab.ca Cc: linux-kernel@vger.kernel.org, Adrian Hunter , Alan Cox Subject: [PATCH] gpio: langwell: ensure alternate function is cleared Date: Mon, 3 Oct 2011 14:36:07 +0300 Message-Id: <1317641767-2942-1-git-send-email-adrian.hunter@intel.com> X-Mailer: git-send-email 1.7.6 Organization: Intel Finland Oy, Registered Address: PL 281, 00181 Helsinki, Business Identity Code: 0357606 - 4, Domiciled in Helsinki Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Alternate function must be zero for the pin to act as a GPIO. Signed-off-by: Adrian Hunter Signed-off-by: Alan Cox --- drivers/gpio/gpio-langwell.c | 27 +++++++++++++++++++++++++++ 1 files changed, 27 insertions(+), 0 deletions(-) diff --git a/drivers/gpio/gpio-langwell.c b/drivers/gpio/gpio-langwell.c index d2eb57c..00692e8 100644 --- a/drivers/gpio/gpio-langwell.c +++ b/drivers/gpio/gpio-langwell.c @@ -59,6 +59,7 @@ enum GPIO_REG { GRER, /* rising edge detect */ GFER, /* falling edge detect */ GEDR, /* edge detect result */ + GAFR, /* alt function */ }; struct lnw_gpio { @@ -81,6 +82,31 @@ static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset, return ptr; } +static void __iomem *gpio_reg_2bit(struct gpio_chip *chip, unsigned offset, + enum GPIO_REG reg_type) +{ + struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip); + unsigned nreg = chip->ngpio / 32; + u8 reg = offset / 16; + void __iomem *ptr; + + ptr = (void __iomem *)(lnw->reg_base + reg_type * nreg * 4 + reg * 4); + return ptr; +} + +static int lnw_gpio_request(struct gpio_chip *chip, unsigned offset) +{ + void __iomem *gafr = gpio_reg_2bit(chip, offset, GAFR); + u32 value = readl(gafr); + int shift = (offset % 16) << 1, af = (value >> shift) & 3; + + if (af) { + value &= ~(3 << shift); + writel(value, gafr); + } + return 0; +} + static int lnw_gpio_get(struct gpio_chip *chip, unsigned offset) { void __iomem *gplr = gpio_reg(chip, offset, GPLR); @@ -321,6 +347,7 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, lnw->reg_base = base; lnw->irq_base = irq_base; lnw->chip.label = dev_name(&pdev->dev); + lnw->chip.request = lnw_gpio_request; lnw->chip.direction_input = lnw_gpio_direction_input; lnw->chip.direction_output = lnw_gpio_direction_output; lnw->chip.get = lnw_gpio_get; -- 1.7.6