9
0
Fork 0

Merge branch 'for-next/davinci'

This commit is contained in:
Sascha Hauer 2014-04-04 10:06:14 +02:00
commit 712b555f6c
25 changed files with 824 additions and 0 deletions

View File

@ -43,6 +43,7 @@ ARM type:
@li @subpage tny-a9263
@li @subpage usb-a9g20-lpw
@li @subpage usb-a9263
@li @subpage virt2real
Blackfin type:

View File

@ -54,6 +54,12 @@ config ARCH_CLPS711X
select GPIOLIB
select MFD_SYSCON
config ARCH_DAVINCI
bool "TI Davinci"
select CPU_ARM926T
select HAS_DEBUG_LL
select GPIOLIB
config ARCH_EP93XX
bool "Cirrus Logic EP93xx"
select CPU_ARM920T
@ -188,6 +194,7 @@ source arch/arm/cpu/Kconfig
source arch/arm/mach-at91/Kconfig
source arch/arm/mach-bcm2835/Kconfig
source arch/arm/mach-clps711x/Kconfig
source arch/arm/mach-davinci/Kconfig
source arch/arm/mach-ep93xx/Kconfig
source arch/arm/mach-highbank/Kconfig
source arch/arm/mach-imx/Kconfig

View File

@ -54,6 +54,7 @@ AFLAGS += -include asm/unified.h -msoft-float $(AFLAGS_THUMB2)
machine-$(CONFIG_ARCH_AT91) := at91
machine-$(CONFIG_ARCH_BCM2835) := bcm2835
machine-$(CONFIG_ARCH_CLPS711X) := clps711x
machine-$(CONFIG_ARCH_DAVINCI) := davinci
machine-$(CONFIG_ARCH_EP93XX) := ep93xx
machine-$(CONFIG_ARCH_HIGHBANK) := highbank
machine-$(CONFIG_ARCH_IMX) := imx

View File

@ -99,5 +99,6 @@ obj-$(CONFIG_MACH_USB_A9263) += usb-a926x/
obj-$(CONFIG_MACH_USB_A9G20) += usb-a926x/
obj-$(CONFIG_MACH_VERSATILEPB) += versatile/
obj-$(CONFIG_MACH_VEXPRESS) += vexpress/
obj-$(CONFIG_MACH_VIRT2REAL) += virt2real/
obj-$(CONFIG_MACH_ZEDBOARD) += avnet-zedboard/
obj-$(CONFIG_MACH_VARISCITE_MX6) += variscite-mx6/

View File

@ -0,0 +1 @@
obj-y += lowlevel.o board.o

View File

@ -0,0 +1,27 @@
/*
* Copyright (C) 2014 Antony Pavlov <antonynpavlov@gmail.com>
*
* This file is part of barebox.
* See file CREDITS for list of people who contributed to this project.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License 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.
*
*/
#include <common.h>
#include <init.h>
static int hostname_init(void)
{
barebox_set_hostname("virt2real");
return 0;
}
core_initcall(hostname_init);

View File

@ -0,0 +1,34 @@
/*
* Copyright (C) 2014 Antony Pavlov <antonynpavlov@gmail.com>
*
* This file is part of barebox.
* See file CREDITS for list of people who contributed to this project.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License 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.
*
*/
#define __LOWLEVEL_INIT__
#include <common.h>
#include <asm/barebox-arm.h>
#include <asm/barebox-arm-head.h>
#include <init.h>
#include <sizes.h>
#define VIRT2REAL_SRAM_BASE 0x82000000
#define VIRT2REAL_SRAM_SIZE SZ_16M
void __naked __bare_init barebox_arm_reset_vector(void)
{
arm_cpu_lowlevel_init();
barebox_arm_entry(VIRT2REAL_SRAM_BASE, VIRT2REAL_SRAM_SIZE, 0);
}

View File

@ -0,0 +1,41 @@
/** @page virt2real virt2real board
virt2real is a is a miniature board for creation of WiFi
or internet controllable smart devices.
The board has
@li TI DaVinchi DM365 running at 300 MHz
@li 128 MiB DDR2 SDRAM;
@li 256 MiB NAND Flash Memory;
@li 2 x UART serial interfaces;
@li 2 x Ethernet interfaces;
@li 1 x USB interface;
@li microSD card slot.
The board uses U-Boot as bootloader.
Barebox mini-howto:
1. Connect to the boards's UART0 (115200 8N1);
Use J2.2 (GND), J2.4 (UART0_TXD), J2.6(UART0_RXD) pins.
2. Turn board's power on;
3. Wait 'Hit any key to stop autoboot' prompt and press the space key.
4. Upload barebox.bin via Ymodem
@verbatim
virt2real ># loady
@endverbatim
5. Run barebox
@verbatim
virt2real ># go 0x82000000
@endverbatim
virt2real links:
@li http://virt2real.com/
@li http://wiki.virt2real.ru/
@li https://github.com/virt2real
*/

