ARC: [plat-arcfpga]: Enabling DeviceTree for Angel4 board
* arc-uart platform device now populated dynamically, using of_platform_populate() - applies to any other device whatsoever. * uart in turn requires incore arc-intc to be also present in DT * A irq-domain needs to be instantiated for IRQ requests by DT probed device (e.g. arc-uart) TODO: switch over to linear irq domain once all devs have been transitioned to DT Signed-off-by: Vineet Gupta <vgupta@synopsys.com> Cc: Grant Likely <grant.likely@secretlab.ca> Cc: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Родитель
450dd430bf
Коммит
abe11ddea1
|
@ -0,0 +1,24 @@
|
||||||
|
* ARC700 incore Interrupt Controller
|
||||||
|
|
||||||
|
The core interrupt controller provides 32 prioritised interrupts (2 levels)
|
||||||
|
to ARC700 core.
|
||||||
|
|
||||||
|
Properties:
|
||||||
|
|
||||||
|
- compatible: "snps,arc700-intc"
|
||||||
|
- interrupt-controller: This is an interrupt controller.
|
||||||
|
- #interrupt-cells: Must be <1>.
|
||||||
|
|
||||||
|
Single Cell "interrupts" property of a device specifies the IRQ number
|
||||||
|
between 0 to 31
|
||||||
|
|
||||||
|
intc accessed via the special ARC AUX register interface, hence "reg" property
|
||||||
|
is not specified.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
intc: interrupt-controller {
|
||||||
|
compatible = "snps,arc700-intc";
|
||||||
|
interrupt-controller;
|
||||||
|
#interrupt-cells = <1>;
|
||||||
|
};
|
|
@ -1,5 +1,5 @@
|
||||||
# Built-in dtb
|
# Built-in dtb
|
||||||
builtindtb-y := skeleton
|
builtindtb-y := angel4
|
||||||
|
|
||||||
ifneq ($(CONFIG_ARC_BUILTIN_DTB_NAME),"")
|
ifneq ($(CONFIG_ARC_BUILTIN_DTB_NAME),"")
|
||||||
builtindtb-y := $(patsubst "%",%,$(CONFIG_ARC_BUILTIN_DTB_NAME))
|
builtindtb-y := $(patsubst "%",%,$(CONFIG_ARC_BUILTIN_DTB_NAME))
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2012 Synopsys, Inc. (www.synopsys.com)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
/dts-v1/;
|
||||||
|
|
||||||
|
/include/ "skeleton.dtsi"
|
||||||
|
|
||||||
|
/ {
|
||||||
|
compatible = "snps,arc-angel4";
|
||||||
|
clock-frequency = <80000000>; /* 80 MHZ */
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
interrupt-parent = <&intc>;
|
||||||
|
|
||||||
|
chosen {
|
||||||
|
bootargs = "console=ttyARC0,115200n8";
|
||||||
|
};
|
||||||
|
|
||||||
|
aliases {
|
||||||
|
serial0 = &arcuart0;
|
||||||
|
};
|
||||||
|
|
||||||
|
memory {
|
||||||
|
device_type = "memory";
|
||||||
|
reg = <0x00000000 0x10000000>; /* 256M */
|
||||||
|
};
|
||||||
|
|
||||||
|
fpga {
|
||||||
|
compatible = "simple-bus";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
|
||||||
|
/* child and parent address space 1:1 mapped */
|
||||||
|
ranges;
|
||||||
|
|
||||||
|
intc: interrupt-controller {
|
||||||
|
compatible = "snps,arc700-intc";
|
||||||
|
interrupt-controller;
|
||||||
|
#interrupt-cells = <1>;
|
||||||
|
};
|
||||||
|
|
||||||
|
arcuart0: serial@c0fc1000 {
|
||||||
|
compatible = "snps,arc-uart";
|
||||||
|
reg = <0xc0fc1000 0x100>;
|
||||||
|
interrupts = <5>;
|
||||||
|
clock-frequency = <80000000>;
|
||||||
|
baud = <115200>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
|
@ -18,6 +18,18 @@
|
||||||
#size-cells = <1>;
|
#size-cells = <1>;
|
||||||
chosen { };
|
chosen { };
|
||||||
aliases { };
|
aliases { };
|
||||||
|
|
||||||
|
cpus {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
cpu@0 {
|
||||||
|
device_type = "cpu";
|
||||||
|
compatible = "snps,arc770d";
|
||||||
|
reg = <0>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
memory {
|
memory {
|
||||||
device_type = "memory";
|
device_type = "memory";
|
||||||
reg = <0x00000000 0x10000000>; /* 256M */
|
reg = <0x00000000 0x10000000>; /* 256M */
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
|
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/irqdomain.h>
|
||||||
#include <asm/sections.h>
|
#include <asm/sections.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
|
|
||||||
|
@ -59,16 +61,40 @@ static struct irq_chip onchip_intc = {
|
||||||
.irq_unmask = arc_unmask_irq,
|
.irq_unmask = arc_unmask_irq,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int arc_intc_domain_map(struct irq_domain *d, unsigned int irq,
|
||||||
|
irq_hw_number_t hw)
|
||||||
|
{
|
||||||
|
if (irq == TIMER0_IRQ)
|
||||||
|
irq_set_chip_and_handler(irq, &onchip_intc, handle_percpu_irq);
|
||||||
|
else
|
||||||
|
irq_set_chip_and_handler(irq, &onchip_intc, handle_level_irq);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct irq_domain_ops arc_intc_domain_ops = {
|
||||||
|
.xlate = irq_domain_xlate_onecell,
|
||||||
|
.map = arc_intc_domain_map,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct irq_domain *root_domain;
|
||||||
|
|
||||||
void __init init_onchip_IRQ(void)
|
void __init init_onchip_IRQ(void)
|
||||||
{
|
{
|
||||||
int i;
|
struct device_node *intc = NULL;
|
||||||
|
|
||||||
for (i = 0; i < NR_IRQS; i++)
|
intc = of_find_compatible_node(NULL, NULL, "snps,arc700-intc");
|
||||||
irq_set_chip_and_handler(i, &onchip_intc, handle_level_irq);
|
if(!intc)
|
||||||
|
panic("DeviceTree Missing incore intc\n");
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
root_domain = irq_domain_add_legacy(intc, NR_IRQS, 0, 0,
|
||||||
irq_set_chip_and_handler(TIMER0_IRQ, &onchip_intc, handle_percpu_irq);
|
&arc_intc_domain_ops, NULL);
|
||||||
#endif
|
|
||||||
|
if (!root_domain)
|
||||||
|
panic("root irq domain not avail\n");
|
||||||
|
|
||||||
|
/* with this we don't need to export root_domain */
|
||||||
|
irq_set_default_host(root_domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/console.h>
|
#include <linux/console.h>
|
||||||
|
#include <linux/of_platform.h>
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
#include <asm/clk.h>
|
#include <asm/clk.h>
|
||||||
|
@ -20,58 +21,56 @@
|
||||||
|
|
||||||
/*----------------------- Platform Devices -----------------------------*/
|
/*----------------------- Platform Devices -----------------------------*/
|
||||||
|
|
||||||
#if defined(CONFIG_SERIAL_ARC) || defined(CONFIG_SERIAL_ARC_MODULE)
|
|
||||||
|
|
||||||
static unsigned long arc_uart_info[] = {
|
static unsigned long arc_uart_info[] = {
|
||||||
CONFIG_ARC_SERIAL_BAUD, /* uart->baud */
|
0, /* uart->is_emulated (runtime @running_on_hw) */
|
||||||
-1, /* uart->port.uartclk */
|
0, /* uart->port.uartclk */
|
||||||
-1, /* uart->is_emulated (runtime @running_on_hw) */
|
0, /* uart->baud */
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ARC_UART_DEV(n) \
|
#if defined(CONFIG_SERIAL_ARC_CONSOLE)
|
||||||
\
|
/*
|
||||||
static struct resource arc_uart##n##_res[] = { \
|
* static platform data - but only for early serial
|
||||||
{ \
|
* TBD: derive this from a special DT node
|
||||||
.start = UART##n##_BASE, \
|
*/
|
||||||
.end = UART##n##_BASE + 0xFF, \
|
static struct resource arc_uart0_res[] = {
|
||||||
.flags = IORESOURCE_MEM, \
|
{
|
||||||
}, \
|
.start = UART0_BASE,
|
||||||
{ \
|
.end = UART0_BASE + 0xFF,
|
||||||
.start = UART##n##_IRQ, \
|
.flags = IORESOURCE_MEM,
|
||||||
.end = UART##n##_IRQ, \
|
},
|
||||||
.flags = IORESOURCE_IRQ, \
|
{
|
||||||
}, \
|
.start = UART0_IRQ,
|
||||||
}; \
|
.end = UART0_IRQ,
|
||||||
\
|
.flags = IORESOURCE_IRQ,
|
||||||
static struct platform_device arc_uart##n##_dev = { \
|
},
|
||||||
.name = "arc-uart", \
|
};
|
||||||
.id = n, \
|
|
||||||
.num_resources = ARRAY_SIZE(arc_uart##n##_res), \
|
|
||||||
.resource = arc_uart##n##_res, \
|
|
||||||
.dev = { \
|
|
||||||
.platform_data = &arc_uart_info, \
|
|
||||||
}, \
|
|
||||||
}
|
|
||||||
|
|
||||||
ARC_UART_DEV(0);
|
static struct platform_device arc_uart0_dev = {
|
||||||
#if CONFIG_SERIAL_ARC_NR_PORTS > 1
|
.name = "arc-uart",
|
||||||
ARC_UART_DEV(1);
|
.id = 0,
|
||||||
#endif
|
.num_resources = ARRAY_SIZE(arc_uart0_res),
|
||||||
|
.resource = arc_uart0_res,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &arc_uart_info,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
static struct platform_device *fpga_early_devs[] __initdata = {
|
static struct platform_device *fpga_early_devs[] __initdata = {
|
||||||
#if defined(CONFIG_SERIAL_ARC_CONSOLE)
|
|
||||||
&arc_uart0_dev,
|
&arc_uart0_dev,
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
static void arc_fpga_serial_init(void)
|
static void arc_fpga_serial_init(void)
|
||||||
{
|
{
|
||||||
|
/* To let driver workaround ISS bug: baudh Reg can't be set to 0 */
|
||||||
|
arc_uart_info[0] = !running_on_hw;
|
||||||
|
|
||||||
arc_uart_info[1] = arc_get_core_freq();
|
arc_uart_info[1] = arc_get_core_freq();
|
||||||
|
|
||||||
/* To let driver workaround ISS bug: baudh Reg can't be set to 0 */
|
arc_uart_info[2] = CONFIG_ARC_SERIAL_BAUD;
|
||||||
arc_uart_info[2] = !running_on_hw;
|
|
||||||
|
|
||||||
|
#if defined(CONFIG_SERIAL_ARC_CONSOLE)
|
||||||
early_platform_add_devices(fpga_early_devs,
|
early_platform_add_devices(fpga_early_devs,
|
||||||
ARRAY_SIZE(fpga_early_devs));
|
ARRAY_SIZE(fpga_early_devs));
|
||||||
|
|
||||||
|
@ -97,16 +96,9 @@ static void arc_fpga_serial_init(void)
|
||||||
* otherwise the early console never gets a chance to run.
|
* otherwise the early console never gets a chance to run.
|
||||||
*/
|
*/
|
||||||
add_preferred_console("ttyARC", 0, "115200");
|
add_preferred_console("ttyARC", 0, "115200");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static void arc_fpga_serial_init(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* CONFIG_SERIAL_ARC */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Early Platform Initialization called from setup_arch()
|
* Early Platform Initialization called from setup_arch()
|
||||||
*/
|
*/
|
||||||
|
@ -117,20 +109,23 @@ void __init arc_platform_early_init(void)
|
||||||
arc_fpga_serial_init();
|
arc_fpga_serial_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_device *fpga_devs[] __initdata = {
|
static struct of_dev_auxdata plat_auxdata_lookup[] __initdata = {
|
||||||
#if defined(CONFIG_SERIAL_ARC) || defined(CONFIG_SERIAL_ARC_MODULE)
|
#if defined(CONFIG_SERIAL_ARC) || defined(CONFIG_SERIAL_ARC_MODULE)
|
||||||
&arc_uart0_dev,
|
OF_DEV_AUXDATA("snps,arc-uart", UART0_BASE, "arc-uart", arc_uart_info),
|
||||||
#if CONFIG_SERIAL_ARC_NR_PORTS > 1
|
|
||||||
&arc_uart1_dev,
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
int __init fpga_plat_init(void)
|
int __init fpga_plat_init(void)
|
||||||
{
|
{
|
||||||
pr_info("[plat-arcfpga]: registering device resources\n");
|
pr_info("[plat-arcfpga]: registering device resources\n");
|
||||||
|
|
||||||
platform_add_devices(fpga_devs, ARRAY_SIZE(fpga_devs));
|
/*
|
||||||
|
* Traverses flattened DeviceTree - registering platform devices
|
||||||
|
* complete with their resources
|
||||||
|
*/
|
||||||
|
of_platform_populate(NULL, of_default_bus_match_table,
|
||||||
|
plat_auxdata_lookup, NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче