linux/arch/m68k/coldfire/device.c
<<
>>
Prefs
   1/*
   2 * device.c  -- common ColdFire SoC device support
   3 *
   4 * (C) Copyright 2011, Greg Ungerer <gerg@uclinux.org>
   5 *
   6 * This file is subject to the terms and conditions of the GNU General Public
   7 * License.  See the file COPYING in the main directory of this archive
   8 * for more details.
   9 */
  10
  11#include <linux/kernel.h>
  12#include <linux/init.h>
  13#include <linux/io.h>
  14#include <linux/spi/spi.h>
  15#include <linux/gpio.h>
  16#include <linux/fec.h>
  17#include <linux/dmaengine.h>
  18#include <asm/traps.h>
  19#include <asm/coldfire.h>
  20#include <asm/mcfsim.h>
  21#include <asm/mcfuart.h>
  22#include <asm/mcfqspi.h>
  23#include <linux/platform_data/edma.h>
  24#include <linux/platform_data/dma-mcf-edma.h>
  25#include <linux/platform_data/mmc-esdhc-mcf.h>
  26
  27/*
  28 *      All current ColdFire parts contain from 2, 3, 4 or 10 UARTS.
  29 */
  30static struct mcf_platform_uart mcf_uart_platform_data[] = {
  31        {
  32                .mapbase        = MCFUART_BASE0,
  33                .irq            = MCF_IRQ_UART0,
  34        },
  35        {
  36                .mapbase        = MCFUART_BASE1,
  37                .irq            = MCF_IRQ_UART1,
  38        },
  39#ifdef MCFUART_BASE2
  40        {
  41                .mapbase        = MCFUART_BASE2,
  42                .irq            = MCF_IRQ_UART2,
  43        },
  44#endif
  45#ifdef MCFUART_BASE3
  46        {
  47                .mapbase        = MCFUART_BASE3,
  48                .irq            = MCF_IRQ_UART3,
  49        },
  50#endif
  51#ifdef MCFUART_BASE4
  52        {
  53                .mapbase        = MCFUART_BASE4,
  54                .irq            = MCF_IRQ_UART4,
  55        },
  56#endif
  57#ifdef MCFUART_BASE5
  58        {
  59                .mapbase        = MCFUART_BASE5,
  60                .irq            = MCF_IRQ_UART5,
  61        },
  62#endif
  63#ifdef MCFUART_BASE6
  64        {
  65                .mapbase        = MCFUART_BASE6,
  66                .irq            = MCF_IRQ_UART6,
  67        },
  68#endif
  69#ifdef MCFUART_BASE7
  70        {
  71                .mapbase        = MCFUART_BASE7,
  72                .irq            = MCF_IRQ_UART7,
  73        },
  74#endif
  75#ifdef MCFUART_BASE8
  76        {
  77                .mapbase        = MCFUART_BASE8,
  78                .irq            = MCF_IRQ_UART8,
  79        },
  80#endif
  81#ifdef MCFUART_BASE9
  82        {
  83                .mapbase        = MCFUART_BASE9,
  84                .irq            = MCF_IRQ_UART9,
  85        },
  86#endif
  87        { },
  88};
  89
  90static struct platform_device mcf_uart = {
  91        .name                   = "mcfuart",
  92        .id                     = 0,
  93        .dev.platform_data      = mcf_uart_platform_data,
  94};
  95
  96#if IS_ENABLED(CONFIG_FEC)
  97
  98#ifdef CONFIG_M5441x
  99#define FEC_NAME        "enet-fec"
 100static struct fec_platform_data fec_pdata = {
 101        .phy            = PHY_INTERFACE_MODE_RMII,
 102};
 103#define FEC_PDATA       (&fec_pdata)
 104#else
 105#define FEC_NAME        "fec"
 106#define FEC_PDATA       NULL
 107#endif
 108
 109/*
 110 *      Some ColdFire cores contain the Fast Ethernet Controller (FEC)
 111 *      block. It is Freescale's own hardware block. Some ColdFires
 112 *      have 2 of these.
 113 */
 114static struct resource mcf_fec0_resources[] = {
 115        {
 116                .start          = MCFFEC_BASE0,
 117                .end            = MCFFEC_BASE0 + MCFFEC_SIZE0 - 1,
 118                .flags          = IORESOURCE_MEM,
 119        },
 120        {
 121                .start          = MCF_IRQ_FECRX0,
 122                .end            = MCF_IRQ_FECRX0,
 123                .flags          = IORESOURCE_IRQ,
 124        },
 125        {
 126                .start          = MCF_IRQ_FECTX0,
 127                .end            = MCF_IRQ_FECTX0,
 128                .flags          = IORESOURCE_IRQ,
 129        },
 130        {
 131                .start          = MCF_IRQ_FECENTC0,
 132                .end            = MCF_IRQ_FECENTC0,
 133                .flags          = IORESOURCE_IRQ,
 134        },
 135};
 136
 137static struct platform_device mcf_fec0 = {
 138        .name                   = FEC_NAME,
 139        .id                     = 0,
 140        .num_resources          = ARRAY_SIZE(mcf_fec0_resources),
 141        .resource               = mcf_fec0_resources,
 142        .dev = {
 143                .dma_mask               = &mcf_fec0.dev.coherent_dma_mask,
 144                .coherent_dma_mask      = DMA_BIT_MASK(32),
 145                .platform_data          = FEC_PDATA,
 146        }
 147};
 148
 149#ifdef MCFFEC_BASE1
 150static struct resource mcf_fec1_resources[] = {
 151        {
 152                .start          = MCFFEC_BASE1,
 153                .end            = MCFFEC_BASE1 + MCFFEC_SIZE1 - 1,
 154                .flags          = IORESOURCE_MEM,
 155        },
 156        {
 157                .start          = MCF_IRQ_FECRX1,
 158                .end            = MCF_IRQ_FECRX1,
 159                .flags          = IORESOURCE_IRQ,
 160        },
 161        {
 162                .start          = MCF_IRQ_FECTX1,
 163                .end            = MCF_IRQ_FECTX1,
 164                .flags          = IORESOURCE_IRQ,
 165        },
 166        {
 167                .start          = MCF_IRQ_FECENTC1,
 168                .end            = MCF_IRQ_FECENTC1,
 169                .flags          = IORESOURCE_IRQ,
 170        },
 171};
 172
 173static struct platform_device mcf_fec1 = {
 174        .name                   = FEC_NAME,
 175        .id                     = 1,
 176        .num_resources          = ARRAY_SIZE(mcf_fec1_resources),
 177        .resource               = mcf_fec1_resources,
 178        .dev = {
 179                .dma_mask               = &mcf_fec1.dev.coherent_dma_mask,
 180                .coherent_dma_mask      = DMA_BIT_MASK(32),
 181                .platform_data          = FEC_PDATA,
 182        }
 183};
 184#endif /* MCFFEC_BASE1 */
 185#endif /* CONFIG_FEC */
 186
 187#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
 188/*
 189 *      The ColdFire QSPI module is an SPI protocol hardware block used
 190 *      on a number of different ColdFire CPUs.
 191 */
 192static struct resource mcf_qspi_resources[] = {
 193        {
 194                .start          = MCFQSPI_BASE,
 195                .end            = MCFQSPI_BASE + MCFQSPI_SIZE - 1,
 196                .flags          = IORESOURCE_MEM,
 197        },
 198        {
 199                .start          = MCF_IRQ_QSPI,
 200                .end            = MCF_IRQ_QSPI,
 201                .flags          = IORESOURCE_IRQ,
 202        },
 203};
 204
 205static int mcf_cs_setup(struct mcfqspi_cs_control *cs_control)
 206{
 207        int status;
 208
 209        status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
 210        if (status) {
 211                pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
 212                goto fail0;
 213        }
 214        status = gpio_direction_output(MCFQSPI_CS0, 1);
 215        if (status) {
 216                pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
 217                goto fail1;
 218        }
 219
 220        status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
 221        if (status) {
 222                pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
 223                goto fail1;
 224        }
 225        status = gpio_direction_output(MCFQSPI_CS1, 1);
 226        if (status) {
 227                pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
 228                goto fail2;
 229        }
 230
 231        status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
 232        if (status) {
 233                pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
 234                goto fail2;
 235        }
 236        status = gpio_direction_output(MCFQSPI_CS2, 1);
 237        if (status) {
 238                pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
 239                goto fail3;
 240        }
 241
 242#ifdef MCFQSPI_CS3
 243        status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
 244        if (status) {
 245                pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
 246                goto fail3;
 247        }
 248        status = gpio_direction_output(MCFQSPI_CS3, 1);
 249        if (status) {
 250                pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
 251                gpio_free(MCFQSPI_CS3);
 252                goto fail3;
 253        }
 254#endif
 255
 256        return 0;
 257
 258fail3:
 259        gpio_free(MCFQSPI_CS2);
 260fail2:
 261        gpio_free(MCFQSPI_CS1);
 262fail1:
 263        gpio_free(MCFQSPI_CS0);
 264fail0:
 265        return status;
 266}
 267
 268static void mcf_cs_teardown(struct mcfqspi_cs_control *cs_control)
 269{
 270#ifdef MCFQSPI_CS3
 271        gpio_free(MCFQSPI_CS3);
 272#endif
 273        gpio_free(MCFQSPI_CS2);
 274        gpio_free(MCFQSPI_CS1);
 275        gpio_free(MCFQSPI_CS0);
 276}
 277
 278static void mcf_cs_select(struct mcfqspi_cs_control *cs_control,
 279                          u8 chip_select, bool cs_high)
 280{
 281        switch (chip_select) {
 282        case 0:
 283                gpio_set_value(MCFQSPI_CS0, cs_high);
 284                break;
 285        case 1:
 286                gpio_set_value(MCFQSPI_CS1, cs_high);
 287                break;
 288        case 2:
 289                gpio_set_value(MCFQSPI_CS2, cs_high);
 290                break;
 291#ifdef MCFQSPI_CS3
 292        case 3:
 293                gpio_set_value(MCFQSPI_CS3, cs_high);
 294                break;
 295#endif
 296        }
 297}
 298
 299static void mcf_cs_deselect(struct mcfqspi_cs_control *cs_control,
 300                            u8 chip_select, bool cs_high)
 301{
 302        switch (chip_select) {
 303        case 0:
 304                gpio_set_value(MCFQSPI_CS0, !cs_high);
 305                break;
 306        case 1:
 307                gpio_set_value(MCFQSPI_CS1, !cs_high);
 308                break;
 309        case 2:
 310                gpio_set_value(MCFQSPI_CS2, !cs_high);
 311                break;
 312#ifdef MCFQSPI_CS3
 313        case 3:
 314                gpio_set_value(MCFQSPI_CS3, !cs_high);
 315                break;
 316#endif
 317        }
 318}
 319
 320static struct mcfqspi_cs_control mcf_cs_control = {
 321        .setup                  = mcf_cs_setup,
 322        .teardown               = mcf_cs_teardown,
 323        .select                 = mcf_cs_select,
 324        .deselect               = mcf_cs_deselect,
 325};
 326
 327static struct mcfqspi_platform_data mcf_qspi_data = {
 328        .bus_num                = 0,
 329        .num_chipselect         = 4,
 330        .cs_control             = &mcf_cs_control,
 331};
 332
 333static struct platform_device mcf_qspi = {
 334        .name                   = "mcfqspi",
 335        .id                     = 0,
 336        .num_resources          = ARRAY_SIZE(mcf_qspi_resources),
 337        .resource               = mcf_qspi_resources,
 338        .dev.platform_data      = &mcf_qspi_data,
 339};
 340#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
 341
 342#if IS_ENABLED(CONFIG_I2C_IMX)
 343static struct resource mcf_i2c0_resources[] = {
 344        {
 345                .start          = MCFI2C_BASE0,
 346                .end            = MCFI2C_BASE0 + MCFI2C_SIZE0 - 1,
 347                .flags          = IORESOURCE_MEM,
 348        },
 349        {
 350                .start          = MCF_IRQ_I2C0,
 351                .end            = MCF_IRQ_I2C0,
 352                .flags          = IORESOURCE_IRQ,
 353        },
 354};
 355
 356static struct platform_device mcf_i2c0 = {
 357        .name                   = "imx1-i2c",
 358        .id                     = 0,
 359        .num_resources          = ARRAY_SIZE(mcf_i2c0_resources),
 360        .resource               = mcf_i2c0_resources,
 361};
 362#ifdef MCFI2C_BASE1
 363
 364static struct resource mcf_i2c1_resources[] = {
 365        {
 366                .start          = MCFI2C_BASE1,
 367                .end            = MCFI2C_BASE1 + MCFI2C_SIZE1 - 1,
 368                .flags          = IORESOURCE_MEM,
 369        },
 370        {
 371                .start          = MCF_IRQ_I2C1,
 372                .end            = MCF_IRQ_I2C1,
 373                .flags          = IORESOURCE_IRQ,
 374        },
 375};
 376
 377static struct platform_device mcf_i2c1 = {
 378        .name                   = "imx1-i2c",
 379        .id                     = 1,
 380        .num_resources          = ARRAY_SIZE(mcf_i2c1_resources),
 381        .resource               = mcf_i2c1_resources,
 382};
 383
 384#endif /* MCFI2C_BASE1 */
 385
 386#ifdef MCFI2C_BASE2
 387
 388static struct resource mcf_i2c2_resources[] = {
 389        {
 390                .start          = MCFI2C_BASE2,
 391                .end            = MCFI2C_BASE2 + MCFI2C_SIZE2 - 1,
 392                .flags          = IORESOURCE_MEM,
 393        },
 394        {
 395                .start          = MCF_IRQ_I2C2,
 396                .end            = MCF_IRQ_I2C2,
 397                .flags          = IORESOURCE_IRQ,
 398        },
 399};
 400
 401static struct platform_device mcf_i2c2 = {
 402        .name                   = "imx1-i2c",
 403        .id                     = 2,
 404        .num_resources          = ARRAY_SIZE(mcf_i2c2_resources),
 405        .resource               = mcf_i2c2_resources,
 406};
 407
 408#endif /* MCFI2C_BASE2 */
 409
 410#ifdef MCFI2C_BASE3
 411
 412static struct resource mcf_i2c3_resources[] = {
 413        {
 414                .start          = MCFI2C_BASE3,
 415                .end            = MCFI2C_BASE3 + MCFI2C_SIZE3 - 1,
 416                .flags          = IORESOURCE_MEM,
 417        },
 418        {
 419                .start          = MCF_IRQ_I2C3,
 420                .end            = MCF_IRQ_I2C3,
 421                .flags          = IORESOURCE_IRQ,
 422        },
 423};
 424
 425static struct platform_device mcf_i2c3 = {
 426        .name                   = "imx1-i2c",
 427        .id                     = 3,
 428        .num_resources          = ARRAY_SIZE(mcf_i2c3_resources),
 429        .resource               = mcf_i2c3_resources,
 430};
 431
 432#endif /* MCFI2C_BASE3 */
 433
 434#ifdef MCFI2C_BASE4
 435
 436static struct resource mcf_i2c4_resources[] = {
 437        {
 438                .start          = MCFI2C_BASE4,
 439                .end            = MCFI2C_BASE4 + MCFI2C_SIZE4 - 1,
 440                .flags          = IORESOURCE_MEM,
 441        },
 442        {
 443                .start          = MCF_IRQ_I2C4,
 444                .end            = MCF_IRQ_I2C4,
 445                .flags          = IORESOURCE_IRQ,
 446        },
 447};
 448
 449static struct platform_device mcf_i2c4 = {
 450        .name                   = "imx1-i2c",
 451        .id                     = 4,
 452        .num_resources          = ARRAY_SIZE(mcf_i2c4_resources),
 453        .resource               = mcf_i2c4_resources,
 454};
 455
 456#endif /* MCFI2C_BASE4 */
 457
 458#ifdef MCFI2C_BASE5
 459
 460static struct resource mcf_i2c5_resources[] = {
 461        {
 462                .start          = MCFI2C_BASE5,
 463                .end            = MCFI2C_BASE5 + MCFI2C_SIZE5 - 1,
 464                .flags          = IORESOURCE_MEM,
 465        },
 466        {
 467                .start          = MCF_IRQ_I2C5,
 468                .end            = MCF_IRQ_I2C5,
 469                .flags          = IORESOURCE_IRQ,
 470        },
 471};
 472
 473static struct platform_device mcf_i2c5 = {
 474        .name                   = "imx1-i2c",
 475        .id                     = 5,
 476        .num_resources          = ARRAY_SIZE(mcf_i2c5_resources),
 477        .resource               = mcf_i2c5_resources,
 478};
 479
 480#endif /* MCFI2C_BASE5 */
 481#endif /* IS_ENABLED(CONFIG_I2C_IMX) */
 482
 483#if IS_ENABLED(CONFIG_MCF_EDMA)
 484
 485static const struct dma_slave_map mcf_edma_map[] = {
 486        { "dreq0", "rx-tx", MCF_EDMA_FILTER_PARAM(0) },
 487        { "dreq1", "rx-tx", MCF_EDMA_FILTER_PARAM(1) },
 488        { "uart.0", "rx", MCF_EDMA_FILTER_PARAM(2) },
 489        { "uart.0", "tx", MCF_EDMA_FILTER_PARAM(3) },
 490        { "uart.1", "rx", MCF_EDMA_FILTER_PARAM(4) },
 491        { "uart.1", "tx", MCF_EDMA_FILTER_PARAM(5) },
 492        { "uart.2", "rx", MCF_EDMA_FILTER_PARAM(6) },
 493        { "uart.2", "tx", MCF_EDMA_FILTER_PARAM(7) },
 494        { "timer0", "rx-tx", MCF_EDMA_FILTER_PARAM(8) },
 495        { "timer1", "rx-tx", MCF_EDMA_FILTER_PARAM(9) },
 496        { "timer2", "rx-tx", MCF_EDMA_FILTER_PARAM(10) },
 497        { "timer3", "rx-tx", MCF_EDMA_FILTER_PARAM(11) },
 498        { "fsl-dspi.0", "rx", MCF_EDMA_FILTER_PARAM(12) },
 499        { "fsl-dspi.0", "tx", MCF_EDMA_FILTER_PARAM(13) },
 500        { "fsl-dspi.1", "rx", MCF_EDMA_FILTER_PARAM(14) },
 501        { "fsl-dspi.1", "tx", MCF_EDMA_FILTER_PARAM(15) },
 502};
 503
 504static struct mcf_edma_platform_data mcf_edma_data = {
 505        .dma_channels           = 64,
 506        .slave_map              = mcf_edma_map,
 507        .slavecnt               = ARRAY_SIZE(mcf_edma_map),
 508};
 509
 510static struct resource mcf_edma_resources[] = {
 511        {
 512                .start          = MCFEDMA_BASE,
 513                .end            = MCFEDMA_BASE + MCFEDMA_SIZE - 1,
 514                .flags          = IORESOURCE_MEM,
 515        },
 516        {
 517                .start          = MCFEDMA_IRQ_INTR0,
 518                .end            = MCFEDMA_IRQ_INTR0 + 15,
 519                .flags          = IORESOURCE_IRQ,
 520                .name           = "edma-tx-00-15",
 521        },
 522        {
 523                .start          = MCFEDMA_IRQ_INTR16,
 524                .end            = MCFEDMA_IRQ_INTR16 + 39,
 525                .flags          = IORESOURCE_IRQ,
 526                .name           = "edma-tx-16-55",
 527        },
 528        {
 529                .start          = MCFEDMA_IRQ_INTR56,
 530                .end            = MCFEDMA_IRQ_INTR56,
 531                .flags          = IORESOURCE_IRQ,
 532                .name           = "edma-tx-56-63",
 533        },
 534        {
 535                .start          = MCFEDMA_IRQ_ERR,
 536                .end            = MCFEDMA_IRQ_ERR,
 537                .flags          = IORESOURCE_IRQ,
 538                .name           = "edma-err",
 539        },
 540};
 541
 542static u64 mcf_edma_dmamask = DMA_BIT_MASK(32);
 543
 544static struct platform_device mcf_edma = {
 545        .name                   = "mcf-edma",
 546        .id                     = 0,
 547        .num_resources          = ARRAY_SIZE(mcf_edma_resources),
 548        .resource               = mcf_edma_resources,
 549        .dev = {
 550                .dma_mask = &mcf_edma_dmamask,
 551                .coherent_dma_mask = DMA_BIT_MASK(32),
 552                .platform_data = &mcf_edma_data,
 553        }
 554};
 555#endif /* IS_ENABLED(CONFIG_MCF_EDMA) */
 556
 557#if IS_ENABLED(CONFIG_MMC)
 558static struct mcf_esdhc_platform_data mcf_esdhc_data = {
 559        .max_bus_width = 4,
 560        .cd_type = ESDHC_CD_NONE,
 561};
 562
 563static struct resource mcf_esdhc_resources[] = {
 564        {
 565                .start = MCFSDHC_BASE,
 566                .end = MCFSDHC_BASE + MCFSDHC_SIZE - 1,
 567                .flags = IORESOURCE_MEM,
 568        }, {
 569                .start = MCF_IRQ_SDHC,
 570                .end = MCF_IRQ_SDHC,
 571                .flags = IORESOURCE_IRQ,
 572        },
 573};
 574
 575static struct platform_device mcf_esdhc = {
 576        .name                   = "sdhci-esdhc-mcf",
 577        .id                     = 0,
 578        .num_resources          = ARRAY_SIZE(mcf_esdhc_resources),
 579        .resource               = mcf_esdhc_resources,
 580        .dev.platform_data      = &mcf_esdhc_data,
 581};
 582#endif /* IS_ENABLED(CONFIG_MMC) */
 583
 584static struct platform_device *mcf_devices[] __initdata = {
 585        &mcf_uart,
 586#if IS_ENABLED(CONFIG_FEC)
 587        &mcf_fec0,
 588#ifdef MCFFEC_BASE1
 589        &mcf_fec1,
 590#endif
 591#endif
 592#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
 593        &mcf_qspi,
 594#endif
 595#if IS_ENABLED(CONFIG_I2C_IMX)
 596        &mcf_i2c0,
 597#ifdef MCFI2C_BASE1
 598        &mcf_i2c1,
 599#endif
 600#ifdef MCFI2C_BASE2
 601        &mcf_i2c2,
 602#endif
 603#ifdef MCFI2C_BASE3
 604        &mcf_i2c3,
 605#endif
 606#ifdef MCFI2C_BASE4
 607        &mcf_i2c4,
 608#endif
 609#ifdef MCFI2C_BASE5
 610        &mcf_i2c5,
 611#endif
 612#endif
 613#if IS_ENABLED(CONFIG_MCF_EDMA)
 614        &mcf_edma,
 615#endif
 616#if IS_ENABLED(CONFIG_MMC)
 617        &mcf_esdhc,
 618#endif
 619};
 620
 621/*
 622 *      Some ColdFire UARTs let you set the IRQ line to use.
 623 */
 624static void __init mcf_uart_set_irq(void)
 625{
 626#ifdef MCFUART_UIVR
 627        /* UART0 interrupt setup */
 628        writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCFSIM_UART1ICR);
 629        writeb(MCF_IRQ_UART0, MCFUART_BASE0 + MCFUART_UIVR);
 630        mcf_mapirq2imr(MCF_IRQ_UART0, MCFINTC_UART0);
 631
 632        /* UART1 interrupt setup */
 633        writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCFSIM_UART2ICR);
 634        writeb(MCF_IRQ_UART1, MCFUART_BASE1 + MCFUART_UIVR);
 635        mcf_mapirq2imr(MCF_IRQ_UART1, MCFINTC_UART1);
 636#endif
 637}
 638
 639static int __init mcf_init_devices(void)
 640{
 641        mcf_uart_set_irq();
 642        platform_add_devices(mcf_devices, ARRAY_SIZE(mcf_devices));
 643        return 0;
 644}
 645
 646arch_initcall(mcf_init_devices);
 647