Skip to content

Commit

Permalink
[ARM] mv78xx0: implement GPIO and GPIO interrupt support
Browse files Browse the repository at this point in the history
Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
Signed-off-by: Nicolas Pitre <nico@marvell.com>
  • Loading branch information
Lennert Buytenhek authored and Nicolas Pitre committed Dec 20, 2008
1 parent 4c21343 commit b95a13d
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 6 deletions.
1 change: 1 addition & 0 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,7 @@ config ARCH_MV78XX0
bool "Marvell MV78xx0"
select CPU_FEROCEON
select PCI
select GENERIC_GPIO
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select PLAT_ORION
Expand Down
40 changes: 40 additions & 0 deletions arch/arm/mach-mv78xx0/include/mach/gpio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* arch/asm-arm/mach-mv78xx0/include/mach/gpio.h
*
* 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_GPIO_H
#define __ASM_ARCH_GPIO_H

#include <mach/irqs.h>
#include <plat/gpio.h>
#include <asm-generic/gpio.h> /* cansleep wrappers */

extern int mv78xx0_core_index(void);

#define GPIO_MAX 32
#define GPIO_OUT(pin) (DEV_BUS_VIRT_BASE + 0x0100)
#define GPIO_IO_CONF(pin) (DEV_BUS_VIRT_BASE + 0x0104)
#define GPIO_BLINK_EN(pin) (DEV_BUS_VIRT_BASE + 0x0108)
#define GPIO_IN_POL(pin) (DEV_BUS_VIRT_BASE + 0x010c)
#define GPIO_DATA_IN(pin) (DEV_BUS_VIRT_BASE + 0x0110)
#define GPIO_EDGE_CAUSE(pin) (DEV_BUS_VIRT_BASE + 0x0114)
#define GPIO_MASK_OFF (mv78xx0_core_index() ? 0x18 : 0)
#define GPIO_EDGE_MASK(pin) (DEV_BUS_VIRT_BASE + 0x0118 + GPIO_MASK_OFF)
#define GPIO_LEVEL_MASK(pin) (DEV_BUS_VIRT_BASE + 0x011c + GPIO_MASK_OFF)

static inline int gpio_to_irq(int pin)
{
return pin + IRQ_MV78XX0_GPIO_START;
}

static inline int irq_to_gpio(int irq)
{
return irq - IRQ_MV78XX0_GPIO_START;
}


#endif
4 changes: 1 addition & 3 deletions arch/arm/mach-mv78xx0/include/mach/irqs.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
#ifndef __ASM_ARCH_IRQS_H
#define __ASM_ARCH_IRQS_H

#include "mv78xx0.h" /* need GPIO_MAX */

/*
* MV78xx0 Low Interrupt Controller
*/
Expand Down Expand Up @@ -88,7 +86,7 @@
* MV78XX0 General Purpose Pins
*/
#define IRQ_MV78XX0_GPIO_START 96
#define NR_GPIO_IRQS GPIO_MAX
#define NR_GPIO_IRQS 32

#define NR_IRQS (IRQ_MV78XX0_GPIO_START + NR_GPIO_IRQS)

Expand Down
3 changes: 0 additions & 3 deletions arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,4 @@
#define SATA_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0xa0000)


#define GPIO_MAX 32


#endif
29 changes: 29 additions & 0 deletions arch/arm/mach-mv78xx0/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,42 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/irq.h>
#include <asm/gpio.h>
#include <mach/mv78xx0.h>
#include <plat/irq.h>
#include "common.h"

static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
{
BUG_ON(irq < IRQ_MV78XX0_GPIO_0_7 || irq > IRQ_MV78XX0_GPIO_24_31);

orion_gpio_irq_handler((irq - IRQ_MV78XX0_GPIO_0_7) << 3);
}

void __init mv78xx0_init_irq(void)
{
int i;

orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF));
orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF));
orion_irq_init(64, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_ERR_OFF));

/*
* Mask and clear GPIO IRQ interrupts.
*/
writel(0, GPIO_LEVEL_MASK(0));
writel(0, GPIO_EDGE_MASK(0));
writel(0, GPIO_EDGE_CAUSE(0));

for (i = IRQ_MV78XX0_GPIO_START; i < NR_IRQS; i++) {
set_irq_chip(i, &orion_gpio_irq_level_chip);
set_irq_handler(i, handle_level_irq);
irq_desc[i].status |= IRQ_LEVEL;
set_irq_flags(i, IRQF_VALID);
}
set_irq_chained_handler(IRQ_MV78XX0_GPIO_0_7, gpio_irq_handler);
set_irq_chained_handler(IRQ_MV78XX0_GPIO_8_15, gpio_irq_handler);
set_irq_chained_handler(IRQ_MV78XX0_GPIO_16_23, gpio_irq_handler);
set_irq_chained_handler(IRQ_MV78XX0_GPIO_24_31, gpio_irq_handler);
}

0 comments on commit b95a13d

Please sign in to comment.