forked from luck/tmp_suning_uos_patched
ARM: add basic BCM2835 SoC and Raspberry Pi board support
The BCM2835 is an ARM SoC from Broadcom. This patch adds very basic support for this SoC; enough to boot the system into an initrd with UART console, interrupt controller, timers, and a stub clock driver. Also provided is a similarly basic device tree for the Raspberry Pi Model B board. This series was written by Simon Arlott, Chris Boot, and Dom Cobley downstream, with reference to a Broadcom tree, and modified for upstream and submitted by Stephen Warren. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJQWnCOAAoJEJuNpwkmVCGcQS8P/01yZOE2QhW/S4ap1voLyRuI T7wcjla6UXckuz72qnLitJCDHxwDAF6Kgc/anibQfgambqjOAA5YuXBkJlUaBQF1 3u6k8pNJ7cI3R44BznnLN4U8QXw/w5IlUdFu7Y7Xg4xyb1Fdx11QJelYmiPIdXEQ fFVqO5JQoMWXz7i9fYU/jXHcbINyljgSqhBOM9O1R2W3kayPm3OdmyAXHzmt7rSw XPta3QlrkI/fCgolI2A9LMhrfaJVRQe59H9b+fP2R9baWs7BnkZywjO8mwipR8eI d4tRH8cy+Aa/RobLe5DnorxZ9abj3vlSv0kG0qBhcieqXZmGKlum3J4h1cBAvs8p Cv0Gm7GFxeqCJ3RaLfn1mX2OESmGQ9KH33J3PFQUcNmd82saXz6Kas7YZ5KRlMAI +TS3n9Er7P2HlpYF/3ckE3aYrN/iHJaZ/2pa2ZiR8KRnRTY3DMTxgvNIaz044zud gHUbQpttzNV0aiqMDqMvpVqBhUMCVF0LWlhQyewQHHdVSS9XNq1lrfbXPc4k54Fs Tkz4JT5S1Vhv+iqakwKQvNVpO8XWvj0Z5t5/3IqLpzdYWRp6kQh8giJXhLEQSoVl 38sJ2v6MzNmyx1yggO58Qq+OpelNDowhY0tGcOrSl6uR786gcivw9T2wd8V0iwbw uMeZ6apUnOseOaKU9mrm =vqsx -----END PGP SIGNATURE----- Merge tag 'rpi-for-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-rpi into next/soc ARM: add basic BCM2835 SoC and Raspberry Pi board support The BCM2835 is an ARM SoC from Broadcom. This patch adds very basic support for this SoC; enough to boot the system into an initrd with UART console, interrupt controller, timers, and a stub clock driver. Also provided is a similarly basic device tree for the Raspberry Pi Model B board. This series was written by Simon Arlott, Chris Boot, and Dom Cobley downstream, with reference to a Broadcom tree, and modified for upstream and submitted by Stephen Warren. * tag 'rpi-for-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-rpi: MAINTAINERS: add an entry for the BCM2835 ARM sub-architecture ARM: bcm2835: instantiate console UART ARM: bcm2835: add stub clock driver ARM: bcm2835: add system timer ARM: bcm2835: add interrupt controller driver ARM: add infra-structure for BCM2835 and Raspberry Pi
This commit is contained in:
commit
3aec092eed
8
Documentation/devicetree/bindings/arm/bcm2835.txt
Normal file
8
Documentation/devicetree/bindings/arm/bcm2835.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
Broadcom BCM2835 device tree bindings
|
||||
-------------------------------------------
|
||||
|
||||
Boards with the BCM2835 SoC shall have the following properties:
|
||||
|
||||
Required root node property:
|
||||
|
||||
compatible = "brcm,bcm2835";
|
|
@ -0,0 +1,110 @@
|
|||
BCM2835 Top-Level ("ARMCTRL") Interrupt Controller
|
||||
|
||||
The BCM2835 contains a custom top-level interrupt controller, which supports
|
||||
72 interrupt sources using a 2-level register scheme. The interrupt
|
||||
controller, or the HW block containing it, is referred to occasionally
|
||||
as "armctrl" in the SoC documentation, hence naming of this binding.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : should be "brcm,bcm2835-armctrl-ic.txt"
|
||||
- reg : Specifies base physical address and size of the registers.
|
||||
- interrupt-controller : Identifies the node as an interrupt controller
|
||||
- #interrupt-cells : Specifies the number of cells needed to encode an
|
||||
interrupt source. The value shall be 2.
|
||||
|
||||
The 1st cell is the interrupt bank; 0 for interrupts in the "IRQ basic
|
||||
pending" register, or 1/2 respectively for interrupts in the "IRQ pending
|
||||
1/2" register.
|
||||
|
||||
The 2nd cell contains the interrupt number within the bank. Valid values
|
||||
are 0..7 for bank 0, and 0..31 for bank 1.
|
||||
|
||||
The interrupt sources are as follows:
|
||||
|
||||
Bank 0:
|
||||
0: ARM_TIMER
|
||||
1: ARM_MAILBOX
|
||||
2: ARM_DOORBELL_0
|
||||
3: ARM_DOORBELL_1
|
||||
4: VPU0_HALTED
|
||||
5: VPU1_HALTED
|
||||
6: ILLEGAL_TYPE0
|
||||
7: ILLEGAL_TYPE1
|
||||
|
||||
Bank 1:
|
||||
0: TIMER0
|
||||
1: TIMER1
|
||||
2: TIMER2
|
||||
3: TIMER3
|
||||
4: CODEC0
|
||||
5: CODEC1
|
||||
6: CODEC2
|
||||
7: VC_JPEG
|
||||
8: ISP
|
||||
9: VC_USB
|
||||
10: VC_3D
|
||||
11: TRANSPOSER
|
||||
12: MULTICORESYNC0
|
||||
13: MULTICORESYNC1
|
||||
14: MULTICORESYNC2
|
||||
15: MULTICORESYNC3
|
||||
16: DMA0
|
||||
17: DMA1
|
||||
18: VC_DMA2
|
||||
19: VC_DMA3
|
||||
20: DMA4
|
||||
21: DMA5
|
||||
22: DMA6
|
||||
23: DMA7
|
||||
24: DMA8
|
||||
25: DMA9
|
||||
26: DMA10
|
||||
27: DMA11
|
||||
28: DMA12
|
||||
29: AUX
|
||||
30: ARM
|
||||
31: VPUDMA
|
||||
|
||||
Bank 2:
|
||||
0: HOSTPORT
|
||||
1: VIDEOSCALER
|
||||
2: CCP2TX
|
||||
3: SDC
|
||||
4: DSI0
|
||||
5: AVE
|
||||
6: CAM0
|
||||
7: CAM1
|
||||
8: HDMI0
|
||||
9: HDMI1
|
||||
10: PIXELVALVE1
|
||||
11: I2CSPISLV
|
||||
12: DSI1
|
||||
13: PWA0
|
||||
14: PWA1
|
||||
15: CPR
|
||||
16: SMI
|
||||
17: GPIO0
|
||||
18: GPIO1
|
||||
19: GPIO2
|
||||
20: GPIO3
|
||||
21: VC_I2C
|
||||
22: VC_SPI
|
||||
23: VC_I2SPCM
|
||||
24: VC_SDIO
|
||||
25: VC_UART
|
||||
26: SLIMBUS
|
||||
27: VEC
|
||||
28: CPG
|
||||
29: RNG
|
||||
30: VC_ARASANSDIO
|
||||
31: AVSPMON
|
||||
|
||||
Example:
|
||||
|
||||
intc: interrupt-controller {
|
||||
compatible = "brcm,bcm2835-armctrl-ic";
|
||||
reg = <0x7e00b200 0x200>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
|
@ -0,0 +1,22 @@
|
|||
BCM2835 System Timer
|
||||
|
||||
The System Timer peripheral provides four 32-bit timer channels and a
|
||||
single 64-bit free running counter. Each channel has an output compare
|
||||
register, which is compared against the 32 least significant bits of the
|
||||
free running counter values, and generates an interrupt.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : should be "brcm,bcm2835-system-timer.txt"
|
||||
- reg : Specifies base physical address and size of the registers.
|
||||
- interrupts : A list of 4 interrupt sinks; one per timer channel.
|
||||
- clock-frequency : The frequency of the clock that drives the counter, in Hz.
|
||||
|
||||
Example:
|
||||
|
||||
timer {
|
||||
compatible = "brcm,bcm2835-system-timer";
|
||||
reg = <0x7e003000 0x1000>;
|
||||
interrupts = <1 0>, <1 1>, <1 2>, <1 3>;
|
||||
clock-frequency = <1000000>;
|
||||
};
|
|
@ -10,6 +10,7 @@ apm Applied Micro Circuits Corporation (APM)
|
|||
arm ARM Ltd.
|
||||
atmel Atmel Corporation
|
||||
bosch Bosch Sensortec GmbH
|
||||
brcm Broadcom Corporation
|
||||
cavium Cavium, Inc.
|
||||
chrp Common Hardware Reference Platform
|
||||
cortina Cortina Systems, Inc.
|
||||
|
|
10
MAINTAINERS
10
MAINTAINERS
|
@ -1612,6 +1612,16 @@ L: netdev@vger.kernel.org
|
|||
S: Supported
|
||||
F: drivers/net/ethernet/broadcom/bnx2x/
|
||||
|
||||
BROADCOM BCM2835 ARM ARCHICTURE
|
||||
M: Stephen Warren <swarren@wwwdotorg.org>
|
||||
L: linux-rpi-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-rpi.git
|
||||
S: Maintained
|
||||
F: arch/arm/mach-bcm2835/
|
||||
F: arch/arm/boot/dts/bcm2835*
|
||||
F: arch/arm/configs/bcm2835_defconfig
|
||||
F: drivers/*/*bcm2835*
|
||||
|
||||
BROADCOM TG3 GIGABIT ETHERNET DRIVER
|
||||
M: Matt Carlson <mcarlson@broadcom.com>
|
||||
M: Michael Chan <mchan@broadcom.com>
|
||||
|
|
|
@ -350,6 +350,23 @@ config ARCH_AT91
|
|||
This enables support for systems based on Atmel
|
||||
AT91RM9200 and AT91SAM9* processors.
|
||||
|
||||
config ARCH_BCM2835
|
||||
bool "Broadcom BCM2835 family"
|
||||
select ARCH_WANT_OPTIONAL_GPIOLIB
|
||||
select ARM_AMBA
|
||||
select ARM_ERRATA_411920
|
||||
select ARM_TIMER_SP804
|
||||
select CLKDEV_LOOKUP
|
||||
select COMMON_CLK
|
||||
select CPU_V6
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select MULTI_IRQ_HANDLER
|
||||
select SPARSE_IRQ
|
||||
select USE_OF
|
||||
help
|
||||
This enables support for the Broadcom BCM2835 SoC. This SoC is
|
||||
use in the Raspberry Pi, and Roku 2 devices.
|
||||
|
||||
config ARCH_BCMRING
|
||||
bool "Broadcom BCMRING"
|
||||
depends on MMU
|
||||
|
|
|
@ -136,6 +136,7 @@ textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
|
|||
# Machine directory name. This list is sorted alphanumerically
|
||||
# by CONFIG_* macro name.
|
||||
machine-$(CONFIG_ARCH_AT91) := at91
|
||||
machine-$(CONFIG_ARCH_BCM2835) := bcm2835
|
||||
machine-$(CONFIG_ARCH_BCMRING) := bcmring
|
||||
machine-$(CONFIG_ARCH_CLPS711X) := clps711x
|
||||
machine-$(CONFIG_ARCH_CNS3XXX) := cns3xxx
|
||||
|
|
12
arch/arm/boot/dts/bcm2835-rpi-b.dts
Normal file
12
arch/arm/boot/dts/bcm2835-rpi-b.dts
Normal file
|
@ -0,0 +1,12 @@
|
|||
/dts-v1/;
|
||||
/memreserve/ 0x0c000000 0x04000000;
|
||||
/include/ "bcm2835.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "raspberrypi,model-b", "brcm,bcm2835";
|
||||
model = "Raspberry Pi Model B";
|
||||
|
||||
memory {
|
||||
reg = <0 0x10000000>;
|
||||
};
|
||||
};
|
39
arch/arm/boot/dts/bcm2835.dtsi
Normal file
39
arch/arm/boot/dts/bcm2835.dtsi
Normal file
|
@ -0,0 +1,39 @@
|
|||
/include/ "skeleton.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "brcm,bcm2835";
|
||||
model = "BCM2835";
|
||||
interrupt-parent = <&intc>;
|
||||
|
||||
chosen {
|
||||
bootargs = "earlyprintk console=ttyAMA0";
|
||||
};
|
||||
|
||||
soc {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0x7e000000 0x20000000 0x02000000>;
|
||||
|
||||
timer {
|
||||
compatible = "brcm,bcm2835-system-timer";
|
||||
reg = <0x7e003000 0x1000>;
|
||||
interrupts = <1 0>, <1 1>, <1 2>, <1 3>;
|
||||
clock-frequency = <1000000>;
|
||||
};
|
||||
|
||||
intc: interrupt-controller {
|
||||
compatible = "brcm,bcm2835-armctrl-ic";
|
||||
reg = <0x7e00b200 0x200>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
uart@20201000 {
|
||||
compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
|
||||
reg = <0x7e201000 0x1000>;
|
||||
interrupts = <2 25>;
|
||||
clock-frequency = <3000000>;
|
||||
};
|
||||
};
|
||||
};
|
95
arch/arm/configs/bcm2835_defconfig
Normal file
95
arch/arm/configs/bcm2835_defconfig
Normal file
|
@ -0,0 +1,95 @@
|
|||
CONFIG_EXPERIMENTAL=y
|
||||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_BSD_PROCESS_ACCT=y
|
||||
CONFIG_BSD_PROCESS_ACCT_V3=y
|
||||
CONFIG_FHANDLE=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_LOG_BUF_SHIFT=18
|
||||
CONFIG_CGROUP_FREEZER=y
|
||||
CONFIG_CGROUP_DEVICE=y
|
||||
CONFIG_CPUSETS=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_RESOURCE_COUNTERS=y
|
||||
CONFIG_CGROUP_PERF=y
|
||||
CONFIG_CFS_BANDWIDTH=y
|
||||
CONFIG_RT_GROUP_SCHED=y
|
||||
CONFIG_NAMESPACES=y
|
||||
CONFIG_SCHED_AUTOGROUP=y
|
||||
CONFIG_RELAY=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_RD_BZIP2=y
|
||||
CONFIG_RD_LZMA=y
|
||||
CONFIG_RD_XZ=y
|
||||
CONFIG_RD_LZO=y
|
||||
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
CONFIG_EMBEDDED=y
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_PROFILING=y
|
||||
CONFIG_OPROFILE=y
|
||||
CONFIG_JUMP_LABEL=y
|
||||
# CONFIG_BLOCK is not set
|
||||
CONFIG_ARCH_BCM2835=y
|
||||
CONFIG_PREEMPT_VOLUNTARY=y
|
||||
CONFIG_AEABI=y
|
||||
CONFIG_COMPACTION=y
|
||||
CONFIG_KSM=y
|
||||
CONFIG_DEFAULT_MMAP_MIN_ADDR=65536
|
||||
CONFIG_CLEANCACHE=y
|
||||
CONFIG_SECCOMP=y
|
||||
CONFIG_CC_STACKPROTECTOR=y
|
||||
CONFIG_KEXEC=y
|
||||
CONFIG_CRASH_DUMP=y
|
||||
CONFIG_VFP=y
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
# CONFIG_SUSPEND is not set
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
# CONFIG_STANDALONE is not set
|
||||
# CONFIG_INPUT_MOUSEDEV is not set
|
||||
# CONFIG_INPUT_KEYBOARD is not set
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_VT is not set
|
||||
# CONFIG_UNIX98_PTYS is not set
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
# CONFIG_DEVKMEM is not set
|
||||
CONFIG_SERIAL_AMBA_PL011=y
|
||||
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
|
||||
CONFIG_TTY_PRINTK=y
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
# CONFIG_HWMON is not set
|
||||
# CONFIG_USB_SUPPORT is not set
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
# CONFIG_FILE_LOCKING is not set
|
||||
# CONFIG_DNOTIFY is not set
|
||||
# CONFIG_INOTIFY_USER is not set
|
||||
# CONFIG_PROC_FS is not set
|
||||
# CONFIG_SYSFS is not set
|
||||
# CONFIG_MISC_FILESYSTEMS is not set
|
||||
CONFIG_PRINTK_TIME=y
|
||||
# CONFIG_ENABLE_WARN_DEPRECATED is not set
|
||||
# CONFIG_ENABLE_MUST_CHECK is not set
|
||||
CONFIG_UNUSED_SYMBOLS=y
|
||||
CONFIG_LOCKUP_DETECTOR=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_MEMORY_INIT=y
|
||||
CONFIG_BOOT_PRINTK_DELAY=y
|
||||
CONFIG_SCHED_TRACER=y
|
||||
CONFIG_STACK_TRACER=y
|
||||
CONFIG_FUNCTION_PROFILER=y
|
||||
CONFIG_DYNAMIC_DEBUG=y
|
||||
CONFIG_KGDB=y
|
||||
CONFIG_KGDB_KDB=y
|
||||
CONFIG_TEST_KSTRTOX=y
|
||||
CONFIG_STRICT_DEVMEM=y
|
||||
CONFIG_DEBUG_LL=y
|
||||
CONFIG_EARLY_PRINTK=y
|
||||
# CONFIG_XZ_DEC_X86 is not set
|
||||
# CONFIG_XZ_DEC_POWERPC is not set
|
||||
# CONFIG_XZ_DEC_IA64 is not set
|
||||
# CONFIG_XZ_DEC_ARM is not set
|
||||
# CONFIG_XZ_DEC_ARMTHUMB is not set
|
||||
# CONFIG_XZ_DEC_SPARC is not set
|
1
arch/arm/mach-bcm2835/Makefile
Normal file
1
arch/arm/mach-bcm2835/Makefile
Normal file
|
@ -0,0 +1 @@
|
|||
obj-y += bcm2835.o
|
5
arch/arm/mach-bcm2835/Makefile.boot
Normal file
5
arch/arm/mach-bcm2835/Makefile.boot
Normal file
|
@ -0,0 +1,5 @@
|
|||
zreladdr-y := 0x00008000
|
||||
params_phys-y := 0x00000100
|
||||
initrd_phys-y := 0x00800000
|
||||
|
||||
dtb-y += bcm2835-rpi-b.dtb
|
64
arch/arm/mach-bcm2835/bcm2835.c
Normal file
64
arch/arm/mach-bcm2835/bcm2835.c
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Broadcom
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/irqchip/bcm2835.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/bcm2835_timer.h>
|
||||
#include <linux/clk/bcm2835.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
#include <mach/bcm2835_soc.h>
|
||||
|
||||
static struct map_desc io_map __initdata = {
|
||||
.virtual = BCM2835_PERIPH_VIRT,
|
||||
.pfn = __phys_to_pfn(BCM2835_PERIPH_PHYS),
|
||||
.length = BCM2835_PERIPH_SIZE,
|
||||
.type = MT_DEVICE
|
||||
};
|
||||
|
||||
void __init bcm2835_map_io(void)
|
||||
{
|
||||
iotable_init(&io_map, 1);
|
||||
}
|
||||
|
||||
void __init bcm2835_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
bcm2835_init_clocks();
|
||||
|
||||
ret = of_platform_populate(NULL, of_default_bus_match_table, NULL,
|
||||
NULL);
|
||||
if (ret) {
|
||||
pr_err("of_platform_populate failed: %d\n", ret);
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static const char * const bcm2835_compat[] = {
|
||||
"brcm,bcm2835",
|
||||
NULL
|
||||
};
|
||||
|
||||
DT_MACHINE_START(BCM2835, "BCM2835")
|
||||
.map_io = bcm2835_map_io,
|
||||
.init_irq = bcm2835_init_irq,
|
||||
.handle_irq = bcm2835_handle_irq,
|
||||
.init_machine = bcm2835_init,
|
||||
.timer = &bcm2835_timer,
|
||||
.dt_compat = bcm2835_compat
|
||||
MACHINE_END
|
29
arch/arm/mach-bcm2835/include/mach/bcm2835_soc.h
Normal file
29
arch/arm/mach-bcm2835/include/mach/bcm2835_soc.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (C) 2012 Stephen Warren
|
||||
*
|
||||
* Derived from code:
|
||||
* Copyright (C) 2010 Broadcom
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __MACH_BCM2835_BCM2835_SOC_H__
|
||||
#define __MACH_BCM2835_BCM2835_SOC_H__
|
||||
|
||||
#include <asm/sizes.h>
|
||||
|
||||
#define BCM2835_PERIPH_PHYS 0x20000000
|
||||
#define BCM2835_PERIPH_VIRT 0xf0000000
|
||||
#define BCM2835_PERIPH_SIZE SZ_16M
|
||||
#define BCM2835_DEBUG_PHYS 0x20201000
|
||||
#define BCM2835_DEBUG_VIRT 0xf0201000
|
||||
|
||||
#endif
|
21
arch/arm/mach-bcm2835/include/mach/debug-macro.S
Normal file
21
arch/arm/mach-bcm2835/include/mach/debug-macro.S
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Debugging macro include header
|
||||
*
|
||||
* Copyright (C) 2010 Broadcom
|
||||
* Copyright (C) 1994-1999 Russell King
|
||||
* Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <mach/bcm2835_soc.h>
|
||||
|
||||
.macro addruart, rp, rv, tmp
|
||||
ldr \rp, =BCM2835_DEBUG_PHYS
|
||||
ldr \rv, =BCM2835_DEBUG_VIRT
|
||||
.endm
|
||||
|
||||
#include <asm/hardware/debug-pl01x.S>
|
26
arch/arm/mach-bcm2835/include/mach/timex.h
Normal file
26
arch/arm/mach-bcm2835/include/mach/timex.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* BCM2835 system clock frequency
|
||||
*
|
||||
* Copyright (C) 2010 Broadcom
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARCH_TIMEX_H
|
||||
#define __ASM_ARCH_TIMEX_H
|
||||
|
||||
#define CLOCK_TICK_RATE (1000000)
|
||||
|
||||
#endif
|
45
arch/arm/mach-bcm2835/include/mach/uncompress.h
Normal file
45
arch/arm/mach-bcm2835/include/mach/uncompress.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Broadcom
|
||||
* Copyright (C) 2003 ARM Limited
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/amba/serial.h>
|
||||
#include <mach/bcm2835_soc.h>
|
||||
|
||||
#define UART0_BASE BCM2835_DEBUG_PHYS
|
||||
|
||||
#define BCM2835_UART_DR IOMEM(UART0_BASE + UART01x_DR)
|
||||
#define BCM2835_UART_FR IOMEM(UART0_BASE + UART01x_FR)
|
||||
#define BCM2835_UART_CR IOMEM(UART0_BASE + UART011_CR)
|
||||
|
||||
static inline void putc(int c)
|
||||
{
|
||||
while (__raw_readl(BCM2835_UART_FR) & UART01x_FR_TXFF)
|
||||
barrier();
|
||||
|
||||
__raw_writel(c, BCM2835_UART_DR);
|
||||
}
|
||||
|
||||
static inline void flush(void)
|
||||
{
|
||||
int fr;
|
||||
|
||||
do {
|
||||
fr = __raw_readl(BCM2835_UART_FR);
|
||||
barrier();
|
||||
} while ((fr & (UART011_FR_TXFE | UART01x_FR_BUSY)) != UART011_FR_TXFE);
|
||||
}
|
||||
|
||||
#define arch_decomp_setup()
|
||||
#define arch_decomp_wdog()
|
|
@ -152,4 +152,6 @@ source "drivers/vme/Kconfig"
|
|||
|
||||
source "drivers/pwm/Kconfig"
|
||||
|
||||
source "drivers/irqchip/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
# Rewritten to use lists instead of if-statements.
|
||||
#
|
||||
|
||||
obj-y += irqchip/
|
||||
|
||||
# GPIO must come after pinctrl as gpios may need to mux pins etc
|
||||
obj-y += pinctrl/
|
||||
obj-y += gpio/
|
||||
|
|
|
@ -3,6 +3,7 @@ obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o
|
|||
obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed-rate.o clk-gate.o \
|
||||
clk-mux.o clk-divider.o clk-fixed-factor.o
|
||||
# SoCs specific
|
||||
obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o
|
||||
obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
|
||||
obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
|
||||
obj-$(CONFIG_ARCH_MXS) += mxs/
|
||||
|
|
59
drivers/clk/clk-bcm2835.c
Normal file
59
drivers/clk/clk-bcm2835.c
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Broadcom
|
||||
* Copyright (C) 2012 Stephen Warren
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/clk/bcm2835.h>
|
||||
|
||||
/*
|
||||
* These are fixed clocks. They're probably not all root clocks and it may
|
||||
* be possible to turn them on and off but until this is mapped out better
|
||||
* it's the only way they can be used.
|
||||
*/
|
||||
void __init bcm2835_init_clocks(void)
|
||||
{
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
|
||||
clk = clk_register_fixed_rate(NULL, "sys_pclk", NULL, CLK_IS_ROOT,
|
||||
250000000);
|
||||
if (!clk)
|
||||
pr_err("sys_pclk not registered\n");
|
||||
|
||||
clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT,
|
||||
126000000);
|
||||
if (!clk)
|
||||
pr_err("apb_pclk not registered\n");
|
||||
|
||||
clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, CLK_IS_ROOT,
|
||||
3000000);
|
||||
if (!clk)
|
||||
pr_err("uart0_pclk not registered\n");
|
||||
ret = clk_register_clkdev(clk, NULL, "20201000.uart");
|
||||
if (ret)
|
||||
pr_err("uart0_pclk alias not registered\n");
|
||||
|
||||
clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, CLK_IS_ROOT,
|
||||
125000000);
|
||||
if (!clk)
|
||||
pr_err("uart1_pclk not registered\n");
|
||||
ret = clk_register_clkdev(clk, NULL, "20215000.uart");
|
||||
if (ret)
|
||||
pr_err("uart0_pclk alias not registered\n");
|
||||
}
|
|
@ -13,3 +13,4 @@ obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o
|
|||
obj-$(CONFIG_DW_APB_TIMER_OF) += dw_apb_timer_of.o
|
||||
obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o
|
||||
obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o
|
||||
obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o
|
||||
|
|
161
drivers/clocksource/bcm2835_timer.c
Normal file
161
drivers/clocksource/bcm2835_timer.c
Normal file
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* Copyright 2012 Simon Arlott
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <linux/bcm2835_timer.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irqreturn.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include <asm/sched_clock.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
#define REG_CONTROL 0x00
|
||||
#define REG_COUNTER_LO 0x04
|
||||
#define REG_COUNTER_HI 0x08
|
||||
#define REG_COMPARE(n) (0x0c + (n) * 4)
|
||||
#define MAX_TIMER 3
|
||||
#define DEFAULT_TIMER 3
|
||||
|
||||
struct bcm2835_timer {
|
||||
void __iomem *control;
|
||||
void __iomem *compare;
|
||||
int match_mask;
|
||||
struct clock_event_device evt;
|
||||
struct irqaction act;
|
||||
};
|
||||
|
||||
static void __iomem *system_clock __read_mostly;
|
||||
|
||||
static u32 notrace bcm2835_sched_read(void)
|
||||
{
|
||||
return readl_relaxed(system_clock);
|
||||
}
|
||||
|
||||
static void bcm2835_time_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *evt_dev)
|
||||
{
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
case CLOCK_EVT_MODE_RESUME:
|
||||
break;
|
||||
default:
|
||||
WARN(1, "%s: unhandled event mode %d\n", __func__, mode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int bcm2835_time_set_next_event(unsigned long event,
|
||||
struct clock_event_device *evt_dev)
|
||||
{
|
||||
struct bcm2835_timer *timer = container_of(evt_dev,
|
||||
struct bcm2835_timer, evt);
|
||||
writel_relaxed(readl_relaxed(system_clock) + event,
|
||||
timer->compare);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t bcm2835_time_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct bcm2835_timer *timer = dev_id;
|
||||
void (*event_handler)(struct clock_event_device *);
|
||||
if (readl_relaxed(timer->control) & timer->match_mask) {
|
||||
writel_relaxed(timer->match_mask, timer->control);
|
||||
|
||||
event_handler = ACCESS_ONCE(timer->evt.event_handler);
|
||||
if (event_handler)
|
||||
event_handler(&timer->evt);
|
||||
return IRQ_HANDLED;
|
||||
} else {
|
||||
return IRQ_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static struct of_device_id bcm2835_time_match[] __initconst = {
|
||||
{ .compatible = "brcm,bcm2835-system-timer" },
|
||||
{}
|
||||
};
|
||||
|
||||
static void __init bcm2835_time_init(void)
|
||||
{
|
||||
struct device_node *node;
|
||||
void __iomem *base;
|
||||
u32 freq;
|
||||
int irq;
|
||||
struct bcm2835_timer *timer;
|
||||
|
||||
node = of_find_matching_node(NULL, bcm2835_time_match);
|
||||
if (!node)
|
||||
panic("No bcm2835 timer node");
|
||||
|
||||
base = of_iomap(node, 0);
|
||||
if (!base)
|
||||
panic("Can't remap registers");
|
||||
|
||||
if (of_property_read_u32(node, "clock-frequency", &freq))
|
||||
panic("Can't read clock-frequency");
|
||||
|
||||
system_clock = base + REG_COUNTER_LO;
|
||||
setup_sched_clock(bcm2835_sched_read, 32, freq);
|
||||
|
||||
clocksource_mmio_init(base + REG_COUNTER_LO, node->name,
|
||||
freq, 300, 32, clocksource_mmio_readl_up);
|
||||
|
||||
irq = irq_of_parse_and_map(node, DEFAULT_TIMER);
|
||||
if (irq <= 0)
|
||||
panic("Can't parse IRQ");
|
||||
|
||||
timer = kzalloc(sizeof(*timer), GFP_KERNEL);
|
||||
if (!timer)
|
||||
panic("Can't allocate timer struct\n");
|
||||
|
||||
timer->control = base + REG_CONTROL;
|
||||
timer->compare = base + REG_COMPARE(DEFAULT_TIMER);
|
||||
timer->match_mask = BIT(DEFAULT_TIMER);
|
||||
timer->evt.name = node->name;
|
||||
timer->evt.rating = 300;
|
||||
timer->evt.features = CLOCK_EVT_FEAT_ONESHOT;
|
||||
timer->evt.set_mode = bcm2835_time_set_mode;
|
||||
timer->evt.set_next_event = bcm2835_time_set_next_event;
|
||||
timer->evt.cpumask = cpumask_of(0);
|
||||
timer->act.name = node->name;
|
||||
timer->act.flags = IRQF_TIMER | IRQF_SHARED;
|
||||
timer->act.dev_id = timer;
|
||||
timer->act.handler = bcm2835_time_interrupt;
|
||||
|
||||
if (setup_irq(irq, &timer->act))
|
||||
panic("Can't set up timer IRQ\n");
|
||||
|
||||
clockevents_config_and_register(&timer->evt, freq, 0xf, 0xffffffff);
|
||||
|
||||
pr_info("bcm2835: system timer (irq = %d)\n", irq);
|
||||
}
|
||||
|
||||
struct sys_timer bcm2835_timer = {
|
||||
.init = bcm2835_time_init,
|
||||
};
|
0
drivers/irqchip/Kconfig
Normal file
0
drivers/irqchip/Kconfig
Normal file
1
drivers/irqchip/Makefile
Normal file
1
drivers/irqchip/Makefile
Normal file
|
@ -0,0 +1 @@
|
|||
obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o
|
223
drivers/irqchip/irq-bcm2835.c
Normal file
223
drivers/irqchip/irq-bcm2835.c
Normal file
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
* Copyright 2010 Broadcom
|
||||
* Copyright 2012 Simon Arlott, Chris Boot, Stephen Warren
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Quirk 1: Shortcut interrupts don't set the bank 1/2 register pending bits
|
||||
*
|
||||
* If an interrupt fires on bank 1 that isn't in the shortcuts list, bit 8
|
||||
* on bank 0 is set to signify that an interrupt in bank 1 has fired, and
|
||||
* to look in the bank 1 status register for more information.
|
||||
*
|
||||
* If an interrupt fires on bank 1 that _is_ in the shortcuts list, its
|
||||
* shortcut bit in bank 0 is set as well as its interrupt bit in the bank 1
|
||||
* status register, but bank 0 bit 8 is _not_ set.
|
||||
*
|
||||
* Quirk 2: You can't mask the register 1/2 pending interrupts
|
||||
*
|
||||
* In a proper cascaded interrupt controller, the interrupt lines with
|
||||
* cascaded interrupt controllers on them are just normal interrupt lines.
|
||||
* You can mask the interrupts and get on with things. With this controller
|
||||
* you can't do that.
|
||||
*
|
||||
* Quirk 3: The shortcut interrupts can't be (un)masked in bank 0
|
||||
*
|
||||
* Those interrupts that have shortcuts can only be masked/unmasked in
|
||||
* their respective banks' enable/disable registers. Doing so in the bank 0
|
||||
* enable/disable registers has no effect.
|
||||
*
|
||||
* The FIQ control register:
|
||||
* Bits 0-6: IRQ (index in order of interrupts from banks 1, 2, then 0)
|
||||
* Bit 7: Enable FIQ generation
|
||||
* Bits 8+: Unused
|
||||
*
|
||||
* An interrupt must be disabled before configuring it for FIQ generation
|
||||
* otherwise both handlers will fire at the same time!
|
||||
*/
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/irqchip/bcm2835.h>
|
||||
|
||||
#include <asm/exception.h>
|
||||
|
||||
/* Put the bank and irq (32 bits) into the hwirq */
|
||||
#define MAKE_HWIRQ(b, n) ((b << 5) | (n))
|
||||
#define HWIRQ_BANK(i) (i >> 5)
|
||||
#define HWIRQ_BIT(i) BIT(i & 0x1f)
|
||||
|
||||
#define NR_IRQS_BANK0 8
|
||||
#define BANK0_HWIRQ_MASK 0xff
|
||||
/* Shortcuts can't be disabled so any unknown new ones need to be masked */
|
||||
#define SHORTCUT1_MASK 0x00007c00
|
||||
#define SHORTCUT2_MASK 0x001f8000
|
||||
#define SHORTCUT_SHIFT 10
|
||||
#define BANK1_HWIRQ BIT(8)
|
||||
#define BANK2_HWIRQ BIT(9)
|
||||
#define BANK0_VALID_MASK (BANK0_HWIRQ_MASK | BANK1_HWIRQ | BANK2_HWIRQ \
|
||||
| SHORTCUT1_MASK | SHORTCUT2_MASK)
|
||||
|
||||
#define REG_FIQ_CONTROL 0x0c
|
||||
|
||||
#define NR_BANKS 3
|
||||
#define IRQS_PER_BANK 32
|
||||
|
||||
static int reg_pending[] __initconst = { 0x00, 0x04, 0x08 };
|
||||
static int reg_enable[] __initconst = { 0x18, 0x10, 0x14 };
|
||||
static int reg_disable[] __initconst = { 0x24, 0x1c, 0x20 };
|
||||
static int bank_irqs[] __initconst = { 8, 32, 32 };
|
||||
|
||||
static const int shortcuts[] = {
|
||||
7, 9, 10, 18, 19, /* Bank 1 */
|
||||
21, 22, 23, 24, 25, 30 /* Bank 2 */
|
||||
};
|
||||
|
||||
struct armctrl_ic {
|
||||
void __iomem *base;
|
||||
void __iomem *pending[NR_BANKS];
|
||||
void __iomem *enable[NR_BANKS];
|
||||
void __iomem *disable[NR_BANKS];
|
||||
struct irq_domain *domain;
|
||||
};
|
||||
|
||||
static struct armctrl_ic intc __read_mostly;
|
||||
|
||||
static void armctrl_mask_irq(struct irq_data *d)
|
||||
{
|
||||
writel_relaxed(HWIRQ_BIT(d->hwirq), intc.disable[HWIRQ_BANK(d->hwirq)]);
|
||||
}
|
||||
|
||||
static void armctrl_unmask_irq(struct irq_data *d)
|
||||
{
|
||||
writel_relaxed(HWIRQ_BIT(d->hwirq), intc.enable[HWIRQ_BANK(d->hwirq)]);
|
||||
}
|
||||
|
||||
static struct irq_chip armctrl_chip = {
|
||||
.name = "ARMCTRL-level",
|
||||
.irq_mask = armctrl_mask_irq,
|
||||
.irq_unmask = armctrl_unmask_irq
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
*out_hwirq = MAKE_HWIRQ(intspec[0], intspec[1]);
|
||||
*out_type = IRQ_TYPE_NONE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_domain_ops armctrl_ops = {
|
||||
.xlate = armctrl_xlate
|
||||
};
|
||||
|
||||
static int __init armctrl_of_init(struct device_node *node,
|
||||
struct device_node *parent)
|
||||
{
|
||||
void __iomem *base;
|
||||
int irq, b, i;
|
||||
|
||||
base = of_iomap(node, 0);
|
||||
if (!base)
|
||||
panic("%s: unable to map IC registers\n",
|
||||
node->full_name);
|
||||
|
||||
intc.domain = irq_domain_add_linear(node, MAKE_HWIRQ(NR_BANKS, 0),
|
||||
&armctrl_ops, NULL);
|
||||
if (!intc.domain)
|
||||
panic("%s: unable to create IRQ domain\n", node->full_name);
|
||||
|
||||
for (b = 0; b < NR_BANKS; b++) {
|
||||
intc.pending[b] = base + reg_pending[b];
|
||||
intc.enable[b] = base + reg_enable[b];
|
||||
intc.disable[b] = base + reg_disable[b];
|
||||
|
||||
for (i = 0; i < bank_irqs[b]; i++) {
|
||||
irq = irq_create_mapping(intc.domain, MAKE_HWIRQ(b, i));
|
||||
BUG_ON(irq <= 0);
|
||||
irq_set_chip_and_handler(irq, &armctrl_chip,
|
||||
handle_level_irq);
|
||||
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id irq_of_match[] __initconst = {
|
||||
{ .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init }
|
||||
};
|
||||
|
||||
void __init bcm2835_init_irq(void)
|
||||
{
|
||||
of_irq_init(irq_of_match);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle each interrupt across the entire interrupt controller. This reads the
|
||||
* status register before handling each interrupt, which is necessary given that
|
||||
* handle_IRQ may briefly re-enable interrupts for soft IRQ handling.
|
||||
*/
|
||||
|
||||
static void armctrl_handle_bank(int bank, struct pt_regs *regs)
|
||||
{
|
||||
u32 stat, irq;
|
||||
|
||||
while ((stat = readl_relaxed(intc.pending[bank]))) {
|
||||
irq = MAKE_HWIRQ(bank, ffs(stat) - 1);
|
||||
handle_IRQ(irq_linear_revmap(intc.domain, irq), regs);
|
||||
}
|
||||
}
|
||||
|
||||
static void armctrl_handle_shortcut(int bank, struct pt_regs *regs,
|
||||
u32 stat)
|
||||
{
|
||||
u32 irq = MAKE_HWIRQ(bank, shortcuts[ffs(stat >> SHORTCUT_SHIFT) - 1]);
|
||||
handle_IRQ(irq_linear_revmap(intc.domain, irq), regs);
|
||||
}
|
||||
|
||||
asmlinkage void __exception_irq_entry bcm2835_handle_irq(
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
u32 stat, irq;
|
||||
|
||||
while ((stat = readl_relaxed(intc.pending[0]) & BANK0_VALID_MASK)) {
|
||||
if (stat & BANK0_HWIRQ_MASK) {
|
||||
irq = MAKE_HWIRQ(0, ffs(stat & BANK0_HWIRQ_MASK) - 1);
|
||||
handle_IRQ(irq_linear_revmap(intc.domain, irq), regs);
|
||||
} else if (stat & SHORTCUT1_MASK) {
|
||||
armctrl_handle_shortcut(1, regs, stat & SHORTCUT1_MASK);
|
||||
} else if (stat & SHORTCUT2_MASK) {
|
||||
armctrl_handle_shortcut(2, regs, stat & SHORTCUT2_MASK);
|
||||
} else if (stat & BANK1_HWIRQ) {
|
||||
armctrl_handle_bank(1, regs);
|
||||
} else if (stat & BANK2_HWIRQ) {
|
||||
armctrl_handle_bank(2, regs);
|
||||
} else {
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
}
|
22
include/linux/bcm2835_timer.h
Normal file
22
include/linux/bcm2835_timer.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright 2012 Simon Arlott
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __BCM2835_TIMER_H
|
||||
#define __BCM2835_TIMER_H
|
||||
|
||||
#include <asm/mach/time.h>
|
||||
|
||||
extern struct sys_timer bcm2835_timer;
|
||||
|
||||
#endif
|
24
include/linux/clk/bcm2835.h
Normal file
24
include/linux/clk/bcm2835.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Broadcom
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_CLK_BCM2835_H_
|
||||
#define __LINUX_CLK_BCM2835_H_
|
||||
|
||||
void __init bcm2835_init_clocks(void);
|
||||
|
||||
#endif
|
29
include/linux/irqchip/bcm2835.h
Normal file
29
include/linux/irqchip/bcm2835.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Broadcom
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_IRQCHIP_BCM2835_H_
|
||||
#define __LINUX_IRQCHIP_BCM2835_H_
|
||||
|
||||
#include <asm/exception.h>
|
||||
|
||||
extern void bcm2835_init_irq(void);
|
||||
|
||||
extern asmlinkage void __exception_irq_entry bcm2835_handle_irq(
|
||||
struct pt_regs *regs);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user