linux/arch/mips/vr41xx/common/siu.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *  NEC VR4100 series SIU platform device.
   4 *
   5 *  Copyright (C) 2007-2008  Yoichi Yuasa <yuasa@linux-mips.org>
   6 */
   7#include <linux/errno.h>
   8#include <linux/init.h>
   9#include <linux/ioport.h>
  10#include <linux/platform_device.h>
  11#include <linux/serial_core.h>
  12#include <linux/irq.h>
  13
  14#include <asm/cpu.h>
  15#include <asm/vr41xx/siu.h>
  16
  17static unsigned int siu_type1_ports[SIU_PORTS_MAX] __initdata = {
  18        PORT_VR41XX_SIU,
  19        PORT_UNKNOWN,
  20};
  21
  22static struct resource siu_type1_resource[] __initdata = {
  23        {
  24                .start  = 0x0c000000,
  25                .end    = 0x0c00000a,
  26                .flags  = IORESOURCE_MEM,
  27        },
  28        {
  29                .start  = SIU_IRQ,
  30                .end    = SIU_IRQ,
  31                .flags  = IORESOURCE_IRQ,
  32        },
  33};
  34
  35static unsigned int siu_type2_ports[SIU_PORTS_MAX] __initdata = {
  36        PORT_VR41XX_SIU,
  37        PORT_VR41XX_DSIU,
  38};
  39
  40static struct resource siu_type2_resource[] __initdata = {
  41        {
  42                .start  = 0x0f000800,
  43                .end    = 0x0f00080a,
  44                .flags  = IORESOURCE_MEM,
  45        },
  46        {
  47                .start  = 0x0f000820,
  48                .end    = 0x0f000829,
  49                .flags  = IORESOURCE_MEM,
  50        },
  51        {
  52                .start  = SIU_IRQ,
  53                .end    = SIU_IRQ,
  54                .flags  = IORESOURCE_IRQ,
  55        },
  56        {
  57                .start  = DSIU_IRQ,
  58                .end    = DSIU_IRQ,
  59                .flags  = IORESOURCE_IRQ,
  60        },
  61};
  62
  63static int __init vr41xx_siu_add(void)
  64{
  65        struct platform_device *pdev;
  66        struct resource *res;
  67        unsigned int num;
  68        int retval;
  69
  70        pdev = platform_device_alloc("SIU", -1);
  71        if (!pdev)
  72                return -ENOMEM;
  73
  74        switch (current_cpu_type()) {
  75        case CPU_VR4111:
  76        case CPU_VR4121:
  77                pdev->dev.platform_data = siu_type1_ports;
  78                res = siu_type1_resource;
  79                num = ARRAY_SIZE(siu_type1_resource);
  80                break;
  81        case CPU_VR4122:
  82        case CPU_VR4131:
  83        case CPU_VR4133:
  84                pdev->dev.platform_data = siu_type2_ports;
  85                res = siu_type2_resource;
  86                num = ARRAY_SIZE(siu_type2_resource);
  87                break;
  88        default:
  89                retval = -ENODEV;
  90                goto err_free_device;
  91        }
  92
  93        retval = platform_device_add_resources(pdev, res, num);
  94        if (retval)
  95                goto err_free_device;
  96
  97        retval = platform_device_add(pdev);
  98        if (retval)
  99                goto err_free_device;
 100
 101        return 0;
 102
 103err_free_device:
 104        platform_device_put(pdev);
 105
 106        return retval;
 107}
 108device_initcall(vr41xx_siu_add);
 109
 110void __init vr41xx_siu_setup(void)
 111{
 112        struct uart_port port;
 113        struct resource *res;
 114        unsigned int *type;
 115        int i;
 116
 117        switch (current_cpu_type()) {
 118        case CPU_VR4111:
 119        case CPU_VR4121:
 120                type = siu_type1_ports;
 121                res = siu_type1_resource;
 122                break;
 123        case CPU_VR4122:
 124        case CPU_VR4131:
 125        case CPU_VR4133:
 126                type = siu_type2_ports;
 127                res = siu_type2_resource;
 128                break;
 129        default:
 130                return;
 131        }
 132
 133        for (i = 0; i < SIU_PORTS_MAX; i++) {
 134                port.line = i;
 135                port.type = type[i];
 136                if (port.type == PORT_UNKNOWN)
 137                        break;
 138                port.mapbase = res[i].start;
 139                port.membase = (unsigned char __iomem *)KSEG1ADDR(res[i].start);
 140                vr41xx_siu_early_setup(&port);
 141        }
 142}
 143