aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Vorontsov <avorontsov@ru.mvista.com>2007-10-11 17:53:58 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-10-11 17:53:58 -0400
commit8cb1f567f4c0a2fde9cbf77c2af888a28cab3423 (patch)
tree25eca9fb54250856e9acfcb122a8fbdc1f1d8106
parentb4e44369a380c1836d0983c2a5011099b7b26eb1 (diff)
ide: Platform IDE driver
This is now very similar to pata_platform.c, they both use same platform data structure and same resources. To achieve that, byte_lanes_swapping platform data variable and platform specified iops removed from that driver. It's fine, since those were never used anyway. pata_platform and ide_platform are carrying same driver names, to easily switch between these drivers, without need to touch platform code. Bart: - build fix from Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org> Cc: Sergei Shtylyov <sshtylyov@ru.mvista.com> Acked-by: Alan Cox <alan@redhat.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
-rw-r--r--drivers/ide/Kconfig8
-rw-r--r--drivers/ide/legacy/Makefile2
-rw-r--r--drivers/ide/legacy/ide_platform.c182
3 files changed, 192 insertions, 0 deletions
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 4200251ff635..75b2737510a6 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -308,6 +308,14 @@ config IDE_GENERIC
308 help 308 help
309 If unsure, say N. 309 If unsure, say N.
310 310
311config BLK_DEV_PLATFORM
312 tristate "Platform driver for IDE interfaces"
313 help
314 This is the platform IDE driver, used mostly for Memory Mapped
315 IDE devices, like Compact Flashes running in True IDE mode.
316
317 If unsure, say N.
318
311config BLK_DEV_CMD640 319config BLK_DEV_CMD640
312 bool "CMD640 chipset bugfix/support" 320 bool "CMD640 chipset bugfix/support"
313 depends on X86 321 depends on X86
diff --git a/drivers/ide/legacy/Makefile b/drivers/ide/legacy/Makefile
index c7971061767e..409822349f10 100644
--- a/drivers/ide/legacy/Makefile
+++ b/drivers/ide/legacy/Makefile
@@ -7,6 +7,8 @@ obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o
7 7
8obj-$(CONFIG_BLK_DEV_IDECS) += ide-cs.o 8obj-$(CONFIG_BLK_DEV_IDECS) += ide-cs.o
9 9
10obj-$(CONFIG_BLK_DEV_PLATFORM) += ide_platform.o
11
10# Last of all 12# Last of all
11obj-$(CONFIG_BLK_DEV_HD) += hd.o 13obj-$(CONFIG_BLK_DEV_HD) += hd.o
12 14
diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c
new file mode 100644
index 000000000000..ccfb9893a467
--- /dev/null
+++ b/drivers/ide/legacy/ide_platform.c
@@ -0,0 +1,182 @@
1/*
2 * Platform IDE driver
3 *
4 * Copyright (C) 2007 MontaVista Software
5 *
6 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/types.h>
15#include <linux/init.h>
16#include <linux/kernel.h>
17#include <linux/ide.h>
18#include <linux/ioport.h>
19#include <linux/module.h>
20#include <linux/pata_platform.h>
21#include <linux/platform_device.h>
22#include <linux/io.h>
23
24static struct {
25 void __iomem *plat_ide_mapbase;
26 void __iomem *plat_ide_alt_mapbase;
27 ide_hwif_t *hwif;
28 int index;
29} hwif_prop;
30
31static ide_hwif_t *__devinit plat_ide_locate_hwif(void __iomem *base,
32 void __iomem *ctrl, struct pata_platform_info *pdata, int irq,
33 int mmio)
34{
35 unsigned long port = (unsigned long)base;
36 ide_hwif_t *hwif;
37 int index, i;
38
39 for (index = 0; index < MAX_HWIFS; ++index) {
40 hwif = ide_hwifs + index;
41 if (hwif->io_ports[IDE_DATA_OFFSET] == port)
42 goto found;
43 }
44
45 for (index = 0; index < MAX_HWIFS; ++index) {
46 hwif = ide_hwifs + index;
47 if (hwif->io_ports[IDE_DATA_OFFSET] == 0)
48 goto found;
49 }
50
51 return NULL;
52
53found:
54
55 hwif->hw.io_ports[IDE_DATA_OFFSET] = port;
56
57 port += (1 << pdata->ioport_shift);
58 for (i = IDE_ERROR_OFFSET; i <= IDE_STATUS_OFFSET;
59 i++, port += (1 << pdata->ioport_shift))
60 hwif->hw.io_ports[i] = port;
61
62 hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
63
64 memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));
65 hwif->hw.irq = hwif->irq = irq;
66
67 hwif->hw.dma = NO_DMA;
68 hwif->hw.chipset = ide_generic;
69
70 if (mmio) {
71 hwif->mmio = 1;
72 default_hwif_mmiops(hwif);
73 }
74
75 hwif_prop.hwif = hwif;
76 hwif_prop.index = index;
77
78 return hwif;
79}
80
81static int __devinit plat_ide_probe(struct platform_device *pdev)
82{
83 struct resource *res_base, *res_alt, *res_irq;
84 ide_hwif_t *hwif;
85 struct pata_platform_info *pdata;
86 int ret = 0;
87 int mmio = 0;
88
89 pdata = pdev->dev.platform_data;
90
91 /* get a pointer to the register memory */
92 res_base = platform_get_resource(pdev, IORESOURCE_IO, 0);
93 res_alt = platform_get_resource(pdev, IORESOURCE_IO, 1);
94
95 if (!res_base || !res_alt) {
96 res_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
97 res_alt = platform_get_resource(pdev, IORESOURCE_MEM, 1);
98 if (!res_base || !res_alt) {
99 ret = -ENOMEM;
100 goto out;
101 }
102 mmio = 1;
103 }
104
105 res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
106 if (!res_irq) {
107 ret = -EINVAL;
108 goto out;
109 }
110
111 if (mmio) {
112 hwif_prop.plat_ide_mapbase = devm_ioremap(&pdev->dev,
113 res_base->start, res_base->end - res_base->start + 1);
114 hwif_prop.plat_ide_alt_mapbase = devm_ioremap(&pdev->dev,
115 res_alt->start, res_alt->end - res_alt->start + 1);
116 } else {
117 hwif_prop.plat_ide_mapbase = devm_ioport_map(&pdev->dev,
118 res_base->start, res_base->end - res_base->start + 1);
119 hwif_prop.plat_ide_alt_mapbase = devm_ioport_map(&pdev->dev,
120 res_alt->start, res_alt->end - res_alt->start + 1);
121 }
122
123 hwif = plat_ide_locate_hwif(hwif_prop.plat_ide_mapbase,
124 hwif_prop.plat_ide_alt_mapbase, pdata, res_irq->start, mmio);
125
126 if (!hwif) {
127 ret = -ENODEV;
128 goto out;
129 }
130 hwif->gendev.parent = &pdev->dev;
131 hwif->noprobe = 0;
132
133 probe_hwif_init(hwif);
134
135 platform_set_drvdata(pdev, hwif);
136 ide_proc_register_port(hwif);
137
138 return 0;
139
140out:
141 return ret;
142}
143
144static int __devexit plat_ide_remove(struct platform_device *pdev)
145{
146 ide_hwif_t *hwif = pdev->dev.driver_data;
147
148 if (hwif != hwif_prop.hwif) {
149 dev_printk(KERN_DEBUG, &pdev->dev, "%s: hwif value error",
150 pdev->name);
151 } else {
152 ide_unregister(hwif_prop.index);
153 hwif_prop.index = 0;
154 hwif_prop.hwif = NULL;
155 }
156
157 return 0;
158}
159
160static struct platform_driver platform_ide_driver = {
161 .driver = {
162 .name = "pata_platform",
163 },
164 .probe = plat_ide_probe,
165 .remove = __devexit_p(plat_ide_remove),
166};
167
168static int __init platform_ide_init(void)
169{
170 return platform_driver_register(&platform_ide_driver);
171}
172
173static void __exit platform_ide_exit(void)
174{
175 platform_driver_unregister(&platform_ide_driver);
176}
177
178MODULE_DESCRIPTION("Platform IDE driver");
179MODULE_LICENSE("GPL");
180
181module_init(platform_ide_init);
182module_exit(platform_ide_exit);