blob: 723ce16cbfc0ccaefa981c41d843a6494968b915 [file] [edit]
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* DEC platform devices.
*
* Copyright (c) 2014 Maciej W. Rozycki
*/
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/mc146818rtc.h>
#include <linux/platform_device.h>
#include <asm/bootinfo.h>
#include <asm/dec/interrupts.h>
#include <asm/dec/ioasic_addrs.h>
#include <asm/dec/kn01.h>
#include <asm/dec/kn02.h>
#include <asm/dec/system.h>
static struct resource dec_rtc_resources[] = {
{
.name = "rtc",
.flags = IORESOURCE_MEM,
},
};
static struct cmos_rtc_board_info dec_rtc_info = {
.flags = CMOS_RTC_FLAGS_NOFREQ,
.address_space = 64,
};
static struct platform_device dec_rtc_device = {
.name = "rtc_cmos",
.id = PLATFORM_DEVID_NONE,
.dev.platform_data = &dec_rtc_info,
.resource = dec_rtc_resources,
.num_resources = ARRAY_SIZE(dec_rtc_resources),
};
static struct resource dec_dz_resources[] = {
{ .name = "dz", .flags = IORESOURCE_MEM, },
{ .name = "dz", .flags = IORESOURCE_IRQ, },
};
static struct platform_device dec_dz_device = {
.name = "dz",
.id = PLATFORM_DEVID_NONE,
.resource = dec_dz_resources,
.num_resources = ARRAY_SIZE(dec_dz_resources),
};
static struct platform_device *dec_dz_devices[] __initdata = {
&dec_dz_device,
};
static struct resource dec_zs_resources[][2] = {
{
{ .name = "scc0", .flags = IORESOURCE_MEM, },
{ .name = "scc0", .flags = IORESOURCE_IRQ, },
},
{
{ .name = "scc1", .flags = IORESOURCE_MEM, },
{ .name = "scc1", .flags = IORESOURCE_IRQ, },
},
};
static struct platform_device dec_zs_device[] = {
{
.name = "zs",
.id = 0,
.resource = dec_zs_resources[0],
.num_resources = ARRAY_SIZE(dec_zs_resources[0]),
},
{
.name = "zs",
.id = 1,
.resource = dec_zs_resources[1],
.num_resources = ARRAY_SIZE(dec_zs_resources[1]),
},
};
static int __init dec_add_devices(void)
{
struct platform_device *dec_zs_devices[ARRAY_SIZE(dec_zs_device)];
int ret1, ret2, ret3;
int num_dz, num_zs;
int irq, i;
dec_rtc_resources[0].start = RTC_PORT(0);
dec_rtc_resources[0].end = RTC_PORT(0) + dec_kn_slot_size - 1;
i = 0;
irq = dec_interrupt[DEC_IRQ_DZ11];
if (IS_ENABLED(CONFIG_32BIT) && irq >= 0) {
resource_size_t base;
switch (mips_machtype) {
case MACH_DS23100:
case MACH_DS5100:
base = dec_kn_slot_base + KN01_DZ11;
break;
default:
base = dec_kn_slot_base + KN02_DZ11;
break;
}
dec_dz_device.resource[0].start = base;
dec_dz_device.resource[0].end = base + dec_kn_slot_size - 1;
dec_dz_device.resource[1].start = irq;
dec_dz_device.resource[1].end = irq;
i++;
}
num_dz = i;
i = 0;
irq = dec_interrupt[DEC_IRQ_SCC0];
if (irq >= 0) {
resource_size_t base = dec_kn_slot_base + IOASIC_SCC0;
dec_zs_device[i].resource[0].start = base;
dec_zs_device[i].resource[0].end = base + dec_kn_slot_size - 1;
dec_zs_device[i].resource[1].start = irq;
dec_zs_device[i].resource[1].end = irq;
dec_zs_devices[i] = &dec_zs_device[i];
i++;
}
irq = dec_interrupt[DEC_IRQ_SCC1];
if (irq >= 0) {
resource_size_t base = dec_kn_slot_base + IOASIC_SCC1;
dec_zs_device[i].resource[0].start = base;
dec_zs_device[i].resource[0].end = base + dec_kn_slot_size - 1;
dec_zs_device[i].resource[1].start = irq;
dec_zs_device[i].resource[1].end = irq;
dec_zs_devices[i] = &dec_zs_device[i];
i++;
}
num_zs = i;
ret1 = platform_device_register(&dec_rtc_device);
ret2 = IS_ENABLED(CONFIG_32BIT) ?
platform_add_devices(dec_dz_devices, num_dz) : 0;
ret3 = platform_add_devices(dec_zs_devices, num_zs);
return ret1 ? ret1 : ret2 ? ret2 : ret3;
}
device_initcall(dec_add_devices);