Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757835Ab0FPCnz (ORCPT ); Tue, 15 Jun 2010 22:43:55 -0400 Received: from wolverine01.qualcomm.com ([199.106.114.254]:28267 "EHLO wolverine01.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755329Ab0FPCnw (ORCPT ); Tue, 15 Jun 2010 22:43:52 -0400 X-IronPort-AV: E=McAfee;i="5400,1158,6014"; a="44571491" From: Gregory Bean To: davidb@codeaurora.org, dwalker@codeaurora.org, bryanh@codeaurora.org Cc: linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Gregory Bean Subject: [PATCH 1/2] arm: msm: Add gpiolib support for MSM7200A-family chips. Date: Tue, 15 Jun 2010 19:43:47 -0700 Message-Id: <1276656228-9376-2-git-send-email-gbean@codeaurora.org> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1276656228-9376-1-git-send-email-gbean@codeaurora.org> References: <1276656228-9376-1-git-send-email-gbean@codeaurora.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 10184 Lines: 313 Add support for uniprocessor MSM chips whose TLMM/GPIO design is the same as the MSM7200A. This includes, but is not necessarily limited to, the: MSM7200A, MSM7x25, MSM7x27, MSM7x30, QSD8x50, QSD8x50A Signed-off-by: Gregory Bean --- arch/arm/mach-msm/Kconfig | 7 ++ arch/arm/mach-msm/Makefile | 2 +- arch/arm/mach-msm/msm7200a-gpio.c | 187 +++++++++++++++++++++++++++++++++++++ arch/arm/mach-msm/msm7200a-gpio.h | 62 ++++++++++++ 4 files changed, 257 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-msm/msm7200a-gpio.c create mode 100644 arch/arm/mach-msm/msm7200a-gpio.h diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index 47264a7..d919b90 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig @@ -106,4 +106,11 @@ config MSM_SMD_PKG3 config MSM_SMD bool +config MSM7200A_GPIO + tristate "Qualcomm MSM7200A SoC GPIO support" + depends on GPIOLIB + help + Say yes here to support GPIO functionality on Qualcomm's + MSM chipsets which descend from the MSM7200a: + MSM7x01(a), MSM7x25, MSM7x27, MSM7x30, QSD8x50(a). endif diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 66677f0..50af063 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -19,4 +19,4 @@ obj-$(CONFIG_MACH_TROUT) += board-trout.o devices-msm7x00.o obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o - +obj-$(CONFIG_MSM7200A_GPIO) += msm7200a-gpio.o diff --git a/arch/arm/mach-msm/msm7200a-gpio.c b/arch/arm/mach-msm/msm7200a-gpio.c new file mode 100644 index 0000000..d24768d --- /dev/null +++ b/arch/arm/mach-msm/msm7200a-gpio.c @@ -0,0 +1,187 @@ +/* + * Driver for Qualcomm MSM7200a and related SoC GPIO. + * Supported chipset families include: + * MSM7x01(a), MSM7x25, MSM7x27, MSM7x30, QSD8x50(a) + * + * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2010, Code Aurora Forum. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ +#include +#include +#include +#include +#include +#include +#include "msm7200a-gpio.h" + +struct msm_gpio_dev { + struct gpio_chip gpio_chip; + spinlock_t lock; + struct msm7200a_gpio_regs regs; +}; + +static inline struct msm_gpio_dev *to_msm_gpio_dev(struct gpio_chip *chip) +{ + return container_of(chip, struct msm_gpio_dev, gpio_chip); +} + +/* + * This function assumes that msm_gpio_dev::lock is held. + */ +static inline void set_gpio_bit(unsigned n, void __iomem *reg) +{ + writel(readl(reg) | BIT(n), reg); +} + +/* + * This function assumes that msm_gpio_dev::lock is held. + */ +static inline void clr_gpio_bit(unsigned n, void __iomem *reg) +{ + writel(readl(reg) & ~BIT(n), reg); +} + +/* + * This function assumes that msm_gpio_dev::lock is held. + */ +static inline void +msm_gpio_write(struct msm_gpio_dev *dev, unsigned n, unsigned on) +{ + if (on) + set_gpio_bit(n, dev->regs.out); + else + clr_gpio_bit(n, dev->regs.out); +} + +static int gpio_chip_direction_input(struct gpio_chip *chip, unsigned offset) +{ + struct msm_gpio_dev *msm_gpio = to_msm_gpio_dev(chip); + unsigned long irq_flags; + + spin_lock_irqsave(&msm_gpio->lock, irq_flags); + clr_gpio_bit(offset, msm_gpio->regs.oe); + spin_unlock_irqrestore(&msm_gpio->lock, irq_flags); + + return 0; +} + +static int +gpio_chip_direction_output(struct gpio_chip *chip, unsigned offset, int value) +{ + struct msm_gpio_dev *msm_gpio = to_msm_gpio_dev(chip); + unsigned long irq_flags; + + spin_lock_irqsave(&msm_gpio->lock, irq_flags); + msm_gpio_write(msm_gpio, offset, value); + set_gpio_bit(offset, msm_gpio->regs.oe); + spin_unlock_irqrestore(&msm_gpio->lock, irq_flags); + + return 0; +} + +static int gpio_chip_get(struct gpio_chip *chip, unsigned offset) +{ + struct msm_gpio_dev *msm_gpio = to_msm_gpio_dev(chip); + + return readl(msm_gpio->regs.in) & BIT(offset) ? 1 : 0; +} + +static void gpio_chip_set(struct gpio_chip *chip, unsigned offset, int value) +{ + struct msm_gpio_dev *msm_gpio = to_msm_gpio_dev(chip); + unsigned long irq_flags; + + spin_lock_irqsave(&msm_gpio->lock, irq_flags); + msm_gpio_write(msm_gpio, offset, value); + spin_unlock_irqrestore(&msm_gpio->lock, irq_flags); +} + +static int __devinit msm_gpio_probe(struct platform_device *dev) +{ + struct msm_gpio_dev *msm_gpio; + struct msm7200a_gpio_platform_data *pdata = dev->dev.platform_data; + int ret; + + if (!pdata) + return -EINVAL; + + msm_gpio = kzalloc(sizeof(struct msm_gpio_dev), GFP_KERNEL); + if (!msm_gpio) + return -ENOMEM; + + spin_lock_init(&msm_gpio->lock); + platform_set_drvdata(dev, msm_gpio); + + msm_gpio->regs = pdata->regs; + msm_gpio->gpio_chip.label = dev->name; + msm_gpio->gpio_chip.base = pdata->gpio_base; + msm_gpio->gpio_chip.ngpio = pdata->ngpio; + msm_gpio->gpio_chip.direction_input = gpio_chip_direction_input; + msm_gpio->gpio_chip.direction_output = gpio_chip_direction_output; + msm_gpio->gpio_chip.get = gpio_chip_get; + msm_gpio->gpio_chip.set = gpio_chip_set; + + ret = gpiochip_add(&msm_gpio->gpio_chip); + if (ret < 0) + goto err_post_malloc; + + return ret; +err_post_malloc: + platform_set_drvdata(dev, NULL); + kfree(msm_gpio); + return ret; +} + +static int __devexit msm_gpio_remove(struct platform_device *dev) +{ + struct msm_gpio_dev *msm_gpio = platform_get_drvdata(dev); + int ret = gpiochip_remove(&msm_gpio->gpio_chip); + + if (ret < 0) + return ret; + + kfree(msm_gpio); + + return 0; +} + +static struct platform_driver msm_gpio_driver = { + .probe = msm_gpio_probe, + .remove = __devexit_p(msm_gpio_remove), + .driver = { + .name = "msm7200a-gpio", + .owner = THIS_MODULE, + }, +}; + +static int __init msm_gpio_init(void) +{ + return platform_driver_register(&msm_gpio_driver); +} + +static void __exit msm_gpio_exit(void) +{ + platform_driver_unregister(&msm_gpio_driver); +} + +postcore_initcall(msm_gpio_init); +module_exit(msm_gpio_exit); + +MODULE_AUTHOR("Gregory Bean "); +MODULE_DESCRIPTION("Driver for Qualcomm MSM 7200a-family SoC GPIOs"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:msm7200a-gpio"); diff --git a/arch/arm/mach-msm/msm7200a-gpio.h b/arch/arm/mach-msm/msm7200a-gpio.h new file mode 100644 index 0000000..c44d16b --- /dev/null +++ b/arch/arm/mach-msm/msm7200a-gpio.h @@ -0,0 +1,62 @@ +/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Code Aurora Forum, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef __LINUX_MSM7200A_GPIO_H +#define __LINUX_MSM7200A_GPIO_H + +/** + * struct msm7200a_gpio_regs - addresess of iomapped GPIO registers + * @in: GPIO_IN_n + * @out: GPIO_OUT_n + * @oe: GPIO_OE_n + * + * Registers are not guaranteed to be packed in memory, or even + * located in a predictable pattern. + */ +struct msm7200a_gpio_regs { + void __iomem *in; + void __iomem *out; + void __iomem *oe; +}; + +/** + * struct msm7200a_gpio_platform_data - configuration for msm7200a-gpio + * @gpio_base: The first gpio to be assigned to the device. Corresponds + * directly to gpio_chip.base. + * @ngpio: The number of gpio lines to be managed by the device. + * Must be <= 32. Corresponds directly to gpio_chip.ngpio. + * @regs: Addresses of the registers which control the gpios + * to be managed by the device. + */ +struct msm7200a_gpio_platform_data { + unsigned gpio_base; + unsigned ngpio; + struct msm7200a_gpio_regs regs; +}; + +#endif -- 1.7.0.4 -- Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/