/*
* arch/arm/plat-orion/common.c
*
* Marvell Orion SoC common setup code used by multiple mach-/common.c
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/serial_8250.h>
#include <linux/ata_platform.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/mv643xx_eth.h>
#include <linux/mv643xx_i2c.h>
#include <net/dsa.h>
#include <plat/mv_xor.h>
#include <plat/ehci-orion.h>
#include <mach/bridge-regs.h>
/* Create a clkdev entry for a given device/clk */
void __init orion_clkdev_add(const char *con_id, const char *dev_id,
struct clk *clk)
{
struct clk_lookup *cl;
cl = clkdev_alloc(clk, con_id, dev_id);
if (cl)
clkdev_add(cl);
}
/* Create clkdev entries for all orion platforms except kirkwood.
Kirkwood has gated clocks for some of its peripherals, so creates
its own clkdev entries. For all the other orion devices, create
clkdev entries to the tclk. */
void __init orion_clkdev_init(struct clk *tclk)
{
orion_clkdev_add(NULL, "orion_spi.0", tclk);
orion_clkdev_add(NULL, "orion_spi.1", tclk);
orion_clkdev_add(NULL, MV643XX_ETH_NAME ".0", tclk);
orion_clkdev_add(NULL, MV643XX_ETH_NAME ".1", tclk);
orion_clkdev_add(NULL, MV643XX_ETH_NAME ".2", tclk);
orion_clkdev_add(NULL, MV643XX_ETH_NAME ".3", tclk);
orion_clkdev_add(NULL, "orion_wdt", tclk);
}
/* Fill in the resources structure and link it into the platform
device structure. There is always a memory region, and nearly
always an interrupt.*/
static void fill_resources(struct platform_device *device,
struct resource *resources,
resource_size_t mapbase,
resource_size_t size,
unsigned int irq)
{
device->resource = resources;
device->num_resources = 1;
resources[0].flags = IORESOURCE_MEM;
resources[0].start = mapbase;
resources[0].end = mapbase + size;
if (irq != NO_IRQ) {
device->num_resources++;
resources[1].flags = IORESOURCE_IRQ;
resources[1].start = irq;
resources[1].end = irq;
}
}
/*****************************************************************************
* UART
****************************************************************************/
static unsigned long __init uart_get_clk_rate(struct clk *clk)
{
clk_prepare_enable(clk);
return clk_get_rate(clk);
}
static void __init uart_complete(
struct platform_device *orion_uart,
struct plat_serial8250_port *data,
struct resource *resources,
unsigned int membase,
resource_size_t mapbase,
unsigned int irq,
struct clk *clk)
{
data->mapbase = mapbase;
data->membase = (void __iomem *)membase;
data->irq = irq;
data->uartclk = uart_get_clk_rate(clk);
orion_uart->dev.platform_data = data;
fill_resources(orion_uart, resources, mapbase, 0xff, irq);
platform_device_register(orion_uart);
}
/*****************************************************************************
* UART0
****************************************************************************/
static struct plat_serial8250_port orion_uart0_data[] = {
{
.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
}, {
},
};
static struct resource orion_uart0_resources[2];
static struct platform_device orion_uart0 = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
};
void __init orion_uart0_init(unsigned int membase,
resource_size_t mapbase,
unsigned int irq,
struct clk *clk)
{
uart_complete(&orion_uart0, orion_uart0_data, orion_uart0_resources,
membase, mapbase, irq, clk);
}
/*****************************************************************************
* UART1
****************************************************************************/
static struct plat_serial8250_port orion_uart1_data[] = {
{
.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
}, {
},
};
static struct resource orion_uart1_resources[2];
static struct platform_device orion_uart1 = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM1,
};
void __init orion_uart1_init(unsigned int membase,
resource_size_t mapbase,
unsigned int irq,
struct clk *clk)
{
uart_complete(&orion_uart1, orion_uart1_data, orion_uart1_resources,
membase, mapbase, irq, clk);
}
/*****************************************************************************
* UART2
****************************************************************************/
static struct plat_serial8250_port orion_uart2_data[] = {
{