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:
Vineet Gupta 2013-01-18 15:12:21 +05:30
Родитель 450dd430bf
Коммит abe11ddea1
6 изменённых файлов: 170 добавлений и 58 удалений

Просмотреть файл

@ -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;
} }