Skip to content

BCM2708: Add core Device Tree support #634

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 9, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions arch/arm/boot/dts/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ dtb-$(CONFIG_ARCH_AT91) += sama5d35ek.dtb
dtb-$(CONFIG_ARCH_AT91) += sama5d36ek.dtb

dtb-$(CONFIG_ARCH_ATLAS6) += atlas6-evb.dtb
dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b.dtb
dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
dtb-$(CONFIG_ARCH_BCM_5301X) += bcm4708-netgear-r6250.dtb
dtb-$(CONFIG_ARCH_BCM_MOBILE) += bcm28155-ap.dtb \
Expand Down
8 changes: 8 additions & 0 deletions arch/arm/boot/dts/bcm2708-rpi-b.dts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/dts-v1/;

/include/ "bcm2708.dtsi"

/ {
compatible = "brcm,bcm2708";
model = "Raspberry Pi";
};
36 changes: 36 additions & 0 deletions arch/arm/boot/dts/bcm2708.dtsi
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/include/ "skeleton.dtsi"

/ {
compatible = "brcm,bcm2708";
model = "BCM2708";

interrupt-parent = <&intc>;

chosen {
/*
bootargs must be 1024 characters long because the
VC bootloader can't expand it
*/
bootargs = "console=ttyAMA0 ";
};

axi {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x7e000000 0x20000000 0x02000000>;

intc: interrupt-controller {
compatible = "brcm,bcm2708-armctrl-ic";
reg = <0x7e00b200 0x200>;
interrupt-controller;
#interrupt-cells = <2>;
};
};

clocks {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <0>;
};
};
8 changes: 8 additions & 0 deletions arch/arm/mach-bcm2708/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ config MACH_BCM2708
help
Include support for the Broadcom(R) BCM2708 platform.

config BCM2708_DT
bool "BCM2708 Device Tree support"
depends on MACH_BCM2708
default n
select USE_OF
help
Enable Device Tree support for BCM2708

config BCM2708_GPIO
bool "BCM2708 gpio support"
depends on MACH_BCM2708
Expand Down
97 changes: 97 additions & 0 deletions arch/arm/mach-bcm2708/armctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include <linux/version.h>
#include <linux/syscore_ops.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/of.h>

#include <asm/mach/irq.h>
#include <mach/hardware.h>
Expand Down Expand Up @@ -79,6 +81,100 @@ static void armctrl_unmask_irq(struct irq_data *d)
}
}

#ifdef CONFIG_OF

#define NR_IRQS_BANK0 21
#define NR_BANKS 3 + 1 /* bank 3 is used for GPIO interrupts */
#define IRQS_PER_BANK 32

/* from drivers/irqchip/irq-bcm2835.c */
static int armctrl_xlate(struct irq_domain *d, struct device_node *ctrlr,
const u32 *intspec, unsigned int intsize,
unsigned long *out_hwirq, unsigned int *out_type)
{
if (WARN_ON(intsize != 2))
return -EINVAL;

if (WARN_ON(intspec[0] >= NR_BANKS))
return -EINVAL;

if (WARN_ON(intspec[1] >= IRQS_PER_BANK))
return -EINVAL;

if (WARN_ON(intspec[0] == 0 && intspec[1] >= NR_IRQS_BANK0))
return -EINVAL;

if (intspec[0] == 0)
*out_hwirq = ARM_IRQ0_BASE + intspec[1];
else if (intspec[0] == 1)
*out_hwirq = ARM_IRQ1_BASE + intspec[1];
else if (intspec[0] == 2)
*out_hwirq = ARM_IRQ2_BASE + intspec[1];
else
*out_hwirq = GPIO_IRQ_START + intspec[1];

/* reverse remap_irqs[] */
switch (*out_hwirq) {
case INTERRUPT_VC_JPEG:
*out_hwirq = INTERRUPT_JPEG;
break;
case INTERRUPT_VC_USB:
*out_hwirq = INTERRUPT_USB;
break;
case INTERRUPT_VC_3D:
*out_hwirq = INTERRUPT_3D;
break;
case INTERRUPT_VC_DMA2:
*out_hwirq = INTERRUPT_DMA2;
break;
case INTERRUPT_VC_DMA3:
*out_hwirq = INTERRUPT_DMA3;
break;
case INTERRUPT_VC_I2C:
*out_hwirq = INTERRUPT_I2C;
break;
case INTERRUPT_VC_SPI:
*out_hwirq = INTERRUPT_SPI;
break;
case INTERRUPT_VC_I2SPCM:
*out_hwirq = INTERRUPT_I2SPCM;
break;
case INTERRUPT_VC_SDIO:
*out_hwirq = INTERRUPT_SDIO;
break;
case INTERRUPT_VC_UART:
*out_hwirq = INTERRUPT_UART;
break;
case INTERRUPT_VC_ARASANSDIO:
*out_hwirq = INTERRUPT_ARASANSDIO;
break;
}

*out_type = IRQ_TYPE_NONE;
return 0;
}

static struct irq_domain_ops armctrl_ops = {
.xlate = armctrl_xlate
};

void __init armctrl_dt_init(void)
{
struct device_node *np;
struct irq_domain *domain;

np = of_find_compatible_node(NULL, NULL, "brcm,bcm2708-armctrl-ic");
if (!np)
return;

domain = irq_domain_add_legacy(np, NR_IRQS, IRQ_ARMCTRL_START, 0,
&armctrl_ops, NULL);
WARN_ON(!domain);
}
#else
void __init armctrl_dt_init(void) { }
#endif /* CONFIG_OF */

#if defined(CONFIG_PM)

/* for kernels 3.xx use the new syscore_ops apis but for older kernels use the sys dev class */
Expand Down Expand Up @@ -215,5 +311,6 @@ int __init armctrl_init(void __iomem * base, unsigned int irq_start,

armctrl_pm_register(base, irq_start, resume_sources);
init_FIQ(FIQ_START);
armctrl_dt_init();
return 0;
}
24 changes: 24 additions & 0 deletions arch/arm/mach-bcm2708/bcm2708.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <linux/cnt32_to_63.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/spi/spi.h>
#include <linux/w1-gpio.h>

Expand Down Expand Up @@ -762,6 +763,22 @@ static void bcm2708_power_off(void)
}
}

#ifdef CONFIG_OF
static void __init bcm2708_dt_init(void)
{
int ret;

of_clk_init(NULL);
ret = of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
if (ret) {
pr_err("of_platform_populate failed: %d\n", ret);
BUG();
}
}
#else
static void __init bcm2708_dt_init(void) { }
#endif /* CONFIG_OF */

void __init bcm2708_init(void)
{
int i;
Expand All @@ -773,6 +790,7 @@ void __init bcm2708_init(void)
pm_power_off = bcm2708_power_off;

bcm2708_init_clocks();
bcm2708_dt_init();

bcm_register_device(&bcm2708_dmaman_device);
bcm_register_device(&bcm2708_vcio_device);
Expand Down Expand Up @@ -996,6 +1014,11 @@ static void __init board_reserve(void)
#endif
}

static const char * const bcm2708_compat[] = {
"brcm,bcm2708",
NULL
};

MACHINE_START(BCM2708, "BCM2708")
/* Maintainer: Broadcom Europe Ltd. */
.map_io = bcm2708_map_io,
Expand All @@ -1005,6 +1028,7 @@ MACHINE_START(BCM2708, "BCM2708")
.init_early = bcm2708_init_early,
.reserve = board_reserve,
.restart = bcm2708_restart,
.dt_compat = bcm2708_compat,
MACHINE_END

module_param(boardrev, uint, 0644);
Expand Down