0f269c15ec255b61958978d4da4906951f53c237
[lede.git] / target / linux / coldfire / patches / 013-m5445x_ata.patch
1 From c9e68ea1a541b9762ec0b656509aef3cdd75e035 Mon Sep 17 00:00:00 2001
2 From: Kurt Mahan <kmahan@freescale.com>
3 Date: Mon, 19 Nov 2007 12:01:34 -0700
4 Subject: [PATCH] Add support for the M5445x ATA controller.
5
6 LTIBName: m5445x-ata
7 Signed-off-by: Kurt Mahan <kmahan@freescale.com>
8 ---
9  arch/m68k/coldfire/Makefile           |    1 +
10  arch/m68k/coldfire/head.S             |    5 +
11  arch/m68k/coldfire/mcf5445x-devices.c |  125 +++++
12  drivers/ata/Kconfig                   |   11 +-
13  drivers/ata/Makefile                  |    2 +-
14  drivers/ata/pata_fsl.c                |  829 +++++++++++++++++++++++++++++++++
15  include/asm-m68k/pci.h                |   10 +-
16  include/linux/fsl_devices.h           |   11 +
17  8 files changed, 990 insertions(+), 4 deletions(-)
18  create mode 100644 arch/m68k/coldfire/mcf5445x-devices.c
19  create mode 100644 drivers/ata/pata_fsl.c
20
21 --- a/arch/m68k/coldfire/Makefile
22 +++ b/arch/m68k/coldfire/Makefile
23 @@ -9,3 +9,4 @@ ifneq ($(strip $(CONFIG_USB) $(CONFIG_US
24  endif
25  
26  obj-$(CONFIG_PCI)      += pci.o mcf5445x-pci.o iomap.o
27 +obj-$(CONFIG_M54455)   += mcf5445x-devices.o
28 --- a/arch/m68k/coldfire/head.S
29 +++ b/arch/m68k/coldfire/head.S
30 @@ -374,6 +374,11 @@ ENTRY(__start)
31                 MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
32                 0, MMUDR_LK, %d0
33  
34 +       /* Map ATA registers -- sacrifice a data TLB due to the hw design */
35 +       mmu_map (0x90000000), (0x90000000), 0, 0, \
36 +               MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
37 +               0, MMUDR_LK, %d0
38 +
39         /* Do unity mapping to enable the MMU.  Map first 16 MB in place as 
40            code (delete TLBs after MMU is enabled and we are executing in high 
41            memory). */
42 --- /dev/null
43 +++ b/arch/m68k/coldfire/mcf5445x-devices.c
44 @@ -0,0 +1,125 @@
45 +/*
46 + * arch/m68k/coldfire/mcf5445x-devices.c
47 + *
48 + * Coldfire M5445x Platform Device Configuration
49 + *
50 + * Based on the Freescale MXC devices.c
51 + *
52 + * Copyright (c) 2007 Freescale Semiconductor, Inc.
53 + *     Kurt Mahan <kmahan@freescale.com>
54 + */
55 +#include <linux/module.h>
56 +#include <linux/kernel.h>
57 +#include <linux/init.h>
58 +#include <linux/platform_device.h>
59 +#include <linux/fsl_devices.h>
60 +
61 +#include <asm/coldfire.h>
62 +#include <asm/mcfsim.h>
63 +
64 +/* ATA Interrupt */
65 +#define IRQ_ATA                (64 + 64 + 54)
66 +
67 +/* ATA Base */
68 +#define        BASE_IO_ATA     0x90000000
69 +
70 +#define ATA_IER                MCF_REG08(BASE_IO_ATA+0x2c)     /* int enable reg */
71 +#define ATA_ICR                MCF_REG08(BASE_IO_ATA+0x30)     /* int clear reg */
72 +
73 +/*
74 + * On-chip PATA
75 + */
76 +#if defined(CONFIG_PATA_FSL) || defined(CONFIG_PATA_FSL_MODULE)
77 +static int ata_init(struct platform_device *pdev)
78 +{
79 +       /* clear ints */
80 +       ATA_IER = 0x00;
81 +       ATA_ICR = 0xff;
82 +
83 +       /* setup shared pins */
84 +       MCF_GPIO_PAR_FEC = (MCF_GPIO_PAR_FEC & MCF_GPIO_PAR_FEC_FEC1_MASK) |
85 +                          MCF_GPIO_PAR_FEC_FEC1_ATA;
86 +
87 +       MCF_GPIO_PAR_FECI2C = (MCF_GPIO_PAR_FECI2C &
88 +                             (MCF_GPIO_PAR_FECI2C_MDC1_MASK &
89 +                             MCF_GPIO_PAR_FECI2C_MDIO1_MASK)) |
90 +                             MCF_GPIO_PAR_FECI2C_MDC1_ATA_DIOR |
91 +                             MCF_GPIO_PAR_FECI2C_MDIO1_ATA_DIOW;
92 +
93 +       MCF_GPIO_PAR_ATA = MCF_GPIO_PAR_ATA_BUFEN |
94 +                          MCF_GPIO_PAR_ATA_CS1 |
95 +                          MCF_GPIO_PAR_ATA_CS0 |
96 +                          MCF_GPIO_PAR_ATA_DA2 |
97 +                          MCF_GPIO_PAR_ATA_DA1 |
98 +                          MCF_GPIO_PAR_ATA_DA0 |
99 +                          MCF_GPIO_PAR_ATA_RESET_RESET |
100 +                          MCF_GPIO_PAR_ATA_DMARQ_DMARQ |
101 +                          MCF_GPIO_PAR_ATA_IORDY_IORDY;
102 +
103 +       MCF_GPIO_PAR_PCI = (MCF_GPIO_PAR_PCI &
104 +                            (MCF_GPIO_PAR_PCI_GNT3_MASK &
105 +                             MCF_GPIO_PAR_PCI_REQ3_MASK)) |
106 +                          MCF_GPIO_PAR_PCI_GNT3_ATA_DMACK |
107 +                          MCF_GPIO_PAR_PCI_REQ3_ATA_INTRQ;
108 +
109 +       return 0;
110 +}
111 +
112 +static void ata_exit(void)
113 +{
114 +       printk(KERN_INFO "** ata_exit\n");
115 +}
116 +
117 +static int ata_get_clk_rate(void)
118 +{
119 +       return MCF_BUSCLK;
120 +}
121 +
122 +static struct fsl_ata_platform_data ata_data = {
123 +       .init             = ata_init,
124 +       .exit             = ata_exit,
125 +       .get_clk_rate     = ata_get_clk_rate,
126 +};
127 +
128 +static struct resource pata_fsl_resources[] = {
129 +       [0] = {         /* I/O */
130 +               .start          = BASE_IO_ATA,
131 +               .end            = BASE_IO_ATA + 0x000000d8,
132 +               .flags          = IORESOURCE_MEM,
133 +       },
134 +       [2] = {         /* IRQ */
135 +               .start          = IRQ_ATA,
136 +               .end            = IRQ_ATA,
137 +               .flags          = IORESOURCE_IRQ,
138 +       },
139 +};
140 +
141 +static struct platform_device pata_fsl_device = {
142 +       .name                   = "pata_fsl",
143 +       .id                     = -1,
144 +       .num_resources          = ARRAY_SIZE(pata_fsl_resources),
145 +       .resource               = pata_fsl_resources,
146 +       .dev                    = {
147 +               .platform_data  = &ata_data,
148 +               .coherent_dma_mask = ~0,        /* $$$ REVISIT */
149 +       },
150 +};
151 +
152 +static inline void mcf5445x_init_pata(void)
153 +{
154 +       (void)platform_device_register(&pata_fsl_device);
155 +}
156 +#else
157 +static inline void mcf5445x_init_pata(void)
158 +{
159 +}
160 +#endif
161 +
162 +static int __init mcf5445x_init_devices(void)
163 +{
164 +       printk(KERN_INFO "MCF5445x INIT_DEVICES\n");
165 +       mcf5445x_init_pata();
166 +
167 +       return 0;
168 +}
169 +arch_initcall(mcf5445x_init_devices);
170 --- a/drivers/ata/Kconfig
171 +++ b/drivers/ata/Kconfig
172 @@ -6,7 +6,7 @@ menuconfig ATA
173         tristate "Serial ATA (prod) and Parallel ATA (experimental) drivers"
174         depends on HAS_IOMEM
175         depends on BLOCK
176 -       depends on !(M32R || M68K) || BROKEN
177 +       depends on !M32R || BROKEN
178         depends on !SUN4 || BROKEN
179         select SCSI
180         ---help---
181 @@ -679,4 +679,13 @@ config PATA_BF54X
182  
183           If unsure, say N.
184  
185 +config PATA_FSL
186 +       tristate "Freescale on-chip PATA support"
187 +       depends on (ARCH_MX3 || ARCH_MX27 || PPC_512x || M54455)
188 +       help
189 +         On Freescale processors, say Y here if you wish to use the on-chip
190 +         ATA interface.
191 +
192 +         If you are unsure, say N to this.
193 +
194  endif # ATA
195 --- a/drivers/ata/Makefile
196 +++ b/drivers/ata/Makefile
197 @@ -1,4 +1,3 @@
198 -
199  obj-$(CONFIG_ATA)              += libata.o
200  
201  obj-$(CONFIG_SATA_AHCI)                += ahci.o
202 @@ -71,6 +70,7 @@ obj-$(CONFIG_PATA_BF54X)      += pata_bf54x.o
203  obj-$(CONFIG_PATA_PLATFORM)    += pata_platform.o
204  obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.o
205  obj-$(CONFIG_PATA_ICSIDE)      += pata_icside.o
206 +obj-$(CONFIG_PATA_FSL)         += pata_fsl.o
207  # Should be last but two libata driver
208  obj-$(CONFIG_PATA_ACPI)                += pata_acpi.o
209  # Should be last but one libata driver
210 --- /dev/null
211 +++ b/drivers/ata/pata_fsl.c
212 @@ -0,0 +1,829 @@
213 +/*
214 + * Freescale integrated PATA driver
215 + */
216 +
217 +/*
218 + * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
219 + */
220 +
221 +/*
222 + * The code contained herein is licensed under the GNU General Public
223 + * License. You may obtain a copy of the GNU General Public License
224 + * Version 2 or later at the following locations:
225 + *
226 + * http://www.opensource.org/licenses/gpl-license.html
227 + * http://www.gnu.org/copyleft/gpl.html
228 + */
229 +
230 +#include <linux/kernel.h>
231 +#include <linux/module.h>
232 +#include <linux/init.h>
233 +#include <linux/blkdev.h>
234 +#include <scsi/scsi_host.h>
235 +#include <linux/ata.h>
236 +#include <linux/libata.h>
237 +#include <linux/platform_device.h>
238 +#include <linux/fsl_devices.h>
239 +#ifdef CONFIG_FSL_PATA_USE_DMA
240 +#include <asm/dma.h>
241 +#endif
242 +
243 +#define DRV_NAME "pata_fsl"
244 +#define DRV_VERSION "1.0"
245 +
246 +#ifdef CONFIG_M54455
247 +#define WRITE_ATA8(val, reg)                   \
248 +       __raw_writeb(val, (ata_regs + reg));
249 +#define WRITE_ATA16(val, reg)                  \
250 +       __raw_writew(val, (ata_regs + reg));
251 +#else
252 +#define WRITE_ATA8(val, reg)                   \
253 +       __raw_writel(val, (ata_regs + reg));
254 +#define WRITE_ATA16(val, reg)                  \
255 +       __raw_writel(val, (ata_regs + reg));
256 +#endif
257 +
258 +struct pata_fsl_priv {
259 +#ifdef CONFIG_FSL_PATA_USE_DMA
260 +       int ultra;
261 +#endif
262 +       u8 *fsl_ata_regs;
263 +#ifdef CONFIG_FSL_PATA_USE_DMA
264 +       int dma_rchan;
265 +       int dma_wchan;
266 +       int dma_done;
267 +       int dma_dir;
268 +#endif
269 +};
270 +
271 +enum {
272 +       /* various constants */
273 +
274 +#ifdef CONFIG_FSL_PATA_USE_DMA
275 +       FSL_ATA_MAX_SG_LEN      = 65534,
276 +#endif
277 +
278 +       /* offsets to registers */
279 +
280 +       FSL_ATA_TIMING_REGS     = 0x00,
281 +       FSL_ATA_FIFO_FILL       = 0x20,
282 +       FSL_ATA_CONTROL         = 0x24,
283 +       FSL_ATA_INT_PEND        = 0x28,
284 +       FSL_ATA_INT_EN          = 0x2C,
285 +       FSL_ATA_INT_CLEAR       = 0x30,
286 +       FSL_ATA_FIFO_ALARM      = 0x34,
287 +       FSL_ATA_DRIVE_DATA      = 0xA0,
288 +       FSL_ATA_DRIVE_CONTROL   = 0xD8,
289 +
290 +       /* bits within FSL_ATA_CONTROL */
291 +
292 +       FSL_ATA_CTRL_FIFO_RST_B    = 0x80,
293 +       FSL_ATA_CTRL_ATA_RST_B     = 0x40,
294 +       FSL_ATA_CTRL_FIFO_TX_EN    = 0x20,
295 +       FSL_ATA_CTRL_FIFO_RCV_EN   = 0x10,
296 +       FSL_ATA_CTRL_DMA_PENDING   = 0x08,
297 +       FSL_ATA_CTRL_DMA_ULTRA     = 0x04,
298 +       FSL_ATA_CTRL_DMA_WRITE     = 0x02,
299 +       FSL_ATA_CTRL_IORDY_EN      = 0x01,
300 +
301 +       /* bits within the interrupt control registers */
302 +
303 +       FSL_ATA_INTR_ATA_INTRQ1      = 0x80,
304 +       FSL_ATA_INTR_FIFO_UNDERFLOW  = 0x40,
305 +       FSL_ATA_INTR_FIFO_OVERFLOW   = 0x20,
306 +       FSL_ATA_INTR_CTRL_IDLE       = 0x10,
307 +       FSL_ATA_INTR_ATA_INTRQ2      = 0x08,
308 +};
309 +
310 +/*
311 + * This structure contains the timing parameters for
312 + * ATA bus timing in the 5 PIO modes.  The timings
313 + * are in nanoseconds, and are converted to clock
314 + * cycles before being stored in the ATA controller
315 + * timing registers.
316 + */
317 +static struct {
318 +       short t0, t1, t2_8, t2_16, t2i, t4, t9, tA;
319 +} pio_specs[] = {
320 +       [0] = {
321 +               .t0 = 600, .t1 = 70, .t2_8 = 290, .t2_16 = 165, .t2i = 0,
322 +               .t4 = 30,.t9 = 20,.tA = 50
323 +       },
324 +       [1] = {
325 +               .t0 = 383, .t1 = 50, .t2_8 = 290, .t2_16 = 125, .t2i = 0,
326 +               .t4 = 20, .t9 = 15, .tA = 50
327 +       },
328 +       [2] = {
329 +               .t0 = 240, .t1 = 30, .t2_8 = 290, .t2_16 = 100, .t2i = 0,
330 +               .t4 = 15, .t9 = 10, .tA = 50
331 +       },
332 +       [3] = {
333 +               .t0 = 180, .t1 = 30, .t2_8 = 80, .t2_16 = 80, .t2i = 0,
334 +               .t4 = 10, .t9 = 10, .tA = 50
335 +       },
336 +       [4] = {
337 +               .t0 = 120, .t1 = 25, .t2_8 = 70, .t2_16 = 70, .t2i = 0,
338 +               .t4 = 10, .t9 = 10, .tA = 50
339 +       },
340 +};
341 +
342 +#define NR_PIO_SPECS (sizeof pio_specs / sizeof pio_specs[0])
343 +
344 +/*
345 + * This structure contains the timing parameters for
346 + * ATA bus timing in the 3 MDMA modes.  The timings
347 + * are in nanoseconds, and are converted to clock
348 + * cycles before being stored in the ATA controller
349 + * timing registers.
350 + */
351 +static struct {
352 +       short t0M, tD, tH, tJ, tKW, tM, tN, tJNH;
353 +} mdma_specs[] = {
354 +       [0] = {
355 +               .t0M = 480, .tD = 215, .tH = 20, .tJ = 20, .tKW = 215,
356 +               .tM = 50, .tN = 15, .tJNH = 20
357 +       },
358 +       [1] = {
359 +               .t0M = 150, .tD = 80, .tH = 15, .tJ = 5, .tKW = 50,
360 +               .tM = 30, .tN = 10, .tJNH = 15
361 +       },
362 +       [2] = {
363 +               .t0M = 120, .tD = 70, .tH = 10, .tJ = 5, .tKW = 25,
364 +               .tM = 25, .tN = 10, .tJNH = 10
365 +       },
366 +};
367 +
368 +#define NR_MDMA_SPECS (sizeof mdma_specs / sizeof mdma_specs[0])
369 +
370 +/*
371 + * This structure contains the timing parameters for
372 + * ATA bus timing in the 6 UDMA modes.  The timings
373 + * are in nanoseconds, and are converted to clock
374 + * cycles before being stored in the ATA controller
375 + * timing registers.
376 + */
377 +static struct {
378 +       short t2CYC, tCYC, tDS, tDH, tDVS, tDVH, tCVS, tCVH, tFS_min, tLI_max,
379 +           tMLI, tAZ, tZAH, tENV_min, tSR, tRFS, tRP, tACK, tSS, tDZFS;
380 +} udma_specs[] = {
381 +       [0] = {
382 +               .t2CYC = 235, .tCYC = 114, .tDS = 15, .tDH = 5, .tDVS = 70,
383 +               .tDVH = 6, .tCVS = 70, .tCVH = 6, .tFS_min = 0,
384 +               .tLI_max = 100, .tMLI = 20, .tAZ = 10, .tZAH = 20,
385 +               .tENV_min = 20, .tSR = 50, .tRFS = 75, .tRP = 160,
386 +               .tACK = 20, .tSS = 50, .tDZFS = 80
387 +       },
388 +       [1] = {
389 +               .t2CYC = 156, .tCYC = 75, .tDS = 10, .tDH = 5, .tDVS = 48,
390 +               .tDVH = 6, .tCVS = 48, .tCVH = 6, .tFS_min = 0,
391 +               .tLI_max = 100, .tMLI = 20, .tAZ = 10, .tZAH = 20,
392 +               .tENV_min = 20, .tSR = 30, .tRFS = 70, .tRP = 125,
393 +               .tACK = 20, .tSS = 50, .tDZFS = 63
394 +       },
395 +       [2] = {
396 +               .t2CYC = 117, .tCYC = 55, .tDS = 7, .tDH = 5, .tDVS = 34,
397 +               .tDVH = 6, .tCVS = 34, .tCVH = 6, .tFS_min = 0,
398 +               .tLI_max = 100, .tMLI = 20, .tAZ = 10, .tZAH = 20,
399 +               .tENV_min = 20, .tSR = 20, .tRFS = 60, .tRP = 100,
400 +               .tACK = 20, .tSS = 50, .tDZFS = 47
401 +       },
402 +       [3] = {
403 +               .t2CYC = 86, .tCYC = 39, .tDS = 7, .tDH = 5, .tDVS = 20,
404 +               .tDVH = 6, .tCVS = 20, .tCVH = 6, .tFS_min = 0,
405 +               .tLI_max = 100, .tMLI = 20, .tAZ = 10, .tZAH = 20,
406 +               .tENV_min = 20, .tSR = 20, .tRFS = 60, .tRP = 100,
407 +               .tACK = 20, .tSS = 50, .tDZFS = 35
408 +       },
409 +       [4] = {
410 +               .t2CYC = 57, .tCYC = 25, .tDS = 5, .tDH = 5, .tDVS = 7,
411 +               .tDVH = 6, .tCVS = 7, .tCVH = 6, .tFS_min = 0,
412 +               .tLI_max = 100, .tMLI = 20, .tAZ = 10, .tZAH = 20,
413 +               .tENV_min = 20, .tSR = 50, .tRFS = 60, .tRP = 100,
414 +               .tACK = 20, .tSS = 50, .tDZFS = 25
415 +       },
416 +       [5] = {
417 +               .t2CYC = 38, .tCYC = 17, .tDS = 4, .tDH = 5, .tDVS = 5,
418 +               .tDVH = 6, .tCVS = 10, .tCVH = 10, .tFS_min = 0,
419 +               .tLI_max = 75, .tMLI = 20, .tAZ = 10, .tZAH = 20,
420 +               .tENV_min = 20, .tSR = 20, .tRFS = 50, .tRP = 85,
421 +               .tACK = 20, .tSS = 50, .tDZFS = 40
422 +       },
423 +};
424 +
425 +#define NR_UDMA_SPECS (sizeof udma_specs / sizeof udma_specs[0])
426 +
427 +struct fsl_ata_time_regs {
428 +       u8 time_off, time_on, time_1, time_2w;
429 +       u8 time_2r, time_ax, time_pio_rdx, time_4;
430 +       u8 time_9, time_m, time_jn, time_d;
431 +       u8 time_k, time_ack, time_env, time_rpx;
432 +       u8 time_zah, time_mlix, time_dvh, time_dzfs;
433 +       u8 time_dvs, time_cvh, time_ss, time_cyc;
434 +};
435 +
436 +static void update_timing_config(struct fsl_ata_time_regs *tp, struct ata_host *host)
437 +{
438 +       u32 *lp = (u32 *)tp;
439 +       struct pata_fsl_priv *priv = host->private_data;
440 +       u32 *ctlp = (u32 *)priv->fsl_ata_regs;
441 +       int i;
442 +
443 +       /* 
444 +        * JKM - this could have endianess issues on BE depending
445 +        * on how the controller is glued to the bus -- probably
446 +        * should rewrite this to write byte at a time.
447 +        */
448 +       for (i = 0; i < 5; i++) {
449 +               __raw_writel(*lp, ctlp);
450 +               lp++;
451 +               ctlp++;
452 +       }
453 +       mb();
454 +}
455 +
456 +/*!
457 + * Calculate values for the ATA bus timing registers and store
458 + * them into the hardware.
459 + *
460 + * @param       xfer_mode   specifies XFER xfer_mode
461 + * @param       pdev        specifies platform_device
462 + *
463 + * @return      EINVAL      speed out of range, or illegal mode
464 + */
465 +static int set_ata_bus_timing(u8 xfer_mode, struct platform_device *pdev)
466 +{
467 +       struct fsl_ata_platform_data *plat = (struct fsl_ata_platform_data *)
468 +                                            pdev->dev.platform_data;
469 +       struct ata_host *host = dev_get_drvdata(&pdev->dev);
470 +
471 +       /* get the bus clock cycle time, in ns */
472 +       int T = 1 * 1000 * 1000 * 1000 / plat->get_clk_rate();
473 +       struct fsl_ata_time_regs tr = {0};
474 +       DPRINTK("clk_rate = %d  T = %d\n",plat->get_clk_rate(), T);
475 +
476 +       /*
477 +        * every mode gets the same t_off and t_on
478 +        */
479 +       tr.time_off = 3;
480 +       tr.time_on = 3;
481 +
482 +       if (xfer_mode >= XFER_UDMA_0) {
483 +               int speed = xfer_mode - XFER_UDMA_0;
484 +               if (speed >= NR_UDMA_SPECS) {
485 +                       return -EINVAL;
486 +               }
487 +               tr.time_ack = (udma_specs[speed].tACK + T) / T;
488 +               tr.time_env = (udma_specs[speed].tENV_min + T) / T;
489 +               tr.time_rpx = (udma_specs[speed].tRP + T) / T + 2;
490 +
491 +               tr.time_zah = (udma_specs[speed].tZAH + T) / T;
492 +               tr.time_mlix = (udma_specs[speed].tMLI + T) / T;
493 +               tr.time_dvh = (udma_specs[speed].tDVH + T) / T + 1;
494 +               tr.time_dzfs = (udma_specs[speed].tDZFS + T) / T;
495 +
496 +               tr.time_dvs = (udma_specs[speed].tDVS + T) / T;
497 +               tr.time_cvh = (udma_specs[speed].tCVH + T) / T;
498 +               tr.time_ss = (udma_specs[speed].tSS + T) / T;
499 +               tr.time_cyc = (udma_specs[speed].tCYC + T) / T;
500 +       } else if (xfer_mode >= XFER_MW_DMA_0) {
501 +               int speed = xfer_mode - XFER_MW_DMA_0;
502 +               if (speed >= NR_MDMA_SPECS) {
503 +                       return -EINVAL;
504 +               }
505 +               tr.time_m = (mdma_specs[speed].tM + T) / T;
506 +               tr.time_jn = (mdma_specs[speed].tJNH + T) / T;
507 +               tr.time_d = (mdma_specs[speed].tD + T) / T;
508 +
509 +               tr.time_k = (mdma_specs[speed].tKW + T) / T;
510 +       } else {
511 +               int speed = xfer_mode - XFER_PIO_0;
512 +               if (speed >= NR_PIO_SPECS) {
513 +                       return -EINVAL;
514 +               }
515 +               tr.time_1 = (pio_specs[speed].t1 + T) / T;
516 +               tr.time_2w = (pio_specs[speed].t2_8 + T) / T;
517 +
518 +               tr.time_2r = (pio_specs[speed].t2_8 + T) / T;
519 +               tr.time_ax = (pio_specs[speed].tA + T) / T + 2;
520 +               tr.time_pio_rdx = 1;
521 +               tr.time_4 = (pio_specs[speed].t4 + T) / T;
522 +
523 +               tr.time_9 = (pio_specs[speed].t9 + T) / T;
524 +       }
525 +
526 +       update_timing_config(&tr, host);
527 +
528 +       return 0;
529 +}
530 +
531 +static void pata_fsl_set_piomode(struct ata_port *ap, struct ata_device *adev)
532 +{
533 +       set_ata_bus_timing(adev->pio_mode, to_platform_device(ap->dev));
534 +}
535 +
536 +#ifdef CONFIG_FSL_PATA_USE_DMA
537 +static void pata_fsl_set_dmamode(struct ata_port *ap, struct ata_device *adev)
538 +{
539 +       struct pata_fsl_priv *priv = ap->host->private_data;
540 +
541 +       priv->ultra = adev->dma_mode >= XFER_UDMA_0;
542 +
543 +       set_ata_bus_timing(adev->dma_mode, to_platform_device(ap->dev));
544 +}
545 +#endif
546 +
547 +static int pata_fsl_port_start(struct ata_port *ap)
548 +{
549 +       return 0;
550 +}
551 +
552 +#ifdef CONFIG_FSL_PATA_USE_DMA
553 +static void dma_callback(void *arg, int error_status, unsigned int count)
554 +{
555 +       struct ata_port *ap = arg;
556 +       struct pata_fsl_priv *priv = ap->host->private_data;
557 +       u8 *ata_regs = priv->fsl_ata_regs;
558 +
559 +       priv->dma_done = 1;
560 +       /* 
561 +        * DMA is finished, so unmask INTRQ from the drive to allow the
562 +        * normal ISR to fire.
563 +        */
564 +#if 0
565 +       __raw_writel(FSL_ATA_INTR_ATA_INTRQ2, ata_regs + FSL_ATA_INT_EN);
566 +#else
567 +       WRITE_ATA8(FSL_ATA_INTR_ATA_INTRQ2, FSL_ATA_INT_EN);
568 +#endif
569 +       mb();
570 +}
571 +
572 +static void pata_fsl_bmdma_setup(struct ata_queued_cmd *qc)
573 +{
574 +       int nr_sg = 0;
575 +       int chan;
576 +       int dma_mode = 0, dma_ultra;
577 +       u8 ata_control;
578 +       struct ata_port *ap = qc->ap;
579 +       struct pata_fsl_priv *priv = ap->host->private_data;
580 +       u8 *ata_regs = priv->fsl_ata_regs;
581 +       struct fsl_ata_platform_data *plat = ap->dev->platform_data;
582 +       struct scatterlist tmp[plat->max_sg], *tsg, *sg;
583 +       int err;
584 +
585 +       DPRINTK("ENTER\n");
586 +
587 +       priv->dma_dir = qc->dma_dir;
588 +
589 +       /*
590 +        * Configure the on-chip ATA interface hardware.
591 +        */
592 +       dma_ultra = priv->ultra ?
593 +               FSL_ATA_CTRL_DMA_ULTRA : 0;
594 +
595 +       ata_control = FSL_ATA_CTRL_FIFO_RST_B |
596 +                     FSL_ATA_CTRL_ATA_RST_B |
597 +                     FSL_ATA_CTRL_DMA_PENDING |
598 +                     dma_ultra;
599 +
600 +       if (qc->dma_dir == DMA_TO_DEVICE) {
601 +               chan = priv->dma_wchan;
602 +               ata_control |= FSL_ATA_CTRL_FIFO_TX_EN |
603 +                             FSL_ATA_CTRL_DMA_WRITE;
604 +               dma_mode = DMA_MODE_WRITE;
605 +       } else {
606 +               chan = priv->dma_rchan;
607 +               ata_control |= FSL_ATA_CTRL_FIFO_RCV_EN;
608 +               dma_mode = DMA_MODE_READ;
609 +       }
610 +#if 0
611 +       __raw_writel(ata_control, ata_regs + FSL_ATA_CONTROL);
612 +       __raw_writel(plat->fifo_alarm, ata_regs + FSL_ATA_FIFO_ALARM);
613 +       __raw_writel(FSL_ATA_INTR_ATA_INTRQ1, ata_regs + FSL_ATA_INT_EN);
614 +#else
615 +       WRITE_ATA8(ata_control, FSL_ATA_CONTROL);
616 +       WRITE_ATA8(plat->fifo_alarm, FSL_ATA_FIFO_ALARM);
617 +       WRITE_ATA8(FSL_ATA_INTR_ATA_INTRQ1, FSL_ATA_INT_EN);
618 +#endif
619 +       mb();
620 +
621 +       /*
622 +        * Set up the DMA completion callback.
623 +        */
624 +       mxc_dma_callback_set(chan, dma_callback, (void *)ap);
625 +
626 +       /*
627 +        * Copy the sg list to an array.
628 +        */
629 +       tsg = tmp;
630 +       ata_for_each_sg(sg, qc) {
631 +               memcpy(tsg, sg, sizeof *sg);
632 +               tsg++;
633 +               nr_sg++;
634 +       }
635 +       
636 +       err = mxc_dma_sg_config(chan, tmp, nr_sg, 0, dma_mode);
637 +       if (err) {
638 +               printk(KERN_ERR "pata_fsl_bmdma_setup: error %d\n", err);
639 +       }
640 +       DPRINTK("EXIT\n");
641 +}
642 +
643 +static void pata_fsl_bmdma_start(struct ata_queued_cmd *qc)
644 +{
645 +       struct ata_port *ap = qc->ap;
646 +       struct pata_fsl_priv *priv = ap->host->private_data;
647 +       int chan;
648 +       int err;
649 +
650 +       /*
651 +        * Start the channel.
652 +        */
653 +       chan = qc->dma_dir == DMA_TO_DEVICE ? priv->dma_wchan : priv->dma_rchan;
654 +
655 +       priv->dma_done = 0;
656 +
657 +       err = mxc_dma_enable(chan);
658 +       if (err) {
659 +               printk(KERN_ERR "%s: : error %d\n", __func__, err);
660 +       }
661 +
662 +       ap->ops->exec_command(ap, &qc->tf);
663 +}
664 +
665 +static void pata_fsl_bmdma_stop(struct ata_queued_cmd *qc)
666 +{
667 +       struct ata_port *ap = qc->ap;
668 +
669 +       /* do a dummy read as in ata_bmdma_stop */
670 +       ata_altstatus(ap);
671 +}
672 +
673 +static u8 pata_fsl_bmdma_status(struct ata_port *ap)
674 +{
675 +       struct pata_fsl_priv *priv = ap->host->private_data;
676 +
677 +       return priv->dma_done ? ATA_DMA_INTR : 0;
678 +}
679 +
680 +static void pata_fsl_dma_init(struct ata_port *ap)
681 +{
682 +       struct pata_fsl_priv *priv = ap->host->private_data;
683 +
684 +       priv->dma_rchan = -1;
685 +       priv->dma_wchan = -1;
686 +
687 +       priv->dma_rchan = mxc_dma_request(MXC_DMA_ATA_RX, "MXC ATA RX");
688 +       if (priv->dma_rchan < 0) {
689 +               dev_printk(KERN_ERR, ap->dev, "couldn't get RX DMA channel\n");
690 +               goto err_out;
691 +       }
692 +
693 +       priv->dma_wchan = mxc_dma_request(MXC_DMA_ATA_TX, "MXC ATA TX");
694 +       if (priv->dma_wchan < 0) {
695 +               dev_printk(KERN_ERR, ap->dev, "couldn't get TX DMA channel\n");
696 +               goto err_out;
697 +       }       
698 +
699 +       dev_printk(KERN_ERR, ap->dev, "rchan=%d wchan=%d\n", priv->dma_rchan,
700 +                  priv->dma_wchan);
701 +       return;
702 +
703 +err_out:
704 +       ap->mwdma_mask = 0;
705 +       ap->udma_mask = 0;
706 +       mxc_dma_free(priv->dma_rchan);
707 +       mxc_dma_free(priv->dma_wchan);
708 +       kfree(priv);
709 +}
710 +#endif /* CONFIG_FSL_PATA_USE_DMA */
711 +
712 +static u8 pata_fsl_irq_ack(struct ata_port *ap, unsigned int chk_drq)
713 +{
714 +       unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
715 +       u8 status;
716 +
717 +       status = ata_busy_wait(ap, bits, 1000);
718 +       if (status & bits)
719 +               if (ata_msg_err(ap))
720 +                       printk(KERN_ERR "abnormal status 0x%X\n", status);
721 +
722 +       return status;
723 +}
724 +
725 +static void ata_dummy_noret(struct ata_port *ap) { return; }
726 +
727 +static struct scsi_host_template pata_fsl_sht = {
728 +       .module                 = THIS_MODULE,
729 +       .name                   = DRV_NAME,
730 +       .ioctl                  = ata_scsi_ioctl,
731 +       .queuecommand           = ata_scsi_queuecmd,
732 +       .can_queue              = ATA_DEF_QUEUE,
733 +       .this_id                = ATA_SHT_THIS_ID,
734 +       .sg_tablesize           = LIBATA_MAX_PRD,
735 +       .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
736 +       .emulated               = ATA_SHT_EMULATED,
737 +       .use_clustering         = ATA_SHT_USE_CLUSTERING,
738 +       .proc_name              = DRV_NAME,
739 +#ifdef CONFIG_FSL_PATA_USE_DMA
740 +       .dma_boundary           = FSL_ATA_MAX_SG_LEN,
741 +#endif
742 +       .slave_configure        = ata_scsi_slave_config,
743 +       .slave_destroy          = ata_scsi_slave_destroy,
744 +       .bios_param             = ata_std_bios_param,
745 +};
746 +
747 +static struct ata_port_operations pata_fsl_port_ops = {
748 +       .set_piomode            = pata_fsl_set_piomode,
749 +#ifdef CONFIG_FSL_PATA_USE_DMA
750 +       .set_dmamode            = pata_fsl_set_dmamode,
751 +#endif
752 +
753 +       .port_disable           = ata_port_disable,
754 +       .tf_load                = ata_tf_load,
755 +       .tf_read                = ata_tf_read,
756 +       .check_status           = ata_check_status,
757 +       .exec_command           = ata_exec_command,
758 +       .dev_select             = ata_std_dev_select,
759 +
760 +       .freeze                 = ata_bmdma_freeze,
761 +       .thaw                   = ata_bmdma_thaw,
762 +       .error_handler          = ata_bmdma_error_handler,
763 +       .post_internal_cmd      = ata_bmdma_post_internal_cmd,
764 +       .cable_detect           = ata_cable_unknown,
765 +
766 +#ifdef CONFIG_FSL_PATA_USE_DMA
767 +       .bmdma_setup            = pata_fsl_bmdma_setup,
768 +       .bmdma_start            = pata_fsl_bmdma_start,
769 +#endif
770 +
771 +       .qc_prep                = ata_noop_qc_prep,
772 +       .qc_issue               = ata_qc_issue_prot,
773 +
774 +       .data_xfer              = ata_data_xfer_noirq,
775 +
776 +       .irq_clear              = ata_dummy_noret,
777 +       .irq_on                 = ata_irq_on,
778 +       .irq_ack                = pata_fsl_irq_ack,
779 +
780 +       .port_start             = pata_fsl_port_start,
781 +
782 +#ifdef CONFIG_FSL_PATA_USE_DMA
783 +       .bmdma_stop             = pata_fsl_bmdma_stop,
784 +       .bmdma_status           = pata_fsl_bmdma_status,
785 +#endif
786 +};
787 +
788 +static void fsl_setup_port(struct ata_ioports *ioaddr)
789 +{
790 +       unsigned int shift = 2;
791 +
792 +       ioaddr->data_addr       = ioaddr->cmd_addr + (ATA_REG_DATA    << shift);
793 +       ioaddr->error_addr      = ioaddr->cmd_addr + (ATA_REG_ERR     << shift);
794 +       ioaddr->feature_addr    = ioaddr->cmd_addr + (ATA_REG_FEATURE << shift);
795 +       ioaddr->nsect_addr      = ioaddr->cmd_addr + (ATA_REG_NSECT   << shift);
796 +       ioaddr->lbal_addr       = ioaddr->cmd_addr + (ATA_REG_LBAL    << shift);
797 +       ioaddr->lbam_addr       = ioaddr->cmd_addr + (ATA_REG_LBAM    << shift);
798 +       ioaddr->lbah_addr       = ioaddr->cmd_addr + (ATA_REG_LBAH    << shift);
799 +       ioaddr->device_addr     = ioaddr->cmd_addr + (ATA_REG_DEVICE  << shift);
800 +       ioaddr->status_addr     = ioaddr->cmd_addr + (ATA_REG_STATUS  << shift);
801 +       ioaddr->command_addr    = ioaddr->cmd_addr + (ATA_REG_CMD     << shift);
802 +}
803 +
804 +/**
805 + *     pata_fsl_probe          -       attach a platform interface
806 + *     @pdev: platform device
807 + *
808 + *     Register a platform bus integrated ATA host controller
809 + *
810 + *     The 3 platform device resources are used as follows:
811 + *
812 + *             - I/O Base (IORESOURCE_MEM) virt. addr. of ATA controller regs
813 + *             - CTL Base (IORESOURCE_MEM) unused
814 + *             - IRQ      (IORESOURCE_IRQ) platform IRQ assigned to ATA
815 + *
816 + */
817 +static int __devinit pata_fsl_probe(struct platform_device *pdev)
818 +{
819 +       struct resource *io_res;
820 +       struct ata_host *host;
821 +       struct ata_port *ap;
822 +       struct fsl_ata_platform_data *plat = (struct fsl_ata_platform_data *)
823 +                                            pdev->dev.platform_data;
824 +       struct pata_fsl_priv *priv;
825 +       u8 *ata_regs;
826 +       int ret;
827 +
828 +       DPRINTK("ENTER\n");
829 +       /* 
830 +        * Get an ata_host structure for this device
831 +        */
832 +       host = ata_host_alloc(&pdev->dev, 1);
833 +       if (!host)
834 +               return -ENOMEM;
835 +       ap = host->ports[0];
836 +
837 +       /* 
838 +        * Allocate private data
839 +        */
840 +       priv = kzalloc(sizeof (struct pata_fsl_priv), GFP_KERNEL);
841 +       if(priv == NULL) {
842 +               /* free(host); */
843 +               return -ENOMEM;
844 +       }
845 +       host->private_data = priv;
846 +
847 +       /*
848 +        * Set up resources
849 +        */
850 +       if (unlikely(pdev->num_resources != 3)) {
851 +               dev_err(&pdev->dev, "invalid number of resources\n");
852 +               return -EINVAL;
853 +       }
854 +
855 +       io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
856 +       ata_regs = (u8 *)io_res->start;
857 +       priv->fsl_ata_regs = ata_regs;
858 +       ap->ioaddr.cmd_addr = (void *)(ata_regs + FSL_ATA_DRIVE_DATA);
859 +       ap->ioaddr.ctl_addr = (void *)(ata_regs + FSL_ATA_DRIVE_CONTROL);
860 +       ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr;
861 +       ap->ops = &pata_fsl_port_ops;
862 +       ap->pio_mask = 0x7F;
863 +#ifdef CONFIG_FSL_PATA_USE_DMA
864 +       ap->mwdma_mask = 0x7F;
865 +       ap->udma_mask = plat->udma_mask;
866 +       pata_fsl_sht.sg_tablesize = plat->max_sg;
867 +#else
868 +       ap->mwdma_mask = 0x00;
869 +       ap->udma_mask = 0x00;
870 +#endif
871 +       fsl_setup_port(&ap->ioaddr);
872 +
873 +       /*
874 +        * Do platform-specific initialization (e.g. allocate pins,
875 +        * turn on clock).  After this call it is assumed that
876 +        * plat->get_clk_rate() can be called to calculate
877 +        * timing.
878 +        */
879 +       if (plat->init && plat->init(pdev)) {
880 +               /* REVISIT: don't leak what ata_host_alloc() allocated */
881 +               return -ENODEV;
882 +       }
883 +
884 +       /* Deassert the reset bit to enable the interface */
885 +       WRITE_ATA8(FSL_ATA_CTRL_ATA_RST_B, FSL_ATA_CONTROL);
886 +       mb();
887 +
888 +       /* Set initial timing and mode */
889 +       set_ata_bus_timing(XFER_PIO_4, pdev);
890 +
891 +#ifdef CONFIG_FSL_PATA_USE_DMA
892 +       /* get DMA ready */
893 +       pata_fsl_dma_init(ap);
894 +#endif
895 +
896 +       /*
897 +        * Enable the ATA INTRQ interrupt from the bus, but
898 +        * only allow the CPU to see it (INTRQ2) at this point.
899 +        * INTRQ1, which goes to the DMA, will be enabled later.
900 +        */
901 +#if 0
902 +       __raw_writel(FSL_ATA_INTR_ATA_INTRQ2, ata_regs + FSL_ATA_INT_EN);
903 +#else
904 +       WRITE_ATA8(FSL_ATA_INTR_ATA_INTRQ2, FSL_ATA_INT_EN);
905 +#endif
906 +       mb();
907 +
908 +       /* activate */
909 +       ret = ata_host_activate(host, platform_get_irq(pdev, 0), ata_interrupt,
910 +                                0, &pata_fsl_sht);
911 +       DPRINTK("EXIT ret=%d\n", ret);
912 +       return ret;
913 +}
914 +
915 +/**
916 + *     pata_fsl_remove -       unplug a platform interface
917 + *     @pdev: platform device
918 + *
919 + *     A platform bus ATA device has been unplugged. Perform the needed
920 + *     cleanup. Also called on module unload for any active devices.
921 + */
922 +static int __devexit pata_fsl_remove(struct platform_device *pdev)
923 +{
924 +       struct device *dev = &pdev->dev;
925 +       struct ata_host *host = dev_get_drvdata(dev);
926 +       struct pata_fsl_priv *priv = host->private_data;
927 +       struct fsl_ata_platform_data *plat = (struct fsl_ata_platform_data *)
928 +                                            pdev->dev.platform_data;
929 +       u8 *ata_regs = priv->fsl_ata_regs;
930 +
931 +#if 0
932 +       __raw_writel(0, ata_regs + FSL_ATA_INT_EN);  /* Disable interrupts */
933 +#else
934 +       WRITE_ATA8(0, FSL_ATA_INT_EN); /* Disable interrupts */
935 +#endif
936 +       mb();
937 +
938 +       ata_host_detach(host);
939 +
940 +       if (plat->exit)
941 +               plat->exit();
942 +
943 +       kfree(priv);
944 +
945 +       return 0;
946 +}
947 +
948 +#ifdef CONFIG_PM
949 +static int pata_fsl_suspend(struct platform_device *pdev, pm_message_t state)
950 +{
951 +       struct ata_host *host = dev_get_drvdata(&pdev->dev);
952 +       struct pata_fsl_priv *priv = host->private_data;
953 +       struct fsl_ata_platform_data *plat = (struct fsl_ata_platform_data *)
954 +                                            pdev->dev.platform_data;
955 +       u8 *ata_regs = priv->fsl_ata_regs;
956 +
957 +       /* Disable interrupts. */
958 +#if 0
959 +       __raw_writel(0, ata_regs + FSL_ATA_INT_EN);
960 +#else
961 +       WRITE_ATA8(0, FSL_ATA_INT_EN);
962 +#endif
963 +       mb();
964 +
965 +       if (plat->exit)
966 +               plat->exit();
967 +
968 +       return 0;
969 +}
970 +
971 +static int pata_fsl_resume(struct platform_device *pdev)
972 +{
973 +       struct ata_host *host = dev_get_drvdata(&pdev->dev);
974 +       struct pata_fsl_priv *priv = host->private_data;
975 +       struct fsl_ata_platform_data *plat = (struct fsl_ata_platform_data *)
976 +                                            pdev->dev.platform_data;
977 +       u8 *ata_regs = priv->fsl_ata_regs;
978 +
979 +       if (plat->init && plat->init(pdev)) {
980 +               return -ENODEV;
981 +       }
982 +
983 +       /* Deassert the reset bit to enable the interface */
984 +#if 0
985 +       __raw_writel(FSL_ATA_CTRL_ATA_RST_B, ata_regs + FSL_ATA_CONTROL);
986 +#else
987 +       WRITE_ATA8(FSL_ATA_CTRL_ATA_RST_B, FSL_ATA_CONTROL);
988 +#endif
989 +       mb();
990 +
991 +       /* Set initial timing and mode */
992 +       set_ata_bus_timing(XFER_PIO_4, pdev);
993 +
994 +       /*
995 +        * Enable hardware interrupts.
996 +        */
997 +#if 0
998 +       __raw_writel(FSL_ATA_INTR_ATA_INTRQ2, ata_regs + FSL_ATA_INT_EN);
999 +#else
1000 +       WRITE_ATA8(FSL_ATA_INTR_ATA_INTRQ2, FSL_ATA_INT_EN);
1001 +#endif
1002 +       mb();
1003 +
1004 +       return 0;
1005 +}
1006 +#endif
1007 +
1008 +static struct platform_driver pata_fsl_driver = {
1009 +       .probe          = pata_fsl_probe,
1010 +       .remove         = __devexit_p(pata_fsl_remove),
1011 +#ifdef CONFIG_PM
1012 +       .suspend        = pata_fsl_suspend,
1013 +       .resume         = pata_fsl_resume,
1014 +#endif
1015 +       .driver = {
1016 +               .name           = DRV_NAME,
1017 +               .owner          = THIS_MODULE,
1018 +       },
1019 +};
1020 +
1021 +static int __init pata_fsl_init(void)
1022 +{
1023 +       int ret;
1024 +
1025 +       DPRINTK("ENTER\n");
1026 +       ret = platform_driver_register(&pata_fsl_driver);
1027 +       DPRINTK("EXIT ret=%d\n", ret);
1028 +       return ret;
1029 +}
1030 +
1031 +static void __exit pata_fsl_exit(void)
1032 +{
1033 +       platform_driver_unregister(&pata_fsl_driver);
1034 +}
1035 +module_init(pata_fsl_init);
1036 +module_exit(pata_fsl_exit);
1037 +
1038 +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
1039 +MODULE_DESCRIPTION("low-level driver for Freescale ATA");
1040 +MODULE_LICENSE("GPL");
1041 +MODULE_VERSION(DRV_VERSION);
1042 --- a/include/asm-m68k/pci.h
1043 +++ b/include/asm-m68k/pci.h
1044 @@ -7,8 +7,14 @@
1045  #ifndef _ASM_M68K_PCI_H
1046  #define _ASM_M68K_PCI_H
1047  
1048 -#ifdef CONFIG_PCI
1049 -
1050 +#ifndef CONFIG_PCI
1051 +/*
1052 + * The PCI address space does equal the physical memory
1053 + * address space.  The networking and block device layers use
1054 + * this boolean for bounce buffer decisions.
1055 + */
1056 +#define PCI_DMA_BUS_IS_PHYS            (1)
1057 +#else
1058  #include <asm-generic/pci-dma-compat.h>
1059  
1060  /*
1061 --- a/include/linux/fsl_devices.h
1062 +++ b/include/linux/fsl_devices.h
1063 @@ -126,5 +126,16 @@ struct mpc8xx_pcmcia_ops {
1064         int(*voltage_set)(int slot, int vcc, int vpp);
1065  };
1066  
1067 +struct fsl_ata_platform_data {
1068 +#ifdef CONFIG_FSL_PATA_USE_DMA
1069 +       int     udma_mask;      /* UDMA modes h/w can handle */
1070 +       int     fifo_alarm;     /* value for fifo_alarm reg */
1071 +       int     max_sg;         /* longest sglist h/w can handle */
1072 +#endif
1073 +       int     (*init)(struct platform_device *pdev);
1074 +       void    (*exit)(void);
1075 +       int     (*get_clk_rate)(void);
1076 +};
1077 +
1078  #endif /* _FSL_DEVICE_H_ */
1079  #endif /* __KERNEL__ */