diff options
author | David Woodhouse <dwmw2@infradead.org> | 2006-10-01 17:55:53 +0100 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2006-10-01 17:55:53 +0100 |
commit | 8a84fc15ae5cafcc366dd85cf8e1ab2040679abc (patch) | |
tree | 5d8dce194c9667fa92e9ec9f545cec867a9a1e0d /arch/sh/boards | |
parent | 28b79ff9661b22e4c41c0d00d4ab8503e810f13d (diff) | |
parent | 82965addad66fce61a92c5f03104ea90b0b87124 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Manually resolve conflict in include/mtd/Kbuild
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'arch/sh/boards')
114 files changed, 3727 insertions, 4176 deletions
diff --git a/arch/sh/boards/adx/Makefile b/arch/sh/boards/adx/Makefile deleted file mode 100644 index 5b1c531b399..00000000000 --- a/arch/sh/boards/adx/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# -# Makefile for ADX boards -# - -obj-y := setup.o irq.o irq_maskreq.o - diff --git a/arch/sh/boards/adx/irq.c b/arch/sh/boards/adx/irq.c deleted file mode 100644 index c6ca409dff9..00000000000 --- a/arch/sh/boards/adx/irq.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * linux/arch/sh/boards/adx/irq.c - * - * Copyright (C) 2001 A&D Co., Ltd. - * - * I/O routine and setup routines for A&D ADX Board - * - * 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 <asm/irq.h> - -void init_adx_IRQ(void) -{ - int i; - -/* printk("init_adx_IRQ()\n");*/ - /* setup irq_mask_register */ - irq_mask_register = (unsigned short *)0xa6000008; - - /* cover all external interrupt area by maskreg_irq_type - * (Actually, irq15 doesn't exist) - */ - for (i = 0; i < 16; i++) { - make_maskreg_irq(i); - disable_irq(i); - } -} diff --git a/arch/sh/boards/adx/irq_maskreg.c b/arch/sh/boards/adx/irq_maskreg.c deleted file mode 100644 index 4b2abe5eb16..00000000000 --- a/arch/sh/boards/adx/irq_maskreg.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * linux/arch/sh/kernel/irq_maskreg.c - * - * Copyright (C) 2001 A&D Co., Ltd. <http://www.aandd.co.jp> - * - * This file may be copied or modified under the terms of the GNU - * General Public License. See linux/COPYING for more information. - * - * Interrupt handling for Simple external interrupt mask register - * - * This is for the machine which have single 16 bit register - * for masking external IRQ individually. - * Each bit of the register is for masking each interrupt. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/irq.h> - -#include <asm/system.h> -#include <asm/io.h> -#include <asm/machvec.h> - -/* address of external interrupt mask register - * address must be set prior to use these (maybe in init_XXX_irq()) - * XXX : is it better to use .config than specifying it in code? */ -unsigned short *irq_mask_register = 0; - -/* forward declaration */ -static unsigned int startup_maskreg_irq(unsigned int irq); -static void shutdown_maskreg_irq(unsigned int irq); -static void enable_maskreg_irq(unsigned int irq); -static void disable_maskreg_irq(unsigned int irq); -static void mask_and_ack_maskreg(unsigned int); -static void end_maskreg_irq(unsigned int irq); - -/* hw_interrupt_type */ -static struct hw_interrupt_type maskreg_irq_type = { - .typename = " Mask Register", - .startup = startup_maskreg_irq, - .shutdown = shutdown_maskreg_irq, - .enable = enable_maskreg_irq, - .disable = disable_maskreg_irq, - .ack = mask_and_ack_maskreg, - .end = end_maskreg_irq -}; - -/* actual implementatin */ -static unsigned int startup_maskreg_irq(unsigned int irq) -{ - enable_maskreg_irq(irq); - return 0; /* never anything pending */ -} - -static void shutdown_maskreg_irq(unsigned int irq) -{ - disable_maskreg_irq(irq); -} - -static void disable_maskreg_irq(unsigned int irq) -{ - if (irq_mask_register) { - unsigned long flags; - unsigned short val, mask = 0x01 << irq; - - /* Set "irq"th bit */ - local_irq_save(flags); - val = ctrl_inw((unsigned long)irq_mask_register); - val |= mask; - ctrl_outw(val, (unsigned long)irq_mask_register); - local_irq_restore(flags); - } -} - -static void enable_maskreg_irq(unsigned int irq) -{ - if (irq_mask_register) { - unsigned long flags; - unsigned short val, mask = ~(0x01 << irq); - - /* Clear "irq"th bit */ - local_irq_save(flags); - val = ctrl_inw((unsigned long)irq_mask_register); - val &= mask; - ctrl_outw(val, (unsigned long)irq_mask_register); - local_irq_restore(flags); - } -} - -static void mask_and_ack_maskreg(unsigned int irq) -{ - disable_maskreg_irq(irq); -} - -static void end_maskreg_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_maskreg_irq(irq); -} - -void make_maskreg_irq(unsigned int irq) -{ - disable_irq_nosync(irq); - irq_desc[irq].chip = &maskreg_irq_type; - disable_maskreg_irq(irq); -} diff --git a/arch/sh/boards/adx/setup.c b/arch/sh/boards/adx/setup.c deleted file mode 100644 index 4938d959234..00000000000 --- a/arch/sh/boards/adx/setup.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * linux/arch/sh/board/adx/setup.c - * - * Copyright (C) 2001 A&D Co., Ltd. - * - * I/O routine and setup routines for A&D ADX Board - * - * 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 <asm/machvec.h> -#include <linux/module.h> - -extern void init_adx_IRQ(void); -extern void *cf_io_base; - -const char *get_system_type(void) -{ - return "A&D ADX"; -} - -unsigned long adx_isa_port2addr(unsigned long offset) -{ - /* CompactFlash (IDE) */ - if (((offset >= 0x1f0) && (offset <= 0x1f7)) || (offset == 0x3f6)) { - return (unsigned long)cf_io_base + offset; - } - - /* eth0 */ - if ((offset >= 0x300) && (offset <= 0x30f)) { - return 0xa5000000 + offset; /* COMM BOARD (AREA1) */ - } - - return offset + 0xb0000000; /* IOBUS (AREA 4)*/ -} - -/* - * The Machine Vector - */ - -struct sh_machine_vector mv_adx __initmv = { - .mv_nr_irqs = 48, - .mv_isa_port2addr = adx_isa_port2addr, - .mv_init_irq = init_adx_IRQ, -}; -ALIAS_MV(adx) - -int __init platform_setup(void) -{ - /* Nothing to see here .. */ - return 0; -} - diff --git a/arch/sh/boards/bigsur/irq.c b/arch/sh/boards/bigsur/irq.c index ac946a2201c..1ab04da3638 100644 --- a/arch/sh/boards/bigsur/irq.c +++ b/arch/sh/boards/bigsur/irq.c @@ -19,6 +19,7 @@ * IRQ functions for a Hitachi Big Sur Evaluation Board. * */ +#undef DEBUG #include <linux/sched.h> #include <linux/module.h> @@ -41,10 +42,8 @@ #undef BIGSUR_DEBUG #ifdef BIGSUR_DEBUG -#define DPRINTK(args...) printk(args) #define DIPRINTK(n, args...) if (BIGSUR_DEBUG>(n)) printk(args) #else -#define DPRINTK(args...) #define DIPRINTK(n, args...) #endif /* BIGSUR_DEBUG */ @@ -60,45 +59,39 @@ extern int hd64465_irq_demux(int irq); /* Level 1 IRQ routines */ static void disable_bigsur_l1irq(unsigned int irq) { - unsigned long flags; unsigned char mask; unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0; unsigned char bit = (1 << ((irq - MGATE_IRQ_LOW)%8) ); if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) { - DPRINTK("Disable L1 IRQ %d\n", irq); + pr_debug("Disable L1 IRQ %d\n", irq); DIPRINTK(2,"disable_bigsur_l1irq: IMR=0x%08x mask=0x%x\n", mask_port, bit); - local_irq_save(flags); /* Disable IRQ - set mask bit */ mask = inb(mask_port) | bit; outb(mask, mask_port); - local_irq_restore(flags); return; } - DPRINTK("disable_bigsur_l1irq: Invalid IRQ %d\n", irq); + pr_debug("disable_bigsur_l1irq: Invalid IRQ %d\n", irq); } static void enable_bigsur_l1irq(unsigned int irq) { - unsigned long flags; unsigned char mask; unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0; unsigned char bit = (1 << ((irq - MGATE_IRQ_LOW)%8) ); if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) { - DPRINTK("Enable L1 IRQ %d\n", irq); + pr_debug("Enable L1 IRQ %d\n", irq); DIPRINTK(2,"enable_bigsur_l1irq: IMR=0x%08x mask=0x%x\n", mask_port, bit); - local_irq_save(flags); /* Enable L1 IRQ - clear mask bit */ mask = inb(mask_port) & ~bit; outb(mask, mask_port); - local_irq_restore(flags); return; } - DPRINTK("enable_bigsur_l1irq: Invalid IRQ %d\n", irq); + pr_debug("enable_bigsur_l1irq: Invalid IRQ %d\n", irq); } @@ -126,51 +119,45 @@ static const u32 imr_offset = BIGSUR_IMR0 - BIGSUR_IMR1; /* Level 2 IRQ routines */ static void disable_bigsur_l2irq(unsigned int irq) { - unsigned long flags; unsigned char mask; unsigned char bit = 1 << ((irq-BIGSUR_2NDLVL_IRQ_LOW)%8); unsigned int mask_port = imr_base - REG_NUM(irq)*imr_offset; - if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) { - DPRINTK("Disable L2 IRQ %d\n", irq); + if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) { + pr_debug("Disable L2 IRQ %d\n", irq); DIPRINTK(2,"disable_bigsur_l2irq: IMR=0x%08x mask=0x%x\n", mask_port, bit); - local_irq_save(flags); /* Disable L2 IRQ - set mask bit */ mask = inb(mask_port) | bit; outb(mask, mask_port); - local_irq_restore(flags); return; } - DPRINTK("disable_bigsur_l2irq: Invalid IRQ %d\n", irq); + pr_debug("disable_bigsur_l2irq: Invalid IRQ %d\n", irq); } static void enable_bigsur_l2irq(unsigned int irq) { - unsigned long flags; unsigned char mask; unsigned char bit = 1 << ((irq-BIGSUR_2NDLVL_IRQ_LOW)%8); unsigned int mask_port = imr_base - REG_NUM(irq)*imr_offset; - if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) { - DPRINTK("Enable L2 IRQ %d\n", irq); + if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) { + pr_debug("Enable L2 IRQ %d\n", irq); DIPRINTK(2,"enable_bigsur_l2irq: IMR=0x%08x mask=0x%x\n", mask_port, bit); - local_irq_save(flags); /* Enable L2 IRQ - clear mask bit */ mask = inb(mask_port) & ~bit; outb(mask, mask_port); - local_irq_restore(flags); return; } - DPRINTK("enable_bigsur_l2irq: Invalid IRQ %d\n", irq); + pr_debug("enable_bigsur_l2irq: Invalid IRQ %d\n", irq); } static void mask_and_ack_bigsur(unsigned int irq) { - DPRINTK("mask_and_ack_bigsur IRQ %d\n", irq); + pr_debug("mask_and_ack_bigsur IRQ %d\n", irq); if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) disable_bigsur_l1irq(irq); else @@ -179,7 +166,7 @@ static void mask_and_ack_bigsur(unsigned int irq) static void end_bigsur_irq(unsigned int irq) { - DPRINTK("end_bigsur_irq IRQ %d\n", irq); + pr_debug("end_bigsur_irq IRQ %d\n", irq); if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) enable_bigsur_l1irq(irq); @@ -193,7 +180,7 @@ static unsigned int startup_bigsur_irq(unsigned int irq) u8 mask; u32 reg; - DPRINTK("startup_bigsur_irq IRQ %d\n", irq); + pr_debug("startup_bigsur_irq IRQ %d\n", irq); if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) { /* Enable the L1 IRQ */ @@ -218,7 +205,7 @@ static unsigned int startup_bigsur_irq(unsigned int irq) static void shutdown_bigsur_irq(unsigned int irq) { - DPRINTK("shutdown_bigsur_irq IRQ %d\n", irq); + pr_debug("shutdown_bigsur_irq IRQ %d\n", irq); if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) disable_bigsur_l1irq(irq); else @@ -260,7 +247,7 @@ static void make_bigsur_l1isr(unsigned int irq) { disable_bigsur_l1irq(irq); return; } - DPRINTK("make_bigsur_l1isr: bad irq, %d\n", irq); + pr_debug("make_bigsur_l1isr: bad irq, %d\n", irq); return; } @@ -277,7 +264,7 @@ static void make_bigsur_l2isr(unsigned int irq) { disable_bigsur_l2irq(irq); return; } - DPRINTK("make_bigsur_l2isr: bad irq, %d\n", irq); + pr_debug("make_bigsur_l2isr: bad irq, %d\n", irq); return; } diff --git a/arch/sh/boards/bigsur/setup.c b/arch/sh/boards/bigsur/setup.c index dfeede9da50..9711c20fc9e 100644 --- a/arch/sh/boards/bigsur/setup.c +++ b/arch/sh/boards/bigsur/setup.c @@ -41,31 +41,7 @@ // Big Sur Init Routines /*===========================================================*/ -const char *get_system_type(void) -{ - return "Big Sur"; -} - -/* - * The Machine Vector - */ -extern void heartbeat_bigsur(void); -extern void init_bigsur_IRQ(void); - -struct sh_machine_vector mv_bigsur __initmv = { - .mv_nr_irqs = NR_IRQS, // Defined in <asm/irq.h> - - .mv_isa_port2addr = bigsur_isa_port2addr, - .mv_irq_demux = bigsur_irq_demux, - - .mv_init_irq = init_bigsur_IRQ, -#ifdef CONFIG_HEARTBEAT - .mv_heartbeat = heartbeat_bigsur, -#endif -}; -ALIAS_MV(bigsur) - -int __init platform_setup(void) +static void __init bigsur_setup(char **cmdline_p) { /* Mask all 2nd level IRQ's */ outb(-1,BIGSUR_IMR0); @@ -89,7 +65,24 @@ int __init platform_setup(void) outw(1, BIGSUR_ETHR+0xe); /* set the IO port to BIGSUR_ETHER_IOPORT */ outw(BIGSUR_ETHER_IOPORT<<3, BIGSUR_ETHR+0x2); - - return 0; } +/* + * The Machine Vector + */ +extern void heartbeat_bigsur(void); +extern void init_bigsur_IRQ(void); + +struct sh_machine_vector mv_bigsur __initmv = { + .mv_name = "Big Sur", + .mv_setup = bigsur_setup, + + .mv_isa_port2addr = bigsur_isa_port2addr, + .mv_irq_demux = bigsur_irq_demux, + + .mv_init_irq = init_bigsur_IRQ, +#ifdef CONFIG_HEARTBEAT + .mv_heartbeat = heartbeat_bigsur, +#endif +}; +ALIAS_MV(bigsur) diff --git a/arch/sh/boards/cat68701/Makefile b/arch/sh/boards/cat68701/Makefile deleted file mode 100644 index 52c1de0a6df..00000000000 --- a/arch/sh/boards/cat68701/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# -# Makefile for the CAT-68701 specific parts of the kernel -# - -obj-y := setup.o irq.o - diff --git a/arch/sh/boards/cat68701/irq.c b/arch/sh/boards/cat68701/irq.c deleted file mode 100644 index f9a6d185fb8..00000000000 --- a/arch/sh/boards/cat68701/irq.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * linux/arch/sh/boards/cat68701/irq.c - * - * Copyright (C) 2000 Niibe Yutaka - * 2001 Yutaro Ebihara - * - * Setup routines for A-ONE Corp CAT-68701 SH7708 Board - * - * 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 <asm/irq.h> - -int cat68701_irq_demux(int irq) -{ - if(irq==13) return 14; - if(irq==7) return 10; - return irq; -} - -void init_cat68701_IRQ() -{ - make_imask_irq(10); - make_imask_irq(14); -} diff --git a/arch/sh/boards/cat68701/setup.c b/arch/sh/boards/cat68701/setup.c deleted file mode 100644 index 90e5175df22..00000000000 --- a/arch/sh/boards/cat68701/setup.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * linux/arch/sh/boards/cat68701/setup.c - * - * Copyright (C) 2000 Niibe Yutaka - * 2001 Yutaro Ebihara - * - * Setup routines for A-ONE Corp CAT-68701 SH7708 Board - * - * 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 <asm/io.h> -#include <asm/machvec.h> -#include <asm/mach/io.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/sched.h> - -const char *get_system_type(void) -{ - return "CAT-68701"; -} - -#ifdef CONFIG_HEARTBEAT -void heartbeat_cat68701() -{ - static unsigned int cnt = 0, period = 0 , bit = 0; - cnt += 1; - if (cnt < period) { - return; - } - cnt = 0; - - /* Go through the points (roughly!): - * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110 - */ - period = 110 - ( (300<<FSHIFT)/ - ((avenrun[0]/5) + (3<<FSHIFT)) ); - - if(bit){ bit=0; }else{ bit=1; } - outw(bit<<15,0x3fe); -} -#endif /* CONFIG_HEARTBEAT */ - -unsigned long cat68701_isa_port2addr(unsigned long offset) -{ - /* CompactFlash (IDE) */ - if (((offset >= 0x1f0) && (offset <= 0x1f7)) || (offset==0x3f6)) - return 0xba000000 + offset; - - /* INPUT PORT */ - if ((offset >= 0x3fc) && (offset <= 0x3fd)) - return 0xb4007000 + offset; - - /* OUTPUT PORT */ - if ((offset >= 0x3fe) && (offset <= 0x3ff)) - return 0xb4007400 + offset; - - return offset + 0xb4000000; /* other I/O (EREA 5)*/ -} - -/* - * The Machine Vector - */ - -struct sh_machine_vector mv_cat68701 __initmv = { - .mv_nr_irqs = 32, - .mv_isa_port2addr = cat68701_isa_port2addr, - .mv_irq_demux = cat68701_irq_demux, - - .mv_init_irq = init_cat68701_IRQ, -#ifdef CONFIG_HEARTBEAT - .mv_heartbeat = heartbeat_cat68701, -#endif -}; -ALIAS_MV(cat68701) - -int __init platform_setup(void) -{ - /* dummy read erea5 (CS8900A) */ -} - diff --git a/arch/sh/boards/cqreek/Makefile b/arch/sh/boards/cqreek/Makefile deleted file mode 100644 index 1a788a85eba..00000000000 --- a/arch/sh/boards/cqreek/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# -# Makefile for the CqREEK specific parts of the kernel -# - -obj-y := setup.o irq.o - diff --git a/arch/sh/boards/cqreek/irq.c b/arch/sh/boards/cqreek/irq.c deleted file mode 100644 index 2955adc5231..00000000000 --- a/arch/sh/boards/cqreek/irq.c +++ /dev/null @@ -1,128 +0,0 @@ -/* $Id: irq.c,v 1.1.2.4 2002/11/04 20:33:56 lethal Exp $ - * - * arch/sh/boards/cqreek/irq.c - * - * Copyright (C) 2000 Niibe Yutaka - * - * CqREEK IDE/ISA Bridge Support. - * - */ - -#include <linux/irq.h> -#include <linux/init.h> - -#include <asm/cqreek/cqreek.h> -#include <asm/io.h> -#include <asm/io_generic.h> -#include <asm/irq.h> -#include <asm/machvec.h> -#include <asm/machvec_init.h> -#include <asm/rtc.h> - -struct cqreek_irq_data { - unsigned short mask_port; /* Port of Interrupt Mask Register */ - unsigned short stat_port; /* Port of Interrupt Status Register */ - unsigned short bit; /* Value of the bit */ -}; -static struct cqreek_irq_data cqreek_irq_data[NR_IRQS]; - -static void disable_cqreek_irq(unsigned int irq) -{ - unsigned long flags; - unsigned short mask; - unsigned short mask_port = cqreek_irq_data[irq].mask_port; - unsigned short bit = cqreek_irq_data[irq].bit; - - local_irq_save(flags); - /* Disable IRQ */ - mask = inw(mask_port) & ~bit; - outw_p(mask, mask_port); - local_irq_restore(flags); -} - -static void enable_cqreek_irq(unsigned int irq) -{ - unsigned long flags; - unsigned short mask; - unsigned short mask_port = cqreek_irq_data[irq].mask_port; - unsigned short bit = cqreek_irq_data[irq].bit; - - local_irq_save(flags); - /* Enable IRQ */ - mask = inw(mask_port) | bit; - outw_p(mask, mask_port); - local_irq_restore(flags); -} - -static void mask_and_ack_cqreek(unsigned int irq) -{ - unsigned short stat_port = cqreek_irq_data[irq].stat_port; - unsigned short bit = cqreek_irq_data[irq].bit; - - disable_cqreek_irq(irq); - /* Clear IRQ (it might be edge IRQ) */ - inw(stat_port); - outw_p(bit, stat_port); -} - -static void end_cqreek_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_cqreek_irq(irq); -} - -static unsigned int startup_cqreek_irq(unsigned int irq) -{ - enable_cqreek_irq(irq); - return 0; -} - -static void shutdown_cqreek_irq(unsigned int irq) -{ - disable_cqreek_irq(irq); -} - -static struct hw_interrupt_type cqreek_irq_type = { - .typename = "CqREEK-IRQ", - .startup = startup_cqreek_irq, - .shutdown = shutdown_cqreek_irq, - .enable = enable_cqreek_irq, - .disable = disable_cqreek_irq, - .ack = mask_and_ack_cqreek, - .end = end_cqreek_irq -}; - -int cqreek_has_ide, cqreek_has_isa; - -/* XXX: This is just for test for my NE2000 ISA board - What we really need is virtualized IRQ and demultiplexer like HP600 port */ -void __init init_cqreek_IRQ(void) -{ - if (cqreek_has_ide) { - cqreek_irq_data[14].mask_port = BRIDGE_IDE_INTR_MASK; - cqreek_irq_data[14].stat_port = BRIDGE_IDE_INTR_STAT; - cqreek_irq_data[14].bit = 1; - - irq_desc[14].chip = &cqreek_irq_type; - irq_desc[14].status = IRQ_DISABLED; - irq_desc[14].action = 0; - irq_desc[14].depth = 1; - - disable_cqreek_irq(14); - } - - if (cqreek_has_isa) { - cqreek_irq_data[10].mask_port = BRIDGE_ISA_INTR_MASK; - cqreek_irq_data[10].stat_port = BRIDGE_ISA_INTR_STAT; - cqreek_irq_data[10].bit = (1 << 10); - - /* XXX: Err... we may need demultiplexer for ISA irq... */ - irq_desc[10].chip = &cqreek_irq_type; - irq_desc[10].status = IRQ_DISABLED; - irq_desc[10].action = 0; - irq_desc[10].depth = 1; - - disable_cqreek_irq(10); - } -} - diff --git a/arch/sh/boards/cqreek/setup.c b/arch/sh/boards/cqreek/setup.c deleted file mode 100644 index eff4ed93599..00000000000 --- a/arch/sh/boards/cqreek/setup.c +++ /dev/null @@ -1,100 +0,0 @@ -/* $Id: setup.c,v 1.5 2003/08/04 01:51:58 lethal Exp $ - * - * arch/sh/kernel/setup_cqreek.c - * - * Copyright (C) 2000 Niibe Yutaka - * - * CqREEK IDE/ISA Bridge Support. - * - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/irq.h> - -#include <asm/mach/cqreek.h> -#include <asm/machvec.h> -#include <asm/io.h> -#include <asm/io_generic.h> -#include <asm/irq.h> -#include <asm/rtc.h> - -#define IDE_OFFSET 0xA4000000UL -#define ISA_OFFSET 0xA4A00000UL - -const char *get_system_type(void) -{ - return "CqREEK"; -} - -static unsigned long cqreek_port2addr(unsigned long port) -{ - if (0x0000<=port && port<=0x0040) - return IDE_OFFSET + port; - if ((0x01f0<=port && port<=0x01f7) || port == 0x03f6) - return IDE_OFFSET + port; - - return ISA_OFFSET + port; -} - -/* - * The Machine Vector - */ -struct sh_machine_vector mv_cqreek __initmv = { -#if defined(CONFIG_CPU_SH4) - .mv_nr_irqs = 48, -#elif defined(CONFIG_CPU_SUBTYPE_SH7708) - .mv_nr_irqs = 32, -#elif defined(CONFIG_CPU_SUBTYPE_SH7709) - .mv_nr_irqs = 61, -#endif - - .mv_init_irq = init_cqreek_IRQ, - - .mv_isa_port2addr = cqreek_port2addr, -}; -ALIAS_MV(cqreek) - -/* - * Initialize the board - */ -void __init platform_setup(void) -{ - int i; -/* udelay is not available at setup time yet... */ -#define DELAY() do {for (i=0; i<10000; i++) ctrl_inw(0xa0000000);} while(0) - - if ((inw (BRIDGE_FEATURE) & 1)) { /* We have IDE interface */ - outw_p(0, BRIDGE_IDE_INTR_LVL); - outw_p(0, BRIDGE_IDE_INTR_MASK); - - outw_p(0, BRIDGE_IDE_CTRL); - DELAY(); - - outw_p(0x8000, BRIDGE_IDE_CTRL); - DELAY(); - - outw_p(0xffff, BRIDGE_IDE_INTR_STAT); /* Clear interrupt status */ - outw_p(0x0f-14, BRIDGE_IDE_INTR_LVL); /* Use 14 IPR */ - outw_p(1, BRIDGE_IDE_INTR_MASK); /* Enable interrupt */ - cqreek_has_ide=1; - } - - if ((inw (BRIDGE_FEATURE) & 2)) { /* We have ISA interface */ - outw_p(0, BRIDGE_ISA_INTR_LVL); - outw_p(0, BRIDGE_ISA_INTR_MASK); - - outw_p(0, BRIDGE_ISA_CTRL); - DELAY(); - outw_p(0x8000, BRIDGE_ISA_CTRL); - DELAY(); - - outw_p(0xffff, BRIDGE_ISA_INTR_STAT); /* Clear interrupt status */ - outw_p(0x0f-10, BRIDGE_ISA_INTR_LVL); /* Use 10 IPR */ - outw_p(0xfff8, BRIDGE_ISA_INTR_MASK); /* Enable interrupt */ - cqreek_has_isa=1; - } - - printk(KERN_INFO "CqREEK Setup (IDE=%d, ISA=%d)...done\n", cqreek_has_ide, cqreek_has_isa); -} - diff --git a/arch/sh/boards/dmida/Makefile b/arch/sh/boards/dmida/Makefile deleted file mode 100644 index 75999aa0a2d..00000000000 --- a/arch/sh/boards/dmida/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for the DataMyte Industrial Digital Assistant(tm) specific parts -# of the kernel -# - -obj-y := mach.o - diff --git a/arch/sh/boards/dmida/mach.c b/arch/sh/boards/dmida/mach.c deleted file mode 100644 index d03a25f989c..00000000000 --- a/arch/sh/boards/dmida/mach.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * linux/arch/sh/boards/dmida/mach.c - * - * by Greg Banks <gbanks@pocketpenguins.com> - * (c) 2000 PocketPenguins Inc - * - * Derived from mach_hp600.c, which bore the message: - * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * Machine vector for the DataMyte Industrial Digital Assistant(tm). - * See http://www.dmida.com - * - */ - -#include <linux/init.h> - -#include <asm/machvec.h> -#include <asm/rtc.h> -#include <asm/machvec_init.h> - -#include <asm/io.h> -#include <asm/hd64465/hd64465.h> -#include <asm/irq.h> - -/* - * The Machine Vector - */ - -struct sh_machine_vector mv_dmida __initmv = { - .mv_nr_irqs = HD64465_IRQ_BASE+HD64465_IRQ_NUM, - - .mv_inb = hd64465_inb, - .mv_inw = hd64465_inw, - .mv_inl = hd64465_inl, - .mv_outb = hd64465_outb, - .mv_outw = hd64465_outw, - .mv_outl = hd64465_outl, - - .mv_inb_p = hd64465_inb_p, - .mv_inw_p = hd64465_inw, - .mv_inl_p = hd64465_inl, - .mv_outb_p = hd64465_outb_p, - .mv_outw_p = hd64465_outw, - .mv_outl_p = hd64465_outl, - - .mv_insb = hd64465_insb, - .mv_insw = hd64465_insw, - .mv_insl = hd64465_insl, - .mv_outsb = hd64465_outsb, - .mv_outsw = hd64465_outsw, - .mv_outsl = hd64465_outsl, - - .mv_irq_demux = hd64465_irq_demux, -}; -ALIAS_MV(dmida) - diff --git a/arch/sh/boards/dreamcast/irq.c b/arch/sh/boards/dreamcast/irq.c index b10a6b11c03..5bf01f86c20 100644 --- a/arch/sh/boards/dreamcast/irq.c +++ b/arch/sh/boards/dreamcast/irq.c @@ -10,7 +10,6 @@ */ #include <linux/irq.h> - #include <asm/io.h> #include <asm/irq.h> #include <asm/dreamcast/sysasic.h> @@ -26,10 +25,10 @@ event. There are three 32-bit ESRs located at 0xa05f8900 - 0xa05f6908. Event - types can be found in include/asm-sh/dc_sysasic.h. There are three groups - of EMRs that parallel the ESRs. Each EMR group corresponds to an IRQ, so - 0xa05f6910 - 0xa05f6918 triggers IRQ 13, 0xa05f6920 - 0xa05f6928 triggers - IRQ 11, and 0xa05f6930 - 0xa05f6938 triggers IRQ 9. + types can be found in include/asm-sh/dreamcast/sysasic.h. There are three + groups of EMRs that parallel the ESRs. Each EMR group corresponds to an + IRQ, so 0xa05f6910 - 0xa05f6918 triggers IRQ 13, 0xa05f6920 - 0xa05f6928 + triggers IRQ 11, and 0xa05f6930 - 0xa05f6938 triggers IRQ 9. In the kernel, these events are mapped to virtual IRQs so that drivers can respond to them as they would a normal interrupt. In order to keep this @@ -57,29 +56,23 @@ /* Disable the hardware event by masking its bit in its EMR */ static inline void disable_systemasic_irq(unsigned int irq) { - unsigned long flags; __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2); __u32 mask; - local_irq_save(flags); mask = inl(emr); mask &= ~(1 << EVENT_BIT(irq)); outl(mask, emr); - local_irq_restore(flags); } /* Enable the hardware event by setting its bit in its EMR */ static inline void enable_systemasic_irq(unsigned int irq) { - unsigned long flags; __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2); __u32 mask; - local_irq_save(flags); mask = inl(emr); mask |= (1 << EVENT_BIT(irq)); outl(mask, emr); - local_irq_restore(flags); } /* Acknowledge a hardware event by writing its bit back to its ESR */ diff --git a/arch/sh/boards/dreamcast/rtc.c b/arch/sh/boards/dreamcast/rtc.c index 379de162913..b3a876a3b85 100644 --- a/arch/sh/boards/dreamcast/rtc.c +++ b/arch/sh/boards/dreamcast/rtc.c @@ -1,4 +1,5 @@ -/* arch/sh/kernel/rtc-aica.c +/* + * arch/sh/boards/dreamcast/rtc.c * * Dreamcast AICA RTC routines. * @@ -10,15 +11,12 @@ */ #include <linux/time.h> - +#include <asm/rtc.h> #include <asm/io.h> -extern void (*rtc_get_time)(struct timespec *); -extern int (*rtc_set_time)(const time_t); - /* The AICA RTC has an Epoch of 1/1/1950, so we must subtract 20 years (in - seconds to get the standard Unix Epoch when getting the time, and add 20 - years when setting the time. */ + seconds) to get the standard Unix Epoch when getting the time, and add + 20 years when setting the time. */ #define TWENTY_YEARS ((20 * 365LU + 5) * 86400) /* The AICA RTC is represented by a 32-bit seconds counter stored in 2 16-bit @@ -32,7 +30,8 @@ extern int (*rtc_set_time)(const time_t); * * Grabs the current RTC seconds counter and adjusts it to the Unix Epoch. */ -void aica_rtc_gettimeofday(struct timespec *ts) { +void aica_rtc_gettimeofday(struct timespec *ts) +{ unsigned long val1, val2; do { @@ -55,7 +54,8 @@ void aica_rtc_gettimeofday(struct timespec *ts) { * * Adjusts the given @tv to the AICA Epoch and sets the RTC seconds counter. */ -int aica_rtc_settimeofday(const time_t secs) { +int aica_rtc_settimeofday(const time_t secs) +{ unsigned long val1, val2; unsigned long adj = secs + TWENTY_YEARS; @@ -75,7 +75,7 @@ int aica_rtc_settimeofday(const time_t secs) { void aica_time_init(void) { - rtc_get_time = aica_rtc_gettimeofday; - rtc_set_time = aica_rtc_settimeofday; + rtc_sh_get_time = aica_rtc_gettimeofday; + rtc_sh_set_time = aica_rtc_settimeofday; } diff --git a/arch/sh/boards/dreamcast/setup.c b/arch/sh/boards/dreamcast/setup.c index 0027b80a234..f13017eeeb2 100644 --- a/arch/sh/boards/dreamcast/setup.c +++ b/arch/sh/boards/dreamcast/setup.c @@ -22,41 +22,21 @@ #include <linux/init.h> #include <linux/irq.h> #include <linux/device.h> - #include <asm/io.h> #include <asm/irq.h> +#include <asm/rtc.h> #include <asm/machvec.h> -#include <asm/machvec_init.h> #include <asm/mach/sysasic.h> extern struct hw_interrupt_type systemasic_int; -/* XXX: Move this into it's proper header. */ -extern void (*board_time_init)(void); extern void aica_time_init(void); extern int gapspci_init(void); extern int systemasic_irq_demux(int); -void *dreamcast_consistent_alloc(struct device *, size_t, dma_addr_t *, int); +void *dreamcast_consistent_alloc(struct device *, size_t, dma_addr_t *, gfp_t); int dreamcast_consistent_free(struct device *, size_t, void *, dma_addr_t); -const char *get_system_type(void) -{ - return "Sega Dreamcast"; -} - -struct sh_machine_vector mv_dreamcast __initmv = { - .mv_nr_irqs = NR_IRQS, - - .mv_irq_demux = systemasic_irq_demux, - -#ifdef CONFIG_PCI - .mv_consistent_alloc = dreamcast_consistent_alloc, - .mv_consistent_free = dreamcast_consistent_free, -#endif -}; -ALIAS_MV(dreamcast) - -int __init platform_setup(void) +static void __init dreamcast_setup(char **cmdline_p) { int i; @@ -78,6 +58,16 @@ int __init platform_setup(void) if (gapspci_init() < 0) printk(KERN_WARNING "GAPSPCI was not detected.\n"); #endif - - return 0; } + +struct sh_machine_vector mv_dreamcast __initmv = { + .mv_name = "Sega Dreamcast", + .mv_setup = dreamcast_setup, + .mv_irq_demux = systemasic_irq_demux, + +#ifdef CONFIG_PCI + .mv_consistent_alloc = dreamcast_consistent_alloc, + .mv_consistent_free = dreamcast_consistent_free, +#endif +}; +ALIAS_MV(dreamcast) diff --git a/arch/sh/boards/ec3104/setup.c b/arch/sh/boards/ec3104/setup.c index 4b3ef16a0e9..902bc975a13 100644 --- a/arch/sh/boards/ec3104/setup.c +++ b/arch/sh/boards/ec3104/setup.c @@ -21,22 +21,36 @@ #include <linux/init.h> #include <linux/irq.h> #include <linux/types.h> - #include <asm/io.h> #include <asm/irq.h> #include <asm/machvec.h> #include <asm/mach/ec3104.h> -const char *get_system_type(void) +static void __init ec3104_setup(char **cmdline_p) { - return "EC3104"; + char str[8]; + int i; + + for (i=0; i<8; i++) + str[i] = ctrl_readb(EC3104_BASE + i); + + for (i = EC3104_IRQBASE; i < EC3104_IRQBASE + 32; i++) + irq_desc[i].handler = &ec3104_int; + + printk("initializing EC3104 \"%.8s\" at %08x, IRQ %d, IRQ base %d\n", + str, EC3104_BASE, EC3104_IRQ, EC3104_IRQBASE); + + /* mask all interrupts. this should have been done by the boot + * loader for us but we want to be sure ... */ + ctrl_writel(0xffffffff, EC3104_IMR); } /* * The Machine Vector */ - struct sh_machine_vector mv_ec3104 __initmv = { + .mv_name = "EC3104", + .mv_setup = ec3104_setup, .mv_nr_irqs = 96, .mv_inb = ec3104_inb, @@ -48,31 +62,4 @@ struct sh_machine_vector mv_ec3104 __initmv = { .mv_irq_demux = ec3104_irq_demux, }; - ALIAS_MV(ec3104) - -int __init platform_setup(void) -{ - char str[8]; - int i; - - if (0) - return 0; - - for (i=0; i<8; i++) - str[i] = ctrl_readb(EC3104_BASE + i); - - for (i = EC3104_IRQBASE; i < EC3104_IRQBASE + 32; i++) - irq_desc[i].chip = &ec3104_int; - - printk("initializing EC3104 \"%.8s\" at %08x, IRQ %d, IRQ base %d\n", - str, EC3104_BASE, EC3104_IRQ, EC3104_IRQBASE); - - - /* mask all interrupts. this should have been done by the boot - * loader for us but we want to be sure ... */ - ctrl_writel(0xffffffff, EC3104_IMR); - - return 0; -} - diff --git a/arch/sh/boards/harp/Makefile b/arch/sh/boards/harp/Makefile deleted file mode 100644 index eb753d31812..00000000000 --- a/arch/sh/boards/harp/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for STMicroelectronics board specific parts of the kernel -# - -obj-y := irq.o setup.o mach.o led.o - -obj-$(CONFIG_PCI) += pcidma.o - diff --git a/arch/sh/boards/harp/irq.c b/arch/sh/boards/harp/irq.c deleted file mode 100644 index 96bb41c9fc5..00000000000 --- a/arch/sh/boards/harp/irq.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * Looks after interrupts on the HARP board. - * - * Bases on the IPR irq system - */ - -#include <linux/init.h> -#include <linux/irq.h> - -#include <asm/system.h> -#include <asm/io.h> -#include <asm/harp/harp.h> - - -#define NUM_EXTERNAL_IRQS 16 - -// Early versions of the STB1 Overdrive required this nasty frig -//#define INVERT_INTMASK_WRITES - -static void enable_harp_irq(unsigned int irq); -static void disable_harp_irq(unsigned int irq); - -/* shutdown is same as "disable" */ -#define shutdown_harp_irq disable_harp_irq - -static void mask_and_ack_harp(unsigned int); -static void end_harp_irq(unsigned int irq); - -static unsigned int startup_harp_irq(unsigned int irq) -{ - enable_harp_irq(irq); - return 0; /* never anything pending */ -} - -static struct hw_interrupt_type harp_irq_type = { - .typename = "Harp-IRQ", - .startup = startup_harp_irq, - .shutdown = shutdown_harp_irq, - .enable = enable_harp_irq, - .disable = disable_harp_irq, - .ack = mask_and_ack_harp, - .end = end_harp_irq -}; - -static void disable_harp_irq(unsigned int irq) -{ - unsigned val, flags; - unsigned maskReg; - unsigned mask; - int pri; - - if (irq < 0 || irq >= NUM_EXTERNAL_IRQS) - return; - - pri = 15 - irq; - - if (pri < 8) { - maskReg = EPLD_INTMASK0; - } else { - maskReg = EPLD_INTMASK1; - pri -= 8; - } - - local_irq_save(flags); - mask = ctrl_inl(maskReg); - mask &= (~(1 << pri)); -#if defined(INVERT_INTMASK_WRITES) - mask ^= 0xff; -#endif - ctrl_outl(mask, maskReg); - local_irq_restore(flags); -} - -static void enable_harp_irq(unsigned int irq) -{ - unsigned flags; - unsigned maskReg; - unsigned mask; - int pri; - - if (irq < 0 || irq >= NUM_EXTERNAL_IRQS) - return; - - pri = 15 - irq; - - if (pri < 8) { - maskReg = EPLD_INTMASK0; - } else { - maskReg = EPLD_INTMASK1; - pri -= 8; - } - - local_irq_save(flags); - mask = ctrl_inl(maskReg); - - - mask |= (1 << pri); - -#if defined(INVERT_INTMASK_WRITES) - mask ^= 0xff; -#endif - ctrl_outl(mask, maskReg); - - local_irq_restore(flags); -} - -/* This functions sets the desired irq handler to be an overdrive type */ -static void __init make_harp_irq(unsigned int irq) -{ - disable_irq_nosync(irq); - irq_desc[irq].chip = &harp_irq_type; - disable_harp_irq(irq); -} - -static void mask_and_ack_harp(unsigned int irq) -{ - disable_harp_irq(irq); -} - -static void end_harp_irq(unsigned int irq) -{ - enable_harp_irq(irq); -} - -void __init init_harp_irq(void) -{ - int i; - -#if !defined(INVERT_INTMASK_WRITES) - // On the harp these are set to enable an interrupt - ctrl_outl(0x00, EPLD_INTMASK0); - ctrl_outl(0x00, EPLD_INTMASK1); -#else - // On the Overdrive the data is inverted before being stored in the reg - ctrl_outl(0xff, EPLD_INTMASK0); - ctrl_outl(0xff, EPLD_INTMASK1); -#endif - - for (i = 0; i < NUM_EXTERNAL_IRQS; i++) { - make_harp_irq(i); - } -} diff --git a/arch/sh/boards/harp/led.c b/arch/sh/boards/harp/led.c deleted file mode 100644 index aeb7b392b19..00000000000 --- a/arch/sh/boards/harp/led.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * linux/arch/sh/stboards/led.c - * - * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com> - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * This file contains ST40STB1 HARP and compatible code. - */ - -#include <asm/io.h> -#include <asm/harp/harp.h> - -/* Harp: Flash LD10 (front pannel) connected to EPLD (IC8) */ -/* Overdrive: Flash LD1 (front panel) connected to EPLD (IC4) */ -/* Works for HARP and overdrive */ -static void mach_led(int position, int value) -{ - if (value) { - ctrl_outl(EPLD_LED_ON, EPLD_LED); - } else { - ctrl_outl(EPLD_LED_OFF, EPLD_LED); - } -} - -#ifdef CONFIG_HEARTBEAT - -#include <linux/sched.h> - -/* acts like an actual heart beat -- ie thump-thump-pause... */ -void heartbeat_harp(void) -{ - static unsigned cnt = 0, period = 0, dist = 0; - - if (cnt == 0 || cnt == dist) - mach_led( -1, 1); - else if (cnt == 7 || cnt == dist+7) - mach_led( -1, 0); - - if (++cnt > period) { - cnt = 0; - /* The hyperbolic function below modifies the heartbeat period - * length in dependency of the current (5min) load. It goes - * through the points f(0)=126, f(1)=86, f(5)=51, - * f(inf)->30. */ - period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30; - dist = period / 4; - } -} -#endif diff --git a/arch/sh/boards/harp/mach.c b/arch/sh/boards/harp/mach.c deleted file mode 100644 index a946dd1674c..00000000000 --- a/arch/sh/boards/harp/mach.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * linux/arch/sh/boards/harp/mach.c - * - * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * Machine vector for the STMicroelectronics STB1 HARP and compatible boards - */ - -#include <linux/init.h> - -#include <asm/machvec.h> -#include <asm/rtc.h> -#include <asm/machvec_init.h> -#include <asm/hd64465/io.h> -#include <asm/hd64465/hd64465.h> - -void setup_harp(void); -void init_harp_irq(void); -void heartbeat_harp(void); - -/* - * The Machine Vector - */ - -struct sh_machine_vector mv_harp __initmv = { - .mv_nr_irqs = 89 + HD64465_IRQ_NUM, - - .mv_inb = hd64465_inb, - .mv_inw = hd64465_inw, - .mv_inl = hd64465_inl, - .mv_outb = hd64465_outb, - .mv_outw = hd64465_outw, - .mv_outl = hd64465_outl, - - .mv_inb_p = hd64465_inb_p, - .mv_inw_p = hd64465_inw, - .mv_inl_p = hd64465_inl, - .mv_outb_p = hd64465_outb_p, - .mv_outw_p = hd64465_outw, - .mv_outl_p = hd64465_outl, - - .mv_insb = hd64465_insb, - .mv_insw = hd64465_insw, - .mv_insl = hd64465_insl, - .mv_outsb = hd64465_outsb, - .mv_outsw = hd64465_outsw, - .mv_outsl = hd64465_outsl, - - .mv_isa_port2addr = hd64465_isa_port2addr, - -#ifdef CONFIG_PCI - .mv_init_irq = init_harp_irq, -#endif -#ifdef CONFIG_HEARTBEAT - .mv_heartbeat = heartbeat_harp, -#endif -}; - -ALIAS_MV(harp) diff --git a/arch/sh/boards/harp/pcidma.c b/arch/sh/boards/harp/pcidma.c deleted file mode 100644 index 475311390fd..00000000000 --- a/arch/sh/boards/harp/pcidma.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2001 David J. Mckay (david.mckay@st.com) - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * Dynamic DMA mapping support. - */ - -#include <linux/types.h> -#include <linux/mm.h> -#include <linux/string.h> -#include <linux/pci.h> -#include <asm/io.h> -#include <asm/addrspace.h> - - -void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, - dma_addr_t * dma_handle) -{ - void *ret; - int gfp = GFP_ATOMIC; - - ret = (void *) __get_free_pages(gfp, get_order(size)); - - if (ret != NULL) { - /* Is it neccessary to do the memset? */ - memset(ret, 0, size); - *dma_handle = virt_to_bus(ret); - } - /* We must flush the cache before we pass it on to the device */ - flush_cache_all(); - return P2SEGADDR(ret); -} - -void pci_free_consistent(struct pci_dev *hwdev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ - unsigned long p1addr=P1SEGADDR((unsigned long)vaddr); - - free_pages(p1addr, get_order(size)); -} diff --git a/arch/sh/boards/harp/setup.c b/arch/sh/boards/harp/setup.c deleted file mode 100644 index 886e450ab63..00000000000 --- a/arch/sh/boards/harp/setup.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * arch/sh/stboard/setup.c - * - * Copyright (C) 2001 Stuart Menefy (stuart.menefy@st.com) - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * STMicroelectronics ST40STB1 HARP and compatible support. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <asm/io.h> -#include <asm/harp/harp.h> - -const char *get_system_type(void) -{ - return "STB1 Harp"; -} - -/* - * Initialize the board - */ -int __init platform_setup(void) -{ -#ifdef CONFIG_SH_STB1_HARP - unsigned long ic8_version, ic36_version; - - ic8_version = ctrl_inl(EPLD_REVID2); - ic36_version = ctrl_inl(EPLD_REVID1); - - printk("STMicroelectronics STB1 HARP initialisaton\n"); - printk("EPLD versions: IC8: %d.%02d, IC36: %d.%02d\n", - (ic8_version >> 4) & 0xf, ic8_version & 0xf, - (ic36_version >> 4) & 0xf, ic36_version & 0xf); -#elif defined(CONFIG_SH_STB1_OVERDRIVE) - unsigned long version; - - version = ctrl_inl(EPLD_REVID); - - printk("STMicroelectronics STB1 Overdrive initialisaton\n"); - printk("EPLD version: %d.%02d\n", - (version >> 4) & 0xf, version & 0xf); -#else -#error Undefined machine -#endif - - /* Currently all STB1 chips have problems with the sleep instruction, - * so disable it here. - */ - disable_hlt(); - - return 0; -} - -/* - * pcibios_map_platform_irq - * - * This is board specific and returns the IRQ for a given PCI device. - * It is used by the PCI code (arch/sh/kernel/st40_pci*) - * - */ - -#define HARP_PCI_IRQ 1 -#define HARP_BRIDGE_IRQ 2 -#define OVERDRIVE_SLOT0_IRQ 0 - - -int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - switch (slot) { -#ifdef CONFIG_SH_STB1_HARP - case 2: /*This is the PCI slot on the */ - return HARP_PCI_IRQ; - case 1: /* this is the bridge */ - return HARP_BRIDGE_IRQ; -#elif defined(CONFIG_SH_STB1_OVERDRIVE) - case 1: - case 2: - case 3: - return slot - 1; -#else -#error Unknown board -#endif - default: - return -1; - } -} - diff --git a/arch/sh/boards/hp6xx/Makefile b/arch/sh/boards/hp6xx/Makefile index 927fe0aa5df..ff1b7f5b4e9 100644 --- a/arch/sh/boards/hp6xx/Makefile +++ b/arch/sh/boards/hp6xx/Makefile @@ -2,5 +2,6 @@ # Makefile for the HP6xx specific parts of the kernel # -obj-y := mach.o setup.o - +obj-y := setup.o +obj-$(CONFIG_PM) += pm.o pm_wakeup.o +obj-$(CONFIG_APM) += hp6xx_apm.o diff --git a/arch/sh/boards/hp6xx/hp6xx_apm.c b/arch/sh/boards/hp6xx/hp6xx_apm.c new file mode 100644 index 00000000000..ad0e712c29f --- /dev/null +++ b/arch/sh/boards/hp6xx/hp6xx_apm.c @@ -0,0 +1,123 @@ +/* + * bios-less APM driver for hp680 + * + * Copyright 2005 (c) Andriy Skulysh <askulysh@gmail.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License. + */ +#include <linux/config.h> +#include <linux/module.h> +#include <linux/apm_bios.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <asm/io.h> +#include <asm/apm.h> +#include <asm/adc.h> +#include <asm/hp6xx/hp6xx.h> + +#define SH7709_PGDR 0xa400012c + +#define APM_CRITICAL 10 +#define APM_LOW 30 + +#define HP680_BATTERY_MAX 875 +#define HP680_BATTERY_MIN 600 +#define HP680_BATTERY_AC_ON 900 + +#define MODNAME "hp6x0_apm" + +static int hp6x0_apm_get_info(char *buf, char **start, off_t fpos, int length) +{ + u8 pgdr; + char *p; + int battery_status; + int battery_flag; + int ac_line_status; + int time_units = APM_BATTERY_LIFE_UNKNOWN; + + int battery = adc_single(ADC_CHANNEL_BATTERY); + int backup = adc_single(ADC_CHANNEL_BACKUP); + int charging = adc_single(ADC_CHANNEL_CHARGE); + int percentage; + + percentage = 100 * (battery - HP680_BATTERY_MIN) / + (HP680_BATTERY_MAX - HP680_BATTERY_MIN); + + ac_line_status = (battery > HP680_BATTERY_AC_ON) ? + APM_AC_ONLINE : APM_AC_OFFLINE; + + p = buf; + + pgdr = ctrl_inb(SH7709_PGDR); + if (pgdr & PGDR_MAIN_BATTERY_OUT) { + battery_status = APM_BATTERY_STATUS_NOT_PRESENT; + battery_flag = 0x80; + percentage = -1; + } else if (charging < 8 ) { + battery_status = APM_BATTERY_STATUS_CHARGING; + battery_flag = 0x08; + ac_line_status = 0xff; + } else if (percentage <= APM_CRITICAL) { + battery_status = APM_BATTERY_STATUS_CRITICAL; + battery_flag = 0x04; + } else if (percentage <= APM_LOW) { + battery_status = APM_BATTERY_STATUS_LOW; + battery_flag = 0x02; + } else { + battery_status = APM_BATTERY_STATUS_HIGH; + battery_flag = 0x01; + } + + p += sprintf(p, "1.0 1.2 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n", + APM_32_BIT_SUPPORT, + ac_line_status, + battery_status, + battery_flag, + percentage, + time_units, + "min"); + p += sprintf(p, "bat=%d backup=%d charge=%d\n", + battery, backup, charging); + + return p - buf; +} + +static irqreturn_t hp6x0_apm_interrupt(int irq, void *dev, struct pt_regs *regs) +{ + if (!apm_suspended) + apm_queue_event(APM_USER_SUSPEND); + + return IRQ_HANDLED; +} + +static int __init hp6x0_apm_init(void) +{ + int ret; + + ret = request_irq(HP680_BTN_IRQ, hp6x0_apm_interrupt, + SA_INTERRUPT, MODNAME, 0); + if (unlikely(ret < 0)) { + printk(KERN_ERR MODNAME ": IRQ %d request failed\n", + HP680_BTN_IRQ); + return ret; + } + + apm_get_info = hp6x0_apm_get_info; + + return ret; +} + +static void __exit hp6x0_apm_exit(void) +{ + free_irq(HP680_BTN_IRQ, 0); + apm_get_info = 0; +} + +module_init(hp6x0_apm_init); +module_exit(hp6x0_apm_exit); + +MODULE_AUTHOR("Adriy Skulysh"); +MODULE_DESCRIPTION("hp6xx Advanced Power Management"); +MODULE_LICENSE("GPL"); diff --git a/arch/sh/boards/hp6xx/pm.c b/arch/sh/boards/hp6xx/pm.c new file mode 100644 index 00000000000..0e501bcbd7a --- /dev/null +++ b/arch/sh/boards/hp6xx/pm.c @@ -0,0 +1,88 @@ +/* + * hp6x0 Power Management Routines + * + * Copyright (c) 2006 Andriy Skulysh <askulsyh@gmail.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/suspend.h> +#include <linux/errno.h> +#include <linux/time.h> +#include <asm/io.h> +#include <asm/hd64461.h> +#include <asm/hp6xx/hp6xx.h> +#include <asm/cpu/dac.h> +#include <asm/pm.h> + +#define STBCR 0xffffff82 +#define STBCR2 0xffffff88 + +static int hp6x0_pm_enter(suspend_state_t state) +{ + u8 stbcr, stbcr2; +#ifdef CONFIG_HD64461_ENABLER + u8 scr; + u16 hd64461_stbcr; +#endif + + if (state != PM_SUSPEND_MEM) + return -EINVAL; + +#ifdef CONFIG_HD64461_ENABLER + outb(0, HD64461_PCC1CSCIER); + + scr = inb(HD64461_PCC1SCR); + scr |= HD64461_PCCSCR_VCC1; + outb(scr, HD64461_PCC1SCR); + + hd64461_stbcr = inw(HD64461_STBCR); + hd64461_stbcr |= HD64461_STBCR_SPC1ST; + outw(hd64461_stbcr, HD64461_STBCR); +#endif + + ctrl_outb(0x1f, DACR); + + stbcr = ctrl_inb(STBCR); + ctrl_outb(0x01, STBCR); + + stbcr2 = ctrl_inb(STBCR2); + ctrl_outb(0x7f , STBCR2); + + outw(0xf07f, HD64461_SCPUCR); + + pm_enter(); + + outw(0, HD64461_SCPUCR); + ctrl_outb(stbcr, STBCR); + ctrl_outb(stbcr2, STBCR2); + +#ifdef CONFIG_HD64461_ENABLER + hd64461_stbcr = inw(HD64461_STBCR); + hd64461_stbcr &= ~HD64461_STBCR_SPC1ST; + outw(hd64461_stbcr, HD64461_STBCR); + + outb(0x4c, HD64461_PCC1CSCIER); + outb(0x00, HD64461_PCC1CSCR); +#endif + + return 0; +} + +/* + * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk. + */ +static struct pm_ops hp6x0_pm_ops = { + .pm_disk_mode = PM_DISK_FIRMWARE, + .enter = hp6x0_pm_enter, +}; + +static int __init hp6x0_pm_init(void) +{ + pm_set_ops(&hp6x0_pm_ops); + return 0; +} + +late_initcall(hp6x0_pm_init); diff --git a/arch/sh/boards/hp6xx/pm_wakeup.S b/arch/sh/boards/hp6xx/pm_wakeup.S new file mode 100644 index 00000000000..45e9bf0b911 --- /dev/null +++ b/arch/sh/boards/hp6xx/pm_wakeup.S @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2006 Andriy Skulysh <askulsyh@gmail.com> + * + * 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/linkage.h> +#include <asm/cpu/mmu_context.h> + +#define k0 r0 +#define k1 r1 +#define k2 r2 +#define k3 r3 +#define k4 r4 + +/* + * Kernel mode register usage: + * k0 scratch + * k1 scratch + * k2 scratch (Exception code) + * k3 scratch (Return address) + * k4 scratch + * k5 reserved + * k6 Global Interrupt Mask (0--15 << 4) + * k7 CURRENT_THREAD_INFO (pointer to current thread info) + */ + +ENTRY(wakeup_start) +! clear STBY bit + mov #-126, k2 + and #127, k0 + mov.b k0, @k2 +! enable refresh + mov.l 5f, k1 + mov.w 6f, k0 + mov.w k0, @k1 +! jump to handler + mov.l 2f, k2 + mov.l 3f, k3 + mov.l @k2, k2 + + mov.l 4f, k1 + jmp @k1 + nop + + .align 2 +1: .long EXPEVT +2: .long INTEVT +3: .long ret_from_irq +4: .long handle_exception +5: .long 0xffffff68 +6: .word 0x0524 + +ENTRY(wakeup_end) + nop diff --git a/arch/sh/boards/hp6xx/setup.c b/arch/sh/boards/hp6xx/setup.c index 71f315663cc..60ab17ad605 100644 --- a/arch/sh/boards/hp6xx/setup.c +++ b/arch/sh/boards/hp6xx/setup.c @@ -8,22 +8,22 @@ * * Setup code for an HP680 (internal peripherials only) */ - +#include <linux/types.h> #include <linux/init.h> -#include <asm/io.h> #include <asm/hd64461.h> +#include <asm/io.h> +#include <asm/irq.h> #include <asm/hp6xx/hp6xx.h> #include <asm/cpu/dac.h> -const char *get_system_type(void) -{ - return "HP6xx"; -} +#define SCPCR 0xa4000116 +#define SCPDR 0xa4000136 -int __init platform_setup(void) +static void __init hp6xx_setup(char **cmdline_p) { u8 v8; u16 v; + v = inw(HD64461_STBCR); v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST | HD64461_STBCR_STM1ST | HD64461_STBCR_STM0ST | @@ -50,5 +50,51 @@ int __init platform_setup(void) v8 &= ~DACR_DAE; ctrl_outb(v8,DACR); - return 0; + v8 = ctrl_inb(SCPDR); + v8 |= SCPDR_TS_SCAN_X | SCPDR_TS_SCAN_Y; + v8 &= ~SCPDR_TS_SCAN_ENABLE; + ctrl_outb(v8, SCPDR); + + v = ctrl_inw(SCPCR); + v &= ~SCPCR_TS_MASK; + v |= SCPCR_TS_ENABLE; + ctrl_outw(v, SCPCR); } + +/* + * XXX: This is stupid, we should have a generic machine vector for the cchips + * and just wrap the platform setup code in to this, as it's the only thing + * that ends up being different. + */ +struct sh_machine_vector mv_hp6xx __initmv = { + .mv_name = "hp6xx", + .mv_setup = hp6xx_setup, + .mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM, + + .mv_inb = hd64461_inb, + .mv_inw = hd64461_inw, + .mv_inl = hd64461_inl, + .mv_outb = hd64461_outb, + .mv_outw = hd64461_outw, + .mv_outl = hd64461_outl, + + .mv_inb_p = hd64461_inb_p, + .mv_inw_p = hd64461_inw, + .mv_inl_p = hd64461_inl, + .mv_outb_p = hd64461_outb_p, + .mv_outw_p = hd64461_outw, + .mv_outl_p = hd64461_outl, + + .mv_insb = hd64461_insb, + .mv_insw = hd64461_insw, + .mv_insl = hd64461_insl, + .mv_outsb = hd64461_outsb, + .mv_outsw = hd64461_outsw, + .mv_outsl = hd64461_outsl, + + .mv_readw = hd64461_readw, + .mv_writew = hd64461_writew, + + .mv_irq_demux = hd64461_irq_demux, +}; +ALIAS_MV(hp6xx) diff --git a/arch/sh/boards/landisk/Makefile b/arch/sh/boards/landisk/Makefile new file mode 100644 index 00000000000..89e4beb2ad4 --- /dev/null +++ b/arch/sh/boards/landisk/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for I-O DATA DEVICE, INC. "LANDISK Series" +# + +obj-y := setup.o io.o irq.o rtc.o landisk_pwb.o diff --git a/arch/sh/boards/landisk/io.c b/arch/sh/boards/landisk/io.c new file mode 100644 index 00000000000..92498b4947d --- /dev/null +++ b/arch/sh/boards/landisk/io.c @@ -0,0 +1,250 @@ +/* + * arch/sh/boards/landisk/io.c + * + * Copyright (C) 2001 Ian da Silva, Jeremy Siegel + * Based largely on io_se.c. + * + * I/O routine for I-O Data Device, Inc. LANDISK. + * + * Initial version only to support LAN access; some + * placeholder code from io_landisk.c left in with the + * expectation of later SuperIO and PCMCIA access. + */ +/* + * modifed by kogiidena + * 2005.03.03 + */ +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/pci.h> +#include <asm/landisk/iodata_landisk.h> +#include <asm/addrspace.h> +#include <asm/io.h> + +extern void *area5_io_base; /* Area 5 I/O Base address */ +extern void *area6_io_base; /* Area 6 I/O Base address */ + +static inline unsigned long port2adr(unsigned int port) +{ + if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) + if (port == 0x3f6) + return ((unsigned long)area5_io_base + 0x2c); + else + return ((unsigned long)area5_io_base + PA_PIDE_OFFSET + + ((port - 0x1f0) << 1)); + else if ((0x170 <= port && port < 0x178) || port == 0x376) + if (port == 0x376) + return ((unsigned long)area6_io_base + 0x2c); + else + return ((unsigned long)area6_io_base + PA_SIDE_OFFSET + + ((port - 0x170) << 1)); + else + maybebadio((unsigned long)port); + + return port; +} + +/* + * General outline: remap really low stuff [eventually] to SuperIO, + * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) + * is mapped through the PCI IO window. Stuff with high bits (PXSEG) + * should be way beyond the window, and is used w/o translation for + * compatibility. + */ +u8 landisk_inb(unsigned long port) +{ + if (PXSEG(port)) + return ctrl_inb(port); + else if (is_pci_ioaddr(port)) + return ctrl_inb(pci_ioaddr(port)); + + return ctrl_inw(port2adr(port)) & 0xff; +} + +u8 landisk_inb_p(unsigned long port) +{ + u8 v; + + if (PXSEG(port)) + v = ctrl_inb(port); + else if (is_pci_ioaddr(port)) + v = ctrl_inb(pci_ioaddr(port)); + else + v = ctrl_inw(port2adr(port)) & 0xff; + + ctrl_delay(); + + return v; +} + +u16 landisk_inw(unsigned long port) +{ + if (PXSEG(port)) + return ctrl_inw(port); + else if (is_pci_ioaddr(port)) + return ctrl_inw(pci_ioaddr(port)); + else + maybebadio(port); + + return 0; +} + +u32 landisk_inl(unsigned long port) +{ + if (PXSEG(port)) + return ctrl_inl(port); + else if (is_pci_ioaddr(port)) + return ctrl_inl(pci_ioaddr(port)); + else + maybebadio(port); + + return 0; +} + +void landisk_outb(u8 value, unsigned long port) +{ + if (PXSEG(port)) + ctrl_outb(value, port); + else if (is_pci_ioaddr(port)) + ctrl_outb(value, pci_ioaddr(port)); + else + ctrl_outw(value, port2adr(port)); +} + +void landisk_outb_p(u8 value, unsigned long port) +{ + if (PXSEG(port)) + ctrl_outb(value, port); + else if (is_pci_ioaddr(port)) + ctrl_outb(value, pci_ioaddr(port)); + else + ctrl_outw(value, port2adr(port)); + ctrl_delay(); +} + +void landisk_outw(u16 value, unsigned long port) +{ + if (PXSEG(port)) + ctrl_outw(value, port); + else if (is_pci_ioaddr(port)) + ctrl_outw(value, pci_ioaddr(port)); + else + maybebadio(port); +} + +void landisk_outl(u32 value, unsigned long port) +{ + if (PXSEG(port)) + ctrl_outl(value, port); + else if (is_pci_ioaddr(port)) + ctrl_outl(value, pci_ioaddr(port)); + else + maybebadio(port); +} + +void landisk_insb(unsigned long port, void *dst, unsigned long count) +{ + volatile u16 *p; + u8 *buf = dst; + + if (PXSEG(port)) { + while (count--) + *buf++ = *(volatile u8 *)port; + } else if (is_pci_ioaddr(port)) { + volatile u8 *bp = (volatile u8 *)pci_ioaddr(port); + + while (count--) + *buf++ = *bp; + } else { + p = (volatile u16 *)port2adr(port); + while (count--) + *buf++ = *p & 0xff; + } +} + +void landisk_insw(unsigned long port, void *dst, unsigned long count) +{ + volatile u16 *p; + u16 *buf = dst; + + if (PXSEG(port)) + p = (volatile u16 *)port; + else if (is_pci_ioaddr(port)) + p = (volatile u16 *)pci_ioaddr(port); + else + p = (volatile u16 *)port2adr(port); + while (count--) + *buf++ = *p; +} + +void landisk_insl(unsigned long port, void *dst, unsigned long count) +{ + u32 *buf = dst; + + if (is_pci_ioaddr(port)) { + volatile u32 *p = (volatile u32 *)pci_ioaddr(port); + + while (count--) + *buf++ = *p; + } else + maybebadio(port); +} + +void landisk_outsb(unsigned long port, const void *src, unsigned long count) +{ + volatile u16 *p; + const u8 *buf = src; + + if (PXSEG(port)) + while (count--) + ctrl_outb(*buf++, port); + else if (is_pci_ioaddr(port)) { + volatile u8 *bp = (volatile u8 *)pci_ioaddr(port); + + while (count--) + *bp = *buf++; + } else { + p = (volatile u16 *)port2adr(port); + while (count--) + *p = *buf++; + } +} + +void landisk_outsw(unsigned long port, const void *src, unsigned long count) +{ + volatile u16 *p; + const u16 *buf = src; + + if (PXSEG(port)) + p = (volatile u16 *)port; + else if (is_pci_ioaddr(port)) + p = (volatile u16 *)pci_ioaddr(port); + else + p = (volatile u16 *)port2adr(port); + + while (count--) + *p = *buf++; +} + +void landisk_outsl(unsigned long port, const void *src, unsigned long count) +{ + const u32 *buf = src; + + if (is_pci_ioaddr(port)) { + volatile u32 *p = (volatile u32 *)pci_ioaddr(port); + + while (count--) + *p = *buf++; + } else + maybebadio(port); +} + +void __iomem *landisk_ioport_map(unsigned long port, unsigned int size) +{ + if (PXSEG(port)) + return (void __iomem *)port; + else if (is_pci_ioaddr(port)) + return (void __iomem *)pci_ioaddr(port); + + return (void __iomem *)port2adr(port); +} diff --git a/arch/sh/boards/landisk/irq.c b/arch/sh/boards/landisk/irq.c new file mode 100644 index 00000000000..a006d644322 --- /dev/null +++ b/arch/sh/boards/landisk/irq.c @@ -0,0 +1,99 @@ +/* + * arch/sh/boards/landisk/irq.c + * + * Copyright (C) 2001 Ian da Silva, Jeremy Siegel + * Based largely on io_se.c. + * + * I/O routine for I-O Data Device, Inc. LANDISK. + * + * Initial version only to support LAN access; some + * placeholder code from io_landisk.c left in with the + * expectation of later SuperIO and PCMCIA access. + */ +/* + * modified by kogiidena + * 2005.03.03 + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/irq.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/landisk/iodata_landisk.h> + +static void enable_landisk_irq(unsigned int irq); +static void disable_landisk_irq(unsigned int irq); + +/* shutdown is same as "disable" */ +#define shutdown_landisk_irq disable_landisk_irq + +static void ack_landisk_irq(unsigned int irq); +static void end_landisk_irq(unsigned int irq); + +static unsigned int startup_landisk_irq(unsigned int irq) +{ + enable_landisk_irq(irq); + return 0; /* never anything pending */ +} + +static void disable_landisk_irq(unsigned int irq) +{ + unsigned char val; + unsigned char mask = 0xff ^ (0x01 << (irq - 5)); + + /* Set the priority in IPR to 0 */ + val = ctrl_inb(PA_IMASK); + val &= mask; + ctrl_outb(val, PA_IMASK); +} + +static void enable_landisk_irq(unsigned int irq) +{ + unsigned char val; + unsigned char value = (0x01 << (irq - 5)); + + /* Set priority in IPR back to original value */ + val = ctrl_inb(PA_IMASK); + val |= value; + ctrl_outb(val, PA_IMASK); +} + +static void ack_landisk_irq(unsigned int irq) +{ + disable_landisk_irq(irq); +} + +static void end_landisk_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + enable_landisk_irq(irq); +} + +static struct hw_interrupt_type landisk_irq_type = { + .typename = "LANDISK IRQ", + .startup = startup_landisk_irq, + .shutdown = shutdown_landisk_irq, + .enable = enable_landisk_irq, + .disable = disable_landisk_irq, + .ack = ack_landisk_irq, + .end = end_landisk_irq +}; + +static void make_landisk_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + irq_desc[irq].handler = &landisk_irq_type; + disable_landisk_irq(irq); +} + +/* + * Initialize IRQ setting + */ +void __init init_landisk_IRQ(void) +{ + int i; + + for (i = 5; i < 14; i++) + make_landisk_irq(i); +} diff --git a/arch/sh/boards/landisk/landisk_pwb.c b/arch/sh/boards/landisk/landisk_pwb.c new file mode 100644 index 00000000000..e75cb578a28 --- /dev/null +++ b/arch/sh/boards/landisk/landisk_pwb.c @@ -0,0 +1,348 @@ +/* + * arch/sh/boards/landisk/landisk_pwb.c -- driver for the Power control switch. + * + * This driver will also support the I-O DATA Device, Inc. LANDISK Board. + * + * 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. + * + * Copylight (C) 2002 Atom Create Engineering Co., Ltd. + * + * LED control drive function added by kogiidena + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/errno.h> +#include <linux/signal.h> +#include <linux/major.h> +#include <linux/poll.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/sched.h> +#include <linux/timer.h> +#include <linux/interrupt.h> + +#include <asm/system.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/uaccess.h> +#include <asm/landisk/iodata_landisk.h> + +#define SHUTDOWN_BTN_MINOR 1 /* Shutdown button device minor no. */ +#define LED_MINOR 21 /* LED minor no. */ +#define BTN_MINOR 22 /* BUTTON minor no. */ +#define GIO_MINOR 40 /* GIO minor no. */ + +static int openCnt; +static int openCntLED; +static int openCntGio; +static int openCntBtn; +static int landisk_btn; +static int landisk_btnctrlpid; +/* + * Functions prototypes + */ + +static int gio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg); + +static int swdrv_open(struct inode *inode, struct file *filp) +{ + int minor; + + minor = MINOR(inode->i_rdev); + filp->private_data = (void *)minor; + + if (minor == SHUTDOWN_BTN_MINOR) { + if (openCnt > 0) { + return -EALREADY; + } else { + openCnt++; + return 0; + } + } else if (minor == LED_MINOR) { + if (openCntLED > 0) { + return -EALREADY; + } else { + openCntLED++; + return 0; + } + } else if (minor == BTN_MINOR) { + if (openCntBtn > 0) { + return -EALREADY; + } else { + openCntBtn++; + return 0; + } + } else if (minor == GIO_MINOR) { + if (openCntGio > 0) { + return -EALREADY; + } else { + openCntGio++; + return 0; + } + } + return -ENOENT; + +} + +static int swdrv_close(struct inode *inode, struct file *filp) +{ + int minor; + + minor = MINOR(inode->i_rdev); + if (minor == SHUTDOWN_BTN_MINOR) { + openCnt--; + } else if (minor == LED_MINOR) { + openCntLED--; + } else if (minor == BTN_MINOR) { + openCntBtn--; + } else if (minor == GIO_MINOR) { + openCntGio--; + } + return 0; +} + +static int swdrv_read(struct file *filp, char *buff, size_t count, + loff_t * ppos) +{ + int minor; + minor = (int)(filp->private_data); + + if (!access_ok(VERIFY_WRITE, (void *)buff, count)) + return -EFAULT; + + if (minor == SHUTDOWN_BTN_MINOR) { + if (landisk_btn & 0x10) { + put_user(1, buff); + return 1; + } else { + return 0; + } + } + return 0; +} + +static int swdrv_write(struct file *filp, const char *buff, size_t count, + loff_t * ppos) +{ + int minor; + minor = (int)(filp->private_data); + + if (minor == SHUTDOWN_BTN_MINOR) { + return count; + } + return count; +} + +static irqreturn_t sw_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + landisk_btn = (0x0ff & (~ctrl_inb(PA_STATUS))); + disable_irq(IRQ_BUTTON); + disable_irq(IRQ_POWER); + ctrl_outb(0x00, PA_PWRINT_CLR); + + if (landisk_btnctrlpid != 0) { + kill_proc(landisk_btnctrlpid, SIGUSR1, 1); + landisk_btnctrlpid = 0; + } + + return IRQ_HANDLED; +} + +static struct file_operations swdrv_fops = { + .read = swdrv_read, /* read */ + .write = swdrv_write, /* write */ + .open = swdrv_open, /* open */ + .release = swdrv_close, /* release */ + .ioctl = gio_ioctl, /* ioctl */ + +}; + +static char banner[] __initdata = + KERN_INFO "LANDISK and USL-5P Button, LED and GIO driver initialized\n"; + +int __init swdrv_init(void) +{ + int error; + + printk("%s", banner); + + openCnt = 0; + openCntLED = 0; + openCntBtn = 0; + openCntGio = 0; + landisk_btn = 0; + landisk_btnctrlpid = 0; + + if ((error = register_chrdev(SHUTDOWN_BTN_MAJOR, "swdrv", &swdrv_fops))) { + printk(KERN_ERR + "Button, LED and GIO driver:Couldn't register driver, error=%d\n", + error); + return 1; + } + + if (request_irq(IRQ_POWER, sw_interrupt, 0, "SHUTDOWNSWITCH", NULL)) { + printk(KERN_ERR "Unable to get IRQ 11.\n"); + return 1; + } + if (request_irq(IRQ_BUTTON, sw_interrupt, 0, "USL-5P BUTTON", NULL)) { + printk(KERN_ERR "Unable to get IRQ 12.\n"); + return 1; + } + ctrl_outb(0x00, PA_PWRINT_CLR); + + return 0; +} + +module_init(swdrv_init); + +/* + * gio driver + * + */ + +#include <asm/landisk/gio.h> + +static int gio_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + int minor; + unsigned int data, mask; + static unsigned int addr = 0; + + minor = (int)(filp->private_data); + + /* access control */ + if (minor == GIO_MINOR) { + ; + } else if (minor == LED_MINOR) { + if (((cmd & 0x0ff) >= 9) && ((cmd & 0x0ff) < 20)) { + ; + } else { + return -EINVAL; + } + } else if (minor == BTN_MINOR) { + if (((cmd & 0x0ff) >= 20) && ((cmd & 0x0ff) < 30)) { + ; + } else { + return -EINVAL; + } + } else { + return -EINVAL; + } + + if (cmd & 0x01) { /* write */ + if (copy_from_user(&data, (int *)arg, sizeof(int))) { + return -EFAULT; + } + } + + switch (cmd) { + case GIODRV_IOCSGIOSETADDR: /* addres set */ + addr = data; + break; + + case GIODRV_IOCSGIODATA1: /* write byte */ + ctrl_outb((unsigned char)(0x0ff & data), addr); + break; + + case GIODRV_IOCSGIODATA2: /* write word */ + if (addr & 0x01) { + return -EFAULT; + } + ctrl_outw((unsigned short int)(0x0ffff & data), addr); + break; + + case GIODRV_IOCSGIODATA4: /* write long */ + if (addr & 0x03) { + return -EFAULT; + } + ctrl_outl(data, addr); + break; + + case GIODRV_IOCGGIODATA1: /* read byte */ + data = ctrl_inb(addr); + break; + + case GIODRV_IOCGGIODATA2: /* read word */ + if (addr & 0x01) { + return -EFAULT; + } + data = ctrl_inw(addr); + break; + + case GIODRV_IOCGGIODATA4: /* read long */ + if (addr & 0x03) { + return -EFAULT; + } + data = ctrl_inl(addr); + break; + case GIODRV_IOCSGIO_LED: /* write */ + mask = ((data & 0x00ffffff) << 8) + | ((data & 0x0000ffff) << 16) + | ((data & 0x000000ff) << 24); + landisk_ledparam = data & (~mask); + if (landisk_arch == 0) { /* arch == landisk */ + landisk_ledparam &= 0x03030303; + mask = (~(landisk_ledparam >> 22)) & 0x000c; + landisk_ledparam |= mask; + } else { /* arch == usl-5p */ + mask = (landisk_ledparam >> 24) & 0x0001; + landisk_ledparam |= mask; + landisk_ledparam &= 0x007f7f7f; + } + landisk_ledparam |= 0x80; + break; + case GIODRV_IOCGGIO_LED: /* read */ + data = landisk_ledparam; + if (landisk_arch == 0) { /* arch == landisk */ + data &= 0x03030303; + } else { /* arch == usl-5p */ + ; + } + data &= (~0x080); + break; + case GIODRV_IOCSGIO_BUZZER: /* write */ + landisk_buzzerparam = data; + landisk_ledparam |= 0x80; + break; + case GIODRV_IOCGGIO_LANDISK: /* read */ + data = landisk_arch & 0x01; + break; + case GIODRV_IOCGGIO_BTN: /* read */ + data = (0x0ff & ctrl_inb(PA_PWRINT_CLR)); + data <<= 8; + data |= (0x0ff & ctrl_inb(PA_IMASK)); + data <<= 8; + data |= (0x0ff & landisk_btn); + data <<= 8; + data |= (0x0ff & (~ctrl_inb(PA_STATUS))); + break; + case GIODRV_IOCSGIO_BTNPID: /* write */ + landisk_btnctrlpid = data; + landisk_btn = 0; + if (irq_desc[IRQ_BUTTON].depth) { + enable_irq(IRQ_BUTTON); + } + if (irq_desc[IRQ_POWER].depth) { + enable_irq(IRQ_POWER); + } + break; + case GIODRV_IOCGGIO_BTNPID: /* read */ + data = landisk_btnctrlpid; + break; + default: + return -EFAULT; + break; + } + + if ((cmd & 0x01) == 0) { /* read */ + if (copy_to_user((int *)arg, &data, sizeof(int))) { + return -EFAULT; + } + } + return 0; +} diff --git a/arch/sh/boards/landisk/rtc.c b/arch/sh/boards/landisk/rtc.c new file mode 100644 index 00000000000..35ba726a097 --- /dev/null +++ b/arch/sh/boards/landisk/rtc.c @@ -0,0 +1,93 @@ +/* + * arch/sh/boards/landisk/rtc.c -- RTC support + * + * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> + * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka + */ +/* + * modifed by kogiidena + * 2005.09.16 + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/time.h> +#include <linux/delay.h> +#include <linux/spinlock.h> +#include <linux/bcd.h> +#include <asm/rtc.h> + +extern spinlock_t rtc_lock; + +extern void +rs5c313_set_cmos_time(unsigned int BCD_yr, unsigned int BCD_mon, + unsigned int BCD_day, unsigned int BCD_hr, + unsigned int BCD_min, unsigned int BCD_sec); + +extern unsigned long +rs5c313_get_cmos_time(unsigned int *BCD_yr, unsigned int *BCD_mon, + unsigned int *BCD_day, unsigned int *BCD_hr, + unsigned int *BCD_min, unsigned int *BCD_sec); + +void landisk_rtc_gettimeofday(struct timespec *tv) +{ + unsigned int BCD_yr, BCD_mon, BCD_day, BCD_hr, BCD_min, BCD_sec; + unsigned long flags; + + spin_lock_irqsave(&rtc_lock, flags); + tv->tv_sec = rs5c313_get_cmos_time + (&BCD_yr, &BCD_mon, &BCD_day, &BCD_hr, &BCD_min, &BCD_sec); + tv->tv_nsec = 0; + spin_unlock_irqrestore(&rtc_lock, flags); +} + +int landisk_rtc_settimeofday(const time_t secs) +{ + int retval = 0; + int real_seconds, real_minutes, cmos_minutes; + unsigned long flags; + unsigned long nowtime = secs; + unsigned int BCD_yr, BCD_mon, BCD_day, BCD_hr, BCD_min, BCD_sec; + + spin_lock_irqsave(&rtc_lock, flags); + + rs5c313_get_cmos_time + (&BCD_yr, &BCD_mon, &BCD_day, &BCD_hr, &BCD_min, &BCD_sec); + cmos_minutes = BCD_min; + BCD_TO_BIN(cmos_minutes); + + /* + * since we're only adjusting minutes and seconds, + * don't interfere with hour overflow. This avoids + * messing with unknown time zones but requires your + * RTC not to be off by more than 15 minutes + */ + real_seconds = nowtime % 60; + real_minutes = nowtime / 60; + if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1) + real_minutes += 30; /* correct for half hour time zone */ + real_minutes %= 60; + + if (abs(real_minutes - cmos_minutes) < 30) { + BIN_TO_BCD(real_seconds); + BIN_TO_BCD(real_minutes); + rs5c313_set_cmos_time(BCD_yr, BCD_mon, BCD_day, BCD_hr, + real_minutes, real_seconds); + } else { + printk(KERN_WARNING + "set_rtc_time: can't update from %d to %d\n", + cmos_minutes, real_minutes); + retval = -1; + } + + spin_unlock_irqrestore(&rtc_lock, flags); + return retval; +} + +void landisk_time_init(void) +{ + rtc_sh_get_time = landisk_rtc_gettimeofday; + rtc_sh_set_time = landisk_rtc_settimeofday; +} diff --git a/arch/sh/boards/landisk/setup.c b/arch/sh/boards/landisk/setup.c new file mode 100644 index 00000000000..127b9e020e0 --- /dev/null +++ b/arch/sh/boards/landisk/setup.c @@ -0,0 +1,177 @@ +/* + * arch/sh/boards/landisk/setup.c + * + * Copyright (C) 2000 Kazumoto Kojima + * Copyright (C) 2002 Paul Mundt + * + * I-O DATA Device, Inc. LANDISK Support. + * + * Modified for LANDISK by + * Atom Create Engineering Co., Ltd. 2002. + * + * modifed by kogiidena + * 2005.09.16 + * + * 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/config.h> +#include <linux/init.h> +#include <linux/pm.h> +#include <linux/mm.h> +#include <asm/machvec.h> +#include <asm/rtc.h> +#include <asm/landisk/iodata_landisk.h> +#include <asm/io.h> + +void landisk_time_init(void); +void init_landisk_IRQ(void); + +int landisk_ledparam; +int landisk_buzzerparam; +int landisk_arch; + +/* cycle the led's in the clasic knightrider/sun pattern */ +static void heartbeat_landisk(void) +{ + static unsigned int cnt = 0, blink = 0x00, period = 25; + volatile u8 *p = (volatile u8 *)PA_LED; + char data; + + if ((landisk_ledparam & 0x080) == 0) + return; + + cnt += 1; + + if (cnt < period) + return; + + cnt = 0; + blink++; + + data = (blink & 0x01) ? (landisk_ledparam >> 16) : 0; + data |= (blink & 0x02) ? (landisk_ledparam >> 8) : 0; + data |= landisk_ledparam; + + /* buzzer */ + if (landisk_buzzerparam & 0x1) { + data |= 0x80; + } else { + data &= 0x7f; + } + *p = data; + + if (((landisk_ledparam & 0x007f7f00) == 0) && + (landisk_buzzerparam == 0)) + landisk_ledparam &= (~0x0080); + + landisk_buzzerparam >>= 1; +} + +static void landisk_power_off(void) +{ + ctrl_outb(0x01, PA_SHUTDOWN); +} + +static void check_usl5p(void) +{ + volatile u8 *p = (volatile u8 *)PA_LED; + u8 tmp1, tmp2; + + tmp1 = *p; + *p = 0x40; + tmp2 = *p; + *p = tmp1; + + landisk_arch = (tmp2 == 0x40); + if (landisk_arch == 1) { + /* arch == usl-5p */ + landisk_ledparam = 0x00000380; + landisk_ledparam |= (tmp1 & 0x07c); + } else { + /* arch == landisk */ + landisk_ledparam = 0x02000180; + landisk_ledparam |= 0x04; + } +} + +void *area5_io_base; +void *area6_io_base; + +static int __init landisk_cf_init(void) +{ + pgprot_t prot; + unsigned long paddrbase, psize; + + /* open I/O area window */ + paddrbase = virt_to_phys((void *)PA_AREA5_IO); + psize = PAGE_SIZE; + prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16); + area5_io_base = p3_ioremap(paddrbase, psize, prot.pgprot); + if (!area5_io_base) { + printk("allocate_cf_area : can't open CF I/O window!\n"); + return -ENOMEM; + } + + paddrbase = virt_to_phys((void *)PA_AREA6_IO); + psize = PAGE_SIZE; + prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO16); + area6_io_base = p3_ioremap(paddrbase, psize, prot.pgprot); + if (!area6_io_base) { + printk("allocate_cf_area : can't open HDD I/O window!\n"); + return -ENOMEM; + } + + printk(KERN_INFO "Allocate Area5/6 success.\n"); + + /* XXX : do we need attribute and common-memory area also? */ + + return 0; +} + +static void __init landisk_setup(char **cmdline_p) +{ + device_initcall(landisk_cf_init); + + landisk_buzzerparam = 0; + check_usl5p(); + + printk(KERN_INFO "I-O DATA DEVICE, INC. \"LANDISK Series\" support.\n"); + + board_time_init = landisk_time_init; + pm_power_off = landisk_power_off; +} + +/* + * The Machine Vector + */ +struct sh_machine_vector mv_landisk __initmv = { + .mv_name = "LANDISK", + .mv_setup = landisk_setup, + .mv_nr_irqs = 72, + .mv_inb = landisk_inb, + .mv_inw = landisk_inw, + .mv_inl = landisk_inl, + .mv_outb = landisk_outb, + .mv_outw = landisk_outw, + .mv_outl = landisk_outl, + .mv_inb_p = landisk_inb_p, + .mv_inw_p = landisk_inw, + .mv_inl_p = landisk_inl, + .mv_outb_p = landisk_outb_p, + .mv_outw_p = landisk_outw, + .mv_outl_p = landisk_outl, + .mv_insb = landisk_insb, + .mv_insw = landisk_insw, + .mv_insl = landisk_insl, + .mv_outsb = landisk_outsb, + .mv_outsw = landisk_outsw, + .mv_outsl = landisk_outsl, + .mv_ioport_map = landisk_ioport_map, + .mv_init_irq = init_landisk_IRQ, +#ifdef CONFIG_HEARTBEAT + .mv_heartbeat = heartbeat_landisk, +#endif +}; +ALIAS_MV(landisk) diff --git a/arch/sh/boards/mpc1211/rtc.c b/arch/sh/boards/mpc1211/rtc.c index a76c655dcee..03b123a4bba 100644 --- a/arch/sh/boards/mpc1211/rtc.c +++ b/arch/sh/boards/mpc1211/rtc.c @@ -130,7 +130,7 @@ int mpc1211_rtc_settimeofday(const struct timeval *tv) void mpc1211_time_init(void) { - rtc_get_time = mpc1211_rtc_gettimeofday; - rtc_set_time = mpc1211_rtc_settimeofday; + rtc_sh_get_time = mpc1211_rtc_gettimeofday; + rtc_sh_set_time = mpc1211_rtc_settimeofday; } diff --git a/arch/sh/boards/mpc1211/setup.c b/arch/sh/boards/mpc1211/setup.c index 2bfb221cc35..8eb5d430397 100644 --- a/arch/sh/boards/mpc1211/setup.c +++ b/arch/sh/boards/mpc1211/setup.c @@ -10,14 +10,12 @@ #include <linux/hdreg.h> #include <linux/ide.h> #include <linux/interrupt.h> - #include <asm/io.h> #include <asm/machvec.h> #include <asm/mpc1211/mpc1211.h> #include <asm/mpc1211/pci.h> #include <asm/mpc1211/m1543c.h> - /* ALI15X3 SMBus address offsets */ #define SMBHSTSTS (0 + 0x3100) #define SMBHSTCNT (1 + 0x3100) @@ -50,11 +48,6 @@ #define ALI15X3_STS_TERM 0x80 /* terminated by abort */ #define ALI15X3_STS_ERR 0xE0 /* all the bad error bits */ -const char *get_system_type(void) -{ - return "Interface MPC-1211(CTP/PCI/MPC-SH02)"; -} - static void __init pci_write_config(unsigned long busNo, unsigned long devNo, unsigned long fncNo, @@ -80,9 +73,6 @@ volatile unsigned long irq_err_count; static void disable_mpc1211_irq(unsigned int irq) { - unsigned long flags; - - save_and_cli(flags); if( irq < 8) { m_irq_mask |= (1 << irq); outb(m_irq_mask,I8259_M_MR); @@ -90,16 +80,11 @@ static void disable_mpc1211_irq(unsigned int irq) s_irq_mask |= (1 << (irq - 8)); outb(s_irq_mask,I8259_S_MR); } - restore_flags(flags); } static void enable_mpc1211_irq(unsigned int irq) { - unsigned long flags; - - save_and_cli(flags); - if( irq < 8) { m_irq_mask &= ~(1 << irq); outb(m_irq_mask,I8259_M_MR); @@ -107,7 +92,6 @@ static void enable_mpc1211_irq(unsigned int irq) s_irq_mask &= ~(1 << (irq - 8)); outb(s_irq_mask,I8259_S_MR); } - restore_flags(flags); } static inline int mpc1211_irq_real(unsigned int irq) @@ -131,10 +115,6 @@ static inline int mpc1211_irq_real(unsigned int irq) static void mask_and_ack_mpc1211(unsigned int irq) { - unsigned long flags; - - save_and_cli(flags); - if(irq < 8) { if(m_irq_mask & (1<<irq)){ if(!mpc1211_irq_real(irq)){ @@ -162,7 +142,6 @@ static void mask_and_ack_mpc1211(unsigned int irq) outb(0x60+(irq-8),I8259_S_CR); /* EOI */ outb(0x60+2,I8259_M_CR); } - restore_flags(flags); } static void end_mpc1211_irq(unsigned int irq) @@ -219,7 +198,7 @@ int mpc1211_irq_demux(int irq) return irq; } -void __init init_mpc1211_IRQ(void) +static void __init init_mpc1211_IRQ(void) { int i; /* @@ -255,23 +234,12 @@ void __init init_mpc1211_IRQ(void) } } -/* - Initialize the board -*/ - - -static void delay (void) -{ - volatile unsigned short tmp; - tmp = *(volatile unsigned short *) 0xa0000000; -} - -static void delay1000 (void) +static void delay1000(void) { int i; for (i=0; i<1000; i++) - delay (); + ctrl_delay(); } static int put_smb_blk(unsigned char *p, int address, int command, int no) @@ -314,26 +282,10 @@ static int put_smb_blk(unsigned char *p, int address, int command, int no) return 0; } -/* - * The Machine Vector - */ - -struct sh_machine_vector mv_mpc1211 __initmv = { - .mv_nr_irqs = 48, - .mv_irq_demux = mpc1211_irq_demux, - .mv_init_irq = init_mpc1211_IRQ, - -#ifdef CONFIG_HEARTBEAT - .mv_heartbeat = heartbeat_mpc1211, -#endif -}; - -ALIAS_MV(mpc1211) - /* arch/sh/boards/mpc1211/rtc.c */ void mpc1211_time_init(void); -int __init platform_setup(void) +static void __init mpc1211_setup(char **cmdline_p) { unsigned char spd_buf[128]; @@ -357,3 +309,18 @@ int __init platform_setup(void) return 0; } +/* + * The Machine Vector + */ +struct sh_machine_vector mv_mpc1211 __initmv = { + .mv_name = "Interface MPC-1211(CTP/PCI/MPC-SH02)", + .mv_setup = mpc1211_setup, + .mv_nr_irqs = 48, + .mv_irq_demux = mpc1211_irq_demux, + .mv_init_irq = init_mpc1211_IRQ, + +#ifdef CONFIG_HEARTBEAT + .mv_heartbeat = heartbeat_mpc1211, +#endif +}; +ALIAS_MV(mpc1211) diff --git a/arch/sh/boards/overdrive/Makefile b/arch/sh/boards/overdrive/Makefile deleted file mode 100644 index 245f03baf76..00000000000 --- a/arch/sh/boards/overdrive/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for the STMicroelectronics Overdrive specific parts of the kernel -# - -obj-y := mach.o setup.o io.o irq.o led.o - -obj-$(CONFIG_PCI) += fpga.o galileo.o pcidma.o - diff --git a/arch/sh/boards/overdrive/fpga.c b/arch/sh/boards/overdrive/fpga.c deleted file mode 100644 index 956c2390122..00000000000 --- a/arch/sh/boards/overdrive/fpga.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * This file handles programming up the Altera Flex10K that interfaces to - * the Galileo, and does the PS/2 keyboard and mouse - * - */ - - -#include <linux/kernel.h> -#include <linux/smp.h> -#include <linux/smp_lock.h> -#include <linux/init.h> -#include <linux/errno.h> -#include <linux/pci.h> -#include <linux/delay.h> - - -#include <asm/overdriver/gt64111.h> -#include <asm/overdrive/overdrive.h> -#include <asm/overdrive/fpga.h> - -#define FPGA_NotConfigHigh() (*FPGA_ControlReg) = (*FPGA_ControlReg) | ENABLE_FPGA_BIT -#define FPGA_NotConfigLow() (*FPGA_ControlReg) = (*FPGA_ControlReg) & RESET_FPGA_MASK - -/* I need to find out what (if any) the real delay factor here is */ -/* The delay is definately not critical */ -#define long_delay() {int i;for(i=0;i<10000;i++);} -#define short_delay() {int i;for(i=0;i<100;i++);} - -static void __init program_overdrive_fpga(const unsigned char *fpgacode, - int size) -{ - int timeout = 0; - int i, j; - unsigned char b; - static volatile unsigned char *FPGA_ControlReg = - (volatile unsigned char *) (OVERDRIVE_CTRL); - static volatile unsigned char *FPGA_ProgramReg = - (volatile unsigned char *) (FPGA_DCLK_ADDRESS); - - printk("FPGA: Commencing FPGA Programming\n"); - - /* The PCI reset but MUST be low when programming the FPGA !!! */ - b = (*FPGA_ControlReg) & RESET_PCI_MASK; - - (*FPGA_ControlReg) = b; - - /* Prepare FPGA to program */ - - FPGA_NotConfigHigh(); - long_delay(); - - FPGA_NotConfigLow(); - short_delay(); - - while ((*FPGA_ProgramReg & FPGA_NOT_STATUS) != 0) { - printk("FPGA: Waiting for NotStatus to go Low ... \n"); - } - - FPGA_NotConfigHigh(); - - /* Wait for FPGA "ready to be programmed" signal */ - printk("FPGA: Waiting for NotStatus to go high (FPGA ready)... \n"); - - for (timeout = 0; - (((*FPGA_ProgramReg & FPGA_NOT_STATUS) == 0) - && (timeout < FPGA_TIMEOUT)); timeout++); - - /* Check if timeout condition occured - i.e. an error */ - - if (timeout == FPGA_TIMEOUT) { - printk - ("FPGA: Failed to program - Timeout waiting for notSTATUS to go high\n"); - return; - } - - printk("FPGA: Copying data to FPGA ... %d bytes\n", size); - - /* Copy array to FPGA - bit at a time */ - - for (i = 0; i < size; i++) { - volatile unsigned w = 0; - - for (j = 0; j < 8; j++) { - *FPGA_ProgramReg = (fpgacode[i] >> j) & 0x01; - short_delay(); - } - if ((i & 0x3ff) == 0) { - printk("."); - } - } - - /* Waiting for CONFDONE to go high - means the program is complete */ - - for (timeout = 0; - (((*FPGA_ProgramReg & FPGA_CONFDONE) == 0) - && (timeout < FPGA_TIMEOUT)); timeout++) { - - *FPGA_ProgramReg = 0x0; - long_delay(); - } - - if (timeout == FPGA_TIMEOUT) { - printk - ("FPGA: Failed to program - Timeout waiting for CONFDONE to go high\n"); - return; - } else { /* Clock another 10 times - gets the device into a working state */ - for (i = 0; i < 10; i++) { - *FPGA_ProgramReg = 0x0; - short_delay(); - } - } - - printk("FPGA: Programming complete\n"); -} - - -static const unsigned char __init fpgacode[] = { -#include "./overdrive.ttf" /* Code from maxplus2 compiler */ - , 0, 0 -}; - - -int __init init_overdrive_fpga(void) -{ - program_overdrive_fpga(fpgacode, sizeof(fpgacode)); - - return 0; -} diff --git a/arch/sh/boards/overdrive/galileo.c b/arch/sh/boards/overdrive/galileo.c deleted file mode 100644 index 29e48971bba..00000000000 --- a/arch/sh/boards/overdrive/galileo.c +++ /dev/null @@ -1,587 +0,0 @@ -/* - * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * This file contains the PCI routines required for the Galileo GT6411 - * PCI bridge as used on the Orion and Overdrive boards. - * - */ - -#include <linux/kernel.h> -#include <linux/smp.h> -#include <linux/smp_lock.h> -#include <linux/init.h> -#include <linux/errno.h> -#include <linux/pci.h> -#include <linux/delay.h> -#include <linux/types.h> -#include <linux/ioport.h> - -#include <asm/overdrive/overdrive.h> -#include <asm/overdrive/gt64111.h> - - -/* After boot, we shift the Galileo registers so that they appear - * in BANK6, along with IO space. This means we can have one contingous - * lump of PCI address space without these registers appearing in the - * middle of them - */ - -#define GT64111_BASE_ADDRESS 0xbb000000 -#define GT64111_IO_BASE_ADDRESS 0x1000 -/* The GT64111 registers appear at this address to the SH4 after reset */ -#define RESET_GT64111_BASE_ADDRESS 0xb4000000 - -/* Macros used to access the Galileo registers */ -#define RESET_GT64111_REG(x) (RESET_GT64111_BASE_ADDRESS+x) -#define GT64111_REG(x) (GT64111_BASE_ADDRESS+x) - -#define RESET_GT_WRITE(x,v) writel((v),RESET_GT64111_REG(x)) - -#define RESET_GT_READ(x) readl(RESET_GT64111_REG(x)) - -#define GT_WRITE(x,v) writel((v),GT64111_REG(x)) -#define GT_WRITE_BYTE(x,v) writeb((v),GT64111_REG(x)) -#define GT_WRITE_SHORT(x,v) writew((v),GT64111_REG(x)) - -#define GT_READ(x) readl(GT64111_REG(x)) -#define GT_READ_BYTE(x) readb(GT64111_REG(x)) -#define GT_READ_SHORT(x) readw(GT64111_REG(x)) - - -/* Where the various SH banks start at */ -#define SH_BANK4_ADR 0xb0000000 -#define SH_BANK5_ADR 0xb4000000 -#define SH_BANK6_ADR 0xb8000000 - -/* Masks out everything but lines 28,27,26 */ -#define BANK_SELECT_MASK 0x1c000000 - -#define SH4_TO_BANK(x) ( (x) & BANK_SELECT_MASK) - -/* - * Masks used for address conversaion. Bank 6 is used for IO and - * has all the address bits zeroed by the FPGA. Special case this - */ -#define MEMORY_BANK_MASK 0x1fffffff -#define IO_BANK_MASK 0x03ffffff - -/* Mark bank 6 as the bank used for IO. You can change this in the FPGA code - * if you want - */ -#define IO_BANK_ADR PCI_GTIO_BASE - -/* Will select the correct mask to apply depending on the SH$ address */ -#define SELECT_BANK_MASK(x) \ - ( (SH4_TO_BANK(x)==SH4_TO_BANK(IO_BANK_ADR)) ? IO_BANK_MASK : MEMORY_BANK_MASK) - -/* Converts between PCI space and P2 region */ -#define SH4_TO_PCI(x) ((x)&SELECT_BANK_MASK(x)) - -/* Various macros for figuring out what to stick in the Galileo registers. - * You *really* don't want to figure this stuff out by hand, you always get - * it wrong - */ -#define GT_MEM_LO_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>21)&0x7ff) -#define GT_MEM_HI_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>21)&0x7f) -#define GT_MEM_SUB_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>20)&0xff) - -#define PROGRAM_HI_LO(block,a,s) \ - GT_WRITE(block##_LO_DEC_ADR,GT_MEM_LO_ADR(a));\ - GT_WRITE(block##_HI_DEC_ADR,GT_MEM_HI_ADR(a+s-1)) - -#define PROGRAM_SUB_HI_LO(block,a,s) \ - GT_WRITE(block##_LO_DEC_ADR,GT_MEM_SUB_ADR(a));\ - GT_WRITE(block##_HI_DEC_ADR,GT_MEM_SUB_ADR(a+s-1)) - -/* We need to set the size, and the offset register */ - -#define GT_BAR_MASK(x) ((x)&~0xfff) - -/* Macro to set up the BAR in the Galileo. Essentially used for the DRAM */ -#define PROGRAM_GT_BAR(block,a,s) \ - GT_WRITE(PCI_##block##_BANK_SIZE,GT_BAR_MASK((s-1)));\ - write_config_to_galileo(PCI_CONFIG_##block##_BASE_ADR,\ - GT_BAR_MASK(a)) - -#define DISABLE_GT_BAR(block) \ - GT_WRITE(PCI_##block##_BANK_SIZE,0),\ - GT_CONFIG_WRITE(PCI_CONFIG_##block##_BASE_ADR,\ - 0x80000000) - -/* Macros to disable things we are not going to use */ -#define DISABLE_DECODE(x) GT_WRITE(x##_LO_DEC_ADR,0x7ff);\ - GT_WRITE(x##_HI_DEC_ADR,0x00) - -#define DISABLE_SUB_DECODE(x) GT_WRITE(x##_LO_DEC_ADR,0xff);\ - GT_WRITE(x##_HI_DEC_ADR,0x00) - -static void __init reset_pci(void) -{ - /* Set RESET_PCI bit high */ - writeb(readb(OVERDRIVE_CTRL) | ENABLE_PCI_BIT, OVERDRIVE_CTRL); - udelay(250); - - /* Set RESET_PCI bit low */ - writeb(readb(OVERDRIVE_CTRL) & RESET_PCI_MASK, OVERDRIVE_CTRL); - udelay(250); - - writeb(readb(OVERDRIVE_CTRL) | ENABLE_PCI_BIT, OVERDRIVE_CTRL); - udelay(250); -} - -static int write_config_to_galileo(int where, u32 val); -#define GT_CONFIG_WRITE(where,val) write_config_to_galileo(where,val) - -#define ENABLE_PCI_DRAM - - -#ifdef TEST_DRAM -/* Test function to check out if the PCI DRAM is working OK */ -static int /* __init */ test_dram(unsigned *base, unsigned size) -{ - unsigned *p = base; - unsigned *end = (unsigned *) (((unsigned) base) + size); - unsigned w; - - for (p = base; p < end; p++) { - *p = 0xffffffff; - if (*p != 0xffffffff) { - printk("AAARGH -write failed!!! at %p is %x\n", p, - *p); - return 0; - } - *p = 0x0; - if (*p != 0x0) { - printk("AAARGH -write failed!!!\n"); - return 0; - } - } - - for (p = base; p < end; p++) { - *p = (unsigned) p; - if (*p != (unsigned) p) { - printk("Failed at 0x%p, actually is 0x%x\n", p, - *p); - return 0; - } - } - - for (p = base; p < end; p++) { - w = ((unsigned) p & 0xffff0000); - *p = w | (w >> 16); - } - - for (p = base; p < end; p++) { - w = ((unsigned) p & 0xffff0000); - w |= (w >> 16); - if (*p != w) { - printk - ("Failed at 0x%p, should be 0x%x actually is 0x%x\n", - p, w, *p); - return 0; - } - } - - return 1; -} -#endif - - -/* Function to set up and initialise the galileo. This sets up the BARS, - * maps the DRAM into the address space etc,etc - */ -int __init galileo_init(void) -{ - reset_pci(); - - /* Now shift the galileo regs into this block */ - RESET_GT_WRITE(INTERNAL_SPACE_DEC, - GT_MEM_LO_ADR(GT64111_BASE_ADDRESS)); - - /* Should have a sanity check here, that you can read back at the new - * address what you just wrote - */ - - /* Disable decode for all regions */ - DISABLE_DECODE(RAS10); - DISABLE_DECODE(RAS32); - DISABLE_DECODE(CS20); - DISABLE_DECODE(CS3); - DISABLE_DECODE(PCI_IO); - DISABLE_DECODE(PCI_MEM0); - DISABLE_DECODE(PCI_MEM1); - - /* Disable all BARS */ - GT_WRITE(BAR_ENABLE_ADR, 0x1ff); - DISABLE_GT_BAR(RAS10); - DISABLE_GT_BAR(RAS32); - DISABLE_GT_BAR(CS20); - DISABLE_GT_BAR(CS3); - - /* Tell the BAR where the IO registers now are */ - GT_CONFIG_WRITE(PCI_CONFIG_INT_REG_IO_ADR,GT_BAR_MASK( - (GT64111_IO_BASE_ADDRESS & - IO_BANK_MASK))); - /* set up a 112 Mb decode */ - PROGRAM_HI_LO(PCI_MEM0, SH_BANK4_ADR, 112 * 1024 * 1024); - - /* Set up a 32 MB io space decode */ - PROGRAM_HI_LO(PCI_IO, IO_BANK_ADR, 32 * 1024 * 1024); - -#ifdef ENABLE_PCI_DRAM - /* Program up the DRAM configuration - there is DRAM only in bank 0 */ - /* Now set up the DRAM decode */ - PROGRAM_HI_LO(RAS10, PCI_DRAM_BASE, PCI_DRAM_SIZE); - /* And the sub decode */ - PROGRAM_SUB_HI_LO(RAS0, PCI_DRAM_BASE, PCI_DRAM_SIZE); - - DISABLE_SUB_DECODE(RAS1); - - /* Set refresh rate */ - GT_WRITE(DRAM_BANK0_PARMS, 0x3f); - GT_WRITE(DRAM_CFG, 0x100); - - /* we have to lob off the top bits rememeber!! */ - PROGRAM_GT_BAR(RAS10, SH4_TO_PCI(PCI_DRAM_BASE), PCI_DRAM_SIZE); - -#endif - - /* We are only interested in decoding RAS10 and the Galileo's internal - * registers (as IO) on the PCI bus - */ -#ifdef ENABLE_PCI_DRAM - GT_WRITE(BAR_ENABLE_ADR, (~((1 << 8) | (1 << 3))) & 0x1ff); -#else - GT_WRITE(BAR_ENABLE_ADR, (~(1 << 3)) & 0x1ff); -#endif - - /* Change the class code to host bridge, it actually powers up - * as a memory controller - */ - GT_CONFIG_WRITE(8, 0x06000011); - - /* Allow the galileo to master the PCI bus */ - GT_CONFIG_WRITE(PCI_COMMAND, - PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | - PCI_COMMAND_IO); - - -#if 0 - printk("Testing PCI DRAM - "); - if(test_dram(PCI_DRAM_BASE,PCI_DRAM_SIZE)) { - printk("Passed\n"); - }else { - printk("FAILED\n"); - } -#endif - return 0; - -} - - -#define SET_CONFIG_BITS(bus,devfn,where)\ - ((1<<31) | ((bus) << 16) | ((devfn) << 8) | ((where) & ~3)) - -#define CONFIG_CMD(dev, where) SET_CONFIG_BITS((dev)->bus->number,(dev)->devfn,where) - -/* This write to the galileo config registers, unlike the functions below, can - * be used before the PCI subsystem has started up - */ -static int __init write_config_to_galileo(int where, u32 val) -{ - GT_WRITE(PCI_CFG_ADR, SET_CONFIG_BITS(0, 0, where)); - - GT_WRITE(PCI_CFG_DATA, val); - return 0; -} - -/* We exclude the galileo and slot 31, the galileo because I don't know how to stop - * the setup code shagging up the setup I have done on it, and 31 because the whole - * thing locks up if you try to access that slot (which doesn't exist of course anyway - */ - -#define EXCLUDED_DEV(dev) ((dev->bus->number==0) && ((PCI_SLOT(dev->devfn)==0) || (PCI_SLOT(dev->devfn) == 31))) - -static int galileo_read_config_byte(struct pci_dev *dev, int where, - u8 * val) -{ - - - /* I suspect this doesn't work because this drives a special cycle ? */ - if (EXCLUDED_DEV(dev)) { - *val = 0xff; - return PCIBIOS_SUCCESSFUL; - } - /* Start the config cycle */ - GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); - /* Read back the result */ - *val = GT_READ_BYTE(PCI_CFG_DATA + (where & 3)); - - return PCIBIOS_SUCCESSFUL; -} - - -static int galileo_read_config_word(struct pci_dev *dev, int where, - u16 * val) -{ - - if (EXCLUDED_DEV(dev)) { - *val = 0xffff; - return PCIBIOS_SUCCESSFUL; - } - - GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); - *val = GT_READ_SHORT(PCI_CFG_DATA + (where & 2)); - - return PCIBIOS_SUCCESSFUL; -} - - -static int galileo_read_config_dword(struct pci_dev *dev, int where, - u32 * val) -{ - if (EXCLUDED_DEV(dev)) { - *val = 0xffffffff; - return PCIBIOS_SUCCESSFUL; - } - - GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); - *val = GT_READ(PCI_CFG_DATA); - - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_write_config_byte(struct pci_dev *dev, int where, - u8 val) -{ - GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); - - GT_WRITE_BYTE(PCI_CFG_DATA + (where & 3), val); - - return PCIBIOS_SUCCESSFUL; -} - - -static int galileo_write_config_word(struct pci_dev *dev, int where, - u16 val) -{ - GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); - - GT_WRITE_SHORT(PCI_CFG_DATA + (where & 2), val); - - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_write_config_dword(struct pci_dev *dev, int where, - u32 val) -{ - GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); - - GT_WRITE(PCI_CFG_DATA, val); - - return PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops pci_config_ops = { - galileo_read_config_byte, - galileo_read_config_word, - galileo_read_config_dword, - galileo_write_config_byte, - galileo_write_config_word, - galileo_write_config_dword -}; - - -/* Everything hangs off this */ -static struct pci_bus *pci_root_bus; - - -static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin) -{ - return PCI_SLOT(dev->devfn); -} - -static int __init map_od_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - /* Slot 1: Galileo - * Slot 2: PCI Slot 1 - * Slot 3: PCI Slot 2 - * Slot 4: ESS - */ - switch (slot) { - case 2: - return OVERDRIVE_PCI_IRQ1; - case 3: - /* Note this assumes you have a hacked card in slot 2 */ - return OVERDRIVE_PCI_IRQ2; - case 4: - return OVERDRIVE_ESS_IRQ; - default: - /* printk("PCI: Unexpected IRQ mapping request for slot %d\n", slot); */ - return -1; - } -} - - - -void __init -pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *ranges) -{ - ranges->io_start -= bus->resource[0]->start; - ranges->io_end -= bus->resource[0]->start; - ranges->mem_start -= bus->resource[1]->start; - ranges->mem_end -= bus->resource[1]->start; -} - -static void __init pci_fixup_ide_bases(struct pci_dev *d) -{ - int i; - - /* - * PCI IDE controllers use non-standard I/O port decoding, respect it. - */ - if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE) - return; - printk("PCI: IDE base address fixup for %s\n", pci_name(d)); - for(i=0; i<4; i++) { - struct resource *r = &d->resource[i]; - if ((r->start & ~0x80) == 0x374) { - r->start |= 2; - r->end = r->start; - } - } -} -DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); - -void __init pcibios_init(void) -{ - static struct resource galio,galmem; - - /* Allocate the registers used by the Galileo */ - galio.flags = IORESOURCE_IO; - galio.name = "Galileo GT64011"; - galmem.flags = IORESOURCE_MEM|IORESOURCE_PREFETCH; - galmem.name = "Galileo GT64011 DRAM"; - - allocate_resource(&ioport_resource, &galio, 256, - GT64111_IO_BASE_ADDRESS,GT64111_IO_BASE_ADDRESS+256, 256, NULL, NULL); - allocate_resource(&iomem_resource, &galmem,PCI_DRAM_SIZE, - PHYSADDR(PCI_DRAM_BASE), PHYSADDR(PCI_DRAM_BASE)+PCI_DRAM_SIZE, - PCI_DRAM_SIZE, NULL, NULL); - - /* ok, do the scan man */ - pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL); - - pci_assign_unassigned_resources(); - pci_fixup_irqs(no_swizzle, map_od_irq); - -#ifdef TEST_DRAM - printk("Testing PCI DRAM - "); - if(test_dram(PCI_DRAM_BASE,PCI_DRAM_SIZE)) { - printk("Passed\n"); - }else { - printk("FAILED\n"); - } -#endif - -} - -char * __init pcibios_setup(char *str) -{ - return str; -} - - - -int pcibios_enable_device(struct pci_dev *dev) -{ - - u16 cmd, old_cmd; - int idx; - struct resource *r; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - old_cmd = cmd; - for (idx = 0; idx < 6; idx++) { - r = dev->resource + idx; - if (!r->start && r->end) { - printk(KERN_ERR - "PCI: Device %s not available because" - " of resource collisions\n", - pci_name(dev)); - return -EINVAL; - } - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - if (cmd != old_cmd) { - printk("PCI: enabling device %s (%04x -> %04x)\n", - pci_name(dev), old_cmd, cmd); - pci_write_config_word(dev, PCI_COMMAND, cmd); - } - return 0; - -} - -/* We should do some optimisation work here I think. Ok for now though */ -void __init pcibios_fixup_bus(struct pci_bus *bus) -{ - -} - -void pcibios_align_resource(void *data, struct resource *res, - resource_size_t size) -{ -} - -void __init pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - - unsigned long where, size; - u32 reg; - - - printk("PCI: Assigning %3s %08lx to %s\n", - res->flags & IORESOURCE_IO ? "IO" : "MEM", - res->start, dev->name); - - where = PCI_BASE_ADDRESS_0 + resource * 4; - size = res->end - res->start; - - pci_read_config_dword(dev, where, ®); - reg = (reg & size) | (((u32) (res->start - root->start)) & ~size); - pci_write_config_dword(dev, where, reg); -} - - -void __init pcibios_update_irq(struct pci_dev *dev, int irq) -{ - printk("PCI: Assigning IRQ %02d to %s\n", irq, dev->name); - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); -} - -/* - * If we set up a device for bus mastering, we need to check the latency - * timer as certain crappy BIOSes forget to set it properly. - */ -unsigned int pcibios_max_latency = 255; - -void pcibios_set_master(struct pci_dev *dev) -{ - u8 lat; - pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); - if (lat < 16) - lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; - else if (lat > pcibios_max_latency) - lat = pcibios_max_latency; - else - return; - printk("PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat); - pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); -} diff --git a/arch/sh/boards/overdrive/io.c b/arch/sh/boards/overdrive/io.c deleted file mode 100644 index 4671b6b047b..00000000000 --- a/arch/sh/boards/overdrive/io.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * This file contains the I/O routines for use on the overdrive board - * - */ - -#include <linux/types.h> -#include <linux/delay.h> -#include <asm/processor.h> -#include <asm/io.h> -#include <asm/addrspace.h> - -#include <asm/overdrive/overdrive.h> - -/* - * readX/writeX() are used to access memory mapped devices. On some - * architectures the memory mapped IO stuff needs to be accessed - * differently. On the SuperH architecture, we just read/write the - * memory location directly. - */ - -#define dprintk(x...) - -/* Translates an IO address to where it is mapped in memory */ - -#define io_addr(x) (((unsigned)(x))|PCI_GTIO_BASE) - -unsigned char od_inb(unsigned long port) -{ -dprintk("od_inb(%x)\n", port); - return readb(io_addr(port)) & 0xff; -} - - -unsigned short od_inw(unsigned long port) -{ -dprintk("od_inw(%x)\n", port); - return readw(io_addr(port)) & 0xffff; -} - -unsigned int od_inl(unsigned long port) -{ -dprintk("od_inl(%x)\n", port); - return readl(io_addr(port)); -} - -void od_outb(unsigned char value, unsigned long port) -{ -dprintk("od_outb(%x, %x)\n", value, port); - writeb(value, io_addr(port)); -} - -void od_outw(unsigned short value, unsigned long port) -{ -dprintk("od_outw(%x, %x)\n", value, port); - writew(value, io_addr(port)); -} - -void od_outl(unsigned int value, unsigned long port) -{ -dprintk("od_outl(%x, %x)\n", value, port); - writel(value, io_addr(port)); -} - -/* This is horrible at the moment - needs more work to do something sensible */ -#define IO_DELAY() udelay(10) - -#define OUT_DELAY(x,type) \ -void od_out##x##_p(unsigned type value,unsigned long port){out##x(value,port);IO_DELAY();} - -#define IN_DELAY(x,type) \ -unsigned type od_in##x##_p(unsigned long port) {unsigned type tmp=in##x(port);IO_DELAY();return tmp;} - - -OUT_DELAY(b,char) -OUT_DELAY(w,short) -OUT_DELAY(l,int) - -IN_DELAY(b,char) -IN_DELAY(w,short) -IN_DELAY(l,int) - - -/* Now for the string version of these functions */ -void od_outsb(unsigned long port, const void *addr, unsigned long count) -{ - int i; - unsigned char *p = (unsigned char *) addr; - - for (i = 0; i < count; i++, p++) { - outb(*p, port); - } -} - - -void od_insb(unsigned long port, void *addr, unsigned long count) -{ - int i; - unsigned char *p = (unsigned char *) addr; - - for (i = 0; i < count; i++, p++) { - *p = inb(port); - } -} - -/* For the 16 and 32 bit string functions, we have to worry about alignment. - * The SH does not do unaligned accesses, so we have to read as bytes and - * then write as a word or dword. - * This can be optimised a lot more, especially in the case where the data - * is aligned - */ - -void od_outsw(unsigned long port, const void *addr, unsigned long count) -{ - int i; - unsigned short tmp; - unsigned char *p = (unsigned char *) addr; - - for (i = 0; i < count; i++, p += 2) { - tmp = (*p) | ((*(p + 1)) << 8); - outw(tmp, port); - } -} - - -void od_insw(unsigned long port, void *addr, unsigned long count) -{ - int i; - unsigned short tmp; - unsigned char *p = (unsigned char *) addr; - - for (i = 0; i < count; i++, p += 2) { - tmp = inw(port); - p[0] = tmp & 0xff; - p[1] = (tmp >> 8) & 0xff; - } -} - - -void od_outsl(unsigned long port, const void *addr, unsigned long count) -{ - int i; - unsigned tmp; - unsigned char *p = (unsigned char *) addr; - - for (i = 0; i < count; i++, p += 4) { - tmp = (*p) | ((*(p + 1)) << 8) | ((*(p + 2)) << 16) | - ((*(p + 3)) << 24); - outl(tmp, port); - } -} - - -void od_insl(unsigned long port, void *addr, unsigned long count) -{ - int i; - unsigned tmp; - unsigned char *p = (unsigned char *) addr; - - for (i = 0; i < count; i++, p += 4) { - tmp = inl(port); - p[0] = tmp & 0xff; - p[1] = (tmp >> 8) & 0xff; - p[2] = (tmp >> 16) & 0xff; - p[3] = (tmp >> 24) & 0xff; - - } -} diff --git a/arch/sh/boards/overdrive/irq.c b/arch/sh/boards/overdrive/irq.c deleted file mode 100644 index 5d730c70389..00000000000 --- a/arch/sh/boards/overdrive/irq.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * Looks after interrupts on the overdrive board. - * - * Bases on the IPR irq system - */ - -#include <linux/init.h> -#include <linux/irq.h> - -#include <asm/system.h> -#include <asm/io.h> - -#include <asm/overdrive/overdrive.h> - -struct od_data { - int overdrive_irq; - int irq_mask; -}; - -#define NUM_EXTERNAL_IRQS 16 -#define EXTERNAL_IRQ_NOT_IN_USE (-1) -#define EXTERNAL_IRQ_NOT_ASSIGNED (-1) - -/* - * This table is used to determine what to program into the FPGA's CT register - * for the specified Linux IRQ. - * - * The irq_mask gives the interrupt number from the PCI board (PCI_Int(6:0)) - * but is one greater than that because the because the FPGA treats 0 - * as disabled, a value of 1 asserts PCI_Int0, and so on. - * - * The overdrive_irq specifies which of the eight interrupt sources generates - * that interrupt, and but is multiplied by four to give the bit offset into - * the CT register. - * - * The seven interrupts levels (SH4 IRL's) we have available here is hardwired - * by the EPLD. The assignments here of which PCI interrupt generates each - * level is arbitary. - */ -static struct od_data od_data_table[NUM_EXTERNAL_IRQS] = { - /* overdrive_irq , irq_mask */ - {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 0 */ - {EXTERNAL_IRQ_NOT_ASSIGNED, 7}, /* 1 */ - {EXTERNAL_IRQ_NOT_ASSIGNED, 6}, /* 2 */ - {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 3 */ - {EXTERNAL_IRQ_NOT_ASSIGNED, 5}, /* 4 */ - {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 5 */ - {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 6 */ - {EXTERNAL_IRQ_NOT_ASSIGNED, 4}, /* 7 */ - {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 8 */ - {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 9 */ - {EXTERNAL_IRQ_NOT_ASSIGNED, 3}, /* 10 */ - {EXTERNAL_IRQ_NOT_ASSIGNED, 2}, /* 11 */ - {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 12 */ - {EXTERNAL_IRQ_NOT_ASSIGNED, 1}, /* 13 */ - {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 14 */ - {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE} /* 15 */ -}; - -static void set_od_data(int overdrive_irq, int irq) -{ - if (irq >= NUM_EXTERNAL_IRQS || irq < 0) - return; - od_data_table[irq].overdrive_irq = overdrive_irq << 2; -} - -static void enable_od_irq(unsigned int irq); -void disable_od_irq(unsigned int irq); - -/* shutdown is same as "disable" */ -#define shutdown_od_irq disable_od_irq - -static void mask_and_ack_od(unsigned int); -static void end_od_irq(unsigned int irq); - -static unsigned int startup_od_irq(unsigned int irq) -{ - enable_od_irq(irq); - return 0; /* never anything pending */ -} - -static struct hw_interrupt_type od_irq_type = { - .typename = "Overdrive-IRQ", - .startup = startup_od_irq, - .shutdown = shutdown_od_irq, - .enable = enable_od_irq, - .disable = disable_od_irq, - .ack = mask_and_ack_od, - .end = end_od_irq -}; - -static void disable_od_irq(unsigned int irq) -{ - unsigned val, flags; - int overdrive_irq; - unsigned mask; - - /* Not a valid interrupt */ - if (irq < 0 || irq >= NUM_EXTERNAL_IRQS) - return; - - /* Is is necessary to use a cli here? Would a spinlock not be - * mroe efficient? - */ - local_irq_save(flags); - overdrive_irq = od_data_table[irq].overdrive_irq; - if (overdrive_irq != EXTERNAL_IRQ_NOT_ASSIGNED) { - mask = ~(0x7 << overdrive_irq); - val = ctrl_inl(OVERDRIVE_INT_CT); - val &= mask; - ctrl_outl(val, OVERDRIVE_INT_CT); - } - local_irq_restore(flags); -} - -static void enable_od_irq(unsigned int irq) -{ - unsigned val, flags; - int overdrive_irq; - unsigned mask; - - /* Not a valid interrupt */ - if (irq < 0 || irq >= NUM_EXTERNAL_IRQS) - return; - - /* Set priority in OD back to original value */ - local_irq_save(flags); - /* This one is not in use currently */ - overdrive_irq = od_data_table[irq].overdrive_irq; - if (overdrive_irq != EXTERNAL_IRQ_NOT_ASSIGNED) { - val = ctrl_inl(OVERDRIVE_INT_CT); - mask = ~(0x7 << overdrive_irq); - val &= mask; - mask = od_data_table[irq].irq_mask << overdrive_irq; - val |= mask; - ctrl_outl(val, OVERDRIVE_INT_CT); - } - local_irq_restore(flags); -} - - - -/* this functions sets the desired irq handler to be an overdrive type */ -static void __init make_od_irq(unsigned int irq) -{ - disable_irq_nosync(irq); - irq_desc[irq].chip = &od_irq_type; - disable_od_irq(irq); -} - - -static void mask_and_ack_od(unsigned int irq) -{ - disable_od_irq(irq); -} - -static void end_od_irq(unsigned int irq) -{ - enable_od_irq(irq); -} - -void __init init_overdrive_irq(void) -{ - int i; - - /* Disable all interrupts */ - ctrl_outl(0, OVERDRIVE_INT_CT); - - /* Update interrupt pin mode to use encoded interrupts */ - i = ctrl_inw(INTC_ICR); - i &= ~INTC_ICR_IRLM; - ctrl_outw(i, INTC_ICR); - - for (i = 0; i < NUM_EXTERNAL_IRQS; i++) { - if (od_data_table[i].irq_mask != EXTERNAL_IRQ_NOT_IN_USE) { - make_od_irq(i); - } else if (i != 15) { // Cannot use imask on level 15 - make_imask_irq(i); - } - } - - /* Set up the interrupts */ - set_od_data(OVERDRIVE_PCI_INTA, OVERDRIVE_PCI_IRQ1); - set_od_data(OVERDRIVE_PCI_INTB, OVERDRIVE_PCI_IRQ2); - set_od_data(OVERDRIVE_AUDIO_INT, OVERDRIVE_ESS_IRQ); -} diff --git a/arch/sh/boards/overdrive/led.c b/arch/sh/boards/overdrive/led.c deleted file mode 100644 index 860d7f204a4..00000000000 --- a/arch/sh/boards/overdrive/led.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * linux/arch/sh/overdrive/led.c - * - * Copyright (C) 1999 Stuart Menefy <stuart.menefy@st.com> - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * This file contains an Overdrive specific LED feature. - */ - -#include <asm/system.h> -#include <asm/io.h> -#include <asm/overdrive/overdrive.h> - -static void mach_led(int position, int value) -{ - unsigned long flags; - unsigned long reg; - - local_irq_save(flags); - - reg = readl(OVERDRIVE_CTRL); - if (value) { - reg |= (1<<3); - } else { - reg &= ~(1<<3); - } - writel(reg, OVERDRIVE_CTRL); - - local_irq_restore(flags); -} - -#ifdef CONFIG_HEARTBEAT - -#include <linux/sched.h> - -/* acts like an actual heart beat -- ie thump-thump-pause... */ -void heartbeat_od(void) -{ - static unsigned cnt = 0, period = 0, dist = 0; - - if (cnt == 0 || cnt == dist) - mach_led( -1, 1); - else if (cnt == 7 || cnt == dist+7) - mach_led( -1, 0); - - if (++cnt > period) { - cnt = 0; - /* The hyperbolic function below modifies the heartbeat period - * length in dependency of the current (5min) load. It goes - * through the points f(0)=126, f(1)=86, f(5)=51, - * f(inf)->30. */ - period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30; - dist = period / 4; - } -} -#endif /* CONFIG_HEARTBEAT */ diff --git a/arch/sh/boards/overdrive/mach.c b/arch/sh/boards/overdrive/mach.c deleted file mode 100644 index 2834a03ae47..00000000000 --- a/arch/sh/boards/overdrive/mach.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * linux/arch/sh/overdrive/mach.c - * - * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * Machine vector for the STMicroelectronics Overdrive - */ - -#include <linux/init.h> - -#include <asm/machvec.h> -#include <asm/rtc.h> -#include <asm/machvec_init.h> - -#include <asm/io_unknown.h> -#include <asm/io_generic.h> -#include <asm/overdrive/io.h> - -void heartbeat_od(void); -void init_overdrive_irq(void); -void galileo_pcibios_init(void); - -/* - * The Machine Vector - */ - -struct sh_machine_vector mv_od __initmv = { - .mv_nr_irqs = 48, - - .mv_inb = od_inb, - .mv_inw = od_inw, - .mv_inl = od_inl, - .mv_outb = od_outb, - .mv_outw = od_outw, - .mv_outl = od_outl, - - .mv_inb_p = od_inb_p, - .mv_inw_p = od_inw_p, - .mv_inl_p = od_inl_p, - .mv_outb_p = od_outb_p, - .mv_outw_p = od_outw_p, - .mv_outl_p = od_outl_p, - - .mv_insb = od_insb, - .mv_insw = od_insw, - .mv_insl = od_insl, - .mv_outsb = od_outsb, - .mv_outsw = od_outsw, - .mv_outsl = od_outsl, - -#ifdef CONFIG_PCI - .mv_init_irq = init_overdrive_irq, -#endif -#ifdef CONFIG_HEARTBEAT - .mv_heartbeat = heartbeat_od, -#endif -}; - -ALIAS_MV(od) diff --git a/arch/sh/boards/overdrive/pcidma.c b/arch/sh/boards/overdrive/pcidma.c deleted file mode 100644 index 1c9bfeda00b..00000000000 --- a/arch/sh/boards/overdrive/pcidma.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * Dynamic DMA mapping support. - * - * On the overdrive, we can only DMA from memory behind the PCI bus! - * this means that all DMA'able memory must come from there. - * this restriction will not apply to later boards. - */ - -#include <linux/types.h> -#include <linux/mm.h> -#include <linux/string.h> -#include <linux/pci.h> -#include <asm/io.h> - -void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, - dma_addr_t * dma_handle) -{ - void *ret; - int gfp = GFP_ATOMIC; - - printk("BUG: pci_alloc_consistent() called - not yet supported\n"); - /* We ALWAYS need DMA memory on the overdrive hardware, - * due to it's extreme weirdness - * Need to flush the cache here as well, since the memory - * can still be seen through the cache! - */ - gfp |= GFP_DMA; - ret = (void *) __get_free_pages(gfp, get_order(size)); - - if (ret != NULL) { - memset(ret, 0, size); - *dma_handle = virt_to_bus(ret); - } - return ret; -} - -void pci_free_consistent(struct pci_dev *hwdev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ - free_pages((unsigned long) vaddr, get_order(size)); -} diff --git a/arch/sh/boards/overdrive/setup.c b/arch/sh/boards/overdrive/setup.c deleted file mode 100644 index a3a7744c204..00000000000 --- a/arch/sh/boards/overdrive/setup.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * arch/sh/overdrive/setup.c - * - * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * STMicroelectronics Overdrive Support. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <asm/io.h> - -#include <asm/overdrive/overdrive.h> -#include <asm/overdrive/fpga.h> - -const char *get_system_type(void) -{ - return "SH7750 Overdrive"; -} - -/* - * Initialize the board - */ -int __init platform_setup(void) -{ -#ifdef CONFIG_PCI - init_overdrive_fpga(); - galileo_init(); -#endif - - /* Enable RS232 receive buffers */ - writel(0x1e, OVERDRIVE_CTRL); -} diff --git a/arch/sh/boards/renesas/edosk7705/Makefile b/arch/sh/boards/renesas/edosk7705/Makefile index 7fccbf2e4a1..14bdd531f11 100644 --- a/arch/sh/boards/renesas/edosk7705/Makefile +++ b/arch/sh/boards/renesas/edosk7705/Makefile @@ -1,10 +1,6 @@ # # Makefile for the EDOSK7705 specific parts of the kernel # -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# obj-y := setup.o io.o diff --git a/arch/sh/boards/renesas/edosk7705/setup.c b/arch/sh/boards/renesas/edosk7705/setup.c index ba143fa4afa..ec5be010771 100644 --- a/arch/sh/boards/renesas/edosk7705/setup.c +++ b/arch/sh/boards/renesas/edosk7705/setup.c @@ -8,19 +8,21 @@ * Modified for edosk7705 development * board by S. Dunn, 2003. */ - #include <linux/init.h> #include <asm/machvec.h> -#include <asm/machvec_init.h> #include <asm/edosk7705/io.h> -static void init_edosk7705(void); +static void __init sh_edosk7705_init_irq(void) +{ + /* This is the Ethernet interrupt */ + make_imask_irq(0x09); +} /* * The Machine Vector */ - struct sh_machine_vector mv_edosk7705 __initmv = { + .mv_name = "EDOSK7705", .mv_nr_irqs = 80, .mv_inb = sh_edosk7705_inb, @@ -37,23 +39,6 @@ struct sh_machine_vector mv_edosk7705 __initmv = { .mv_outsl = sh_edosk7705_outsl, .mv_isa_port2addr = sh_edosk7705_isa_port2addr, - .mv_init_irq = init_edosk7705, + .mv_init_irq = sh_edosk7705_init_irq, }; ALIAS_MV(edosk7705) - -static void __init init_edosk7705(void) -{ - /* This is the Ethernet interrupt */ - make_imask_irq(0x09); -} - -const char *get_system_type(void) -{ - return "EDOSK7705"; -} - -void __init platform_setup(void) -{ - /* Nothing .. */ -} - diff --git a/arch/sh/boards/renesas/hs7751rvoip/Kconfig b/arch/sh/boards/renesas/hs7751rvoip/Kconfig new file mode 100644 index 00000000000..1743be477be --- /dev/null +++ b/arch/sh/boards/renesas/hs7751rvoip/Kconfig @@ -0,0 +1,12 @@ +if SH_HS7751RVOIP + +menu "HS7751RVoIP options" + +config HS7751RVOIP_CODEC + bool "Support VoIP Codec section" + help + Selecting this option will support CODEC section. + +endmenu + +endif diff --git a/arch/sh/boards/renesas/hs7751rvoip/Makefile b/arch/sh/boards/renesas/hs7751rvoip/Makefile index e8b4109ace1..e626377c55e 100644 --- a/arch/sh/boards/renesas/hs7751rvoip/Makefile +++ b/arch/sh/boards/renesas/hs7751rvoip/Makefile @@ -1,12 +1,8 @@ # # Makefile for the HS7751RVoIP specific parts of the kernel # -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# -obj-y := mach.o setup.o io.o irq.o led.o +obj-y := setup.o io.o irq.o obj-$(CONFIG_PCI) += pci.o diff --git a/arch/sh/boards/renesas/hs7751rvoip/io.c b/arch/sh/boards/renesas/hs7751rvoip/io.c index 3a1abfa2fef..9ea1136b219 100644 --- a/arch/sh/boards/renesas/hs7751rvoip/io.c +++ b/arch/sh/boards/renesas/hs7751rvoip/io.c @@ -10,21 +10,16 @@ * placeholder code from io_hs7751rvoip.c left in with the * expectation of later SuperIO and PCMCIA access. */ - #include <linux/kernel.h> #include <linux/types.h> +#include <linux/module.h> +#include <linux/pci.h> #include <asm/io.h> #include <asm/hs7751rvoip/hs7751rvoip.h> #include <asm/addrspace.h> -#include <linux/module.h> -#include <linux/pci.h> -#include "../../../drivers/pci/pci-sh7751.h" - -extern void *area5_io8_base; /* Area 5 8bit I/O Base address */ extern void *area6_io8_base; /* Area 6 8bit I/O Base address */ extern void *area5_io16_base; /* Area 5 16bit I/O Base address */ -extern void *area6_io16_base; /* Area 6 16bit I/O Base address */ /* * The 7751R HS7751RVoIP uses the built-in PCI controller (PCIC) @@ -33,25 +28,8 @@ extern void *area6_io16_base; /* Area 6 16bit I/O Base address */ * like the other Solution Engine boards. */ -#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR) -#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR) -#define PCI_IO_AREA SH7751_PCI_IO_BASE -#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE - -#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK)) - -#if defined(CONFIG_HS7751RVOIP_CODEC) #define CODEC_IO_BASE 0x1000 -#endif - -#define maybebadio(name,port) \ - printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \ - #name, (port), (__u32) __builtin_return_address(0)) - -static inline void delay(void) -{ - ctrl_inw(0xa0000000); -} +#define CODEC_IOMAP(a) ((unsigned long)area6_io8_base + ((a) - CODEC_IO_BASE)) static inline unsigned long port2adr(unsigned int port) { @@ -59,9 +37,10 @@ static inline unsigned long port2adr(unsigned int port) if (port == 0x3f6) return ((unsigned long)area5_io16_base + 0x0c); else - return ((unsigned long)area5_io16_base + 0x800 + ((port-0x1f0) << 1)); + return ((unsigned long)area5_io16_base + 0x800 + + ((port-0x1f0) << 1)); else - maybebadio(port2adr, (unsigned long)port); + maybebadio((unsigned long)port); return port; } @@ -78,25 +57,10 @@ static inline int shifted_port(unsigned long port) } #if defined(CONFIG_HS7751RVOIP_CODEC) -static inline int -codec_port(unsigned long port) -{ - if (CODEC_IO_BASE <= port && port < (CODEC_IO_BASE+0x20)) - return 1; - else - return 0; -} -#endif - -/* In case someone configures the kernel w/o PCI support: in that */ -/* scenario, don't ever bother to check for PCI-window addresses */ - -/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */ -#if defined(CONFIG_PCI) -#define CHECK_SH7751_PCIIO(port) \ - ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE))) +#define codec_port(port) \ + ((CODEC_IO_BASE <= (port)) && ((port) < (CODEC_IO_BASE + 0x20))) #else -#define CHECK_SH7751_PCIIO(port) (0) +#define codec_port(port) (0) #endif /* @@ -109,15 +73,13 @@ codec_port(unsigned long port) unsigned char hs7751rvoip_inb(unsigned long port) { if (PXSEG(port)) - return *(volatile unsigned char *)port; -#if defined(CONFIG_HS7751RVOIP_CODEC) + return ctrl_inb(port); else if (codec_port(port)) - return *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)); -#endif - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - return *(volatile unsigned char *)PCI_IOMAP(port); + return ctrl_inb(CODEC_IOMAP(port)); + else if (is_pci_ioaddr(port) || shifted_port(port)) + return ctrl_inb(pci_ioaddr(port)); else - return (*(volatile unsigned short *)port2adr(port) & 0xff); + return ctrl_inw(port2adr(port)) & 0xff; } unsigned char hs7751rvoip_inb_p(unsigned long port) @@ -125,38 +87,36 @@ unsigned char hs7751rvoip_inb_p(unsigned long port) unsigned char v; if (PXSEG(port)) - v = *(volatile unsigned char *)port; -#if defined(CONFIG_HS7751RVOIP_CODEC) + v = ctrl_inb(port); else if (codec_port(port)) - v = *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)); -#endif - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - v = *(volatile unsigned char *)PCI_IOMAP(port); + v = ctrl_inb(CODEC_IOMAP(port)); + else if (is_pci_ioaddr(port) || shifted_port(port)) + v = ctrl_inb(pci_ioaddr(port)); else - v = (*(volatile unsigned short *)port2adr(port) & 0xff); - delay(); + v = ctrl_inw(port2adr(port)) & 0xff; + ctrl_delay(); return v; } unsigned short hs7751rvoip_inw(unsigned long port) { if (PXSEG(port)) - return *(volatile unsigned short *)port; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - return *(volatile unsigned short *)PCI_IOMAP(port); + return ctrl_inw(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + return ctrl_inw(pci_ioaddr(port)); else - maybebadio(inw, port); + maybebadio(port); return 0; } unsigned int hs7751rvoip_inl(unsigned long port) { if (PXSEG(port)) - return *(volatile unsigned long *)port; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - return *(volatile unsigned long *)PCI_IOMAP(port); + return ctrl_inl(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + return ctrl_inl(pci_ioaddr(port)); else - maybebadio(inl, port); + maybebadio(port); return 0; } @@ -164,146 +124,160 @@ void hs7751rvoip_outb(unsigned char value, unsigned long port) { if (PXSEG(port)) - *(volatile unsigned char *)port = value; -#if defined(CONFIG_HS7751RVOIP_CODEC) + ctrl_outb(value, port); else if (codec_port(port)) - *(volatile unsigned cjar *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)) = value; -#endif - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - *(unsigned char *)PCI_IOMAP(port) = value; + ctrl_outb(value, CODEC_IOMAP(port)); + else if (is_pci_ioaddr(port) || shifted_port(port)) + ctrl_outb(value, pci_ioaddr(port)); else - *(volatile unsigned short *)port2adr(port) = value; + ctrl_outb(value, port2adr(port)); } void hs7751rvoip_outb_p(unsigned char value, unsigned long port) { if (PXSEG(port)) - *(volatile unsigned char *)port = value; -#if defined(CONFIG_HS7751RVOIP_CODEC) + ctrl_outb(value, port); else if (codec_port(port)) - *(volatile unsigned cjar *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)) = value; -#endif - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - *(unsigned char *)PCI_IOMAP(port) = value; + ctrl_outb(value, CODEC_IOMAP(port)); + else if (is_pci_ioaddr(port) || shifted_port(port)) + ctrl_outb(value, pci_ioaddr(port)); else - *(volatile unsigned short *)port2adr(port) = value; - delay(); + ctrl_outw(value, port2adr(port)); + + ctrl_delay(); } void hs7751rvoip_outw(unsigned short value, unsigned long port) { if (PXSEG(port)) - *(volatile unsigned short *)port = value; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - *(unsigned short *)PCI_IOMAP(port) = value; + ctrl_outw(value, port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + ctrl_outw(value, pci_ioaddr(port)); else - maybebadio(outw, port); + maybebadio(port); } void hs7751rvoip_outl(unsigned int value, unsigned long port) { if (PXSEG(port)) - *(volatile unsigned long *)port = value; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - *((unsigned long *)PCI_IOMAP(port)) = value; + ctrl_outl(value, port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + ctrl_outl(value, pci_ioaddr(port)); else - maybebadio(outl, port); + maybebadio(port); } void hs7751rvoip_insb(unsigned long port, void *addr, unsigned long count) { + u8 *buf = addr; + if (PXSEG(port)) - while (count--) *((unsigned char *) addr)++ = *(volatile unsigned char *)port; -#if defined(CONFIG_HS7751RVOIP_CODEC) + while (count--) + *buf++ = ctrl_inb(port); else if (codec_port(port)) - while (count--) *((unsigned char *) addr)++ = *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)); -#endif - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { - volatile __u8 *bp = (__u8 *)PCI_IOMAP(port); + while (count--) + *buf++ = ctrl_inb(CODEC_IOMAP(port)); + else if (is_pci_ioaddr(port) || shifted_port(port)) { + volatile u8 *bp = (volatile u8 *)pci_ioaddr(port); - while (count--) *((volatile unsigned char *) addr)++ = *bp; + while (count--) + *buf++ = *bp; } else { - volatile __u16 *p = (volatile unsigned short *)port2adr(port); + volatile u16 *p = (volatile u16 *)port2adr(port); - while (count--) *((unsigned char *) addr)++ = *p & 0xff; + while (count--) + *buf++ = *p & 0xff; } } void hs7751rvoip_insw(unsigned long port, void *addr, unsigned long count) { - volatile __u16 *p; + volatile u16 *p; + u16 *buf = addr; if (PXSEG(port)) - p = (volatile unsigned short *)port; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - p = (volatile unsigned short *)PCI_IOMAP(port); + p = (volatile u16 *)port; + else if (is_pci_ioaddr(port) || shifted_port(port)) + p = (volatile u16 *)pci_ioaddr(port); else - p = (volatile unsigned short *)port2adr(port); - while (count--) *((__u16 *) addr)++ = *p; + p = (volatile u16 *)port2adr(port); + while (count--) + *buf++ = *p; } void hs7751rvoip_insl(unsigned long port, void *addr, unsigned long count) { - if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { - volatile __u32 *p = (__u32 *)PCI_IOMAP(port); - while (count--) *((__u32 *) addr)++ = *p; + if (is_pci_ioaddr(port) || shifted_port(port)) { + volatile u32 *p = (volatile u32 *)pci_ioaddr(port); + u32 *buf = addr; + + while (count--) + *buf++ = *p; } else - maybebadio(insl, port); + maybebadio(port); } void hs7751rvoip_outsb(unsigned long port, const void *addr, unsigned long count) { + const u8 *buf = addr; + if (PXSEG(port)) - while (count--) *(volatile unsigned char *)port = *((unsigned char *) addr)++; -#if defined(CONFIG_HS7751RVOIP_CODEC) + while (count--) + ctrl_outb(*buf++, port); else if (codec_port(port)) - while (count--) *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)) = *((unsigned char *) addr)++; -#endif - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { - volatile __u8 *bp = (__u8 *)PCI_IOMAP(port); + while (count--) + ctrl_outb(*buf++, CODEC_IOMAP(port)); + else if (is_pci_ioaddr(port) || shifted_port(port)) { + volatile u8 *bp = (volatile u8 *)pci_ioaddr(port); - while (count--) *bp = *((volatile unsigned char *) addr)++; + while (count--) + *bp = *buf++; } else { - volatile __u16 *p = (volatile unsigned short *)port2adr(port); + volatile u16 *p = (volatile u16 *)port2adr(port); - while (count--) *p = *((unsigned char *) addr)++; + while (count--) + *p = *buf++; } } void hs7751rvoip_outsw(unsigned long port, const void *addr, unsigned long count) { - volatile __u16 *p; + volatile u16 *p; + const u16 *buf = addr; if (PXSEG(port)) - p = (volatile unsigned short *)port; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - p = (volatile unsigned short *)PCI_IOMAP(port); + p = (volatile u16 *)port; + else if (is_pci_ioaddr(port) || shifted_port(port)) + p = (volatile u16 *)pci_ioaddr(port); else - p = (volatile unsigned short *)port2adr(port); - while (count--) *p = *((__u16 *) addr)++; + p = (volatile u16 *)port2adr(port); + + while (count--) + *p = *buf++; } void hs7751rvoip_outsl(unsigned long port, const void *addr, unsigned long count) { - if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { - volatile __u32 *p = (__u32 *)PCI_IOMAP(port); + const u32 *buf = addr; - while (count--) *p = *((__u32 *) addr)++; + if (is_pci_ioaddr(port) || shifted_port(port)) { + volatile u32 *p = (volatile u32 *)pci_ioaddr(port); + + while (count--) + *p = *buf++; } else - maybebadio(outsl, port); + maybebadio(port); } -void *hs7751rvoip_ioremap(unsigned long offset, unsigned long size) +void __iomem *hs7751rvoip_ioport_map(unsigned long port, unsigned int size) { - if (offset >= 0xfd000000) - return (void *)offset; - else - return (void *)P2SEGADDR(offset); -} -EXPORT_SYMBOL(hs7751rvoip_ioremap); + if (PXSEG(port)) + return (void __iomem *)port; + else if (unlikely(codec_port(port) && (size == 1))) + return (void __iomem *)CODEC_IOMAP(port); + else if (is_pci_ioaddr(port)) + return (void __iomem *)pci_ioaddr(port); -unsigned long hs7751rvoip_isa_port2addr(unsigned long offset) -{ - return port2adr(offset); + return (void __iomem *)port2adr(port); } diff --git a/arch/sh/boards/renesas/hs7751rvoip/irq.c b/arch/sh/boards/renesas/hs7751rvoip/irq.c index 705b7ddcb0d..c617b188258 100644 --- a/arch/sh/boards/renesas/hs7751rvoip/irq.c +++ b/arch/sh/boards/renesas/hs7751rvoip/irq.c @@ -35,30 +35,24 @@ static unsigned int startup_hs7751rvoip_irq(unsigned int irq) static void disable_hs7751rvoip_irq(unsigned int irq) { - unsigned long flags; unsigned short val; unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]); /* Set the priority in IPR to 0 */ - local_irq_save(flags); val = ctrl_inw(IRLCNTR3); val &= mask; ctrl_outw(val, IRLCNTR3); - local_irq_restore(flags); } static void enable_hs7751rvoip_irq(unsigned int irq) { - unsigned long flags; unsigned short val; unsigned short value = (0x0001 << mask_pos[irq]); /* Set priority in IPR back to original value */ - local_irq_save(flags); val = ctrl_inw(IRLCNTR3); val |= value; ctrl_outw(val, IRLCNTR3); - local_irq_restore(flags); } static void ack_hs7751rvoip_irq(unsigned int irq) diff --git a/arch/sh/boards/renesas/hs7751rvoip/led.c b/arch/sh/boards/renesas/hs7751rvoip/led.c deleted file mode 100644 index b6608fff9f3..00000000000 --- a/arch/sh/boards/renesas/hs7751rvoip/led.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * linux/arch/sh/kernel/setup_hs7751rvoip.c - * - * Copyright (C) 2000 Kazumoto Kojima - * - * Renesas Technology Sales HS7751RVoIP Support. - * - * Modified for HS7751RVoIP by - * Atom Create Engineering Co., Ltd. 2002. - * Lineo uSolutions, Inc. 2003. - */ - -#include <asm/io.h> -#include <asm/hs7751rvoip/hs7751rvoip.h> - -extern unsigned int debug_counter; - -void debug_led_disp(void) -{ - unsigned short value; - - value = (unsigned char)debug_counter++; - ctrl_outb((0xf0|value), PA_OUTPORTR); - if (value == 0x0f) - debug_counter = 0; -} diff --git a/arch/sh/boards/renesas/hs7751rvoip/mach.c b/arch/sh/boards/renesas/hs7751rvoip/mach.c deleted file mode 100644 index caf967f77c6..00000000000 --- a/arch/sh/boards/renesas/hs7751rvoip/mach.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * linux/arch/sh/kernel/mach_hs7751rvoip.c - * - * Minor tweak of mach_se.c file to reference hs7751rvoip-specific items. - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * Machine vector for the Renesas Technology sales HS7751RVoIP - */ - -#include <linux/init.h> - -#include <asm/machvec.h> -#include <asm/rtc.h> -#include <asm/irq.h> -#include <asm/hs7751rvoip/io.h> - -extern void init_hs7751rvoip_IRQ(void); -extern void *hs7751rvoip_ioremap(unsigned long, unsigned long); - -/* - * The Machine Vector - */ - -struct sh_machine_vector mv_hs7751rvoip __initmv = { - .mv_nr_irqs = 72, - - .mv_inb = hs7751rvoip_inb, - .mv_inw = hs7751rvoip_inw, - .mv_inl = hs7751rvoip_inl, - .mv_outb = hs7751rvoip_outb, - .mv_outw = hs7751rvoip_outw, - .mv_outl = hs7751rvoip_outl, - - .mv_inb_p = hs7751rvoip_inb_p, - .mv_inw_p = hs7751rvoip_inw, - .mv_inl_p = hs7751rvoip_inl, - .mv_outb_p = hs7751rvoip_outb_p, - .mv_outw_p = hs7751rvoip_outw, - .mv_outl_p = hs7751rvoip_outl, - - .mv_insb = hs7751rvoip_insb, - .mv_insw = hs7751rvoip_insw, - .mv_insl = hs7751rvoip_insl, - .mv_outsb = hs7751rvoip_outsb, - .mv_outsw = hs7751rvoip_outsw, - .mv_outsl = hs7751rvoip_outsl, - - .mv_ioremap = hs7751rvoip_ioremap, - .mv_isa_port2addr = hs7751rvoip_isa_port2addr, - .mv_init_irq = init_hs7751rvoip_IRQ, -}; -ALIAS_MV(hs7751rvoip) diff --git a/arch/sh/boards/renesas/hs7751rvoip/setup.c b/arch/sh/boards/renesas/hs7751rvoip/setup.c index 29fb5ff70fb..0414c15c345 100644 --- a/arch/sh/boards/renesas/hs7751rvoip/setup.c +++ b/arch/sh/boards/renesas/hs7751rvoip/setup.c @@ -1,44 +1,38 @@ /* - * linux/arch/sh/kernel/setup_hs7751rvoip.c + * Renesas Technology Sales HS7751RVoIP Support. * * Copyright (C) 2000 Kazumoto Kojima * - * Renesas Technology Sales HS7751RVoIP Support. - * * Modified for HS7751RVoIP by * Atom Create Engineering Co., Ltd. 2002. * Lineo uSolutions, Inc. 2003. */ - #include <linux/init.h> #include <linux/irq.h> - +#include <linux/mm.h> +#include <linux/vmalloc.h> #include <linux/hdreg.h> #include <linux/ide.h> +#include <linux/pm.h> #include <asm/io.h> #include <asm/hs7751rvoip/hs7751rvoip.h> +#include <asm/machvec.h> +#include <asm/rtc.h> +#include <asm/irq.h> -#include <linux/mm.h> -#include <linux/vmalloc.h> - -/* defined in mm/ioremap.c */ -extern void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags); - -unsigned int debug_counter; - -const char *get_system_type(void) +static void __init hs7751rvoip_init_irq(void) { - return "HS7751RVoIP"; +#if defined(CONFIG_HS7751RVOIP_CODEC) + make_ipr_irq(DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); + make_ipr_irq(DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); +#endif + + init_hs7751rvoip_IRQ(); } -/* - * Initialize the board - */ -void __init platform_setup(void) +static void hs7751rvoip_power_off(void) { - printk(KERN_INFO "Renesas Technology Sales HS7751RVoIP-2 support.\n"); - ctrl_outb(0xf0, PA_OUTPORTR); - debug_counter = 0; + ctrl_outw(ctrl_inw(PA_OUTPORTR) & 0xffdf, PA_OUTPORTR); } void *area5_io8_base; @@ -46,16 +40,15 @@ void *area6_io8_base; void *area5_io16_base; void *area6_io16_base; -int __init cf_init(void) +static int __init hs7751rvoip_cf_init(void) { pgprot_t prot; - unsigned long paddrbase, psize; + unsigned long paddrbase; /* open I/O area window */ paddrbase = virt_to_phys((void *)(PA_AREA5_IO+0x00000800)); - psize = PAGE_SIZE; prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_COM16); - area5_io16_base = p3_ioremap(paddrbase, psize, prot.pgprot); + area5_io16_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot); if (!area5_io16_base) { printk("allocate_cf_area : can't open CF I/O window!\n"); return -ENOMEM; @@ -64,19 +57,18 @@ int __init cf_init(void) /* XXX : do we need attribute and common-memory area also? */ paddrbase = virt_to_phys((void *)PA_AREA6_IO); - psize = PAGE_SIZE; #if defined(CONFIG_HS7751RVOIP_CODEC) prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_COM8); #else prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO8); #endif - area6_io8_base = p3_ioremap(paddrbase, psize, prot.pgprot); + area6_io8_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot); if (!area6_io8_base) { printk("allocate_cf_area : can't open CODEC I/O 8bit window!\n"); return -ENOMEM; } prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO16); - area6_io16_base = p3_ioremap(paddrbase, psize, prot.pgprot); + area6_io16_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot); if (!area6_io16_base) { printk("allocate_cf_area : can't open CODEC I/O 16bit window!\n"); return -ENOMEM; @@ -85,4 +77,46 @@ int __init cf_init(void) return 0; } -__initcall (cf_init); +/* + * Initialize the board + */ +static void __init hs7751rvoip_setup(char **cmdline_p) +{ + device_initcall(hs7751rvoip_cf_init); + + ctrl_outb(0xf0, PA_OUTPORTR); + pm_power_off = hs7751rvoip_power_off; + + printk(KERN_INFO "Renesas Technology Sales HS7751RVoIP-2 support.\n"); +} + +struct sh_machine_vector mv_hs7751rvoip __initmv = { + .mv_name = "HS7751RVoIP", + .mv_setup = hs7751rvoip_setup, + .mv_nr_irqs = 72, + + .mv_inb = hs7751rvoip_inb, + .mv_inw = hs7751rvoip_inw, + .mv_inl = hs7751rvoip_inl, + .mv_outb = hs7751rvoip_outb, + .mv_outw = hs7751rvoip_outw, + .mv_outl = hs7751rvoip_outl, + + .mv_inb_p = hs7751rvoip_inb_p, + .mv_inw_p = hs7751rvoip_inw, + .mv_inl_p = hs7751rvoip_inl, + .mv_outb_p = hs7751rvoip_outb_p, + .mv_outw_p = hs7751rvoip_outw, + .mv_outl_p = hs7751rvoip_outl, + + .mv_insb = hs7751rvoip_insb, + .mv_insw = hs7751rvoip_insw, + .mv_insl = hs7751rvoip_insl, + .mv_outsb = hs7751rvoip_outsb, + .mv_outsw = hs7751rvoip_outsw, + .mv_outsl = hs7751rvoip_outsl, + + .mv_init_irq = hs7751rvoip_init_irq, + .mv_ioport_map = hs7751rvoip_ioport_map, +}; +ALIAS_MV(hs7751rvoip) diff --git a/arch/sh/boards/renesas/r7780rp/Kconfig b/arch/sh/boards/renesas/r7780rp/Kconfig new file mode 100644 index 00000000000..c26d9813d23 --- /dev/null +++ b/arch/sh/boards/renesas/r7780rp/Kconfig @@ -0,0 +1,14 @@ +if SH_R7780RP + +menu "R7780RP options" + +config SH_R7780MP + bool "R7780MP board support" + default y + help + Selecting this option will enable support for the mass-production + version of the R7780RP. If in doubt, say Y. + +endmenu + +endif diff --git a/arch/sh/boards/renesas/r7780rp/Makefile b/arch/sh/boards/renesas/r7780rp/Makefile new file mode 100644 index 00000000000..f1776d02797 --- /dev/null +++ b/arch/sh/boards/renesas/r7780rp/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the R7780RP-1 specific parts of the kernel +# + +obj-y := setup.o io.o irq.o +obj-$(CONFIG_HEARTBEAT) += led.o diff --git a/arch/sh/boards/renesas/r7780rp/io.c b/arch/sh/boards/renesas/r7780rp/io.c new file mode 100644 index 00000000000..db92d6e6ae9 --- /dev/null +++ b/arch/sh/boards/renesas/r7780rp/io.c @@ -0,0 +1,301 @@ +/* + * Copyright (C) 2001 Ian da Silva, Jeremy Siegel + * Based largely on io_se.c. + * + * I/O routine for Renesas Solutions Highlander R7780RP-1 + * + * Initial version only to support LAN access; some + * placeholder code from io_r7780rp.c left in with the + * expectation of later SuperIO and PCMCIA access. + */ +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <asm/r7780rp/r7780rp.h> +#include <asm/addrspace.h> +#include <asm/io.h> + +static inline unsigned long port2adr(unsigned int port) +{ + if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) + if (port == 0x3f6) + return (PA_AREA5_IO + 0x80c); + else + return (PA_AREA5_IO + 0x1000 + ((port-0x1f0) << 1)); + else + maybebadio((unsigned long)port); + + return port; +} + +static inline unsigned long port88796l(unsigned int port, int flag) +{ + unsigned long addr; + + if (flag) + addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1); + else + addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1) + 0x1000; + + return addr; +} + +/* The 7780 R7780RP-1 seems to have everything hooked */ +/* up pretty normally (nothing on high-bytes only...) so this */ +/* shouldn't be needed */ +static inline int shifted_port(unsigned long port) +{ + /* For IDE registers, value is not shifted */ + if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) + return 0; + else + return 1; +} + +#if defined(CONFIG_NE2000) || defined(CONFIG_NE2000_MODULE) +#define CHECK_AX88796L_PORT(port) \ + ((port >= AX88796L_IO_BASE) && (port < (AX88796L_IO_BASE+0x20))) +#else +#define CHECK_AX88796L_PORT(port) (0) +#endif + +/* + * General outline: remap really low stuff [eventually] to SuperIO, + * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) + * is mapped through the PCI IO window. Stuff with high bits (PXSEG) + * should be way beyond the window, and is used w/o translation for + * compatibility. + */ +u8 r7780rp_inb(unsigned long port) +{ + if (CHECK_AX88796L_PORT(port)) + return ctrl_inw(port88796l(port, 0)) & 0xff; + else if (PXSEG(port)) + return ctrl_inb(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + return ctrl_inb(pci_ioaddr(port)); + + return ctrl_inw(port2adr(port)) & 0xff; +} + +u8 r7780rp_inb_p(unsigned long port) +{ + u8 v; + + if (CHECK_AX88796L_PORT(port)) + v = ctrl_inw(port88796l(port, 0)) & 0xff; + else if (PXSEG(port)) + v = ctrl_inb(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + v = ctrl_inb(pci_ioaddr(port)); + else + v = ctrl_inw(port2adr(port)) & 0xff; + + ctrl_delay(); + + return v; +} + +u16 r7780rp_inw(unsigned long port) +{ + if (CHECK_AX88796L_PORT(port)) + maybebadio(port); + else if (PXSEG(port)) + return ctrl_inw(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + return ctrl_inw(pci_ioaddr(port)); + else + maybebadio(port); + + return 0; +} + +u32 r7780rp_inl(unsigned long port) +{ + if (CHECK_AX88796L_PORT(port)) + maybebadio(port); + else if (PXSEG(port)) + return ctrl_inl(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + return ctrl_inl(pci_ioaddr(port)); + else + maybebadio(port); + + return 0; +} + +void r7780rp_outb(u8 value, unsigned long port) +{ + if (CHECK_AX88796L_PORT(port)) + ctrl_outw(value, port88796l(port, 0)); + else if (PXSEG(port)) + ctrl_outb(value, port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + ctrl_outb(value, pci_ioaddr(port)); + else + ctrl_outw(value, port2adr(port)); +} + +void r7780rp_outb_p(u8 value, unsigned long port) +{ + if (CHECK_AX88796L_PORT(port)) + ctrl_outw(value, port88796l(port, 0)); + else if (PXSEG(port)) + ctrl_outb(value, port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + ctrl_outb(value, pci_ioaddr(port)); + else + ctrl_outw(value, port2adr(port)); + + ctrl_delay(); +} + +void r7780rp_outw(u16 value, unsigned long port) +{ + if (CHECK_AX88796L_PORT(port)) + maybebadio(port); + else if (PXSEG(port)) + ctrl_outw(value, port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + ctrl_outw(value, pci_ioaddr(port)); + else + maybebadio(port); +} + +void r7780rp_outl(u32 value, unsigned long port) +{ + if (CHECK_AX88796L_PORT(port)) + maybebadio(port); + else if (PXSEG(port)) + ctrl_outl(value, port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + ctrl_outl(value, pci_ioaddr(port)); + else + maybebadio(port); +} + +void r7780rp_insb(unsigned long port, void *dst, unsigned long count) +{ + volatile u16 *p; + u8 *buf = dst; + + if (CHECK_AX88796L_PORT(port)) { + p = (volatile u16 *)port88796l(port, 0); + while (count--) + *buf++ = *p & 0xff; + } else if (PXSEG(port)) { + while (count--) + *buf++ = *(volatile u8 *)port; + } else if (is_pci_ioaddr(port) || shifted_port(port)) { + volatile u8 *bp = (volatile u8 *)pci_ioaddr(port); + + while (count--) + *buf++ = *bp; + } else { + p = (volatile u16 *)port2adr(port); + while (count--) + *buf++ = *p & 0xff; + } +} + +void r7780rp_insw(unsigned long port, void *dst, unsigned long count) +{ + volatile u16 *p; + u16 *buf = dst; + + if (CHECK_AX88796L_PORT(port)) + p = (volatile u16 *)port88796l(port, 1); + else if (PXSEG(port)) + p = (volatile u16 *)port; + else if (is_pci_ioaddr(port) || shifted_port(port)) + p = (volatile u16 *)pci_ioaddr(port); + else + p = (volatile u16 *)port2adr(port); + + while (count--) + *buf++ = *p; +} + +void r7780rp_insl(unsigned long port, void *dst, unsigned long count) +{ + u32 *buf = dst; + + if (CHECK_AX88796L_PORT(port)) + maybebadio(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) { + volatile u32 *p = (volatile u32 *)pci_ioaddr(port); + + while (count--) + *buf++ = *p; + } else + maybebadio(port); +} + +void r7780rp_outsb(unsigned long port, const void *src, unsigned long count) +{ + volatile u16 *p; + const u8 *buf = src; + + if (CHECK_AX88796L_PORT(port)) { + p = (volatile u16 *)port88796l(port, 0); + while (count--) + *p = *buf++; + } else if (PXSEG(port)) + while (count--) + ctrl_outb(*buf++, port); + else if (is_pci_ioaddr(port) || shifted_port(port)) { + volatile u8 *bp = (volatile u8 *)pci_ioaddr(port); + + while (count--) + *bp = *buf++; + } else { + p = (volatile u16 *)port2adr(port); + while (count--) + *p = *buf++; + } +} + +void r7780rp_outsw(unsigned long port, const void *src, unsigned long count) +{ + volatile u16 *p; + const u16 *buf = src; + + if (CHECK_AX88796L_PORT(port)) + p = (volatile u16 *)port88796l(port, 1); + else if (PXSEG(port)) + p = (volatile u16 *)port; + else if (is_pci_ioaddr(port) || shifted_port(port)) + p = (volatile u16 *)pci_ioaddr(port); + else + p = (volatile u16 *)port2adr(port); + + while (count--) + *p = *buf++; +} + +void r7780rp_outsl(unsigned long port, const void *src, unsigned long count) +{ + const u32 *buf = src; + + if (CHECK_AX88796L_PORT(port)) + maybebadio(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) { + volatile u32 *p = (volatile u32 *)pci_ioaddr(port); + + while (count--) + *p = *buf++; + } else + maybebadio(port); +} + +void __iomem *r7780rp_ioport_map(unsigned long port, unsigned int size) +{ + if (CHECK_AX88796L_PORT(port)) + return (void __iomem *)port88796l(port, size > 1); + else if (PXSEG(port)) + return (void __iomem *)port; + else if (is_pci_ioaddr(port) || shifted_port(port)) + return (void __iomem *)pci_ioaddr(port); + + return (void __iomem *)port2adr(port); +} diff --git a/arch/sh/boards/renesas/r7780rp/irq.c b/arch/sh/boards/renesas/r7780rp/irq.c new file mode 100644 index 00000000000..61d5e5d3c29 --- /dev/null +++ b/arch/sh/boards/renesas/r7780rp/irq.c @@ -0,0 +1,117 @@ +/* + * linux/arch/sh/boards/renesas/r7780rp/irq.c + * + * Copyright (C) 2000 Kazumoto Kojima + * + * Renesas Solutions Highlander R7780RP-1 Support. + * + * Modified for R7780RP-1 by + * Atom Create Engineering Co., Ltd. 2002. + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/irq.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/r7780rp/r7780rp.h> + +#ifdef CONFIG_SH_R7780MP +static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0}; +#else +static int mask_pos[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 5, 6, 4, 0, 1, 2, 0}; +#endif + +static void enable_r7780rp_irq(unsigned int irq); +static void disable_r7780rp_irq(unsigned int irq); + +/* shutdown is same as "disable" */ +#define shutdown_r7780rp_irq disable_r7780rp_irq + +static void ack_r7780rp_irq(unsigned int irq); +static void end_r7780rp_irq(unsigned int irq); + +static unsigned int startup_r7780rp_irq(unsigned int irq) +{ + enable_r7780rp_irq(irq); + return 0; /* never anything pending */ +} + +static void disable_r7780rp_irq(unsigned int irq) +{ + unsigned short val; + unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]); + + /* Set the priority in IPR to 0 */ + val = ctrl_inw(IRLCNTR1); + val &= mask; + ctrl_outw(val, IRLCNTR1); +} + +static void enable_r7780rp_irq(unsigned int irq) +{ + unsigned short val; + unsigned short value = (0x0001 << mask_pos[irq]); + + /* Set priority in IPR back to original value */ + val = ctrl_inw(IRLCNTR1); + val |= value; + ctrl_outw(val, IRLCNTR1); +} + +static void ack_r7780rp_irq(unsigned int irq) +{ + disable_r7780rp_irq(irq); +} + +static void end_r7780rp_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_r7780rp_irq(irq); +} + +static struct hw_interrupt_type r7780rp_irq_type = { + .typename = "R7780RP-IRQ", + .startup = startup_r7780rp_irq, + .shutdown = shutdown_r7780rp_irq, + .enable = enable_r7780rp_irq, + .disable = disable_r7780rp_irq, + .ack = ack_r7780rp_irq, + .end = end_r7780rp_irq, +}; + +static void make_r7780rp_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + irq_desc[irq].handler = &r7780rp_irq_type; + disable_r7780rp_irq(irq); +} + +/* + * Initialize IRQ setting + */ +void __init init_r7780rp_IRQ(void) +{ + int i; + + /* IRL0=PCI Slot #A + * IRL1=PCI Slot #B + * IRL2=PCI Slot #C + * IRL3=PCI Slot #D + * IRL4=CF Card + * IRL5=CF Card Insert + * IRL6=M66596 + * IRL7=SD Card + * IRL8=Touch Panel + * IRL9=SCI + * IRL10=Serial + * IRL11=Extention #A + * IRL11=Extention #B + * IRL12=Debug LAN + * IRL13=Push Switch + * IRL14=ZiggBee IO + */ + + for (i=0; i<15; i++) + make_r7780rp_irq(i); +} diff --git a/arch/sh/boards/renesas/r7780rp/led.c b/arch/sh/boards/renesas/r7780rp/led.c new file mode 100644 index 00000000000..9f02766b6f5 --- /dev/null +++ b/arch/sh/boards/renesas/r7780rp/led.c @@ -0,0 +1,45 @@ +/* + * Copyright (C) Atom Create Engineering Co., Ltd. + * + * May be copied or modified under the terms of GNU General Public + * License. See linux/COPYING for more information. + * + * This file contains Renesas Solutions HIGHLANDER R7780RP-1 specific LED code. + */ + +#include <linux/config.h> +#include <linux/sched.h> +#include <asm/io.h> +#include <asm/r7780rp/r7780rp.h> + +/* Cycle the LED's in the clasic Knightriger/Sun pattern */ +void heartbeat_r7780rp(void) +{ + static unsigned int cnt = 0, period = 0; + volatile unsigned short *p = (volatile unsigned short *)PA_OBLED; + static unsigned bit = 0, up = 1; + unsigned bit_pos[] = {2, 1, 0, 3, 6, 5, 4, 7}; + + cnt += 1; + if (cnt < period) + return; + + cnt = 0; + + /* Go through the points (roughly!): + * f(0)=10, f(1)=16, f(2)=20, f(5)=35, f(int)->110 + */ + period = 110 - ((300 << FSHIFT)/((avenrun[0]/5) + (3<<FSHIFT))); + + *p = 1 << bit_pos[bit]; + if (up) + if (bit == 7) { + bit--; + up = 0; + } else + bit++; + else if (bit == 0) + up = 1; + else + bit--; +} diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c new file mode 100644 index 00000000000..b941aa0aa34 --- /dev/null +++ b/arch/sh/boards/renesas/r7780rp/setup.c @@ -0,0 +1,163 @@ +/* + * arch/sh/boards/renesas/r7780rp/setup.c + * + * Copyright (C) 2002 Atom Create Engineering Co., Ltd. + * Copyright (C) 2005, 2006 Paul Mundt + * + * Renesas Solutions Highlander R7780RP-1 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 <asm/machvec.h> +#include <asm/r7780rp/r7780rp.h> +#include <asm/clock.h> +#include <asm/io.h> + +extern void heartbeat_r7780rp(void); +extern void init_r7780rp_IRQ(void); + +static struct resource m66596_usb_host_resources[] = { + [0] = { + .start = 0xa4800000, + .end = 0xa4ffffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 6, /* irq number */ + .end = 6, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device m66596_usb_host_device = { + .name = "m66596-hcd", + .id = 0, + .dev = { + .dma_mask = NULL, /* don't use dma */ + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(m66596_usb_host_resources), + .resource = m66596_usb_host_resources, +}; + +static struct platform_device *r7780rp_devices[] __initdata = { + &m66596_usb_host_device, +}; + +static int __init r7780rp_devices_setup(void) +{ + return platform_add_devices(r7780rp_devices, + ARRAY_SIZE(r7780rp_devices)); +} + +/* + * Platform specific clocks + */ +static void ivdr_clk_enable(struct clk *clk) +{ + ctrl_outw(ctrl_inw(PA_IVDRCTL) | (1 << 8), PA_IVDRCTL); +} + +static void ivdr_clk_disable(struct clk *clk) +{ + ctrl_outw(ctrl_inw(PA_IVDRCTL) & ~(1 << 8), PA_IVDRCTL); +} + +static struct clk_ops ivdr_clk_ops = { + .enable = ivdr_clk_enable, + .disable = ivdr_clk_disable, +}; + +static struct clk ivdr_clk = { + .name = "ivdr_clk", + .ops = &ivdr_clk_ops, +}; + +static struct clk *r7780rp_clocks[] = { + &ivdr_clk, +}; + +static void r7780rp_power_off(void) +{ +#ifdef CONFIG_SH_R7780MP + ctrl_outw(0x0001, PA_POFF); +#endif +} + +/* + * Initialize the board + */ +static void __init r7780rp_setup(char **cmdline_p) +{ + u16 ver = ctrl_inw(PA_VERREG); + int i; + + device_initcall(r7780rp_devices_setup); + + printk(KERN_INFO "Renesas Solutions Highlander R7780RP-1 support.\n"); + + printk(KERN_INFO "Board version: %d (revision %d), " + "FPGA version: %d (revision %d)\n", + (ver >> 12) & 0xf, (ver >> 8) & 0xf, + (ver >> 4) & 0xf, ver & 0xf); + + /* + * Enable the important clocks right away.. + */ + for (i = 0; i < ARRAY_SIZE(r7780rp_clocks); i++) { + struct clk *clk = r7780rp_clocks[i]; + + clk_register(clk); + clk_enable(clk); + } + + ctrl_outw(0x0000, PA_OBLED); /* Clear LED. */ +#ifndef CONFIG_SH_R7780MP + ctrl_outw(0x0001, PA_SDPOW); /* SD Power ON */ +#endif + ctrl_outw(ctrl_inw(PA_IVDRCTL) | 0x0100, PA_IVDRCTL); /* Si13112 */ + + pm_power_off = r7780rp_power_off; +} + +/* + * The Machine Vector + */ +struct sh_machine_vector mv_r7780rp __initmv = { + .mv_name = "Highlander R7780RP-1", + .mv_setup = r7780rp_setup, + + .mv_nr_irqs = 109, + + .mv_inb = r7780rp_inb, + .mv_inw = r7780rp_inw, + .mv_inl = r7780rp_inl, + .mv_outb = r7780rp_outb, + .mv_outw = r7780rp_outw, + .mv_outl = r7780rp_outl, + + .mv_inb_p = r7780rp_inb_p, + .mv_inw_p = r7780rp_inw, + .mv_inl_p = r7780rp_inl, + .mv_outb_p = r7780rp_outb_p, + .mv_outw_p = r7780rp_outw, + .mv_outl_p = r7780rp_outl, + + .mv_insb = r7780rp_insb, + .mv_insw = r7780rp_insw, + .mv_insl = r7780rp_insl, + .mv_outsb = r7780rp_outsb, + .mv_outsw = r7780rp_outsw, + .mv_outsl = r7780rp_outsl, + + .mv_ioport_map = r7780rp_ioport_map, + .mv_init_irq = init_r7780rp_IRQ, +#ifdef CONFIG_HEARTBEAT + .mv_heartbeat = heartbeat_r7780rp, +#endif +}; +ALIAS_MV(r7780rp) diff --git a/arch/sh/boards/renesas/rts7751r2d/Kconfig b/arch/sh/boards/renesas/rts7751r2d/Kconfig new file mode 100644 index 00000000000..7780d1fb13f --- /dev/null +++ b/arch/sh/boards/renesas/rts7751r2d/Kconfig @@ -0,0 +1,12 @@ +if SH_RTS7751R2D + +menu "RTS7751R2D options" + +config RTS7751R2D_REV11 + bool "RTS7751R2D Rev. 1.1 board support" + help + Selecting this option will support version rev. 1.1. +endmenu + +endif + diff --git a/arch/sh/boards/renesas/rts7751r2d/Makefile b/arch/sh/boards/renesas/rts7751r2d/Makefile index daa53334bdc..686fc9ea598 100644 --- a/arch/sh/boards/renesas/rts7751r2d/Makefile +++ b/arch/sh/boards/renesas/rts7751r2d/Makefile @@ -1,10 +1,6 @@ # # Makefile for the RTS7751R2D specific parts of the kernel # -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# - -obj-y := mach.o setup.o io.o irq.o led.o +obj-y := setup.o io.o irq.o +obj-$(CONFIG_HEARTBEAT) += led.o diff --git a/arch/sh/boards/renesas/rts7751r2d/io.c b/arch/sh/boards/renesas/rts7751r2d/io.c index 123abbbc91e..135aa0b5e62 100644 --- a/arch/sh/boards/renesas/rts7751r2d/io.c +++ b/arch/sh/boards/renesas/rts7751r2d/io.c @@ -1,6 +1,4 @@ /* - * linux/arch/sh/kernel/io_rts7751r2d.c - * * Copyright (C) 2001 Ian da Silva, Jeremy Siegel * Based largely on io_se.c. * @@ -10,17 +8,13 @@ * placeholder code from io_rts7751r2d.c left in with the * expectation of later SuperIO and PCMCIA access. */ - #include <linux/kernel.h> #include <linux/types.h> -#include <asm/io.h> +#include <linux/pci.h> #include <asm/rts7751r2d/rts7751r2d.h> +#include <asm/io.h> #include <asm/addrspace.h> -#include <linux/module.h> -#include <linux/pci.h> -#include "../../../drivers/pci/pci-sh7751.h" - /* * The 7751R RTS7751R2D uses the built-in PCI controller (PCIC) * of the 7751R processor, and has a SuperIO accessible via the PCI. @@ -28,22 +22,6 @@ * like the other Solution Engine boards. */ -#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR) -#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR) -#define PCI_IO_AREA SH7751_PCI_IO_BASE -#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE - -#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK)) - -#define maybebadio(name,port) \ - printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \ - #name, (port), (__u32) __builtin_return_address(0)) - -static inline void delay(void) -{ - ctrl_inw(0xa0000000); -} - static inline unsigned long port2adr(unsigned int port) { if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) @@ -52,7 +30,7 @@ static inline unsigned long port2adr(unsigned int port) else return (PA_AREA5_IO + 0x1000 + ((port-0x1f0) << 1)); else - maybebadio(port2adr, (unsigned long)port); + maybebadio((unsigned long)port); return port; } @@ -81,17 +59,6 @@ static inline int shifted_port(unsigned long port) return 1; } -/* In case someone configures the kernel w/o PCI support: in that */ -/* scenario, don't ever bother to check for PCI-window addresses */ - -/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */ -#if defined(CONFIG_PCI) -#define CHECK_SH7751_PCIIO(port) \ - ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE))) -#else -#define CHECK_SH7751_PCIIO(port) (0) -#endif - #if defined(CONFIG_NE2000) || defined(CONFIG_NE2000_MODULE) #define CHECK_AX88796L_PORT(port) \ ((port >= AX88796L_IO_BASE) && (port < (AX88796L_IO_BASE+0x20))) @@ -112,8 +79,8 @@ unsigned char rts7751r2d_inb(unsigned long port) return (*(volatile unsigned short *)port88796l(port, 0)) & 0xff; else if (PXSEG(port)) return *(volatile unsigned char *)port; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - return *(volatile unsigned char *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + return *(volatile unsigned char *)pci_ioaddr(port); else return (*(volatile unsigned short *)port2adr(port) & 0xff); } @@ -126,11 +93,12 @@ unsigned char rts7751r2d_inb_p(unsigned long port) v = (*(volatile unsigned short *)port88796l(port, 0)) & 0xff; else if (PXSEG(port)) v = *(volatile unsigned char *)port; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - v = *(volatile unsigned char *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + v = *(volatile unsigned char *)pci_ioaddr(port); else v = (*(volatile unsigned short *)port2adr(port) & 0xff); - delay(); + + ctrl_delay(); return v; } @@ -138,13 +106,13 @@ unsigned char rts7751r2d_inb_p(unsigned long port) unsigned short rts7751r2d_inw(unsigned long port) { if (CHECK_AX88796L_PORT(port)) - maybebadio(inw, port); + maybebadio(port); else if (PXSEG(port)) return *(volatile unsigned short *)port; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - return *(volatile unsigned short *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + return *(volatile unsigned short *)pci_ioaddr(port); else - maybebadio(inw, port); + maybebadio(port); return 0; } @@ -152,13 +120,13 @@ unsigned short rts7751r2d_inw(unsigned long port) unsigned int rts7751r2d_inl(unsigned long port) { if (CHECK_AX88796L_PORT(port)) - maybebadio(inl, port); + maybebadio(port); else if (PXSEG(port)) return *(volatile unsigned long *)port; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - return *(volatile unsigned long *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + return *(volatile unsigned long *)pci_ioaddr(port); else - maybebadio(inl, port); + maybebadio(port); return 0; } @@ -169,8 +137,8 @@ void rts7751r2d_outb(unsigned char value, unsigned long port) *((volatile unsigned short *)port88796l(port, 0)) = value; else if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - *(volatile unsigned char *)PCI_IOMAP(port) = value; + else if (is_pci_ioaddr(port) || shifted_port(port)) + *(volatile unsigned char *)pci_ioaddr(port) = value; else *(volatile unsigned short *)port2adr(port) = value; } @@ -181,143 +149,152 @@ void rts7751r2d_outb_p(unsigned char value, unsigned long port) *((volatile unsigned short *)port88796l(port, 0)) = value; else if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - *(volatile unsigned char *)PCI_IOMAP(port) = value; + else if (is_pci_ioaddr(port) || shifted_port(port)) + *(volatile unsigned char *)pci_ioaddr(port) = value; else *(volatile unsigned short *)port2adr(port) = value; - delay(); + + ctrl_delay(); } void rts7751r2d_outw(unsigned short value, unsigned long port) { if (CHECK_AX88796L_PORT(port)) - maybebadio(outw, port); + maybebadio(port); else if (PXSEG(port)) *(volatile unsigned short *)port = value; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - *(volatile unsigned short *)PCI_IOMAP(port) = value; + else if (is_pci_ioaddr(port) || shifted_port(port)) + *(volatile unsigned short *)pci_ioaddr(port) = value; else - maybebadio(outw, port); + maybebadio(port); } void rts7751r2d_outl(unsigned int value, unsigned long port) { if (CHECK_AX88796L_PORT(port)) - maybebadio(outl, port); + maybebadio(port); else if (PXSEG(port)) *(volatile unsigned long *)port = value; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - *(volatile unsigned long *)PCI_IOMAP(port) = value; + else if (is_pci_ioaddr(port) || shifted_port(port)) + *(volatile unsigned long *)pci_ioaddr(port) = value; else - maybebadio(outl, port); + maybebadio(port); } void rts7751r2d_insb(unsigned long port, void *addr, unsigned long count) { + unsigned long a = (unsigned long)addr; volatile __u8 *bp; volatile __u16 *p; - unsigned char *s = addr; if (CHECK_AX88796L_PORT(port)) { p = (volatile unsigned short *)port88796l(port, 0); - while (count--) *s++ = *p & 0xff; + while (count--) + ctrl_outb(*p & 0xff, a++); } else if (PXSEG(port)) - while (count--) *s++ = *(volatile unsigned char *)port; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { - bp = (__u8 *)PCI_IOMAP(port); - while (count--) *s++ = *bp; + while (count--) + ctrl_outb(ctrl_inb(port), a++); + else if (is_pci_ioaddr(port) || shifted_port(port)) { + bp = (__u8 *)pci_ioaddr(port); + while (count--) + ctrl_outb(*bp, a++); } else { p = (volatile unsigned short *)port2adr(port); - while (count--) *s++ = *p & 0xff; + while (count--) + ctrl_outb(*p & 0xff, a++); } } void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count) { + unsigned long a = (unsigned long)addr; volatile __u16 *p; - __u16 *s = addr; if (CHECK_AX88796L_PORT(port)) p = (volatile unsigned short *)port88796l(port, 1); else if (PXSEG(port)) p = (volatile unsigned short *)port; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - p = (volatile unsigned short *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + p = (volatile unsigned short *)pci_ioaddr(port); else p = (volatile unsigned short *)port2adr(port); - while (count--) *s++ = *p; + while (count--) + ctrl_outw(*p, a++); } void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count) { if (CHECK_AX88796L_PORT(port)) - maybebadio(insl, port); - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { - volatile __u32 *p = (__u32 *)PCI_IOMAP(port); - __u32 *s = addr; - - while (count--) *s++ = *p; + maybebadio(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) { + unsigned long a = (unsigned long)addr; + + while (count--) { + ctrl_outl(ctrl_inl(pci_ioaddr(port)), a); + a += 4; + } } else - maybebadio(insl, port); + maybebadio(port); } void rts7751r2d_outsb(unsigned long port, const void *addr, unsigned long count) { + unsigned long a = (unsigned long)addr; volatile __u8 *bp; volatile __u16 *p; - const __u8 *s = addr; if (CHECK_AX88796L_PORT(port)) { p = (volatile unsigned short *)port88796l(port, 0); - while (count--) *p = *s++; + while (count--) + *p = ctrl_inb(a++); } else if (PXSEG(port)) - while (count--) *(volatile unsigned char *)port = *s++; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { - bp = (__u8 *)PCI_IOMAP(port); - while (count--) *bp = *s++; + while (count--) + ctrl_outb(a++, port); + else if (is_pci_ioaddr(port) || shifted_port(port)) { + bp = (__u8 *)pci_ioaddr(port); + while (count--) + *bp = ctrl_inb(a++); } else { p = (volatile unsigned short *)port2adr(port); - while (count--) *p = *s++; + while (count--) + *p = ctrl_inb(a++); } } void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count) { + unsigned long a = (unsigned long)addr; volatile __u16 *p; - const __u16 *s = addr; if (CHECK_AX88796L_PORT(port)) p = (volatile unsigned short *)port88796l(port, 1); else if (PXSEG(port)) p = (volatile unsigned short *)port; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - p = (volatile unsigned short *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + p = (volatile unsigned short *)pci_ioaddr(port); else p = (volatile unsigned short *)port2adr(port); - while (count--) *p = *s++; + + while (count--) { + ctrl_outw(*p, a); + a += 2; + } } void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count) { if (CHECK_AX88796L_PORT(port)) - maybebadio(outsl, port); - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { - volatile __u32 *p = (__u32 *)PCI_IOMAP(port); - const __u32 *s = addr; - - while (count--) *p = *s++; + maybebadio(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) { + unsigned long a = (unsigned long)addr; + + while (count--) { + ctrl_outl(ctrl_inl(a), pci_ioaddr(port)); + a += 4; + } } else - maybebadio(outsl, port); -} - -void *rts7751r2d_ioremap(unsigned long offset, unsigned long size) -{ - if (offset >= 0xfd000000) - return (void *)offset; - else - return (void *)P2SEGADDR(offset); + maybebadio(port); } -EXPORT_SYMBOL(rts7751r2d_ioremap); unsigned long rts7751r2d_isa_port2addr(unsigned long offset) { diff --git a/arch/sh/boards/renesas/rts7751r2d/irq.c b/arch/sh/boards/renesas/rts7751r2d/irq.c index 154535440bb..c915e7a3693 100644 --- a/arch/sh/boards/renesas/rts7751r2d/irq.c +++ b/arch/sh/boards/renesas/rts7751r2d/irq.c @@ -41,30 +41,24 @@ static unsigned int startup_rts7751r2d_irq(unsigned int irq) static void disable_rts7751r2d_irq(unsigned int irq) { - unsigned long flags; unsigned short val; unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]); /* Set the priority in IPR to 0 */ - local_irq_save(flags); val = ctrl_inw(IRLCNTR1); val &= mask; ctrl_outw(val, IRLCNTR1); - local_irq_restore(flags); } static void enable_rts7751r2d_irq(unsigned int irq) { - unsigned long flags; unsigned short val; unsigned short value = (0x0001 << mask_pos[irq]); /* Set priority in IPR back to original value */ - local_irq_save(flags); val = ctrl_inw(IRLCNTR1); val |= value; ctrl_outw(val, IRLCNTR1); - local_irq_restore(flags); } int rts7751r2d_irq_demux(int irq) diff --git a/arch/sh/boards/renesas/rts7751r2d/led.c b/arch/sh/boards/renesas/rts7751r2d/led.c index 4d16de71fac..e14a13d12d4 100644 --- a/arch/sh/boards/renesas/rts7751r2d/led.c +++ b/arch/sh/boards/renesas/rts7751r2d/led.c @@ -12,8 +12,6 @@ #include <asm/io.h> #include <asm/rts7751r2d/rts7751r2d.h> -extern unsigned int debug_counter; - #ifdef CONFIG_HEARTBEAT #include <linux/sched.h> @@ -55,12 +53,3 @@ void rts7751r2d_led(unsigned short value) ctrl_outw(value, PA_OUTPORT); } -void debug_led_disp(void) -{ - unsigned short value; - - value = (unsigned short)debug_counter++; - rts7751r2d_led(value); - if (value == 0xff) - debug_counter = 0; -} diff --git a/arch/sh/boards/renesas/rts7751r2d/mach.c b/arch/sh/boards/renesas/rts7751r2d/mach.c deleted file mode 100644 index 5ed9e97ea19..00000000000 --- a/arch/sh/boards/renesas/rts7751r2d/mach.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * linux/arch/sh/kernel/mach_rts7751r2d.c - * - * Minor tweak of mach_se.c file to reference rts7751r2d-specific items. - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * Machine vector for the Renesas Technology sales RTS7751R2D - */ - -#include <linux/init.h> -#include <linux/types.h> - -#include <asm/machvec.h> -#include <asm/rtc.h> -#include <asm/irq.h> -#include <asm/rts7751r2d/io.h> - -extern void heartbeat_rts7751r2d(void); -extern void init_rts7751r2d_IRQ(void); -extern void *rts7751r2d_ioremap(unsigned long, unsigned long); -extern int rts7751r2d_irq_demux(int irq); - -extern void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, gfp_t); -extern int voyagergx_consistent_free(struct device *, size_t, void *, dma_addr_t); - -/* - * The Machine Vector - */ - -struct sh_machine_vector mv_rts7751r2d __initmv = { - .mv_nr_irqs = 72, - - .mv_inb = rts7751r2d_inb, - .mv_inw = rts7751r2d_inw, - .mv_inl = rts7751r2d_inl, - .mv_outb = rts7751r2d_outb, - .mv_outw = rts7751r2d_outw, - .mv_outl = rts7751r2d_outl, - - .mv_inb_p = rts7751r2d_inb_p, - .mv_inw_p = rts7751r2d_inw, - .mv_inl_p = rts7751r2d_inl, - .mv_outb_p = rts7751r2d_outb_p, - .mv_outw_p = rts7751r2d_outw, - .mv_outl_p = rts7751r2d_outl, - - .mv_insb = rts7751r2d_insb, - .mv_insw = rts7751r2d_insw, - .mv_insl = rts7751r2d_insl, - .mv_outsb = rts7751r2d_outsb, - .mv_outsw = rts7751r2d_outsw, - .mv_outsl = rts7751r2d_outsl, - - .mv_ioremap = rts7751r2d_ioremap, - .mv_isa_port2addr = rts7751r2d_isa_port2addr, - .mv_init_irq = init_rts7751r2d_IRQ, -#ifdef CONFIG_HEARTBEAT - .mv_heartbeat = heartbeat_rts7751r2d, -#endif - .mv_irq_demux = rts7751r2d_irq_demux, - -#ifdef CONFIG_USB_OHCI_HCD - .mv_consistent_alloc = voyagergx_consistent_alloc, - .mv_consistent_free = voyagergx_consistent_free, -#endif -}; -ALIAS_MV(rts7751r2d) diff --git a/arch/sh/boards/renesas/rts7751r2d/setup.c b/arch/sh/boards/renesas/rts7751r2d/setup.c index 2587fd1a024..20597a6e670 100644 --- a/arch/sh/boards/renesas/rts7751r2d/setup.c +++ b/arch/sh/boards/renesas/rts7751r2d/setup.c @@ -1,31 +1,142 @@ /* - * linux/arch/sh/kernel/setup_rts7751r2d.c - * - * Copyright (C) 2000 Kazumoto Kojima - * * Renesas Technology Sales RTS7751R2D Support. * - * Modified for RTS7751R2D by - * Atom Create Engineering Co., Ltd. 2002. + * Copyright (C) 2002 Atom Create Engineering Co., Ltd. + * Copyright (C) 2004 - 2006 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. */ - #include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/serial_8250.h> +#include <linux/pm.h> #include <asm/io.h> -#include <asm/rts7751r2d/rts7751r2d.h> +#include <asm/machvec.h> +#include <asm/mach/rts7751r2d.h> +#include <asm/voyagergx.h> + +extern void heartbeat_rts7751r2d(void); +extern void init_rts7751r2d_IRQ(void); +extern int rts7751r2d_irq_demux(int irq); + +extern void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, gfp_t); +extern int voyagergx_consistent_free(struct device *, size_t, void *, dma_addr_t); + +static struct plat_serial8250_port uart_platform_data[] = { + { + .membase = (void *)VOYAGER_UART_BASE, + .mapbase = VOYAGER_UART_BASE, + .iotype = UPIO_MEM, + .irq = VOYAGER_UART0_IRQ, + .flags = UPF_BOOT_AUTOCONF, + .regshift = 2, + .uartclk = (9600 * 16), + }, { + .flags = 0, + }, +}; + +static void __init voyagergx_serial_init(void) +{ + unsigned long val; + + /* + * GPIO Control + */ + val = inl(GPIO_MUX_HIGH); + val |= 0x00001fe0; + outl(val, GPIO_MUX_HIGH); + + /* + * Power Mode Gate + */ + val = inl(POWER_MODE0_GATE); + val |= (POWER_MODE0_GATE_U0 | POWER_MODE0_GATE_U1); + outl(val, POWER_MODE0_GATE); + + val = inl(POWER_MODE1_GATE); + val |= (POWER_MODE1_GATE_U0 | POWER_MODE1_GATE_U1); + outl(val, POWER_MODE1_GATE); +} + +static struct platform_device uart_device = { + .name = "serial8250", + .id = -1, + .dev = { + .platform_data = uart_platform_data, + }, +}; + +static struct platform_device *rts7751r2d_devices[] __initdata = { + &uart_device, +}; -unsigned int debug_counter; +static int __init rts7751r2d_devices_setup(void) +{ + return platform_add_devices(rts7751r2d_devices, + ARRAY_SIZE(rts7751r2d_devices)); +} -const char *get_system_type(void) +static void rts7751r2d_power_off(void) { - return "RTS7751R2D"; + ctrl_outw(0x0001, PA_POWOFF); } /* * Initialize the board */ -void __init platform_setup(void) +static void __init rts7751r2d_setup(char **cmdline_p) { - printk(KERN_INFO "Renesas Technology Sales RTS7751R2D support.\n"); + device_initcall(rts7751r2d_devices_setup); + ctrl_outw(0x0000, PA_OUTPORT); - debug_counter = 0; + pm_power_off = rts7751r2d_power_off; + + voyagergx_serial_init(); + + printk(KERN_INFO "Renesas Technology Sales RTS7751R2D support.\n"); } + +/* + * The Machine Vector + */ +struct sh_machine_vector mv_rts7751r2d __initmv = { + .mv_name = "RTS7751R2D", + .mv_setup = rts7751r2d_setup, + .mv_nr_irqs = 72, + + .mv_inb = rts7751r2d_inb, + .mv_inw = rts7751r2d_inw, + .mv_inl = rts7751r2d_inl, + .mv_outb = rts7751r2d_outb, + .mv_outw = rts7751r2d_outw, + .mv_outl = rts7751r2d_outl, + + .mv_inb_p = rts7751r2d_inb_p, + .mv_inw_p = rts7751r2d_inw, + .mv_inl_p = rts7751r2d_inl, + .mv_outb_p = rts7751r2d_outb_p, + .mv_outw_p = rts7751r2d_outw, + .mv_outl_p = rts7751r2d_outl, + + .mv_insb = rts7751r2d_insb, + .mv_insw = rts7751r2d_insw, + .mv_insl = rts7751r2d_insl, + .mv_outsb = rts7751r2d_outsb, + .mv_outsw = rts7751r2d_outsw, + .mv_outsl = rts7751r2d_outsl, + + .mv_init_irq = init_rts7751r2d_IRQ, +#ifdef CONFIG_HEARTBEAT + .mv_heartbeat = heartbeat_rts7751r2d, +#endif + .mv_irq_demux = rts7751r2d_irq_demux, + +#ifdef CONFIG_USB_SM501 + .mv_consistent_alloc = voyagergx_consistent_alloc, + .mv_consistent_free = voyagergx_consistent_free, +#endif +}; +ALIAS_MV(rts7751r2d) diff --git a/arch/sh/boards/renesas/sh7710voipgw/Makefile b/arch/sh/boards/renesas/sh7710voipgw/Makefile new file mode 100644 index 00000000000..77037567633 --- /dev/null +++ b/arch/sh/boards/renesas/sh7710voipgw/Makefile @@ -0,0 +1 @@ +obj-y := setup.o diff --git a/arch/sh/boards/renesas/sh7710voipgw/setup.c b/arch/sh/boards/renesas/sh7710voipgw/setup.c new file mode 100644 index 00000000000..e57e7afab8c --- /dev/null +++ b/arch/sh/boards/renesas/sh7710voipgw/setup.c @@ -0,0 +1,109 @@ +/* + * Renesas Technology SH7710 VoIP Gateway + * + * Copyright (C) 2006 Ranjit Deshpande + * Kenati Technologies Inc. + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + */ +#include <linux/init.h> +#include <asm/machvec.h> +#include <asm/irq.h> +#include <asm/io.h> +#include <asm/irq.h> + +/* + * Initialize IRQ setting + */ +static void __init sh7710voipgw_init_irq(void) +{ + /* Disable all interrupts in IPR registers */ + ctrl_outw(0x0, INTC_IPRA); + ctrl_outw(0x0, INTC_IPRB); + ctrl_outw(0x0, INTC_IPRC); + ctrl_outw(0x0, INTC_IPRD); + ctrl_outw(0x0, INTC_IPRE); + ctrl_outw(0x0, INTC_IPRF); + ctrl_outw(0x0, INTC_IPRG); + ctrl_outw(0x0, INTC_IPRH); + ctrl_outw(0x0, INTC_IPRI); + + /* Ack all interrupt sources in the IRR0 register */ + ctrl_outb(0x3f, INTC_IRR0); + + /* Use IRQ0 - IRQ3 as active low interrupt lines i.e. disable + * IRL mode. + */ + ctrl_outw(0x2aa, INTC_ICR1); + + /* Now make IPR interrupts */ + make_ipr_irq(TIMER2_IRQ, TIMER2_IPR_ADDR, + TIMER2_IPR_POS, TIMER2_PRIORITY); + make_ipr_irq(WDT_IRQ, WDT_IPR_ADDR, WDT_IPR_POS, WDT_PRIORITY); + + /* SCIF0 */ + make_ipr_irq(SCIF0_ERI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, + SCIF0_PRIORITY); + make_ipr_irq(SCIF0_RXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, + SCIF0_PRIORITY); + make_ipr_irq(SCIF0_BRI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, + SCIF0_PRIORITY); + make_ipr_irq(SCIF0_TXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, + SCIF0_PRIORITY); + + /* DMAC-1 */ + make_ipr_irq(DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); + make_ipr_irq(DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); + make_ipr_irq(DMTE2_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); + make_ipr_irq(DMTE3_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); + + /* DMAC-2 */ + make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY); + make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY); + + /* IPSEC */ + make_ipr_irq(IPSEC_IRQ, IPSEC_IPR_ADDR, IPSEC_IPR_POS, IPSEC_PRIORITY); + + /* EDMAC */ + make_ipr_irq(EDMAC0_IRQ, EDMAC0_IPR_ADDR, EDMAC0_IPR_POS, + EDMAC0_PRIORITY); + make_ipr_irq(EDMAC1_IRQ, EDMAC1_IPR_ADDR, EDMAC1_IPR_POS, + EDMAC1_PRIORITY); + make_ipr_irq(EDMAC2_IRQ, EDMAC2_IPR_ADDR, EDMAC2_IPR_POS, + EDMAC2_PRIORITY); + + /* SIOF0 */ + make_ipr_irq(SIOF0_ERI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, + SIOF0_PRIORITY); + make_ipr_irq(SIOF0_TXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, + SIOF0_PRIORITY); + make_ipr_irq(SIOF0_RXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, + SIOF0_PRIORITY); + make_ipr_irq(SIOF0_CCI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, + SIOF0_PRIORITY); + + /* SIOF1 */ + make_ipr_irq(SIOF1_ERI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, + SIOF1_PRIORITY); + make_ipr_irq(SIOF1_TXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, + SIOF1_PRIORITY); + make_ipr_irq(SIOF1_RXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, + SIOF1_PRIORITY); + make_ipr_irq(SIOF1_CCI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, + SIOF1_PRIORITY); + + /* SLIC IRQ's */ + make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY); + make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY); +} + +/* + * The Machine Vector + */ +struct sh_machine_vector mv_sh7710voipgw __initmv = { + .mv_name = "SH7710 VoIP Gateway", + .mv_nr_irqs = 104, + .mv_init_irq = sh7710voipgw_init_irq, +}; +ALIAS_MV(sh7710voipgw) diff --git a/arch/sh/boards/renesas/systemh/io.c b/arch/sh/boards/renesas/systemh/io.c index cf979011aa9..cde6e5d192c 100644 --- a/arch/sh/boards/renesas/systemh/io.c +++ b/arch/sh/boards/renesas/systemh/io.c @@ -5,66 +5,25 @@ * Based largely on io_se.c. * * I/O routine for Hitachi 7751 Systemh. - * */ - #include <linux/kernel.h> #include <linux/types.h> -#include <asm/systemh/7751systemh.h> +#include <linux/pci.h> +#include <asm/systemh7751.h> #include <asm/addrspace.h> #include <asm/io.h> -#include <linux/pci.h> -#include "../../drivers/pci/pci-sh7751.h" - -/* - * The 7751 SystemH Engine uses the built-in PCI controller (PCIC) - * of the 7751 processor, and has a SuperIO accessible on its memory - * bus. - */ - -#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR) -#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR) -#define PCI_IO_AREA SH7751_PCI_IO_BASE -#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE - -#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK)) #define ETHER_IOMAP(adr) (0xB3000000 + (adr)) /*map to 16bits access area of smc lan chip*/ - -#define maybebadio(name,port) \ - printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \ - #name, (port), (__u32) __builtin_return_address(0)) - -static inline void delay(void) -{ - ctrl_inw(0xa0000000); -} - static inline volatile __u16 * port2adr(unsigned int port) { if (port >= 0x2000) return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); -#if 0 - else - return (volatile __u16 *) (PA_SUPERIO + (port << 1)); -#endif - maybebadio(name,(unsigned long)port); + maybebadio((unsigned long)port); return (volatile __u16*)port; } -/* In case someone configures the kernel w/o PCI support: in that */ -/* scenario, don't ever bother to check for PCI-window addresses */ - -/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */ -#if defined(CONFIG_PCI) -#define CHECK_SH7751_PCIIO(port) \ - ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE))) -#else -#define CHECK_SH7751_PCIIO(port) (0) -#endif - /* * General outline: remap really low stuff [eventually] to SuperIO, * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) @@ -76,8 +35,8 @@ unsigned char sh7751systemh_inb(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned char *)port; - else if (CHECK_SH7751_PCIIO(port)) - return *(volatile unsigned char *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + return *(volatile unsigned char *)pci_ioaddr(port); else if (port <= 0x3F1) return *(volatile unsigned char *)ETHER_IOMAP(port); else @@ -90,13 +49,13 @@ unsigned char sh7751systemh_inb_p(unsigned long port) if (PXSEG(port)) v = *(volatile unsigned char *)port; - else if (CHECK_SH7751_PCIIO(port)) - v = *(volatile unsigned char *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + v = *(volatile unsigned char *)pci_ioaddr(port); else if (port <= 0x3F1) v = *(volatile unsigned char *)ETHER_IOMAP(port); else v = (*port2adr(port))&0xff; - delay(); + ctrl_delay(); return v; } @@ -104,14 +63,14 @@ unsigned short sh7751systemh_inw(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned short *)port; - else if (CHECK_SH7751_PCIIO(port)) - return *(volatile unsigned short *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + return *(volatile unsigned short *)pci_ioaddr(port); else if (port >= 0x2000) return *port2adr(port); else if (port <= 0x3F1) return *(volatile unsigned int *)ETHER_IOMAP(port); else - maybebadio(inw, port); + maybebadio(port); return 0; } @@ -119,14 +78,14 @@ unsigned int sh7751systemh_inl(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned long *)port; - else if (CHECK_SH7751_PCIIO(port)) - return *(volatile unsigned int *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + return *(volatile unsigned int *)pci_ioaddr(port); else if (port >= 0x2000) return *port2adr(port); else if (port <= 0x3F1) return *(volatile unsigned int *)ETHER_IOMAP(port); else - maybebadio(inl, port); + maybebadio(port); return 0; } @@ -135,8 +94,8 @@ void sh7751systemh_outb(unsigned char value, unsigned long port) if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned char*)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned char*)pci_ioaddr(port)) = value; else if (port <= 0x3F1) *(volatile unsigned char *)ETHER_IOMAP(port) = value; else @@ -147,37 +106,37 @@ void sh7751systemh_outb_p(unsigned char value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned char*)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned char*)pci_ioaddr(port)) = value; else if (port <= 0x3F1) *(volatile unsigned char *)ETHER_IOMAP(port) = value; else *(port2adr(port)) = value; - delay(); + ctrl_delay(); } void sh7751systemh_outw(unsigned short value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned short *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned short *)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned short *)pci_ioaddr(port)) = value; else if (port >= 0x2000) *port2adr(port) = value; else if (port <= 0x3F1) *(volatile unsigned short *)ETHER_IOMAP(port) = value; else - maybebadio(outw, port); + maybebadio(port); } void sh7751systemh_outl(unsigned int value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned long *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned long*)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned long*)pci_ioaddr(port)) = value; else - maybebadio(outl, port); + maybebadio(port); } void sh7751systemh_insb(unsigned long port, void *addr, unsigned long count) @@ -194,7 +153,7 @@ void sh7751systemh_insw(unsigned long port, void *addr, unsigned long count) void sh7751systemh_insl(unsigned long port, void *addr, unsigned long count) { - maybebadio(insl, port); + maybebadio(port); } void sh7751systemh_outsb(unsigned long port, const void *addr, unsigned long count) @@ -211,73 +170,5 @@ void sh7751systemh_outsw(unsigned long port, const void *addr, unsigned long cou void sh7751systemh_outsl(unsigned long port, const void *addr, unsigned long count) { - maybebadio(outsw, port); -} - -/* For read/write calls, just copy generic (pass-thru); PCIMBR is */ -/* already set up. For a larger memory space, these would need to */ -/* reset PCIMBR as needed on a per-call basis... */ - -unsigned char sh7751systemh_readb(unsigned long addr) -{ - return *(volatile unsigned char*)addr; -} - -unsigned short sh7751systemh_readw(unsigned long addr) -{ - return *(volatile unsigned short*)addr; -} - -unsigned int sh7751systemh_readl(unsigned long addr) -{ - return *(volatile unsigned long*)addr; -} - -void sh7751systemh_writeb(unsigned char b, unsigned long addr) -{ - *(volatile unsigned char*)addr = b; -} - -void sh7751systemh_writew(unsigned short b, unsigned long addr) -{ - *(volatile unsigned short*)addr = b; -} - -void sh7751systemh_writel(unsigned int b, unsigned long addr) -{ - *(volatile unsigned long*)addr = b; -} - - - -/* Map ISA bus address to the real address. Only for PCMCIA. */ - -/* ISA page descriptor. */ -static __u32 sh_isa_memmap[256]; - -#if 0 -static int -sh_isa_mmap(__u32 start, __u32 length, __u32 offset) -{ - int idx; - - if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000)) - return -1; - - idx = start >> 12; - sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff); - printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n", - start, length, offset, idx, sh_isa_memmap[idx]); - return 0; -} -#endif - -unsigned long -sh7751systemh_isa_port2addr(unsigned long offset) -{ - int idx; - - idx = (offset >> 12) & 0xff; - offset &= 0xfff; - return sh_isa_memmap[idx] + offset; + maybebadio(port); } diff --git a/arch/sh/boards/renesas/systemh/irq.c b/arch/sh/boards/renesas/systemh/irq.c index 8372d967f60..8d016dae233 100644 --- a/arch/sh/boards/renesas/systemh/irq.c +++ b/arch/sh/boards/renesas/systemh/irq.c @@ -15,7 +15,7 @@ #include <linux/hdreg.h> #include <linux/ide.h> #include <asm/io.h> -#include <asm/mach/7751systemh.h> +#include <asm/systemh7751.h> #include <asm/smc37c93x.h> /* address of external interrupt mask register @@ -57,12 +57,9 @@ static void shutdown_systemh_irq(unsigned int irq) static void disable_systemh_irq(unsigned int irq) { if (systemh_irq_mask_register) { - unsigned long flags; unsigned long val, mask = 0x01 << 1; /* Clear the "irq"th bit in the mask and set it in the request */ - local_irq_save(flags); - val = ctrl_inl((unsigned long)systemh_irq_mask_register); val &= ~mask; ctrl_outl(val, (unsigned long)systemh_irq_mask_register); @@ -70,23 +67,18 @@ static void disable_systemh_irq(unsigned int irq) val = ctrl_inl((unsigned long)systemh_irq_request_register); val |= mask; ctrl_outl(val, (unsigned long)systemh_irq_request_register); - - local_irq_restore(flags); } } static void enable_systemh_irq(unsigned int irq) { if (systemh_irq_mask_register) { - unsigned long flags; unsigned long val, mask = 0x01 << 1; /* Set "irq"th bit in the mask register */ - local_irq_save(flags); val = ctrl_inl((unsigned long)systemh_irq_mask_register); val |= mask; ctrl_outl(val, (unsigned long)systemh_irq_mask_register); - local_irq_restore(flags); } } diff --git a/arch/sh/boards/renesas/systemh/setup.c b/arch/sh/boards/renesas/systemh/setup.c index 826fa3d7669..a8467bf90c2 100644 --- a/arch/sh/boards/renesas/systemh/setup.c +++ b/arch/sh/boards/renesas/systemh/setup.c @@ -15,28 +15,21 @@ * for more details. */ #include <linux/init.h> -#include <asm/mach/7751systemh.h> -#include <asm/mach/io.h> #include <asm/machvec.h> +#include <asm/systemh7751.h> extern void make_systemh_irq(unsigned int irq); -const char *get_system_type(void) -{ - return "7751 SystemH"; -} - /* * Initialize IRQ setting */ -void __init init_7751systemh_IRQ(void) +static void __init sh7751systemh_init_irq(void) { -/* make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); LAN */ -/* make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-4); */ make_systemh_irq(0xb); /* Ethernet interrupt */ } struct sh_machine_vector mv_7751systemh __initmv = { + .mv_name = "7751 SystemH", .mv_nr_irqs = 72, .mv_inb = sh7751systemh_inb, @@ -60,21 +53,6 @@ struct sh_machine_vector mv_7751systemh __initmv = { .mv_outsw = sh7751systemh_outsw, .mv_outsl = sh7751systemh_outsl, - .mv_readb = sh7751systemh_readb, - .mv_readw = sh7751systemh_readw, - .mv_readl = sh7751systemh_readl, - .mv_writeb = sh7751systemh_writeb, - .mv_writew = sh7751systemh_writew, - .mv_writel = sh7751systemh_writel, - - .mv_isa_port2addr = sh7751systemh_isa_port2addr, - - .mv_init_irq = init_7751systemh_IRQ, + .mv_init_irq = sh7751system_init_irq, }; ALIAS_MV(7751systemh) - -int __init platform_setup(void) -{ - return 0; -} - diff --git a/arch/sh/boards/saturn/setup.c b/arch/sh/boards/saturn/setup.c index bea6c572ad8..a3a37c9aad2 100644 --- a/arch/sh/boards/saturn/setup.c +++ b/arch/sh/boards/saturn/setup.c @@ -9,22 +9,17 @@ */ #include <linux/kernel.h> #include <linux/init.h> - #include <asm/io.h> #include <asm/machvec.h> #include <asm/mach/io.h> extern int saturn_irq_demux(int irq_nr); -const char *get_system_type(void) -{ - return "Sega Saturn"; -} - /* * The Machine Vector */ struct sh_machine_vector mv_saturn __initmv = { + .mv_name = "Sega Saturn", .mv_nr_irqs = 80, /* Fix this later */ .mv_isa_port2addr = saturn_isa_port2addr, @@ -33,11 +28,4 @@ struct sh_machine_vector mv_saturn __initmv = { .mv_ioremap = saturn_ioremap, .mv_iounmap = saturn_iounmap, }; - ALIAS_MV(saturn) - -int __init platform_setup(void) -{ - return 0; -} - diff --git a/arch/sh/boards/se/7300/io.c b/arch/sh/boards/se/7300/io.c index f449a94ddff..8a03d7a52a7 100644 --- a/arch/sh/boards/se/7300/io.c +++ b/arch/sh/boards/se/7300/io.c @@ -9,8 +9,8 @@ */ #include <linux/kernel.h> -#include <asm/mach/se7300.h> #include <asm/io.h> +#include <asm/se7300.h> #define badio(fn, a) panic("bad i/o operation %s for %08lx.", #fn, a) @@ -99,6 +99,7 @@ bad_outb(struct iop *p, unsigned char value, unsigned long port) badio(inw, port); } +#ifdef CONFIG_SMC91X /* MSTLANEX01 LAN at 0xb400:0000 */ static struct iop laniop = { .start = 0x300, @@ -110,6 +111,7 @@ static struct iop laniop = { .outb = simple_outb, .outw = simple_outw, }; +#endif /* NE2000 pc card NIC */ static struct iop neiop = { @@ -123,6 +125,7 @@ static struct iop neiop = { .outw = simple_outw, }; +#ifdef CONFIG_IDE /* CF in CF slot */ static struct iop cfiop = { .base = 0xb0600000, @@ -132,12 +135,13 @@ static struct iop cfiop = { .outb = pcc_outb, .outw = simple_outw, }; +#endif static __inline__ struct iop * port2iop(unsigned long port) { if (0) ; -#if defined(CONFIG_SMC91111) +#if defined(CONFIG_SMC91X) else if (laniop.check(&laniop, port)) return &laniop; #endif diff --git a/arch/sh/boards/se/7300/irq.c b/arch/sh/boards/se/7300/irq.c index 216a78d1a10..ad1034f98a2 100644 --- a/arch/sh/boards/se/7300/irq.c +++ b/arch/sh/boards/se/7300/irq.c @@ -11,7 +11,7 @@ #include <linux/irq.h> #include <asm/irq.h> #include <asm/io.h> -#include <asm/mach/se7300.h> +#include <asm/se7300.h> /* * Initialize IRQ setting diff --git a/arch/sh/boards/se/7300/led.c b/arch/sh/boards/se/7300/led.c index ad51f0a9c1e..4d03bb7774b 100644 --- a/arch/sh/boards/se/7300/led.c +++ b/arch/sh/boards/se/7300/led.c @@ -12,24 +12,10 @@ */ #include <linux/sched.h> -#include <asm/mach/se7300.h> - -static void -mach_led(int position, int value) -{ - volatile unsigned short *p = (volatile unsigned short *) PA_LED; - - if (value) { - *p |= (1 << 8); - } else { - *p &= ~(1 << 8); - } -} - +#include <asm/se7300.h> /* Cycle the LED's in the clasic Knightrider/Sun pattern */ -void -heartbeat_7300se(void) +void heartbeat_7300se(void) { static unsigned int cnt = 0, period = 0; volatile unsigned short *p = (volatile unsigned short *) PA_LED; diff --git a/arch/sh/boards/se/7300/setup.c b/arch/sh/boards/se/7300/setup.c index ebcd98d4c08..6f082a722d4 100644 --- a/arch/sh/boards/se/7300/setup.c +++ b/arch/sh/boards/se/7300/setup.c @@ -9,23 +9,16 @@ #include <linux/init.h> #include <asm/machvec.h> -#include <asm/machvec_init.h> -#include <asm/mach/io.h> +#include <asm/se7300.h> void heartbeat_7300se(void); void init_7300se_IRQ(void); -const char * -get_system_type(void) -{ - return "SolutionEngine 7300"; -} - /* * The Machine Vector */ - struct sh_machine_vector mv_7300se __initmv = { + .mv_name = "SolutionEngine 7300", .mv_nr_irqs = 109, .mv_inb = sh7300se_inb, .mv_inw = sh7300se_inw, @@ -53,13 +46,4 @@ struct sh_machine_vector mv_7300se __initmv = { .mv_heartbeat = heartbeat_7300se, #endif }; - ALIAS_MV(7300se) -/* - * Initialize the board - */ -void __init -platform_setup(void) -{ - -} diff --git a/arch/sh/boards/se/73180/io.c b/arch/sh/boards/se/73180/io.c index 755df5ac4a4..72715575458 100644 --- a/arch/sh/boards/se/73180/io.c +++ b/arch/sh/boards/se/73180/io.c @@ -99,6 +99,7 @@ bad_outb(struct iop *p, unsigned char value, unsigned long port) badio(inw, port); } +#ifdef CONFIG_SMC91X /* MSTLANEX01 LAN at 0xb400:0000 */ static struct iop laniop = { .start = 0x300, @@ -110,6 +111,7 @@ static struct iop laniop = { .outb = simple_outb, .outw = simple_outw, }; +#endif /* NE2000 pc card NIC */ static struct iop neiop = { @@ -123,6 +125,7 @@ static struct iop neiop = { .outw = simple_outw, }; +#ifdef CONFIG_IDE /* CF in CF slot */ static struct iop cfiop = { .base = 0xb0600000, @@ -132,12 +135,13 @@ static struct iop cfiop = { .outb = pcc_outb, .outw = simple_outw, }; +#endif static __inline__ struct iop * port2iop(unsigned long port) { if (0) ; -#if defined(CONFIG_SMC91111) +#if defined(CONFIG_SMC91X) else if (laniop.check(&laniop, port)) return &laniop; #endif diff --git a/arch/sh/boards/se/73180/irq.c b/arch/sh/boards/se/73180/irq.c index 4344d0ef24a..2c62b8ea350 100644 --- a/arch/sh/boards/se/73180/irq.c +++ b/arch/sh/boards/se/73180/irq.c @@ -7,7 +7,6 @@ * Modified for SH-Mobile SolutionEngine 73180 Support * by YOSHII Takashi <yoshii-takashi@hitachi-ul.co.jp> * - * */ #include <linux/init.h> @@ -17,14 +16,6 @@ #include <asm/mach/se73180.h> static int -intreq2irq(int i) -{ - if (i == 5) - return 10; - return 32 + 7 - i; -} - -static int irq2intreq(int irq) { if (irq == 10) diff --git a/arch/sh/boards/se/73180/led.c b/arch/sh/boards/se/73180/led.c index 610439fde6e..4b72e9a3ead 100644 --- a/arch/sh/boards/se/73180/led.c +++ b/arch/sh/boards/se/73180/led.c @@ -14,21 +14,8 @@ #include <linux/sched.h> #include <asm/mach/se73180.h> -static void -mach_led(int position, int value) -{ - volatile unsigned short *p = (volatile unsigned short *) PA_LED; - - if (value) { - *p |= (1 << LED_SHIFT); - } else { - *p &= ~(1 << LED_SHIFT); - } -} - /* Cycle the LED's in the clasic Knightrider/Sun pattern */ -void -heartbeat_73180se(void) +void heartbeat_73180se(void) { static unsigned int cnt = 0, period = 0; volatile unsigned short *p = (volatile unsigned short *) PA_LED; diff --git a/arch/sh/boards/se/73180/setup.c b/arch/sh/boards/se/73180/setup.c index cdb7b5f8d94..b38ef50a160 100644 --- a/arch/sh/boards/se/73180/setup.c +++ b/arch/sh/boards/se/73180/setup.c @@ -11,23 +11,17 @@ #include <linux/init.h> #include <asm/machvec.h> -#include <asm/machvec_init.h> -#include <asm/mach/io.h> +#include <asm/se73180.h> +#include <asm/irq.h> void heartbeat_73180se(void); void init_73180se_IRQ(void); -const char * -get_system_type(void) -{ - return "SolutionEngine 73180"; -} - /* * The Machine Vector */ - struct sh_machine_vector mv_73180se __initmv = { + .mv_name = "SolutionEngine 73180", .mv_nr_irqs = 108, .mv_inb = sh73180se_inb, .mv_inw = sh73180se_inw, @@ -51,17 +45,9 @@ struct sh_machine_vector mv_73180se __initmv = { .mv_outsl = sh73180se_outsl, .mv_init_irq = init_73180se_IRQ, + .mv_irq_demux = shmse_irq_demux, #ifdef CONFIG_HEARTBEAT .mv_heartbeat = heartbeat_73180se, #endif }; - ALIAS_MV(73180se) -/* - * Initialize the board - */ -void __init -platform_setup(void) -{ - -} diff --git a/arch/sh/boards/se/7343/Makefile b/arch/sh/boards/se/7343/Makefile new file mode 100644 index 00000000000..4291069c0b4 --- /dev/null +++ b/arch/sh/boards/se/7343/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for the 7343 SolutionEngine specific parts of the kernel +# + +obj-y := setup.o io.o irq.o + +obj-$(CONFIG_HEARTBEAT) += led.o diff --git a/arch/sh/boards/se/7343/io.c b/arch/sh/boards/se/7343/io.c new file mode 100644 index 00000000000..646661a146a --- /dev/null +++ b/arch/sh/boards/se/7343/io.c @@ -0,0 +1,275 @@ +/* + * arch/sh/boards/se/7343/io.c + * + * I/O routine for SH-Mobile3AS 7343 SolutionEngine. + * + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <asm/io.h> +#include <asm/mach/se7343.h> + +#define badio(fn, a) panic("bad i/o operation %s for %08lx.", #fn, a) + +struct iop { + unsigned long start, end; + unsigned long base; + struct iop *(*check) (struct iop * p, unsigned long port); + unsigned char (*inb) (struct iop * p, unsigned long port); + unsigned short (*inw) (struct iop * p, unsigned long port); + void (*outb) (struct iop * p, unsigned char value, unsigned long port); + void (*outw) (struct iop * p, unsigned short value, unsigned long port); +}; + +struct iop * +simple_check(struct iop *p, unsigned long port) +{ + static int count; + + if (count < 100) + count++; + + port &= 0xFFFF; + + if ((p->start <= port) && (port <= p->end)) + return p; + else + badio(check, port); +} + +struct iop * +ide_check(struct iop *p, unsigned long port) +{ + if (((0x1f0 <= port) && (port <= 0x1f7)) || (port == 0x3f7)) + return p; + return NULL; +} + +unsigned char +simple_inb(struct iop *p, unsigned long port) +{ + return *(unsigned char *) (p->base + port); +} + +unsigned short +simple_inw(struct iop *p, unsigned long port) +{ + return *(unsigned short *) (p->base + port); +} + +void +simple_outb(struct iop *p, unsigned char value, unsigned long port) +{ + *(unsigned char *) (p->base + port) = value; +} + +void +simple_outw(struct iop *p, unsigned short value, unsigned long port) +{ + *(unsigned short *) (p->base + port) = value; +} + +unsigned char +pcc_inb(struct iop *p, unsigned long port) +{ + unsigned long addr = p->base + port + 0x40000; + unsigned long v; + + if (port & 1) + addr += 0x00400000; + v = *(volatile unsigned char *) addr; + return v; +} + +void +pcc_outb(struct iop *p, unsigned char value, unsigned long port) +{ + unsigned long addr = p->base + port + 0x40000; + + if (port & 1) + addr += 0x00400000; + *(volatile unsigned char *) addr = value; +} + +unsigned char +bad_inb(struct iop *p, unsigned long port) +{ + badio(inb, port); +} + +void +bad_outb(struct iop *p, unsigned char value, unsigned long port) +{ + badio(inw, port); +} + +#ifdef CONFIG_SMC91X +/* MSTLANEX01 LAN at 0xb400:0000 */ +static struct iop laniop = { + .start = 0x00, + .end = 0x0F, + .base = 0x04000000, + .check = simple_check, + .inb = simple_inb, + .inw = simple_inw, + .outb = simple_outb, + .outw = simple_outw, +}; +#endif + +#ifdef CONFIG_NE2000 +/* NE2000 pc card NIC */ +static struct iop neiop = { + .start = 0x280, + .end = 0x29f, + .base = 0xb0600000 + 0x80, /* soft 0x280 -> hard 0x300 */ + .check = simple_check, + .inb = pcc_inb, + .inw = simple_inw, + .outb = pcc_outb, + .outw = simple_outw, +}; +#endif + +#ifdef CONFIG_IDE +/* CF in CF slot */ +static struct iop cfiop = { + .base = 0xb0600000, + .check = ide_check, + .inb = pcc_inb, + .inw = simple_inw, + .outb = pcc_outb, + .outw = simple_outw, +}; +#endif + +static __inline__ struct iop * +port2iop(unsigned long port) +{ + if (0) ; +#if defined(CONFIG_SMC91X) + else if (laniop.check(&laniop, port)) + return &laniop; +#endif +#if defined(CONFIG_NE2000) + else if (neiop.check(&neiop, port)) + return &neiop; +#endif +#if defined(CONFIG_IDE) + else if (cfiop.check(&cfiop, port)) + return &cfiop; +#endif + else + return NULL; +} + +static inline void +delay(void) +{ + ctrl_inw(0xac000000); + ctrl_inw(0xac000000); +} + +unsigned char +sh7343se_inb(unsigned long port) +{ + struct iop *p = port2iop(port); + return (p->inb) (p, port); +} + +unsigned char +sh7343se_inb_p(unsigned long port) +{ + unsigned char v = sh7343se_inb(port); + delay(); + return v; +} + +unsigned short +sh7343se_inw(unsigned long port) +{ + struct iop *p = port2iop(port); + return (p->inw) (p, port); +} + +unsigned int +sh7343se_inl(unsigned long port) +{ + badio(inl, port); +} + +void +sh7343se_outb(unsigned char value, unsigned long port) +{ + struct iop *p = port2iop(port); + (p->outb) (p, value, port); +} + +void +sh7343se_outb_p(unsigned char value, unsigned long port) +{ + sh7343se_outb(value, port); + delay(); +} + +void +sh7343se_outw(unsigned short value, unsigned long port) +{ + struct iop *p = port2iop(port); + (p->outw) (p, value, port); +} + +void +sh7343se_outl(unsigned int value, unsigned long port) +{ + badio(outl, port); +} + +void +sh7343se_insb(unsigned long port, void *addr, unsigned long count) +{ + unsigned char *a = addr; + struct iop *p = port2iop(port); + while (count--) + *a++ = (p->inb) (p, port); +} + +void +sh7343se_insw(unsigned long port, void *addr, unsigned long count) +{ + unsigned short *a = addr; + struct iop *p = port2iop(port); + while (count--) + *a++ = (p->inw) (p, port); +} + +void +sh7343se_insl(unsigned long port, void *addr, unsigned long count) +{ + badio(insl, port); +} + +void +sh7343se_outsb(unsigned long port, const void *addr, unsigned long count) +{ + unsigned char *a = (unsigned char *) addr; + struct iop *p = port2iop(port); + while (count--) + (p->outb) (p, *a++, port); +} + +void +sh7343se_outsw(unsigned long port, const void *addr, unsigned long count) +{ + unsigned short *a = (unsigned short *) addr; + struct iop *p = port2iop(port); + while (count--) + (p->outw) (p, *a++, port); +} + +void +sh7343se_outsl(unsigned long port, const void *addr, unsigned long count) +{ + badio(outsw, port); +} diff --git a/arch/sh/boards/se/7343/irq.c b/arch/sh/boards/se/7343/irq.c new file mode 100644 index 00000000000..b41e3d4ea37 --- /dev/null +++ b/arch/sh/boards/se/7343/irq.c @@ -0,0 +1,193 @@ +/* + * arch/sh/boards/se/7343/irq.c + * + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <asm/irq.h> +#include <asm/io.h> +#include <asm/mach/se7343.h> + +static void +disable_intreq_irq(unsigned int irq) +{ + int bit = irq - OFFCHIP_IRQ_BASE; + u16 val; + + val = ctrl_inw(PA_CPLD_IMSK); + val |= 1 << bit; + ctrl_outw(val, PA_CPLD_IMSK); +} + +static void +enable_intreq_irq(unsigned int irq) +{ + int bit = irq - OFFCHIP_IRQ_BASE; + u16 val; + + val = ctrl_inw(PA_CPLD_IMSK); + val &= ~(1 << bit); + ctrl_outw(val, PA_CPLD_IMSK); +} + +static void +mask_and_ack_intreq_irq(unsigned int irq) +{ + disable_intreq_irq(irq); +} + +static unsigned int +startup_intreq_irq(unsigned int irq) +{ + enable_intreq_irq(irq); + return 0; +} + +static void +shutdown_intreq_irq(unsigned int irq) +{ + disable_intreq_irq(irq); +} + +static void +end_intreq_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + enable_intreq_irq(irq); +} + +static struct hw_interrupt_type intreq_irq_type = { + .typename = "FPGA-IRQ", + .startup = startup_intreq_irq, + .shutdown = shutdown_intreq_irq, + .enable = enable_intreq_irq, + .disable = disable_intreq_irq, + .ack = mask_and_ack_intreq_irq, + .end = end_intreq_irq +}; + +static void +make_intreq_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + irq_desc[irq].handler = &intreq_irq_type; + disable_intreq_irq(irq); +} + +int +shmse_irq_demux(int irq) +{ + int bit; + volatile u16 val; + + if (irq == IRQ5_IRQ) { + /* Read status Register */ + val = ctrl_inw(PA_CPLD_ST); + bit = ffs(val); + if (bit != 0) + return OFFCHIP_IRQ_BASE + bit - 1; + } + return irq; +} + +/* IRQ5 is multiplexed between the following sources: + * 1. PC Card socket + * 2. Extension slot + * 3. USB Controller + * 4. Serial Controller + * + * We configure IRQ5 as a cascade IRQ. + */ +static struct irqaction irq5 = { no_action, 0, CPU_MASK_NONE, "IRQ5-cascade", + NULL, NULL}; + +/* + * Initialize IRQ setting + */ +void __init +init_7343se_IRQ(void) +{ + /* Setup Multiplexed interrupts */ + ctrl_outw(8, PA_CPLD_MODESET); /* Set all CPLD interrupts to active + * low. + */ + /* Mask all CPLD controller interrupts */ + ctrl_outw(0x0fff, PA_CPLD_IMSK); + + /* PC Card interrupts */ + make_intreq_irq(PC_IRQ0); + make_intreq_irq(PC_IRQ1); + make_intreq_irq(PC_IRQ2); + make_intreq_irq(PC_IRQ3); + + /* Extension Slot Interrupts */ + make_intreq_irq(EXT_IRQ0); + make_intreq_irq(EXT_IRQ1); + make_intreq_irq(EXT_IRQ2); + make_intreq_irq(EXT_IRQ3); + + /* USB Controller interrupts */ + make_intreq_irq(USB_IRQ0); + make_intreq_irq(USB_IRQ1); + + /* Serial Controller interrupts */ + make_intreq_irq(UART_IRQ0); + make_intreq_irq(UART_IRQ1); + + /* Setup all external interrupts to be active low */ + ctrl_outw(0xaaaa, INTC_ICR1); + + make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR+2, IRQ5_IPR_POS, IRQ5_PRIORITY); + setup_irq(IRQ5_IRQ, &irq5); + /* Set port control to use IRQ5 */ + *(u16 *)0xA4050108 &= ~0xc; + + make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY); + make_ipr_irq(VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8); + + ctrl_outb(0x0f, INTC_IMCR5); /* enable SCIF IRQ */ + + make_ipr_irq(DMTE0_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); + make_ipr_irq(DMTE1_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); + make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); + make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); + make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY); + make_ipr_irq(DMTE5_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY); + + /* I2C block */ + make_ipr_irq(IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY); + make_ipr_irq(IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, + IIC0_PRIORITY); + make_ipr_irq(IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, + IIC0_PRIORITY); + make_ipr_irq(IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY); + + make_ipr_irq(IIC1_ALI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY); + make_ipr_irq(IIC1_TACKI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, + IIC1_PRIORITY); + make_ipr_irq(IIC1_WAITI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, + IIC1_PRIORITY); + make_ipr_irq(IIC1_DTEI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY); + + /* SIOF */ + make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY); + + /* SIU */ + make_ipr_irq(SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY); + + /* VIO interrupt */ + make_ipr_irq(CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); + make_ipr_irq(BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); + make_ipr_irq(VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); + + /*MFI interrupt*/ + + make_ipr_irq(MFI_IRQ, MFI_IPR_ADDR, MFI_IPR_POS, MFI_PRIORITY); + + /* LCD controller */ + make_ipr_irq(LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY); + ctrl_outw(0x2000, PA_MRSHPC + 0x0c); /* mrshpc irq enable */ +} diff --git a/arch/sh/boards/se/7343/led.c b/arch/sh/boards/se/7343/led.c new file mode 100644 index 00000000000..6a439cf83e4 --- /dev/null +++ b/arch/sh/boards/se/7343/led.c @@ -0,0 +1,46 @@ +/* + * arch/sh/boards/se/7343/led.c + * + */ + +#include <linux/config.h> +#include <linux/sched.h> +#include <asm/mach/se7343.h> + +/* Cycle the LED's in the clasic Knightrider/Sun pattern */ +void heartbeat_7343se(void) +{ + static unsigned int cnt = 0, period = 0; + volatile unsigned short *p = (volatile unsigned short *) PA_LED; + static unsigned bit = 0, up = 1; + + cnt += 1; + if (cnt < period) { + return; + } + + cnt = 0; + + /* Go through the points (roughly!): + * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110 + */ + period = 110 - ((300 << FSHIFT) / ((avenrun[0] / 5) + (3 << FSHIFT))); + + if (up) { + if (bit == 7) { + bit--; + up = 0; + } else { + bit++; + } + } else { + if (bit == 0) { + bit++; + up = 1; + } else { + bit--; + } + } + *p = 1 << (bit + LED_SHIFT); + +} diff --git a/arch/sh/boards/se/7343/setup.c b/arch/sh/boards/se/7343/setup.c new file mode 100644 index 00000000000..787322291fb --- /dev/null +++ b/arch/sh/boards/se/7343/setup.c @@ -0,0 +1,84 @@ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <asm/machvec.h> +#include <asm/mach/se7343.h> +#include <asm/irq.h> + +void heartbeat_7343se(void); +void init_7343se_IRQ(void); + +static struct resource smc91x_resources[] = { + [0] = { + .start = 0x10000000, + .end = 0x1000000F, + .flags = IORESOURCE_MEM, + }, + [1] = { + /* + * shared with other devices via externel + * interrupt controller in FPGA... + */ + .start = EXT_IRQ2, + .end = EXT_IRQ2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; + +static struct platform_device *smc91x_platform_devices[] __initdata = { + &smc91x_device, +}; + +static int __init sh7343se_devices_setup(void) +{ + return platform_add_devices(smc91x_platform_devices, + ARRAY_SIZE(smc91x_platform_devices)); +} + +static void __init sh7343se_setup(char **cmdline_p) +{ + device_initcall(sh7343se_devices_setup); +} + +/* + * The Machine Vector + */ +struct sh_machine_vector mv_7343se __initmv = { + .mv_name = "SolutionEngine 7343", + .mv_setup = sh7343se_setup, + .mv_nr_irqs = 108, + .mv_inb = sh7343se_inb, + .mv_inw = sh7343se_inw, + .mv_inl = sh7343se_inl, + .mv_outb = sh7343se_outb, + .mv_outw = sh7343se_outw, + .mv_outl = sh7343se_outl, + + .mv_inb_p = sh7343se_inb_p, + .mv_inw_p = sh7343se_inw, + .mv_inl_p = sh7343se_inl, + .mv_outb_p = sh7343se_outb_p, + .mv_outw_p = sh7343se_outw, + .mv_outl_p = sh7343se_outl, + + .mv_insb = sh7343se_insb, + .mv_insw = sh7343se_insw, + .mv_insl = sh7343se_insl, + .mv_outsb = sh7343se_outsb, + .mv_outsw = sh7343se_outsw, + .mv_outsl = sh7343se_outsl, + + .mv_init_irq = init_7343se_IRQ, + .mv_irq_demux = shmse_irq_demux, +#ifdef CONFIG_HEARTBEAT + .mv_heartbeat = heartbeat_7343se, +#endif +}; +ALIAS_MV(7343se) diff --git a/arch/sh/boards/se/770x/Makefile b/arch/sh/boards/se/770x/Makefile index be89a73cc41..9a5035f80ec 100644 --- a/arch/sh/boards/se/770x/Makefile +++ b/arch/sh/boards/se/770x/Makefile @@ -2,5 +2,5 @@ # Makefile for the 770x SolutionEngine specific parts of the kernel # -obj-y := mach.o setup.o io.o irq.o led.o - +obj-y := setup.o io.o irq.o +obj-$(CONFIG_HEARTBEAT) += led.o diff --git a/arch/sh/boards/se/770x/io.c b/arch/sh/boards/se/770x/io.c index 9a39ee96314..9941949331a 100644 --- a/arch/sh/boards/se/770x/io.c +++ b/arch/sh/boards/se/770x/io.c @@ -1,4 +1,4 @@ -/* $Id: io.c,v 1.5 2004/02/22 23:08:43 kkojima Exp $ +/* $Id: io.c,v 1.7 2006/02/05 21:55:29 lethal Exp $ * * linux/arch/sh/kernel/io_se.c * @@ -11,7 +11,7 @@ #include <linux/kernel.h> #include <linux/types.h> #include <asm/io.h> -#include <asm/se/se.h> +#include <asm/se.h> /* SH pcmcia io window base, start and end. */ int sh_pcic_io_wbase = 0xb8400000; @@ -20,11 +20,6 @@ int sh_pcic_io_stop; int sh_pcic_io_type; int sh_pcic_io_dummy; -static inline void delay(void) -{ - ctrl_inw(0xa0000000); -} - /* MS7750 requires special versions of in*, out* routines, since PC-like io ports are located at upper half byte of 16-bit word which can be accessed only with 16-bit wide. */ @@ -52,10 +47,6 @@ shifted_port(unsigned long port) return 1; } -#define maybebadio(name,port) \ - printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \ - #name, (port), (__u32) __builtin_return_address(0)) - unsigned char se_inb(unsigned long port) { if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) @@ -76,7 +67,7 @@ unsigned char se_inb_p(unsigned long port) v = (*port2adr(port) >> 8); else v = (*port2adr(port))&0xff; - delay(); + ctrl_delay(); return v; } @@ -86,13 +77,13 @@ unsigned short se_inw(unsigned long port) (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)) return *port2adr(port); else - maybebadio(inw, port); + maybebadio(port); return 0; } unsigned int se_inl(unsigned long port) { - maybebadio(inl, port); + maybebadio(port); return 0; } @@ -114,7 +105,7 @@ void se_outb_p(unsigned char value, unsigned long port) *(port2adr(port)) = value << 8; else *(port2adr(port)) = value; - delay(); + ctrl_delay(); } void se_outw(unsigned short value, unsigned long port) @@ -123,12 +114,12 @@ void se_outw(unsigned short value, unsigned long port) (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)) *port2adr(port) = value; else - maybebadio(outw, port); + maybebadio(port); } void se_outl(unsigned int value, unsigned long port) { - maybebadio(outl, port); + maybebadio(port); } void se_insb(unsigned long port, void *addr, unsigned long count) @@ -159,7 +150,7 @@ void se_insw(unsigned long port, void *addr, unsigned long count) void se_insl(unsigned long port, void *addr, unsigned long count) { - maybebadio(insl, port); + maybebadio(port); } void se_outsb(unsigned long port, const void *addr, unsigned long count) @@ -190,37 +181,5 @@ void se_outsw(unsigned long port, const void *addr, unsigned long count) void se_outsl(unsigned long port, const void *addr, unsigned long count) { - maybebadio(outsw, port); -} - -/* Map ISA bus address to the real address. Only for PCMCIA. */ - -/* ISA page descriptor. */ -static __u32 sh_isa_memmap[256]; - -static int -sh_isa_mmap(__u32 start, __u32 length, __u32 offset) -{ - int idx; - - if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000)) - return -1; - - idx = start >> 12; - sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff); -#if 0 - printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n", - start, length, offset, idx, sh_isa_memmap[idx]); -#endif - return 0; -} - -unsigned long -se_isa_port2addr(unsigned long offset) -{ - int idx; - - idx = (offset >> 12) & 0xff; - offset &= 0xfff; - return sh_isa_memmap[idx] + offset; + maybebadio(port); } diff --git a/arch/sh/boards/se/770x/irq.c b/arch/sh/boards/se/770x/irq.c index 3e558716ce1..cff6700bbaf 100644 --- a/arch/sh/boards/se/770x/irq.c +++ b/arch/sh/boards/se/770x/irq.c @@ -11,7 +11,7 @@ #include <linux/irq.h> #include <asm/irq.h> #include <asm/io.h> -#include <asm/se/se.h> +#include <asm/se.h> /* * Initialize IRQ setting diff --git a/arch/sh/boards/se/770x/led.c b/arch/sh/boards/se/770x/led.c index 3cddbda025f..daf7b1ee786 100644 --- a/arch/sh/boards/se/770x/led.c +++ b/arch/sh/boards/se/770x/led.c @@ -9,22 +9,8 @@ * This file contains Solution Engine specific LED code. */ -#include <asm/se/se.h> - -static void mach_led(int position, int value) -{ - volatile unsigned short* p = (volatile unsigned short*)PA_LED; - - if (value) { - *p |= (1<<8); - } else { - *p &= ~(1<<8); - } -} - -#ifdef CONFIG_HEARTBEAT - #include <linux/sched.h> +#include <asm/se.h> /* Cycle the LED's in the clasic Knightrider/Sun pattern */ void heartbeat_se(void) @@ -64,4 +50,3 @@ void heartbeat_se(void) *p = 1<<(bit+8); } -#endif /* CONFIG_HEARTBEAT */ diff --git a/arch/sh/boards/se/770x/mach.c b/arch/sh/boards/se/770x/mach.c deleted file mode 100644 index 6ec07bd3dcf..00000000000 --- a/arch/sh/boards/se/770x/mach.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * linux/arch/sh/kernel/mach_se.c - * - * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * Machine vector for the Hitachi SolutionEngine - */ - -#include <linux/init.h> - -#include <asm/machvec.h> -#include <asm/rtc.h> -#include <asm/machvec_init.h> - -#include <asm/se/io.h> - -void heartbeat_se(void); -void setup_se(void); -void init_se_IRQ(void); - -/* - * The Machine Vector - */ - -struct sh_machine_vector mv_se __initmv = { -#if defined(CONFIG_CPU_SH4) - .mv_nr_irqs = 48, -#elif defined(CONFIG_CPU_SUBTYPE_SH7708) - .mv_nr_irqs = 32, -#elif defined(CONFIG_CPU_SUBTYPE_SH7709) - .mv_nr_irqs = 61, -#elif defined(CONFIG_CPU_SUBTYPE_SH7705) - .mv_nr_irqs = 86, -#endif - - .mv_inb = se_inb, - .mv_inw = se_inw, - .mv_inl = se_inl, - .mv_outb = se_outb, - .mv_outw = se_outw, - .mv_outl = se_outl, - - .mv_inb_p = se_inb_p, - .mv_inw_p = se_inw, - .mv_inl_p = se_inl, - .mv_outb_p = se_outb_p, - .mv_outw_p = se_outw, - .mv_outl_p = se_outl, - - .mv_insb = se_insb, - .mv_insw = se_insw, - .mv_insl = se_insl, - .mv_outsb = se_outsb, - .mv_outsw = se_outsw, - .mv_outsl = se_outsl, - - .mv_isa_port2addr = se_isa_port2addr, - - .mv_init_irq = init_se_IRQ, -#ifdef CONFIG_HEARTBEAT - .mv_heartbeat = heartbeat_se, -#endif -}; -ALIAS_MV(se) diff --git a/arch/sh/boards/se/770x/setup.c b/arch/sh/boards/se/770x/setup.c index 7d1a071727c..f3f82b7c821 100644 --- a/arch/sh/boards/se/770x/setup.c +++ b/arch/sh/boards/se/770x/setup.c @@ -7,15 +7,17 @@ * Hitachi SolutionEngine Support. * */ - #include <linux/init.h> #include <linux/irq.h> - #include <linux/hdreg.h> #include <linux/ide.h> #include <asm/io.h> -#include <asm/se/se.h> -#include <asm/se/smc37c93x.h> +#include <asm/se.h> +#include <asm/smc37c93x.h> +#include <asm/machvec.h> + +void heartbeat_se(void); +void init_se_IRQ(void); /* * Configure the Super I/O chip @@ -26,7 +28,8 @@ static void __init smsc_config(int index, int data) outb_p(data, DATA_PORT); } -static void __init init_smsc(void) +/* XXX: Another candidate for a more generic cchip machine vector */ +static void __init smsc_setup(char **cmdline_p) { outb_p(CONFIG_ENTER, CONFIG_PORT); outb_p(CONFIG_ENTER, CONFIG_PORT); @@ -69,16 +72,46 @@ static void __init init_smsc(void) outb_p(CONFIG_EXIT, CONFIG_PORT); } -const char *get_system_type(void) -{ - return "SolutionEngine"; -} - /* - * Initialize the board + * The Machine Vector */ -void __init platform_setup(void) -{ - init_smsc(); - /* XXX: RTC setting comes here */ -} +struct sh_machine_vector mv_se __initmv = { + .mv_name = "SolutionEngine", + .mv_setup = smsc_setup, +#if defined(CONFIG_CPU_SH4) + .mv_nr_irqs = 48, +#elif defined(CONFIG_CPU_SUBTYPE_SH7708) + .mv_nr_irqs = 32, +#elif defined(CONFIG_CPU_SUBTYPE_SH7709) + .mv_nr_irqs = 61, +#elif defined(CONFIG_CPU_SUBTYPE_SH7705) + .mv_nr_irqs = 86, +#endif + + .mv_inb = se_inb, + .mv_inw = se_inw, + .mv_inl = se_inl, + .mv_outb = se_outb, + .mv_outw = se_outw, + .mv_outl = se_outl, + + .mv_inb_p = se_inb_p, + .mv_inw_p = se_inw, + .mv_inl_p = se_inl, + .mv_outb_p = se_outb_p, + .mv_outw_p = se_outw, + .mv_outl_p = se_outl, + + .mv_insb = se_insb, + .mv_insw = se_insw, + .mv_insl = se_insl, + .mv_outsb = se_outsb, + .mv_outsw = se_outsw, + .mv_outsl = se_outsl, + + .mv_init_irq = init_se_IRQ, +#ifdef CONFIG_HEARTBEAT + .mv_heartbeat = heartbeat_se, +#endif +}; +ALIAS_MV(se) diff --git a/arch/sh/boards/se/7751/Makefile b/arch/sh/boards/se/7751/Makefile index ce7ca247f84..188900c4832 100644 --- a/arch/sh/boards/se/7751/Makefile +++ b/arch/sh/boards/se/7751/Makefile @@ -2,7 +2,7 @@ # Makefile for the 7751 SolutionEngine specific parts of the kernel # -obj-y := mach.o setup.o io.o irq.o led.o +obj-y := setup.o io.o irq.o obj-$(CONFIG_PCI) += pci.o - +obj-$(CONFIG_HEARTBEAT) += led.o diff --git a/arch/sh/boards/se/7751/io.c b/arch/sh/boards/se/7751/io.c index 99041b26926..e8d846cec89 100644 --- a/arch/sh/boards/se/7751/io.c +++ b/arch/sh/boards/se/7751/io.c @@ -1,6 +1,4 @@ -/* - * linux/arch/sh/kernel/io_7751se.c - * +/* * Copyright (C) 2001 Ian da Silva, Jeremy Siegel * Based largely on io_se.c. * @@ -10,96 +8,21 @@ * placeholder code from io_se.c left in with the * expectation of later SuperIO and PCMCIA access. */ - #include <linux/kernel.h> #include <linux/types.h> +#include <linux/pci.h> #include <asm/io.h> -#include <asm/se7751/se7751.h> +#include <asm/se7751.h> #include <asm/addrspace.h> -#include <linux/pci.h> -#include "../../../drivers/pci/pci-sh7751.h" - -#if 0 -/****************************************************************** - * Variables from io_se.c, related to PCMCIA (not PCI); we're not - * compiling them in, and have removed references from functions - * which follow. [Many checked for IO ports in the range bounded - * by sh_pcic_io_start/stop, and used sh_pcic_io_wbase as offset. - * As start/stop are uninitialized, only port 0x0 would match?] - * When used, remember to adjust names to avoid clash with io_se? - *****************************************************************/ -/* SH pcmcia io window base, start and end. */ -int sh_pcic_io_wbase = 0xb8400000; -int sh_pcic_io_start; -int sh_pcic_io_stop; -int sh_pcic_io_type; -int sh_pcic_io_dummy; -/*************************************************************/ -#endif - -/* - * The 7751 Solution Engine uses the built-in PCI controller (PCIC) - * of the 7751 processor, and has a SuperIO accessible via the PCI. - * The board also includes a PCMCIA controller on its memory bus, - * like the other Solution Engine boards. - */ - -#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR) -#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR) -#define PCI_IO_AREA SH7751_PCI_IO_BASE -#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE - -#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK)) - -#define maybebadio(name,port) \ - printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \ - #name, (port), (__u32) __builtin_return_address(0)) - -static inline void delay(void) -{ - ctrl_inw(0xa0000000); -} - -static inline volatile __u16 * -port2adr(unsigned int port) +static inline volatile u16 *port2adr(unsigned int port) { if (port >= 0x2000) return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); -#if 0 - else - return (volatile __u16 *) (PA_SUPERIO + (port << 1)); -#endif - maybebadio(name,(unsigned long)port); + maybebadio((unsigned long)port); return (volatile __u16*)port; } -#if 0 -/* The 7751 Solution Engine seems to have everything hooked */ -/* up pretty normally (nothing on high-bytes only...) so this */ -/* shouldn't be needed */ -static inline int -shifted_port(unsigned long port) -{ - /* For IDE registers, value is not shifted */ - if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) - return 0; - else - return 1; -} -#endif - -/* In case someone configures the kernel w/o PCI support: in that */ -/* scenario, don't ever bother to check for PCI-window addresses */ - -/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */ -#if defined(CONFIG_PCI) -#define CHECK_SH7751_PCIIO(port) \ - ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE))) -#else -#define CHECK_SH7751_PCIIO(port) (0) -#endif - /* * General outline: remap really low stuff [eventually] to SuperIO, * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) @@ -111,10 +34,10 @@ unsigned char sh7751se_inb(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned char *)port; - else if (CHECK_SH7751_PCIIO(port)) - return *(volatile unsigned char *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + return *(volatile unsigned char *)pci_ioaddr(port); else - return (*port2adr(port))&0xff; + return (*port2adr(port)) & 0xff; } unsigned char sh7751se_inb_p(unsigned long port) @@ -123,11 +46,11 @@ unsigned char sh7751se_inb_p(unsigned long port) if (PXSEG(port)) v = *(volatile unsigned char *)port; - else if (CHECK_SH7751_PCIIO(port)) - v = *(volatile unsigned char *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + v = *(volatile unsigned char *)pci_ioaddr(port); else - v = (*port2adr(port))&0xff; - delay(); + v = (*port2adr(port)) & 0xff; + ctrl_delay(); return v; } @@ -135,12 +58,12 @@ unsigned short sh7751se_inw(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned short *)port; - else if (CHECK_SH7751_PCIIO(port)) - return *(volatile unsigned short *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + return *(volatile unsigned short *)pci_ioaddr(port); else if (port >= 0x2000) return *port2adr(port); else - maybebadio(inw, port); + maybebadio(port); return 0; } @@ -148,12 +71,12 @@ unsigned int sh7751se_inl(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned long *)port; - else if (CHECK_SH7751_PCIIO(port)) - return *(volatile unsigned int *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + return *(volatile unsigned int *)pci_ioaddr(port); else if (port >= 0x2000) return *port2adr(port); else - maybebadio(inl, port); + maybebadio(port); return 0; } @@ -162,8 +85,8 @@ void sh7751se_outb(unsigned char value, unsigned long port) if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned char*)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned char*)pci_ioaddr(port)) = value; else *(port2adr(port)) = value; } @@ -172,73 +95,41 @@ void sh7751se_outb_p(unsigned char value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned char*)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned char*)pci_ioaddr(port)) = value; else *(port2adr(port)) = value; - delay(); + ctrl_delay(); } void sh7751se_outw(unsigned short value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned short *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned short *)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned short *)pci_ioaddr(port)) = value; else if (port >= 0x2000) *port2adr(port) = value; else - maybebadio(outw, port); + maybebadio(port); } void sh7751se_outl(unsigned int value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned long *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned long*)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned long*)pci_ioaddr(port)) = value; else - maybebadio(outl, port); + maybebadio(port); } void sh7751se_insl(unsigned long port, void *addr, unsigned long count) { - maybebadio(insl, port); + maybebadio(port); } void sh7751se_outsl(unsigned long port, const void *addr, unsigned long count) { - maybebadio(outsw, port); -} - -/* Map ISA bus address to the real address. Only for PCMCIA. */ - -/* ISA page descriptor. */ -static __u32 sh_isa_memmap[256]; - -#if 0 -static int -sh_isa_mmap(__u32 start, __u32 length, __u32 offset) -{ - int idx; - - if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000)) - return -1; - - idx = start >> 12; - sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff); - printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n", - start, length, offset, idx, sh_isa_memmap[idx]); - return 0; -} -#endif - -unsigned long -sh7751se_isa_port2addr(unsigned long offset) -{ - int idx; - - idx = (offset >> 12) & 0xff; - offset &= 0xfff; - return sh_isa_memmap[idx] + offset; + maybebadio(port); } diff --git a/arch/sh/boards/se/7751/irq.c b/arch/sh/boards/se/7751/irq.c index bf6c023615d..c607b0a4847 100644 --- a/arch/sh/boards/se/7751/irq.c +++ b/arch/sh/boards/se/7751/irq.c @@ -12,7 +12,7 @@ #include <linux/init.h> #include <linux/irq.h> #include <asm/irq.h> -#include <asm/se7751/se7751.h> +#include <asm/se7751.h> /* * Initialize IRQ setting diff --git a/arch/sh/boards/se/7751/led.c b/arch/sh/boards/se/7751/led.c index a878726d3c7..ff0355dea81 100644 --- a/arch/sh/boards/se/7751/led.c +++ b/arch/sh/boards/se/7751/led.c @@ -8,23 +8,8 @@ * * This file contains Solution Engine specific LED code. */ - -#include <asm/se7751/se7751.h> - -static void mach_led(int position, int value) -{ - volatile unsigned short* p = (volatile unsigned short*)PA_LED; - - if (value) { - *p |= (1<<8); - } else { - *p &= ~(1<<8); - } -} - -#ifdef CONFIG_HEARTBEAT - #include <linux/sched.h> +#include <asm/se7751.h> /* Cycle the LED's in the clasic Knightrider/Sun pattern */ void heartbeat_7751se(void) @@ -64,4 +49,3 @@ void heartbeat_7751se(void) *p = 1<<(bit+8); } -#endif /* CONFIG_HEARTBEAT */ diff --git a/arch/sh/boards/se/7751/mach.c b/arch/sh/boards/se/7751/mach.c deleted file mode 100644 index 62d8d3e6259..00000000000 --- a/arch/sh/boards/se/7751/mach.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * linux/arch/sh/kernel/mach_7751se.c - * - * Minor tweak of mach_se.c file to reference 7751se-specific items. - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * Machine vector for the Hitachi 7751 SolutionEngine - */ - -#include <linux/init.h> - -#include <asm/machvec.h> -#include <asm/rtc.h> -#include <asm/machvec_init.h> - -#include <asm/se7751/io.h> - -void heartbeat_7751se(void); -void init_7751se_IRQ(void); - -/* - * The Machine Vector - */ - -struct sh_machine_vector mv_7751se __initmv = { - .mv_nr_irqs = 72, - - .mv_inb = sh7751se_inb, - .mv_inw = sh7751se_inw, - .mv_inl = sh7751se_inl, - .mv_outb = sh7751se_outb, - .mv_outw = sh7751se_outw, - .mv_outl = sh7751se_outl, - - .mv_inb_p = sh7751se_inb_p, - .mv_inw_p = sh7751se_inw, - .mv_inl_p = sh7751se_inl, - .mv_outb_p = sh7751se_outb_p, - .mv_outw_p = sh7751se_outw, - .mv_outl_p = sh7751se_outl, - - .mv_insl = sh7751se_insl, - .mv_outsl = sh7751se_outsl, - - .mv_isa_port2addr = sh7751se_isa_port2addr, - - .mv_init_irq = init_7751se_IRQ, -#ifdef CONFIG_HEARTBEAT - .mv_heartbeat = heartbeat_7751se, -#endif -}; -ALIAS_MV(7751se) diff --git a/arch/sh/boards/se/7751/setup.c b/arch/sh/boards/se/7751/setup.c index 48dc5aee67d..73e826310ba 100644 --- a/arch/sh/boards/se/7751/setup.c +++ b/arch/sh/boards/se/7751/setup.c @@ -1,4 +1,4 @@ -/* +/* * linux/arch/sh/kernel/setup_7751se.c * * Copyright (C) 2000 Kazumoto Kojima @@ -11,78 +11,15 @@ #include <linux/init.h> #include <linux/irq.h> - -#include <linux/hdreg.h> #include <linux/ide.h> #include <asm/io.h> -#include <asm/se7751/se7751.h> +#include <asm/se7751.h> -#ifdef CONFIG_SH_KGDB -#include <asm/kgdb.h> -#endif - -/* - * Configure the Super I/O chip - */ -#if 0 -/* Leftover code from regular Solution Engine, for reference. */ -/* The SH7751 Solution Engine has a different SuperIO. */ -static void __init smsc_config(int index, int data) -{ - outb_p(index, INDEX_PORT); - outb_p(data, DATA_PORT); -} - -static void __init init_smsc(void) -{ - outb_p(CONFIG_ENTER, CONFIG_PORT); - outb_p(CONFIG_ENTER, CONFIG_PORT); - - /* FDC */ - smsc_config(CURRENT_LDN_INDEX, LDN_FDC); - smsc_config(ACTIVATE_INDEX, 0x01); - smsc_config(IRQ_SELECT_INDEX, 6); /* IRQ6 */ - - /* IDE1 */ - smsc_config(CURRENT_LDN_INDEX, LDN_IDE1); - smsc_config(ACTIVATE_INDEX, 0x01); - smsc_config(IRQ_SELECT_INDEX, 14); /* IRQ14 */ - - /* AUXIO (GPIO): to use IDE1 */ - smsc_config(CURRENT_LDN_INDEX, LDN_AUXIO); - smsc_config(GPIO46_INDEX, 0x00); /* nIOROP */ - smsc_config(GPIO47_INDEX, 0x00); /* nIOWOP */ - - /* COM1 */ - smsc_config(CURRENT_LDN_INDEX, LDN_COM1); - smsc_config(ACTIVATE_INDEX, 0x01); - smsc_config(IO_BASE_HI_INDEX, 0x03); - smsc_config(IO_BASE_LO_INDEX, 0xf8); - smsc_config(IRQ_SELECT_INDEX, 4); /* IRQ4 */ - - /* COM2 */ - smsc_config(CURRENT_LDN_INDEX, LDN_COM2); - smsc_config(ACTIVATE_INDEX, 0x01); - smsc_config(IO_BASE_HI_INDEX, 0x02); - smsc_config(IO_BASE_LO_INDEX, 0xf8); - smsc_config(IRQ_SELECT_INDEX, 3); /* IRQ3 */ - - /* RTC */ - smsc_config(CURRENT_LDN_INDEX, LDN_RTC); - smsc_config(ACTIVATE_INDEX, 0x01); - smsc_config(IRQ_SELECT_INDEX, 8); /* IRQ8 */ - - /* XXX: PARPORT, KBD, and MOUSE will come here... */ - outb_p(CONFIG_EXIT, CONFIG_PORT); -} -#endif - -const char *get_system_type(void) -{ - return "7751 SolutionEngine"; -} +void heartbeat_7751se(void); +void init_7751se_IRQ(void); #ifdef CONFIG_SH_KGDB +#include <asm/kgdb.h> static int kgdb_uart_setup(void); static struct kgdb_sermap kgdb_uart_sermap = { "ttyS", 0, kgdb_uart_setup, NULL }; @@ -91,7 +28,7 @@ static struct kgdb_sermap kgdb_uart_sermap = /* * Initialize the board */ -void __init platform_setup(void) +static void __init sh7751se_setup(char **cmdline_p) { /* Call init_smsc() replacement to set up SuperIO. */ /* XXX: RTC setting comes here */ @@ -225,3 +162,37 @@ static int kgdb_uart_setup(void) return 0; } #endif /* CONFIG_SH_KGDB */ + + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_7751se __initmv = { + .mv_name = "7751 SolutionEngine", + .mv_setup = sh7751se_setup, + .mv_nr_irqs = 72, + + .mv_inb = sh7751se_inb, + .mv_inw = sh7751se_inw, + .mv_inl = sh7751se_inl, + .mv_outb = sh7751se_outb, + .mv_outw = sh7751se_outw, + .mv_outl = sh7751se_outl, + + .mv_inb_p = sh7751se_inb_p, + .mv_inw_p = sh7751se_inw, + .mv_inl_p = sh7751se_inl, + .mv_outb_p = sh7751se_outb_p, + .mv_outw_p = sh7751se_outw, + .mv_outl_p = sh7751se_outl, + + .mv_insl = sh7751se_insl, + .mv_outsl = sh7751se_outsl, + + .mv_init_irq = init_7751se_IRQ, +#ifdef CONFIG_HEARTBEAT + .mv_heartbeat = heartbeat_7751se, +#endif +}; +ALIAS_MV(7751se) diff --git a/arch/sh/boards/sh03/rtc.c b/arch/sh/boards/sh03/rtc.c index d609863cfe5..0a9266bb51c 100644 --- a/arch/sh/boards/sh03/rtc.c +++ b/arch/sh/boards/sh03/rtc.c @@ -10,9 +10,10 @@ #include <linux/sched.h> #include <linux/time.h> #include <linux/bcd.h> -#include <asm/io.h> #include <linux/rtc.h> #include <linux/spinlock.h> +#include <asm/io.h> +#include <asm/rtc.h> #define RTC_BASE 0xb0000000 #define RTC_SEC1 (RTC_BASE + 0) @@ -34,8 +35,6 @@ #define RTC_BUSY 1 #define RTC_STOP 2 -extern void (*rtc_get_time)(struct timespec *); -extern int (*rtc_set_time)(const time_t); extern spinlock_t rtc_lock; unsigned long get_cmos_time(void) @@ -128,6 +127,6 @@ int sh03_rtc_settimeofday(const time_t secs) void sh03_time_init(void) { - rtc_get_time = sh03_rtc_gettimeofday; - rtc_set_time = sh03_rtc_settimeofday; + rtc_sh_get_time = sh03_rtc_gettimeofday; + rtc_sh_set_time = sh03_rtc_settimeofday; } diff --git a/arch/sh/boards/sh03/setup.c b/arch/sh/boards/sh03/setup.c index 60290f8f289..6c310587ddf 100644 --- a/arch/sh/boards/sh03/setup.c +++ b/arch/sh/boards/sh03/setup.c @@ -7,22 +7,13 @@ #include <linux/init.h> #include <linux/irq.h> -#include <linux/hdreg.h> -#include <linux/ide.h> #include <asm/io.h> +#include <asm/rtc.h> #include <asm/sh03/io.h> #include <asm/sh03/sh03.h> #include <asm/addrspace.h> -#include "../../drivers/pci/pci-sh7751.h" -extern void (*board_time_init)(void); - -const char *get_system_type(void) -{ - return "Interface CTP/PCI-SH03)"; -} - -void init_sh03_IRQ(void) +static void __init init_sh03_IRQ(void) { ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); @@ -34,38 +25,34 @@ void init_sh03_IRQ(void) extern void *cf_io_base; -unsigned long sh03_isa_port2addr(unsigned long port) +static void __iomem *sh03_ioport_map(unsigned long port, unsigned int size) { if (PXSEG(port)) - return port; + return (void __iomem *)port; /* CompactFlash (IDE) */ - if (((port >= 0x1f0) && (port <= 0x1f7)) || (port == 0x3f6)) { - return (unsigned long)cf_io_base + port; - } - return port + SH7751_PCI_IO_BASE; + if (((port >= 0x1f0) && (port <= 0x1f7)) || (port == 0x3f6)) + return (void __iomem *)((unsigned long)cf_io_base + port); + + return (void __iomem *)(port + PCI_IO_BASE); } -/* - * The Machine Vector - */ +/* arch/sh/boards/sh03/rtc.c */ +void sh03_time_init(void); + +static void __init sh03_setup(char **cmdline_p) +{ + board_time_init = sh03_time_init; +} struct sh_machine_vector mv_sh03 __initmv = { + .mv_name = "Interface (CTP/PCI-SH03)", + .mv_setup = sh03_setup, .mv_nr_irqs = 48, - .mv_isa_port2addr = sh03_isa_port2addr, + .mv_ioport_map = sh03_ioport_map, .mv_init_irq = init_sh03_IRQ, #ifdef CONFIG_HEARTBEAT .mv_heartbeat = heartbeat_sh03, #endif }; - ALIAS_MV(sh03) - -/* arch/sh/boards/sh03/rtc.c */ -void sh03_time_init(void); - -int __init platform_setup(void) -{ - board_time_init = sh03_time_init; - return 0; -} diff --git a/arch/sh/boards/sh2000/Makefile b/arch/sh/boards/sh2000/Makefile deleted file mode 100644 index 05d390c3599..00000000000 --- a/arch/sh/boards/sh2000/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# -# Makefile for the SH2000 specific parts of the kernel -# - -obj-y := setup.o - diff --git a/arch/sh/boards/sh2000/setup.c b/arch/sh/boards/sh2000/setup.c deleted file mode 100644 index 2fe6a11765e..00000000000 --- a/arch/sh/boards/sh2000/setup.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * linux/arch/sh/kernel/setup_sh2000.c - * - * Copyright (C) 2001 SUGIOKA Tochinobu - * - * SH-2000 Support. - * - */ - -#include <linux/init.h> -#include <linux/irq.h> - -#include <asm/io.h> -#include <asm/machvec.h> -#include <asm/mach/sh2000.h> - -#define CF_CIS_BASE 0xb4200000 - -#define PORT_PECR 0xa4000108 -#define PORT_PHCR 0xa400010E -#define PORT_ICR1 0xa4000010 -#define PORT_IRR0 0xa4000004 - -#define IDE_OFFSET 0xb6200000 -#define NIC_OFFSET 0xb6000000 -#define EXTBUS_OFFSET 0xba000000 - - -const char *get_system_type(void) -{ - return "sh2000"; -} - -static unsigned long sh2000_isa_port2addr(unsigned long offset) -{ - if((offset & ~7) == 0x1f0 || offset == 0x3f6) - return IDE_OFFSET + offset; - else if((offset & ~0x1f) == 0x300) - return NIC_OFFSET + offset; - return EXTBUS_OFFSET + offset; -} - -/* - * The Machine Vector - */ -struct sh_machine_vector mv_sh2000 __initmv = { - .mv_nr_irqs = 80, - .mv_isa_port2addr = sh2000_isa_port2addr, -}; -ALIAS_MV(sh2000) - -/* - * Initialize the board - */ -int __init platform_setup(void) -{ - /* XXX: RTC setting comes here */ - - /* These should be done by BIOS/IPL ... */ - /* Enable nCE2A, nCE2B output */ - ctrl_outw(ctrl_inw(PORT_PECR) & ~0xf00, PORT_PECR); - /* Enable the Compact Flash card, and set the level interrupt */ - ctrl_outw(0x0042, CF_CIS_BASE+0x0200); - /* Enable interrupt */ - ctrl_outw(ctrl_inw(PORT_PHCR) & ~0x03f3, PORT_PHCR); - ctrl_outw(1, PORT_ICR1); - ctrl_outw(ctrl_inw(PORT_IRR0) & ~0xff3f, PORT_IRR0); - printk(KERN_INFO "SH-2000 Setup...done\n"); - return 0; -} diff --git a/arch/sh/boards/shmin/Makefile b/arch/sh/boards/shmin/Makefile new file mode 100644 index 00000000000..3190cc72430 --- /dev/null +++ b/arch/sh/boards/shmin/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the SHMIN board. +# + +obj-y := setup.o diff --git a/arch/sh/boards/shmin/setup.c b/arch/sh/boards/shmin/setup.c new file mode 100644 index 00000000000..2f0c19706cf --- /dev/null +++ b/arch/sh/boards/shmin/setup.c @@ -0,0 +1,41 @@ +/* + * arch/sh/boards/shmin/setup.c + * + * Copyright (C) 2006 Takashi YOSHII + * + * SHMIN Support. + */ +#include <linux/init.h> +#include <asm/machvec.h> +#include <asm/shmin/shmin.h> +#include <asm/clock.h> +#include <asm/irq.h> +#include <asm/io.h> + +#define PFC_PHCR 0xa400010e + +static void __init init_shmin_irq(void) +{ + ctrl_outw(0x2a00, PFC_PHCR); // IRQ0-3=IRQ + ctrl_outw(0x0aaa, INTC_ICR1); // IRQ0-3=IRQ-mode,Low-active. +} + +static void __iomem *shmin_ioport_map(unsigned long port, unsigned int size) +{ + static int dummy; + + if ((port & ~0x1f) == SHMIN_NE_BASE) + return (void __iomem *)(SHMIN_IO_BASE + port); + + dummy = 0; + + return &dummy; + +} + +struct sh_machine_vector mv_shmin __initmv = { + .mv_name = "SHMIN", + .mv_init_irq = init_shmin_irq, + .mv_ioport_map = shmin_ioport_map, +}; +ALIAS_MV(shmin) diff --git a/arch/sh/boards/snapgear/io.c b/arch/sh/boards/snapgear/io.c index e2eb78fc381..0f482426455 100644 --- a/arch/sh/boards/snapgear/io.c +++ b/arch/sh/boards/snapgear/io.c @@ -1,6 +1,4 @@ -/* - * linux/arch/sh/kernel/io_7751se.c - * +/* * Copyright (C) 2002 David McCullough <davidm@snapgear.com> * Copyright (C) 2001 Ian da Silva, Jeremy Siegel * Based largely on io_se.c. @@ -11,67 +9,22 @@ * placeholder code from io_se.c left in with the * expectation of later SuperIO and PCMCIA access. */ - #include <linux/kernel.h> #include <linux/types.h> #include <linux/pci.h> #include <asm/io.h> #include <asm/addrspace.h> -#include <asm/pci.h> -#include "../../drivers/pci/pci-sh7751.h" - #ifdef CONFIG_SH_SECUREEDGE5410 unsigned short secureedge5410_ioport; #endif -/* - * The SnapGear uses the built-in PCI controller (PCIC) - * of the 7751 processor - */ - -#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR) -#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR) -#define PCI_IO_AREA SH7751_PCI_IO_BASE -#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE - - -#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK)) - - -#define maybebadio(name,port) \ - printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \ - #name, (port), (__u32) __builtin_return_address(0)) - - -static inline void delay(void) -{ - ctrl_inw(0xa0000000); -} - - static inline volatile __u16 *port2adr(unsigned int port) { -#if 0 - if (port >= 0x2000) - return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); -#endif - maybebadio(name,(unsigned long)port); + maybebadio((unsigned long)port); return (volatile __u16*)port; } - -/* In case someone configures the kernel w/o PCI support: in that */ -/* scenario, don't ever bother to check for PCI-window addresses */ - -/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */ -#if defined(CONFIG_PCI) -#define CHECK_SH7751_PCIIO(port) \ - ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE))) -#else -#define CHECK_SH7751_PCIIO(port) (0) -#endif - /* * General outline: remap really low stuff [eventually] to SuperIO, * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) @@ -79,148 +32,106 @@ static inline volatile __u16 *port2adr(unsigned int port) * should be way beyond the window, and is used w/o translation for * compatibility. */ - unsigned char snapgear_inb(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned char *)port; - else if (CHECK_SH7751_PCIIO(port)) - return *(volatile unsigned char *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + return *(volatile unsigned char *)pci_ioaddr(port); else - return (*port2adr(port))&0xff; + return (*port2adr(port)) & 0xff; } - unsigned char snapgear_inb_p(unsigned long port) { unsigned char v; if (PXSEG(port)) v = *(volatile unsigned char *)port; - else if (CHECK_SH7751_PCIIO(port)) - v = *(volatile unsigned char *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + v = *(volatile unsigned char *)pci_ioaddr(port); else - v = (*port2adr(port))&0xff; - delay(); + v = (*port2adr(port))&0xff; + ctrl_delay(); return v; } - unsigned short snapgear_inw(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned short *)port; - else if (CHECK_SH7751_PCIIO(port)) - return *(volatile unsigned short *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + return *(volatile unsigned short *)pci_ioaddr(port); else if (port >= 0x2000) return *port2adr(port); else - maybebadio(inw, port); + maybebadio(port); return 0; } - unsigned int snapgear_inl(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned long *)port; - else if (CHECK_SH7751_PCIIO(port)) - return *(volatile unsigned int *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + return *(volatile unsigned int *)pci_ioaddr(port); else if (port >= 0x2000) return *port2adr(port); else - maybebadio(inl, port); + maybebadio(port); return 0; } - void snapgear_outb(unsigned char value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned char*)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned char*)pci_ioaddr(port)) = value; else *(port2adr(port)) = value; } - void snapgear_outb_p(unsigned char value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned char*)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned char*)pci_ioaddr(port)) = value; else *(port2adr(port)) = value; - delay(); + ctrl_delay(); } - void snapgear_outw(unsigned short value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned short *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned short *)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned short *)pci_ioaddr(port)) = value; else if (port >= 0x2000) *port2adr(port) = value; else - maybebadio(outw, port); + maybebadio(port); } - void snapgear_outl(unsigned int value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned long *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned long*)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned long*)pci_ioaddr(port)) = value; else - maybebadio(outl, port); + maybebadio(port); } void snapgear_insl(unsigned long port, void *addr, unsigned long count) { - maybebadio(insl, port); + maybebadio(port); } void snapgear_outsl(unsigned long port, const void *addr, unsigned long count) { - maybebadio(outsw, port); -} - -/* Map ISA bus address to the real address. Only for PCMCIA. */ - - -/* ISA page descriptor. */ -static __u32 sh_isa_memmap[256]; - - -#if 0 -static int sh_isa_mmap(__u32 start, __u32 length, __u32 offset) -{ - int idx; - - if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000)) - return -1; - - idx = start >> 12; - sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff); -#if 0 - printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n", - start, length, offset, idx, sh_isa_memmap[idx]); -#endif - return 0; -} -#endif - -unsigned long snapgear_isa_port2addr(unsigned long offset) -{ - int idx; - - idx = (offset >> 12) & 0xff; - offset &= 0xfff; - return sh_isa_memmap[idx] + offset; + maybebadio(port); } diff --git a/arch/sh/boards/snapgear/rtc.c b/arch/sh/boards/snapgear/rtc.c index b71e009da35..1659fdd6695 100644 --- a/arch/sh/boards/snapgear/rtc.c +++ b/arch/sh/boards/snapgear/rtc.c @@ -17,14 +17,9 @@ #include <linux/time.h> #include <linux/rtc.h> #include <linux/mc146818rtc.h> - #include <asm/io.h> -#include <asm/rtc.h> -#include <asm/mc146818rtc.h> - -/****************************************************************************/ -static int use_ds1302 = 0; +static int use_ds1302; /****************************************************************************/ /* @@ -82,10 +77,6 @@ static unsigned int ds1302_readbyte(unsigned int addr) unsigned int val; unsigned long flags; -#if 0 - printk("SnapGear RTC: ds1302_readbyte(addr=%x)\n", addr); -#endif - local_irq_save(flags); set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK); set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); @@ -104,10 +95,6 @@ static void ds1302_writebyte(unsigned int addr, unsigned int val) { unsigned long flags; -#if 0 - printk("SnapGear RTC: ds1302_writebyte(addr=%x)\n", addr); -#endif - local_irq_save(flags); set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK); set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); @@ -168,11 +155,8 @@ void __init secureedge5410_rtc_init(void) } if (use_ds1302) { - rtc_get_time = snapgear_rtc_gettimeofday; - rtc_set_time = snapgear_rtc_settimeofday; - } else { - rtc_get_time = sh_rtc_gettimeofday; - rtc_set_time = sh_rtc_settimeofday; + rtc_sh_get_time = snapgear_rtc_gettimeofday; + rtc_sh_set_time = snapgear_rtc_settimeofday; } printk("SnapGear RTC: using %s rtc.\n", use_ds1302 ? "ds1302" : "internal"); @@ -187,10 +171,8 @@ void snapgear_rtc_gettimeofday(struct timespec *ts) { unsigned int sec, min, hr, day, mon, yr; - if (!use_ds1302) { - sh_rtc_gettimeofday(ts); + if (!use_ds1302) return; - } sec = bcd2int(ds1302_readbyte(RTC_ADDR_SEC)); min = bcd2int(ds1302_readbyte(RTC_ADDR_MIN)); @@ -231,7 +213,7 @@ int snapgear_rtc_settimeofday(const time_t secs) unsigned long nowtime; if (!use_ds1302) - return sh_rtc_settimeofday(secs); + return 0; /* * This is called direct from the kernel timer handling code. @@ -240,10 +222,6 @@ int snapgear_rtc_settimeofday(const time_t secs) nowtime = secs; -#if 1 - printk("SnapGear RTC: snapgear_rtc_settimeofday(nowtime=%ld)\n", nowtime); -#endif - /* STOP RTC */ ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80); @@ -329,5 +307,3 @@ void secureedge5410_cmos_write(unsigned char val, int addr) default: break; } } - -/****************************************************************************/ diff --git a/arch/sh/boards/snapgear/setup.c b/arch/sh/boards/snapgear/setup.c index f1f7c70c940..f5e98c56b53 100644 --- a/arch/sh/boards/snapgear/setup.c +++ b/arch/sh/boards/snapgear/setup.c @@ -1,5 +1,4 @@ -/****************************************************************************/ -/* +/* * linux/arch/sh/boards/snapgear/setup.c * * Copyright (C) 2002 David McCullough <davidm@snapgear.com> @@ -12,8 +11,6 @@ * Modified for 7751 Solution Engine by * Ian da Silva and Jeremy Siegel, 2001. */ -/****************************************************************************/ - #include <linux/init.h> #include <linux/irq.h> #include <linux/interrupt.h> @@ -21,14 +18,13 @@ #include <linux/delay.h> #include <linux/module.h> #include <linux/sched.h> - #include <asm/machvec.h> -#include <asm/mach/io.h> +#include <asm/snapgear.h> #include <asm/irq.h> #include <asm/io.h> +#include <asm/rtc.h> #include <asm/cpu/timer.h> -extern void (*board_time_init)(void); extern void secureedge5410_rtc_init(void); extern void pcibios_init(void); @@ -85,101 +81,20 @@ static void __init init_snapgear_IRQ(void) make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY); } -/****************************************************************************/ -/* - * Fast poll interrupt simulator. - */ - /* - * Leave all of the fast timer/fast poll stuff commented out for now, since - * it's not clear whether it actually works or not. Since it wasn't being used - * at all in 2.4, we'll assume it's not sane for 2.6 either.. -- PFM - */ -#if 0 -#define FAST_POLL 1000 -//#define FAST_POLL_INTR - -#define FASTTIMER_IRQ 17 -#define FASTTIMER_IPR_ADDR INTC_IPRA -#define FASTTIMER_IPR_POS 2 -#define FASTTIMER_PRIORITY 3 - -#ifdef FAST_POLL_INTR -#define TMU1_TCR_INIT 0x0020 -#else -#define TMU1_TCR_INIT 0 -#endif -#define TMU_TSTR_INIT 1 -#define TMU1_TCR_CALIB 0x0000 - - -#ifdef FAST_POLL_INTR -static void fast_timer_irq(int irq, void *dev_instance, struct pt_regs *regs) -{ - unsigned long timer_status; - timer_status = ctrl_inw(TMU1_TCR); - timer_status &= ~0x100; - ctrl_outw(timer_status, TMU1_TCR); -} -#endif - -/* - * return the current ticks on the fast timer - */ - -unsigned long fast_timer_count(void) -{ - return(ctrl_inl(TMU1_TCNT)); -} - -/* - * setup a fast timer for profiling etc etc + * Initialize the board */ - -static void setup_fast_timer() -{ - unsigned long interval; - -#ifdef FAST_POLL_INTR - interval = (current_cpu_data.module_clock/4 + FAST_POLL/2) / FAST_POLL; - - make_ipr_irq(FASTTIMER_IRQ, FASTTIMER_IPR_ADDR, FASTTIMER_IPR_POS, - FASTTIMER_PRIORITY); - - printk("SnapGear: %dHz fast timer on IRQ %d\n",FAST_POLL,FASTTIMER_IRQ); - - if (request_irq(FASTTIMER_IRQ, fast_timer_irq, 0, "SnapGear fast timer", - NULL) != 0) - printk("%s(%d): request_irq() failed?\n", __FILE__, __LINE__); -#else - printk("SnapGear: fast timer running\n",FAST_POLL,FASTTIMER_IRQ); - interval = 0xffffffff; -#endif - - ctrl_outb(ctrl_inb(TMU_TSTR) & ~0x2, TMU_TSTR); /* disable timer 1 */ - ctrl_outw(TMU1_TCR_INIT, TMU1_TCR); - ctrl_outl(interval, TMU1_TCOR); - ctrl_outl(interval, TMU1_TCNT); - ctrl_outb(ctrl_inb(TMU_TSTR) | 0x2, TMU_TSTR); /* enable timer 1 */ - - printk("Timer count 1 = 0x%x\n", fast_timer_count()); - udelay(1000); - printk("Timer count 2 = 0x%x\n", fast_timer_count()); -} -#endif - -/****************************************************************************/ - -const char *get_system_type(void) +static void __init snapgear_setup(char **cmdline_p) { - return "SnapGear SecureEdge5410"; + board_time_init = secureedge5410_rtc_init; } /* * The Machine Vector */ - struct sh_machine_vector mv_snapgear __initmv = { + .mv_name = "SnapGear SecureEdge5410", + .mv_setup = snapgear_setup, .mv_nr_irqs = 72, .mv_inb = snapgear_inb, @@ -196,20 +111,6 @@ struct sh_machine_vector mv_snapgear __initmv = { .mv_outw_p = snapgear_outw, .mv_outl_p = snapgear_outl, - .mv_isa_port2addr = snapgear_isa_port2addr, - .mv_init_irq = init_snapgear_IRQ, }; ALIAS_MV(snapgear) - -/* - * Initialize the board - */ - -int __init platform_setup(void) -{ - board_time_init = secureedge5410_rtc_init; - - return 0; -} - diff --git a/arch/sh/boards/superh/microdev/irq.c b/arch/sh/boards/superh/microdev/irq.c index 236398fbc08..8c64baa3036 100644 --- a/arch/sh/boards/superh/microdev/irq.c +++ b/arch/sh/boards/superh/microdev/irq.c @@ -11,14 +11,12 @@ #include <linux/init.h> #include <linux/irq.h> - #include <asm/system.h> #include <asm/io.h> #include <asm/microdev.h> #define NUM_EXTERNAL_IRQS 16 /* IRL0 .. IRL15 */ - static const struct { unsigned char fpgaIrq; unsigned char mapped; @@ -93,53 +91,42 @@ static struct hw_interrupt_type microdev_irq_type = { static void disable_microdev_irq(unsigned int irq) { - unsigned int flags; unsigned int fpgaIrq; - if (irq >= NUM_EXTERNAL_IRQS) return; - if (!fpgaIrqTable[irq].mapped) return; + if (irq >= NUM_EXTERNAL_IRQS) + return; + if (!fpgaIrqTable[irq].mapped) + return; fpgaIrq = fpgaIrqTable[irq].fpgaIrq; - /* disable interrupts */ - local_irq_save(flags); - - /* disable interupts on the FPGA INTC register */ + /* disable interupts on the FPGA INTC register */ ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG); - - /* restore interrupts */ - local_irq_restore(flags); } static void enable_microdev_irq(unsigned int irq) { unsigned long priorityReg, priorities, pri; - unsigned int flags; unsigned int fpgaIrq; - - if (irq >= NUM_EXTERNAL_IRQS) return; - if (!fpgaIrqTable[irq].mapped) return; + if (unlikely(irq >= NUM_EXTERNAL_IRQS)) + return; + if (unlikely(!fpgaIrqTable[irq].mapped)) + return; pri = 15 - irq; fpgaIrq = fpgaIrqTable[irq].fpgaIrq; priorityReg = MICRODEV_FPGA_INTPRI_REG(fpgaIrq); - /* disable interrupts */ - local_irq_save(flags); - - /* set priority for the interrupt */ + /* set priority for the interrupt */ priorities = ctrl_inl(priorityReg); priorities &= ~MICRODEV_FPGA_INTPRI_MASK(fpgaIrq); priorities |= MICRODEV_FPGA_INTPRI_LEVEL(fpgaIrq, pri); ctrl_outl(priorities, priorityReg); - /* enable interupts on the FPGA INTC register */ + /* enable interupts on the FPGA INTC register */ ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG); - - /* restore interrupts */ - local_irq_restore(flags); } /* This functions sets the desired irq handler to be a MicroDev type */ @@ -158,9 +145,7 @@ static void mask_and_ack_microdev(unsigned int irq) static void end_microdev_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - { enable_microdev_irq(irq); - } } extern void __init init_microdev_irq(void) @@ -171,9 +156,7 @@ extern void __init init_microdev_irq(void) ctrl_outl(~0ul, MICRODEV_FPGA_INTDSB_REG); for (i = 0; i < NUM_EXTERNAL_IRQS; i++) - { make_microdev_irq(i); - } } extern void microdev_print_fpga_intc_status(void) diff --git a/arch/sh/boards/superh/microdev/setup.c b/arch/sh/boards/superh/microdev/setup.c index 61b402a3f5d..031c814e6e7 100644 --- a/arch/sh/boards/superh/microdev/setup.c +++ b/arch/sh/boards/superh/microdev/setup.c @@ -10,7 +10,6 @@ * May be copied or modified under the terms of the GNU General Public * License. See linux/COPYING for more information. */ - #include <linux/init.h> #include <linux/platform_device.h> #include <linux/ioport.h> @@ -21,41 +20,6 @@ extern void microdev_heartbeat(void); -/* - * The Machine Vector - */ - -struct sh_machine_vector mv_sh4202_microdev __initmv = { - .mv_nr_irqs = 72, /* QQQ need to check this - use the MACRO */ - - .mv_inb = microdev_inb, - .mv_inw = microdev_inw, - .mv_inl = microdev_inl, - .mv_outb = microdev_outb, - .mv_outw = microdev_outw, - .mv_outl = microdev_outl, - - .mv_inb_p = microdev_inb_p, - .mv_inw_p = microdev_inw_p, - .mv_inl_p = microdev_inl_p, - .mv_outb_p = microdev_outb_p, - .mv_outw_p = microdev_outw_p, - .mv_outl_p = microdev_outl_p, - - .mv_insb = microdev_insb, - .mv_insw = microdev_insw, - .mv_insl = microdev_insl, - .mv_outsb = microdev_outsb, - .mv_outsw = microdev_outsw, - .mv_outsl = microdev_outsl, - - .mv_init_irq = init_microdev_irq, - -#ifdef CONFIG_HEARTBEAT - .mv_heartbeat = microdev_heartbeat, -#endif -}; -ALIAS_MV(sh4202_microdev) /****************************************************************************/ @@ -113,11 +77,6 @@ ALIAS_MV(sh4202_microdev) /* assume a Keyboard Controller is present */ int microdev_kbd_controller_present = 1; -const char *get_system_type(void) -{ - return "SH4-202 MicroDev"; -} - static struct resource smc91x_resources[] = { [0] = { .start = 0x300, @@ -291,25 +250,9 @@ static int __init microdev_devices_setup(void) return platform_add_devices(microdev_devices, ARRAY_SIZE(microdev_devices)); } -__initcall(microdev_devices_setup); - -void __init platform_setup(void) -{ - int * const fpgaRevisionRegister = (int*)(MICRODEV_FPGA_GP_BASE + 0x8ul); - const int fpgaRevision = *fpgaRevisionRegister; - int * const CacheControlRegister = (int*)CCR; - - printk("SuperH %s board (FPGA rev: 0x%0x, CCR: 0x%0x)\n", - get_system_type(), fpgaRevision, *CacheControlRegister); -} - - -/****************************************************************************/ - - - /* - * Setup for the SMSC FDC37C93xAPM - */ +/* + * Setup for the SMSC FDC37C93xAPM + */ static int __init smsc_superio_setup(void) { @@ -412,8 +355,52 @@ static int __init smsc_superio_setup(void) return 0; } +static void __init microdev_setup(char **cmdline_p) +{ + int * const fpgaRevisionRegister = (int*)(MICRODEV_FPGA_GP_BASE + 0x8ul); + const int fpgaRevision = *fpgaRevisionRegister; + int * const CacheControlRegister = (int*)CCR; + + device_initcall(microdev_devices_setup); + device_initcall(smsc_superio_setup); -/* This is grotty, but, because kernel is always referenced on the link line - * before any devices, this is safe. + printk("SuperH %s board (FPGA rev: 0x%0x, CCR: 0x%0x)\n", + get_system_type(), fpgaRevision, *CacheControlRegister); +} + +/* + * The Machine Vector */ -__initcall(smsc_superio_setup); +struct sh_machine_vector mv_sh4202_microdev __initmv = { + .mv_name = "SH4-202 MicroDev", + .mv_setup = microdev_setup, + .mv_nr_irqs = 72, /* QQQ need to check this - use the MACRO */ + + .mv_inb = microdev_inb, + .mv_inw = microdev_inw, + .mv_inl = microdev_inl, + .mv_outb = microdev_outb, + .mv_outw = microdev_outw, + .mv_outl = microdev_outl, + + .mv_inb_p = microdev_inb_p, + .mv_inw_p = microdev_inw_p, + .mv_inl_p = microdev_inl_p, + .mv_outb_p = microdev_outb_p, + .mv_outw_p = microdev_outw_p, + .mv_outl_p = microdev_outl_p, + + .mv_insb = microdev_insb, + .mv_insw = microdev_insw, + .mv_insl = microdev_insl, + .mv_outsb = microdev_outsb, + .mv_outsw = microdev_outsw, + .mv_outsl = microdev_outsl, + + .mv_init_irq = init_microdev_irq, + +#ifdef CONFIG_HEARTBEAT + .mv_heartbeat = microdev_heartbeat, +#endif +}; +ALIAS_MV(sh4202_microdev) diff --git a/arch/sh/boards/titan/Makefile b/arch/sh/boards/titan/Makefile new file mode 100644 index 00000000000..08d75370006 --- /dev/null +++ b/arch/sh/boards/titan/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the Nimble Microsystems TITAN specific parts of the kernel +# + +obj-y := setup.o io.o diff --git a/arch/sh/boards/titan/io.c b/arch/sh/boards/titan/io.c new file mode 100644 index 00000000000..4730c1dd697 --- /dev/null +++ b/arch/sh/boards/titan/io.c @@ -0,0 +1,126 @@ +/* + * I/O routines for Titan + */ +#include <linux/pci.h> +#include <asm/machvec.h> +#include <asm/addrspace.h> +#include <asm/titan.h> +#include <asm/io.h> + +static inline unsigned int port2adr(unsigned int port) +{ + maybebadio((unsigned long)port); + return port; +} + +u8 titan_inb(unsigned long port) +{ + if (PXSEG(port)) + return ctrl_inb(port); + else if (is_pci_ioaddr(port)) + return ctrl_inb(pci_ioaddr(port)); + return ctrl_inw(port2adr(port)) & 0xff; +} + +u8 titan_inb_p(unsigned long port) +{ + u8 v; + + if (PXSEG(port)) + v = ctrl_inb(port); + else if (is_pci_ioaddr(port)) + v = ctrl_inb(pci_ioaddr(port)); + else + v = ctrl_inw(port2adr(port)) & 0xff; + ctrl_delay(); + return v; +} + +u16 titan_inw(unsigned long port) +{ + if (PXSEG(port)) + return ctrl_inw(port); + else if (is_pci_ioaddr(port)) + return ctrl_inw(pci_ioaddr(port)); + else if (port >= 0x2000) + return ctrl_inw(port2adr(port)); + else + maybebadio(port); + return 0; +} + +u32 titan_inl(unsigned long port) +{ + if (PXSEG(port)) + return ctrl_inl(port); + else if (is_pci_ioaddr(port)) + return ctrl_inl(pci_ioaddr(port)); + else if (port >= 0x2000) + return ctrl_inw(port2adr(port)); + else + maybebadio(port); + return 0; +} + +void titan_outb(u8 value, unsigned long port) +{ + if (PXSEG(port)) + ctrl_outb(value, port); + else if (is_pci_ioaddr(port)) + ctrl_outb(value, pci_ioaddr(port)); + else + ctrl_outw(value, port2adr(port)); +} + +void titan_outb_p(u8 value, unsigned long port) +{ + if (PXSEG(port)) + ctrl_outb(value, port); + else if (is_pci_ioaddr(port)) + ctrl_outb(value, pci_ioaddr(port)); + else + ctrl_outw(value, port2adr(port)); + ctrl_delay(); +} + +void titan_outw(u16 value, unsigned long port) +{ + if (PXSEG(port)) + ctrl_outw(value, port); + else if (is_pci_ioaddr(port)) + ctrl_outw(value, pci_ioaddr(port)); + else if (port >= 0x2000) + ctrl_outw(value, port2adr(port)); + else + maybebadio(port); +} + +void titan_outl(u32 value, unsigned long port) +{ + if (PXSEG(port)) + ctrl_outl(value, port); + else if (is_pci_ioaddr(port)) + ctrl_outl(value, pci_ioaddr(port)); + else + maybebadio(port); +} + +void titan_insl(unsigned long port, void *dst, unsigned long count) +{ + maybebadio(port); +} + +void titan_outsl(unsigned long port, const void *src, unsigned long count) +{ + maybebadio(port); +} + +void __iomem *titan_ioport_map(unsigned long port, unsigned int size) +{ + if (PXSEG(port) || is_pci_memaddr(port)) + return (void __iomem *)port; + else if (is_pci_ioaddr(port)) + return (void __iomem *)pci_ioaddr(port); + + return (void __iomem *)port2adr(port); +} diff --git a/arch/sh/boards/titan/setup.c b/arch/sh/boards/titan/setup.c new file mode 100644 index 00000000000..52b66d8b8d2 --- /dev/null +++ b/arch/sh/boards/titan/setup.c @@ -0,0 +1,48 @@ +/* + * Setup for Titan + */ + +#include <linux/init.h> +#include <asm/irq.h> +#include <asm/titan.h> +#include <asm/io.h> + +extern void __init pcibios_init_platform(void); + +static void __init init_titan_irq(void) +{ + /* enable individual interrupt mode for externals */ + ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); + + make_ipr_irq( TITAN_IRQ_WAN, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY); /* PCIRQ0 */ + make_ipr_irq( TITAN_IRQ_LAN, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY); /* PCIRQ1 */ + make_ipr_irq( TITAN_IRQ_MPCIA, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY); /* PCIRQ2 */ + make_ipr_irq( TITAN_IRQ_USB, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY); /* PCIRQ3 */ +} + +struct sh_machine_vector mv_titan __initmv = { + .mv_name = "Titan", + + .mv_inb = titan_inb, + .mv_inw = titan_inw, + .mv_inl = titan_inl, + .mv_outb = titan_outb, + .mv_outw = titan_outw, + .mv_outl = titan_outl, + + .mv_inb_p = titan_inb_p, + .mv_inw_p = titan_inw, + .mv_inl_p = titan_inl, + .mv_outb_p = titan_outb_p, + .mv_outw_p = titan_outw, + .mv_outl_p = titan_outl, + + .mv_insl = titan_insl, + .mv_outsl = titan_outsl, + + .mv_ioport_map = titan_ioport_map, + + .mv_init_irq = init_titan_irq, + .mv_init_pci = pcibios_init_platform, +}; +ALIAS_MV(titan) diff --git a/arch/sh/boards/unknown/setup.c b/arch/sh/boards/unknown/setup.c index c5e4ed10876..1c941370a2e 100644 --- a/arch/sh/boards/unknown/setup.c +++ b/arch/sh/boards/unknown/setup.c @@ -14,19 +14,8 @@ */ #include <linux/init.h> #include <asm/machvec.h> -#include <asm/irq.h> struct sh_machine_vector mv_unknown __initmv = { - .mv_nr_irqs = NR_IRQS, + .mv_name = "Unknown", }; ALIAS_MV(unknown) - -const char *get_system_type(void) -{ - return "Unknown"; -} - -void __init platform_setup(void) -{ -} - |