forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
unicore32 core architecture: interrupts ang gpio handling
This patch implements interrupts and gpio handling. UniCore32 has 9 gpio interrupt sources. And gpio device operations are also here. Signed-off-by: Guan Xuetao <[email protected]>
- Loading branch information
Showing
5 changed files
with
811 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
/* | ||
* linux/arch/unicore32/include/asm/gpio.h | ||
* | ||
* Code specific to PKUnity SoC and UniCore ISA | ||
* | ||
* Copyright (C) 2001-2010 GUAN Xue-tao | ||
* | ||
* 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. | ||
*/ | ||
|
||
#ifndef __UNICORE_GPIO_H__ | ||
#define __UNICORE_GPIO_H__ | ||
|
||
#include <asm/irq.h> | ||
#include <mach/hardware.h> | ||
#include <asm-generic/gpio.h> | ||
|
||
#define GPI_OTP_INT 0 | ||
#define GPI_PCI_INTA 1 | ||
#define GPI_PCI_INTB 2 | ||
#define GPI_PCI_INTC 3 | ||
#define GPI_PCI_INTD 4 | ||
#define GPI_BAT_DET 5 | ||
#define GPI_SD_CD 6 | ||
#define GPI_SOFF_REQ 7 | ||
#define GPI_SD_WP 8 | ||
#define GPI_LCD_CASE_OFF 9 | ||
#define GPO_WIFI_EN 10 | ||
#define GPO_HDD_LED 11 | ||
#define GPO_VGA_EN 12 | ||
#define GPO_LCD_EN 13 | ||
#define GPO_LED_DATA 14 | ||
#define GPO_LED_CLK 15 | ||
#define GPO_CAM_PWR_EN 16 | ||
#define GPO_LCD_VCC_EN 17 | ||
#define GPO_SOFT_OFF 18 | ||
#define GPO_BT_EN 19 | ||
#define GPO_FAN_ON 20 | ||
#define GPO_SPKR 21 | ||
#define GPO_SET_V1 23 | ||
#define GPO_SET_V2 24 | ||
#define GPO_CPU_HEALTH 25 | ||
#define GPO_LAN_SEL 26 | ||
|
||
#ifdef CONFIG_PUV3_NB0916 | ||
#define GPI_BTN_TOUCH 14 | ||
#define GPIO_IN 0x000043ff /* 1 for input */ | ||
#define GPIO_OUT 0x0fffbc00 /* 1 for output */ | ||
#endif /* CONFIG_PUV3_NB0916 */ | ||
|
||
#ifdef CONFIG_PUV3_SMW0919 | ||
#define GPIO_IN 0x000003ff /* 1 for input */ | ||
#define GPIO_OUT 0x0ffffc00 /* 1 for output */ | ||
#endif /* CONFIG_PUV3_SMW0919 */ | ||
|
||
#ifdef CONFIG_PUV3_DB0913 | ||
#define GPIO_IN 0x000001df /* 1 for input */ | ||
#define GPIO_OUT 0x03fee800 /* 1 for output */ | ||
#endif /* CONFIG_PUV3_DB0913 */ | ||
|
||
#define GPIO_DIR (~((GPIO_IN) | 0xf0000000)) | ||
/* 0 input, 1 output */ | ||
|
||
static inline int gpio_get_value(unsigned gpio) | ||
{ | ||
if (__builtin_constant_p(gpio) && (gpio <= GPIO_MAX)) | ||
return GPIO_GPLR & GPIO_GPIO(gpio); | ||
else | ||
return __gpio_get_value(gpio); | ||
} | ||
|
||
static inline void gpio_set_value(unsigned gpio, int value) | ||
{ | ||
if (__builtin_constant_p(gpio) && (gpio <= GPIO_MAX)) | ||
if (value) | ||
GPIO_GPSR = GPIO_GPIO(gpio); | ||
else | ||
GPIO_GPCR = GPIO_GPIO(gpio); | ||
else | ||
__gpio_set_value(gpio, value); | ||
} | ||
|
||
#define gpio_cansleep __gpio_cansleep | ||
|
||
static inline unsigned gpio_to_irq(unsigned gpio) | ||
{ | ||
if ((gpio < IRQ_GPIOHIGH) && (FIELD(1, 1, gpio) & GPIO_GPIR)) | ||
return IRQ_GPIOLOW0 + gpio; | ||
else | ||
return IRQ_GPIO0 + gpio; | ||
} | ||
|
||
static inline unsigned irq_to_gpio(unsigned irq) | ||
{ | ||
if (irq < IRQ_GPIOHIGH) | ||
return irq - IRQ_GPIOLOW0; | ||
else | ||
return irq - IRQ_GPIO0; | ||
} | ||
|
||
#endif /* __UNICORE_GPIO_H__ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/* | ||
* linux/arch/unicore32/include/asm/irq.h | ||
* | ||
* Code specific to PKUnity SoC and UniCore ISA | ||
* | ||
* Copyright (C) 2001-2010 GUAN Xue-tao | ||
* | ||
* 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. | ||
*/ | ||
#ifndef __UNICORE_IRQ_H__ | ||
#define __UNICORE_IRQ_H__ | ||
|
||
#include <asm-generic/irq.h> | ||
|
||
#define IRQ_GPIOLOW0 0x00 | ||
#define IRQ_GPIOLOW1 0x01 | ||
#define IRQ_GPIOLOW2 0x02 | ||
#define IRQ_GPIOLOW3 0x03 | ||
#define IRQ_GPIOLOW4 0x04 | ||
#define IRQ_GPIOLOW5 0x05 | ||
#define IRQ_GPIOLOW6 0x06 | ||
#define IRQ_GPIOLOW7 0x07 | ||
#define IRQ_GPIOHIGH 0x08 | ||
#define IRQ_USB 0x09 | ||
#define IRQ_SDC 0x0a | ||
#define IRQ_AC97 0x0b | ||
#define IRQ_SATA 0x0c | ||
#define IRQ_MME 0x0d | ||
#define IRQ_PCI_BRIDGE 0x0e | ||
#define IRQ_DDR 0x0f | ||
#define IRQ_SPI 0x10 | ||
#define IRQ_UNIGFX 0x11 | ||
#define IRQ_I2C 0x11 | ||
#define IRQ_UART1 0x12 | ||
#define IRQ_UART0 0x13 | ||
#define IRQ_UMAL 0x14 | ||
#define IRQ_NAND 0x15 | ||
#define IRQ_PS2_KBD 0x16 | ||
#define IRQ_PS2_AUX 0x17 | ||
#define IRQ_DMA 0x18 | ||
#define IRQ_DMAERR 0x19 | ||
#define IRQ_TIMER0 0x1a | ||
#define IRQ_TIMER1 0x1b | ||
#define IRQ_TIMER2 0x1c | ||
#define IRQ_TIMER3 0x1d | ||
#define IRQ_RTC 0x1e | ||
#define IRQ_RTCAlarm 0x1f | ||
|
||
#define IRQ_GPIO0 0x20 | ||
#define IRQ_GPIO1 0x21 | ||
#define IRQ_GPIO2 0x22 | ||
#define IRQ_GPIO3 0x23 | ||
#define IRQ_GPIO4 0x24 | ||
#define IRQ_GPIO5 0x25 | ||
#define IRQ_GPIO6 0x26 | ||
#define IRQ_GPIO7 0x27 | ||
#define IRQ_GPIO8 0x28 | ||
#define IRQ_GPIO9 0x29 | ||
#define IRQ_GPIO10 0x2a | ||
#define IRQ_GPIO11 0x2b | ||
#define IRQ_GPIO12 0x2c | ||
#define IRQ_GPIO13 0x2d | ||
#define IRQ_GPIO14 0x2e | ||
#define IRQ_GPIO15 0x2f | ||
#define IRQ_GPIO16 0x30 | ||
#define IRQ_GPIO17 0x31 | ||
#define IRQ_GPIO18 0x32 | ||
#define IRQ_GPIO19 0x33 | ||
#define IRQ_GPIO20 0x34 | ||
#define IRQ_GPIO21 0x35 | ||
#define IRQ_GPIO22 0x36 | ||
#define IRQ_GPIO23 0x37 | ||
#define IRQ_GPIO24 0x38 | ||
#define IRQ_GPIO25 0x39 | ||
#define IRQ_GPIO26 0x3a | ||
#define IRQ_GPIO27 0x3b | ||
|
||
#ifdef CONFIG_ARCH_FPGA | ||
#define IRQ_PCIINTA IRQ_GPIOLOW2 | ||
#define IRQ_PCIINTB IRQ_GPIOLOW1 | ||
#define IRQ_PCIINTC IRQ_GPIOLOW0 | ||
#define IRQ_PCIINTD IRQ_GPIOLOW6 | ||
#endif | ||
|
||
#if defined(CONFIG_PUV3_DB0913) || defined(CONFIG_PUV3_NB0916) \ | ||
|| defined(CONFIG_PUV3_SMW0919) | ||
#define IRQ_PCIINTA IRQ_GPIOLOW1 | ||
#define IRQ_PCIINTB IRQ_GPIOLOW2 | ||
#define IRQ_PCIINTC IRQ_GPIOLOW3 | ||
#define IRQ_PCIINTD IRQ_GPIOLOW4 | ||
#endif | ||
|
||
#define IRQ_SD_CD IRQ_GPIO6 /* falling or rising trigger */ | ||
|
||
#ifndef __ASSEMBLY__ | ||
struct irqaction; | ||
struct pt_regs; | ||
extern void migrate_irqs(void); | ||
|
||
extern void asm_do_IRQ(unsigned int, struct pt_regs *); | ||
|
||
#endif | ||
|
||
#endif | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/* | ||
* linux/arch/unicore32/include/asm/irqflags.h | ||
* | ||
* Code specific to PKUnity SoC and UniCore ISA | ||
* | ||
* Copyright (C) 2001-2010 GUAN Xue-tao | ||
* | ||
* 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. | ||
*/ | ||
#ifndef __UNICORE_IRQFLAGS_H__ | ||
#define __UNICORE_IRQFLAGS_H__ | ||
|
||
#ifdef __KERNEL__ | ||
|
||
#include <asm/ptrace.h> | ||
|
||
#define ARCH_IRQ_DISABLED (PRIV_MODE | PSR_I_BIT) | ||
#define ARCH_IRQ_ENABLED (PRIV_MODE) | ||
|
||
/* | ||
* Save the current interrupt enable state. | ||
*/ | ||
static inline unsigned long arch_local_save_flags(void) | ||
{ | ||
unsigned long temp; | ||
|
||
asm volatile("mov %0, asr" : "=r" (temp) : : "memory", "cc"); | ||
|
||
return temp & PSR_c; | ||
} | ||
|
||
/* | ||
* restore saved IRQ state | ||
*/ | ||
static inline void arch_local_irq_restore(unsigned long flags) | ||
{ | ||
unsigned long temp; | ||
|
||
asm volatile( | ||
"mov %0, asr\n" | ||
"mov.a asr, %1\n" | ||
"mov.f asr, %0" | ||
: "=&r" (temp) | ||
: "r" (flags) | ||
: "memory", "cc"); | ||
} | ||
|
||
#include <asm-generic/irqflags.h> | ||
|
||
#endif | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
/* | ||
* linux/arch/unicore32/kernel/gpio.c | ||
* | ||
* Code specific to PKUnity SoC and UniCore ISA | ||
* | ||
* Maintained by GUAN Xue-tao <[email protected]> | ||
* Copyright (C) 2001-2010 Guan Xuetao | ||
* | ||
* 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. | ||
*/ | ||
/* in FPGA, no GPIO support */ | ||
|
||
#include <linux/init.h> | ||
#include <linux/module.h> | ||
#include <linux/gpio.h> | ||
#include <mach/hardware.h> | ||
|
||
#ifdef CONFIG_LEDS | ||
#include <linux/leds.h> | ||
#include <linux/platform_device.h> | ||
|
||
static const struct gpio_led puv3_gpio_leds[] = { | ||
{ .name = "cpuhealth", .gpio = GPO_CPU_HEALTH, .active_low = 0, | ||
.default_trigger = "heartbeat", }, | ||
{ .name = "hdd_led", .gpio = GPO_HDD_LED, .active_low = 1, | ||
.default_trigger = "ide-disk", }, | ||
}; | ||
|
||
static const struct gpio_led_platform_data puv3_gpio_led_data = { | ||
.num_leds = ARRAY_SIZE(puv3_gpio_leds), | ||
.leds = (void *) puv3_gpio_leds, | ||
}; | ||
|
||
static struct platform_device puv3_gpio_gpio_leds = { | ||
.name = "leds-gpio", | ||
.id = -1, | ||
.dev = { | ||
.platform_data = (void *) &puv3_gpio_led_data, | ||
} | ||
}; | ||
|
||
static int __init puv3_gpio_leds_init(void) | ||
{ | ||
platform_device_register(&puv3_gpio_gpio_leds); | ||
return 0; | ||
} | ||
|
||
device_initcall(puv3_gpio_leds_init); | ||
#endif | ||
|
||
static int puv3_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
{ | ||
return GPIO_GPLR & GPIO_GPIO(offset); | ||
} | ||
|
||
static void puv3_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
{ | ||
if (value) | ||
GPIO_GPSR = GPIO_GPIO(offset); | ||
else | ||
GPIO_GPCR = GPIO_GPIO(offset); | ||
} | ||
|
||
static int puv3_direction_input(struct gpio_chip *chip, unsigned offset) | ||
{ | ||
unsigned long flags; | ||
|
||
local_irq_save(flags); | ||
GPIO_GPDR &= ~GPIO_GPIO(offset); | ||
local_irq_restore(flags); | ||
return 0; | ||
} | ||
|
||
static int puv3_direction_output(struct gpio_chip *chip, unsigned offset, | ||
int value) | ||
{ | ||
unsigned long flags; | ||
|
||
local_irq_save(flags); | ||
puv3_gpio_set(chip, offset, value); | ||
GPIO_GPDR |= GPIO_GPIO(offset); | ||
local_irq_restore(flags); | ||
return 0; | ||
} | ||
|
||
static struct gpio_chip puv3_gpio_chip = { | ||
.label = "gpio", | ||
.direction_input = puv3_direction_input, | ||
.direction_output = puv3_direction_output, | ||
.set = puv3_gpio_set, | ||
.get = puv3_gpio_get, | ||
.base = 0, | ||
.ngpio = GPIO_MAX + 1, | ||
}; | ||
|
||
void __init puv3_init_gpio(void) | ||
{ | ||
GPIO_GPDR = GPIO_DIR; | ||
#if defined(CONFIG_PUV3_NB0916) || defined(CONFIG_PUV3_SMW0919) \ | ||
|| defined(CONFIG_PUV3_DB0913) | ||
gpio_set_value(GPO_WIFI_EN, 1); | ||
gpio_set_value(GPO_HDD_LED, 1); | ||
gpio_set_value(GPO_VGA_EN, 1); | ||
gpio_set_value(GPO_LCD_EN, 1); | ||
gpio_set_value(GPO_CAM_PWR_EN, 0); | ||
gpio_set_value(GPO_LCD_VCC_EN, 1); | ||
gpio_set_value(GPO_SOFT_OFF, 1); | ||
gpio_set_value(GPO_BT_EN, 1); | ||
gpio_set_value(GPO_FAN_ON, 0); | ||
gpio_set_value(GPO_SPKR, 0); | ||
gpio_set_value(GPO_CPU_HEALTH, 1); | ||
gpio_set_value(GPO_LAN_SEL, 1); | ||
/* | ||
* DO NOT modify the GPO_SET_V1 and GPO_SET_V2 in kernel | ||
* gpio_set_value(GPO_SET_V1, 1); | ||
* gpio_set_value(GPO_SET_V2, 1); | ||
*/ | ||
#endif | ||
gpiochip_add(&puv3_gpio_chip); | ||
} |
Oops, something went wrong.