View File

@ -0,0 +1,49 @@
CONFIG_BUILTIN_DTB=y
CONFIG_BUILTIN_DTB_NAME="virt2real"
CONFIG_ARCH_DAVINCI=y
CONFIG_AEABI=y
CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
CONFIG_TEXT_BASE=0x82300000
CONFIG_MALLOC_SIZE=0x200000
CONFIG_MALLOC_TLSF=y
CONFIG_PROMPT="virt2real: "
CONFIG_LONGHELP=y
CONFIG_GLOB=y
CONFIG_HUSH_FANCY_PROMPT=y
CONFIG_CMDLINE_EDITING=y
CONFIG_AUTO_COMPLETE=y
CONFIG_MENU=y
CONFIG_PASSWORD=y
CONFIG_PARTITION=y
CONFIG_CMD_EDIT=y
CONFIG_CMD_SLEEP=y
CONFIG_CMD_EXPORT=y
CONFIG_CMD_PRINTENV=y
CONFIG_CMD_READLINE=y
CONFIG_CMD_ECHO_E=y
CONFIG_CMD_LOADB=y
CONFIG_CMD_LOADY=y
CONFIG_CMD_MEMINFO=y
CONFIG_CMD_IOMEM=y
CONFIG_CMD_MM=y
# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTU is not set
CONFIG_CMD_RESET=y
CONFIG_CMD_GO=y
CONFIG_CMD_OFTREE=y
CONFIG_CMD_OF_PROPERTY=y
CONFIG_CMD_OF_NODE=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_UNCOMPRESS=y
CONFIG_CMD_LED=y
CONFIG_OFDEVICE=y
CONFIG_OF_BAREBOX_DRIVERS=y
CONFIG_DRIVER_SERIAL_NS16550=y
# CONFIG_SPI is not set
CONFIG_LED=y
CONFIG_LED_GPIO=y
CONFIG_LED_GPIO_OF=y
CONFIG_SHA1=y
CONFIG_SHA256=y

28
arch/arm/dts/dm365.dtsi Normal file
View File

@ -0,0 +1,28 @@
#include "skeleton.dtsi"
/ {
soc {
compatible = "simple-bus";
model = "TI TMS320DM365";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0x01c00000 0x400000>;
serial0: serial@1c20000 {
compatible = "ns16550a";
reg = <0x20000 0x400>;
reg-shift = <2>;
clock-frequency = <24000000>;
status = "disabled";
};
gpio: gpio@1c67000 {
compatible = "ti,dm6441-gpio";
gpio-controller;
reg = <0x67000 0x800>;
#gpio-cells = <2>;
ti,ngpio = <107>;
status = "disabled";
};
};
};

View File

@ -0,0 +1,35 @@
/dts-v1/;
#include "dm365.dtsi"
/ {
model = "virt2real";
memory {
reg = <0x82000000 0x01000000>;
};
soc {
serial0: serial@1c20000 {
status = "okay";
};
gpio: gpio@1c67000 {
status = "okay";
};
};
leds {
compatible = "gpio-leds";
green_led {
label = "green-led";
gpios = <&gpio 73 0>;
};
red_led {
label = "red-led";
gpios = <&gpio 74 0>;
};
};
};

View File

