siu.c (2713B)
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}