diff options
Diffstat (limited to 'kernel/arch/sh/boards/mach-se/7722')
-rw-r--r-- | kernel/arch/sh/boards/mach-se/7722/Makefile | 10 | ||||
-rw-r--r-- | kernel/arch/sh/boards/mach-se/7722/irq.c | 119 | ||||
-rw-r--r-- | kernel/arch/sh/boards/mach-se/7722/setup.c | 194 |
3 files changed, 323 insertions, 0 deletions
diff --git a/kernel/arch/sh/boards/mach-se/7722/Makefile b/kernel/arch/sh/boards/mach-se/7722/Makefile new file mode 100644 index 000000000..869437338 --- /dev/null +++ b/kernel/arch/sh/boards/mach-se/7722/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for the HITACHI UL SolutionEngine 7722 specific parts of the kernel +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# + +obj-y := setup.o irq.o diff --git a/kernel/arch/sh/boards/mach-se/7722/irq.c b/kernel/arch/sh/boards/mach-se/7722/irq.c new file mode 100644 index 000000000..00e699232 --- /dev/null +++ b/kernel/arch/sh/boards/mach-se/7722/irq.c @@ -0,0 +1,119 @@ +/* + * Hitachi UL SolutionEngine 7722 FPGA IRQ Support. + * + * Copyright (C) 2007 Nobuhiro Iwamatsu + * Copyright (C) 2012 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#define DRV_NAME "SE7722-FPGA" +#define pr_fmt(fmt) DRV_NAME ": " fmt + +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/interrupt.h> +#include <linux/irqdomain.h> +#include <linux/io.h> +#include <linux/err.h> +#include <asm/sizes.h> +#include <mach-se/mach/se7722.h> + +#define IRQ01_BASE_ADDR 0x11800000 +#define IRQ01_MODE_REG 0 +#define IRQ01_STS_REG 4 +#define IRQ01_MASK_REG 8 + +static void __iomem *se7722_irq_regs; +struct irq_domain *se7722_irq_domain; + +static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc) +{ + struct irq_data *data = irq_get_irq_data(irq); + struct irq_chip *chip = irq_data_get_irq_chip(data); + unsigned long mask; + int bit; + + chip->irq_mask_ack(data); + + mask = ioread16(se7722_irq_regs + IRQ01_STS_REG); + + for_each_set_bit(bit, &mask, SE7722_FPGA_IRQ_NR) + generic_handle_irq(irq_linear_revmap(se7722_irq_domain, bit)); + + chip->irq_unmask(data); +} + +static void __init se7722_domain_init(void) +{ + int i; + + se7722_irq_domain = irq_domain_add_linear(NULL, SE7722_FPGA_IRQ_NR, + &irq_domain_simple_ops, NULL); + if (unlikely(!se7722_irq_domain)) { + printk("Failed to get IRQ domain\n"); + return; + } + + for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) { + int irq = irq_create_mapping(se7722_irq_domain, i); + + if (unlikely(irq == 0)) { + printk("Failed to allocate IRQ %d\n", i); + return; + } + } +} + +static void __init se7722_gc_init(void) +{ + struct irq_chip_generic *gc; + struct irq_chip_type *ct; + unsigned int irq_base; + + irq_base = irq_linear_revmap(se7722_irq_domain, 0); + + gc = irq_alloc_generic_chip(DRV_NAME, 1, irq_base, se7722_irq_regs, + handle_level_irq); + if (unlikely(!gc)) + return; + + ct = gc->chip_types; + ct->chip.irq_mask = irq_gc_mask_set_bit; + ct->chip.irq_unmask = irq_gc_mask_clr_bit; + + ct->regs.mask = IRQ01_MASK_REG; + + irq_setup_generic_chip(gc, IRQ_MSK(SE7722_FPGA_IRQ_NR), + IRQ_GC_INIT_MASK_CACHE, + IRQ_NOREQUEST | IRQ_NOPROBE, 0); + + irq_set_chained_handler(IRQ0_IRQ, se7722_irq_demux); + irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); + + irq_set_chained_handler(IRQ1_IRQ, se7722_irq_demux); + irq_set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW); +} + +/* + * Initialize FPGA IRQs + */ +void __init init_se7722_IRQ(void) +{ + se7722_irq_regs = ioremap(IRQ01_BASE_ADDR, SZ_16); + if (unlikely(!se7722_irq_regs)) { + printk("Failed to remap IRQ01 regs\n"); + return; + } + + /* + * All FPGA IRQs disabled by default + */ + iowrite16(0, se7722_irq_regs + IRQ01_MASK_REG); + + __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */ + + se7722_domain_init(); + se7722_gc_init(); +} diff --git a/kernel/arch/sh/boards/mach-se/7722/setup.c b/kernel/arch/sh/boards/mach-se/7722/setup.c new file mode 100644 index 000000000..e04e2bc46 --- /dev/null +++ b/kernel/arch/sh/boards/mach-se/7722/setup.c @@ -0,0 +1,194 @@ +/* + * linux/arch/sh/boards/se/7722/setup.c + * + * Copyright (C) 2007 Nobuhiro Iwamatsu + * Copyright (C) 2012 Paul Mundt + * + * Hitachi UL SolutionEngine 7722 Support. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/ata_platform.h> +#include <linux/input.h> +#include <linux/input/sh_keysc.h> +#include <linux/irqdomain.h> +#include <linux/smc91x.h> +#include <linux/sh_intc.h> +#include <mach-se/mach/se7722.h> +#include <mach-se/mach/mrshpc.h> +#include <asm/machvec.h> +#include <asm/clock.h> +#include <asm/io.h> +#include <asm/heartbeat.h> +#include <cpu/sh7722.h> + +/* Heartbeat */ +static struct resource heartbeat_resource = { + .start = PA_LED, + .end = PA_LED, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT, +}; + +static struct platform_device heartbeat_device = { + .name = "heartbeat", + .id = -1, + .num_resources = 1, + .resource = &heartbeat_resource, +}; + +/* SMC91x */ +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT, +}; + +static struct resource smc91x_eth_resources[] = { + [0] = { + .name = "smc91x-regs" , + .start = PA_LAN + 0x300, + .end = PA_LAN + 0x300 + 0x10 , + .flags = IORESOURCE_MEM, + }, + [1] = { + /* Filled in later */ + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smc91x_eth_device = { + .name = "smc91x", + .id = 0, + .dev = { + .dma_mask = NULL, /* don't use dma */ + .coherent_dma_mask = 0xffffffff, + .platform_data = &smc91x_info, + }, + .num_resources = ARRAY_SIZE(smc91x_eth_resources), + .resource = smc91x_eth_resources, +}; + +static struct resource cf_ide_resources[] = { + [0] = { + .start = PA_MRSHPC_IO + 0x1f0, + .end = PA_MRSHPC_IO + 0x1f0 + 8 , + .flags = IORESOURCE_IO, + }, + [1] = { + .start = PA_MRSHPC_IO + 0x1f0 + 0x206, + .end = PA_MRSHPC_IO + 0x1f0 +8 + 0x206 + 8, + .flags = IORESOURCE_IO, + }, + [2] = { + /* Filled in later */ + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device cf_ide_device = { + .name = "pata_platform", + .id = -1, + .num_resources = ARRAY_SIZE(cf_ide_resources), + .resource = cf_ide_resources, +}; + +static struct sh_keysc_info sh_keysc_info = { + .mode = SH_KEYSC_MODE_1, /* KEYOUT0->5, KEYIN0->4 */ + .scan_timing = 3, + .delay = 5, + .keycodes = { /* SW1 -> SW30 */ + KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, + KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, + KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, + KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, + KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, + KEY_Z, + KEY_HOME, KEY_SLEEP, KEY_WAKEUP, KEY_COFFEE, /* life */ + }, +}; + +static struct resource sh_keysc_resources[] = { + [0] = { + .start = 0x044b0000, + .end = 0x044b000f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = evt2irq(0xbe0), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sh_keysc_device = { + .name = "sh_keysc", + .id = 0, /* "keysc0" clock */ + .num_resources = ARRAY_SIZE(sh_keysc_resources), + .resource = sh_keysc_resources, + .dev = { + .platform_data = &sh_keysc_info, + }, +}; + +static struct platform_device *se7722_devices[] __initdata = { + &heartbeat_device, + &smc91x_eth_device, + &cf_ide_device, + &sh_keysc_device, +}; + +static int __init se7722_devices_setup(void) +{ + mrshpc_setup_windows(); + + /* Wire-up dynamic vectors */ + cf_ide_resources[2].start = cf_ide_resources[2].end = + irq_find_mapping(se7722_irq_domain, SE7722_FPGA_IRQ_MRSHPC0); + + smc91x_eth_resources[1].start = smc91x_eth_resources[1].end = + irq_find_mapping(se7722_irq_domain, SE7722_FPGA_IRQ_SMC); + + return platform_add_devices(se7722_devices, ARRAY_SIZE(se7722_devices)); +} +device_initcall(se7722_devices_setup); + +static void __init se7722_setup(char **cmdline_p) +{ + __raw_writew(0x010D, FPGA_OUT); /* FPGA */ + + __raw_writew(0x0000, PORT_PECR); /* PORT E 1 = IRQ5 ,E 0 = BS */ + __raw_writew(0x1000, PORT_PJCR); /* PORT J 1 = IRQ1,J 0 =IRQ0 */ + + /* LCDC I/O */ + __raw_writew(0x0020, PORT_PSELD); + + /* SIOF1*/ + __raw_writew(0x0003, PORT_PSELB); + __raw_writew(0xe000, PORT_PSELC); + __raw_writew(0x0000, PORT_PKCR); + + /* LCDC */ + __raw_writew(0x4020, PORT_PHCR); + __raw_writew(0x0000, PORT_PLCR); + __raw_writew(0x0000, PORT_PMCR); + __raw_writew(0x0002, PORT_PRCR); + __raw_writew(0x0000, PORT_PXCR); /* LCDC,CS6A */ + + /* KEYSC */ + __raw_writew(0x0A10, PORT_PSELA); /* BS,SHHID2 */ + __raw_writew(0x0000, PORT_PYCR); + __raw_writew(0x0000, PORT_PZCR); + __raw_writew(__raw_readw(PORT_HIZCRA) & ~0x4000, PORT_HIZCRA); + __raw_writew(__raw_readw(PORT_HIZCRC) & ~0xc000, PORT_HIZCRC); +} + +/* + * The Machine Vector + */ +static struct sh_machine_vector mv_se7722 __initmv = { + .mv_name = "Solution Engine 7722" , + .mv_setup = se7722_setup , + .mv_init_irq = init_se7722_IRQ, +}; |