aboutsummaryrefslogtreecommitdiffstats
path: root/arch/avr32/mach-at32ap
diff options
context:
space:
mode:
Diffstat (limited to 'arch/avr32/mach-at32ap')
-rw-r--r--arch/avr32/mach-at32ap/Kconfig12
-rw-r--r--arch/avr32/mach-at32ap/Makefile4
-rw-r--r--arch/avr32/mach-at32ap/at32ap700x.c (renamed from arch/avr32/mach-at32ap/at32ap7000.c)15
-rw-r--r--arch/avr32/mach-at32ap/extint.c59
4 files changed, 62 insertions, 28 deletions
diff --git a/arch/avr32/mach-at32ap/Kconfig b/arch/avr32/mach-at32ap/Kconfig
index eb307838457b..a7bbcc82058e 100644
--- a/arch/avr32/mach-at32ap/Kconfig
+++ b/arch/avr32/mach-at32ap/Kconfig
@@ -3,9 +3,9 @@ if PLATFORM_AT32AP
menu "Atmel AVR32 AP options"
choice
- prompt "AT32AP7000 static memory bus width"
- depends on CPU_AT32AP7000
- default AP7000_16_BIT_SMC
+ prompt "AT32AP700x static memory bus width"
+ depends on CPU_AT32AP700X
+ default AP700X_16_BIT_SMC
help
Define the width of the AP7000 external static memory interface.
This is used to determine how to mangle the address and/or data
@@ -15,13 +15,13 @@ choice
width for all chip selects, excluding the flash (which is using
raw access and is thus not affected by any of this.)
-config AP7000_32_BIT_SMC
+config AP700X_32_BIT_SMC
bool "32 bit"
-config AP7000_16_BIT_SMC
+config AP700X_16_BIT_SMC
bool "16 bit"
-config AP7000_8_BIT_SMC
+config AP700X_8_BIT_SMC
bool "8 bit"
endchoice
diff --git a/arch/avr32/mach-at32ap/Makefile b/arch/avr32/mach-at32ap/Makefile
index a8b445046e3e..5e9f8217befc 100644
--- a/arch/avr32/mach-at32ap/Makefile
+++ b/arch/avr32/mach-at32ap/Makefile
@@ -1,4 +1,4 @@
obj-y += at32ap.o clock.o intc.o extint.o pio.o hsmc.o
-obj-$(CONFIG_CPU_AT32AP7000) += at32ap7000.o
-obj-$(CONFIG_CPU_AT32AP7000) += time-tc.o
+obj-$(CONFIG_CPU_AT32AP700X) += at32ap700x.o
+obj-$(CONFIG_CPU_AT32AP700X) += time-tc.o
obj-$(CONFIG_CPU_FREQ_AT32AP) += cpufreq.o
diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap700x.c
index 7c4388f4f17f..14e61f05e1f6 100644
--- a/arch/avr32/mach-at32ap/at32ap7000.c
+++ b/arch/avr32/mach-at32ap/at32ap700x.c
@@ -13,8 +13,9 @@
#include <linux/spi/spi.h>
#include <asm/io.h>
+#include <asm/irq.h>
-#include <asm/arch/at32ap7000.h>
+#include <asm/arch/at32ap700x.h>
#include <asm/arch/board.h>
#include <asm/arch/portmux.h>
@@ -803,6 +804,7 @@ void __init at32_setup_serial_console(unsigned int usart_id)
* Ethernet
* -------------------------------------------------------------------- */
+#ifdef CONFIG_CPU_AT32AP7000
static struct eth_platform_data macb0_data;
static struct resource macb0_resource[] = {
PBMEM(0xfff01800),
@@ -890,6 +892,7 @@ at32_add_device_eth(unsigned int id, struct eth_platform_data *data)
return pdev;
}
+#endif
/* --------------------------------------------------------------------
* SPI
@@ -1064,6 +1067,7 @@ err_add_resources:
/* --------------------------------------------------------------------
* LCDC
* -------------------------------------------------------------------- */
+#if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7002)
static struct atmel_lcdfb_info atmel_lcdfb0_data;
static struct resource atmel_lcdfb0_resource[] = {
{
@@ -1179,6 +1183,7 @@ err_dup_modedb:
kfree(monspecs);
return NULL;
}
+#endif
/* --------------------------------------------------------------------
* SSC
@@ -1332,6 +1337,7 @@ out_free_pdev:
/* --------------------------------------------------------------------
* IDE / CompactFlash
* -------------------------------------------------------------------- */
+#if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7001)
static struct resource at32_smc_cs4_resource[] __initdata = {
{
.start = 0x04000000,
@@ -1464,6 +1470,7 @@ fail:
platform_device_put(pdev);
return NULL;
}
+#endif
/* --------------------------------------------------------------------
* AC97C
@@ -1639,16 +1646,20 @@ struct clk *at32_clock_list[] = {
&atmel_usart1_usart,
&atmel_usart2_usart,
&atmel_usart3_usart,
+#if defined(CONFIG_CPU_AT32AP7000)
&macb0_hclk,
&macb0_pclk,
&macb1_hclk,
&macb1_pclk,
+#endif
&atmel_spi0_spi_clk,
&atmel_spi1_spi_clk,
&atmel_twi0_pclk,
&atmel_mci0_pclk,
+#if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7002)
&atmel_lcdfb0_hck1,
&atmel_lcdfb0_pixclk,
+#endif
&ssc0_pclk,
&ssc1_pclk,
&ssc2_pclk,
@@ -1697,7 +1708,9 @@ void __init at32_clock_init(void)
genclk_init_parent(&gclk2);
genclk_init_parent(&gclk3);
genclk_init_parent(&gclk4);
+#if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7002)
genclk_init_parent(&atmel_lcdfb0_pixclk);
+#endif
genclk_init_parent(&abdac0_sample_clk);
/*
diff --git a/arch/avr32/mach-at32ap/extint.c b/arch/avr32/mach-at32ap/extint.c
index f5bfd4c81fe7..c36a6d59d6f0 100644
--- a/arch/avr32/mach-at32ap/extint.c
+++ b/arch/avr32/mach-at32ap/extint.c
@@ -26,16 +26,10 @@
#define EIC_MODE 0x0014
#define EIC_EDGE 0x0018
#define EIC_LEVEL 0x001c
-#define EIC_TEST 0x0020
#define EIC_NMIC 0x0024
-/* Bitfields in TEST */
-#define EIC_TESTEN_OFFSET 31
-#define EIC_TESTEN_SIZE 1
-
/* Bitfields in NMIC */
-#define EIC_EN_OFFSET 0
-#define EIC_EN_SIZE 1
+#define EIC_NMIC_ENABLE (1 << 0)
/* Bit manipulation macros */
#define EIC_BIT(name) \
@@ -63,6 +57,9 @@ struct eic {
unsigned int first_irq;
};
+static struct eic *nmi_eic;
+static bool nmi_enabled;
+
static void eic_ack_irq(unsigned int irq)
{
struct eic *eic = get_irq_chip_data(irq);
@@ -133,8 +130,11 @@ static int eic_set_irq_type(unsigned int irq, unsigned int flow_type)
eic_writel(eic, EDGE, edge);
eic_writel(eic, LEVEL, level);
- if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
+ if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) {
flow_type |= IRQ_LEVEL;
+ __set_irq_handler_unlocked(irq, handle_level_irq);
+ } else
+ __set_irq_handler_unlocked(irq, handle_edge_irq);
desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
desc->status |= flow_type;
}
@@ -154,9 +154,8 @@ static struct irq_chip eic_chip = {
static void demux_eic_irq(unsigned int irq, struct irq_desc *desc)
{
struct eic *eic = desc->handler_data;
- struct irq_desc *ext_desc;
unsigned long status, pending;
- unsigned int i, ext_irq;
+ unsigned int i;
status = eic_readl(eic, ISR);
pending = status & eic_readl(eic, IMR);
@@ -165,15 +164,28 @@ static void demux_eic_irq(unsigned int irq, struct irq_desc *desc)
i = fls(pending) - 1;
pending &= ~(1 << i);
- ext_irq = i + eic->first_irq;
- ext_desc = irq_desc + ext_irq;
- if (ext_desc->status & IRQ_LEVEL)
- handle_level_irq(ext_irq, ext_desc);
- else
- handle_edge_irq(ext_irq, ext_desc);
+ generic_handle_irq(i + eic->first_irq);
}
}
+int nmi_enable(void)
+{
+ nmi_enabled = true;
+
+ if (nmi_eic)
+ eic_writel(nmi_eic, NMIC, EIC_NMIC_ENABLE);
+
+ return 0;
+}
+
+void nmi_disable(void)
+{
+ if (nmi_eic)
+ eic_writel(nmi_eic, NMIC, 0);
+
+ nmi_enabled = false;
+}
+
static int __init eic_probe(struct platform_device *pdev)
{
struct eic *eic;
@@ -214,14 +226,13 @@ static int __init eic_probe(struct platform_device *pdev)
pattern = eic_readl(eic, MODE);
nr_irqs = fls(pattern);
- /* Trigger on falling edge unless overridden by driver */
- eic_writel(eic, MODE, 0UL);
+ /* Trigger on low level unless overridden by driver */
eic_writel(eic, EDGE, 0UL);
+ eic_writel(eic, LEVEL, 0UL);
eic->chip = &eic_chip;
for (i = 0; i < nr_irqs; i++) {
- /* NOTE the handler we set here is ignored by the demux */
set_irq_chip_and_handler(eic->first_irq + i, &eic_chip,
handle_level_irq);
set_irq_chip_data(eic->first_irq + i, eic);
@@ -230,6 +241,16 @@ static int __init eic_probe(struct platform_device *pdev)
set_irq_chained_handler(int_irq, demux_eic_irq);
set_irq_data(int_irq, eic);
+ if (pdev->id == 0) {
+ nmi_eic = eic;
+ if (nmi_enabled)
+ /*
+ * Someone tried to enable NMI before we were
+ * ready. Do it now.
+ */
+ nmi_enable();
+ }
+
dev_info(&pdev->dev,
"External Interrupt Controller at 0x%p, IRQ %u\n",
eic->regs, int_irq);