162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * arch/arm/mach-ep93xx/core.c
462306a36Sopenharmony_ci * Core routines for Cirrus EP93xx chips.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
762306a36Sopenharmony_ci * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org>
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci * Thanks go to Michael Burian and Ray Lehtiniemi for their key
1062306a36Sopenharmony_ci * role in the ep93xx linux community.
1162306a36Sopenharmony_ci */
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <linux/kernel.h>
1662306a36Sopenharmony_ci#include <linux/init.h>
1762306a36Sopenharmony_ci#include <linux/platform_device.h>
1862306a36Sopenharmony_ci#include <linux/interrupt.h>
1962306a36Sopenharmony_ci#include <linux/dma-mapping.h>
2062306a36Sopenharmony_ci#include <linux/sys_soc.h>
2162306a36Sopenharmony_ci#include <linux/irq.h>
2262306a36Sopenharmony_ci#include <linux/io.h>
2362306a36Sopenharmony_ci#include <linux/gpio.h>
2462306a36Sopenharmony_ci#include <linux/leds.h>
2562306a36Sopenharmony_ci#include <linux/uaccess.h>
2662306a36Sopenharmony_ci#include <linux/termios.h>
2762306a36Sopenharmony_ci#include <linux/amba/bus.h>
2862306a36Sopenharmony_ci#include <linux/amba/serial.h>
2962306a36Sopenharmony_ci#include <linux/mtd/physmap.h>
3062306a36Sopenharmony_ci#include <linux/i2c.h>
3162306a36Sopenharmony_ci#include <linux/gpio/machine.h>
3262306a36Sopenharmony_ci#include <linux/spi/spi.h>
3362306a36Sopenharmony_ci#include <linux/export.h>
3462306a36Sopenharmony_ci#include <linux/irqchip/arm-vic.h>
3562306a36Sopenharmony_ci#include <linux/reboot.h>
3662306a36Sopenharmony_ci#include <linux/usb/ohci_pdriver.h>
3762306a36Sopenharmony_ci#include <linux/random.h>
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci#include "hardware.h"
4062306a36Sopenharmony_ci#include <linux/platform_data/video-ep93xx.h>
4162306a36Sopenharmony_ci#include <linux/platform_data/keypad-ep93xx.h>
4262306a36Sopenharmony_ci#include <linux/platform_data/spi-ep93xx.h>
4362306a36Sopenharmony_ci#include <linux/soc/cirrus/ep93xx.h>
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci#include "gpio-ep93xx.h"
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci#include <asm/mach/arch.h>
4862306a36Sopenharmony_ci#include <asm/mach/map.h>
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci#include "soc.h"
5162306a36Sopenharmony_ci#include "irqs.h"
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci/*************************************************************************
5462306a36Sopenharmony_ci * Static I/O mappings that are needed for all EP93xx platforms
5562306a36Sopenharmony_ci *************************************************************************/
5662306a36Sopenharmony_cistatic struct map_desc ep93xx_io_desc[] __initdata = {
5762306a36Sopenharmony_ci	{
5862306a36Sopenharmony_ci		.virtual	= EP93XX_AHB_VIRT_BASE,
5962306a36Sopenharmony_ci		.pfn		= __phys_to_pfn(EP93XX_AHB_PHYS_BASE),
6062306a36Sopenharmony_ci		.length		= EP93XX_AHB_SIZE,
6162306a36Sopenharmony_ci		.type		= MT_DEVICE,
6262306a36Sopenharmony_ci	}, {
6362306a36Sopenharmony_ci		.virtual	= EP93XX_APB_VIRT_BASE,
6462306a36Sopenharmony_ci		.pfn		= __phys_to_pfn(EP93XX_APB_PHYS_BASE),
6562306a36Sopenharmony_ci		.length		= EP93XX_APB_SIZE,
6662306a36Sopenharmony_ci		.type		= MT_DEVICE,
6762306a36Sopenharmony_ci	},
6862306a36Sopenharmony_ci};
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_civoid __init ep93xx_map_io(void)
7162306a36Sopenharmony_ci{
7262306a36Sopenharmony_ci	iotable_init(ep93xx_io_desc, ARRAY_SIZE(ep93xx_io_desc));
7362306a36Sopenharmony_ci}
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci/*************************************************************************
7662306a36Sopenharmony_ci * EP93xx IRQ handling
7762306a36Sopenharmony_ci *************************************************************************/
7862306a36Sopenharmony_civoid __init ep93xx_init_irq(void)
7962306a36Sopenharmony_ci{
8062306a36Sopenharmony_ci	vic_init(EP93XX_VIC1_BASE, IRQ_EP93XX_VIC0, EP93XX_VIC1_VALID_IRQ_MASK, 0);
8162306a36Sopenharmony_ci	vic_init(EP93XX_VIC2_BASE, IRQ_EP93XX_VIC1, EP93XX_VIC2_VALID_IRQ_MASK, 0);
8262306a36Sopenharmony_ci}
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci/*************************************************************************
8662306a36Sopenharmony_ci * EP93xx System Controller Software Locked register handling
8762306a36Sopenharmony_ci *************************************************************************/
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci/*
9062306a36Sopenharmony_ci * syscon_swlock prevents anything else from writing to the syscon
9162306a36Sopenharmony_ci * block while a software locked register is being written.
9262306a36Sopenharmony_ci */
9362306a36Sopenharmony_cistatic DEFINE_SPINLOCK(syscon_swlock);
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_civoid ep93xx_syscon_swlocked_write(unsigned int val, void __iomem *reg)
9662306a36Sopenharmony_ci{
9762306a36Sopenharmony_ci	unsigned long flags;
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	spin_lock_irqsave(&syscon_swlock, flags);
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci	__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
10262306a36Sopenharmony_ci	__raw_writel(val, reg);
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci	spin_unlock_irqrestore(&syscon_swlock, flags);
10562306a36Sopenharmony_ci}
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_civoid ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits)
10862306a36Sopenharmony_ci{
10962306a36Sopenharmony_ci	unsigned long flags;
11062306a36Sopenharmony_ci	unsigned int val;
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci	spin_lock_irqsave(&syscon_swlock, flags);
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci	val = __raw_readl(EP93XX_SYSCON_DEVCFG);
11562306a36Sopenharmony_ci	val &= ~clear_bits;
11662306a36Sopenharmony_ci	val |= set_bits;
11762306a36Sopenharmony_ci	__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
11862306a36Sopenharmony_ci	__raw_writel(val, EP93XX_SYSCON_DEVCFG);
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci	spin_unlock_irqrestore(&syscon_swlock, flags);
12162306a36Sopenharmony_ci}
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci/**
12462306a36Sopenharmony_ci * ep93xx_chip_revision() - returns the EP93xx chip revision
12562306a36Sopenharmony_ci *
12662306a36Sopenharmony_ci * See "platform.h" for more information.
12762306a36Sopenharmony_ci */
12862306a36Sopenharmony_ciunsigned int ep93xx_chip_revision(void)
12962306a36Sopenharmony_ci{
13062306a36Sopenharmony_ci	unsigned int v;
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci	v = __raw_readl(EP93XX_SYSCON_SYSCFG);
13362306a36Sopenharmony_ci	v &= EP93XX_SYSCON_SYSCFG_REV_MASK;
13462306a36Sopenharmony_ci	v >>= EP93XX_SYSCON_SYSCFG_REV_SHIFT;
13562306a36Sopenharmony_ci	return v;
13662306a36Sopenharmony_ci}
13762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ep93xx_chip_revision);
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci/*************************************************************************
14062306a36Sopenharmony_ci * EP93xx GPIO
14162306a36Sopenharmony_ci *************************************************************************/
14262306a36Sopenharmony_cistatic struct resource ep93xx_gpio_resource[] = {
14362306a36Sopenharmony_ci	DEFINE_RES_MEM(EP93XX_GPIO_PHYS_BASE, 0xcc),
14462306a36Sopenharmony_ci	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO_AB),
14562306a36Sopenharmony_ci	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO0MUX),
14662306a36Sopenharmony_ci	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO1MUX),
14762306a36Sopenharmony_ci	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO2MUX),
14862306a36Sopenharmony_ci	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO3MUX),
14962306a36Sopenharmony_ci	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO4MUX),
15062306a36Sopenharmony_ci	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO5MUX),
15162306a36Sopenharmony_ci	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO6MUX),
15262306a36Sopenharmony_ci	DEFINE_RES_IRQ(IRQ_EP93XX_GPIO7MUX),
15362306a36Sopenharmony_ci};
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_cistatic struct platform_device ep93xx_gpio_device = {
15662306a36Sopenharmony_ci	.name		= "gpio-ep93xx",
15762306a36Sopenharmony_ci	.id		= -1,
15862306a36Sopenharmony_ci	.num_resources	= ARRAY_SIZE(ep93xx_gpio_resource),
15962306a36Sopenharmony_ci	.resource	= ep93xx_gpio_resource,
16062306a36Sopenharmony_ci};
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ci/*************************************************************************
16362306a36Sopenharmony_ci * EP93xx peripheral handling
16462306a36Sopenharmony_ci *************************************************************************/
16562306a36Sopenharmony_ci#define EP93XX_UART_MCR_OFFSET		(0x0100)
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_cistatic void ep93xx_uart_set_mctrl(struct amba_device *dev,
16862306a36Sopenharmony_ci				  void __iomem *base, unsigned int mctrl)
16962306a36Sopenharmony_ci{
17062306a36Sopenharmony_ci	unsigned int mcr;
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci	mcr = 0;
17362306a36Sopenharmony_ci	if (mctrl & TIOCM_RTS)
17462306a36Sopenharmony_ci		mcr |= 2;
17562306a36Sopenharmony_ci	if (mctrl & TIOCM_DTR)
17662306a36Sopenharmony_ci		mcr |= 1;
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ci	__raw_writel(mcr, base + EP93XX_UART_MCR_OFFSET);
17962306a36Sopenharmony_ci}
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_cistatic struct amba_pl010_data ep93xx_uart_data = {
18262306a36Sopenharmony_ci	.set_mctrl	= ep93xx_uart_set_mctrl,
18362306a36Sopenharmony_ci};
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_cistatic AMBA_APB_DEVICE(uart1, "apb:uart1", 0x00041010, EP93XX_UART1_PHYS_BASE,
18662306a36Sopenharmony_ci	{ IRQ_EP93XX_UART1 }, &ep93xx_uart_data);
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_cistatic AMBA_APB_DEVICE(uart2, "apb:uart2", 0x00041010, EP93XX_UART2_PHYS_BASE,
18962306a36Sopenharmony_ci	{ IRQ_EP93XX_UART2 }, NULL);
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_cistatic AMBA_APB_DEVICE(uart3, "apb:uart3", 0x00041010, EP93XX_UART3_PHYS_BASE,
19262306a36Sopenharmony_ci	{ IRQ_EP93XX_UART3 }, &ep93xx_uart_data);
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_cistatic struct resource ep93xx_rtc_resource[] = {
19562306a36Sopenharmony_ci	DEFINE_RES_MEM(EP93XX_RTC_PHYS_BASE, 0x10c),
19662306a36Sopenharmony_ci};
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_cistatic struct platform_device ep93xx_rtc_device = {
19962306a36Sopenharmony_ci	.name		= "ep93xx-rtc",
20062306a36Sopenharmony_ci	.id		= -1,
20162306a36Sopenharmony_ci	.num_resources	= ARRAY_SIZE(ep93xx_rtc_resource),
20262306a36Sopenharmony_ci	.resource	= ep93xx_rtc_resource,
20362306a36Sopenharmony_ci};
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci/*************************************************************************
20662306a36Sopenharmony_ci * EP93xx OHCI USB Host
20762306a36Sopenharmony_ci *************************************************************************/
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_cistatic struct clk *ep93xx_ohci_host_clock;
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_cistatic int ep93xx_ohci_power_on(struct platform_device *pdev)
21262306a36Sopenharmony_ci{
21362306a36Sopenharmony_ci	if (!ep93xx_ohci_host_clock) {
21462306a36Sopenharmony_ci		ep93xx_ohci_host_clock = devm_clk_get(&pdev->dev, NULL);
21562306a36Sopenharmony_ci		if (IS_ERR(ep93xx_ohci_host_clock))
21662306a36Sopenharmony_ci			return PTR_ERR(ep93xx_ohci_host_clock);
21762306a36Sopenharmony_ci	}
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ci	return clk_prepare_enable(ep93xx_ohci_host_clock);
22062306a36Sopenharmony_ci}
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_cistatic void ep93xx_ohci_power_off(struct platform_device *pdev)
22362306a36Sopenharmony_ci{
22462306a36Sopenharmony_ci	clk_disable(ep93xx_ohci_host_clock);
22562306a36Sopenharmony_ci}
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_cistatic struct usb_ohci_pdata ep93xx_ohci_pdata = {
22862306a36Sopenharmony_ci	.power_on	= ep93xx_ohci_power_on,
22962306a36Sopenharmony_ci	.power_off	= ep93xx_ohci_power_off,
23062306a36Sopenharmony_ci	.power_suspend	= ep93xx_ohci_power_off,
23162306a36Sopenharmony_ci};
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_cistatic struct resource ep93xx_ohci_resources[] = {
23462306a36Sopenharmony_ci	DEFINE_RES_MEM(EP93XX_USB_PHYS_BASE, 0x1000),
23562306a36Sopenharmony_ci	DEFINE_RES_IRQ(IRQ_EP93XX_USB),
23662306a36Sopenharmony_ci};
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_cistatic u64 ep93xx_ohci_dma_mask = DMA_BIT_MASK(32);
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_cistatic struct platform_device ep93xx_ohci_device = {
24162306a36Sopenharmony_ci	.name		= "ohci-platform",
24262306a36Sopenharmony_ci	.id		= -1,
24362306a36Sopenharmony_ci	.num_resources	= ARRAY_SIZE(ep93xx_ohci_resources),
24462306a36Sopenharmony_ci	.resource	= ep93xx_ohci_resources,
24562306a36Sopenharmony_ci	.dev		= {
24662306a36Sopenharmony_ci		.dma_mask		= &ep93xx_ohci_dma_mask,
24762306a36Sopenharmony_ci		.coherent_dma_mask	= DMA_BIT_MASK(32),
24862306a36Sopenharmony_ci		.platform_data		= &ep93xx_ohci_pdata,
24962306a36Sopenharmony_ci	},
25062306a36Sopenharmony_ci};
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci/*************************************************************************
25362306a36Sopenharmony_ci * EP93xx physmap'ed flash
25462306a36Sopenharmony_ci *************************************************************************/
25562306a36Sopenharmony_cistatic struct physmap_flash_data ep93xx_flash_data;
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_cistatic struct resource ep93xx_flash_resource = {
25862306a36Sopenharmony_ci	.flags		= IORESOURCE_MEM,
25962306a36Sopenharmony_ci};
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_cistatic struct platform_device ep93xx_flash = {
26262306a36Sopenharmony_ci	.name		= "physmap-flash",
26362306a36Sopenharmony_ci	.id		= 0,
26462306a36Sopenharmony_ci	.dev		= {
26562306a36Sopenharmony_ci		.platform_data	= &ep93xx_flash_data,
26662306a36Sopenharmony_ci	},
26762306a36Sopenharmony_ci	.num_resources	= 1,
26862306a36Sopenharmony_ci	.resource	= &ep93xx_flash_resource,
26962306a36Sopenharmony_ci};
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_ci/**
27262306a36Sopenharmony_ci * ep93xx_register_flash() - Register the external flash device.
27362306a36Sopenharmony_ci * @width:	bank width in octets
27462306a36Sopenharmony_ci * @start:	resource start address
27562306a36Sopenharmony_ci * @size:	resource size
27662306a36Sopenharmony_ci */
27762306a36Sopenharmony_civoid __init ep93xx_register_flash(unsigned int width,
27862306a36Sopenharmony_ci				  resource_size_t start, resource_size_t size)
27962306a36Sopenharmony_ci{
28062306a36Sopenharmony_ci	ep93xx_flash_data.width		= width;
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_ci	ep93xx_flash_resource.start	= start;
28362306a36Sopenharmony_ci	ep93xx_flash_resource.end	= start + size - 1;
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ci	platform_device_register(&ep93xx_flash);
28662306a36Sopenharmony_ci}
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci/*************************************************************************
29062306a36Sopenharmony_ci * EP93xx ethernet peripheral handling
29162306a36Sopenharmony_ci *************************************************************************/
29262306a36Sopenharmony_cistatic struct ep93xx_eth_data ep93xx_eth_data;
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_cistatic struct resource ep93xx_eth_resource[] = {
29562306a36Sopenharmony_ci	DEFINE_RES_MEM(EP93XX_ETHERNET_PHYS_BASE, 0x10000),
29662306a36Sopenharmony_ci	DEFINE_RES_IRQ(IRQ_EP93XX_ETHERNET),
29762306a36Sopenharmony_ci};
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_cistatic u64 ep93xx_eth_dma_mask = DMA_BIT_MASK(32);
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_cistatic struct platform_device ep93xx_eth_device = {
30262306a36Sopenharmony_ci	.name		= "ep93xx-eth",
30362306a36Sopenharmony_ci	.id		= -1,
30462306a36Sopenharmony_ci	.dev		= {
30562306a36Sopenharmony_ci		.platform_data		= &ep93xx_eth_data,
30662306a36Sopenharmony_ci		.coherent_dma_mask	= DMA_BIT_MASK(32),
30762306a36Sopenharmony_ci		.dma_mask		= &ep93xx_eth_dma_mask,
30862306a36Sopenharmony_ci	},
30962306a36Sopenharmony_ci	.num_resources	= ARRAY_SIZE(ep93xx_eth_resource),
31062306a36Sopenharmony_ci	.resource	= ep93xx_eth_resource,
31162306a36Sopenharmony_ci};
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci/**
31462306a36Sopenharmony_ci * ep93xx_register_eth - Register the built-in ethernet platform device.
31562306a36Sopenharmony_ci * @data:	platform specific ethernet configuration (__initdata)
31662306a36Sopenharmony_ci * @copy_addr:	flag indicating that the MAC address should be copied
31762306a36Sopenharmony_ci *		from the IndAd registers (as programmed by the bootloader)
31862306a36Sopenharmony_ci */
31962306a36Sopenharmony_civoid __init ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr)
32062306a36Sopenharmony_ci{
32162306a36Sopenharmony_ci	if (copy_addr)
32262306a36Sopenharmony_ci		memcpy_fromio(data->dev_addr, EP93XX_ETHERNET_BASE + 0x50, 6);
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci	ep93xx_eth_data = *data;
32562306a36Sopenharmony_ci	platform_device_register(&ep93xx_eth_device);
32662306a36Sopenharmony_ci}
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci/*************************************************************************
33062306a36Sopenharmony_ci * EP93xx i2c peripheral handling
33162306a36Sopenharmony_ci *************************************************************************/
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci/* All EP93xx devices use the same two GPIO pins for I2C bit-banging */
33462306a36Sopenharmony_cistatic struct gpiod_lookup_table ep93xx_i2c_gpiod_table = {
33562306a36Sopenharmony_ci	.dev_id		= "i2c-gpio.0",
33662306a36Sopenharmony_ci	.table		= {
33762306a36Sopenharmony_ci		/* Use local offsets on gpiochip/port "G" */
33862306a36Sopenharmony_ci		GPIO_LOOKUP_IDX("G", 1, NULL, 0,
33962306a36Sopenharmony_ci				GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
34062306a36Sopenharmony_ci		GPIO_LOOKUP_IDX("G", 0, NULL, 1,
34162306a36Sopenharmony_ci				GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
34262306a36Sopenharmony_ci		{ }
34362306a36Sopenharmony_ci	},
34462306a36Sopenharmony_ci};
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_cistatic struct platform_device ep93xx_i2c_device = {
34762306a36Sopenharmony_ci	.name		= "i2c-gpio",
34862306a36Sopenharmony_ci	.id		= 0,
34962306a36Sopenharmony_ci	.dev		= {
35062306a36Sopenharmony_ci		.platform_data	= NULL,
35162306a36Sopenharmony_ci	},
35262306a36Sopenharmony_ci};
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci/**
35562306a36Sopenharmony_ci * ep93xx_register_i2c - Register the i2c platform device.
35662306a36Sopenharmony_ci * @devices:	platform specific i2c bus device information (__initdata)
35762306a36Sopenharmony_ci * @num:	the number of devices on the i2c bus
35862306a36Sopenharmony_ci */
35962306a36Sopenharmony_civoid __init ep93xx_register_i2c(struct i2c_board_info *devices, int num)
36062306a36Sopenharmony_ci{
36162306a36Sopenharmony_ci	/*
36262306a36Sopenharmony_ci	 * FIXME: this just sets the two pins as non-opendrain, as no
36362306a36Sopenharmony_ci	 * platforms tries to do that anyway. Flag the applicable lines
36462306a36Sopenharmony_ci	 * as open drain in the GPIO_LOOKUP above and the driver or
36562306a36Sopenharmony_ci	 * gpiolib will handle open drain/open drain emulation as need
36662306a36Sopenharmony_ci	 * be. Right now i2c-gpio emulates open drain which is not
36762306a36Sopenharmony_ci	 * optimal.
36862306a36Sopenharmony_ci	 */
36962306a36Sopenharmony_ci	__raw_writel((0 << 1) | (0 << 0),
37062306a36Sopenharmony_ci		     EP93XX_GPIO_EEDRIVE);
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_ci	i2c_register_board_info(0, devices, num);
37362306a36Sopenharmony_ci	gpiod_add_lookup_table(&ep93xx_i2c_gpiod_table);
37462306a36Sopenharmony_ci	platform_device_register(&ep93xx_i2c_device);
37562306a36Sopenharmony_ci}
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_ci/*************************************************************************
37862306a36Sopenharmony_ci * EP93xx SPI peripheral handling
37962306a36Sopenharmony_ci *************************************************************************/
38062306a36Sopenharmony_cistatic struct ep93xx_spi_info ep93xx_spi_master_data;
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_cistatic struct resource ep93xx_spi_resources[] = {
38362306a36Sopenharmony_ci	DEFINE_RES_MEM(EP93XX_SPI_PHYS_BASE, 0x18),
38462306a36Sopenharmony_ci	DEFINE_RES_IRQ(IRQ_EP93XX_SSP),
38562306a36Sopenharmony_ci};
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_cistatic u64 ep93xx_spi_dma_mask = DMA_BIT_MASK(32);
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_cistatic struct platform_device ep93xx_spi_device = {
39062306a36Sopenharmony_ci	.name		= "ep93xx-spi",
39162306a36Sopenharmony_ci	.id		= 0,
39262306a36Sopenharmony_ci	.dev		= {
39362306a36Sopenharmony_ci		.platform_data		= &ep93xx_spi_master_data,
39462306a36Sopenharmony_ci		.coherent_dma_mask	= DMA_BIT_MASK(32),
39562306a36Sopenharmony_ci		.dma_mask		= &ep93xx_spi_dma_mask,
39662306a36Sopenharmony_ci	},
39762306a36Sopenharmony_ci	.num_resources	= ARRAY_SIZE(ep93xx_spi_resources),
39862306a36Sopenharmony_ci	.resource	= ep93xx_spi_resources,
39962306a36Sopenharmony_ci};
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_ci/**
40262306a36Sopenharmony_ci * ep93xx_register_spi() - registers spi platform device
40362306a36Sopenharmony_ci * @info: ep93xx board specific spi master info (__initdata)
40462306a36Sopenharmony_ci * @devices: SPI devices to register (__initdata)
40562306a36Sopenharmony_ci * @num: number of SPI devices to register
40662306a36Sopenharmony_ci *
40762306a36Sopenharmony_ci * This function registers platform device for the EP93xx SPI controller and
40862306a36Sopenharmony_ci * also makes sure that SPI pins are muxed so that I2S is not using those pins.
40962306a36Sopenharmony_ci */
41062306a36Sopenharmony_civoid __init ep93xx_register_spi(struct ep93xx_spi_info *info,
41162306a36Sopenharmony_ci				struct spi_board_info *devices, int num)
41262306a36Sopenharmony_ci{
41362306a36Sopenharmony_ci	/*
41462306a36Sopenharmony_ci	 * When SPI is used, we need to make sure that I2S is muxed off from
41562306a36Sopenharmony_ci	 * SPI pins.
41662306a36Sopenharmony_ci	 */
41762306a36Sopenharmony_ci	ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_I2SONSSP);
41862306a36Sopenharmony_ci
41962306a36Sopenharmony_ci	ep93xx_spi_master_data = *info;
42062306a36Sopenharmony_ci	spi_register_board_info(devices, num);
42162306a36Sopenharmony_ci	platform_device_register(&ep93xx_spi_device);
42262306a36Sopenharmony_ci}
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ci/*************************************************************************
42562306a36Sopenharmony_ci * EP93xx LEDs
42662306a36Sopenharmony_ci *************************************************************************/
42762306a36Sopenharmony_cistatic const struct gpio_led ep93xx_led_pins[] __initconst = {
42862306a36Sopenharmony_ci	{
42962306a36Sopenharmony_ci		.name	= "platform:grled",
43062306a36Sopenharmony_ci	}, {
43162306a36Sopenharmony_ci		.name	= "platform:rdled",
43262306a36Sopenharmony_ci	},
43362306a36Sopenharmony_ci};
43462306a36Sopenharmony_ci
43562306a36Sopenharmony_cistatic const struct gpio_led_platform_data ep93xx_led_data __initconst = {
43662306a36Sopenharmony_ci	.num_leds	= ARRAY_SIZE(ep93xx_led_pins),
43762306a36Sopenharmony_ci	.leds		= ep93xx_led_pins,
43862306a36Sopenharmony_ci};
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_cistatic struct gpiod_lookup_table ep93xx_leds_gpio_table = {
44162306a36Sopenharmony_ci	.dev_id = "leds-gpio",
44262306a36Sopenharmony_ci	.table = {
44362306a36Sopenharmony_ci		/* Use local offsets on gpiochip/port "E" */
44462306a36Sopenharmony_ci		GPIO_LOOKUP_IDX("E", 0, NULL, 0, GPIO_ACTIVE_HIGH),
44562306a36Sopenharmony_ci		GPIO_LOOKUP_IDX("E", 1,	NULL, 1, GPIO_ACTIVE_HIGH),
44662306a36Sopenharmony_ci		{ }
44762306a36Sopenharmony_ci	},
44862306a36Sopenharmony_ci};
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_ci/*************************************************************************
45162306a36Sopenharmony_ci * EP93xx pwm peripheral handling
45262306a36Sopenharmony_ci *************************************************************************/
45362306a36Sopenharmony_cistatic struct resource ep93xx_pwm0_resource[] = {
45462306a36Sopenharmony_ci	DEFINE_RES_MEM(EP93XX_PWM_PHYS_BASE, 0x10),
45562306a36Sopenharmony_ci};
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_cistatic struct platform_device ep93xx_pwm0_device = {
45862306a36Sopenharmony_ci	.name		= "ep93xx-pwm",
45962306a36Sopenharmony_ci	.id		= 0,
46062306a36Sopenharmony_ci	.num_resources	= ARRAY_SIZE(ep93xx_pwm0_resource),
46162306a36Sopenharmony_ci	.resource	= ep93xx_pwm0_resource,
46262306a36Sopenharmony_ci};
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_cistatic struct resource ep93xx_pwm1_resource[] = {
46562306a36Sopenharmony_ci	DEFINE_RES_MEM(EP93XX_PWM_PHYS_BASE + 0x20, 0x10),
46662306a36Sopenharmony_ci};
46762306a36Sopenharmony_ci
46862306a36Sopenharmony_cistatic struct platform_device ep93xx_pwm1_device = {
46962306a36Sopenharmony_ci	.name		= "ep93xx-pwm",
47062306a36Sopenharmony_ci	.id		= 1,
47162306a36Sopenharmony_ci	.num_resources	= ARRAY_SIZE(ep93xx_pwm1_resource),
47262306a36Sopenharmony_ci	.resource	= ep93xx_pwm1_resource,
47362306a36Sopenharmony_ci};
47462306a36Sopenharmony_ci
47562306a36Sopenharmony_civoid __init ep93xx_register_pwm(int pwm0, int pwm1)
47662306a36Sopenharmony_ci{
47762306a36Sopenharmony_ci	if (pwm0)
47862306a36Sopenharmony_ci		platform_device_register(&ep93xx_pwm0_device);
47962306a36Sopenharmony_ci
48062306a36Sopenharmony_ci	/* NOTE: EP9307 does not have PWMOUT1 (pin EGPIO14) */
48162306a36Sopenharmony_ci	if (pwm1)
48262306a36Sopenharmony_ci		platform_device_register(&ep93xx_pwm1_device);
48362306a36Sopenharmony_ci}
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ciint ep93xx_pwm_acquire_gpio(struct platform_device *pdev)
48662306a36Sopenharmony_ci{
48762306a36Sopenharmony_ci	int err;
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_ci	if (pdev->id == 0) {
49062306a36Sopenharmony_ci		err = 0;
49162306a36Sopenharmony_ci	} else if (pdev->id == 1) {
49262306a36Sopenharmony_ci		err = gpio_request(EP93XX_GPIO_LINE_EGPIO14,
49362306a36Sopenharmony_ci				   dev_name(&pdev->dev));
49462306a36Sopenharmony_ci		if (err)
49562306a36Sopenharmony_ci			return err;
49662306a36Sopenharmony_ci		err = gpio_direction_output(EP93XX_GPIO_LINE_EGPIO14, 0);
49762306a36Sopenharmony_ci		if (err)
49862306a36Sopenharmony_ci			goto fail;
49962306a36Sopenharmony_ci
50062306a36Sopenharmony_ci		/* PWM 1 output on EGPIO[14] */
50162306a36Sopenharmony_ci		ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_PONG);
50262306a36Sopenharmony_ci	} else {
50362306a36Sopenharmony_ci		err = -ENODEV;
50462306a36Sopenharmony_ci	}
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_ci	return err;
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_cifail:
50962306a36Sopenharmony_ci	gpio_free(EP93XX_GPIO_LINE_EGPIO14);
51062306a36Sopenharmony_ci	return err;
51162306a36Sopenharmony_ci}
51262306a36Sopenharmony_ciEXPORT_SYMBOL(ep93xx_pwm_acquire_gpio);
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_civoid ep93xx_pwm_release_gpio(struct platform_device *pdev)
51562306a36Sopenharmony_ci{
51662306a36Sopenharmony_ci	if (pdev->id == 1) {
51762306a36Sopenharmony_ci		gpio_direction_input(EP93XX_GPIO_LINE_EGPIO14);
51862306a36Sopenharmony_ci		gpio_free(EP93XX_GPIO_LINE_EGPIO14);
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_ci		/* EGPIO[14] used for GPIO */
52162306a36Sopenharmony_ci		ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_PONG);
52262306a36Sopenharmony_ci	}
52362306a36Sopenharmony_ci}
52462306a36Sopenharmony_ciEXPORT_SYMBOL(ep93xx_pwm_release_gpio);
52562306a36Sopenharmony_ci
52662306a36Sopenharmony_ci
52762306a36Sopenharmony_ci/*************************************************************************
52862306a36Sopenharmony_ci * EP93xx video peripheral handling
52962306a36Sopenharmony_ci *************************************************************************/
53062306a36Sopenharmony_cistatic struct ep93xxfb_mach_info ep93xxfb_data;
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_cistatic struct resource ep93xx_fb_resource[] = {
53362306a36Sopenharmony_ci	DEFINE_RES_MEM(EP93XX_RASTER_PHYS_BASE, 0x800),
53462306a36Sopenharmony_ci};
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_cistatic struct platform_device ep93xx_fb_device = {
53762306a36Sopenharmony_ci	.name			= "ep93xx-fb",
53862306a36Sopenharmony_ci	.id			= -1,
53962306a36Sopenharmony_ci	.dev			= {
54062306a36Sopenharmony_ci		.platform_data		= &ep93xxfb_data,
54162306a36Sopenharmony_ci		.coherent_dma_mask	= DMA_BIT_MASK(32),
54262306a36Sopenharmony_ci		.dma_mask		= &ep93xx_fb_device.dev.coherent_dma_mask,
54362306a36Sopenharmony_ci	},
54462306a36Sopenharmony_ci	.num_resources		= ARRAY_SIZE(ep93xx_fb_resource),
54562306a36Sopenharmony_ci	.resource		= ep93xx_fb_resource,
54662306a36Sopenharmony_ci};
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci/* The backlight use a single register in the framebuffer's register space */
54962306a36Sopenharmony_ci#define EP93XX_RASTER_REG_BRIGHTNESS 0x20
55062306a36Sopenharmony_ci
55162306a36Sopenharmony_cistatic struct resource ep93xx_bl_resources[] = {
55262306a36Sopenharmony_ci	DEFINE_RES_MEM(EP93XX_RASTER_PHYS_BASE +
55362306a36Sopenharmony_ci		       EP93XX_RASTER_REG_BRIGHTNESS, 0x04),
55462306a36Sopenharmony_ci};
55562306a36Sopenharmony_ci
55662306a36Sopenharmony_cistatic struct platform_device ep93xx_bl_device = {
55762306a36Sopenharmony_ci	.name		= "ep93xx-bl",
55862306a36Sopenharmony_ci	.id		= -1,
55962306a36Sopenharmony_ci	.num_resources	= ARRAY_SIZE(ep93xx_bl_resources),
56062306a36Sopenharmony_ci	.resource	= ep93xx_bl_resources,
56162306a36Sopenharmony_ci};
56262306a36Sopenharmony_ci
56362306a36Sopenharmony_ci/**
56462306a36Sopenharmony_ci * ep93xx_register_fb - Register the framebuffer platform device.
56562306a36Sopenharmony_ci * @data:	platform specific framebuffer configuration (__initdata)
56662306a36Sopenharmony_ci */
56762306a36Sopenharmony_civoid __init ep93xx_register_fb(struct ep93xxfb_mach_info *data)
56862306a36Sopenharmony_ci{
56962306a36Sopenharmony_ci	ep93xxfb_data = *data;
57062306a36Sopenharmony_ci	platform_device_register(&ep93xx_fb_device);
57162306a36Sopenharmony_ci	platform_device_register(&ep93xx_bl_device);
57262306a36Sopenharmony_ci}
57362306a36Sopenharmony_ci
57462306a36Sopenharmony_ci
57562306a36Sopenharmony_ci/*************************************************************************
57662306a36Sopenharmony_ci * EP93xx matrix keypad peripheral handling
57762306a36Sopenharmony_ci *************************************************************************/
57862306a36Sopenharmony_cistatic struct ep93xx_keypad_platform_data ep93xx_keypad_data;
57962306a36Sopenharmony_ci
58062306a36Sopenharmony_cistatic struct resource ep93xx_keypad_resource[] = {
58162306a36Sopenharmony_ci	DEFINE_RES_MEM(EP93XX_KEY_MATRIX_PHYS_BASE, 0x0c),
58262306a36Sopenharmony_ci	DEFINE_RES_IRQ(IRQ_EP93XX_KEY),
58362306a36Sopenharmony_ci};
58462306a36Sopenharmony_ci
58562306a36Sopenharmony_cistatic struct platform_device ep93xx_keypad_device = {
58662306a36Sopenharmony_ci	.name		= "ep93xx-keypad",
58762306a36Sopenharmony_ci	.id		= -1,
58862306a36Sopenharmony_ci	.dev		= {
58962306a36Sopenharmony_ci		.platform_data	= &ep93xx_keypad_data,
59062306a36Sopenharmony_ci	},
59162306a36Sopenharmony_ci	.num_resources	= ARRAY_SIZE(ep93xx_keypad_resource),
59262306a36Sopenharmony_ci	.resource	= ep93xx_keypad_resource,
59362306a36Sopenharmony_ci};
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_ci/**
59662306a36Sopenharmony_ci * ep93xx_register_keypad - Register the keypad platform device.
59762306a36Sopenharmony_ci * @data:	platform specific keypad configuration (__initdata)
59862306a36Sopenharmony_ci */
59962306a36Sopenharmony_civoid __init ep93xx_register_keypad(struct ep93xx_keypad_platform_data *data)
60062306a36Sopenharmony_ci{
60162306a36Sopenharmony_ci	ep93xx_keypad_data = *data;
60262306a36Sopenharmony_ci	platform_device_register(&ep93xx_keypad_device);
60362306a36Sopenharmony_ci}
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_ciint ep93xx_keypad_acquire_gpio(struct platform_device *pdev)
60662306a36Sopenharmony_ci{
60762306a36Sopenharmony_ci	int err;
60862306a36Sopenharmony_ci	int i;
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_ci	for (i = 0; i < 8; i++) {
61162306a36Sopenharmony_ci		err = gpio_request(EP93XX_GPIO_LINE_C(i), dev_name(&pdev->dev));
61262306a36Sopenharmony_ci		if (err)
61362306a36Sopenharmony_ci			goto fail_gpio_c;
61462306a36Sopenharmony_ci		err = gpio_request(EP93XX_GPIO_LINE_D(i), dev_name(&pdev->dev));
61562306a36Sopenharmony_ci		if (err)
61662306a36Sopenharmony_ci			goto fail_gpio_d;
61762306a36Sopenharmony_ci	}
61862306a36Sopenharmony_ci
61962306a36Sopenharmony_ci	/* Enable the keypad controller; GPIO ports C and D used for keypad */
62062306a36Sopenharmony_ci	ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_KEYS |
62162306a36Sopenharmony_ci				 EP93XX_SYSCON_DEVCFG_GONK);
62262306a36Sopenharmony_ci
62362306a36Sopenharmony_ci	return 0;
62462306a36Sopenharmony_ci
62562306a36Sopenharmony_cifail_gpio_d:
62662306a36Sopenharmony_ci	gpio_free(EP93XX_GPIO_LINE_C(i));
62762306a36Sopenharmony_cifail_gpio_c:
62862306a36Sopenharmony_ci	for (--i; i >= 0; --i) {
62962306a36Sopenharmony_ci		gpio_free(EP93XX_GPIO_LINE_C(i));
63062306a36Sopenharmony_ci		gpio_free(EP93XX_GPIO_LINE_D(i));
63162306a36Sopenharmony_ci	}
63262306a36Sopenharmony_ci	return err;
63362306a36Sopenharmony_ci}
63462306a36Sopenharmony_ciEXPORT_SYMBOL(ep93xx_keypad_acquire_gpio);
63562306a36Sopenharmony_ci
63662306a36Sopenharmony_civoid ep93xx_keypad_release_gpio(struct platform_device *pdev)
63762306a36Sopenharmony_ci{
63862306a36Sopenharmony_ci	int i;
63962306a36Sopenharmony_ci
64062306a36Sopenharmony_ci	for (i = 0; i < 8; i++) {
64162306a36Sopenharmony_ci		gpio_free(EP93XX_GPIO_LINE_C(i));
64262306a36Sopenharmony_ci		gpio_free(EP93XX_GPIO_LINE_D(i));
64362306a36Sopenharmony_ci	}
64462306a36Sopenharmony_ci
64562306a36Sopenharmony_ci	/* Disable the keypad controller; GPIO ports C and D used for GPIO */
64662306a36Sopenharmony_ci	ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_KEYS |
64762306a36Sopenharmony_ci			       EP93XX_SYSCON_DEVCFG_GONK);
64862306a36Sopenharmony_ci}
64962306a36Sopenharmony_ciEXPORT_SYMBOL(ep93xx_keypad_release_gpio);
65062306a36Sopenharmony_ci
65162306a36Sopenharmony_ci/*************************************************************************
65262306a36Sopenharmony_ci * EP93xx I2S audio peripheral handling
65362306a36Sopenharmony_ci *************************************************************************/
65462306a36Sopenharmony_cistatic struct resource ep93xx_i2s_resource[] = {
65562306a36Sopenharmony_ci	DEFINE_RES_MEM(EP93XX_I2S_PHYS_BASE, 0x100),
65662306a36Sopenharmony_ci	DEFINE_RES_IRQ(IRQ_EP93XX_SAI),
65762306a36Sopenharmony_ci};
65862306a36Sopenharmony_ci
65962306a36Sopenharmony_cistatic struct platform_device ep93xx_i2s_device = {
66062306a36Sopenharmony_ci	.name		= "ep93xx-i2s",
66162306a36Sopenharmony_ci	.id		= -1,
66262306a36Sopenharmony_ci	.num_resources	= ARRAY_SIZE(ep93xx_i2s_resource),
66362306a36Sopenharmony_ci	.resource	= ep93xx_i2s_resource,
66462306a36Sopenharmony_ci};
66562306a36Sopenharmony_ci
66662306a36Sopenharmony_cistatic struct platform_device ep93xx_pcm_device = {
66762306a36Sopenharmony_ci	.name		= "ep93xx-pcm-audio",
66862306a36Sopenharmony_ci	.id		= -1,
66962306a36Sopenharmony_ci};
67062306a36Sopenharmony_ci
67162306a36Sopenharmony_civoid __init ep93xx_register_i2s(void)
67262306a36Sopenharmony_ci{
67362306a36Sopenharmony_ci	platform_device_register(&ep93xx_i2s_device);
67462306a36Sopenharmony_ci	platform_device_register(&ep93xx_pcm_device);
67562306a36Sopenharmony_ci}
67662306a36Sopenharmony_ci
67762306a36Sopenharmony_ci#define EP93XX_SYSCON_DEVCFG_I2S_MASK	(EP93XX_SYSCON_DEVCFG_I2SONSSP | \
67862306a36Sopenharmony_ci					 EP93XX_SYSCON_DEVCFG_I2SONAC97)
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_ci#define EP93XX_I2SCLKDIV_MASK		(EP93XX_SYSCON_I2SCLKDIV_ORIDE | \
68162306a36Sopenharmony_ci					 EP93XX_SYSCON_I2SCLKDIV_SPOL)
68262306a36Sopenharmony_ci
68362306a36Sopenharmony_ciint ep93xx_i2s_acquire(void)
68462306a36Sopenharmony_ci{
68562306a36Sopenharmony_ci	unsigned val;
68662306a36Sopenharmony_ci
68762306a36Sopenharmony_ci	ep93xx_devcfg_set_clear(EP93XX_SYSCON_DEVCFG_I2SONAC97,
68862306a36Sopenharmony_ci			EP93XX_SYSCON_DEVCFG_I2S_MASK);
68962306a36Sopenharmony_ci
69062306a36Sopenharmony_ci	/*
69162306a36Sopenharmony_ci	 * This is potentially racy with the clock api for i2s_mclk, sclk and
69262306a36Sopenharmony_ci	 * lrclk. Since the i2s driver is the only user of those clocks we
69362306a36Sopenharmony_ci	 * rely on it to prevent parallel use of this function and the
69462306a36Sopenharmony_ci	 * clock api for the i2s clocks.
69562306a36Sopenharmony_ci	 */
69662306a36Sopenharmony_ci	val = __raw_readl(EP93XX_SYSCON_I2SCLKDIV);
69762306a36Sopenharmony_ci	val &= ~EP93XX_I2SCLKDIV_MASK;
69862306a36Sopenharmony_ci	val |= EP93XX_SYSCON_I2SCLKDIV_ORIDE | EP93XX_SYSCON_I2SCLKDIV_SPOL;
69962306a36Sopenharmony_ci	ep93xx_syscon_swlocked_write(val, EP93XX_SYSCON_I2SCLKDIV);
70062306a36Sopenharmony_ci
70162306a36Sopenharmony_ci	return 0;
70262306a36Sopenharmony_ci}
70362306a36Sopenharmony_ciEXPORT_SYMBOL(ep93xx_i2s_acquire);
70462306a36Sopenharmony_ci
70562306a36Sopenharmony_civoid ep93xx_i2s_release(void)
70662306a36Sopenharmony_ci{
70762306a36Sopenharmony_ci	ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_I2S_MASK);
70862306a36Sopenharmony_ci}
70962306a36Sopenharmony_ciEXPORT_SYMBOL(ep93xx_i2s_release);
71062306a36Sopenharmony_ci
71162306a36Sopenharmony_ci/*************************************************************************
71262306a36Sopenharmony_ci * EP93xx AC97 audio peripheral handling
71362306a36Sopenharmony_ci *************************************************************************/
71462306a36Sopenharmony_cistatic struct resource ep93xx_ac97_resources[] = {
71562306a36Sopenharmony_ci	DEFINE_RES_MEM(EP93XX_AAC_PHYS_BASE, 0xac),
71662306a36Sopenharmony_ci	DEFINE_RES_IRQ(IRQ_EP93XX_AACINTR),
71762306a36Sopenharmony_ci};
71862306a36Sopenharmony_ci
71962306a36Sopenharmony_cistatic struct platform_device ep93xx_ac97_device = {
72062306a36Sopenharmony_ci	.name		= "ep93xx-ac97",
72162306a36Sopenharmony_ci	.id		= -1,
72262306a36Sopenharmony_ci	.num_resources	= ARRAY_SIZE(ep93xx_ac97_resources),
72362306a36Sopenharmony_ci	.resource	= ep93xx_ac97_resources,
72462306a36Sopenharmony_ci};
72562306a36Sopenharmony_ci
72662306a36Sopenharmony_civoid __init ep93xx_register_ac97(void)
72762306a36Sopenharmony_ci{
72862306a36Sopenharmony_ci	/*
72962306a36Sopenharmony_ci	 * Make sure that the AC97 pins are not used by I2S.
73062306a36Sopenharmony_ci	 */
73162306a36Sopenharmony_ci	ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_I2SONAC97);
73262306a36Sopenharmony_ci
73362306a36Sopenharmony_ci	platform_device_register(&ep93xx_ac97_device);
73462306a36Sopenharmony_ci	platform_device_register(&ep93xx_pcm_device);
73562306a36Sopenharmony_ci}
73662306a36Sopenharmony_ci
73762306a36Sopenharmony_ci/*************************************************************************
73862306a36Sopenharmony_ci * EP93xx Watchdog
73962306a36Sopenharmony_ci *************************************************************************/
74062306a36Sopenharmony_cistatic struct resource ep93xx_wdt_resources[] = {
74162306a36Sopenharmony_ci	DEFINE_RES_MEM(EP93XX_WATCHDOG_PHYS_BASE, 0x08),
74262306a36Sopenharmony_ci};
74362306a36Sopenharmony_ci
74462306a36Sopenharmony_cistatic struct platform_device ep93xx_wdt_device = {
74562306a36Sopenharmony_ci	.name		= "ep93xx-wdt",
74662306a36Sopenharmony_ci	.id		= -1,
74762306a36Sopenharmony_ci	.num_resources	= ARRAY_SIZE(ep93xx_wdt_resources),
74862306a36Sopenharmony_ci	.resource	= ep93xx_wdt_resources,
74962306a36Sopenharmony_ci};
75062306a36Sopenharmony_ci
75162306a36Sopenharmony_ci/*************************************************************************
75262306a36Sopenharmony_ci * EP93xx IDE
75362306a36Sopenharmony_ci *************************************************************************/
75462306a36Sopenharmony_cistatic struct resource ep93xx_ide_resources[] = {
75562306a36Sopenharmony_ci	DEFINE_RES_MEM(EP93XX_IDE_PHYS_BASE, 0x38),
75662306a36Sopenharmony_ci	DEFINE_RES_IRQ(IRQ_EP93XX_EXT3),
75762306a36Sopenharmony_ci};
75862306a36Sopenharmony_ci
75962306a36Sopenharmony_cistatic struct platform_device ep93xx_ide_device = {
76062306a36Sopenharmony_ci	.name		= "ep93xx-ide",
76162306a36Sopenharmony_ci	.id		= -1,
76262306a36Sopenharmony_ci	.dev		= {
76362306a36Sopenharmony_ci		.dma_mask		= &ep93xx_ide_device.dev.coherent_dma_mask,
76462306a36Sopenharmony_ci		.coherent_dma_mask	= DMA_BIT_MASK(32),
76562306a36Sopenharmony_ci	},
76662306a36Sopenharmony_ci	.num_resources	= ARRAY_SIZE(ep93xx_ide_resources),
76762306a36Sopenharmony_ci	.resource	= ep93xx_ide_resources,
76862306a36Sopenharmony_ci};
76962306a36Sopenharmony_ci
77062306a36Sopenharmony_civoid __init ep93xx_register_ide(void)
77162306a36Sopenharmony_ci{
77262306a36Sopenharmony_ci	platform_device_register(&ep93xx_ide_device);
77362306a36Sopenharmony_ci}
77462306a36Sopenharmony_ci
77562306a36Sopenharmony_ciint ep93xx_ide_acquire_gpio(struct platform_device *pdev)
77662306a36Sopenharmony_ci{
77762306a36Sopenharmony_ci	int err;
77862306a36Sopenharmony_ci	int i;
77962306a36Sopenharmony_ci
78062306a36Sopenharmony_ci	err = gpio_request(EP93XX_GPIO_LINE_EGPIO2, dev_name(&pdev->dev));
78162306a36Sopenharmony_ci	if (err)
78262306a36Sopenharmony_ci		return err;
78362306a36Sopenharmony_ci	err = gpio_request(EP93XX_GPIO_LINE_EGPIO15, dev_name(&pdev->dev));
78462306a36Sopenharmony_ci	if (err)
78562306a36Sopenharmony_ci		goto fail_egpio15;
78662306a36Sopenharmony_ci	for (i = 2; i < 8; i++) {
78762306a36Sopenharmony_ci		err = gpio_request(EP93XX_GPIO_LINE_E(i), dev_name(&pdev->dev));
78862306a36Sopenharmony_ci		if (err)
78962306a36Sopenharmony_ci			goto fail_gpio_e;
79062306a36Sopenharmony_ci	}
79162306a36Sopenharmony_ci	for (i = 4; i < 8; i++) {
79262306a36Sopenharmony_ci		err = gpio_request(EP93XX_GPIO_LINE_G(i), dev_name(&pdev->dev));
79362306a36Sopenharmony_ci		if (err)
79462306a36Sopenharmony_ci			goto fail_gpio_g;
79562306a36Sopenharmony_ci	}
79662306a36Sopenharmony_ci	for (i = 0; i < 8; i++) {
79762306a36Sopenharmony_ci		err = gpio_request(EP93XX_GPIO_LINE_H(i), dev_name(&pdev->dev));
79862306a36Sopenharmony_ci		if (err)
79962306a36Sopenharmony_ci			goto fail_gpio_h;
80062306a36Sopenharmony_ci	}
80162306a36Sopenharmony_ci
80262306a36Sopenharmony_ci	/* GPIO ports E[7:2], G[7:4] and H used by IDE */
80362306a36Sopenharmony_ci	ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_EONIDE |
80462306a36Sopenharmony_ci				 EP93XX_SYSCON_DEVCFG_GONIDE |
80562306a36Sopenharmony_ci				 EP93XX_SYSCON_DEVCFG_HONIDE);
80662306a36Sopenharmony_ci	return 0;
80762306a36Sopenharmony_ci
80862306a36Sopenharmony_cifail_gpio_h:
80962306a36Sopenharmony_ci	for (--i; i >= 0; --i)
81062306a36Sopenharmony_ci		gpio_free(EP93XX_GPIO_LINE_H(i));
81162306a36Sopenharmony_ci	i = 8;
81262306a36Sopenharmony_cifail_gpio_g:
81362306a36Sopenharmony_ci	for (--i; i >= 4; --i)
81462306a36Sopenharmony_ci		gpio_free(EP93XX_GPIO_LINE_G(i));
81562306a36Sopenharmony_ci	i = 8;
81662306a36Sopenharmony_cifail_gpio_e:
81762306a36Sopenharmony_ci	for (--i; i >= 2; --i)
81862306a36Sopenharmony_ci		gpio_free(EP93XX_GPIO_LINE_E(i));
81962306a36Sopenharmony_ci	gpio_free(EP93XX_GPIO_LINE_EGPIO15);
82062306a36Sopenharmony_cifail_egpio15:
82162306a36Sopenharmony_ci	gpio_free(EP93XX_GPIO_LINE_EGPIO2);
82262306a36Sopenharmony_ci	return err;
82362306a36Sopenharmony_ci}
82462306a36Sopenharmony_ciEXPORT_SYMBOL(ep93xx_ide_acquire_gpio);
82562306a36Sopenharmony_ci
82662306a36Sopenharmony_civoid ep93xx_ide_release_gpio(struct platform_device *pdev)
82762306a36Sopenharmony_ci{
82862306a36Sopenharmony_ci	int i;
82962306a36Sopenharmony_ci
83062306a36Sopenharmony_ci	for (i = 2; i < 8; i++)
83162306a36Sopenharmony_ci		gpio_free(EP93XX_GPIO_LINE_E(i));
83262306a36Sopenharmony_ci	for (i = 4; i < 8; i++)
83362306a36Sopenharmony_ci		gpio_free(EP93XX_GPIO_LINE_G(i));
83462306a36Sopenharmony_ci	for (i = 0; i < 8; i++)
83562306a36Sopenharmony_ci		gpio_free(EP93XX_GPIO_LINE_H(i));
83662306a36Sopenharmony_ci	gpio_free(EP93XX_GPIO_LINE_EGPIO15);
83762306a36Sopenharmony_ci	gpio_free(EP93XX_GPIO_LINE_EGPIO2);
83862306a36Sopenharmony_ci
83962306a36Sopenharmony_ci
84062306a36Sopenharmony_ci	/* GPIO ports E[7:2], G[7:4] and H used by GPIO */
84162306a36Sopenharmony_ci	ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_EONIDE |
84262306a36Sopenharmony_ci			       EP93XX_SYSCON_DEVCFG_GONIDE |
84362306a36Sopenharmony_ci			       EP93XX_SYSCON_DEVCFG_HONIDE);
84462306a36Sopenharmony_ci}
84562306a36Sopenharmony_ciEXPORT_SYMBOL(ep93xx_ide_release_gpio);
84662306a36Sopenharmony_ci
84762306a36Sopenharmony_ci/*************************************************************************
84862306a36Sopenharmony_ci * EP93xx ADC
84962306a36Sopenharmony_ci *************************************************************************/
85062306a36Sopenharmony_cistatic struct resource ep93xx_adc_resources[] = {
85162306a36Sopenharmony_ci	DEFINE_RES_MEM(EP93XX_ADC_PHYS_BASE, 0x28),
85262306a36Sopenharmony_ci	DEFINE_RES_IRQ(IRQ_EP93XX_TOUCH),
85362306a36Sopenharmony_ci};
85462306a36Sopenharmony_ci
85562306a36Sopenharmony_cistatic struct platform_device ep93xx_adc_device = {
85662306a36Sopenharmony_ci	.name		= "ep93xx-adc",
85762306a36Sopenharmony_ci	.id		= -1,
85862306a36Sopenharmony_ci	.num_resources	= ARRAY_SIZE(ep93xx_adc_resources),
85962306a36Sopenharmony_ci	.resource	= ep93xx_adc_resources,
86062306a36Sopenharmony_ci};
86162306a36Sopenharmony_ci
86262306a36Sopenharmony_civoid __init ep93xx_register_adc(void)
86362306a36Sopenharmony_ci{
86462306a36Sopenharmony_ci	/* Power up ADC, deactivate Touch Screen Controller */
86562306a36Sopenharmony_ci	ep93xx_devcfg_set_clear(EP93XX_SYSCON_DEVCFG_TIN,
86662306a36Sopenharmony_ci				EP93XX_SYSCON_DEVCFG_ADCPD);
86762306a36Sopenharmony_ci
86862306a36Sopenharmony_ci	platform_device_register(&ep93xx_adc_device);
86962306a36Sopenharmony_ci}
87062306a36Sopenharmony_ci
87162306a36Sopenharmony_ci/*************************************************************************
87262306a36Sopenharmony_ci * EP93xx Security peripheral
87362306a36Sopenharmony_ci *************************************************************************/
87462306a36Sopenharmony_ci
87562306a36Sopenharmony_ci/*
87662306a36Sopenharmony_ci * The Maverick Key is 256 bits of micro fuses blown at the factory during
87762306a36Sopenharmony_ci * manufacturing to uniquely identify a part.
87862306a36Sopenharmony_ci *
87962306a36Sopenharmony_ci * See: http://arm.cirrus.com/forum/viewtopic.php?t=486&highlight=maverick+key
88062306a36Sopenharmony_ci */
88162306a36Sopenharmony_ci#define EP93XX_SECURITY_REG(x)		(EP93XX_SECURITY_BASE + (x))
88262306a36Sopenharmony_ci#define EP93XX_SECURITY_SECFLG		EP93XX_SECURITY_REG(0x2400)
88362306a36Sopenharmony_ci#define EP93XX_SECURITY_FUSEFLG		EP93XX_SECURITY_REG(0x2410)
88462306a36Sopenharmony_ci#define EP93XX_SECURITY_UNIQID		EP93XX_SECURITY_REG(0x2440)
88562306a36Sopenharmony_ci#define EP93XX_SECURITY_UNIQCHK		EP93XX_SECURITY_REG(0x2450)
88662306a36Sopenharmony_ci#define EP93XX_SECURITY_UNIQVAL		EP93XX_SECURITY_REG(0x2460)
88762306a36Sopenharmony_ci#define EP93XX_SECURITY_SECID1		EP93XX_SECURITY_REG(0x2500)
88862306a36Sopenharmony_ci#define EP93XX_SECURITY_SECID2		EP93XX_SECURITY_REG(0x2504)
88962306a36Sopenharmony_ci#define EP93XX_SECURITY_SECCHK1		EP93XX_SECURITY_REG(0x2520)
89062306a36Sopenharmony_ci#define EP93XX_SECURITY_SECCHK2		EP93XX_SECURITY_REG(0x2524)
89162306a36Sopenharmony_ci#define EP93XX_SECURITY_UNIQID2		EP93XX_SECURITY_REG(0x2700)
89262306a36Sopenharmony_ci#define EP93XX_SECURITY_UNIQID3		EP93XX_SECURITY_REG(0x2704)
89362306a36Sopenharmony_ci#define EP93XX_SECURITY_UNIQID4		EP93XX_SECURITY_REG(0x2708)
89462306a36Sopenharmony_ci#define EP93XX_SECURITY_UNIQID5		EP93XX_SECURITY_REG(0x270c)
89562306a36Sopenharmony_ci
89662306a36Sopenharmony_cistatic char ep93xx_soc_id[33];
89762306a36Sopenharmony_ci
89862306a36Sopenharmony_cistatic const char __init *ep93xx_get_soc_id(void)
89962306a36Sopenharmony_ci{
90062306a36Sopenharmony_ci	unsigned int id, id2, id3, id4, id5;
90162306a36Sopenharmony_ci
90262306a36Sopenharmony_ci	if (__raw_readl(EP93XX_SECURITY_UNIQVAL) != 1)
90362306a36Sopenharmony_ci		return "bad Hamming code";
90462306a36Sopenharmony_ci
90562306a36Sopenharmony_ci	id = __raw_readl(EP93XX_SECURITY_UNIQID);
90662306a36Sopenharmony_ci	id2 = __raw_readl(EP93XX_SECURITY_UNIQID2);
90762306a36Sopenharmony_ci	id3 = __raw_readl(EP93XX_SECURITY_UNIQID3);
90862306a36Sopenharmony_ci	id4 = __raw_readl(EP93XX_SECURITY_UNIQID4);
90962306a36Sopenharmony_ci	id5 = __raw_readl(EP93XX_SECURITY_UNIQID5);
91062306a36Sopenharmony_ci
91162306a36Sopenharmony_ci	if (id != id2)
91262306a36Sopenharmony_ci		return "invalid";
91362306a36Sopenharmony_ci
91462306a36Sopenharmony_ci	/* Toss the unique ID into the entropy pool */
91562306a36Sopenharmony_ci	add_device_randomness(&id2, 4);
91662306a36Sopenharmony_ci	add_device_randomness(&id3, 4);
91762306a36Sopenharmony_ci	add_device_randomness(&id4, 4);
91862306a36Sopenharmony_ci	add_device_randomness(&id5, 4);
91962306a36Sopenharmony_ci
92062306a36Sopenharmony_ci	snprintf(ep93xx_soc_id, sizeof(ep93xx_soc_id),
92162306a36Sopenharmony_ci		 "%08x%08x%08x%08x", id2, id3, id4, id5);
92262306a36Sopenharmony_ci
92362306a36Sopenharmony_ci	return ep93xx_soc_id;
92462306a36Sopenharmony_ci}
92562306a36Sopenharmony_ci
92662306a36Sopenharmony_cistatic const char __init *ep93xx_get_soc_rev(void)
92762306a36Sopenharmony_ci{
92862306a36Sopenharmony_ci	int rev = ep93xx_chip_revision();
92962306a36Sopenharmony_ci
93062306a36Sopenharmony_ci	switch (rev) {
93162306a36Sopenharmony_ci	case EP93XX_CHIP_REV_D0:
93262306a36Sopenharmony_ci		return "D0";
93362306a36Sopenharmony_ci	case EP93XX_CHIP_REV_D1:
93462306a36Sopenharmony_ci		return "D1";
93562306a36Sopenharmony_ci	case EP93XX_CHIP_REV_E0:
93662306a36Sopenharmony_ci		return "E0";
93762306a36Sopenharmony_ci	case EP93XX_CHIP_REV_E1:
93862306a36Sopenharmony_ci		return "E1";
93962306a36Sopenharmony_ci	case EP93XX_CHIP_REV_E2:
94062306a36Sopenharmony_ci		return "E2";
94162306a36Sopenharmony_ci	default:
94262306a36Sopenharmony_ci		return "unknown";
94362306a36Sopenharmony_ci	}
94462306a36Sopenharmony_ci}
94562306a36Sopenharmony_ci
94662306a36Sopenharmony_cistatic const char __init *ep93xx_get_machine_name(void)
94762306a36Sopenharmony_ci{
94862306a36Sopenharmony_ci	return kasprintf(GFP_KERNEL,"%s", machine_desc->name);
94962306a36Sopenharmony_ci}
95062306a36Sopenharmony_ci
95162306a36Sopenharmony_cistatic struct device __init *ep93xx_init_soc(void)
95262306a36Sopenharmony_ci{
95362306a36Sopenharmony_ci	struct soc_device_attribute *soc_dev_attr;
95462306a36Sopenharmony_ci	struct soc_device *soc_dev;
95562306a36Sopenharmony_ci
95662306a36Sopenharmony_ci	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
95762306a36Sopenharmony_ci	if (!soc_dev_attr)
95862306a36Sopenharmony_ci		return NULL;
95962306a36Sopenharmony_ci
96062306a36Sopenharmony_ci	soc_dev_attr->machine = ep93xx_get_machine_name();
96162306a36Sopenharmony_ci	soc_dev_attr->family = "Cirrus Logic EP93xx";
96262306a36Sopenharmony_ci	soc_dev_attr->revision = ep93xx_get_soc_rev();
96362306a36Sopenharmony_ci	soc_dev_attr->soc_id = ep93xx_get_soc_id();
96462306a36Sopenharmony_ci
96562306a36Sopenharmony_ci	soc_dev = soc_device_register(soc_dev_attr);
96662306a36Sopenharmony_ci	if (IS_ERR(soc_dev)) {
96762306a36Sopenharmony_ci		kfree(soc_dev_attr->machine);
96862306a36Sopenharmony_ci		kfree(soc_dev_attr);
96962306a36Sopenharmony_ci		return NULL;
97062306a36Sopenharmony_ci	}
97162306a36Sopenharmony_ci
97262306a36Sopenharmony_ci	return soc_device_to_device(soc_dev);
97362306a36Sopenharmony_ci}
97462306a36Sopenharmony_ci
97562306a36Sopenharmony_cistruct device __init *ep93xx_init_devices(void)
97662306a36Sopenharmony_ci{
97762306a36Sopenharmony_ci	struct device *parent;
97862306a36Sopenharmony_ci
97962306a36Sopenharmony_ci	/* Disallow access to MaverickCrunch initially */
98062306a36Sopenharmony_ci	ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA);
98162306a36Sopenharmony_ci
98262306a36Sopenharmony_ci	/* Default all ports to GPIO */
98362306a36Sopenharmony_ci	ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_KEYS |
98462306a36Sopenharmony_ci			       EP93XX_SYSCON_DEVCFG_GONK |
98562306a36Sopenharmony_ci			       EP93XX_SYSCON_DEVCFG_EONIDE |
98662306a36Sopenharmony_ci			       EP93XX_SYSCON_DEVCFG_GONIDE |
98762306a36Sopenharmony_ci			       EP93XX_SYSCON_DEVCFG_HONIDE);
98862306a36Sopenharmony_ci
98962306a36Sopenharmony_ci	parent = ep93xx_init_soc();
99062306a36Sopenharmony_ci
99162306a36Sopenharmony_ci	/* Get the GPIO working early, other devices need it */
99262306a36Sopenharmony_ci	platform_device_register(&ep93xx_gpio_device);
99362306a36Sopenharmony_ci
99462306a36Sopenharmony_ci	amba_device_register(&uart1_device, &iomem_resource);
99562306a36Sopenharmony_ci	amba_device_register(&uart2_device, &iomem_resource);
99662306a36Sopenharmony_ci	amba_device_register(&uart3_device, &iomem_resource);
99762306a36Sopenharmony_ci
99862306a36Sopenharmony_ci	platform_device_register(&ep93xx_rtc_device);
99962306a36Sopenharmony_ci	platform_device_register(&ep93xx_ohci_device);
100062306a36Sopenharmony_ci	platform_device_register(&ep93xx_wdt_device);
100162306a36Sopenharmony_ci
100262306a36Sopenharmony_ci	gpiod_add_lookup_table(&ep93xx_leds_gpio_table);
100362306a36Sopenharmony_ci	gpio_led_register_device(-1, &ep93xx_led_data);
100462306a36Sopenharmony_ci
100562306a36Sopenharmony_ci	return parent;
100662306a36Sopenharmony_ci}
100762306a36Sopenharmony_ci
100862306a36Sopenharmony_civoid ep93xx_restart(enum reboot_mode mode, const char *cmd)
100962306a36Sopenharmony_ci{
101062306a36Sopenharmony_ci	/*
101162306a36Sopenharmony_ci	 * Set then clear the SWRST bit to initiate a software reset
101262306a36Sopenharmony_ci	 */
101362306a36Sopenharmony_ci	ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_SWRST);
101462306a36Sopenharmony_ci	ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_SWRST);
101562306a36Sopenharmony_ci
101662306a36Sopenharmony_ci	while (1)
101762306a36Sopenharmony_ci		;
101862306a36Sopenharmony_ci}
1019