mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-08-09 06:14:34 +02:00
Switch RTC platform device registration from platform_device_register()
to platform_add_devices() so as to make sure any failure will result in
automatic device unregistration.
Fixes: fae67ad431 ("arch/mips/dec: switch DECstation systems to rtc-cmos")
Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
Acked-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
152 lines
3.6 KiB
C
152 lines
3.6 KiB
C
// 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 platform_device *dec_rtc_devices[] __initdata = {
|
|
&dec_rtc_device,
|
|
};
|
|
|
|
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_add_devices(dec_rtc_devices, 1);
|
|
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);
|