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:
		
					parent
					
						
							
								450dd430bf
							
						
					
				
			
			
				commit
				
					
						abe11ddea1
					
				
			
		
					 6 changed files with 170 additions and 58 deletions
				
			
		
							
								
								
									
										24
									
								
								Documentation/devicetree/bindings/arc/interrupts.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								Documentation/devicetree/bindings/arc/interrupts.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
 | 
			
		||||
builtindtb-y		:= skeleton
 | 
			
		||||
builtindtb-y		:= angel4
 | 
			
		||||
 | 
			
		||||
ifneq ($(CONFIG_ARC_BUILTIN_DTB_NAME),"")
 | 
			
		||||
	builtindtb-y	:= $(patsubst "%",%,$(CONFIG_ARC_BUILTIN_DTB_NAME))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										55
									
								
								arch/arc/boot/dts/angel4.dts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								arch/arc/boot/dts/angel4.dts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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>;
 | 
			
		||||
	chosen { };
 | 
			
		||||
	aliases { };
 | 
			
		||||
 | 
			
		||||
	cpus {
 | 
			
		||||
		#address-cells = <1>;
 | 
			
		||||
		#size-cells = <0>;
 | 
			
		||||
 | 
			
		||||
		cpu@0 {
 | 
			
		||||
			device_type = "cpu";
 | 
			
		||||
			compatible = "snps,arc770d";
 | 
			
		||||
			reg = <0>;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	memory {
 | 
			
		||||
		device_type = "memory";
 | 
			
		||||
		reg = <0x00000000 0x10000000>;	/* 256M */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,6 +9,8 @@
 | 
			
		|||
 | 
			
		||||
#include <linux/interrupt.h>
 | 
			
		||||
#include <linux/module.h>
 | 
			
		||||
#include <linux/of.h>
 | 
			
		||||
#include <linux/irqdomain.h>
 | 
			
		||||
#include <asm/sections.h>
 | 
			
		||||
#include <asm/irq.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -59,16 +61,40 @@ static struct irq_chip onchip_intc = {
 | 
			
		|||
	.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)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	struct device_node *intc = NULL;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < NR_IRQS; i++)
 | 
			
		||||
		irq_set_chip_and_handler(i, &onchip_intc, handle_level_irq);
 | 
			
		||||
	intc = of_find_compatible_node(NULL, NULL, "snps,arc700-intc");
 | 
			
		||||
	if(!intc)
 | 
			
		||||
		panic("DeviceTree Missing incore intc\n");
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_SMP
 | 
			
		||||
	irq_set_chip_and_handler(TIMER0_IRQ, &onchip_intc, handle_percpu_irq);
 | 
			
		||||
#endif
 | 
			
		||||
	root_domain = irq_domain_add_legacy(intc, NR_IRQS, 0, 0,
 | 
			
		||||
					    &arc_intc_domain_ops, NULL);
 | 
			
		||||
 | 
			
		||||
	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/platform_device.h>
 | 
			
		||||
#include <linux/console.h>
 | 
			
		||||
#include <linux/of_platform.h>
 | 
			
		||||
#include <asm/setup.h>
 | 
			
		||||
#include <asm/irq.h>
 | 
			
		||||
#include <asm/clk.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -20,58 +21,56 @@
 | 
			
		|||
 | 
			
		||||
/*----------------------- Platform Devices -----------------------------*/
 | 
			
		||||
 | 
			
		||||
#if defined(CONFIG_SERIAL_ARC) || defined(CONFIG_SERIAL_ARC_MODULE)
 | 
			
		||||
 | 
			
		||||
static unsigned long arc_uart_info[] = {
 | 
			
		||||
	CONFIG_ARC_SERIAL_BAUD,	/* uart->baud */
 | 
			
		||||
	-1,			/* uart->port.uartclk */
 | 
			
		||||
	-1,			/* uart->is_emulated (runtime @running_on_hw) */
 | 
			
		||||
	0,	/* uart->is_emulated (runtime @running_on_hw) */
 | 
			
		||||
	0,	/* uart->port.uartclk */
 | 
			
		||||
	0,	/* uart->baud */
 | 
			
		||||
	0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define ARC_UART_DEV(n)					\
 | 
			
		||||
							\
 | 
			
		||||
static struct resource arc_uart##n##_res[] = {		\
 | 
			
		||||
	{						\
 | 
			
		||||
		.start = UART##n##_BASE,			\
 | 
			
		||||
		.end   = UART##n##_BASE + 0xFF,		\
 | 
			
		||||
		.flags = IORESOURCE_MEM,		\
 | 
			
		||||
	},						\
 | 
			
		||||
	{						\
 | 
			
		||||
		.start = UART##n##_IRQ,			\
 | 
			
		||||
		.end   = UART##n##_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,	\
 | 
			
		||||
	},						\
 | 
			
		||||
}
 | 
			
		||||
#if defined(CONFIG_SERIAL_ARC_CONSOLE)
 | 
			
		||||
/*
 | 
			
		||||
 * static platform data - but only for early serial
 | 
			
		||||
 * TBD: derive this from a special DT node
 | 
			
		||||
 */
 | 
			
		||||
static struct resource arc_uart0_res[] = {
 | 
			
		||||
	{
 | 
			
		||||
		.start = UART0_BASE,
 | 
			
		||||
		.end   = UART0_BASE + 0xFF,
 | 
			
		||||
		.flags = IORESOURCE_MEM,
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		.start = UART0_IRQ,
 | 
			
		||||
		.end   = UART0_IRQ,
 | 
			
		||||
		.flags = IORESOURCE_IRQ,
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ARC_UART_DEV(0);
 | 
			
		||||
#if CONFIG_SERIAL_ARC_NR_PORTS > 1
 | 
			
		||||
ARC_UART_DEV(1);
 | 
			
		||||
#endif
 | 
			
		||||
static struct platform_device arc_uart0_dev = {
 | 
			
		||||
	.name = "arc-uart",
 | 
			
		||||
	.id = 0,
 | 
			
		||||
	.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 = {
 | 
			
		||||
#if defined(CONFIG_SERIAL_ARC_CONSOLE)
 | 
			
		||||
	&arc_uart0_dev,
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
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();
 | 
			
		||||
 | 
			
		||||
	/* To let driver workaround ISS bug: baudh Reg can't be set to 0 */
 | 
			
		||||
	arc_uart_info[2] = !running_on_hw;
 | 
			
		||||
	arc_uart_info[2] = CONFIG_ARC_SERIAL_BAUD;
 | 
			
		||||
 | 
			
		||||
#if defined(CONFIG_SERIAL_ARC_CONSOLE)
 | 
			
		||||
	early_platform_add_devices(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.
 | 
			
		||||
	 */
 | 
			
		||||
	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()
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -117,20 +109,23 @@ void __init arc_platform_early_init(void)
 | 
			
		|||
	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)
 | 
			
		||||
	&arc_uart0_dev,
 | 
			
		||||
#if CONFIG_SERIAL_ARC_NR_PORTS > 1
 | 
			
		||||
	&arc_uart1_dev,
 | 
			
		||||
#endif
 | 
			
		||||
	OF_DEV_AUXDATA("snps,arc-uart", UART0_BASE, "arc-uart", arc_uart_info),
 | 
			
		||||
#endif
 | 
			
		||||
	{}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int __init fpga_plat_init(void)
 | 
			
		||||
{
 | 
			
		||||
	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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue