Commit 8f29e650 authored by Jordan Crouse's avatar Jordan Crouse Committed by Bartlomiej Zolnierkiewicz

[PATCH] ide: AU1200 IDE update

Changes here include removing all of CONFIG_PM while it is being repeatedly
smacked with a lead pipe, moving the BURSTMODE param to a #define (it should
be defined almost always anyway), fixing the rqsize stuff, pulling ide_ioreg_t,
and general cleanups and whatnot.
Signed-off-by: default avatarJordan Crouse <jordan.crouse@amd.com>
Signed-off-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
parent 65e5f2e3
...@@ -807,14 +807,6 @@ config BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA ...@@ -807,14 +807,6 @@ config BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
depends on SOC_AU1200 && BLK_DEV_IDE_AU1XXX depends on SOC_AU1200 && BLK_DEV_IDE_AU1XXX
endchoice endchoice
config BLK_DEV_IDE_AU1XXX_BURSTABLE_ON
bool "Enable burstable Mode on DbDMA"
default false
depends BLK_DEV_IDE_AU1XXX
help
This option enable the burstable Flag on DbDMA controller
(cf. "AMD Alchemy 'Au1200' Processor Data Book - PRELIMINARY").
config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ
int "Maximum transfer size (KB) per request (up to 128)" int "Maximum transfer size (KB) per request (up to 128)"
default "128" default "128"
......
obj-$(CONFIG_BLK_DEV_IDE_SWARM) += swarm.o obj-$(CONFIG_BLK_DEV_IDE_SWARM) += swarm.o
obj-$(CONFIG_BLK_DEV_IDE_AU1XXX) += au1xxx-ide.o
EXTRA_CFLAGS := -Idrivers/ide
...@@ -31,63 +31,40 @@ ...@@ -31,63 +31,40 @@
*/ */
#undef REALLY_SLOW_IO /* most systems can safely undef this */ #undef REALLY_SLOW_IO /* most systems can safely undef this */
#include <linux/config.h> /* for CONFIG_BLK_DEV_IDEPCI */
#include <linux/types.h> #include <linux/types.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/timer.h> #include <linux/platform_device.h>
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/hdreg.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/ide.h> #include <linux/ide.h>
#include <linux/sysdev.h> #include <linux/sysdev.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include "ide-timing.h"
#include <asm/io.h> #include <asm/io.h>
#include <asm/mach-au1x00/au1xxx.h> #include <asm/mach-au1x00/au1xxx.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h> #include <asm/mach-au1x00/au1xxx_dbdma.h>
#if CONFIG_PM
#include <asm/mach-au1x00/au1xxx_pm.h>
#endif
#include <asm/mach-au1x00/au1xxx_ide.h> #include <asm/mach-au1x00/au1xxx_ide.h>
#define DRV_NAME "au1200-ide" #define DRV_NAME "au1200-ide"
#define DRV_VERSION "1.0" #define DRV_VERSION "1.0"
#define DRV_AUTHOR "AMD PCS / Pete Popov <ppopov@embeddedalley.com>" #define DRV_AUTHOR "Enrico Walther <enrico.walther@amd.com> / Pete Popov <ppopov@embeddedalley.com>"
#define DRV_DESC "Au1200 IDE"
static _auide_hwif auide_hwif; /* enable the burstmode in the dbdma */
static spinlock_t ide_tune_drive_spin_lock = SPIN_LOCK_UNLOCKED; #define IDE_AU1XXX_BURSTMODE 1
static spinlock_t ide_tune_chipset_spin_lock = SPIN_LOCK_UNLOCKED;
static int dbdma_init_done = 0;
/*
* local I/O functions
*/
u8 auide_inb(unsigned long port)
{
return (au_readb(port));
}
u16 auide_inw(unsigned long port) static _auide_hwif auide_hwif;
{ static int dbdma_init_done;
return (au_readw(port));
}
u32 auide_inl(unsigned long port) #if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
{
return (au_readl(port));
}
void auide_insw(unsigned long port, void *addr, u32 count) void auide_insw(unsigned long port, void *addr, u32 count)
{ {
#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
_auide_hwif *ahwif = &auide_hwif; _auide_hwif *ahwif = &auide_hwif;
chan_tab_t *ctp; chan_tab_t *ctp;
au1x_ddma_desc_t *dp; au1x_ddma_desc_t *dp;
...@@ -102,50 +79,10 @@ void auide_insw(unsigned long port, void *addr, u32 count) ...@@ -102,50 +79,10 @@ void auide_insw(unsigned long port, void *addr, u32 count)
while (dp->dscr_cmd0 & DSCR_CMD0_V) while (dp->dscr_cmd0 & DSCR_CMD0_V)
; ;
ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp); ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
#else
while (count--)
{
*(u16 *)addr = au_readw(port);
addr +=2 ;
}
#endif
}
void auide_insl(unsigned long port, void *addr, u32 count)
{
while (count--)
{
*(u32 *)addr = au_readl(port);
/* NOTE: For IDE interfaces over PCMCIA,
* 32-bit access does not work
*/
addr += 4;
}
}
void auide_outb(u8 addr, unsigned long port)
{
return (au_writeb(addr, port));
}
void auide_outbsync(ide_drive_t *drive, u8 addr, unsigned long port)
{
return (au_writeb(addr, port));
}
void auide_outw(u16 addr, unsigned long port)
{
return (au_writew(addr, port));
}
void auide_outl(u32 addr, unsigned long port)
{
return (au_writel(addr, port));
} }
void auide_outsw(unsigned long port, void *addr, u32 count) void auide_outsw(unsigned long port, void *addr, u32 count)
{ {
#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
_auide_hwif *ahwif = &auide_hwif; _auide_hwif *ahwif = &auide_hwif;
chan_tab_t *ctp; chan_tab_t *ctp;
au1x_ddma_desc_t *dp; au1x_ddma_desc_t *dp;
...@@ -160,75 +97,40 @@ void auide_outsw(unsigned long port, void *addr, u32 count) ...@@ -160,75 +97,40 @@ void auide_outsw(unsigned long port, void *addr, u32 count)
while (dp->dscr_cmd0 & DSCR_CMD0_V) while (dp->dscr_cmd0 & DSCR_CMD0_V)
; ;
ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp); ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
#else
while (count--)
{
au_writew(*(u16 *)addr, port);
addr += 2;
}
#endif
} }
void auide_outsl(unsigned long port, void *addr, u32 count) #endif
{
while (count--)
{
au_writel(*(u32 *)addr, port);
/* NOTE: For IDE interfaces over PCMCIA,
* 32-bit access does not work
*/
addr += 4;
}
}
static void auide_tune_drive(ide_drive_t *drive, byte pio) static void auide_tune_drive(ide_drive_t *drive, byte pio)
{ {
int mem_sttime; int mem_sttime;
int mem_stcfg; int mem_stcfg;
unsigned long flags;
u8 speed; u8 speed;
/* get the best pio mode for the drive */ /* get the best pio mode for the drive */
pio = ide_get_best_pio_mode(drive, pio, 4, NULL); pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
printk("%s: setting Au1XXX IDE to PIO mode%d\n", printk(KERN_INFO "%s: setting Au1XXX IDE to PIO mode%d\n",
drive->name, pio); drive->name, pio);
spin_lock_irqsave(&ide_tune_drive_spin_lock, flags);
mem_sttime = 0; mem_sttime = 0;
mem_stcfg = au_readl(MEM_STCFG2); mem_stcfg = au_readl(MEM_STCFG2);
/* set pio mode! */ /* set pio mode! */
switch(pio) { switch(pio) {
case 0: case 0:
/* set timing parameters for RCS2# */ mem_sttime = SBC_IDE_TIMING(PIO0);
mem_sttime = SBC_IDE_PIO0_TWCS
| SBC_IDE_PIO0_TCSH
| SBC_IDE_PIO0_TCSOFF
| SBC_IDE_PIO0_TWP
| SBC_IDE_PIO0_TCSW
| SBC_IDE_PIO0_TPM
| SBC_IDE_PIO0_TA;
/* set configuration for RCS2# */ /* set configuration for RCS2# */
mem_stcfg |= TS_MASK; mem_stcfg |= TS_MASK;
mem_stcfg &= ~TCSOE_MASK; mem_stcfg &= ~TCSOE_MASK;
mem_stcfg &= ~TOECS_MASK; mem_stcfg &= ~TOECS_MASK;
mem_stcfg |= SBC_IDE_PIO0_TCSOE | SBC_IDE_PIO0_TOECS; mem_stcfg |= SBC_IDE_PIO0_TCSOE | SBC_IDE_PIO0_TOECS;
au_writel(mem_sttime,MEM_STTIME2);
au_writel(mem_stcfg,MEM_STCFG2);
break; break;
case 1: case 1:
/* set timing parameters for RCS2# */ mem_sttime = SBC_IDE_TIMING(PIO1);
mem_sttime = SBC_IDE_PIO1_TWCS
| SBC_IDE_PIO1_TCSH
| SBC_IDE_PIO1_TCSOFF
| SBC_IDE_PIO1_TWP
| SBC_IDE_PIO1_TCSW
| SBC_IDE_PIO1_TPM
| SBC_IDE_PIO1_TA;
/* set configuration for RCS2# */ /* set configuration for RCS2# */
mem_stcfg |= TS_MASK; mem_stcfg |= TS_MASK;
mem_stcfg &= ~TCSOE_MASK; mem_stcfg &= ~TCSOE_MASK;
...@@ -237,14 +139,8 @@ static void auide_tune_drive(ide_drive_t *drive, byte pio) ...@@ -237,14 +139,8 @@ static void auide_tune_drive(ide_drive_t *drive, byte pio)
break; break;
case 2: case 2:
/* set timing parameters for RCS2# */ mem_sttime = SBC_IDE_TIMING(PIO2);
mem_sttime = SBC_IDE_PIO2_TWCS
| SBC_IDE_PIO2_TCSH
| SBC_IDE_PIO2_TCSOFF
| SBC_IDE_PIO2_TWP
| SBC_IDE_PIO2_TCSW
| SBC_IDE_PIO2_TPM
| SBC_IDE_PIO2_TA;
/* set configuration for RCS2# */ /* set configuration for RCS2# */
mem_stcfg &= ~TS_MASK; mem_stcfg &= ~TS_MASK;
mem_stcfg &= ~TCSOE_MASK; mem_stcfg &= ~TCSOE_MASK;
...@@ -253,16 +149,9 @@ static void auide_tune_drive(ide_drive_t *drive, byte pio) ...@@ -253,16 +149,9 @@ static void auide_tune_drive(ide_drive_t *drive, byte pio)
break; break;
case 3: case 3:
/* set timing parameters for RCS2# */ mem_sttime = SBC_IDE_TIMING(PIO3);
mem_sttime = SBC_IDE_PIO3_TWCS
| SBC_IDE_PIO3_TCSH
| SBC_IDE_PIO3_TCSOFF
| SBC_IDE_PIO3_TWP
| SBC_IDE_PIO3_TCSW
| SBC_IDE_PIO3_TPM
| SBC_IDE_PIO3_TA;
/* set configuration for RCS2# */ /* set configuration for RCS2# */
mem_stcfg |= TS_MASK;
mem_stcfg &= ~TS_MASK; mem_stcfg &= ~TS_MASK;
mem_stcfg &= ~TCSOE_MASK; mem_stcfg &= ~TCSOE_MASK;
mem_stcfg &= ~TOECS_MASK; mem_stcfg &= ~TOECS_MASK;
...@@ -271,14 +160,8 @@ static void auide_tune_drive(ide_drive_t *drive, byte pio) ...@@ -271,14 +160,8 @@ static void auide_tune_drive(ide_drive_t *drive, byte pio)
break; break;
case 4: case 4:
/* set timing parameters for RCS2# */ mem_sttime = SBC_IDE_TIMING(PIO4);
mem_sttime = SBC_IDE_PIO4_TWCS
| SBC_IDE_PIO4_TCSH
| SBC_IDE_PIO4_TCSOFF
| SBC_IDE_PIO4_TWP
| SBC_IDE_PIO4_TCSW
| SBC_IDE_PIO4_TPM
| SBC_IDE_PIO4_TA;
/* set configuration for RCS2# */ /* set configuration for RCS2# */
mem_stcfg &= ~TS_MASK; mem_stcfg &= ~TS_MASK;
mem_stcfg &= ~TCSOE_MASK; mem_stcfg &= ~TCSOE_MASK;
...@@ -290,61 +173,34 @@ static void auide_tune_drive(ide_drive_t *drive, byte pio) ...@@ -290,61 +173,34 @@ static void auide_tune_drive(ide_drive_t *drive, byte pio)
au_writel(mem_sttime,MEM_STTIME2); au_writel(mem_sttime,MEM_STTIME2);
au_writel(mem_stcfg,MEM_STCFG2); au_writel(mem_stcfg,MEM_STCFG2);
spin_unlock_irqrestore(&ide_tune_drive_spin_lock, flags);
speed = pio + XFER_PIO_0; speed = pio + XFER_PIO_0;
ide_config_drive_speed(drive, speed); ide_config_drive_speed(drive, speed);
} }
static int auide_tune_chipset (ide_drive_t *drive, u8 speed) static int auide_tune_chipset (ide_drive_t *drive, u8 speed)
{ {
u8 mode = 0;
int mem_sttime; int mem_sttime;
int mem_stcfg; int mem_stcfg;
unsigned long flags; unsigned long mode;
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
struct hd_driveid *id = drive->id;
/* #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
* Now see what the current drive is capable of, if (ide_use_dma(drive))
* selecting UDMA only if the mate said it was ok. mode = ide_dma_speed(drive, 0);
*/
if (id && (id->capability & 1) && drive->autodma &&
!__ide_dma_bad_drive(drive)) {
if (!mode && (id->field_valid & 2) && (id->dma_mword & 7)) {
if (id->dma_mword & 4)
mode = XFER_MW_DMA_2;
else if (id->dma_mword & 2)
mode = XFER_MW_DMA_1;
else if (id->dma_mword & 1)
mode = XFER_MW_DMA_0;
}
}
#endif #endif
spin_lock_irqsave(&ide_tune_chipset_spin_lock, flags);
mem_sttime = 0; mem_sttime = 0;
mem_stcfg = au_readl(MEM_STCFG2); mem_stcfg = au_readl(MEM_STCFG2);
if (speed >= XFER_PIO_0 && speed <= XFER_PIO_4) {
auide_tune_drive(drive, speed - XFER_PIO_0);
return 0;
}
switch(speed) { switch(speed) {
case XFER_PIO_4:
case XFER_PIO_3:
case XFER_PIO_2:
case XFER_PIO_1:
case XFER_PIO_0:
auide_tune_drive(drive, (speed - XFER_PIO_0));
break;
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
case XFER_MW_DMA_2: case XFER_MW_DMA_2:
/* set timing parameters for RCS2# */ mem_sttime = SBC_IDE_TIMING(MDMA2);
mem_sttime = SBC_IDE_MDMA2_TWCS
| SBC_IDE_MDMA2_TCSH
| SBC_IDE_MDMA2_TCSOFF
| SBC_IDE_MDMA2_TWP
| SBC_IDE_MDMA2_TCSW
| SBC_IDE_MDMA2_TPM
| SBC_IDE_MDMA2_TA;
/* set configuration for RCS2# */ /* set configuration for RCS2# */
mem_stcfg &= ~TS_MASK; mem_stcfg &= ~TS_MASK;
mem_stcfg &= ~TCSOE_MASK; mem_stcfg &= ~TCSOE_MASK;
...@@ -354,14 +210,8 @@ static int auide_tune_chipset (ide_drive_t *drive, u8 speed) ...@@ -354,14 +210,8 @@ static int auide_tune_chipset (ide_drive_t *drive, u8 speed)
mode = XFER_MW_DMA_2; mode = XFER_MW_DMA_2;
break; break;
case XFER_MW_DMA_1: case XFER_MW_DMA_1:
/* set timing parameters for RCS2# */ mem_sttime = SBC_IDE_TIMING(MDMA1);
mem_sttime = SBC_IDE_MDMA1_TWCS
| SBC_IDE_MDMA1_TCSH
| SBC_IDE_MDMA1_TCSOFF
| SBC_IDE_MDMA1_TWP
| SBC_IDE_MDMA1_TCSW
| SBC_IDE_MDMA1_TPM
| SBC_IDE_MDMA1_TA;
/* set configuration for RCS2# */ /* set configuration for RCS2# */
mem_stcfg &= ~TS_MASK; mem_stcfg &= ~TS_MASK;
mem_stcfg &= ~TCSOE_MASK; mem_stcfg &= ~TCSOE_MASK;
...@@ -371,14 +221,8 @@ static int auide_tune_chipset (ide_drive_t *drive, u8 speed) ...@@ -371,14 +221,8 @@ static int auide_tune_chipset (ide_drive_t *drive, u8 speed)
mode = XFER_MW_DMA_1; mode = XFER_MW_DMA_1;
break; break;
case XFER_MW_DMA_0: case XFER_MW_DMA_0:
/* set timing parameters for RCS2# */ mem_sttime = SBC_IDE_TIMING(MDMA0);
mem_sttime = SBC_IDE_MDMA0_TWCS
| SBC_IDE_MDMA0_TCSH
| SBC_IDE_MDMA0_TCSOFF
| SBC_IDE_MDMA0_TWP
| SBC_IDE_MDMA0_TCSW
| SBC_IDE_MDMA0_TPM
| SBC_IDE_MDMA0_TA;
/* set configuration for RCS2# */ /* set configuration for RCS2# */
mem_stcfg |= TS_MASK; mem_stcfg |= TS_MASK;
mem_stcfg &= ~TCSOE_MASK; mem_stcfg &= ~TCSOE_MASK;
...@@ -392,40 +236,20 @@ static int auide_tune_chipset (ide_drive_t *drive, u8 speed) ...@@ -392,40 +236,20 @@ static int auide_tune_chipset (ide_drive_t *drive, u8 speed)
return 1; return 1;
} }
/* if (ide_config_drive_speed(drive, mode))
* Tell the drive to switch to the new mode; abort on failure. return 1;
*/
if (!mode || ide_config_drive_speed(drive, mode))
{
return 1; /* failure */
}
au_writel(mem_sttime,MEM_STTIME2); au_writel(mem_sttime,MEM_STTIME2);
au_writel(mem_stcfg,MEM_STCFG2); au_writel(mem_stcfg,MEM_STCFG2);
spin_unlock_irqrestore(&ide_tune_chipset_spin_lock, flags);
return 0; return 0;
} }
/* /*
* Multi-Word DMA + DbDMA functions * Multi-Word DMA + DbDMA functions
*/ */
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
static int in_drive_list(struct hd_driveid *id, #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
const struct drive_list_entry *drive_table)
{
for ( ; drive_table->id_model ; drive_table++){
if ((!strcmp(drive_table->id_model, id->model)) &&
((strstr(drive_table->id_firmware, id->fw_rev)) ||
(!strcmp(drive_table->id_firmware, "ALL")))
)
return 1;
}
return 0;
}
static int auide_build_sglist(ide_drive_t *drive, struct request *rq) static int auide_build_sglist(ide_drive_t *drive, struct request *rq)
{ {
...@@ -518,7 +342,7 @@ static int auide_build_dmatable(ide_drive_t *drive) ...@@ -518,7 +342,7 @@ static int auide_build_dmatable(ide_drive_t *drive)
if (count) if (count)
return 1; return 1;
use_pio_instead: use_pio_instead:
dma_unmap_sg(ahwif->dev, dma_unmap_sg(ahwif->dev,
hwif->sg_table, hwif->sg_table,
hwif->sg_nents, hwif->sg_nents,
...@@ -543,64 +367,39 @@ static int auide_dma_end(ide_drive_t *drive) ...@@ -543,64 +367,39 @@ static int auide_dma_end(ide_drive_t *drive)
static void auide_dma_start(ide_drive_t *drive ) static void auide_dma_start(ide_drive_t *drive )
{ {
// printk("%s\n", __FUNCTION__);
} }
ide_startstop_t auide_dma_intr(ide_drive_t *drive)
{
//printk("%s\n", __FUNCTION__);
u8 stat = 0, dma_stat = 0;
dma_stat = HWIF(drive)->ide_dma_end(drive);
stat = HWIF(drive)->INB(IDE_STATUS_REG); /* get drive status */
if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
if (!dma_stat) {
struct request *rq = HWGROUP(drive)->rq;
ide_end_request(drive, 1, rq->nr_sectors);
return ide_stopped;
}
printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n",
drive->name, dma_stat);
}
return ide_error(drive, "dma_intr", stat);
}
static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command) static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command)
{ {
//printk("%s\n", __FUNCTION__);
/* issue cmd to drive */ /* issue cmd to drive */
ide_execute_command(drive, command, &auide_dma_intr, ide_execute_command(drive, command, &ide_dma_intr,
(2*WAIT_CMD), NULL); (2*WAIT_CMD), NULL);
} }
static int auide_dma_setup(ide_drive_t *drive) static int auide_dma_setup(ide_drive_t *drive)
{ {
// printk("%s\n", __FUNCTION__); struct request *rq = HWGROUP(drive)->rq;
if (drive->media != ide_disk)
return 1;
if (!auide_build_dmatable(drive)) if (!auide_build_dmatable(drive)) {
/* try PIO instead of DMA */ ide_map_sg(drive, rq);
return 1; return 1;
}
drive->waiting_for_dma = 1; drive->waiting_for_dma = 1;
return 0; return 0;
} }
static int auide_dma_check(ide_drive_t *drive) static int auide_dma_check(ide_drive_t *drive)
{ {
// printk("%s\n", __FUNCTION__); u8 speed;
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
if( !dbdma_init_done ){
auide_hwif.white_list = in_drive_list(drive->id, if( dbdma_init_done == 0 ){
auide_hwif.white_list = ide_in_drive_list(drive->id,
dma_white_list); dma_white_list);
auide_hwif.black_list = in_drive_list(drive->id, auide_hwif.black_list = ide_in_drive_list(drive->id,
dma_black_list); dma_black_list);
auide_hwif.drive = drive; auide_hwif.drive = drive;
auide_ddma_init(&auide_hwif); auide_ddma_init(&auide_hwif);
...@@ -609,22 +408,29 @@ static int auide_dma_check(ide_drive_t *drive) ...@@ -609,22 +408,29 @@ static int auide_dma_check(ide_drive_t *drive)
#endif #endif
/* Is the drive in our DMA black list? */ /* Is the drive in our DMA black list? */
if ( auide_hwif.black_list ) { if ( auide_hwif.black_list ) {
drive->using_dma = 0; drive->using_dma = 0;
printk("%s found in dma_blacklist[]! Disabling DMA.\n",
drive->id->model); /* Borrowed the warning message from ide-dma.c */
printk(KERN_WARNING "%s: Disabling DMA for %s (blacklisted)\n",
drive->name, drive->id->model);
} }
else else
drive->using_dma = 1; drive->using_dma = 1;
return HWIF(drive)->ide_dma_host_on(drive); speed = ide_find_best_mode(drive, XFER_PIO | XFER_MWDMA);
if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
return HWIF(drive)->ide_dma_on(drive);
return HWIF(drive)->ide_dma_off_quietly(drive);
} }
static int auide_dma_test_irq(ide_drive_t *drive) static int auide_dma_test_irq(ide_drive_t *drive)
{ {
// printk("%s\n", __FUNCTION__); if (drive->waiting_for_dma == 0)
if (!drive->waiting_for_dma)
printk(KERN_WARNING "%s: ide_dma_test_irq \ printk(KERN_WARNING "%s: ide_dma_test_irq \
called while not waiting\n", drive->name); called while not waiting\n", drive->name);
...@@ -643,13 +449,11 @@ static int auide_dma_test_irq(ide_drive_t *drive) ...@@ -643,13 +449,11 @@ static int auide_dma_test_irq(ide_drive_t *drive)
static int auide_dma_host_on(ide_drive_t *drive) static int auide_dma_host_on(ide_drive_t *drive)
{ {
// printk("%s\n", __FUNCTION__);
return 0; return 0;
} }
static int auide_dma_on(ide_drive_t *drive) static int auide_dma_on(ide_drive_t *drive)
{ {
// printk("%s\n", __FUNCTION__);
drive->using_dma = 1; drive->using_dma = 1;
return auide_dma_host_on(drive); return auide_dma_host_on(drive);
} }
...@@ -657,43 +461,48 @@ static int auide_dma_on(ide_drive_t *drive) ...@@ -657,43 +461,48 @@ static int auide_dma_on(ide_drive_t *drive)
static int auide_dma_host_off(ide_drive_t *drive) static int auide_dma_host_off(ide_drive_t *drive)
{ {
// printk("%s\n", __FUNCTION__);
return 0; return 0;
} }
static int auide_dma_off_quietly(ide_drive_t *drive) static int auide_dma_off_quietly(ide_drive_t *drive)
{ {
// printk("%s\n", __FUNCTION__);
drive->using_dma = 0; drive->using_dma = 0;
return auide_dma_host_off(drive); return auide_dma_host_off(drive);
} }
static int auide_dma_lostirq(ide_drive_t *drive) static int auide_dma_lostirq(ide_drive_t *drive)
{ {
// printk("%s\n", __FUNCTION__);
printk(KERN_ERR "%s: IRQ lost\n", drive->name); printk(KERN_ERR "%s: IRQ lost\n", drive->name);
return 0; return 0;
} }
static void auide_ddma_tx_callback(int irq, void *param, struct pt_regs *regs) static void auide_ddma_tx_callback(int irq, void *param, struct pt_regs *regs)
{ {
// printk("%s\n", __FUNCTION__);
_auide_hwif *ahwif = (_auide_hwif*)param; _auide_hwif *ahwif = (_auide_hwif*)param;
ahwif->drive->waiting_for_dma = 0; ahwif->drive->waiting_for_dma = 0;
return;
} }
static void auide_ddma_rx_callback(int irq, void *param, struct pt_regs *regs) static void auide_ddma_rx_callback(int irq, void *param, struct pt_regs *regs)
{ {
// printk("%s\n", __FUNCTION__);
_auide_hwif *ahwif = (_auide_hwif*)param; _auide_hwif *ahwif = (_auide_hwif*)param;
ahwif->drive->waiting_for_dma = 0; ahwif->drive->waiting_for_dma = 0;
return;
} }
#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 devwidth, u32 flags)
{
dev->dev_id = dev_id;
dev->dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
dev->dev_intlevel = 0;
dev->dev_intpolarity = 0;
dev->dev_tsize = tsize;
dev->dev_devwidth = devwidth;
dev->dev_flags = flags;
}
#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
static int auide_dma_timeout(ide_drive_t *drive) static int auide_dma_timeout(ide_drive_t *drive)
{ {
// printk("%s\n", __FUNCTION__); // printk("%s\n", __FUNCTION__);
...@@ -705,112 +514,49 @@ static int auide_dma_timeout(ide_drive_t *drive) ...@@ -705,112 +514,49 @@ static int auide_dma_timeout(ide_drive_t *drive)
return HWIF(drive)->ide_dma_end(drive); return HWIF(drive)->ide_dma_end(drive);
} }
#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
static int auide_ddma_init( _auide_hwif *auide ) static int auide_ddma_init(_auide_hwif *auide) {
{
// printk("%s\n", __FUNCTION__);
dbdev_tab_t source_dev_tab; dbdev_tab_t source_dev_tab, target_dev_tab;
#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA) u32 dev_id, tsize, devwidth, flags;
dbdev_tab_t target_dev_tab;
ide_hwif_t *hwif = auide->hwif; ide_hwif_t *hwif = auide->hwif;
char warning_output [2][80];
int i;
#endif
/* Add our custom device to DDMA device table */ dev_id = AU1XXX_ATA_DDMA_REQ;
/* Create our new device entries in the table */
#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
source_dev_tab.dev_id = AU1XXX_ATA_DDMA_REQ;
if( auide->white_list || auide->black_list ){
source_dev_tab.dev_tsize = 8;
source_dev_tab.dev_devwidth = 32;
source_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
source_dev_tab.dev_intlevel = 0;
source_dev_tab.dev_intpolarity = 0;
/* init device table for target - static bus controller - */
target_dev_tab.dev_id = DSCR_CMD0_ALWAYS;
target_dev_tab.dev_tsize = 8;
target_dev_tab.dev_devwidth = 32;
target_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
target_dev_tab.dev_intlevel = 0;
target_dev_tab.dev_intpolarity = 0;
target_dev_tab.dev_flags = DEV_FLAGS_ANYUSE;
}
else{
source_dev_tab.dev_tsize = 1;
source_dev_tab.dev_devwidth = 16;
source_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
source_dev_tab.dev_intlevel = 0;
source_dev_tab.dev_intpolarity = 0;
/* init device table for target - static bus controller - */
target_dev_tab.dev_id = DSCR_CMD0_ALWAYS;
target_dev_tab.dev_tsize = 1;
target_dev_tab.dev_devwidth = 16;
target_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
target_dev_tab.dev_intlevel = 0;
target_dev_tab.dev_intpolarity = 0;
target_dev_tab.dev_flags = DEV_FLAGS_ANYUSE;
sprintf(&warning_output[0][0],
"%s is not on ide driver white list.",
auide_hwif.drive->id->model);
for ( i=strlen(&warning_output[0][0]) ; i<76; i++ ){
sprintf(&warning_output[0][i]," ");
}
sprintf(&warning_output[1][0], if (auide->white_list || auide->black_list) {
"To add %s please read 'Documentation/mips/AU1xxx_IDE.README'.", tsize = 8;
auide_hwif.drive->id->model); devwidth = 32;
for ( i=strlen(&warning_output[1][0]) ; i<76; i++ ){
sprintf(&warning_output[1][i]," ");
} }
else {
tsize = 1;
devwidth = 16;
printk("\n****************************************"); printk(KERN_ERR "au1xxx-ide: %s is not on ide driver whitelist.\n",auide_hwif.drive->id->model);
printk("****************************************\n"); printk(KERN_ERR " please read 'Documentation/mips/AU1xxx_IDE.README'");
printk("* %s *\n",&warning_output[0][0]);
printk("* Switch to safe MWDMA Mode! ");
printk(" *\n");
printk("* %s *\n",&warning_output[1][0]);
printk("****************************************");
printk("****************************************\n\n");
} }
#ifdef IDE_AU1XXX_BURSTMODE
flags = DEV_FLAGS_SYNC | DEV_FLAGS_BURSTABLE;
#else #else
source_dev_tab.dev_id = DSCR_CMD0_ALWAYS; flags = DEV_FLAGS_SYNC;
source_dev_tab.dev_tsize = 8;
source_dev_tab.dev_devwidth = 32;
source_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR;
source_dev_tab.dev_intlevel = 0;
source_dev_tab.dev_intpolarity = 0;
#endif #endif
#if CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON /* setup dev_tab for tx channel */
/* set flags for tx channel */ auide_init_dbdma_dev( &source_dev_tab,
source_dev_tab.dev_flags = DEV_FLAGS_OUT dev_id,
| DEV_FLAGS_SYNC tsize, devwidth, DEV_FLAGS_OUT | flags);
| DEV_FLAGS_BURSTABLE;
auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab ); auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
/* set flags for rx channel */
source_dev_tab.dev_flags = DEV_FLAGS_IN
| DEV_FLAGS_SYNC
| DEV_FLAGS_BURSTABLE;
auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
#else
/* set flags for tx channel */
source_dev_tab.dev_flags = DEV_FLAGS_OUT | DEV_FLAGS_SYNC;
auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
/* set flags for rx channel */
source_dev_tab.dev_flags = DEV_FLAGS_IN | DEV_FLAGS_SYNC;
auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
#endif
#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA) auide_init_dbdma_dev( &source_dev_tab,
dev_id,
tsize, devwidth, DEV_FLAGS_IN | flags);
auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
/* We also need to add a target device for the DMA */
auide_init_dbdma_dev( &target_dev_tab,
(u32)DSCR_CMD0_ALWAYS,
tsize, devwidth, DEV_FLAGS_ANYUSE);
auide->target_dev_id = au1xxx_ddma_add_device(&target_dev_tab); auide->target_dev_id = au1xxx_ddma_add_device(&target_dev_tab);
/* Get a channel for TX */ /* Get a channel for TX */
...@@ -818,60 +564,87 @@ static int auide_ddma_init( _auide_hwif *auide ) ...@@ -818,60 +564,87 @@ static int auide_ddma_init( _auide_hwif *auide )
auide->tx_dev_id, auide->tx_dev_id,
auide_ddma_tx_callback, auide_ddma_tx_callback,
(void*)auide); (void*)auide);
/* Get a channel for RX */ /* Get a channel for RX */
auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id, auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,
auide->target_dev_id, auide->target_dev_id,
auide_ddma_rx_callback, auide_ddma_rx_callback,
(void*)auide); (void*)auide);
#else /* CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA */
/* auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan,
* Note: if call back is not enabled, update ctp->cur_ptr manually NUM_DESCRIPTORS);
*/ auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan,
NUM_DESCRIPTORS);
hwif->dmatable_cpu = dma_alloc_coherent(auide->dev,
PRD_ENTRIES * PRD_BYTES, /* 1 Page */
&hwif->dmatable_dma, GFP_KERNEL);
au1xxx_dbdma_start( auide->tx_chan );
au1xxx_dbdma_start( auide->rx_chan );
return 0;
}
#else
static int auide_ddma_init( _auide_hwif *auide )
{
dbdev_tab_t source_dev_tab;
int flags;
#ifdef IDE_AU1XXX_BURSTMODE
flags = DEV_FLAGS_SYNC | DEV_FLAGS_BURSTABLE;
#else
flags = DEV_FLAGS_SYNC;
#endif
/* setup dev_tab for tx channel */
auide_init_dbdma_dev( &source_dev_tab,
(u32)DSCR_CMD0_ALWAYS,
8, 32, DEV_FLAGS_OUT | flags);
auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
auide_init_dbdma_dev( &source_dev_tab,
(u32)DSCR_CMD0_ALWAYS,
8, 32, DEV_FLAGS_IN | flags);
auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
/* Get a channel for TX */
auide->tx_chan = au1xxx_dbdma_chan_alloc(DSCR_CMD0_ALWAYS, auide->tx_chan = au1xxx_dbdma_chan_alloc(DSCR_CMD0_ALWAYS,
auide->tx_dev_id, auide->tx_dev_id,
NULL, NULL,
(void*)auide); (void*)auide);
/* Get a channel for RX */
auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id, auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,
DSCR_CMD0_ALWAYS, DSCR_CMD0_ALWAYS,
NULL, NULL,
(void*)auide); (void*)auide);
#endif
auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan, auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan,
NUM_DESCRIPTORS); NUM_DESCRIPTORS);
auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan, auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan,
NUM_DESCRIPTORS); NUM_DESCRIPTORS);
#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
hwif->dmatable_cpu = dma_alloc_coherent(auide->dev,
PRD_ENTRIES * PRD_BYTES, /* 1 Page */
&hwif->dmatable_dma, GFP_KERNEL);
auide->sg_table = kmalloc(sizeof(struct scatterlist) * PRD_ENTRIES,
GFP_KERNEL|GFP_DMA);
if (auide->sg_table == NULL) {
return -ENOMEM;
}
#endif
au1xxx_dbdma_start( auide->tx_chan ); au1xxx_dbdma_start( auide->tx_chan );
au1xxx_dbdma_start( auide->rx_chan ); au1xxx_dbdma_start( auide->rx_chan );
return 0; return 0;
} }
#endif
static void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif) static void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif)
{ {
int i; int i;
#define ide_ioreg_t unsigned long unsigned long *ata_regs = hw->io_ports;
ide_ioreg_t *ata_regs = hw->io_ports;
/* fixme */ /* FIXME? */
for (i = 0; i < IDE_CONTROL_OFFSET; i++) { for (i = 0; i < IDE_CONTROL_OFFSET; i++) {
*ata_regs++ = (ide_ioreg_t) ahwif->regbase *ata_regs++ = ahwif->regbase + (i << AU1XXX_ATA_REG_OFFSET);
+ (ide_ioreg_t)(i << AU1XXX_ATA_REG_OFFSET);
} }
/* set the Alternative Status register */ /* set the Alternative Status register */
*ata_regs = (ide_ioreg_t) ahwif->regbase *ata_regs = ahwif->regbase + (14 << AU1XXX_ATA_REG_OFFSET);
+ (ide_ioreg_t)(14 << AU1XXX_ATA_REG_OFFSET);
} }
static int au_ide_probe(struct device *dev) static int au_ide_probe(struct device *dev)
...@@ -914,6 +687,8 @@ static int au_ide_probe(struct device *dev) ...@@ -914,6 +687,8 @@ static int au_ide_probe(struct device *dev)
goto out; goto out;
} }
/* FIXME: This might possibly break PCMCIA IDE devices */
hwif = &ide_hwifs[pdev->id]; hwif = &ide_hwifs[pdev->id];
hw_regs_t *hw = &hwif->hw; hw_regs_t *hw = &hwif->hw;
hwif->irq = hw->irq = ahwif->irq; hwif->irq = hw->irq = ahwif->irq;
...@@ -922,23 +697,15 @@ static int au_ide_probe(struct device *dev) ...@@ -922,23 +697,15 @@ static int au_ide_probe(struct device *dev)
auide_setup_ports(hw, ahwif); auide_setup_ports(hw, ahwif);
memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports)); memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports));
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ
hwif->rqsize = CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ;
hwif->rqsize = ((hwif->rqsize > AU1XXX_ATA_RQSIZE)
|| (hwif->rqsize < 32)) ? AU1XXX_ATA_RQSIZE : hwif->rqsize;
#else /* if kernel config is not set */
hwif->rqsize = AU1XXX_ATA_RQSIZE;
#endif
hwif->ultra_mask = 0x0; /* Disable Ultra DMA */ hwif->ultra_mask = 0x0; /* Disable Ultra DMA */
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
hwif->mwdma_mask = 0x07; /* Multimode-2 DMA */ hwif->mwdma_mask = 0x07; /* Multimode-2 DMA */
hwif->swdma_mask = 0x07; hwif->swdma_mask = 0x00;
#else #else
hwif->mwdma_mask = 0x0; hwif->mwdma_mask = 0x0;
hwif->swdma_mask = 0x0; hwif->swdma_mask = 0x0;
#endif #endif
//hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
hwif->noprobe = 0; hwif->noprobe = 0;
hwif->drives[0].unmask = 1; hwif->drives[0].unmask = 1;
hwif->drives[1].unmask = 1; hwif->drives[1].unmask = 1;
...@@ -947,18 +714,14 @@ static int au_ide_probe(struct device *dev) ...@@ -947,18 +714,14 @@ static int au_ide_probe(struct device *dev)
hwif->hold = 1; hwif->hold = 1;
hwif->mmio = 2; hwif->mmio = 2;
/* set up local I/O function entry points */ /* If the user has selected DDMA assisted copies,
hwif->INB = auide_inb; then set up a few local I/O function entry points
hwif->INW = auide_inw; */
hwif->INL = auide_inl;
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
hwif->INSW = auide_insw; hwif->INSW = auide_insw;
hwif->INSL = auide_insl;
hwif->OUTB = auide_outb;
hwif->OUTBSYNC = auide_outbsync;
hwif->OUTW = auide_outw;
hwif->OUTL = auide_outl;
hwif->OUTSW = auide_outsw; hwif->OUTSW = auide_outsw;
hwif->OUTSL = auide_outsl; #endif
hwif->tuneproc = &auide_tune_drive; hwif->tuneproc = &auide_tune_drive;
hwif->speedproc = &auide_tune_chipset; hwif->speedproc = &auide_tune_chipset;
...@@ -982,8 +745,7 @@ static int au_ide_probe(struct device *dev) ...@@ -982,8 +745,7 @@ static int au_ide_probe(struct device *dev)
hwif->drives[0].autodma = hwif->autodma; hwif->drives[0].autodma = hwif->autodma;
hwif->drives[1].autodma = hwif->autodma; hwif->drives[1].autodma = hwif->autodma;
hwif->atapi_dma = 1; hwif->atapi_dma = 1;
hwif->drives[0].using_dma = 1;
hwif->drives[1].using_dma = 1;
#else /* !CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */ #else /* !CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
hwif->autodma = 0; hwif->autodma = 0;
hwif->channel = 0; hwif->channel = 0;
...@@ -992,36 +754,9 @@ static int au_ide_probe(struct device *dev) ...@@ -992,36 +754,9 @@ static int au_ide_probe(struct device *dev)
hwif->config_data = 0; /* no chipset-specific code */ hwif->config_data = 0; /* no chipset-specific code */
hwif->drives[0].autodma = 0; hwif->drives[0].autodma = 0;
hwif->drives[0].drive_data = 0; /* no drive data */
hwif->drives[0].using_dma = 0;
hwif->drives[0].waiting_for_dma = 0;
hwif->drives[0].autotune = 1; /* 1=autotune, 2=noautotune, 0=default */ hwif->drives[0].autotune = 1; /* 1=autotune, 2=noautotune, 0=default */
/* secondary hdd not supported */
hwif->drives[1].autodma = 0;
hwif->drives[1].drive_data = 0;
hwif->drives[1].using_dma = 0;
hwif->drives[1].waiting_for_dma = 0;
hwif->drives[1].autotune = 2; /* 1=autotune, 2=noautotune, 0=default */
#endif
hwif->drives[0].io_32bit = 0; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
hwif->drives[1].io_32bit = 0; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
/*Register Driver with PM Framework*/
#ifdef CONFIG_PM
auide_hwif.pm.lock = SPIN_LOCK_UNLOCKED;
auide_hwif.pm.stopped = 0;
auide_hwif.pm.dev = new_au1xxx_power_device( "ide",
&au1200ide_pm_callback,
NULL);
if ( auide_hwif.pm.dev == NULL )
printk(KERN_INFO "Unable to create a power management \
device entry for the au1200-IDE.\n");
else
printk(KERN_INFO "Power management device entry for the \
au1200-IDE loaded.\n");
#endif #endif
hwif->drives[0].no_io_32bit = 1;
auide_hwif.hwif = hwif; auide_hwif.hwif = hwif;
hwif->hwif_data = &auide_hwif; hwif->hwif_data = &auide_hwif;
...@@ -1036,7 +771,7 @@ static int au_ide_probe(struct device *dev) ...@@ -1036,7 +771,7 @@ static int au_ide_probe(struct device *dev)
printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode ); printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode );
out: out:
return ret; return ret;
} }
...@@ -1069,180 +804,11 @@ static int __init au_ide_init(void) ...@@ -1069,180 +804,11 @@ static int __init au_ide_init(void)
return driver_register(&au1200_ide_driver); return driver_register(&au1200_ide_driver);
} }
static void __init au_ide_exit(void) static void __exit au_ide_exit(void)
{ {
driver_unregister(&au1200_ide_driver); driver_unregister(&au1200_ide_driver);
} }
#ifdef CONFIG_PM
int au1200ide_pm_callback( au1xxx_power_dev_t *dev,\
au1xxx_request_t request, void *data) {
unsigned int d, err = 0;
unsigned long flags;
spin_lock_irqsave(auide_hwif.pm.lock, flags);
switch (request){
case AU1XXX_PM_SLEEP:
err = au1xxxide_pm_sleep(dev);
break;
case AU1XXX_PM_WAKEUP:
d = *((unsigned int*)data);
if ( d > 0 && d <= 99) {
err = au1xxxide_pm_standby(dev);
}
else {
err = au1xxxide_pm_resume(dev);
}
break;
case AU1XXX_PM_GETSTATUS:
err = au1xxxide_pm_getstatus(dev);
break;
case AU1XXX_PM_ACCESS:
err = au1xxxide_pm_access(dev);
break;
case AU1XXX_PM_IDLE:
err = au1xxxide_pm_idle(dev);
break;
case AU1XXX_PM_CLEANUP:
err = au1xxxide_pm_cleanup(dev);
break;
default:
err = -1;
break;
}
spin_unlock_irqrestore(auide_hwif.pm.lock, flags);
return err;
}
static int au1xxxide_pm_standby( au1xxx_power_dev_t *dev ) {
return 0;
}
static int au1xxxide_pm_sleep( au1xxx_power_dev_t *dev ) {
int retval;
ide_hwif_t *hwif = auide_hwif.hwif;
struct request rq;
struct request_pm_state rqpm;
ide_task_t args;
if(auide_hwif.pm.stopped)
return -1;
/*
* wait until hard disc is ready
*/
if ( wait_for_ready(&hwif->drives[0], 35000) ) {
printk("Wait for drive sleep timeout!\n");
retval = -1;
}
/*
* sequenz to tell the high level ide driver that pm is resuming
*/
memset(&rq, 0, sizeof(rq));
memset(&rqpm, 0, sizeof(rqpm));
memset(&args, 0, sizeof(args));
rq.flags = REQ_PM_SUSPEND;
rq.special = &args;
rq.pm = &rqpm;
rqpm.pm_step = ide_pm_state_start_suspend;
rqpm.pm_state = PMSG_SUSPEND;
retval = ide_do_drive_cmd(&hwif->drives[0], &rq, ide_wait);
if (wait_for_ready (&hwif->drives[0], 35000)) {
printk("Wait for drive sleep timeout!\n");
retval = -1;
}
/*
* stop dbdma channels
*/
au1xxx_dbdma_reset(auide_hwif.tx_chan);
au1xxx_dbdma_reset(auide_hwif.rx_chan);
auide_hwif.pm.stopped = 1;
return retval;
}
static int au1xxxide_pm_resume( au1xxx_power_dev_t *dev ) {
int retval;
ide_hwif_t *hwif = auide_hwif.hwif;
struct request rq;
struct request_pm_state rqpm;
ide_task_t args;
if(!auide_hwif.pm.stopped)
return -1;
/*
* start dbdma channels
*/
au1xxx_dbdma_start(auide_hwif.tx_chan);
au1xxx_dbdma_start(auide_hwif.rx_chan);
/*
* wait until hard disc is ready
*/
if (wait_for_ready ( &hwif->drives[0], 35000)) {
printk("Wait for drive wake up timeout!\n");
retval = -1;
}
/*
* sequenz to tell the high level ide driver that pm is resuming
*/
memset(&rq, 0, sizeof(rq));
memset(&rqpm, 0, sizeof(rqpm));
memset(&args, 0, sizeof(args));
rq.flags = REQ_PM_RESUME;
rq.special = &args;
rq.pm = &rqpm;
rqpm.pm_step = ide_pm_state_start_resume;
rqpm.pm_state = PMSG_ON;
retval = ide_do_drive_cmd(&hwif->drives[0], &rq, ide_head_wait);
/*
* wait for hard disc
*/
if ( wait_for_ready(&hwif->drives[0], 35000) ) {
printk("Wait for drive wake up timeout!\n");
retval = -1;
}
auide_hwif.pm.stopped = 0;
return retval;
}
static int au1xxxide_pm_getstatus( au1xxx_power_dev_t *dev ) {
return dev->cur_state;
}
static int au1xxxide_pm_access( au1xxx_power_dev_t *dev ) {
if (dev->cur_state != AWAKE_STATE)
return 0;
else
return -1;
}
static int au1xxxide_pm_idle( au1xxx_power_dev_t *dev ) {
return 0;
}
static int au1xxxide_pm_cleanup( au1xxx_power_dev_t *dev ) {
return 0;
}
#endif /* CONFIG_PM */
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("AU1200 IDE driver"); MODULE_DESCRIPTION("AU1200 IDE driver");
......
...@@ -74,9 +74,6 @@ typedef struct ...@@ -74,9 +74,6 @@ typedef struct
u8 white_list, black_list; u8 white_list, black_list;
struct dbdma_cmd *dma_table_cpu; struct dbdma_cmd *dma_table_cpu;
dma_addr_t dma_table_dma; dma_addr_t dma_table_dma;
struct scatterlist *sg_table;
int sg_nents;
int sg_dma_direction;
#endif #endif
struct device *dev; struct device *dev;
int irq; int irq;
...@@ -162,13 +159,9 @@ int __init auide_probe(void); ...@@ -162,13 +159,9 @@ int __init auide_probe(void);
* Multi-Word DMA + DbDMA functions * Multi-Word DMA + DbDMA functions
*/ */
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
static int in_drive_list(struct hd_driveid *id,
const struct drive_list_entry *drive_table);
static int auide_build_sglist(ide_drive_t *drive, struct request *rq); static int auide_build_sglist(ide_drive_t *drive, struct request *rq);
static int auide_build_dmatable(ide_drive_t *drive); static int auide_build_dmatable(ide_drive_t *drive);
static int auide_dma_end(ide_drive_t *drive); static int auide_dma_end(ide_drive_t *drive);
static void auide_dma_start(ide_drive_t *drive );
ide_startstop_t auide_dma_intr (ide_drive_t *drive); ide_startstop_t auide_dma_intr (ide_drive_t *drive);
static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command); static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command);
static int auide_dma_setup(ide_drive_t *drive); static int auide_dma_setup(ide_drive_t *drive);
...@@ -183,8 +176,6 @@ int __init auide_probe(void); ...@@ -183,8 +176,6 @@ int __init auide_probe(void);
static void auide_ddma_rx_callback(int irq, void *param, static void auide_ddma_rx_callback(int irq, void *param,
struct pt_regs *regs); struct pt_regs *regs);
static int auide_dma_off_quietly(ide_drive_t *drive); static int auide_dma_off_quietly(ide_drive_t *drive);
static int auide_dma_timeout(ide_drive_t *drive);
#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */ #endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
/******************************************************************************* /*******************************************************************************
...@@ -294,3 +285,11 @@ int __init auide_probe(void); ...@@ -294,3 +285,11 @@ int __init auide_probe(void);
#define SBC_IDE_MDMA2_TPM (0x00<<6) #define SBC_IDE_MDMA2_TPM (0x00<<6)
#define SBC_IDE_MDMA2_TA (0x12<<0) #define SBC_IDE_MDMA2_TA (0x12<<0)
#define SBC_IDE_TIMING(mode) \
SBC_IDE_##mode##_TWCS | \
SBC_IDE_##mode##_TCSH | \
SBC_IDE_##mode##_TCSOFF | \
SBC_IDE_##mode##_TWP | \
SBC_IDE_##mode##_TCSW | \
SBC_IDE_##mode##_TPM | \
SBC_IDE_##mode##_TA
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