linux/arch/mips/vr41xx/common/siu.c
<<
>>
Prefs
   1/*
   2 *  NEC VR4100 series SIU platform device.
   3 *
   4 *  Copyright (C) 2007-2008  Yoichi Yuasa <yuasa@linux-mips.org>
   5 *
   6 *  This program is free software; you can redistribute it and/or modify
   7 *  it under the terms of the GNU General Public License as published by
   8 *  the Free Software Foundation; either version 2 of the License, or
   9 *  (at your option) any later version.
  10 *
  11 *  This program is distributed in the hope that it will be useful,
  12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 *  GNU General Public License for more details.
  15 *
  16 *  You should have received a copy of the GNU General Public License
  17 *  along with this program; if not, write to the Free Software
  18 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  19 */
  20#include <linux/errno.h>
  21#include <linux/init.h>
  22#include <linux/ioport.h>
  23#include <linux/platform_device.h>
  24#include <linux/serial_core.h>
  25#include <linux/irq.h>
  26
  27#include <asm/cpu.h>
  28#include <asm/vr41xx/siu.h>
  29
  30static unsigned int siu_type1_ports[SIU_PORTS_MAX] __initdata = {
  31        PORT_VR41XX_SIU,
  32        PORT_UNKNOWN,
  33};
  34
  35static struct resource siu_type1_resource[] __initdata = {
  36        {
  37                .start  = 0x0c000000,
  38                .end    = 0x0c00000a,
  39                .flags  = IORESOURCE_MEM,
  40        },
  41        {
  42                .start  = SIU_IRQ,
  43                .end    = SIU_IRQ,
  44                .flags  = IORESOURCE_IRQ,
  45        },
  46};
  47
  48static unsigned int siu_type2_ports[SIU_PORTS_MAX] __initdata = {
  49        PORT_VR41XX_SIU,
  50        PORT_VR41XX_DSIU,
  51};
  52
  53static struct resource siu_type2_resource[] __initdata = {
  54        {
  55                .start  = 0x0f000800,
  56                .end    = 0x0f00080a,
  57                .flags  = IORESOURCE_MEM,
  58        },
  59        {
  60                .start  = 0x0f000820,
  61                .end    = 0x0f000829,
  62                .flags  = IORESOURCE_MEM,
  63        },
  64        {
  65                .start  = SIU_IRQ,
  66                .end    = SIU_IRQ,
  67                .flags  = IORESOURCE_IRQ,
  68        },
  69        {
  70                .start  = DSIU_IRQ,
  71                .end    = DSIU_IRQ,
  72                .flags  = IORESOURCE_IRQ,
  73        },
  74};
  75
  76static int __init vr41xx_siu_add(void)
  77{
  78        struct platform_device *pdev;
  79        struct resource *res;
  80        unsigned int num;
  81        int retval;
  82
  83        pdev = platform_device_alloc("SIU", -1);
  84        if (!pdev)
  85                return -ENOMEM;
  86
  87        switch (current_cpu_type()) {
  88        case CPU_VR4111:
  89        case CPU_VR4121:
  90                pdev->dev.platform_data = siu_type1_ports;
  91                res = siu_type1_resource;
  92                num = ARRAY_SIZE(siu_type1_resource);
  93                break;
  94        case CPU_VR4122:
  95        case CPU_VR4131:
  96        case CPU_VR4133:
  97                pdev->dev.platform_data = siu_type2_ports;
  98                res = siu_type2_resource;
  99                num = ARRAY_SIZE(siu_type2_resource);
 100                break;
 101        default:
 102                retval = -ENODEV;
 103                goto err_free_device;
 104        }
 105
 106        retval = platform_device_add_resources(pdev, res, num);
 107        if (retval)
 108                goto err_free_device;
 109
 110        retval = platform_device_add(pdev);
 111        if (retval)
 112                goto err_free_device;
 113
 114        return 0;
 115
 116err_free_device:
 117        platform_device_put(pdev);
 118
 119        return retval;
 120}
 121device_initcall(vr41xx_siu_add);
 122
 123void __init vr41xx_siu_setup(void)
 124{
 125        struct uart_port port;
 126        struct resource *res;
 127        unsigned int *type;
 128        int i;
 129
 130        switch (current_cpu_type()) {
 131        case CPU_VR4111:
 132        case CPU_VR4121:
 133                type = siu_type1_ports;
 134                res = siu_type1_resource;
 135                break;
 136        case CPU_VR4122:
 137        case CPU_VR4131:
 138        case CPU_VR4133:
 139                type = siu_type2_ports;
 140                res = siu_type2_resource;
 141                break;
 142        default:
 143                return;
 144        }
 145
 146        for (i = 0; i < SIU_PORTS_MAX; i++) {
 147                port.line = i;
 148                port.type = type[i];
 149                if (port.type == PORT_UNKNOWN)
 150                        break;
 151                port.mapbase = res[i].start;
 152                port.membase = (unsigned char __iomem *)KSEG1ADDR(res[i].start);
 153                vr41xx_siu_early_setup(&port);
 154        }
 155}
 156