@ -3,6 +3,13 @@
#include <memory.h>
#include <linux/const.h>
/*
* Allow for constants defined here to be used from assembly code
* by prepending the UL suffix only with actual C code compilation.
*/
#define UL(x) _AC(x, UL)
static inline void arm_add_mem_device(const char* name, resource_size_t start,
resource_size_t size)
{

View File

@ -54,6 +54,8 @@ For details on specific architectures:
@subsection mach_arm_omap_info OMAP CPUs
@li @subpage dev_davinci_arch
@li @subpage dev_omap_arch
@subsection mach_arm_s3c24xx_info S3C24XX CPUs

View File

@ -0,0 +1,16 @@
if ARCH_DAVINCI
config ARCH_TEXT_BASE
hex
default 0x82000000
choice
prompt "Davinci Board type"
config MACH_VIRT2REAL
bool "Virt2Real"
select HAVE_DEFAULT_ENVIRONMENT_NEW
endchoice
endif

View File

@ -0,0 +1 @@
obj-y += time.o

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2014 Antony Pavlov <antonynpavlov@gmail.com>
*
* This file is part of barebox.
* See file CREDITS for list of people who contributed to this project.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License 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.
*
*/
/** @file
* This File contains declaration for early output support
*/
#ifndef __INCLUDE_ARCH_DEBUG_LL_H__
#define __INCLUDE_ARCH_DEBUG_LL_H__
#include <asm/io.h>
#include <mach/serial.h>
#define DEBUG_LL_UART_ADDR DAVINCI_UART0_BASE
#define DEBUG_LL_UART_RSHFT 2
#define rbr (0 << DEBUG_LL_UART_RSHFT)
#define lsr (5 << DEBUG_LL_UART_RSHFT)
#define LSR_THRE 0x20 /* Xmit holding register empty */
static inline void PUTC_LL(char ch)
{
while (!(__raw_readb(DEBUG_LL_UART_ADDR + lsr) & LSR_THRE))
;
__raw_writeb(ch, DEBUG_LL_UART_ADDR + rbr);
}
#endif /* __INCLUDE_ARCH_DEBUG_LL_H__ */

View File

@ -0,0 +1,29 @@
/*
* Hardware definitions common to all DaVinci family processors
*
* Author: Kevin Hilman, Deep Root Systems, LLC
*
* 2007 (c) Deep Root Systems, LLC. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#ifndef __ASM_ARCH_HARDWARE_H
#define __ASM_ARCH_HARDWARE_H
#include <asm/memory.h>
/*
* Before you add anything to this file:
*
* This header is for defines common to ALL DaVinci family chips.
* Anything that is chip specific should go in <chipname>.h,
* and the chip/board init code should then explicitly include
* <chipname>.h
*/
/*
* I/O mapping
*/
#define IO_PHYS UL(0x01c00000)
#endif /* __ASM_ARCH_HARDWARE_H */

View File

@ -0,0 +1,20 @@
/*
* DaVinci serial device definitions
*
* Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
*
* 2007 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#ifndef __ASM_ARCH_SERIAL_H
#define __ASM_ARCH_SERIAL_H
#include <mach/hardware.h>
#define DAVINCI_UART0_BASE (IO_PHYS + 0x20000)
#define DAVINCI_UART1_BASE (IO_PHYS + 0x20400)
#define DAVINCI_UART2_BASE (IO_PHYS + 0x20800)
#endif /* __ASM_ARCH_SERIAL_H */

View File

@ -0,0 +1,20 @@
/*
* Local header file for DaVinci time code.
*
* Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
*
* 2007 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#ifndef __ARCH_ARM_MACH_DAVINCI_TIME_H
#define __ARCH_ARM_MACH_DAVINCI_TIME_H
#include <mach/hardware.h>
#define DAVINCI_TIMER0_BASE (IO_PHYS + 0x21400)
#define DAVINCI_TIMER1_BASE (IO_PHYS + 0x21800)
#define DAVINCI_WDOG_BASE (IO_PHYS + 0x21C00)
#endif /* __ARCH_ARM_MACH_DAVINCI_TIME_H */

View File

@ -0,0 +1,7 @@
/** @page dev_davinci_arch TI DaVinci in barebox
@section davinci_boards DaVinci-based boards
@li @subpage virt2real
*/

View File

@ -0,0 +1,209 @@
/*
* DaVinci timer subsystem
*
* Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
*
* 2007 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <common.h>
#include <io.h>
#include <init.h>
#include <clock.h>
#include <mach/time.h>
/* Timer register offsets */
#define PID12 0x0
#define TIM12 0x10
#define TIM34 0x14
#define PRD12 0x18
#define PRD34 0x1c
#define TCR 0x20
#define TGCR 0x24
#define WDTCR 0x28
/* Timer register bitfields */
#define TCR_ENAMODE_DISABLE 0x0
#define TCR_ENAMODE_ONESHOT 0x1
#define TCR_ENAMODE_PERIODIC 0x2
#define TCR_ENAMODE_MASK 0x3
#define TGCR_TIMMODE_SHIFT 2
#define TGCR_TIMMODE_64BIT_GP 0x0
#define TGCR_TIMMODE_32BIT_UNCHAINED 0x1
#define TGCR_TIMMODE_64BIT_WDOG 0x2
#define TGCR_TIMMODE_32BIT_CHAINED 0x3
#define TGCR_TIM12RS_SHIFT 0
#define TGCR_TIM34RS_SHIFT 1
#define TGCR_RESET 0x0
#define TGCR_UNRESET 0x1
#define TGCR_RESET_MASK 0x3
#define WDTCR_WDEN_SHIFT 14
#define WDTCR_WDEN_DISABLE 0x0
#define WDTCR_WDEN_ENABLE 0x1
#define WDTCR_WDKEY_SHIFT 16
#define WDTCR_WDKEY_SEQ0 0xa5c6
#define WDTCR_WDKEY_SEQ1 0xda7e
#define DAVINCI_TIMER_CLOCK 24000000
struct timer_s {
void __iomem *base;
unsigned long tim_off;
unsigned long prd_off;
unsigned long enamode_shift;
};
static struct timer_s timers[] = {
{
.base = IOMEM(DAVINCI_TIMER0_BASE),
.enamode_shift = 6,
.tim_off = TIM12,
.prd_off = PRD12,
},
{
.base = IOMEM(DAVINCI_TIMER0_BASE),
.enamode_shift = 22,
.tim_off = TIM34,
.prd_off = PRD34,
},
{
.base = IOMEM(DAVINCI_TIMER1_BASE),
.enamode_shift = 6,
.tim_off = TIM12,
.prd_off = PRD12,
},
{
.base = IOMEM(DAVINCI_TIMER1_BASE),
.enamode_shift = 22,
.tim_off = TIM34,
.prd_off = PRD34,
},
};
static struct timer_s *t = &timers[0];
static uint64_t davinci_cs_read(void)
{
return (uint64_t)__raw_readl(t->base + t->tim_off);
}
static struct clocksource davinci_cs = {
.read = davinci_cs_read,
.mask = CLOCKSOURCE_MASK(32),
};
static int timer32_config(struct timer_s *t)
{
u32 tcr;
tcr = __raw_readl(t->base + TCR);
/* disable timer */
tcr &= ~(TCR_ENAMODE_MASK << t->enamode_shift);
__raw_writel(tcr, t->base + TCR);
/* reset counter to zero, set new period */
__raw_writel(0, t->base + t->tim_off);
__raw_writel(0xffffffff, t->base + t->prd_off);
/* Set enable mode for periodic timer */
tcr |= TCR_ENAMODE_PERIODIC << t->enamode_shift;
__raw_writel(tcr, t->base + TCR);
return 0;
}
/* Global init of 64-bit timer as a whole */
static void __init timer_init(void __iomem *base)
{
u32 tgcr;
/* Disabled, Internal clock source */
__raw_writel(0, base + TCR);
/* reset both timers, no pre-scaler for timer34 */
tgcr = 0;
__raw_writel(tgcr, base + TGCR);
/* Set both timers to unchained 32-bit */
tgcr = TGCR_TIMMODE_32BIT_UNCHAINED << TGCR_TIMMODE_SHIFT;
__raw_writel(tgcr, base + TGCR);
/* Unreset timers */
tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) |
(TGCR_UNRESET << TGCR_TIM34RS_SHIFT);
__raw_writel(tgcr, base + TGCR);
/* Init both counters to zero */
__raw_writel(0, base + TIM12);
__raw_writel(0, base + TIM34);
}
static int clocksource_init(void)
{
clocks_calc_mult_shift(&davinci_cs.mult, &davinci_cs.shift,
DAVINCI_TIMER_CLOCK, NSEC_PER_SEC, 10);
init_clock(&davinci_cs);
timer_init(IOMEM(DAVINCI_TIMER0_BASE));
timer_init(IOMEM(DAVINCI_TIMER1_BASE));
timer32_config(t);
return 0;
}
core_initcall(clocksource_init);
/* reset board using watchdog timer */
void __noreturn reset_cpu(ulong addr)
{
u32 tgcr, wdtcr;
void __iomem *base;
base = IOMEM(DAVINCI_WDOG_BASE);
/* disable, internal clock source */
__raw_writel(0, base + TCR);
/* reset timer, set mode to 64-bit watchdog, and unreset */
tgcr = 0;
__raw_writel(tgcr, base + TGCR);
tgcr = TGCR_TIMMODE_64BIT_WDOG << TGCR_TIMMODE_SHIFT;
tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) |
(TGCR_UNRESET << TGCR_TIM34RS_SHIFT);
__raw_writel(tgcr, base + TGCR);
/* clear counter and period regs */
__raw_writel(0, base + TIM12);
__raw_writel(0, base + TIM34);
__raw_writel(0, base + PRD12);
__raw_writel(0, base + PRD34);
/* put watchdog in pre-active state */
wdtcr = __raw_readl(base + WDTCR);
wdtcr = (WDTCR_WDKEY_SEQ0 << WDTCR_WDKEY_SHIFT) |
(WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT);
__raw_writel(wdtcr, base + WDTCR);
/* put watchdog in active state */
wdtcr = (WDTCR_WDKEY_SEQ1 << WDTCR_WDKEY_SHIFT) |
(WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT);
__raw_writel(wdtcr, base + WDTCR);
/* write an invalid value to the WDKEY field to trigger
* a watchdog reset */
wdtcr = 0x00004000;
__raw_writel(wdtcr, base + WDTCR);
unreachable();
}
EXPORT_SYMBOL(reset_cpu);

