ide-h8300.c revision cfd30daa0d6cbdb0bbc2bc40a10097231b23b204
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * H8/300 generic IDE interface 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ide.h> 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h> 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/irq.h> 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11eb3aff5530d22eb4be0a99c9d39c9ffde7b9891aBartlomiej Zolnierkiewicz#define DRV_NAME "ide-h8300" 12eb3aff5530d22eb4be0a99c9d39c9ffde7b9891aBartlomiej Zolnierkiewicz 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define bswap(d) \ 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds({ \ 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 r; \ 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __asm__("mov.b %w1,r1h\n\t" \ 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "mov.b %x1,r1l\n\t" \ 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "mov.w r1,%0" \ 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds :"=r"(r) \ 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds :"r"(d) \ 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds :"er1"); \ 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (r); \ 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}) 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mm_outsw(unsigned long addr, void *buf, u32 len) 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned short *bp = (unsigned short *)buf; 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (; len > 0; len--, bp++) 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(volatile u16 *)addr = bswap(*bp); 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mm_insw(unsigned long addr, void *buf, u32 len) 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned short *bp = (unsigned short *)buf; 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (; len > 0; len--, bp++) 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *bp = bswap(*(volatile u16 *)addr); 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 39adb1af9803d167091c2cb4de14014185054bfe2cBartlomiej Zolnierkiewiczstatic void h8300_input_data(ide_drive_t *drive, struct ide_cmd *cmd, 40f04ff9cbb6389a6db64659cf917a1b6ac159f9f2Bartlomiej Zolnierkiewicz void *buf, unsigned int len) 41f04ff9cbb6389a6db64659cf917a1b6ac159f9f2Bartlomiej Zolnierkiewicz{ 42f04ff9cbb6389a6db64659cf917a1b6ac159f9f2Bartlomiej Zolnierkiewicz mm_insw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2); 43f04ff9cbb6389a6db64659cf917a1b6ac159f9f2Bartlomiej Zolnierkiewicz} 44f04ff9cbb6389a6db64659cf917a1b6ac159f9f2Bartlomiej Zolnierkiewicz 45adb1af9803d167091c2cb4de14014185054bfe2cBartlomiej Zolnierkiewiczstatic void h8300_output_data(ide_drive_t *drive, struct ide_cmd *cmd, 46f04ff9cbb6389a6db64659cf917a1b6ac159f9f2Bartlomiej Zolnierkiewicz void *buf, unsigned int len) 47f04ff9cbb6389a6db64659cf917a1b6ac159f9f2Bartlomiej Zolnierkiewicz{ 48f04ff9cbb6389a6db64659cf917a1b6ac159f9f2Bartlomiej Zolnierkiewicz mm_outsw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2); 49f04ff9cbb6389a6db64659cf917a1b6ac159f9f2Bartlomiej Zolnierkiewicz} 50f04ff9cbb6389a6db64659cf917a1b6ac159f9f2Bartlomiej Zolnierkiewicz 51374e042c3e767ac2e5a40b78529220e0b3de793cBartlomiej Zolnierkiewiczstatic const struct ide_tp_ops h8300_tp_ops = { 52374e042c3e767ac2e5a40b78529220e0b3de793cBartlomiej Zolnierkiewicz .exec_command = ide_exec_command, 53374e042c3e767ac2e5a40b78529220e0b3de793cBartlomiej Zolnierkiewicz .read_status = ide_read_status, 54374e042c3e767ac2e5a40b78529220e0b3de793cBartlomiej Zolnierkiewicz .read_altstatus = ide_read_altstatus, 55ecf3a31d2a08a419bdf919456f1724f5b72bde2cSergei Shtylyov .write_devctl = ide_write_devctl, 56374e042c3e767ac2e5a40b78529220e0b3de793cBartlomiej Zolnierkiewicz 57abb596b25edac1ec1acc4ef53df190771661c3d2Sergei Shtylyov .dev_select = ide_dev_select, 58cfd30daa0d6cbdb0bbc2bc40a10097231b23b204Sergei Shtylyov .tf_load = ide_tf_load, 59cfd30daa0d6cbdb0bbc2bc40a10097231b23b204Sergei Shtylyov .tf_read = ide_tf_read, 60374e042c3e767ac2e5a40b78529220e0b3de793cBartlomiej Zolnierkiewicz 61374e042c3e767ac2e5a40b78529220e0b3de793cBartlomiej Zolnierkiewicz .input_data = h8300_input_data, 62374e042c3e767ac2e5a40b78529220e0b3de793cBartlomiej Zolnierkiewicz .output_data = h8300_output_data, 63374e042c3e767ac2e5a40b78529220e0b3de793cBartlomiej Zolnierkiewicz}; 64374e042c3e767ac2e5a40b78529220e0b3de793cBartlomiej Zolnierkiewicz 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define H8300_IDE_GAP (2) 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void hw_setup(hw_regs_t *hw) 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(hw, 0, sizeof(hw_regs_t)); 724c3032d8a4d6c97bd6e02bcab524ef2428d89561Bartlomiej Zolnierkiewicz for (i = 0; i <= 7; i++) 734c3032d8a4d6c97bd6e02bcab524ef2428d89561Bartlomiej Zolnierkiewicz hw->io_ports_array[i] = CONFIG_H8300_IDE_BASE + H8300_IDE_GAP*i; 744c3032d8a4d6c97bd6e02bcab524ef2428d89561Bartlomiej Zolnierkiewicz hw->io_ports.ctl_addr = CONFIG_H8300_IDE_ALT; 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hw->irq = EXT_IRQ0 + CONFIG_H8300_IDE_IRQ; 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hw->chipset = ide_generic; 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 79f81eb80bbb949f9498980c785ef7dd4c994a4909Bartlomiej Zolnierkiewiczstatic const struct ide_port_info h8300_port_info = { 80374e042c3e767ac2e5a40b78529220e0b3de793cBartlomiej Zolnierkiewicz .tp_ops = &h8300_tp_ops, 81f81eb80bbb949f9498980c785ef7dd4c994a4909Bartlomiej Zolnierkiewicz .host_flags = IDE_HFLAG_NO_IO_32BIT | IDE_HFLAG_NO_DMA, 82f81eb80bbb949f9498980c785ef7dd4c994a4909Bartlomiej Zolnierkiewicz}; 83f81eb80bbb949f9498980c785ef7dd4c994a4909Bartlomiej Zolnierkiewicz 84ade2daf9c6e57845fe83a24e0a9fa1c03c6e91b1Bartlomiej Zolnierkiewiczstatic int __init h8300_ide_init(void) 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 86c97c6aca75fd5f718056fde7cff798b8cbdb07c0Bartlomiej Zolnierkiewicz hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 88740c397cc64272917a4c4c283649579d2044a836Bartlomiej Zolnierkiewicz printk(KERN_INFO DRV_NAME ": H8/300 generic IDE interface\n"); 89740c397cc64272917a4c4c283649579d2044a836Bartlomiej Zolnierkiewicz 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!request_region(CONFIG_H8300_IDE_BASE, H8300_IDE_GAP*8, "ide-h8300")) 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_busy; 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!request_region(CONFIG_H8300_IDE_ALT, H8300_IDE_GAP, "ide-h8300")) { 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds release_region(CONFIG_H8300_IDE_BASE, H8300_IDE_GAP*8); 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_busy; 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hw_setup(&hw); 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 996f904d015262dfa43eb1cecc00b0998b4c3543f2Bartlomiej Zolnierkiewicz return ide_host_add(&h8300_port_info, hws, NULL); 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout_busy: 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "ide-h8300: IDE I/F resource already used.\n"); 103ade2daf9c6e57845fe83a24e0a9fa1c03c6e91b1Bartlomiej Zolnierkiewicz 104ade2daf9c6e57845fe83a24e0a9fa1c03c6e91b1Bartlomiej Zolnierkiewicz return -EBUSY; 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 106ade2daf9c6e57845fe83a24e0a9fa1c03c6e91b1Bartlomiej Zolnierkiewicz 107ade2daf9c6e57845fe83a24e0a9fa1c03c6e91b1Bartlomiej Zolnierkiewiczmodule_init(h8300_ide_init); 108f95dc32001445c6706ce0c337628b7c12d42a267Adrian Bunk 109f95dc32001445c6706ce0c337628b7c12d42a267Adrian BunkMODULE_LICENSE("GPL"); 110