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 resource dec_dz_resources[] = { 42 { .name = "dz", .flags = IORESOURCE_MEM, }, 43 { .name = "dz", .flags = IORESOURCE_IRQ, }, 44 }; 45 46 static struct platform_device dec_dz_device = { 47 .name = "dz", 48 .id = PLATFORM_DEVID_NONE, 49 .resource = dec_dz_resources, 50 .num_resources = ARRAY_SIZE(dec_dz_resources), 51 }; 52 53 static struct platform_device *dec_dz_devices[] __initdata = { 54 &dec_dz_device, 55 }; 56 57 static struct resource dec_zs_resources[][2] = { 58 { 59 { .name = "scc0", .flags = IORESOURCE_MEM, }, 60 { .name = "scc0", .flags = IORESOURCE_IRQ, }, 61 }, 62 { 63 { .name = "scc1", .flags = IORESOURCE_MEM, }, 64 { .name = "scc1", .flags = IORESOURCE_IRQ, }, 65 }, 66 }; 67 68 static struct platform_device dec_zs_device[] = { 69 { 70 .name = "zs", 71 .id = 0, 72 .resource = dec_zs_resources[0], 73 .num_resources = ARRAY_SIZE(dec_zs_resources[0]), 74 }, 75 { 76 .name = "zs", 77 .id = 1, 78 .resource = dec_zs_resources[1], 79 .num_resources = ARRAY_SIZE(dec_zs_resources[1]), 80 }, 81 }; 82 83 static int __init dec_add_devices(void) 84 { 85 struct platform_device *dec_zs_devices[ARRAY_SIZE(dec_zs_device)]; 86 int ret1, ret2, ret3; 87 int num_dz, num_zs; 88 int irq, i; 89 90 dec_rtc_resources[0].start = RTC_PORT(0); 91 dec_rtc_resources[0].end = RTC_PORT(0) + dec_kn_slot_size - 1; 92 93 i = 0; 94 irq = dec_interrupt[DEC_IRQ_DZ11]; 95 if (IS_ENABLED(CONFIG_32BIT) && irq >= 0) { 96 resource_size_t base; 97 98 switch (mips_machtype) { 99 case MACH_DS23100: 100 case MACH_DS5100: 101 base = dec_kn_slot_base + KN01_DZ11; 102 break; 103 default: 104 base = dec_kn_slot_base + KN02_DZ11; 105 break; 106 } 107 dec_dz_device.resource[0].start = base; 108 dec_dz_device.resource[0].end = base + dec_kn_slot_size - 1; 109 dec_dz_device.resource[1].start = irq; 110 dec_dz_device.resource[1].end = irq; 111 i++; 112 } 113 num_dz = i; 114 115 i = 0; 116 irq = dec_interrupt[DEC_IRQ_SCC0]; 117 if (irq >= 0) { 118 resource_size_t base = dec_kn_slot_base + IOASIC_SCC0; 119 120 dec_zs_device[i].resource[0].start = base; 121 dec_zs_device[i].resource[0].end = base + dec_kn_slot_size - 1; 122 dec_zs_device[i].resource[1].start = irq; 123 dec_zs_device[i].resource[1].end = irq; 124 dec_zs_devices[i] = &dec_zs_device[i]; 125 i++; 126 } 127 irq = dec_interrupt[DEC_IRQ_SCC1]; 128 if (irq >= 0) { 129 resource_size_t base = dec_kn_slot_base + IOASIC_SCC1; 130 131 dec_zs_device[i].resource[0].start = base; 132 dec_zs_device[i].resource[0].end = base + dec_kn_slot_size - 1; 133 dec_zs_device[i].resource[1].start = irq; 134 dec_zs_device[i].resource[1].end = irq; 135 dec_zs_devices[i] = &dec_zs_device[i]; 136 i++; 137 } 138 num_zs = i; 139 140 ret1 = platform_device_register(&dec_rtc_device); 141 ret2 = IS_ENABLED(CONFIG_32BIT) ? 142 platform_add_devices(dec_dz_devices, num_dz) : 0; 143 ret3 = platform_add_devices(dec_zs_devices, num_zs); 144 return ret1 ? ret1 : ret2 ? ret2 : ret3; 145 } 146 147 device_initcall(dec_add_devices); 148