View File

@ -20,6 +20,13 @@ config GPIO_CLPS711X
help
Say yes here to enable the GPIO driver for the CLPS711X CPUs
config GPIO_DAVINCI
bool "TI Davinci/Keystone GPIO support"
default y if ARCH_DAVINCI
depends on ARM && ARCH_DAVINCI
help
Say yes here to enable GPIO support for TI Davinci/Keystone SoCs.
config GPIO_GENERIC_PLATFORM
bool "Generic memory-mapped GPIO controller support"
select GPIO_GENERIC

View File

@ -1,6 +1,7 @@
obj-$(CONFIG_GPIOLIB) += gpiolib.o
obj-$(CONFIG_GPIO_BCM2835) += gpio-bcm2835.o
obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o
obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o
obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
obj-$(CONFIG_GPIO_IMX) += gpio-imx.o

211
drivers/gpio/gpio-davinci.c Normal file
View File

@ -0,0 +1,211 @@
/*
* TI DaVinci GPIO Support
*
* Copyright (c) 2006-2007 David Brownell
* Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com>
* Copyright (c) 2014 Antony Pavlov <antonynpavlov@gmail.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; either version 2 of the License, or
* (at your option) any later version.
*/
#include <common.h>
#include <gpio.h>
#include <init.h>
#include <io.h>
#include <linux/err.h>
#define readl_relaxed readl
#define writel_relaxed writel
struct davinci_gpio_regs {
u32 dir;
u32 out_data;
u32 set_data;
u32 clr_data;
u32 in_data;
u32 set_rising;
u32 clr_rising;
u32 set_falling;
u32 clr_falling;
u32 intstat;
};
struct davinci_gpio_controller {
struct gpio_chip chip;
/* Serialize access to GPIO registers */
void __iomem *regs;
void __iomem *set_data;
void __iomem *clr_data;
void __iomem *in_data;
};
#define chip2controller(chip) \
container_of(chip, struct davinci_gpio_controller, chip)
static struct davinci_gpio_regs __iomem *gpio2regs(void __iomem *gpio_base,
unsigned gpio)
{
void __iomem *ptr;
if (gpio < 32 * 1)
ptr = gpio_base + 0x10;
else if (gpio < 32 * 2)
ptr = gpio_base + 0x38;
else if (gpio < 32 * 3)
ptr = gpio_base + 0x60;
else if (gpio < 32 * 4)
ptr = gpio_base + 0x88;
else if (gpio < 32 * 5)
ptr = gpio_base + 0xb0;
else
ptr = NULL;
return ptr;
}
static int davinci_get_direction(struct gpio_chip *chip, unsigned offset)
{
struct davinci_gpio_controller *d = chip2controller(chip);
struct davinci_gpio_regs __iomem *g = d->regs;
return ((readl_relaxed(&g->dir)) & (1 << offset)) ?
GPIOF_DIR_IN : GPIOF_DIR_OUT;
}
static inline int __davinci_direction(struct gpio_chip *chip,
unsigned offset, bool out, int value)
{
struct davinci_gpio_controller *d = chip2controller(chip);
struct davinci_gpio_regs __iomem *g = d->regs;
u32 temp;
u32 mask = 1 << offset;
temp = readl_relaxed(&g->dir);
if (out) {
temp &= ~mask;
writel_relaxed(mask, value ? &g->set_data : &g->clr_data);
} else {
temp |= mask;
}
writel_relaxed(temp, &g->dir);
return 0;
}
static int davinci_direction_in(struct gpio_chip *chip, unsigned offset)
{
return __davinci_direction(chip, offset, false, 0);
}
static int
davinci_direction_out(struct gpio_chip *chip, unsigned offset, int value)
{
return __davinci_direction(chip, offset, true, value);
}
/*
* Read the pin's value (works even if it's set up as output);
* returns zero/nonzero.
*
* Note that changes are synched to the GPIO clock, so reading values back
* right after you've set them may give old values.
*/
static int davinci_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct davinci_gpio_controller *d = chip2controller(chip);
struct davinci_gpio_regs __iomem *g = d->regs;
return (1 << offset) & readl_relaxed(&g->in_data);
}
/*
* Assuming the pin is muxed as a gpio output, set its output value.
*/
static void
davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct davinci_gpio_controller *d = chip2controller(chip);
struct davinci_gpio_regs __iomem *g = d->regs;
writel_relaxed((1 << offset), value ? &g->set_data : &g->clr_data);
}
static struct gpio_ops davinci_gpio_ops = {
.direction_input = davinci_direction_in,
.direction_output = davinci_direction_out,
.get_direction = davinci_get_direction,
.get = davinci_gpio_get,
.set = davinci_gpio_set,
};
static int davinci_gpio_probe(struct device_d *dev)
{
void __iomem *gpio_base;
int ret;
u32 val;
int i, base;
unsigned ngpio;
struct davinci_gpio_controller *chips;
ret = of_property_read_u32(dev->device_node, "ti,ngpio", &val);
if (ret) {
dev_err(dev, "could not read 'ti,ngpio' property\n");
return -EINVAL;
}
ngpio = val;
if (WARN_ON(ARCH_NR_GPIOS < ngpio))
ngpio = ARCH_NR_GPIOS;
chips = xzalloc((ngpio / 32 + 1) * sizeof(*chips));
gpio_base = dev_request_mem_region(dev, 0);
if (!gpio_base) {
dev_err(dev, "could not get memory region\n");
return -ENODEV;
}
for (i = 0, base = 0; base < ngpio; i++, base += 32) {
struct davinci_gpio_regs __iomem *regs;
struct gpio_chip *gc;
gc = &chips[i].chip;
gc->ops = &davinci_gpio_ops;
gc->dev = dev;
gc->base = base;
gc->ngpio = ngpio - base;
if (gc->ngpio > 32)
gc->ngpio = 32;
regs = gpio2regs(gpio_base, base);
chips[i].regs = regs;
chips[i].set_data = &regs->set_data;
chips[i].clr_data = &regs->clr_data;
chips[i].in_data = &regs->in_data;
gpiochip_add(gc);
}
return 0;
}
static struct of_device_id davinci_gpio_ids[] = {
{ .compatible = "ti,dm6441-gpio", },
{ /* sentinel */ },
};
static struct driver_d davinci_gpio_driver = {
.name = "davinci_gpio",
.probe = davinci_gpio_probe,
.of_compatible = DRV_OF_COMPAT(davinci_gpio_ids),
};
static int davinci_gpio_drv_reg(void)
{
return platform_driver_register(&davinci_gpio_driver);
}
coredevice_initcall(davinci_gpio_drv_reg);

27
include/linux/const.h Normal file
View File

@ -0,0 +1,27 @@
/* const.h: Macros for dealing with constants. */
#ifndef _LINUX_CONST_H
#define _LINUX_CONST_H
/* Some constant macros are used in both assembler and
* C code. Therefore we cannot annotate them always with
* 'UL' and other type specifiers unilaterally. We
* use the following macros to deal with this.
*
* Similarly, _AT() will cast an expression with a type in C, but
* leave it unchanged in asm.
*/
#ifdef __ASSEMBLY__
#define _AC(X,Y) X
#define _AT(T,X) X
#else
#define __AC(X,Y) (X##Y)
#define _AC(X,Y) __AC(X,Y)
#define _AT(T,X) ((T)(X))
#endif
#define _BITUL(x) (_AC(1,UL) << (x))
#define _BITULL(x) (_AC(1,ULL) << (x))
#endif /* !(_LINUX_CONST_H) */