Commit 94fd05b4 authored by Marc Singer's avatar Marc Singer Committed by Russell King

[ARM PATCH] 2001/1: lh7a40x IDE cleanup

Patch from Marc Singer

This patch aligns the lh7a40x port with the updated structure of IDE
drivers.  It also removes an unused FIQ handler.  This patch is made
in order to get the lh7a40x port to build.
parent f94f9db6
......@@ -4,11 +4,10 @@
# Object file lists.
obj-y := fiq.o time.o
# generic.o
obj-y := time.o
obj-$(CONFIG_MACH_KEV7A400) += arch-kev7a400.o irq-lh7a400.o
obj-$(CONFIG_MACH_LPD7A400) += arch-lpd7a40x.o ide-lpd7a40x.o irq-lh7a400.o
obj-$(CONFIG_MACH_LPD7A404) += arch-lpd7a40x.o ide-lpd7a40x.o irq-lh7a404.o
obj-$(CONFIG_MACH_LPD7A400) += arch-lpd7a40x.o irq-lh7a400.o
obj-$(CONFIG_MACH_LPD7A404) += arch-lpd7a40x.o irq-lh7a404.o
obj-m :=
obj-n :=
......
/*
* linux/arch/arm/lib/lh7a400-fiqhandler.S
* Copyright (C) 2002, Lineo, Inc.
* based on linux/arch/arm/lib/floppydma.S, which is
* Copyright (C) 1995, 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.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
.text
.global fiqhandler_end
@ register usage:
@ r8 &interrupt controller registers
@ r9 &gpio registers
@ r11 work
@ r12 work
ENTRY(fiqhandler)
@ read the status register to find out which FIQ this is
ldr r12, [r8] @ intc->status
and r12, r12, #0xf @ only interested in low-order 4 bits
@ translate FIQ 0:3 to IRQ 23:26
@ disable this FIQ and enable the corresponding IRQ
str r12, [r8, #0xc] @ disable this FIQ
mov r12, r12, lsl #23 @ get the corresopnding IRQ bit
str r12, [r8, #0x8] @ enable that IRQ
subs pc, lr, #4
fiqhandler_end:
/* arch/arm/mach-lh7a40x/ide-lpd7a40x.c
*
* Copyright (C) 2004 Logic Product Development
*
* 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/config.h>
#include <linux/ide.h>
#include <asm/io.h>
#define IOBARRIER_READ readl (IOBARRIER_VIRT)
static u8 lpd7a40x_ide_inb (unsigned long port)
{
u16 v = (u16) readw (port & ~0x1);
IOBARRIER_READ;
if (port & 0x1)
v >>= 8;
return v & 0xff;
}
static u16 lpd7a40x_ide_inw (unsigned long port)
{
u16 v = (u16) readw (port);
IOBARRIER_READ;
return v;
}
static void lpd7a40x_ide_insw (unsigned long port, void *addr, u32 count)
{
while (count--) {
*((u16*) addr)++ = (u16) readw (port);
IOBARRIER_READ;
}
}
static u32 lpd7a40x_ide_inl (unsigned long port)
{
u32 v = (u16) readw (port);
IOBARRIER_READ;
v |= (u16) readw (port + 2);
IOBARRIER_READ;
return v;
}
static void lpd7a40x_ide_insl (unsigned long port, void *addr, u32 count)
{
while (count--) {
*((u16*) addr)++ = (u16) readw (port);
IOBARRIER_READ;
*((u16*) addr)++ = (u16) readw (port + 2);
IOBARRIER_READ;
}
}
/* lpd7a40x_ide_outb -- this function is complicated by the fact that
* the user wants to be able to do byte IO and the hardware cannot.
* In order to write the high byte, we need to write a short. So, we
* read before writing in order to maintain the register values that
* shouldn't change. This isn't a good idea for the data IO registers
* since reading from them will not return the current value. We
* expect that this function handles the control register adequately.
*/
static void lpd7a40x_ide_outb (u8 valueUser, unsigned long port)
{
/* Block writes to SELECT register. Draconian, but the only
* way to cope with this hardware configuration without
* modifying the SELECT_DRIVE call in the ide driver. */
if ((port & 0xf) == 0x6)
return;
if (port & 0x1) { /* Perform read before write. Only
* the COMMAND register needs
* this. */
u16 value = (u16) readw (port & ~0x1);
IOBARRIER_READ;
value = (value & 0x00ff) | (valueUser << 8);
writew (value, port & ~0x1);
IOBARRIER_READ;
}
else { /* Allow low-byte writes which seem to
* be OK. */
writeb (valueUser, port);
IOBARRIER_READ;
}
}
static void lpd7a40x_ide_outbsync (ide_drive_t *drive, u8 value,
unsigned long port)
{
lpd7a40x_ide_outb (value, port);
}
static void lpd7a40x_ide_outw (u16 value, unsigned long port)
{
writew (value, port);
IOBARRIER_READ;
}
static void lpd7a40x_ide_outsw (unsigned long port, void *addr, u32 count)
{
while (count-- > 0) {
writew (*((u16*) addr)++, port);
IOBARRIER_READ;
}
}
static void lpd7a40x_ide_outl (u32 value, unsigned long port)
{
writel (value, port);
IOBARRIER_READ;
}
static void lpd7a40x_ide_outsl (unsigned long port, void *addr, u32 count)
{
while (count-- > 0) {
writel (*((u32*) addr)++, port);
IOBARRIER_READ;
}
}
void lpd7a40x_SELECT_DRIVE (ide_drive_t *drive)
{
unsigned jifStart = jiffies;
#define WAIT_TIME (30*HZ/1000)
/* Check for readiness. */
while ((HWIF(drive)->INB(IDE_STATUS_REG) & 0x40) == 0)
if (jifStart <= jiffies + WAIT_TIME)
return;
/* Only allow one drive.
For more information, see Documentation/arm/Sharp-LH/ */
if (drive->select.all & (1<<4))
return;
/* OUTW so that the IDLE_IMMEDIATE (and not NOP) command is sent. */
HWIF(drive)->OUTW(drive->select.all | 0xe100, IDE_SELECT_REG);
}
void lpd7a40x_hwif_ioops (ide_hwif_t *hwif)
{
hwif->mmio = 2; /* Just for show */
hwif->irq = IDE_NO_IRQ; /* Stop this probing */
hwif->OUTB = lpd7a40x_ide_outb;
hwif->OUTBSYNC = lpd7a40x_ide_outbsync;
hwif->OUTW = lpd7a40x_ide_outw;
hwif->OUTL = lpd7a40x_ide_outl;
hwif->OUTSW = lpd7a40x_ide_outsw;
hwif->OUTSL = lpd7a40x_ide_outsl;
hwif->INB = lpd7a40x_ide_inb;
hwif->INW = lpd7a40x_ide_inw;
hwif->INL = lpd7a40x_ide_inl;
hwif->INSW = lpd7a40x_ide_insw;
hwif->INSL = lpd7a40x_ide_insl;
hwif->selectproc = lpd7a40x_SELECT_DRIVE;
}
/* include/asm-arm/arch-lh7a40x/ide.h
*
* Copyright (C) 2004 Logic Product Development
*
* 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.
*
*/
#ifndef __ASM_ARCH_IDE_H
#define __ASM_ARCH_IDE_H
#if defined (CONFIG_MACH_LPD7A400) || defined (CONFIG_MACH_LPD7A404)
/* This implementation of ide.h only applies to the LPD CardEngines.
* Thankfully, there is less to do for the KEV.
*/
#include <linux/config.h>
#include <asm/irq.h>
#include <asm/hardware.h>
#include <asm/arch/registers.h>
#define IDE_REG_LINE (1<<12) /* A12 drives !REG */
#define IDE_ALT_LINE (1<<11) /* Unused A11 allows non-overlapping regions */
#define IDE_CONTROLREG_OFFSET (0xe)
void lpd7a40x_hwif_ioops (struct hwif_s* hwif);
static __inline__ void ide_init_hwif_ports (hw_regs_t *hw, int data_port,
int ctrl_port, int *irq)
{
ide_ioreg_t reg;
int i;
int regincr = 1;
memset (hw, 0, sizeof (*hw));
reg = (ide_ioreg_t) data_port;
for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
hw->io_ports[i] = reg;
reg += regincr;
}
hw->io_ports[IDE_CONTROL_OFFSET] = (ide_ioreg_t) ctrl_port;
if (irq)
*irq = IDE_NO_IRQ;
}
static __inline__ void ide_init_default_hwifs (void)
{
hw_regs_t hw;
struct hwif_s* hwif;
ide_init_hwif_ports (&hw,
CF_VIRT + IDE_REG_LINE,
CF_VIRT + IDE_REG_LINE + IDE_ALT_LINE
+ IDE_CONTROLREG_OFFSET,
NULL);
ide_register_hw (&hw, &hwif);
lpd7a40x_hwif_ioops (hwif); /* Override IO routines */
}
#endif
#endif
......@@ -17,18 +17,18 @@
#define MAX_HWIFS 4
#endif
#if defined(CONFIG_ARCH_LH7A40X) || defined(CONFIG_ARCH_SA1100)
#if defined(CONFIG_ARCH_SA1100)
# include <asm/arch/ide.h> /* obsolete + broken */
#endif
#if !defined(CONFIG_ARCH_L7200) && !defined(CONFIG_ARCH_LH7A40X)
#if !defined(CONFIG_ARCH_L7200)
# define IDE_ARCH_OBSOLETE_INIT
# ifdef CONFIG_ARCH_CLPS7500
# define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */
# else
# define ide_default_io_ctl(base) (0)
# endif
#endif /* !ARCH_L7200 && !ARCH_LH7A40X */
#endif /* !ARCH_L7200 */
#define __ide_mm_insw(port,addr,len) readsw(port,addr,len)
#define __ide_mm_insl(port,addr,len) readsl(port,addr,len)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment