mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-09-09 01:28:05 -04:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
7
arch/arm/mach-ebsa110/Makefile
Normal file
7
arch/arm/mach-ebsa110/Makefile
Normal file
|
@ -0,0 +1,7 @@
|
|||
#
|
||||
# Makefile for the linux kernel.
|
||||
#
|
||||
|
||||
# Object file lists.
|
||||
|
||||
obj-y := core.o io.o leds.o
|
4
arch/arm/mach-ebsa110/Makefile.boot
Normal file
4
arch/arm/mach-ebsa110/Makefile.boot
Normal file
|
@ -0,0 +1,4 @@
|
|||
zreladdr-y += 0x00008000
|
||||
params_phys-y := 0x00000400
|
||||
initrd_phys-y := 0x00800000
|
||||
|
329
arch/arm/mach-ebsa110/core.c
Normal file
329
arch/arm/mach-ebsa110/core.c
Normal file
|
@ -0,0 +1,329 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-ebsa110/core.c
|
||||
*
|
||||
* Copyright (C) 1998-2001 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.
|
||||
*
|
||||
* Extra MM routines for the EBSA-110 architecture
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/serial_8250.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/system_misc.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/irq.h>
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
#include <asm/mach/time.h>
|
||||
|
||||
#include "core.h"
|
||||
|
||||
static void ebsa110_mask_irq(struct irq_data *d)
|
||||
{
|
||||
__raw_writeb(1 << d->irq, IRQ_MCLR);
|
||||
}
|
||||
|
||||
static void ebsa110_unmask_irq(struct irq_data *d)
|
||||
{
|
||||
__raw_writeb(1 << d->irq, IRQ_MSET);
|
||||
}
|
||||
|
||||
static struct irq_chip ebsa110_irq_chip = {
|
||||
.irq_ack = ebsa110_mask_irq,
|
||||
.irq_mask = ebsa110_mask_irq,
|
||||
.irq_unmask = ebsa110_unmask_irq,
|
||||
};
|
||||
|
||||
static void __init ebsa110_init_irq(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int irq;
|
||||
|
||||
local_irq_save(flags);
|
||||
__raw_writeb(0xff, IRQ_MCLR);
|
||||
__raw_writeb(0x55, IRQ_MSET);
|
||||
__raw_writeb(0x00, IRQ_MSET);
|
||||
if (__raw_readb(IRQ_MASK) != 0x55)
|
||||
while (1);
|
||||
__raw_writeb(0xff, IRQ_MCLR); /* clear all interrupt enables */
|
||||
local_irq_restore(flags);
|
||||
|
||||
for (irq = 0; irq < NR_IRQS; irq++) {
|
||||
irq_set_chip_and_handler(irq, &ebsa110_irq_chip,
|
||||
handle_level_irq);
|
||||
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
|
||||
}
|
||||
}
|
||||
|
||||
static struct map_desc ebsa110_io_desc[] __initdata = {
|
||||
/*
|
||||
* sparse external-decode ISAIO space
|
||||
*/
|
||||
{ /* IRQ_STAT/IRQ_MCLR */
|
||||
.virtual = (unsigned long)IRQ_STAT,
|
||||
.pfn = __phys_to_pfn(TRICK4_PHYS),
|
||||
.length = TRICK4_SIZE,
|
||||
.type = MT_DEVICE
|
||||
}, { /* IRQ_MASK/IRQ_MSET */
|
||||
.virtual = (unsigned long)IRQ_MASK,
|
||||
.pfn = __phys_to_pfn(TRICK3_PHYS),
|
||||
.length = TRICK3_SIZE,
|
||||
.type = MT_DEVICE
|
||||
}, { /* SOFT_BASE */
|
||||
.virtual = (unsigned long)SOFT_BASE,
|
||||
.pfn = __phys_to_pfn(TRICK1_PHYS),
|
||||
.length = TRICK1_SIZE,
|
||||
.type = MT_DEVICE
|
||||
}, { /* PIT_BASE */
|
||||
.virtual = (unsigned long)PIT_BASE,
|
||||
.pfn = __phys_to_pfn(TRICK0_PHYS),
|
||||
.length = TRICK0_SIZE,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
|
||||
/*
|
||||
* self-decode ISAIO space
|
||||
*/
|
||||
{
|
||||
.virtual = ISAIO_BASE,
|
||||
.pfn = __phys_to_pfn(ISAIO_PHYS),
|
||||
.length = ISAIO_SIZE,
|
||||
.type = MT_DEVICE
|
||||
}, {
|
||||
.virtual = ISAMEM_BASE,
|
||||
.pfn = __phys_to_pfn(ISAMEM_PHYS),
|
||||
.length = ISAMEM_SIZE,
|
||||
.type = MT_DEVICE
|
||||
}
|
||||
};
|
||||
|
||||
static void __init ebsa110_map_io(void)
|
||||
{
|
||||
iotable_init(ebsa110_io_desc, ARRAY_SIZE(ebsa110_io_desc));
|
||||
}
|
||||
|
||||
static void __iomem *ebsa110_ioremap_caller(phys_addr_t cookie, size_t size,
|
||||
unsigned int flags, void *caller)
|
||||
{
|
||||
return (void __iomem *)cookie;
|
||||
}
|
||||
|
||||
static void ebsa110_iounmap(volatile void __iomem *io_addr)
|
||||
{}
|
||||
|
||||
static void __init ebsa110_init_early(void)
|
||||
{
|
||||
arch_ioremap_caller = ebsa110_ioremap_caller;
|
||||
arch_iounmap = ebsa110_iounmap;
|
||||
}
|
||||
|
||||
#define PIT_CTRL (PIT_BASE + 0x0d)
|
||||
#define PIT_T2 (PIT_BASE + 0x09)
|
||||
#define PIT_T1 (PIT_BASE + 0x05)
|
||||
#define PIT_T0 (PIT_BASE + 0x01)
|
||||
|
||||
/*
|
||||
* This is the rate at which your MCLK signal toggles (in Hz)
|
||||
* This was measured on a 10 digit frequency counter sampling
|
||||
* over 1 second.
|
||||
*/
|
||||
#define MCLK 47894000
|
||||
|
||||
/*
|
||||
* This is the rate at which the PIT timers get clocked
|
||||
*/
|
||||
#define CLKBY7 (MCLK / 7)
|
||||
|
||||
/*
|
||||
* This is the counter value. We tick at 200Hz on this platform.
|
||||
*/
|
||||
#define COUNT ((CLKBY7 + (HZ / 2)) / HZ)
|
||||
|
||||
/*
|
||||
* Get the time offset from the system PIT. Note that if we have missed an
|
||||
* interrupt, then the PIT counter will roll over (ie, be negative).
|
||||
* This actually works out to be convenient.
|
||||
*/
|
||||
static u32 ebsa110_gettimeoffset(void)
|
||||
{
|
||||
unsigned long offset, count;
|
||||
|
||||
__raw_writeb(0x40, PIT_CTRL);
|
||||
count = __raw_readb(PIT_T1);
|
||||
count |= __raw_readb(PIT_T1) << 8;
|
||||
|
||||
/*
|
||||
* If count > COUNT, make the number negative.
|
||||
*/
|
||||
if (count > COUNT)
|
||||
count |= 0xffff0000;
|
||||
|
||||
offset = COUNT;
|
||||
offset -= count;
|
||||
|
||||
/*
|
||||
* `offset' is in units of timer counts. Convert
|
||||
* offset to units of microseconds.
|
||||
*/
|
||||
offset = offset * (1000000 / HZ) / COUNT;
|
||||
|
||||
return offset * 1000;
|
||||
}
|
||||
|
||||
static irqreturn_t
|
||||
ebsa110_timer_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
u32 count;
|
||||
|
||||
/* latch and read timer 1 */
|
||||
__raw_writeb(0x40, PIT_CTRL);
|
||||
count = __raw_readb(PIT_T1);
|
||||
count |= __raw_readb(PIT_T1) << 8;
|
||||
|
||||
count += COUNT;
|
||||
|
||||
__raw_writeb(count & 0xff, PIT_T1);
|
||||
__raw_writeb(count >> 8, PIT_T1);
|
||||
|
||||
timer_tick();
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction ebsa110_timer_irq = {
|
||||
.name = "EBSA110 Timer Tick",
|
||||
.flags = IRQF_TIMER | IRQF_IRQPOLL,
|
||||
.handler = ebsa110_timer_interrupt,
|
||||
};
|
||||
|
||||
/*
|
||||
* Set up timer interrupt.
|
||||
*/
|
||||
void __init ebsa110_timer_init(void)
|
||||
{
|
||||
arch_gettimeoffset = ebsa110_gettimeoffset;
|
||||
|
||||
/*
|
||||
* Timer 1, mode 2, LSB/MSB
|
||||
*/
|
||||
__raw_writeb(0x70, PIT_CTRL);
|
||||
__raw_writeb(COUNT & 0xff, PIT_T1);
|
||||
__raw_writeb(COUNT >> 8, PIT_T1);
|
||||
|
||||
setup_irq(IRQ_EBSA110_TIMER0, &ebsa110_timer_irq);
|
||||
}
|
||||
|
||||
static struct plat_serial8250_port serial_platform_data[] = {
|
||||
{
|
||||
.iobase = 0x3f8,
|
||||
.irq = 1,
|
||||
.uartclk = 1843200,
|
||||
.regshift = 0,
|
||||
.iotype = UPIO_PORT,
|
||||
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
|
||||
},
|
||||
{
|
||||
.iobase = 0x2f8,
|
||||
.irq = 2,
|
||||
.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,
|
||||
},
|
||||
};
|
||||
|
||||
static struct resource am79c961_resources[] = {
|
||||
{
|
||||
.start = 0x220,
|
||||
.end = 0x238,
|
||||
.flags = IORESOURCE_IO,
|
||||
}, {
|
||||
.start = IRQ_EBSA110_ETHERNET,
|
||||
.end = IRQ_EBSA110_ETHERNET,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device am79c961_device = {
|
||||
.name = "am79c961",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(am79c961_resources),
|
||||
.resource = am79c961_resources,
|
||||
};
|
||||
|
||||
static struct platform_device *ebsa110_devices[] = {
|
||||
&serial_device,
|
||||
&am79c961_device,
|
||||
};
|
||||
|
||||
/*
|
||||
* EBSA110 idling methodology:
|
||||
*
|
||||
* We can not execute the "wait for interrupt" instruction since that
|
||||
* will stop our MCLK signal (which provides the clock for the glue
|
||||
* logic, and therefore the timer interrupt).
|
||||
*
|
||||
* Instead, we spin, polling the IRQ_STAT register for the occurrence
|
||||
* of any interrupt with core clock down to the memory clock.
|
||||
*/
|
||||
static void ebsa110_idle(void)
|
||||
{
|
||||
const char *irq_stat = (char *)0xff000000;
|
||||
|
||||
/* disable clock switching */
|
||||
asm volatile ("mcr p15, 0, ip, c15, c2, 2" : : : "cc");
|
||||
|
||||
/* wait for an interrupt to occur */
|
||||
while (!*irq_stat);
|
||||
|
||||
/* enable clock switching */
|
||||
asm volatile ("mcr p15, 0, ip, c15, c1, 2" : : : "cc");
|
||||
}
|
||||
|
||||
static int __init ebsa110_init(void)
|
||||
{
|
||||
arm_pm_idle = ebsa110_idle;
|
||||
return platform_add_devices(ebsa110_devices, ARRAY_SIZE(ebsa110_devices));
|
||||
}
|
||||
|
||||
arch_initcall(ebsa110_init);
|
||||
|
||||
static void ebsa110_restart(enum reboot_mode mode, const char *cmd)
|
||||
{
|
||||
soft_restart(0x80000000);
|
||||
}
|
||||
|
||||
MACHINE_START(EBSA110, "EBSA110")
|
||||
/* Maintainer: Russell King */
|
||||
.atag_offset = 0x400,
|
||||
.reserve_lp0 = 1,
|
||||
.reserve_lp2 = 1,
|
||||
.map_io = ebsa110_map_io,
|
||||
.init_early = ebsa110_init_early,
|
||||
.init_irq = ebsa110_init_irq,
|
||||
.init_time = ebsa110_timer_init,
|
||||
.restart = ebsa110_restart,
|
||||
MACHINE_END
|
41
arch/arm/mach-ebsa110/core.h
Normal file
41
arch/arm/mach-ebsa110/core.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* This file contains the core hardware definitions of the EBSA-110.
|
||||
*/
|
||||
#ifndef CORE_H
|
||||
#define CORE_H
|
||||
|
||||
/* Physical addresses/sizes */
|
||||
#define ISAMEM_PHYS 0xe0000000
|
||||
#define ISAMEM_SIZE 0x10000000
|
||||
|
||||
#define ISAIO_PHYS 0xf0000000
|
||||
#define ISAIO_SIZE PGDIR_SIZE
|
||||
|
||||
#define TRICK0_PHYS 0xf2000000
|
||||
#define TRICK0_SIZE PGDIR_SIZE
|
||||
#define TRICK1_PHYS 0xf2400000
|
||||
#define TRICK1_SIZE PGDIR_SIZE
|
||||
#define TRICK2_PHYS 0xf2800000
|
||||
#define TRICK3_PHYS 0xf2c00000
|
||||
#define TRICK3_SIZE PGDIR_SIZE
|
||||
#define TRICK4_PHYS 0xf3000000
|
||||
#define TRICK4_SIZE PGDIR_SIZE
|
||||
#define TRICK5_PHYS 0xf3400000
|
||||
#define TRICK6_PHYS 0xf3800000
|
||||
#define TRICK7_PHYS 0xf3c00000
|
||||
|
||||
/* Virtual addresses */
|
||||
#define PIT_BASE IOMEM(0xfc000000) /* trick 0 */
|
||||
#define SOFT_BASE IOMEM(0xfd000000) /* trick 1 */
|
||||
#define IRQ_MASK IOMEM(0xfe000000) /* trick 3 - read */
|
||||
#define IRQ_MSET IOMEM(0xfe000000) /* trick 3 - write */
|
||||
#define IRQ_STAT IOMEM(0xff000000) /* trick 4 - read */
|
||||
#define IRQ_MCLR IOMEM(0xff000000) /* trick 4 - write */
|
||||
|
||||
#endif
|
33
arch/arm/mach-ebsa110/include/mach/entry-macro.S
Normal file
33
arch/arm/mach-ebsa110/include/mach/entry-macro.S
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* arch/arm/mach-ebsa110/include/mach/entry-macro.S
|
||||
*
|
||||
* Low-level IRQ helper macros for ebsa110 platform.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#define IRQ_STAT 0xff000000 /* read */
|
||||
|
||||
.macro get_irqnr_preamble, base, tmp
|
||||
mov \base, #IRQ_STAT
|
||||
.endm
|
||||
|
||||
.macro get_irqnr_and_base, irqnr, stat, base, tmp
|
||||
ldrb \stat, [\base] @ get interrupts
|
||||
mov \irqnr, #0
|
||||
tst \stat, #15
|
||||
addeq \irqnr, \irqnr, #4
|
||||
moveq \stat, \stat, lsr #4
|
||||
tst \stat, #3
|
||||
addeq \irqnr, \irqnr, #2
|
||||
moveq \stat, \stat, lsr #2
|
||||
tst \stat, #1
|
||||
addeq \irqnr, \irqnr, #1
|
||||
moveq \stat, \stat, lsr #1
|
||||
tst \stat, #1 @ bit 0 should be set
|
||||
.endm
|
||||
|
24
arch/arm/mach-ebsa110/include/mach/hardware.h
Normal file
24
arch/arm/mach-ebsa110/include/mach/hardware.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* arch/arm/mach-ebsa110/include/mach/hardware.h
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This file contains the hardware definitions of the EBSA-110.
|
||||
*/
|
||||
#ifndef __ASM_ARCH_HARDWARE_H
|
||||
#define __ASM_ARCH_HARDWARE_H
|
||||
|
||||
#define ISAMEM_BASE 0xe0000000
|
||||
#define ISAIO_BASE 0xf0000000
|
||||
|
||||
/*
|
||||
* RAM definitions
|
||||
*/
|
||||
#define UNCACHEABLE_ADDR 0xff000000 /* IRQ_STAT */
|
||||
|
||||
#endif
|
||||
|
81
arch/arm/mach-ebsa110/include/mach/io.h
Normal file
81
arch/arm/mach-ebsa110/include/mach/io.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* arch/arm/mach-ebsa110/include/mach/io.h
|
||||
*
|
||||
* Copyright (C) 1997,1998 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-Dec-1997 RMK Created.
|
||||
*/
|
||||
#ifndef __ASM_ARM_ARCH_IO_H
|
||||
#define __ASM_ARM_ARCH_IO_H
|
||||
|
||||
u8 __inb8(unsigned int port);
|
||||
void __outb8(u8 val, unsigned int port);
|
||||
|
||||
u8 __inb16(unsigned int port);
|
||||
void __outb16(u8 val, unsigned int port);
|
||||
|
||||
u16 __inw(unsigned int port);
|
||||
void __outw(u16 val, unsigned int port);
|
||||
|
||||
u32 __inl(unsigned int port);
|
||||
void __outl(u32 val, unsigned int port);
|
||||
|
||||
u8 __readb(const volatile void __iomem *addr);
|
||||
u16 __readw(const volatile void __iomem *addr);
|
||||
u32 __readl(const volatile void __iomem *addr);
|
||||
|
||||
void __writeb(u8 val, void __iomem *addr);
|
||||
void __writew(u16 val, void __iomem *addr);
|
||||
void __writel(u32 val, void __iomem *addr);
|
||||
|
||||
/*
|
||||
* Argh, someone forgot the IOCS16 line. We therefore have to handle
|
||||
* the byte stearing by selecting the correct byte IO functions here.
|
||||
*/
|
||||
#ifdef ISA_SIXTEEN_BIT_PERIPHERAL
|
||||
#define inb(p) __inb16(p)
|
||||
#define outb(v,p) __outb16(v,p)
|
||||
#else
|
||||
#define inb(p) __inb8(p)
|
||||
#define outb(v,p) __outb8(v,p)
|
||||
#endif
|
||||
|
||||
#define inw(p) __inw(p)
|
||||
#define outw(v,p) __outw(v,p)
|
||||
|
||||
#define inl(p) __inl(p)
|
||||
#define outl(v,p) __outl(v,p)
|
||||
|
||||
#define readb(b) __readb(b)
|
||||
#define readw(b) __readw(b)
|
||||
#define readl(b) __readl(b)
|
||||
#define readb_relaxed(addr) readb(addr)
|
||||
#define readw_relaxed(addr) readw(addr)
|
||||
#define readl_relaxed(addr) readl(addr)
|
||||
|
||||
#define writeb(v,b) __writeb(v,b)
|
||||
#define writew(v,b) __writew(v,b)
|
||||
#define writel(v,b) __writel(v,b)
|
||||
|
||||
extern void insb(unsigned int port, void *buf, int sz);
|
||||
extern void insw(unsigned int port, void *buf, int sz);
|
||||
extern void insl(unsigned int port, void *buf, int sz);
|
||||
|
||||
extern void outsb(unsigned int port, const void *buf, int sz);
|
||||
extern void outsw(unsigned int port, const void *buf, int sz);
|
||||
extern void outsl(unsigned int port, const void *buf, int sz);
|
||||
|
||||
/* can't support writesb atm */
|
||||
extern void writesw(void __iomem *addr, const void *data, int wordlen);
|
||||
extern void writesl(void __iomem *addr, const void *data, int longlen);
|
||||
|
||||
/* can't support readsb atm */
|
||||
extern void readsw(const void __iomem *addr, void *data, int wordlen);
|
||||
extern void readsl(const void __iomem *addr, void *data, int longlen);
|
||||
|
||||
#endif
|
20
arch/arm/mach-ebsa110/include/mach/irqs.h
Normal file
20
arch/arm/mach-ebsa110/include/mach/irqs.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* arch/arm/mach-ebsa110/include/mach/irqs.h
|
||||
*
|
||||
* Copyright (C) 1996 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.
|
||||
*/
|
||||
|
||||
#define NR_IRQS 8
|
||||
|
||||
#define IRQ_EBSA110_PRINTER 0
|
||||
#define IRQ_EBSA110_COM1 1
|
||||
#define IRQ_EBSA110_COM2 2
|
||||
#define IRQ_EBSA110_ETHERNET 3
|
||||
#define IRQ_EBSA110_TIMER0 4
|
||||
#define IRQ_EBSA110_TIMER1 5
|
||||
#define IRQ_EBSA110_PCMCIA 6
|
||||
#define IRQ_EBSA110_IMMEDIATE 7
|
25
arch/arm/mach-ebsa110/include/mach/memory.h
Normal file
25
arch/arm/mach-ebsa110/include/mach/memory.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* arch/arm/mach-ebsa110/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
|
||||
* 21-Mar-1999 RMK Renamed to memory.h
|
||||
* RMK Moved TASK_SIZE and PAGE_OFFSET here
|
||||
*/
|
||||
#ifndef __ASM_ARCH_MEMORY_H
|
||||
#define __ASM_ARCH_MEMORY_H
|
||||
|
||||
/*
|
||||
* Cache flushing area - SRAM
|
||||
*/
|
||||
#define FLUSH_BASE_PHYS 0x40000000
|
||||
#define FLUSH_BASE 0xdf000000
|
||||
|
||||
#endif
|
44
arch/arm/mach-ebsa110/include/mach/uncompress.h
Normal file
44
arch/arm/mach-ebsa110/include/mach/uncompress.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* arch/arm/mach-ebsa110/include/mach/uncompress.h
|
||||
*
|
||||
* Copyright (C) 1996,1997,1998 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/serial_reg.h>
|
||||
|
||||
#define SERIAL_BASE ((unsigned char *)0xf0000be0)
|
||||
|
||||
/*
|
||||
* This does not append a newline
|
||||
*/
|
||||
static inline void putc(int c)
|
||||
{
|
||||
unsigned char v, *base = SERIAL_BASE;
|
||||
|
||||
do {
|
||||
v = base[UART_LSR << 2];
|
||||
barrier();
|
||||
} while (!(v & UART_LSR_THRE));
|
||||
|
||||
base[UART_TX << 2] = c;
|
||||
}
|
||||
|
||||
static inline void flush(void)
|
||||
{
|
||||
unsigned char v, *base = SERIAL_BASE;
|
||||
|
||||
do {
|
||||
v = base[UART_LSR << 2];
|
||||
barrier();
|
||||
} while ((v & (UART_LSR_TEMT|UART_LSR_THRE)) !=
|
||||
(UART_LSR_TEMT|UART_LSR_THRE));
|
||||
}
|
||||
|
||||
/*
|
||||
* nothing to do
|
||||
*/
|
||||
#define arch_decomp_setup()
|
439
arch/arm/mach-ebsa110/io.c
Normal file
439
arch/arm/mach-ebsa110/io.c
Normal file
|
@ -0,0 +1,439 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-ebsa110/isamem.c
|
||||
*
|
||||
* Copyright (C) 2001 Russell King
|
||||
*
|
||||
* Perform "ISA" memory and IO accesses. The EBSA110 has some "peculiarities"
|
||||
* in the way it handles accesses to odd IO ports on 16-bit devices. These
|
||||
* devices have their D0-D15 lines connected to the processors D0-D15 lines.
|
||||
* Since they expect all byte IO operations to be performed on D0-D7, and the
|
||||
* StrongARM expects to transfer the byte to these odd addresses on D8-D15,
|
||||
* we must use a trick to get the required behaviour.
|
||||
*
|
||||
* The trick employed here is to use long word stores to odd address -1. The
|
||||
* glue logic picks this up as a "trick" access, and asserts the LSB of the
|
||||
* peripherals address bus, thereby accessing the odd IO port. Meanwhile, the
|
||||
* StrongARM transfers its data on D0-D7 as expected.
|
||||
*
|
||||
* Things get more interesting on the pass-1 EBSA110 - the PCMCIA controller
|
||||
* wiring was screwed in such a way that it had limited memory space access.
|
||||
* Luckily, the work-around for this is not too horrible. See
|
||||
* __isamem_convert_addr for the details.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
static void __iomem *__isamem_convert_addr(const volatile void __iomem *addr)
|
||||
{
|
||||
u32 ret, a = (u32 __force) addr;
|
||||
|
||||
/*
|
||||
* The PCMCIA controller is wired up as follows:
|
||||
* +---------+---------+---------+---------+---------+---------+
|
||||
* PCMCIA | 2 2 2 2 | 1 1 1 1 | 1 1 1 1 | 1 1 | | |
|
||||
* | 3 2 1 0 | 9 8 7 6 | 5 4 3 2 | 1 0 9 8 | 7 6 5 4 | 3 2 1 0 |
|
||||
* +---------+---------+---------+---------+---------+---------+
|
||||
* CPU | 2 2 2 2 | 2 1 1 1 | 1 1 1 1 | 1 1 1 | | |
|
||||
* | 4 3 2 1 | 0 9 9 8 | 7 6 5 4 | 3 2 0 9 | 8 7 6 5 | 4 3 2 x |
|
||||
* +---------+---------+---------+---------+---------+---------+
|
||||
*
|
||||
* This means that we can access PCMCIA regions as follows:
|
||||
* 0x*10000 -> 0x*1ffff
|
||||
* 0x*70000 -> 0x*7ffff
|
||||
* 0x*90000 -> 0x*9ffff
|
||||
* 0x*f0000 -> 0x*fffff
|
||||
*/
|
||||
ret = (a & 0xf803fe) << 1;
|
||||
ret |= (a & 0x03fc00) << 2;
|
||||
|
||||
ret += 0xe8000000;
|
||||
|
||||
if ((a & 0x20000) == (a & 0x40000) >> 1)
|
||||
return (void __iomem *)ret;
|
||||
|
||||
BUG();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* read[bwl] and write[bwl]
|
||||
*/
|
||||
u8 __readb(const volatile void __iomem *addr)
|
||||
{
|
||||
void __iomem *a = __isamem_convert_addr(addr);
|
||||
u32 ret;
|
||||
|
||||
if ((unsigned long)addr & 1)
|
||||
ret = __raw_readl(a);
|
||||
else
|
||||
ret = __raw_readb(a);
|
||||
return ret;
|
||||
}
|
||||
|
||||
u16 __readw(const volatile void __iomem *addr)
|
||||
{
|
||||
void __iomem *a = __isamem_convert_addr(addr);
|
||||
|
||||
if ((unsigned long)addr & 1)
|
||||
BUG();
|
||||
|
||||
return __raw_readw(a);
|
||||
}
|
||||
|
||||
u32 __readl(const volatile void __iomem *addr)
|
||||
{
|
||||
void __iomem *a = __isamem_convert_addr(addr);
|
||||
u32 ret;
|
||||
|
||||
if ((unsigned long)addr & 3)
|
||||
BUG();
|
||||
|
||||
ret = __raw_readw(a);
|
||||
ret |= __raw_readw(a + 4) << 16;
|
||||
return ret;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(__readb);
|
||||
EXPORT_SYMBOL(__readw);
|
||||
EXPORT_SYMBOL(__readl);
|
||||
|
||||
void readsw(const void __iomem *addr, void *data, int len)
|
||||
{
|
||||
void __iomem *a = __isamem_convert_addr(addr);
|
||||
|
||||
BUG_ON((unsigned long)addr & 1);
|
||||
|
||||
__raw_readsw(a, data, len);
|
||||
}
|
||||
EXPORT_SYMBOL(readsw);
|
||||
|
||||
void readsl(const void __iomem *addr, void *data, int len)
|
||||
{
|
||||
void __iomem *a = __isamem_convert_addr(addr);
|
||||
|
||||
BUG_ON((unsigned long)addr & 3);
|
||||
|
||||
__raw_readsl(a, data, len);
|
||||
}
|
||||
EXPORT_SYMBOL(readsl);
|
||||
|
||||
void __writeb(u8 val, void __iomem *addr)
|
||||
{
|
||||
void __iomem *a = __isamem_convert_addr(addr);
|
||||
|
||||
if ((unsigned long)addr & 1)
|
||||
__raw_writel(val, a);
|
||||
else
|
||||
__raw_writeb(val, a);
|
||||
}
|
||||
|
||||
void __writew(u16 val, void __iomem *addr)
|
||||
{
|
||||
void __iomem *a = __isamem_convert_addr(addr);
|
||||
|
||||
if ((unsigned long)addr & 1)
|
||||
BUG();
|
||||
|
||||
__raw_writew(val, a);
|
||||
}
|
||||
|
||||
void __writel(u32 val, void __iomem *addr)
|
||||
{
|
||||
void __iomem *a = __isamem_convert_addr(addr);
|
||||
|
||||
if ((unsigned long)addr & 3)
|
||||
BUG();
|
||||
|
||||
__raw_writew(val, a);
|
||||
__raw_writew(val >> 16, a + 4);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(__writeb);
|
||||
EXPORT_SYMBOL(__writew);
|
||||
EXPORT_SYMBOL(__writel);
|
||||
|
||||
void writesw(void __iomem *addr, const void *data, int len)
|
||||
{
|
||||
void __iomem *a = __isamem_convert_addr(addr);
|
||||
|
||||
BUG_ON((unsigned long)addr & 1);
|
||||
|
||||
__raw_writesw(a, data, len);
|
||||
}
|
||||
EXPORT_SYMBOL(writesw);
|
||||
|
||||
void writesl(void __iomem *addr, const void *data, int len)
|
||||
{
|
||||
void __iomem *a = __isamem_convert_addr(addr);
|
||||
|
||||
BUG_ON((unsigned long)addr & 3);
|
||||
|
||||
__raw_writesl(a, data, len);
|
||||
}
|
||||
EXPORT_SYMBOL(writesl);
|
||||
|
||||
/*
|
||||
* The EBSA110 has a weird "ISA IO" region:
|
||||
*
|
||||
* Region 0 (addr = 0xf0000000 + io << 2)
|
||||
* --------------------------------------------------------
|
||||
* Physical region IO region
|
||||
* f0000fe0 - f0000ffc 3f8 - 3ff ttyS0
|
||||
* f0000e60 - f0000e64 398 - 399
|
||||
* f0000de0 - f0000dfc 378 - 37f lp0
|
||||
* f0000be0 - f0000bfc 2f8 - 2ff ttyS1
|
||||
*
|
||||
* Region 1 (addr = 0xf0000000 + (io & ~1) << 1 + (io & 1))
|
||||
* --------------------------------------------------------
|
||||
* Physical region IO region
|
||||
* f00014f1 a79 pnp write data
|
||||
* f00007c0 - f00007c1 3e0 - 3e1 pcmcia
|
||||
* f00004f1 279 pnp address
|
||||
* f0000440 - f000046c 220 - 236 eth0
|
||||
* f0000405 203 pnp read data
|
||||
*/
|
||||
#define SUPERIO_PORT(p) \
|
||||
(((p) >> 3) == (0x3f8 >> 3) || \
|
||||
((p) >> 3) == (0x2f8 >> 3) || \
|
||||
((p) >> 3) == (0x378 >> 3))
|
||||
|
||||
/*
|
||||
* We're addressing an 8 or 16-bit peripheral which tranfers
|
||||
* odd addresses on the low ISA byte lane.
|
||||
*/
|
||||
u8 __inb8(unsigned int port)
|
||||
{
|
||||
u32 ret;
|
||||
|
||||
/*
|
||||
* The SuperIO registers use sane addressing techniques...
|
||||
*/
|
||||
if (SUPERIO_PORT(port))
|
||||
ret = __raw_readb((void __iomem *)ISAIO_BASE + (port << 2));
|
||||
else {
|
||||
void __iomem *a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1);
|
||||
|
||||
/*
|
||||
* Shame nothing else does
|
||||
*/
|
||||
if (port & 1)
|
||||
ret = __raw_readl(a);
|
||||
else
|
||||
ret = __raw_readb(a);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* We're addressing a 16-bit peripheral which transfers odd
|
||||
* addresses on the high ISA byte lane.
|
||||
*/
|
||||
u8 __inb16(unsigned int port)
|
||||
{
|
||||
unsigned int offset;
|
||||
|
||||
/*
|
||||
* The SuperIO registers use sane addressing techniques...
|
||||
*/
|
||||
if (SUPERIO_PORT(port))
|
||||
offset = port << 2;
|
||||
else
|
||||
offset = (port & ~1) << 1 | (port & 1);
|
||||
|
||||
return __raw_readb((void __iomem *)ISAIO_BASE + offset);
|
||||
}
|
||||
|
||||
u16 __inw(unsigned int port)
|
||||
{
|
||||
unsigned int offset;
|
||||
|
||||
/*
|
||||
* The SuperIO registers use sane addressing techniques...
|
||||
*/
|
||||
if (SUPERIO_PORT(port))
|
||||
offset = port << 2;
|
||||
else {
|
||||
offset = port << 1;
|
||||
BUG_ON(port & 1);
|
||||
}
|
||||
return __raw_readw((void __iomem *)ISAIO_BASE + offset);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fake a 32-bit read with two 16-bit reads. Needed for 3c589.
|
||||
*/
|
||||
u32 __inl(unsigned int port)
|
||||
{
|
||||
void __iomem *a;
|
||||
|
||||
if (SUPERIO_PORT(port) || port & 3)
|
||||
BUG();
|
||||
|
||||
a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1);
|
||||
|
||||
return __raw_readw(a) | __raw_readw(a + 4) << 16;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(__inb8);
|
||||
EXPORT_SYMBOL(__inb16);
|
||||
EXPORT_SYMBOL(__inw);
|
||||
EXPORT_SYMBOL(__inl);
|
||||
|
||||
void __outb8(u8 val, unsigned int port)
|
||||
{
|
||||
/*
|
||||
* The SuperIO registers use sane addressing techniques...
|
||||
*/
|
||||
if (SUPERIO_PORT(port))
|
||||
__raw_writeb(val, (void __iomem *)ISAIO_BASE + (port << 2));
|
||||
else {
|
||||
void __iomem *a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1);
|
||||
|
||||
/*
|
||||
* Shame nothing else does
|
||||
*/
|
||||
if (port & 1)
|
||||
__raw_writel(val, a);
|
||||
else
|
||||
__raw_writeb(val, a);
|
||||
}
|
||||
}
|
||||
|
||||
void __outb16(u8 val, unsigned int port)
|
||||
{
|
||||
unsigned int offset;
|
||||
|
||||
/*
|
||||
* The SuperIO registers use sane addressing techniques...
|
||||
*/
|
||||
if (SUPERIO_PORT(port))
|
||||
offset = port << 2;
|
||||
else
|
||||
offset = (port & ~1) << 1 | (port & 1);
|
||||
|
||||
__raw_writeb(val, (void __iomem *)ISAIO_BASE + offset);
|
||||
}
|
||||
|
||||
void __outw(u16 val, unsigned int port)
|
||||
{
|
||||
unsigned int offset;
|
||||
|
||||
/*
|
||||
* The SuperIO registers use sane addressing techniques...
|
||||
*/
|
||||
if (SUPERIO_PORT(port))
|
||||
offset = port << 2;
|
||||
else {
|
||||
offset = port << 1;
|
||||
BUG_ON(port & 1);
|
||||
}
|
||||
__raw_writew(val, (void __iomem *)ISAIO_BASE + offset);
|
||||
}
|
||||
|
||||
void __outl(u32 val, unsigned int port)
|
||||
{
|
||||
BUG();
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(__outb8);
|
||||
EXPORT_SYMBOL(__outb16);
|
||||
EXPORT_SYMBOL(__outw);
|
||||
EXPORT_SYMBOL(__outl);
|
||||
|
||||
void outsb(unsigned int port, const void *from, int len)
|
||||
{
|
||||
u32 off;
|
||||
|
||||
if (SUPERIO_PORT(port))
|
||||
off = port << 2;
|
||||
else {
|
||||
off = (port & ~1) << 1;
|
||||
if (port & 1)
|
||||
BUG();
|
||||
}
|
||||
|
||||
__raw_writesb((void __iomem *)ISAIO_BASE + off, from, len);
|
||||
}
|
||||
|
||||
void insb(unsigned int port, void *from, int len)
|
||||
{
|
||||
u32 off;
|
||||
|
||||
if (SUPERIO_PORT(port))
|
||||
off = port << 2;
|
||||
else {
|
||||
off = (port & ~1) << 1;
|
||||
if (port & 1)
|
||||
BUG();
|
||||
}
|
||||
|
||||
__raw_readsb((void __iomem *)ISAIO_BASE + off, from, len);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(outsb);
|
||||
EXPORT_SYMBOL(insb);
|
||||
|
||||
void outsw(unsigned int port, const void *from, int len)
|
||||
{
|
||||
u32 off;
|
||||
|
||||
if (SUPERIO_PORT(port))
|
||||
off = port << 2;
|
||||
else {
|
||||
off = (port & ~1) << 1;
|
||||
if (port & 1)
|
||||
BUG();
|
||||
}
|
||||
|
||||
__raw_writesw((void __iomem *)ISAIO_BASE + off, from, len);
|
||||
}
|
||||
|
||||
void insw(unsigned int port, void *from, int len)
|
||||
{
|
||||
u32 off;
|
||||
|
||||
if (SUPERIO_PORT(port))
|
||||
off = port << 2;
|
||||
else {
|
||||
off = (port & ~1) << 1;
|
||||
if (port & 1)
|
||||
BUG();
|
||||
}
|
||||
|
||||
__raw_readsw((void __iomem *)ISAIO_BASE + off, from, len);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(outsw);
|
||||
EXPORT_SYMBOL(insw);
|
||||
|
||||
/*
|
||||
* We implement these as 16-bit insw/outsw, mainly for
|
||||
* 3c589 cards.
|
||||
*/
|
||||
void outsl(unsigned int port, const void *from, int len)
|
||||
{
|
||||
u32 off = port << 1;
|
||||
|
||||
if (SUPERIO_PORT(port) || port & 3)
|
||||
BUG();
|
||||
|
||||
__raw_writesw((void __iomem *)ISAIO_BASE + off, from, len << 1);
|
||||
}
|
||||
|
||||
void insl(unsigned int port, void *from, int len)
|
||||
{
|
||||
u32 off = port << 1;
|
||||
|
||||
if (SUPERIO_PORT(port) || port & 3)
|
||||
BUG();
|
||||
|
||||
__raw_readsw((void __iomem *)ISAIO_BASE + off, from, len << 1);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(outsl);
|
||||
EXPORT_SYMBOL(insl);
|
71
arch/arm/mach-ebsa110/leds.c
Normal file
71
arch/arm/mach-ebsa110/leds.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Driver for the LED found on the EBSA110 machine
|
||||
* Based on Versatile and RealView machine LED code
|
||||
*
|
||||
* License terms: GNU General Public License (GPL) version 2
|
||||
* Author: Bryan Wu <bryan.wu@canonical.com>
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/leds.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include "core.h"
|
||||
|
||||
#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
|
||||
static void ebsa110_led_set(struct led_classdev *cdev,
|
||||
enum led_brightness b)
|
||||
{
|
||||
u8 reg = __raw_readb(SOFT_BASE);
|
||||
|
||||
if (b != LED_OFF)
|
||||
reg |= 0x80;
|
||||
else
|
||||
reg &= ~0x80;
|
||||
|
||||
__raw_writeb(reg, SOFT_BASE);
|
||||
}
|
||||
|
||||
static enum led_brightness ebsa110_led_get(struct led_classdev *cdev)
|
||||
{
|
||||
u8 reg = __raw_readb(SOFT_BASE);
|
||||
|
||||
return (reg & 0x80) ? LED_FULL : LED_OFF;
|
||||
}
|
||||
|
||||
static int __init ebsa110_leds_init(void)
|
||||
{
|
||||
|
||||
struct led_classdev *cdev;
|
||||
int ret;
|
||||
|
||||
if (!machine_is_ebsa110())
|
||||
return -ENODEV;
|
||||
|
||||
cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
|
||||
if (!cdev)
|
||||
return -ENOMEM;
|
||||
|
||||
cdev->name = "ebsa110:0";
|
||||
cdev->brightness_set = ebsa110_led_set;
|
||||
cdev->brightness_get = ebsa110_led_get;
|
||||
cdev->default_trigger = "heartbeat";
|
||||
|
||||
ret = led_classdev_register(NULL, cdev);
|
||||
if (ret < 0) {
|
||||
kfree(cdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since we may have triggers on any subsystem, defer registration
|
||||
* until after subsystem_init.
|
||||
*/
|
||||
fs_initcall(ebsa110_leds_init);
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue