Contributors: 6
Author Tokens Token Proportion Commits Commit Proportion
Maciej W. Rozycki 710 96.21% 6 54.55%
Andrew Morton 19 2.57% 1 9.09%
Ralf Baechle 4 0.54% 1 9.09%
Thomas Gleixner 2 0.27% 1 9.09%
Linus Torvalds (pre-git) 2 0.27% 1 9.09%
Zihao Tang 1 0.14% 1 9.09%
Total 738 11


// 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);