The spear3xx, lpc32xx, shmobile and mmp platforms are joining the game of booting using device trees, which is a great step forward for them. at91 and spear have pretty much completed this process with a huge amount of work being put into at91. The other platforms are continuing the process. We finally start to see the payback on this investment, as new machines are getting supported purely by adding a .dts source file that can be completely independent of the kernel source. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJPueqRAAoJEIwa5zzehBx3AYkP/ibDGGd0qp1gxnxPYowliXcp lrWP8KB2PVcX/041jwpvsWeHzWT+Gm39ryBfz2L3pq/RiuU0jPPwChKgy1iglE8X 6Rq6sPWkXoDRtyeCuoiaxf1AYuzzAVdzZ0HlPO93tSKgo5eeyZRC5OeebAnrLDCE SDi8gZx2mm9+j2Dz46gq8QluyswMMbke3fHHHaHUlcP9fKIvFWvEfsn5j+YQ9bSw DrSIqGOzv6Emn7F6yhFQqxmk86KLnaXDVpAWgjVDhzaPv0rcTzloN6D2Ie2e5Vev BiRM1zvWn2d9kDk7gpm0t67nguYxsCBl1GNCP1brrncGwt15S10JimYlRhYW+B7u qgJqMPko3OnONvyl6e8qgIa2M5N4K/mo1i/jfOwFw3+KfUjXqLeio53Ysr4a6tsM Ev3bEsofNJKA0dlMcVzr7ntL087B6Y8mY3oJsVZji5M0KVfx1Jfn+X1W+l/2KD1H XWhJrCGa1HlbtSnrD+E91VHGC3M4sEXbbTljMAjHImlU9dGXmmbRMNsqNwkF6qFj EO2HnFvdN1oK+zEmeAttR1JHxfMdPFnTfmpUf3AiVSjGO//Wltelqx8ibA2Smn7S xXmzqX/HMhIOYCh81FdvzsK4qRYU5QyOsEJB4G0UjBZ66M1A3T/+vPpWuKsw5bUb qbnxaaXNsaZjWbbSSrZ4 =7DYv -----END PGP SIGNATURE----- Merge tag 'dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc Pull device tree conversions for arm-soc, part 1, from Olof Johansson: "The spear3xx, lpc32xx, shmobile and mmp platforms are joining the game of booting using device trees, which is a great step forward for them. at91 and spear have pretty much completed this process with a huge amount of work being put into at91. The other platforms are continuing the process. We finally start to see the payback on this investment, as new machines are getting supported purely by adding a .dts source file that can be completely independent of the kernel source." Fix up trivial conflict in arch/arm/Kconfig * tag 'dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (83 commits) ARM: at91: Add ADC driver to at91sam9260/at91sam9g20 dtsi files arm/dts: omap4-panda: Add LEDs support arm/dts: omap4-sdp: Add LEDs support arm/dts: twl4030: Add twl4030-gpio node OMAP4: devices: Do not create mcpdm device if the dtb has been provided OMAP4: devices: Do not create dmic device if the dtb has been provided Documentation: update docs for mmp dt ARM: dts: refresh dts file for arch mmp ARM: mmp: support pxa910 with device tree ARM: mmp: support mmp2 with device tree gpio: pxa: parse gpio from DTS file ARM: mmp: support DT in timer ARM: mmp: support DT in irq ARM: mmp: append CONFIG_MACH_MMP2_DT ARM: mmp: fix build issue on mmp with device tree ARM: ux500: Enable PRCMU Timer 4 (clocksource) for Device Tree ARM: ux500: Disable SMSC911x platform code registration when DT is enabled ARM: ux500: Fork cpu-db8500 platform_devs for sequential DT enablement ARM: ux500: Do not attempt to register non-existent i2c devices on Snowball ARM: SPEAr3xx: Correct keyboard data passed from DT ...
157 lines
5.1 KiB
C
157 lines
5.1 KiB
C
/*
|
|
* OMAP2+ specific gpio initialization
|
|
*
|
|
* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
|
|
*
|
|
* Author:
|
|
* Charulatha V <charu@ti.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation version 2.
|
|
*
|
|
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
|
|
* kind, whether express or implied; without even the implied warranty
|
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#include <linux/gpio.h>
|
|
#include <linux/err.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/of.h>
|
|
|
|
#include <plat/omap_hwmod.h>
|
|
#include <plat/omap_device.h>
|
|
#include <plat/omap-pm.h>
|
|
|
|
#include "powerdomain.h"
|
|
|
|
static int __init omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
|
|
{
|
|
struct platform_device *pdev;
|
|
struct omap_gpio_platform_data *pdata;
|
|
struct omap_gpio_dev_attr *dev_attr;
|
|
char *name = "omap_gpio";
|
|
int id;
|
|
struct powerdomain *pwrdm;
|
|
|
|
/*
|
|
* extract the device id from name field available in the
|
|
* hwmod database and use the same for constructing ids for
|
|
* gpio devices.
|
|
* CAUTION: Make sure the name in the hwmod database does
|
|
* not change. If changed, make corresponding change here
|
|
* or make use of static variable mechanism to handle this.
|
|
*/
|
|
sscanf(oh->name, "gpio%d", &id);
|
|
|
|
pdata = kzalloc(sizeof(struct omap_gpio_platform_data), GFP_KERNEL);
|
|
if (!pdata) {
|
|
pr_err("gpio%d: Memory allocation failed\n", id);
|
|
return -ENOMEM;
|
|
}
|
|
|
|
dev_attr = (struct omap_gpio_dev_attr *)oh->dev_attr;
|
|
pdata->bank_width = dev_attr->bank_width;
|
|
pdata->dbck_flag = dev_attr->dbck_flag;
|
|
pdata->virtual_irq_start = IH_GPIO_BASE + 32 * (id - 1);
|
|
pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
|
|
pdata->regs = kzalloc(sizeof(struct omap_gpio_reg_offs), GFP_KERNEL);
|
|
if (!pdata->regs) {
|
|
pr_err("gpio%d: Memory allocation failed\n", id);
|
|
return -ENOMEM;
|
|
}
|
|
|
|
switch (oh->class->rev) {
|
|
case 0:
|
|
if (id == 1)
|
|
/* non-wakeup GPIO pins for OMAP2 Bank1 */
|
|
pdata->non_wakeup_gpios = 0xe203ffc0;
|
|
else if (id == 2)
|
|
/* non-wakeup GPIO pins for OMAP2 Bank2 */
|
|
pdata->non_wakeup_gpios = 0x08700040;
|
|
/* fall through */
|
|
|
|
case 1:
|
|
pdata->regs->revision = OMAP24XX_GPIO_REVISION;
|
|
pdata->regs->direction = OMAP24XX_GPIO_OE;
|
|
pdata->regs->datain = OMAP24XX_GPIO_DATAIN;
|
|
pdata->regs->dataout = OMAP24XX_GPIO_DATAOUT;
|
|
pdata->regs->set_dataout = OMAP24XX_GPIO_SETDATAOUT;
|
|
pdata->regs->clr_dataout = OMAP24XX_GPIO_CLEARDATAOUT;
|
|
pdata->regs->irqstatus = OMAP24XX_GPIO_IRQSTATUS1;
|
|
pdata->regs->irqstatus2 = OMAP24XX_GPIO_IRQSTATUS2;
|
|
pdata->regs->irqenable = OMAP24XX_GPIO_IRQENABLE1;
|
|
pdata->regs->irqenable2 = OMAP24XX_GPIO_IRQENABLE2;
|
|
pdata->regs->set_irqenable = OMAP24XX_GPIO_SETIRQENABLE1;
|
|
pdata->regs->clr_irqenable = OMAP24XX_GPIO_CLEARIRQENABLE1;
|
|
pdata->regs->debounce = OMAP24XX_GPIO_DEBOUNCE_VAL;
|
|
pdata->regs->debounce_en = OMAP24XX_GPIO_DEBOUNCE_EN;
|
|
pdata->regs->ctrl = OMAP24XX_GPIO_CTRL;
|
|
pdata->regs->wkup_en = OMAP24XX_GPIO_WAKE_EN;
|
|
pdata->regs->leveldetect0 = OMAP24XX_GPIO_LEVELDETECT0;
|
|
pdata->regs->leveldetect1 = OMAP24XX_GPIO_LEVELDETECT1;
|
|
pdata->regs->risingdetect = OMAP24XX_GPIO_RISINGDETECT;
|
|
pdata->regs->fallingdetect = OMAP24XX_GPIO_FALLINGDETECT;
|
|
break;
|
|
case 2:
|
|
pdata->regs->revision = OMAP4_GPIO_REVISION;
|
|
pdata->regs->direction = OMAP4_GPIO_OE;
|
|
pdata->regs->datain = OMAP4_GPIO_DATAIN;
|
|
pdata->regs->dataout = OMAP4_GPIO_DATAOUT;
|
|
pdata->regs->set_dataout = OMAP4_GPIO_SETDATAOUT;
|
|
pdata->regs->clr_dataout = OMAP4_GPIO_CLEARDATAOUT;
|
|
pdata->regs->irqstatus = OMAP4_GPIO_IRQSTATUS0;
|
|
pdata->regs->irqstatus2 = OMAP4_GPIO_IRQSTATUS1;
|
|
pdata->regs->irqenable = OMAP4_GPIO_IRQSTATUSSET0;
|
|
pdata->regs->irqenable2 = OMAP4_GPIO_IRQSTATUSSET1;
|
|
pdata->regs->set_irqenable = OMAP4_GPIO_IRQSTATUSSET0;
|
|
pdata->regs->clr_irqenable = OMAP4_GPIO_IRQSTATUSCLR0;
|
|
pdata->regs->debounce = OMAP4_GPIO_DEBOUNCINGTIME;
|
|
pdata->regs->debounce_en = OMAP4_GPIO_DEBOUNCENABLE;
|
|
pdata->regs->ctrl = OMAP4_GPIO_CTRL;
|
|
pdata->regs->wkup_en = OMAP4_GPIO_IRQWAKEN0;
|
|
pdata->regs->leveldetect0 = OMAP4_GPIO_LEVELDETECT0;
|
|
pdata->regs->leveldetect1 = OMAP4_GPIO_LEVELDETECT1;
|
|
pdata->regs->risingdetect = OMAP4_GPIO_RISINGDETECT;
|
|
pdata->regs->fallingdetect = OMAP4_GPIO_FALLINGDETECT;
|
|
break;
|
|
default:
|
|
WARN(1, "Invalid gpio bank_type\n");
|
|
kfree(pdata);
|
|
return -EINVAL;
|
|
}
|
|
|
|
pwrdm = omap_hwmod_get_pwrdm(oh);
|
|
pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm);
|
|
|
|
pdev = omap_device_build(name, id - 1, oh, pdata,
|
|
sizeof(*pdata), NULL, 0, false);
|
|
kfree(pdata);
|
|
|
|
if (IS_ERR(pdev)) {
|
|
WARN(1, "Can't build omap_device for %s:%s.\n",
|
|
name, oh->name);
|
|
return PTR_ERR(pdev);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* gpio_init needs to be done before
|
|
* machine_init functions access gpio APIs.
|
|
* Hence gpio_init is a postcore_initcall.
|
|
*/
|
|
static int __init omap2_gpio_init(void)
|
|
{
|
|
/* If dtb is there, the devices will be created dynamically */
|
|
if (of_have_populated_dt())
|
|
return -ENODEV;
|
|
|
|
return omap_hwmod_for_each_by_class("gpio", omap2_gpio_dev_init, NULL);
|
|
}
|
|
postcore_initcall(omap2_gpio_init);
|