linux-2.6.34: remove c7x0 patch from SRC_URI override as that file was removed in...
[openembedded.git] / recipes / linux / linux-efika-2.6.20 / 0023-POWERPC-Make-FEC-work-on-the-lite5200.txt
blobbdbafcb30d04e66cc0bdc296d3174ba6fe5b0570
1 From 3c687b616fee5d7097e965fce80f8f8b2b6e14cf Mon Sep 17 00:00:00 2001
2 From: Grant Likely <grant.likely@secretlab.ca>
3 Date: Mon, 4 Dec 2006 22:29:03 -0700
4 Subject: [PATCH] [POWERPC] Make FEC work on the lite5200
6 This patch may very well break Eth support on the Efika, and it's not
7 very pretty.  But is works well enough for an NFS rootfs.  This also
8 makes major bestcomm changes by removing Efika-specific bestcomm
9 support and porting the arch/ppc bestcomm support driver which
10 was posted to linuxppc-embedded about a year ago.
12 Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
13 ---
14  arch/powerpc/Kconfig                   |    5 +
15  arch/powerpc/platforms/52xx/Makefile   |    3 +
16  arch/powerpc/platforms/52xx/bestcomm.c |   98 ++++++++++-------------
17  arch/powerpc/platforms/52xx/bestcomm.h |   13 ++-
18  arch/powerpc/platforms/52xx/fec.c      |    1 -
19  arch/powerpc/platforms/52xx/lite5200.c |    9 ++
20  drivers/net/fec_mpc52xx/Kconfig        |    2 +-
21  drivers/net/fec_mpc52xx/fec.c          |  137 +++++++++++++++++++++++++++----
22  drivers/net/fec_mpc52xx/fec_phy.c      |    6 ++
23  9 files changed, 196 insertions(+), 78 deletions(-)
25 diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
26 index 8699dad..23d7d73 100644
27 --- a/arch/powerpc/Kconfig
28 +++ b/arch/powerpc/Kconfig
29 @@ -429,6 +429,11 @@ config PPC_MPC52xx
30         bool
31         default n
33 +config PPC_BESTCOMM
34 +       bool
35 +       depends on PPC_MPC52xx
36 +       default y
38  config PPC_EFIKA
39         bool "bPlan Efika 5k2. MPC5200B based computer"
40         depends on PPC_MULTIPLATFORM && PPC32
41 diff --git a/arch/powerpc/platforms/52xx/Makefile b/arch/powerpc/platforms/52xx/Makefile
42 index a46184a..d85ea04 100644
43 --- a/arch/powerpc/platforms/52xx/Makefile
44 +++ b/arch/powerpc/platforms/52xx/Makefile
45 @@ -3,6 +3,9 @@
46  #
47  ifeq ($(CONFIG_PPC_MERGE),y)
48  obj-y                          += mpc52xx_pic.o mpc52xx_common.o
49 +obj-$(CONFIG_PCI)              += mpc52xx_pci.o
50 +obj-$(CONFIG_PPC_BESTCOMM)     += bestcomm.o
51 +obj-$(CONFIG_FEC_MPC52xx)      += sdma_fec_rx_task.o sdma_fec_tx_task.o fec.o
52  endif
54  obj-$(CONFIG_PPC_EFIKA)                += efika-setup.o efika-pci.o
55 diff --git a/arch/powerpc/platforms/52xx/bestcomm.c b/arch/powerpc/platforms/52xx/bestcomm.c
56 index ef45e02..9935b01 100644
57 --- a/arch/powerpc/platforms/52xx/bestcomm.c
58 +++ b/arch/powerpc/platforms/52xx/bestcomm.c
59 @@ -16,7 +16,6 @@
60   *             Andrey Volkov <avolkov@varma-el.com>, Varma Electronics Oy
61   */
63 -#include <linux/config.h>
64  #include <linux/version.h>
65  #include <linux/module.h>
66  #include <linux/kernel.h>
67 @@ -24,17 +23,19 @@
68  #include <linux/slab.h>
69  #include <linux/spinlock.h>
70  #include <linux/string.h>
71 -#include <linux/device.h>
73  #include <asm/bug.h>
74  #include <asm/io.h>
75  #include <asm/mpc52xx.h>
76 +#include <asm/of_platform.h>
78  #include "bestcomm.h"
80 -#define DRIVER_NAME            "mpc52xx-sdma"
81 +#define DRIVER_NAME "mpc52xx-bestcomm"
83  struct sdma_io sdma;
84 +struct device_node *sdma_node;
85 +struct device_node *sram_node;
87  static spinlock_t sdma_lock = SPIN_LOCK_UNLOCKED;
89 @@ -42,7 +43,8 @@ static spinlock_t sdma_lock = SPIN_LOCK_UNLOCKED;
90  void sdma_dump(void)
91  {
92         int i;
93 -       printk("** SDMA registers: pa = %08x, va = %08x\n", sdma.base_reg_addr, sdma.io);
94 +       printk("** SDMA registers: pa = %.8lx, va = %p\n",
95 +              sdma.base_reg_addr, sdma.io);
96         printk("**  taskBar = %08x\n", sdma.io->taskBar);
97         printk("**  currentPointer = %08x\n", sdma.io->currentPointer);
98         printk("**  endPointer = %08x\n", sdma.io->endPointer);
99 @@ -254,6 +256,7 @@ struct sdma *sdma_alloc(int queue_size)
100         }
102         s->num_bd = queue_size;
103 +       s->node = sdma_node;
104         return s;
107 @@ -264,29 +267,49 @@ void sdma_free(struct sdma *s)
108         kfree(s);
111 -static int __devinit mpc52xx_sdma_probe(struct device *dev)
112 +static int __init mpc52xx_sdma_init(void)
114 -       struct platform_device *pdev = to_platform_device(dev);
115         int task;
116         u32 *context;
117         u32 *fdt;
118         struct sdma_tdt *tdt;
119 -       struct resource *mem_io, *mem_sram;
120 -       u32 tdt_pa, var_pa, context_pa, fdt_pa; 
121 +       struct resource mem_io, mem_sram;
122 +       u32 tdt_pa, var_pa, context_pa, fdt_pa;
123         int ret = -ENODEV;
125 -       mem_io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
126 -       mem_sram = platform_get_resource(pdev, IORESOURCE_MEM, 1);
127 -       if (!mem_io || !mem_sram)
128 +       /* Find SDMA registers */
129 +       sdma_node = of_find_compatible_node(NULL, "dma-controller", "mpc52xx-bestcomm");
130 +       if (!sdma_node) {
131 +               printk (KERN_ERR DRIVER_NAME ": could not locate SDRAM controller\n");
132                 goto out;
133 +       }
135 +       if ((ret = of_address_to_resource(sdma_node, 0, &mem_io)) != 0) {
136 +               printk(KERN_ERR "Could not get address of SDMA controller\n");
137 +               goto out;
138 +       }
140 +       /* Find SRAM location */
141 +       sram_node = of_find_compatible_node(NULL, "sram", "mpc52xx-sram");
142 +       if (!sram_node) {
143 +               printk (KERN_ERR DRIVER_NAME ": could not locate SRAM\n");
144 +               goto out;
145 +       }
147 +       if ((ret = of_address_to_resource(sram_node, 0, &mem_sram)) != 0) {
148 +               printk(KERN_ERR "Could not get address of SRAM\n");
149 +               goto out;
150 +       }
152 -       if (!request_mem_region(mem_io->start, mem_io->end - mem_io->start + 1, DRIVER_NAME)) {
153 +       /* Map register regions */
154 +       if (!request_mem_region(mem_io.start, mem_io.end - mem_io.start + 1,
155 +                               DRIVER_NAME)) {
156                 printk(KERN_ERR DRIVER_NAME " - resource unavailable\n");
157                 goto out;
158         }
159 -       sdma.base_reg_addr = mem_io->start;
160 +       sdma.base_reg_addr = mem_io.start;
162 -       sdma.io = ioremap_nocache(mem_io->start, sizeof(struct mpc52xx_sdma));
163 +       sdma.io = ioremap_nocache(mem_io.start, sizeof(struct mpc52xx_sdma));
165         if (!sdma.io ) {
166                 printk(KERN_ERR DRIVER_NAME " - failed to map sdma regs\n");
167 @@ -296,14 +319,14 @@ static int __devinit mpc52xx_sdma_probe(struct device *dev)
169         SDMA_DUMP_REGS();
171 -       sdma.sram_size = mem_sram->end - mem_sram->start + 1;
172 -       if (!request_mem_region(mem_sram->start, sdma.sram_size, DRIVER_NAME)) {
173 +       sdma.sram_size = mem_sram.end - mem_sram.start + 1;
174 +       if (!request_mem_region(mem_sram.start, sdma.sram_size, DRIVER_NAME)) {
175                 printk(KERN_ERR DRIVER_NAME " - resource unavailable\n");
176                 goto req_sram_error;
177         }
179 -       sdma.base_sram_addr = mem_sram->start;
180 -       sdma.sram = ioremap_nocache(mem_sram->start, sdma.sram_size);
181 +       sdma.base_sram_addr = mem_sram.start;
182 +       sdma.sram = ioremap_nocache(mem_sram.start, sdma.sram_size);
183         if (!sdma.sram ) {
184                 printk(KERN_ERR DRIVER_NAME " - failed to map sdma sram\n");
185                 ret = -ENOMEM;
186 @@ -350,50 +373,17 @@ static int __devinit mpc52xx_sdma_probe(struct device *dev)
187         return 0;
189  map_sram_error:
190 -       release_mem_region(mem_sram->start, sdma.sram_size);
191 +       release_mem_region(mem_sram.start, sdma.sram_size);
192  req_sram_error:
193         iounmap(sdma.io);
194  map_io_error:
195 -       release_mem_region(mem_io->start, mem_io->end - mem_io->start + 1);
196 +       release_mem_region(mem_io.start, mem_io.end - mem_io.start + 1);
197  out:
198         printk(KERN_ERR "DMA: MPC52xx BestComm init FAILED !!!\n");
199         return ret;
203 -static struct device_driver mpc52xx_sdma_driver = {
204 -       .owner    = THIS_MODULE,
205 -       .name     = DRIVER_NAME,
206 -       .bus      = &platform_bus_type,
207 -       .probe    = mpc52xx_sdma_probe,
208 -/*     .remove   = mpc52xx_sdma_remove,        TODO */
209 -#ifdef CONFIG_PM
210 -/*     .suspend        = mpc52xx_sdma_suspend, TODO */
211 -/*     .resume         = mpc52xx_sdma_resume,  TODO */
212 -#endif
215 -static int __init
216 -mpc52xx_sdma_init(void)
218 -       printk(KERN_INFO "DMA: MPC52xx BestComm driver\n");
219 -       return driver_register(&mpc52xx_sdma_driver);
222 -#ifdef MODULE
223 -static void __exit
224 -mpc52xx_sdma_exit(void)
226 -       driver_unregister(&mpc52xx_sdma_driver);
228 -#endif
230 -#ifndef MODULE
231 - subsys_initcall(mpc52xx_sdma_init);
232 -#else
233 - module_init(mpc52xx_sdma_init);
234 - module_exit(mpc52xx_sdma_exit);
235 -#endif
236 +subsys_initcall(mpc52xx_sdma_init);
239  MODULE_DESCRIPTION("Freescale MPC52xx BestComm DMA");
240 diff --git a/arch/powerpc/platforms/52xx/bestcomm.h b/arch/powerpc/platforms/52xx/bestcomm.h
241 index 14bf397..bd2619d 100644
242 --- a/arch/powerpc/platforms/52xx/bestcomm.h
243 +++ b/arch/powerpc/platforms/52xx/bestcomm.h
244 @@ -19,6 +19,8 @@
245  #ifndef __BESTCOMM_BESTCOMM_H__
246  #define __BESTCOMM_BESTCOMM_H__
248 +#include "mpc52xx_pic.h"
250  /* Buffer Descriptor definitions */
251  struct sdma_bd {
252         u32 status;
253 @@ -70,6 +72,7 @@ struct sdma {
254         u16 num_bd;
255         s16 tasknum;
256         u32 flags;
257 +       struct device_node *node;
258  };
260  #define SDMA_FLAGS_NONE                0x0000
261 @@ -116,7 +119,9 @@ struct sdma_tdt {
263  static inline void sdma_enable_task(int task)
265 -       DPRINTK("***DMA enable task (%d): tdt = %08x\n",task, sdma.tdt);
266 +       u16 reg;
268 +       DPRINTK("***DMA enable task (%d): tdt = %p\n",task, sdma.tdt);
269         DPRINTK("***tdt->start   = %08x\n",sdma.tdt[task].start);
270         DPRINTK("***tdt->stop    = %08x\n",sdma.tdt[task].stop);
271         DPRINTK("***tdt->var     = %08x\n",sdma.tdt[task].var);
272 @@ -127,8 +132,8 @@ static inline void sdma_enable_task(int task)
273         DPRINTK("***tdt->litbase = %08x\n",sdma.tdt[task].litbase);
274         DPRINTK("***--------------\n");
276 -       u16 reg = in_be16(&sdma.io->tcr[task]);
277 -       DPRINTK("***enable task: &sdma.io->tcr=%08x, reg = %04x\n", &sdma.io->tcr, reg);
278 +       reg = in_be16(&sdma.io->tcr[task]);
279 +       DPRINTK("***enable task: &sdma.io->tcr=%p, reg = %04x\n", &sdma.io->tcr, reg);
280         out_be16(&sdma.io->tcr[task],  reg | TASK_ENABLE);
283 @@ -141,7 +146,7 @@ static inline void sdma_disable_task(int task)
285  static inline int sdma_irq(struct sdma *s)
287 -       return MPC52xx_SDMA_IRQ_BASE + s->tasknum;
288 +       return irq_of_parse_and_map(s->node, s->tasknum);
291  static inline void sdma_enable(struct sdma *s)
292 diff --git a/arch/powerpc/platforms/52xx/fec.c b/arch/powerpc/platforms/52xx/fec.c
293 index 8756856..90df6f4 100644
294 --- a/arch/powerpc/platforms/52xx/fec.c
295 +++ b/arch/powerpc/platforms/52xx/fec.c
296 @@ -16,7 +16,6 @@
297   *             Andrey Volkov <avolkov@varma-el.com>, Varma Electronics Oy
298   */
300 -#include <linux/config.h>
301  #include <linux/version.h>
302  #include <linux/module.h>
303  #include <linux/kernel.h>
304 diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c
305 index 0f21bab..f1bbe24 100644
306 --- a/arch/powerpc/platforms/52xx/lite5200.c
307 +++ b/arch/powerpc/platforms/52xx/lite5200.c
308 @@ -107,6 +107,15 @@ static void __init lite52xx_setup_arch(void)
309         mpc52xx_setup_cpu();    /* Generic */
310         lite52xx_setup_cpu();   /* Platorm specific */
312 +#ifdef CONFIG_PCI
313 +       np = of_find_node_by_type(np, "pci");
314 +       if (np)
315 +               mpc52xx_add_bridge(np);
317 +       //ppc_md.pci_swizzle = common_swizzle;
318 +       //ppc_md.pci_exclude_device = mpc52xx_exclude_device;
319 +#endif
321  #ifdef CONFIG_BLK_DEV_INITRD
322         if (initrd_start)
323                 ROOT_DEV = Root_RAM0;
324 diff --git a/drivers/net/fec_mpc52xx/Kconfig b/drivers/net/fec_mpc52xx/Kconfig
325 index 098c3fa..b6bce55 100644
326 --- a/drivers/net/fec_mpc52xx/Kconfig
327 +++ b/drivers/net/fec_mpc52xx/Kconfig
328 @@ -11,7 +11,7 @@ config FEC_MPC52xx
329           Fast Ethernet Controller
331  config USE_MDIO
332 -       bool "  Use external Ethernet MII PHY"
333 +       bool "Use external Ethernet MII PHY"
334         select MII
335         depends FEC_MPC52xx
336         ---help---
337 diff --git a/drivers/net/fec_mpc52xx/fec.c b/drivers/net/fec_mpc52xx/fec.c
338 index b5f1559..894da79 100644
339 --- a/drivers/net/fec_mpc52xx/fec.c
340 +++ b/drivers/net/fec_mpc52xx/fec.c
341 @@ -30,17 +30,24 @@
342  #include <asm/ppcboot.h>
343  #include <asm/mpc52xx.h>
345 +#if defined(CONFIG_PPC_MERGE)
346 +#include <asm/of_device.h>
347 +#include <asm/of_platform.h>
348 +#include <platforms/52xx/bestcomm.h>
349 +#include <platforms/52xx/fec.h>
350 +#else
351  #include <syslib/bestcomm/bestcomm.h>
352  #include <syslib/bestcomm/fec.h>
353 +#endif
355  #include "fec_phy.h"
356  #include "fec.h"
358  #define DRIVER_NAME "mpc52xx-fec"
360 -static irqreturn_t fec_interrupt(int, void *, struct pt_regs *);
361 -static irqreturn_t fec_rx_interrupt(int, void *, struct pt_regs *);
362 -static irqreturn_t fec_tx_interrupt(int, void *, struct pt_regs *);
363 +static irqreturn_t fec_interrupt(int, void *);
364 +static irqreturn_t fec_rx_interrupt(int, void *);
365 +static irqreturn_t fec_tx_interrupt(int, void *);
366  static struct net_device_stats *fec_get_stats(struct net_device *);
367  static void fec_set_multicast_list(struct net_device *dev);
368  static void fec_reinit(struct net_device *dev);
369 @@ -233,7 +240,7 @@ static int fec_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
371  /* This handles BestComm transmit task interrupts
372   */
373 -static irqreturn_t fec_tx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
374 +static irqreturn_t fec_tx_interrupt(int irq, void *dev_id)
376         struct net_device *dev = dev_id;
377         struct fec_priv *priv = (struct fec_priv *)dev->priv;
378 @@ -259,7 +266,7 @@ static irqreturn_t fec_tx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
379         return IRQ_HANDLED;
382 -static irqreturn_t fec_rx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
383 +static irqreturn_t fec_rx_interrupt(int irq, void *dev_id)
385         struct net_device *dev = dev_id;
386         struct fec_priv *priv = (struct fec_priv *)dev->priv;
387 @@ -316,7 +323,7 @@ static irqreturn_t fec_rx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
388         return IRQ_HANDLED;
391 -static irqreturn_t fec_interrupt(int irq, void *dev_id, struct pt_regs *regs)
392 +static irqreturn_t fec_interrupt(int irq, void *dev_id)
394         struct net_device *dev = (struct net_device *)dev_id;
395         struct fec_priv *priv = (struct fec_priv *)dev->priv;
396 @@ -324,13 +331,18 @@ static irqreturn_t fec_interrupt(int irq, void *dev_id, struct pt_regs *regs)
397         int ievent;
399         ievent = in_be32(&fec->ievent);
400 +       if (!ievent)
401 +               return IRQ_NONE;
403         out_be32(&fec->ievent, ievent);         /* clear pending events */
405         if (ievent & (FEC_IEVENT_RFIFO_ERROR | FEC_IEVENT_XFIFO_ERROR)) {
406 -               if (ievent & FEC_IEVENT_RFIFO_ERROR)
407 -                       printk(KERN_WARNING "FEC_IEVENT_RFIFO_ERROR\n");
408 -               if (ievent & FEC_IEVENT_XFIFO_ERROR)
409 -                       printk(KERN_WARNING "FEC_IEVENT_XFIFO_ERROR\n");
410 +               if (net_ratelimit() && (ievent & FEC_IEVENT_RFIFO_ERROR))
411 +                       printk(KERN_WARNING "FEC_IEVENT_RFIFO_ERROR (%.8x)\n",
412 +                              ievent);
413 +               if (net_ratelimit() && (ievent & FEC_IEVENT_XFIFO_ERROR))
414 +                       printk(KERN_WARNING "FEC_IEVENT_XFIFO_ERROR (%.8x)\n",
415 +                              ievent);
416                 fec_reinit(dev);
417         }
418         else if (ievent & FEC_IEVENT_MII)
419 @@ -495,7 +507,9 @@ static void fec_hw_init(struct net_device *dev)
421         struct fec_priv *priv = (struct fec_priv *)dev->priv;
422         struct mpc52xx_fec *fec = priv->fec;
423 +#if !defined(CONFIG_PPC_MERGE)
424         bd_t *bd = (bd_t *) &__res;
425 +#endif
427         out_be32(&fec->op_pause, 0x00010020);
428         out_be32(&fec->rfifo_cntrl, 0x0f000000);
429 @@ -507,7 +521,9 @@ static void fec_hw_init(struct net_device *dev)
430         out_be32(&fec->iaddr1, 0x00000000);     /* No individual filter */
431         out_be32(&fec->iaddr2, 0x00000000);     /* No individual filter */
433 +#if !defined(CONFIG_PPC_MERGE)
434         priv->phy_speed = ((bd->bi_ipbfreq >> 20) / 5) << 1;
435 +#endif
437         fec_restart(dev, 0);    /* always use half duplex mode only */
438         /*
439 @@ -522,7 +538,6 @@ static void fec_reinit(struct net_device *dev)
441         struct fec_priv *priv = (struct fec_priv *)dev->priv;
442         struct mpc52xx_fec *fec = priv->fec;
443 -       static void fec_update_stat(struct net_device *);
445         netif_stop_queue(dev);
446         out_be32(&fec->imask, 0x0);
447 @@ -551,19 +566,38 @@ static void fec_reinit(struct net_device *dev)
448  /* Platform Driver                                                               */
449  /* ======================================================================== */
451 +#if defined(CONFIG_PPC_MERGE)
452 +static int __devinit
453 +mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
454 +#else
455  static int __devinit
456  mpc52xx_fec_probe(struct device *dev)
457 +#endif
459         int ret;
460 +#if defined(CONFIG_PPC_MERGE)
461 +       int rv;
462 +       struct resource __mem;
463 +       struct resource *mem = &__mem;
464 +#else
465         struct platform_device *pdev = to_platform_device(dev);
466 +       struct resource *mem;
467 +#endif
468         struct net_device *ndev;
469         struct fec_priv *priv = NULL;
470 -       struct resource *mem;
472         volatile int dbg=0;
473         while(dbg)
474                 __asm("nop");
475         /* Reserve FEC control zone */
476 +#if defined(CONFIG_PPC_MERGE)
477 +       rv = of_address_to_resource(op->node, 0, mem);
478 +       if (rv) {
479 +               printk(KERN_ERR DRIVER_NAME ": "
480 +                       "Error while parsing device node resource\n" );
481 +               return rv;
482 +       }
483 +#else
484         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
485         if ((mem->end - mem->start + 1) != sizeof(struct mpc52xx_fec)) {
486                 printk(KERN_ERR DRIVER_NAME 
487 @@ -571,7 +605,8 @@ mpc52xx_fec_probe(struct device *dev)
488                                                                         mem->end - mem->start + 1, sizeof(struct mpc52xx_fec));
489                 return -EINVAL;
490         }
491 -       
492 +#endif
494         if (!request_mem_region(mem->start, sizeof(struct mpc52xx_fec),
495                                 DRIVER_NAME))
496                 return -EBUSY;
497 @@ -579,6 +614,8 @@ mpc52xx_fec_probe(struct device *dev)
498         /* Get the ether ndev & it's private zone */
499         ndev = alloc_etherdev(sizeof(struct fec_priv));
500         if (!ndev) {
501 +               printk(KERN_ERR DRIVER_NAME ": "
502 +                       "Can not allocate the ethernet device\n" );
503                 ret = -ENOMEM;
504                 goto probe_error;
505         }
506 @@ -609,6 +646,8 @@ mpc52xx_fec_probe(struct device *dev)
507                 ioremap(mem->start, sizeof(struct mpc52xx_fec));
508         
509         if (!priv->fec) {
510 +               printk(KERN_ERR DRIVER_NAME ": "
511 +                       "Can not remap IO memory at 0x%8.8x\n", mem->start );
512                 ret = -ENOMEM;
513                 goto probe_error;
514         }
515 @@ -618,6 +657,8 @@ mpc52xx_fec_probe(struct device *dev)
516         priv->tx_sdma = sdma_alloc(FEC_TX_NUM_BD);
517         
518         if (!priv->rx_sdma || !priv->tx_sdma) {
519 +               printk(KERN_ERR DRIVER_NAME ": "
520 +                       "Can not init SDMA tasks\n" );
521                 ret = -ENOMEM;
522                 goto probe_error;
523         }
524 @@ -631,8 +672,13 @@ mpc52xx_fec_probe(struct device *dev)
525                 goto probe_error;
527         /* Get the IRQ we need one by one */
528 -               /* Control */
529 +       /* Control */
530 +#if defined(CONFIG_PPC_MERGE)
531 +       ndev->irq = irq_of_parse_and_map(op->node, 0);
532 +#else
533         ndev->irq = platform_get_irq(pdev, 0);
534 +#endif
536         if (request_irq(ndev->irq, &fec_interrupt, SA_INTERRUPT,
537                         DRIVER_NAME "_ctrl", ndev)) {
538                 printk(KERN_ERR DRIVER_NAME ": ctrl interrupt request failed\n");
539 @@ -641,26 +687,32 @@ mpc52xx_fec_probe(struct device *dev)
540                 goto probe_error;
541         }
543 -               /* RX */
544 +       /* RX */
545         priv->r_irq = sdma_irq(priv->rx_sdma);
546         if (request_irq(priv->r_irq, &fec_rx_interrupt, SA_INTERRUPT,
547                         DRIVER_NAME "_rx", ndev)) {
548 -               printk(KERN_ERR DRIVER_NAME ": rx interrupt request failed\n");
549 +               printk(KERN_ERR DRIVER_NAME ": rx request_irq(0x%x) failed\n",
550 +                      priv->r_irq);
551                 ret = -EBUSY;
552                 priv->r_irq = -1;       /* Don't try to free it */
553                 goto probe_error;
554         }
556 -               /* TX */
557 +       /* TX */
558         priv->t_irq = sdma_irq(priv->tx_sdma);
559         if (request_irq(priv->t_irq, &fec_tx_interrupt, SA_INTERRUPT,
560                         DRIVER_NAME "_tx", ndev)) {
561 -               printk(KERN_ERR DRIVER_NAME ": tx interrupt request failed\n");
562 +               printk(KERN_ERR DRIVER_NAME ": tx request_irq(0x%x) failed\n",
563 +                      priv->t_irq);
564                 ret = -EBUSY;
565                 priv->t_irq = -1;       /* Don't try to free it */
566                 goto probe_error;
567         }
569 +#if defined(CONFIG_PPC_MERGE)
570 +       priv->phy_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1;
571 +#endif
573         /* MAC address init */
574         if (memcmp(mpc52xx_fec_mac_addr, null_mac, 6) != 0)
575                 memcpy(ndev->dev_addr, mpc52xx_fec_mac_addr, 6);
576 @@ -679,7 +731,11 @@ mpc52xx_fec_probe(struct device *dev)
577         fec_mii_init(ndev);
578         
579         /* We're done ! */
580 +#if defined(CONFIG_PPC_MERGE)
581 +       dev_set_drvdata(&op->dev, ndev);
582 +#else
583         dev_set_drvdata(dev, ndev);
584 +#endif
586         return 0;
588 @@ -705,13 +761,22 @@ probe_error:
589         return ret;
592 +#if defined(CONFIG_PPC_MERGE)
593 +static int
594 +mpc52xx_fec_remove(struct of_device *op)
595 +#else
596  static int
597  mpc52xx_fec_remove(struct device *dev)
598 +#endif
600         struct net_device *ndev;
601         struct fec_priv *priv;
602         
603 +#if defined(CONFIG_PPC_MERGE)
604 +       ndev = (struct net_device *) dev_get_drvdata(&op->dev);
605 +#else
606         ndev = (struct net_device *) dev_get_drvdata(dev);
607 +#endif
608         if (!ndev)
609                 return 0;
610         priv = (struct fec_priv *) ndev->priv;
611 @@ -728,10 +793,37 @@ mpc52xx_fec_remove(struct device *dev)
613         free_netdev(ndev);
614         
615 +#if defined(CONFIG_PPC_MERGE)
616 +       dev_set_drvdata(&op->dev, NULL);
617 +#else
618         dev_set_drvdata(dev, NULL);
619 +#endif
620         return 0;
623 +#if defined(CONFIG_PPC_MERGE)
624 +static struct of_device_id mpc52xx_fec_of_match[] = {
625 +       { .compatible = "mpc5200-ethernet", },
626 +       { .compatible = "mpc52xx-fec", },
627 +       {},
630 +static struct of_platform_driver mpc52xx_fec_driver = {
631 +       .name = DRIVER_NAME,
632 +       .owner = THIS_MODULE,
633 +       .match_table = mpc52xx_fec_of_match,
634 +       .probe = mpc52xx_fec_probe,
635 +       .remove = mpc52xx_fec_remove,
636 +#ifdef CONFIG_PM
637 +/*     .suspend = mpc52xx_fec_suspend, TODO */
638 +/*     .resume = mpc52xx_fec_resume, TODO */
639 +#endif
640 +       .driver = {
641 +               .name = DRIVER_NAME,
642 +               .owner = THIS_MODULE,
643 +       },
645 +#else
646  static struct device_driver mpc52xx_fec_driver = {
647         .name     = DRIVER_NAME,
648         .bus            = &platform_bus_type,
649 @@ -742,6 +834,7 @@ static struct device_driver mpc52xx_fec_driver = {
650  /*     .resume         = mpc52xx_fec_resume,   TODO */
651  #endif
652  };
653 +#endif
655  /* ======================================================================== */
656  /* Module                                                                   */
657 @@ -750,13 +843,21 @@ static struct device_driver mpc52xx_fec_driver = {
658  static int __init
659  mpc52xx_fec_init(void)
661 +#if defined(CONFIG_PPC_MERGE)
662 +       return of_register_platform_driver(&mpc52xx_fec_driver);
663 +#else
664         return driver_register(&mpc52xx_fec_driver);
665 +#endif
668  static void __exit
669  mpc52xx_fec_exit(void)
671 +#if defined(CONFIG_PPC_MERGE)
672 +       of_unregister_platform_driver(&mpc52xx_fec_driver);
673 +#else
674         driver_unregister(&mpc52xx_fec_driver);
675 +#endif
679 diff --git a/drivers/net/fec_mpc52xx/fec_phy.c b/drivers/net/fec_mpc52xx/fec_phy.c
680 index 2a287de..25e0409 100644
681 --- a/drivers/net/fec_mpc52xx/fec_phy.c
682 +++ b/drivers/net/fec_mpc52xx/fec_phy.c
683 @@ -20,8 +20,14 @@
684  #include <linux/mii.h>
685  #include <asm/io.h>
686  #include <asm/mpc52xx.h>
688 +#ifdef CONFIG_PPC_MERGE
689 +#include <platforms/52xx/bestcomm.h>
690 +#else
691  #include <syslib/bestcomm/bestcomm.h>
692  #include <syslib/bestcomm/fec.h>
693 +#endif
695  #include "fec_phy.h"
696  #include "fec.h"
698 -- 
699 1.4.4.2