From: "João Ramos" <joao.ramos@inov.pt>
To: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Cc: Sergei Shtylyov <sshtylyov@ru.mvista.com>,
Alan Cox <alan@lxorguk.ukuu.org.uk>,
linux-ide@vger.kernel.org
Subject: Re: EP93xx PIO IDE driver proposal
Date: Tue, 19 May 2009 16:50:36 +0100 [thread overview]
Message-ID: <4A12D54C.3040507@inov.pt> (raw)
In-Reply-To: <4A12BCA5.2030302@inov.pt>
[-- Attachment #1: Type: text/plain, Size: 2080 bytes --]
Ok, I've done the fixes you suggested and tested the patch.
It is working fine, and I'm sending you (once again) the patch attached
to this e-mail.
In the meanwhile, I will post the entire patch to the 'arm-linux'
mailing list, iterating untill I get a final patch for the platform
dependent part.
Then, I will send the full patch back at linux-ide for submission.
I'll keep you both (Bart, Sergei) posted (CC) about iterations in the
'arm-linux' mailing list.
Best regards,
João Ramos
João Ramos escreveu:
> Bartlomiej Zolnierkiewicz escreveu:
>> On Tuesday 19 May 2009 15:20:00 João Ramos wrote:
>>
>>> Ok, I will apply the changes, test them and then resubmit the final
>>> patch.
>>> By the way, I will submit the final patch through 'arm-linux'
>>> mailing list, if that is OK to you, since the full patch has
>>> platform-specific dependencies.
>>> I mean, as long as we iterate with the IDE part of it untill it is
>>> good for submission from you, I can submit it in 'arm-linux' with
>>> your acknowledge, right?
>>>
>>
>> It is good to post it also to linux-arm for additional review &
>> better merge
>> coordination but the patch itself should go through IDE tree and
>> linux-ide.
>>
>> [ It is IDE host driver, has also IDE dependencies
>> (ide_{set,get}_drivedata()
>> patch) and there are some other pending IDE changes that will
>> require minor
>> updates to the patch. ]
>>
>> Just ping me after platform-specific part is in and I'll push the driver
>> to Linus (of course given that everybody is happy with the final
>> version).
>>
>> Thanks.
>> Bart
>>
>
> Ok, will do so.
>
> João
>
>
--
************************************************************************
João Ramos <joao.ramos@inov.pt>
INOV INESC Inovação - ESTG Leiria
Escola Superior de Tecnologia e Gestão de Leiria
Edíficio C1, Campus 2
Morro do Lena, Alto do Vieiro
Leiria
2411-901 Leiria
Portugal
Tel: +351244843424
Fax: +351244843424
************************************************************************
[-- Attachment #2: linux-2.6.30-rc6-ep93xx-ide.patch --]
[-- Type: text/x-patch, Size: 18841 bytes --]
Add IDE host controller support for Cirrus Logic's EP93xx CPUs.
Signed-off-by: Joao Ramos <joao.ramos@inov.pt>
Cc: H Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Ryan Mallon <ryan@bluewatersys.com>
Cc: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Cc: Sergei Shtylyov <sshtylyov@ru.montavista.com>
---
diff -urN linux-2.6.30-rc6.orig/arch/arm/mach-ep93xx/core.c linux-2.6.30-rc6/arch/arm/mach-ep93xx/core.c
--- linux-2.6.30-rc6.orig/arch/arm/mach-ep93xx/core.c 2009-05-16 05:12:57.000000000 +0100
+++ linux-2.6.30-rc6/arch/arm/mach-ep93xx/core.c 2009-05-19 16:03:36.000000000 +0100
@@ -537,6 +537,31 @@
platform_device_register(&ep93xx_i2c_device);
}
+static struct resource ep93xx_ide_resources[] = {
+ {
+ .start = EP93XX_IDE_PHYS_BASE,
+ .end = EP93XX_IDE_PHYS_BASE + 0x37,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_EP93XX_EXT3,
+ .end = IRQ_EP93XX_EXT3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ep93xx_ide_device = {
+ .name = "ep93xx-ide",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ep93xx_ide_resources),
+ .resource = ep93xx_ide_resources,
+};
+
+void __init ep93xx_register_ide(void)
+{
+ platform_device_register(&ep93xx_ide_device);
+}
+
extern void ep93xx_gpio_init(void);
void __init ep93xx_init_devices(void)
diff -urN linux-2.6.30-rc6.orig/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h linux-2.6.30-rc6/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
--- linux-2.6.30-rc6.orig/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h 2009-05-16 05:12:57.000000000 +0100
+++ linux-2.6.30-rc6/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h 2009-05-19 16:03:36.000000000 +0100
@@ -78,6 +78,7 @@
#define EP93XX_BOOT_ROM_BASE (EP93XX_AHB_VIRT_BASE + 0x00090000)
#define EP93XX_IDE_BASE (EP93XX_AHB_VIRT_BASE + 0x000a0000)
+#define EP93XX_IDE_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x000a0000)
#define EP93XX_VIC1_BASE (EP93XX_AHB_VIRT_BASE + 0x000b0000)
diff -urN linux-2.6.30-rc6.orig/arch/arm/mach-ep93xx/include/mach/platform.h linux-2.6.30-rc6/arch/arm/mach-ep93xx/include/mach/platform.h
--- linux-2.6.30-rc6.orig/arch/arm/mach-ep93xx/include/mach/platform.h 2009-05-16 05:12:57.000000000 +0100
+++ linux-2.6.30-rc6/arch/arm/mach-ep93xx/include/mach/platform.h 2009-05-19 16:03:36.000000000 +0100
@@ -15,6 +15,7 @@
void ep93xx_map_io(void);
void ep93xx_init_irq(void);
void ep93xx_init_time(unsigned long);
+void ep93xx_register_ide(void);
void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr);
void ep93xx_register_i2c(struct i2c_board_info *devices, int num);
void ep93xx_init_devices(void);
diff -urN linux-2.6.30-rc6.orig/drivers/ide/ep93xx-ide.c linux-2.6.30-rc6/drivers/ide/ep93xx-ide.c
--- linux-2.6.30-rc6.orig/drivers/ide/ep93xx-ide.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.30-rc6/drivers/ide/ep93xx-ide.c 2009-05-19 16:06:33.000000000 +0100
@@ -0,0 +1,521 @@
+/*
+ * Support for Cirrus Logic's EP93xx (EP9312, EP9315) CPUs
+ * IDE host controller driver.
+ *
+ * Copyright (c) 2009, Joao Ramos <joao.ramos@inov.pt>
+ * INESC Inovacao (INOV)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/ide.h>
+#include <linux/delay.h>
+
+#define MODULE_NAME "ep93xx-ide"
+
+/*
+ * Configuration and usage of the IDE device is made through the
+ * IDE Interface Register Map (EP93xx User's Guide, Section 27).
+ *
+ * This section holds common registers and flag definitions for
+ * that interface.
+ */
+
+/*
+ * IDE Register offset
+ */
+#define IDECTRL 0x00
+#define IDECFG 0x04
+#define IDEMDMAOP 0x08
+#define IDEUDMAOP 0x0C
+#define IDEDATAOUT 0x10
+#define IDEDATAIN 0x14
+#define IDEMDMADATAOUT 0x18
+#define IDEMDMADATAIN 0x1C
+#define IDEUDMADATAOUT 0x20
+#define IDEUDMADATAIN 0x24
+#define IDEUDMASTS 0x28
+#define IDEUDMADEBUG 0x2C
+#define IDEUDMAWRBUFSTS 0x30
+#define IDEUDMARDBUFSTS 0x34
+
+/*
+ * IDE Control Register bit fields
+ */
+#define IDECTRL_CS0N 0x00000001
+#define IDECTRL_CS1N 0x00000002
+#define IDECTRL_DA 0x0000001C
+#define IDECTRL_DIORN 0x00000020
+#define IDECTRL_DIOWN 0x00000040
+#define IDECTRL_DASPN 0x00000080
+#define IDECTRL_DMARQ 0x00000100
+#define IDECTRL_INTRQ 0x00000200
+#define IDECTRL_IORDY 0x00000400
+
+/*
+ * IDE Configuration Register bit fields
+ */
+#define IDECFG_IDEEN 0x00000001
+#define IDECFG_PIO 0x00000002
+#define IDECFG_MDMA 0x00000004
+#define IDECFG_UDMA 0x00000008
+#define IDECFG_PIO_MODE_0 0x00000000
+#define IDECFG_PIO_MODE_1 0x00000010
+#define IDECFG_PIO_MODE_2 0x00000020
+#define IDECFG_PIO_MODE_3 0x00000030
+#define IDECFG_PIO_MODE_4 0x00000040
+#define IDECFG_MDMA_MODE_0 0x00000000
+#define IDECFG_MDMA_MODE_1 0x00000010
+#define IDECFG_MDMA_MODE_2 0x00000020
+#define IDECFG_UDMA_MODE_0 0x00000000
+#define IDECFG_UDMA_MODE_1 0x00000010
+#define IDECFG_UDMA_MODE_2 0x00000020
+#define IDECFG_UDMA_MODE_3 0x00000030
+#define IDECFG_UDMA_MODE_4 0x00000040
+#define IDECFG_WST 0x00000300
+
+/*
+ * Check whether IORDY is asserted or not.
+ */
+static inline int ep93xx_ide_check_iordy(void __iomem *base)
+{
+ u32 reg = readl(base + IDECTRL);
+
+ return (reg & IDECTRL_IORDY) ? 1 : 0;
+}
+
+/*
+ * IDE Interface register map default state
+ * (shutdown)
+ */
+static void ep93xx_ide_clean_regs(void __iomem *base)
+{
+ /* disable IDE interface initially */
+ writel(IDECTRL_CS0N | IDECTRL_CS1N | IDECTRL_DIORN |
+ IDECTRL_DIOWN, base + IDECTRL);
+
+ /* clear IDE registers */
+ writel(0, base + IDECFG);
+ writel(0, base + IDEMDMAOP);
+ writel(0, base + IDEUDMAOP);
+ writel(0, base + IDEDATAOUT);
+ writel(0, base + IDEDATAIN);
+ writel(0, base + IDEMDMADATAOUT);
+ writel(0, base + IDEMDMADATAIN);
+ writel(0, base + IDEUDMADATAOUT);
+ writel(0, base + IDEUDMADATAIN);
+ writel(0, base + IDEUDMADEBUG);
+}
+
+static u16 __ep93xx_ide_read(void __iomem *base, unsigned long addr,
+ struct ide_timing *t)
+{
+ u32 reg;
+
+ reg = addr | IDECTRL_DIORN | IDECTRL_DIOWN;
+ writel(reg, base + IDECTRL);
+ ndelay(t->setup);
+
+ reg &= ~IDECTRL_DIORN;
+ writel(reg, base + IDECTRL);
+ ndelay(t->active);
+
+ while (!ep93xx_ide_check_iordy(base))
+ cpu_relax();
+
+ reg |= IDECTRL_DIORN;
+ writel(reg, base + IDECTRL);
+ ndelay(t->recover);
+
+ return readl(base + IDEDATAIN);
+}
+
+static inline u16 ep93xx_ide_read(ide_hwif_t *hwif, unsigned long addr)
+{
+ void __iomem *base = hwif->host->host_priv;
+ struct ide_timing *t = (struct ide_timing *)ide_get_hwifdata(hwif);
+
+ return __ep93xx_ide_read(base, addr, t);
+}
+
+static void __ep93xx_ide_write(void __iomem *base, u16 value,
+ unsigned long addr, struct ide_timing *t)
+{
+ u32 reg;
+
+ reg = addr | IDECTRL_DIORN | IDECTRL_DIOWN;
+ writel(reg, base + IDECTRL);
+ ndelay(t->setup);
+
+ writel(value, base + IDEDATAOUT);
+
+ reg &= ~IDECTRL_DIOWN;
+ writel(reg, base + IDECTRL);
+ ndelay(t->active);
+
+ while (!ep93xx_ide_check_iordy(base))
+ cpu_relax();
+
+ reg |= IDECTRL_DIOWN;
+ writel(reg, base + IDECTRL);
+ ndelay(t->recover);
+}
+
+static inline void ep93xx_ide_write(ide_hwif_t *hwif, u16 value,
+ unsigned long addr)
+{
+ void __iomem *base = hwif->host->host_priv;
+ struct ide_timing *t = (struct ide_timing *)ide_get_hwifdata(hwif);
+
+ __ep93xx_ide_write(base, value, addr, t);
+}
+
+/*
+ * EP93xx IDE PIO Transport Operations
+ */
+
+static void ep93xx_ide_exec_command(struct hwif_s *hwif, u8 cmd)
+{
+ ep93xx_ide_write(hwif, cmd, hwif->io_ports.command_addr);
+}
+
+static u8 ep93xx_ide_read_status(ide_hwif_t *hwif)
+{
+ return ep93xx_ide_read(hwif, hwif->io_ports.status_addr);
+}
+
+static u8 ep93xx_ide_read_altstatus(ide_hwif_t *hwif)
+{
+ return ep93xx_ide_read(hwif, hwif->io_ports.ctl_addr);
+}
+
+static void ep93xx_ide_write_devctl(ide_hwif_t *hwif, u8 ctl)
+{
+ ep93xx_ide_write(hwif, ctl, hwif->io_ports.ctl_addr);
+}
+
+static void ep93xx_ide_dev_select(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ u8 select = drive->select | ATA_DEVICE_OBS;
+
+ ep93xx_ide_write(hwif, select, hwif->io_ports.device_addr);
+}
+
+static void ep93xx_ide_tf_load(ide_drive_t *drive, struct ide_taskfile *tf,
+ u8 valid)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+
+ if (valid & IDE_VALID_FEATURE)
+ ep93xx_ide_write(hwif, tf->feature, io_ports->feature_addr);
+ if (valid & IDE_VALID_NSECT)
+ ep93xx_ide_write(hwif, tf->nsect, io_ports->nsect_addr);
+ if (valid & IDE_VALID_LBAL)
+ ep93xx_ide_write(hwif, tf->lbal, io_ports->lbal_addr);
+ if (valid & IDE_VALID_LBAM)
+ ep93xx_ide_write(hwif, tf->lbam, io_ports->lbam_addr);
+ if (valid & IDE_VALID_LBAH)
+ ep93xx_ide_write(hwif, tf->lbah, io_ports->lbah_addr);
+ if (valid & IDE_VALID_DEVICE)
+ ep93xx_ide_write(hwif, tf->device, io_ports->device_addr);
+}
+
+static void ep93xx_ide_tf_read(ide_drive_t *drive, struct ide_taskfile *tf,
+ u8 valid)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+
+ if (valid & IDE_VALID_ERROR)
+ tf->error = ep93xx_ide_read(hwif, io_ports->feature_addr);
+ if (valid & IDE_VALID_NSECT)
+ tf->nsect = ep93xx_ide_read(hwif, io_ports->nsect_addr);
+ if (valid & IDE_VALID_LBAL)
+ tf->lbal = ep93xx_ide_read(hwif, io_ports->lbal_addr);
+ if (valid & IDE_VALID_LBAM)
+ tf->lbam = ep93xx_ide_read(hwif, io_ports->lbam_addr);
+ if (valid & IDE_VALID_LBAH)
+ tf->lbah = ep93xx_ide_read(hwif, io_ports->lbah_addr);
+ if (valid & IDE_VALID_DEVICE)
+ tf->device = ep93xx_ide_read(hwif, io_ports->device_addr);
+}
+
+static void ep93xx_ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
+ void *buf, unsigned int len)
+{
+ u16 *data = (u16 *)buf;
+ ide_hwif_t *hwif = drive->hwif;
+ void __iomem *base = hwif->host->host_priv;
+ unsigned long data_addr = hwif->io_ports.data_addr;
+ struct ide_timing *t = (struct ide_timing *)ide_get_drivedata(drive);
+ unsigned int words = (len + 1) >> 1;
+
+ while (words--)
+ *data++ = cpu_to_le16(__ep93xx_ide_read(base, data_addr, t));
+}
+
+static void ep93xx_ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
+ void *buf, unsigned int len)
+{
+ u16 *data = (u16 *)buf;
+ ide_hwif_t *hwif = drive->hwif;
+ void __iomem *base = hwif->host->host_priv;
+ unsigned long data_addr = hwif->io_ports.data_addr;
+ struct ide_timing *t = (struct ide_timing *)ide_get_drivedata(drive);
+ unsigned int words = (len + 1) >> 1;
+
+ while (words--)
+ __ep93xx_ide_write(base, le16_to_cpu(*data++), data_addr, t);
+}
+
+static struct ide_tp_ops ep93xx_ide_tp_ops = {
+ .exec_command = ep93xx_ide_exec_command,
+ .read_status = ep93xx_ide_read_status,
+ .read_altstatus = ep93xx_ide_read_altstatus,
+ .write_devctl = ep93xx_ide_write_devctl,
+ .dev_select = ep93xx_ide_dev_select,
+ .tf_load = ep93xx_ide_tf_load,
+ .tf_read = ep93xx_ide_tf_read,
+ .input_data = ep93xx_ide_input_data,
+ .output_data = ep93xx_ide_output_data,
+};
+
+static void ep93xx_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
+{
+ ide_drive_t *pair = ide_get_pair_dev(drive);
+ struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
+ struct ide_timing *cmd_t = t;
+ u32 reg = IDECFG_IDEEN | IDECFG_PIO;
+ void __iomem *base = drive->hwif->host->host_priv;
+
+ if (pair) {
+ struct ide_timing *pair_t = ide_get_drivedata(pair);
+
+ if (pair_t && pair_t->mode < t->mode)
+ cmd_t = pair_t;
+ }
+
+ /*
+ * store the adequate PIO mode timings, to be used later
+ * by ep93xx_ide_{read,write}
+ */
+ ide_set_drivedata(drive, (void *)t);
+ ide_set_hwifdata(drive->hwif, (void *)cmd_t);
+
+ /* reconfigure IDE controller according to PIO mode */
+ switch (pio) {
+ case 4:
+ reg |= IDECFG_PIO_MODE_4 | ((1 << 8) & IDECFG_WST);
+ break;
+ case 3:
+ reg |= IDECFG_PIO_MODE_3 | ((1 << 8) & IDECFG_WST);
+ break;
+ case 2:
+ reg |= IDECFG_PIO_MODE_2 | ((2 << 8) & IDECFG_WST);
+ break;
+ case 1:
+ reg |= IDECFG_PIO_MODE_1 | ((2 << 8) & IDECFG_WST);
+ break;
+ case 0:
+ default:
+ reg |= IDECFG_PIO_MODE_0 | ((3 << 8) & IDECFG_WST);
+ break;
+ }
+ writel(reg, base + IDECFG);
+}
+
+static struct ide_port_ops ep93xx_ide_port_ops = {
+ .set_pio_mode = ep93xx_ide_set_pio_mode,
+};
+
+static struct ide_port_info ep93xx_ide_port_info = {
+ .name = MODULE_NAME,
+ .tp_ops = &ep93xx_ide_tp_ops,
+ .port_ops = &ep93xx_ide_port_ops,
+ .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE |
+ IDE_HFLAG_NO_DMA | IDE_HFLAG_MMIO |
+ IDE_HFLAG_NO_IO_32BIT | IDE_HFLAG_NO_UNMASK_IRQS,
+ .pio_mask = ATA_PIO4,
+};
+
+static int __init ep93xx_ide_probe(struct platform_device *pdev)
+{
+ int retval;
+ int irq;
+ void __iomem *ide_base;
+ struct resource *mem_res;
+ hw_regs_t hw;
+ hw_regs_t *hws[] = { &hw, NULL, NULL, NULL };
+ struct ide_host *host;
+
+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem_res) {
+ dev_err(&pdev->dev,
+ "could not retrieve device memory resources!\n");
+ return -ENXIO;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev,
+ "could not retrieve device IRQ resource!\n");
+ return -ENXIO;
+ }
+
+ if (!request_mem_region
+ (mem_res->start, mem_res->end - mem_res->start + 1, MODULE_NAME)) {
+ dev_err(&pdev->dev, "could not request memory resources!\n");
+ return -EBUSY;
+ }
+
+ ide_base = ioremap(mem_res->start, mem_res->end - mem_res->start + 1);
+ if (!ide_base) {
+ dev_err(&pdev->dev, "could not map memory resources!\n");
+ retval = -ENOMEM;
+ goto fail_release_mem;
+ }
+
+ memset(&hw, 0, sizeof(hw));
+
+ /*
+ * fill in ide_io_ports structure.
+ * the device IDE register to be accessed is selected through
+ * IDECTRL register's specific bitfields 'DA', 'CS1n' and 'CS0n':
+ * b4 b3 b2 b1 b0
+ * A2 A1 A0 CS1n CS0n
+ * the values filled in this structure allows the value to be directly
+ * ORed to the IDECTRL register, hence giving directly the A[2:0] and
+ * CS1n/CS0n values for each IDE register.
+ * The values correspond to the transformation:
+ * ((real IDE address) << 2) | CS1n value << 1 | CS0n value
+ */
+ hw.io_ports.data_addr = 0x02;
+ hw.io_ports.error_addr = 0x06;
+ hw.io_ports.nsect_addr = 0x0A;
+ hw.io_ports.lbal_addr = 0x0E;
+ hw.io_ports.lbam_addr = 0x12;
+ hw.io_ports.lbah_addr = 0x16;
+ hw.io_ports.device_addr = 0x1A;
+ hw.io_ports.command_addr = 0x1E;
+ hw.io_ports.ctl_addr = 0x01;
+
+ hw.irq = irq;
+ hw.chipset = ide_generic;
+ hw.dev = &pdev->dev;
+
+ /* enforce EP93xx IDE controller reset state */
+ ep93xx_ide_clean_regs(ide_base);
+
+ /* set gpio port E, G and H for IDE */
+ ep93xx_ide_aquire_gpios();
+
+ /*
+ * configure IDE interface:
+ * - IDE Master Enable
+ * - Polled IO Operation
+ * - PIO Mode 0 -> 3.33 MBps
+ * - 3 Wait States -> 30 ns
+ */
+ writel(IDECFG_IDEEN | IDECFG_PIO | IDECFG_PIO_MODE_0 |
+ ((3 << 8) & IDECFG_WST), ide_base + IDECFG);
+
+ host = ide_host_alloc(&ep93xx_ide_port_info, hws);
+ if (!host) {
+ dev_err(&pdev->dev,
+ "failed to allocate memory for EP93xx IDE host!\n");
+ retval = -ENOMEM;
+ goto fail_unmap;
+ }
+
+ host->host_priv = ide_base;
+
+ retval = ide_host_register(host, &ep93xx_ide_port_info, hws);
+ if (retval) {
+ dev_err(&pdev->dev,
+ "unable to register EP93xx IDE driver!\n");
+ goto fail_free_host;
+ }
+
+ platform_set_drvdata(pdev, host);
+
+ dev_info(&pdev->dev, "EP93xx IDE host controller driver initialized\n");
+
+ return 0;
+
+fail_free_host:
+ ide_host_free(host);
+fail_unmap:
+ iounmap(ide_base);
+fail_release_mem:
+ release_mem_region(mem_res->start, mem_res->end - mem_res->start + 1);
+ return retval;
+}
+
+static int __devexit ep93xx_ide_remove(struct platform_device *pdev)
+{
+ struct ide_host *host = pdev->dev.driver_data;
+ void __iomem *base = host->host_priv;
+ struct resource *mem_res;
+
+ ide_host_remove(host);
+
+ /* reset state */
+ ep93xx_ide_clean_regs(base);
+
+ /* restore back GPIO port E, G and H for GPIO use */
+ ep93xx_ide_release_gpios();
+
+ iounmap(base);
+
+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(mem_res->start, mem_res->end - mem_res->start + 1);
+
+ return 0;
+}
+
+static struct platform_driver ep93xx_ide_driver = {
+ .remove = __exit_p(ep93xx_ide_remove),
+ .driver = {
+ .name = MODULE_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init ep93xx_ide_init(void)
+{
+ return platform_driver_probe(&ep93xx_ide_driver, ep93xx_ide_probe);
+}
+module_init(ep93xx_ide_init);
+
+static void __exit ep93xx_ide_exit(void)
+{
+ platform_driver_unregister(&ep93xx_ide_driver);
+}
+module_exit(ep93xx_ide_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Joao Ramos <joao.ramos@inov.pt>");
+MODULE_DESCRIPTION("EP93xx IDE host controller driver");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("platform:ep93xx-ide");
diff -urN linux-2.6.30-rc6.orig/drivers/ide/Kconfig linux-2.6.30-rc6/drivers/ide/Kconfig
--- linux-2.6.30-rc6.orig/drivers/ide/Kconfig 2009-05-16 05:12:57.000000000 +0100
+++ linux-2.6.30-rc6/drivers/ide/Kconfig 2009-05-19 16:03:36.000000000 +0100
@@ -732,6 +732,19 @@
depends on ARM && ARCH_AT91 && !ARCH_AT91RM9200 && !ARCH_AT91X40
select IDE_TIMINGS
+config BLK_DEV_IDE_EP93XX
+ tristate "Cirrus Logic EPxx (EP9312, EP9315) IDE support"
+ depends on ARM && ARCH_EP93XX
+ select IDE_TIMINGS
+ help
+ This is a host controller driver for IDE hardware included in
+ Cirrus Logic's EP9312 and EP9315 CPUs.
+ Say Y here if you want to enable the IDE host controller support
+ for your machine.
+
+ Choose 'M' to compile this driver as a module; the module will be
+ called 'ep93xx-ide'.
+
config BLK_DEV_IDE_ICSIDE
tristate "ICS IDE interface support"
depends on ARM && ARCH_ACORN
diff -urN linux-2.6.30-rc6.orig/drivers/ide/Makefile linux-2.6.30-rc6/drivers/ide/Makefile
--- linux-2.6.30-rc6.orig/drivers/ide/Makefile 2009-05-16 05:12:57.000000000 +0100
+++ linux-2.6.30-rc6/drivers/ide/Makefile 2009-05-19 16:03:36.000000000 +0100
@@ -117,3 +117,4 @@
obj-$(CONFIG_BLK_DEV_IDE_TX4938) += tx4938ide.o
obj-$(CONFIG_BLK_DEV_IDE_TX4939) += tx4939ide.o
obj-$(CONFIG_BLK_DEV_IDE_AT91) += at91_ide.o
+obj-$(CONFIG_BLK_DEV_IDE_EP93XX) += ep93xx-ide.o
next prev parent reply other threads:[~2009-05-19 15:51 UTC|newest]
Thread overview: 59+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <49CCD7C4.8000207@inov.pt>
[not found] ` <49CFDD8F.1030306@bluewatersys.com>
[not found] ` <BD79186B4FD85F4B8E60E381CAEE1909014E2E09@mi8nycmail19.Mi8.com>
[not found] ` <49D0CAE4.9090306@inov.pt>
2009-03-30 15:34 ` EP93xx PIO IDE driver proposal Sergei Shtylyov
2009-05-04 11:24 ` João Ramos
2009-05-05 12:04 ` Sergei Shtylyov
2009-05-06 14:17 ` João Ramos
2009-05-06 17:05 ` Sergei Shtylyov
2009-05-07 9:36 ` João Ramos
2009-05-07 11:01 ` João Ramos
2009-05-07 13:53 ` Alan Cox
2009-05-07 15:33 ` João Ramos
2009-05-08 12:04 ` Bartlomiej Zolnierkiewicz
2009-05-08 12:16 ` João Ramos
2009-05-08 12:40 ` Bartlomiej Zolnierkiewicz
2009-05-08 13:30 ` Sergei Shtylyov
2009-05-08 14:09 ` Bartlomiej Zolnierkiewicz
2009-05-08 17:28 ` João Ramos
2009-05-08 18:02 ` Bartlomiej Zolnierkiewicz
2009-05-08 18:16 ` João Ramos
2009-05-08 18:55 ` Bartlomiej Zolnierkiewicz
2009-05-08 20:24 ` joao.ramos
2009-05-08 21:01 ` Sergei Shtylyov
2009-05-08 22:07 ` Bartlomiej Zolnierkiewicz
2009-05-11 11:10 ` João Ramos
2009-05-12 16:49 ` Sergei Shtylyov
2009-05-12 17:23 ` Bartlomiej Zolnierkiewicz
2009-05-13 11:01 ` João Ramos
2009-05-17 15:20 ` Bartlomiej Zolnierkiewicz
2009-05-22 17:52 ` Sergei Shtylyov
2009-05-13 14:18 ` João Ramos
2009-05-14 19:44 ` Bartlomiej Zolnierkiewicz
2009-05-15 17:01 ` João Ramos
2009-05-17 16:16 ` Bartlomiej Zolnierkiewicz
2009-05-18 13:49 ` João Ramos
2009-05-19 13:06 ` Bartlomiej Zolnierkiewicz
2009-05-19 13:20 ` João Ramos
2009-05-19 13:56 ` Bartlomiej Zolnierkiewicz
2009-05-19 14:05 ` João Ramos
2009-05-19 15:50 ` João Ramos [this message]
2009-06-06 15:26 ` Sergei Shtylyov
2009-06-22 10:01 ` Bartlomiej Zolnierkiewicz
2009-05-14 16:30 ` Sergei Shtylyov
2009-05-14 16:36 ` Sergei Shtylyov
2009-05-14 18:58 ` Bartlomiej Zolnierkiewicz
2009-05-11 13:20 ` João Ramos
2009-05-12 16:41 ` Bartlomiej Zolnierkiewicz
2009-05-12 16:57 ` Sergei Shtylyov
2009-05-12 16:01 ` João Ramos
2009-05-12 16:30 ` Bartlomiej Zolnierkiewicz
2009-05-12 16:45 ` João Ramos
2009-05-07 16:52 ` H Hartley Sweeten
2009-05-07 22:09 ` Ryan Mallon
2009-05-07 22:31 ` H Hartley Sweeten
2009-05-07 22:51 ` Ryan Mallon
2009-05-07 23:01 ` H Hartley Sweeten
2009-05-07 23:12 ` Ryan Mallon
2009-05-07 23:32 ` João Ramos
2009-05-07 23:58 ` H Hartley Sweeten
2009-05-08 11:23 ` Sergei Shtylyov
2009-05-08 12:47 ` João Ramos
[not found] ` <49D12669.4030207@bluewatersys.com>
2009-03-31 10:36 ` Sergei Shtylyov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4A12D54C.3040507@inov.pt \
--to=joao.ramos@inov.pt \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=bzolnier@gmail.com \
--cc=linux-ide@vger.kernel.org \
--cc=sshtylyov@ru.mvista.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.