From dwery. Index: linux-2.6.16/arch/arm/mach-ep93xx/ts72xx.c =================================================================== --- linux-2.6.16.orig/arch/arm/mach-ep93xx/ts72xx.c +++ linux-2.6.16/arch/arm/mach-ep93xx/ts72xx.c @@ -113,8 +113,8 @@ static void __init ts72xx_map_io(void) static struct resource ts7200_cf_resources[] = { [0] = { - .start = TS7200_CF_CTRL_PHYS_BASE, - .end = TS7200_CF_CTRL_PHYS_BASE + 7, + .start = TS7200_CF_CMD_PHYS_BASE, + .end = TS7200_CF_CMD_PHYS_BASE + 7, .flags = IORESOURCE_MEM, }, [1] = { Index: linux-2.6.16/drivers/scsi/Kconfig =================================================================== --- linux-2.6.16.orig/drivers/scsi/Kconfig +++ linux-2.6.16/drivers/scsi/Kconfig @@ -908,6 +908,9 @@ config SCSI_PATA_WINBOND If unsure, say N. +config SCSI_PATA_TS7200 + tristate "TS7200 Compact Flash support" + depends on MACH_TS72XX config SCSI_BUSLOGIC tristate "BusLogic SCSI support" Index: linux-2.6.16/drivers/scsi/Makefile =================================================================== --- linux-2.6.16.orig/drivers/scsi/Makefile +++ linux-2.6.16/drivers/scsi/Makefile @@ -174,6 +174,7 @@ obj-$(CONFIG_SCSI_PATA_VIA) += libata.o obj-$(CONFIG_SCSI_PATA_WINBOND) += libata.o pata_sl82c105.o obj-$(CONFIG_SCSI_ATA_GENERIC) += libata.o ata_generic.o obj-$(CONFIG_SCSI_PATA_LEGACY) += libata.o pata_legacy.o +obj-$(CONFIG_SCSI_PATA_TS7200) += libata.o pata_ts7200.o obj-$(CONFIG_ARM) += arm/ Index: linux-2.6.16/drivers/scsi/pata_ts7200.c =================================================================== --- /dev/null +++ linux-2.6.16/drivers/scsi/pata_ts7200.c @@ -0,0 +1,201 @@ +/* + * pata-ts7200.c - Legacy port PATA/SATA controller driver. + * Copyright (c) 2006 Tower Technologies + * Author: Alessandro Zummo + * + * An ATA driver to handle a Compact Flash connected + * to the ts7200. + */ + +#include +#include +#include +#include +#include + +#define DRV_NAME "pata_ts7200" +#define DRV_VERSION "0.1" + +static unsigned int ts7200_mode_filter(const struct ata_port *ap, + struct ata_device *adev, unsigned int mask, int shift) +{ + if (shift != ATA_SHIFT_PIO) + return 0; + return mask; +} + +static void ts7200_set_mode(struct ata_port *ap) +{ + int i; + + for (i = 0; i < ATA_MAX_DEVICES; i++) { + struct ata_device *dev = &ap->device[i]; + if (ata_dev_present(dev)) { + dev->pio_mode = XFER_PIO_0; + dev->xfer_mode = XFER_PIO_0; + dev->xfer_shift = ATA_SHIFT_PIO; + dev->flags |= ATA_DFLAG_PIO; + } + } +} + +static void ts7200_phy_reset(struct ata_port *ap) +{ + ap->cbl = ATA_CBL_PATA40; + ata_port_probe(ap); + ata_bus_reset(ap); +} + +void ts7200_irq_clear(struct ata_port *ap) +{ +} + +int ts7200_port_start(struct ata_port *ap) +{ + return 0; +} + +void ts7200_port_stop(struct ata_port *ap) +{ +} + +void ts7200_host_stop (struct ata_host_set *host_set) +{ +// struct device *dev = host_set->private_data; +// struct ts7200_pata_data *data = dev->platform_data; + + /* XXX iounmap here */ +} + +static struct scsi_host_template ts7200_sht = { + .module = THIS_MODULE, + .name = DRV_NAME, + .ioctl = ata_scsi_ioctl, + .queuecommand = ata_scsi_queuecmd, + .eh_strategy_handler = ata_scsi_error, + .can_queue = ATA_DEF_QUEUE, + .this_id = ATA_SHT_THIS_ID, + .sg_tablesize = LIBATA_MAX_PRD, + .max_sectors = ATA_MAX_SECTORS, + .cmd_per_lun = ATA_SHT_CMD_PER_LUN, + .emulated = ATA_SHT_EMULATED, + .use_clustering = ATA_SHT_USE_CLUSTERING, + .proc_name = DRV_NAME, + .dma_boundary = ATA_DMA_BOUNDARY, + .slave_configure = ata_scsi_slave_config, + .bios_param = ata_std_bios_param, +// .ordered_flush = 1, +}; + +static struct ata_port_operations ts7200_port_ops = { + .set_mode = ts7200_set_mode, + .mode_filter = ts7200_mode_filter, + + .port_disable = ata_port_disable, + .tf_load = ata_tf_load, + .tf_read = ata_tf_read, + .check_status = ata_check_status, + .exec_command = ata_exec_command, + .dev_select = ata_std_dev_select, + + .qc_prep = ata_qc_prep, + .qc_issue = ata_qc_issue_prot, + .eng_timeout = ata_eng_timeout, + + .irq_handler = ata_interrupt, + .irq_clear = ts7200_irq_clear, + + .port_start = ata_port_start, + .port_stop = ata_port_stop, + .host_stop = ts7200_host_stop, + + .phy_reset = ts7200_phy_reset, +}; + +static __devinit int ts7200_pata_probe(struct platform_device *dev) +{ + int ret; + struct ata_probe_ent ae; + +// struct ts7200_pata_data *data = dev->dev.platform_data; + + unsigned int irq = platform_get_irq(dev, 0); + struct resource *pata_cmd = platform_get_resource(dev, IORESOURCE_MEM, 0); + struct resource *pata_aux = platform_get_resource(dev, IORESOURCE_MEM, 1); + struct resource *pata_data = platform_get_resource(dev, IORESOURCE_MEM, 2); + + if (!pata_cmd || !pata_aux || !pata_data) + return -EINVAL; + +// data->cs0 = ioremap(cs0->start, 0x1000); +// data->cs1 = ioremap(cs1->start, 0x1000); + +/* if (irq) + set_irq_type(irq, IRQT_HIGH); +*/ + + memset(&ae, 0, sizeof(struct ata_probe_ent)); + INIT_LIST_HEAD(&ae.node); + + ae.dev = NULL; + ae.private_data = &dev->dev; + ae.port_ops = &ts7200_port_ops; + ae.sht = &ts7200_sht; + ae.n_ports = 1; + ae.pio_mask = 0x1f; /* PIO4 */ + ae.irq = 0; + ae.irq_flags = 0; + ae.host_flags = ATA_FLAG_IRQ_MASK | ATA_FLAG_MMIO; + + ae.port[0].cmd_addr = ioremap(pata_cmd->start, 8); + ae.port[0].altstatus_addr = ioremap(pata_aux->start, 2); + ae.port[0].ctl_addr = ae.port[0].altstatus_addr; + ata_std_ports(&ae.port[0]); + + ae.port[0].data_addr = ioremap(pata_data->start, 2); + + ret = ata_device_add(&ae); + if (ret == 0) + return -ENODEV; + + platform_set_drvdata(dev, ae.host_set); + + return 0; +} + +static __devexit int ts7200_pata_remove(struct platform_device *dev) +{ + struct ata_host_set *host_set = platform_get_drvdata(dev); + + ata_host_set_remove(host_set); + platform_set_drvdata(dev, NULL); + + return 0; +} + +static struct platform_driver ts7200_pata_platform_driver = { + .driver = { + .name = "ts7200-cf", + .owner = THIS_MODULE, + }, + .probe = ts7200_pata_probe, + .remove = __devexit_p(ts7200_pata_remove), +}; + +static int __init ts7200_pata_init(void) +{ + return platform_driver_register(&ts7200_pata_platform_driver); +} + +static void __exit ts7200_pata_exit(void) +{ + platform_driver_unregister(&ts7200_pata_platform_driver); +} + +MODULE_AUTHOR("Alessandro Zummo"); +MODULE_DESCRIPTION("low-level driver for ts7200 CF/ATA"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_VERSION); + +module_init(ts7200_pata_init); +module_exit(ts7200_pata_exit); Index: linux-2.6.16/include/asm-arm/arch-ep93xx/ts72xx.h =================================================================== --- linux-2.6.16.orig/include/asm-arm/arch-ep93xx/ts72xx.h +++ linux-2.6.16/include/asm-arm/arch-ep93xx/ts72xx.h @@ -67,7 +67,7 @@ * 21000000 2 CF data register (16-bit) */ -#define TS7200_CF_CTRL_PHYS_BASE 0x11000001 +#define TS7200_CF_CMD_PHYS_BASE 0x11000000 #define TS7200_CF_AUX_PHYS_BASE 0x10400006 #define TS7200_CF_DATA_PHYS_BASE 0x21000000