1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * DEC platform devices. 4 * 5 * Copyright (c) 2014 Maciej W. Rozycki 6 */ 7 8 #include <linux/ioport.h> 9 #include <linux/kernel.h> 10 #include <linux/mc146818rtc.h> 11 #include <linux/platform_device.h> 12 13 #include <asm/bootinfo.h> 14 15 #include <asm/dec/interrupts.h> 16 #include <asm/dec/ioasic_addrs.h> 17 #include <asm/dec/kn01.h> 18 #include <asm/dec/kn02.h> 19 #include <asm/dec/system.h> 20 21 static struct resource dec_rtc_resources[] = { 22 { 23 .name = "rtc", 24 .flags = IORESOURCE_MEM, 25 }, 26 }; 27 28 static struct cmos_rtc_board_info dec_rtc_info = { 29 .flags = CMOS_RTC_FLAGS_NOFREQ, 30 .address_space = 64, 31 }; 32 33 static struct platform_device dec_rtc_device = { 34 .name = "rtc_cmos", 35 .id = PLATFORM_DEVID_NONE, 36 .dev.platform_data = &dec_rtc_info, 37 .resource = dec_rtc_resources, 38 .num_resources = ARRAY_SIZE(dec_rtc_resources), 39 }; 40 41 static struct platform_device *dec_rtc_devices[] __initdata = { 42 &dec_rtc_device, 43 }; 44 45 static struct resource dec_dz_resources[] = { 46 { .name = "dz", .flags = IORESOURCE_MEM, }, 47 { .name = "dz", .flags = IORESOURCE_IRQ, }, 48 }; 49 50 static struct platform_device dec_dz_device = { 51 .name = "dz", 52 .id = PLATFORM_DEVID_NONE, 53 .resource = dec_dz_resources, 54 .num_resources = ARRAY_SIZE(dec_dz_resources), 55 }; 56 57 static struct platform_device *dec_dz_devices[] __initdata = { 58 &dec_dz_device, 59 }; 60 61 static struct resource dec_zs_resources[][2] = { 62 { 63 { .name = "scc0", .flags = IORESOURCE_MEM, }, 64 { .name = "scc0", .flags = IORESOURCE_IRQ, }, 65 }, 66 { 67 { .name = "scc1", .flags = IORESOURCE_MEM, }, 68 { .name = "scc1", .flags = IORESOURCE_IRQ, }, 69 }, 70 }; 71 72 static struct platform_device dec_zs_device[] = { 73 { 74 .name = "zs", 75 .id = 0, 76 .resource = dec_zs_resources[0], 77 .num_resources = ARRAY_SIZE(dec_zs_resources[0]), 78 }, 79 { 80 .name = "zs", 81 .id = 1, 82 .resource = dec_zs_resources[1], 83 .num_resources = ARRAY_SIZE(dec_zs_resources[1]), 84 }, 85 }; 86 87 static int __init dec_add_devices(void) 88 { 89 struct platform_device *dec_zs_devices[ARRAY_SIZE(dec_zs_device)]; 90 int ret1, ret2, ret3; 91 int num_dz, num_zs; 92 int irq, i; 93 94 dec_rtc_resources[0].start = RTC_PORT(0); 95 dec_rtc_resources[0].end = RTC_PORT(0) + dec_kn_slot_size - 1; 96 97 i = 0; 98 irq = dec_interrupt[DEC_IRQ_DZ11]; 99 if (IS_ENABLED(CONFIG_32BIT) && irq >= 0) { 100 resource_size_t base; 101 102 switch (mips_machtype) { 103 case MACH_DS23100: 104 case MACH_DS5100: 105 base = dec_kn_slot_base + KN01_DZ11; 106 break; 107 default: 108 base = dec_kn_slot_base + KN02_DZ11; 109 break; 110 } 111 dec_dz_device.resource[0].start = base; 112 dec_dz_device.resource[0].end = base + dec_kn_slot_size - 1; 113 dec_dz_device.resource[1].start = irq; 114 dec_dz_device.resource[1].end = irq; 115 i++; 116 } 117 num_dz = i; 118 119 i = 0; 120 irq = dec_interrupt[DEC_IRQ_SCC0]; 121 if (irq >= 0) { 122 resource_size_t base = dec_kn_slot_base + IOASIC_SCC0; 123 124 dec_zs_device[i].resource[0].start = base; 125 dec_zs_device[i].resource[0].end = base + dec_kn_slot_size - 1; 126 dec_zs_device[i].resource[1].start = irq; 127 dec_zs_device[i].resource[1].end = irq; 128 dec_zs_devices[i] = &dec_zs_device[i]; 129 i++; 130 } 131 irq = dec_interrupt[DEC_IRQ_SCC1]; 132 if (irq >= 0) { 133 resource_size_t base = dec_kn_slot_base + IOASIC_SCC1; 134 135 dec_zs_device[i].resource[0].start = base; 136 dec_zs_device[i].resource[0].end = base + dec_kn_slot_size - 1; 137 dec_zs_device[i].resource[1].start = irq; 138 dec_zs_device[i].resource[1].end = irq; 139 dec_zs_devices[i] = &dec_zs_device[i]; 140 i++; 141 } 142 num_zs = i; 143 144 ret1 = platform_add_devices(dec_rtc_devices, 1); 145 ret2 = IS_ENABLED(CONFIG_32BIT) ? 146 platform_add_devices(dec_dz_devices, num_dz) : 0; 147 ret3 = platform_add_devices(dec_zs_devices, num_zs); 148 return ret1 ? ret1 : ret2 ? ret2 : ret3; 149 } 150 151 device_initcall(dec_add_devices); 152