mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-09-08 01:08:03 -04:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
99
arch/arm/mach-footbridge/Kconfig
Normal file
99
arch/arm/mach-footbridge/Kconfig
Normal file
|
@ -0,0 +1,99 @@
|
|||
if ARCH_FOOTBRIDGE
|
||||
|
||||
menu "Footbridge Implementations"
|
||||
|
||||
config ARCH_CATS
|
||||
bool "CATS"
|
||||
select CLKEVT_I8253
|
||||
select CLKSRC_I8253
|
||||
select FOOTBRIDGE_HOST
|
||||
select ISA
|
||||
select ISA_DMA
|
||||
select PCI
|
||||
help
|
||||
Say Y here if you intend to run this kernel on the CATS.
|
||||
|
||||
Saying N will reduce the size of the Footbridge kernel.
|
||||
|
||||
config ARCH_PERSONAL_SERVER
|
||||
bool "Compaq Personal Server"
|
||||
select FOOTBRIDGE_HOST
|
||||
select ISA
|
||||
select ISA_DMA
|
||||
select PCI
|
||||
---help---
|
||||
Say Y here if you intend to run this kernel on the Compaq
|
||||
Personal Server.
|
||||
|
||||
Saying N will reduce the size of the Footbridge kernel.
|
||||
|
||||
The Compaq Personal Server is not available for purchase.
|
||||
There are no product plans beyond the current research
|
||||
prototypes at this time. Information is available at:
|
||||
|
||||
<http://www.crl.hpl.hp.com/projects/personalserver/>
|
||||
|
||||
If you have any questions or comments about the Compaq Personal
|
||||
Server, send e-mail to <skiff@crl.dec.com>.
|
||||
|
||||
config ARCH_EBSA285_ADDIN
|
||||
bool "EBSA285 (addin mode)"
|
||||
select ARCH_EBSA285
|
||||
select FOOTBRIDGE_ADDIN
|
||||
help
|
||||
Say Y here if you intend to run this kernel on the EBSA285 card
|
||||
in addin mode.
|
||||
|
||||
Saying N will reduce the size of the Footbridge kernel.
|
||||
|
||||
config ARCH_EBSA285_HOST
|
||||
bool "EBSA285 (host mode)"
|
||||
select ARCH_EBSA285
|
||||
select FOOTBRIDGE_HOST
|
||||
select ISA
|
||||
select ISA_DMA
|
||||
select ARCH_MAY_HAVE_PC_FDC
|
||||
select PCI
|
||||
help
|
||||
Say Y here if you intend to run this kernel on the EBSA285 card
|
||||
in host ("central function") mode.
|
||||
|
||||
Saying N will reduce the size of the Footbridge kernel.
|
||||
|
||||
config ARCH_NETWINDER
|
||||
bool "NetWinder"
|
||||
select CLKEVT_I8253
|
||||
select CLKSRC_I8253
|
||||
select FOOTBRIDGE_HOST
|
||||
select ISA
|
||||
select ISA_DMA
|
||||
select PCI
|
||||
select VIRT_TO_BUS
|
||||
help
|
||||
Say Y here if you intend to run this kernel on the Rebel.COM
|
||||
NetWinder. Information about this machine can be found at:
|
||||
|
||||
<http://www.netwinder.org/>
|
||||
|
||||
Saying N will reduce the size of the Footbridge kernel.
|
||||
|
||||
endmenu
|
||||
|
||||
# Footbridge support
|
||||
config FOOTBRIDGE
|
||||
bool
|
||||
|
||||
# Footbridge in host mode
|
||||
config FOOTBRIDGE_HOST
|
||||
bool
|
||||
select ARCH_MIGHT_HAVE_PC_SERIO
|
||||
|
||||
# Footbridge in addin mode
|
||||
config FOOTBRIDGE_ADDIN
|
||||
bool
|
||||
|
||||
# EBSA285 board in either host or addin mode
|
||||
config ARCH_EBSA285
|
||||
bool
|
||||
|
||||
endif
|
22
arch/arm/mach-footbridge/Makefile
Normal file
22
arch/arm/mach-footbridge/Makefile
Normal file
|
@ -0,0 +1,22 @@
|
|||
#
|
||||
# Makefile for the linux kernel.
|
||||
#
|
||||
|
||||
# Object file lists.
|
||||
|
||||
obj-y := common.o dma.o isa-irq.o
|
||||
|
||||
pci-y += dc21285.o
|
||||
pci-$(CONFIG_ARCH_CATS) += cats-pci.o
|
||||
pci-$(CONFIG_ARCH_EBSA285_HOST) += ebsa285-pci.o
|
||||
pci-$(CONFIG_ARCH_NETWINDER) += netwinder-pci.o
|
||||
pci-$(CONFIG_ARCH_PERSONAL_SERVER) += personal-pci.o
|
||||
|
||||
obj-$(CONFIG_ARCH_CATS) += cats-hw.o isa-timer.o
|
||||
obj-$(CONFIG_ARCH_EBSA285) += ebsa285.o dc21285-timer.o
|
||||
obj-$(CONFIG_ARCH_NETWINDER) += netwinder-hw.o isa-timer.o
|
||||
obj-$(CONFIG_ARCH_PERSONAL_SERVER) += personal.o dc21285-timer.o
|
||||
|
||||
obj-$(CONFIG_PCI) +=$(pci-y)
|
||||
|
||||
obj-$(CONFIG_ISA) += isa.o isa-rtc.o
|
4
arch/arm/mach-footbridge/Makefile.boot
Normal file
4
arch/arm/mach-footbridge/Makefile.boot
Normal file
|
@ -0,0 +1,4 @@
|
|||
zreladdr-y += 0x00008000
|
||||
params_phys-y := 0x00000100
|
||||
initrd_phys-y := 0x00800000
|
||||
|
97
arch/arm/mach-footbridge/cats-hw.c
Normal file
97
arch/arm/mach-footbridge/cats-hw.c
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-footbridge/cats-hw.c
|
||||
*
|
||||
* CATS machine fixup
|
||||
*
|
||||
* Copyright (C) 1998, 1999 Russell King, Phil Blundell
|
||||
*/
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/screen_info.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <asm/hardware/dec21285.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define CFG_PORT 0x370
|
||||
#define INDEX_PORT (CFG_PORT)
|
||||
#define DATA_PORT (CFG_PORT + 1)
|
||||
|
||||
static int __init cats_hw_init(void)
|
||||
{
|
||||
if (machine_is_cats()) {
|
||||
/* Set Aladdin to CONFIGURE mode */
|
||||
outb(0x51, CFG_PORT);
|
||||
outb(0x23, CFG_PORT);
|
||||
|
||||
/* Select logical device 3 */
|
||||
outb(0x07, INDEX_PORT);
|
||||
outb(0x03, DATA_PORT);
|
||||
|
||||
/* Set parallel port to DMA channel 3, ECP+EPP1.9,
|
||||
enable EPP timeout */
|
||||
outb(0x74, INDEX_PORT);
|
||||
outb(0x03, DATA_PORT);
|
||||
|
||||
outb(0xf0, INDEX_PORT);
|
||||
outb(0x0f, DATA_PORT);
|
||||
|
||||
outb(0xf1, INDEX_PORT);
|
||||
outb(0x07, DATA_PORT);
|
||||
|
||||
/* Select logical device 4 */
|
||||
outb(0x07, INDEX_PORT);
|
||||
outb(0x04, DATA_PORT);
|
||||
|
||||
/* UART1 high speed mode */
|
||||
outb(0xf0, INDEX_PORT);
|
||||
outb(0x02, DATA_PORT);
|
||||
|
||||
/* Select logical device 5 */
|
||||
outb(0x07, INDEX_PORT);
|
||||
outb(0x05, DATA_PORT);
|
||||
|
||||
/* UART2 high speed mode */
|
||||
outb(0xf0, INDEX_PORT);
|
||||
outb(0x02, DATA_PORT);
|
||||
|
||||
/* Set Aladdin to RUN mode */
|
||||
outb(0xbb, CFG_PORT);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__initcall(cats_hw_init);
|
||||
|
||||
/*
|
||||
* CATS uses soft-reboot by default, since
|
||||
* hard reboots fail on early boards.
|
||||
*/
|
||||
static void __init
|
||||
fixup_cats(struct tag *tags, char **cmdline)
|
||||
{
|
||||
#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
|
||||
screen_info.orig_video_lines = 25;
|
||||
screen_info.orig_video_points = 16;
|
||||
screen_info.orig_y = 24;
|
||||
#endif
|
||||
}
|
||||
|
||||
MACHINE_START(CATS, "Chalice-CATS")
|
||||
/* Maintainer: Philip Blundell */
|
||||
.atag_offset = 0x100,
|
||||
.reboot_mode = REBOOT_SOFT,
|
||||
.fixup = fixup_cats,
|
||||
.map_io = footbridge_map_io,
|
||||
.init_irq = footbridge_init_irq,
|
||||
.init_time = isa_timer_init,
|
||||
.restart = footbridge_restart,
|
||||
MACHINE_END
|
63
arch/arm/mach-footbridge/cats-pci.c
Normal file
63
arch/arm/mach-footbridge/cats-pci.c
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-footbridge/cats-pci.c
|
||||
*
|
||||
* PCI bios-type initialisation for PCI machines
|
||||
*
|
||||
* Bits taken from various places.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mach/pci.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
/* cats host-specific stuff */
|
||||
static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 };
|
||||
|
||||
static u8 cats_no_swizzle(struct pci_dev *dev, u8 *pin)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init cats_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
|
||||
{
|
||||
if (dev->irq >= 255)
|
||||
return -1; /* not a valid interrupt. */
|
||||
|
||||
if (dev->irq >= 128)
|
||||
return dev->irq & 0x1f;
|
||||
|
||||
if (dev->irq >= 1 && dev->irq <= 4)
|
||||
return irqmap_cats[dev->irq - 1];
|
||||
|
||||
if (dev->irq != 0)
|
||||
printk("PCI: device %02x:%02x has unknown irq line %x\n",
|
||||
dev->bus->number, dev->devfn, dev->irq);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* why not the standard PCI swizzle? does this prevent 4-port tulip
|
||||
* cards being used (ie, pci-pci bridge based cards)?
|
||||
*/
|
||||
static struct hw_pci cats_pci __initdata = {
|
||||
.swizzle = cats_no_swizzle,
|
||||
.map_irq = cats_map_irq,
|
||||
.nr_controllers = 1,
|
||||
.ops = &dc21285_ops,
|
||||
.setup = dc21285_setup,
|
||||
.preinit = dc21285_preinit,
|
||||
.postinit = dc21285_postinit,
|
||||
};
|
||||
|
||||
static int __init cats_pci_init(void)
|
||||
{
|
||||
if (machine_is_cats())
|
||||
pci_common_init(&cats_pci);
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(cats_pci_init);
|
268
arch/arm/mach-footbridge/common.c
Normal file
268
arch/arm/mach-footbridge/common.c
Normal file
|
@ -0,0 +1,268 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-footbridge/common.c
|
||||
*
|
||||
* Copyright (C) 1998-2000 Russell King, Dave Gilbert.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <video/vga.h>
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/system_misc.h>
|
||||
#include <asm/hardware/dec21285.h>
|
||||
|
||||
#include <asm/mach/irq.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/pci.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
unsigned int mem_fclk_21285 = 50000000;
|
||||
|
||||
EXPORT_SYMBOL(mem_fclk_21285);
|
||||
|
||||
static int __init early_fclk(char *arg)
|
||||
{
|
||||
mem_fclk_21285 = simple_strtoul(arg, NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
early_param("mem_fclk_21285", early_fclk);
|
||||
|
||||
static int __init parse_tag_memclk(const struct tag *tag)
|
||||
{
|
||||
mem_fclk_21285 = tag->u.memclk.fmemclk;
|
||||
return 0;
|
||||
}
|
||||
|
||||
__tagtable(ATAG_MEMCLK, parse_tag_memclk);
|
||||
|
||||
/*
|
||||
* Footbridge IRQ translation table
|
||||
* Converts from our IRQ numbers into FootBridge masks
|
||||
*/
|
||||
static const int fb_irq_mask[] = {
|
||||
IRQ_MASK_UART_RX, /* 0 */
|
||||
IRQ_MASK_UART_TX, /* 1 */
|
||||
IRQ_MASK_TIMER1, /* 2 */
|
||||
IRQ_MASK_TIMER2, /* 3 */
|
||||
IRQ_MASK_TIMER3, /* 4 */
|
||||
IRQ_MASK_IN0, /* 5 */
|
||||
IRQ_MASK_IN1, /* 6 */
|
||||
IRQ_MASK_IN2, /* 7 */
|
||||
IRQ_MASK_IN3, /* 8 */
|
||||
IRQ_MASK_DOORBELLHOST, /* 9 */
|
||||
IRQ_MASK_DMA1, /* 10 */
|
||||
IRQ_MASK_DMA2, /* 11 */
|
||||
IRQ_MASK_PCI, /* 12 */
|
||||
IRQ_MASK_SDRAMPARITY, /* 13 */
|
||||
IRQ_MASK_I2OINPOST, /* 14 */
|
||||
IRQ_MASK_PCI_ABORT, /* 15 */
|
||||
IRQ_MASK_PCI_SERR, /* 16 */
|
||||
IRQ_MASK_DISCARD_TIMER, /* 17 */
|
||||
IRQ_MASK_PCI_DPERR, /* 18 */
|
||||
IRQ_MASK_PCI_PERR, /* 19 */
|
||||
};
|
||||
|
||||
static void fb_mask_irq(struct irq_data *d)
|
||||
{
|
||||
*CSR_IRQ_DISABLE = fb_irq_mask[_DC21285_INR(d->irq)];
|
||||
}
|
||||
|
||||
static void fb_unmask_irq(struct irq_data *d)
|
||||
{
|
||||
*CSR_IRQ_ENABLE = fb_irq_mask[_DC21285_INR(d->irq)];
|
||||
}
|
||||
|
||||
static struct irq_chip fb_chip = {
|
||||
.irq_ack = fb_mask_irq,
|
||||
.irq_mask = fb_mask_irq,
|
||||
.irq_unmask = fb_unmask_irq,
|
||||
};
|
||||
|
||||
static void __init __fb_init_irq(void)
|
||||
{
|
||||
unsigned int irq;
|
||||
|
||||
/*
|
||||
* setup DC21285 IRQs
|
||||
*/
|
||||
*CSR_IRQ_DISABLE = -1;
|
||||
*CSR_FIQ_DISABLE = -1;
|
||||
|
||||
for (irq = _DC21285_IRQ(0); irq < _DC21285_IRQ(20); irq++) {
|
||||
irq_set_chip_and_handler(irq, &fb_chip, handle_level_irq);
|
||||
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
|
||||
}
|
||||
}
|
||||
|
||||
void __init footbridge_init_irq(void)
|
||||
{
|
||||
__fb_init_irq();
|
||||
|
||||
if (!footbridge_cfn_mode())
|
||||
return;
|
||||
|
||||
if (machine_is_ebsa285())
|
||||
/* The following is dependent on which slot
|
||||
* you plug the Southbridge card into. We
|
||||
* currently assume that you plug it into
|
||||
* the right-hand most slot.
|
||||
*/
|
||||
isa_init_irq(IRQ_PCI);
|
||||
|
||||
if (machine_is_cats())
|
||||
isa_init_irq(IRQ_IN2);
|
||||
|
||||
if (machine_is_netwinder())
|
||||
isa_init_irq(IRQ_IN3);
|
||||
}
|
||||
|
||||
/*
|
||||
* Common mapping for all systems. Note that the outbound write flush is
|
||||
* commented out since there is a "No Fix" problem with it. Not mapping
|
||||
* it means that we have extra bullet protection on our feet.
|
||||
*/
|
||||
static struct map_desc fb_common_io_desc[] __initdata = {
|
||||
{
|
||||
.virtual = ARMCSR_BASE,
|
||||
.pfn = __phys_to_pfn(DC21285_ARMCSR_BASE),
|
||||
.length = ARMCSR_SIZE,
|
||||
.type = MT_DEVICE,
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* The mapping when the footbridge is in host mode. We don't map any of
|
||||
* this when we are in add-in mode.
|
||||
*/
|
||||
static struct map_desc ebsa285_host_io_desc[] __initdata = {
|
||||
#if defined(CONFIG_ARCH_FOOTBRIDGE) && defined(CONFIG_FOOTBRIDGE_HOST)
|
||||
{
|
||||
.virtual = PCIMEM_BASE,
|
||||
.pfn = __phys_to_pfn(DC21285_PCI_MEM),
|
||||
.length = PCIMEM_SIZE,
|
||||
.type = MT_DEVICE,
|
||||
}, {
|
||||
.virtual = PCICFG0_BASE,
|
||||
.pfn = __phys_to_pfn(DC21285_PCI_TYPE_0_CONFIG),
|
||||
.length = PCICFG0_SIZE,
|
||||
.type = MT_DEVICE,
|
||||
}, {
|
||||
.virtual = PCICFG1_BASE,
|
||||
.pfn = __phys_to_pfn(DC21285_PCI_TYPE_1_CONFIG),
|
||||
.length = PCICFG1_SIZE,
|
||||
.type = MT_DEVICE,
|
||||
}, {
|
||||
.virtual = PCIIACK_BASE,
|
||||
.pfn = __phys_to_pfn(DC21285_PCI_IACK),
|
||||
.length = PCIIACK_SIZE,
|
||||
.type = MT_DEVICE,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
void __init footbridge_map_io(void)
|
||||
{
|
||||
/*
|
||||
* Set up the common mapping first; we need this to
|
||||
* determine whether we're in host mode or not.
|
||||
*/
|
||||
iotable_init(fb_common_io_desc, ARRAY_SIZE(fb_common_io_desc));
|
||||
|
||||
/*
|
||||
* Now, work out what we've got to map in addition on this
|
||||
* platform.
|
||||
*/
|
||||
if (footbridge_cfn_mode()) {
|
||||
iotable_init(ebsa285_host_io_desc, ARRAY_SIZE(ebsa285_host_io_desc));
|
||||
pci_map_io_early(__phys_to_pfn(DC21285_PCI_IO));
|
||||
}
|
||||
|
||||
vga_base = PCIMEM_BASE;
|
||||
}
|
||||
|
||||
void footbridge_restart(enum reboot_mode mode, const char *cmd)
|
||||
{
|
||||
if (mode == REBOOT_SOFT) {
|
||||
/* Jump into the ROM */
|
||||
soft_restart(0x41000000);
|
||||
} else {
|
||||
/*
|
||||
* Force the watchdog to do a CPU reset.
|
||||
*
|
||||
* After making sure that the watchdog is disabled
|
||||
* (so we can change the timer registers) we first
|
||||
* enable the timer to autoreload itself. Next, the
|
||||
* timer interval is set really short and any
|
||||
* current interrupt request is cleared (so we can
|
||||
* see an edge transition). Finally, TIMER4 is
|
||||
* enabled as the watchdog.
|
||||
*/
|
||||
*CSR_SA110_CNTL &= ~(1 << 13);
|
||||
*CSR_TIMER4_CNTL = TIMER_CNTL_ENABLE |
|
||||
TIMER_CNTL_AUTORELOAD |
|
||||
TIMER_CNTL_DIV16;
|
||||
*CSR_TIMER4_LOAD = 0x2;
|
||||
*CSR_TIMER4_CLR = 0;
|
||||
*CSR_SA110_CNTL |= (1 << 13);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FOOTBRIDGE_ADDIN
|
||||
|
||||
static inline unsigned long fb_bus_sdram_offset(void)
|
||||
{
|
||||
return *CSR_PCISDRAMBASE & 0xfffffff0;
|
||||
}
|
||||
|
||||
/*
|
||||
* These two functions convert virtual addresses to PCI addresses and PCI
|
||||
* addresses to virtual addresses. Note that it is only legal to use these
|
||||
* on memory obtained via get_zeroed_page or kmalloc.
|
||||
*/
|
||||
unsigned long __virt_to_bus(unsigned long res)
|
||||
{
|
||||
WARN_ON(res < PAGE_OFFSET || res >= (unsigned long)high_memory);
|
||||
|
||||
return res + (fb_bus_sdram_offset() - PAGE_OFFSET);
|
||||
}
|
||||
EXPORT_SYMBOL(__virt_to_bus);
|
||||
|
||||
unsigned long __bus_to_virt(unsigned long res)
|
||||
{
|
||||
res = res - (fb_bus_sdram_offset() - PAGE_OFFSET);
|
||||
|
||||
WARN_ON(res < PAGE_OFFSET || res >= (unsigned long)high_memory);
|
||||
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL(__bus_to_virt);
|
||||
|
||||
unsigned long __pfn_to_bus(unsigned long pfn)
|
||||
{
|
||||
return __pfn_to_phys(pfn) + (fb_bus_sdram_offset() - PHYS_OFFSET);
|
||||
}
|
||||
EXPORT_SYMBOL(__pfn_to_bus);
|
||||
|
||||
unsigned long __bus_to_pfn(unsigned long bus)
|
||||
{
|
||||
return __phys_to_pfn(bus - (fb_bus_sdram_offset() - PHYS_OFFSET));
|
||||
}
|
||||
EXPORT_SYMBOL(__bus_to_pfn);
|
||||
|
||||
#endif
|
14
arch/arm/mach-footbridge/common.h
Normal file
14
arch/arm/mach-footbridge/common.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#include <linux/reboot.h>
|
||||
|
||||
extern void footbridge_timer_init(void);
|
||||
extern void isa_timer_init(void);
|
||||
|
||||
extern void isa_rtc_init(void);
|
||||
|
||||
extern void footbridge_map_io(void);
|
||||
extern void footbridge_init_irq(void);
|
||||
|
||||
extern void isa_init_irq(unsigned int irq);
|
||||
extern void footbridge_restart(enum reboot_mode, const char *);
|
||||
|
||||
extern void footbridge_sched_clock(void);
|
142
arch/arm/mach-footbridge/dc21285-timer.c
Normal file
142
arch/arm/mach-footbridge/dc21285-timer.c
Normal file
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-footbridge/dc21285-timer.c
|
||||
*
|
||||
* Copyright (C) 1998 Russell King.
|
||||
* Copyright (C) 1998 Phil Blundell
|
||||
*/
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/sched_clock.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
|
||||
#include <asm/hardware/dec21285.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <asm/system_info.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
static cycle_t cksrc_dc21285_read(struct clocksource *cs)
|
||||
{
|
||||
return cs->mask - *CSR_TIMER2_VALUE;
|
||||
}
|
||||
|
||||
static int cksrc_dc21285_enable(struct clocksource *cs)
|
||||
{
|
||||
*CSR_TIMER2_LOAD = cs->mask;
|
||||
*CSR_TIMER2_CLR = 0;
|
||||
*CSR_TIMER2_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV16;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cksrc_dc21285_disable(struct clocksource *cs)
|
||||
{
|
||||
*CSR_TIMER2_CNTL = 0;
|
||||
}
|
||||
|
||||
static struct clocksource cksrc_dc21285 = {
|
||||
.name = "dc21285_timer2",
|
||||
.rating = 200,
|
||||
.read = cksrc_dc21285_read,
|
||||
.enable = cksrc_dc21285_enable,
|
||||
.disable = cksrc_dc21285_disable,
|
||||
.mask = CLOCKSOURCE_MASK(24),
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
};
|
||||
|
||||
static int ckevt_dc21285_set_next_event(unsigned long delta,
|
||||
struct clock_event_device *c)
|
||||
{
|
||||
*CSR_TIMER1_CLR = 0;
|
||||
*CSR_TIMER1_LOAD = delta;
|
||||
*CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV16;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ckevt_dc21285_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *c)
|
||||
{
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_RESUME:
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
*CSR_TIMER1_CLR = 0;
|
||||
*CSR_TIMER1_LOAD = (mem_fclk_21285 + 8 * HZ) / (16 * HZ);
|
||||
*CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD |
|
||||
TIMER_CNTL_DIV16;
|
||||
break;
|
||||
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
*CSR_TIMER1_CNTL = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct clock_event_device ckevt_dc21285 = {
|
||||
.name = "dc21285_timer1",
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC |
|
||||
CLOCK_EVT_FEAT_ONESHOT,
|
||||
.rating = 200,
|
||||
.irq = IRQ_TIMER1,
|
||||
.set_next_event = ckevt_dc21285_set_next_event,
|
||||
.set_mode = ckevt_dc21285_set_mode,
|
||||
};
|
||||
|
||||
static irqreturn_t timer1_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct clock_event_device *ce = dev_id;
|
||||
|
||||
*CSR_TIMER1_CLR = 0;
|
||||
|
||||
/* Stop the timer if in one-shot mode */
|
||||
if (ce->mode == CLOCK_EVT_MODE_ONESHOT)
|
||||
*CSR_TIMER1_CNTL = 0;
|
||||
|
||||
ce->event_handler(ce);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction footbridge_timer_irq = {
|
||||
.name = "dc21285_timer1",
|
||||
.handler = timer1_interrupt,
|
||||
.flags = IRQF_TIMER | IRQF_IRQPOLL,
|
||||
.dev_id = &ckevt_dc21285,
|
||||
};
|
||||
|
||||
/*
|
||||
* Set up timer interrupt.
|
||||
*/
|
||||
void __init footbridge_timer_init(void)
|
||||
{
|
||||
struct clock_event_device *ce = &ckevt_dc21285;
|
||||
unsigned rate = DIV_ROUND_CLOSEST(mem_fclk_21285, 16);
|
||||
|
||||
clocksource_register_hz(&cksrc_dc21285, rate);
|
||||
|
||||
setup_irq(ce->irq, &footbridge_timer_irq);
|
||||
|
||||
ce->cpumask = cpumask_of(smp_processor_id());
|
||||
clockevents_config_and_register(ce, rate, 0x4, 0xffffff);
|
||||
}
|
||||
|
||||
static u64 notrace footbridge_read_sched_clock(void)
|
||||
{
|
||||
return ~*CSR_TIMER3_VALUE;
|
||||
}
|
||||
|
||||
void __init footbridge_sched_clock(void)
|
||||
{
|
||||
unsigned rate = DIV_ROUND_CLOSEST(mem_fclk_21285, 16);
|
||||
|
||||
*CSR_TIMER3_LOAD = 0;
|
||||
*CSR_TIMER3_CLR = 0;
|
||||
*CSR_TIMER3_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV16;
|
||||
|
||||
sched_clock_register(footbridge_read_sched_clock, 24, rate);
|
||||
}
|
376
arch/arm/mach-footbridge/dc21285.c
Normal file
376
arch/arm/mach-footbridge/dc21285.c
Normal file
|
@ -0,0 +1,376 @@
|
|||
/*
|
||||
* linux/arch/arm/kernel/dec21285.c: PCI functions for DC21285
|
||||
*
|
||||
* Copyright (C) 1998-2001 Russell King
|
||||
* Copyright (C) 1998-2000 Phil Blundell
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mach/pci.h>
|
||||
#include <asm/hardware/dec21285.h>
|
||||
|
||||
#define MAX_SLOTS 21
|
||||
|
||||
#define PCICMD_ABORT ((PCI_STATUS_REC_MASTER_ABORT| \
|
||||
PCI_STATUS_REC_TARGET_ABORT)<<16)
|
||||
|
||||
#define PCICMD_ERROR_BITS ((PCI_STATUS_DETECTED_PARITY | \
|
||||
PCI_STATUS_REC_MASTER_ABORT | \
|
||||
PCI_STATUS_REC_TARGET_ABORT | \
|
||||
PCI_STATUS_PARITY) << 16)
|
||||
|
||||
extern int setup_arm_irq(int, struct irqaction *);
|
||||
extern void pcibios_report_status(u_int status_mask, int warn);
|
||||
|
||||
static unsigned long
|
||||
dc21285_base_address(struct pci_bus *bus, unsigned int devfn)
|
||||
{
|
||||
unsigned long addr = 0;
|
||||
|
||||
if (bus->number == 0) {
|
||||
if (PCI_SLOT(devfn) == 0)
|
||||
/*
|
||||
* For devfn 0, point at the 21285
|
||||
*/
|
||||
addr = ARMCSR_BASE;
|
||||
else {
|
||||
devfn -= 1 << 3;
|
||||
|
||||
if (devfn < PCI_DEVFN(MAX_SLOTS, 0))
|
||||
addr = PCICFG0_BASE | 0xc00000 | (devfn << 8);
|
||||
}
|
||||
} else
|
||||
addr = PCICFG1_BASE | (bus->number << 16) | (devfn << 8);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
static int
|
||||
dc21285_read_config(struct pci_bus *bus, unsigned int devfn, int where,
|
||||
int size, u32 *value)
|
||||
{
|
||||
unsigned long addr = dc21285_base_address(bus, devfn);
|
||||
u32 v = 0xffffffff;
|
||||
|
||||
if (addr)
|
||||
switch (size) {
|
||||
case 1:
|
||||
asm("ldrb %0, [%1, %2]"
|
||||
: "=r" (v) : "r" (addr), "r" (where) : "cc");
|
||||
break;
|
||||
case 2:
|
||||
asm("ldrh %0, [%1, %2]"
|
||||
: "=r" (v) : "r" (addr), "r" (where) : "cc");
|
||||
break;
|
||||
case 4:
|
||||
asm("ldr %0, [%1, %2]"
|
||||
: "=r" (v) : "r" (addr), "r" (where) : "cc");
|
||||
break;
|
||||
}
|
||||
|
||||
*value = v;
|
||||
|
||||
v = *CSR_PCICMD;
|
||||
if (v & PCICMD_ABORT) {
|
||||
*CSR_PCICMD = v & (0xffff|PCICMD_ABORT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int
|
||||
dc21285_write_config(struct pci_bus *bus, unsigned int devfn, int where,
|
||||
int size, u32 value)
|
||||
{
|
||||
unsigned long addr = dc21285_base_address(bus, devfn);
|
||||
u32 v;
|
||||
|
||||
if (addr)
|
||||
switch (size) {
|
||||
case 1:
|
||||
asm("strb %0, [%1, %2]"
|
||||
: : "r" (value), "r" (addr), "r" (where)
|
||||
: "cc");
|
||||
break;
|
||||
case 2:
|
||||
asm("strh %0, [%1, %2]"
|
||||
: : "r" (value), "r" (addr), "r" (where)
|
||||
: "cc");
|
||||
break;
|
||||
case 4:
|
||||
asm("str %0, [%1, %2]"
|
||||
: : "r" (value), "r" (addr), "r" (where)
|
||||
: "cc");
|
||||
break;
|
||||
}
|
||||
|
||||
v = *CSR_PCICMD;
|
||||
if (v & PCICMD_ABORT) {
|
||||
*CSR_PCICMD = v & (0xffff|PCICMD_ABORT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
struct pci_ops dc21285_ops = {
|
||||
.read = dc21285_read_config,
|
||||
.write = dc21285_write_config,
|
||||
};
|
||||
|
||||
static struct timer_list serr_timer;
|
||||
static struct timer_list perr_timer;
|
||||
|
||||
static void dc21285_enable_error(unsigned long __data)
|
||||
{
|
||||
switch (__data) {
|
||||
case IRQ_PCI_SERR:
|
||||
del_timer(&serr_timer);
|
||||
break;
|
||||
|
||||
case IRQ_PCI_PERR:
|
||||
del_timer(&perr_timer);
|
||||
break;
|
||||
}
|
||||
|
||||
enable_irq(__data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Warn on PCI errors.
|
||||
*/
|
||||
static irqreturn_t dc21285_abort_irq(int irq, void *dev_id)
|
||||
{
|
||||
unsigned int cmd;
|
||||
unsigned int status;
|
||||
|
||||
cmd = *CSR_PCICMD;
|
||||
status = cmd >> 16;
|
||||
cmd = cmd & 0xffff;
|
||||
|
||||
if (status & PCI_STATUS_REC_MASTER_ABORT) {
|
||||
printk(KERN_DEBUG "PCI: master abort, pc=0x%08lx\n",
|
||||
instruction_pointer(get_irq_regs()));
|
||||
cmd |= PCI_STATUS_REC_MASTER_ABORT << 16;
|
||||
}
|
||||
|
||||
if (status & PCI_STATUS_REC_TARGET_ABORT) {
|
||||
printk(KERN_DEBUG "PCI: target abort: ");
|
||||
pcibios_report_status(PCI_STATUS_REC_MASTER_ABORT |
|
||||
PCI_STATUS_SIG_TARGET_ABORT |
|
||||
PCI_STATUS_REC_TARGET_ABORT, 1);
|
||||
printk("\n");
|
||||
|
||||
cmd |= PCI_STATUS_REC_TARGET_ABORT << 16;
|
||||
}
|
||||
|
||||
*CSR_PCICMD = cmd;
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t dc21285_serr_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct timer_list *timer = dev_id;
|
||||
unsigned int cntl;
|
||||
|
||||
printk(KERN_DEBUG "PCI: system error received: ");
|
||||
pcibios_report_status(PCI_STATUS_SIG_SYSTEM_ERROR, 1);
|
||||
printk("\n");
|
||||
|
||||
cntl = *CSR_SA110_CNTL & 0xffffdf07;
|
||||
*CSR_SA110_CNTL = cntl | SA110_CNTL_RXSERR;
|
||||
|
||||
/*
|
||||
* back off this interrupt
|
||||
*/
|
||||
disable_irq(irq);
|
||||
timer->expires = jiffies + HZ;
|
||||
add_timer(timer);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t dc21285_discard_irq(int irq, void *dev_id)
|
||||
{
|
||||
printk(KERN_DEBUG "PCI: discard timer expired\n");
|
||||
*CSR_SA110_CNTL &= 0xffffde07;
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t dc21285_dparity_irq(int irq, void *dev_id)
|
||||
{
|
||||
unsigned int cmd;
|
||||
|
||||
printk(KERN_DEBUG "PCI: data parity error detected: ");
|
||||
pcibios_report_status(PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY, 1);
|
||||
printk("\n");
|
||||
|
||||
cmd = *CSR_PCICMD & 0xffff;
|
||||
*CSR_PCICMD = cmd | 1 << 24;
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t dc21285_parity_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct timer_list *timer = dev_id;
|
||||
unsigned int cmd;
|
||||
|
||||
printk(KERN_DEBUG "PCI: parity error detected: ");
|
||||
pcibios_report_status(PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY, 1);
|
||||
printk("\n");
|
||||
|
||||
cmd = *CSR_PCICMD & 0xffff;
|
||||
*CSR_PCICMD = cmd | 1 << 31;
|
||||
|
||||
/*
|
||||
* back off this interrupt
|
||||
*/
|
||||
disable_irq(irq);
|
||||
timer->expires = jiffies + HZ;
|
||||
add_timer(timer);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
int __init dc21285_setup(int nr, struct pci_sys_data *sys)
|
||||
{
|
||||
struct resource *res;
|
||||
|
||||
if (nr || !footbridge_cfn_mode())
|
||||
return 0;
|
||||
|
||||
res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
|
||||
if (!res) {
|
||||
printk("out of memory for root bus resources");
|
||||
return 0;
|
||||
}
|
||||
|
||||
res[0].flags = IORESOURCE_MEM;
|
||||
res[0].name = "Footbridge non-prefetch";
|
||||
res[1].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
|
||||
res[1].name = "Footbridge prefetch";
|
||||
|
||||
allocate_resource(&iomem_resource, &res[1], 0x20000000,
|
||||
0xa0000000, 0xffffffff, 0x20000000, NULL, NULL);
|
||||
allocate_resource(&iomem_resource, &res[0], 0x40000000,
|
||||
0x80000000, 0xffffffff, 0x40000000, NULL, NULL);
|
||||
|
||||
sys->mem_offset = DC21285_PCI_MEM;
|
||||
|
||||
pci_add_resource_offset(&sys->resources, &res[0], sys->mem_offset);
|
||||
pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define dc21285_request_irq(_a, _b, _c, _d, _e) \
|
||||
WARN_ON(request_irq(_a, _b, _c, _d, _e) < 0)
|
||||
|
||||
void __init dc21285_preinit(void)
|
||||
{
|
||||
unsigned int mem_size, mem_mask;
|
||||
int cfn_mode;
|
||||
|
||||
pcibios_min_mem = 0x81000000;
|
||||
|
||||
mem_size = (unsigned int)high_memory - PAGE_OFFSET;
|
||||
for (mem_mask = 0x00100000; mem_mask < 0x10000000; mem_mask <<= 1)
|
||||
if (mem_mask >= mem_size)
|
||||
break;
|
||||
|
||||
/*
|
||||
* These registers need to be set up whether we're the
|
||||
* central function or not.
|
||||
*/
|
||||
*CSR_SDRAMBASEMASK = (mem_mask - 1) & 0x0ffc0000;
|
||||
*CSR_SDRAMBASEOFFSET = 0;
|
||||
*CSR_ROMBASEMASK = 0x80000000;
|
||||
*CSR_CSRBASEMASK = 0;
|
||||
*CSR_CSRBASEOFFSET = 0;
|
||||
*CSR_PCIADDR_EXTN = 0;
|
||||
|
||||
cfn_mode = __footbridge_cfn_mode();
|
||||
|
||||
printk(KERN_INFO "PCI: DC21285 footbridge, revision %02lX, in "
|
||||
"%s mode\n", *CSR_CLASSREV & 0xff, cfn_mode ?
|
||||
"central function" : "addin");
|
||||
|
||||
if (footbridge_cfn_mode()) {
|
||||
/*
|
||||
* Clear any existing errors - we aren't
|
||||
* interested in historical data...
|
||||
*/
|
||||
*CSR_SA110_CNTL = (*CSR_SA110_CNTL & 0xffffde07) |
|
||||
SA110_CNTL_RXSERR;
|
||||
*CSR_PCICMD = (*CSR_PCICMD & 0xffff) | PCICMD_ERROR_BITS;
|
||||
}
|
||||
|
||||
init_timer(&serr_timer);
|
||||
init_timer(&perr_timer);
|
||||
|
||||
serr_timer.data = IRQ_PCI_SERR;
|
||||
serr_timer.function = dc21285_enable_error;
|
||||
perr_timer.data = IRQ_PCI_PERR;
|
||||
perr_timer.function = dc21285_enable_error;
|
||||
|
||||
/*
|
||||
* We don't care if these fail.
|
||||
*/
|
||||
dc21285_request_irq(IRQ_PCI_SERR, dc21285_serr_irq, 0,
|
||||
"PCI system error", &serr_timer);
|
||||
dc21285_request_irq(IRQ_PCI_PERR, dc21285_parity_irq, 0,
|
||||
"PCI parity error", &perr_timer);
|
||||
dc21285_request_irq(IRQ_PCI_ABORT, dc21285_abort_irq, 0,
|
||||
"PCI abort", NULL);
|
||||
dc21285_request_irq(IRQ_DISCARD_TIMER, dc21285_discard_irq, 0,
|
||||
"Discard timer", NULL);
|
||||
dc21285_request_irq(IRQ_PCI_DPERR, dc21285_dparity_irq, 0,
|
||||
"PCI data parity", NULL);
|
||||
|
||||
if (cfn_mode) {
|
||||
/*
|
||||
* Map our SDRAM at a known address in PCI space, just in case
|
||||
* the firmware had other ideas. Using a nonzero base is
|
||||
* necessary, since some VGA cards forcefully use PCI addresses
|
||||
* in the range 0x000a0000 to 0x000c0000. (eg, S3 cards).
|
||||
*/
|
||||
*CSR_PCICSRBASE = 0xf4000000;
|
||||
*CSR_PCICSRIOBASE = 0;
|
||||
*CSR_PCISDRAMBASE = __virt_to_bus(PAGE_OFFSET);
|
||||
*CSR_PCIROMBASE = 0;
|
||||
*CSR_PCICMD = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
|
||||
PCI_COMMAND_INVALIDATE | PCICMD_ERROR_BITS;
|
||||
} else if (footbridge_cfn_mode() != 0) {
|
||||
/*
|
||||
* If we are not compiled to accept "add-in" mode, then
|
||||
* we are using a constant virt_to_bus translation which
|
||||
* can not hope to cater for the way the host BIOS has
|
||||
* set up the machine.
|
||||
*/
|
||||
panic("PCI: this kernel is compiled for central "
|
||||
"function mode only");
|
||||
}
|
||||
}
|
||||
|
||||
void __init dc21285_postinit(void)
|
||||
{
|
||||
register_isa_ports(DC21285_PCI_MEM, DC21285_PCI_IO, 0);
|
||||
}
|
57
arch/arm/mach-footbridge/dma.c
Normal file
57
arch/arm/mach-footbridge/dma.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* linux/arch/arm/kernel/dma-ebsa285.c
|
||||
*
|
||||
* Copyright (C) 1998 Phil Blundell
|
||||
*
|
||||
* DMA functions specific to EBSA-285/CATS architectures
|
||||
*
|
||||
* Changelog:
|
||||
* 09-Nov-1998 RMK Split out ISA DMA functions to dma-isa.c
|
||||
* 17-Mar-1999 RMK Allow any EBSA285-like architecture to have
|
||||
* ISA DMA controllers.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <asm/dma.h>
|
||||
#include <asm/scatterlist.h>
|
||||
|
||||
#include <asm/mach/dma.h>
|
||||
#include <asm/hardware/dec21285.h>
|
||||
|
||||
#if 0
|
||||
static int fb_dma_request(unsigned int chan, dma_t *dma)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void fb_dma_enable(unsigned int chan, dma_t *dma)
|
||||
{
|
||||
}
|
||||
|
||||
static void fb_dma_disable(unsigned int chan, dma_t *dma)
|
||||
{
|
||||
}
|
||||
|
||||
static struct dma_ops fb_dma_ops = {
|
||||
.type = "fb",
|
||||
.request = fb_dma_request,
|
||||
.enable = fb_dma_enable,
|
||||
.disable = fb_dma_disable,
|
||||
};
|
||||
#endif
|
||||
|
||||
static int __init fb_dma_init(void)
|
||||
{
|
||||
#if 0
|
||||
dma[_DC21285_DMA(0)].d_ops = &fb_dma_ops;
|
||||
dma[_DC21285_DMA(1)].d_ops = &fb_dma_ops;
|
||||
#endif
|
||||
#ifdef CONFIG_ISA_DMA
|
||||
if (footbridge_cfn_mode())
|
||||
isa_init_dma();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
core_initcall(fb_dma_init);
|
47
arch/arm/mach-footbridge/ebsa285-pci.c
Normal file
47
arch/arm/mach-footbridge/ebsa285-pci.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-footbridge/ebsa285-pci.c
|
||||
*
|
||||
* PCI bios-type initialisation for PCI machines
|
||||
*
|
||||
* Bits taken from various places.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mach/pci.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
static int irqmap_ebsa285[] __initdata = { IRQ_IN3, IRQ_IN1, IRQ_IN0, IRQ_PCI };
|
||||
|
||||
static int __init ebsa285_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
|
||||
{
|
||||
if (dev->vendor == PCI_VENDOR_ID_CONTAQ &&
|
||||
dev->device == PCI_DEVICE_ID_CONTAQ_82C693)
|
||||
switch (PCI_FUNC(dev->devfn)) {
|
||||
case 1: return 14;
|
||||
case 2: return 15;
|
||||
case 3: return 12;
|
||||
}
|
||||
|
||||
return irqmap_ebsa285[(slot + pin) & 3];
|
||||
}
|
||||
|
||||
static struct hw_pci ebsa285_pci __initdata = {
|
||||
.map_irq = ebsa285_map_irq,
|
||||
.nr_controllers = 1,
|
||||
.ops = &dc21285_ops,
|
||||
.setup = dc21285_setup,
|
||||
.preinit = dc21285_preinit,
|
||||
.postinit = dc21285_postinit,
|
||||
};
|
||||
|
||||
static int __init ebsa285_init_pci(void)
|
||||
{
|
||||
if (machine_is_ebsa285())
|
||||
pci_common_init(&ebsa285_pci);
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(ebsa285_init_pci);
|
123
arch/arm/mach-footbridge/ebsa285.c
Normal file
123
arch/arm/mach-footbridge/ebsa285.c
Normal file
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-footbridge/ebsa285.c
|
||||
*
|
||||
* EBSA285 machine fixup
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/leds.h>
|
||||
|
||||
#include <asm/hardware/dec21285.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/* LEDs */
|
||||
#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
|
||||
#define XBUS_AMBER_L BIT(0)
|
||||
#define XBUS_GREEN_L BIT(1)
|
||||
#define XBUS_RED_L BIT(2)
|
||||
#define XBUS_TOGGLE BIT(7)
|
||||
|
||||
struct ebsa285_led {
|
||||
struct led_classdev cdev;
|
||||
u8 mask;
|
||||
};
|
||||
|
||||
/*
|
||||
* The triggers lines up below will only be used if the
|
||||
* LED triggers are compiled in.
|
||||
*/
|
||||
static const struct {
|
||||
const char *name;
|
||||
const char *trigger;
|
||||
} ebsa285_leds[] = {
|
||||
{ "ebsa285:amber", "cpu0", },
|
||||
{ "ebsa285:green", "heartbeat", },
|
||||
{ "ebsa285:red",},
|
||||
};
|
||||
|
||||
static unsigned char hw_led_state;
|
||||
static void __iomem *xbus;
|
||||
|
||||
static void ebsa285_led_set(struct led_classdev *cdev,
|
||||
enum led_brightness b)
|
||||
{
|
||||
struct ebsa285_led *led = container_of(cdev,
|
||||
struct ebsa285_led, cdev);
|
||||
|
||||
if (b == LED_OFF)
|
||||
hw_led_state |= led->mask;
|
||||
else
|
||||
hw_led_state &= ~led->mask;
|
||||
writeb(hw_led_state, xbus);
|
||||
}
|
||||
|
||||
static enum led_brightness ebsa285_led_get(struct led_classdev *cdev)
|
||||
{
|
||||
struct ebsa285_led *led = container_of(cdev,
|
||||
struct ebsa285_led, cdev);
|
||||
|
||||
return hw_led_state & led->mask ? LED_OFF : LED_FULL;
|
||||
}
|
||||
|
||||
static int __init ebsa285_leds_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!machine_is_ebsa285())
|
||||
return -ENODEV;
|
||||
|
||||
xbus = ioremap(XBUS_CS2, SZ_4K);
|
||||
if (!xbus)
|
||||
return -ENOMEM;
|
||||
|
||||
/* 3 LEDS all off */
|
||||
hw_led_state = XBUS_AMBER_L | XBUS_GREEN_L | XBUS_RED_L;
|
||||
writeb(hw_led_state, xbus);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ebsa285_leds); i++) {
|
||||
struct ebsa285_led *led;
|
||||
|
||||
led = kzalloc(sizeof(*led), GFP_KERNEL);
|
||||
if (!led)
|
||||
break;
|
||||
|
||||
led->cdev.name = ebsa285_leds[i].name;
|
||||
led->cdev.brightness_set = ebsa285_led_set;
|
||||
led->cdev.brightness_get = ebsa285_led_get;
|
||||
led->cdev.default_trigger = ebsa285_leds[i].trigger;
|
||||
led->mask = BIT(i);
|
||||
|
||||
if (led_classdev_register(NULL, &led->cdev) < 0) {
|
||||
kfree(led);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since we may have triggers on any subsystem, defer registration
|
||||
* until after subsystem_init.
|
||||
*/
|
||||
fs_initcall(ebsa285_leds_init);
|
||||
#endif
|
||||
|
||||
MACHINE_START(EBSA285, "EBSA285")
|
||||
/* Maintainer: Russell King */
|
||||
.atag_offset = 0x100,
|
||||
.video_start = 0x000a0000,
|
||||
.video_end = 0x000bffff,
|
||||
.map_io = footbridge_map_io,
|
||||
.init_early = footbridge_sched_clock,
|
||||
.init_irq = footbridge_init_irq,
|
||||
.init_time = footbridge_timer_init,
|
||||
.restart = footbridge_restart,
|
||||
MACHINE_END
|
||||
|
42
arch/arm/mach-footbridge/include/mach/debug-macro.S
Normal file
42
arch/arm/mach-footbridge/include/mach/debug-macro.S
Normal file
|
@ -0,0 +1,42 @@
|
|||
/* arch/arm/mach-footbridge/include/mach/debug-macro.S
|
||||
*
|
||||
* Debugging macro include header
|
||||
*
|
||||
* Copyright (C) 1994-1999 Russell King
|
||||
* Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <asm/hardware/dec21285.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
/* For EBSA285 debugging */
|
||||
.equ dc21285_high, ARMCSR_BASE & 0xff000000
|
||||
.equ dc21285_low, ARMCSR_BASE & 0x00ffffff
|
||||
|
||||
.macro addruart, rp, rv, tmp
|
||||
.if dc21285_low
|
||||
mov \rp, #dc21285_low
|
||||
.else
|
||||
mov \rp, #0
|
||||
.endif
|
||||
orr \rv, \rp, #dc21285_high
|
||||
orr \rp, \rp, #0x42000000
|
||||
.endm
|
||||
|
||||
.macro senduart,rd,rx
|
||||
str \rd, [\rx, #0x160] @ UARTDR
|
||||
.endm
|
||||
|
||||
.macro busyuart,rd,rx
|
||||
1001: ldr \rd, [\rx, #0x178] @ UARTFLG
|
||||
tst \rd, #1 << 3
|
||||
bne 1001b
|
||||
.endm
|
||||
|
||||
.macro waituart,rd,rx
|
||||
.endm
|
107
arch/arm/mach-footbridge/include/mach/entry-macro.S
Normal file
107
arch/arm/mach-footbridge/include/mach/entry-macro.S
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* arch/arm/mach-footbridge/include/mach/entry-macro.S
|
||||
*
|
||||
* Low-level IRQ helper macros for footbridge-based platforms
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <asm/hardware/dec21285.h>
|
||||
|
||||
.equ dc21285_high, ARMCSR_BASE & 0xff000000
|
||||
.equ dc21285_low, ARMCSR_BASE & 0x00ffffff
|
||||
|
||||
.macro get_irqnr_preamble, base, tmp
|
||||
mov \base, #dc21285_high
|
||||
.if dc21285_low
|
||||
orr \base, \base, #dc21285_low
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
|
||||
ldr \irqstat, [\base, #0x180] @ get interrupts
|
||||
|
||||
mov \irqnr, #IRQ_SDRAMPARITY
|
||||
tst \irqstat, #IRQ_MASK_SDRAMPARITY
|
||||
bne 1001f
|
||||
|
||||
tst \irqstat, #IRQ_MASK_UART_RX
|
||||
movne \irqnr, #IRQ_CONRX
|
||||
bne 1001f
|
||||
|
||||
tst \irqstat, #IRQ_MASK_DMA1
|
||||
movne \irqnr, #IRQ_DMA1
|
||||
bne 1001f
|
||||
|
||||
tst \irqstat, #IRQ_MASK_DMA2
|
||||
movne \irqnr, #IRQ_DMA2
|
||||
bne 1001f
|
||||
|
||||
tst \irqstat, #IRQ_MASK_IN0
|
||||
movne \irqnr, #IRQ_IN0
|
||||
bne 1001f
|
||||
|
||||
tst \irqstat, #IRQ_MASK_IN1
|
||||
movne \irqnr, #IRQ_IN1
|
||||
bne 1001f
|
||||
|
||||
tst \irqstat, #IRQ_MASK_IN2
|
||||
movne \irqnr, #IRQ_IN2
|
||||
bne 1001f
|
||||
|
||||
tst \irqstat, #IRQ_MASK_IN3
|
||||
movne \irqnr, #IRQ_IN3
|
||||
bne 1001f
|
||||
|
||||
tst \irqstat, #IRQ_MASK_PCI
|
||||
movne \irqnr, #IRQ_PCI
|
||||
bne 1001f
|
||||
|
||||
tst \irqstat, #IRQ_MASK_DOORBELLHOST
|
||||
movne \irqnr, #IRQ_DOORBELLHOST
|
||||
bne 1001f
|
||||
|
||||
tst \irqstat, #IRQ_MASK_I2OINPOST
|
||||
movne \irqnr, #IRQ_I2OINPOST
|
||||
bne 1001f
|
||||
|
||||
tst \irqstat, #IRQ_MASK_TIMER1
|
||||
movne \irqnr, #IRQ_TIMER1
|
||||
bne 1001f
|
||||
|
||||
tst \irqstat, #IRQ_MASK_TIMER2
|
||||
movne \irqnr, #IRQ_TIMER2
|
||||
bne 1001f
|
||||
|
||||
tst \irqstat, #IRQ_MASK_TIMER3
|
||||
movne \irqnr, #IRQ_TIMER3
|
||||
bne 1001f
|
||||
|
||||
tst \irqstat, #IRQ_MASK_UART_TX
|
||||
movne \irqnr, #IRQ_CONTX
|
||||
bne 1001f
|
||||
|
||||
tst \irqstat, #IRQ_MASK_PCI_ABORT
|
||||
movne \irqnr, #IRQ_PCI_ABORT
|
||||
bne 1001f
|
||||
|
||||
tst \irqstat, #IRQ_MASK_PCI_SERR
|
||||
movne \irqnr, #IRQ_PCI_SERR
|
||||
bne 1001f
|
||||
|
||||
tst \irqstat, #IRQ_MASK_DISCARD_TIMER
|
||||
movne \irqnr, #IRQ_DISCARD_TIMER
|
||||
bne 1001f
|
||||
|
||||
tst \irqstat, #IRQ_MASK_PCI_DPERR
|
||||
movne \irqnr, #IRQ_PCI_DPERR
|
||||
bne 1001f
|
||||
|
||||
tst \irqstat, #IRQ_MASK_PCI_PERR
|
||||
movne \irqnr, #IRQ_PCI_PERR
|
||||
1001:
|
||||
.endm
|
||||
|
99
arch/arm/mach-footbridge/include/mach/hardware.h
Normal file
99
arch/arm/mach-footbridge/include/mach/hardware.h
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* arch/arm/mach-footbridge/include/mach/hardware.h
|
||||
*
|
||||
* Copyright (C) 1998-1999 Russell King.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This file contains the hardware definitions of the EBSA-285.
|
||||
*/
|
||||
#ifndef __ASM_ARCH_HARDWARE_H
|
||||
#define __ASM_ARCH_HARDWARE_H
|
||||
|
||||
/* Virtual Physical Size
|
||||
* 0xff800000 0x40000000 1MB X-Bus
|
||||
* 0xff000000 0x7c000000 1MB PCI I/O space
|
||||
* 0xfe000000 0x42000000 1MB CSR
|
||||
* 0xfd000000 0x78000000 1MB Outbound write flush (not supported)
|
||||
* 0xfc000000 0x79000000 1MB PCI IACK/special space
|
||||
* 0xfb000000 0x7a000000 16MB PCI Config type 1
|
||||
* 0xfa000000 0x7b000000 16MB PCI Config type 0
|
||||
* 0xf9000000 0x50000000 1MB Cache flush
|
||||
* 0xf0000000 0x80000000 16MB ISA memory
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
#define MMU_IO(a, b) (a)
|
||||
#else
|
||||
#define MMU_IO(a, b) (b)
|
||||
#endif
|
||||
|
||||
#define XBUS_SIZE 0x00100000
|
||||
#define XBUS_BASE MMU_IO(0xff800000, 0x40000000)
|
||||
|
||||
#define ARMCSR_SIZE 0x00100000
|
||||
#define ARMCSR_BASE MMU_IO(0xfe000000, 0x42000000)
|
||||
|
||||
#define WFLUSH_SIZE 0x00100000
|
||||
#define WFLUSH_BASE MMU_IO(0xfd000000, 0x78000000)
|
||||
|
||||
#define PCIIACK_SIZE 0x00100000
|
||||
#define PCIIACK_BASE MMU_IO(0xfc000000, 0x79000000)
|
||||
|
||||
#define PCICFG1_SIZE 0x01000000
|
||||
#define PCICFG1_BASE MMU_IO(0xfb000000, 0x7a000000)
|
||||
|
||||
#define PCICFG0_SIZE 0x01000000
|
||||
#define PCICFG0_BASE MMU_IO(0xfa000000, 0x7b000000)
|
||||
|
||||
#define PCIMEM_SIZE 0x01000000
|
||||
#define PCIMEM_BASE MMU_IO(0xf0000000, 0x80000000)
|
||||
|
||||
#define XBUS_CS2 0x40012000
|
||||
|
||||
#define XBUS_SWITCH ((volatile unsigned char *)(XBUS_BASE + 0x12000))
|
||||
#define XBUS_SWITCH_SWITCH ((*XBUS_SWITCH) & 15)
|
||||
#define XBUS_SWITCH_J17_13 ((*XBUS_SWITCH) & (1 << 4))
|
||||
#define XBUS_SWITCH_J17_11 ((*XBUS_SWITCH) & (1 << 5))
|
||||
#define XBUS_SWITCH_J17_9 ((*XBUS_SWITCH) & (1 << 6))
|
||||
|
||||
#define UNCACHEABLE_ADDR (ARMCSR_BASE + 0x108)
|
||||
|
||||
|
||||
/* PIC irq control */
|
||||
#define PIC_LO 0x20
|
||||
#define PIC_MASK_LO 0x21
|
||||
#define PIC_HI 0xA0
|
||||
#define PIC_MASK_HI 0xA1
|
||||
|
||||
/* GPIO pins */
|
||||
#define GPIO_CCLK 0x800
|
||||
#define GPIO_DSCLK 0x400
|
||||
#define GPIO_E2CLK 0x200
|
||||
#define GPIO_IOLOAD 0x100
|
||||
#define GPIO_RED_LED 0x080
|
||||
#define GPIO_WDTIMER 0x040
|
||||
#define GPIO_DATA 0x020
|
||||
#define GPIO_IOCLK 0x010
|
||||
#define GPIO_DONE 0x008
|
||||
#define GPIO_FAN 0x004
|
||||
#define GPIO_GREEN_LED 0x002
|
||||
#define GPIO_RESET 0x001
|
||||
|
||||
/* CPLD pins */
|
||||
#define CPLD_DS_ENABLE 8
|
||||
#define CPLD_7111_DISABLE 4
|
||||
#define CPLD_UNMUTE 2
|
||||
#define CPLD_FLASH_WR_ENABLE 1
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
extern raw_spinlock_t nw_gpio_lock;
|
||||
extern void nw_gpio_modify_op(unsigned int mask, unsigned int set);
|
||||
extern void nw_gpio_modify_io(unsigned int mask, unsigned int in);
|
||||
extern unsigned int nw_gpio_read(void);
|
||||
extern void nw_cpld_modify(unsigned int mask, unsigned int set);
|
||||
#endif
|
||||
|
||||
#endif
|
23
arch/arm/mach-footbridge/include/mach/io.h
Normal file
23
arch/arm/mach-footbridge/include/mach/io.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* arch/arm/mach-footbridge/include/mach/io.h
|
||||
*
|
||||
* Copyright (C) 1997-1999 Russell King
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Modifications:
|
||||
* 06-12-1997 RMK Created.
|
||||
* 07-04-1999 RMK Major cleanup
|
||||
*/
|
||||
#ifndef __ASM_ARM_ARCH_IO_H
|
||||
#define __ASM_ARM_ARCH_IO_H
|
||||
|
||||
/*
|
||||
* Translation of various i/o addresses to host addresses for !CONFIG_MMU
|
||||
*/
|
||||
#define PCIO_BASE 0x7c000000
|
||||
#define __io(a) ((void __iomem *)(PCIO_BASE + (a)))
|
||||
|
||||
#endif
|
96
arch/arm/mach-footbridge/include/mach/irqs.h
Normal file
96
arch/arm/mach-footbridge/include/mach/irqs.h
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* arch/arm/mach-footbridge/include/mach/irqs.h
|
||||
*
|
||||
* Copyright (C) 1998 Russell King
|
||||
* Copyright (C) 1998 Phil Blundell
|
||||
*
|
||||
* Changelog:
|
||||
* 20-Jan-1998 RMK Started merge of EBSA286, CATS and NetWinder
|
||||
* 01-Feb-1999 PJB ISA IRQs start at 0 not 16
|
||||
*/
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#define NR_IRQS 36
|
||||
#define NR_DC21285_IRQS 16
|
||||
|
||||
#define _ISA_IRQ(x) (0 + (x))
|
||||
#define _ISA_INR(x) ((x) - 0)
|
||||
#define _DC21285_IRQ(x) (16 + (x))
|
||||
#define _DC21285_INR(x) ((x) - 16)
|
||||
|
||||
/*
|
||||
* This is a list of all interrupts that the 21285
|
||||
* can generate and we handle.
|
||||
*/
|
||||
#define IRQ_CONRX _DC21285_IRQ(0)
|
||||
#define IRQ_CONTX _DC21285_IRQ(1)
|
||||
#define IRQ_TIMER1 _DC21285_IRQ(2)
|
||||
#define IRQ_TIMER2 _DC21285_IRQ(3)
|
||||
#define IRQ_TIMER3 _DC21285_IRQ(4)
|
||||
#define IRQ_IN0 _DC21285_IRQ(5)
|
||||
#define IRQ_IN1 _DC21285_IRQ(6)
|
||||
#define IRQ_IN2 _DC21285_IRQ(7)
|
||||
#define IRQ_IN3 _DC21285_IRQ(8)
|
||||
#define IRQ_DOORBELLHOST _DC21285_IRQ(9)
|
||||
#define IRQ_DMA1 _DC21285_IRQ(10)
|
||||
#define IRQ_DMA2 _DC21285_IRQ(11)
|
||||
#define IRQ_PCI _DC21285_IRQ(12)
|
||||
#define IRQ_SDRAMPARITY _DC21285_IRQ(13)
|
||||
#define IRQ_I2OINPOST _DC21285_IRQ(14)
|
||||
#define IRQ_PCI_ABORT _DC21285_IRQ(15)
|
||||
#define IRQ_PCI_SERR _DC21285_IRQ(16)
|
||||
#define IRQ_DISCARD_TIMER _DC21285_IRQ(17)
|
||||
#define IRQ_PCI_DPERR _DC21285_IRQ(18)
|
||||
#define IRQ_PCI_PERR _DC21285_IRQ(19)
|
||||
|
||||
#define IRQ_ISA_TIMER _ISA_IRQ(0)
|
||||
#define IRQ_ISA_KEYBOARD _ISA_IRQ(1)
|
||||
#define IRQ_ISA_CASCADE _ISA_IRQ(2)
|
||||
#define IRQ_ISA_UART2 _ISA_IRQ(3)
|
||||
#define IRQ_ISA_UART _ISA_IRQ(4)
|
||||
#define IRQ_ISA_FLOPPY _ISA_IRQ(6)
|
||||
#define IRQ_ISA_PRINTER _ISA_IRQ(7)
|
||||
#define IRQ_ISA_RTC_ALARM _ISA_IRQ(8)
|
||||
#define IRQ_ISA_2 _ISA_IRQ(9)
|
||||
#define IRQ_ISA_PS2MOUSE _ISA_IRQ(12)
|
||||
#define IRQ_ISA_HARDDISK1 _ISA_IRQ(14)
|
||||
#define IRQ_ISA_HARDDISK2 _ISA_IRQ(15)
|
||||
|
||||
#define IRQ_MASK_UART_RX (1 << 2)
|
||||
#define IRQ_MASK_UART_TX (1 << 3)
|
||||
#define IRQ_MASK_TIMER1 (1 << 4)
|
||||
#define IRQ_MASK_TIMER2 (1 << 5)
|
||||
#define IRQ_MASK_TIMER3 (1 << 6)
|
||||
#define IRQ_MASK_IN0 (1 << 8)
|
||||
#define IRQ_MASK_IN1 (1 << 9)
|
||||
#define IRQ_MASK_IN2 (1 << 10)
|
||||
#define IRQ_MASK_IN3 (1 << 11)
|
||||
#define IRQ_MASK_DOORBELLHOST (1 << 15)
|
||||
#define IRQ_MASK_DMA1 (1 << 16)
|
||||
#define IRQ_MASK_DMA2 (1 << 17)
|
||||
#define IRQ_MASK_PCI (1 << 18)
|
||||
#define IRQ_MASK_SDRAMPARITY (1 << 24)
|
||||
#define IRQ_MASK_I2OINPOST (1 << 25)
|
||||
#define IRQ_MASK_PCI_ABORT ((1 << 29) | (1 << 30))
|
||||
#define IRQ_MASK_PCI_SERR (1 << 23)
|
||||
#define IRQ_MASK_DISCARD_TIMER (1 << 27)
|
||||
#define IRQ_MASK_PCI_DPERR (1 << 28)
|
||||
#define IRQ_MASK_PCI_PERR (1 << 31)
|
||||
|
||||
/*
|
||||
* Netwinder interrupt allocations
|
||||
*/
|
||||
#define IRQ_NETWINDER_ETHER10 IRQ_IN0
|
||||
#define IRQ_NETWINDER_ETHER100 IRQ_IN1
|
||||
#define IRQ_NETWINDER_VIDCOMP IRQ_IN2
|
||||
#define IRQ_NETWINDER_PS2MOUSE _ISA_IRQ(5)
|
||||
#define IRQ_NETWINDER_IR _ISA_IRQ(6)
|
||||
#define IRQ_NETWINDER_BUTTON _ISA_IRQ(10)
|
||||
#define IRQ_NETWINDER_VGA _ISA_IRQ(11)
|
||||
#define IRQ_NETWINDER_SOUND _ISA_IRQ(12)
|
||||
|
||||
#define I8042_KBD_IRQ IRQ_ISA_KEYBOARD
|
||||
#define I8042_AUX_IRQ (machine_is_netwinder() ? IRQ_NETWINDER_PS2MOUSE : IRQ_ISA_PS2MOUSE)
|
||||
#define IRQ_FLOPPYDISK IRQ_ISA_FLOPPY
|
||||
|
||||
#define irq_canonicalize(_i) (((_i) == IRQ_ISA_CASCADE) ? IRQ_ISA_2 : _i)
|
25
arch/arm/mach-footbridge/include/mach/isa-dma.h
Normal file
25
arch/arm/mach-footbridge/include/mach/isa-dma.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* arch/arm/mach-footbridge/include/mach/isa-dma.h
|
||||
*
|
||||
* Architecture DMA routines
|
||||
*
|
||||
* Copyright (C) 1998,1999 Russell King
|
||||
* Copyright (C) 1998,1999 Philip Blundell
|
||||
*/
|
||||
#ifndef __ASM_ARCH_DMA_H
|
||||
#define __ASM_ARCH_DMA_H
|
||||
|
||||
/*
|
||||
* The 21285 has two internal DMA channels; we call these 8 and 9.
|
||||
* On CATS hardware we have an additional eight ISA dma channels
|
||||
* numbered 0..7.
|
||||
*/
|
||||
#define _ISA_DMA(x) (0+(x))
|
||||
#define _DC21285_DMA(x) (8+(x))
|
||||
|
||||
#define MAX_DMA_CHANNELS 10
|
||||
|
||||
#define DMA_FLOPPY _ISA_DMA(2)
|
||||
#define DMA_ISA_CASCADE _ISA_DMA(4)
|
||||
|
||||
#endif /* _ASM_ARCH_DMA_H */
|
64
arch/arm/mach-footbridge/include/mach/memory.h
Normal file
64
arch/arm/mach-footbridge/include/mach/memory.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* arch/arm/mach-footbridge/include/mach/memory.h
|
||||
*
|
||||
* Copyright (C) 1996-1999 Russell King.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Changelog:
|
||||
* 20-Oct-1996 RMK Created
|
||||
* 31-Dec-1997 RMK Fixed definitions to reduce warnings.
|
||||
* 17-May-1998 DAG Added __virt_to_bus and __bus_to_virt functions.
|
||||
* 21-Nov-1998 RMK Changed __virt_to_bus and __bus_to_virt to macros.
|
||||
* 21-Mar-1999 RMK Added PAGE_OFFSET for co285 architecture.
|
||||
* Renamed to memory.h
|
||||
* Moved PAGE_OFFSET and TASK_SIZE here
|
||||
*/
|
||||
#ifndef __ASM_ARCH_MEMORY_H
|
||||
#define __ASM_ARCH_MEMORY_H
|
||||
|
||||
|
||||
#if defined(CONFIG_FOOTBRIDGE_ADDIN)
|
||||
/*
|
||||
* If we may be using add-in footbridge mode, then we must
|
||||
* use the out-of-line translation that makes use of the
|
||||
* PCI BAR
|
||||
*/
|
||||
#ifndef __ASSEMBLY__
|
||||
extern unsigned long __virt_to_bus(unsigned long);
|
||||
extern unsigned long __bus_to_virt(unsigned long);
|
||||
extern unsigned long __pfn_to_bus(unsigned long);
|
||||
extern unsigned long __bus_to_pfn(unsigned long);
|
||||
#endif
|
||||
#define __virt_to_bus __virt_to_bus
|
||||
#define __bus_to_virt __bus_to_virt
|
||||
|
||||
#elif defined(CONFIG_FOOTBRIDGE_HOST)
|
||||
|
||||
/*
|
||||
* The footbridge is programmed to expose the system RAM at 0xe0000000.
|
||||
* The requirement is that the RAM isn't placed at bus address 0, which
|
||||
* would clash with VGA cards.
|
||||
*/
|
||||
#define BUS_OFFSET 0xe0000000
|
||||
#define __virt_to_bus(x) ((x) + (BUS_OFFSET - PAGE_OFFSET))
|
||||
#define __bus_to_virt(x) ((x) - (BUS_OFFSET - PAGE_OFFSET))
|
||||
#define __pfn_to_bus(x) (__pfn_to_phys(x) + (BUS_OFFSET - PHYS_OFFSET))
|
||||
#define __bus_to_pfn(x) __phys_to_pfn((x) - (BUS_OFFSET - PHYS_OFFSET))
|
||||
|
||||
#else
|
||||
|
||||
#error "Undefined footbridge mode"
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Cache flushing area.
|
||||
*/
|
||||
#define FLUSH_BASE 0xf9000000
|
||||
|
||||
#define FLUSH_BASE_PHYS 0x50000000
|
||||
|
||||
#endif
|
37
arch/arm/mach-footbridge/include/mach/uncompress.h
Normal file
37
arch/arm/mach-footbridge/include/mach/uncompress.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* arch/arm/mach-footbridge/include/mach/uncompress.h
|
||||
*
|
||||
* Copyright (C) 1996-1999 Russell King
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
/*
|
||||
* Note! This could cause problems on the NetWinder
|
||||
*/
|
||||
#define DC21285_BASE ((volatile unsigned int *)0x42000160)
|
||||
#define SER0_BASE ((volatile unsigned char *)0x7c0003f8)
|
||||
|
||||
static inline void putc(char c)
|
||||
{
|
||||
if (machine_is_netwinder()) {
|
||||
while ((SER0_BASE[5] & 0x60) != 0x60)
|
||||
barrier();
|
||||
SER0_BASE[0] = c;
|
||||
} else {
|
||||
while (DC21285_BASE[6] & 8);
|
||||
DC21285_BASE[0] = c;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void flush(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* nothing to do
|
||||
*/
|
||||
#define arch_decomp_setup()
|
183
arch/arm/mach-footbridge/isa-irq.c
Normal file
183
arch/arm/mach-footbridge/isa-irq.c
Normal file
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-footbridge/irq.c
|
||||
*
|
||||
* Copyright (C) 1996-2000 Russell King
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Changelog:
|
||||
* 22-Aug-1998 RMK Restructured IRQ routines
|
||||
* 03-Sep-1998 PJB Merged CATS support
|
||||
* 20-Jan-1998 RMK Started merge of EBSA286, CATS and NetWinder
|
||||
* 26-Jan-1999 PJB Don't use IACK on CATS
|
||||
* 16-Mar-1999 RMK Added autodetect of ISA PICs
|
||||
*/
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <asm/mach/irq.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <asm/hardware/dec21285.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
static void isa_mask_pic_lo_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int mask = 1 << (d->irq & 7);
|
||||
|
||||
outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
|
||||
}
|
||||
|
||||
static void isa_ack_pic_lo_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int mask = 1 << (d->irq & 7);
|
||||
|
||||
outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
|
||||
outb(0x20, PIC_LO);
|
||||
}
|
||||
|
||||
static void isa_unmask_pic_lo_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int mask = 1 << (d->irq & 7);
|
||||
|
||||
outb(inb(PIC_MASK_LO) & ~mask, PIC_MASK_LO);
|
||||
}
|
||||
|
||||
static struct irq_chip isa_lo_chip = {
|
||||
.irq_ack = isa_ack_pic_lo_irq,
|
||||
.irq_mask = isa_mask_pic_lo_irq,
|
||||
.irq_unmask = isa_unmask_pic_lo_irq,
|
||||
};
|
||||
|
||||
static void isa_mask_pic_hi_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int mask = 1 << (d->irq & 7);
|
||||
|
||||
outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
|
||||
}
|
||||
|
||||
static void isa_ack_pic_hi_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int mask = 1 << (d->irq & 7);
|
||||
|
||||
outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
|
||||
outb(0x62, PIC_LO);
|
||||
outb(0x20, PIC_HI);
|
||||
}
|
||||
|
||||
static void isa_unmask_pic_hi_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int mask = 1 << (d->irq & 7);
|
||||
|
||||
outb(inb(PIC_MASK_HI) & ~mask, PIC_MASK_HI);
|
||||
}
|
||||
|
||||
static struct irq_chip isa_hi_chip = {
|
||||
.irq_ack = isa_ack_pic_hi_irq,
|
||||
.irq_mask = isa_mask_pic_hi_irq,
|
||||
.irq_unmask = isa_unmask_pic_hi_irq,
|
||||
};
|
||||
|
||||
static void
|
||||
isa_irq_handler(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
unsigned int isa_irq = *(unsigned char *)PCIIACK_BASE;
|
||||
|
||||
if (isa_irq < _ISA_IRQ(0) || isa_irq >= _ISA_IRQ(16)) {
|
||||
do_bad_IRQ(isa_irq, desc);
|
||||
return;
|
||||
}
|
||||
|
||||
generic_handle_irq(isa_irq);
|
||||
}
|
||||
|
||||
static struct irqaction irq_cascade = {
|
||||
.handler = no_action,
|
||||
.name = "cascade",
|
||||
};
|
||||
|
||||
static struct resource pic1_resource = {
|
||||
.name = "pic1",
|
||||
.start = 0x20,
|
||||
.end = 0x3f,
|
||||
};
|
||||
|
||||
static struct resource pic2_resource = {
|
||||
.name = "pic2",
|
||||
.start = 0xa0,
|
||||
.end = 0xbf,
|
||||
};
|
||||
|
||||
void __init isa_init_irq(unsigned int host_irq)
|
||||
{
|
||||
unsigned int irq;
|
||||
|
||||
/*
|
||||
* Setup, and then probe for an ISA PIC
|
||||
* If the PIC is not there, then we
|
||||
* ignore the PIC.
|
||||
*/
|
||||
outb(0x11, PIC_LO);
|
||||
outb(_ISA_IRQ(0), PIC_MASK_LO); /* IRQ number */
|
||||
outb(0x04, PIC_MASK_LO); /* Slave on Ch2 */
|
||||
outb(0x01, PIC_MASK_LO); /* x86 */
|
||||
outb(0xf5, PIC_MASK_LO); /* pattern: 11110101 */
|
||||
|
||||
outb(0x11, PIC_HI);
|
||||
outb(_ISA_IRQ(8), PIC_MASK_HI); /* IRQ number */
|
||||
outb(0x02, PIC_MASK_HI); /* Slave on Ch1 */
|
||||
outb(0x01, PIC_MASK_HI); /* x86 */
|
||||
outb(0xfa, PIC_MASK_HI); /* pattern: 11111010 */
|
||||
|
||||
outb(0x0b, PIC_LO);
|
||||
outb(0x0b, PIC_HI);
|
||||
|
||||
if (inb(PIC_MASK_LO) == 0xf5 && inb(PIC_MASK_HI) == 0xfa) {
|
||||
outb(0xff, PIC_MASK_LO);/* mask all IRQs */
|
||||
outb(0xff, PIC_MASK_HI);/* mask all IRQs */
|
||||
} else {
|
||||
printk(KERN_INFO "IRQ: ISA PIC not found\n");
|
||||
host_irq = (unsigned int)-1;
|
||||
}
|
||||
|
||||
if (host_irq != (unsigned int)-1) {
|
||||
for (irq = _ISA_IRQ(0); irq < _ISA_IRQ(8); irq++) {
|
||||
irq_set_chip_and_handler(irq, &isa_lo_chip,
|
||||
handle_level_irq);
|
||||
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
|
||||
}
|
||||
|
||||
for (irq = _ISA_IRQ(8); irq < _ISA_IRQ(16); irq++) {
|
||||
irq_set_chip_and_handler(irq, &isa_hi_chip,
|
||||
handle_level_irq);
|
||||
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
|
||||
}
|
||||
|
||||
request_resource(&ioport_resource, &pic1_resource);
|
||||
request_resource(&ioport_resource, &pic2_resource);
|
||||
setup_irq(IRQ_ISA_CASCADE, &irq_cascade);
|
||||
|
||||
irq_set_chained_handler(host_irq, isa_irq_handler);
|
||||
|
||||
/*
|
||||
* On the NetWinder, don't automatically
|
||||
* enable ISA IRQ11 when it is requested.
|
||||
* There appears to be a missing pull-up
|
||||
* resistor on this line.
|
||||
*/
|
||||
if (machine_is_netwinder())
|
||||
set_irq_flags(_ISA_IRQ(11), IRQF_VALID |
|
||||
IRQF_PROBE | IRQF_NOAUTOEN);
|
||||
}
|
||||
}
|
||||
|
||||
|
57
arch/arm/mach-footbridge/isa-rtc.c
Normal file
57
arch/arm/mach-footbridge/isa-rtc.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* arch/arm/mach-footbridge/isa-rtc.c
|
||||
*
|
||||
* Copyright (C) 1998 Russell King.
|
||||
* Copyright (C) 1998 Phil Blundell
|
||||
*
|
||||
* CATS has a real-time clock, though the evaluation board doesn't.
|
||||
*
|
||||
* Changelog:
|
||||
* 21-Mar-1998 RMK Created
|
||||
* 27-Aug-1998 PJB CATS support
|
||||
* 28-Dec-1998 APH Made leds optional
|
||||
* 20-Jan-1999 RMK Started merge of EBSA285, CATS and NetWinder
|
||||
* 16-Mar-1999 RMK More support for EBSA285-like machines with RTCs in
|
||||
*/
|
||||
|
||||
#define RTC_PORT(x) (0x70+(x))
|
||||
#define RTC_ALWAYS_BCD 0
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/mc146818rtc.h>
|
||||
#include <linux/bcd.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void __init isa_rtc_init(void)
|
||||
{
|
||||
int reg_d, reg_b;
|
||||
|
||||
/*
|
||||
* Probe for the RTC.
|
||||
*/
|
||||
reg_d = CMOS_READ(RTC_REG_D);
|
||||
|
||||
/*
|
||||
* make sure the divider is set
|
||||
*/
|
||||
CMOS_WRITE(RTC_REF_CLCK_32KHZ, RTC_REG_A);
|
||||
|
||||
/*
|
||||
* Set control reg B
|
||||
* (24 hour mode, update enabled)
|
||||
*/
|
||||
reg_b = CMOS_READ(RTC_REG_B) & 0x7f;
|
||||
reg_b |= 2;
|
||||
CMOS_WRITE(reg_b, RTC_REG_B);
|
||||
|
||||
if ((CMOS_READ(RTC_REG_A) & 0x7f) == RTC_REF_CLCK_32KHZ &&
|
||||
CMOS_READ(RTC_REG_B) == reg_b) {
|
||||
/*
|
||||
* We have a RTC. Check the battery
|
||||
*/
|
||||
if ((reg_d & 0x80) == 0)
|
||||
printk(KERN_WARNING "RTC: *** warning: CMOS battery bad\n");
|
||||
}
|
||||
}
|
40
arch/arm/mach-footbridge/isa-timer.c
Normal file
40
arch/arm/mach-footbridge/isa-timer.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-footbridge/isa-timer.c
|
||||
*
|
||||
* Copyright (C) 1998 Russell King.
|
||||
* Copyright (C) 1998 Phil Blundell
|
||||
*/
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/i8253.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/timex.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mach/time.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct clock_event_device *ce = dev_id;
|
||||
ce->event_handler(ce);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction pit_timer_irq = {
|
||||
.name = "pit",
|
||||
.handler = pit_timer_interrupt,
|
||||
.flags = IRQF_TIMER | IRQF_IRQPOLL,
|
||||
.dev_id = &i8253_clockevent,
|
||||
};
|
||||
|
||||
void __init isa_timer_init(void)
|
||||
{
|
||||
clocksource_i8253_init();
|
||||
|
||||
setup_irq(i8253_clockevent.irq, &pit_timer_irq);
|
||||
clockevent_i8253_init(false);
|
||||
}
|
101
arch/arm/mach-footbridge/isa.c
Normal file
101
arch/arm/mach-footbridge/isa.c
Normal file
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-footbridge/isa.c
|
||||
*
|
||||
* Copyright (C) 2004 Russell King.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/serial_8250.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/hardware/dec21285.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
static struct resource rtc_resources[] = {
|
||||
[0] = {
|
||||
.start = 0x70,
|
||||
.end = 0x73,
|
||||
.flags = IORESOURCE_IO,
|
||||
},
|
||||
[1] = {
|
||||
.start = IRQ_ISA_RTC_ALARM,
|
||||
.end = IRQ_ISA_RTC_ALARM,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device rtc_device = {
|
||||
.name = "rtc_cmos",
|
||||
.id = -1,
|
||||
.resource = rtc_resources,
|
||||
.num_resources = ARRAY_SIZE(rtc_resources),
|
||||
};
|
||||
|
||||
static struct resource serial_resources[] = {
|
||||
[0] = {
|
||||
.start = 0x3f8,
|
||||
.end = 0x3ff,
|
||||
.flags = IORESOURCE_IO,
|
||||
},
|
||||
[1] = {
|
||||
.start = 0x2f8,
|
||||
.end = 0x2ff,
|
||||
.flags = IORESOURCE_IO,
|
||||
},
|
||||
};
|
||||
|
||||
static struct plat_serial8250_port serial_platform_data[] = {
|
||||
{
|
||||
.iobase = 0x3f8,
|
||||
.irq = IRQ_ISA_UART,
|
||||
.uartclk = 1843200,
|
||||
.regshift = 0,
|
||||
.iotype = UPIO_PORT,
|
||||
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
|
||||
},
|
||||
{
|
||||
.iobase = 0x2f8,
|
||||
.irq = IRQ_ISA_UART2,
|
||||
.uartclk = 1843200,
|
||||
.regshift = 0,
|
||||
.iotype = UPIO_PORT,
|
||||
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct platform_device serial_device = {
|
||||
.name = "serial8250",
|
||||
.id = PLAT8250_DEV_PLATFORM,
|
||||
.dev = {
|
||||
.platform_data = serial_platform_data,
|
||||
},
|
||||
.resource = serial_resources,
|
||||
.num_resources = ARRAY_SIZE(serial_resources),
|
||||
};
|
||||
|
||||
static int __init footbridge_isa_init(void)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if (!footbridge_cfn_mode())
|
||||
return 0;
|
||||
|
||||
/* Personal server doesn't have RTC */
|
||||
if (!machine_is_personal_server()) {
|
||||
isa_rtc_init();
|
||||
err = platform_device_register(&rtc_device);
|
||||
if (err)
|
||||
printk(KERN_ERR "Unable to register RTC device: %d\n", err);
|
||||
}
|
||||
err = platform_device_register(&serial_device);
|
||||
if (err)
|
||||
printk(KERN_ERR "Unable to register serial device: %d\n", err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(footbridge_isa_init);
|
771
arch/arm/mach-footbridge/netwinder-hw.c
Normal file
771
arch/arm/mach-footbridge/netwinder-hw.c
Normal file
|
@ -0,0 +1,771 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-footbridge/netwinder-hw.c
|
||||
*
|
||||
* Netwinder machine fixup
|
||||
*
|
||||
* Copyright (C) 1998, 1999 Russell King, Phil Blundell
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/leds.h>
|
||||
|
||||
#include <asm/hardware/dec21285.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/system_misc.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define IRDA_IO_BASE 0x180
|
||||
#define GP1_IO_BASE 0x338
|
||||
#define GP2_IO_BASE 0x33a
|
||||
|
||||
/*
|
||||
* Winbond WB83977F accessibility stuff
|
||||
*/
|
||||
static inline void wb977_open(void)
|
||||
{
|
||||
outb(0x87, 0x370);
|
||||
outb(0x87, 0x370);
|
||||
}
|
||||
|
||||
static inline void wb977_close(void)
|
||||
{
|
||||
outb(0xaa, 0x370);
|
||||
}
|
||||
|
||||
static inline void wb977_wb(int reg, int val)
|
||||
{
|
||||
outb(reg, 0x370);
|
||||
outb(val, 0x371);
|
||||
}
|
||||
|
||||
static inline void wb977_ww(int reg, int val)
|
||||
{
|
||||
outb(reg, 0x370);
|
||||
outb(val >> 8, 0x371);
|
||||
outb(reg + 1, 0x370);
|
||||
outb(val & 255, 0x371);
|
||||
}
|
||||
|
||||
#define wb977_device_select(dev) wb977_wb(0x07, dev)
|
||||
#define wb977_device_disable() wb977_wb(0x30, 0x00)
|
||||
#define wb977_device_enable() wb977_wb(0x30, 0x01)
|
||||
|
||||
/*
|
||||
* This is a lock for accessing ports GP1_IO_BASE and GP2_IO_BASE
|
||||
*/
|
||||
DEFINE_RAW_SPINLOCK(nw_gpio_lock);
|
||||
EXPORT_SYMBOL(nw_gpio_lock);
|
||||
|
||||
static unsigned int current_gpio_op;
|
||||
static unsigned int current_gpio_io;
|
||||
static unsigned int current_cpld;
|
||||
|
||||
void nw_gpio_modify_op(unsigned int mask, unsigned int set)
|
||||
{
|
||||
unsigned int new_gpio, changed;
|
||||
|
||||
new_gpio = (current_gpio_op & ~mask) | set;
|
||||
changed = new_gpio ^ current_gpio_op;
|
||||
current_gpio_op = new_gpio;
|
||||
|
||||
if (changed & 0xff)
|
||||
outb(new_gpio, GP1_IO_BASE);
|
||||
if (changed & 0xff00)
|
||||
outb(new_gpio >> 8, GP2_IO_BASE);
|
||||
}
|
||||
EXPORT_SYMBOL(nw_gpio_modify_op);
|
||||
|
||||
static inline void __gpio_modify_io(int mask, int in)
|
||||
{
|
||||
unsigned int new_gpio, changed;
|
||||
int port;
|
||||
|
||||
new_gpio = (current_gpio_io & ~mask) | in;
|
||||
changed = new_gpio ^ current_gpio_io;
|
||||
current_gpio_io = new_gpio;
|
||||
|
||||
changed >>= 1;
|
||||
new_gpio >>= 1;
|
||||
|
||||
wb977_device_select(7);
|
||||
|
||||
for (port = 0xe1; changed && port < 0xe8; changed >>= 1) {
|
||||
wb977_wb(port, new_gpio & 1);
|
||||
|
||||
port += 1;
|
||||
new_gpio >>= 1;
|
||||
}
|
||||
|
||||
wb977_device_select(8);
|
||||
|
||||
for (port = 0xe8; changed && port < 0xec; changed >>= 1) {
|
||||
wb977_wb(port, new_gpio & 1);
|
||||
|
||||
port += 1;
|
||||
new_gpio >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void nw_gpio_modify_io(unsigned int mask, unsigned int in)
|
||||
{
|
||||
/* Open up the SuperIO chip */
|
||||
wb977_open();
|
||||
|
||||
__gpio_modify_io(mask, in);
|
||||
|
||||
/* Close up the EFER gate */
|
||||
wb977_close();
|
||||
}
|
||||
EXPORT_SYMBOL(nw_gpio_modify_io);
|
||||
|
||||
unsigned int nw_gpio_read(void)
|
||||
{
|
||||
return inb(GP1_IO_BASE) | inb(GP2_IO_BASE) << 8;
|
||||
}
|
||||
EXPORT_SYMBOL(nw_gpio_read);
|
||||
|
||||
/*
|
||||
* Initialise the Winbond W83977F global registers
|
||||
*/
|
||||
static inline void wb977_init_global(void)
|
||||
{
|
||||
/*
|
||||
* Enable R/W config registers
|
||||
*/
|
||||
wb977_wb(0x26, 0x40);
|
||||
|
||||
/*
|
||||
* Power down FDC (not used)
|
||||
*/
|
||||
wb977_wb(0x22, 0xfe);
|
||||
|
||||
/*
|
||||
* GP12, GP11, CIRRX, IRRXH, GP10
|
||||
*/
|
||||
wb977_wb(0x2a, 0xc1);
|
||||
|
||||
/*
|
||||
* GP23, GP22, GP21, GP20, GP13
|
||||
*/
|
||||
wb977_wb(0x2b, 0x6b);
|
||||
|
||||
/*
|
||||
* GP17, GP16, GP15, GP14
|
||||
*/
|
||||
wb977_wb(0x2c, 0x55);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise the Winbond W83977F printer port
|
||||
*/
|
||||
static inline void wb977_init_printer(void)
|
||||
{
|
||||
wb977_device_select(1);
|
||||
|
||||
/*
|
||||
* mode 1 == EPP
|
||||
*/
|
||||
wb977_wb(0xf0, 0x01);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise the Winbond W83977F keyboard controller
|
||||
*/
|
||||
static inline void wb977_init_keyboard(void)
|
||||
{
|
||||
wb977_device_select(5);
|
||||
|
||||
/*
|
||||
* Keyboard controller address
|
||||
*/
|
||||
wb977_ww(0x60, 0x0060);
|
||||
wb977_ww(0x62, 0x0064);
|
||||
|
||||
/*
|
||||
* Keyboard IRQ 1, active high, edge trigger
|
||||
*/
|
||||
wb977_wb(0x70, 1);
|
||||
wb977_wb(0x71, 0x02);
|
||||
|
||||
/*
|
||||
* Mouse IRQ 5, active high, edge trigger
|
||||
*/
|
||||
wb977_wb(0x72, 5);
|
||||
wb977_wb(0x73, 0x02);
|
||||
|
||||
/*
|
||||
* KBC 8MHz
|
||||
*/
|
||||
wb977_wb(0xf0, 0x40);
|
||||
|
||||
/*
|
||||
* Enable device
|
||||
*/
|
||||
wb977_device_enable();
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise the Winbond W83977F Infra-Red device
|
||||
*/
|
||||
static inline void wb977_init_irda(void)
|
||||
{
|
||||
wb977_device_select(6);
|
||||
|
||||
/*
|
||||
* IR base address
|
||||
*/
|
||||
wb977_ww(0x60, IRDA_IO_BASE);
|
||||
|
||||
/*
|
||||
* IRDA IRQ 6, active high, edge trigger
|
||||
*/
|
||||
wb977_wb(0x70, 6);
|
||||
wb977_wb(0x71, 0x02);
|
||||
|
||||
/*
|
||||
* RX DMA - ISA DMA 0
|
||||
*/
|
||||
wb977_wb(0x74, 0x00);
|
||||
|
||||
/*
|
||||
* TX DMA - Disable Tx DMA
|
||||
*/
|
||||
wb977_wb(0x75, 0x04);
|
||||
|
||||
/*
|
||||
* Append CRC, Enable bank selection
|
||||
*/
|
||||
wb977_wb(0xf0, 0x03);
|
||||
|
||||
/*
|
||||
* Enable device
|
||||
*/
|
||||
wb977_device_enable();
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise Winbond W83977F general purpose IO
|
||||
*/
|
||||
static inline void wb977_init_gpio(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* Set up initial I/O definitions
|
||||
*/
|
||||
current_gpio_io = -1;
|
||||
__gpio_modify_io(-1, GPIO_DONE | GPIO_WDTIMER);
|
||||
|
||||
wb977_device_select(7);
|
||||
|
||||
/*
|
||||
* Group1 base address
|
||||
*/
|
||||
wb977_ww(0x60, GP1_IO_BASE);
|
||||
wb977_ww(0x62, 0);
|
||||
wb977_ww(0x64, 0);
|
||||
|
||||
/*
|
||||
* GP10 (Orage button) IRQ 10, active high, edge trigger
|
||||
*/
|
||||
wb977_wb(0x70, 10);
|
||||
wb977_wb(0x71, 0x02);
|
||||
|
||||
/*
|
||||
* GP10: Debounce filter enabled, IRQ, input
|
||||
*/
|
||||
wb977_wb(0xe0, 0x19);
|
||||
|
||||
/*
|
||||
* Enable Group1
|
||||
*/
|
||||
wb977_device_enable();
|
||||
|
||||
wb977_device_select(8);
|
||||
|
||||
/*
|
||||
* Group2 base address
|
||||
*/
|
||||
wb977_ww(0x60, GP2_IO_BASE);
|
||||
|
||||
/*
|
||||
* Clear watchdog timer regs
|
||||
* - timer disable
|
||||
*/
|
||||
wb977_wb(0xf2, 0x00);
|
||||
|
||||
/*
|
||||
* - disable LED, no mouse nor keyboard IRQ
|
||||
*/
|
||||
wb977_wb(0xf3, 0x00);
|
||||
|
||||
/*
|
||||
* - timer counting, disable power LED, disable timeouot
|
||||
*/
|
||||
wb977_wb(0xf4, 0x00);
|
||||
|
||||
/*
|
||||
* Enable group2
|
||||
*/
|
||||
wb977_device_enable();
|
||||
|
||||
/*
|
||||
* Set Group1/Group2 outputs
|
||||
*/
|
||||
raw_spin_lock_irqsave(&nw_gpio_lock, flags);
|
||||
nw_gpio_modify_op(-1, GPIO_RED_LED | GPIO_FAN);
|
||||
raw_spin_unlock_irqrestore(&nw_gpio_lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise the Winbond W83977F chip.
|
||||
*/
|
||||
static void __init wb977_init(void)
|
||||
{
|
||||
request_region(0x370, 2, "W83977AF configuration");
|
||||
|
||||
/*
|
||||
* Open up the SuperIO chip
|
||||
*/
|
||||
wb977_open();
|
||||
|
||||
/*
|
||||
* Initialise the global registers
|
||||
*/
|
||||
wb977_init_global();
|
||||
|
||||
/*
|
||||
* Initialise the various devices in
|
||||
* the multi-IO chip.
|
||||
*/
|
||||
wb977_init_printer();
|
||||
wb977_init_keyboard();
|
||||
wb977_init_irda();
|
||||
wb977_init_gpio();
|
||||
|
||||
/*
|
||||
* Close up the EFER gate
|
||||
*/
|
||||
wb977_close();
|
||||
}
|
||||
|
||||
void nw_cpld_modify(unsigned int mask, unsigned int set)
|
||||
{
|
||||
int msk;
|
||||
|
||||
current_cpld = (current_cpld & ~mask) | set;
|
||||
|
||||
nw_gpio_modify_io(GPIO_DATA | GPIO_IOCLK | GPIO_IOLOAD, 0);
|
||||
nw_gpio_modify_op(GPIO_IOLOAD, 0);
|
||||
|
||||
for (msk = 8; msk; msk >>= 1) {
|
||||
int bit = current_cpld & msk;
|
||||
|
||||
nw_gpio_modify_op(GPIO_DATA | GPIO_IOCLK, bit ? GPIO_DATA : 0);
|
||||
nw_gpio_modify_op(GPIO_IOCLK, GPIO_IOCLK);
|
||||
}
|
||||
|
||||
nw_gpio_modify_op(GPIO_IOCLK|GPIO_DATA, 0);
|
||||
nw_gpio_modify_op(GPIO_IOLOAD|GPIO_DSCLK, GPIO_IOLOAD|GPIO_DSCLK);
|
||||
nw_gpio_modify_op(GPIO_IOLOAD, 0);
|
||||
}
|
||||
EXPORT_SYMBOL(nw_cpld_modify);
|
||||
|
||||
static void __init cpld_init(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&nw_gpio_lock, flags);
|
||||
nw_cpld_modify(-1, CPLD_UNMUTE | CPLD_7111_DISABLE);
|
||||
raw_spin_unlock_irqrestore(&nw_gpio_lock, flags);
|
||||
}
|
||||
|
||||
static unsigned char rwa_unlock[] __initdata =
|
||||
{ 0x00, 0x00, 0x6a, 0xb5, 0xda, 0xed, 0xf6, 0xfb, 0x7d, 0xbe, 0xdf, 0x6f, 0x37, 0x1b,
|
||||
0x0d, 0x86, 0xc3, 0x61, 0xb0, 0x58, 0x2c, 0x16, 0x8b, 0x45, 0xa2, 0xd1, 0xe8, 0x74,
|
||||
0x3a, 0x9d, 0xce, 0xe7, 0x73, 0x39 };
|
||||
|
||||
#ifndef DEBUG
|
||||
#define dprintk(x...)
|
||||
#else
|
||||
#define dprintk(x...) printk(x)
|
||||
#endif
|
||||
|
||||
#define WRITE_RWA(r,v) do { outb((r), 0x279); udelay(10); outb((v), 0xa79); } while (0)
|
||||
|
||||
static inline void rwa010_unlock(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
WRITE_RWA(2, 2);
|
||||
mdelay(10);
|
||||
|
||||
for (i = 0; i < sizeof(rwa_unlock); i++) {
|
||||
outb(rwa_unlock[i], 0x279);
|
||||
udelay(10);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void rwa010_read_ident(void)
|
||||
{
|
||||
unsigned char si[9];
|
||||
int i, j;
|
||||
|
||||
WRITE_RWA(3, 0);
|
||||
WRITE_RWA(0, 128);
|
||||
|
||||
outb(1, 0x279);
|
||||
|
||||
mdelay(1);
|
||||
|
||||
dprintk("Identifier: ");
|
||||
for (i = 0; i < 9; i++) {
|
||||
si[i] = 0;
|
||||
for (j = 0; j < 8; j++) {
|
||||
int bit;
|
||||
udelay(250);
|
||||
inb(0x203);
|
||||
udelay(250);
|
||||
bit = inb(0x203);
|
||||
dprintk("%02X ", bit);
|
||||
bit = (bit == 0xaa) ? 1 : 0;
|
||||
si[i] |= bit << j;
|
||||
}
|
||||
dprintk("(%02X) ", si[i]);
|
||||
}
|
||||
dprintk("\n");
|
||||
}
|
||||
|
||||
static inline void rwa010_global_init(void)
|
||||
{
|
||||
WRITE_RWA(6, 2); // Assign a card no = 2
|
||||
|
||||
dprintk("Card no = %d\n", inb(0x203));
|
||||
|
||||
/* disable the modem section of the chip */
|
||||
WRITE_RWA(7, 3);
|
||||
WRITE_RWA(0x30, 0);
|
||||
|
||||
/* disable the cdrom section of the chip */
|
||||
WRITE_RWA(7, 4);
|
||||
WRITE_RWA(0x30, 0);
|
||||
|
||||
/* disable the MPU-401 section of the chip */
|
||||
WRITE_RWA(7, 2);
|
||||
WRITE_RWA(0x30, 0);
|
||||
}
|
||||
|
||||
static inline void rwa010_game_port_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
WRITE_RWA(7, 5);
|
||||
|
||||
dprintk("Slider base: ");
|
||||
WRITE_RWA(0x61, 1);
|
||||
i = inb(0x203);
|
||||
|
||||
WRITE_RWA(0x60, 2);
|
||||
dprintk("%02X%02X (201)\n", inb(0x203), i);
|
||||
|
||||
WRITE_RWA(0x30, 1);
|
||||
}
|
||||
|
||||
static inline void rwa010_waveartist_init(int base, int irq, int dma)
|
||||
{
|
||||
int i;
|
||||
|
||||
WRITE_RWA(7, 0);
|
||||
|
||||
dprintk("WaveArtist base: ");
|
||||
WRITE_RWA(0x61, base & 255);
|
||||
i = inb(0x203);
|
||||
|
||||
WRITE_RWA(0x60, base >> 8);
|
||||
dprintk("%02X%02X (%X),", inb(0x203), i, base);
|
||||
|
||||
WRITE_RWA(0x70, irq);
|
||||
dprintk(" irq: %d (%d),", inb(0x203), irq);
|
||||
|
||||
WRITE_RWA(0x74, dma);
|
||||
dprintk(" dma: %d (%d)\n", inb(0x203), dma);
|
||||
|
||||
WRITE_RWA(0x30, 1);
|
||||
}
|
||||
|
||||
static inline void rwa010_soundblaster_init(int sb_base, int al_base, int irq, int dma)
|
||||
{
|
||||
int i;
|
||||
|
||||
WRITE_RWA(7, 1);
|
||||
|
||||
dprintk("SoundBlaster base: ");
|
||||
WRITE_RWA(0x61, sb_base & 255);
|
||||
i = inb(0x203);
|
||||
|
||||
WRITE_RWA(0x60, sb_base >> 8);
|
||||
dprintk("%02X%02X (%X),", inb(0x203), i, sb_base);
|
||||
|
||||
dprintk(" irq: ");
|
||||
WRITE_RWA(0x70, irq);
|
||||
dprintk("%d (%d),", inb(0x203), irq);
|
||||
|
||||
dprintk(" 8-bit DMA: ");
|
||||
WRITE_RWA(0x74, dma);
|
||||
dprintk("%d (%d)\n", inb(0x203), dma);
|
||||
|
||||
dprintk("AdLib base: ");
|
||||
WRITE_RWA(0x63, al_base & 255);
|
||||
i = inb(0x203);
|
||||
|
||||
WRITE_RWA(0x62, al_base >> 8);
|
||||
dprintk("%02X%02X (%X)\n", inb(0x203), i, al_base);
|
||||
|
||||
WRITE_RWA(0x30, 1);
|
||||
}
|
||||
|
||||
static void rwa010_soundblaster_reset(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
outb(1, 0x226);
|
||||
udelay(3);
|
||||
outb(0, 0x226);
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
if (inb(0x22e) & 0x80)
|
||||
break;
|
||||
mdelay(1);
|
||||
}
|
||||
if (i == 5)
|
||||
printk("SoundBlaster: DSP reset failed\n");
|
||||
|
||||
dprintk("SoundBlaster DSP reset: %02X (AA)\n", inb(0x22a));
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
if ((inb(0x22c) & 0x80) == 0)
|
||||
break;
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
if (i == 5)
|
||||
printk("SoundBlaster: DSP not ready\n");
|
||||
else {
|
||||
outb(0xe1, 0x22c);
|
||||
|
||||
dprintk("SoundBlaster DSP id: ");
|
||||
i = inb(0x22a);
|
||||
udelay(1);
|
||||
i |= inb(0x22a) << 8;
|
||||
dprintk("%04X\n", i);
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
if ((inb(0x22c) & 0x80) == 0)
|
||||
break;
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
if (i == 5)
|
||||
printk("SoundBlaster: could not turn speaker off\n");
|
||||
|
||||
outb(0xd3, 0x22c);
|
||||
}
|
||||
|
||||
/* turn on OPL3 */
|
||||
outb(5, 0x38a);
|
||||
outb(1, 0x38b);
|
||||
}
|
||||
|
||||
static void __init rwa010_init(void)
|
||||
{
|
||||
rwa010_unlock();
|
||||
rwa010_read_ident();
|
||||
rwa010_global_init();
|
||||
rwa010_game_port_init();
|
||||
rwa010_waveartist_init(0x250, 3, 7);
|
||||
rwa010_soundblaster_init(0x220, 0x388, 3, 1);
|
||||
rwa010_soundblaster_reset();
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise any other hardware after we've got the PCI bus
|
||||
* initialised. We may need the PCI bus to talk to this other
|
||||
* hardware.
|
||||
*/
|
||||
static int __init nw_hw_init(void)
|
||||
{
|
||||
if (machine_is_netwinder()) {
|
||||
wb977_init();
|
||||
cpld_init();
|
||||
rwa010_init();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
__initcall(nw_hw_init);
|
||||
|
||||
/*
|
||||
* Older NeTTroms either do not provide a parameters
|
||||
* page, or they don't supply correct information in
|
||||
* the parameter page.
|
||||
*/
|
||||
static void __init
|
||||
fixup_netwinder(struct tag *tags, char **cmdline)
|
||||
{
|
||||
#ifdef CONFIG_ISAPNP
|
||||
extern int isapnp_disable;
|
||||
|
||||
/*
|
||||
* We must not use the kernels ISAPnP code
|
||||
* on the NetWinder - it will reset the settings
|
||||
* for the WaveArtist chip and render it inoperable.
|
||||
*/
|
||||
isapnp_disable = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void netwinder_restart(enum reboot_mode mode, const char *cmd)
|
||||
{
|
||||
if (mode == REBOOT_SOFT) {
|
||||
/* Jump into the ROM */
|
||||
soft_restart(0x41000000);
|
||||
} else {
|
||||
local_irq_disable();
|
||||
local_fiq_disable();
|
||||
|
||||
/* open up the SuperIO chip */
|
||||
outb(0x87, 0x370);
|
||||
outb(0x87, 0x370);
|
||||
|
||||
/* aux function group 1 (logical device 7) */
|
||||
outb(0x07, 0x370);
|
||||
outb(0x07, 0x371);
|
||||
|
||||
/* set GP16 for WD-TIMER output */
|
||||
outb(0xe6, 0x370);
|
||||
outb(0x00, 0x371);
|
||||
|
||||
/* set a RED LED and toggle WD_TIMER for rebooting */
|
||||
outb(0xc4, 0x338);
|
||||
}
|
||||
}
|
||||
|
||||
/* LEDs */
|
||||
#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
|
||||
struct netwinder_led {
|
||||
struct led_classdev cdev;
|
||||
u8 mask;
|
||||
};
|
||||
|
||||
/*
|
||||
* The triggers lines up below will only be used if the
|
||||
* LED triggers are compiled in.
|
||||
*/
|
||||
static const struct {
|
||||
const char *name;
|
||||
const char *trigger;
|
||||
} netwinder_leds[] = {
|
||||
{ "netwinder:green", "heartbeat", },
|
||||
{ "netwinder:red", "cpu0", },
|
||||
};
|
||||
|
||||
/*
|
||||
* The LED control in Netwinder is reversed:
|
||||
* - setting bit means turn off LED
|
||||
* - clearing bit means turn on LED
|
||||
*/
|
||||
static void netwinder_led_set(struct led_classdev *cdev,
|
||||
enum led_brightness b)
|
||||
{
|
||||
struct netwinder_led *led = container_of(cdev,
|
||||
struct netwinder_led, cdev);
|
||||
unsigned long flags;
|
||||
u32 reg;
|
||||
|
||||
raw_spin_lock_irqsave(&nw_gpio_lock, flags);
|
||||
reg = nw_gpio_read();
|
||||
if (b != LED_OFF)
|
||||
reg &= ~led->mask;
|
||||
else
|
||||
reg |= led->mask;
|
||||
nw_gpio_modify_op(led->mask, reg);
|
||||
raw_spin_unlock_irqrestore(&nw_gpio_lock, flags);
|
||||
}
|
||||
|
||||
static enum led_brightness netwinder_led_get(struct led_classdev *cdev)
|
||||
{
|
||||
struct netwinder_led *led = container_of(cdev,
|
||||
struct netwinder_led, cdev);
|
||||
unsigned long flags;
|
||||
u32 reg;
|
||||
|
||||
raw_spin_lock_irqsave(&nw_gpio_lock, flags);
|
||||
reg = nw_gpio_read();
|
||||
raw_spin_unlock_irqrestore(&nw_gpio_lock, flags);
|
||||
|
||||
return (reg & led->mask) ? LED_OFF : LED_FULL;
|
||||
}
|
||||
|
||||
static int __init netwinder_leds_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!machine_is_netwinder())
|
||||
return -ENODEV;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(netwinder_leds); i++) {
|
||||
struct netwinder_led *led;
|
||||
|
||||
led = kzalloc(sizeof(*led), GFP_KERNEL);
|
||||
if (!led)
|
||||
break;
|
||||
|
||||
led->cdev.name = netwinder_leds[i].name;
|
||||
led->cdev.brightness_set = netwinder_led_set;
|
||||
led->cdev.brightness_get = netwinder_led_get;
|
||||
led->cdev.default_trigger = netwinder_leds[i].trigger;
|
||||
|
||||
if (i == 0)
|
||||
led->mask = GPIO_GREEN_LED;
|
||||
else
|
||||
led->mask = GPIO_RED_LED;
|
||||
|
||||
if (led_classdev_register(NULL, &led->cdev) < 0) {
|
||||
kfree(led);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since we may have triggers on any subsystem, defer registration
|
||||
* until after subsystem_init.
|
||||
*/
|
||||
fs_initcall(netwinder_leds_init);
|
||||
#endif
|
||||
|
||||
MACHINE_START(NETWINDER, "Rebel-NetWinder")
|
||||
/* Maintainer: Russell King/Rebel.com */
|
||||
.atag_offset = 0x100,
|
||||
.video_start = 0x000a0000,
|
||||
.video_end = 0x000bffff,
|
||||
.reserve_lp0 = 1,
|
||||
.reserve_lp2 = 1,
|
||||
.fixup = fixup_netwinder,
|
||||
.map_io = footbridge_map_io,
|
||||
.init_irq = footbridge_init_irq,
|
||||
.init_time = isa_timer_init,
|
||||
.restart = netwinder_restart,
|
||||
MACHINE_END
|
61
arch/arm/mach-footbridge/netwinder-pci.c
Normal file
61
arch/arm/mach-footbridge/netwinder-pci.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-footbridge/netwinder-pci.c
|
||||
*
|
||||
* PCI bios-type initialisation for PCI machines
|
||||
*
|
||||
* Bits taken from various places.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mach/pci.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
/*
|
||||
* We now use the slot ID instead of the device identifiers to select
|
||||
* which interrupt is routed where.
|
||||
*/
|
||||
static int __init netwinder_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
|
||||
{
|
||||
switch (slot) {
|
||||
case 0: /* host bridge */
|
||||
return 0;
|
||||
|
||||
case 9: /* CyberPro */
|
||||
return IRQ_NETWINDER_VGA;
|
||||
|
||||
case 10: /* DC21143 */
|
||||
return IRQ_NETWINDER_ETHER100;
|
||||
|
||||
case 12: /* Winbond 553 */
|
||||
return IRQ_ISA_HARDDISK1;
|
||||
|
||||
case 13: /* Winbond 89C940F */
|
||||
return IRQ_NETWINDER_ETHER10;
|
||||
|
||||
default:
|
||||
printk(KERN_ERR "PCI: unknown device in slot %s\n",
|
||||
pci_name(dev));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static struct hw_pci netwinder_pci __initdata = {
|
||||
.map_irq = netwinder_map_irq,
|
||||
.nr_controllers = 1,
|
||||
.ops = &dc21285_ops,
|
||||
.setup = dc21285_setup,
|
||||
.preinit = dc21285_preinit,
|
||||
.postinit = dc21285_postinit,
|
||||
};
|
||||
|
||||
static int __init netwinder_pci_init(void)
|
||||
{
|
||||
if (machine_is_netwinder())
|
||||
pci_common_init(&netwinder_pci);
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(netwinder_pci_init);
|
57
arch/arm/mach-footbridge/personal-pci.c
Normal file
57
arch/arm/mach-footbridge/personal-pci.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-footbridge/personal-pci.c
|
||||
*
|
||||
* PCI bios-type initialisation for PCI machines
|
||||
*
|
||||
* Bits taken from various places.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mach/pci.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
static int irqmap_personal_server[] __initdata = {
|
||||
IRQ_IN0, IRQ_IN1, IRQ_IN2, IRQ_IN3, 0, 0, 0,
|
||||
IRQ_DOORBELLHOST, IRQ_DMA1, IRQ_DMA2, IRQ_PCI
|
||||
};
|
||||
|
||||
static int __init personal_server_map_irq(const struct pci_dev *dev, u8 slot,
|
||||
u8 pin)
|
||||
{
|
||||
unsigned char line;
|
||||
|
||||
pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line);
|
||||
|
||||
if (line > 0x40 && line <= 0x5f) {
|
||||
/* line corresponds to the bit controlling this interrupt
|
||||
* in the footbridge. Ignore the first 8 interrupt bits,
|
||||
* look up the rest in the map. IN0 is bit number 8
|
||||
*/
|
||||
return irqmap_personal_server[(line & 0x1f) - 8];
|
||||
} else if (line == 0) {
|
||||
/* no interrupt */
|
||||
return 0;
|
||||
} else
|
||||
return irqmap_personal_server[(line - 1) & 3];
|
||||
}
|
||||
|
||||
static struct hw_pci personal_server_pci __initdata = {
|
||||
.map_irq = personal_server_map_irq,
|
||||
.nr_controllers = 1,
|
||||
.ops = &dc21285_ops,
|
||||
.setup = dc21285_setup,
|
||||
.preinit = dc21285_preinit,
|
||||
.postinit = dc21285_postinit,
|
||||
};
|
||||
|
||||
static int __init personal_pci_init(void)
|
||||
{
|
||||
if (machine_is_personal_server())
|
||||
pci_common_init(&personal_server_pci);
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(personal_pci_init);
|
24
arch/arm/mach-footbridge/personal.c
Normal file
24
arch/arm/mach-footbridge/personal.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-footbridge/personal.c
|
||||
*
|
||||
* Personal server (Skiff) machine fixup
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <asm/hardware/dec21285.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
MACHINE_START(PERSONAL_SERVER, "Compaq-PersonalServer")
|
||||
/* Maintainer: Jamey Hicks / George France */
|
||||
.atag_offset = 0x100,
|
||||
.map_io = footbridge_map_io,
|
||||
.init_irq = footbridge_init_irq,
|
||||
.init_time = footbridge_timer_init,
|
||||
.restart = footbridge_restart,
|
||||
MACHINE_END
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue