ide-h8300.c revision f04ff9cbb6389a6db64659cf917a1b6ac159f9f2
130edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk/* 230edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk * H8/300 generic IDE interface 330edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk */ 430edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk 530edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk#include <linux/init.h> 630edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk#include <linux/ide.h> 730edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk 830edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk#include <asm/io.h> 930edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk#include <asm/irq.h> 1030edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk 1130edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk#define bswap(d) \ 1230edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk({ \ 1330edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk u16 r; \ 14a92336a1176b2119eaa990a1e8bf3109665fdbc6Konrad Rzeszutek Wilk __asm__("mov.b %w1,r1h\n\t" \ 1530edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk "mov.b %x1,r1l\n\t" \ 1630edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk "mov.w r1,%0" \ 1730edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk :"=r"(r) \ 1830edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk :"r"(d) \ 1930edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk :"er1"); \ 2030edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk (r); \ 2130edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk}) 2230edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk 2330edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilkstatic void mm_outw(u16 d, unsigned long a) 2430edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk{ 2530edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk __asm__("mov.b %w0,r2h\n\t" 2630edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk "mov.b %x0,r2l\n\t" 2730edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk "mov.w r2,@%1" 2830edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk : 29a92336a1176b2119eaa990a1e8bf3109665fdbc6Konrad Rzeszutek Wilk :"r"(d),"r"(a) 3030edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk :"er2"); 31a92336a1176b2119eaa990a1e8bf3109665fdbc6Konrad Rzeszutek Wilk} 3230edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk 33a92336a1176b2119eaa990a1e8bf3109665fdbc6Konrad Rzeszutek Wilkstatic u16 mm_inw(unsigned long a) 3430edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk{ 3530edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk register u16 r __asm__("er0"); 3630edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk __asm__("mov.w @%1,r2\n\t" 37a92336a1176b2119eaa990a1e8bf3109665fdbc6Konrad Rzeszutek Wilk "mov.b r2l,%x0\n\t" 38402c5e15b44070461dcc2f41536c16d0cfbca9c3Jan Beulich "mov.b r2h,%w0" 3930edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk :"=r"(r) 4030edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk :"r"(a) 4130edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk :"er2"); 4230edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk return r; 43a92336a1176b2119eaa990a1e8bf3109665fdbc6Konrad Rzeszutek Wilk} 4430edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk 45a92336a1176b2119eaa990a1e8bf3109665fdbc6Konrad Rzeszutek Wilkstatic void mm_outsw(unsigned long addr, void *buf, u32 len) 4630edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk{ 4730edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk unsigned short *bp = (unsigned short *)buf; 48a92336a1176b2119eaa990a1e8bf3109665fdbc6Konrad Rzeszutek Wilk for (; len > 0; len--, bp++) 4930edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk *(volatile u16 *)addr = bswap(*bp); 5030edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk} 51a92336a1176b2119eaa990a1e8bf3109665fdbc6Konrad Rzeszutek Wilk 5230edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilkstatic void mm_insw(unsigned long addr, void *buf, u32 len) 5330edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk{ 5430edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk unsigned short *bp = (unsigned short *)buf; 5530edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk for (; len > 0; len--, bp++) 5630edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk *bp = bswap(*(volatile u16 *)addr); 5730edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk} 5830edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk 5930edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilkstatic void h8300_input_data(ide_drive_t *drive, struct request *rq, 6030edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk void *buf, unsigned int len) 6130edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk{ 6230edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk mm_insw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2); 63a92336a1176b2119eaa990a1e8bf3109665fdbc6Konrad Rzeszutek Wilk} 6430edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk 6530edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilkstatic void h8300_output_data(ide_drive_t *drive, struct request *rq, 6630edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk void *buf, unsigned int len) 6730edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk{ 6830edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk mm_outsw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2); 6930edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk} 70a92336a1176b2119eaa990a1e8bf3109665fdbc6Konrad Rzeszutek Wilk 71a92336a1176b2119eaa990a1e8bf3109665fdbc6Konrad Rzeszutek Wilk#define H8300_IDE_GAP (2) 7230edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk 7330edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilkstatic inline void hw_setup(hw_regs_t *hw) 74a92336a1176b2119eaa990a1e8bf3109665fdbc6Konrad Rzeszutek Wilk{ 75a92336a1176b2119eaa990a1e8bf3109665fdbc6Konrad Rzeszutek Wilk int i; 7630edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk 7730edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk memset(hw, 0, sizeof(hw_regs_t)); 78a92336a1176b2119eaa990a1e8bf3109665fdbc6Konrad Rzeszutek Wilk for (i = 0; i <= 7; i++) 79a92336a1176b2119eaa990a1e8bf3109665fdbc6Konrad Rzeszutek Wilk hw->io_ports_array[i] = CONFIG_H8300_IDE_BASE + H8300_IDE_GAP*i; 8030edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk hw->io_ports.ctl_addr = CONFIG_H8300_IDE_ALT; 8130edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk hw->irq = EXT_IRQ0 + CONFIG_H8300_IDE_IRQ; 8230edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk hw->chipset = ide_generic; 8330edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk} 8430edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk 8530edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilkstatic inline void hwif_setup(ide_hwif_t *hwif) 86a92336a1176b2119eaa990a1e8bf3109665fdbc6Konrad Rzeszutek Wilk{ 8730edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk default_hwif_iops(hwif); 8830edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk 8930edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk hwif->input_data = h8300_input_data; 9030edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk hwif->output_data = h8300_output_data; 9130edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk 92a92336a1176b2119eaa990a1e8bf3109665fdbc6Konrad Rzeszutek Wilk hwif->OUTW = mm_outw; 9330edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk hwif->OUTSW = mm_outsw; 94a92336a1176b2119eaa990a1e8bf3109665fdbc6Konrad Rzeszutek Wilk hwif->INW = mm_inw; 9530edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk hwif->INSW = mm_insw; 9630edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk hwif->OUTSL = NULL; 9730edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk hwif->INSL = NULL; 9830edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk} 9930edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk 10030edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilkstatic int __init h8300_ide_init(void) 10130edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk{ 10230edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk hw_regs_t hw; 10330edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk ide_hwif_t *hwif; 10430edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk int index; 10530edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; 10630edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk 10730edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk if (!request_region(CONFIG_H8300_IDE_BASE, H8300_IDE_GAP*8, "ide-h8300")) 10830edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk goto out_busy; 10930edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk if (!request_region(CONFIG_H8300_IDE_ALT, H8300_IDE_GAP, "ide-h8300")) { 11030edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk release_region(CONFIG_H8300_IDE_BASE, H8300_IDE_GAP*8); 11130edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk goto out_busy; 11230edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk } 11330edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk 11430edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk hw_setup(&hw); 11530edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk 11630edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk hwif = ide_find_port(); 11730edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk if (hwif == NULL) { 118a92336a1176b2119eaa990a1e8bf3109665fdbc6Konrad Rzeszutek Wilk printk(KERN_ERR "ide-h8300: IDE I/F register failed\n"); 11930edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk return -ENOENT; 12030edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk } 12130edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk 12230edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk index = hwif->index; 123a92336a1176b2119eaa990a1e8bf3109665fdbc6Konrad Rzeszutek Wilk ide_init_port_data(hwif, index); 12430edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk ide_init_port_hw(hwif, &hw); 125a92336a1176b2119eaa990a1e8bf3109665fdbc6Konrad Rzeszutek Wilk hwif_setup(hwif); 12630edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk hwif->host_flags = IDE_HFLAG_NO_IO_32BIT; 12730edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk printk(KERN_INFO "ide%d: H8/300 generic IDE interface\n", index); 128a92336a1176b2119eaa990a1e8bf3109665fdbc6Konrad Rzeszutek Wilk 12930edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk idx[0] = index; 13030edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk 13130edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk ide_device_add(idx, NULL); 13230edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk 13330edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk return 0; 13430edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk 13530edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilkout_busy: 13630edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk printk(KERN_ERR "ide-h8300: IDE I/F resource already used.\n"); 13730edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk 13830edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk return -EBUSY; 13930edc14bf39afde24ef7db2de66c91805db80828Konrad Rzeszutek Wilk} 140 141module_init(h8300_ide_init); 142 143MODULE_LICENSE("GPL"); 144