xref: /kernel/linux/linux-5.10/arch/mips/ar7/platform.c (revision 8c2ecf20)
18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2006,2007 Felix Fietkau <nbd@openwrt.org>
48c2ecf20Sopenharmony_ci * Copyright (C) 2006,2007 Eugene Konev <ejka@openwrt.org>
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#include <linux/init.h>
88c2ecf20Sopenharmony_ci#include <linux/types.h>
98c2ecf20Sopenharmony_ci#include <linux/delay.h>
108c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h>
118c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
128c2ecf20Sopenharmony_ci#include <linux/mtd/physmap.h>
138c2ecf20Sopenharmony_ci#include <linux/serial.h>
148c2ecf20Sopenharmony_ci#include <linux/serial_8250.h>
158c2ecf20Sopenharmony_ci#include <linux/ioport.h>
168c2ecf20Sopenharmony_ci#include <linux/io.h>
178c2ecf20Sopenharmony_ci#include <linux/vlynq.h>
188c2ecf20Sopenharmony_ci#include <linux/leds.h>
198c2ecf20Sopenharmony_ci#include <linux/string.h>
208c2ecf20Sopenharmony_ci#include <linux/etherdevice.h>
218c2ecf20Sopenharmony_ci#include <linux/phy.h>
228c2ecf20Sopenharmony_ci#include <linux/phy_fixed.h>
238c2ecf20Sopenharmony_ci#include <linux/gpio.h>
248c2ecf20Sopenharmony_ci#include <linux/clk.h>
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci#include <asm/addrspace.h>
278c2ecf20Sopenharmony_ci#include <asm/mach-ar7/ar7.h>
288c2ecf20Sopenharmony_ci#include <asm/mach-ar7/prom.h>
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci/*****************************************************************************
318c2ecf20Sopenharmony_ci * VLYNQ Bus
328c2ecf20Sopenharmony_ci ****************************************************************************/
338c2ecf20Sopenharmony_cistruct plat_vlynq_data {
348c2ecf20Sopenharmony_ci	struct plat_vlynq_ops ops;
358c2ecf20Sopenharmony_ci	int gpio_bit;
368c2ecf20Sopenharmony_ci	int reset_bit;
378c2ecf20Sopenharmony_ci};
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_cistatic int vlynq_on(struct vlynq_device *dev)
408c2ecf20Sopenharmony_ci{
418c2ecf20Sopenharmony_ci	int ret;
428c2ecf20Sopenharmony_ci	struct plat_vlynq_data *pdata = dev->dev.platform_data;
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	ret = gpio_request(pdata->gpio_bit, "vlynq");
458c2ecf20Sopenharmony_ci	if (ret)
468c2ecf20Sopenharmony_ci		goto out;
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci	ar7_device_reset(pdata->reset_bit);
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci	ret = ar7_gpio_disable(pdata->gpio_bit);
518c2ecf20Sopenharmony_ci	if (ret)
528c2ecf20Sopenharmony_ci		goto out_enabled;
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci	ret = ar7_gpio_enable(pdata->gpio_bit);
558c2ecf20Sopenharmony_ci	if (ret)
568c2ecf20Sopenharmony_ci		goto out_enabled;
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci	ret = gpio_direction_output(pdata->gpio_bit, 0);
598c2ecf20Sopenharmony_ci	if (ret)
608c2ecf20Sopenharmony_ci		goto out_gpio_enabled;
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	msleep(50);
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci	gpio_set_value(pdata->gpio_bit, 1);
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci	msleep(50);
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	return 0;
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ciout_gpio_enabled:
718c2ecf20Sopenharmony_ci	ar7_gpio_disable(pdata->gpio_bit);
728c2ecf20Sopenharmony_ciout_enabled:
738c2ecf20Sopenharmony_ci	ar7_device_disable(pdata->reset_bit);
748c2ecf20Sopenharmony_ci	gpio_free(pdata->gpio_bit);
758c2ecf20Sopenharmony_ciout:
768c2ecf20Sopenharmony_ci	return ret;
778c2ecf20Sopenharmony_ci}
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_cistatic void vlynq_off(struct vlynq_device *dev)
808c2ecf20Sopenharmony_ci{
818c2ecf20Sopenharmony_ci	struct plat_vlynq_data *pdata = dev->dev.platform_data;
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci	ar7_gpio_disable(pdata->gpio_bit);
848c2ecf20Sopenharmony_ci	gpio_free(pdata->gpio_bit);
858c2ecf20Sopenharmony_ci	ar7_device_disable(pdata->reset_bit);
868c2ecf20Sopenharmony_ci}
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_cistatic struct resource vlynq_low_res[] = {
898c2ecf20Sopenharmony_ci	{
908c2ecf20Sopenharmony_ci		.name	= "regs",
918c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_MEM,
928c2ecf20Sopenharmony_ci		.start	= AR7_REGS_VLYNQ0,
938c2ecf20Sopenharmony_ci		.end	= AR7_REGS_VLYNQ0 + 0xff,
948c2ecf20Sopenharmony_ci	},
958c2ecf20Sopenharmony_ci	{
968c2ecf20Sopenharmony_ci		.name	= "irq",
978c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_IRQ,
988c2ecf20Sopenharmony_ci		.start	= 29,
998c2ecf20Sopenharmony_ci		.end	= 29,
1008c2ecf20Sopenharmony_ci	},
1018c2ecf20Sopenharmony_ci	{
1028c2ecf20Sopenharmony_ci		.name	= "mem",
1038c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_MEM,
1048c2ecf20Sopenharmony_ci		.start	= 0x04000000,
1058c2ecf20Sopenharmony_ci		.end	= 0x04ffffff,
1068c2ecf20Sopenharmony_ci	},
1078c2ecf20Sopenharmony_ci	{
1088c2ecf20Sopenharmony_ci		.name	= "devirq",
1098c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_IRQ,
1108c2ecf20Sopenharmony_ci		.start	= 80,
1118c2ecf20Sopenharmony_ci		.end	= 111,
1128c2ecf20Sopenharmony_ci	},
1138c2ecf20Sopenharmony_ci};
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_cistatic struct resource vlynq_high_res[] = {
1168c2ecf20Sopenharmony_ci	{
1178c2ecf20Sopenharmony_ci		.name	= "regs",
1188c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_MEM,
1198c2ecf20Sopenharmony_ci		.start	= AR7_REGS_VLYNQ1,
1208c2ecf20Sopenharmony_ci		.end	= AR7_REGS_VLYNQ1 + 0xff,
1218c2ecf20Sopenharmony_ci	},
1228c2ecf20Sopenharmony_ci	{
1238c2ecf20Sopenharmony_ci		.name	= "irq",
1248c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_IRQ,
1258c2ecf20Sopenharmony_ci		.start	= 33,
1268c2ecf20Sopenharmony_ci		.end	= 33,
1278c2ecf20Sopenharmony_ci	},
1288c2ecf20Sopenharmony_ci	{
1298c2ecf20Sopenharmony_ci		.name	= "mem",
1308c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_MEM,
1318c2ecf20Sopenharmony_ci		.start	= 0x0c000000,
1328c2ecf20Sopenharmony_ci		.end	= 0x0cffffff,
1338c2ecf20Sopenharmony_ci	},
1348c2ecf20Sopenharmony_ci	{
1358c2ecf20Sopenharmony_ci		.name	= "devirq",
1368c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_IRQ,
1378c2ecf20Sopenharmony_ci		.start	= 112,
1388c2ecf20Sopenharmony_ci		.end	= 143,
1398c2ecf20Sopenharmony_ci	},
1408c2ecf20Sopenharmony_ci};
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_cistatic struct plat_vlynq_data vlynq_low_data = {
1438c2ecf20Sopenharmony_ci	.ops = {
1448c2ecf20Sopenharmony_ci		.on	= vlynq_on,
1458c2ecf20Sopenharmony_ci		.off	= vlynq_off,
1468c2ecf20Sopenharmony_ci	},
1478c2ecf20Sopenharmony_ci	.reset_bit	= 20,
1488c2ecf20Sopenharmony_ci	.gpio_bit	= 18,
1498c2ecf20Sopenharmony_ci};
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_cistatic struct plat_vlynq_data vlynq_high_data = {
1528c2ecf20Sopenharmony_ci	.ops = {
1538c2ecf20Sopenharmony_ci		.on	= vlynq_on,
1548c2ecf20Sopenharmony_ci		.off	= vlynq_off,
1558c2ecf20Sopenharmony_ci	},
1568c2ecf20Sopenharmony_ci	.reset_bit	= 16,
1578c2ecf20Sopenharmony_ci	.gpio_bit	= 19,
1588c2ecf20Sopenharmony_ci};
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_cistatic struct platform_device vlynq_low = {
1618c2ecf20Sopenharmony_ci	.id		= 0,
1628c2ecf20Sopenharmony_ci	.name		= "vlynq",
1638c2ecf20Sopenharmony_ci	.dev = {
1648c2ecf20Sopenharmony_ci		.platform_data	= &vlynq_low_data,
1658c2ecf20Sopenharmony_ci	},
1668c2ecf20Sopenharmony_ci	.resource	= vlynq_low_res,
1678c2ecf20Sopenharmony_ci	.num_resources	= ARRAY_SIZE(vlynq_low_res),
1688c2ecf20Sopenharmony_ci};
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_cistatic struct platform_device vlynq_high = {
1718c2ecf20Sopenharmony_ci	.id		= 1,
1728c2ecf20Sopenharmony_ci	.name		= "vlynq",
1738c2ecf20Sopenharmony_ci	.dev = {
1748c2ecf20Sopenharmony_ci		.platform_data	= &vlynq_high_data,
1758c2ecf20Sopenharmony_ci	},
1768c2ecf20Sopenharmony_ci	.resource	= vlynq_high_res,
1778c2ecf20Sopenharmony_ci	.num_resources	= ARRAY_SIZE(vlynq_high_res),
1788c2ecf20Sopenharmony_ci};
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci/*****************************************************************************
1818c2ecf20Sopenharmony_ci * Flash
1828c2ecf20Sopenharmony_ci ****************************************************************************/
1838c2ecf20Sopenharmony_cistatic struct resource physmap_flash_resource = {
1848c2ecf20Sopenharmony_ci	.name	= "mem",
1858c2ecf20Sopenharmony_ci	.flags	= IORESOURCE_MEM,
1868c2ecf20Sopenharmony_ci	.start	= 0x10000000,
1878c2ecf20Sopenharmony_ci	.end	= 0x107fffff,
1888c2ecf20Sopenharmony_ci};
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_cistatic const char *ar7_probe_types[] = { "ar7part", NULL };
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_cistatic struct physmap_flash_data physmap_flash_data = {
1938c2ecf20Sopenharmony_ci	.width	= 2,
1948c2ecf20Sopenharmony_ci	.part_probe_types = ar7_probe_types,
1958c2ecf20Sopenharmony_ci};
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_cistatic struct platform_device physmap_flash = {
1988c2ecf20Sopenharmony_ci	.name		= "physmap-flash",
1998c2ecf20Sopenharmony_ci	.dev = {
2008c2ecf20Sopenharmony_ci		.platform_data	= &physmap_flash_data,
2018c2ecf20Sopenharmony_ci	},
2028c2ecf20Sopenharmony_ci	.resource	= &physmap_flash_resource,
2038c2ecf20Sopenharmony_ci	.num_resources	= 1,
2048c2ecf20Sopenharmony_ci};
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci/*****************************************************************************
2078c2ecf20Sopenharmony_ci * Ethernet
2088c2ecf20Sopenharmony_ci ****************************************************************************/
2098c2ecf20Sopenharmony_cistatic struct resource cpmac_low_res[] = {
2108c2ecf20Sopenharmony_ci	{
2118c2ecf20Sopenharmony_ci		.name	= "regs",
2128c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_MEM,
2138c2ecf20Sopenharmony_ci		.start	= AR7_REGS_MAC0,
2148c2ecf20Sopenharmony_ci		.end	= AR7_REGS_MAC0 + 0x7ff,
2158c2ecf20Sopenharmony_ci	},
2168c2ecf20Sopenharmony_ci	{
2178c2ecf20Sopenharmony_ci		.name	= "irq",
2188c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_IRQ,
2198c2ecf20Sopenharmony_ci		.start	= 27,
2208c2ecf20Sopenharmony_ci		.end	= 27,
2218c2ecf20Sopenharmony_ci	},
2228c2ecf20Sopenharmony_ci};
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_cistatic struct resource cpmac_high_res[] = {
2258c2ecf20Sopenharmony_ci	{
2268c2ecf20Sopenharmony_ci		.name	= "regs",
2278c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_MEM,
2288c2ecf20Sopenharmony_ci		.start	= AR7_REGS_MAC1,
2298c2ecf20Sopenharmony_ci		.end	= AR7_REGS_MAC1 + 0x7ff,
2308c2ecf20Sopenharmony_ci	},
2318c2ecf20Sopenharmony_ci	{
2328c2ecf20Sopenharmony_ci		.name	= "irq",
2338c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_IRQ,
2348c2ecf20Sopenharmony_ci		.start	= 41,
2358c2ecf20Sopenharmony_ci		.end	= 41,
2368c2ecf20Sopenharmony_ci	},
2378c2ecf20Sopenharmony_ci};
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_cistatic struct fixed_phy_status fixed_phy_status __initdata = {
2408c2ecf20Sopenharmony_ci	.link		= 1,
2418c2ecf20Sopenharmony_ci	.speed		= 100,
2428c2ecf20Sopenharmony_ci	.duplex		= 1,
2438c2ecf20Sopenharmony_ci};
2448c2ecf20Sopenharmony_ci
2458c2ecf20Sopenharmony_cistatic struct plat_cpmac_data cpmac_low_data = {
2468c2ecf20Sopenharmony_ci	.reset_bit	= 17,
2478c2ecf20Sopenharmony_ci	.power_bit	= 20,
2488c2ecf20Sopenharmony_ci	.phy_mask	= 0x80000000,
2498c2ecf20Sopenharmony_ci};
2508c2ecf20Sopenharmony_ci
2518c2ecf20Sopenharmony_cistatic struct plat_cpmac_data cpmac_high_data = {
2528c2ecf20Sopenharmony_ci	.reset_bit	= 21,
2538c2ecf20Sopenharmony_ci	.power_bit	= 22,
2548c2ecf20Sopenharmony_ci	.phy_mask	= 0x7fffffff,
2558c2ecf20Sopenharmony_ci};
2568c2ecf20Sopenharmony_ci
2578c2ecf20Sopenharmony_cistatic u64 cpmac_dma_mask = DMA_BIT_MASK(32);
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_cistatic struct platform_device cpmac_low = {
2608c2ecf20Sopenharmony_ci	.id		= 0,
2618c2ecf20Sopenharmony_ci	.name		= "cpmac",
2628c2ecf20Sopenharmony_ci	.dev = {
2638c2ecf20Sopenharmony_ci		.dma_mask		= &cpmac_dma_mask,
2648c2ecf20Sopenharmony_ci		.coherent_dma_mask	= DMA_BIT_MASK(32),
2658c2ecf20Sopenharmony_ci		.platform_data		= &cpmac_low_data,
2668c2ecf20Sopenharmony_ci	},
2678c2ecf20Sopenharmony_ci	.resource	= cpmac_low_res,
2688c2ecf20Sopenharmony_ci	.num_resources	= ARRAY_SIZE(cpmac_low_res),
2698c2ecf20Sopenharmony_ci};
2708c2ecf20Sopenharmony_ci
2718c2ecf20Sopenharmony_cistatic struct platform_device cpmac_high = {
2728c2ecf20Sopenharmony_ci	.id		= 1,
2738c2ecf20Sopenharmony_ci	.name		= "cpmac",
2748c2ecf20Sopenharmony_ci	.dev = {
2758c2ecf20Sopenharmony_ci		.dma_mask		= &cpmac_dma_mask,
2768c2ecf20Sopenharmony_ci		.coherent_dma_mask	= DMA_BIT_MASK(32),
2778c2ecf20Sopenharmony_ci		.platform_data		= &cpmac_high_data,
2788c2ecf20Sopenharmony_ci	},
2798c2ecf20Sopenharmony_ci	.resource	= cpmac_high_res,
2808c2ecf20Sopenharmony_ci	.num_resources	= ARRAY_SIZE(cpmac_high_res),
2818c2ecf20Sopenharmony_ci};
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_cistatic void __init cpmac_get_mac(int instance, unsigned char *dev_addr)
2848c2ecf20Sopenharmony_ci{
2858c2ecf20Sopenharmony_ci	char name[5], *mac;
2868c2ecf20Sopenharmony_ci
2878c2ecf20Sopenharmony_ci	sprintf(name, "mac%c", 'a' + instance);
2888c2ecf20Sopenharmony_ci	mac = prom_getenv(name);
2898c2ecf20Sopenharmony_ci	if (!mac && instance) {
2908c2ecf20Sopenharmony_ci		sprintf(name, "mac%c", 'a');
2918c2ecf20Sopenharmony_ci		mac = prom_getenv(name);
2928c2ecf20Sopenharmony_ci	}
2938c2ecf20Sopenharmony_ci
2948c2ecf20Sopenharmony_ci	if (mac) {
2958c2ecf20Sopenharmony_ci		if (!mac_pton(mac, dev_addr)) {
2968c2ecf20Sopenharmony_ci			pr_warn("cannot parse mac address, using random address\n");
2978c2ecf20Sopenharmony_ci			eth_random_addr(dev_addr);
2988c2ecf20Sopenharmony_ci		}
2998c2ecf20Sopenharmony_ci	} else
3008c2ecf20Sopenharmony_ci		eth_random_addr(dev_addr);
3018c2ecf20Sopenharmony_ci}
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ci/*****************************************************************************
3048c2ecf20Sopenharmony_ci * USB
3058c2ecf20Sopenharmony_ci ****************************************************************************/
3068c2ecf20Sopenharmony_cistatic struct resource usb_res[] = {
3078c2ecf20Sopenharmony_ci	{
3088c2ecf20Sopenharmony_ci		.name	= "regs",
3098c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_MEM,
3108c2ecf20Sopenharmony_ci		.start	= AR7_REGS_USB,
3118c2ecf20Sopenharmony_ci		.end	= AR7_REGS_USB + 0xff,
3128c2ecf20Sopenharmony_ci	},
3138c2ecf20Sopenharmony_ci	{
3148c2ecf20Sopenharmony_ci		.name	= "irq",
3158c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_IRQ,
3168c2ecf20Sopenharmony_ci		.start	= 32,
3178c2ecf20Sopenharmony_ci		.end	= 32,
3188c2ecf20Sopenharmony_ci	},
3198c2ecf20Sopenharmony_ci	{
3208c2ecf20Sopenharmony_ci		.name	= "mem",
3218c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_MEM,
3228c2ecf20Sopenharmony_ci		.start	= 0x03400000,
3238c2ecf20Sopenharmony_ci		.end	= 0x03401fff,
3248c2ecf20Sopenharmony_ci	},
3258c2ecf20Sopenharmony_ci};
3268c2ecf20Sopenharmony_ci
3278c2ecf20Sopenharmony_cistatic struct platform_device ar7_udc = {
3288c2ecf20Sopenharmony_ci	.name		= "ar7_udc",
3298c2ecf20Sopenharmony_ci	.resource	= usb_res,
3308c2ecf20Sopenharmony_ci	.num_resources	= ARRAY_SIZE(usb_res),
3318c2ecf20Sopenharmony_ci};
3328c2ecf20Sopenharmony_ci
3338c2ecf20Sopenharmony_ci/*****************************************************************************
3348c2ecf20Sopenharmony_ci * LEDs
3358c2ecf20Sopenharmony_ci ****************************************************************************/
3368c2ecf20Sopenharmony_cistatic const struct gpio_led default_leds[] = {
3378c2ecf20Sopenharmony_ci	{
3388c2ecf20Sopenharmony_ci		.name			= "status",
3398c2ecf20Sopenharmony_ci		.gpio			= 8,
3408c2ecf20Sopenharmony_ci		.active_low		= 1,
3418c2ecf20Sopenharmony_ci	},
3428c2ecf20Sopenharmony_ci};
3438c2ecf20Sopenharmony_ci
3448c2ecf20Sopenharmony_cistatic const struct gpio_led titan_leds[] = {
3458c2ecf20Sopenharmony_ci	{ .name = "status", .gpio = 8, .active_low = 1, },
3468c2ecf20Sopenharmony_ci	{ .name = "wifi", .gpio = 13, .active_low = 1, },
3478c2ecf20Sopenharmony_ci};
3488c2ecf20Sopenharmony_ci
3498c2ecf20Sopenharmony_cistatic const struct gpio_led dsl502t_leds[] = {
3508c2ecf20Sopenharmony_ci	{
3518c2ecf20Sopenharmony_ci		.name			= "status",
3528c2ecf20Sopenharmony_ci		.gpio			= 9,
3538c2ecf20Sopenharmony_ci		.active_low		= 1,
3548c2ecf20Sopenharmony_ci	},
3558c2ecf20Sopenharmony_ci	{
3568c2ecf20Sopenharmony_ci		.name			= "ethernet",
3578c2ecf20Sopenharmony_ci		.gpio			= 7,
3588c2ecf20Sopenharmony_ci		.active_low		= 1,
3598c2ecf20Sopenharmony_ci	},
3608c2ecf20Sopenharmony_ci	{
3618c2ecf20Sopenharmony_ci		.name			= "usb",
3628c2ecf20Sopenharmony_ci		.gpio			= 12,
3638c2ecf20Sopenharmony_ci		.active_low		= 1,
3648c2ecf20Sopenharmony_ci	},
3658c2ecf20Sopenharmony_ci};
3668c2ecf20Sopenharmony_ci
3678c2ecf20Sopenharmony_cistatic const struct gpio_led dg834g_leds[] = {
3688c2ecf20Sopenharmony_ci	{
3698c2ecf20Sopenharmony_ci		.name			= "ppp",
3708c2ecf20Sopenharmony_ci		.gpio			= 6,
3718c2ecf20Sopenharmony_ci		.active_low		= 1,
3728c2ecf20Sopenharmony_ci	},
3738c2ecf20Sopenharmony_ci	{
3748c2ecf20Sopenharmony_ci		.name			= "status",
3758c2ecf20Sopenharmony_ci		.gpio			= 7,
3768c2ecf20Sopenharmony_ci		.active_low		= 1,
3778c2ecf20Sopenharmony_ci	},
3788c2ecf20Sopenharmony_ci	{
3798c2ecf20Sopenharmony_ci		.name			= "adsl",
3808c2ecf20Sopenharmony_ci		.gpio			= 8,
3818c2ecf20Sopenharmony_ci		.active_low		= 1,
3828c2ecf20Sopenharmony_ci	},
3838c2ecf20Sopenharmony_ci	{
3848c2ecf20Sopenharmony_ci		.name			= "wifi",
3858c2ecf20Sopenharmony_ci		.gpio			= 12,
3868c2ecf20Sopenharmony_ci		.active_low		= 1,
3878c2ecf20Sopenharmony_ci	},
3888c2ecf20Sopenharmony_ci	{
3898c2ecf20Sopenharmony_ci		.name			= "power",
3908c2ecf20Sopenharmony_ci		.gpio			= 14,
3918c2ecf20Sopenharmony_ci		.active_low		= 1,
3928c2ecf20Sopenharmony_ci		.default_trigger	= "default-on",
3938c2ecf20Sopenharmony_ci	},
3948c2ecf20Sopenharmony_ci};
3958c2ecf20Sopenharmony_ci
3968c2ecf20Sopenharmony_cistatic const struct gpio_led fb_sl_leds[] = {
3978c2ecf20Sopenharmony_ci	{
3988c2ecf20Sopenharmony_ci		.name			= "1",
3998c2ecf20Sopenharmony_ci		.gpio			= 7,
4008c2ecf20Sopenharmony_ci	},
4018c2ecf20Sopenharmony_ci	{
4028c2ecf20Sopenharmony_ci		.name			= "2",
4038c2ecf20Sopenharmony_ci		.gpio			= 13,
4048c2ecf20Sopenharmony_ci		.active_low		= 1,
4058c2ecf20Sopenharmony_ci	},
4068c2ecf20Sopenharmony_ci	{
4078c2ecf20Sopenharmony_ci		.name			= "3",
4088c2ecf20Sopenharmony_ci		.gpio			= 10,
4098c2ecf20Sopenharmony_ci		.active_low		= 1,
4108c2ecf20Sopenharmony_ci	},
4118c2ecf20Sopenharmony_ci	{
4128c2ecf20Sopenharmony_ci		.name			= "4",
4138c2ecf20Sopenharmony_ci		.gpio			= 12,
4148c2ecf20Sopenharmony_ci		.active_low		= 1,
4158c2ecf20Sopenharmony_ci	},
4168c2ecf20Sopenharmony_ci	{
4178c2ecf20Sopenharmony_ci		.name			= "5",
4188c2ecf20Sopenharmony_ci		.gpio			= 9,
4198c2ecf20Sopenharmony_ci		.active_low		= 1,
4208c2ecf20Sopenharmony_ci	},
4218c2ecf20Sopenharmony_ci};
4228c2ecf20Sopenharmony_ci
4238c2ecf20Sopenharmony_cistatic const struct gpio_led fb_fon_leds[] = {
4248c2ecf20Sopenharmony_ci	{
4258c2ecf20Sopenharmony_ci		.name			= "1",
4268c2ecf20Sopenharmony_ci		.gpio			= 8,
4278c2ecf20Sopenharmony_ci	},
4288c2ecf20Sopenharmony_ci	{
4298c2ecf20Sopenharmony_ci		.name			= "2",
4308c2ecf20Sopenharmony_ci		.gpio			= 3,
4318c2ecf20Sopenharmony_ci		.active_low		= 1,
4328c2ecf20Sopenharmony_ci	},
4338c2ecf20Sopenharmony_ci	{
4348c2ecf20Sopenharmony_ci		.name			= "3",
4358c2ecf20Sopenharmony_ci		.gpio			= 5,
4368c2ecf20Sopenharmony_ci	},
4378c2ecf20Sopenharmony_ci	{
4388c2ecf20Sopenharmony_ci		.name			= "4",
4398c2ecf20Sopenharmony_ci		.gpio			= 4,
4408c2ecf20Sopenharmony_ci		.active_low		= 1,
4418c2ecf20Sopenharmony_ci	},
4428c2ecf20Sopenharmony_ci	{
4438c2ecf20Sopenharmony_ci		.name			= "5",
4448c2ecf20Sopenharmony_ci		.gpio			= 11,
4458c2ecf20Sopenharmony_ci		.active_low		= 1,
4468c2ecf20Sopenharmony_ci	},
4478c2ecf20Sopenharmony_ci};
4488c2ecf20Sopenharmony_ci
4498c2ecf20Sopenharmony_cistatic const struct gpio_led gt701_leds[] = {
4508c2ecf20Sopenharmony_ci	{
4518c2ecf20Sopenharmony_ci		.name			= "inet:green",
4528c2ecf20Sopenharmony_ci		.gpio			= 13,
4538c2ecf20Sopenharmony_ci		.active_low		= 1,
4548c2ecf20Sopenharmony_ci	},
4558c2ecf20Sopenharmony_ci	{
4568c2ecf20Sopenharmony_ci		.name			= "usb",
4578c2ecf20Sopenharmony_ci		.gpio			= 12,
4588c2ecf20Sopenharmony_ci		.active_low		= 1,
4598c2ecf20Sopenharmony_ci	},
4608c2ecf20Sopenharmony_ci	{
4618c2ecf20Sopenharmony_ci		.name			= "inet:red",
4628c2ecf20Sopenharmony_ci		.gpio			= 9,
4638c2ecf20Sopenharmony_ci		.active_low		= 1,
4648c2ecf20Sopenharmony_ci	},
4658c2ecf20Sopenharmony_ci	{
4668c2ecf20Sopenharmony_ci		.name			= "power:red",
4678c2ecf20Sopenharmony_ci		.gpio			= 7,
4688c2ecf20Sopenharmony_ci		.active_low		= 1,
4698c2ecf20Sopenharmony_ci	},
4708c2ecf20Sopenharmony_ci	{
4718c2ecf20Sopenharmony_ci		.name			= "power:green",
4728c2ecf20Sopenharmony_ci		.gpio			= 8,
4738c2ecf20Sopenharmony_ci		.active_low		= 1,
4748c2ecf20Sopenharmony_ci		.default_trigger	= "default-on",
4758c2ecf20Sopenharmony_ci	},
4768c2ecf20Sopenharmony_ci	{
4778c2ecf20Sopenharmony_ci		.name			= "ethernet",
4788c2ecf20Sopenharmony_ci		.gpio			= 10,
4798c2ecf20Sopenharmony_ci		.active_low		= 1,
4808c2ecf20Sopenharmony_ci	},
4818c2ecf20Sopenharmony_ci};
4828c2ecf20Sopenharmony_ci
4838c2ecf20Sopenharmony_cistatic struct gpio_led_platform_data ar7_led_data;
4848c2ecf20Sopenharmony_ci
4858c2ecf20Sopenharmony_cistatic struct platform_device ar7_gpio_leds = {
4868c2ecf20Sopenharmony_ci	.name = "leds-gpio",
4878c2ecf20Sopenharmony_ci	.dev = {
4888c2ecf20Sopenharmony_ci		.platform_data = &ar7_led_data,
4898c2ecf20Sopenharmony_ci	}
4908c2ecf20Sopenharmony_ci};
4918c2ecf20Sopenharmony_ci
4928c2ecf20Sopenharmony_cistatic void __init detect_leds(void)
4938c2ecf20Sopenharmony_ci{
4948c2ecf20Sopenharmony_ci	char *prid, *usb_prod;
4958c2ecf20Sopenharmony_ci
4968c2ecf20Sopenharmony_ci	/* Default LEDs */
4978c2ecf20Sopenharmony_ci	ar7_led_data.num_leds = ARRAY_SIZE(default_leds);
4988c2ecf20Sopenharmony_ci	ar7_led_data.leds = default_leds;
4998c2ecf20Sopenharmony_ci
5008c2ecf20Sopenharmony_ci	/* FIXME: the whole thing is unreliable */
5018c2ecf20Sopenharmony_ci	prid = prom_getenv("ProductID");
5028c2ecf20Sopenharmony_ci	usb_prod = prom_getenv("usb_prod");
5038c2ecf20Sopenharmony_ci
5048c2ecf20Sopenharmony_ci	/* If we can't get the product id from PROM, use the default LEDs */
5058c2ecf20Sopenharmony_ci	if (!prid)
5068c2ecf20Sopenharmony_ci		return;
5078c2ecf20Sopenharmony_ci
5088c2ecf20Sopenharmony_ci	if (strstr(prid, "Fritz_Box_FON")) {
5098c2ecf20Sopenharmony_ci		ar7_led_data.num_leds = ARRAY_SIZE(fb_fon_leds);
5108c2ecf20Sopenharmony_ci		ar7_led_data.leds = fb_fon_leds;
5118c2ecf20Sopenharmony_ci	} else if (strstr(prid, "Fritz_Box_")) {
5128c2ecf20Sopenharmony_ci		ar7_led_data.num_leds = ARRAY_SIZE(fb_sl_leds);
5138c2ecf20Sopenharmony_ci		ar7_led_data.leds = fb_sl_leds;
5148c2ecf20Sopenharmony_ci	} else if ((!strcmp(prid, "AR7RD") || !strcmp(prid, "AR7DB"))
5158c2ecf20Sopenharmony_ci		&& usb_prod != NULL && strstr(usb_prod, "DSL-502T")) {
5168c2ecf20Sopenharmony_ci		ar7_led_data.num_leds = ARRAY_SIZE(dsl502t_leds);
5178c2ecf20Sopenharmony_ci		ar7_led_data.leds = dsl502t_leds;
5188c2ecf20Sopenharmony_ci	} else if (strstr(prid, "DG834")) {
5198c2ecf20Sopenharmony_ci		ar7_led_data.num_leds = ARRAY_SIZE(dg834g_leds);
5208c2ecf20Sopenharmony_ci		ar7_led_data.leds = dg834g_leds;
5218c2ecf20Sopenharmony_ci	} else if (strstr(prid, "CYWM") || strstr(prid, "CYWL")) {
5228c2ecf20Sopenharmony_ci		ar7_led_data.num_leds = ARRAY_SIZE(titan_leds);
5238c2ecf20Sopenharmony_ci		ar7_led_data.leds = titan_leds;
5248c2ecf20Sopenharmony_ci	} else if (strstr(prid, "GT701")) {
5258c2ecf20Sopenharmony_ci		ar7_led_data.num_leds = ARRAY_SIZE(gt701_leds);
5268c2ecf20Sopenharmony_ci		ar7_led_data.leds = gt701_leds;
5278c2ecf20Sopenharmony_ci	}
5288c2ecf20Sopenharmony_ci}
5298c2ecf20Sopenharmony_ci
5308c2ecf20Sopenharmony_ci/*****************************************************************************
5318c2ecf20Sopenharmony_ci * Watchdog
5328c2ecf20Sopenharmony_ci ****************************************************************************/
5338c2ecf20Sopenharmony_cistatic struct resource ar7_wdt_res = {
5348c2ecf20Sopenharmony_ci	.name		= "regs",
5358c2ecf20Sopenharmony_ci	.flags		= IORESOURCE_MEM,
5368c2ecf20Sopenharmony_ci	.start		= -1,	/* Filled at runtime */
5378c2ecf20Sopenharmony_ci	.end		= -1,	/* Filled at runtime */
5388c2ecf20Sopenharmony_ci};
5398c2ecf20Sopenharmony_ci
5408c2ecf20Sopenharmony_cistatic struct platform_device ar7_wdt = {
5418c2ecf20Sopenharmony_ci	.name		= "ar7_wdt",
5428c2ecf20Sopenharmony_ci	.resource	= &ar7_wdt_res,
5438c2ecf20Sopenharmony_ci	.num_resources	= 1,
5448c2ecf20Sopenharmony_ci};
5458c2ecf20Sopenharmony_ci
5468c2ecf20Sopenharmony_ci/*****************************************************************************
5478c2ecf20Sopenharmony_ci * Init
5488c2ecf20Sopenharmony_ci ****************************************************************************/
5498c2ecf20Sopenharmony_cistatic int __init ar7_register_uarts(void)
5508c2ecf20Sopenharmony_ci{
5518c2ecf20Sopenharmony_ci#ifdef CONFIG_SERIAL_8250
5528c2ecf20Sopenharmony_ci	static struct uart_port uart_port __initdata;
5538c2ecf20Sopenharmony_ci	struct clk *bus_clk;
5548c2ecf20Sopenharmony_ci	int res;
5558c2ecf20Sopenharmony_ci
5568c2ecf20Sopenharmony_ci	memset(&uart_port, 0, sizeof(struct uart_port));
5578c2ecf20Sopenharmony_ci
5588c2ecf20Sopenharmony_ci	bus_clk = clk_get(NULL, "bus");
5598c2ecf20Sopenharmony_ci	if (IS_ERR(bus_clk))
5608c2ecf20Sopenharmony_ci		panic("unable to get bus clk");
5618c2ecf20Sopenharmony_ci
5628c2ecf20Sopenharmony_ci	uart_port.type		= PORT_AR7;
5638c2ecf20Sopenharmony_ci	uart_port.uartclk	= clk_get_rate(bus_clk) / 2;
5648c2ecf20Sopenharmony_ci	uart_port.iotype	= UPIO_MEM32;
5658c2ecf20Sopenharmony_ci	uart_port.flags		= UPF_FIXED_TYPE | UPF_BOOT_AUTOCONF;
5668c2ecf20Sopenharmony_ci	uart_port.regshift	= 2;
5678c2ecf20Sopenharmony_ci
5688c2ecf20Sopenharmony_ci	uart_port.line		= 0;
5698c2ecf20Sopenharmony_ci	uart_port.irq		= AR7_IRQ_UART0;
5708c2ecf20Sopenharmony_ci	uart_port.mapbase	= AR7_REGS_UART0;
5718c2ecf20Sopenharmony_ci	uart_port.membase	= ioremap(uart_port.mapbase, 256);
5728c2ecf20Sopenharmony_ci
5738c2ecf20Sopenharmony_ci	res = early_serial_setup(&uart_port);
5748c2ecf20Sopenharmony_ci	if (res)
5758c2ecf20Sopenharmony_ci		return res;
5768c2ecf20Sopenharmony_ci
5778c2ecf20Sopenharmony_ci	/* Only TNETD73xx have a second serial port */
5788c2ecf20Sopenharmony_ci	if (ar7_has_second_uart()) {
5798c2ecf20Sopenharmony_ci		uart_port.line		= 1;
5808c2ecf20Sopenharmony_ci		uart_port.irq		= AR7_IRQ_UART1;
5818c2ecf20Sopenharmony_ci		uart_port.mapbase	= UR8_REGS_UART1;
5828c2ecf20Sopenharmony_ci		uart_port.membase	= ioremap(uart_port.mapbase, 256);
5838c2ecf20Sopenharmony_ci
5848c2ecf20Sopenharmony_ci		res = early_serial_setup(&uart_port);
5858c2ecf20Sopenharmony_ci		if (res)
5868c2ecf20Sopenharmony_ci			return res;
5878c2ecf20Sopenharmony_ci	}
5888c2ecf20Sopenharmony_ci#endif
5898c2ecf20Sopenharmony_ci
5908c2ecf20Sopenharmony_ci	return 0;
5918c2ecf20Sopenharmony_ci}
5928c2ecf20Sopenharmony_ci
5938c2ecf20Sopenharmony_cistatic void __init titan_fixup_devices(void)
5948c2ecf20Sopenharmony_ci{
5958c2ecf20Sopenharmony_ci	/* Set vlynq0 data */
5968c2ecf20Sopenharmony_ci	vlynq_low_data.reset_bit = 15;
5978c2ecf20Sopenharmony_ci	vlynq_low_data.gpio_bit = 14;
5988c2ecf20Sopenharmony_ci
5998c2ecf20Sopenharmony_ci	/* Set vlynq1 data */
6008c2ecf20Sopenharmony_ci	vlynq_high_data.reset_bit = 16;
6018c2ecf20Sopenharmony_ci	vlynq_high_data.gpio_bit = 7;
6028c2ecf20Sopenharmony_ci
6038c2ecf20Sopenharmony_ci	/* Set vlynq0 resources */
6048c2ecf20Sopenharmony_ci	vlynq_low_res[0].start = TITAN_REGS_VLYNQ0;
6058c2ecf20Sopenharmony_ci	vlynq_low_res[0].end = TITAN_REGS_VLYNQ0 + 0xff;
6068c2ecf20Sopenharmony_ci	vlynq_low_res[1].start = 33;
6078c2ecf20Sopenharmony_ci	vlynq_low_res[1].end = 33;
6088c2ecf20Sopenharmony_ci	vlynq_low_res[2].start = 0x0c000000;
6098c2ecf20Sopenharmony_ci	vlynq_low_res[2].end = 0x0fffffff;
6108c2ecf20Sopenharmony_ci	vlynq_low_res[3].start = 80;
6118c2ecf20Sopenharmony_ci	vlynq_low_res[3].end = 111;
6128c2ecf20Sopenharmony_ci
6138c2ecf20Sopenharmony_ci	/* Set vlynq1 resources */
6148c2ecf20Sopenharmony_ci	vlynq_high_res[0].start = TITAN_REGS_VLYNQ1;
6158c2ecf20Sopenharmony_ci	vlynq_high_res[0].end = TITAN_REGS_VLYNQ1 + 0xff;
6168c2ecf20Sopenharmony_ci	vlynq_high_res[1].start = 34;
6178c2ecf20Sopenharmony_ci	vlynq_high_res[1].end = 34;
6188c2ecf20Sopenharmony_ci	vlynq_high_res[2].start = 0x40000000;
6198c2ecf20Sopenharmony_ci	vlynq_high_res[2].end = 0x43ffffff;
6208c2ecf20Sopenharmony_ci	vlynq_high_res[3].start = 112;
6218c2ecf20Sopenharmony_ci	vlynq_high_res[3].end = 143;
6228c2ecf20Sopenharmony_ci
6238c2ecf20Sopenharmony_ci	/* Set cpmac0 data */
6248c2ecf20Sopenharmony_ci	cpmac_low_data.phy_mask = 0x40000000;
6258c2ecf20Sopenharmony_ci
6268c2ecf20Sopenharmony_ci	/* Set cpmac1 data */
6278c2ecf20Sopenharmony_ci	cpmac_high_data.phy_mask = 0x80000000;
6288c2ecf20Sopenharmony_ci
6298c2ecf20Sopenharmony_ci	/* Set cpmac0 resources */
6308c2ecf20Sopenharmony_ci	cpmac_low_res[0].start = TITAN_REGS_MAC0;
6318c2ecf20Sopenharmony_ci	cpmac_low_res[0].end = TITAN_REGS_MAC0 + 0x7ff;
6328c2ecf20Sopenharmony_ci
6338c2ecf20Sopenharmony_ci	/* Set cpmac1 resources */
6348c2ecf20Sopenharmony_ci	cpmac_high_res[0].start = TITAN_REGS_MAC1;
6358c2ecf20Sopenharmony_ci	cpmac_high_res[0].end = TITAN_REGS_MAC1 + 0x7ff;
6368c2ecf20Sopenharmony_ci}
6378c2ecf20Sopenharmony_ci
6388c2ecf20Sopenharmony_cistatic int __init ar7_register_devices(void)
6398c2ecf20Sopenharmony_ci{
6408c2ecf20Sopenharmony_ci	void __iomem *bootcr;
6418c2ecf20Sopenharmony_ci	u32 val;
6428c2ecf20Sopenharmony_ci	int res;
6438c2ecf20Sopenharmony_ci
6448c2ecf20Sopenharmony_ci	res = ar7_gpio_init();
6458c2ecf20Sopenharmony_ci	if (res)
6468c2ecf20Sopenharmony_ci		pr_warn("unable to register gpios: %d\n", res);
6478c2ecf20Sopenharmony_ci
6488c2ecf20Sopenharmony_ci	res = ar7_register_uarts();
6498c2ecf20Sopenharmony_ci	if (res)
6508c2ecf20Sopenharmony_ci		pr_err("unable to setup uart(s): %d\n", res);
6518c2ecf20Sopenharmony_ci
6528c2ecf20Sopenharmony_ci	res = platform_device_register(&physmap_flash);
6538c2ecf20Sopenharmony_ci	if (res)
6548c2ecf20Sopenharmony_ci		pr_warn("unable to register physmap-flash: %d\n", res);
6558c2ecf20Sopenharmony_ci
6568c2ecf20Sopenharmony_ci	if (ar7_is_titan())
6578c2ecf20Sopenharmony_ci		titan_fixup_devices();
6588c2ecf20Sopenharmony_ci
6598c2ecf20Sopenharmony_ci	ar7_device_disable(vlynq_low_data.reset_bit);
6608c2ecf20Sopenharmony_ci	res = platform_device_register(&vlynq_low);
6618c2ecf20Sopenharmony_ci	if (res)
6628c2ecf20Sopenharmony_ci		pr_warn("unable to register vlynq-low: %d\n", res);
6638c2ecf20Sopenharmony_ci
6648c2ecf20Sopenharmony_ci	if (ar7_has_high_vlynq()) {
6658c2ecf20Sopenharmony_ci		ar7_device_disable(vlynq_high_data.reset_bit);
6668c2ecf20Sopenharmony_ci		res = platform_device_register(&vlynq_high);
6678c2ecf20Sopenharmony_ci		if (res)
6688c2ecf20Sopenharmony_ci			pr_warn("unable to register vlynq-high: %d\n", res);
6698c2ecf20Sopenharmony_ci	}
6708c2ecf20Sopenharmony_ci
6718c2ecf20Sopenharmony_ci	if (ar7_has_high_cpmac()) {
6728c2ecf20Sopenharmony_ci		res = fixed_phy_add(PHY_POLL, cpmac_high.id,
6738c2ecf20Sopenharmony_ci				    &fixed_phy_status);
6748c2ecf20Sopenharmony_ci		if (!res) {
6758c2ecf20Sopenharmony_ci			cpmac_get_mac(1, cpmac_high_data.dev_addr);
6768c2ecf20Sopenharmony_ci
6778c2ecf20Sopenharmony_ci			res = platform_device_register(&cpmac_high);
6788c2ecf20Sopenharmony_ci			if (res)
6798c2ecf20Sopenharmony_ci				pr_warn("unable to register cpmac-high: %d\n",
6808c2ecf20Sopenharmony_ci					res);
6818c2ecf20Sopenharmony_ci		} else
6828c2ecf20Sopenharmony_ci			pr_warn("unable to add cpmac-high phy: %d\n", res);
6838c2ecf20Sopenharmony_ci	} else
6848c2ecf20Sopenharmony_ci		cpmac_low_data.phy_mask = 0xffffffff;
6858c2ecf20Sopenharmony_ci
6868c2ecf20Sopenharmony_ci	res = fixed_phy_add(PHY_POLL, cpmac_low.id, &fixed_phy_status);
6878c2ecf20Sopenharmony_ci	if (!res) {
6888c2ecf20Sopenharmony_ci		cpmac_get_mac(0, cpmac_low_data.dev_addr);
6898c2ecf20Sopenharmony_ci		res = platform_device_register(&cpmac_low);
6908c2ecf20Sopenharmony_ci		if (res)
6918c2ecf20Sopenharmony_ci			pr_warn("unable to register cpmac-low: %d\n", res);
6928c2ecf20Sopenharmony_ci	} else
6938c2ecf20Sopenharmony_ci		pr_warn("unable to add cpmac-low phy: %d\n", res);
6948c2ecf20Sopenharmony_ci
6958c2ecf20Sopenharmony_ci	detect_leds();
6968c2ecf20Sopenharmony_ci	res = platform_device_register(&ar7_gpio_leds);
6978c2ecf20Sopenharmony_ci	if (res)
6988c2ecf20Sopenharmony_ci		pr_warn("unable to register leds: %d\n", res);
6998c2ecf20Sopenharmony_ci
7008c2ecf20Sopenharmony_ci	res = platform_device_register(&ar7_udc);
7018c2ecf20Sopenharmony_ci	if (res)
7028c2ecf20Sopenharmony_ci		pr_warn("unable to register usb slave: %d\n", res);
7038c2ecf20Sopenharmony_ci
7048c2ecf20Sopenharmony_ci	/* Register watchdog only if enabled in hardware */
7058c2ecf20Sopenharmony_ci	bootcr = ioremap(AR7_REGS_DCL, 4);
7068c2ecf20Sopenharmony_ci	val = readl(bootcr);
7078c2ecf20Sopenharmony_ci	iounmap(bootcr);
7088c2ecf20Sopenharmony_ci	if (val & AR7_WDT_HW_ENA) {
7098c2ecf20Sopenharmony_ci		if (ar7_has_high_vlynq())
7108c2ecf20Sopenharmony_ci			ar7_wdt_res.start = UR8_REGS_WDT;
7118c2ecf20Sopenharmony_ci		else
7128c2ecf20Sopenharmony_ci			ar7_wdt_res.start = AR7_REGS_WDT;
7138c2ecf20Sopenharmony_ci
7148c2ecf20Sopenharmony_ci		ar7_wdt_res.end = ar7_wdt_res.start + 0x20;
7158c2ecf20Sopenharmony_ci		res = platform_device_register(&ar7_wdt);
7168c2ecf20Sopenharmony_ci		if (res)
7178c2ecf20Sopenharmony_ci			pr_warn("unable to register watchdog: %d\n", res);
7188c2ecf20Sopenharmony_ci	}
7198c2ecf20Sopenharmony_ci
7208c2ecf20Sopenharmony_ci	return 0;
7218c2ecf20Sopenharmony_ci}
7228c2ecf20Sopenharmony_cidevice_initcall(ar7_register_devices);
723