diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-04-19 14:23:28 +0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-04-19 14:23:28 +0200 |
commit | d5aeee8cb28317ef608ecac421abc4d986d585d2 (patch) | |
tree | 70ec8ed8891f26e5c58152ffca9924ea1c58fe3a /arch/arm | |
parent | [media] zoran: fix integer overflow in setup_window() (diff) | |
parent | Linux 3.4-rc3 (diff) | |
download | linux-d5aeee8cb28317ef608ecac421abc4d986d585d2.tar.xz linux-d5aeee8cb28317ef608ecac421abc4d986d585d2.zip |
Merge tag 'v3.4-rc3' into staging/for_v3.5
* tag 'v3.4-rc3': (3755 commits)
Linux 3.4-rc3
x86-32: fix up strncpy_from_user() sign error
ARM: 7386/1: jump_label: fixup for rename to static_key
ARM: 7384/1: ThumbEE: Disable userspace TEEHBR access for !CONFIG_ARM_THUMBEE
ARM: 7382/1: mm: truncate memory banks to fit in 4GB space for classic MMU
ARM: 7359/2: smp_twd: Only wait for reprogramming on active cpus
PCI: Fix regression in pci_restore_state(), v3
SCSI: Fix error handling when no ULD is attached
ARM: OMAP: clock: cleanup CPUfreq leftovers, fix build errors
ARM: dts: remove blank interrupt-parent properties
ARM: EXYNOS: Fix Kconfig dependencies for device tree enabled machine files
do not export kernel's NULL #define to userspace
ARM: EXYNOS: Remove broken config values for touchscren for NURI board
ARM: EXYNOS: set fix xusbxti clock for NURI and Universal210 boards
ARM: EXYNOS: fix regulator name for NURI board
ARM: SAMSUNG: make SAMSUNG_PM_DEBUG select DEBUG_LL
cpufreq: OMAP: fix build errors: depends on ARCH_OMAP2PLUS
sparc64: Eliminate obsolete __handle_softirq() function
sparc64: Fix bootup crash on sun4v.
ARM: msm: Fix section mismatches in proc_comm.c
...
Diffstat (limited to 'arch/arm')
1447 files changed, 31799 insertions, 22075 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index dfb0312f4e73..cf006d40342c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -9,6 +9,7 @@ config ARM select SYS_SUPPORTS_APM_EMULATION select GENERIC_ATOMIC64 if (CPU_V6 || !CPU_32v6K || !AEABI) select HAVE_OPROFILE if (HAVE_PERF_EVENTS) + select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL select HAVE_ARCH_KGDB select HAVE_KPROBES if !XIP_KERNEL select HAVE_KRETPROBES if (HAVE_KPROBES) @@ -21,6 +22,7 @@ config ARM select HAVE_KERNEL_GZIP select HAVE_KERNEL_LZO select HAVE_KERNEL_LZMA + select HAVE_KERNEL_XZ select HAVE_IRQ_WORK select HAVE_PERF_EVENTS select PERF_USE_VMALLOC @@ -28,10 +30,10 @@ config ARM select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7)) select HAVE_C_RECORDMCOUNT select HAVE_GENERIC_HARDIRQS - select HAVE_SPARSE_IRQ select GENERIC_IRQ_SHOW select CPU_PM if (SUSPEND || CPU_IDLE) select GENERIC_PCI_IOMAP + select HAVE_BPF_JIT if NET help The ARM series is a line of low-power-consumption RISC chip designs licensed by ARM Ltd and targeted at embedded applications and @@ -52,9 +54,6 @@ config MIGHT_HAVE_PCI config SYS_SUPPORTS_APM_EMULATION bool -config HAVE_SCHED_CLOCK - bool - config GENERIC_GPIO bool @@ -180,12 +179,18 @@ config ZONE_DMA config NEED_DMA_MAP_STATE def_bool y +config ARCH_HAS_DMA_SET_COHERENT_MASK + bool + config GENERIC_ISA_DMA bool config FIQ bool +config NEED_RET_TO_USER + bool + config ARCH_MTD_XIP bool @@ -214,6 +219,13 @@ config ARM_PATCH_PHYS_VIRT this feature (eg, building a kernel for a single machine) and you need to shrink the kernel to the minimal size. +config NEED_MACH_IO_H + bool + help + Select this when mach/io.h is required to provide special + definitions for this platform. The need for mach/io.h should + be avoided when possible. + config NEED_MACH_MEMORY_H bool help @@ -265,7 +277,9 @@ config ARCH_INTEGRATOR select GENERIC_CLOCKEVENTS select PLAT_VERSATILE select PLAT_VERSATILE_FPGA_IRQ + select NEED_MACH_IO_H select NEED_MACH_MEMORY_H + select SPARSE_IRQ help Support for ARM's Integrator platform. @@ -312,6 +326,7 @@ config ARCH_VEXPRESS select HAVE_CLK select HAVE_PATA_PLATFORM select ICST + select NO_IOPORT select PLAT_VERSATILE select PLAT_VERSATILE_CLCD help @@ -322,9 +337,11 @@ config ARCH_AT91 select ARCH_REQUIRE_GPIOLIB select HAVE_CLK select CLKDEV_LOOKUP + select IRQ_DOMAIN + select NEED_MACH_IO_H if PCCARD help This enables support for systems based on the Atmel AT91RM9200, - AT91SAM9 and AT91CAP9 processors. + AT91SAM9 processors. config ARCH_BCMRING bool "Broadcom BCMRING" @@ -350,6 +367,7 @@ config ARCH_HIGHBANK select GENERIC_CLOCKEVENTS select HAVE_ARM_SCU select HAVE_SMP + select SPARSE_IRQ select USE_OF help Support for the Calxeda Highbank SoC based boards. @@ -400,6 +418,7 @@ config ARCH_EBSA110 select ISA select NO_IOPORT select ARCH_USES_GETTIMEOFFSET + select NEED_MACH_IO_H select NEED_MACH_MEMORY_H help This is an evaluation board for the StrongARM processor available @@ -426,6 +445,7 @@ config ARCH_FOOTBRIDGE select FOOTBRIDGE select GENERIC_CLOCKEVENTS select HAVE_IDE + select NEED_MACH_IO_H select NEED_MACH_MEMORY_H help Support for systems based on the DC21285 companion chip @@ -438,7 +458,6 @@ config ARCH_MXC select CLKDEV_LOOKUP select CLKSRC_MMIO select GENERIC_IRQ_CHIP - select HAVE_SCHED_CLOCK select MULTI_IRQ_HANDLER help Support for Freescale MXC/iMX-based family of processors @@ -478,7 +497,9 @@ config ARCH_IOP13XX select PCI select ARCH_SUPPORTS_MSI select VMSPLIT_1G + select NEED_MACH_IO_H select NEED_MACH_MEMORY_H + select NEED_RET_TO_USER help Support for Intel's IOP13XX (XScale) family of processors. @@ -486,6 +507,8 @@ config ARCH_IOP32X bool "IOP32x-based" depends on MMU select CPU_XSCALE + select NEED_MACH_IO_H + select NEED_RET_TO_USER select PLAT_IOP select PCI select ARCH_REQUIRE_GPIOLIB @@ -497,6 +520,8 @@ config ARCH_IOP33X bool "IOP33x-based" depends on MMU select CPU_XSCALE + select NEED_MACH_IO_H + select NEED_RET_TO_USER select PLAT_IOP select PCI select ARCH_REQUIRE_GPIOLIB @@ -509,6 +534,7 @@ config ARCH_IXP23XX select CPU_XSC3 select PCI select ARCH_USES_GETTIMEOFFSET + select NEED_MACH_IO_H select NEED_MACH_MEMORY_H help Support for Intel's IXP23xx (XScale) family of processors. @@ -519,6 +545,7 @@ config ARCH_IXP2000 select CPU_XSCALE select PCI select ARCH_USES_GETTIMEOFFSET + select NEED_MACH_IO_H select NEED_MACH_MEMORY_H help Support for Intel's IXP2400/2800 (XScale) family of processors. @@ -526,12 +553,13 @@ config ARCH_IXP2000 config ARCH_IXP4XX bool "IXP4xx-based" depends on MMU + select ARCH_HAS_DMA_SET_COHERENT_MASK select CLKSRC_MMIO select CPU_XSCALE select GENERIC_GPIO select GENERIC_CLOCKEVENTS - select HAVE_SCHED_CLOCK select MIGHT_HAVE_PCI + select NEED_MACH_IO_H select DMABOUNCE if PCI help Support for Intel's IXP4XX (XScale) family of processors. @@ -542,6 +570,7 @@ config ARCH_DOVE select PCI select ARCH_REQUIRE_GPIOLIB select GENERIC_CLOCKEVENTS + select NEED_MACH_IO_H select PLAT_ORION help Support for the Marvell Dove SoC 88AP510 @@ -552,6 +581,7 @@ config ARCH_KIRKWOOD select PCI select ARCH_REQUIRE_GPIOLIB select GENERIC_CLOCKEVENTS + select NEED_MACH_IO_H select PLAT_ORION help Support for the following Marvell Kirkwood series SoCs: @@ -576,6 +606,7 @@ config ARCH_MV78XX0 select PCI select ARCH_REQUIRE_GPIOLIB select GENERIC_CLOCKEVENTS + select NEED_MACH_IO_H select PLAT_ORION help Support for the following Marvell MV78xx0 series SoCs: @@ -601,7 +632,6 @@ config ARCH_MMP select CLKDEV_LOOKUP select GENERIC_CLOCKEVENTS select GPIO_PXA - select HAVE_SCHED_CLOCK select TICK_ONESHOT select PLAT_PXA select SPARSE_IRQ @@ -642,9 +672,9 @@ config ARCH_TEGRA select GENERIC_CLOCKEVENTS select GENERIC_GPIO select HAVE_CLK - select HAVE_SCHED_CLOCK select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 + select NEED_MACH_IO_H if PCI select ARCH_HAS_CPUFREQ help This enables support for NVIDIA Tegra based systems (Tegra APX, @@ -659,7 +689,6 @@ config ARCH_PICOXCELL select DW_APB_TIMER select GENERIC_CLOCKEVENTS select GENERIC_GPIO - select HAVE_SCHED_CLOCK select HAVE_TCM select NO_IOPORT select SPARSE_IRQ @@ -687,7 +716,6 @@ config ARCH_PXA select ARCH_REQUIRE_GPIOLIB select GENERIC_CLOCKEVENTS select GPIO_PXA - select HAVE_SCHED_CLOCK select TICK_ONESHOT select PLAT_PXA select SPARSE_IRQ @@ -731,7 +759,6 @@ config ARCH_RPC bool "RiscPC" select ARCH_ACORN select FIQ - select TIMER_ACORN select ARCH_MAY_HAVE_PC_FDC select HAVE_PATA_PLATFORM select ISA_DMA_API @@ -739,6 +766,7 @@ config ARCH_RPC select ARCH_SPARSEMEM_ENABLE select ARCH_USES_GETTIMEOFFSET select HAVE_IDE + select NEED_MACH_IO_H select NEED_MACH_MEMORY_H help On the Acorn Risc-PC, Linux can support the internal IDE disk and @@ -754,31 +782,31 @@ config ARCH_SA1100 select ARCH_HAS_CPUFREQ select CPU_FREQ select GENERIC_CLOCKEVENTS - select HAVE_CLK - select HAVE_SCHED_CLOCK + select CLKDEV_LOOKUP select TICK_ONESHOT select ARCH_REQUIRE_GPIOLIB select HAVE_IDE select NEED_MACH_MEMORY_H + select SPARSE_IRQ help Support for StrongARM 11x0 based boards. -config ARCH_S3C2410 - bool "Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443, S3C2450" +config ARCH_S3C24XX + bool "Samsung S3C24XX SoCs" select GENERIC_GPIO select ARCH_HAS_CPUFREQ select HAVE_CLK select CLKDEV_LOOKUP select ARCH_USES_GETTIMEOFFSET select HAVE_S3C2410_I2C if I2C + select HAVE_S3C_RTC if RTC_CLASS + select HAVE_S3C2410_WATCHDOG if WATCHDOG + select NEED_MACH_IO_H help - Samsung S3C2410X CPU based systems, such as the Simtec Electronics - BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or - the Samsung SMDK2410 development board (and derivatives). - - Note, the S3C2416 and the S3C2450 are so close that they even share - the same SoC ID code. This means that there is no separate machine - directory (no arch/arm/mach-s3c2450) as the S3C2416 was first. + Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443 + and S3C2450 SoCs based systems, such as the Simtec Electronics BAST + (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or the + Samsung SMDK2410 development board (and derivatives). config ARCH_S3C64XX bool "Samsung S3C64XX" @@ -812,7 +840,6 @@ config ARCH_S5P64X0 select CLKSRC_MMIO select HAVE_S3C2410_WATCHDOG if WATCHDOG select GENERIC_CLOCKEVENTS - select HAVE_SCHED_CLOCK select HAVE_S3C2410_I2C if I2C select HAVE_S3C_RTC if RTC_CLASS help @@ -843,7 +870,6 @@ config ARCH_S5PV210 select CLKSRC_MMIO select ARCH_HAS_CPUFREQ select GENERIC_CLOCKEVENTS - select HAVE_SCHED_CLOCK select HAVE_S3C2410_I2C if I2C select HAVE_S3C_RTC if RTC_CLASS select HAVE_S3C2410_WATCHDOG if WATCHDOG @@ -877,6 +903,7 @@ config ARCH_SHARK select PCI select ARCH_USES_GETTIMEOFFSET select NEED_MACH_MEMORY_H + select NEED_MACH_IO_H help Support for the StrongARM based Digital DNARD machine, also known as "Shark" (<http://www.shark-linux.de/shark.html>). @@ -886,7 +913,6 @@ config ARCH_U300 depends on MMU select CLKSRC_MMIO select CPU_ARM926T - select HAVE_SCHED_CLOCK select HAVE_TCM select ARM_AMBA select ARM_PATCH_PHYS_VIRT @@ -901,6 +927,7 @@ config ARCH_U300 config ARCH_U8500 bool "ST-Ericsson U8500 Series" + depends on MMU select CPU_V7 select ARM_AMBA select GENERIC_CLOCKEVENTS @@ -944,7 +971,6 @@ config ARCH_OMAP select ARCH_HAS_CPUFREQ select CLKSRC_MMIO select GENERIC_CLOCKEVENTS - select HAVE_SCHED_CLOCK select ARCH_HAS_HOLES_MEMORYMODEL help Support for TI's OMAP platform (OMAP1/2/3/4). @@ -1066,12 +1092,10 @@ source "arch/arm/plat-s5p/Kconfig" source "arch/arm/plat-spear/Kconfig" -if ARCH_S3C2410 -source "arch/arm/mach-s3c2410/Kconfig" +source "arch/arm/mach-s3c24xx/Kconfig" +if ARCH_S3C24XX source "arch/arm/mach-s3c2412/Kconfig" -source "arch/arm/mach-s3c2416/Kconfig" source "arch/arm/mach-s3c2440/Kconfig" -source "arch/arm/mach-s3c2443/Kconfig" endif if ARCH_S3C64XX @@ -1110,13 +1134,11 @@ config ARCH_ACORN config PLAT_IOP bool select GENERIC_CLOCKEVENTS - select HAVE_SCHED_CLOCK config PLAT_ORION bool select CLKSRC_MMIO select GENERIC_IRQ_CHIP - select HAVE_SCHED_CLOCK config PLAT_PXA bool @@ -1127,6 +1149,7 @@ config PLAT_VERSATILE config ARM_TIMER_SP804 bool select CLKSRC_MMIO + select HAVE_SCHED_CLOCK source arch/arm/mm/Kconfig @@ -1577,7 +1600,8 @@ config LOCAL_TIMERS config ARCH_NR_GPIO int default 1024 if ARCH_SHMOBILE || ARCH_TEGRA - default 350 if ARCH_U8500 + default 355 if ARCH_U8500 + default 264 if MACH_H4700 default 0 help Maximum number of GPIOs in the system. @@ -1588,7 +1612,7 @@ source kernel/Kconfig.preempt config HZ int - default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P64X0 || \ + default 200 if ARCH_EBSA110 || ARCH_S3C24XX || ARCH_S5P64X0 || \ ARCH_S5PV210 || ARCH_EXYNOS4 default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER default AT91_TIMER_HZ if ARCH_AT91 @@ -2114,7 +2138,7 @@ config CPU_FREQ_S3C config CPU_FREQ_S3C24XX bool "CPUfreq driver for Samsung S3C24XX series CPUs (EXPERIMENTAL)" - depends on ARCH_S3C2410 && CPU_FREQ && EXPERIMENTAL + depends on ARCH_S3C24XX && CPU_FREQ && EXPERIMENTAL select CPU_FREQ_S3C help This enables the CPUfreq driver for the Samsung S3C24XX family diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index e0d236d7ff73..85348a09d655 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -81,47 +81,14 @@ choice prompt "Kernel low-level debugging port" depends on DEBUG_LL - config DEBUG_LL_UART_NONE - bool "No low-level debugging UART" - help - Say Y here if your platform doesn't provide a UART option - below. This relies on your platform choosing the right UART - definition internally in order for low-level debugging to - work. - - config DEBUG_ICEDCC - bool "Kernel low-level debugging via EmbeddedICE DCC channel" - help - Say Y here if you want the debug print routines to direct - their output to the EmbeddedICE macrocell's DCC channel using - co-processor 14. This is known to work on the ARM9 style ICE - channel and on the XScale with the PEEDI. - - Note that the system will appear to hang during boot if there - is nothing connected to read from the DCC. - config AT91_DEBUG_LL_DBGU0 bool "Kernel low-level debugging on rm9200, 9260/9g20, 9261/9g10 and 9rl" depends on HAVE_AT91_DBGU0 config AT91_DEBUG_LL_DBGU1 - bool "Kernel low-level debugging on 9263, 9g45 and cap9" + bool "Kernel low-level debugging on 9263 and 9g45" depends on HAVE_AT91_DBGU1 - config DEBUG_FOOTBRIDGE_COM1 - bool "Kernel low-level debugging messages via footbridge 8250 at PCI COM1" - depends on FOOTBRIDGE - help - Say Y here if you want the debug print routines to direct - their output to the 8250 at PCI COM1. - - config DEBUG_DC21285_PORT - bool "Kernel low-level debugging messages via footbridge serial port" - depends on FOOTBRIDGE - help - Say Y here if you want the debug print routines to direct - their output to the serial port in the DC21285 (Footbridge). - config DEBUG_CLPS711X_UART1 bool "Kernel low-level debugging messages via UART1" depends on ARCH_CLPS711X @@ -136,6 +103,20 @@ choice Say Y here if you want the debug print routines to direct their output to the second serial port on these devices. + config DEBUG_DC21285_PORT + bool "Kernel low-level debugging messages via footbridge serial port" + depends on FOOTBRIDGE + help + Say Y here if you want the debug print routines to direct + their output to the serial port in the DC21285 (Footbridge). + + config DEBUG_FOOTBRIDGE_COM1 + bool "Kernel low-level debugging messages via footbridge 8250 at PCI COM1" + depends on FOOTBRIDGE + help + Say Y here if you want the debug print routines to direct + their output to the 8250 at PCI COM1. + config DEBUG_HIGHBANK_UART bool "Kernel low-level debugging messages via Highbank UART" depends on ARCH_HIGHBANK @@ -199,45 +180,49 @@ choice Say Y here if you want kernel low-level debugging support on i.MX50 or i.MX53. - config DEBUG_IMX6Q_UART - bool "i.MX6Q Debug UART" + config DEBUG_IMX6Q_UART4 + bool "i.MX6Q Debug UART4" depends on SOC_IMX6Q help Say Y here if you want kernel low-level debugging support - on i.MX6Q. + on i.MX6Q UART4. - config DEBUG_S3C_UART0 - depends on PLAT_SAMSUNG - bool "Use S3C UART 0 for low-level debug" + config DEBUG_MSM_UART1 + bool "Kernel low-level debugging messages via MSM UART1" + depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50 help Say Y here if you want the debug print routines to direct - their output to UART 0. The port must have been initialised - by the boot-loader before use. - - The uncompressor code port configuration is now handled - by CONFIG_S3C_LOWLEVEL_UART_PORT. + their output to the first serial port on MSM devices. - config DEBUG_S3C_UART1 - depends on PLAT_SAMSUNG - bool "Use S3C UART 1 for low-level debug" + config DEBUG_MSM_UART2 + bool "Kernel low-level debugging messages via MSM UART2" + depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50 help Say Y here if you want the debug print routines to direct - their output to UART 1. The port must have been initialised - by the boot-loader before use. + their output to the second serial port on MSM devices. - The uncompressor code port configuration is now handled - by CONFIG_S3C_LOWLEVEL_UART_PORT. + config DEBUG_MSM_UART3 + bool "Kernel low-level debugging messages via MSM UART3" + depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50 + help + Say Y here if you want the debug print routines to direct + their output to the third serial port on MSM devices. - config DEBUG_S3C_UART2 - depends on PLAT_SAMSUNG - bool "Use S3C UART 2 for low-level debug" + config DEBUG_MSM8660_UART + bool "Kernel low-level debugging messages via MSM 8660 UART" + depends on ARCH_MSM8X60 + select MSM_HAS_DEBUG_UART_HS help Say Y here if you want the debug print routines to direct - their output to UART 2. The port must have been initialised - by the boot-loader before use. + their output to the serial port on MSM 8660 devices. - The uncompressor code port configuration is now handled - by CONFIG_S3C_LOWLEVEL_UART_PORT. + config DEBUG_MSM8960_UART + bool "Kernel low-level debugging messages via MSM 8960 UART" + depends on ARCH_MSM8960 + select MSM_HAS_DEBUG_UART_HS + help + Say Y here if you want the debug print routines to direct + their output to the serial port on MSM 8960 devices. config DEBUG_REALVIEW_STD_PORT bool "RealView Default UART" @@ -255,42 +240,73 @@ choice their output to the standard serial port on the RealView PB1176 platform. - config DEBUG_MSM_UART1 - bool "Kernel low-level debugging messages via MSM UART1" - depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50 + config DEBUG_S3C_UART0 + depends on PLAT_SAMSUNG + bool "Use S3C UART 0 for low-level debug" help Say Y here if you want the debug print routines to direct - their output to the first serial port on MSM devices. + their output to UART 0. The port must have been initialised + by the boot-loader before use. - config DEBUG_MSM_UART2 - bool "Kernel low-level debugging messages via MSM UART2" - depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50 + The uncompressor code port configuration is now handled + by CONFIG_S3C_LOWLEVEL_UART_PORT. + + config DEBUG_S3C_UART1 + depends on PLAT_SAMSUNG + bool "Use S3C UART 1 for low-level debug" help Say Y here if you want the debug print routines to direct - their output to the second serial port on MSM devices. + their output to UART 1. The port must have been initialised + by the boot-loader before use. - config DEBUG_MSM_UART3 - bool "Kernel low-level debugging messages via MSM UART3" - depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50 + The uncompressor code port configuration is now handled + by CONFIG_S3C_LOWLEVEL_UART_PORT. + + config DEBUG_S3C_UART2 + depends on PLAT_SAMSUNG + bool "Use S3C UART 2 for low-level debug" help Say Y here if you want the debug print routines to direct - their output to the third serial port on MSM devices. + their output to UART 2. The port must have been initialised + by the boot-loader before use. - config DEBUG_MSM8660_UART - bool "Kernel low-level debugging messages via MSM 8660 UART" - depends on ARCH_MSM8X60 - select MSM_HAS_DEBUG_UART_HS + The uncompressor code port configuration is now handled + by CONFIG_S3C_LOWLEVEL_UART_PORT. + + config DEBUG_LL_UART_NONE + bool "No low-level debugging UART" help - Say Y here if you want the debug print routines to direct - their output to the serial port on MSM 8660 devices. + Say Y here if your platform doesn't provide a UART option + below. This relies on your platform choosing the right UART + definition internally in order for low-level debugging to + work. - config DEBUG_MSM8960_UART - bool "Kernel low-level debugging messages via MSM 8960 UART" - depends on ARCH_MSM8960 - select MSM_HAS_DEBUG_UART_HS + config DEBUG_ICEDCC + bool "Kernel low-level debugging via EmbeddedICE DCC channel" help Say Y here if you want the debug print routines to direct - their output to the serial port on MSM 8960 devices. + their output to the EmbeddedICE macrocell's DCC channel using + co-processor 14. This is known to work on the ARM9 style ICE + channel and on the XScale with the PEEDI. + + Note that the system will appear to hang during boot if there + is nothing connected to read from the DCC. + + config DEBUG_SEMIHOSTING + bool "Kernel low-level debug output via semihosting I" + help + Semihosting enables code running on an ARM target to use + the I/O facilities on a host debugger/emulator through a + simple SVC calls. The host debugger or emulator must have + semihosting enabled for the special svc call to be trapped + otherwise the kernel will crash. + + This is known to work with OpenOCD, as wellas + ARM's Fast Models, or any other controlling environment + that implements semihosting. + + For more details about semihosting, please see + chapter 8 of DUI0203I_rvct_developer_guide.pdf from ARM Ltd. endchoice diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 1683bfb9166f..047a20780fc1 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -174,12 +174,13 @@ machine-$(CONFIG_ARCH_PRIMA2) := prima2 machine-$(CONFIG_ARCH_PXA) := pxa machine-$(CONFIG_ARCH_REALVIEW) := realview machine-$(CONFIG_ARCH_RPC) := rpc -machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2412 s3c2416 s3c2440 s3c2443 +machine-$(CONFIG_ARCH_S3C24XX) := s3c24xx s3c2412 s3c2440 machine-$(CONFIG_ARCH_S3C64XX) := s3c64xx machine-$(CONFIG_ARCH_S5P64X0) := s5p64x0 machine-$(CONFIG_ARCH_S5PC100) := s5pc100 machine-$(CONFIG_ARCH_S5PV210) := s5pv210 machine-$(CONFIG_ARCH_EXYNOS4) := exynos +machine-$(CONFIG_ARCH_EXYNOS5) := exynos machine-$(CONFIG_ARCH_SA1100) := sa1100 machine-$(CONFIG_ARCH_SHARK) := shark machine-$(CONFIG_ARCH_SHMOBILE) := shmobile @@ -252,6 +253,7 @@ core-$(CONFIG_VFP) += arch/arm/vfp/ # If we have a machine-specific directory, then include it in the build. core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/ +core-y += arch/arm/net/ core-y += $(machdirs) $(platdirs) drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/ diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index fc871e719aae..c877087d2000 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -11,8 +11,6 @@ # Copyright (C) 1995-2002 Russell King # -MKIMAGE := $(srctree)/scripts/mkuboot.sh - ifneq ($(MACHINE),) include $(srctree)/$(MACHINE)/Makefile.boot endif @@ -69,22 +67,19 @@ $(obj)/dtbs: $(addprefix $(obj)/, $(dtb-y)) clean-files := *.dtb -quiet_cmd_uimage = UIMAGE $@ - cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \ - -C none -a $(LOADADDR) -e $(STARTADDR) \ - -n 'Linux-$(KERNELRELEASE)' -d $< $@ - -ifeq ($(CONFIG_ZBOOT_ROM),y) -$(obj)/uImage: LOADADDR=$(CONFIG_ZBOOT_ROM_TEXT) +ifneq ($(LOADADDR),) + UIMAGE_LOADADDR=$(LOADADDR) else -$(obj)/uImage: LOADADDR=$(ZRELADDR) + ifeq ($(CONFIG_ZBOOT_ROM),y) + UIMAGE_LOADADDR=$(CONFIG_ZBOOT_ROM_TEXT) + else + UIMAGE_LOADADDR=$(ZRELADDR) + endif endif -$(obj)/uImage: STARTADDR=$(LOADADDR) - check_for_multiple_loadaddr = \ -if [ $(words $(LOADADDR)) -gt 1 ]; then \ - echo 'multiple load addresses: $(LOADADDR)'; \ +if [ $(words $(UIMAGE_LOADADDR)) -gt 1 ]; then \ + echo 'multiple load addresses: $(UIMAGE_LOADADDR)'; \ echo 'This is incompatible with uImages'; \ echo 'Specify LOADADDR on the commandline to build an uImage'; \ false; \ diff --git a/arch/arm/boot/compressed/.gitignore b/arch/arm/boot/compressed/.gitignore index e0936a148516..d0d441c429ae 100644 --- a/arch/arm/boot/compressed/.gitignore +++ b/arch/arm/boot/compressed/.gitignore @@ -1,8 +1,10 @@ +ashldi3.S font.c lib1funcs.S piggy.gzip piggy.lzo piggy.lzma +piggy.xzkern vmlinux vmlinux.lds diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index cf0a64ce4b83..bb267562e7ed 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -92,6 +92,7 @@ SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/ suffix_$(CONFIG_KERNEL_GZIP) = gzip suffix_$(CONFIG_KERNEL_LZO) = lzo suffix_$(CONFIG_KERNEL_LZMA) = lzma +suffix_$(CONFIG_KERNEL_XZ) = xzkern # Borrowed libfdt files for the ATAG compatibility mode @@ -112,10 +113,12 @@ endif targets := vmlinux vmlinux.lds \ piggy.$(suffix_y) piggy.$(suffix_y).o \ - lib1funcs.o lib1funcs.S font.o font.c head.o misc.o $(OBJS) + lib1funcs.o lib1funcs.S ashldi3.o ashldi3.S \ + font.o font.c head.o misc.o $(OBJS) # Make sure files are removed during clean -extra-y += piggy.gzip piggy.lzo piggy.lzma lib1funcs.S $(libfdt) $(libfdt_hdrs) +extra-y += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern \ + lib1funcs.S ashldi3.S $(libfdt) $(libfdt_hdrs) ifeq ($(CONFIG_FUNCTION_TRACER),y) ORIG_CFLAGS := $(KBUILD_CFLAGS) @@ -151,6 +154,12 @@ lib1funcs = $(obj)/lib1funcs.o $(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S $(call cmd,shipped) +# For __aeabi_llsl +ashldi3 = $(obj)/ashldi3.o + +$(obj)/ashldi3.S: $(srctree)/arch/$(SRCARCH)/lib/ashldi3.S + $(call cmd,shipped) + # We need to prevent any GOTOFF relocs being used with references # to symbols in the .bss section since we cannot relocate them # independently from the rest at run time. This can be achieved by @@ -172,7 +181,7 @@ if [ $(words $(ZRELADDR)) -gt 1 -a "$(CONFIG_AUTO_ZRELADDR)" = "" ]; then \ fi $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \ - $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE + $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) FORCE @$(check_for_multiple_zreladdr) $(call if_changed,ld) @$(check_for_bad_syms) diff --git a/arch/arm/boot/compressed/atags_to_fdt.c b/arch/arm/boot/compressed/atags_to_fdt.c index 6ce11c481178..797f04bedb47 100644 --- a/arch/arm/boot/compressed/atags_to_fdt.c +++ b/arch/arm/boot/compressed/atags_to_fdt.c @@ -77,6 +77,8 @@ int atags_to_fdt(void *atag_list, void *fdt, int total_space) } else if (atag->hdr.tag == ATAG_MEM) { if (memcount >= sizeof(mem_reg_property)/4) continue; + if (!atag->u.mem.size) + continue; mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.start); mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.size); } else if (atag->hdr.tag == ATAG_INITRD2) { diff --git a/arch/arm/boot/compressed/decompress.c b/arch/arm/boot/compressed/decompress.c index 07be5a2f8302..f41b38cafce8 100644 --- a/arch/arm/boot/compressed/decompress.c +++ b/arch/arm/boot/compressed/decompress.c @@ -44,6 +44,12 @@ extern void error(char *); #include "../../../../lib/decompress_unlzma.c" #endif +#ifdef CONFIG_KERNEL_XZ +#define memmove memmove +#define memcpy memcpy +#include "../../../../lib/decompress_unxz.c" +#endif + int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)) { return decompress(input, len, NULL, NULL, output, NULL, error); diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index c5d60250d43d..dc7e8ce8e6be 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -58,7 +58,7 @@ add \rb, \rb, #0x00010000 @ Ser1 #endif .endm -#elif defined(CONFIG_ARCH_S3C2410) +#elif defined(CONFIG_ARCH_S3C24XX) .macro loadsp, rb, tmp mov \rb, #0x50000000 add \rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT @@ -273,7 +273,7 @@ restart: adr r0, LC0 add r0, r0, #0x100 mov r1, r6 sub r2, sp, r6 - blne atags_to_fdt + bleq atags_to_fdt ldmfd sp!, {r0-r3, ip, lr} sub sp, sp, #0x10000 diff --git a/arch/arm/boot/compressed/piggy.xzkern.S b/arch/arm/boot/compressed/piggy.xzkern.S new file mode 100644 index 000000000000..5703f300d027 --- /dev/null +++ b/arch/arm/boot/compressed/piggy.xzkern.S @@ -0,0 +1,6 @@ + .section .piggydata,#alloc + .globl input_data +input_data: + .incbin "arch/arm/boot/compressed/piggy.xzkern" + .globl input_data_end +input_data_end: diff --git a/arch/arm/boot/dts/am3517_mt_ventoux.dts b/arch/arm/boot/dts/am3517_mt_ventoux.dts new file mode 100644 index 000000000000..5eb26d7d9b4e --- /dev/null +++ b/arch/arm/boot/dts/am3517_mt_ventoux.dts @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2011 Ilya Yanok, EmCraft Systems + * + * 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/ "omap3.dtsi" + +/ { + model = "TeeJet Mt.Ventoux"; + compatible = "teejet,mt_ventoux", "ti,omap3"; + + memory { + device_type = "memory"; + reg = <0x80000000 0x10000000>; /* 256 MB */ + }; + + /* AM35xx doesn't have IVA */ + soc { + iva { + status = "disabled"; + }; + }; +}; diff --git a/arch/arm/boot/dts/at91sam9g20.dtsi b/arch/arm/boot/dts/at91sam9g20.dtsi index 07603b8c9503..773ef484037a 100644 --- a/arch/arm/boot/dts/at91sam9g20.dtsi +++ b/arch/arm/boot/dts/at91sam9g20.dtsi @@ -23,6 +23,11 @@ serial4 = &usart3; serial5 = &usart4; serial6 = &usart5; + gpio0 = &pioA; + gpio1 = &pioB; + gpio2 = &pioC; + tcb0 = &tcb0; + tcb1 = &tcb1; }; cpus { cpu@0 { @@ -30,7 +35,7 @@ }; }; - memory@20000000 { + memory { reg = <0x20000000 0x08000000>; }; @@ -47,24 +52,88 @@ ranges; aic: interrupt-controller@fffff000 { - #interrupt-cells = <1>; + #interrupt-cells = <2>; compatible = "atmel,at91rm9200-aic"; interrupt-controller; - interrupt-parent; reg = <0xfffff000 0x200>; }; + ramc0: ramc@ffffea00 { + compatible = "atmel,at91sam9260-sdramc"; + reg = <0xffffea00 0x200>; + }; + + pmc: pmc@fffffc00 { + compatible = "atmel,at91rm9200-pmc"; + reg = <0xfffffc00 0x100>; + }; + + rstc@fffffd00 { + compatible = "atmel,at91sam9260-rstc"; + reg = <0xfffffd00 0x10>; + }; + + shdwc@fffffd10 { + compatible = "atmel,at91sam9260-shdwc"; + reg = <0xfffffd10 0x10>; + }; + + pit: timer@fffffd30 { + compatible = "atmel,at91sam9260-pit"; + reg = <0xfffffd30 0xf>; + interrupts = <1 4>; + }; + + tcb0: timer@fffa0000 { + compatible = "atmel,at91rm9200-tcb"; + reg = <0xfffa0000 0x100>; + interrupts = <17 4 18 4 19 4>; + }; + + tcb1: timer@fffdc000 { + compatible = "atmel,at91rm9200-tcb"; + reg = <0xfffdc000 0x100>; + interrupts = <26 4 27 4 28 4>; + }; + + pioA: gpio@fffff400 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff400 0x100>; + interrupts = <2 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + }; + + pioB: gpio@fffff600 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff600 0x100>; + interrupts = <3 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + }; + + pioC: gpio@fffff800 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff800 0x100>; + interrupts = <4 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + }; + dbgu: serial@fffff200 { compatible = "atmel,at91sam9260-usart"; reg = <0xfffff200 0x200>; - interrupts = <1>; + interrupts = <1 4>; status = "disabled"; }; usart0: serial@fffb0000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfffb0000 0x200>; - interrupts = <6>; + interrupts = <6 4>; atmel,use-dma-rx; atmel,use-dma-tx; status = "disabled"; @@ -73,7 +142,7 @@ usart1: serial@fffb4000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfffb4000 0x200>; - interrupts = <7>; + interrupts = <7 4>; atmel,use-dma-rx; atmel,use-dma-tx; status = "disabled"; @@ -82,7 +151,7 @@ usart2: serial@fffb8000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfffb8000 0x200>; - interrupts = <8>; + interrupts = <8 4>; atmel,use-dma-rx; atmel,use-dma-tx; status = "disabled"; @@ -91,7 +160,7 @@ usart3: serial@fffd0000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfffd0000 0x200>; - interrupts = <23>; + interrupts = <23 4>; atmel,use-dma-rx; atmel,use-dma-tx; status = "disabled"; @@ -100,7 +169,7 @@ usart4: serial@fffd4000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfffd4000 0x200>; - interrupts = <24>; + interrupts = <24 4>; atmel,use-dma-rx; atmel,use-dma-tx; status = "disabled"; @@ -109,7 +178,7 @@ usart5: serial@fffd8000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfffd8000 0x200>; - interrupts = <25>; + interrupts = <25 4>; atmel,use-dma-rx; atmel,use-dma-tx; status = "disabled"; @@ -118,9 +187,52 @@ macb0: ethernet@fffc4000 { compatible = "cdns,at32ap7000-macb", "cdns,macb"; reg = <0xfffc4000 0x100>; - interrupts = <21>; + interrupts = <21 4>; + status = "disabled"; + }; + + usb1: gadget@fffa4000 { + compatible = "atmel,at91rm9200-udc"; + reg = <0xfffa4000 0x4000>; + interrupts = <10 4>; status = "disabled"; }; }; + + nand0: nand@40000000 { + compatible = "atmel,at91rm9200-nand"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x40000000 0x10000000 + 0xffffe800 0x200 + >; + atmel,nand-addr-offset = <21>; + atmel,nand-cmd-offset = <22>; + gpios = <&pioC 13 0 + &pioC 14 0 + 0 + >; + status = "disabled"; + }; + + usb0: ohci@00500000 { + compatible = "atmel,at91rm9200-ohci", "usb-ohci"; + reg = <0x00500000 0x100000>; + interrupts = <20 4>; + status = "disabled"; + }; + }; + + i2c@0 { + compatible = "i2c-gpio"; + gpios = <&pioA 23 0 /* sda */ + &pioA 24 0 /* scl */ + >; + i2c-gpio,sda-open-drain; + i2c-gpio,scl-open-drain; + i2c-gpio,delay-us = <2>; /* ~100 kHz */ + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/at91sam9g25ek.dts b/arch/arm/boot/dts/at91sam9g25ek.dts new file mode 100644 index 000000000000..7829a4d0cb22 --- /dev/null +++ b/arch/arm/boot/dts/at91sam9g25ek.dts @@ -0,0 +1,49 @@ +/* + * at91sam9g25ek.dts - Device Tree file for AT91SAM9G25-EK board + * + * Copyright (C) 2012 Atmel, + * 2012 Nicolas Ferre <nicolas.ferre@atmel.com> + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +/include/ "at91sam9x5.dtsi" +/include/ "at91sam9x5cm.dtsi" + +/ { + model = "Atmel AT91SAM9G25-EK"; + compatible = "atmel,at91sam9g25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9"; + + chosen { + bootargs = "128M console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs"; + }; + + ahb { + apb { + dbgu: serial@fffff200 { + status = "okay"; + }; + + usart0: serial@f801c000 { + status = "okay"; + }; + + macb0: ethernet@f802c000 { + phy-mode = "rmii"; + status = "okay"; + }; + }; + + usb0: ohci@00600000 { + status = "okay"; + num-ports = <2>; + atmel,vbus-gpio = <&pioD 19 1 + &pioD 20 1 + >; + }; + + usb1: ehci@00700000 { + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index fffa005300a4..c8042147eaa2 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -22,6 +22,13 @@ serial2 = &usart1; serial3 = &usart2; serial4 = &usart3; + gpio0 = &pioA; + gpio1 = &pioB; + gpio2 = &pioC; + gpio3 = &pioD; + gpio4 = &pioE; + tcb0 = &tcb0; + tcb1 = &tcb1; }; cpus { cpu@0 { @@ -29,7 +36,7 @@ }; }; - memory@70000000 { + memory { reg = <0x70000000 0x10000000>; }; @@ -46,30 +53,114 @@ ranges; aic: interrupt-controller@fffff000 { - #interrupt-cells = <1>; + #interrupt-cells = <2>; compatible = "atmel,at91rm9200-aic"; interrupt-controller; - interrupt-parent; reg = <0xfffff000 0x200>; }; + ramc0: ramc@ffffe400 { + compatible = "atmel,at91sam9g45-ddramc"; + reg = <0xffffe400 0x200 + 0xffffe600 0x200>; + }; + + pmc: pmc@fffffc00 { + compatible = "atmel,at91rm9200-pmc"; + reg = <0xfffffc00 0x100>; + }; + + rstc@fffffd00 { + compatible = "atmel,at91sam9g45-rstc"; + reg = <0xfffffd00 0x10>; + }; + + pit: timer@fffffd30 { + compatible = "atmel,at91sam9260-pit"; + reg = <0xfffffd30 0xf>; + interrupts = <1 4>; + }; + + + shdwc@fffffd10 { + compatible = "atmel,at91sam9rl-shdwc"; + reg = <0xfffffd10 0x10>; + }; + + tcb0: timer@fff7c000 { + compatible = "atmel,at91rm9200-tcb"; + reg = <0xfff7c000 0x100>; + interrupts = <18 4>; + }; + + tcb1: timer@fffd4000 { + compatible = "atmel,at91rm9200-tcb"; + reg = <0xfffd4000 0x100>; + interrupts = <18 4>; + }; + dma: dma-controller@ffffec00 { compatible = "atmel,at91sam9g45-dma"; reg = <0xffffec00 0x200>; - interrupts = <21>; + interrupts = <21 4>; + }; + + pioA: gpio@fffff200 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff200 0x100>; + interrupts = <2 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + }; + + pioB: gpio@fffff400 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff400 0x100>; + interrupts = <3 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + }; + + pioC: gpio@fffff600 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff600 0x100>; + interrupts = <4 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + }; + + pioD: gpio@fffff800 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff800 0x100>; + interrupts = <5 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + }; + + pioE: gpio@fffffa00 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffffa00 0x100>; + interrupts = <5 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; }; dbgu: serial@ffffee00 { compatible = "atmel,at91sam9260-usart"; reg = <0xffffee00 0x200>; - interrupts = <1>; + interrupts = <1 4>; status = "disabled"; }; usart0: serial@fff8c000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfff8c000 0x200>; - interrupts = <7>; + interrupts = <7 4>; atmel,use-dma-rx; atmel,use-dma-tx; status = "disabled"; @@ -78,7 +169,7 @@ usart1: serial@fff90000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfff90000 0x200>; - interrupts = <8>; + interrupts = <8 4>; atmel,use-dma-rx; atmel,use-dma-tx; status = "disabled"; @@ -87,7 +178,7 @@ usart2: serial@fff94000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfff94000 0x200>; - interrupts = <9>; + interrupts = <9 4>; atmel,use-dma-rx; atmel,use-dma-tx; status = "disabled"; @@ -96,7 +187,7 @@ usart3: serial@fff98000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfff98000 0x200>; - interrupts = <10>; + interrupts = <10 4>; atmel,use-dma-rx; atmel,use-dma-tx; status = "disabled"; @@ -105,9 +196,52 @@ macb0: ethernet@fffbc000 { compatible = "cdns,at32ap7000-macb", "cdns,macb"; reg = <0xfffbc000 0x100>; - interrupts = <25>; + interrupts = <25 4>; status = "disabled"; }; }; + + nand0: nand@40000000 { + compatible = "atmel,at91rm9200-nand"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x40000000 0x10000000 + 0xffffe200 0x200 + >; + atmel,nand-addr-offset = <21>; + atmel,nand-cmd-offset = <22>; + gpios = <&pioC 8 0 + &pioC 14 0 + 0 + >; + status = "disabled"; + }; + + usb0: ohci@00700000 { + compatible = "atmel,at91rm9200-ohci", "usb-ohci"; + reg = <0x00700000 0x100000>; + interrupts = <22 4>; + status = "disabled"; + }; + + usb1: ehci@00800000 { + compatible = "atmel,at91sam9g45-ehci", "usb-ehci"; + reg = <0x00800000 0x100000>; + interrupts = <22 4>; + status = "disabled"; + }; + }; + + i2c@0 { + compatible = "i2c-gpio"; + gpios = <&pioA 20 0 /* sda */ + &pioA 21 0 /* scl */ + >; + i2c-gpio,sda-open-drain; + i2c-gpio,scl-open-drain; + i2c-gpio,delay-us = <5>; /* ~100 kHz */ + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts index a387e7704ce1..a3633bd13111 100644 --- a/arch/arm/boot/dts/at91sam9m10g45ek.dts +++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts @@ -14,13 +14,24 @@ compatible = "atmel,at91sam9m10g45ek", "atmel,at91sam9g45", "atmel,at91sam9"; chosen { - bootargs = "mem=64M console=ttyS0,115200 mtdparts=atmel_nand:4M(bootstrap/uboot/kernel)ro,60M(rootfs),-(data) root=/dev/mtdblock1 rw rootfstype=jffs2"; + bootargs = "mem=64M console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=jffs2"; }; - memory@70000000 { + memory { reg = <0x70000000 0x4000000>; }; + clocks { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + main_clock: clock@0 { + compatible = "atmel,osc", "fixed-clock"; + clock-frequency = <12000000>; + }; + }; + ahb { apb { dbgu: serial@ffffee00 { @@ -36,5 +47,110 @@ status = "okay"; }; }; + + nand0: nand@40000000 { + nand-bus-width = <8>; + nand-ecc-mode = "soft"; + nand-on-flash-bbt; + status = "okay"; + + boot@0 { + label = "bootstrap/uboot/kernel"; + reg = <0x0 0x400000>; + }; + + rootfs@400000 { + label = "rootfs"; + reg = <0x400000 0x3C00000>; + }; + + data@4000000 { + label = "data"; + reg = <0x4000000 0xC000000>; + }; + }; + + usb0: ohci@00700000 { + status = "okay"; + num-ports = <2>; + atmel,vbus-gpio = <&pioD 1 1 + &pioD 3 1>; + }; + + usb1: ehci@00800000 { + status = "okay"; + }; + }; + + leds { + compatible = "gpio-leds"; + + d8 { + label = "d8"; + gpios = <&pioD 30 0>; + linux,default-trigger = "heartbeat"; + }; + + d6 { + label = "d6"; + gpios = <&pioD 0 1>; + linux,default-trigger = "nand-disk"; + }; + + d7 { + label = "d7"; + gpios = <&pioD 31 1>; + linux,default-trigger = "mmc0"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + left_click { + label = "left_click"; + gpios = <&pioB 6 1>; + linux,code = <272>; + gpio-key,wakeup; + }; + + right_click { + label = "right_click"; + gpios = <&pioB 7 1>; + linux,code = <273>; + gpio-key,wakeup; + }; + + left { + label = "Joystick Left"; + gpios = <&pioB 14 1>; + linux,code = <105>; + }; + + right { + label = "Joystick Right"; + gpios = <&pioB 15 1>; + linux,code = <106>; + }; + + up { + label = "Joystick Up"; + gpios = <&pioB 16 1>; + linux,code = <103>; + }; + + down { + label = "Joystick Down"; + gpios = <&pioB 17 1>; + linux,code = <108>; + }; + + enter { + label = "Joystick Press"; + gpios = <&pioB 18 1>; + linux,code = <28>; + }; }; }; diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi new file mode 100644 index 000000000000..dd4ed748469a --- /dev/null +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -0,0 +1,263 @@ +/* + * at91sam9x5.dtsi - Device Tree Include file for AT91SAM9x5 family SoC + * applies to AT91SAM9G15, AT91SAM9G25, AT91SAM9G35, + * AT91SAM9X25, AT91SAM9X35 SoC + * + * Copyright (C) 2012 Atmel, + * 2012 Nicolas Ferre <nicolas.ferre@atmel.com> + * + * Licensed under GPLv2 or later. + */ + +/include/ "skeleton.dtsi" + +/ { + model = "Atmel AT91SAM9x5 family SoC"; + compatible = "atmel,at91sam9x5"; + interrupt-parent = <&aic>; + + aliases { + serial0 = &dbgu; + serial1 = &usart0; + serial2 = &usart1; + serial3 = &usart2; + gpio0 = &pioA; + gpio1 = &pioB; + gpio2 = &pioC; + gpio3 = &pioD; + tcb0 = &tcb0; + tcb1 = &tcb1; + }; + cpus { + cpu@0 { + compatible = "arm,arm926ejs"; + }; + }; + + memory { + reg = <0x20000000 0x10000000>; + }; + + ahb { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + apb { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + aic: interrupt-controller@fffff000 { + #interrupt-cells = <2>; + compatible = "atmel,at91rm9200-aic"; + interrupt-controller; + reg = <0xfffff000 0x200>; + }; + + ramc0: ramc@ffffe800 { + compatible = "atmel,at91sam9g45-ddramc"; + reg = <0xffffe800 0x200>; + }; + + pmc: pmc@fffffc00 { + compatible = "atmel,at91rm9200-pmc"; + reg = <0xfffffc00 0x100>; + }; + + rstc@fffffe00 { + compatible = "atmel,at91sam9g45-rstc"; + reg = <0xfffffe00 0x10>; + }; + + shdwc@fffffe10 { + compatible = "atmel,at91sam9x5-shdwc"; + reg = <0xfffffe10 0x10>; + }; + + pit: timer@fffffe30 { + compatible = "atmel,at91sam9260-pit"; + reg = <0xfffffe30 0xf>; + interrupts = <1 4>; + }; + + tcb0: timer@f8008000 { + compatible = "atmel,at91sam9x5-tcb"; + reg = <0xf8008000 0x100>; + interrupts = <17 4>; + }; + + tcb1: timer@f800c000 { + compatible = "atmel,at91sam9x5-tcb"; + reg = <0xf800c000 0x100>; + interrupts = <17 4>; + }; + + dma0: dma-controller@ffffec00 { + compatible = "atmel,at91sam9g45-dma"; + reg = <0xffffec00 0x200>; + interrupts = <20 4>; + }; + + dma1: dma-controller@ffffee00 { + compatible = "atmel,at91sam9g45-dma"; + reg = <0xffffee00 0x200>; + interrupts = <21 4>; + }; + + pioA: gpio@fffff400 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffff400 0x100>; + interrupts = <2 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + }; + + pioB: gpio@fffff600 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffff600 0x100>; + interrupts = <2 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + }; + + pioC: gpio@fffff800 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffff800 0x100>; + interrupts = <3 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + }; + + pioD: gpio@fffffa00 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffffa00 0x100>; + interrupts = <3 4>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + }; + + dbgu: serial@fffff200 { + compatible = "atmel,at91sam9260-usart"; + reg = <0xfffff200 0x200>; + interrupts = <1 4>; + status = "disabled"; + }; + + usart0: serial@f801c000 { + compatible = "atmel,at91sam9260-usart"; + reg = <0xf801c000 0x200>; + interrupts = <5 4>; + atmel,use-dma-rx; + atmel,use-dma-tx; + status = "disabled"; + }; + + usart1: serial@f8020000 { + compatible = "atmel,at91sam9260-usart"; + reg = <0xf8020000 0x200>; + interrupts = <6 4>; + atmel,use-dma-rx; + atmel,use-dma-tx; + status = "disabled"; + }; + + usart2: serial@f8024000 { + compatible = "atmel,at91sam9260-usart"; + reg = <0xf8024000 0x200>; + interrupts = <7 4>; + atmel,use-dma-rx; + atmel,use-dma-tx; + status = "disabled"; + }; + + macb0: ethernet@f802c000 { + compatible = "cdns,at32ap7000-macb", "cdns,macb"; + reg = <0xf802c000 0x100>; + interrupts = <24 4>; + status = "disabled"; + }; + + macb1: ethernet@f8030000 { + compatible = "cdns,at32ap7000-macb", "cdns,macb"; + reg = <0xf8030000 0x100>; + interrupts = <27 4>; + status = "disabled"; + }; + }; + + nand0: nand@40000000 { + compatible = "atmel,at91rm9200-nand"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x40000000 0x10000000 + >; + atmel,nand-addr-offset = <21>; + atmel,nand-cmd-offset = <22>; + gpios = <&pioD 5 0 + &pioD 4 0 + 0 + >; + status = "disabled"; + }; + + usb0: ohci@00600000 { + compatible = "atmel,at91rm9200-ohci", "usb-ohci"; + reg = <0x00600000 0x100000>; + interrupts = <22 4>; + status = "disabled"; + }; + + usb1: ehci@00700000 { + compatible = "atmel,at91sam9g45-ehci", "usb-ehci"; + reg = <0x00700000 0x100000>; + interrupts = <22 4>; + status = "disabled"; + }; + }; + + i2c@0 { + compatible = "i2c-gpio"; + gpios = <&pioA 30 0 /* sda */ + &pioA 31 0 /* scl */ + >; + i2c-gpio,sda-open-drain; + i2c-gpio,scl-open-drain; + i2c-gpio,delay-us = <2>; /* ~100 kHz */ + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c@1 { + compatible = "i2c-gpio"; + gpios = <&pioC 0 0 /* sda */ + &pioC 1 0 /* scl */ + >; + i2c-gpio,sda-open-drain; + i2c-gpio,scl-open-drain; + i2c-gpio,delay-us = <2>; /* ~100 kHz */ + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c@2 { + compatible = "i2c-gpio"; + gpios = <&pioB 4 0 /* sda */ + &pioB 5 0 /* scl */ + >; + i2c-gpio,sda-open-drain; + i2c-gpio,scl-open-drain; + i2c-gpio,delay-us = <2>; /* ~100 kHz */ + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; +}; diff --git a/arch/arm/boot/dts/at91sam9x5cm.dtsi b/arch/arm/boot/dts/at91sam9x5cm.dtsi new file mode 100644 index 000000000000..31e7be23703d --- /dev/null +++ b/arch/arm/boot/dts/at91sam9x5cm.dtsi @@ -0,0 +1,74 @@ +/* + * at91sam9x5cm.dtsi - Device Tree Include file for AT91SAM9x5 CPU Module + * + * Copyright (C) 2012 Atmel, + * 2012 Nicolas Ferre <nicolas.ferre@atmel.com> + * + * Licensed under GPLv2 or later. + */ + +/ { + memory { + reg = <0x20000000 0x8000000>; + }; + + clocks { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + main_clock: clock@0 { + compatible = "atmel,osc", "fixed-clock"; + clock-frequency = <12000000>; + }; + }; + + ahb { + nand0: nand@40000000 { + nand-bus-width = <8>; + nand-ecc-mode = "soft"; + nand-on-flash-bbt; + status = "okay"; + + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x40000>; + }; + + uboot@40000 { + label = "u-boot"; + reg = <0x40000 0x80000>; + }; + + ubootenv@c0000 { + label = "U-Boot Env"; + reg = <0xc0000 0x140000>; + }; + + kernel@200000 { + label = "kernel"; + reg = <0x200000 0x600000>; + }; + + rootfs@800000 { + label = "rootfs"; + reg = <0x800000 0x1f800000>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + + pb18 { + label = "pb18"; + gpios = <&pioB 18 1>; + linux,default-trigger = "heartbeat"; + }; + + pd21 { + label = "pd21"; + gpios = <&pioD 21 0>; + }; + }; +}; diff --git a/arch/arm/boot/dts/db8500.dtsi b/arch/arm/boot/dts/db8500.dtsi new file mode 100644 index 000000000000..14bc30705099 --- /dev/null +++ b/arch/arm/boot/dts/db8500.dtsi @@ -0,0 +1,274 @@ +/* + * Copyright 2012 Linaro Ltd + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/include/ "skeleton.dtsi" + +/ { + soc-u9500 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "stericsson,db8500"; + interrupt-parent = <&intc>; + ranges; + + intc: interrupt-controller@a0411000 { + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + #address-cells = <1>; + interrupt-controller; + reg = <0xa0411000 0x1000>, + <0xa0410100 0x100>; + }; + + L2: l2-cache { + compatible = "arm,pl310-cache"; + reg = <0xa0412000 0x1000>; + interrupts = <0 13 4>; + cache-unified; + cache-level = <2>; + }; + + pmu { + compatible = "arm,cortex-a9-pmu"; + interrupts = <0 7 0x4>; + }; + + timer@a0410600 { + compatible = "arm,cortex-a9-twd-timer"; + reg = <0xa0410600 0x20>; + interrupts = <1 13 0x304>; + }; + + rtc@80154000 { + compatible = "stericsson,db8500-rtc"; + reg = <0x80154000 0x1000>; + interrupts = <0 18 0x4>; + }; + + gpio0: gpio@8012e000 { + compatible = "stericsson,db8500-gpio", + "stmicroelectronics,nomadik-gpio"; + reg = <0x8012e000 0x80>; + interrupts = <0 119 0x4>; + supports-sleepmode; + gpio-controller; + }; + + gpio1: gpio@8012e080 { + compatible = "stericsson,db8500-gpio", + "stmicroelectronics,nomadik-gpio"; + reg = <0x8012e080 0x80>; + interrupts = <0 120 0x4>; + supports-sleepmode; + gpio-controller; + }; + + gpio2: gpio@8000e000 { + compatible = "stericsson,db8500-gpio", + "stmicroelectronics,nomadik-gpio"; + reg = <0x8000e000 0x80>; + interrupts = <0 121 0x4>; + supports-sleepmode; + gpio-controller; + }; + + gpio3: gpio@8000e080 { + compatible = "stericsson,db8500-gpio", + "stmicroelectronics,nomadik-gpio"; + reg = <0x8000e080 0x80>; + interrupts = <0 122 0x4>; + supports-sleepmode; + gpio-controller; + }; + + gpio4: gpio@8000e100 { + compatible = "stericsson,db8500-gpio", + "stmicroelectronics,nomadik-gpio"; + reg = <0x8000e100 0x80>; + interrupts = <0 123 0x4>; + supports-sleepmode; + gpio-controller; + }; + + gpio5: gpio@8000e180 { + compatible = "stericsson,db8500-gpio", + "stmicroelectronics,nomadik-gpio"; + reg = <0x8000e180 0x80>; + interrupts = <0 124 0x4>; + supports-sleepmode; + gpio-controller; + }; + + gpio6: gpio@8011e000 { + compatible = "stericsson,db8500-gpio", + "stmicroelectronics,nomadik-gpio"; + reg = <0x8011e000 0x80>; + interrupts = <0 125 0x4>; + supports-sleepmode; + gpio-controller; + }; + + gpio7: gpio@8011e080 { + compatible = "stericsson,db8500-gpio", + "stmicroelectronics,nomadik-gpio"; + reg = <0x8011e080 0x80>; + interrupts = <0 126 0x4>; + supports-sleepmode; + gpio-controller; + }; + + gpio8: gpio@a03fe000 { + compatible = "stericsson,db8500-gpio", + "stmicroelectronics,nomadik-gpio"; + reg = <0xa03fe000 0x80>; + interrupts = <0 127 0x4>; + supports-sleepmode; + gpio-controller; + }; + + usb@a03e0000 { + compatible = "stericsson,db8500-musb", + "mentor,musb"; + reg = <0xa03e0000 0x10000>; + interrupts = <0 23 0x4>; + }; + + dma-controller@801C0000 { + compatible = "stericsson,db8500-dma40", + "stericsson,dma40"; + reg = <0x801C0000 0x1000 0x40010000 0x800>; + interrupts = <0 25 0x4>; + }; + + prcmu@80157000 { + compatible = "stericsson,db8500-prcmu"; + reg = <0x80157000 0x1000>; + interrupts = <46 47>; + #address-cells = <1>; + #size-cells = <0>; + + ab8500@5 { + compatible = "stericsson,ab8500"; + reg = <5>; /* mailbox 5 is i2c */ + interrupts = <0 40 0x4>; + }; + }; + + i2c@80004000 { + compatible = "stericsson,db8500-i2c", "stmicroelectronics,nomadik-i2c"; + reg = <0x80004000 0x1000>; + interrupts = <0 21 0x4>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c@80122000 { + compatible = "stericsson,db8500-i2c", "stmicroelectronics,nomadik-i2c"; + reg = <0x80122000 0x1000>; + interrupts = <0 22 0x4>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c@80128000 { + compatible = "stericsson,db8500-i2c", "stmicroelectronics,nomadik-i2c"; + reg = <0x80128000 0x1000>; + interrupts = <0 55 0x4>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c@80110000 { + compatible = "stericsson,db8500-i2c", "stmicroelectronics,nomadik-i2c"; + reg = <0x80110000 0x1000>; + interrupts = <0 12 0x4>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c@8012a000 { + compatible = "stericsson,db8500-i2c", "stmicroelectronics,nomadik-i2c"; + reg = <0x8012a000 0x1000>; + interrupts = <0 51 0x4>; + #address-cells = <1>; + #size-cells = <0>; + }; + + ssp@80002000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <80002000 0x1000>; + interrupts = <0 14 0x4>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + // Add one of these for each child device + cs-gpios = <&gpio0 31 &gpio4 14 &gpio4 16 &gpio6 22 &gpio7 0>; + + }; + + uart@80120000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x80120000 0x1000>; + interrupts = <0 11 0x4>; + status = "disabled"; + }; + uart@80121000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x80121000 0x1000>; + interrupts = <0 19 0x4>; + status = "disabled"; + }; + uart@80007000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x80007000 0x1000>; + interrupts = <0 26 0x4>; + status = "disabled"; + }; + + sdi@80126000 { + compatible = "arm,pl18x", "arm,primecell"; + reg = <0x80126000 0x1000>; + interrupts = <0 60 0x4>; + status = "disabled"; + }; + sdi@80118000 { + compatible = "arm,pl18x", "arm,primecell"; + reg = <0x80118000 0x1000>; + interrupts = <0 50 0x4>; + status = "disabled"; + }; + sdi@80005000 { + compatible = "arm,pl18x", "arm,primecell"; + reg = <0x80005000 0x1000>; + interrupts = <0 41 0x4>; + status = "disabled"; + }; + sdi@80119000 { + compatible = "arm,pl18x", "arm,primecell"; + reg = <0x80119000 0x1000>; + interrupts = <0 59 0x4>; + status = "disabled"; + }; + sdi@80114000 { + compatible = "arm,pl18x", "arm,primecell"; + reg = <0x80114000 0x1000>; + interrupts = <0 99 0x4>; + status = "disabled"; + }; + sdi@80008000 { + compatible = "arm,pl18x", "arm,primecell"; + reg = <0x80114000 0x1000>; + interrupts = <0 100 0x4>; + status = "disabled"; + }; + }; +}; diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts new file mode 100644 index 000000000000..399d17b231d2 --- /dev/null +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts @@ -0,0 +1,26 @@ +/* + * SAMSUNG SMDK5250 board device tree source + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.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/ "exynos5250.dtsi" + +/ { + model = "SAMSUNG SMDK5250 board based on EXYNOS5250"; + compatible = "samsung,smdk5250", "samsung,exynos5250"; + + memory { + reg = <0x40000000 0x80000000>; + }; + + chosen { + bootargs = "root=/dev/ram0 rw ramdisk=8192 console=ttySAC1,115200"; + }; +}; diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi new file mode 100644 index 000000000000..dfc433599436 --- /dev/null +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -0,0 +1,413 @@ +/* + * SAMSUNG EXYNOS5250 SoC device tree source + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * SAMSUNG EXYNOS5250 SoC device nodes are listed in this file. + * EXYNOS5250 based board files can include this file and provide + * values for board specfic bindings. + * + * Note: This file does not include device nodes for all the controllers in + * EXYNOS5250 SoC. As device tree coverage for EXYNOS5250 increases, + * additional nodes can be added to this file. + * + * 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/ "skeleton.dtsi" + +/ { + compatible = "samsung,exynos5250"; + interrupt-parent = <&gic>; + + gic:interrupt-controller@10490000 { + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x10490000 0x1000>, <0x10480000 0x100>; + }; + + watchdog { + compatible = "samsung,s3c2410-wdt"; + reg = <0x101D0000 0x100>; + interrupts = <0 42 0>; + }; + + rtc { + compatible = "samsung,s3c6410-rtc"; + reg = <0x101E0000 0x100>; + interrupts = <0 43 0>, <0 44 0>; + }; + + sdhci@12200000 { + compatible = "samsung,exynos4210-sdhci"; + reg = <0x12200000 0x100>; + interrupts = <0 75 0>; + }; + + sdhci@12210000 { + compatible = "samsung,exynos4210-sdhci"; + reg = <0x12210000 0x100>; + interrupts = <0 76 0>; + }; + + sdhci@12220000 { + compatible = "samsung,exynos4210-sdhci"; + reg = <0x12220000 0x100>; + interrupts = <0 77 0>; + }; + + sdhci@12230000 { + compatible = "samsung,exynos4210-sdhci"; + reg = <0x12230000 0x100>; + interrupts = <0 78 0>; + }; + + serial@12C00000 { + compatible = "samsung,exynos4210-uart"; + reg = <0x12C00000 0x100>; + interrupts = <0 51 0>; + }; + + serial@12C10000 { + compatible = "samsung,exynos4210-uart"; + reg = <0x12C10000 0x100>; + interrupts = <0 52 0>; + }; + + serial@12C20000 { + compatible = "samsung,exynos4210-uart"; + reg = <0x12C20000 0x100>; + interrupts = <0 53 0>; + }; + + serial@12C30000 { + compatible = "samsung,exynos4210-uart"; + reg = <0x12C30000 0x100>; + interrupts = <0 54 0>; + }; + + i2c@12C60000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x12C60000 0x100>; + interrupts = <0 56 0>; + }; + + i2c@12C70000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x12C70000 0x100>; + interrupts = <0 57 0>; + }; + + i2c@12C80000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x12C80000 0x100>; + interrupts = <0 58 0>; + }; + + i2c@12C90000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x12C90000 0x100>; + interrupts = <0 59 0>; + }; + + i2c@12CA0000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x12CA0000 0x100>; + interrupts = <0 60 0>; + }; + + i2c@12CB0000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x12CB0000 0x100>; + interrupts = <0 61 0>; + }; + + i2c@12CC0000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x12CC0000 0x100>; + interrupts = <0 62 0>; + }; + + i2c@12CD0000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x12CD0000 0x100>; + interrupts = <0 63 0>; + }; + + amba { + #address-cells = <1>; + #size-cells = <1>; + compatible = "arm,amba-bus"; + interrupt-parent = <&gic>; + ranges; + + pdma0: pdma@121A0000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x121A0000 0x1000>; + interrupts = <0 34 0>; + }; + + pdma1: pdma@121B0000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x121B0000 0x1000>; + interrupts = <0 35 0>; + }; + + mdma0: pdma@10800000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x10800000 0x1000>; + interrupts = <0 33 0>; + }; + + mdma1: pdma@11C10000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x11C10000 0x1000>; + interrupts = <0 124 0>; + }; + }; + + gpio-controllers { + #address-cells = <1>; + #size-cells = <1>; + gpio-controller; + ranges; + + gpa0: gpio-controller@11400000 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400000 0x20>; + #gpio-cells = <4>; + }; + + gpa1: gpio-controller@11400020 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400020 0x20>; + #gpio-cells = <4>; + }; + + gpa2: gpio-controller@11400040 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400040 0x20>; + #gpio-cells = <4>; + }; + + gpb0: gpio-controller@11400060 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400060 0x20>; + #gpio-cells = <4>; + }; + + gpb1: gpio-controller@11400080 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400080 0x20>; + #gpio-cells = <4>; + }; + + gpb2: gpio-controller@114000A0 { + compatible = "samsung,exynos4-gpio"; + reg = <0x114000A0 0x20>; + #gpio-cells = <4>; + }; + + gpb3: gpio-controller@114000C0 { + compatible = "samsung,exynos4-gpio"; + reg = <0x114000C0 0x20>; + #gpio-cells = <4>; + }; + + gpc0: gpio-controller@114000E0 { + compatible = "samsung,exynos4-gpio"; + reg = <0x114000E0 0x20>; + #gpio-cells = <4>; + }; + + gpc1: gpio-controller@11400100 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400100 0x20>; + #gpio-cells = <4>; + }; + + gpc2: gpio-controller@11400120 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400120 0x20>; + #gpio-cells = <4>; + }; + + gpc3: gpio-controller@11400140 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400140 0x20>; + #gpio-cells = <4>; + }; + + gpd0: gpio-controller@11400160 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400160 0x20>; + #gpio-cells = <4>; + }; + + gpd1: gpio-controller@11400180 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400180 0x20>; + #gpio-cells = <4>; + }; + + gpy0: gpio-controller@114001A0 { + compatible = "samsung,exynos4-gpio"; + reg = <0x114001A0 0x20>; + #gpio-cells = <4>; + }; + + gpy1: gpio-controller@114001C0 { + compatible = "samsung,exynos4-gpio"; + reg = <0x114001C0 0x20>; + #gpio-cells = <4>; + }; + + gpy2: gpio-controller@114001E0 { + compatible = "samsung,exynos4-gpio"; + reg = <0x114001E0 0x20>; + #gpio-cells = <4>; + }; + + gpy3: gpio-controller@11400200 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400200 0x20>; + #gpio-cells = <4>; + }; + + gpy4: gpio-controller@11400220 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400220 0x20>; + #gpio-cells = <4>; + }; + + gpy5: gpio-controller@11400240 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400240 0x20>; + #gpio-cells = <4>; + }; + + gpy6: gpio-controller@11400260 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400260 0x20>; + #gpio-cells = <4>; + }; + + gpx0: gpio-controller@11400C00 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400C00 0x20>; + #gpio-cells = <4>; + }; + + gpx1: gpio-controller@11400C20 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400C20 0x20>; + #gpio-cells = <4>; + }; + + gpx2: gpio-controller@11400C40 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400C40 0x20>; + #gpio-cells = <4>; + }; + + gpx3: gpio-controller@11400C60 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400C60 0x20>; + #gpio-cells = <4>; + }; + + gpe0: gpio-controller@13400000 { + compatible = "samsung,exynos4-gpio"; + reg = <0x13400000 0x20>; + #gpio-cells = <4>; + }; + + gpe1: gpio-controller@13400020 { + compatible = "samsung,exynos4-gpio"; + reg = <0x13400020 0x20>; + #gpio-cells = <4>; + }; + + gpf0: gpio-controller@13400040 { + compatible = "samsung,exynos4-gpio"; + reg = <0x13400040 0x20>; + #gpio-cells = <4>; + }; + + gpf1: gpio-controller@13400060 { + compatible = "samsung,exynos4-gpio"; + reg = <0x13400060 0x20>; + #gpio-cells = <4>; + }; + + gpg0: gpio-controller@13400080 { + compatible = "samsung,exynos4-gpio"; + reg = <0x13400080 0x20>; + #gpio-cells = <4>; + }; + + gpg1: gpio-controller@134000A0 { + compatible = "samsung,exynos4-gpio"; + reg = <0x134000A0 0x20>; + #gpio-cells = <4>; + }; + + gpg2: gpio-controller@134000C0 { + compatible = "samsung,exynos4-gpio"; + reg = <0x134000C0 0x20>; + #gpio-cells = <4>; + }; + + gph0: gpio-controller@134000E0 { + compatible = "samsung,exynos4-gpio"; + reg = <0x134000E0 0x20>; + #gpio-cells = <4>; + }; + + gph1: gpio-controller@13400100 { + compatible = "samsung,exynos4-gpio"; + reg = <0x13400100 0x20>; + #gpio-cells = <4>; + }; + + gpv0: gpio-controller@10D10000 { + compatible = "samsung,exynos4-gpio"; + reg = <0x10D10000 0x20>; + #gpio-cells = <4>; + }; + + gpv1: gpio-controller@10D10020 { + compatible = "samsung,exynos4-gpio"; + reg = <0x10D10020 0x20>; + #gpio-cells = <4>; + }; + + gpv2: gpio-controller@10D10040 { + compatible = "samsung,exynos4-gpio"; + reg = <0x10D10040 0x20>; + #gpio-cells = <4>; + }; + + gpv3: gpio-controller@10D10060 { + compatible = "samsung,exynos4-gpio"; + reg = <0x10D10060 0x20>; + #gpio-cells = <4>; + }; + + gpv4: gpio-controller@10D10080 { + compatible = "samsung,exynos4-gpio"; + reg = <0x10D10080 0x20>; + #gpio-cells = <4>; + }; + + gpz: gpio-controller@03860000 { + compatible = "samsung,exynos4-gpio"; + reg = <0x03860000 0x20>; + #gpio-cells = <4>; + }; + }; +}; diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts index 305635bd45c0..83e72294aefb 100644 --- a/arch/arm/boot/dts/highbank.dts +++ b/arch/arm/boot/dts/highbank.dts @@ -72,15 +72,15 @@ ranges; timer@fff10600 { - compatible = "arm,smp-twd"; + compatible = "arm,cortex-a9-twd-timer"; reg = <0xfff10600 0x20>; - interrupts = <1 13 0xf04>; + interrupts = <1 13 0xf01>; }; watchdog@fff10620 { - compatible = "arm,cortex-a9-wdt"; + compatible = "arm,cortex-a9-twd-wdt"; reg = <0xfff10620 0x20>; - interrupts = <1 14 0xf04>; + interrupts = <1 14 0xf01>; }; intc: interrupt-controller@fff11000 { @@ -89,7 +89,6 @@ #size-cells = <0>; #address-cells = <1>; interrupt-controller; - interrupt-parent; reg = <0xfff11000 0x1000>, <0xfff10100 0x100>; }; diff --git a/arch/arm/boot/dts/imx27-phytec-phycore.dts b/arch/arm/boot/dts/imx27-phytec-phycore.dts new file mode 100644 index 000000000000..a51a08fc2af9 --- /dev/null +++ b/arch/arm/boot/dts/imx27-phytec-phycore.dts @@ -0,0 +1,76 @@ +/* + * Copyright 2012 Sascha Hauer, Pengutronix + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +/include/ "imx27.dtsi" + +/ { + model = "Phytec pcm038"; + compatible = "phytec,imx27-pcm038", "fsl,imx27"; + + memory { + reg = <0x0 0x0>; + }; + + soc { + aipi@10000000 { /* aipi */ + + wdog@10002000 { + status = "okay"; + }; + + uart@1000a000 { + fsl,uart-has-rtscts; + status = "okay"; + }; + + uart@1000b000 { + fsl,uart-has-rtscts; + status = "okay"; + }; + + uart@1000c000 { + fsl,uart-has-rtscts; + status = "okay"; + }; + + fec@1002b000 { + status = "okay"; + }; + + i2c@1001d000 { + clock-frequency = <400000>; + status = "okay"; + at24@4c { + compatible = "at,24c32"; + pagesize = <32>; + reg = <0x52>; + }; + pcf8563@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; + }; + lm75@4a { + compatible = "national,lm75"; + reg = <0x4a>; + }; + }; + }; + }; + + nor_flash@c0000000 { + compatible = "cfi-flash"; + bank-width = <2>; + reg = <0xc0000000 0x02000000>; + #address-cells = <1>; + #size-cells = <1>; + }; +}; diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi new file mode 100644 index 000000000000..bc5e7d5ddd54 --- /dev/null +++ b/arch/arm/boot/dts/imx27.dtsi @@ -0,0 +1,217 @@ +/* + * Copyright 2012 Sascha Hauer, Pengutronix + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/include/ "skeleton.dtsi" + +/ { + aliases { + serial0 = &uart1; + serial1 = &uart2; + serial2 = &uart3; + serial3 = &uart4; + serial4 = &uart5; + serial5 = &uart6; + }; + + avic: avic-interrupt-controller@e0000000 { + compatible = "fsl,imx27-avic", "fsl,avic"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x10040000 0x1000>; + }; + + clocks { + #address-cells = <1>; + #size-cells = <0>; + + osc26m { + compatible = "fsl,imx-osc26m", "fixed-clock"; + clock-frequency = <26000000>; + }; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + interrupt-parent = <&avic>; + ranges; + + aipi@10000000 { /* AIPI1 */ + compatible = "fsl,aipi-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x10000000 0x10000000>; + ranges; + + wdog@10002000 { + compatible = "fsl,imx27-wdt", "fsl,imx21-wdt"; + reg = <0x10002000 0x4000>; + interrupts = <27>; + status = "disabled"; + }; + + uart1: uart@1000a000 { + compatible = "fsl,imx27-uart", "fsl,imx21-uart"; + reg = <0x1000a000 0x1000>; + interrupts = <20>; + status = "disabled"; + }; + + uart2: uart@1000b000 { + compatible = "fsl,imx27-uart", "fsl,imx21-uart"; + reg = <0x1000b000 0x1000>; + interrupts = <19>; + status = "disabled"; + }; + + uart3: uart@1000c000 { + compatible = "fsl,imx27-uart", "fsl,imx21-uart"; + reg = <0x1000c000 0x1000>; + interrupts = <18>; + status = "disabled"; + }; + + uart4: uart@1000d000 { + compatible = "fsl,imx27-uart", "fsl,imx21-uart"; + reg = <0x1000d000 0x1000>; + interrupts = <17>; + status = "disabled"; + }; + + cspi1: cspi@1000e000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx27-cspi"; + reg = <0x1000e000 0x1000>; + interrupts = <16>; + status = "disabled"; + }; + + cspi2: cspi@1000f000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx27-cspi"; + reg = <0x1000f000 0x1000>; + interrupts = <15>; + status = "disabled"; + }; + + i2c1: i2c@10012000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx27-i2c", "fsl,imx1-i2c"; + reg = <0x10012000 0x1000>; + interrupts = <12>; + status = "disabled"; + }; + + gpio1: gpio@10015000 { + compatible = "fsl,imx27-gpio", "fsl,imx21-gpio"; + reg = <0x10015000 0x100>; + interrupts = <8>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + gpio2: gpio@10015100 { + compatible = "fsl,imx27-gpio", "fsl,imx21-gpio"; + reg = <0x10015100 0x100>; + interrupts = <8>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + gpio3: gpio@10015200 { + compatible = "fsl,imx27-gpio", "fsl,imx21-gpio"; + reg = <0x10015200 0x100>; + interrupts = <8>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + gpio4: gpio@10015300 { + compatible = "fsl,imx27-gpio", "fsl,imx21-gpio"; + reg = <0x10015300 0x100>; + interrupts = <8>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + gpio5: gpio@10015400 { + compatible = "fsl,imx27-gpio", "fsl,imx21-gpio"; + reg = <0x10015400 0x100>; + interrupts = <8>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + gpio6: gpio@10015500 { + compatible = "fsl,imx27-gpio", "fsl,imx21-gpio"; + reg = <0x10015500 0x100>; + interrupts = <8>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + cspi3: cspi@10017000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx27-cspi"; + reg = <0x10017000 0x1000>; + interrupts = <6>; + status = "disabled"; + }; + + uart5: uart@1001b000 { + compatible = "fsl,imx27-uart", "fsl,imx21-uart"; + reg = <0x1001b000 0x1000>; + interrupts = <49>; + status = "disabled"; + }; + + uart6: uart@1001c000 { + compatible = "fsl,imx27-uart", "fsl,imx21-uart"; + reg = <0x1001c000 0x1000>; + interrupts = <48>; + status = "disabled"; + }; + + i2c2: i2c@1001d000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx27-i2c", "fsl,imx1-i2c"; + reg = <0x1001d000 0x1000>; + interrupts = <1>; + status = "disabled"; + }; + + fec: fec@1002b000 { + compatible = "fsl,imx27-fec"; + reg = <0x1002b000 0x4000>; + interrupts = <50>; + status = "disabled"; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts index 564cb8c19f15..9949e6060dee 100644 --- a/arch/arm/boot/dts/imx51-babbage.dts +++ b/arch/arm/boot/dts/imx51-babbage.dts @@ -56,8 +56,95 @@ compatible = "fsl,mc13892"; spi-max-frequency = <6000000>; reg = <0>; - mc13xxx-irq-gpios = <&gpio1 8 0>; - fsl,mc13xxx-uses-regulator; + interrupt-parent = <&gpio1>; + interrupts = <8>; + + regulators { + sw1_reg: sw1 { + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1375000>; + regulator-boot-on; + regulator-always-on; + }; + + sw2_reg: sw2 { + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1850000>; + regulator-boot-on; + regulator-always-on; + }; + + sw3_reg: sw3 { + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1850000>; + regulator-boot-on; + regulator-always-on; + }; + + sw4_reg: sw4 { + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1850000>; + regulator-boot-on; + regulator-always-on; + }; + + vpll_reg: vpll { + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + vdig_reg: vdig { + regulator-min-microvolt = <1650000>; + regulator-max-microvolt = <1650000>; + regulator-boot-on; + }; + + vsd_reg: vsd { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3150000>; + }; + + vusb2_reg: vusb2 { + regulator-min-microvolt = <2400000>; + regulator-max-microvolt = <2775000>; + regulator-boot-on; + regulator-always-on; + }; + + vvideo_reg: vvideo { + regulator-min-microvolt = <2775000>; + regulator-max-microvolt = <2775000>; + }; + + vaudio_reg: vaudio { + regulator-min-microvolt = <2300000>; + regulator-max-microvolt = <3000000>; + }; + + vcam_reg: vcam { + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <3000000>; + }; + + vgen1_reg: vgen1 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + + vgen2_reg: vgen2 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3150000>; + regulator-always-on; + }; + + vgen3_reg: vgen3 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2900000>; + regulator-always-on; + }; + }; }; flash: at45db321d@1 { diff --git a/arch/arm/boot/dts/imx6q-arm2.dts b/arch/arm/boot/dts/imx6q-arm2.dts index c3977e0478b9..ce1c8238c897 100644 --- a/arch/arm/boot/dts/imx6q-arm2.dts +++ b/arch/arm/boot/dts/imx6q-arm2.dts @@ -36,11 +36,13 @@ usdhc@02198000 { /* uSDHC3 */ cd-gpios = <&gpio6 11 0>; wp-gpios = <&gpio6 14 0>; + vmmc-supply = <®_3p3v>; status = "okay"; }; usdhc@0219c000 { /* uSDHC4 */ fsl,card-wired; + vmmc-supply = <®_3p3v>; status = "okay"; }; @@ -50,6 +52,18 @@ }; }; + regulators { + compatible = "simple-bus"; + + reg_3p3v: 3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; + leds { compatible = "gpio-leds"; diff --git a/arch/arm/boot/dts/imx6q-sabrelite.dts b/arch/arm/boot/dts/imx6q-sabrelite.dts index 08d920de7286..4663a4e5a285 100644 --- a/arch/arm/boot/dts/imx6q-sabrelite.dts +++ b/arch/arm/boot/dts/imx6q-sabrelite.dts @@ -32,18 +32,52 @@ usdhc@02198000 { /* uSDHC3 */ cd-gpios = <&gpio7 0 0>; wp-gpios = <&gpio7 1 0>; + vmmc-supply = <®_3p3v>; status = "okay"; }; usdhc@0219c000 { /* uSDHC4 */ cd-gpios = <&gpio2 6 0>; wp-gpios = <&gpio2 7 0>; + vmmc-supply = <®_3p3v>; status = "okay"; }; uart2: uart@021e8000 { status = "okay"; }; + + i2c@021a0000 { /* I2C1 */ + status = "okay"; + clock-frequency = <100000>; + + codec: sgtl5000@0a { + compatible = "fsl,sgtl5000"; + reg = <0x0a>; + VDDA-supply = <®_2p5v>; + VDDIO-supply = <®_3p3v>; + }; + }; + }; + }; + + regulators { + compatible = "simple-bus"; + + reg_2p5v: 2p5v { + compatible = "regulator-fixed"; + regulator-name = "2P5V"; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-always-on; + }; + + reg_3p3v: 3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; }; }; }; diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index 263e8f3664b5..4905f51a106f 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi @@ -88,9 +88,9 @@ ranges; timer@00a00600 { - compatible = "arm,smp-twd"; - reg = <0x00a00600 0x100>; - interrupts = <1 13 0xf4>; + compatible = "arm,cortex-a9-twd-timer"; + reg = <0x00a00600 0x20>; + interrupts = <1 13 0xf01>; }; L2: l2-cache@00a02000 { diff --git a/arch/arm/boot/dts/kirkwood-dreamplug.dts b/arch/arm/boot/dts/kirkwood-dreamplug.dts new file mode 100644 index 000000000000..a5376b84227f --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-dreamplug.dts @@ -0,0 +1,24 @@ +/dts-v1/; + +/include/ "kirkwood.dtsi" + +/ { + model = "Globalscale Technologies Dreamplug"; + compatible = "globalscale,dreamplug-003-ds2001", "globalscale,dreamplug", "mrvl,kirkwood-88f6281", "mrvl,kirkwood"; + + memory { + device_type = "memory"; + reg = <0x00000000 0x20000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200n8 earlyprintk"; + }; + + ocp@f1000000 { + serial@12000 { + clock-frequency = <200000000>; + status = "ok"; + }; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi new file mode 100644 index 000000000000..3474ef890945 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood.dtsi @@ -0,0 +1,36 @@ +/include/ "skeleton.dtsi" + +/ { + compatible = "mrvl,kirkwood"; + + ocp@f1000000 { + compatible = "simple-bus"; + ranges = <0 0xf1000000 0x1000000>; + #address-cells = <1>; + #size-cells = <1>; + + serial@12000 { + compatible = "ns16550a"; + reg = <0x12000 0x100>; + reg-shift = <2>; + interrupts = <33>; + /* set clock-frequency in board dts */ + status = "disabled"; + }; + + serial@12100 { + compatible = "ns16550a"; + reg = <0x12100 0x100>; + reg-shift = <2>; + interrupts = <34>; + /* set clock-frequency in board dts */ + status = "disabled"; + }; + + rtc@10300 { + compatible = "mrvl,kirkwood-rtc", "mrvl,orion-rtc"; + reg = <0x10300 0x20>; + interrupts = <53>; + }; + }; +}; diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts index 9486be62bcdd..9f72cd4cf308 100644 --- a/arch/arm/boot/dts/omap3-beagle.dts +++ b/arch/arm/boot/dts/omap3-beagle.dts @@ -13,15 +13,6 @@ model = "TI OMAP3 BeagleBoard"; compatible = "ti,omap3-beagle", "ti,omap3"; - /* - * Since the initial device tree board file does not create any - * devices (MMC, network...), the only way to boot is to provide a - * ramdisk. - */ - chosen { - bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug earlyprintk"; - }; - memory { device_type = "memory"; reg = <0x80000000 0x20000000>; /* 512 MB */ diff --git a/arch/arm/boot/dts/omap3-evm.dts b/arch/arm/boot/dts/omap3-evm.dts new file mode 100644 index 000000000000..2eee16ec59b4 --- /dev/null +++ b/arch/arm/boot/dts/omap3-evm.dts @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.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/ "omap3.dtsi" + +/ { + model = "TI OMAP3 EVM (OMAP3530, AM/DM37x)"; + compatible = "ti,omap3-evm", "ti,omap3"; + + memory { + device_type = "memory"; + reg = <0x80000000 0x10000000>; /* 256 MB */ + }; +}; diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi index 216c3317461d..c6121357c1eb 100644 --- a/arch/arm/boot/dts/omap3.dtsi +++ b/arch/arm/boot/dts/omap3.dtsi @@ -61,34 +61,57 @@ ranges; ti,hwmods = "l3_main"; - intc: interrupt-controller@1 { - compatible = "ti,omap3-intc"; + intc: interrupt-controller@48200000 { + compatible = "ti,omap2-intc"; interrupt-controller; #interrupt-cells = <1>; + ti,intc-size = <96>; + reg = <0x48200000 0x1000>; }; - uart1: serial@0x4806a000 { + uart1: serial@4806a000 { compatible = "ti,omap3-uart"; ti,hwmods = "uart1"; clock-frequency = <48000000>; }; - uart2: serial@0x4806c000 { + uart2: serial@4806c000 { compatible = "ti,omap3-uart"; ti,hwmods = "uart2"; clock-frequency = <48000000>; }; - uart3: serial@0x49020000 { + uart3: serial@49020000 { compatible = "ti,omap3-uart"; ti,hwmods = "uart3"; clock-frequency = <48000000>; }; - uart4: serial@0x49042000 { + uart4: serial@49042000 { compatible = "ti,omap3-uart"; ti,hwmods = "uart4"; clock-frequency = <48000000>; }; + + i2c1: i2c@48070000 { + compatible = "ti,omap3-i2c"; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "i2c1"; + }; + + i2c2: i2c@48072000 { + compatible = "ti,omap3-i2c"; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "i2c2"; + }; + + i2c3: i2c@48060000 { + compatible = "ti,omap3-i2c"; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "i2c3"; + }; }; }; diff --git a/arch/arm/boot/dts/omap4-panda.dts b/arch/arm/boot/dts/omap4-panda.dts index c7026578ce7d..9755ad5917f8 100644 --- a/arch/arm/boot/dts/omap4-panda.dts +++ b/arch/arm/boot/dts/omap4-panda.dts @@ -13,15 +13,6 @@ model = "TI OMAP4 PandaBoard"; compatible = "ti,omap4-panda", "ti,omap4430", "ti,omap4"; - /* - * Since the initial device tree board file does not create any - * devices (MMC, network...), the only way to boot is to provide a - * ramdisk. - */ - chosen { - bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug"; - }; - memory { device_type = "memory"; reg = <0x80000000 0x40000000>; /* 1 GB */ diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts index 066e28c90328..63c6b2b2bf42 100644 --- a/arch/arm/boot/dts/omap4-sdp.dts +++ b/arch/arm/boot/dts/omap4-sdp.dts @@ -13,15 +13,6 @@ model = "TI OMAP4 SDP board"; compatible = "ti,omap4-sdp", "ti,omap4430", "ti,omap4"; - /* - * Since the initial device tree board file does not create any - * devices (MMC, network...), the only way to boot is to provide a - * ramdisk. - */ - chosen { - bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug"; - }; - memory { device_type = "memory"; reg = <0x80000000 0x40000000>; /* 1 GB */ diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index e8fe75fac7c5..3d35559e77bc 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi @@ -99,33 +99,61 @@ gic: interrupt-controller@48241000 { compatible = "arm,cortex-a9-gic"; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <3>; reg = <0x48241000 0x1000>, <0x48240100 0x0100>; }; - uart1: serial@0x4806a000 { + uart1: serial@4806a000 { compatible = "ti,omap4-uart"; ti,hwmods = "uart1"; clock-frequency = <48000000>; }; - uart2: serial@0x4806c000 { + uart2: serial@4806c000 { compatible = "ti,omap4-uart"; ti,hwmods = "uart2"; clock-frequency = <48000000>; }; - uart3: serial@0x48020000 { + uart3: serial@48020000 { compatible = "ti,omap4-uart"; ti,hwmods = "uart3"; clock-frequency = <48000000>; }; - uart4: serial@0x4806e000 { + uart4: serial@4806e000 { compatible = "ti,omap4-uart"; ti,hwmods = "uart4"; clock-frequency = <48000000>; }; + + i2c1: i2c@48070000 { + compatible = "ti,omap4-i2c"; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "i2c1"; + }; + + i2c2: i2c@48072000 { + compatible = "ti,omap4-i2c"; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "i2c2"; + }; + + i2c3: i2c@48060000 { + compatible = "ti,omap4-i2c"; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "i2c3"; + }; + + i2c4: i2c@48350000 { + compatible = "ti,omap4-i2c"; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "i2c4"; + }; }; }; diff --git a/arch/arm/boot/dts/pxa168-aspenite.dts b/arch/arm/boot/dts/pxa168-aspenite.dts new file mode 100644 index 000000000000..e762facb3fa4 --- /dev/null +++ b/arch/arm/boot/dts/pxa168-aspenite.dts @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2012 Marvell Technology Group Ltd. + * Author: Haojian Zhuang <haojian.zhuang@marvell.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 + * publishhed by the Free Software Foundation. + */ + +/dts-v1/; +/include/ "pxa168.dtsi" + +/ { + model = "Marvell PXA168 Aspenite Development Board"; + compatible = "mrvl,pxa168-aspenite", "mrvl,pxa168"; + + chosen { + bootargs = "console=ttyS0,115200 root=/dev/nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on"; + }; + + memory { + reg = <0x00000000 0x04000000>; + }; + + soc { + apb@d4000000 { + uart1: uart@d4017000 { + status = "okay"; + }; + twsi1: i2c@d4011000 { + status = "okay"; + }; + rtc: rtc@d4010000 { + status = "okay"; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/pxa168.dtsi b/arch/arm/boot/dts/pxa168.dtsi new file mode 100644 index 000000000000..d32d5128f225 --- /dev/null +++ b/arch/arm/boot/dts/pxa168.dtsi @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2012 Marvell Technology Group Ltd. + * Author: Haojian Zhuang <haojian.zhuang@marvell.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 + * publishhed by the Free Software Foundation. + */ + +/include/ "skeleton.dtsi" + +/ { + aliases { + serial0 = &uart1; + serial1 = &uart2; + serial2 = &uart3; + i2c0 = &twsi1; + i2c1 = &twsi2; + }; + + intc: intc-interrupt-controller@d4282000 { + compatible = "mrvl,mmp-intc", "mrvl,intc"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0xd4282000 0x1000>; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + interrupt-parent = <&intc>; + ranges; + + apb@d4000000 { /* APB */ + compatible = "mrvl,apb-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xd4000000 0x00200000>; + ranges; + + uart1: uart@d4017000 { + compatible = "mrvl,mmp-uart", "mrvl,pxa-uart"; + reg = <0xd4017000 0x1000>; + interrupts = <27>; + status = "disabled"; + }; + + uart2: uart@d4018000 { + compatible = "mrvl,mmp-uart", "mrvl,pxa-uart"; + reg = <0xd4018000 0x1000>; + interrupts = <28>; + status = "disabled"; + }; + + uart3: uart@d4026000 { + compatible = "mrvl,mmp-uart", "mrvl,pxa-uart"; + reg = <0xd4026000 0x1000>; + interrupts = <29>; + status = "disabled"; + }; + + gpio: gpio@d4019000 { + compatible = "mrvl,mmp-gpio", "mrvl,pxa-gpio"; + reg = <0xd4019000 0x1000>; + interrupts = <49>; + interrupt-names = "gpio_mux"; + gpio-controller; + #gpio-cells = <1>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + twsi1: i2c@d4011000 { + compatible = "mrvl,mmp-twsi", "mrvl,pxa-i2c"; + reg = <0xd4011000 0x1000>; + interrupts = <7>; + mrvl,i2c-fast-mode; + status = "disabled"; + }; + + twsi2: i2c@d4025000 { + compatible = "mrvl,mmp-twsi", "mrvl,pxa-i2c"; + reg = <0xd4025000 0x1000>; + interrupts = <58>; + status = "disabled"; + }; + + rtc: rtc@d4010000 { + compatible = "mrvl,mmp-rtc"; + reg = <0xd4010000 0x1000>; + interrupts = <5 6>; + interrupt-names = "rtc 1Hz", "rtc alarm"; + status = "disabled"; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/snowball.dts b/arch/arm/boot/dts/snowball.dts new file mode 100644 index 000000000000..359c6d679156 --- /dev/null +++ b/arch/arm/boot/dts/snowball.dts @@ -0,0 +1,139 @@ +/* + * Copyright 2011 ST-Ericsson AB + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +/include/ "db8500.dtsi" + +/ { + model = "Calao Systems Snowball platform with device tree"; + compatible = "calaosystems,snowball-a9500"; + + memory { + reg = <0x00000000 0x20000000>; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + button@1 { + debounce_interval = <50>; + wakeup = <1>; + linux,code = <2>; + label = "userpb"; + gpios = <&gpio1 0>; + }; + button@2 { + debounce_interval = <50>; + wakeup = <1>; + linux,code = <3>; + label = "userpb"; + gpios = <&gpio4 23>; + }; + button@3 { + debounce_interval = <50>; + wakeup = <1>; + linux,code = <4>; + label = "userpb"; + gpios = <&gpio4 23>; + }; + button@4 { + debounce_interval = <50>; + wakeup = <1>; + linux,code = <5>; + label = "userpb"; + gpios = <&gpio5 1>; + }; + button@5 { + debounce_interval = <50>; + wakeup = <1>; + linux,code = <6>; + label = "userpb"; + gpios = <&gpio5 2>; + }; + }; + + leds { + compatible = "gpio-leds"; + used-led { + label = "user_led"; + gpios = <&gpio4 14>; + }; + }; + + soc-u9500 { + + external-bus@50000000 { + compatible = "simple-bus"; + reg = <0x50000000 0x10000000>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + ethernet@50000000 { + compatible = "smsc,9111"; + reg = <0x50000000 0x10000>; + interrupts = <12>; + interrupt-parent = <&gpio4>; + }; + }; + + sdi@80126000 { + status = "enabled"; + cd-gpios = <&gpio6 26>; + }; + + sdi@80114000 { + status = "enabled"; + }; + + uart@80120000 { + status = "okay"; + }; + + uart@80121000 { + status = "okay"; + }; + + uart@80007000 { + status = "okay"; + }; + + i2c@80004000 { + tc3589x@42 { + //compatible = "tc3589x"; + reg = <0x42>; + interrupts = <25>; + interrupt-parent = <&gpio6>; + }; + tps61052@33 { + //compatible = "tps61052"; + reg = <0x33>; + }; + }; + + i2c@80128000 { + lp5521@0x33 { + // compatible = "lp5521"; + reg = <0x33>; + }; + lp5521@0x34 { + // compatible = "lp5521"; + reg = <0x34>; + }; + bh1780@0x29 { + // compatible = "rohm,bh1780gli"; + reg = <0x33>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/spear600-evb.dts b/arch/arm/boot/dts/spear600-evb.dts new file mode 100644 index 000000000000..636292e18c90 --- /dev/null +++ b/arch/arm/boot/dts/spear600-evb.dts @@ -0,0 +1,47 @@ +/* + * Copyright 2012 Stefan Roese <sr@denx.de> + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +/include/ "spear600.dtsi" + +/ { + model = "ST SPEAr600 Evaluation Board"; + compatible = "st,spear600-evb", "st,spear600"; + #address-cells = <1>; + #size-cells = <1>; + + memory { + device_type = "memory"; + reg = <0 0x10000000>; + }; + + ahb { + gmac: ethernet@e0800000 { + phy-mode = "gmii"; + status = "okay"; + }; + + apb { + serial@d0000000 { + status = "okay"; + }; + + serial@d0080000 { + status = "okay"; + }; + + i2c@d0200000 { + clock-frequency = <400000>; + status = "okay"; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/spear600.dtsi b/arch/arm/boot/dts/spear600.dtsi new file mode 100644 index 000000000000..ebe0885a2b98 --- /dev/null +++ b/arch/arm/boot/dts/spear600.dtsi @@ -0,0 +1,174 @@ +/* + * Copyright 2012 Stefan Roese <sr@denx.de> + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/include/ "skeleton.dtsi" + +/ { + compatible = "st,spear600"; + + cpus { + cpu@0 { + compatible = "arm,arm926ejs"; + }; + }; + + memory { + device_type = "memory"; + reg = <0 0x40000000>; + }; + + ahb { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges = <0xd0000000 0xd0000000 0x30000000>; + + vic0: interrupt-controller@f1100000 { + compatible = "arm,pl190-vic"; + interrupt-controller; + reg = <0xf1100000 0x1000>; + #interrupt-cells = <1>; + }; + + vic1: interrupt-controller@f1000000 { + compatible = "arm,pl190-vic"; + interrupt-controller; + reg = <0xf1000000 0x1000>; + #interrupt-cells = <1>; + }; + + gmac: ethernet@e0800000 { + compatible = "st,spear600-gmac"; + reg = <0xe0800000 0x8000>; + interrupt-parent = <&vic1>; + interrupts = <24 23>; + interrupt-names = "macirq", "eth_wake_irq"; + status = "disabled"; + }; + + fsmc: flash@d1800000 { + compatible = "st,spear600-fsmc-nand"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xd1800000 0x1000 /* FSMC Register */ + 0xd2000000 0x4000>; /* NAND Base */ + reg-names = "fsmc_regs", "nand_data"; + st,ale-off = <0x20000>; + st,cle-off = <0x10000>; + status = "disabled"; + }; + + smi: flash@fc000000 { + compatible = "st,spear600-smi"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xfc000000 0x1000>; + interrupt-parent = <&vic1>; + interrupts = <12>; + status = "disabled"; + }; + + ehci@e1800000 { + compatible = "st,spear600-ehci", "usb-ehci"; + reg = <0xe1800000 0x1000>; + interrupt-parent = <&vic1>; + interrupts = <27>; + status = "disabled"; + }; + + ehci@e2000000 { + compatible = "st,spear600-ehci", "usb-ehci"; + reg = <0xe2000000 0x1000>; + interrupt-parent = <&vic1>; + interrupts = <29>; + status = "disabled"; + }; + + ohci@e1900000 { + compatible = "st,spear600-ohci", "usb-ohci"; + reg = <0xe1900000 0x1000>; + interrupt-parent = <&vic1>; + interrupts = <26>; + status = "disabled"; + }; + + ohci@e2100000 { + compatible = "st,spear600-ohci", "usb-ohci"; + reg = <0xe2100000 0x1000>; + interrupt-parent = <&vic1>; + interrupts = <28>; + status = "disabled"; + }; + + apb { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges = <0xd0000000 0xd0000000 0x30000000>; + + serial@d0000000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0xd0000000 0x1000>; + interrupt-parent = <&vic0>; + interrupts = <24>; + status = "disabled"; + }; + + serial@d0080000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0xd0080000 0x1000>; + interrupt-parent = <&vic0>; + interrupts = <25>; + status = "disabled"; + }; + + /* local/cpu GPIO */ + gpio0: gpio@f0100000 { + #gpio-cells = <2>; + compatible = "arm,pl061", "arm,primecell"; + gpio-controller; + reg = <0xf0100000 0x1000>; + interrupt-parent = <&vic0>; + interrupts = <18>; + }; + + /* basic GPIO */ + gpio1: gpio@fc980000 { + #gpio-cells = <2>; + compatible = "arm,pl061", "arm,primecell"; + gpio-controller; + reg = <0xfc980000 0x1000>; + interrupt-parent = <&vic1>; + interrupts = <19>; + }; + + /* appl GPIO */ + gpio2: gpio@d8100000 { + #gpio-cells = <2>; + compatible = "arm,pl061", "arm,primecell"; + gpio-controller; + reg = <0xd8100000 0x1000>; + interrupt-parent = <&vic1>; + interrupts = <4>; + }; + + i2c@d0200000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,designware-i2c"; + reg = <0xd0200000 0x1000>; + interrupt-parent = <&vic0>; + interrupts = <28>; + status = "disabled"; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/tegra-cardhu.dts b/arch/arm/boot/dts/tegra-cardhu.dts index 70c41fc897d7..ac3fb7558459 100644 --- a/arch/arm/boot/dts/tegra-cardhu.dts +++ b/arch/arm/boot/dts/tegra-cardhu.dts @@ -14,6 +14,22 @@ clock-frequency = < 408000000 >; }; + serial@70006040 { + status = "disable"; + }; + + serial@70006200 { + status = "disable"; + }; + + serial@70006300 { + status = "disable"; + }; + + serial@70006400 { + status = "disable"; + }; + i2c@7000c000 { clock-frequency = <100000>; }; @@ -33,4 +49,22 @@ i2c@7000d000 { clock-frequency = <100000>; }; + + sdhci@78000000 { + cd-gpios = <&gpio 69 0>; /* gpio PI5 */ + wp-gpios = <&gpio 155 0>; /* gpio PT3 */ + power-gpios = <&gpio 31 0>; /* gpio PD7 */ + }; + + sdhci@78000200 { + status = "disable"; + }; + + sdhci@78000400 { + status = "disable"; + }; + + sdhci@78000400 { + support-8bit; + }; }; diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts index 80afa1b70b80..6e8447dc0202 100644 --- a/arch/arm/boot/dts/tegra-harmony.dts +++ b/arch/arm/boot/dts/tegra-harmony.dts @@ -10,19 +10,25 @@ reg = < 0x00000000 0x40000000 >; }; + pmc@7000f400 { + nvidia,invert-interrupt; + }; + i2c@7000c000 { clock-frequency = <400000>; - codec: wm8903@1a { + wm8903: wm8903@1a { compatible = "wlf,wm8903"; reg = <0x1a>; - interrupts = < 347 >; + interrupt-parent = <&gpio>; + interrupts = < 187 0x04 >; gpio-controller; #gpio-cells = <2>; - /* 0x8000 = Not configured */ - gpio-cfg = < 0x8000 0x8000 0 0x8000 0x8000 >; + micdet-cfg = <0>; + micdet-delay = <100>; + gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >; }; }; @@ -38,13 +44,32 @@ clock-frequency = <400000>; }; - sound { - compatible = "nvidia,harmony-sound", "nvidia,tegra-wm8903"; + i2s@70002a00 { + status = "disable"; + }; - spkr-en-gpios = <&codec 2 0>; - hp-det-gpios = <&gpio 178 0>; - int-mic-en-gpios = <&gpio 184 0>; - ext-mic-en-gpios = <&gpio 185 0>; + sound { + compatible = "nvidia,tegra-audio-wm8903-harmony", + "nvidia,tegra-audio-wm8903"; + nvidia,model = "NVIDIA Tegra Harmony"; + + nvidia,audio-routing = + "Headphone Jack", "HPOUTR", + "Headphone Jack", "HPOUTL", + "Int Spk", "ROP", + "Int Spk", "RON", + "Int Spk", "LOP", + "Int Spk", "LON", + "Mic Jack", "MICBIAS", + "IN1L", "Mic Jack"; + + nvidia,i2s-controller = <&tegra_i2s1>; + nvidia,audio-codec = <&wm8903>; + + nvidia,spkr-en-gpios = <&wm8903 2 0>; + nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */ + nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */ + nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */ }; serial@70006000 { diff --git a/arch/arm/boot/dts/tegra-paz00.dts b/arch/arm/boot/dts/tegra-paz00.dts index 825d2957da0b..6c02abb469d4 100644 --- a/arch/arm/boot/dts/tegra-paz00.dts +++ b/arch/arm/boot/dts/tegra-paz00.dts @@ -12,6 +12,13 @@ i2c@7000c000 { clock-frequency = <400000>; + + alc5632: alc5632@1e { + compatible = "realtek,alc5632"; + reg = <0x1e>; + gpio-controller; + #gpio-cells = <2>; + }; }; i2c@7000c400 { @@ -35,6 +42,35 @@ i2c@7000d000 { clock-frequency = <400000>; + + adt7461@4c { + compatible = "adi,adt7461"; + reg = <0x4c>; + }; + }; + + i2s@70002a00 { + status = "disable"; + }; + + sound { + compatible = "nvidia,tegra-audio-alc5632-paz00", + "nvidia,tegra-audio-alc5632"; + + nvidia,model = "Compal PAZ00"; + + nvidia,audio-routing = + "Int Spk", "SPKOUT", + "Int Spk", "SPKOUTN", + "Headset Mic", "MICBIAS1", + "MIC1", "Headset Mic", + "Headset Stereophone", "HPR", + "Headset Stereophone", "HPL", + "DMICDAT", "Digital Mic"; + + nvidia,audio-codec = <&alc5632>; + nvidia,i2s-controller = <&tegra_i2s1>; + nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */ }; serial@70006000 { @@ -74,4 +110,25 @@ sdhci@c8000600 { support-8bit; }; + + gpio-keys { + compatible = "gpio-keys"; + + power { + label = "Power"; + gpios = <&gpio 79 1>; /* gpio PJ7, active low */ + linux,code = <116>; /* KEY_POWER */ + gpio-key,wakeup; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + wifi { + label = "wifi-led"; + gpios = <&gpio 24 0>; + linux,default-trigger = "rfkill0"; + }; + }; }; diff --git a/arch/arm/boot/dts/tegra-seaboard.dts b/arch/arm/boot/dts/tegra-seaboard.dts index b55a02e34ba7..dbf1c5a171c2 100644 --- a/arch/arm/boot/dts/tegra-seaboard.dts +++ b/arch/arm/boot/dts/tegra-seaboard.dts @@ -13,6 +13,20 @@ i2c@7000c000 { clock-frequency = <400000>; + + wm8903: wm8903@1a { + compatible = "wlf,wm8903"; + reg = <0x1a>; + interrupt-parent = <&gpio>; + interrupts = < 187 0x04 >; + + gpio-controller; + #gpio-cells = <2>; + + micdet-cfg = <0>; + micdet-delay = <100>; + gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >; + }; }; i2c@7000c400 { @@ -32,6 +46,32 @@ }; }; + i2s@70002a00 { + status = "disable"; + }; + + sound { + compatible = "nvidia,tegra-audio-wm8903-seaboard", + "nvidia,tegra-audio-wm8903"; + nvidia,model = "NVIDIA Tegra Seaboard"; + + nvidia,audio-routing = + "Headphone Jack", "HPOUTR", + "Headphone Jack", "HPOUTL", + "Int Spk", "ROP", + "Int Spk", "RON", + "Int Spk", "LOP", + "Int Spk", "LON", + "Mic Jack", "MICBIAS", + "IN1R", "Mic Jack"; + + nvidia,i2s-controller = <&tegra_i2s1>; + nvidia,audio-codec = <&wm8903>; + + nvidia,spkr-en-gpios = <&wm8903 2 0>; + nvidia,hp-det-gpios = <&gpio 185 0>; /* gpio PX1 */ + }; + serial@70006000 { status = "disable"; }; @@ -72,6 +112,7 @@ usb@c5000000 { nvidia,vbus-gpio = <&gpio 24 0>; /* PD0 */ + dr_mode = "otg"; }; gpio-keys { @@ -93,4 +134,42 @@ gpio-key,wakeup; }; }; + + emc@7000f400 { + emc-table@190000 { + reg = < 190000 >; + compatible = "nvidia,tegra20-emc-table"; + clock-frequency = < 190000 >; + nvidia,emc-registers = < 0x0000000c 0x00000026 + 0x00000009 0x00000003 0x00000004 0x00000004 + 0x00000002 0x0000000c 0x00000003 0x00000003 + 0x00000002 0x00000001 0x00000004 0x00000005 + 0x00000004 0x00000009 0x0000000d 0x0000059f + 0x00000000 0x00000003 0x00000003 0x00000003 + 0x00000003 0x00000001 0x0000000b 0x000000c8 + 0x00000003 0x00000007 0x00000004 0x0000000f + 0x00000002 0x00000000 0x00000000 0x00000002 + 0x00000000 0x00000000 0x00000083 0xa06204ae + 0x007dc010 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 >; + }; + + emc-table@380000 { + reg = < 380000 >; + compatible = "nvidia,tegra20-emc-table"; + clock-frequency = < 380000 >; + nvidia,emc-registers = < 0x00000017 0x0000004b + 0x00000012 0x00000006 0x00000004 0x00000005 + 0x00000003 0x0000000c 0x00000006 0x00000006 + 0x00000003 0x00000001 0x00000004 0x00000005 + 0x00000004 0x00000009 0x0000000d 0x00000b5f + 0x00000000 0x00000003 0x00000003 0x00000006 + 0x00000006 0x00000001 0x00000011 0x000000c8 + 0x00000003 0x0000000e 0x00000007 0x0000000f + 0x00000002 0x00000000 0x00000000 0x00000002 + 0x00000000 0x00000000 0x00000083 0xe044048b + 0x007d8010 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 >; + }; + }; }; diff --git a/arch/arm/boot/dts/tegra-trimslice.dts b/arch/arm/boot/dts/tegra-trimslice.dts index 3b3ee7db99f3..252476867b54 100644 --- a/arch/arm/boot/dts/tegra-trimslice.dts +++ b/arch/arm/boot/dts/tegra-trimslice.dts @@ -26,6 +26,18 @@ status = "disable"; }; + i2s@70002800 { + status = "disable"; + }; + + i2s@70002a00 { + status = "disable"; + }; + + das@70000c00 { + status = "disable"; + }; + serial@70006000 { clock-frequency = < 216000000 >; }; diff --git a/arch/arm/boot/dts/tegra-ventana.dts b/arch/arm/boot/dts/tegra-ventana.dts index c7d3b87f29df..2dcff8728e90 100644 --- a/arch/arm/boot/dts/tegra-ventana.dts +++ b/arch/arm/boot/dts/tegra-ventana.dts @@ -12,6 +12,20 @@ i2c@7000c000 { clock-frequency = <400000>; + + wm8903: wm8903@1a { + compatible = "wlf,wm8903"; + reg = <0x1a>; + interrupt-parent = <&gpio>; + interrupts = < 187 0x04 >; + + gpio-controller; + #gpio-cells = <2>; + + micdet-cfg = <0>; + micdet-delay = <100>; + gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >; + }; }; i2c@7000c400 { @@ -26,6 +40,34 @@ clock-frequency = <400000>; }; + i2s@70002a00 { + status = "disable"; + }; + + sound { + compatible = "nvidia,tegra-audio-wm8903-ventana", + "nvidia,tegra-audio-wm8903"; + nvidia,model = "NVIDIA Tegra Ventana"; + + nvidia,audio-routing = + "Headphone Jack", "HPOUTR", + "Headphone Jack", "HPOUTL", + "Int Spk", "ROP", + "Int Spk", "RON", + "Int Spk", "LOP", + "Int Spk", "LON", + "Mic Jack", "MICBIAS", + "IN1L", "Mic Jack"; + + nvidia,i2s-controller = <&tegra_i2s1>; + nvidia,audio-codec = <&wm8903>; + + nvidia,spkr-en-gpios = <&wm8903 2 0>; + nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */ + nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */ + nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */ + }; + serial@70006000 { status = "disable"; }; diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index 3da7afd45322..108e894a8926 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi @@ -4,6 +4,11 @@ compatible = "nvidia,tegra20"; interrupt-parent = <&intc>; + pmc@7000f400 { + compatible = "nvidia,tegra20-pmc"; + reg = <0x7000e400 0x400>; + }; + intc: interrupt-controller@50041000 { compatible = "arm,cortex-a9-gic"; interrupt-controller; @@ -12,6 +17,33 @@ < 0x50040100 0x0100 >; }; + pmu { + compatible = "arm,cortex-a9-pmu"; + interrupts = <0 56 0x04 + 0 57 0x04>; + }; + + apbdma: dma@6000a000 { + compatible = "nvidia,tegra20-apbdma"; + reg = <0x6000a000 0x1200>; + interrupts = < 0 104 0x04 + 0 105 0x04 + 0 106 0x04 + 0 107 0x04 + 0 108 0x04 + 0 109 0x04 + 0 110 0x04 + 0 111 0x04 + 0 112 0x04 + 0 113 0x04 + 0 114 0x04 + 0 115 0x04 + 0 116 0x04 + 0 117 0x04 + 0 118 0x04 + 0 119 0x04 >; + }; + i2c@7000c000 { #address-cells = <1>; #size-cells = <0>; @@ -44,18 +76,18 @@ interrupts = < 0 53 0x04 >; }; - i2s@70002800 { + tegra_i2s1: i2s@70002800 { compatible = "nvidia,tegra20-i2s"; reg = <0x70002800 0x200>; interrupts = < 0 13 0x04 >; - dma-channel = < 2 >; + nvidia,dma-request-selector = < &apbdma 2 >; }; - i2s@70002a00 { + tegra_i2s2: i2s@70002a00 { compatible = "nvidia,tegra20-i2s"; reg = <0x70002a00 0x200>; interrupts = < 0 3 0x04 >; - dma-channel = < 1 >; + nvidia,dma-request-selector = < &apbdma 1 >; }; das@70000c00 { @@ -75,6 +107,8 @@ 0 89 0x04 >; #gpio-cells = <2>; gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; }; pinmux: pinmux@70000000 { @@ -120,6 +154,13 @@ interrupts = < 0 91 0x04 >; }; + emc@7000f400 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nvidia,tegra20-emc"; + reg = <0x7000f400 0x200>; + }; + sdhci@c8000000 { compatible = "nvidia,tegra20-sdhci"; reg = <0xc8000000 0x200>; @@ -149,6 +190,7 @@ reg = <0xc5000000 0x4000>; interrupts = < 0 20 0x04 >; phy_type = "utmi"; + nvidia,has-legacy-mode; }; usb@c5004000 { diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi index ee7db9892e02..62a7b39f1c9a 100644 --- a/arch/arm/boot/dts/tegra30.dtsi +++ b/arch/arm/boot/dts/tegra30.dtsi @@ -4,6 +4,11 @@ compatible = "nvidia,tegra30"; interrupt-parent = <&intc>; + pmc@7000f400 { + compatible = "nvidia,tegra20-pmc", "nvidia,tegra30-pmc"; + reg = <0x7000e400 0x400>; + }; + intc: interrupt-controller@50041000 { compatible = "arm,cortex-a9-gic"; interrupt-controller; @@ -12,6 +17,51 @@ < 0x50040100 0x0100 >; }; + pmu { + compatible = "arm,cortex-a9-pmu"; + interrupts = <0 144 0x04 + 0 145 0x04 + 0 146 0x04 + 0 147 0x04>; + }; + + apbdma: dma@6000a000 { + compatible = "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma"; + reg = <0x6000a000 0x1400>; + interrupts = < 0 104 0x04 + 0 105 0x04 + 0 106 0x04 + 0 107 0x04 + 0 108 0x04 + 0 109 0x04 + 0 110 0x04 + 0 111 0x04 + 0 112 0x04 + 0 113 0x04 + 0 114 0x04 + 0 115 0x04 + 0 116 0x04 + 0 117 0x04 + 0 118 0x04 + 0 119 0x04 + 0 128 0x04 + 0 129 0x04 + 0 130 0x04 + 0 131 0x04 + 0 132 0x04 + 0 133 0x04 + 0 134 0x04 + 0 135 0x04 + 0 136 0x04 + 0 137 0x04 + 0 138 0x04 + 0 139 0x04 + 0 140 0x04 + 0 141 0x04 + 0 142 0x04 + 0 143 0x04 >; + }; + i2c@7000c000 { #address-cells = <1>; #size-cells = <0>; @@ -55,9 +105,18 @@ gpio: gpio@6000d000 { compatible = "nvidia,tegra30-gpio", "nvidia,tegra20-gpio"; reg = < 0x6000d000 0x1000 >; - interrupts = < 0 32 0x04 0 33 0x04 0 34 0x04 0 35 0x04 0 55 0x04 0 87 0x04 0 89 0x04 >; + interrupts = < 0 32 0x04 + 0 33 0x04 + 0 34 0x04 + 0 35 0x04 + 0 55 0x04 + 0 87 0x04 + 0 89 0x04 + 0 125 0x04 >; #gpio-cells = <2>; gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; }; serial@70006000 { diff --git a/arch/arm/boot/dts/usb_a9g20-dab-mmx.dtsi b/arch/arm/boot/dts/usb_a9g20-dab-mmx.dtsi new file mode 100644 index 000000000000..ad3eca17c436 --- /dev/null +++ b/arch/arm/boot/dts/usb_a9g20-dab-mmx.dtsi @@ -0,0 +1,96 @@ +/* + * calao-dab-mmx.dtsi - Device Tree Include file for Calao DAB-MMX Daughter Board + * + * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Licensed under GPLv2. + */ + +/ { + ahb { + apb { + usart1: serial@fffb4000 { + status = "okay"; + }; + + usart3: serial@fffd0000 { + status = "okay"; + }; + }; + }; + + i2c-gpio@0 { + status = "okay"; + }; + + leds { + compatible = "gpio-leds"; + + user_led1 { + label = "user_led1"; + gpios = <&pioB 20 1>; + }; + +/* +* led already used by mother board but active as high +* user_led2 { +* label = "user_led2"; +* gpios = <&pioB 21 1>; +* }; +*/ + user_led3 { + label = "user_led3"; + gpios = <&pioB 22 1>; + }; + + user_led4 { + label = "user_led4"; + gpios = <&pioB 23 1>; + }; + + red { + label = "red"; + gpios = <&pioB 24 1>; + }; + + orange { + label = "orange"; + gpios = <&pioB 30 1>; + }; + + green { + label = "green"; + gpios = <&pioB 31 1>; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + user_pb1 { + label = "user_pb1"; + gpios = <&pioB 25 1>; + linux,code = <0x100>; + }; + + user_pb2 { + label = "user_pb2"; + gpios = <&pioB 13 1>; + linux,code = <0x101>; + }; + + user_pb3 { + label = "user_pb3"; + gpios = <&pioA 26 1>; + linux,code = <0x102>; + }; + + user_pb4 { + label = "user_pb4"; + gpios = <&pioC 9 1>; + linux,code = <0x103>; + }; + }; +}; diff --git a/arch/arm/boot/dts/usb_a9g20.dts b/arch/arm/boot/dts/usb_a9g20.dts index f04b535477f5..7c2399c532e5 100644 --- a/arch/arm/boot/dts/usb_a9g20.dts +++ b/arch/arm/boot/dts/usb_a9g20.dts @@ -13,13 +13,24 @@ compatible = "calao,usb-a9g20", "atmel,at91sam9g20", "atmel,at91sam9"; chosen { - bootargs = "mem=64M console=ttyS0,115200 mtdparts=atmel_nand:128k(at91bootstrap),256k(barebox)ro,128k(bareboxenv),128k(bareboxenv2),4M(kernel),120M(rootfs),-(data) root=/dev/mtdblock5 rw rootfstype=ubifs"; + bootargs = "mem=64M console=ttyS0,115200 root=/dev/mtdblock5 rw rootfstype=ubifs"; }; - memory@20000000 { + memory { reg = <0x20000000 0x4000000>; }; + clocks { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + main_clock: clock@0 { + compatible = "atmel,osc", "fixed-clock"; + clock-frequency = <12000000>; + }; + }; + ahb { apb { dbgu: serial@fffff200 { @@ -30,6 +41,90 @@ phy-mode = "rmii"; status = "okay"; }; + + usb1: gadget@fffa4000 { + atmel,vbus-gpio = <&pioC 5 0>; + status = "okay"; + }; + }; + + nand0: nand@40000000 { + nand-bus-width = <8>; + nand-ecc-mode = "soft"; + nand-on-flash-bbt; + status = "okay"; + + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x20000>; + }; + + barebox@20000 { + label = "barebox"; + reg = <0x20000 0x40000>; + }; + + bareboxenv@60000 { + label = "bareboxenv"; + reg = <0x60000 0x20000>; + }; + + bareboxenv2@80000 { + label = "bareboxenv2"; + reg = <0x80000 0x20000>; + }; + + kernel@a0000 { + label = "kernel"; + reg = <0xa0000 0x400000>; + }; + + rootfs@4a0000 { + label = "rootfs"; + reg = <0x4a0000 0x7800000>; + }; + + data@7ca0000 { + label = "data"; + reg = <0x7ca0000 0x8360000>; + }; + }; + + usb0: ohci@00500000 { + num-ports = <2>; + status = "okay"; + }; + }; + + leds { + compatible = "gpio-leds"; + + user_led { + label = "user_led"; + gpios = <&pioB 21 1>; + linux,default-trigger = "heartbeat"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + user_pb { + label = "user_pb"; + gpios = <&pioB 10 1>; + linux,code = <28>; + gpio-key,wakeup; + }; + }; + + i2c@0 { + status = "okay"; + + rv3029c2@56 { + compatible = "rv3029c2"; + reg = <0x56>; }; }; }; diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi new file mode 100644 index 000000000000..16076e2d0934 --- /dev/null +++ b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi @@ -0,0 +1,201 @@ +/* + * ARM Ltd. Versatile Express + * + * Motherboard Express uATX + * V2M-P1 + * + * HBI-0190D + * + * RS1 memory map ("ARM Cortex-A Series memory map" in the board's + * Technical Reference Manual) + * + * WARNING! The hardware described in this file is independent from the + * original variant (vexpress-v2m.dtsi), but there is a strong + * correspondence between the two configurations. + * + * TAKE CARE WHEN MAINTAINING THIS FILE TO PROPAGATE ANY RELEVANT + * CHANGES TO vexpress-v2m.dtsi! + */ + +/ { + aliases { + arm,v2m_timer = &v2m_timer01; + }; + + motherboard { + compatible = "simple-bus"; + arm,v2m-memory-map = "rs1"; + #address-cells = <2>; /* SMB chipselect number and offset */ + #size-cells = <1>; + #interrupt-cells = <1>; + + flash@0,00000000 { + compatible = "arm,vexpress-flash", "cfi-flash"; + reg = <0 0x00000000 0x04000000>, + <4 0x00000000 0x04000000>; + bank-width = <4>; + }; + + psram@1,00000000 { + compatible = "arm,vexpress-psram", "mtd-ram"; + reg = <1 0x00000000 0x02000000>; + bank-width = <4>; + }; + + vram@2,00000000 { + compatible = "arm,vexpress-vram"; + reg = <2 0x00000000 0x00800000>; + }; + + ethernet@2,02000000 { + compatible = "smsc,lan9118", "smsc,lan9115"; + reg = <2 0x02000000 0x10000>; + interrupts = <15>; + phy-mode = "mii"; + reg-io-width = <4>; + smsc,irq-active-high; + smsc,irq-push-pull; + }; + + usb@2,03000000 { + compatible = "nxp,usb-isp1761"; + reg = <2 0x03000000 0x20000>; + interrupts = <16>; + port1-otg; + }; + + iofpga@3,00000000 { + compatible = "arm,amba-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 3 0 0x200000>; + + sysreg@010000 { + compatible = "arm,vexpress-sysreg"; + reg = <0x010000 0x1000>; + }; + + sysctl@020000 { + compatible = "arm,sp810", "arm,primecell"; + reg = <0x020000 0x1000>; + }; + + /* PCI-E I2C bus */ + v2m_i2c_pcie: i2c@030000 { + compatible = "arm,versatile-i2c"; + reg = <0x030000 0x1000>; + + #address-cells = <1>; + #size-cells = <0>; + + pcie-switch@60 { + compatible = "idt,89hpes32h8"; + reg = <0x60>; + }; + }; + + aaci@040000 { + compatible = "arm,pl041", "arm,primecell"; + reg = <0x040000 0x1000>; + interrupts = <11>; + }; + + mmci@050000 { + compatible = "arm,pl180", "arm,primecell"; + reg = <0x050000 0x1000>; + interrupts = <9 10>; + }; + + kmi@060000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x060000 0x1000>; + interrupts = <12>; + }; + + kmi@070000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x070000 0x1000>; + interrupts = <13>; + }; + + v2m_serial0: uart@090000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x090000 0x1000>; + interrupts = <5>; + }; + + v2m_serial1: uart@0a0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0a0000 0x1000>; + interrupts = <6>; + }; + + v2m_serial2: uart@0b0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0b0000 0x1000>; + interrupts = <7>; + }; + + v2m_serial3: uart@0c0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0c0000 0x1000>; + interrupts = <8>; + }; + + wdt@0f0000 { + compatible = "arm,sp805", "arm,primecell"; + reg = <0x0f0000 0x1000>; + interrupts = <0>; + }; + + v2m_timer01: timer@110000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x110000 0x1000>; + interrupts = <2>; + }; + + v2m_timer23: timer@120000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x120000 0x1000>; + }; + + /* DVI I2C bus */ + v2m_i2c_dvi: i2c@160000 { + compatible = "arm,versatile-i2c"; + reg = <0x160000 0x1000>; + + #address-cells = <1>; + #size-cells = <0>; + + dvi-transmitter@39 { + compatible = "sil,sii9022-tpi", "sil,sii9022"; + reg = <0x39>; + }; + + dvi-transmitter@60 { + compatible = "sil,sii9022-cpi", "sil,sii9022"; + reg = <0x60>; + }; + }; + + rtc@170000 { + compatible = "arm,pl031", "arm,primecell"; + reg = <0x170000 0x1000>; + interrupts = <4>; + }; + + compact-flash@1a0000 { + compatible = "arm,vexpress-cf", "ata-generic"; + reg = <0x1a0000 0x100 + 0x1a0100 0xf00>; + reg-shift = <2>; + }; + + clcd@1f0000 { + compatible = "arm,pl111", "arm,primecell"; + reg = <0x1f0000 0x1000>; + interrupts = <14>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/vexpress-v2m.dtsi b/arch/arm/boot/dts/vexpress-v2m.dtsi new file mode 100644 index 000000000000..a6c9c7c82d53 --- /dev/null +++ b/arch/arm/boot/dts/vexpress-v2m.dtsi @@ -0,0 +1,200 @@ +/* + * ARM Ltd. Versatile Express + * + * Motherboard Express uATX + * V2M-P1 + * + * HBI-0190D + * + * Original memory map ("Legacy memory map" in the board's + * Technical Reference Manual) + * + * WARNING! The hardware described in this file is independent from the + * RS1 variant (vexpress-v2m-rs1.dtsi), but there is a strong + * correspondence between the two configurations. + * + * TAKE CARE WHEN MAINTAINING THIS FILE TO PROPAGATE ANY RELEVANT + * CHANGES TO vexpress-v2m-rs1.dtsi! + */ + +/ { + aliases { + arm,v2m_timer = &v2m_timer01; + }; + + motherboard { + compatible = "simple-bus"; + #address-cells = <2>; /* SMB chipselect number and offset */ + #size-cells = <1>; + #interrupt-cells = <1>; + + flash@0,00000000 { + compatible = "arm,vexpress-flash", "cfi-flash"; + reg = <0 0x00000000 0x04000000>, + <1 0x00000000 0x04000000>; + bank-width = <4>; + }; + + psram@2,00000000 { + compatible = "arm,vexpress-psram", "mtd-ram"; + reg = <2 0x00000000 0x02000000>; + bank-width = <4>; + }; + + vram@3,00000000 { + compatible = "arm,vexpress-vram"; + reg = <3 0x00000000 0x00800000>; + }; + + ethernet@3,02000000 { + compatible = "smsc,lan9118", "smsc,lan9115"; + reg = <3 0x02000000 0x10000>; + interrupts = <15>; + phy-mode = "mii"; + reg-io-width = <4>; + smsc,irq-active-high; + smsc,irq-push-pull; + }; + + usb@3,03000000 { + compatible = "nxp,usb-isp1761"; + reg = <3 0x03000000 0x20000>; + interrupts = <16>; + port1-otg; + }; + + iofpga@7,00000000 { + compatible = "arm,amba-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 7 0 0x20000>; + + sysreg@00000 { + compatible = "arm,vexpress-sysreg"; + reg = <0x00000 0x1000>; + }; + + sysctl@01000 { + compatible = "arm,sp810", "arm,primecell"; + reg = <0x01000 0x1000>; + }; + + /* PCI-E I2C bus */ + v2m_i2c_pcie: i2c@02000 { + compatible = "arm,versatile-i2c"; + reg = <0x02000 0x1000>; + + #address-cells = <1>; + #size-cells = <0>; + + pcie-switch@60 { + compatible = "idt,89hpes32h8"; + reg = <0x60>; + }; + }; + + aaci@04000 { + compatible = "arm,pl041", "arm,primecell"; + reg = <0x04000 0x1000>; + interrupts = <11>; + }; + + mmci@05000 { + compatible = "arm,pl180", "arm,primecell"; + reg = <0x05000 0x1000>; + interrupts = <9 10>; + }; + + kmi@06000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x06000 0x1000>; + interrupts = <12>; + }; + + kmi@07000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x07000 0x1000>; + interrupts = <13>; + }; + + v2m_serial0: uart@09000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x09000 0x1000>; + interrupts = <5>; + }; + + v2m_serial1: uart@0a000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0a000 0x1000>; + interrupts = <6>; + }; + + v2m_serial2: uart@0b000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0b000 0x1000>; + interrupts = <7>; + }; + + v2m_serial3: uart@0c000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0c000 0x1000>; + interrupts = <8>; + }; + + wdt@0f000 { + compatible = "arm,sp805", "arm,primecell"; + reg = <0x0f000 0x1000>; + interrupts = <0>; + }; + + v2m_timer01: timer@11000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x11000 0x1000>; + interrupts = <2>; + }; + + v2m_timer23: timer@12000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x12000 0x1000>; + }; + + /* DVI I2C bus */ + v2m_i2c_dvi: i2c@16000 { + compatible = "arm,versatile-i2c"; + reg = <0x16000 0x1000>; + + #address-cells = <1>; + #size-cells = <0>; + + dvi-transmitter@39 { + compatible = "sil,sii9022-tpi", "sil,sii9022"; + reg = <0x39>; + }; + + dvi-transmitter@60 { + compatible = "sil,sii9022-cpi", "sil,sii9022"; + reg = <0x60>; + }; + }; + + rtc@17000 { + compatible = "arm,pl031", "arm,primecell"; + reg = <0x17000 0x1000>; + interrupts = <4>; + }; + + compact-flash@1a000 { + compatible = "arm,vexpress-cf", "ata-generic"; + reg = <0x1a000 0x100 + 0x1a100 0xf00>; + reg-shift = <2>; + }; + + clcd@1f000 { + compatible = "arm,pl111", "arm,primecell"; + reg = <0x1f000 0x1000>; + interrupts = <14>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts new file mode 100644 index 000000000000..941b161ab78c --- /dev/null +++ b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts @@ -0,0 +1,157 @@ +/* + * ARM Ltd. Versatile Express + * + * CoreTile Express A15x2 (version with Test Chip 1) + * Cortex-A15 MPCore (V2P-CA15) + * + * HBI-0237A + */ + +/dts-v1/; + +/ { + model = "V2P-CA15"; + arm,hbi = <0x237>; + compatible = "arm,vexpress,v2p-ca15,tc1", "arm,vexpress,v2p-ca15", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <1>; + + chosen { }; + + aliases { + serial0 = &v2m_serial0; + serial1 = &v2m_serial1; + serial2 = &v2m_serial2; + serial3 = &v2m_serial3; + i2c0 = &v2m_i2c_dvi; + i2c1 = &v2m_i2c_pcie; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <1>; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x40000000>; + }; + + hdlcd@2b000000 { + compatible = "arm,hdlcd"; + reg = <0x2b000000 0x1000>; + interrupts = <0 85 4>; + }; + + memory-controller@2b0a0000 { + compatible = "arm,pl341", "arm,primecell"; + reg = <0x2b0a0000 0x1000>; + }; + + wdt@2b060000 { + compatible = "arm,sp805", "arm,primecell"; + reg = <0x2b060000 0x1000>; + interrupts = <98>; + }; + + gic: interrupt-controller@2c001000 { + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0x2c001000 0x1000>, + <0x2c002000 0x100>; + }; + + memory-controller@7ffd0000 { + compatible = "arm,pl354", "arm,primecell"; + reg = <0x7ffd0000 0x1000>; + interrupts = <0 86 4>, + <0 87 4>; + }; + + dma@7ffb0000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x7ffb0000 0x1000>; + interrupts = <0 92 4>, + <0 88 4>, + <0 89 4>, + <0 90 4>, + <0 91 4>; + }; + + pmu { + compatible = "arm,cortex-a15-pmu", "arm,cortex-a9-pmu"; + interrupts = <0 68 4>, + <0 69 4>; + }; + + motherboard { + ranges = <0 0 0x08000000 0x04000000>, + <1 0 0x14000000 0x04000000>, + <2 0 0x18000000 0x04000000>, + <3 0 0x1c000000 0x04000000>, + <4 0 0x0c000000 0x04000000>, + <5 0 0x10000000 0x04000000>; + + interrupt-map-mask = <0 0 63>; + interrupt-map = <0 0 0 &gic 0 0 4>, + <0 0 1 &gic 0 1 4>, + <0 0 2 &gic 0 2 4>, + <0 0 3 &gic 0 3 4>, + <0 0 4 &gic 0 4 4>, + <0 0 5 &gic 0 5 4>, + <0 0 6 &gic 0 6 4>, + <0 0 7 &gic 0 7 4>, + <0 0 8 &gic 0 8 4>, + <0 0 9 &gic 0 9 4>, + <0 0 10 &gic 0 10 4>, + <0 0 11 &gic 0 11 4>, + <0 0 12 &gic 0 12 4>, + <0 0 13 &gic 0 13 4>, + <0 0 14 &gic 0 14 4>, + <0 0 15 &gic 0 15 4>, + <0 0 16 &gic 0 16 4>, + <0 0 17 &gic 0 17 4>, + <0 0 18 &gic 0 18 4>, + <0 0 19 &gic 0 19 4>, + <0 0 20 &gic 0 20 4>, + <0 0 21 &gic 0 21 4>, + <0 0 22 &gic 0 22 4>, + <0 0 23 &gic 0 23 4>, + <0 0 24 &gic 0 24 4>, + <0 0 25 &gic 0 25 4>, + <0 0 26 &gic 0 26 4>, + <0 0 27 &gic 0 27 4>, + <0 0 28 &gic 0 28 4>, + <0 0 29 &gic 0 29 4>, + <0 0 30 &gic 0 30 4>, + <0 0 31 &gic 0 31 4>, + <0 0 32 &gic 0 32 4>, + <0 0 33 &gic 0 33 4>, + <0 0 34 &gic 0 34 4>, + <0 0 35 &gic 0 35 4>, + <0 0 36 &gic 0 36 4>, + <0 0 37 &gic 0 37 4>, + <0 0 38 &gic 0 38 4>, + <0 0 39 &gic 0 39 4>, + <0 0 40 &gic 0 40 4>, + <0 0 41 &gic 0 41 4>, + <0 0 42 &gic 0 42 4>; + }; +}; + +/include/ "vexpress-v2m-rs1.dtsi" diff --git a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts new file mode 100644 index 000000000000..6905e66d4748 --- /dev/null +++ b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts @@ -0,0 +1,162 @@ +/* + * ARM Ltd. Versatile Express + * + * CoreTile Express A5x2 + * Cortex-A5 MPCore (V2P-CA5s) + * + * HBI-0225B + */ + +/dts-v1/; + +/ { + model = "V2P-CA5s"; + arm,hbi = <0x225>; + compatible = "arm,vexpress,v2p-ca5s", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <1>; + + chosen { }; + + aliases { + serial0 = &v2m_serial0; + serial1 = &v2m_serial1; + serial2 = &v2m_serial2; + serial3 = &v2m_serial3; + i2c0 = &v2m_i2c_dvi; + i2c1 = &v2m_i2c_pcie; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a5"; + reg = <0>; + next-level-cache = <&L2>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a5"; + reg = <1>; + next-level-cache = <&L2>; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x40000000>; + }; + + hdlcd@2a110000 { + compatible = "arm,hdlcd"; + reg = <0x2a110000 0x1000>; + interrupts = <0 85 4>; + }; + + memory-controller@2a150000 { + compatible = "arm,pl341", "arm,primecell"; + reg = <0x2a150000 0x1000>; + }; + + memory-controller@2a190000 { + compatible = "arm,pl354", "arm,primecell"; + reg = <0x2a190000 0x1000>; + interrupts = <0 86 4>, + <0 87 4>; + }; + + scu@2c000000 { + compatible = "arm,cortex-a5-scu"; + reg = <0x2c000000 0x58>; + }; + + timer@2c000600 { + compatible = "arm,cortex-a5-twd-timer"; + reg = <0x2c000600 0x38>; + interrupts = <1 2 0x304>, + <1 3 0x304>; + }; + + gic: interrupt-controller@2c001000 { + compatible = "arm,corex-a5-gic", "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0x2c001000 0x1000>, + <0x2c000100 0x100>; + }; + + L2: cache-controller@2c0f0000 { + compatible = "arm,pl310-cache"; + reg = <0x2c0f0000 0x1000>; + interrupts = <0 84 4>; + cache-level = <2>; + }; + + pmu { + compatible = "arm,cortex-a5-pmu", "arm,cortex-a9-pmu"; + interrupts = <0 68 4>, + <0 69 4>; + }; + + motherboard { + ranges = <0 0 0x08000000 0x04000000>, + <1 0 0x14000000 0x04000000>, + <2 0 0x18000000 0x04000000>, + <3 0 0x1c000000 0x04000000>, + <4 0 0x0c000000 0x04000000>, + <5 0 0x10000000 0x04000000>; + + interrupt-map-mask = <0 0 63>; + interrupt-map = <0 0 0 &gic 0 0 4>, + <0 0 1 &gic 0 1 4>, + <0 0 2 &gic 0 2 4>, + <0 0 3 &gic 0 3 4>, + <0 0 4 &gic 0 4 4>, + <0 0 5 &gic 0 5 4>, + <0 0 6 &gic 0 6 4>, + <0 0 7 &gic 0 7 4>, + <0 0 8 &gic 0 8 4>, + <0 0 9 &gic 0 9 4>, + <0 0 10 &gic 0 10 4>, + <0 0 11 &gic 0 11 4>, + <0 0 12 &gic 0 12 4>, + <0 0 13 &gic 0 13 4>, + <0 0 14 &gic 0 14 4>, + <0 0 15 &gic 0 15 4>, + <0 0 16 &gic 0 16 4>, + <0 0 17 &gic 0 17 4>, + <0 0 18 &gic 0 18 4>, + <0 0 19 &gic 0 19 4>, + <0 0 20 &gic 0 20 4>, + <0 0 21 &gic 0 21 4>, + <0 0 22 &gic 0 22 4>, + <0 0 23 &gic 0 23 4>, + <0 0 24 &gic 0 24 4>, + <0 0 25 &gic 0 25 4>, + <0 0 26 &gic 0 26 4>, + <0 0 27 &gic 0 27 4>, + <0 0 28 &gic 0 28 4>, + <0 0 29 &gic 0 29 4>, + <0 0 30 &gic 0 30 4>, + <0 0 31 &gic 0 31 4>, + <0 0 32 &gic 0 32 4>, + <0 0 33 &gic 0 33 4>, + <0 0 34 &gic 0 34 4>, + <0 0 35 &gic 0 35 4>, + <0 0 36 &gic 0 36 4>, + <0 0 37 &gic 0 37 4>, + <0 0 38 &gic 0 38 4>, + <0 0 39 &gic 0 39 4>, + <0 0 40 &gic 0 40 4>, + <0 0 41 &gic 0 41 4>, + <0 0 42 &gic 0 42 4>; + }; +}; + +/include/ "vexpress-v2m-rs1.dtsi" diff --git a/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/vexpress-v2p-ca9.dts new file mode 100644 index 000000000000..da778693be54 --- /dev/null +++ b/arch/arm/boot/dts/vexpress-v2p-ca9.dts @@ -0,0 +1,192 @@ +/* + * ARM Ltd. Versatile Express + * + * CoreTile Express A9x4 + * Cortex-A9 MPCore (V2P-CA9) + * + * HBI-0191B + */ + +/dts-v1/; + +/ { + model = "V2P-CA9"; + arm,hbi = <0x191>; + compatible = "arm,vexpress,v2p-ca9", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <1>; + + chosen { }; + + aliases { + serial0 = &v2m_serial0; + serial1 = &v2m_serial1; + serial2 = &v2m_serial2; + serial3 = &v2m_serial3; + i2c0 = &v2m_i2c_dvi; + i2c1 = &v2m_i2c_pcie; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <0>; + next-level-cache = <&L2>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <1>; + next-level-cache = <&L2>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <2>; + next-level-cache = <&L2>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <3>; + next-level-cache = <&L2>; + }; + }; + + memory@60000000 { + device_type = "memory"; + reg = <0x60000000 0x40000000>; + }; + + clcd@10020000 { + compatible = "arm,pl111", "arm,primecell"; + reg = <0x10020000 0x1000>; + interrupts = <0 44 4>; + }; + + memory-controller@100e0000 { + compatible = "arm,pl341", "arm,primecell"; + reg = <0x100e0000 0x1000>; + }; + + memory-controller@100e1000 { + compatible = "arm,pl354", "arm,primecell"; + reg = <0x100e1000 0x1000>; + interrupts = <0 45 4>, + <0 46 4>; + }; + + timer@100e4000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x100e4000 0x1000>; + interrupts = <0 48 4>, + <0 49 4>; + }; + + watchdog@100e5000 { + compatible = "arm,sp805", "arm,primecell"; + reg = <0x100e5000 0x1000>; + interrupts = <0 51 4>; + }; + + scu@1e000000 { + compatible = "arm,cortex-a9-scu"; + reg = <0x1e000000 0x58>; + }; + + timer@1e000600 { + compatible = "arm,cortex-a9-twd-timer"; + reg = <0x1e000600 0x20>; + interrupts = <1 2 0xf04>, + <1 3 0xf04>; + }; + + gic: interrupt-controller@1e001000 { + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0x1e001000 0x1000>, + <0x1e000100 0x100>; + }; + + L2: cache-controller@1e00a000 { + compatible = "arm,pl310-cache"; + reg = <0x1e00a000 0x1000>; + interrupts = <0 43 4>; + cache-level = <2>; + arm,data-latency = <1 1 1>; + arm,tag-latency = <1 1 1>; + }; + + pmu { + compatible = "arm,cortex-a9-pmu"; + interrupts = <0 60 4>, + <0 61 4>, + <0 62 4>, + <0 63 4>; + }; + + motherboard { + ranges = <0 0 0x40000000 0x04000000>, + <1 0 0x44000000 0x04000000>, + <2 0 0x48000000 0x04000000>, + <3 0 0x4c000000 0x04000000>, + <7 0 0x10000000 0x00020000>; + + interrupt-map-mask = <0 0 63>; + interrupt-map = <0 0 0 &gic 0 0 4>, + <0 0 1 &gic 0 1 4>, + <0 0 2 &gic 0 2 4>, + <0 0 3 &gic 0 3 4>, + <0 0 4 &gic 0 4 4>, + <0 0 5 &gic 0 5 4>, + <0 0 6 &gic 0 6 4>, + <0 0 7 &gic 0 7 4>, + <0 0 8 &gic 0 8 4>, + <0 0 9 &gic 0 9 4>, + <0 0 10 &gic 0 10 4>, + <0 0 11 &gic 0 11 4>, + <0 0 12 &gic 0 12 4>, + <0 0 13 &gic 0 13 4>, + <0 0 14 &gic 0 14 4>, + <0 0 15 &gic 0 15 4>, + <0 0 16 &gic 0 16 4>, + <0 0 17 &gic 0 17 4>, + <0 0 18 &gic 0 18 4>, + <0 0 19 &gic 0 19 4>, + <0 0 20 &gic 0 20 4>, + <0 0 21 &gic 0 21 4>, + <0 0 22 &gic 0 22 4>, + <0 0 23 &gic 0 23 4>, + <0 0 24 &gic 0 24 4>, + <0 0 25 &gic 0 25 4>, + <0 0 26 &gic 0 26 4>, + <0 0 27 &gic 0 27 4>, + <0 0 28 &gic 0 28 4>, + <0 0 29 &gic 0 29 4>, + <0 0 30 &gic 0 30 4>, + <0 0 31 &gic 0 31 4>, + <0 0 32 &gic 0 32 4>, + <0 0 33 &gic 0 33 4>, + <0 0 34 &gic 0 34 4>, + <0 0 35 &gic 0 35 4>, + <0 0 36 &gic 0 36 4>, + <0 0 37 &gic 0 37 4>, + <0 0 38 &gic 0 38 4>, + <0 0 39 &gic 0 39 4>, + <0 0 40 &gic 0 40 4>, + <0 0 41 &gic 0 41 4>, + <0 0 42 &gic 0 42 4>; + }; +}; + +/include/ "vexpress-v2m.dtsi" diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index 81a933eb0903..283fa1d804f4 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -24,9 +24,6 @@ config ARM_VIC_NR config ICST bool -config PL330 - bool - config SA1111 bool select DMABOUNCE if !ARCH_PXA @@ -35,9 +32,6 @@ config DMABOUNCE bool select ZONE_DMA -config TIMER_ACORN - bool - config SHARP_LOCOMO bool diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index 6ea9b6f3607a..215816f1775f 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -5,11 +5,9 @@ obj-$(CONFIG_ARM_GIC) += gic.o obj-$(CONFIG_ARM_VIC) += vic.o obj-$(CONFIG_ICST) += icst.o -obj-$(CONFIG_PL330) += pl330.o obj-$(CONFIG_SA1111) += sa1111.o obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o obj-$(CONFIG_DMABOUNCE) += dmabounce.o -obj-$(CONFIG_TIMER_ACORN) += time-acorn.o obj-$(CONFIG_SHARP_LOCOMO) += locomo.o obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o obj-$(CONFIG_SHARP_SCOOP) += scoop.o diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index f0783be17352..aa5269984187 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c @@ -686,13 +686,12 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, * For primary GICs, skip over SGIs. * For secondary GICs, skip over PPIs, too. */ - hwirq_base = 32; - if (gic_nr == 0) { - if ((irq_start & 31) > 0) { - hwirq_base = 16; - if (irq_start != -1) - irq_start = (irq_start & ~31) + 16; - } + if (gic_nr == 0 && (irq_start & 31) > 0) { + hwirq_base = 16; + if (irq_start != -1) + irq_start = (irq_start & ~31) + 16; + } else { + hwirq_base = 32; } /* diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c index fb1f1cfce60c..dcb13494ca0d 100644 --- a/arch/arm/common/it8152.c +++ b/arch/arm/common/it8152.c @@ -299,8 +299,8 @@ int __init it8152_pci_setup(int nr, struct pci_sys_data *sys) goto err1; } - pci_add_resource(&sys->resources, &it8152_io); - pci_add_resource(&sys->resources, &it8152_mem); + pci_add_resource_offset(&sys->resources, &it8152_io, sys->io_offset); + pci_add_resource_offset(&sys->resources, &it8152_mem, sys->mem_offset); if (platform_notify || platform_notify_remove) { printk(KERN_ERR "PCI: Can't use platform_notify\n"); diff --git a/arch/arm/common/pl330.c b/arch/arm/common/pl330.c deleted file mode 100644 index ff3ad2244824..000000000000 --- a/arch/arm/common/pl330.c +++ /dev/null @@ -1,1960 +0,0 @@ -/* linux/arch/arm/common/pl330.c - * - * Copyright (C) 2010 Samsung Electronics Co Ltd. - * Jaswinder Singh <jassi.brar@samsung.com> - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/io.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/dma-mapping.h> - -#include <asm/hardware/pl330.h> - -/* Register and Bit field Definitions */ -#define DS 0x0 -#define DS_ST_STOP 0x0 -#define DS_ST_EXEC 0x1 -#define DS_ST_CMISS 0x2 -#define DS_ST_UPDTPC 0x3 -#define DS_ST_WFE 0x4 -#define DS_ST_ATBRR 0x5 -#define DS_ST_QBUSY 0x6 -#define DS_ST_WFP 0x7 -#define DS_ST_KILL 0x8 -#define DS_ST_CMPLT 0x9 -#define DS_ST_FLTCMP 0xe -#define DS_ST_FAULT 0xf - -#define DPC 0x4 -#define INTEN 0x20 -#define ES 0x24 -#define INTSTATUS 0x28 -#define INTCLR 0x2c -#define FSM 0x30 -#define FSC 0x34 -#define FTM 0x38 - -#define _FTC 0x40 -#define FTC(n) (_FTC + (n)*0x4) - -#define _CS 0x100 -#define CS(n) (_CS + (n)*0x8) -#define CS_CNS (1 << 21) - -#define _CPC 0x104 -#define CPC(n) (_CPC + (n)*0x8) - -#define _SA 0x400 -#define SA(n) (_SA + (n)*0x20) - -#define _DA 0x404 -#define DA(n) (_DA + (n)*0x20) - -#define _CC 0x408 -#define CC(n) (_CC + (n)*0x20) - -#define CC_SRCINC (1 << 0) -#define CC_DSTINC (1 << 14) -#define CC_SRCPRI (1 << 8) -#define CC_DSTPRI (1 << 22) -#define CC_SRCNS (1 << 9) -#define CC_DSTNS (1 << 23) -#define CC_SRCIA (1 << 10) -#define CC_DSTIA (1 << 24) -#define CC_SRCBRSTLEN_SHFT 4 -#define CC_DSTBRSTLEN_SHFT 18 -#define CC_SRCBRSTSIZE_SHFT 1 -#define CC_DSTBRSTSIZE_SHFT 15 -#define CC_SRCCCTRL_SHFT 11 -#define CC_SRCCCTRL_MASK 0x7 -#define CC_DSTCCTRL_SHFT 25 -#define CC_DRCCCTRL_MASK 0x7 -#define CC_SWAP_SHFT 28 - -#define _LC0 0x40c -#define LC0(n) (_LC0 + (n)*0x20) - -#define _LC1 0x410 -#define LC1(n) (_LC1 + (n)*0x20) - -#define DBGSTATUS 0xd00 -#define DBG_BUSY (1 << 0) - -#define DBGCMD 0xd04 -#define DBGINST0 0xd08 -#define DBGINST1 0xd0c - -#define CR0 0xe00 -#define CR1 0xe04 -#define CR2 0xe08 -#define CR3 0xe0c -#define CR4 0xe10 -#define CRD 0xe14 - -#define PERIPH_ID 0xfe0 -#define PCELL_ID 0xff0 - -#define CR0_PERIPH_REQ_SET (1 << 0) -#define CR0_BOOT_EN_SET (1 << 1) -#define CR0_BOOT_MAN_NS (1 << 2) -#define CR0_NUM_CHANS_SHIFT 4 -#define CR0_NUM_CHANS_MASK 0x7 -#define CR0_NUM_PERIPH_SHIFT 12 -#define CR0_NUM_PERIPH_MASK 0x1f -#define CR0_NUM_EVENTS_SHIFT 17 -#define CR0_NUM_EVENTS_MASK 0x1f - -#define CR1_ICACHE_LEN_SHIFT 0 -#define CR1_ICACHE_LEN_MASK 0x7 -#define CR1_NUM_ICACHELINES_SHIFT 4 -#define CR1_NUM_ICACHELINES_MASK 0xf - -#define CRD_DATA_WIDTH_SHIFT 0 -#define CRD_DATA_WIDTH_MASK 0x7 -#define CRD_WR_CAP_SHIFT 4 -#define CRD_WR_CAP_MASK 0x7 -#define CRD_WR_Q_DEP_SHIFT 8 -#define CRD_WR_Q_DEP_MASK 0xf -#define CRD_RD_CAP_SHIFT 12 -#define CRD_RD_CAP_MASK 0x7 -#define CRD_RD_Q_DEP_SHIFT 16 -#define CRD_RD_Q_DEP_MASK 0xf -#define CRD_DATA_BUFF_SHIFT 20 -#define CRD_DATA_BUFF_MASK 0x3ff - -#define PART 0x330 -#define DESIGNER 0x41 -#define REVISION 0x0 -#define INTEG_CFG 0x0 -#define PERIPH_ID_VAL ((PART << 0) | (DESIGNER << 12)) - -#define PCELL_ID_VAL 0xb105f00d - -#define PL330_STATE_STOPPED (1 << 0) -#define PL330_STATE_EXECUTING (1 << 1) -#define PL330_STATE_WFE (1 << 2) -#define PL330_STATE_FAULTING (1 << 3) -#define PL330_STATE_COMPLETING (1 << 4) -#define PL330_STATE_WFP (1 << 5) -#define PL330_STATE_KILLING (1 << 6) -#define PL330_STATE_FAULT_COMPLETING (1 << 7) -#define PL330_STATE_CACHEMISS (1 << 8) -#define PL330_STATE_UPDTPC (1 << 9) -#define PL330_STATE_ATBARRIER (1 << 10) -#define PL330_STATE_QUEUEBUSY (1 << 11) -#define PL330_STATE_INVALID (1 << 15) - -#define PL330_STABLE_STATES (PL330_STATE_STOPPED | PL330_STATE_EXECUTING \ - | PL330_STATE_WFE | PL330_STATE_FAULTING) - -#define CMD_DMAADDH 0x54 -#define CMD_DMAEND 0x00 -#define CMD_DMAFLUSHP 0x35 -#define CMD_DMAGO 0xa0 -#define CMD_DMALD 0x04 -#define CMD_DMALDP 0x25 -#define CMD_DMALP 0x20 -#define CMD_DMALPEND 0x28 -#define CMD_DMAKILL 0x01 -#define CMD_DMAMOV 0xbc -#define CMD_DMANOP 0x18 -#define CMD_DMARMB 0x12 -#define CMD_DMASEV 0x34 -#define CMD_DMAST 0x08 -#define CMD_DMASTP 0x29 -#define CMD_DMASTZ 0x0c -#define CMD_DMAWFE 0x36 -#define CMD_DMAWFP 0x30 -#define CMD_DMAWMB 0x13 - -#define SZ_DMAADDH 3 -#define SZ_DMAEND 1 -#define SZ_DMAFLUSHP 2 -#define SZ_DMALD 1 -#define SZ_DMALDP 2 -#define SZ_DMALP 2 -#define SZ_DMALPEND 2 -#define SZ_DMAKILL 1 -#define SZ_DMAMOV 6 -#define SZ_DMANOP 1 -#define SZ_DMARMB 1 -#define SZ_DMASEV 2 -#define SZ_DMAST 1 -#define SZ_DMASTP 2 -#define SZ_DMASTZ 1 -#define SZ_DMAWFE 2 -#define SZ_DMAWFP 2 -#define SZ_DMAWMB 1 -#define SZ_DMAGO 6 - -#define BRST_LEN(ccr) ((((ccr) >> CC_SRCBRSTLEN_SHFT) & 0xf) + 1) -#define BRST_SIZE(ccr) (1 << (((ccr) >> CC_SRCBRSTSIZE_SHFT) & 0x7)) - -#define BYTE_TO_BURST(b, ccr) ((b) / BRST_SIZE(ccr) / BRST_LEN(ccr)) -#define BURST_TO_BYTE(c, ccr) ((c) * BRST_SIZE(ccr) * BRST_LEN(ccr)) - -/* - * With 256 bytes, we can do more than 2.5MB and 5MB xfers per req - * at 1byte/burst for P<->M and M<->M respectively. - * For typical scenario, at 1word/burst, 10MB and 20MB xfers per req - * should be enough for P<->M and M<->M respectively. - */ -#define MCODE_BUFF_PER_REQ 256 - -/* If the _pl330_req is available to the client */ -#define IS_FREE(req) (*((u8 *)((req)->mc_cpu)) == CMD_DMAEND) - -/* Use this _only_ to wait on transient states */ -#define UNTIL(t, s) while (!(_state(t) & (s))) cpu_relax(); - -#ifdef PL330_DEBUG_MCGEN -static unsigned cmd_line; -#define PL330_DBGCMD_DUMP(off, x...) do { \ - printk("%x:", cmd_line); \ - printk(x); \ - cmd_line += off; \ - } while (0) -#define PL330_DBGMC_START(addr) (cmd_line = addr) -#else -#define PL330_DBGCMD_DUMP(off, x...) do {} while (0) -#define PL330_DBGMC_START(addr) do {} while (0) -#endif - -struct _xfer_spec { - u32 ccr; - struct pl330_req *r; - struct pl330_xfer *x; -}; - -enum dmamov_dst { - SAR = 0, - CCR, - DAR, -}; - -enum pl330_dst { - SRC = 0, - DST, -}; - -enum pl330_cond { - SINGLE, - BURST, - ALWAYS, -}; - -struct _pl330_req { - u32 mc_bus; - void *mc_cpu; - /* Number of bytes taken to setup MC for the req */ - u32 mc_len; - struct pl330_req *r; - /* Hook to attach to DMAC's list of reqs with due callback */ - struct list_head rqd; -}; - -/* ToBeDone for tasklet */ -struct _pl330_tbd { - bool reset_dmac; - bool reset_mngr; - u8 reset_chan; -}; - -/* A DMAC Thread */ -struct pl330_thread { - u8 id; - int ev; - /* If the channel is not yet acquired by any client */ - bool free; - /* Parent DMAC */ - struct pl330_dmac *dmac; - /* Only two at a time */ - struct _pl330_req req[2]; - /* Index of the last enqueued request */ - unsigned lstenq; - /* Index of the last submitted request or -1 if the DMA is stopped */ - int req_running; -}; - -enum pl330_dmac_state { - UNINIT, - INIT, - DYING, -}; - -/* A DMAC */ -struct pl330_dmac { - spinlock_t lock; - /* Holds list of reqs with due callbacks */ - struct list_head req_done; - /* Pointer to platform specific stuff */ - struct pl330_info *pinfo; - /* Maximum possible events/irqs */ - int events[32]; - /* BUS address of MicroCode buffer */ - u32 mcode_bus; - /* CPU address of MicroCode buffer */ - void *mcode_cpu; - /* List of all Channel threads */ - struct pl330_thread *channels; - /* Pointer to the MANAGER thread */ - struct pl330_thread *manager; - /* To handle bad news in interrupt */ - struct tasklet_struct tasks; - struct _pl330_tbd dmac_tbd; - /* State of DMAC operation */ - enum pl330_dmac_state state; -}; - -static inline void _callback(struct pl330_req *r, enum pl330_op_err err) -{ - if (r && r->xfer_cb) - r->xfer_cb(r->token, err); -} - -static inline bool _queue_empty(struct pl330_thread *thrd) -{ - return (IS_FREE(&thrd->req[0]) && IS_FREE(&thrd->req[1])) - ? true : false; -} - -static inline bool _queue_full(struct pl330_thread *thrd) -{ - return (IS_FREE(&thrd->req[0]) || IS_FREE(&thrd->req[1])) - ? false : true; -} - -static inline bool is_manager(struct pl330_thread *thrd) -{ - struct pl330_dmac *pl330 = thrd->dmac; - - /* MANAGER is indexed at the end */ - if (thrd->id == pl330->pinfo->pcfg.num_chan) - return true; - else - return false; -} - -/* If manager of the thread is in Non-Secure mode */ -static inline bool _manager_ns(struct pl330_thread *thrd) -{ - struct pl330_dmac *pl330 = thrd->dmac; - - return (pl330->pinfo->pcfg.mode & DMAC_MODE_NS) ? true : false; -} - -static inline u32 get_id(struct pl330_info *pi, u32 off) -{ - void __iomem *regs = pi->base; - u32 id = 0; - - id |= (readb(regs + off + 0x0) << 0); - id |= (readb(regs + off + 0x4) << 8); - id |= (readb(regs + off + 0x8) << 16); - id |= (readb(regs + off + 0xc) << 24); - - return id; -} - -static inline u32 _emit_ADDH(unsigned dry_run, u8 buf[], - enum pl330_dst da, u16 val) -{ - if (dry_run) - return SZ_DMAADDH; - - buf[0] = CMD_DMAADDH; - buf[0] |= (da << 1); - *((u16 *)&buf[1]) = val; - - PL330_DBGCMD_DUMP(SZ_DMAADDH, "\tDMAADDH %s %u\n", - da == 1 ? "DA" : "SA", val); - - return SZ_DMAADDH; -} - -static inline u32 _emit_END(unsigned dry_run, u8 buf[]) -{ - if (dry_run) - return SZ_DMAEND; - - buf[0] = CMD_DMAEND; - - PL330_DBGCMD_DUMP(SZ_DMAEND, "\tDMAEND\n"); - - return SZ_DMAEND; -} - -static inline u32 _emit_FLUSHP(unsigned dry_run, u8 buf[], u8 peri) -{ - if (dry_run) - return SZ_DMAFLUSHP; - - buf[0] = CMD_DMAFLUSHP; - - peri &= 0x1f; - peri <<= 3; - buf[1] = peri; - - PL330_DBGCMD_DUMP(SZ_DMAFLUSHP, "\tDMAFLUSHP %u\n", peri >> 3); - - return SZ_DMAFLUSHP; -} - -static inline u32 _emit_LD(unsigned dry_run, u8 buf[], enum pl330_cond cond) -{ - if (dry_run) - return SZ_DMALD; - - buf[0] = CMD_DMALD; - - if (cond == SINGLE) - buf[0] |= (0 << 1) | (1 << 0); - else if (cond == BURST) - buf[0] |= (1 << 1) | (1 << 0); - - PL330_DBGCMD_DUMP(SZ_DMALD, "\tDMALD%c\n", - cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A')); - - return SZ_DMALD; -} - -static inline u32 _emit_LDP(unsigned dry_run, u8 buf[], - enum pl330_cond cond, u8 peri) -{ - if (dry_run) - return SZ_DMALDP; - - buf[0] = CMD_DMALDP; - - if (cond == BURST) - buf[0] |= (1 << 1); - - peri &= 0x1f; - peri <<= 3; - buf[1] = peri; - - PL330_DBGCMD_DUMP(SZ_DMALDP, "\tDMALDP%c %u\n", - cond == SINGLE ? 'S' : 'B', peri >> 3); - - return SZ_DMALDP; -} - -static inline u32 _emit_LP(unsigned dry_run, u8 buf[], - unsigned loop, u8 cnt) -{ - if (dry_run) - return SZ_DMALP; - - buf[0] = CMD_DMALP; - - if (loop) - buf[0] |= (1 << 1); - - cnt--; /* DMAC increments by 1 internally */ - buf[1] = cnt; - - PL330_DBGCMD_DUMP(SZ_DMALP, "\tDMALP_%c %u\n", loop ? '1' : '0', cnt); - - return SZ_DMALP; -} - -struct _arg_LPEND { - enum pl330_cond cond; - bool forever; - unsigned loop; - u8 bjump; -}; - -static inline u32 _emit_LPEND(unsigned dry_run, u8 buf[], - const struct _arg_LPEND *arg) -{ - enum pl330_cond cond = arg->cond; - bool forever = arg->forever; - unsigned loop = arg->loop; - u8 bjump = arg->bjump; - - if (dry_run) - return SZ_DMALPEND; - - buf[0] = CMD_DMALPEND; - - if (loop) - buf[0] |= (1 << 2); - - if (!forever) - buf[0] |= (1 << 4); - - if (cond == SINGLE) - buf[0] |= (0 << 1) | (1 << 0); - else if (cond == BURST) - buf[0] |= (1 << 1) | (1 << 0); - - buf[1] = bjump; - - PL330_DBGCMD_DUMP(SZ_DMALPEND, "\tDMALP%s%c_%c bjmpto_%x\n", - forever ? "FE" : "END", - cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A'), - loop ? '1' : '0', - bjump); - - return SZ_DMALPEND; -} - -static inline u32 _emit_KILL(unsigned dry_run, u8 buf[]) -{ - if (dry_run) - return SZ_DMAKILL; - - buf[0] = CMD_DMAKILL; - - return SZ_DMAKILL; -} - -static inline u32 _emit_MOV(unsigned dry_run, u8 buf[], - enum dmamov_dst dst, u32 val) -{ - if (dry_run) - return SZ_DMAMOV; - - buf[0] = CMD_DMAMOV; - buf[1] = dst; - *((u32 *)&buf[2]) = val; - - PL330_DBGCMD_DUMP(SZ_DMAMOV, "\tDMAMOV %s 0x%x\n", - dst == SAR ? "SAR" : (dst == DAR ? "DAR" : "CCR"), val); - - return SZ_DMAMOV; -} - -static inline u32 _emit_NOP(unsigned dry_run, u8 buf[]) -{ - if (dry_run) - return SZ_DMANOP; - - buf[0] = CMD_DMANOP; - - PL330_DBGCMD_DUMP(SZ_DMANOP, "\tDMANOP\n"); - - return SZ_DMANOP; -} - -static inline u32 _emit_RMB(unsigned dry_run, u8 buf[]) -{ - if (dry_run) - return SZ_DMARMB; - - buf[0] = CMD_DMARMB; - - PL330_DBGCMD_DUMP(SZ_DMARMB, "\tDMARMB\n"); - - return SZ_DMARMB; -} - -static inline u32 _emit_SEV(unsigned dry_run, u8 buf[], u8 ev) -{ - if (dry_run) - return SZ_DMASEV; - - buf[0] = CMD_DMASEV; - - ev &= 0x1f; - ev <<= 3; - buf[1] = ev; - - PL330_DBGCMD_DUMP(SZ_DMASEV, "\tDMASEV %u\n", ev >> 3); - - return SZ_DMASEV; -} - -static inline u32 _emit_ST(unsigned dry_run, u8 buf[], enum pl330_cond cond) -{ - if (dry_run) - return SZ_DMAST; - - buf[0] = CMD_DMAST; - - if (cond == SINGLE) - buf[0] |= (0 << 1) | (1 << 0); - else if (cond == BURST) - buf[0] |= (1 << 1) | (1 << 0); - - PL330_DBGCMD_DUMP(SZ_DMAST, "\tDMAST%c\n", - cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A')); - - return SZ_DMAST; -} - -static inline u32 _emit_STP(unsigned dry_run, u8 buf[], - enum pl330_cond cond, u8 peri) -{ - if (dry_run) - return SZ_DMASTP; - - buf[0] = CMD_DMASTP; - - if (cond == BURST) - buf[0] |= (1 << 1); - - peri &= 0x1f; - peri <<= 3; - buf[1] = peri; - - PL330_DBGCMD_DUMP(SZ_DMASTP, "\tDMASTP%c %u\n", - cond == SINGLE ? 'S' : 'B', peri >> 3); - - return SZ_DMASTP; -} - -static inline u32 _emit_STZ(unsigned dry_run, u8 buf[]) -{ - if (dry_run) - return SZ_DMASTZ; - - buf[0] = CMD_DMASTZ; - - PL330_DBGCMD_DUMP(SZ_DMASTZ, "\tDMASTZ\n"); - - return SZ_DMASTZ; -} - -static inline u32 _emit_WFE(unsigned dry_run, u8 buf[], u8 ev, - unsigned invalidate) -{ - if (dry_run) - return SZ_DMAWFE; - - buf[0] = CMD_DMAWFE; - - ev &= 0x1f; - ev <<= 3; - buf[1] = ev; - - if (invalidate) - buf[1] |= (1 << 1); - - PL330_DBGCMD_DUMP(SZ_DMAWFE, "\tDMAWFE %u%s\n", - ev >> 3, invalidate ? ", I" : ""); - - return SZ_DMAWFE; -} - -static inline u32 _emit_WFP(unsigned dry_run, u8 buf[], - enum pl330_cond cond, u8 peri) -{ - if (dry_run) - return SZ_DMAWFP; - - buf[0] = CMD_DMAWFP; - - if (cond == SINGLE) - buf[0] |= (0 << 1) | (0 << 0); - else if (cond == BURST) - buf[0] |= (1 << 1) | (0 << 0); - else - buf[0] |= (0 << 1) | (1 << 0); - - peri &= 0x1f; - peri <<= 3; - buf[1] = peri; - - PL330_DBGCMD_DUMP(SZ_DMAWFP, "\tDMAWFP%c %u\n", - cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'P'), peri >> 3); - - return SZ_DMAWFP; -} - -static inline u32 _emit_WMB(unsigned dry_run, u8 buf[]) -{ - if (dry_run) - return SZ_DMAWMB; - - buf[0] = CMD_DMAWMB; - - PL330_DBGCMD_DUMP(SZ_DMAWMB, "\tDMAWMB\n"); - - return SZ_DMAWMB; -} - -struct _arg_GO { - u8 chan; - u32 addr; - unsigned ns; -}; - -static inline u32 _emit_GO(unsigned dry_run, u8 buf[], - const struct _arg_GO *arg) -{ - u8 chan = arg->chan; - u32 addr = arg->addr; - unsigned ns = arg->ns; - - if (dry_run) - return SZ_DMAGO; - - buf[0] = CMD_DMAGO; - buf[0] |= (ns << 1); - - buf[1] = chan & 0x7; - - *((u32 *)&buf[2]) = addr; - - return SZ_DMAGO; -} - -#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) - -/* Returns Time-Out */ -static bool _until_dmac_idle(struct pl330_thread *thrd) -{ - void __iomem *regs = thrd->dmac->pinfo->base; - unsigned long loops = msecs_to_loops(5); - - do { - /* Until Manager is Idle */ - if (!(readl(regs + DBGSTATUS) & DBG_BUSY)) - break; - - cpu_relax(); - } while (--loops); - - if (!loops) - return true; - - return false; -} - -static inline void _execute_DBGINSN(struct pl330_thread *thrd, - u8 insn[], bool as_manager) -{ - void __iomem *regs = thrd->dmac->pinfo->base; - u32 val; - - val = (insn[0] << 16) | (insn[1] << 24); - if (!as_manager) { - val |= (1 << 0); - val |= (thrd->id << 8); /* Channel Number */ - } - writel(val, regs + DBGINST0); - - val = *((u32 *)&insn[2]); - writel(val, regs + DBGINST1); - - /* If timed out due to halted state-machine */ - if (_until_dmac_idle(thrd)) { - dev_err(thrd->dmac->pinfo->dev, "DMAC halted!\n"); - return; - } - - /* Get going */ - writel(0, regs + DBGCMD); -} - -/* - * Mark a _pl330_req as free. - * We do it by writing DMAEND as the first instruction - * because no valid request is going to have DMAEND as - * its first instruction to execute. - */ -static void mark_free(struct pl330_thread *thrd, int idx) -{ - struct _pl330_req *req = &thrd->req[idx]; - - _emit_END(0, req->mc_cpu); - req->mc_len = 0; - - thrd->req_running = -1; -} - -static inline u32 _state(struct pl330_thread *thrd) -{ - void __iomem *regs = thrd->dmac->pinfo->base; - u32 val; - - if (is_manager(thrd)) - val = readl(regs + DS) & 0xf; - else - val = readl(regs + CS(thrd->id)) & 0xf; - - switch (val) { - case DS_ST_STOP: - return PL330_STATE_STOPPED; - case DS_ST_EXEC: - return PL330_STATE_EXECUTING; - case DS_ST_CMISS: - return PL330_STATE_CACHEMISS; - case DS_ST_UPDTPC: - return PL330_STATE_UPDTPC; - case DS_ST_WFE: - return PL330_STATE_WFE; - case DS_ST_FAULT: - return PL330_STATE_FAULTING; - case DS_ST_ATBRR: - if (is_manager(thrd)) - return PL330_STATE_INVALID; - else - return PL330_STATE_ATBARRIER; - case DS_ST_QBUSY: - if (is_manager(thrd)) - return PL330_STATE_INVALID; - else - return PL330_STATE_QUEUEBUSY; - case DS_ST_WFP: - if (is_manager(thrd)) - return PL330_STATE_INVALID; - else - return PL330_STATE_WFP; - case DS_ST_KILL: - if (is_manager(thrd)) - return PL330_STATE_INVALID; - else - return PL330_STATE_KILLING; - case DS_ST_CMPLT: - if (is_manager(thrd)) - return PL330_STATE_INVALID; - else - return PL330_STATE_COMPLETING; - case DS_ST_FLTCMP: - if (is_manager(thrd)) - return PL330_STATE_INVALID; - else - return PL330_STATE_FAULT_COMPLETING; - default: - return PL330_STATE_INVALID; - } -} - -static void _stop(struct pl330_thread *thrd) -{ - void __iomem *regs = thrd->dmac->pinfo->base; - u8 insn[6] = {0, 0, 0, 0, 0, 0}; - - if (_state(thrd) == PL330_STATE_FAULT_COMPLETING) - UNTIL(thrd, PL330_STATE_FAULTING | PL330_STATE_KILLING); - - /* Return if nothing needs to be done */ - if (_state(thrd) == PL330_STATE_COMPLETING - || _state(thrd) == PL330_STATE_KILLING - || _state(thrd) == PL330_STATE_STOPPED) - return; - - _emit_KILL(0, insn); - - /* Stop generating interrupts for SEV */ - writel(readl(regs + INTEN) & ~(1 << thrd->ev), regs + INTEN); - - _execute_DBGINSN(thrd, insn, is_manager(thrd)); -} - -/* Start doing req 'idx' of thread 'thrd' */ -static bool _trigger(struct pl330_thread *thrd) -{ - void __iomem *regs = thrd->dmac->pinfo->base; - struct _pl330_req *req; - struct pl330_req *r; - struct _arg_GO go; - unsigned ns; - u8 insn[6] = {0, 0, 0, 0, 0, 0}; - int idx; - - /* Return if already ACTIVE */ - if (_state(thrd) != PL330_STATE_STOPPED) - return true; - - idx = 1 - thrd->lstenq; - if (!IS_FREE(&thrd->req[idx])) - req = &thrd->req[idx]; - else { - idx = thrd->lstenq; - if (!IS_FREE(&thrd->req[idx])) - req = &thrd->req[idx]; - else - req = NULL; - } - - /* Return if no request */ - if (!req || !req->r) - return true; - - r = req->r; - - if (r->cfg) - ns = r->cfg->nonsecure ? 1 : 0; - else if (readl(regs + CS(thrd->id)) & CS_CNS) - ns = 1; - else - ns = 0; - - /* See 'Abort Sources' point-4 at Page 2-25 */ - if (_manager_ns(thrd) && !ns) - dev_info(thrd->dmac->pinfo->dev, "%s:%d Recipe for ABORT!\n", - __func__, __LINE__); - - go.chan = thrd->id; - go.addr = req->mc_bus; - go.ns = ns; - _emit_GO(0, insn, &go); - - /* Set to generate interrupts for SEV */ - writel(readl(regs + INTEN) | (1 << thrd->ev), regs + INTEN); - - /* Only manager can execute GO */ - _execute_DBGINSN(thrd, insn, true); - - thrd->req_running = idx; - - return true; -} - -static bool _start(struct pl330_thread *thrd) -{ - switch (_state(thrd)) { - case PL330_STATE_FAULT_COMPLETING: - UNTIL(thrd, PL330_STATE_FAULTING | PL330_STATE_KILLING); - - if (_state(thrd) == PL330_STATE_KILLING) - UNTIL(thrd, PL330_STATE_STOPPED) - - case PL330_STATE_FAULTING: - _stop(thrd); - - case PL330_STATE_KILLING: - case PL330_STATE_COMPLETING: - UNTIL(thrd, PL330_STATE_STOPPED) - - case PL330_STATE_STOPPED: - return _trigger(thrd); - - case PL330_STATE_WFP: - case PL330_STATE_QUEUEBUSY: - case PL330_STATE_ATBARRIER: - case PL330_STATE_UPDTPC: - case PL330_STATE_CACHEMISS: - case PL330_STATE_EXECUTING: - return true; - - case PL330_STATE_WFE: /* For RESUME, nothing yet */ - default: - return false; - } -} - -static inline int _ldst_memtomem(unsigned dry_run, u8 buf[], - const struct _xfer_spec *pxs, int cyc) -{ - int off = 0; - - while (cyc--) { - off += _emit_LD(dry_run, &buf[off], ALWAYS); - off += _emit_RMB(dry_run, &buf[off]); - off += _emit_ST(dry_run, &buf[off], ALWAYS); - off += _emit_WMB(dry_run, &buf[off]); - } - - return off; -} - -static inline int _ldst_devtomem(unsigned dry_run, u8 buf[], - const struct _xfer_spec *pxs, int cyc) -{ - int off = 0; - - while (cyc--) { - off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->r->peri); - off += _emit_LDP(dry_run, &buf[off], SINGLE, pxs->r->peri); - off += _emit_ST(dry_run, &buf[off], ALWAYS); - off += _emit_FLUSHP(dry_run, &buf[off], pxs->r->peri); - } - - return off; -} - -static inline int _ldst_memtodev(unsigned dry_run, u8 buf[], - const struct _xfer_spec *pxs, int cyc) -{ - int off = 0; - - while (cyc--) { - off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->r->peri); - off += _emit_LD(dry_run, &buf[off], ALWAYS); - off += _emit_STP(dry_run, &buf[off], SINGLE, pxs->r->peri); - off += _emit_FLUSHP(dry_run, &buf[off], pxs->r->peri); - } - - return off; -} - -static int _bursts(unsigned dry_run, u8 buf[], - const struct _xfer_spec *pxs, int cyc) -{ - int off = 0; - - switch (pxs->r->rqtype) { - case MEMTODEV: - off += _ldst_memtodev(dry_run, &buf[off], pxs, cyc); - break; - case DEVTOMEM: - off += _ldst_devtomem(dry_run, &buf[off], pxs, cyc); - break; - case MEMTOMEM: - off += _ldst_memtomem(dry_run, &buf[off], pxs, cyc); - break; - default: - off += 0x40000000; /* Scare off the Client */ - break; - } - - return off; -} - -/* Returns bytes consumed and updates bursts */ -static inline int _loop(unsigned dry_run, u8 buf[], - unsigned long *bursts, const struct _xfer_spec *pxs) -{ - int cyc, cycmax, szlp, szlpend, szbrst, off; - unsigned lcnt0, lcnt1, ljmp0, ljmp1; - struct _arg_LPEND lpend; - - /* Max iterations possible in DMALP is 256 */ - if (*bursts >= 256*256) { - lcnt1 = 256; - lcnt0 = 256; - cyc = *bursts / lcnt1 / lcnt0; - } else if (*bursts > 256) { - lcnt1 = 256; - lcnt0 = *bursts / lcnt1; - cyc = 1; - } else { - lcnt1 = *bursts; - lcnt0 = 0; - cyc = 1; - } - - szlp = _emit_LP(1, buf, 0, 0); - szbrst = _bursts(1, buf, pxs, 1); - - lpend.cond = ALWAYS; - lpend.forever = false; - lpend.loop = 0; - lpend.bjump = 0; - szlpend = _emit_LPEND(1, buf, &lpend); - - if (lcnt0) { - szlp *= 2; - szlpend *= 2; - } - - /* - * Max bursts that we can unroll due to limit on the - * size of backward jump that can be encoded in DMALPEND - * which is 8-bits and hence 255 - */ - cycmax = (255 - (szlp + szlpend)) / szbrst; - - cyc = (cycmax < cyc) ? cycmax : cyc; - - off = 0; - - if (lcnt0) { - off += _emit_LP(dry_run, &buf[off], 0, lcnt0); - ljmp0 = off; - } - - off += _emit_LP(dry_run, &buf[off], 1, lcnt1); - ljmp1 = off; - - off += _bursts(dry_run, &buf[off], pxs, cyc); - - lpend.cond = ALWAYS; - lpend.forever = false; - lpend.loop = 1; - lpend.bjump = off - ljmp1; - off += _emit_LPEND(dry_run, &buf[off], &lpend); - - if (lcnt0) { - lpend.cond = ALWAYS; - lpend.forever = false; - lpend.loop = 0; - lpend.bjump = off - ljmp0; - off += _emit_LPEND(dry_run, &buf[off], &lpend); - } - - *bursts = lcnt1 * cyc; - if (lcnt0) - *bursts *= lcnt0; - - return off; -} - -static inline int _setup_loops(unsigned dry_run, u8 buf[], - const struct _xfer_spec *pxs) -{ - struct pl330_xfer *x = pxs->x; - u32 ccr = pxs->ccr; - unsigned long c, bursts = BYTE_TO_BURST(x->bytes, ccr); - int off = 0; - - while (bursts) { - c = bursts; - off += _loop(dry_run, &buf[off], &c, pxs); - bursts -= c; - } - - return off; -} - -static inline int _setup_xfer(unsigned dry_run, u8 buf[], - const struct _xfer_spec *pxs) -{ - struct pl330_xfer *x = pxs->x; - int off = 0; - - /* DMAMOV SAR, x->src_addr */ - off += _emit_MOV(dry_run, &buf[off], SAR, x->src_addr); - /* DMAMOV DAR, x->dst_addr */ - off += _emit_MOV(dry_run, &buf[off], DAR, x->dst_addr); - - /* Setup Loop(s) */ - off += _setup_loops(dry_run, &buf[off], pxs); - - return off; -} - -/* - * A req is a sequence of one or more xfer units. - * Returns the number of bytes taken to setup the MC for the req. - */ -static int _setup_req(unsigned dry_run, struct pl330_thread *thrd, - unsigned index, struct _xfer_spec *pxs) -{ - struct _pl330_req *req = &thrd->req[index]; - struct pl330_xfer *x; - u8 *buf = req->mc_cpu; - int off = 0; - - PL330_DBGMC_START(req->mc_bus); - - /* DMAMOV CCR, ccr */ - off += _emit_MOV(dry_run, &buf[off], CCR, pxs->ccr); - - x = pxs->r->x; - do { - /* Error if xfer length is not aligned at burst size */ - if (x->bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr))) - return -EINVAL; - - pxs->x = x; - off += _setup_xfer(dry_run, &buf[off], pxs); - - x = x->next; - } while (x); - - /* DMASEV peripheral/event */ - off += _emit_SEV(dry_run, &buf[off], thrd->ev); - /* DMAEND */ - off += _emit_END(dry_run, &buf[off]); - - return off; -} - -static inline u32 _prepare_ccr(const struct pl330_reqcfg *rqc) -{ - u32 ccr = 0; - - if (rqc->src_inc) - ccr |= CC_SRCINC; - - if (rqc->dst_inc) - ccr |= CC_DSTINC; - - /* We set same protection levels for Src and DST for now */ - if (rqc->privileged) - ccr |= CC_SRCPRI | CC_DSTPRI; - if (rqc->nonsecure) - ccr |= CC_SRCNS | CC_DSTNS; - if (rqc->insnaccess) - ccr |= CC_SRCIA | CC_DSTIA; - - ccr |= (((rqc->brst_len - 1) & 0xf) << CC_SRCBRSTLEN_SHFT); - ccr |= (((rqc->brst_len - 1) & 0xf) << CC_DSTBRSTLEN_SHFT); - - ccr |= (rqc->brst_size << CC_SRCBRSTSIZE_SHFT); - ccr |= (rqc->brst_size << CC_DSTBRSTSIZE_SHFT); - - ccr |= (rqc->scctl << CC_SRCCCTRL_SHFT); - ccr |= (rqc->dcctl << CC_DSTCCTRL_SHFT); - - ccr |= (rqc->swap << CC_SWAP_SHFT); - - return ccr; -} - -static inline bool _is_valid(u32 ccr) -{ - enum pl330_dstcachectrl dcctl; - enum pl330_srccachectrl scctl; - - dcctl = (ccr >> CC_DSTCCTRL_SHFT) & CC_DRCCCTRL_MASK; - scctl = (ccr >> CC_SRCCCTRL_SHFT) & CC_SRCCCTRL_MASK; - - if (dcctl == DINVALID1 || dcctl == DINVALID2 - || scctl == SINVALID1 || scctl == SINVALID2) - return false; - else - return true; -} - -/* - * Submit a list of xfers after which the client wants notification. - * Client is not notified after each xfer unit, just once after all - * xfer units are done or some error occurs. - */ -int pl330_submit_req(void *ch_id, struct pl330_req *r) -{ - struct pl330_thread *thrd = ch_id; - struct pl330_dmac *pl330; - struct pl330_info *pi; - struct _xfer_spec xs; - unsigned long flags; - void __iomem *regs; - unsigned idx; - u32 ccr; - int ret = 0; - - /* No Req or Unacquired Channel or DMAC */ - if (!r || !thrd || thrd->free) - return -EINVAL; - - pl330 = thrd->dmac; - pi = pl330->pinfo; - regs = pi->base; - - if (pl330->state == DYING - || pl330->dmac_tbd.reset_chan & (1 << thrd->id)) { - dev_info(thrd->dmac->pinfo->dev, "%s:%d\n", - __func__, __LINE__); - return -EAGAIN; - } - - /* If request for non-existing peripheral */ - if (r->rqtype != MEMTOMEM && r->peri >= pi->pcfg.num_peri) { - dev_info(thrd->dmac->pinfo->dev, - "%s:%d Invalid peripheral(%u)!\n", - __func__, __LINE__, r->peri); - return -EINVAL; - } - - spin_lock_irqsave(&pl330->lock, flags); - - if (_queue_full(thrd)) { - ret = -EAGAIN; - goto xfer_exit; - } - - /* Prefer Secure Channel */ - if (!_manager_ns(thrd)) - r->cfg->nonsecure = 0; - else - r->cfg->nonsecure = 1; - - /* Use last settings, if not provided */ - if (r->cfg) - ccr = _prepare_ccr(r->cfg); - else - ccr = readl(regs + CC(thrd->id)); - - /* If this req doesn't have valid xfer settings */ - if (!_is_valid(ccr)) { - ret = -EINVAL; - dev_info(thrd->dmac->pinfo->dev, "%s:%d Invalid CCR(%x)!\n", - __func__, __LINE__, ccr); - goto xfer_exit; - } - - idx = IS_FREE(&thrd->req[0]) ? 0 : 1; - - xs.ccr = ccr; - xs.r = r; - - /* First dry run to check if req is acceptable */ - ret = _setup_req(1, thrd, idx, &xs); - if (ret < 0) - goto xfer_exit; - - if (ret > pi->mcbufsz / 2) { - dev_info(thrd->dmac->pinfo->dev, - "%s:%d Trying increasing mcbufsz\n", - __func__, __LINE__); - ret = -ENOMEM; - goto xfer_exit; - } - - /* Hook the request */ - thrd->lstenq = idx; - thrd->req[idx].mc_len = _setup_req(0, thrd, idx, &xs); - thrd->req[idx].r = r; - - ret = 0; - -xfer_exit: - spin_unlock_irqrestore(&pl330->lock, flags); - - return ret; -} -EXPORT_SYMBOL(pl330_submit_req); - -static void pl330_dotask(unsigned long data) -{ - struct pl330_dmac *pl330 = (struct pl330_dmac *) data; - struct pl330_info *pi = pl330->pinfo; - unsigned long flags; - int i; - - spin_lock_irqsave(&pl330->lock, flags); - - /* The DMAC itself gone nuts */ - if (pl330->dmac_tbd.reset_dmac) { - pl330->state = DYING; - /* Reset the manager too */ - pl330->dmac_tbd.reset_mngr = true; - /* Clear the reset flag */ - pl330->dmac_tbd.reset_dmac = false; - } - - if (pl330->dmac_tbd.reset_mngr) { - _stop(pl330->manager); - /* Reset all channels */ - pl330->dmac_tbd.reset_chan = (1 << pi->pcfg.num_chan) - 1; - /* Clear the reset flag */ - pl330->dmac_tbd.reset_mngr = false; - } - - for (i = 0; i < pi->pcfg.num_chan; i++) { - - if (pl330->dmac_tbd.reset_chan & (1 << i)) { - struct pl330_thread *thrd = &pl330->channels[i]; - void __iomem *regs = pi->base; - enum pl330_op_err err; - - _stop(thrd); - - if (readl(regs + FSC) & (1 << thrd->id)) - err = PL330_ERR_FAIL; - else - err = PL330_ERR_ABORT; - - spin_unlock_irqrestore(&pl330->lock, flags); - - _callback(thrd->req[1 - thrd->lstenq].r, err); - _callback(thrd->req[thrd->lstenq].r, err); - - spin_lock_irqsave(&pl330->lock, flags); - - thrd->req[0].r = NULL; - thrd->req[1].r = NULL; - mark_free(thrd, 0); - mark_free(thrd, 1); - - /* Clear the reset flag */ - pl330->dmac_tbd.reset_chan &= ~(1 << i); - } - } - - spin_unlock_irqrestore(&pl330->lock, flags); - - return; -} - -/* Returns 1 if state was updated, 0 otherwise */ -int pl330_update(const struct pl330_info *pi) -{ - struct _pl330_req *rqdone; - struct pl330_dmac *pl330; - unsigned long flags; - void __iomem *regs; - u32 val; - int id, ev, ret = 0; - - if (!pi || !pi->pl330_data) - return 0; - - regs = pi->base; - pl330 = pi->pl330_data; - - spin_lock_irqsave(&pl330->lock, flags); - - val = readl(regs + FSM) & 0x1; - if (val) - pl330->dmac_tbd.reset_mngr = true; - else - pl330->dmac_tbd.reset_mngr = false; - - val = readl(regs + FSC) & ((1 << pi->pcfg.num_chan) - 1); - pl330->dmac_tbd.reset_chan |= val; - if (val) { - int i = 0; - while (i < pi->pcfg.num_chan) { - if (val & (1 << i)) { - dev_info(pi->dev, - "Reset Channel-%d\t CS-%x FTC-%x\n", - i, readl(regs + CS(i)), - readl(regs + FTC(i))); - _stop(&pl330->channels[i]); - } - i++; - } - } - - /* Check which event happened i.e, thread notified */ - val = readl(regs + ES); - if (pi->pcfg.num_events < 32 - && val & ~((1 << pi->pcfg.num_events) - 1)) { - pl330->dmac_tbd.reset_dmac = true; - dev_err(pi->dev, "%s:%d Unexpected!\n", __func__, __LINE__); - ret = 1; - goto updt_exit; - } - - for (ev = 0; ev < pi->pcfg.num_events; ev++) { - if (val & (1 << ev)) { /* Event occurred */ - struct pl330_thread *thrd; - u32 inten = readl(regs + INTEN); - int active; - - /* Clear the event */ - if (inten & (1 << ev)) - writel(1 << ev, regs + INTCLR); - - ret = 1; - - id = pl330->events[ev]; - - thrd = &pl330->channels[id]; - - active = thrd->req_running; - if (active == -1) /* Aborted */ - continue; - - rqdone = &thrd->req[active]; - mark_free(thrd, active); - - /* Get going again ASAP */ - _start(thrd); - - /* For now, just make a list of callbacks to be done */ - list_add_tail(&rqdone->rqd, &pl330->req_done); - } - } - - /* Now that we are in no hurry, do the callbacks */ - while (!list_empty(&pl330->req_done)) { - struct pl330_req *r; - - rqdone = container_of(pl330->req_done.next, - struct _pl330_req, rqd); - - list_del_init(&rqdone->rqd); - - /* Detach the req */ - r = rqdone->r; - rqdone->r = NULL; - - spin_unlock_irqrestore(&pl330->lock, flags); - _callback(r, PL330_ERR_NONE); - spin_lock_irqsave(&pl330->lock, flags); - } - -updt_exit: - spin_unlock_irqrestore(&pl330->lock, flags); - - if (pl330->dmac_tbd.reset_dmac - || pl330->dmac_tbd.reset_mngr - || pl330->dmac_tbd.reset_chan) { - ret = 1; - tasklet_schedule(&pl330->tasks); - } - - return ret; -} -EXPORT_SYMBOL(pl330_update); - -int pl330_chan_ctrl(void *ch_id, enum pl330_chan_op op) -{ - struct pl330_thread *thrd = ch_id; - struct pl330_dmac *pl330; - unsigned long flags; - int ret = 0, active; - - if (!thrd || thrd->free || thrd->dmac->state == DYING) - return -EINVAL; - - pl330 = thrd->dmac; - active = thrd->req_running; - - spin_lock_irqsave(&pl330->lock, flags); - - switch (op) { - case PL330_OP_FLUSH: - /* Make sure the channel is stopped */ - _stop(thrd); - - thrd->req[0].r = NULL; - thrd->req[1].r = NULL; - mark_free(thrd, 0); - mark_free(thrd, 1); - break; - - case PL330_OP_ABORT: - /* Make sure the channel is stopped */ - _stop(thrd); - - /* ABORT is only for the active req */ - if (active == -1) - break; - - thrd->req[active].r = NULL; - mark_free(thrd, active); - - /* Start the next */ - case PL330_OP_START: - if ((active == -1) && !_start(thrd)) - ret = -EIO; - break; - - default: - ret = -EINVAL; - } - - spin_unlock_irqrestore(&pl330->lock, flags); - return ret; -} -EXPORT_SYMBOL(pl330_chan_ctrl); - -int pl330_chan_status(void *ch_id, struct pl330_chanstatus *pstatus) -{ - struct pl330_thread *thrd = ch_id; - struct pl330_dmac *pl330; - struct pl330_info *pi; - void __iomem *regs; - int active; - u32 val; - - if (!pstatus || !thrd || thrd->free) - return -EINVAL; - - pl330 = thrd->dmac; - pi = pl330->pinfo; - regs = pi->base; - - /* The client should remove the DMAC and add again */ - if (pl330->state == DYING) - pstatus->dmac_halted = true; - else - pstatus->dmac_halted = false; - - val = readl(regs + FSC); - if (val & (1 << thrd->id)) - pstatus->faulting = true; - else - pstatus->faulting = false; - - active = thrd->req_running; - - if (active == -1) { - /* Indicate that the thread is not running */ - pstatus->top_req = NULL; - pstatus->wait_req = NULL; - } else { - pstatus->top_req = thrd->req[active].r; - pstatus->wait_req = !IS_FREE(&thrd->req[1 - active]) - ? thrd->req[1 - active].r : NULL; - } - - pstatus->src_addr = readl(regs + SA(thrd->id)); - pstatus->dst_addr = readl(regs + DA(thrd->id)); - - return 0; -} -EXPORT_SYMBOL(pl330_chan_status); - -/* Reserve an event */ -static inline int _alloc_event(struct pl330_thread *thrd) -{ - struct pl330_dmac *pl330 = thrd->dmac; - struct pl330_info *pi = pl330->pinfo; - int ev; - - for (ev = 0; ev < pi->pcfg.num_events; ev++) - if (pl330->events[ev] == -1) { - pl330->events[ev] = thrd->id; - return ev; - } - - return -1; -} - -static bool _chan_ns(const struct pl330_info *pi, int i) -{ - return pi->pcfg.irq_ns & (1 << i); -} - -/* Upon success, returns IdentityToken for the - * allocated channel, NULL otherwise. - */ -void *pl330_request_channel(const struct pl330_info *pi) -{ - struct pl330_thread *thrd = NULL; - struct pl330_dmac *pl330; - unsigned long flags; - int chans, i; - - if (!pi || !pi->pl330_data) - return NULL; - - pl330 = pi->pl330_data; - - if (pl330->state == DYING) - return NULL; - - chans = pi->pcfg.num_chan; - - spin_lock_irqsave(&pl330->lock, flags); - - for (i = 0; i < chans; i++) { - thrd = &pl330->channels[i]; - if ((thrd->free) && (!_manager_ns(thrd) || - _chan_ns(pi, i))) { - thrd->ev = _alloc_event(thrd); - if (thrd->ev >= 0) { - thrd->free = false; - thrd->lstenq = 1; - thrd->req[0].r = NULL; - mark_free(thrd, 0); - thrd->req[1].r = NULL; - mark_free(thrd, 1); - break; - } - } - thrd = NULL; - } - - spin_unlock_irqrestore(&pl330->lock, flags); - - return thrd; -} -EXPORT_SYMBOL(pl330_request_channel); - -/* Release an event */ -static inline void _free_event(struct pl330_thread *thrd, int ev) -{ - struct pl330_dmac *pl330 = thrd->dmac; - struct pl330_info *pi = pl330->pinfo; - - /* If the event is valid and was held by the thread */ - if (ev >= 0 && ev < pi->pcfg.num_events - && pl330->events[ev] == thrd->id) - pl330->events[ev] = -1; -} - -void pl330_release_channel(void *ch_id) -{ - struct pl330_thread *thrd = ch_id; - struct pl330_dmac *pl330; - unsigned long flags; - - if (!thrd || thrd->free) - return; - - _stop(thrd); - - _callback(thrd->req[1 - thrd->lstenq].r, PL330_ERR_ABORT); - _callback(thrd->req[thrd->lstenq].r, PL330_ERR_ABORT); - - pl330 = thrd->dmac; - - spin_lock_irqsave(&pl330->lock, flags); - _free_event(thrd, thrd->ev); - thrd->free = true; - spin_unlock_irqrestore(&pl330->lock, flags); -} -EXPORT_SYMBOL(pl330_release_channel); - -/* Initialize the structure for PL330 configuration, that can be used - * by the client driver the make best use of the DMAC - */ -static void read_dmac_config(struct pl330_info *pi) -{ - void __iomem *regs = pi->base; - u32 val; - - val = readl(regs + CRD) >> CRD_DATA_WIDTH_SHIFT; - val &= CRD_DATA_WIDTH_MASK; - pi->pcfg.data_bus_width = 8 * (1 << val); - - val = readl(regs + CRD) >> CRD_DATA_BUFF_SHIFT; - val &= CRD_DATA_BUFF_MASK; - pi->pcfg.data_buf_dep = val + 1; - - val = readl(regs + CR0) >> CR0_NUM_CHANS_SHIFT; - val &= CR0_NUM_CHANS_MASK; - val += 1; - pi->pcfg.num_chan = val; - - val = readl(regs + CR0); - if (val & CR0_PERIPH_REQ_SET) { - val = (val >> CR0_NUM_PERIPH_SHIFT) & CR0_NUM_PERIPH_MASK; - val += 1; - pi->pcfg.num_peri = val; - pi->pcfg.peri_ns = readl(regs + CR4); - } else { - pi->pcfg.num_peri = 0; - } - - val = readl(regs + CR0); - if (val & CR0_BOOT_MAN_NS) - pi->pcfg.mode |= DMAC_MODE_NS; - else - pi->pcfg.mode &= ~DMAC_MODE_NS; - - val = readl(regs + CR0) >> CR0_NUM_EVENTS_SHIFT; - val &= CR0_NUM_EVENTS_MASK; - val += 1; - pi->pcfg.num_events = val; - - pi->pcfg.irq_ns = readl(regs + CR3); - - pi->pcfg.periph_id = get_id(pi, PERIPH_ID); - pi->pcfg.pcell_id = get_id(pi, PCELL_ID); -} - -static inline void _reset_thread(struct pl330_thread *thrd) -{ - struct pl330_dmac *pl330 = thrd->dmac; - struct pl330_info *pi = pl330->pinfo; - - thrd->req[0].mc_cpu = pl330->mcode_cpu - + (thrd->id * pi->mcbufsz); - thrd->req[0].mc_bus = pl330->mcode_bus - + (thrd->id * pi->mcbufsz); - thrd->req[0].r = NULL; - mark_free(thrd, 0); - - thrd->req[1].mc_cpu = thrd->req[0].mc_cpu - + pi->mcbufsz / 2; - thrd->req[1].mc_bus = thrd->req[0].mc_bus - + pi->mcbufsz / 2; - thrd->req[1].r = NULL; - mark_free(thrd, 1); -} - -static int dmac_alloc_threads(struct pl330_dmac *pl330) -{ - struct pl330_info *pi = pl330->pinfo; - int chans = pi->pcfg.num_chan; - struct pl330_thread *thrd; - int i; - - /* Allocate 1 Manager and 'chans' Channel threads */ - pl330->channels = kzalloc((1 + chans) * sizeof(*thrd), - GFP_KERNEL); - if (!pl330->channels) - return -ENOMEM; - - /* Init Channel threads */ - for (i = 0; i < chans; i++) { - thrd = &pl330->channels[i]; - thrd->id = i; - thrd->dmac = pl330; - _reset_thread(thrd); - thrd->free = true; - } - - /* MANAGER is indexed at the end */ - thrd = &pl330->channels[chans]; - thrd->id = chans; - thrd->dmac = pl330; - thrd->free = false; - pl330->manager = thrd; - - return 0; -} - -static int dmac_alloc_resources(struct pl330_dmac *pl330) -{ - struct pl330_info *pi = pl330->pinfo; - int chans = pi->pcfg.num_chan; - int ret; - - /* - * Alloc MicroCode buffer for 'chans' Channel threads. - * A channel's buffer offset is (Channel_Id * MCODE_BUFF_PERCHAN) - */ - pl330->mcode_cpu = dma_alloc_coherent(pi->dev, - chans * pi->mcbufsz, - &pl330->mcode_bus, GFP_KERNEL); - if (!pl330->mcode_cpu) { - dev_err(pi->dev, "%s:%d Can't allocate memory!\n", - __func__, __LINE__); - return -ENOMEM; - } - - ret = dmac_alloc_threads(pl330); - if (ret) { - dev_err(pi->dev, "%s:%d Can't to create channels for DMAC!\n", - __func__, __LINE__); - dma_free_coherent(pi->dev, - chans * pi->mcbufsz, - pl330->mcode_cpu, pl330->mcode_bus); - return ret; - } - - return 0; -} - -int pl330_add(struct pl330_info *pi) -{ - struct pl330_dmac *pl330; - void __iomem *regs; - int i, ret; - - if (!pi || !pi->dev) - return -EINVAL; - - /* If already added */ - if (pi->pl330_data) - return -EINVAL; - - /* - * If the SoC can perform reset on the DMAC, then do it - * before reading its configuration. - */ - if (pi->dmac_reset) - pi->dmac_reset(pi); - - regs = pi->base; - - /* Check if we can handle this DMAC */ - if ((get_id(pi, PERIPH_ID) & 0xfffff) != PERIPH_ID_VAL - || get_id(pi, PCELL_ID) != PCELL_ID_VAL) { - dev_err(pi->dev, "PERIPH_ID 0x%x, PCELL_ID 0x%x !\n", - get_id(pi, PERIPH_ID), get_id(pi, PCELL_ID)); - return -EINVAL; - } - - /* Read the configuration of the DMAC */ - read_dmac_config(pi); - - if (pi->pcfg.num_events == 0) { - dev_err(pi->dev, "%s:%d Can't work without events!\n", - __func__, __LINE__); - return -EINVAL; - } - - pl330 = kzalloc(sizeof(*pl330), GFP_KERNEL); - if (!pl330) { - dev_err(pi->dev, "%s:%d Can't allocate memory!\n", - __func__, __LINE__); - return -ENOMEM; - } - - /* Assign the info structure and private data */ - pl330->pinfo = pi; - pi->pl330_data = pl330; - - spin_lock_init(&pl330->lock); - - INIT_LIST_HEAD(&pl330->req_done); - - /* Use default MC buffer size if not provided */ - if (!pi->mcbufsz) - pi->mcbufsz = MCODE_BUFF_PER_REQ * 2; - - /* Mark all events as free */ - for (i = 0; i < pi->pcfg.num_events; i++) - pl330->events[i] = -1; - - /* Allocate resources needed by the DMAC */ - ret = dmac_alloc_resources(pl330); - if (ret) { - dev_err(pi->dev, "Unable to create channels for DMAC\n"); - kfree(pl330); - return ret; - } - - tasklet_init(&pl330->tasks, pl330_dotask, (unsigned long) pl330); - - pl330->state = INIT; - - return 0; -} -EXPORT_SYMBOL(pl330_add); - -static int dmac_free_threads(struct pl330_dmac *pl330) -{ - struct pl330_info *pi = pl330->pinfo; - int chans = pi->pcfg.num_chan; - struct pl330_thread *thrd; - int i; - - /* Release Channel threads */ - for (i = 0; i < chans; i++) { - thrd = &pl330->channels[i]; - pl330_release_channel((void *)thrd); - } - - /* Free memory */ - kfree(pl330->channels); - - return 0; -} - -static void dmac_free_resources(struct pl330_dmac *pl330) -{ - struct pl330_info *pi = pl330->pinfo; - int chans = pi->pcfg.num_chan; - - dmac_free_threads(pl330); - - dma_free_coherent(pi->dev, chans * pi->mcbufsz, - pl330->mcode_cpu, pl330->mcode_bus); -} - -void pl330_del(struct pl330_info *pi) -{ - struct pl330_dmac *pl330; - - if (!pi || !pi->pl330_data) - return; - - pl330 = pi->pl330_data; - - pl330->state = UNINIT; - - tasklet_kill(&pl330->tasks); - - /* Free DMAC resources */ - dmac_free_resources(pl330); - - kfree(pl330); - pi->pl330_data = NULL; -} -EXPORT_SYMBOL(pl330_del); diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 61691cdbdcf2..9173d112ea01 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -16,6 +16,7 @@ */ #include <linux/module.h> #include <linux/init.h> +#include <linux/irq.h> #include <linux/kernel.h> #include <linux/delay.h> #include <linux/errno.h> @@ -28,9 +29,8 @@ #include <linux/io.h> #include <mach/hardware.h> -#include <asm/mach-types.h> -#include <asm/irq.h> #include <asm/mach/irq.h> +#include <asm/mach-types.h> #include <asm/sizes.h> #include <asm/hardware/sa1111.h> @@ -86,8 +86,10 @@ #define IRQ_S1_CD_VALID (52) #define IRQ_S0_BVD1_STSCHG (53) #define IRQ_S1_BVD1_STSCHG (54) +#define SA1111_IRQ_NR (55) -extern void __init sa1110_mb_enable(void); +extern void sa1110_mb_enable(void); +extern void sa1110_mb_disable(void); /* * We keep the following data for the overall SA1111. Note that the @@ -104,6 +106,7 @@ struct sa1111 { int irq_base; /* base for cascaded on-chip IRQs */ spinlock_t lock; void __iomem *base; + struct sa1111_platform_data *pdata; #ifdef CONFIG_PM void *saved_state; #endif @@ -118,6 +121,7 @@ static struct sa1111 *g_sa1111; struct sa1111_dev_info { unsigned long offset; unsigned long skpcr_mask; + bool dma; unsigned int devid; unsigned int irq[6]; }; @@ -126,6 +130,7 @@ static struct sa1111_dev_info sa1111_devices[] = { { .offset = SA1111_USB, .skpcr_mask = SKPCR_UCLKEN, + .dma = true, .devid = SA1111_DEVID_USB, .irq = { IRQ_USBPWR, @@ -139,6 +144,7 @@ static struct sa1111_dev_info sa1111_devices[] = { { .offset = 0x0600, .skpcr_mask = SKPCR_I2SCLKEN | SKPCR_L3CLKEN, + .dma = true, .devid = SA1111_DEVID_SAC, .irq = { AUDXMTDMADONEA, @@ -155,7 +161,7 @@ static struct sa1111_dev_info sa1111_devices[] = { { .offset = SA1111_KBD, .skpcr_mask = SKPCR_PTCLKEN, - .devid = SA1111_DEVID_PS2, + .devid = SA1111_DEVID_PS2_KBD, .irq = { IRQ_TPRXINT, IRQ_TPTXINT @@ -164,7 +170,7 @@ static struct sa1111_dev_info sa1111_devices[] = { { .offset = SA1111_MSE, .skpcr_mask = SKPCR_PMCLKEN, - .devid = SA1111_DEVID_PS2, + .devid = SA1111_DEVID_PS2_MSE, .irq = { IRQ_MSRXINT, IRQ_MSTXINT @@ -434,16 +440,28 @@ static struct irq_chip sa1111_high_chip = { .irq_set_wake = sa1111_wake_highirq, }; -static void sa1111_setup_irq(struct sa1111 *sachip) +static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base) { void __iomem *irqbase = sachip->base + SA1111_INTC; - unsigned int irq; + unsigned i, irq; + int ret; /* * We're guaranteed that this region hasn't been taken. */ request_mem_region(sachip->phys + SA1111_INTC, 512, "irq"); + ret = irq_alloc_descs(-1, irq_base, SA1111_IRQ_NR, -1); + if (ret <= 0) { + dev_err(sachip->dev, "unable to allocate %u irqs: %d\n", + SA1111_IRQ_NR, ret); + if (ret == 0) + ret = -EINVAL; + return ret; + } + + sachip->irq_base = ret; + /* disable all IRQs */ sa1111_writel(0, irqbase + SA1111_INTEN0); sa1111_writel(0, irqbase + SA1111_INTEN1); @@ -463,14 +481,16 @@ static void sa1111_setup_irq(struct sa1111 *sachip) sa1111_writel(~0, irqbase + SA1111_INTSTATCLR0); sa1111_writel(~0, irqbase + SA1111_INTSTATCLR1); - for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) { + for (i = IRQ_GPAIN0; i <= SSPROR; i++) { + irq = sachip->irq_base + i; irq_set_chip_and_handler(irq, &sa1111_low_chip, handle_edge_irq); irq_set_chip_data(irq, sachip); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } - for (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) { + for (i = AUDXMTDMADONEA; i <= IRQ_S1_BVD1_STSCHG; i++) { + irq = sachip->irq_base + i; irq_set_chip_and_handler(irq, &sa1111_high_chip, handle_edge_irq); irq_set_chip_data(irq, sachip); @@ -483,6 +503,11 @@ static void sa1111_setup_irq(struct sa1111 *sachip) irq_set_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING); irq_set_handler_data(sachip->irq, sachip); irq_set_chained_handler(sachip->irq, sa1111_irq_handler); + + dev_info(sachip->dev, "Providing IRQ%u-%u\n", + sachip->irq_base, sachip->irq_base + SA1111_IRQ_NR - 1); + + return 0; } /* @@ -581,41 +606,10 @@ sa1111_configure_smc(struct sa1111 *sachip, int sdram, unsigned int drac, } #endif -#ifdef CONFIG_DMABOUNCE -/* - * According to the "Intel StrongARM SA-1111 Microprocessor Companion - * Chip Specification Update" (June 2000), erratum #7, there is a - * significant bug in the SA1111 SDRAM shared memory controller. If - * an access to a region of memory above 1MB relative to the bank base, - * it is important that address bit 10 _NOT_ be asserted. Depending - * on the configuration of the RAM, bit 10 may correspond to one - * of several different (processor-relative) address bits. - * - * This routine only identifies whether or not a given DMA address - * is susceptible to the bug. - * - * This should only get called for sa1111_device types due to the - * way we configure our device dma_masks. - */ -static int sa1111_needs_bounce(struct device *dev, dma_addr_t addr, size_t size) -{ - /* - * Section 4.6 of the "Intel StrongARM SA-1111 Development Module - * User's Guide" mentions that jumpers R51 and R52 control the - * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or - * SDRAM bank 1 on Neponset). The default configuration selects - * Assabet, so any address in bank 1 is necessarily invalid. - */ - return (machine_is_assabet() || machine_is_pfs168()) && - (addr >= 0xc8000000 || (addr + size) >= 0xc8000000); -} -#endif - static void sa1111_dev_release(struct device *_dev) { struct sa1111_dev *dev = SA1111_DEV(_dev); - release_resource(&dev->res); kfree(dev); } @@ -624,67 +618,58 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, struct sa1111_dev_info *info) { struct sa1111_dev *dev; + unsigned i; int ret; dev = kzalloc(sizeof(struct sa1111_dev), GFP_KERNEL); if (!dev) { ret = -ENOMEM; - goto out; + goto err_alloc; } + device_initialize(&dev->dev); dev_set_name(&dev->dev, "%4.4lx", info->offset); dev->devid = info->devid; dev->dev.parent = sachip->dev; dev->dev.bus = &sa1111_bus_type; dev->dev.release = sa1111_dev_release; - dev->dev.coherent_dma_mask = sachip->dev->coherent_dma_mask; dev->res.start = sachip->phys + info->offset; dev->res.end = dev->res.start + 511; dev->res.name = dev_name(&dev->dev); dev->res.flags = IORESOURCE_MEM; dev->mapbase = sachip->base + info->offset; dev->skpcr_mask = info->skpcr_mask; - memmove(dev->irq, info->irq, sizeof(dev->irq)); - - ret = request_resource(parent, &dev->res); - if (ret) { - printk("SA1111: failed to allocate resource for %s\n", - dev->res.name); - dev_set_name(&dev->dev, NULL); - kfree(dev); - goto out; - } - - ret = device_register(&dev->dev); - if (ret) { - release_resource(&dev->res); - kfree(dev); - goto out; - } + for (i = 0; i < ARRAY_SIZE(info->irq); i++) + dev->irq[i] = sachip->irq_base + info->irq[i]; -#ifdef CONFIG_DMABOUNCE /* - * If the parent device has a DMA mask associated with it, - * propagate it down to the children. + * If the parent device has a DMA mask associated with it, and + * this child supports DMA, propagate it down to the children. */ - if (sachip->dev->dma_mask) { + if (info->dma && sachip->dev->dma_mask) { dev->dma_mask = *sachip->dev->dma_mask; dev->dev.dma_mask = &dev->dma_mask; + dev->dev.coherent_dma_mask = sachip->dev->coherent_dma_mask; + } - if (dev->dma_mask != 0xffffffffUL) { - ret = dmabounce_register_dev(&dev->dev, 1024, 4096, - sa1111_needs_bounce); - if (ret) { - dev_err(&dev->dev, "SA1111: Failed to register" - " with dmabounce\n"); - device_unregister(&dev->dev); - } - } + ret = request_resource(parent, &dev->res); + if (ret) { + dev_err(sachip->dev, "failed to allocate resource for %s\n", + dev->res.name); + goto err_resource; } -#endif -out: + ret = device_add(&dev->dev); + if (ret) + goto err_add; + return 0; + + err_add: + release_resource(&dev->res); + err_resource: + put_device(&dev->dev); + err_alloc: return ret; } @@ -698,16 +683,21 @@ out: * Returns: * %-ENODEV device not found. * %-EBUSY physical address already marked in-use. + * %-EINVAL no platform data passed * %0 successful. */ static int __devinit __sa1111_probe(struct device *me, struct resource *mem, int irq) { + struct sa1111_platform_data *pd = me->platform_data; struct sa1111 *sachip; unsigned long id; unsigned int has_devs; int i, ret = -ENODEV; + if (!pd) + return -EINVAL; + sachip = kzalloc(sizeof(struct sa1111), GFP_KERNEL); if (!sachip) return -ENOMEM; @@ -727,6 +717,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) sachip->dev = me; dev_set_drvdata(sachip->dev, sachip); + sachip->pdata = pd; sachip->phys = mem->start; sachip->irq = irq; @@ -759,6 +750,16 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) */ sa1111_wake(sachip); + /* + * The interrupt controller must be initialised before any + * other device to ensure that the interrupts are available. + */ + if (sachip->irq != NO_IRQ) { + ret = sa1111_setup_irq(sachip, pd->irq_base); + if (ret) + goto err_unmap; + } + #ifdef CONFIG_ARCH_SA1100 { unsigned int val; @@ -789,24 +790,14 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) } #endif - /* - * The interrupt controller must be initialised before any - * other device to ensure that the interrupts are available. - */ - if (sachip->irq != NO_IRQ) - sa1111_setup_irq(sachip); - g_sa1111 = sachip; has_devs = ~0; - if (machine_is_assabet() || machine_is_jornada720() || - machine_is_badge4()) - has_devs &= ~(1 << 4); - else - has_devs &= ~(1 << 1); + if (pd) + has_devs &= ~pd->disable_devs; for (i = 0; i < ARRAY_SIZE(sa1111_devices); i++) - if (has_devs & (1 << i)) + if (sa1111_devices[i].devid & has_devs) sa1111_init_one_child(sachip, mem, &sa1111_devices[i]); return 0; @@ -824,7 +815,10 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) static int sa1111_remove_one(struct device *dev, void *data) { - device_unregister(dev); + struct sa1111_dev *sadev = SA1111_DEV(dev); + device_del(&sadev->dev); + release_resource(&sadev->res); + put_device(&sadev->dev); return 0; } @@ -846,6 +840,7 @@ static void __sa1111_remove(struct sa1111 *sachip) if (sachip->irq != NO_IRQ) { irq_set_chained_handler(sachip->irq, NULL); irq_set_handler_data(sachip->irq, NULL); + irq_free_descs(sachip->irq_base, SA1111_IRQ_NR); release_mem_region(sachip->phys + SA1111_INTC, 512); } @@ -904,6 +899,9 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state) save->skpwm0 = sa1111_readl(base + SA1111_SKPWM0); save->skpwm1 = sa1111_readl(base + SA1111_SKPWM1); + sa1111_writel(0, sachip->base + SA1111_SKPWM0); + sa1111_writel(0, sachip->base + SA1111_SKPWM1); + base = sachip->base + SA1111_INTC; save->intpol0 = sa1111_readl(base + SA1111_INTPOL0); save->intpol1 = sa1111_readl(base + SA1111_INTPOL1); @@ -919,13 +917,15 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state) */ val = sa1111_readl(sachip->base + SA1111_SKCR); sa1111_writel(val | SKCR_SLEEP, sachip->base + SA1111_SKCR); - sa1111_writel(0, sachip->base + SA1111_SKPWM0); - sa1111_writel(0, sachip->base + SA1111_SKPWM1); clk_disable(sachip->clk); spin_unlock_irqrestore(&sachip->lock, flags); +#ifdef CONFIG_ARCH_SA1100 + sa1110_mb_disable(); +#endif + return 0; } @@ -966,6 +966,11 @@ static int sa1111_resume(struct platform_device *dev) */ sa1111_wake(sachip); +#ifdef CONFIG_ARCH_SA1100 + /* Enable the memory bus request/grant signals */ + sa1110_mb_enable(); +#endif + /* * Only lock for write ops. Also, sa1111_wake must be called with * released spinlock! @@ -1053,6 +1058,7 @@ static struct platform_driver sa1111_device_driver = { .resume = sa1111_resume, .driver = { .name = "sa1111", + .owner = THIS_MODULE, }, }; @@ -1238,16 +1244,23 @@ EXPORT_SYMBOL(sa1111_set_sleep_io); * sa1111_enable_device - enable an on-chip SA1111 function block * @sadev: SA1111 function block device to enable */ -void sa1111_enable_device(struct sa1111_dev *sadev) +int sa1111_enable_device(struct sa1111_dev *sadev) { struct sa1111 *sachip = sa1111_chip_driver(sadev); unsigned long flags; unsigned int val; + int ret = 0; - spin_lock_irqsave(&sachip->lock, flags); - val = sa1111_readl(sachip->base + SA1111_SKPCR); - sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR); - spin_unlock_irqrestore(&sachip->lock, flags); + if (sachip->pdata && sachip->pdata->enable) + ret = sachip->pdata->enable(sachip->pdata->data, sadev->devid); + + if (ret == 0) { + spin_lock_irqsave(&sachip->lock, flags); + val = sa1111_readl(sachip->base + SA1111_SKPCR); + sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR); + spin_unlock_irqrestore(&sachip->lock, flags); + } + return ret; } EXPORT_SYMBOL(sa1111_enable_device); @@ -1265,6 +1278,9 @@ void sa1111_disable_device(struct sa1111_dev *sadev) val = sa1111_readl(sachip->base + SA1111_SKPCR); sa1111_writel(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR); spin_unlock_irqrestore(&sachip->lock, flags); + + if (sachip->pdata && sachip->pdata->disable) + sachip->pdata->disable(sachip->pdata->data, sadev->devid); } EXPORT_SYMBOL(sa1111_disable_device); @@ -1279,7 +1295,7 @@ static int sa1111_match(struct device *_dev, struct device_driver *_drv) struct sa1111_dev *dev = SA1111_DEV(_dev); struct sa1111_driver *drv = SA1111_DRV(_drv); - return dev->devid == drv->devid; + return dev->devid & drv->devid; } static int sa1111_bus_suspend(struct device *dev, pm_message_t state) @@ -1304,6 +1320,14 @@ static int sa1111_bus_resume(struct device *dev) return ret; } +static void sa1111_bus_shutdown(struct device *dev) +{ + struct sa1111_driver *drv = SA1111_DRV(dev->driver); + + if (drv && drv->shutdown) + drv->shutdown(SA1111_DEV(dev)); +} + static int sa1111_bus_probe(struct device *dev) { struct sa1111_dev *sadev = SA1111_DEV(dev); @@ -1333,6 +1357,7 @@ struct bus_type sa1111_bus_type = { .remove = sa1111_bus_remove, .suspend = sa1111_bus_suspend, .resume = sa1111_bus_resume, + .shutdown = sa1111_bus_shutdown, }; EXPORT_SYMBOL(sa1111_bus_type); @@ -1349,9 +1374,70 @@ void sa1111_driver_unregister(struct sa1111_driver *driver) } EXPORT_SYMBOL(sa1111_driver_unregister); +#ifdef CONFIG_DMABOUNCE +/* + * According to the "Intel StrongARM SA-1111 Microprocessor Companion + * Chip Specification Update" (June 2000), erratum #7, there is a + * significant bug in the SA1111 SDRAM shared memory controller. If + * an access to a region of memory above 1MB relative to the bank base, + * it is important that address bit 10 _NOT_ be asserted. Depending + * on the configuration of the RAM, bit 10 may correspond to one + * of several different (processor-relative) address bits. + * + * This routine only identifies whether or not a given DMA address + * is susceptible to the bug. + * + * This should only get called for sa1111_device types due to the + * way we configure our device dma_masks. + */ +static int sa1111_needs_bounce(struct device *dev, dma_addr_t addr, size_t size) +{ + /* + * Section 4.6 of the "Intel StrongARM SA-1111 Development Module + * User's Guide" mentions that jumpers R51 and R52 control the + * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or + * SDRAM bank 1 on Neponset). The default configuration selects + * Assabet, so any address in bank 1 is necessarily invalid. + */ + return (machine_is_assabet() || machine_is_pfs168()) && + (addr >= 0xc8000000 || (addr + size) >= 0xc8000000); +} + +static int sa1111_notifier_call(struct notifier_block *n, unsigned long action, + void *data) +{ + struct sa1111_dev *dev = SA1111_DEV(data); + + switch (action) { + case BUS_NOTIFY_ADD_DEVICE: + if (dev->dev.dma_mask && dev->dma_mask < 0xffffffffUL) { + int ret = dmabounce_register_dev(&dev->dev, 1024, 4096, + sa1111_needs_bounce); + if (ret) + dev_err(&dev->dev, "failed to register with dmabounce: %d\n", ret); + } + break; + + case BUS_NOTIFY_DEL_DEVICE: + if (dev->dev.dma_mask && dev->dma_mask < 0xffffffffUL) + dmabounce_unregister_dev(&dev->dev); + break; + } + return NOTIFY_OK; +} + +static struct notifier_block sa1111_bus_notifier = { + .notifier_call = sa1111_notifier_call, +}; +#endif + static int __init sa1111_init(void) { int ret = bus_register(&sa1111_bus_type); +#ifdef CONFIG_DMABOUNCE + if (ret == 0) + bus_register_notifier(&sa1111_bus_type, &sa1111_bus_notifier); +#endif if (ret == 0) platform_driver_register(&sa1111_device_driver); return ret; @@ -1360,6 +1446,9 @@ static int __init sa1111_init(void) static void __exit sa1111_exit(void) { platform_driver_unregister(&sa1111_device_driver); +#ifdef CONFIG_DMABOUNCE + bus_unregister_notifier(&sa1111_bus_type, &sa1111_bus_notifier); +#endif bus_unregister(&sa1111_bus_type); } diff --git a/arch/arm/common/timer-sp.c b/arch/arm/common/timer-sp.c index 8794a34eae61..df13a3ffff35 100644 --- a/arch/arm/common/timer-sp.c +++ b/arch/arm/common/timer-sp.c @@ -26,6 +26,7 @@ #include <linux/irq.h> #include <linux/io.h> +#include <asm/sched_clock.h> #include <asm/hardware/arm_timer.h> static long __init sp804_get_clock_rate(const char *name) @@ -67,7 +68,16 @@ static long __init sp804_get_clock_rate(const char *name) return rate; } -void __init sp804_clocksource_init(void __iomem *base, const char *name) +static void __iomem *sched_clock_base; + +static u32 sp804_read(void) +{ + return ~readl_relaxed(sched_clock_base + TIMER_VALUE); +} + +void __init __sp804_clocksource_and_sched_clock_init(void __iomem *base, + const char *name, + int use_sched_clock) { long rate = sp804_get_clock_rate(name); @@ -83,6 +93,11 @@ void __init sp804_clocksource_init(void __iomem *base, const char *name) clocksource_mmio_init(base + TIMER_VALUE, name, rate, 200, 32, clocksource_mmio_readl_down); + + if (use_sched_clock) { + sched_clock_base = base; + setup_sched_clock(sp804_read, 32, rate); + } } diff --git a/arch/arm/common/via82c505.c b/arch/arm/common/via82c505.c index 67dd2affc57a..1171a5010aea 100644 --- a/arch/arm/common/via82c505.c +++ b/arch/arm/common/via82c505.c @@ -6,7 +6,6 @@ #include <linux/ioport.h> #include <linux/io.h> -#include <asm/system.h> #include <asm/mach/pci.h> diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c index 7a66311f3066..7e288f96cedf 100644 --- a/arch/arm/common/vic.c +++ b/arch/arm/common/vic.c @@ -427,19 +427,18 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent) /* * Handle each interrupt in a single VIC. Returns non-zero if we've - * handled at least one interrupt. This does a single read of the - * status register and handles all interrupts in order from LSB first. + * handled at least one interrupt. 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 int handle_one_vic(struct vic_device *vic, struct pt_regs *regs) { u32 stat, irq; int handled = 0; - stat = readl_relaxed(vic->base + VIC_IRQ_STATUS); - while (stat) { + while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) { irq = ffs(stat) - 1; handle_IRQ(irq_find_mapping(vic->domain, irq), regs); - stat &= ~(1 << irq); handled = 1; } diff --git a/arch/arm/configs/at91cap9_defconfig b/arch/arm/configs/at91cap9_defconfig deleted file mode 100644 index 8826eb218e73..000000000000 --- a/arch/arm/configs/at91cap9_defconfig +++ /dev/null @@ -1,108 +0,0 @@ -CONFIG_EXPERIMENTAL=y -# CONFIG_LOCALVERSION_AUTO is not set -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_BLK_DEV_INITRD=y -CONFIG_SLAB=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_ARCH_AT91=y -CONFIG_ARCH_AT91CAP9=y -CONFIG_MACH_AT91CAP9ADK=y -CONFIG_MTD_AT91_DATAFLASH_CARD=y -CONFIG_AT91_PROGRAMMABLE_CLOCKS=y -# CONFIG_ARM_THUMB is not set -CONFIG_AEABI=y -CONFIG_LEDS=y -CONFIG_LEDS_CPU=y -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/ram0 rw" -CONFIG_FPE_NWFPE=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -# CONFIG_INET_DIAG is not set -# CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_DATAFLASH=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_ATMEL=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_SCSI=y -CONFIG_BLK_DEV_SD=y -CONFIG_SCSI_MULTI_LUN=y -CONFIG_NETDEVICES=y -CONFIG_MII=y -CONFIG_MACB=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_ADS7846=y -# CONFIG_SERIO is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -CONFIG_HW_RANDOM=y -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_WATCHDOG_NOWAYOUT=y -CONFIG_FB=y -CONFIG_FB_ATMEL=y -CONFIG_LOGO=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_CLUT224 is not set -# CONFIG_USB_HID is not set -CONFIG_USB=y -CONFIG_USB_DEVICEFS=y -CONFIG_USB_MON=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_STORAGE=y -CONFIG_USB_GADGET=y -CONFIG_USB_ETH=m -CONFIG_USB_FILE_STORAGE=m -CONFIG_MMC=y -CONFIG_MMC_AT91=m -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT91SAM9=y -CONFIG_EXT2_FS=y -CONFIG_VFAT_FS=y -CONFIG_TMPFS=y -CONFIG_JFFS2_FS=y -CONFIG_CRAMFS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_850=y -CONFIG_NLS_ISO8859_1=y -CONFIG_DEBUG_FS=y -CONFIG_DEBUG_KERNEL=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_USER=y diff --git a/arch/arm/configs/at91sam9g20_defconfig b/arch/arm/configs/at91sam9g20_defconfig index 9123568d9a8d..994d331b2319 100644 --- a/arch/arm/configs/at91sam9g20_defconfig +++ b/arch/arm/configs/at91sam9g20_defconfig @@ -74,6 +74,8 @@ CONFIG_LEGACY_PTY_COUNT=16 CONFIG_SERIAL_ATMEL=y CONFIG_SERIAL_ATMEL_CONSOLE=y CONFIG_HW_RANDOM=y +CONFIG_I2C=y +CONFIG_I2C_GPIO=y CONFIG_SPI=y CONFIG_SPI_ATMEL=y CONFIG_SPI_SPIDEV=y @@ -105,6 +107,7 @@ CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_RV3029C2=y CONFIG_RTC_DRV_AT91SAM9=y CONFIG_EXT2_FS=y CONFIG_MSDOS_FS=y diff --git a/arch/arm/configs/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig index a22e93079063..b5ac644e12af 100644 --- a/arch/arm/configs/imx_v4_v5_defconfig +++ b/arch/arm/configs/imx_v4_v5_defconfig @@ -45,6 +45,7 @@ CONFIG_FPE_NWFPE=y CONFIG_FPE_NWFPE_XP=y CONFIG_PM_DEBUG=y CONFIG_NET=y +CONFIG_SMSC911X=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y @@ -68,6 +69,7 @@ CONFIG_MTD_CFI=y CONFIG_MTD_CFI_ADV_OPTIONS=y CONFIG_MTD_CFI_GEOMETRY=y # CONFIG_MTD_MAP_BANK_WIDTH_1 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y # CONFIG_MTD_CFI_I2 is not set CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_PHYSMAP=y @@ -78,6 +80,8 @@ CONFIG_MISC_DEVICES=y CONFIG_EEPROM_AT24=y CONFIG_EEPROM_AT25=y CONFIG_NETDEVICES=y +CONFIG_CS89x0=y +CONFIG_CS89x0_PLATFORM=y CONFIG_DM9000=y CONFIG_SMC91X=y CONFIG_SMC911X=y @@ -115,6 +119,21 @@ CONFIG_FB_IMX=y CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_LCD_L4F00242T03=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_COMMON=y +CONFIG_VIDEO_MEDIA=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEOBUF_GEN=y +CONFIG_VIDEOBUF_DMA_CONTIG=y +CONFIG_VIDEOBUF2_CORE=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_SOC_CAMERA=y +CONFIG_SOC_CAMERA_OV2640=y +CONFIG_VIDEO_MX2_HOSTSUPPORT=y +CONFIG_VIDEO_MX2=y CONFIG_BACKLIGHT_PWM=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FONTS=y diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index 3a4fb2e5fc68..dc6f6411bbf5 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig @@ -5,6 +5,7 @@ CONFIG_SYSVIPC=y CONFIG_LOG_BUF_SHIFT=18 CONFIG_CGROUPS=y CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y CONFIG_EXPERT=y # CONFIG_SLUB_DEBUG is not set # CONFIG_COMPAT_BRK is not set @@ -12,7 +13,6 @@ CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y -# CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set CONFIG_ARCH_MXC=y CONFIG_MACH_MX31LILLY=y @@ -26,7 +26,6 @@ CONFIG_MACH_ARMADILLO5X0=y CONFIG_MACH_KZM_ARM11_01=y CONFIG_MACH_PCM043=y CONFIG_MACH_MX35_3DS=y -CONFIG_MACH_EUKREA_CPUIMX35=y CONFIG_MACH_VPR200=y CONFIG_MACH_IMX51_DT=y CONFIG_MACH_MX51_3DS=y @@ -82,8 +81,9 @@ CONFIG_PATA_IMX=y CONFIG_NETDEVICES=y # CONFIG_NET_VENDOR_BROADCOM is not set # CONFIG_NET_VENDOR_CHELSIO is not set +CONFIG_CS89x0=y +CONFIG_CS89x0_PLATFORM=y # CONFIG_NET_VENDOR_FARADAY is not set -CONFIG_FEC=y # CONFIG_NET_VENDOR_INTEL is not set # CONFIG_NET_VENDOR_MARVELL is not set # CONFIG_NET_VENDOR_MICREL is not set @@ -126,7 +126,40 @@ CONFIG_WATCHDOG=y CONFIG_IMX2_WDT=y CONFIG_MFD_MC13XXX=y CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_MC13783=y CONFIG_REGULATOR_MC13892=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_COMMON=y +CONFIG_VIDEOBUF_GEN=y +CONFIG_VIDEOBUF2_CORE=y +CONFIG_VIDEOBUF2_MEMOPS=y +CONFIG_VIDEOBUF2_DMA_CONTIG=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_SOC_CAMERA=y +CONFIG_SOC_CAMERA_OV2640=y +CONFIG_MX3_VIDEO=y +CONFIG_VIDEO_MX3=y +CONFIG_FB=y +CONFIG_FB_MX3=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=y +CONFIG_LCD_L4F00242T03=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GENERIC=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_MXC=y diff --git a/arch/arm/configs/integrator_defconfig b/arch/arm/configs/integrator_defconfig index 1103f62a1964..a8314c3ee84d 100644 --- a/arch/arm/configs/integrator_defconfig +++ b/arch/arm/configs/integrator_defconfig @@ -57,18 +57,24 @@ CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_NET_PCI=y CONFIG_E100=y +CONFIG_SMC91X=y # CONFIG_KEYBOARD_ATKBD is not set # CONFIG_SERIO_SERPORT is not set CONFIG_SERIAL_AMBA_PL010=y CONFIG_SERIAL_AMBA_PL010_CONSOLE=y CONFIG_FB=y CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_ARMCLCD=y CONFIG_FB_MATROX=y CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y +# CONFIG_VGA_CONSOLE is not set +CONFIG_MMC=y +CONFIG_MMC_ARMMMCI=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_PL030=y CONFIG_EXT2_FS=y +CONFIG_VFAT_FS=y CONFIG_TMPFS=y CONFIG_JFFS2_FS=y CONFIG_CRAMFS=y @@ -78,5 +84,7 @@ CONFIG_ROOT_NFS=y CONFIG_NFSD=y CONFIG_NFSD_V3=y CONFIG_PARTITION_ADVANCED=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y diff --git a/arch/arm/configs/lpc32xx_defconfig b/arch/arm/configs/lpc32xx_defconfig new file mode 100644 index 000000000000..fb2088171ca9 --- /dev/null +++ b/arch/arm/configs/lpc32xx_defconfig @@ -0,0 +1,145 @@ +CONFIG_EXPERIMENTAL=y +CONFIG_SYSVIPC=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_EMBEDDED=y +CONFIG_SLAB=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_BLK_DEV_BSG is not set +CONFIG_PARTITION_ADVANCED=y +CONFIG_ARCH_LPC32XX=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_PREEMPT=y +CONFIG_AEABI=y +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyS0,115200n81 root=/dev/ram0" +CONFIG_CPU_IDLE=y +CONFIG_FPE_NWFPE=y +CONFIG_VFP=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_BINFMT_AOUT=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_IPV6 is not set +# CONFIG_WIRELESS is not set +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_FW_LOADER is not set +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_MUSEUM_IDS=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=1 +CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_MISC_DEVICES=y +CONFIG_EEPROM_AT25=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_NETDEVICES=y +CONFIG_MII=y +CONFIG_PHYLIB=y +CONFIG_SMSC_PHY=y +# CONFIG_WLAN is not set +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=240 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320 +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_LPC32XX=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_HW_RANDOM is not set +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_PNX=y +CONFIG_SPI=y +CONFIG_SPI_PL022=y +CONFIG_GPIO_SYSFS=y +# CONFIG_HWMON is not set +CONFIG_WATCHDOG=y +CONFIG_PNX4008_WATCHDOG=y +CONFIG_FB=y +CONFIG_FB_ARMCLCD=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_SEQUENCER=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_DYNAMIC_MINORS=y +# CONFIG_SND_VERBOSE_PROCFS is not set +# CONFIG_SND_DRIVERS is not set +# CONFIG_SND_ARM is not set +# CONFIG_SND_SPI is not set +CONFIG_SND_SOC=y +# CONFIG_HID_SUPPORT is not set +CONFIG_USB=y +CONFIG_USB_STORAGE=y +CONFIG_USB_LIBUSUAL=y +CONFIG_MMC=y +# CONFIG_MMC_BLOCK_BOUNCE is not set +CONFIG_MMC_ARMMMCI=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_DRV_LPC32XX=y +CONFIG_EXT2_FS=y +CONFIG_AUTOFS4_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_WBUF_VERIFY=y +CONFIG_CRAMFS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_ROOT_NFS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_UTF8=y +# CONFIG_SCHED_DEBUG is not set +# CONFIG_DEBUG_PREEMPT is not set +CONFIG_DEBUG_INFO=y +# CONFIG_FTRACE is not set +# CONFIG_ARM_UNWIND is not set +CONFIG_DEBUG_LL=y +CONFIG_EARLY_PRINTK=y +CONFIG_CRYPTO_ANSI_CPRNG=y +# CONFIG_CRYPTO_HW is not set +CONFIG_CRC_CCITT=y diff --git a/arch/arm/configs/magician_defconfig b/arch/arm/configs/magician_defconfig index 443675d317e6..a691ef4c6008 100644 --- a/arch/arm/configs/magician_defconfig +++ b/arch/arm/configs/magician_defconfig @@ -101,7 +101,7 @@ CONFIG_MFD_ASIC3=y CONFIG_HTC_EGPIO=y CONFIG_HTC_PASIC3=y CONFIG_REGULATOR=y -CONFIG_REGULATOR_BQ24022=y +CONFIG_REGULATOR_GPIO=y CONFIG_FB=y CONFIG_FB_PXA=y CONFIG_FB_PXA_OVERLAY=y diff --git a/arch/arm/configs/mini2440_defconfig b/arch/arm/configs/mini2440_defconfig index 2472a9585834..42da9183acc8 100644 --- a/arch/arm/configs/mini2440_defconfig +++ b/arch/arm/configs/mini2440_defconfig @@ -13,7 +13,7 @@ CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set CONFIG_BLK_DEV_INTEGRITY=y -CONFIG_ARCH_S3C2410=y +CONFIG_ARCH_S3C24XX=y CONFIG_S3C_ADC=y CONFIG_S3C24XX_PWM=y CONFIG_MACH_MINI2440=y diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig index 6ee781bf6bf1..1ebbf451c48d 100644 --- a/arch/arm/configs/mxs_defconfig +++ b/arch/arm/configs/mxs_defconfig @@ -77,10 +77,10 @@ CONFIG_DEVPTS_MULTIPLE_INSTANCES=y CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y # CONFIG_HW_RANDOM is not set -CONFIG_I2C=m +CONFIG_I2C=y # CONFIG_I2C_COMPAT is not set -CONFIG_I2C_CHARDEV=m -CONFIG_I2C_MXS=m +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MXS=y CONFIG_SPI=y CONFIG_SPI_GPIO=m CONFIG_DEBUG_GPIO=y @@ -90,6 +90,20 @@ CONFIG_GPIO_SYSFS=y CONFIG_DISPLAY_SUPPORT=m # CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_JACK=y +CONFIG_SND_DRIVERS=y +CONFIG_SND_ARM=y +CONFIG_SND_SOC=y +CONFIG_SND_MXS_SOC=y +CONFIG_SND_SOC_MXS_SGTL5000=y +CONFIG_SND_SOC_I2C_AND_SPI=y +CONFIG_SND_SOC_SGTL5000=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_MMC=y CONFIG_MMC_MXS=y CONFIG_RTC_CLASS=y diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index f9096c1b0a65..193448f31284 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig @@ -3,40 +3,47 @@ CONFIG_SYSVIPC=y CONFIG_IKCONFIG=m CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=16 -CONFIG_SYSFS_DEPRECATED_V2=y CONFIG_BLK_DEV_INITRD=y CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set -CONFIG_ARCH_S3C2410=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_BSD_DISKLABEL=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_ARCH_S3C24XX=y CONFIG_S3C_BOOT_ERROR_RESET=y CONFIG_S3C_ADC=y CONFIG_S3C24XX_PWM=y -CONFIG_ARCH_SMDK2410=y +CONFIG_CPU_S3C2412=y +CONFIG_CPU_S3C2416=y +CONFIG_CPU_S3C2440=y +CONFIG_CPU_S3C2442=y +CONFIG_CPU_S3C2443=y +CONFIG_MACH_AML_M5900=y +CONFIG_ARCH_BAST=y CONFIG_ARCH_H1940=y CONFIG_MACH_N30=y -CONFIG_ARCH_BAST=y CONFIG_MACH_OTOM=y -CONFIG_MACH_AML_M5900=y +CONFIG_MACH_QT2410=y +CONFIG_ARCH_SMDK2410=y CONFIG_MACH_TCT_HAMMER=y CONFIG_MACH_VR1000=y -CONFIG_MACH_QT2410=y CONFIG_MACH_JIVE=y CONFIG_MACH_SMDK2412=y CONFIG_MACH_VSTMS=y CONFIG_MACH_SMDK2416=y CONFIG_MACH_ANUBIS=y -CONFIG_MACH_NEO1973_GTA02=y +CONFIG_MACH_AT2440EVB=y +CONFIG_MACH_MINI2440=y +CONFIG_MACH_NEXCODER_2440=y CONFIG_MACH_OSIRIS=y CONFIG_MACH_OSIRIS_DVS=m CONFIG_MACH_RX3715=y CONFIG_ARCH_S3C2440=y -CONFIG_MACH_NEXCODER_2440=y -CONFIG_SMDK2440_CPU2442=y -CONFIG_MACH_AT2440EVB=y -CONFIG_MACH_MINI2440=y +CONFIG_MACH_NEO1973_GTA02=y CONFIG_MACH_RX1950=y +CONFIG_SMDK2440_CPU2442=y CONFIG_MACH_SMDK2443=y # CONFIG_ARM_THUMB is not set CONFIG_ZBOOT_ROM_TEXT=0x0 @@ -45,7 +52,6 @@ CONFIG_CMDLINE="root=/dev/hda1 ro init=/bin/bash console=ttySAC0" CONFIG_FPE_NWFPE=y CONFIG_FPE_NWFPE_XP=y CONFIG_BINFMT_AOUT=y -CONFIG_PM=y CONFIG_APM_EMULATION=m CONFIG_NET=y CONFIG_PACKET=y @@ -58,7 +64,6 @@ CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_NET_IPIP=m -CONFIG_NET_IPGRE=m CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m @@ -80,7 +85,6 @@ CONFIG_IPV6_MIP6=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_TUNNEL=m CONFIG_NETFILTER=y -CONFIG_NETFILTER_NETLINK_QUEUE=m CONFIG_NF_CONNTRACK=m CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CT_PROTO_DCCP=m @@ -138,7 +142,6 @@ CONFIG_IP_VS=m CONFIG_NF_CONNTRACK_IPV4=m CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m CONFIG_IP_NF_MATCH_TTL=m @@ -150,7 +153,6 @@ CONFIG_NF_NAT=m CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m @@ -177,8 +179,6 @@ CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m CONFIG_BT=m -CONFIG_BT_L2CAP=m -CONFIG_BT_SCO=m CONFIG_BT_RFCOMM=m CONFIG_BT_RFCOMM_TTY=y CONFIG_BT_BNEP=m @@ -199,7 +199,6 @@ CONFIG_MAC80211_MESH=y CONFIG_MAC80211_LEDS=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y CONFIG_MTD_CMDLINE_PARTS=y @@ -221,9 +220,6 @@ CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_UB=m CONFIG_BLK_DEV_RAM=y CONFIG_ATA_OVER_ETH=m -CONFIG_EEPROM_AT25=m -CONFIG_EEPROM_LEGACY=m -CONFIG_EEPROM_93CX6=m CONFIG_IDE=y CONFIG_BLK_DEV_IDECD=y CONFIG_BLK_DEV_IDETAPE=m @@ -240,7 +236,6 @@ CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SCAN_ASYNC=y CONFIG_NETDEVICES=y -CONFIG_NET_ETHERNET=y CONFIG_DM9000=y CONFIG_INPUT_EVDEV=y CONFIG_MOUSE_APPLETOUCH=m @@ -274,7 +269,6 @@ CONFIG_JOYSTICK_XPAD_LEDS=y CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_USB_COMPOSITE=m CONFIG_INPUT_MISC=y -CONFIG_INPUT_ATI_REMOTE=m CONFIG_INPUT_ATI_REMOTE2=m CONFIG_INPUT_KEYSPAN_REMOTE=m CONFIG_INPUT_POWERMATE=m @@ -300,7 +294,6 @@ CONFIG_I2C_SIMTEC=y CONFIG_SPI=y CONFIG_SPI_GPIO=m CONFIG_SPI_S3C24XX=m -CONFIG_SPI_S3C24XX_GPIO=m CONFIG_SPI_SPIDEV=m CONFIG_SPI_TLE62X0=m CONFIG_SENSORS_LM75=m @@ -315,7 +308,6 @@ CONFIG_FB_MODE_HELPERS=y CONFIG_FB_S3C2410=y CONFIG_FB_SM501=y CONFIG_BACKLIGHT_PWM=m -# CONFIG_VGA_CONSOLE is not set CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_SOUND=y CONFIG_SND=y @@ -330,10 +322,6 @@ CONFIG_SND_VERBOSE_PRINTK=y CONFIG_SND_USB_AUDIO=m CONFIG_SND_USB_CAIAQ=m CONFIG_SND_SOC=y -CONFIG_SND_S3C24XX_SOC=y -CONFIG_SND_S3C24XX_SOC_JIVE_WM8750=m -CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710=m -CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650=m # CONFIG_USB_HID is not set CONFIG_USB=y CONFIG_USB_DEVICEFS=y @@ -387,9 +375,7 @@ CONFIG_MMC_TEST=m CONFIG_MMC_SDHCI=m CONFIG_MMC_SPI=m CONFIG_MMC_S3C=y -CONFIG_LEDS_CLASS=m CONFIG_LEDS_S3C24XX=m -CONFIG_LEDS_H1940=m CONFIG_LEDS_PCA9532=m CONFIG_LEDS_GPIO=m CONFIG_LEDS_PCA955X=m @@ -410,8 +396,6 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_EXT4_FS=m CONFIG_EXT4_FS_POSIX_ACL=y -CONFIG_INOTIFY=y -CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m CONFIG_ISO9660_FS=y @@ -436,9 +420,6 @@ CONFIG_NFSD=m CONFIG_NFSD_V3_ACL=y CONFIG_NFSD_V4=y CONFIG_CIFS=m -CONFIG_PARTITION_ADVANCED=y -CONFIG_BSD_DISKLABEL=y -CONFIG_SOLARIS_X86_PARTITION=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_737=m CONFIG_NLS_CODEPAGE_775=m @@ -481,9 +462,7 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_MUTEXES=y CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_DEBUG_USER=y -CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/arm/configs/tct_hammer_defconfig b/arch/arm/configs/tct_hammer_defconfig index 95c0f0d63db6..1d24f8458bef 100644 --- a/arch/arm/configs/tct_hammer_defconfig +++ b/arch/arm/configs/tct_hammer_defconfig @@ -14,7 +14,7 @@ CONFIG_SLOB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set -CONFIG_ARCH_S3C2410=y +CONFIG_ARCH_S3C24XX=y CONFIG_MACH_TCT_HAMMER=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig index fd5d3041d717..351d6708c3ae 100644 --- a/arch/arm/configs/tegra_defconfig +++ b/arch/arm/configs/tegra_defconfig @@ -11,11 +11,14 @@ CONFIG_RT_GROUP_SCHED=y CONFIG_BLK_DEV_INITRD=y # CONFIG_ELF_CORE is not set CONFIG_EMBEDDED=y +CONFIG_PERF_EVENTS=y CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set +CONFIG_PARTITION_ADVANCED=y +CONFIG_EFI_PARTITION=y # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set CONFIG_ARCH_TEGRA=y @@ -27,18 +30,20 @@ CONFIG_MACH_PAZ00=y CONFIG_MACH_TRIMSLICE=y CONFIG_MACH_WARIO=y CONFIG_MACH_VENTANA=y -CONFIG_TEGRA_DEBUG_UARTD=y -CONFIG_ARM_ERRATA_742230=y +CONFIG_TEGRA_EMC_SCALING_ENABLE=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_SMP=y -CONFIG_NR_CPUS=2 CONFIG_PREEMPT=y CONFIG_AEABI=y # CONFIG_OABI_COMPAT is not set CONFIG_HIGHMEM=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_AUTO_ZRELADDR=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +CONFIG_CPU_IDLE=y CONFIG_VFP=y CONFIG_NET=y CONFIG_PACKET=y @@ -68,7 +73,6 @@ CONFIG_IPV6_MULTIPLE_TABLES=y # CONFIG_FIRMWARE_IN_KERNEL is not set CONFIG_PROC_DEVICETREE=y CONFIG_BLK_DEV_LOOP=y -CONFIG_MISC_DEVICES=y CONFIG_AD525X_DPOT=y CONFIG_AD525X_DPOT_I2C=y CONFIG_ICS932S401=y @@ -76,6 +80,7 @@ CONFIG_APDS9802ALS=y CONFIG_ISL29003=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y +CONFIG_BLK_DEV_SR=y # CONFIG_SCSI_LOWLEVEL is not set CONFIG_NETDEVICES=y CONFIG_DUMMY=y @@ -85,8 +90,7 @@ CONFIG_USB_USBNET=y CONFIG_USB_NET_SMSC75XX=y CONFIG_USB_NET_SMSC95XX=y # CONFIG_WLAN is not set -# CONFIG_INPUT is not set -# CONFIG_SERIO is not set +CONFIG_INPUT_EVDEV=y # CONFIG_VT is not set # CONFIG_LEGACY_PTYS is not set # CONFIG_DEVKMEM is not set @@ -96,13 +100,15 @@ CONFIG_SERIAL_OF_PLATFORM=y # CONFIG_HW_RANDOM is not set CONFIG_I2C=y # CONFIG_I2C_COMPAT is not set -# CONFIG_I2C_HELPER_AUTO is not set CONFIG_I2C_TEGRA=y CONFIG_SPI=y CONFIG_SPI_TEGRA=y CONFIG_SENSORS_LM90=y CONFIG_MFD_TPS6586X=y CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_VIRTUAL_CONSUMER=y +CONFIG_REGULATOR_GPIO=y CONFIG_REGULATOR_TPS6586X=y CONFIG_SOUND=y CONFIG_SND=y @@ -116,11 +122,13 @@ CONFIG_SND_SOC=y CONFIG_SND_SOC_TEGRA=y CONFIG_SND_SOC_TEGRA_WM8903=y CONFIG_SND_SOC_TEGRA_TRIMSLICE=y +CONFIG_SND_SOC_TEGRA_ALC5632=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_TEGRA=y CONFIG_USB_STORAGE=y CONFIG_MMC=y +CONFIG_MMC_BLOCK_MINORS=16 CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_TEGRA=y @@ -130,6 +138,11 @@ CONFIG_STAGING=y CONFIG_IIO=y CONFIG_SENSORS_ISL29018=y CONFIG_SENSORS_AK8975=y +CONFIG_MFD_NVEC=y +CONFIG_KEYBOARD_NVEC=y +CONFIG_SERIO_NVEC_PS2=y +CONFIG_TEGRA_IOMMU_GART=y +CONFIG_TEGRA_IOMMU_SMMU=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y @@ -138,13 +151,12 @@ CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=y # CONFIG_DNOTIFY is not set CONFIG_VFAT_FS=y CONFIG_TMPFS=y CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y -CONFIG_PARTITION_ADVANCED=y -CONFIG_EFI_PARTITION=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y @@ -162,9 +174,8 @@ CONFIG_DEBUG_SG=y CONFIG_DEBUG_LL=y CONFIG_EARLY_PRINTK=y CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_AES=y CONFIG_CRYPTO_ARC4=y CONFIG_CRYPTO_TWOFISH=y # CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_DEV_TEGRA_AES=y CONFIG_CRC_CCITT=y -CONFIG_CRC16=y diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index 2d7b6e7b7271..889d73ac1ae1 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -13,6 +13,7 @@ CONFIG_UX500_SOC_DB8500=y CONFIG_MACH_HREFV60=y CONFIG_MACH_SNOWBALL=y CONFIG_MACH_U5500=y +CONFIG_MACH_UX500_DT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_SMP=y diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 23371b17b23e..03fb93621d0d 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -23,6 +23,8 @@ #include <asm/ptrace.h> #include <asm/domain.h> +#define IOMEM(x) (x) + /* * Endian independent macros for shifting bytes within registers. */ diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h index 86976d034382..68374ba6a943 100644 --- a/arch/arm/include/asm/atomic.h +++ b/arch/arm/include/asm/atomic.h @@ -13,7 +13,9 @@ #include <linux/compiler.h> #include <linux/types.h> -#include <asm/system.h> +#include <linux/irqflags.h> +#include <asm/barrier.h> +#include <asm/cmpxchg.h> #define ATOMIC_INIT(i) { (i) } diff --git a/arch/arm/include/asm/barrier.h b/arch/arm/include/asm/barrier.h new file mode 100644 index 000000000000..05112380dc53 --- /dev/null +++ b/arch/arm/include/asm/barrier.h @@ -0,0 +1,69 @@ +#ifndef __ASM_BARRIER_H +#define __ASM_BARRIER_H + +#ifndef __ASSEMBLY__ +#include <asm/outercache.h> + +#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t"); + +#if __LINUX_ARM_ARCH__ >= 7 || \ + (__LINUX_ARM_ARCH__ == 6 && defined(CONFIG_CPU_32v6K)) +#define sev() __asm__ __volatile__ ("sev" : : : "memory") +#define wfe() __asm__ __volatile__ ("wfe" : : : "memory") +#define wfi() __asm__ __volatile__ ("wfi" : : : "memory") +#endif + +#if __LINUX_ARM_ARCH__ >= 7 +#define isb() __asm__ __volatile__ ("isb" : : : "memory") +#define dsb() __asm__ __volatile__ ("dsb" : : : "memory") +#define dmb() __asm__ __volatile__ ("dmb" : : : "memory") +#elif defined(CONFIG_CPU_XSC3) || __LINUX_ARM_ARCH__ == 6 +#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \ + : : "r" (0) : "memory") +#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ + : : "r" (0) : "memory") +#define dmb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \ + : : "r" (0) : "memory") +#elif defined(CONFIG_CPU_FA526) +#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \ + : : "r" (0) : "memory") +#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ + : : "r" (0) : "memory") +#define dmb() __asm__ __volatile__ ("" : : : "memory") +#else +#define isb() __asm__ __volatile__ ("" : : : "memory") +#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ + : : "r" (0) : "memory") +#define dmb() __asm__ __volatile__ ("" : : : "memory") +#endif + +#ifdef CONFIG_ARCH_HAS_BARRIERS +#include <mach/barriers.h> +#elif defined(CONFIG_ARM_DMA_MEM_BUFFERABLE) || defined(CONFIG_SMP) +#define mb() do { dsb(); outer_sync(); } while (0) +#define rmb() dsb() +#define wmb() mb() +#else +#include <asm/memory.h> +#define mb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) +#define rmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) +#define wmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) +#endif + +#ifndef CONFIG_SMP +#define smp_mb() barrier() +#define smp_rmb() barrier() +#define smp_wmb() barrier() +#else +#define smp_mb() dmb() +#define smp_rmb() dmb() +#define smp_wmb() dmb() +#endif + +#define read_barrier_depends() do { } while(0) +#define smp_read_barrier_depends() do { } while(0) + +#define set_mb(var, value) do { var = value; smp_mb(); } while (0) + +#endif /* !__ASSEMBLY__ */ +#endif /* __ASM_BARRIER_H */ diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h index f7419ef9c8f9..e691ec91e4d3 100644 --- a/arch/arm/include/asm/bitops.h +++ b/arch/arm/include/asm/bitops.h @@ -24,7 +24,7 @@ #endif #include <linux/compiler.h> -#include <asm/system.h> +#include <linux/irqflags.h> #define smp_mb__before_clear_bit() smp_mb() #define smp_mb__after_clear_bit() smp_mb() diff --git a/arch/arm/include/asm/bug.h b/arch/arm/include/asm/bug.h index fac79dceb736..7af5c6c3653a 100644 --- a/arch/arm/include/asm/bug.h +++ b/arch/arm/include/asm/bug.h @@ -1,6 +1,7 @@ #ifndef _ASMARM_BUG_H #define _ASMARM_BUG_H +#include <linux/linkage.h> #ifdef CONFIG_BUG @@ -57,4 +58,33 @@ do { \ #include <asm-generic/bug.h> +struct pt_regs; +void die(const char *msg, struct pt_regs *regs, int err); + +struct siginfo; +void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info, + unsigned long err, unsigned long trap); + +#ifdef CONFIG_ARM_LPAE +#define FAULT_CODE_ALIGNMENT 33 +#define FAULT_CODE_DEBUG 34 +#else +#define FAULT_CODE_ALIGNMENT 1 +#define FAULT_CODE_DEBUG 2 +#endif + +void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, + struct pt_regs *), + int sig, int code, const char *name); + +void hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int, + struct pt_regs *), + int sig, int code, const char *name); + +extern asmlinkage void c_backtrace(unsigned long fp, int pmode); + +struct mm_struct; +extern void show_pte(struct mm_struct *mm, unsigned long addr); +extern void __show_regs(struct pt_regs *); + #endif diff --git a/arch/arm/include/asm/cmpxchg.h b/arch/arm/include/asm/cmpxchg.h new file mode 100644 index 000000000000..d41d7cbf0ada --- /dev/null +++ b/arch/arm/include/asm/cmpxchg.h @@ -0,0 +1,295 @@ +#ifndef __ASM_ARM_CMPXCHG_H +#define __ASM_ARM_CMPXCHG_H + +#include <linux/irqflags.h> +#include <asm/barrier.h> + +#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110) +/* + * On the StrongARM, "swp" is terminally broken since it bypasses the + * cache totally. This means that the cache becomes inconsistent, and, + * since we use normal loads/stores as well, this is really bad. + * Typically, this causes oopsen in filp_close, but could have other, + * more disastrous effects. There are two work-arounds: + * 1. Disable interrupts and emulate the atomic swap + * 2. Clean the cache, perform atomic swap, flush the cache + * + * We choose (1) since its the "easiest" to achieve here and is not + * dependent on the processor type. + * + * NOTE that this solution won't work on an SMP system, so explcitly + * forbid it here. + */ +#define swp_is_buggy +#endif + +static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size) +{ + extern void __bad_xchg(volatile void *, int); + unsigned long ret; +#ifdef swp_is_buggy + unsigned long flags; +#endif +#if __LINUX_ARM_ARCH__ >= 6 + unsigned int tmp; +#endif + + smp_mb(); + + switch (size) { +#if __LINUX_ARM_ARCH__ >= 6 + case 1: + asm volatile("@ __xchg1\n" + "1: ldrexb %0, [%3]\n" + " strexb %1, %2, [%3]\n" + " teq %1, #0\n" + " bne 1b" + : "=&r" (ret), "=&r" (tmp) + : "r" (x), "r" (ptr) + : "memory", "cc"); + break; + case 4: + asm volatile("@ __xchg4\n" + "1: ldrex %0, [%3]\n" + " strex %1, %2, [%3]\n" + " teq %1, #0\n" + " bne 1b" + : "=&r" (ret), "=&r" (tmp) + : "r" (x), "r" (ptr) + : "memory", "cc"); + break; +#elif defined(swp_is_buggy) +#ifdef CONFIG_SMP +#error SMP is not supported on this platform +#endif + case 1: + raw_local_irq_save(flags); + ret = *(volatile unsigned char *)ptr; + *(volatile unsigned char *)ptr = x; + raw_local_irq_restore(flags); + break; + + case 4: + raw_local_irq_save(flags); + ret = *(volatile unsigned long *)ptr; + *(volatile unsigned long *)ptr = x; + raw_local_irq_restore(flags); + break; +#else + case 1: + asm volatile("@ __xchg1\n" + " swpb %0, %1, [%2]" + : "=&r" (ret) + : "r" (x), "r" (ptr) + : "memory", "cc"); + break; + case 4: + asm volatile("@ __xchg4\n" + " swp %0, %1, [%2]" + : "=&r" (ret) + : "r" (x), "r" (ptr) + : "memory", "cc"); + break; +#endif + default: + __bad_xchg(ptr, size), ret = 0; + break; + } + smp_mb(); + + return ret; +} + +#define xchg(ptr,x) \ + ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) + +#include <asm-generic/cmpxchg-local.h> + +#if __LINUX_ARM_ARCH__ < 6 +/* min ARCH < ARMv6 */ + +#ifdef CONFIG_SMP +#error "SMP is not supported on this platform" +#endif + +/* + * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make + * them available. + */ +#define cmpxchg_local(ptr, o, n) \ + ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\ + (unsigned long)(n), sizeof(*(ptr)))) +#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) + +#ifndef CONFIG_SMP +#include <asm-generic/cmpxchg.h> +#endif + +#else /* min ARCH >= ARMv6 */ + +extern void __bad_cmpxchg(volatile void *ptr, int size); + +/* + * cmpxchg only support 32-bits operands on ARMv6. + */ + +static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, + unsigned long new, int size) +{ + unsigned long oldval, res; + + switch (size) { +#ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */ + case 1: + do { + asm volatile("@ __cmpxchg1\n" + " ldrexb %1, [%2]\n" + " mov %0, #0\n" + " teq %1, %3\n" + " strexbeq %0, %4, [%2]\n" + : "=&r" (res), "=&r" (oldval) + : "r" (ptr), "Ir" (old), "r" (new) + : "memory", "cc"); + } while (res); + break; + case 2: + do { + asm volatile("@ __cmpxchg1\n" + " ldrexh %1, [%2]\n" + " mov %0, #0\n" + " teq %1, %3\n" + " strexheq %0, %4, [%2]\n" + : "=&r" (res), "=&r" (oldval) + : "r" (ptr), "Ir" (old), "r" (new) + : "memory", "cc"); + } while (res); + break; +#endif + case 4: + do { + asm volatile("@ __cmpxchg4\n" + " ldrex %1, [%2]\n" + " mov %0, #0\n" + " teq %1, %3\n" + " strexeq %0, %4, [%2]\n" + : "=&r" (res), "=&r" (oldval) + : "r" (ptr), "Ir" (old), "r" (new) + : "memory", "cc"); + } while (res); + break; + default: + __bad_cmpxchg(ptr, size); + oldval = 0; + } + + return oldval; +} + +static inline unsigned long __cmpxchg_mb(volatile void *ptr, unsigned long old, + unsigned long new, int size) +{ + unsigned long ret; + + smp_mb(); + ret = __cmpxchg(ptr, old, new, size); + smp_mb(); + + return ret; +} + +#define cmpxchg(ptr,o,n) \ + ((__typeof__(*(ptr)))__cmpxchg_mb((ptr), \ + (unsigned long)(o), \ + (unsigned long)(n), \ + sizeof(*(ptr)))) + +static inline unsigned long __cmpxchg_local(volatile void *ptr, + unsigned long old, + unsigned long new, int size) +{ + unsigned long ret; + + switch (size) { +#ifdef CONFIG_CPU_V6 /* min ARCH == ARMv6 */ + case 1: + case 2: + ret = __cmpxchg_local_generic(ptr, old, new, size); + break; +#endif + default: + ret = __cmpxchg(ptr, old, new, size); + } + + return ret; +} + +#define cmpxchg_local(ptr,o,n) \ + ((__typeof__(*(ptr)))__cmpxchg_local((ptr), \ + (unsigned long)(o), \ + (unsigned long)(n), \ + sizeof(*(ptr)))) + +#ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */ + +/* + * Note : ARMv7-M (currently unsupported by Linux) does not support + * ldrexd/strexd. If ARMv7-M is ever supported by the Linux kernel, it should + * not be allowed to use __cmpxchg64. + */ +static inline unsigned long long __cmpxchg64(volatile void *ptr, + unsigned long long old, + unsigned long long new) +{ + register unsigned long long oldval asm("r0"); + register unsigned long long __old asm("r2") = old; + register unsigned long long __new asm("r4") = new; + unsigned long res; + + do { + asm volatile( + " @ __cmpxchg8\n" + " ldrexd %1, %H1, [%2]\n" + " mov %0, #0\n" + " teq %1, %3\n" + " teqeq %H1, %H3\n" + " strexdeq %0, %4, %H4, [%2]\n" + : "=&r" (res), "=&r" (oldval) + : "r" (ptr), "Ir" (__old), "r" (__new) + : "memory", "cc"); + } while (res); + + return oldval; +} + +static inline unsigned long long __cmpxchg64_mb(volatile void *ptr, + unsigned long long old, + unsigned long long new) +{ + unsigned long long ret; + + smp_mb(); + ret = __cmpxchg64(ptr, old, new); + smp_mb(); + + return ret; +} + +#define cmpxchg64(ptr,o,n) \ + ((__typeof__(*(ptr)))__cmpxchg64_mb((ptr), \ + (unsigned long long)(o), \ + (unsigned long long)(n))) + +#define cmpxchg64_local(ptr,o,n) \ + ((__typeof__(*(ptr)))__cmpxchg64((ptr), \ + (unsigned long long)(o), \ + (unsigned long long)(n))) + +#else /* min ARCH = ARMv6 */ + +#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) + +#endif + +#endif /* __LINUX_ARM_ARCH__ >= 6 */ + +#endif /* __ASM_ARM_CMPXCHG_H */ diff --git a/arch/arm/include/asm/compiler.h b/arch/arm/include/asm/compiler.h new file mode 100644 index 000000000000..8155db2f7fa1 --- /dev/null +++ b/arch/arm/include/asm/compiler.h @@ -0,0 +1,15 @@ +#ifndef __ASM_ARM_COMPILER_H +#define __ASM_ARM_COMPILER_H + +/* + * This is used to ensure the compiler did actually allocate the register we + * asked it for some inline assembly sequences. Apparently we can't trust + * the compiler from one version to another so a bit of paranoia won't hurt. + * This string is meant to be concatenated with the inline asm string and + * will cause compilation to stop on mismatch. + * (for details, see gcc PR 15089) + */ +#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t" + + +#endif /* __ASM_ARM_COMPILER_H */ diff --git a/arch/arm/include/asm/cp15.h b/arch/arm/include/asm/cp15.h new file mode 100644 index 000000000000..5ef4d8015a60 --- /dev/null +++ b/arch/arm/include/asm/cp15.h @@ -0,0 +1,87 @@ +#ifndef __ASM_ARM_CP15_H +#define __ASM_ARM_CP15_H + +#include <asm/barrier.h> + +/* + * CR1 bits (CP#15 CR1) + */ +#define CR_M (1 << 0) /* MMU enable */ +#define CR_A (1 << 1) /* Alignment abort enable */ +#define CR_C (1 << 2) /* Dcache enable */ +#define CR_W (1 << 3) /* Write buffer enable */ +#define CR_P (1 << 4) /* 32-bit exception handler */ +#define CR_D (1 << 5) /* 32-bit data address range */ +#define CR_L (1 << 6) /* Implementation defined */ +#define CR_B (1 << 7) /* Big endian */ +#define CR_S (1 << 8) /* System MMU protection */ +#define CR_R (1 << 9) /* ROM MMU protection */ +#define CR_F (1 << 10) /* Implementation defined */ +#define CR_Z (1 << 11) /* Implementation defined */ +#define CR_I (1 << 12) /* Icache enable */ +#define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */ +#define CR_RR (1 << 14) /* Round Robin cache replacement */ +#define CR_L4 (1 << 15) /* LDR pc can set T bit */ +#define CR_DT (1 << 16) +#define CR_IT (1 << 18) +#define CR_ST (1 << 19) +#define CR_FI (1 << 21) /* Fast interrupt (lower latency mode) */ +#define CR_U (1 << 22) /* Unaligned access operation */ +#define CR_XP (1 << 23) /* Extended page tables */ +#define CR_VE (1 << 24) /* Vectored interrupts */ +#define CR_EE (1 << 25) /* Exception (Big) Endian */ +#define CR_TRE (1 << 28) /* TEX remap enable */ +#define CR_AFE (1 << 29) /* Access flag enable */ +#define CR_TE (1 << 30) /* Thumb exception enable */ + +#ifndef __ASSEMBLY__ + +#if __LINUX_ARM_ARCH__ >= 4 +#define vectors_high() (cr_alignment & CR_V) +#else +#define vectors_high() (0) +#endif + +extern unsigned long cr_no_alignment; /* defined in entry-armv.S */ +extern unsigned long cr_alignment; /* defined in entry-armv.S */ + +static inline unsigned int get_cr(void) +{ + unsigned int val; + asm("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val) : : "cc"); + return val; +} + +static inline void set_cr(unsigned int val) +{ + asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR" + : : "r" (val) : "cc"); + isb(); +} + +#ifndef CONFIG_SMP +extern void adjust_cr(unsigned long mask, unsigned long set); +#endif + +#define CPACC_FULL(n) (3 << (n * 2)) +#define CPACC_SVC(n) (1 << (n * 2)) +#define CPACC_DISABLE(n) (0 << (n * 2)) + +static inline unsigned int get_copro_access(void) +{ + unsigned int val; + asm("mrc p15, 0, %0, c1, c0, 2 @ get copro access" + : "=r" (val) : : "cc"); + return val; +} + +static inline void set_copro_access(unsigned int val) +{ + asm volatile("mcr p15, 0, %0, c1, c0, 2 @ set copro access" + : : "r" (val) : "cc"); + isb(); +} + +#endif + +#endif diff --git a/arch/arm/include/asm/cpuidle.h b/arch/arm/include/asm/cpuidle.h new file mode 100644 index 000000000000..2fca60ab513a --- /dev/null +++ b/arch/arm/include/asm/cpuidle.h @@ -0,0 +1,29 @@ +#ifndef __ASM_ARM_CPUIDLE_H +#define __ASM_ARM_CPUIDLE_H + +#ifdef CONFIG_CPU_IDLE +extern int arm_cpuidle_simple_enter(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index); +#else +static inline int arm_cpuidle_simple_enter(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) { return -ENODEV; } +#endif + +/* Common ARM WFI state */ +#define ARM_CPUIDLE_WFI_STATE_PWR(p) {\ + .enter = arm_cpuidle_simple_enter,\ + .exit_latency = 1,\ + .target_residency = 1,\ + .power_usage = p,\ + .flags = CPUIDLE_FLAG_TIME_VALID,\ + .name = "WFI",\ + .desc = "ARM WFI",\ +} + +/* + * in case power_specified == 1, give a default WFI power value needed + * by some governors + */ +#define ARM_CPUIDLE_WFI_STATE ARM_CPUIDLE_WFI_STATE_PWR(UINT_MAX) + +#endif diff --git a/arch/arm/include/asm/div64.h b/arch/arm/include/asm/div64.h index d3f0a9eee9f6..fe92ccf1d0b0 100644 --- a/arch/arm/include/asm/div64.h +++ b/arch/arm/include/asm/div64.h @@ -1,8 +1,8 @@ #ifndef __ASM_ARM_DIV64 #define __ASM_ARM_DIV64 -#include <asm/system.h> #include <linux/types.h> +#include <asm/compiler.h> /* * The semantics of do_div() are: diff --git a/arch/arm/include/asm/dma.h b/arch/arm/include/asm/dma.h index 69a5b0b6455c..5694a0d6576b 100644 --- a/arch/arm/include/asm/dma.h +++ b/arch/arm/include/asm/dma.h @@ -19,7 +19,6 @@ * It should not be re-used except for that purpose. */ #include <linux/spinlock.h> -#include <asm/system.h> #include <asm/scatterlist.h> #include <mach/isa-dma.h> diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h index b5dc173d336f..3d2220498abc 100644 --- a/arch/arm/include/asm/domain.h +++ b/arch/arm/include/asm/domain.h @@ -10,6 +10,10 @@ #ifndef __ASM_PROC_DOMAIN_H #define __ASM_PROC_DOMAIN_H +#ifndef __ASSEMBLY__ +#include <asm/barrier.h> +#endif + /* * Domain numbers * diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h index 0e9ce8d9686e..38050b1c4800 100644 --- a/arch/arm/include/asm/elf.h +++ b/arch/arm/include/asm/elf.h @@ -130,8 +130,4 @@ struct mm_struct; extern unsigned long arch_randomize_brk(struct mm_struct *mm); #define arch_randomize_brk arch_randomize_brk -extern int vectors_user_mapping(void); -#define arch_setup_additional_pages(bprm, uses_interp) vectors_user_mapping() -#define ARCH_HAS_SETUP_ADDITIONAL_PAGES - #endif diff --git a/arch/arm/include/asm/exec.h b/arch/arm/include/asm/exec.h new file mode 100644 index 000000000000..7c4fbef72b3a --- /dev/null +++ b/arch/arm/include/asm/exec.h @@ -0,0 +1,6 @@ +#ifndef __ASM_ARM_EXEC_H +#define __ASM_ARM_EXEC_H + +#define arch_align_stack(x) (x) + +#endif /* __ASM_ARM_EXEC_H */ diff --git a/arch/arm/include/asm/hardware/arm_timer.h b/arch/arm/include/asm/hardware/arm_timer.h index c0f4e7bf22de..d6030ff599db 100644 --- a/arch/arm/include/asm/hardware/arm_timer.h +++ b/arch/arm/include/asm/hardware/arm_timer.h @@ -9,7 +9,12 @@ * * Integrator AP has 16-bit timers, Integrator CP, Versatile and Realview * can have 16-bit or 32-bit selectable via a bit in the control register. + * + * Every SP804 contains two identical timers. */ +#define TIMER_1_BASE 0x00 +#define TIMER_2_BASE 0x20 + #define TIMER_LOAD 0x00 /* ACVR rw */ #define TIMER_VALUE 0x04 /* ACVR ro */ #define TIMER_CTRL 0x08 /* ACVR rw */ diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h index 7df239bcdf27..c4c87bc12231 100644 --- a/arch/arm/include/asm/hardware/cache-l2x0.h +++ b/arch/arm/include/asm/hardware/cache-l2x0.h @@ -103,11 +103,11 @@ #define L2X0_ADDR_FILTER_EN 1 #ifndef __ASSEMBLY__ -extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask); +extern void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask); #if defined(CONFIG_CACHE_L2X0) && defined(CONFIG_OF) -extern int l2x0_of_init(__u32 aux_val, __u32 aux_mask); +extern int l2x0_of_init(u32 aux_val, u32 aux_mask); #else -static inline int l2x0_of_init(__u32 aux_val, __u32 aux_mask) +static inline int l2x0_of_init(u32 aux_val, u32 aux_mask) { return -ENODEV; } diff --git a/arch/arm/include/asm/hardware/entry-macro-iomd.S b/arch/arm/include/asm/hardware/entry-macro-iomd.S index e0af4983723f..8c215acd9b57 100644 --- a/arch/arm/include/asm/hardware/entry-macro-iomd.S +++ b/arch/arm/include/asm/hardware/entry-macro-iomd.S @@ -11,14 +11,6 @@ /* IOC / IOMD based hardware */ #include <asm/hardware/iomd.h> - .macro disable_fiq - mov r12, #ioc_base_high - .if ioc_base_low - orr r12, r12, #ioc_base_low - .endif - strb r12, [r12, #0x38] @ Disable FIQ register - .endm - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldrb \irqstat, [\base, #IOMD_IRQREQB] @ get high priority first ldr \tmp, =irq_prio_h diff --git a/arch/arm/include/asm/hardware/iop3xx.h b/arch/arm/include/asm/hardware/iop3xx.h index 077c32326c63..2ff2c75a4639 100644 --- a/arch/arm/include/asm/hardware/iop3xx.h +++ b/arch/arm/include/asm/hardware/iop3xx.h @@ -231,6 +231,9 @@ extern int iop3xx_get_init_atu(void); #ifndef __ASSEMBLY__ + +#include <linux/types.h> + void iop3xx_map_io(void); void iop_init_cp6_handler(void); void iop_init_time(unsigned long tickrate); diff --git a/arch/arm/include/asm/hardware/iop_adma.h b/arch/arm/include/asm/hardware/iop_adma.h index 59b8c3892f76..122f86d8c991 100644 --- a/arch/arm/include/asm/hardware/iop_adma.h +++ b/arch/arm/include/asm/hardware/iop_adma.h @@ -49,7 +49,6 @@ struct iop_adma_device { /** * struct iop_adma_chan - internal representation of an ADMA device * @pending: allows batching of hardware operations - * @completed_cookie: identifier for the most recently completed operation * @lock: serializes enqueue/dequeue operations to the slot pool * @mmr_base: memory mapped register base * @chain: device chain view of the descriptors @@ -62,7 +61,6 @@ struct iop_adma_device { */ struct iop_adma_chan { int pending; - dma_cookie_t completed_cookie; spinlock_t lock; /* protects the descriptor slot pool */ void __iomem *mmr_base; struct list_head chain; diff --git a/arch/arm/include/asm/hardware/it8152.h b/arch/arm/include/asm/hardware/it8152.h index 43cab498bc27..73f84fa4f366 100644 --- a/arch/arm/include/asm/hardware/it8152.h +++ b/arch/arm/include/asm/hardware/it8152.h @@ -9,6 +9,9 @@ #ifndef __ASM_HARDWARE_IT8152_H #define __ASM_HARDWARE_IT8152_H + +#include <mach/irqs.h> + extern void __iomem *it8152_base_address; #define IT8152_IO_BASE (it8152_base_address + 0x03e00000) diff --git a/arch/arm/include/asm/hardware/pl330.h b/arch/arm/include/asm/hardware/pl330.h deleted file mode 100644 index c1821385abfa..000000000000 --- a/arch/arm/include/asm/hardware/pl330.h +++ /dev/null @@ -1,217 +0,0 @@ -/* linux/include/asm/hardware/pl330.h - * - * Copyright (C) 2010 Samsung Electronics Co. Ltd. - * Jaswinder Singh <jassi.brar@samsung.com> - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __PL330_CORE_H -#define __PL330_CORE_H - -#define PL330_MAX_CHAN 8 -#define PL330_MAX_IRQS 32 -#define PL330_MAX_PERI 32 - -enum pl330_srccachectrl { - SCCTRL0 = 0, /* Noncacheable and nonbufferable */ - SCCTRL1, /* Bufferable only */ - SCCTRL2, /* Cacheable, but do not allocate */ - SCCTRL3, /* Cacheable and bufferable, but do not allocate */ - SINVALID1, - SINVALID2, - SCCTRL6, /* Cacheable write-through, allocate on reads only */ - SCCTRL7, /* Cacheable write-back, allocate on reads only */ -}; - -enum pl330_dstcachectrl { - DCCTRL0 = 0, /* Noncacheable and nonbufferable */ - DCCTRL1, /* Bufferable only */ - DCCTRL2, /* Cacheable, but do not allocate */ - DCCTRL3, /* Cacheable and bufferable, but do not allocate */ - DINVALID1, /* AWCACHE = 0x1000 */ - DINVALID2, - DCCTRL6, /* Cacheable write-through, allocate on writes only */ - DCCTRL7, /* Cacheable write-back, allocate on writes only */ -}; - -/* Populated by the PL330 core driver for DMA API driver's info */ -struct pl330_config { - u32 periph_id; - u32 pcell_id; -#define DMAC_MODE_NS (1 << 0) - unsigned int mode; - unsigned int data_bus_width:10; /* In number of bits */ - unsigned int data_buf_dep:10; - unsigned int num_chan:4; - unsigned int num_peri:6; - u32 peri_ns; - unsigned int num_events:6; - u32 irq_ns; -}; - -/* Handle to the DMAC provided to the PL330 core */ -struct pl330_info { - /* Owning device */ - struct device *dev; - /* Size of MicroCode buffers for each channel. */ - unsigned mcbufsz; - /* ioremap'ed address of PL330 registers. */ - void __iomem *base; - /* Client can freely use it. */ - void *client_data; - /* PL330 core data, Client must not touch it. */ - void *pl330_data; - /* Populated by the PL330 core driver during pl330_add */ - struct pl330_config pcfg; - /* - * If the DMAC has some reset mechanism, then the - * client may want to provide pointer to the method. - */ - void (*dmac_reset)(struct pl330_info *pi); -}; - -enum pl330_byteswap { - SWAP_NO = 0, - SWAP_2, - SWAP_4, - SWAP_8, - SWAP_16, -}; - -/** - * Request Configuration. - * The PL330 core does not modify this and uses the last - * working configuration if the request doesn't provide any. - * - * The Client may want to provide this info only for the - * first request and a request with new settings. - */ -struct pl330_reqcfg { - /* Address Incrementing */ - unsigned dst_inc:1; - unsigned src_inc:1; - - /* - * For now, the SRC & DST protection levels - * and burst size/length are assumed same. - */ - bool nonsecure; - bool privileged; - bool insnaccess; - unsigned brst_len:5; - unsigned brst_size:3; /* in power of 2 */ - - enum pl330_dstcachectrl dcctl; - enum pl330_srccachectrl scctl; - enum pl330_byteswap swap; -}; - -/* - * One cycle of DMAC operation. - * There may be more than one xfer in a request. - */ -struct pl330_xfer { - u32 src_addr; - u32 dst_addr; - /* Size to xfer */ - u32 bytes; - /* - * Pointer to next xfer in the list. - * The last xfer in the req must point to NULL. - */ - struct pl330_xfer *next; -}; - -/* The xfer callbacks are made with one of these arguments. */ -enum pl330_op_err { - /* The all xfers in the request were success. */ - PL330_ERR_NONE, - /* If req aborted due to global error. */ - PL330_ERR_ABORT, - /* If req failed due to problem with Channel. */ - PL330_ERR_FAIL, -}; - -enum pl330_reqtype { - MEMTOMEM, - MEMTODEV, - DEVTOMEM, - DEVTODEV, -}; - -/* A request defining Scatter-Gather List ending with NULL xfer. */ -struct pl330_req { - enum pl330_reqtype rqtype; - /* Index of peripheral for the xfer. */ - unsigned peri:5; - /* Unique token for this xfer, set by the client. */ - void *token; - /* Callback to be called after xfer. */ - void (*xfer_cb)(void *token, enum pl330_op_err err); - /* If NULL, req will be done at last set parameters. */ - struct pl330_reqcfg *cfg; - /* Pointer to first xfer in the request. */ - struct pl330_xfer *x; -}; - -/* - * To know the status of the channel and DMAC, the client - * provides a pointer to this structure. The PL330 core - * fills it with current information. - */ -struct pl330_chanstatus { - /* - * If the DMAC engine halted due to some error, - * the client should remove-add DMAC. - */ - bool dmac_halted; - /* - * If channel is halted due to some error, - * the client should ABORT/FLUSH and START the channel. - */ - bool faulting; - /* Location of last load */ - u32 src_addr; - /* Location of last store */ - u32 dst_addr; - /* - * Pointer to the currently active req, NULL if channel is - * inactive, even though the requests may be present. - */ - struct pl330_req *top_req; - /* Pointer to req waiting second in the queue if any. */ - struct pl330_req *wait_req; -}; - -enum pl330_chan_op { - /* Start the channel */ - PL330_OP_START, - /* Abort the active xfer */ - PL330_OP_ABORT, - /* Stop xfer and flush queue */ - PL330_OP_FLUSH, -}; - -extern int pl330_add(struct pl330_info *); -extern void pl330_del(struct pl330_info *pi); -extern int pl330_update(const struct pl330_info *pi); -extern void pl330_release_channel(void *ch_id); -extern void *pl330_request_channel(const struct pl330_info *pi); -extern int pl330_chan_status(void *ch_id, struct pl330_chanstatus *pstatus); -extern int pl330_chan_ctrl(void *ch_id, enum pl330_chan_op op); -extern int pl330_submit_req(void *ch_id, struct pl330_req *r); - -#endif /* __PL330_CORE_H */ diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h index 92ed254c175b..7c2bbc7f0be1 100644 --- a/arch/arm/include/asm/hardware/sa1111.h +++ b/arch/arm/include/asm/hardware/sa1111.h @@ -132,34 +132,10 @@ #define SKPCR_DCLKEN (1<<7) #define SKPCR_PWMCLKEN (1<<8) -/* - * USB Host controller - */ +/* USB Host controller */ #define SA1111_USB 0x0400 /* - * Offsets from SA1111_USB_BASE - */ -#define SA1111_USB_STATUS 0x0118 -#define SA1111_USB_RESET 0x011c -#define SA1111_USB_IRQTEST 0x0120 - -#define USB_RESET_FORCEIFRESET (1 << 0) -#define USB_RESET_FORCEHCRESET (1 << 1) -#define USB_RESET_CLKGENRESET (1 << 2) -#define USB_RESET_SIMSCALEDOWN (1 << 3) -#define USB_RESET_USBINTTEST (1 << 4) -#define USB_RESET_SLEEPSTBYEN (1 << 5) -#define USB_RESET_PWRSENSELOW (1 << 6) -#define USB_RESET_PWRCTRLLOW (1 << 7) - -#define USB_STATUS_IRQHCIRMTWKUP (1 << 7) -#define USB_STATUS_IRQHCIBUFFACC (1 << 8) -#define USB_STATUS_NIRQHCIM (1 << 9) -#define USB_STATUS_NHCIMFCLR (1 << 10) -#define USB_STATUS_USBPWRSENSE (1 << 11) - -/* * Serial Audio Controller * * Registers @@ -327,22 +303,6 @@ * PC_SSR GPIO Block C Sleep State */ -#define _PA_DDR _SA1111( 0x1000 ) -#define _PA_DRR _SA1111( 0x1004 ) -#define _PA_DWR _SA1111( 0x1004 ) -#define _PA_SDR _SA1111( 0x1008 ) -#define _PA_SSR _SA1111( 0x100c ) -#define _PB_DDR _SA1111( 0x1010 ) -#define _PB_DRR _SA1111( 0x1014 ) -#define _PB_DWR _SA1111( 0x1014 ) -#define _PB_SDR _SA1111( 0x1018 ) -#define _PB_SSR _SA1111( 0x101c ) -#define _PC_DDR _SA1111( 0x1020 ) -#define _PC_DRR _SA1111( 0x1024 ) -#define _PC_DWR _SA1111( 0x1024 ) -#define _PC_SDR _SA1111( 0x1028 ) -#define _PC_SSR _SA1111( 0x102c ) - #define SA1111_GPIO 0x1000 #define SA1111_GPIO_PADDR (0x000) @@ -425,106 +385,30 @@ #define SA1111_WAKEPOL0 0x0034 #define SA1111_WAKEPOL1 0x0038 -/* - * PS/2 Trackpad and Mouse Interfaces - * - * Registers - * PS2CR Control Register - * PS2STAT Status Register - * PS2DATA Transmit/Receive Data register - * PS2CLKDIV Clock Division Register - * PS2PRECNT Clock Precount Register - * PS2TEST1 Test register 1 - * PS2TEST2 Test register 2 - * PS2TEST3 Test register 3 - * PS2TEST4 Test register 4 - */ - +/* PS/2 Trackpad and Mouse Interfaces */ #define SA1111_KBD 0x0a00 #define SA1111_MSE 0x0c00 -/* - * These are offsets from the above bases. - */ -#define SA1111_PS2CR 0x0000 -#define SA1111_PS2STAT 0x0004 -#define SA1111_PS2DATA 0x0008 -#define SA1111_PS2CLKDIV 0x000c -#define SA1111_PS2PRECNT 0x0010 - -#define PS2CR_ENA 0x08 -#define PS2CR_FKD 0x02 -#define PS2CR_FKC 0x01 - -#define PS2STAT_STP 0x0100 -#define PS2STAT_TXE 0x0080 -#define PS2STAT_TXB 0x0040 -#define PS2STAT_RXF 0x0020 -#define PS2STAT_RXB 0x0010 -#define PS2STAT_ENA 0x0008 -#define PS2STAT_RXP 0x0004 -#define PS2STAT_KBD 0x0002 -#define PS2STAT_KBC 0x0001 +/* PCMCIA Interface */ +#define SA1111_PCMCIA 0x1600 -/* - * PCMCIA Interface - * - * Registers - * PCSR Status Register - * PCCR Control Register - * PCSSR Sleep State Register - */ - -#define SA1111_PCMCIA 0x1600 - -/* - * These are offsets from the above base. - */ -#define SA1111_PCCR 0x0000 -#define SA1111_PCSSR 0x0004 -#define SA1111_PCSR 0x0008 - -#define PCSR_S0_READY (1<<0) -#define PCSR_S1_READY (1<<1) -#define PCSR_S0_DETECT (1<<2) -#define PCSR_S1_DETECT (1<<3) -#define PCSR_S0_VS1 (1<<4) -#define PCSR_S0_VS2 (1<<5) -#define PCSR_S1_VS1 (1<<6) -#define PCSR_S1_VS2 (1<<7) -#define PCSR_S0_WP (1<<8) -#define PCSR_S1_WP (1<<9) -#define PCSR_S0_BVD1 (1<<10) -#define PCSR_S0_BVD2 (1<<11) -#define PCSR_S1_BVD1 (1<<12) -#define PCSR_S1_BVD2 (1<<13) - -#define PCCR_S0_RST (1<<0) -#define PCCR_S1_RST (1<<1) -#define PCCR_S0_FLT (1<<2) -#define PCCR_S1_FLT (1<<3) -#define PCCR_S0_PWAITEN (1<<4) -#define PCCR_S1_PWAITEN (1<<5) -#define PCCR_S0_PSE (1<<6) -#define PCCR_S1_PSE (1<<7) - -#define PCSSR_S0_SLEEP (1<<0) -#define PCSSR_S1_SLEEP (1<<1) extern struct bus_type sa1111_bus_type; -#define SA1111_DEVID_SBI 0 -#define SA1111_DEVID_SK 1 -#define SA1111_DEVID_USB 2 -#define SA1111_DEVID_SAC 3 -#define SA1111_DEVID_SSP 4 -#define SA1111_DEVID_PS2 5 -#define SA1111_DEVID_GPIO 6 -#define SA1111_DEVID_INT 7 -#define SA1111_DEVID_PCMCIA 8 +#define SA1111_DEVID_SBI (1 << 0) +#define SA1111_DEVID_SK (1 << 1) +#define SA1111_DEVID_USB (1 << 2) +#define SA1111_DEVID_SAC (1 << 3) +#define SA1111_DEVID_SSP (1 << 4) +#define SA1111_DEVID_PS2 (3 << 5) +#define SA1111_DEVID_PS2_KBD (1 << 5) +#define SA1111_DEVID_PS2_MSE (1 << 6) +#define SA1111_DEVID_GPIO (1 << 7) +#define SA1111_DEVID_INT (1 << 8) +#define SA1111_DEVID_PCMCIA (1 << 9) struct sa1111_dev { struct device dev; @@ -548,6 +432,7 @@ struct sa1111_driver { int (*remove)(struct sa1111_dev *); int (*suspend)(struct sa1111_dev *, pm_message_t); int (*resume)(struct sa1111_dev *); + void (*shutdown)(struct sa1111_dev *); }; #define SA1111_DRV(_d) container_of((_d), struct sa1111_driver, drv) @@ -555,9 +440,10 @@ struct sa1111_driver { #define SA1111_DRIVER_NAME(_sadev) ((_sadev)->dev.driver->name) /* - * These frob the SKPCR register. + * These frob the SKPCR register, and call platform specific + * enable/disable functions. */ -void sa1111_enable_device(struct sa1111_dev *); +int sa1111_enable_device(struct sa1111_dev *); void sa1111_disable_device(struct sa1111_dev *); unsigned int sa1111_pll_clock(struct sa1111_dev *); @@ -580,6 +466,10 @@ void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned i struct sa1111_platform_data { int irq_base; /* base for cascaded on-chip IRQs */ + unsigned disable_devs; + void *data; + int (*enable)(void *, unsigned); + void (*disable)(void *, unsigned); }; #endif /* _ASM_ARCH_SA1111 */ diff --git a/arch/arm/include/asm/hardware/timer-sp.h b/arch/arm/include/asm/hardware/timer-sp.h index 4384d81eee79..2dd9d3f83f29 100644 --- a/arch/arm/include/asm/hardware/timer-sp.h +++ b/arch/arm/include/asm/hardware/timer-sp.h @@ -1,2 +1,15 @@ -void sp804_clocksource_init(void __iomem *, const char *); +void __sp804_clocksource_and_sched_clock_init(void __iomem *, + const char *, int); + +static inline void sp804_clocksource_init(void __iomem *base, const char *name) +{ + __sp804_clocksource_and_sched_clock_init(base, name, 0); +} + +static inline void sp804_clocksource_and_sched_clock_init(void __iomem *base, + const char *name) +{ + __sp804_clocksource_and_sched_clock_init(base, name, 1); +} + void sp804_clockevents_init(void __iomem *, unsigned int, const char *); diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 9275828feb3d..9af5563dd3eb 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -26,7 +26,6 @@ #include <linux/types.h> #include <asm/byteorder.h> #include <asm/memory.h> -#include <asm/system.h> #include <asm-generic/pci_iomap.h> /* @@ -83,6 +82,11 @@ extern void __iomem *__arm_ioremap_pfn(unsigned long, unsigned long, size_t, uns extern void __iomem *__arm_ioremap(unsigned long, size_t, unsigned int); extern void __iomem *__arm_ioremap_exec(unsigned long, size_t, bool cached); extern void __iounmap(volatile void __iomem *addr); +extern void __arm_iounmap(volatile void __iomem *addr); + +extern void __iomem * (*arch_ioremap_caller)(unsigned long, size_t, + unsigned int, void *); +extern void (*arch_iounmap)(volatile void __iomem *); /* * Bad read/write accesses... @@ -97,8 +101,11 @@ static inline void __iomem *__typesafe_io(unsigned long addr) return (void __iomem *)addr; } +#define IOMEM(x) ((void __force __iomem *)(x)) + /* IO barriers */ #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE +#include <asm/barrier.h> #define __iormb() rmb() #define __iowmb() wmb() #else @@ -109,7 +116,11 @@ static inline void __iomem *__typesafe_io(unsigned long addr) /* * Now, pick up the machine-defined IO definitions */ +#ifdef CONFIG_NEED_MACH_IO_H #include <mach/io.h> +#else +#define __io(a) __typesafe_io((a) & IO_SPACE_LIMIT) +#endif /* * This is the limit of PC card/PCI/ISA IO space, which is by default @@ -211,18 +222,18 @@ extern void _memset_io(volatile void __iomem *, int, size_t); * Again, this are defined to perform little endian accesses. See the * IO port primitives for more information. */ -#ifdef __mem_pci -#define readb_relaxed(c) ({ u8 __r = __raw_readb(__mem_pci(c)); __r; }) +#ifndef readl +#define readb_relaxed(c) ({ u8 __r = __raw_readb(c); __r; }) #define readw_relaxed(c) ({ u16 __r = le16_to_cpu((__force __le16) \ - __raw_readw(__mem_pci(c))); __r; }) + __raw_readw(c)); __r; }) #define readl_relaxed(c) ({ u32 __r = le32_to_cpu((__force __le32) \ - __raw_readl(__mem_pci(c))); __r; }) + __raw_readl(c)); __r; }) -#define writeb_relaxed(v,c) ((void)__raw_writeb(v,__mem_pci(c))) +#define writeb_relaxed(v,c) ((void)__raw_writeb(v,c)) #define writew_relaxed(v,c) ((void)__raw_writew((__force u16) \ - cpu_to_le16(v),__mem_pci(c))) + cpu_to_le16(v),c)) #define writel_relaxed(v,c) ((void)__raw_writel((__force u32) \ - cpu_to_le32(v),__mem_pci(c))) + cpu_to_le32(v),c)) #define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; }) #define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; }) @@ -232,30 +243,19 @@ extern void _memset_io(volatile void __iomem *, int, size_t); #define writew(v,c) ({ __iowmb(); writew_relaxed(v,c); }) #define writel(v,c) ({ __iowmb(); writel_relaxed(v,c); }) -#define readsb(p,d,l) __raw_readsb(__mem_pci(p),d,l) -#define readsw(p,d,l) __raw_readsw(__mem_pci(p),d,l) -#define readsl(p,d,l) __raw_readsl(__mem_pci(p),d,l) - -#define writesb(p,d,l) __raw_writesb(__mem_pci(p),d,l) -#define writesw(p,d,l) __raw_writesw(__mem_pci(p),d,l) -#define writesl(p,d,l) __raw_writesl(__mem_pci(p),d,l) +#define readsb(p,d,l) __raw_readsb(p,d,l) +#define readsw(p,d,l) __raw_readsw(p,d,l) +#define readsl(p,d,l) __raw_readsl(p,d,l) -#define memset_io(c,v,l) _memset_io(__mem_pci(c),(v),(l)) -#define memcpy_fromio(a,c,l) _memcpy_fromio((a),__mem_pci(c),(l)) -#define memcpy_toio(c,a,l) _memcpy_toio(__mem_pci(c),(a),(l)) +#define writesb(p,d,l) __raw_writesb(p,d,l) +#define writesw(p,d,l) __raw_writesw(p,d,l) +#define writesl(p,d,l) __raw_writesl(p,d,l) -#elif !defined(readb) +#define memset_io(c,v,l) _memset_io(c,(v),(l)) +#define memcpy_fromio(a,c,l) _memcpy_fromio((a),c,(l)) +#define memcpy_toio(c,a,l) _memcpy_toio(c,(a),(l)) -#define readb(c) (__readwrite_bug("readb"),0) -#define readw(c) (__readwrite_bug("readw"),0) -#define readl(c) (__readwrite_bug("readl"),0) -#define writeb(v,c) __readwrite_bug("writeb") -#define writew(v,c) __readwrite_bug("writew") -#define writel(v,c) __readwrite_bug("writel") - -#define check_signature(io,sig,len) (0) - -#endif /* __mem_pci */ +#endif /* readl */ /* * ioremap and friends. @@ -264,16 +264,11 @@ extern void _memset_io(volatile void __iomem *, int, size_t); * Documentation/io-mapping.txt. * */ -#ifndef __arch_ioremap -#define __arch_ioremap __arm_ioremap -#define __arch_iounmap __iounmap -#endif - -#define ioremap(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE) -#define ioremap_nocache(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE) -#define ioremap_cached(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE_CACHED) -#define ioremap_wc(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE_WC) -#define iounmap __arch_iounmap +#define ioremap(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE) +#define ioremap_nocache(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE) +#define ioremap_cached(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE_CACHED) +#define ioremap_wc(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE_WC) +#define iounmap __arm_iounmap /* * io{read,write}{8,16,32} macros diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h index 5a526afb5f18..35c21c375d81 100644 --- a/arch/arm/include/asm/irq.h +++ b/arch/arm/include/asm/irq.h @@ -1,14 +1,18 @@ #ifndef __ASM_ARM_IRQ_H #define __ASM_ARM_IRQ_H +#define NR_IRQS_LEGACY 16 + +#ifndef CONFIG_SPARSE_IRQ #include <mach/irqs.h> +#else +#define NR_IRQS NR_IRQS_LEGACY +#endif #ifndef irq_canonicalize #define irq_canonicalize(i) (i) #endif -#define NR_IRQS_LEGACY 16 - /* * Use this value to indicate lack of interrupt * capability diff --git a/arch/arm/include/asm/jump_label.h b/arch/arm/include/asm/jump_label.h new file mode 100644 index 000000000000..bfc198c75913 --- /dev/null +++ b/arch/arm/include/asm/jump_label.h @@ -0,0 +1,41 @@ +#ifndef _ASM_ARM_JUMP_LABEL_H +#define _ASM_ARM_JUMP_LABEL_H + +#ifdef __KERNEL__ + +#include <linux/types.h> +#include <asm/system.h> + +#define JUMP_LABEL_NOP_SIZE 4 + +#ifdef CONFIG_THUMB2_KERNEL +#define JUMP_LABEL_NOP "nop.w" +#else +#define JUMP_LABEL_NOP "nop" +#endif + +static __always_inline bool arch_static_branch(struct static_key *key) +{ + asm goto("1:\n\t" + JUMP_LABEL_NOP "\n\t" + ".pushsection __jump_table, \"aw\"\n\t" + ".word 1b, %l[l_yes], %c0\n\t" + ".popsection\n\t" + : : "i" (key) : : l_yes); + + return false; +l_yes: + return true; +} + +#endif /* __KERNEL__ */ + +typedef u32 jump_label_t; + +struct jump_entry { + jump_label_t code; + jump_label_t target; + jump_label_t key; +}; + +#endif diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h index c6a18424888e..f77ffc1eb0c2 100644 --- a/arch/arm/include/asm/localtimer.h +++ b/arch/arm/include/asm/localtimer.h @@ -11,47 +11,24 @@ #define __ASM_ARM_LOCALTIMER_H #include <linux/errno.h> -#include <linux/interrupt.h> struct clock_event_device; -/* - * Setup a per-cpu timer, whether it be a local timer or dummy broadcast - */ -void percpu_timer_setup(void); +struct local_timer_ops { + int (*setup)(struct clock_event_device *); + void (*stop)(struct clock_event_device *); +}; #ifdef CONFIG_LOCAL_TIMERS - -#ifdef CONFIG_HAVE_ARM_TWD - -#include "smp_twd.h" - -#define local_timer_stop(c) twd_timer_stop((c)) - -#else - -/* - * Stop the local timer - */ -void local_timer_stop(struct clock_event_device *); - -#endif - /* - * Setup a local timer interrupt for a CPU. + * Register a local timer driver */ -int local_timer_setup(struct clock_event_device *); - +int local_timer_register(struct local_timer_ops *); #else - -static inline int local_timer_setup(struct clock_event_device *evt) +static inline int local_timer_register(struct local_timer_ops *ops) { return -ENXIO; } - -static inline void local_timer_stop(struct clock_event_device *evt) -{ -} #endif #endif diff --git a/arch/arm/include/asm/mc146818rtc.h b/arch/arm/include/asm/mc146818rtc.h index 6b884d2b0b69..e8567bb99dfc 100644 --- a/arch/arm/include/asm/mc146818rtc.h +++ b/arch/arm/include/asm/mc146818rtc.h @@ -5,7 +5,9 @@ #define _ASM_MC146818RTC_H #include <linux/io.h> -#include <mach/irqs.h> +#include <linux/kernel.h> + +#define RTC_IRQ BUILD_BUG_ON(1) #ifndef RTC_PORT #define RTC_PORT(x) (0x70 + (x)) diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index a8997d71084e..fcb575747e5e 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -116,6 +116,8 @@ #define MODULES_END (END_MEM) #define MODULES_VADDR (PHYS_OFFSET) +#define XIP_VIRT_ADDR(physaddr) (physaddr) + #endif /* !CONFIG_MMU */ /* diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h index 14965658a923..b8e580a297e4 100644 --- a/arch/arm/include/asm/mmu.h +++ b/arch/arm/include/asm/mmu.h @@ -34,4 +34,11 @@ typedef struct { #endif +/* + * switch_mm() may do a full cache flush over the context switch, + * so enable interrupts over the context switch to avoid high + * latency. + */ +#define __ARCH_WANT_INTERRUPTS_ON_CTXSW + #endif diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h index 71605d9f8e42..a0b3cac0547c 100644 --- a/arch/arm/include/asm/mmu_context.h +++ b/arch/arm/include/asm/mmu_context.h @@ -18,6 +18,7 @@ #include <asm/cacheflush.h> #include <asm/cachetype.h> #include <asm/proc-fns.h> +#include <asm-generic/mm_hooks.h> void __check_kvm_seq(struct mm_struct *mm); @@ -133,32 +134,4 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next, #define deactivate_mm(tsk,mm) do { } while (0) #define activate_mm(prev,next) switch_mm(prev, next, NULL) -/* - * We are inserting a "fake" vma for the user-accessible vector page so - * gdb and friends can get to it through ptrace and /proc/<pid>/mem. - * But we also want to remove it before the generic code gets to see it - * during process exit or the unmapping of it would cause total havoc. - * (the macro is used as remove_vma() is static to mm/mmap.c) - */ -#define arch_exit_mmap(mm) \ -do { \ - struct vm_area_struct *high_vma = find_vma(mm, 0xffff0000); \ - if (high_vma) { \ - BUG_ON(high_vma->vm_next); /* it should be last */ \ - if (high_vma->vm_prev) \ - high_vma->vm_prev->vm_next = NULL; \ - else \ - mm->mmap = NULL; \ - rb_erase(&high_vma->vm_rb, &mm->mm_rb); \ - mm->mmap_cache = NULL; \ - mm->map_count--; \ - remove_vma(high_vma); \ - } \ -} while (0) - -static inline void arch_dup_mmap(struct mm_struct *oldmm, - struct mm_struct *mm) -{ -} - #endif diff --git a/arch/arm/include/asm/opcodes.h b/arch/arm/include/asm/opcodes.h index c0efdd60966f..19c48deda70f 100644 --- a/arch/arm/include/asm/opcodes.h +++ b/arch/arm/include/asm/opcodes.h @@ -17,4 +17,63 @@ extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr); #define ARM_OPCODE_CONDTEST_PASS 1 #define ARM_OPCODE_CONDTEST_UNCOND 2 + +/* + * Opcode byteswap helpers + * + * These macros help with converting instructions between a canonical integer + * format and in-memory representation, in an endianness-agnostic manner. + * + * __mem_to_opcode_*() convert from in-memory representation to canonical form. + * __opcode_to_mem_*() convert from canonical form to in-memory representation. + * + * + * Canonical instruction representation: + * + * ARM: 0xKKLLMMNN + * Thumb 16-bit: 0x0000KKLL, where KK < 0xE8 + * Thumb 32-bit: 0xKKLLMMNN, where KK >= 0xE8 + * + * There is no way to distinguish an ARM instruction in canonical representation + * from a Thumb instruction (just as these cannot be distinguished in memory). + * Where this distinction is important, it needs to be tracked separately. + * + * Note that values in the range 0x0000E800..0xE7FFFFFF intentionally do not + * represent any valid Thumb-2 instruction. For this range, + * __opcode_is_thumb32() and __opcode_is_thumb16() will both be false. + */ + +#ifndef __ASSEMBLY__ + +#include <linux/types.h> +#include <linux/swab.h> + +#ifdef CONFIG_CPU_ENDIAN_BE8 +#define __opcode_to_mem_arm(x) swab32(x) +#define __opcode_to_mem_thumb16(x) swab16(x) +#define __opcode_to_mem_thumb32(x) swahb32(x) +#else +#define __opcode_to_mem_arm(x) ((u32)(x)) +#define __opcode_to_mem_thumb16(x) ((u16)(x)) +#define __opcode_to_mem_thumb32(x) swahw32(x) +#endif + +#define __mem_to_opcode_arm(x) __opcode_to_mem_arm(x) +#define __mem_to_opcode_thumb16(x) __opcode_to_mem_thumb16(x) +#define __mem_to_opcode_thumb32(x) __opcode_to_mem_thumb32(x) + +/* Operations specific to Thumb opcodes */ + +/* Instruction size checks: */ +#define __opcode_is_thumb32(x) ((u32)(x) >= 0xE8000000UL) +#define __opcode_is_thumb16(x) ((u32)(x) < 0xE800UL) + +/* Operations to construct or split 32-bit Thumb instructions: */ +#define __opcode_thumb32_first(x) ((u16)((x) >> 16)) +#define __opcode_thumb32_second(x) ((u16)(x)) +#define __opcode_thumb32_compose(first, second) \ + (((u32)(u16)(first) << 16) | (u32)(u16)(second)) + +#endif /* __ASSEMBLY__ */ + #endif /* __ASM_ARM_OPCODES_H */ diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h index 97b440c25c58..5838361c48b3 100644 --- a/arch/arm/include/asm/page.h +++ b/arch/arm/include/asm/page.h @@ -151,6 +151,8 @@ extern void __cpu_copy_user_highpage(struct page *to, struct page *from, #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) extern void copy_page(void *to, const void *from); +#define __HAVE_ARCH_GATE_AREA 1 + #ifdef CONFIG_ARM_LPAE #include <asm/pgtable-3level-types.h> #else diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h index da337ba57ffd..a98a2e112fae 100644 --- a/arch/arm/include/asm/pci.h +++ b/arch/arm/include/asm/pci.h @@ -57,14 +57,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine); -extern void -pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, - struct resource *res); - -extern void -pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region); - /* * Dummy implementation; always return 0. */ diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h index 7523340afb8a..00cbe10a50e3 100644 --- a/arch/arm/include/asm/perf_event.h +++ b/arch/arm/include/asm/perf_event.h @@ -22,6 +22,7 @@ enum arm_perf_pmu_ids { ARM_PERF_PMU_ID_CA9, ARM_PERF_PMU_ID_CA5, ARM_PERF_PMU_ID_CA15, + ARM_PERF_PMU_ID_CA7, ARM_NUM_PMU_IDS, }; diff --git a/arch/arm/include/asm/posix_types.h b/arch/arm/include/asm/posix_types.h index 2446d23bfdbf..efdf99045d87 100644 --- a/arch/arm/include/asm/posix_types.h +++ b/arch/arm/include/asm/posix_types.h @@ -19,59 +19,22 @@ * assume GCC is being used. */ -typedef unsigned long __kernel_ino_t; typedef unsigned short __kernel_mode_t; +#define __kernel_mode_t __kernel_mode_t + typedef unsigned short __kernel_nlink_t; -typedef long __kernel_off_t; -typedef int __kernel_pid_t; +#define __kernel_nlink_t __kernel_nlink_t + typedef unsigned short __kernel_ipc_pid_t; +#define __kernel_ipc_pid_t __kernel_ipc_pid_t + typedef unsigned short __kernel_uid_t; typedef unsigned short __kernel_gid_t; -typedef unsigned int __kernel_size_t; -typedef int __kernel_ssize_t; -typedef int __kernel_ptrdiff_t; -typedef long __kernel_time_t; -typedef long __kernel_suseconds_t; -typedef long __kernel_clock_t; -typedef int __kernel_timer_t; -typedef int __kernel_clockid_t; -typedef int __kernel_daddr_t; -typedef char * __kernel_caddr_t; -typedef unsigned short __kernel_uid16_t; -typedef unsigned short __kernel_gid16_t; -typedef unsigned int __kernel_uid32_t; -typedef unsigned int __kernel_gid32_t; +#define __kernel_uid_t __kernel_uid_t -typedef unsigned short __kernel_old_uid_t; -typedef unsigned short __kernel_old_gid_t; typedef unsigned short __kernel_old_dev_t; +#define __kernel_old_dev_t __kernel_old_dev_t -#ifdef __GNUC__ -typedef long long __kernel_loff_t; -#endif - -typedef struct { - int val[2]; -} __kernel_fsid_t; - -#if defined(__KERNEL__) - -#undef __FD_SET -#define __FD_SET(fd, fdsetp) \ - (((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] |= (1<<((fd) & 31))) - -#undef __FD_CLR -#define __FD_CLR(fd, fdsetp) \ - (((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] &= ~(1<<((fd) & 31))) - -#undef __FD_ISSET -#define __FD_ISSET(fd, fdsetp) \ - ((((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] & (1<<((fd) & 31))) != 0) - -#undef __FD_ZERO -#define __FD_ZERO(fdsetp) \ - (memset (fdsetp, 0, sizeof (*(fd_set *)(fdsetp)))) - -#endif +#include <asm-generic/posix_types.h> #endif diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h index cb8d638924fd..5ac8d3d3e025 100644 --- a/arch/arm/include/asm/processor.h +++ b/arch/arm/include/asm/processor.h @@ -22,7 +22,6 @@ #include <asm/hw_breakpoint.h> #include <asm/ptrace.h> #include <asm/types.h> -#include <asm/system.h> #ifdef __KERNEL__ #define STACK_TOP ((current->personality & ADDR_LIMIT_32BIT) ? \ @@ -56,7 +55,6 @@ struct thread_struct { #define start_thread(regs,pc,sp) \ ({ \ unsigned long *stack = (unsigned long *)sp; \ - set_fs(USER_DS); \ memset(regs->uregs, 0, sizeof(regs->uregs)); \ if (current->personality & ADDR_LIMIT_32BIT) \ regs->ARM_cpsr = USR_MODE; \ @@ -90,6 +88,8 @@ unsigned long get_wchan(struct task_struct *p); #define cpu_relax() barrier() #endif +void cpu_idle_wait(void); + /* * Create a new kernel thread */ diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h index ee0363307918..aeae9c609df4 100644 --- a/arch/arm/include/asm/prom.h +++ b/arch/arm/include/asm/prom.h @@ -13,8 +13,6 @@ #ifdef CONFIG_OF -#include <asm/irq.h> - extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys); extern void arm_dt_memblock_reserve(void); diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h index ef9ffba97ad8..0f01f4677bd2 100644 --- a/arch/arm/include/asm/smp_twd.h +++ b/arch/arm/include/asm/smp_twd.h @@ -18,11 +18,28 @@ #define TWD_TIMER_CONTROL_PERIODIC (1 << 1) #define TWD_TIMER_CONTROL_IT_ENABLE (1 << 2) -struct clock_event_device; +#include <linux/ioport.h> -extern void __iomem *twd_base; +struct twd_local_timer { + struct resource res[2]; +}; -void twd_timer_setup(struct clock_event_device *); -void twd_timer_stop(struct clock_event_device *); +#define DEFINE_TWD_LOCAL_TIMER(name,base,irq) \ +struct twd_local_timer name __initdata = { \ + .res = { \ + DEFINE_RES_MEM(base, 0x10), \ + DEFINE_RES_IRQ(irq), \ + }, \ +}; + +int twd_local_timer_register(struct twd_local_timer *); + +#ifdef CONFIG_HAVE_ARM_TWD +void twd_local_timer_of_register(void); +#else +static inline void twd_local_timer_of_register(void) +{ +} +#endif #endif diff --git a/arch/arm/include/asm/switch_to.h b/arch/arm/include/asm/switch_to.h new file mode 100644 index 000000000000..fa09e6b49bf1 --- /dev/null +++ b/arch/arm/include/asm/switch_to.h @@ -0,0 +1,18 @@ +#ifndef __ASM_ARM_SWITCH_TO_H +#define __ASM_ARM_SWITCH_TO_H + +#include <linux/thread_info.h> + +/* + * switch_to(prev, next) should switch from task `prev' to `next' + * `prev' will never be the same as `next'. schedule() itself + * contains the memory barrier to tell GCC not to cache `current'. + */ +extern struct task_struct *__switch_to(struct task_struct *, struct thread_info *, struct thread_info *); + +#define switch_to(prev,next,last) \ +do { \ + last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \ +} while (0) + +#endif /* __ASM_ARM_SWITCH_TO_H */ diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index e4c96cc6ec0c..74542c52f9be 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -1,543 +1,8 @@ -#ifndef __ASM_ARM_SYSTEM_H -#define __ASM_ARM_SYSTEM_H - -#ifdef __KERNEL__ - -#define CPU_ARCH_UNKNOWN 0 -#define CPU_ARCH_ARMv3 1 -#define CPU_ARCH_ARMv4 2 -#define CPU_ARCH_ARMv4T 3 -#define CPU_ARCH_ARMv5 4 -#define CPU_ARCH_ARMv5T 5 -#define CPU_ARCH_ARMv5TE 6 -#define CPU_ARCH_ARMv5TEJ 7 -#define CPU_ARCH_ARMv6 8 -#define CPU_ARCH_ARMv7 9 - -/* - * CR1 bits (CP#15 CR1) - */ -#define CR_M (1 << 0) /* MMU enable */ -#define CR_A (1 << 1) /* Alignment abort enable */ -#define CR_C (1 << 2) /* Dcache enable */ -#define CR_W (1 << 3) /* Write buffer enable */ -#define CR_P (1 << 4) /* 32-bit exception handler */ -#define CR_D (1 << 5) /* 32-bit data address range */ -#define CR_L (1 << 6) /* Implementation defined */ -#define CR_B (1 << 7) /* Big endian */ -#define CR_S (1 << 8) /* System MMU protection */ -#define CR_R (1 << 9) /* ROM MMU protection */ -#define CR_F (1 << 10) /* Implementation defined */ -#define CR_Z (1 << 11) /* Implementation defined */ -#define CR_I (1 << 12) /* Icache enable */ -#define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */ -#define CR_RR (1 << 14) /* Round Robin cache replacement */ -#define CR_L4 (1 << 15) /* LDR pc can set T bit */ -#define CR_DT (1 << 16) -#define CR_IT (1 << 18) -#define CR_ST (1 << 19) -#define CR_FI (1 << 21) /* Fast interrupt (lower latency mode) */ -#define CR_U (1 << 22) /* Unaligned access operation */ -#define CR_XP (1 << 23) /* Extended page tables */ -#define CR_VE (1 << 24) /* Vectored interrupts */ -#define CR_EE (1 << 25) /* Exception (Big) Endian */ -#define CR_TRE (1 << 28) /* TEX remap enable */ -#define CR_AFE (1 << 29) /* Access flag enable */ -#define CR_TE (1 << 30) /* Thumb exception enable */ - -/* - * This is used to ensure the compiler did actually allocate the register we - * asked it for some inline assembly sequences. Apparently we can't trust - * the compiler from one version to another so a bit of paranoia won't hurt. - * This string is meant to be concatenated with the inline asm string and - * will cause compilation to stop on mismatch. - * (for details, see gcc PR 15089) - */ -#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t" - -#ifndef __ASSEMBLY__ - -#include <linux/compiler.h> -#include <linux/linkage.h> -#include <linux/irqflags.h> - -#include <asm/outercache.h> - -struct thread_info; -struct task_struct; - -/* information about the system we're running on */ -extern unsigned int system_rev; -extern unsigned int system_serial_low; -extern unsigned int system_serial_high; -extern unsigned int mem_fclk_21285; - -struct pt_regs; - -void die(const char *msg, struct pt_regs *regs, int err); - -struct siginfo; -void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info, - unsigned long err, unsigned long trap); - -#ifdef CONFIG_ARM_LPAE -#define FAULT_CODE_ALIGNMENT 33 -#define FAULT_CODE_DEBUG 34 -#else -#define FAULT_CODE_ALIGNMENT 1 -#define FAULT_CODE_DEBUG 2 -#endif - -void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, - struct pt_regs *), - int sig, int code, const char *name); - -void hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int, - struct pt_regs *), - int sig, int code, const char *name); - -#define xchg(ptr,x) \ - ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) - -extern asmlinkage void c_backtrace(unsigned long fp, int pmode); - -struct mm_struct; -extern void show_pte(struct mm_struct *mm, unsigned long addr); -extern void __show_regs(struct pt_regs *); - -extern int __pure cpu_architecture(void); -extern void cpu_init(void); - -void soft_restart(unsigned long); -extern void (*arm_pm_restart)(char str, const char *cmd); - -#define UDBG_UNDEFINED (1 << 0) -#define UDBG_SYSCALL (1 << 1) -#define UDBG_BADABORT (1 << 2) -#define UDBG_SEGV (1 << 3) -#define UDBG_BUS (1 << 4) - -extern unsigned int user_debug; - -#if __LINUX_ARM_ARCH__ >= 4 -#define vectors_high() (cr_alignment & CR_V) -#else -#define vectors_high() (0) -#endif - -#if __LINUX_ARM_ARCH__ >= 7 || \ - (__LINUX_ARM_ARCH__ == 6 && defined(CONFIG_CPU_32v6K)) -#define sev() __asm__ __volatile__ ("sev" : : : "memory") -#define wfe() __asm__ __volatile__ ("wfe" : : : "memory") -#define wfi() __asm__ __volatile__ ("wfi" : : : "memory") -#endif - -#if __LINUX_ARM_ARCH__ >= 7 -#define isb() __asm__ __volatile__ ("isb" : : : "memory") -#define dsb() __asm__ __volatile__ ("dsb" : : : "memory") -#define dmb() __asm__ __volatile__ ("dmb" : : : "memory") -#elif defined(CONFIG_CPU_XSC3) || __LINUX_ARM_ARCH__ == 6 -#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \ - : : "r" (0) : "memory") -#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ - : : "r" (0) : "memory") -#define dmb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \ - : : "r" (0) : "memory") -#elif defined(CONFIG_CPU_FA526) -#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \ - : : "r" (0) : "memory") -#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ - : : "r" (0) : "memory") -#define dmb() __asm__ __volatile__ ("" : : : "memory") -#else -#define isb() __asm__ __volatile__ ("" : : : "memory") -#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ - : : "r" (0) : "memory") -#define dmb() __asm__ __volatile__ ("" : : : "memory") -#endif - -#ifdef CONFIG_ARCH_HAS_BARRIERS -#include <mach/barriers.h> -#elif defined(CONFIG_ARM_DMA_MEM_BUFFERABLE) || defined(CONFIG_SMP) -#define mb() do { dsb(); outer_sync(); } while (0) -#define rmb() dsb() -#define wmb() mb() -#else -#include <asm/memory.h> -#define mb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) -#define rmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) -#define wmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) -#endif - -#ifndef CONFIG_SMP -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#else -#define smp_mb() dmb() -#define smp_rmb() dmb() -#define smp_wmb() dmb() -#endif - -#define read_barrier_depends() do { } while(0) -#define smp_read_barrier_depends() do { } while(0) - -#define set_mb(var, value) do { var = value; smp_mb(); } while (0) -#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t"); - -extern unsigned long cr_no_alignment; /* defined in entry-armv.S */ -extern unsigned long cr_alignment; /* defined in entry-armv.S */ - -static inline unsigned int get_cr(void) -{ - unsigned int val; - asm("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val) : : "cc"); - return val; -} - -static inline void set_cr(unsigned int val) -{ - asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR" - : : "r" (val) : "cc"); - isb(); -} - -#ifndef CONFIG_SMP -extern void adjust_cr(unsigned long mask, unsigned long set); -#endif - -#define CPACC_FULL(n) (3 << (n * 2)) -#define CPACC_SVC(n) (1 << (n * 2)) -#define CPACC_DISABLE(n) (0 << (n * 2)) - -static inline unsigned int get_copro_access(void) -{ - unsigned int val; - asm("mrc p15, 0, %0, c1, c0, 2 @ get copro access" - : "=r" (val) : : "cc"); - return val; -} - -static inline void set_copro_access(unsigned int val) -{ - asm volatile("mcr p15, 0, %0, c1, c0, 2 @ set copro access" - : : "r" (val) : "cc"); - isb(); -} - -/* - * switch_mm() may do a full cache flush over the context switch, - * so enable interrupts over the context switch to avoid high - * latency. - */ -#define __ARCH_WANT_INTERRUPTS_ON_CTXSW - -/* - * switch_to(prev, next) should switch from task `prev' to `next' - * `prev' will never be the same as `next'. schedule() itself - * contains the memory barrier to tell GCC not to cache `current'. - */ -extern struct task_struct *__switch_to(struct task_struct *, struct thread_info *, struct thread_info *); - -#define switch_to(prev,next,last) \ -do { \ - last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \ -} while (0) - -#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110) -/* - * On the StrongARM, "swp" is terminally broken since it bypasses the - * cache totally. This means that the cache becomes inconsistent, and, - * since we use normal loads/stores as well, this is really bad. - * Typically, this causes oopsen in filp_close, but could have other, - * more disastrous effects. There are two work-arounds: - * 1. Disable interrupts and emulate the atomic swap - * 2. Clean the cache, perform atomic swap, flush the cache - * - * We choose (1) since its the "easiest" to achieve here and is not - * dependent on the processor type. - * - * NOTE that this solution won't work on an SMP system, so explcitly - * forbid it here. - */ -#define swp_is_buggy -#endif - -static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size) -{ - extern void __bad_xchg(volatile void *, int); - unsigned long ret; -#ifdef swp_is_buggy - unsigned long flags; -#endif -#if __LINUX_ARM_ARCH__ >= 6 - unsigned int tmp; -#endif - - smp_mb(); - - switch (size) { -#if __LINUX_ARM_ARCH__ >= 6 - case 1: - asm volatile("@ __xchg1\n" - "1: ldrexb %0, [%3]\n" - " strexb %1, %2, [%3]\n" - " teq %1, #0\n" - " bne 1b" - : "=&r" (ret), "=&r" (tmp) - : "r" (x), "r" (ptr) - : "memory", "cc"); - break; - case 4: - asm volatile("@ __xchg4\n" - "1: ldrex %0, [%3]\n" - " strex %1, %2, [%3]\n" - " teq %1, #0\n" - " bne 1b" - : "=&r" (ret), "=&r" (tmp) - : "r" (x), "r" (ptr) - : "memory", "cc"); - break; -#elif defined(swp_is_buggy) -#ifdef CONFIG_SMP -#error SMP is not supported on this platform -#endif - case 1: - raw_local_irq_save(flags); - ret = *(volatile unsigned char *)ptr; - *(volatile unsigned char *)ptr = x; - raw_local_irq_restore(flags); - break; - - case 4: - raw_local_irq_save(flags); - ret = *(volatile unsigned long *)ptr; - *(volatile unsigned long *)ptr = x; - raw_local_irq_restore(flags); - break; -#else - case 1: - asm volatile("@ __xchg1\n" - " swpb %0, %1, [%2]" - : "=&r" (ret) - : "r" (x), "r" (ptr) - : "memory", "cc"); - break; - case 4: - asm volatile("@ __xchg4\n" - " swp %0, %1, [%2]" - : "=&r" (ret) - : "r" (x), "r" (ptr) - : "memory", "cc"); - break; -#endif - default: - __bad_xchg(ptr, size), ret = 0; - break; - } - smp_mb(); - - return ret; -} - -extern void disable_hlt(void); -extern void enable_hlt(void); - -void cpu_idle_wait(void); - -#include <asm-generic/cmpxchg-local.h> - -#if __LINUX_ARM_ARCH__ < 6 -/* min ARCH < ARMv6 */ - -#ifdef CONFIG_SMP -#error "SMP is not supported on this platform" -#endif - -/* - * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make - * them available. - */ -#define cmpxchg_local(ptr, o, n) \ - ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\ - (unsigned long)(n), sizeof(*(ptr)))) -#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) - -#ifndef CONFIG_SMP -#include <asm-generic/cmpxchg.h> -#endif - -#else /* min ARCH >= ARMv6 */ - -extern void __bad_cmpxchg(volatile void *ptr, int size); - -/* - * cmpxchg only support 32-bits operands on ARMv6. - */ - -static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, - unsigned long new, int size) -{ - unsigned long oldval, res; - - switch (size) { -#ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */ - case 1: - do { - asm volatile("@ __cmpxchg1\n" - " ldrexb %1, [%2]\n" - " mov %0, #0\n" - " teq %1, %3\n" - " strexbeq %0, %4, [%2]\n" - : "=&r" (res), "=&r" (oldval) - : "r" (ptr), "Ir" (old), "r" (new) - : "memory", "cc"); - } while (res); - break; - case 2: - do { - asm volatile("@ __cmpxchg1\n" - " ldrexh %1, [%2]\n" - " mov %0, #0\n" - " teq %1, %3\n" - " strexheq %0, %4, [%2]\n" - : "=&r" (res), "=&r" (oldval) - : "r" (ptr), "Ir" (old), "r" (new) - : "memory", "cc"); - } while (res); - break; -#endif - case 4: - do { - asm volatile("@ __cmpxchg4\n" - " ldrex %1, [%2]\n" - " mov %0, #0\n" - " teq %1, %3\n" - " strexeq %0, %4, [%2]\n" - : "=&r" (res), "=&r" (oldval) - : "r" (ptr), "Ir" (old), "r" (new) - : "memory", "cc"); - } while (res); - break; - default: - __bad_cmpxchg(ptr, size); - oldval = 0; - } - - return oldval; -} - -static inline unsigned long __cmpxchg_mb(volatile void *ptr, unsigned long old, - unsigned long new, int size) -{ - unsigned long ret; - - smp_mb(); - ret = __cmpxchg(ptr, old, new, size); - smp_mb(); - - return ret; -} - -#define cmpxchg(ptr,o,n) \ - ((__typeof__(*(ptr)))__cmpxchg_mb((ptr), \ - (unsigned long)(o), \ - (unsigned long)(n), \ - sizeof(*(ptr)))) - -static inline unsigned long __cmpxchg_local(volatile void *ptr, - unsigned long old, - unsigned long new, int size) -{ - unsigned long ret; - - switch (size) { -#ifdef CONFIG_CPU_V6 /* min ARCH == ARMv6 */ - case 1: - case 2: - ret = __cmpxchg_local_generic(ptr, old, new, size); - break; -#endif - default: - ret = __cmpxchg(ptr, old, new, size); - } - - return ret; -} - -#define cmpxchg_local(ptr,o,n) \ - ((__typeof__(*(ptr)))__cmpxchg_local((ptr), \ - (unsigned long)(o), \ - (unsigned long)(n), \ - sizeof(*(ptr)))) - -#ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */ - -/* - * Note : ARMv7-M (currently unsupported by Linux) does not support - * ldrexd/strexd. If ARMv7-M is ever supported by the Linux kernel, it should - * not be allowed to use __cmpxchg64. - */ -static inline unsigned long long __cmpxchg64(volatile void *ptr, - unsigned long long old, - unsigned long long new) -{ - register unsigned long long oldval asm("r0"); - register unsigned long long __old asm("r2") = old; - register unsigned long long __new asm("r4") = new; - unsigned long res; - - do { - asm volatile( - " @ __cmpxchg8\n" - " ldrexd %1, %H1, [%2]\n" - " mov %0, #0\n" - " teq %1, %3\n" - " teqeq %H1, %H3\n" - " strexdeq %0, %4, %H4, [%2]\n" - : "=&r" (res), "=&r" (oldval) - : "r" (ptr), "Ir" (__old), "r" (__new) - : "memory", "cc"); - } while (res); - - return oldval; -} - -static inline unsigned long long __cmpxchg64_mb(volatile void *ptr, - unsigned long long old, - unsigned long long new) -{ - unsigned long long ret; - - smp_mb(); - ret = __cmpxchg64(ptr, old, new); - smp_mb(); - - return ret; -} - -#define cmpxchg64(ptr,o,n) \ - ((__typeof__(*(ptr)))__cmpxchg64_mb((ptr), \ - (unsigned long long)(o), \ - (unsigned long long)(n))) - -#define cmpxchg64_local(ptr,o,n) \ - ((__typeof__(*(ptr)))__cmpxchg64((ptr), \ - (unsigned long long)(o), \ - (unsigned long long)(n))) - -#else /* min ARCH = ARMv6 */ - -#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) - -#endif - -#endif /* __LINUX_ARM_ARCH__ >= 6 */ - -#endif /* __ASSEMBLY__ */ - -#define arch_align_stack(x) (x) - -#endif /* __KERNEL__ */ - -#endif +/* FILE TO BE DELETED. DO NOT ADD STUFF HERE! */ +#include <asm/barrier.h> +#include <asm/compiler.h> +#include <asm/cmpxchg.h> +#include <asm/exec.h> +#include <asm/switch_to.h> +#include <asm/system_info.h> +#include <asm/system_misc.h> diff --git a/arch/arm/include/asm/system_info.h b/arch/arm/include/asm/system_info.h new file mode 100644 index 000000000000..dfd386d0c022 --- /dev/null +++ b/arch/arm/include/asm/system_info.h @@ -0,0 +1,27 @@ +#ifndef __ASM_ARM_SYSTEM_INFO_H +#define __ASM_ARM_SYSTEM_INFO_H + +#define CPU_ARCH_UNKNOWN 0 +#define CPU_ARCH_ARMv3 1 +#define CPU_ARCH_ARMv4 2 +#define CPU_ARCH_ARMv4T 3 +#define CPU_ARCH_ARMv5 4 +#define CPU_ARCH_ARMv5T 5 +#define CPU_ARCH_ARMv5TE 6 +#define CPU_ARCH_ARMv5TEJ 7 +#define CPU_ARCH_ARMv6 8 +#define CPU_ARCH_ARMv7 9 + +#ifndef __ASSEMBLY__ + +/* information about the system we're running on */ +extern unsigned int system_rev; +extern unsigned int system_serial_low; +extern unsigned int system_serial_high; +extern unsigned int mem_fclk_21285; + +extern int __pure cpu_architecture(void); + +#endif /* !__ASSEMBLY__ */ + +#endif /* __ASM_ARM_SYSTEM_INFO_H */ diff --git a/arch/arm/include/asm/system_misc.h b/arch/arm/include/asm/system_misc.h new file mode 100644 index 000000000000..5a85f148b607 --- /dev/null +++ b/arch/arm/include/asm/system_misc.h @@ -0,0 +1,29 @@ +#ifndef __ASM_ARM_SYSTEM_MISC_H +#define __ASM_ARM_SYSTEM_MISC_H + +#ifndef __ASSEMBLY__ + +#include <linux/compiler.h> +#include <linux/linkage.h> +#include <linux/irqflags.h> + +extern void cpu_init(void); + +void soft_restart(unsigned long); +extern void (*arm_pm_restart)(char str, const char *cmd); +extern void (*arm_pm_idle)(void); + +#define UDBG_UNDEFINED (1 << 0) +#define UDBG_SYSCALL (1 << 1) +#define UDBG_BADABORT (1 << 2) +#define UDBG_SEGV (1 << 3) +#define UDBG_BUS (1 << 4) + +extern unsigned int user_debug; + +extern void disable_hlt(void); +extern void enable_hlt(void); + +#endif /* !__ASSEMBLY__ */ + +#endif /* __ASM_ARM_SYSTEM_MISC_H */ diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h index 02b2f8203982..85fe61e73202 100644 --- a/arch/arm/include/asm/tlbflush.h +++ b/arch/arm/include/asm/tlbflush.h @@ -318,6 +318,21 @@ extern struct cpu_tlb_fns cpu_tlb; #define tlb_flag(f) ((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f))) +#define __tlb_op(f, insnarg, arg) \ + do { \ + if (always_tlb_flags & (f)) \ + asm("mcr " insnarg \ + : : "r" (arg) : "cc"); \ + else if (possible_tlb_flags & (f)) \ + asm("tst %1, %2\n\t" \ + "mcrne " insnarg \ + : : "r" (arg), "r" (__tlb_flag), "Ir" (f) \ + : "cc"); \ + } while (0) + +#define tlb_op(f, regs, arg) __tlb_op(f, "p15, 0, %0, " regs, arg) +#define tlb_l2_op(f, regs, arg) __tlb_op(f, "p15, 1, %0, " regs, arg) + static inline void local_flush_tlb_all(void) { const int zero = 0; @@ -326,16 +341,11 @@ static inline void local_flush_tlb_all(void) if (tlb_flag(TLB_WB)) dsb(); - if (tlb_flag(TLB_V3_FULL)) - asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc"); - if (tlb_flag(TLB_V4_U_FULL | TLB_V6_U_FULL)) - asm("mcr p15, 0, %0, c8, c7, 0" : : "r" (zero) : "cc"); - if (tlb_flag(TLB_V4_D_FULL | TLB_V6_D_FULL)) - asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc"); - if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL)) - asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); - if (tlb_flag(TLB_V7_UIS_FULL)) - asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc"); + tlb_op(TLB_V3_FULL, "c6, c0, 0", zero); + tlb_op(TLB_V4_U_FULL | TLB_V6_U_FULL, "c8, c7, 0", zero); + tlb_op(TLB_V4_D_FULL | TLB_V6_D_FULL, "c8, c6, 0", zero); + tlb_op(TLB_V4_I_FULL | TLB_V6_I_FULL, "c8, c5, 0", zero); + tlb_op(TLB_V7_UIS_FULL, "c8, c3, 0", zero); if (tlb_flag(TLB_BARRIER)) { dsb(); @@ -352,29 +362,23 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm) if (tlb_flag(TLB_WB)) dsb(); - if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) { - if (tlb_flag(TLB_V3_FULL)) - asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc"); - if (tlb_flag(TLB_V4_U_FULL)) - asm("mcr p15, 0, %0, c8, c7, 0" : : "r" (zero) : "cc"); - if (tlb_flag(TLB_V4_D_FULL)) - asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc"); - if (tlb_flag(TLB_V4_I_FULL)) - asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); + if (possible_tlb_flags & (TLB_V3_FULL|TLB_V4_U_FULL|TLB_V4_D_FULL|TLB_V4_I_FULL)) { + if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) { + tlb_op(TLB_V3_FULL, "c6, c0, 0", zero); + tlb_op(TLB_V4_U_FULL, "c8, c7, 0", zero); + tlb_op(TLB_V4_D_FULL, "c8, c6, 0", zero); + tlb_op(TLB_V4_I_FULL, "c8, c5, 0", zero); + } + put_cpu(); } - put_cpu(); - - if (tlb_flag(TLB_V6_U_ASID)) - asm("mcr p15, 0, %0, c8, c7, 2" : : "r" (asid) : "cc"); - if (tlb_flag(TLB_V6_D_ASID)) - asm("mcr p15, 0, %0, c8, c6, 2" : : "r" (asid) : "cc"); - if (tlb_flag(TLB_V6_I_ASID)) - asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc"); - if (tlb_flag(TLB_V7_UIS_ASID)) + + tlb_op(TLB_V6_U_ASID, "c8, c7, 2", asid); + tlb_op(TLB_V6_D_ASID, "c8, c6, 2", asid); + tlb_op(TLB_V6_I_ASID, "c8, c5, 2", asid); #ifdef CONFIG_ARM_ERRATA_720789 - asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc"); + tlb_op(TLB_V7_UIS_ASID, "c8, c3, 0", zero); #else - asm("mcr p15, 0, %0, c8, c3, 2" : : "r" (asid) : "cc"); + tlb_op(TLB_V7_UIS_ASID, "c8, c3, 2", asid); #endif if (tlb_flag(TLB_BARRIER)) @@ -392,30 +396,23 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) if (tlb_flag(TLB_WB)) dsb(); - if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { - if (tlb_flag(TLB_V3_PAGE)) - asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (uaddr) : "cc"); - if (tlb_flag(TLB_V4_U_PAGE)) - asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (uaddr) : "cc"); - if (tlb_flag(TLB_V4_D_PAGE)) - asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc"); - if (tlb_flag(TLB_V4_I_PAGE)) - asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc"); + if (possible_tlb_flags & (TLB_V3_PAGE|TLB_V4_U_PAGE|TLB_V4_D_PAGE|TLB_V4_I_PAGE|TLB_V4_I_FULL) && + cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { + tlb_op(TLB_V3_PAGE, "c6, c0, 0", uaddr); + tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", uaddr); + tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", uaddr); + tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", uaddr); if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL)) asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); } - if (tlb_flag(TLB_V6_U_PAGE)) - asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (uaddr) : "cc"); - if (tlb_flag(TLB_V6_D_PAGE)) - asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc"); - if (tlb_flag(TLB_V6_I_PAGE)) - asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc"); - if (tlb_flag(TLB_V7_UIS_PAGE)) + tlb_op(TLB_V6_U_PAGE, "c8, c7, 1", uaddr); + tlb_op(TLB_V6_D_PAGE, "c8, c6, 1", uaddr); + tlb_op(TLB_V6_I_PAGE, "c8, c5, 1", uaddr); #ifdef CONFIG_ARM_ERRATA_720789 - asm("mcr p15, 0, %0, c8, c3, 3" : : "r" (uaddr & PAGE_MASK) : "cc"); + tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 3", uaddr & PAGE_MASK); #else - asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (uaddr) : "cc"); + tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 1", uaddr); #endif if (tlb_flag(TLB_BARRIER)) @@ -432,25 +429,17 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr) if (tlb_flag(TLB_WB)) dsb(); - if (tlb_flag(TLB_V3_PAGE)) - asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (kaddr) : "cc"); - if (tlb_flag(TLB_V4_U_PAGE)) - asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (kaddr) : "cc"); - if (tlb_flag(TLB_V4_D_PAGE)) - asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc"); - if (tlb_flag(TLB_V4_I_PAGE)) - asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc"); + tlb_op(TLB_V3_PAGE, "c6, c0, 0", kaddr); + tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", kaddr); + tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", kaddr); + tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", kaddr); if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL)) asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); - if (tlb_flag(TLB_V6_U_PAGE)) - asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (kaddr) : "cc"); - if (tlb_flag(TLB_V6_D_PAGE)) - asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc"); - if (tlb_flag(TLB_V6_I_PAGE)) - asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc"); - if (tlb_flag(TLB_V7_UIS_PAGE)) - asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (kaddr) : "cc"); + tlb_op(TLB_V6_U_PAGE, "c8, c7, 1", kaddr); + tlb_op(TLB_V6_D_PAGE, "c8, c6, 1", kaddr); + tlb_op(TLB_V6_I_PAGE, "c8, c5, 1", kaddr); + tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 1", kaddr); if (tlb_flag(TLB_BARRIER)) { dsb(); @@ -475,13 +464,8 @@ static inline void flush_pmd_entry(void *pmd) { const unsigned int __tlb_flag = __cpu_tlb_flags; - if (tlb_flag(TLB_DCLEAN)) - asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pmd" - : : "r" (pmd) : "cc"); - - if (tlb_flag(TLB_L2CLEAN_FR)) - asm("mcr p15, 1, %0, c15, c9, 1 @ L2 flush_pmd" - : : "r" (pmd) : "cc"); + tlb_op(TLB_DCLEAN, "c7, c10, 1 @ flush_pmd", pmd); + tlb_l2_op(TLB_L2CLEAN_FR, "c15, c9, 1 @ L2 flush_pmd", pmd); if (tlb_flag(TLB_WB)) dsb(); @@ -491,15 +475,11 @@ static inline void clean_pmd_entry(void *pmd) { const unsigned int __tlb_flag = __cpu_tlb_flags; - if (tlb_flag(TLB_DCLEAN)) - asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pmd" - : : "r" (pmd) : "cc"); - - if (tlb_flag(TLB_L2CLEAN_FR)) - asm("mcr p15, 1, %0, c15, c9, 1 @ L2 flush_pmd" - : : "r" (pmd) : "cc"); + tlb_op(TLB_DCLEAN, "c7, c10, 1 @ flush_pmd", pmd); + tlb_l2_op(TLB_L2CLEAN_FR, "c15, c9, 1 @ L2 flush_pmd", pmd); } +#undef tlb_op #undef tlb_flag #undef always_tlb_flags #undef possible_tlb_flags diff --git a/arch/arm/include/asm/traps.h b/arch/arm/include/asm/traps.h index 5b29a6673625..f555bb3664dc 100644 --- a/arch/arm/include/asm/traps.h +++ b/arch/arm/include/asm/traps.h @@ -46,7 +46,7 @@ static inline int in_exception_text(unsigned long ptr) return in ? : __in_irqentry_text(ptr); } -extern void __init early_trap_init(void); +extern void __init early_trap_init(void *); extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame); extern void ptrace_break(struct task_struct *tsk, struct pt_regs *regs); diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h index 2958976d867b..71f6536d17ac 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h @@ -16,8 +16,8 @@ #include <asm/errno.h> #include <asm/memory.h> #include <asm/domain.h> -#include <asm/system.h> #include <asm/unified.h> +#include <asm/compiler.h> #define VERIFY_READ 0 #define VERIFY_WRITE 1 diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 43b740d0e374..7b787d642af4 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -7,6 +7,8 @@ AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET) ifdef CONFIG_FUNCTION_TRACER CFLAGS_REMOVE_ftrace.o = -pg +CFLAGS_REMOVE_insn.o = -pg +CFLAGS_REMOVE_patch.o = -pg endif CFLAGS_REMOVE_return_address.o = -pg @@ -14,30 +16,29 @@ CFLAGS_REMOVE_return_address.o = -pg # Object file lists. obj-y := elf.o entry-armv.o entry-common.o irq.o opcodes.o \ - process.o ptrace.o return_address.o setup.o signal.o \ - sys_arm.o stacktrace.o time.o traps.o + process.o ptrace.o return_address.o sched_clock.o \ + setup.o signal.o stacktrace.o sys_arm.o time.o traps.o obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o obj-$(CONFIG_LEDS) += leds.o obj-$(CONFIG_OC_ETM) += etm.o - +obj-$(CONFIG_CPU_IDLE) += cpuidle.o obj-$(CONFIG_ISA_DMA_API) += dma.o -obj-$(CONFIG_ARCH_ACORN) += ecard.o obj-$(CONFIG_FIQ) += fiq.o fiqasm.o obj-$(CONFIG_MODULES) += armksyms.o module.o obj-$(CONFIG_ARTHUR) += arthur.o obj-$(CONFIG_ISA_DMA) += dma-isa.o obj-$(CONFIG_PCI) += bios32.o isa.o obj-$(CONFIG_ARM_CPU_SUSPEND) += sleep.o suspend.o -obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o obj-$(CONFIG_SMP) += smp.o smp_tlb.o obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o -obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o -obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o +obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o +obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o +obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o -obj-$(CONFIG_KPROBES) += kprobes.o kprobes-common.o +obj-$(CONFIG_KPROBES) += kprobes.o kprobes-common.o patch.o ifdef CONFIG_THUMB2_KERNEL obj-$(CONFIG_KPROBES) += kprobes-thumb.o else @@ -62,9 +63,6 @@ obj-$(CONFIG_SWP_EMULATE) += swp_emulate.o CFLAGS_swp_emulate.o := -Wa,-march=armv7-a obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o -obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o -AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312 - obj-$(CONFIG_CPU_XSCALE) += xscale-cp0.o obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 5b0bce61eb69..b57c75e0b01f 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -18,7 +18,6 @@ #include <linux/io.h> #include <asm/checksum.h> -#include <asm/system.h> #include <asm/ftrace.h> /* diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index f58ba3589908..ede5f7741c42 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -16,7 +16,6 @@ #include <asm/mach/pci.h> static int debug_pci; -static int use_firmware; /* * We can't use pci_find_device() here since we are @@ -295,34 +294,11 @@ static inline int pdev_bad_for_parity(struct pci_dev *dev) } /* - * Adjust the device resources from bus-centric to Linux-centric. - */ -static void __devinit -pdev_fixup_device_resources(struct pci_sys_data *root, struct pci_dev *dev) -{ - resource_size_t offset; - int i; - - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - if (dev->resource[i].start == 0) - continue; - if (dev->resource[i].flags & IORESOURCE_MEM) - offset = root->mem_offset; - else - offset = root->io_offset; - - dev->resource[i].start += offset; - dev->resource[i].end += offset; - } -} - -/* * pcibios_fixup_bus - Called after each bus is probed, * but before its children are examined. */ void pcibios_fixup_bus(struct pci_bus *bus) { - struct pci_sys_data *root = bus->sysdata; struct pci_dev *dev; u16 features = PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_FAST_BACK; @@ -333,8 +309,6 @@ void pcibios_fixup_bus(struct pci_bus *bus) list_for_each_entry(dev, &bus->devices, bus_list) { u16 status; - pdev_fixup_device_resources(root, dev); - pci_read_config_word(dev, PCI_STATUS, &status); /* @@ -400,43 +374,6 @@ EXPORT_SYMBOL(pcibios_fixup_bus); #endif /* - * Convert from Linux-centric to bus-centric addresses for bridge devices. - */ -void -pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, - struct resource *res) -{ - struct pci_sys_data *root = dev->sysdata; - unsigned long offset = 0; - - if (res->flags & IORESOURCE_IO) - offset = root->io_offset; - if (res->flags & IORESOURCE_MEM) - offset = root->mem_offset; - - region->start = res->start - offset; - region->end = res->end - offset; -} -EXPORT_SYMBOL(pcibios_resource_to_bus); - -void __devinit -pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region) -{ - struct pci_sys_data *root = dev->sysdata; - unsigned long offset = 0; - - if (res->flags & IORESOURCE_IO) - offset = root->io_offset; - if (res->flags & IORESOURCE_MEM) - offset = root->mem_offset; - - res->start = region->start + offset; - res->end = region->end + offset; -} -EXPORT_SYMBOL(pcibios_bus_to_resource); - -/* * Swizzle the device pin each time we cross a bridge. * This might update pin and returns the slot number. */ @@ -497,10 +434,10 @@ static void __init pcibios_init_hw(struct hw_pci *hw) if (ret > 0) { if (list_empty(&sys->resources)) { - pci_add_resource(&sys->resources, - &ioport_resource); - pci_add_resource(&sys->resources, - &iomem_resource); + pci_add_resource_offset(&sys->resources, + &ioport_resource, sys->io_offset); + pci_add_resource_offset(&sys->resources, + &iomem_resource, sys->mem_offset); } sys->bus = hw->scan(nr, sys); @@ -525,6 +462,7 @@ void __init pci_common_init(struct hw_pci *hw) INIT_LIST_HEAD(&hw->buses); + pci_add_flags(PCI_REASSIGN_ALL_RSRC); if (hw->preinit) hw->preinit(); pcibios_init_hw(hw); @@ -536,7 +474,7 @@ void __init pci_common_init(struct hw_pci *hw) list_for_each_entry(sys, &hw->buses, node) { struct pci_bus *bus = sys->bus; - if (!use_firmware) { + if (!pci_has_flag(PCI_PROBE_ONLY)) { /* * Size the bridge windows. */ @@ -573,7 +511,7 @@ char * __init pcibios_setup(char *str) debug_pci = 1; return NULL; } else if (!strcmp(str, "firmware")) { - use_firmware = 1; + pci_add_flags(PCI_PROBE_ONLY); return NULL; } return str; diff --git a/arch/arm/kernel/cpuidle.c b/arch/arm/kernel/cpuidle.c new file mode 100644 index 000000000000..89545f6c8403 --- /dev/null +++ b/arch/arm/kernel/cpuidle.c @@ -0,0 +1,21 @@ +/* + * Copyright 2012 Linaro Ltd. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include <linux/cpuidle.h> +#include <asm/proc-fns.h> + +int arm_cpuidle_simple_enter(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) +{ + cpu_do_idle(); + + return index; +} diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S index 204e2160cfcc..c45522c36787 100644 --- a/arch/arm/kernel/debug.S +++ b/arch/arm/kernel/debug.S @@ -10,6 +10,7 @@ * 32-bit debugging code */ #include <linux/linkage.h> +#include <asm/assembler.h> .text @@ -100,7 +101,7 @@ #endif /* CONFIG_CPU_V6 */ -#else +#elif !defined(CONFIG_DEBUG_SEMIHOSTING) #include <mach/debug-macro.S> #endif /* CONFIG_DEBUG_ICEDCC */ @@ -155,6 +156,8 @@ hexbuf: .space 16 .ltorg +#ifndef CONFIG_DEBUG_SEMIHOSTING + ENTRY(printascii) addruart_current r3, r1, r2 b 2f @@ -177,3 +180,24 @@ ENTRY(printch) mov r0, #0 b 1b ENDPROC(printch) + +#else + +ENTRY(printascii) + mov r1, r0 + mov r0, #0x04 @ SYS_WRITE0 + ARM( svc #0x123456 ) + THUMB( svc #0xab ) + mov pc, lr +ENDPROC(printascii) + +ENTRY(printch) + adr r1, hexbuf + strb r0, [r1] + mov r0, #0x03 @ SYS_WRITEC + ARM( svc #0x123456 ) + THUMB( svc #0xab ) + mov pc, lr +ENDPROC(printch) + +#endif diff --git a/arch/arm/kernel/elf.c b/arch/arm/kernel/elf.c index ddba41d1fcf1..d0d1e83150c9 100644 --- a/arch/arm/kernel/elf.c +++ b/arch/arm/kernel/elf.c @@ -3,6 +3,7 @@ #include <linux/personality.h> #include <linux/binfmts.h> #include <linux/elf.h> +#include <asm/system_info.h> int elf_check_arch(const struct elf32_hdr *x) { diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index be16a48007b4..7fd3ad048da9 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -15,16 +15,19 @@ * that causes it to save wrong values... Be aware! */ +#include <asm/assembler.h> #include <asm/memory.h> #include <asm/glue-df.h> #include <asm/glue-pf.h> #include <asm/vfpmacros.h> +#ifndef CONFIG_MULTI_IRQ_HANDLER #include <mach/entry-macro.S> +#endif #include <asm/thread_notify.h> #include <asm/unwind.h> #include <asm/unistd.h> #include <asm/tls.h> -#include <asm/system.h> +#include <asm/system_info.h> #include "entry-header.S" #include <asm/entry-macro-multi.S> @@ -1101,7 +1104,6 @@ __stubs_start: * get out of that mode without clobbering one register. */ vector_fiq: - disable_fiq subs pc, lr, #4 /*============================================================================= diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 9fd0ba90c1d2..54ee265dd819 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -10,9 +10,15 @@ #include <asm/unistd.h> #include <asm/ftrace.h> -#include <mach/entry-macro.S> #include <asm/unwind.h> +#ifdef CONFIG_NEED_RET_TO_USER +#include <mach/entry-macro.S> +#else + .macro arch_ret_to_user, tmp1, tmp2 + .endm +#endif + #include "entry-header.S" diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c index 4c164ece5891..c32f8456aa09 100644 --- a/arch/arm/kernel/fiq.c +++ b/arch/arm/kernel/fiq.c @@ -42,9 +42,9 @@ #include <linux/seq_file.h> #include <asm/cacheflush.h> +#include <asm/cp15.h> #include <asm/fiq.h> #include <asm/irq.h> -#include <asm/system.h> #include <asm/traps.h> static unsigned long no_fiq_insn; diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c index c0062ad1e847..df0bf0c8cb79 100644 --- a/arch/arm/kernel/ftrace.c +++ b/arch/arm/kernel/ftrace.c @@ -16,10 +16,13 @@ #include <linux/uaccess.h> #include <asm/cacheflush.h> +#include <asm/opcodes.h> #include <asm/ftrace.h> +#include "insn.h" + #ifdef CONFIG_THUMB2_KERNEL -#define NOP 0xeb04f85d /* pop.w {lr} */ +#define NOP 0xf85deb04 /* pop.w {lr} */ #else #define NOP 0xe8bd4000 /* pop {lr} */ #endif @@ -60,76 +63,31 @@ static unsigned long adjust_address(struct dyn_ftrace *rec, unsigned long addr) } #endif -#ifdef CONFIG_THUMB2_KERNEL -static unsigned long ftrace_gen_branch(unsigned long pc, unsigned long addr, - bool link) -{ - unsigned long s, j1, j2, i1, i2, imm10, imm11; - unsigned long first, second; - long offset; - - offset = (long)addr - (long)(pc + 4); - if (offset < -16777216 || offset > 16777214) { - WARN_ON_ONCE(1); - return 0; - } - - s = (offset >> 24) & 0x1; - i1 = (offset >> 23) & 0x1; - i2 = (offset >> 22) & 0x1; - imm10 = (offset >> 12) & 0x3ff; - imm11 = (offset >> 1) & 0x7ff; - - j1 = (!i1) ^ s; - j2 = (!i2) ^ s; - - first = 0xf000 | (s << 10) | imm10; - second = 0x9000 | (j1 << 13) | (j2 << 11) | imm11; - if (link) - second |= 1 << 14; - - return (second << 16) | first; -} -#else -static unsigned long ftrace_gen_branch(unsigned long pc, unsigned long addr, - bool link) -{ - unsigned long opcode = 0xea000000; - long offset; - - if (link) - opcode |= 1 << 24; - - offset = (long)addr - (long)(pc + 8); - if (unlikely(offset < -33554432 || offset > 33554428)) { - /* Can't generate branches that far (from ARM ARM). Ftrace - * doesn't generate branches outside of kernel text. - */ - WARN_ON_ONCE(1); - return 0; - } - - offset = (offset >> 2) & 0x00ffffff; - - return opcode | offset; -} -#endif - static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr) { - return ftrace_gen_branch(pc, addr, true); + return arm_gen_branch_link(pc, addr); } static int ftrace_modify_code(unsigned long pc, unsigned long old, - unsigned long new) + unsigned long new, bool validate) { unsigned long replaced; - if (probe_kernel_read(&replaced, (void *)pc, MCOUNT_INSN_SIZE)) - return -EFAULT; + if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) { + old = __opcode_to_mem_thumb32(old); + new = __opcode_to_mem_thumb32(new); + } else { + old = __opcode_to_mem_arm(old); + new = __opcode_to_mem_arm(new); + } - if (replaced != old) - return -EINVAL; + if (validate) { + if (probe_kernel_read(&replaced, (void *)pc, MCOUNT_INSN_SIZE)) + return -EFAULT; + + if (replaced != old) + return -EINVAL; + } if (probe_kernel_write((void *)pc, &new, MCOUNT_INSN_SIZE)) return -EPERM; @@ -141,23 +99,21 @@ static int ftrace_modify_code(unsigned long pc, unsigned long old, int ftrace_update_ftrace_func(ftrace_func_t func) { - unsigned long pc, old; + unsigned long pc; unsigned long new; int ret; pc = (unsigned long)&ftrace_call; - memcpy(&old, &ftrace_call, MCOUNT_INSN_SIZE); new = ftrace_call_replace(pc, (unsigned long)func); - ret = ftrace_modify_code(pc, old, new); + ret = ftrace_modify_code(pc, 0, new, false); #ifdef CONFIG_OLD_MCOUNT if (!ret) { pc = (unsigned long)&ftrace_call_old; - memcpy(&old, &ftrace_call_old, MCOUNT_INSN_SIZE); new = ftrace_call_replace(pc, (unsigned long)func); - ret = ftrace_modify_code(pc, old, new); + ret = ftrace_modify_code(pc, 0, new, false); } #endif @@ -172,7 +128,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) old = ftrace_nop_replace(rec); new = ftrace_call_replace(ip, adjust_address(rec, addr)); - return ftrace_modify_code(rec->ip, old, new); + return ftrace_modify_code(rec->ip, old, new, true); } int ftrace_make_nop(struct module *mod, @@ -185,7 +141,7 @@ int ftrace_make_nop(struct module *mod, old = ftrace_call_replace(ip, adjust_address(rec, addr)); new = ftrace_nop_replace(rec); - ret = ftrace_modify_code(ip, old, new); + ret = ftrace_modify_code(ip, old, new, true); #ifdef CONFIG_OLD_MCOUNT if (ret == -EINVAL && addr == MCOUNT_ADDR) { @@ -193,7 +149,7 @@ int ftrace_make_nop(struct module *mod, old = ftrace_call_replace(ip, adjust_address(rec, addr)); new = ftrace_nop_replace(rec); - ret = ftrace_modify_code(ip, old, new); + ret = ftrace_modify_code(ip, old, new, true); } #endif @@ -249,12 +205,12 @@ static int __ftrace_modify_caller(unsigned long *callsite, { unsigned long caller_fn = (unsigned long) func; unsigned long pc = (unsigned long) callsite; - unsigned long branch = ftrace_gen_branch(pc, caller_fn, false); + unsigned long branch = arm_gen_branch(pc, caller_fn); unsigned long nop = 0xe1a00000; /* mov r0, r0 */ unsigned long old = enable ? nop : branch; unsigned long new = enable ? branch : nop; - return ftrace_modify_code(pc, old, new); + return ftrace_modify_code(pc, old, new, true); } static int ftrace_modify_graph_caller(bool enable) diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S index d46f25968bec..278cfc144f44 100644 --- a/arch/arm/kernel/head-nommu.S +++ b/arch/arm/kernel/head-nommu.S @@ -17,8 +17,8 @@ #include <asm/assembler.h> #include <asm/ptrace.h> #include <asm/asm-offsets.h> +#include <asm/cp15.h> #include <asm/thread_info.h> -#include <asm/system.h> /* * Kernel startup entry point. diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 6d5791144066..3bf0c7f8b043 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -15,12 +15,12 @@ #include <linux/init.h> #include <asm/assembler.h> +#include <asm/cp15.h> #include <asm/domain.h> #include <asm/ptrace.h> #include <asm/asm-offsets.h> #include <asm/memory.h> #include <asm/thread_info.h> -#include <asm/system.h> #include <asm/pgtable.h> #ifdef CONFIG_DEBUG_LL @@ -265,7 +265,7 @@ __create_page_tables: str r6, [r3] #ifdef CONFIG_DEBUG_LL -#ifndef CONFIG_DEBUG_ICEDCC +#if !defined(CONFIG_DEBUG_ICEDCC) && !defined(CONFIG_DEBUG_SEMIHOSTING) /* * Map in IO space for serial debugging. * This allows debug messages to be output @@ -297,10 +297,10 @@ __create_page_tables: cmp r0, r6 blo 1b -#else /* CONFIG_DEBUG_ICEDCC */ - /* we don't need any serial debugging mappings for ICEDCC */ +#else /* CONFIG_DEBUG_ICEDCC || CONFIG_DEBUG_SEMIHOSTING */ + /* we don't need any serial debugging mappings */ ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags -#endif /* !CONFIG_DEBUG_ICEDCC */ +#endif #if defined(CONFIG_ARCH_NETWINDER) || defined(CONFIG_ARCH_CATS) /* diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index d6a95ef9131d..ba386bd94107 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -34,7 +34,6 @@ #include <asm/current.h> #include <asm/hw_breakpoint.h> #include <asm/kdebug.h> -#include <asm/system.h> #include <asm/traps.h> /* Breakpoint currently in use for each BRP. */ diff --git a/arch/arm/kernel/insn.c b/arch/arm/kernel/insn.c new file mode 100644 index 000000000000..b760340b7014 --- /dev/null +++ b/arch/arm/kernel/insn.c @@ -0,0 +1,62 @@ +#include <linux/bug.h> +#include <linux/kernel.h> +#include <asm/opcodes.h> + +static unsigned long +__arm_gen_branch_thumb2(unsigned long pc, unsigned long addr, bool link) +{ + unsigned long s, j1, j2, i1, i2, imm10, imm11; + unsigned long first, second; + long offset; + + offset = (long)addr - (long)(pc + 4); + if (offset < -16777216 || offset > 16777214) { + WARN_ON_ONCE(1); + return 0; + } + + s = (offset >> 24) & 0x1; + i1 = (offset >> 23) & 0x1; + i2 = (offset >> 22) & 0x1; + imm10 = (offset >> 12) & 0x3ff; + imm11 = (offset >> 1) & 0x7ff; + + j1 = (!i1) ^ s; + j2 = (!i2) ^ s; + + first = 0xf000 | (s << 10) | imm10; + second = 0x9000 | (j1 << 13) | (j2 << 11) | imm11; + if (link) + second |= 1 << 14; + + return __opcode_thumb32_compose(first, second); +} + +static unsigned long +__arm_gen_branch_arm(unsigned long pc, unsigned long addr, bool link) +{ + unsigned long opcode = 0xea000000; + long offset; + + if (link) + opcode |= 1 << 24; + + offset = (long)addr - (long)(pc + 8); + if (unlikely(offset < -33554432 || offset > 33554428)) { + WARN_ON_ONCE(1); + return 0; + } + + offset = (offset >> 2) & 0x00ffffff; + + return opcode | offset; +} + +unsigned long +__arm_gen_branch(unsigned long pc, unsigned long addr, bool link) +{ + if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) + return __arm_gen_branch_thumb2(pc, addr, link); + else + return __arm_gen_branch_arm(pc, addr, link); +} diff --git a/arch/arm/kernel/insn.h b/arch/arm/kernel/insn.h new file mode 100644 index 000000000000..e96065da4dae --- /dev/null +++ b/arch/arm/kernel/insn.h @@ -0,0 +1,29 @@ +#ifndef __ASM_ARM_INSN_H +#define __ASM_ARM_INSN_H + +static inline unsigned long +arm_gen_nop(void) +{ +#ifdef CONFIG_THUMB2_KERNEL + return 0xf3af8000; /* nop.w */ +#else + return 0xe1a00000; /* mov r0, r0 */ +#endif +} + +unsigned long +__arm_gen_branch(unsigned long pc, unsigned long addr, bool link); + +static inline unsigned long +arm_gen_branch(unsigned long pc, unsigned long addr) +{ + return __arm_gen_branch(pc, addr, false); +} + +static inline unsigned long +arm_gen_branch_link(unsigned long pc, unsigned long addr) +{ + return __arm_gen_branch(pc, addr, true); +} + +#endif diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 3efd82cc95f0..71ccdbfed662 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -36,7 +36,6 @@ #include <linux/proc_fs.h> #include <asm/exception.h> -#include <asm/system.h> #include <asm/mach/arch.h> #include <asm/mach/irq.h> #include <asm/mach/time.h> @@ -181,10 +180,7 @@ void migrate_irqs(void) local_irq_save(flags); for_each_irq_desc(i, desc) { - bool affinity_broken = false; - - if (!desc) - continue; + bool affinity_broken; raw_spin_lock(&desc->lock); affinity_broken = migrate_one_irq(desc); diff --git a/arch/arm/kernel/jump_label.c b/arch/arm/kernel/jump_label.c new file mode 100644 index 000000000000..4ce4f789446d --- /dev/null +++ b/arch/arm/kernel/jump_label.c @@ -0,0 +1,39 @@ +#include <linux/kernel.h> +#include <linux/jump_label.h> + +#include "insn.h" +#include "patch.h" + +#ifdef HAVE_JUMP_LABEL + +static void __arch_jump_label_transform(struct jump_entry *entry, + enum jump_label_type type, + bool is_static) +{ + void *addr = (void *)entry->code; + unsigned int insn; + + if (type == JUMP_LABEL_ENABLE) + insn = arm_gen_branch(entry->code, entry->target); + else + insn = arm_gen_nop(); + + if (is_static) + __patch_text(addr, insn); + else + patch_text(addr, insn); +} + +void arch_jump_label_transform(struct jump_entry *entry, + enum jump_label_type type) +{ + __arch_jump_label_transform(entry, type, false); +} + +void arch_jump_label_transform_static(struct jump_entry *entry, + enum jump_label_type type) +{ + __arch_jump_label_transform(entry, type, true); +} + +#endif diff --git a/arch/arm/kernel/kprobes-common.c b/arch/arm/kernel/kprobes-common.c index a5394fb4e4e0..18a76282970e 100644 --- a/arch/arm/kernel/kprobes-common.c +++ b/arch/arm/kernel/kprobes-common.c @@ -13,6 +13,7 @@ #include <linux/kernel.h> #include <linux/kprobes.h> +#include <asm/system_info.h> #include "kprobes.h" diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c index 129c1163248b..4dd41fc9e235 100644 --- a/arch/arm/kernel/kprobes.c +++ b/arch/arm/kernel/kprobes.c @@ -29,6 +29,7 @@ #include <asm/cacheflush.h> #include "kprobes.h" +#include "patch.h" #define MIN_STACK_SIZE(addr) \ min((unsigned long)MAX_STACK_SIZE, \ @@ -103,57 +104,33 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) return 0; } -#ifdef CONFIG_THUMB2_KERNEL - -/* - * For a 32-bit Thumb breakpoint spanning two memory words we need to take - * special precautions to insert the breakpoint atomically, especially on SMP - * systems. This is achieved by calling this arming function using stop_machine. - */ -static int __kprobes set_t32_breakpoint(void *addr) -{ - ((u16 *)addr)[0] = KPROBE_THUMB32_BREAKPOINT_INSTRUCTION >> 16; - ((u16 *)addr)[1] = KPROBE_THUMB32_BREAKPOINT_INSTRUCTION & 0xffff; - flush_insns(addr, 2*sizeof(u16)); - return 0; -} - void __kprobes arch_arm_kprobe(struct kprobe *p) { - uintptr_t addr = (uintptr_t)p->addr & ~1; /* Remove any Thumb flag */ - - if (!is_wide_instruction(p->opcode)) { - *(u16 *)addr = KPROBE_THUMB16_BREAKPOINT_INSTRUCTION; - flush_insns(addr, sizeof(u16)); - } else if (addr & 2) { - /* A 32-bit instruction spanning two words needs special care */ - stop_machine(set_t32_breakpoint, (void *)addr, &cpu_online_map); + unsigned int brkp; + void *addr; + + if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) { + /* Remove any Thumb flag */ + addr = (void *)((uintptr_t)p->addr & ~1); + + if (is_wide_instruction(p->opcode)) + brkp = KPROBE_THUMB32_BREAKPOINT_INSTRUCTION; + else + brkp = KPROBE_THUMB16_BREAKPOINT_INSTRUCTION; } else { - /* Word aligned 32-bit instruction can be written atomically */ - u32 bkp = KPROBE_THUMB32_BREAKPOINT_INSTRUCTION; -#ifndef __ARMEB__ /* Swap halfwords for little-endian */ - bkp = (bkp >> 16) | (bkp << 16); -#endif - *(u32 *)addr = bkp; - flush_insns(addr, sizeof(u32)); - } -} + kprobe_opcode_t insn = p->opcode; -#else /* !CONFIG_THUMB2_KERNEL */ + addr = p->addr; + brkp = KPROBE_ARM_BREAKPOINT_INSTRUCTION; -void __kprobes arch_arm_kprobe(struct kprobe *p) -{ - kprobe_opcode_t insn = p->opcode; - kprobe_opcode_t brkp = KPROBE_ARM_BREAKPOINT_INSTRUCTION; - if (insn >= 0xe0000000) - brkp |= 0xe0000000; /* Unconditional instruction */ - else - brkp |= insn & 0xf0000000; /* Copy condition from insn */ - *p->addr = brkp; - flush_insns(p->addr, sizeof(p->addr[0])); -} + if (insn >= 0xe0000000) + brkp |= 0xe0000000; /* Unconditional instruction */ + else + brkp |= insn & 0xf0000000; /* Copy condition from insn */ + } -#endif /* !CONFIG_THUMB2_KERNEL */ + patch_text(addr, brkp); +} /* * The actual disarming is done here on each CPU and synchronized using @@ -166,31 +143,16 @@ void __kprobes arch_arm_kprobe(struct kprobe *p) int __kprobes __arch_disarm_kprobe(void *p) { struct kprobe *kp = p; -#ifdef CONFIG_THUMB2_KERNEL - u16 *addr = (u16 *)((uintptr_t)kp->addr & ~1); - kprobe_opcode_t insn = kp->opcode; - unsigned int len; + void *addr = (void *)((uintptr_t)kp->addr & ~1); - if (is_wide_instruction(insn)) { - ((u16 *)addr)[0] = insn>>16; - ((u16 *)addr)[1] = insn; - len = 2*sizeof(u16); - } else { - ((u16 *)addr)[0] = insn; - len = sizeof(u16); - } - flush_insns(addr, len); + __patch_text(addr, kp->opcode); -#else /* !CONFIG_THUMB2_KERNEL */ - *kp->addr = kp->opcode; - flush_insns(kp->addr, sizeof(kp->addr[0])); -#endif return 0; } void __kprobes arch_disarm_kprobe(struct kprobe *p) { - stop_machine(__arch_disarm_kprobe, p, &cpu_online_map); + stop_machine(__arch_disarm_kprobe, p, cpu_online_mask); } void __kprobes arch_remove_kprobe(struct kprobe *p) diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index 764bd456d84f..dfcdb9f7c126 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c @@ -7,12 +7,13 @@ #include <linux/delay.h> #include <linux/reboot.h> #include <linux/io.h> +#include <linux/irq.h> #include <asm/pgtable.h> #include <asm/pgalloc.h> #include <asm/mmu_context.h> #include <asm/cacheflush.h> #include <asm/mach-types.h> -#include <asm/system.h> +#include <asm/system_misc.h> extern const unsigned char relocate_new_kernel[]; extern const unsigned int relocate_new_kernel_size; @@ -53,6 +54,29 @@ void machine_crash_nonpanic_core(void *unused) cpu_relax(); } +static void machine_kexec_mask_interrupts(void) +{ + unsigned int i; + struct irq_desc *desc; + + for_each_irq_desc(i, desc) { + struct irq_chip *chip; + + chip = irq_desc_get_chip(desc); + if (!chip) + continue; + + if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data)) + chip->irq_eoi(&desc->irq_data); + + if (chip->irq_mask) + chip->irq_mask(&desc->irq_data); + + if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data)) + chip->irq_disable(&desc->irq_data); + } +} + void machine_crash_shutdown(struct pt_regs *regs) { unsigned long msecs; @@ -70,6 +94,7 @@ void machine_crash_shutdown(struct pt_regs *regs) printk(KERN_WARNING "Non-crashing CPUs did not react to IPI\n"); crash_save_cpu(regs, smp_processor_id()); + machine_kexec_mask_interrupts(); printk(KERN_INFO "Loading crashdump kernel...\n"); } diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c new file mode 100644 index 000000000000..07314af47733 --- /dev/null +++ b/arch/arm/kernel/patch.c @@ -0,0 +1,75 @@ +#include <linux/kernel.h> +#include <linux/kprobes.h> +#include <linux/stop_machine.h> + +#include <asm/cacheflush.h> +#include <asm/smp_plat.h> +#include <asm/opcodes.h> + +#include "patch.h" + +struct patch { + void *addr; + unsigned int insn; +}; + +void __kprobes __patch_text(void *addr, unsigned int insn) +{ + bool thumb2 = IS_ENABLED(CONFIG_THUMB2_KERNEL); + int size; + + if (thumb2 && __opcode_is_thumb16(insn)) { + *(u16 *)addr = __opcode_to_mem_thumb16(insn); + size = sizeof(u16); + } else if (thumb2 && ((uintptr_t)addr & 2)) { + u16 first = __opcode_thumb32_first(insn); + u16 second = __opcode_thumb32_second(insn); + u16 *addrh = addr; + + addrh[0] = __opcode_to_mem_thumb16(first); + addrh[1] = __opcode_to_mem_thumb16(second); + + size = sizeof(u32); + } else { + if (thumb2) + insn = __opcode_to_mem_thumb32(insn); + else + insn = __opcode_to_mem_arm(insn); + + *(u32 *)addr = insn; + size = sizeof(u32); + } + + flush_icache_range((uintptr_t)(addr), + (uintptr_t)(addr) + size); +} + +static int __kprobes patch_text_stop_machine(void *data) +{ + struct patch *patch = data; + + __patch_text(patch->addr, patch->insn); + + return 0; +} + +void __kprobes patch_text(void *addr, unsigned int insn) +{ + struct patch patch = { + .addr = addr, + .insn = insn, + }; + + if (cache_ops_need_broadcast()) { + stop_machine(patch_text_stop_machine, &patch, cpu_online_mask); + } else { + bool straddles_word = IS_ENABLED(CONFIG_THUMB2_KERNEL) + && __opcode_is_thumb32(insn) + && ((uintptr_t)addr & 2); + + if (straddles_word) + stop_machine(patch_text_stop_machine, &patch, NULL); + else + __patch_text(addr, insn); + } +} diff --git a/arch/arm/kernel/patch.h b/arch/arm/kernel/patch.h new file mode 100644 index 000000000000..b4731f2dac38 --- /dev/null +++ b/arch/arm/kernel/patch.h @@ -0,0 +1,7 @@ +#ifndef _ARM_KERNEL_PATCH_H +#define _ARM_KERNEL_PATCH_H + +void patch_text(void *addr, unsigned int insn); +void __patch_text(void *addr, unsigned int insn); + +#endif diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 8a89d3b7626b..186c8cb982c5 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -738,6 +738,9 @@ init_hw_perf_events(void) case 0xC0F0: /* Cortex-A15 */ cpu_pmu = armv7_a15_pmu_init(); break; + case 0xC070: /* Cortex-A7 */ + cpu_pmu = armv7_a7_pmu_init(); + break; } /* Intel CPUs [xscale]. */ } else if (0x69 == implementor) { diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c index 4d7095af2ab3..00755d82e2f2 100644 --- a/arch/arm/kernel/perf_event_v7.c +++ b/arch/arm/kernel/perf_event_v7.c @@ -610,6 +610,130 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] }; /* + * Cortex-A7 HW events mapping + */ +static const unsigned armv7_a7_perf_map[PERF_COUNT_HW_MAX] = { + [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES, + [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED, + [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS, + [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE, + [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, + [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES, + [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED, + [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED, +}; + +static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] + [PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_COUNT_HW_CACHE_RESULT_MAX] = { + [C(L1D)] = { + /* + * The performance counters don't differentiate between read + * and write accesses/misses so this isn't strictly correct, + * but it's the best we can do. Writes and reads get + * combined. + */ + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS, + [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS, + [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, + [C(L1I)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS, + [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS, + [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, + [C(LL)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_CACHE_ACCESS, + [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_CACHE_ACCESS, + [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, + [C(DTLB)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, + [C(ITLB)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, + [C(BPU)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED, + [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED, + [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, + [C(NODE)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, +}; + +/* * Perf Events' indices */ #define ARMV7_IDX_CYCLE_COUNTER 0 @@ -1104,6 +1228,12 @@ static int armv7_a15_map_event(struct perf_event *event) &armv7_a15_perf_cache_map, 0xFF); } +static int armv7_a7_map_event(struct perf_event *event) +{ + return map_cpu_event(event, &armv7_a7_perf_map, + &armv7_a7_perf_cache_map, 0xFF); +} + static struct arm_pmu armv7pmu = { .handle_irq = armv7pmu_handle_irq, .enable = armv7pmu_enable_event, @@ -1164,6 +1294,16 @@ static struct arm_pmu *__init armv7_a15_pmu_init(void) armv7pmu.set_event_filter = armv7pmu_set_event_filter; return &armv7pmu; } + +static struct arm_pmu *__init armv7_a7_pmu_init(void) +{ + armv7pmu.id = ARM_PERF_PMU_ID_CA7; + armv7pmu.name = "ARMv7 Cortex-A7"; + armv7pmu.map_event = armv7_a7_map_event; + armv7pmu.num_events = armv7_read_num_pmnc_events(); + armv7pmu.set_event_filter = armv7pmu_set_event_filter; + return &armv7pmu; +} #else static struct arm_pmu *__init armv7_a8_pmu_init(void) { @@ -1184,4 +1324,9 @@ static struct arm_pmu *__init armv7_a15_pmu_init(void) { return NULL; } + +static struct arm_pmu *__init armv7_a7_pmu_init(void) +{ + return NULL; +} #endif /* CONFIG_CPU_V7 */ diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index c2ae3cd331fe..2b7b017a20cd 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -35,7 +35,6 @@ #include <asm/cacheflush.h> #include <asm/leds.h> #include <asm/processor.h> -#include <asm/system.h> #include <asm/thread_notify.h> #include <asm/stacktrace.h> #include <asm/mach/time.h> @@ -61,8 +60,6 @@ extern void setup_mm_for_reboot(void); static volatile int hlt_counter; -#include <mach/system.h> - void disable_hlt(void) { hlt_counter++; @@ -181,13 +178,17 @@ void cpu_idle_wait(void) EXPORT_SYMBOL_GPL(cpu_idle_wait); /* - * This is our default idle handler. We need to disable - * interrupts here to ensure we don't miss a wakeup call. + * This is our default idle handler. */ + +void (*arm_pm_idle)(void); + static void default_idle(void) { - if (!need_resched()) - arch_idle(); + if (arm_pm_idle) + arm_pm_idle(); + else + cpu_do_idle(); local_irq_enable(); } @@ -215,6 +216,10 @@ void cpu_idle(void) cpu_die(); #endif + /* + * We need to disable interrupts here + * to ensure we don't miss a wakeup call. + */ local_irq_disable(); #ifdef CONFIG_PL310_ERRATA_769419 wmb(); @@ -222,19 +227,18 @@ void cpu_idle(void) if (hlt_counter) { local_irq_enable(); cpu_relax(); - } else { + } else if (!need_resched()) { stop_critical_timings(); if (cpuidle_idle_call()) pm_idle(); start_critical_timings(); /* - * This will eventually be removed - pm_idle - * functions should always return with IRQs - * enabled. + * pm_idle functions must always + * return with IRQs enabled. */ WARN_ON(irqs_disabled()); + } else local_irq_enable(); - } } leds_event(led_idle_end); rcu_idle_exit(); @@ -524,22 +528,39 @@ unsigned long arch_randomize_brk(struct mm_struct *mm) #ifdef CONFIG_MMU /* * The vectors page is always readable from user space for the - * atomic helpers and the signal restart code. Let's declare a mapping - * for it so it is visible through ptrace and /proc/<pid>/mem. + * atomic helpers and the signal restart code. Insert it into the + * gate_vma so that it is visible through ptrace and /proc/<pid>/mem. */ +static struct vm_area_struct gate_vma; + +static int __init gate_vma_init(void) +{ + gate_vma.vm_start = 0xffff0000; + gate_vma.vm_end = 0xffff0000 + PAGE_SIZE; + gate_vma.vm_page_prot = PAGE_READONLY_EXEC; + gate_vma.vm_flags = VM_READ | VM_EXEC | + VM_MAYREAD | VM_MAYEXEC; + return 0; +} +arch_initcall(gate_vma_init); + +struct vm_area_struct *get_gate_vma(struct mm_struct *mm) +{ + return &gate_vma; +} + +int in_gate_area(struct mm_struct *mm, unsigned long addr) +{ + return (addr >= gate_vma.vm_start) && (addr < gate_vma.vm_end); +} -int vectors_user_mapping(void) +int in_gate_area_no_mm(unsigned long addr) { - struct mm_struct *mm = current->mm; - return install_special_mapping(mm, 0xffff0000, PAGE_SIZE, - VM_READ | VM_EXEC | - VM_MAYREAD | VM_MAYEXEC | - VM_ALWAYSDUMP | VM_RESERVED, - NULL); + return in_gate_area(NULL, addr); } const char *arch_vma_name(struct vm_area_struct *vma) { - return (vma->vm_start == 0xffff0000) ? "[vectors]" : NULL; + return (vma == &gate_vma) ? "[vectors]" : NULL; } #endif diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index ede6443c34d9..80abafb9bf33 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -26,7 +26,6 @@ #include <linux/audit.h> #include <asm/pgtable.h> -#include <asm/system.h> #include <asm/traps.h> #define REG_PC 15 @@ -257,7 +256,7 @@ static int ptrace_read_user(struct task_struct *tsk, unsigned long off, { unsigned long tmp; - if (off & 3 || off >= sizeof(struct user)) + if (off & 3) return -EIO; tmp = 0; @@ -269,6 +268,8 @@ static int ptrace_read_user(struct task_struct *tsk, unsigned long off, tmp = tsk->mm->end_code; else if (off < sizeof(struct pt_regs)) tmp = get_user_reg(tsk, off >> 2); + else if (off >= sizeof(struct user)) + return -EIO; return put_user(tmp, ret); } diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c index 5416c7c12528..27d186abbc06 100644 --- a/arch/arm/kernel/sched_clock.c +++ b/arch/arm/kernel/sched_clock.c @@ -10,6 +10,7 @@ #include <linux/jiffies.h> #include <linux/kernel.h> #include <linux/sched.h> +#include <linux/syscore_ops.h> #include <linux/timer.h> #include <asm/sched_clock.h> @@ -164,3 +165,20 @@ void __init sched_clock_postinit(void) sched_clock_poll(sched_clock_timer.data); } + +static int sched_clock_suspend(void) +{ + sched_clock_poll(sched_clock_timer.data); + return 0; +} + +static struct syscore_ops sched_clock_ops = { + .suspend = sched_clock_suspend, +}; + +static int __init sched_clock_syscore_init(void) +{ + register_syscore_ops(&sched_clock_ops); + return 0; +} +device_initcall(sched_clock_syscore_init); diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index a255c39612ca..ebfac782593f 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -33,6 +33,7 @@ #include <linux/sort.h> #include <asm/unified.h> +#include <asm/cp15.h> #include <asm/cpu.h> #include <asm/cputype.h> #include <asm/elf.h> @@ -44,12 +45,13 @@ #include <asm/cacheflush.h> #include <asm/cachetype.h> #include <asm/tlbflush.h> -#include <asm/system.h> #include <asm/prom.h> #include <asm/mach/arch.h> #include <asm/mach/irq.h> #include <asm/mach/time.h> +#include <asm/system_info.h> +#include <asm/system_misc.h> #include <asm/traps.h> #include <asm/unwind.h> #include <asm/memblock.h> @@ -521,7 +523,21 @@ int __init arm_add_memory(phys_addr_t start, unsigned long size) */ size -= start & ~PAGE_MASK; bank->start = PAGE_ALIGN(start); - bank->size = size & PAGE_MASK; + +#ifndef CONFIG_LPAE + if (bank->start + size < bank->start) { + printk(KERN_CRIT "Truncating memory at 0x%08llx to fit in " + "32-bit physical address space\n", (long long)start); + /* + * To ensure bank->start + bank->size is representable in + * 32 bits, we use ULONG_MAX as the upper limit rather than 4GB. + * This means we lose a page after masking. + */ + size = ULONG_MAX - bank->start; + } +#endif + + bank->size = size & PAGE_MASK; /* * Check whether this memory region has non-zero size or @@ -974,7 +990,6 @@ void __init setup_arch(char **cmdline_p) conswitchp = &dummy_con; #endif #endif - early_trap_init(); if (mdesc->init_early) mdesc->init_early(); diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 9e617bd4a146..7cb532fc8aa4 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -66,12 +66,13 @@ const unsigned long syscall_restart_code[2] = { */ asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask) { - mask &= _BLOCKABLE; - spin_lock_irq(¤t->sighand->siglock); + sigset_t blocked; + current->saved_sigmask = current->blocked; - siginitset(¤t->blocked, mask); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + + mask &= _BLOCKABLE; + siginitset(&blocked, mask); + set_current_blocked(&blocked); current->state = TASK_INTERRUPTIBLE; schedule(); @@ -280,10 +281,7 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf) err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); if (err == 0) { sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + set_current_blocked(&set); } __get_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err); @@ -636,13 +634,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, /* * Block the signal if we were successful. */ - spin_lock_irq(&tsk->sighand->siglock); - sigorsets(&tsk->blocked, &tsk->blocked, - &ka->sa.sa_mask); - if (!(ka->sa.sa_flags & SA_NODEFER)) - sigaddset(&tsk->blocked, sig); - recalc_sigpending(); - spin_unlock_irq(&tsk->sighand->siglock); + block_sigmask(ka, sig); return 0; } diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S index 1f268bda4552..987dcf33415c 100644 --- a/arch/arm/kernel/sleep.S +++ b/arch/arm/kernel/sleep.S @@ -4,7 +4,6 @@ #include <asm/assembler.h> #include <asm/glue-cache.h> #include <asm/glue-proc.h> -#include <asm/system.h> .text /* diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index d616ed51e7a7..addbbe8028c2 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -58,6 +58,8 @@ enum ipi_msg_type { IPI_CPU_STOP, }; +static DECLARE_COMPLETION(cpu_running); + int __cpuinit __cpu_up(unsigned int cpu) { struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu); @@ -98,20 +100,12 @@ int __cpuinit __cpu_up(unsigned int cpu) */ ret = boot_secondary(cpu, idle); if (ret == 0) { - unsigned long timeout; - /* * CPU was successfully started, wait for it * to come online or time out. */ - timeout = jiffies + HZ; - while (time_before(jiffies, timeout)) { - if (cpu_online(cpu)) - break; - - udelay(10); - barrier(); - } + wait_for_completion_timeout(&cpu_running, + msecs_to_jiffies(1000)); if (!cpu_online(cpu)) { pr_crit("CPU%u: failed to come online\n", cpu); @@ -246,6 +240,8 @@ static void __cpuinit smp_store_cpu_info(unsigned int cpuid) store_cpu_topology(cpuid); } +static void percpu_timer_setup(void); + /* * This is the secondary CPU boot entry. We're using this CPUs * idle thread stack, but a set of temporary page tables. @@ -286,9 +282,10 @@ asmlinkage void __cpuinit secondary_start_kernel(void) /* * OK, now it's safe to let the boot CPU continue. Wait for * the CPU migration code to notice that the CPU is online - * before we continue. + * before we continue - which happens after __cpu_up returns. */ set_cpu_online(cpu, true); + complete(&cpu_running); /* * Setup the percpu timer for this CPU. @@ -352,7 +349,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) * re-initialize the map in platform_smp_prepare_cpus() if * present != possible (e.g. physical hotplug). */ - init_cpu_present(&cpu_possible_map); + init_cpu_present(cpu_possible_mask); /* * Initialise the SCU if there are more than one CPU @@ -452,7 +449,20 @@ static void __cpuinit broadcast_timer_setup(struct clock_event_device *evt) clockevents_register_device(evt); } -void __cpuinit percpu_timer_setup(void) +static struct local_timer_ops *lt_ops; + +#ifdef CONFIG_LOCAL_TIMERS +int local_timer_register(struct local_timer_ops *ops) +{ + if (lt_ops) + return -EBUSY; + + lt_ops = ops; + return 0; +} +#endif + +static void __cpuinit percpu_timer_setup(void) { unsigned int cpu = smp_processor_id(); struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu); @@ -460,7 +470,7 @@ void __cpuinit percpu_timer_setup(void) evt->cpumask = cpumask_of(cpu); evt->broadcast = smp_timer_broadcast; - if (local_timer_setup(evt)) + if (!lt_ops || lt_ops->setup(evt)) broadcast_timer_setup(evt); } @@ -475,7 +485,8 @@ static void percpu_timer_stop(void) unsigned int cpu = smp_processor_id(); struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu); - local_timer_stop(evt); + if (lt_ops) + lt_ops->stop(evt); } #endif @@ -570,8 +581,9 @@ void smp_send_stop(void) unsigned long timeout; if (num_online_cpus() > 1) { - cpumask_t mask = cpu_online_map; - cpu_clear(smp_processor_id(), mask); + struct cpumask mask; + cpumask_copy(&mask, cpu_online_mask); + cpumask_clear_cpu(smp_processor_id(), &mask); smp_cross_call(&mask, IPI_CPU_STOP); } diff --git a/arch/arm/kernel/smp_tlb.c b/arch/arm/kernel/smp_tlb.c index 7dcb35285be7..02c5d2ce23bf 100644 --- a/arch/arm/kernel/smp_tlb.c +++ b/arch/arm/kernel/smp_tlb.c @@ -13,18 +13,6 @@ #include <asm/smp_plat.h> #include <asm/tlbflush.h> -static void on_each_cpu_mask(void (*func)(void *), void *info, int wait, - const struct cpumask *mask) -{ - preempt_disable(); - - smp_call_function_many(mask, func, info, wait); - if (cpumask_test_cpu(smp_processor_id(), mask)) - func(info); - - preempt_enable(); -} - /**********************************************************************/ /* @@ -87,7 +75,7 @@ void flush_tlb_all(void) void flush_tlb_mm(struct mm_struct *mm) { if (tlb_ops_need_broadcast()) - on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, mm_cpumask(mm)); + on_each_cpu_mask(mm_cpumask(mm), ipi_flush_tlb_mm, mm, 1); else local_flush_tlb_mm(mm); } @@ -98,7 +86,8 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) struct tlb_args ta; ta.ta_vma = vma; ta.ta_start = uaddr; - on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, mm_cpumask(vma->vm_mm)); + on_each_cpu_mask(mm_cpumask(vma->vm_mm), ipi_flush_tlb_page, + &ta, 1); } else local_flush_tlb_page(vma, uaddr); } @@ -121,7 +110,8 @@ void flush_tlb_range(struct vm_area_struct *vma, ta.ta_vma = vma; ta.ta_start = start; ta.ta_end = end; - on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, mm_cpumask(vma->vm_mm)); + on_each_cpu_mask(mm_cpumask(vma->vm_mm), ipi_flush_tlb_range, + &ta, 1); } else local_flush_tlb_range(vma, start, end); } diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index 7a79b24597b2..5b150afb995b 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -18,20 +18,23 @@ #include <linux/smp.h> #include <linux/jiffies.h> #include <linux/clockchips.h> -#include <linux/irq.h> +#include <linux/interrupt.h> #include <linux/io.h> +#include <linux/of_irq.h> +#include <linux/of_address.h> #include <asm/smp_twd.h> #include <asm/localtimer.h> #include <asm/hardware/gic.h> /* set up by the platform code */ -void __iomem *twd_base; +static void __iomem *twd_base; static struct clk *twd_clk; static unsigned long twd_timer_rate; static struct clock_event_device __percpu **twd_evt; +static int twd_ppi; static void twd_set_mode(enum clock_event_mode mode, struct clock_event_device *clk) @@ -77,7 +80,7 @@ static int twd_set_next_event(unsigned long evt, * If a local timer interrupt has occurred, acknowledge and return 1. * Otherwise, return 0. */ -int twd_timer_ack(void) +static int twd_timer_ack(void) { if (__raw_readl(twd_base + TWD_TIMER_INTSTAT)) { __raw_writel(1, twd_base + TWD_TIMER_INTSTAT); @@ -87,7 +90,7 @@ int twd_timer_ack(void) return 0; } -void twd_timer_stop(struct clock_event_device *clk) +static void twd_timer_stop(struct clock_event_device *clk) { twd_set_mode(CLOCK_EVT_MODE_UNUSED, clk); disable_percpu_irq(clk->irq); @@ -115,10 +118,14 @@ static int twd_cpufreq_transition(struct notifier_block *nb, * The twd clock events must be reprogrammed to account for the new * frequency. The timer is local to a cpu, so cross-call to the * changing cpu. + * + * Only wait for it to finish, if the cpu is active to avoid + * deadlock when cpu1 is spinning on while(!cpu_active(cpu1)) during + * booting of that cpu. */ if (state == CPUFREQ_POSTCHANGE || state == CPUFREQ_RESUMECHANGE) smp_call_function_single(freqs->cpu, twd_update_frequency, - NULL, 1); + NULL, cpu_active(freqs->cpu)); return NOTIFY_OK; } @@ -222,28 +229,10 @@ static struct clk *twd_get_clock(void) /* * Setup the local clock events for a CPU. */ -void __cpuinit twd_timer_setup(struct clock_event_device *clk) +static int __cpuinit twd_timer_setup(struct clock_event_device *clk) { struct clock_event_device **this_cpu_clk; - if (!twd_evt) { - int err; - - twd_evt = alloc_percpu(struct clock_event_device *); - if (!twd_evt) { - pr_err("twd: can't allocate memory\n"); - return; - } - - err = request_percpu_irq(clk->irq, twd_handler, - "twd", twd_evt); - if (err) { - pr_err("twd: can't register interrupt %d (%d)\n", - clk->irq, err); - return; - } - } - if (!twd_clk) twd_clk = twd_get_clock(); @@ -260,6 +249,7 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk) clk->rating = 350; clk->set_mode = twd_set_mode; clk->set_next_event = twd_set_next_event; + clk->irq = twd_ppi; this_cpu_clk = __this_cpu_ptr(twd_evt); *this_cpu_clk = clk; @@ -267,4 +257,95 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk) clockevents_config_and_register(clk, twd_timer_rate, 0xf, 0xffffffff); enable_percpu_irq(clk->irq, 0); + + return 0; +} + +static struct local_timer_ops twd_lt_ops __cpuinitdata = { + .setup = twd_timer_setup, + .stop = twd_timer_stop, +}; + +static int __init twd_local_timer_common_register(void) +{ + int err; + + twd_evt = alloc_percpu(struct clock_event_device *); + if (!twd_evt) { + err = -ENOMEM; + goto out_free; + } + + err = request_percpu_irq(twd_ppi, twd_handler, "twd", twd_evt); + if (err) { + pr_err("twd: can't register interrupt %d (%d)\n", twd_ppi, err); + goto out_free; + } + + err = local_timer_register(&twd_lt_ops); + if (err) + goto out_irq; + + return 0; + +out_irq: + free_percpu_irq(twd_ppi, twd_evt); +out_free: + iounmap(twd_base); + twd_base = NULL; + free_percpu(twd_evt); + + return err; } + +int __init twd_local_timer_register(struct twd_local_timer *tlt) +{ + if (twd_base || twd_evt) + return -EBUSY; + + twd_ppi = tlt->res[1].start; + + twd_base = ioremap(tlt->res[0].start, resource_size(&tlt->res[0])); + if (!twd_base) + return -ENOMEM; + + return twd_local_timer_common_register(); +} + +#ifdef CONFIG_OF +const static struct of_device_id twd_of_match[] __initconst = { + { .compatible = "arm,cortex-a9-twd-timer", }, + { .compatible = "arm,cortex-a5-twd-timer", }, + { .compatible = "arm,arm11mp-twd-timer", }, + { }, +}; + +void __init twd_local_timer_of_register(void) +{ + struct device_node *np; + int err; + + np = of_find_matching_node(NULL, twd_of_match); + if (!np) { + err = -ENODEV; + goto out; + } + + twd_ppi = irq_of_parse_and_map(np, 0); + if (!twd_ppi) { + err = -EINVAL; + goto out; + } + + twd_base = of_iomap(np, 0); + if (!twd_base) { + err = -ENOMEM; + goto out; + } + + err = twd_local_timer_common_register(); + +out: + WARN(err, "twd_local_timer_of_register failed (%d)\n", err); +} +#endif diff --git a/arch/arm/kernel/tcm.c b/arch/arm/kernel/tcm.c index 01ec453bb924..30ae6bb4a310 100644 --- a/arch/arm/kernel/tcm.c +++ b/arch/arm/kernel/tcm.c @@ -16,6 +16,7 @@ #include <asm/cputype.h> #include <asm/mach/map.h> #include <asm/memory.h> +#include <asm/system_info.h> #include "tcm.h" static struct gen_pool *tcm_pool; diff --git a/arch/arm/kernel/thumbee.c b/arch/arm/kernel/thumbee.c index 9cb7aaca159f..aab899764053 100644 --- a/arch/arm/kernel/thumbee.c +++ b/arch/arm/kernel/thumbee.c @@ -20,6 +20,7 @@ #include <linux/kernel.h> #include <linux/init.h> +#include <asm/system_info.h> #include <asm/thread_notify.h> /* diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index 8c57dd3680e9..fe31b22f18fd 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -25,8 +25,6 @@ #include <linux/timer.h> #include <linux/irq.h> -#include <linux/mc146818rtc.h> - #include <asm/leds.h> #include <asm/thread_info.h> #include <asm/sched_clock.h> @@ -149,8 +147,6 @@ void __init time_init(void) { system_timer = machine_desc->timer; system_timer->init(); -#ifdef CONFIG_HAVE_SCHED_CLOCK sched_clock_postinit(); -#endif } diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index f84dfe67724f..778454750a6c 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -29,11 +29,11 @@ #include <linux/atomic.h> #include <asm/cacheflush.h> #include <asm/exception.h> -#include <asm/system.h> #include <asm/unistd.h> #include <asm/traps.h> #include <asm/unwind.h> #include <asm/tls.h> +#include <asm/system_misc.h> #include "signal.h" @@ -227,6 +227,11 @@ void show_stack(struct task_struct *tsk, unsigned long *sp) #else #define S_SMP "" #endif +#ifdef CONFIG_THUMB2_KERNEL +#define S_ISA " THUMB2" +#else +#define S_ISA " ARM" +#endif static int __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs) { @@ -234,8 +239,8 @@ static int __die(const char *str, int err, struct thread_info *thread, struct pt static int die_counter; int ret; - printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n", - str, err, ++die_counter); + printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP + S_ISA "\n", str, err, ++die_counter); /* trap and error numbers are mostly meaningless on ARM */ ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV); @@ -784,18 +789,16 @@ static void __init kuser_get_tls_init(unsigned long vectors) memcpy((void *)vectors + 0xfe0, (void *)vectors + 0xfe8, 4); } -void __init early_trap_init(void) +void __init early_trap_init(void *vectors_base) { -#if defined(CONFIG_CPU_USE_DOMAINS) - unsigned long vectors = CONFIG_VECTORS_BASE; -#else - unsigned long vectors = (unsigned long)vectors_page; -#endif + unsigned long vectors = (unsigned long)vectors_base; extern char __stubs_start[], __stubs_end[]; extern char __vectors_start[], __vectors_end[]; extern char __kuser_helper_start[], __kuser_helper_end[]; int kuser_sz = __kuser_helper_end - __kuser_helper_start; + vectors_page = vectors_base; + /* * Copy the vectors, stubs and kuser helpers (in entry-armv.S) * into the vector page, mapped at 0xffff0000, and ensure these diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 71feb00a1e99..45db05d8d94c 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -20,9 +20,11 @@ config HAVE_AT91_USART5 config AT91_SAM9_ALT_RESET bool + default !ARCH_AT91X40 config AT91_SAM9G45_RESET bool + default !ARCH_AT91X40 menu "Atmel AT91 System-on-Chip" @@ -45,7 +47,6 @@ config ARCH_AT91SAM9260 select HAVE_AT91_USART4 select HAVE_AT91_USART5 select HAVE_NET_MACB - select AT91_SAM9_ALT_RESET config ARCH_AT91SAM9261 bool "AT91SAM9261" @@ -53,7 +54,6 @@ config ARCH_AT91SAM9261 select GENERIC_CLOCKEVENTS select HAVE_FB_ATMEL select HAVE_AT91_DBGU0 - select AT91_SAM9_ALT_RESET config ARCH_AT91SAM9G10 bool "AT91SAM9G10" @@ -61,7 +61,6 @@ config ARCH_AT91SAM9G10 select GENERIC_CLOCKEVENTS select HAVE_AT91_DBGU0 select HAVE_FB_ATMEL - select AT91_SAM9_ALT_RESET config ARCH_AT91SAM9263 bool "AT91SAM9263" @@ -70,7 +69,6 @@ config ARCH_AT91SAM9263 select HAVE_FB_ATMEL select HAVE_NET_MACB select HAVE_AT91_DBGU1 - select AT91_SAM9_ALT_RESET config ARCH_AT91SAM9RL bool "AT91SAM9RL" @@ -79,7 +77,6 @@ config ARCH_AT91SAM9RL select HAVE_AT91_USART3 select HAVE_FB_ATMEL select HAVE_AT91_DBGU0 - select AT91_SAM9_ALT_RESET config ARCH_AT91SAM9G20 bool "AT91SAM9G20" @@ -90,7 +87,6 @@ config ARCH_AT91SAM9G20 select HAVE_AT91_USART4 select HAVE_AT91_USART5 select HAVE_NET_MACB - select AT91_SAM9_ALT_RESET config ARCH_AT91SAM9G45 bool "AT91SAM9G45" @@ -100,16 +96,14 @@ config ARCH_AT91SAM9G45 select HAVE_FB_ATMEL select HAVE_NET_MACB select HAVE_AT91_DBGU1 - select AT91_SAM9G45_RESET -config ARCH_AT91CAP9 - bool "AT91CAP9" +config ARCH_AT91SAM9X5 + bool "AT91SAM9x5 family" select CPU_ARM926T select GENERIC_CLOCKEVENTS select HAVE_FB_ATMEL select HAVE_NET_MACB - select HAVE_AT91_DBGU1 - select AT91_SAM9G45_RESET + select HAVE_AT91_DBGU0 config ARCH_AT91X40 bool "AT91x40" @@ -447,21 +441,6 @@ endif # ---------------------------------------------------------- -if ARCH_AT91CAP9 - -comment "AT91CAP9 Board Type" - -config MACH_AT91CAP9ADK - bool "Atmel AT91CAP9A-DK Evaluation Kit" - select HAVE_AT91_DATAFLASH_CARD - help - Select this if you are using Atmel's AT91CAP9A-DK Evaluation Kit. - <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4138> - -endif - -# ---------------------------------------------------------- - if ARCH_AT91X40 comment "AT91X40 Board Type" @@ -544,7 +523,7 @@ config AT91_EARLY_DBGU0 depends on HAVE_AT91_DBGU0 config AT91_EARLY_DBGU1 - bool "DBGU on 9263, 9g45 and cap9" + bool "DBGU on 9263 and 9g45" depends on HAVE_AT91_DBGU1 config AT91_EARLY_USART0 diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 705e1fbded39..8512e53bed93 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -20,7 +20,7 @@ obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_d obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o -obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o +obj-$(CONFIG_ARCH_AT91SAM9X5) += at91sam9x5.o at91sam926x_time.o sam9_smc.o obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o # AT91RM9200 board-specific support @@ -81,9 +81,6 @@ obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o # AT91SAM board with device-tree obj-$(CONFIG_MACH_AT91SAM_DT) += board-dt.o -# AT91CAP9 board-specific support -obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o - # AT91X40 board-specific support obj-$(CONFIG_MACH_AT91EB01) += board-eb01.o diff --git a/arch/arm/mach-at91/Makefile.boot b/arch/arm/mach-at91/Makefile.boot index 8ddafadfdc7d..0da66ca4a4f8 100644 --- a/arch/arm/mach-at91/Makefile.boot +++ b/arch/arm/mach-at91/Makefile.boot @@ -3,11 +3,7 @@ # PARAMS_PHYS must be within 4MB of ZRELADDR # INITRD_PHYS must be in RAM -ifeq ($(CONFIG_ARCH_AT91CAP9),y) - zreladdr-y += 0x70008000 -params_phys-y := 0x70000100 -initrd_phys-y := 0x70410000 -else ifeq ($(CONFIG_ARCH_AT91SAM9G45),y) +ifeq ($(CONFIG_ARCH_AT91SAM9G45),y) zreladdr-y += 0x70008000 params_phys-y := 0x70000100 initrd_phys-y := 0x70410000 @@ -17,4 +13,10 @@ params_phys-y := 0x20000100 initrd_phys-y := 0x20410000 endif -dtb-$(CONFIG_MACH_AT91SAM_DT) += at91sam9m10g45ek.dtb usb_a9g20.dtb +# Keep dtb files sorted alphabetically for each SoC +# sam9g20 +dtb-$(CONFIG_MACH_AT91SAM_DT) += usb_a9g20.dtb +# sam9g45 +dtb-$(CONFIG_MACH_AT91SAM_DT) += at91sam9m10g45ek.dtb +# sam9x5 +dtb-$(CONFIG_MACH_AT91SAM_DT) += at91sam9g25ek.dtb diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c deleted file mode 100644 index a42edc25a87e..000000000000 --- a/arch/arm/mach-at91/at91cap9.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - * arch/arm/mach-at91/at91cap9.c - * - * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com> - * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com> - * Copyright (C) 2007 Atmel Corporation. - * - * 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. - * - */ - -#include <linux/module.h> - -#include <asm/irq.h> -#include <asm/mach/arch.h> -#include <asm/mach/map.h> - -#include <mach/cpu.h> -#include <mach/at91cap9.h> -#include <mach/at91_pmc.h> - -#include "soc.h" -#include "generic.h" -#include "clock.h" -#include "sam9_smc.h" - -/* -------------------------------------------------------------------- - * Clocks - * -------------------------------------------------------------------- */ - -/* - * The peripheral clocks. - */ -static struct clk pioABCD_clk = { - .name = "pioABCD_clk", - .pmc_mask = 1 << AT91CAP9_ID_PIOABCD, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mpb0_clk = { - .name = "mpb0_clk", - .pmc_mask = 1 << AT91CAP9_ID_MPB0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mpb1_clk = { - .name = "mpb1_clk", - .pmc_mask = 1 << AT91CAP9_ID_MPB1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mpb2_clk = { - .name = "mpb2_clk", - .pmc_mask = 1 << AT91CAP9_ID_MPB2, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mpb3_clk = { - .name = "mpb3_clk", - .pmc_mask = 1 << AT91CAP9_ID_MPB3, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mpb4_clk = { - .name = "mpb4_clk", - .pmc_mask = 1 << AT91CAP9_ID_MPB4, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart0_clk = { - .name = "usart0_clk", - .pmc_mask = 1 << AT91CAP9_ID_US0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart1_clk = { - .name = "usart1_clk", - .pmc_mask = 1 << AT91CAP9_ID_US1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart2_clk = { - .name = "usart2_clk", - .pmc_mask = 1 << AT91CAP9_ID_US2, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mmc0_clk = { - .name = "mci0_clk", - .pmc_mask = 1 << AT91CAP9_ID_MCI0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mmc1_clk = { - .name = "mci1_clk", - .pmc_mask = 1 << AT91CAP9_ID_MCI1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk can_clk = { - .name = "can_clk", - .pmc_mask = 1 << AT91CAP9_ID_CAN, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk twi_clk = { - .name = "twi_clk", - .pmc_mask = 1 << AT91CAP9_ID_TWI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk spi0_clk = { - .name = "spi0_clk", - .pmc_mask = 1 << AT91CAP9_ID_SPI0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk spi1_clk = { - .name = "spi1_clk", - .pmc_mask = 1 << AT91CAP9_ID_SPI1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc0_clk = { - .name = "ssc0_clk", - .pmc_mask = 1 << AT91CAP9_ID_SSC0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc1_clk = { - .name = "ssc1_clk", - .pmc_mask = 1 << AT91CAP9_ID_SSC1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ac97_clk = { - .name = "ac97_clk", - .pmc_mask = 1 << AT91CAP9_ID_AC97C, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tcb_clk = { - .name = "tcb_clk", - .pmc_mask = 1 << AT91CAP9_ID_TCB, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pwm_clk = { - .name = "pwm_clk", - .pmc_mask = 1 << AT91CAP9_ID_PWMC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk macb_clk = { - .name = "pclk", - .pmc_mask = 1 << AT91CAP9_ID_EMAC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk aestdes_clk = { - .name = "aestdes_clk", - .pmc_mask = 1 << AT91CAP9_ID_AESTDES, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk adc_clk = { - .name = "adc_clk", - .pmc_mask = 1 << AT91CAP9_ID_ADC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk isi_clk = { - .name = "isi_clk", - .pmc_mask = 1 << AT91CAP9_ID_ISI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk lcdc_clk = { - .name = "lcdc_clk", - .pmc_mask = 1 << AT91CAP9_ID_LCDC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk dma_clk = { - .name = "dma_clk", - .pmc_mask = 1 << AT91CAP9_ID_DMA, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk udphs_clk = { - .name = "udphs_clk", - .pmc_mask = 1 << AT91CAP9_ID_UDPHS, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ohci_clk = { - .name = "ohci_clk", - .pmc_mask = 1 << AT91CAP9_ID_UHP, - .type = CLK_TYPE_PERIPHERAL, -}; - -static struct clk *periph_clocks[] __initdata = { - &pioABCD_clk, - &mpb0_clk, - &mpb1_clk, - &mpb2_clk, - &mpb3_clk, - &mpb4_clk, - &usart0_clk, - &usart1_clk, - &usart2_clk, - &mmc0_clk, - &mmc1_clk, - &can_clk, - &twi_clk, - &spi0_clk, - &spi1_clk, - &ssc0_clk, - &ssc1_clk, - &ac97_clk, - &tcb_clk, - &pwm_clk, - &macb_clk, - &aestdes_clk, - &adc_clk, - &isi_clk, - &lcdc_clk, - &dma_clk, - &udphs_clk, - &ohci_clk, - // irq0 .. irq1 -}; - -static struct clk_lookup periph_clocks_lookups[] = { - /* One additional fake clock for macb_hclk */ - CLKDEV_CON_ID("hclk", &macb_clk), - CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk), - CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk), - CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk), - CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.1", &mmc1_clk), - CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), - CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), - CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk), - CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), - CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), - /* fake hclk clock */ - CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), - CLKDEV_CON_ID("pioA", &pioABCD_clk), - CLKDEV_CON_ID("pioB", &pioABCD_clk), - CLKDEV_CON_ID("pioC", &pioABCD_clk), - CLKDEV_CON_ID("pioD", &pioABCD_clk), -}; - -static struct clk_lookup usart_clocks_lookups[] = { - CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), -}; - -/* - * The four programmable clocks. - * You must configure pin multiplexing to bring these signals out. - */ -static struct clk pck0 = { - .name = "pck0", - .pmc_mask = AT91_PMC_PCK0, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 0, -}; -static struct clk pck1 = { - .name = "pck1", - .pmc_mask = AT91_PMC_PCK1, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 1, -}; -static struct clk pck2 = { - .name = "pck2", - .pmc_mask = AT91_PMC_PCK2, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 2, -}; -static struct clk pck3 = { - .name = "pck3", - .pmc_mask = AT91_PMC_PCK3, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 3, -}; - -static void __init at91cap9_register_clocks(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) - clk_register(periph_clocks[i]); - - clkdev_add_table(periph_clocks_lookups, - ARRAY_SIZE(periph_clocks_lookups)); - clkdev_add_table(usart_clocks_lookups, - ARRAY_SIZE(usart_clocks_lookups)); - - clk_register(&pck0); - clk_register(&pck1); - clk_register(&pck2); - clk_register(&pck3); -} - -static struct clk_lookup console_clock_lookup; - -void __init at91cap9_set_console_clock(int id) -{ - if (id >= ARRAY_SIZE(usart_clocks_lookups)) - return; - - console_clock_lookup.con_id = "usart"; - console_clock_lookup.clk = usart_clocks_lookups[id].clk; - clkdev_add(&console_clock_lookup); -} - -/* -------------------------------------------------------------------- - * GPIO - * -------------------------------------------------------------------- */ - -static struct at91_gpio_bank at91cap9_gpio[] __initdata = { - { - .id = AT91CAP9_ID_PIOABCD, - .regbase = AT91CAP9_BASE_PIOA, - }, { - .id = AT91CAP9_ID_PIOABCD, - .regbase = AT91CAP9_BASE_PIOB, - }, { - .id = AT91CAP9_ID_PIOABCD, - .regbase = AT91CAP9_BASE_PIOC, - }, { - .id = AT91CAP9_ID_PIOABCD, - .regbase = AT91CAP9_BASE_PIOD, - } -}; - -/* -------------------------------------------------------------------- - * AT91CAP9 processor initialization - * -------------------------------------------------------------------- */ - -static void __init at91cap9_map_io(void) -{ - at91_init_sram(0, AT91CAP9_SRAM_BASE, AT91CAP9_SRAM_SIZE); -} - -static void __init at91cap9_ioremap_registers(void) -{ - at91_ioremap_shdwc(AT91CAP9_BASE_SHDWC); - at91_ioremap_rstc(AT91CAP9_BASE_RSTC); - at91sam926x_ioremap_pit(AT91CAP9_BASE_PIT); - at91sam9_ioremap_smc(0, AT91CAP9_BASE_SMC); -} - -static void __init at91cap9_initialize(void) -{ - arm_pm_restart = at91sam9g45_restart; - at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1); - - /* Register GPIO subsystem */ - at91_gpio_init(at91cap9_gpio, 4); - - /* Remember the silicon revision */ - if (cpu_is_at91cap9_revB()) - system_rev = 0xB; - else if (cpu_is_at91cap9_revC()) - system_rev = 0xC; -} - -/* -------------------------------------------------------------------- - * Interrupt initialization - * -------------------------------------------------------------------- */ - -/* - * The default interrupt priority levels (0 = lowest, 7 = highest). - */ -static unsigned int at91cap9_default_irq_priority[NR_AIC_IRQS] __initdata = { - 7, /* Advanced Interrupt Controller (FIQ) */ - 7, /* System Peripherals */ - 1, /* Parallel IO Controller A, B, C and D */ - 0, /* MP Block Peripheral 0 */ - 0, /* MP Block Peripheral 1 */ - 0, /* MP Block Peripheral 2 */ - 0, /* MP Block Peripheral 3 */ - 0, /* MP Block Peripheral 4 */ - 5, /* USART 0 */ - 5, /* USART 1 */ - 5, /* USART 2 */ - 0, /* Multimedia Card Interface 0 */ - 0, /* Multimedia Card Interface 1 */ - 3, /* CAN */ - 6, /* Two-Wire Interface */ - 5, /* Serial Peripheral Interface 0 */ - 5, /* Serial Peripheral Interface 1 */ - 4, /* Serial Synchronous Controller 0 */ - 4, /* Serial Synchronous Controller 1 */ - 5, /* AC97 Controller */ - 0, /* Timer Counter 0, 1 and 2 */ - 0, /* Pulse Width Modulation Controller */ - 3, /* Ethernet */ - 0, /* Advanced Encryption Standard, Triple DES*/ - 0, /* Analog-to-Digital Converter */ - 0, /* Image Sensor Interface */ - 3, /* LCD Controller */ - 0, /* DMA Controller */ - 2, /* USB Device Port */ - 2, /* USB Host port */ - 0, /* Advanced Interrupt Controller (IRQ0) */ - 0, /* Advanced Interrupt Controller (IRQ1) */ -}; - -struct at91_init_soc __initdata at91cap9_soc = { - .map_io = at91cap9_map_io, - .default_irq_priority = at91cap9_default_irq_priority, - .ioremap_registers = at91cap9_ioremap_registers, - .register_clocks = at91cap9_register_clocks, - .init = at91cap9_initialize, -}; diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c deleted file mode 100644 index d298fb7cb210..000000000000 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ /dev/null @@ -1,1273 +0,0 @@ -/* - * arch/arm/mach-at91/at91cap9_devices.c - * - * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com> - * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com> - * Copyright (C) 2007 Atmel Corporation. - * - * 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. - * - */ -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <linux/dma-mapping.h> -#include <linux/gpio.h> -#include <linux/platform_device.h> -#include <linux/i2c-gpio.h> - -#include <video/atmel_lcdc.h> - -#include <mach/board.h> -#include <mach/cpu.h> -#include <mach/at91cap9.h> -#include <mach/at91cap9_matrix.h> -#include <mach/at91sam9_smc.h> - -#include "generic.h" - - -/* -------------------------------------------------------------------- - * USB Host - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) -static u64 ohci_dmamask = DMA_BIT_MASK(32); -static struct at91_usbh_data usbh_data; - -static struct resource usbh_resources[] = { - [0] = { - .start = AT91CAP9_UHP_BASE, - .end = AT91CAP9_UHP_BASE + SZ_1M - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_UHP, - .end = AT91CAP9_ID_UHP, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91_usbh_device = { - .name = "at91_ohci", - .id = -1, - .dev = { - .dma_mask = &ohci_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &usbh_data, - }, - .resource = usbh_resources, - .num_resources = ARRAY_SIZE(usbh_resources), -}; - -void __init at91_add_device_usbh(struct at91_usbh_data *data) -{ - int i; - - if (!data) - return; - - if (cpu_is_at91cap9_revB()) - irq_set_irq_type(AT91CAP9_ID_UHP, IRQ_TYPE_LEVEL_HIGH); - - /* Enable VBus control for UHP ports */ - for (i = 0; i < data->ports; i++) { - if (gpio_is_valid(data->vbus_pin[i])) - at91_set_gpio_output(data->vbus_pin[i], 0); - } - - /* Enable overcurrent notification */ - for (i = 0; i < data->ports; i++) { - if (data->overcurrent_pin[i]) - at91_set_gpio_input(data->overcurrent_pin[i], 1); - } - - usbh_data = *data; - platform_device_register(&at91_usbh_device); -} -#else -void __init at91_add_device_usbh(struct at91_usbh_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * USB HS Device (Gadget) - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_USB_ATMEL_USBA) || defined(CONFIG_USB_ATMEL_USBA_MODULE) - -static struct resource usba_udc_resources[] = { - [0] = { - .start = AT91CAP9_UDPHS_FIFO, - .end = AT91CAP9_UDPHS_FIFO + SZ_512K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_BASE_UDPHS, - .end = AT91CAP9_BASE_UDPHS + SZ_1K - 1, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = AT91CAP9_ID_UDPHS, - .end = AT91CAP9_ID_UDPHS, - .flags = IORESOURCE_IRQ, - }, -}; - -#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \ - [idx] = { \ - .name = nam, \ - .index = idx, \ - .fifo_size = maxpkt, \ - .nr_banks = maxbk, \ - .can_dma = dma, \ - .can_isoc = isoc, \ - } - -static struct usba_ep_data usba_udc_ep[] = { - EP("ep0", 0, 64, 1, 0, 0), - EP("ep1", 1, 1024, 3, 1, 1), - EP("ep2", 2, 1024, 3, 1, 1), - EP("ep3", 3, 1024, 2, 1, 1), - EP("ep4", 4, 1024, 2, 1, 1), - EP("ep5", 5, 1024, 2, 1, 0), - EP("ep6", 6, 1024, 2, 1, 0), - EP("ep7", 7, 1024, 2, 0, 0), -}; - -#undef EP - -/* - * pdata doesn't have room for any endpoints, so we need to - * append room for the ones we need right after it. - */ -static struct { - struct usba_platform_data pdata; - struct usba_ep_data ep[8]; -} usba_udc_data; - -static struct platform_device at91_usba_udc_device = { - .name = "atmel_usba_udc", - .id = -1, - .dev = { - .platform_data = &usba_udc_data.pdata, - }, - .resource = usba_udc_resources, - .num_resources = ARRAY_SIZE(usba_udc_resources), -}; - -void __init at91_add_device_usba(struct usba_platform_data *data) -{ - if (cpu_is_at91cap9_revB()) { - irq_set_irq_type(AT91CAP9_ID_UDPHS, IRQ_TYPE_LEVEL_HIGH); - at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS | - AT91_MATRIX_UDPHS_BYPASS_LOCK); - } - else - at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS); - - /* - * Invalid pins are 0 on AT91, but the usba driver is shared - * with AVR32, which use negative values instead. Once/if - * gpio_is_valid() is ported to AT91, revisit this code. - */ - usba_udc_data.pdata.vbus_pin = -EINVAL; - usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep); - memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep)); - - if (data && gpio_is_valid(data->vbus_pin)) { - at91_set_gpio_input(data->vbus_pin, 0); - at91_set_deglitch(data->vbus_pin, 1); - usba_udc_data.pdata.vbus_pin = data->vbus_pin; - } - - /* Pullup pin is handled internally by USB device peripheral */ - - platform_device_register(&at91_usba_udc_device); -} -#else -void __init at91_add_device_usba(struct usba_platform_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * Ethernet - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) -static u64 eth_dmamask = DMA_BIT_MASK(32); -static struct macb_platform_data eth_data; - -static struct resource eth_resources[] = { - [0] = { - .start = AT91CAP9_BASE_EMAC, - .end = AT91CAP9_BASE_EMAC + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_EMAC, - .end = AT91CAP9_ID_EMAC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91cap9_eth_device = { - .name = "macb", - .id = -1, - .dev = { - .dma_mask = ð_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = ð_data, - }, - .resource = eth_resources, - .num_resources = ARRAY_SIZE(eth_resources), -}; - -void __init at91_add_device_eth(struct macb_platform_data *data) -{ - if (!data) - return; - - if (gpio_is_valid(data->phy_irq_pin)) { - at91_set_gpio_input(data->phy_irq_pin, 0); - at91_set_deglitch(data->phy_irq_pin, 1); - } - - /* Pins used for MII and RMII */ - at91_set_A_periph(AT91_PIN_PB21, 0); /* ETXCK_EREFCK */ - at91_set_A_periph(AT91_PIN_PB22, 0); /* ERXDV */ - at91_set_A_periph(AT91_PIN_PB25, 0); /* ERX0 */ - at91_set_A_periph(AT91_PIN_PB26, 0); /* ERX1 */ - at91_set_A_periph(AT91_PIN_PB27, 0); /* ERXER */ - at91_set_A_periph(AT91_PIN_PB28, 0); /* ETXEN */ - at91_set_A_periph(AT91_PIN_PB23, 0); /* ETX0 */ - at91_set_A_periph(AT91_PIN_PB24, 0); /* ETX1 */ - at91_set_A_periph(AT91_PIN_PB30, 0); /* EMDIO */ - at91_set_A_periph(AT91_PIN_PB29, 0); /* EMDC */ - - if (!data->is_rmii) { - at91_set_B_periph(AT91_PIN_PC25, 0); /* ECRS */ - at91_set_B_periph(AT91_PIN_PC26, 0); /* ECOL */ - at91_set_B_periph(AT91_PIN_PC22, 0); /* ERX2 */ - at91_set_B_periph(AT91_PIN_PC23, 0); /* ERX3 */ - at91_set_B_periph(AT91_PIN_PC27, 0); /* ERXCK */ - at91_set_B_periph(AT91_PIN_PC20, 0); /* ETX2 */ - at91_set_B_periph(AT91_PIN_PC21, 0); /* ETX3 */ - at91_set_B_periph(AT91_PIN_PC24, 0); /* ETXER */ - } - - eth_data = *data; - platform_device_register(&at91cap9_eth_device); -} -#else -void __init at91_add_device_eth(struct macb_platform_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * MMC / SD - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) -static u64 mmc_dmamask = DMA_BIT_MASK(32); -static struct at91_mmc_data mmc0_data, mmc1_data; - -static struct resource mmc0_resources[] = { - [0] = { - .start = AT91CAP9_BASE_MCI0, - .end = AT91CAP9_BASE_MCI0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_MCI0, - .end = AT91CAP9_ID_MCI0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91cap9_mmc0_device = { - .name = "at91_mci", - .id = 0, - .dev = { - .dma_mask = &mmc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &mmc0_data, - }, - .resource = mmc0_resources, - .num_resources = ARRAY_SIZE(mmc0_resources), -}; - -static struct resource mmc1_resources[] = { - [0] = { - .start = AT91CAP9_BASE_MCI1, - .end = AT91CAP9_BASE_MCI1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_MCI1, - .end = AT91CAP9_ID_MCI1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91cap9_mmc1_device = { - .name = "at91_mci", - .id = 1, - .dev = { - .dma_mask = &mmc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &mmc1_data, - }, - .resource = mmc1_resources, - .num_resources = ARRAY_SIZE(mmc1_resources), -}; - -void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) -{ - if (!data) - return; - - /* input/irq */ - if (gpio_is_valid(data->det_pin)) { - at91_set_gpio_input(data->det_pin, 1); - at91_set_deglitch(data->det_pin, 1); - } - if (gpio_is_valid(data->wp_pin)) - at91_set_gpio_input(data->wp_pin, 1); - if (gpio_is_valid(data->vcc_pin)) - at91_set_gpio_output(data->vcc_pin, 0); - - if (mmc_id == 0) { /* MCI0 */ - /* CLK */ - at91_set_A_periph(AT91_PIN_PA2, 0); - - /* CMD */ - at91_set_A_periph(AT91_PIN_PA1, 1); - - /* DAT0, maybe DAT1..DAT3 */ - at91_set_A_periph(AT91_PIN_PA0, 1); - if (data->wire4) { - at91_set_A_periph(AT91_PIN_PA3, 1); - at91_set_A_periph(AT91_PIN_PA4, 1); - at91_set_A_periph(AT91_PIN_PA5, 1); - } - - mmc0_data = *data; - platform_device_register(&at91cap9_mmc0_device); - } else { /* MCI1 */ - /* CLK */ - at91_set_A_periph(AT91_PIN_PA16, 0); - - /* CMD */ - at91_set_A_periph(AT91_PIN_PA17, 1); - - /* DAT0, maybe DAT1..DAT3 */ - at91_set_A_periph(AT91_PIN_PA18, 1); - if (data->wire4) { - at91_set_A_periph(AT91_PIN_PA19, 1); - at91_set_A_periph(AT91_PIN_PA20, 1); - at91_set_A_periph(AT91_PIN_PA21, 1); - } - - mmc1_data = *data; - platform_device_register(&at91cap9_mmc1_device); - } -} -#else -void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * NAND / SmartMedia - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE) -static struct atmel_nand_data nand_data; - -#define NAND_BASE AT91_CHIPSELECT_3 - -static struct resource nand_resources[] = { - [0] = { - .start = NAND_BASE, - .end = NAND_BASE + SZ_256M - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_BASE_ECC, - .end = AT91CAP9_BASE_ECC + SZ_512 - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device at91cap9_nand_device = { - .name = "atmel_nand", - .id = -1, - .dev = { - .platform_data = &nand_data, - }, - .resource = nand_resources, - .num_resources = ARRAY_SIZE(nand_resources), -}; - -void __init at91_add_device_nand(struct atmel_nand_data *data) -{ - unsigned long csa; - - if (!data) - return; - - csa = at91_sys_read(AT91_MATRIX_EBICSA); - at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA); - - /* enable pin */ - if (gpio_is_valid(data->enable_pin)) - at91_set_gpio_output(data->enable_pin, 1); - - /* ready/busy pin */ - if (gpio_is_valid(data->rdy_pin)) - at91_set_gpio_input(data->rdy_pin, 1); - - /* card detect pin */ - if (gpio_is_valid(data->det_pin)) - at91_set_gpio_input(data->det_pin, 1); - - nand_data = *data; - platform_device_register(&at91cap9_nand_device); -} -#else -void __init at91_add_device_nand(struct atmel_nand_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * TWI (i2c) - * -------------------------------------------------------------------- */ - -/* - * Prefer the GPIO code since the TWI controller isn't robust - * (gets overruns and underruns under load) and can only issue - * repeated STARTs in one scenario (the driver doesn't yet handle them). - */ -#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) - -static struct i2c_gpio_platform_data pdata = { - .sda_pin = AT91_PIN_PB4, - .sda_is_open_drain = 1, - .scl_pin = AT91_PIN_PB5, - .scl_is_open_drain = 1, - .udelay = 2, /* ~100 kHz */ -}; - -static struct platform_device at91cap9_twi_device = { - .name = "i2c-gpio", - .id = -1, - .dev.platform_data = &pdata, -}; - -void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) -{ - at91_set_GPIO_periph(AT91_PIN_PB4, 1); /* TWD (SDA) */ - at91_set_multi_drive(AT91_PIN_PB4, 1); - - at91_set_GPIO_periph(AT91_PIN_PB5, 1); /* TWCK (SCL) */ - at91_set_multi_drive(AT91_PIN_PB5, 1); - - i2c_register_board_info(0, devices, nr_devices); - platform_device_register(&at91cap9_twi_device); -} - -#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) - -static struct resource twi_resources[] = { - [0] = { - .start = AT91CAP9_BASE_TWI, - .end = AT91CAP9_BASE_TWI + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_TWI, - .end = AT91CAP9_ID_TWI, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91cap9_twi_device = { - .name = "at91_i2c", - .id = -1, - .resource = twi_resources, - .num_resources = ARRAY_SIZE(twi_resources), -}; - -void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) -{ - /* pins used for TWI interface */ - at91_set_B_periph(AT91_PIN_PB4, 0); /* TWD */ - at91_set_multi_drive(AT91_PIN_PB4, 1); - - at91_set_B_periph(AT91_PIN_PB5, 0); /* TWCK */ - at91_set_multi_drive(AT91_PIN_PB5, 1); - - i2c_register_board_info(0, devices, nr_devices); - platform_device_register(&at91cap9_twi_device); -} -#else -void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {} -#endif - -/* -------------------------------------------------------------------- - * SPI - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) -static u64 spi_dmamask = DMA_BIT_MASK(32); - -static struct resource spi0_resources[] = { - [0] = { - .start = AT91CAP9_BASE_SPI0, - .end = AT91CAP9_BASE_SPI0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_SPI0, - .end = AT91CAP9_ID_SPI0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91cap9_spi0_device = { - .name = "atmel_spi", - .id = 0, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = spi0_resources, - .num_resources = ARRAY_SIZE(spi0_resources), -}; - -static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PD0, AT91_PIN_PD1 }; - -static struct resource spi1_resources[] = { - [0] = { - .start = AT91CAP9_BASE_SPI1, - .end = AT91CAP9_BASE_SPI1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_SPI1, - .end = AT91CAP9_ID_SPI1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91cap9_spi1_device = { - .name = "atmel_spi", - .id = 1, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = spi1_resources, - .num_resources = ARRAY_SIZE(spi1_resources), -}; - -static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18 }; - -void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) -{ - int i; - unsigned long cs_pin; - short enable_spi0 = 0; - short enable_spi1 = 0; - - /* Choose SPI chip-selects */ - for (i = 0; i < nr_devices; i++) { - if (devices[i].controller_data) - cs_pin = (unsigned long) devices[i].controller_data; - else if (devices[i].bus_num == 0) - cs_pin = spi0_standard_cs[devices[i].chip_select]; - else - cs_pin = spi1_standard_cs[devices[i].chip_select]; - - if (devices[i].bus_num == 0) - enable_spi0 = 1; - else - enable_spi1 = 1; - - /* enable chip-select pin */ - at91_set_gpio_output(cs_pin, 1); - - /* pass chip-select pin to driver */ - devices[i].controller_data = (void *) cs_pin; - } - - spi_register_board_info(devices, nr_devices); - - /* Configure SPI bus(es) */ - if (enable_spi0) { - at91_set_B_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */ - at91_set_B_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ - at91_set_B_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */ - - platform_device_register(&at91cap9_spi0_device); - } - if (enable_spi1) { - at91_set_A_periph(AT91_PIN_PB12, 0); /* SPI1_MISO */ - at91_set_A_periph(AT91_PIN_PB13, 0); /* SPI1_MOSI */ - at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_SPCK */ - - platform_device_register(&at91cap9_spi1_device); - } -} -#else -void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} -#endif - - -/* -------------------------------------------------------------------- - * Timer/Counter block - * -------------------------------------------------------------------- */ - -#ifdef CONFIG_ATMEL_TCLIB - -static struct resource tcb_resources[] = { - [0] = { - .start = AT91CAP9_BASE_TCB0, - .end = AT91CAP9_BASE_TCB0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_TCB, - .end = AT91CAP9_ID_TCB, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91cap9_tcb_device = { - .name = "atmel_tcb", - .id = 0, - .resource = tcb_resources, - .num_resources = ARRAY_SIZE(tcb_resources), -}; - -static void __init at91_add_device_tc(void) -{ - platform_device_register(&at91cap9_tcb_device); -} -#else -static void __init at91_add_device_tc(void) { } -#endif - - -/* -------------------------------------------------------------------- - * RTT - * -------------------------------------------------------------------- */ - -static struct resource rtt_resources[] = { - { - .start = AT91CAP9_BASE_RTT, - .end = AT91CAP9_BASE_RTT + SZ_16 - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device at91cap9_rtt_device = { - .name = "at91_rtt", - .id = 0, - .resource = rtt_resources, - .num_resources = ARRAY_SIZE(rtt_resources), -}; - -static void __init at91_add_device_rtt(void) -{ - platform_device_register(&at91cap9_rtt_device); -} - - -/* -------------------------------------------------------------------- - * Watchdog - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) -static struct resource wdt_resources[] = { - { - .start = AT91CAP9_BASE_WDT, - .end = AT91CAP9_BASE_WDT + SZ_16 - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device at91cap9_wdt_device = { - .name = "at91_wdt", - .id = -1, - .resource = wdt_resources, - .num_resources = ARRAY_SIZE(wdt_resources), -}; - -static void __init at91_add_device_watchdog(void) -{ - platform_device_register(&at91cap9_wdt_device); -} -#else -static void __init at91_add_device_watchdog(void) {} -#endif - - -/* -------------------------------------------------------------------- - * PWM - * --------------------------------------------------------------------*/ - -#if defined(CONFIG_ATMEL_PWM) -static u32 pwm_mask; - -static struct resource pwm_resources[] = { - [0] = { - .start = AT91CAP9_BASE_PWMC, - .end = AT91CAP9_BASE_PWMC + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_PWMC, - .end = AT91CAP9_ID_PWMC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91cap9_pwm0_device = { - .name = "atmel_pwm", - .id = -1, - .dev = { - .platform_data = &pwm_mask, - }, - .resource = pwm_resources, - .num_resources = ARRAY_SIZE(pwm_resources), -}; - -void __init at91_add_device_pwm(u32 mask) -{ - if (mask & (1 << AT91_PWM0)) - at91_set_A_periph(AT91_PIN_PB19, 1); /* enable PWM0 */ - - if (mask & (1 << AT91_PWM1)) - at91_set_B_periph(AT91_PIN_PB8, 1); /* enable PWM1 */ - - if (mask & (1 << AT91_PWM2)) - at91_set_B_periph(AT91_PIN_PC29, 1); /* enable PWM2 */ - - if (mask & (1 << AT91_PWM3)) - at91_set_B_periph(AT91_PIN_PA11, 1); /* enable PWM3 */ - - pwm_mask = mask; - - platform_device_register(&at91cap9_pwm0_device); -} -#else -void __init at91_add_device_pwm(u32 mask) {} -#endif - - - -/* -------------------------------------------------------------------- - * AC97 - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE) -static u64 ac97_dmamask = DMA_BIT_MASK(32); -static struct ac97c_platform_data ac97_data; - -static struct resource ac97_resources[] = { - [0] = { - .start = AT91CAP9_BASE_AC97C, - .end = AT91CAP9_BASE_AC97C + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_AC97C, - .end = AT91CAP9_ID_AC97C, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91cap9_ac97_device = { - .name = "atmel_ac97c", - .id = 1, - .dev = { - .dma_mask = &ac97_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &ac97_data, - }, - .resource = ac97_resources, - .num_resources = ARRAY_SIZE(ac97_resources), -}; - -void __init at91_add_device_ac97(struct ac97c_platform_data *data) -{ - if (!data) - return; - - at91_set_A_periph(AT91_PIN_PA6, 0); /* AC97FS */ - at91_set_A_periph(AT91_PIN_PA7, 0); /* AC97CK */ - at91_set_A_periph(AT91_PIN_PA8, 0); /* AC97TX */ - at91_set_A_periph(AT91_PIN_PA9, 0); /* AC97RX */ - - /* reset */ - if (gpio_is_valid(data->reset_pin)) - at91_set_gpio_output(data->reset_pin, 0); - - ac97_data = *data; - platform_device_register(&at91cap9_ac97_device); -} -#else -void __init at91_add_device_ac97(struct ac97c_platform_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * LCD Controller - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) -static u64 lcdc_dmamask = DMA_BIT_MASK(32); -static struct atmel_lcdfb_info lcdc_data; - -static struct resource lcdc_resources[] = { - [0] = { - .start = AT91CAP9_LCDC_BASE, - .end = AT91CAP9_LCDC_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_LCDC, - .end = AT91CAP9_ID_LCDC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91_lcdc_device = { - .name = "atmel_lcdfb", - .id = 0, - .dev = { - .dma_mask = &lcdc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &lcdc_data, - }, - .resource = lcdc_resources, - .num_resources = ARRAY_SIZE(lcdc_resources), -}; - -void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) -{ - if (!data) - return; - - if (cpu_is_at91cap9_revB()) - irq_set_irq_type(AT91CAP9_ID_LCDC, IRQ_TYPE_LEVEL_HIGH); - - at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDHSYNC */ - at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDDOTCK */ - at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDDEN */ - at91_set_B_periph(AT91_PIN_PB9, 0); /* LCDCC */ - at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDD2 */ - at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDD3 */ - at91_set_A_periph(AT91_PIN_PC8, 0); /* LCDD4 */ - at91_set_A_periph(AT91_PIN_PC9, 0); /* LCDD5 */ - at91_set_A_periph(AT91_PIN_PC10, 0); /* LCDD6 */ - at91_set_A_periph(AT91_PIN_PC11, 0); /* LCDD7 */ - at91_set_A_periph(AT91_PIN_PC14, 0); /* LCDD10 */ - at91_set_A_periph(AT91_PIN_PC15, 0); /* LCDD11 */ - at91_set_A_periph(AT91_PIN_PC16, 0); /* LCDD12 */ - at91_set_A_periph(AT91_PIN_PC17, 0); /* LCDD13 */ - at91_set_A_periph(AT91_PIN_PC18, 0); /* LCDD14 */ - at91_set_A_periph(AT91_PIN_PC19, 0); /* LCDD15 */ - at91_set_A_periph(AT91_PIN_PC22, 0); /* LCDD18 */ - at91_set_A_periph(AT91_PIN_PC23, 0); /* LCDD19 */ - at91_set_A_periph(AT91_PIN_PC24, 0); /* LCDD20 */ - at91_set_A_periph(AT91_PIN_PC25, 0); /* LCDD21 */ - at91_set_A_periph(AT91_PIN_PC26, 0); /* LCDD22 */ - at91_set_A_periph(AT91_PIN_PC27, 0); /* LCDD23 */ - - lcdc_data = *data; - platform_device_register(&at91_lcdc_device); -} -#else -void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} -#endif - - -/* -------------------------------------------------------------------- - * SSC -- Synchronous Serial Controller - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE) -static u64 ssc0_dmamask = DMA_BIT_MASK(32); - -static struct resource ssc0_resources[] = { - [0] = { - .start = AT91CAP9_BASE_SSC0, - .end = AT91CAP9_BASE_SSC0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_SSC0, - .end = AT91CAP9_ID_SSC0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91cap9_ssc0_device = { - .name = "ssc", - .id = 0, - .dev = { - .dma_mask = &ssc0_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = ssc0_resources, - .num_resources = ARRAY_SIZE(ssc0_resources), -}; - -static inline void configure_ssc0_pins(unsigned pins) -{ - if (pins & ATMEL_SSC_TF) - at91_set_A_periph(AT91_PIN_PB0, 1); - if (pins & ATMEL_SSC_TK) - at91_set_A_periph(AT91_PIN_PB1, 1); - if (pins & ATMEL_SSC_TD) - at91_set_A_periph(AT91_PIN_PB2, 1); - if (pins & ATMEL_SSC_RD) - at91_set_A_periph(AT91_PIN_PB3, 1); - if (pins & ATMEL_SSC_RK) - at91_set_A_periph(AT91_PIN_PB4, 1); - if (pins & ATMEL_SSC_RF) - at91_set_A_periph(AT91_PIN_PB5, 1); -} - -static u64 ssc1_dmamask = DMA_BIT_MASK(32); - -static struct resource ssc1_resources[] = { - [0] = { - .start = AT91CAP9_BASE_SSC1, - .end = AT91CAP9_BASE_SSC1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_SSC1, - .end = AT91CAP9_ID_SSC1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91cap9_ssc1_device = { - .name = "ssc", - .id = 1, - .dev = { - .dma_mask = &ssc1_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = ssc1_resources, - .num_resources = ARRAY_SIZE(ssc1_resources), -}; - -static inline void configure_ssc1_pins(unsigned pins) -{ - if (pins & ATMEL_SSC_TF) - at91_set_A_periph(AT91_PIN_PB6, 1); - if (pins & ATMEL_SSC_TK) - at91_set_A_periph(AT91_PIN_PB7, 1); - if (pins & ATMEL_SSC_TD) - at91_set_A_periph(AT91_PIN_PB8, 1); - if (pins & ATMEL_SSC_RD) - at91_set_A_periph(AT91_PIN_PB9, 1); - if (pins & ATMEL_SSC_RK) - at91_set_A_periph(AT91_PIN_PB10, 1); - if (pins & ATMEL_SSC_RF) - at91_set_A_periph(AT91_PIN_PB11, 1); -} - -/* - * SSC controllers are accessed through library code, instead of any - * kind of all-singing/all-dancing driver. For example one could be - * used by a particular I2S audio codec's driver, while another one - * on the same system might be used by a custom data capture driver. - */ -void __init at91_add_device_ssc(unsigned id, unsigned pins) -{ - struct platform_device *pdev; - - /* - * NOTE: caller is responsible for passing information matching - * "pins" to whatever will be using each particular controller. - */ - switch (id) { - case AT91CAP9_ID_SSC0: - pdev = &at91cap9_ssc0_device; - configure_ssc0_pins(pins); - break; - case AT91CAP9_ID_SSC1: - pdev = &at91cap9_ssc1_device; - configure_ssc1_pins(pins); - break; - default: - return; - } - - platform_device_register(pdev); -} - -#else -void __init at91_add_device_ssc(unsigned id, unsigned pins) {} -#endif - - -/* -------------------------------------------------------------------- - * UART - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SERIAL_ATMEL) -static struct resource dbgu_resources[] = { - [0] = { - .start = AT91CAP9_BASE_DBGU, - .end = AT91CAP9_BASE_DBGU + SZ_512 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91_ID_SYS, - .end = AT91_ID_SYS, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data dbgu_data = { - .use_dma_tx = 0, - .use_dma_rx = 0, /* DBGU not capable of receive DMA */ -}; - -static u64 dbgu_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91cap9_dbgu_device = { - .name = "atmel_usart", - .id = 0, - .dev = { - .dma_mask = &dbgu_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &dbgu_data, - }, - .resource = dbgu_resources, - .num_resources = ARRAY_SIZE(dbgu_resources), -}; - -static inline void configure_dbgu_pins(void) -{ - at91_set_A_periph(AT91_PIN_PC30, 0); /* DRXD */ - at91_set_A_periph(AT91_PIN_PC31, 1); /* DTXD */ -} - -static struct resource uart0_resources[] = { - [0] = { - .start = AT91CAP9_BASE_US0, - .end = AT91CAP9_BASE_US0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_US0, - .end = AT91CAP9_ID_US0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart0_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart0_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91cap9_uart0_device = { - .name = "atmel_usart", - .id = 1, - .dev = { - .dma_mask = &uart0_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart0_data, - }, - .resource = uart0_resources, - .num_resources = ARRAY_SIZE(uart0_resources), -}; - -static inline void configure_usart0_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PA22, 1); /* TXD0 */ - at91_set_A_periph(AT91_PIN_PA23, 0); /* RXD0 */ - - if (pins & ATMEL_UART_RTS) - at91_set_A_periph(AT91_PIN_PA24, 0); /* RTS0 */ - if (pins & ATMEL_UART_CTS) - at91_set_A_periph(AT91_PIN_PA25, 0); /* CTS0 */ -} - -static struct resource uart1_resources[] = { - [0] = { - .start = AT91CAP9_BASE_US1, - .end = AT91CAP9_BASE_US1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_US1, - .end = AT91CAP9_ID_US1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart1_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart1_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91cap9_uart1_device = { - .name = "atmel_usart", - .id = 2, - .dev = { - .dma_mask = &uart1_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart1_data, - }, - .resource = uart1_resources, - .num_resources = ARRAY_SIZE(uart1_resources), -}; - -static inline void configure_usart1_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PD0, 1); /* TXD1 */ - at91_set_A_periph(AT91_PIN_PD1, 0); /* RXD1 */ - - if (pins & ATMEL_UART_RTS) - at91_set_B_periph(AT91_PIN_PD7, 0); /* RTS1 */ - if (pins & ATMEL_UART_CTS) - at91_set_B_periph(AT91_PIN_PD8, 0); /* CTS1 */ -} - -static struct resource uart2_resources[] = { - [0] = { - .start = AT91CAP9_BASE_US2, - .end = AT91CAP9_BASE_US2 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91CAP9_ID_US2, - .end = AT91CAP9_ID_US2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart2_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static u64 uart2_dmamask = DMA_BIT_MASK(32); - -static struct platform_device at91cap9_uart2_device = { - .name = "atmel_usart", - .id = 3, - .dev = { - .dma_mask = &uart2_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &uart2_data, - }, - .resource = uart2_resources, - .num_resources = ARRAY_SIZE(uart2_resources), -}; - -static inline void configure_usart2_pins(unsigned pins) -{ - at91_set_A_periph(AT91_PIN_PD2, 1); /* TXD2 */ - at91_set_A_periph(AT91_PIN_PD3, 0); /* RXD2 */ - - if (pins & ATMEL_UART_RTS) - at91_set_B_periph(AT91_PIN_PD5, 0); /* RTS2 */ - if (pins & ATMEL_UART_CTS) - at91_set_B_periph(AT91_PIN_PD6, 0); /* CTS2 */ -} - -static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ -struct platform_device *atmel_default_console_device; /* the serial console device */ - -void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) -{ - struct platform_device *pdev; - struct atmel_uart_data *pdata; - - switch (id) { - case 0: /* DBGU */ - pdev = &at91cap9_dbgu_device; - configure_dbgu_pins(); - break; - case AT91CAP9_ID_US0: - pdev = &at91cap9_uart0_device; - configure_usart0_pins(pins); - break; - case AT91CAP9_ID_US1: - pdev = &at91cap9_uart1_device; - configure_usart1_pins(pins); - break; - case AT91CAP9_ID_US2: - pdev = &at91cap9_uart2_device; - configure_usart2_pins(pins); - break; - default: - return; - } - pdata = pdev->dev.platform_data; - pdata->num = portnr; /* update to mapped ID */ - - if (portnr < ATMEL_MAX_UART) - at91_uarts[portnr] = pdev; -} - -void __init at91_set_serial_console(unsigned portnr) -{ - if (portnr < ATMEL_MAX_UART) { - atmel_default_console_device = at91_uarts[portnr]; - at91cap9_set_console_clock(at91_uarts[portnr]->id); - } -} - -void __init at91_add_device_serial(void) -{ - int i; - - for (i = 0; i < ATMEL_MAX_UART; i++) { - if (at91_uarts[i]) - platform_device_register(at91_uarts[i]); - } - - if (!atmel_default_console_device) - printk(KERN_INFO "AT91: No default serial console defined.\n"); -} -#else -void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} -void __init at91_set_serial_console(unsigned portnr) {} -void __init at91_add_device_serial(void) {} -#endif - - -/* -------------------------------------------------------------------- */ -/* - * These devices are always present and don't need any board-specific - * setup. - */ -static int __init at91_add_standard_devices(void) -{ - at91_add_device_rtt(); - at91_add_device_watchdog(); - at91_add_device_tc(); - return 0; -} - -arch_initcall(at91_add_standard_devices); diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index 99c3174e24a2..364c19357e60 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c @@ -15,6 +15,7 @@ #include <asm/irq.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> +#include <asm/system_misc.h> #include <mach/at91rm9200.h> #include <mach/at91_pmc.h> #include <mach/at91_st.h> @@ -289,13 +290,22 @@ static struct at91_gpio_bank at91rm9200_gpio[] __initdata = { } }; +static void at91rm9200_idle(void) +{ + /* + * Disable the processor clock. The processor will be automatically + * re-enabled by an interrupt or by a reset. + */ + at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK); +} + static void at91rm9200_restart(char mode, const char *cmd) { /* * Perform a hardware reset with the use of the Watchdog timer. */ - at91_sys_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1); - at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); + at91_st_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1); + at91_st_write(AT91_ST_CR, AT91_ST_WDRST); } /* -------------------------------------------------------------------- @@ -310,10 +320,13 @@ static void __init at91rm9200_map_io(void) static void __init at91rm9200_ioremap_registers(void) { + at91rm9200_ioremap_st(AT91RM9200_BASE_ST); + at91_ioremap_ramc(0, AT91RM9200_BASE_MC, 256); } static void __init at91rm9200_initialize(void) { + arm_pm_idle = at91rm9200_idle; arm_pm_restart = at91rm9200_restart; at91_extern_irq = (1 << AT91RM9200_ID_IRQ0) | (1 << AT91RM9200_ID_IRQ1) | (1 << AT91RM9200_ID_IRQ2) | (1 << AT91RM9200_ID_IRQ3) diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 97676bdae998..99ce5c955e39 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -21,6 +21,7 @@ #include <mach/board.h> #include <mach/at91rm9200.h> #include <mach/at91rm9200_mc.h> +#include <mach/at91_ramc.h> #include "generic.h" @@ -241,15 +242,15 @@ void __init at91_add_device_cf(struct at91_cf_data *data) data->chipselect = 4; /* can only use EBI ChipSelect 4 */ /* CF takes over CS4, CS5, CS6 */ - csa = at91_sys_read(AT91_EBI_CSA); - at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH); + csa = at91_ramc_read(0, AT91_EBI_CSA); + at91_ramc_write(0, AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH); /* * Static memory controller timing adjustments. * REVISIT: these timings are in terms of MCK cycles, so * when MCK changes (cpufreq etc) so must these values... */ - at91_sys_write(AT91_SMC_CSR(4), + at91_ramc_write(0, AT91_SMC_CSR(4), AT91_SMC_ACSS_STD | AT91_SMC_DBW_16 | AT91_SMC_BAT @@ -407,11 +408,11 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) return; /* enable the address range of CS3 */ - csa = at91_sys_read(AT91_EBI_CSA); - at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS3A_SMC_SMARTMEDIA); + csa = at91_ramc_read(0, AT91_EBI_CSA); + at91_ramc_write(0, AT91_EBI_CSA, csa | AT91_EBI_CS3A_SMC_SMARTMEDIA); /* set the bus interface characteristics */ - at91_sys_write(AT91_SMC_CSR(3), AT91_SMC_ACSS_STD | AT91_SMC_DBW_8 | AT91_SMC_WSEN + at91_ramc_write(0, AT91_SMC_CSR(3), AT91_SMC_ACSS_STD | AT91_SMC_DBW_8 | AT91_SMC_WSEN | AT91_SMC_NWS_(5) | AT91_SMC_TDF_(1) | AT91_SMC_RWSETUP_(0) /* tDS Data Set up Time 30 - ns */ @@ -1114,7 +1115,6 @@ static inline void configure_usart3_pins(unsigned pins) } static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ -struct platform_device *atmel_default_console_device; /* the serial console device */ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) { diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c index a028cdf8f974..dd7f782b0b91 100644 --- a/arch/arm/mach-at91/at91rm9200_time.c +++ b/arch/arm/mach-at91/at91rm9200_time.c @@ -43,9 +43,9 @@ static inline unsigned long read_CRTR(void) { unsigned long x1, x2; - x1 = at91_sys_read(AT91_ST_CRTR); + x1 = at91_st_read(AT91_ST_CRTR); do { - x2 = at91_sys_read(AT91_ST_CRTR); + x2 = at91_st_read(AT91_ST_CRTR); if (x1 == x2) break; x1 = x2; @@ -58,7 +58,7 @@ static inline unsigned long read_CRTR(void) */ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id) { - u32 sr = at91_sys_read(AT91_ST_SR) & irqmask; + u32 sr = at91_st_read(AT91_ST_SR) & irqmask; /* * irqs should be disabled here, but as the irq is shared they are only @@ -110,22 +110,22 @@ static void clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev) { /* Disable and flush pending timer interrupts */ - at91_sys_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS); - (void) at91_sys_read(AT91_ST_SR); + at91_st_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS); + at91_st_read(AT91_ST_SR); last_crtr = read_CRTR(); switch (mode) { case CLOCK_EVT_MODE_PERIODIC: /* PIT for periodic irqs; fixed rate of 1/HZ */ irqmask = AT91_ST_PITS; - at91_sys_write(AT91_ST_PIMR, RM9200_TIMER_LATCH); + at91_st_write(AT91_ST_PIMR, RM9200_TIMER_LATCH); break; case CLOCK_EVT_MODE_ONESHOT: /* ALM for oneshot irqs, set by next_event() * before 32 seconds have passed */ irqmask = AT91_ST_ALMS; - at91_sys_write(AT91_ST_RTAR, last_crtr); + at91_st_write(AT91_ST_RTAR, last_crtr); break; case CLOCK_EVT_MODE_SHUTDOWN: case CLOCK_EVT_MODE_UNUSED: @@ -133,7 +133,7 @@ clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev) irqmask = 0; break; } - at91_sys_write(AT91_ST_IER, irqmask); + at91_st_write(AT91_ST_IER, irqmask); } static int @@ -156,12 +156,12 @@ clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev) alm = read_CRTR(); /* Cancel any pending alarm; flush any pending IRQ */ - at91_sys_write(AT91_ST_RTAR, alm); - (void) at91_sys_read(AT91_ST_SR); + at91_st_write(AT91_ST_RTAR, alm); + at91_st_read(AT91_ST_SR); /* Schedule alarm by writing RTAR. */ alm += delta; - at91_sys_write(AT91_ST_RTAR, alm); + at91_st_write(AT91_ST_RTAR, alm); return status; } @@ -175,15 +175,24 @@ static struct clock_event_device clkevt = { .set_mode = clkevt32k_mode, }; +void __iomem *at91_st_base; + +void __init at91rm9200_ioremap_st(u32 addr) +{ + at91_st_base = ioremap(addr, 256); + if (!at91_st_base) + panic("Impossible to ioremap ST\n"); +} + /* * ST (system timer) module supports both clockevents and clocksource. */ void __init at91rm9200_timer_init(void) { /* Disable all timer interrupts, and clear any pending ones */ - at91_sys_write(AT91_ST_IDR, + at91_st_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS); - (void) at91_sys_read(AT91_ST_SR); + at91_st_read(AT91_ST_SR); /* Make IRQs happen for the system timer */ setup_irq(AT91_ID_SYS, &at91rm9200_timer_irq); @@ -192,7 +201,7 @@ void __init at91rm9200_timer_init(void) * directly for the clocksource and all clockevents, after adjusting * its prescaler from the 1 Hz default. */ - at91_sys_write(AT91_ST_RTMR, 1); + at91_st_write(AT91_ST_RTMR, 1); /* Setup timer clockevent, with minimum of two ticks (important!!) */ clkevt.mult = div_sc(AT91_SLOW_CLOCK, NSEC_PER_SEC, clkevt.shift); diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index d4036ba43612..46f774233298 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -12,9 +12,11 @@ #include <linux/module.h> +#include <asm/proc-fns.h> #include <asm/irq.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> +#include <asm/system_misc.h> #include <mach/cpu.h> #include <mach/at91_dbgu.h> #include <mach/at91sam9260.h> @@ -208,6 +210,14 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("usart", "fffd0000.serial", &usart3_clk), CLKDEV_CON_DEV_ID("usart", "fffd4000.serial", &usart4_clk), CLKDEV_CON_DEV_ID("usart", "fffd8000.serial", &usart5_clk), + /* more tc lookup table for DT entries */ + CLKDEV_CON_DEV_ID("t0_clk", "fffa0000.timer", &tc0_clk), + CLKDEV_CON_DEV_ID("t1_clk", "fffa0000.timer", &tc1_clk), + CLKDEV_CON_DEV_ID("t2_clk", "fffa0000.timer", &tc2_clk), + CLKDEV_CON_DEV_ID("t0_clk", "fffdc000.timer", &tc3_clk), + CLKDEV_CON_DEV_ID("t1_clk", "fffdc000.timer", &tc4_clk), + CLKDEV_CON_DEV_ID("t2_clk", "fffdc000.timer", &tc5_clk), + CLKDEV_CON_DEV_ID("hclk", "500000.ohci", &ohci_clk), /* fake hclk clock */ CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), CLKDEV_CON_ID("pioA", &pioA_clk), @@ -309,27 +319,27 @@ static void __init at91sam9xe_map_io(void) static void __init at91sam9260_map_io(void) { - if (cpu_is_at91sam9xe()) { + if (cpu_is_at91sam9xe()) at91sam9xe_map_io(); - } else if (cpu_is_at91sam9g20()) { - at91_init_sram(0, AT91SAM9G20_SRAM0_BASE, AT91SAM9G20_SRAM0_SIZE); - at91_init_sram(1, AT91SAM9G20_SRAM1_BASE, AT91SAM9G20_SRAM1_SIZE); - } else { - at91_init_sram(0, AT91SAM9260_SRAM0_BASE, AT91SAM9260_SRAM0_SIZE); - at91_init_sram(1, AT91SAM9260_SRAM1_BASE, AT91SAM9260_SRAM1_SIZE); - } + else if (cpu_is_at91sam9g20()) + at91_init_sram(0, AT91SAM9G20_SRAM_BASE, AT91SAM9G20_SRAM_SIZE); + else + at91_init_sram(0, AT91SAM9260_SRAM_BASE, AT91SAM9260_SRAM_SIZE); } static void __init at91sam9260_ioremap_registers(void) { at91_ioremap_shdwc(AT91SAM9260_BASE_SHDWC); at91_ioremap_rstc(AT91SAM9260_BASE_RSTC); + at91_ioremap_ramc(0, AT91SAM9260_BASE_SDRAMC, 512); at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC); + at91_ioremap_matrix(AT91SAM9260_BASE_MATRIX); } static void __init at91sam9260_initialize(void) { + arm_pm_idle = at91sam9_idle; arm_pm_restart = at91sam9_alt_restart; at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) | (1 << AT91SAM9260_ID_IRQ2); diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 5a24f0b4554d..5652dde4bbe2 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -21,6 +21,7 @@ #include <mach/cpu.h> #include <mach/at91sam9260.h> #include <mach/at91sam9260_matrix.h> +#include <mach/at91_matrix.h> #include <mach/at91sam9_smc.h> #include "generic.h" @@ -422,8 +423,8 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) if (!data) return; - csa = at91_sys_read(AT91_MATRIX_EBICSA); - at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); + csa = at91_matrix_read(AT91_MATRIX_EBICSA); + at91_matrix_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); /* enable pin */ if (gpio_is_valid(data->enable_pin)) @@ -597,6 +598,9 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) else cs_pin = spi1_standard_cs[devices[i].chip_select]; + if (!gpio_is_valid(cs_pin)) + continue; + if (devices[i].bus_num == 0) enable_spi0 = 1; else @@ -641,7 +645,7 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) static struct resource tcb0_resources[] = { [0] = { .start = AT91SAM9260_BASE_TCB0, - .end = AT91SAM9260_BASE_TCB0 + SZ_16K - 1, + .end = AT91SAM9260_BASE_TCB0 + SZ_256 - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -671,7 +675,7 @@ static struct platform_device at91sam9260_tcb0_device = { static struct resource tcb1_resources[] = { [0] = { .start = AT91SAM9260_BASE_TCB1, - .end = AT91SAM9260_BASE_TCB1 + SZ_16K - 1, + .end = AT91SAM9260_BASE_TCB1 + SZ_256 - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -698,8 +702,25 @@ static struct platform_device at91sam9260_tcb1_device = { .num_resources = ARRAY_SIZE(tcb1_resources), }; +#if defined(CONFIG_OF) +static struct of_device_id tcb_ids[] = { + { .compatible = "atmel,at91rm9200-tcb" }, + { /*sentinel*/ } +}; +#endif + static void __init at91_add_device_tc(void) { +#if defined(CONFIG_OF) + struct device_node *np; + + np = of_find_matching_node(NULL, tcb_ids); + if (np) { + of_node_put(np); + return; + } +#endif + platform_device_register(&at91sam9260_tcb0_device); platform_device_register(&at91sam9260_tcb1_device); } @@ -717,18 +738,42 @@ static struct resource rtt_resources[] = { .start = AT91SAM9260_BASE_RTT, .end = AT91SAM9260_BASE_RTT + SZ_16 - 1, .flags = IORESOURCE_MEM, - } + }, { + .flags = IORESOURCE_MEM, + }, }; static struct platform_device at91sam9260_rtt_device = { .name = "at91_rtt", .id = 0, .resource = rtt_resources, - .num_resources = ARRAY_SIZE(rtt_resources), }; + +#if IS_ENABLED(CONFIG_RTC_DRV_AT91SAM9) +static void __init at91_add_device_rtt_rtc(void) +{ + at91sam9260_rtt_device.name = "rtc-at91sam9"; + /* + * The second resource is needed: + * GPBR will serve as the storage for RTC time offset + */ + at91sam9260_rtt_device.num_resources = 2; + rtt_resources[1].start = AT91SAM9260_BASE_GPBR + + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; + rtt_resources[1].end = rtt_resources[1].start + 3; +} +#else +static void __init at91_add_device_rtt_rtc(void) +{ + /* Only one resource is needed: RTT not used as RTC */ + at91sam9260_rtt_device.num_resources = 1; +} +#endif + static void __init at91_add_device_rtt(void) { + at91_add_device_rtt_rtc(); platform_device_register(&at91sam9260_rtt_device); } @@ -1139,7 +1184,6 @@ static inline void configure_usart5_pins(void) } static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ -struct platform_device *atmel_default_console_device; /* the serial console device */ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) { @@ -1264,7 +1308,7 @@ void __init at91_add_device_cf(struct at91_cf_data *data) if (!data) return; - csa = at91_sys_read(AT91_MATRIX_EBICSA); + csa = at91_matrix_read(AT91_MATRIX_EBICSA); switch (data->chipselect) { case 4: @@ -1287,7 +1331,7 @@ void __init at91_add_device_cf(struct at91_cf_data *data) return; } - at91_sys_write(AT91_MATRIX_EBICSA, csa); + at91_matrix_write(AT91_MATRIX_EBICSA, csa); if (gpio_is_valid(data->rst_pin)) { at91_set_multi_drive(data->rst_pin, 0); diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 023c2ff138df..7de81e6222f1 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -12,9 +12,11 @@ #include <linux/module.h> +#include <asm/proc-fns.h> #include <asm/irq.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> +#include <asm/system_misc.h> #include <mach/cpu.h> #include <mach/at91sam9261.h> #include <mach/at91_pmc.h> @@ -282,12 +284,15 @@ static void __init at91sam9261_ioremap_registers(void) { at91_ioremap_shdwc(AT91SAM9261_BASE_SHDWC); at91_ioremap_rstc(AT91SAM9261_BASE_RSTC); + at91_ioremap_ramc(0, AT91SAM9261_BASE_SDRAMC, 512); at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC); + at91_ioremap_matrix(AT91SAM9261_BASE_MATRIX); } static void __init at91sam9261_initialize(void) { + arm_pm_idle = at91sam9_idle; arm_pm_restart = at91sam9_alt_restart; at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1) | (1 << AT91SAM9261_ID_IRQ2); diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index 1e28bed8f425..4db961a93085 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -24,6 +24,7 @@ #include <mach/board.h> #include <mach/at91sam9261.h> #include <mach/at91sam9261_matrix.h> +#include <mach/at91_matrix.h> #include <mach/at91sam9_smc.h> #include "generic.h" @@ -236,8 +237,8 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) if (!data) return; - csa = at91_sys_read(AT91_MATRIX_EBICSA); - at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); + csa = at91_matrix_read(AT91_MATRIX_EBICSA); + at91_matrix_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); /* enable pin */ if (gpio_is_valid(data->enable_pin)) @@ -414,6 +415,9 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) else cs_pin = spi1_standard_cs[devices[i].chip_select]; + if (!gpio_is_valid(cs_pin)) + continue; + if (devices[i].bus_num == 0) enable_spi0 = 1; else @@ -603,6 +607,8 @@ static struct resource rtt_resources[] = { .start = AT91SAM9261_BASE_RTT, .end = AT91SAM9261_BASE_RTT + SZ_16 - 1, .flags = IORESOURCE_MEM, + }, { + .flags = IORESOURCE_MEM, } }; @@ -610,11 +616,32 @@ static struct platform_device at91sam9261_rtt_device = { .name = "at91_rtt", .id = 0, .resource = rtt_resources, - .num_resources = ARRAY_SIZE(rtt_resources), }; +#if IS_ENABLED(CONFIG_RTC_DRV_AT91SAM9) +static void __init at91_add_device_rtt_rtc(void) +{ + at91sam9261_rtt_device.name = "rtc-at91sam9"; + /* + * The second resource is needed: + * GPBR will serve as the storage for RTC time offset + */ + at91sam9261_rtt_device.num_resources = 2; + rtt_resources[1].start = AT91SAM9261_BASE_GPBR + + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; + rtt_resources[1].end = rtt_resources[1].start + 3; +} +#else +static void __init at91_add_device_rtt_rtc(void) +{ + /* Only one resource is needed: RTT not used as RTC */ + at91sam9261_rtt_device.num_resources = 1; +} +#endif + static void __init at91_add_device_rtt(void) { + at91_add_device_rtt_rtc(); platform_device_register(&at91sam9261_rtt_device); } @@ -991,7 +1018,6 @@ static inline void configure_usart2_pins(unsigned pins) } static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ -struct platform_device *atmel_default_console_device; /* the serial console device */ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) { diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index 75e876c258af..ef301be66575 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -12,9 +12,11 @@ #include <linux/module.h> +#include <asm/proc-fns.h> #include <asm/irq.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> +#include <asm/system_misc.h> #include <mach/at91sam9263.h> #include <mach/at91_pmc.h> #include <mach/at91_rstc.h> @@ -302,13 +304,17 @@ static void __init at91sam9263_ioremap_registers(void) { at91_ioremap_shdwc(AT91SAM9263_BASE_SHDWC); at91_ioremap_rstc(AT91SAM9263_BASE_RSTC); + at91_ioremap_ramc(0, AT91SAM9263_BASE_SDRAMC0, 512); + at91_ioremap_ramc(1, AT91SAM9263_BASE_SDRAMC1, 512); at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9263_BASE_SMC0); at91sam9_ioremap_smc(1, AT91SAM9263_BASE_SMC1); + at91_ioremap_matrix(AT91SAM9263_BASE_MATRIX); } static void __init at91sam9263_initialize(void) { + arm_pm_idle = at91sam9_idle; arm_pm_restart = at91sam9_alt_restart; at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1); diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index 366a7765635b..fe99206de880 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -23,6 +23,7 @@ #include <mach/board.h> #include <mach/at91sam9263.h> #include <mach/at91sam9263_matrix.h> +#include <mach/at91_matrix.h> #include <mach/at91sam9_smc.h> #include "generic.h" @@ -71,7 +72,8 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) /* Enable VBus control for UHP ports */ for (i = 0; i < data->ports; i++) { if (gpio_is_valid(data->vbus_pin[i])) - at91_set_gpio_output(data->vbus_pin[i], 0); + at91_set_gpio_output(data->vbus_pin[i], + data->vbus_pin_active_low[i]); } /* Enable overcurrent notification */ @@ -409,7 +411,7 @@ void __init at91_add_device_cf(struct at91_cf_data *data) * we assume SMC timings are configured by board code, * except True IDE where timings are controlled by driver */ - ebi0_csa = at91_sys_read(AT91_MATRIX_EBI0CSA); + ebi0_csa = at91_matrix_read(AT91_MATRIX_EBI0CSA); switch (data->chipselect) { case 4: at91_set_A_periph(AT91_PIN_PD6, 0); /* EBI0_NCS4/CFCS0 */ @@ -428,7 +430,7 @@ void __init at91_add_device_cf(struct at91_cf_data *data) data->chipselect); return; } - at91_sys_write(AT91_MATRIX_EBI0CSA, ebi0_csa); + at91_matrix_write(AT91_MATRIX_EBI0CSA, ebi0_csa); if (gpio_is_valid(data->det_pin)) { at91_set_gpio_input(data->det_pin, 1); @@ -496,8 +498,8 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) if (!data) return; - csa = at91_sys_read(AT91_MATRIX_EBI0CSA); - at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA); + csa = at91_matrix_read(AT91_MATRIX_EBI0CSA); + at91_matrix_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA); /* enable pin */ if (gpio_is_valid(data->enable_pin)) @@ -670,6 +672,9 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) else cs_pin = spi1_standard_cs[devices[i].chip_select]; + if (!gpio_is_valid(cs_pin)) + continue; + if (devices[i].bus_num == 0) enable_spi0 = 1; else @@ -891,7 +896,8 @@ static struct platform_device at91sam9263_isi_device = { .num_resources = ARRAY_SIZE(isi_resources), }; -void __init at91_add_device_isi(void) +void __init at91_add_device_isi(struct isi_platform_data *data, + bool use_pck_as_mck) { at91_set_A_periph(AT91_PIN_PE0, 0); /* ISI_D0 */ at91_set_A_periph(AT91_PIN_PE1, 0); /* ISI_D1 */ @@ -904,14 +910,20 @@ void __init at91_add_device_isi(void) at91_set_A_periph(AT91_PIN_PE8, 0); /* ISI_PCK */ at91_set_A_periph(AT91_PIN_PE9, 0); /* ISI_HSYNC */ at91_set_A_periph(AT91_PIN_PE10, 0); /* ISI_VSYNC */ - at91_set_B_periph(AT91_PIN_PE11, 0); /* ISI_MCK (PCK3) */ at91_set_B_periph(AT91_PIN_PE12, 0); /* ISI_PD8 */ at91_set_B_periph(AT91_PIN_PE13, 0); /* ISI_PD9 */ at91_set_B_periph(AT91_PIN_PE14, 0); /* ISI_PD10 */ at91_set_B_periph(AT91_PIN_PE15, 0); /* ISI_PD11 */ + + if (use_pck_as_mck) { + at91_set_B_periph(AT91_PIN_PE11, 0); /* ISI_MCK (PCK3) */ + + /* TODO: register the PCK for ISI_MCK and set its parent */ + } } #else -void __init at91_add_device_isi(void) {} +void __init at91_add_device_isi(struct isi_platform_data *data, + bool use_pck_as_mck) {} #endif @@ -959,6 +971,8 @@ static struct resource rtt0_resources[] = { .start = AT91SAM9263_BASE_RTT0, .end = AT91SAM9263_BASE_RTT0 + SZ_16 - 1, .flags = IORESOURCE_MEM, + }, { + .flags = IORESOURCE_MEM, } }; @@ -966,7 +980,6 @@ static struct platform_device at91sam9263_rtt0_device = { .name = "at91_rtt", .id = 0, .resource = rtt0_resources, - .num_resources = ARRAY_SIZE(rtt0_resources), }; static struct resource rtt1_resources[] = { @@ -974,6 +987,8 @@ static struct resource rtt1_resources[] = { .start = AT91SAM9263_BASE_RTT1, .end = AT91SAM9263_BASE_RTT1 + SZ_16 - 1, .flags = IORESOURCE_MEM, + }, { + .flags = IORESOURCE_MEM, } }; @@ -981,11 +996,53 @@ static struct platform_device at91sam9263_rtt1_device = { .name = "at91_rtt", .id = 1, .resource = rtt1_resources, - .num_resources = ARRAY_SIZE(rtt1_resources), }; +#if IS_ENABLED(CONFIG_RTC_DRV_AT91SAM9) +static void __init at91_add_device_rtt_rtc(void) +{ + struct platform_device *pdev; + struct resource *r; + + switch (CONFIG_RTC_DRV_AT91SAM9_RTT) { + case 0: + /* + * The second resource is needed only for the chosen RTT: + * GPBR will serve as the storage for RTC time offset + */ + at91sam9263_rtt0_device.num_resources = 2; + at91sam9263_rtt1_device.num_resources = 1; + pdev = &at91sam9263_rtt0_device; + r = rtt0_resources; + break; + case 1: + at91sam9263_rtt0_device.num_resources = 1; + at91sam9263_rtt1_device.num_resources = 2; + pdev = &at91sam9263_rtt1_device; + r = rtt1_resources; + break; + default: + pr_err("at91sam9263: only supports 2 RTT (%d)\n", + CONFIG_RTC_DRV_AT91SAM9_RTT); + return; + } + + pdev->name = "rtc-at91sam9"; + r[1].start = AT91SAM9263_BASE_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; + r[1].end = r[1].start + 3; +} +#else +static void __init at91_add_device_rtt_rtc(void) +{ + /* Only one resource is needed: RTT not used as RTC */ + at91sam9263_rtt0_device.num_resources = 1; + at91sam9263_rtt1_device.num_resources = 1; +} +#endif + static void __init at91_add_device_rtt(void) { + at91_add_device_rtt_rtc(); platform_device_register(&at91sam9263_rtt0_device); platform_device_register(&at91sam9263_rtt1_device); } @@ -1371,7 +1428,6 @@ static inline void configure_usart2_pins(unsigned pins) } static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ -struct platform_device *atmel_default_console_device; /* the serial console device */ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) { diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c index d89ead740a99..a94758b42737 100644 --- a/arch/arm/mach-at91/at91sam926x_time.c +++ b/arch/arm/mach-at91/at91sam926x_time.c @@ -14,6 +14,9 @@ #include <linux/kernel.h> #include <linux/clk.h> #include <linux/clockchips.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> #include <asm/mach/time.h> @@ -133,7 +136,8 @@ static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id) static struct irqaction at91sam926x_pit_irq = { .name = "at91_tick", .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = at91sam926x_pit_interrupt + .handler = at91sam926x_pit_interrupt, + .irq = AT91_ID_SYS, }; static void at91sam926x_pit_reset(void) @@ -149,6 +153,51 @@ static void at91sam926x_pit_reset(void) pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN); } +#ifdef CONFIG_OF +static struct of_device_id pit_timer_ids[] = { + { .compatible = "atmel,at91sam9260-pit" }, + { /* sentinel */ } +}; + +static int __init of_at91sam926x_pit_init(void) +{ + struct device_node *np; + int ret; + + np = of_find_matching_node(NULL, pit_timer_ids); + if (!np) + goto err; + + pit_base_addr = of_iomap(np, 0); + if (!pit_base_addr) + goto node_err; + + /* Get the interrupts property */ + ret = irq_of_parse_and_map(np, 0); + if (!ret) { + pr_crit("AT91: PIT: Unable to get IRQ from DT\n"); + goto ioremap_err; + } + at91sam926x_pit_irq.irq = ret; + + of_node_put(np); + + return 0; + +ioremap_err: + iounmap(pit_base_addr); +node_err: + of_node_put(np); +err: + return -EINVAL; +} +#else +static int __init of_at91sam926x_pit_init(void) +{ + return -EINVAL; +} +#endif + /* * Set up both clocksource and clockevent support. */ @@ -156,6 +205,10 @@ static void __init at91sam926x_pit_init(void) { unsigned long pit_rate; unsigned bits; + int ret; + + /* For device tree enabled device: initialize here */ + of_at91sam926x_pit_init(); /* * Use our actual MCK to figure out how many MCK/16 ticks per @@ -177,7 +230,9 @@ static void __init at91sam926x_pit_init(void) clocksource_register_hz(&pit_clk, pit_rate); /* Set up irq handler */ - setup_irq(AT91_ID_SYS, &at91sam926x_pit_irq); + ret = setup_irq(at91sam926x_pit_irq.irq, &at91sam926x_pit_irq); + if (ret) + pr_crit("AT91: PIT: Unable to setup IRQ\n"); /* Set up and register clockevents */ pit_clkevt.mult = div_sc(pit_rate, NSEC_PER_SEC, pit_clkevt.shift); @@ -193,6 +248,15 @@ static void at91sam926x_pit_suspend(void) void __init at91sam926x_ioremap_pit(u32 addr) { +#if defined(CONFIG_OF) + struct device_node *np = + of_find_matching_node(NULL, pit_timer_ids); + + if (np) { + of_node_put(np); + return; + } +#endif pit_base_addr = ioremap(addr, 16); if (!pit_base_addr) diff --git a/arch/arm/mach-at91/at91sam9_alt_reset.S b/arch/arm/mach-at91/at91sam9_alt_reset.S index 518e42377171..7af2e108b8a0 100644 --- a/arch/arm/mach-at91/at91sam9_alt_reset.S +++ b/arch/arm/mach-at91/at91sam9_alt_reset.S @@ -15,16 +15,17 @@ #include <linux/linkage.h> #include <mach/hardware.h> -#include <mach/at91sam9_sdramc.h> +#include <mach/at91_ramc.h> #include <mach/at91_rstc.h> .arm .globl at91sam9_alt_restart -at91sam9_alt_restart: ldr r0, .at91_va_base_sdramc @ preload constants - ldr r1, =at91_rstc_base - ldr r1, [r1] +at91sam9_alt_restart: ldr r0, =at91_ramc_base @ preload constants + ldr r0, [r0] + ldr r4, =at91_rstc_base + ldr r1, [r4] mov r2, #1 mov r3, #AT91_SDRAMC_LPCB_POWER_DOWN @@ -37,6 +38,3 @@ at91sam9_alt_restart: ldr r0, .at91_va_base_sdramc @ preload constants str r4, [r1, #AT91_RSTC_CR] @ reset processor b . - -.at91_va_base_sdramc: - .word AT91_VA_BASE_SYS + AT91_SDRAMC0 diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 1cb6a96b1c1e..d222f8333dab 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -16,6 +16,7 @@ #include <asm/irq.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> +#include <asm/system_misc.h> #include <mach/at91sam9g45.h> #include <mach/at91_pmc.h> #include <mach/cpu.h> @@ -229,6 +230,11 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("usart", "fff90000.serial", &usart1_clk), CLKDEV_CON_DEV_ID("usart", "fff94000.serial", &usart2_clk), CLKDEV_CON_DEV_ID("usart", "fff98000.serial", &usart3_clk), + /* more tc lookup table for DT entries */ + CLKDEV_CON_DEV_ID("t0_clk", "fff7c000.timer", &tcb0_clk), + CLKDEV_CON_DEV_ID("t0_clk", "fffd4000.timer", &tcb0_clk), + CLKDEV_CON_DEV_ID("hclk", "700000.ohci", &uhphs_clk), + CLKDEV_CON_DEV_ID("ehci_clk", "800000.ehci", &uhphs_clk), /* fake hclk clock */ CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &uhphs_clk), CLKDEV_CON_ID("pioA", &pioA_clk), @@ -331,12 +337,16 @@ static void __init at91sam9g45_ioremap_registers(void) { at91_ioremap_shdwc(AT91SAM9G45_BASE_SHDWC); at91_ioremap_rstc(AT91SAM9G45_BASE_RSTC); + at91_ioremap_ramc(0, AT91SAM9G45_BASE_DDRSDRC1, 512); + at91_ioremap_ramc(1, AT91SAM9G45_BASE_DDRSDRC0, 512); at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9G45_BASE_SMC); + at91_ioremap_matrix(AT91SAM9G45_BASE_MATRIX); } static void __init at91sam9g45_initialize(void) { + arm_pm_idle = at91sam9_idle; arm_pm_restart = at91sam9g45_restart; at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0); diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 96e2adcd5a84..6b008aee1dff 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -14,6 +14,7 @@ #include <linux/dma-mapping.h> #include <linux/gpio.h> +#include <linux/clk.h> #include <linux/platform_device.h> #include <linux/i2c-gpio.h> #include <linux/atmel-mci.h> @@ -24,11 +25,15 @@ #include <mach/board.h> #include <mach/at91sam9g45.h> #include <mach/at91sam9g45_matrix.h> +#include <mach/at91_matrix.h> #include <mach/at91sam9_smc.h> #include <mach/at_hdmac.h> #include <mach/atmel-mci.h> +#include <media/atmel-isi.h> + #include "generic.h" +#include "clock.h" /* -------------------------------------------------------------------- @@ -122,12 +127,13 @@ void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) /* Enable VBus control for UHP ports */ for (i = 0; i < data->ports; i++) { if (gpio_is_valid(data->vbus_pin[i])) - at91_set_gpio_output(data->vbus_pin[i], 0); + at91_set_gpio_output(data->vbus_pin[i], + data->vbus_pin_active_low[i]); } /* Enable overcurrent notification */ for (i = 0; i < data->ports; i++) { - if (data->overcurrent_pin[i]) + if (gpio_is_valid(data->overcurrent_pin[i])) at91_set_gpio_input(data->overcurrent_pin[i], 1); } @@ -183,7 +189,8 @@ void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data) /* Enable VBus control for UHP ports */ for (i = 0; i < data->ports; i++) { if (gpio_is_valid(data->vbus_pin[i])) - at91_set_gpio_output(data->vbus_pin[i], 0); + at91_set_gpio_output(data->vbus_pin[i], + data->vbus_pin_active_low[i]); } usbh_ehci_data = *data; @@ -432,7 +439,6 @@ void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) /* DMA slave channel configuration */ atslave->dma_dev = &at_hdmac_device.dev; - atslave->reg_width = AT_DMA_SLAVE_WIDTH_32BIT; atslave->cfg = ATC_FIFOCFG_HALFFIFO | ATC_SRC_H2SEL_HW | ATC_DST_H2SEL_HW; atslave->ctrla = ATC_SCSIZE_16 | ATC_DCSIZE_16; @@ -553,8 +559,8 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) if (!data) return; - csa = at91_sys_read(AT91_MATRIX_EBICSA); - at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA); + csa = at91_matrix_read(AT91_MATRIX_EBICSA); + at91_matrix_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA); /* enable pin */ if (gpio_is_valid(data->enable_pin)) @@ -781,6 +787,9 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) else cs_pin = spi1_standard_cs[devices[i].chip_select]; + if (!gpio_is_valid(cs_pin)) + continue; + if (devices[i].bus_num == 0) enable_spi0 = 1; else @@ -870,6 +879,96 @@ void __init at91_add_device_ac97(struct ac97c_platform_data *data) void __init at91_add_device_ac97(struct ac97c_platform_data *data) {} #endif +/* -------------------------------------------------------------------- + * Image Sensor Interface + * -------------------------------------------------------------------- */ +#if defined(CONFIG_VIDEO_ATMEL_ISI) || defined(CONFIG_VIDEO_ATMEL_ISI_MODULE) +static u64 isi_dmamask = DMA_BIT_MASK(32); +static struct isi_platform_data isi_data; + +struct resource isi_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_ISI, + .end = AT91SAM9G45_BASE_ISI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_ID_ISI, + .end = AT91SAM9G45_ID_ISI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9g45_isi_device = { + .name = "atmel_isi", + .id = 0, + .dev = { + .dma_mask = &isi_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &isi_data, + }, + .resource = isi_resources, + .num_resources = ARRAY_SIZE(isi_resources), +}; + +static struct clk_lookup isi_mck_lookups[] = { + CLKDEV_CON_DEV_ID("isi_mck", "atmel_isi.0", NULL), +}; + +void __init at91_add_device_isi(struct isi_platform_data *data, + bool use_pck_as_mck) +{ + struct clk *pck; + struct clk *parent; + + if (!data) + return; + isi_data = *data; + + at91_set_A_periph(AT91_PIN_PB20, 0); /* ISI_D0 */ + at91_set_A_periph(AT91_PIN_PB21, 0); /* ISI_D1 */ + at91_set_A_periph(AT91_PIN_PB22, 0); /* ISI_D2 */ + at91_set_A_periph(AT91_PIN_PB23, 0); /* ISI_D3 */ + at91_set_A_periph(AT91_PIN_PB24, 0); /* ISI_D4 */ + at91_set_A_periph(AT91_PIN_PB25, 0); /* ISI_D5 */ + at91_set_A_periph(AT91_PIN_PB26, 0); /* ISI_D6 */ + at91_set_A_periph(AT91_PIN_PB27, 0); /* ISI_D7 */ + at91_set_A_periph(AT91_PIN_PB28, 0); /* ISI_PCK */ + at91_set_A_periph(AT91_PIN_PB30, 0); /* ISI_HSYNC */ + at91_set_A_periph(AT91_PIN_PB29, 0); /* ISI_VSYNC */ + at91_set_B_periph(AT91_PIN_PB8, 0); /* ISI_PD8 */ + at91_set_B_periph(AT91_PIN_PB9, 0); /* ISI_PD9 */ + at91_set_B_periph(AT91_PIN_PB10, 0); /* ISI_PD10 */ + at91_set_B_periph(AT91_PIN_PB11, 0); /* ISI_PD11 */ + + platform_device_register(&at91sam9g45_isi_device); + + if (use_pck_as_mck) { + at91_set_B_periph(AT91_PIN_PB31, 0); /* ISI_MCK (PCK1) */ + + pck = clk_get(NULL, "pck1"); + parent = clk_get(NULL, "plla"); + + BUG_ON(IS_ERR(pck) || IS_ERR(parent)); + + if (clk_set_parent(pck, parent)) { + pr_err("Failed to set PCK's parent\n"); + } else { + /* Register PCK as ISI_MCK */ + isi_mck_lookups[0].clk = pck; + clkdev_add_table(isi_mck_lookups, + ARRAY_SIZE(isi_mck_lookups)); + } + + clk_put(pck); + clk_put(parent); + } +} +#else +void __init at91_add_device_isi(struct isi_platform_data *data, + bool use_pck_as_mck) {} +#endif + /* -------------------------------------------------------------------- * LCD Controller @@ -957,7 +1056,7 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} static struct resource tcb0_resources[] = { [0] = { .start = AT91SAM9G45_BASE_TCB0, - .end = AT91SAM9G45_BASE_TCB0 + SZ_16K - 1, + .end = AT91SAM9G45_BASE_TCB0 + SZ_256 - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -978,7 +1077,7 @@ static struct platform_device at91sam9g45_tcb0_device = { static struct resource tcb1_resources[] = { [0] = { .start = AT91SAM9G45_BASE_TCB1, - .end = AT91SAM9G45_BASE_TCB1 + SZ_16K - 1, + .end = AT91SAM9G45_BASE_TCB1 + SZ_256 - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -995,8 +1094,25 @@ static struct platform_device at91sam9g45_tcb1_device = { .num_resources = ARRAY_SIZE(tcb1_resources), }; +#if defined(CONFIG_OF) +static struct of_device_id tcb_ids[] = { + { .compatible = "atmel,at91rm9200-tcb" }, + { /*sentinel*/ } +}; +#endif + static void __init at91_add_device_tc(void) { +#if defined(CONFIG_OF) + struct device_node *np; + + np = of_find_matching_node(NULL, tcb_ids); + if (np) { + of_node_put(np); + return; + } +#endif + platform_device_register(&at91sam9g45_tcb0_device); platform_device_register(&at91sam9g45_tcb1_device); } @@ -1099,6 +1215,8 @@ static struct resource rtt_resources[] = { .start = AT91SAM9G45_BASE_RTT, .end = AT91SAM9G45_BASE_RTT + SZ_16 - 1, .flags = IORESOURCE_MEM, + }, { + .flags = IORESOURCE_MEM, } }; @@ -1106,11 +1224,32 @@ static struct platform_device at91sam9g45_rtt_device = { .name = "at91_rtt", .id = 0, .resource = rtt_resources, - .num_resources = ARRAY_SIZE(rtt_resources), }; +#if IS_ENABLED(CONFIG_RTC_DRV_AT91SAM9) +static void __init at91_add_device_rtt_rtc(void) +{ + at91sam9g45_rtt_device.name = "rtc-at91sam9"; + /* + * The second resource is needed: + * GPBR will serve as the storage for RTC time offset + */ + at91sam9g45_rtt_device.num_resources = 2; + rtt_resources[1].start = AT91SAM9G45_BASE_GPBR + + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; + rtt_resources[1].end = rtt_resources[1].start + 3; +} +#else +static void __init at91_add_device_rtt_rtc(void) +{ + /* Only one resource is needed: RTT not used as RTC */ + at91sam9g45_rtt_device.num_resources = 1; +} +#endif + static void __init at91_add_device_rtt(void) { + at91_add_device_rtt_rtc(); platform_device_register(&at91sam9g45_rtt_device); } @@ -1565,7 +1704,6 @@ static inline void configure_usart3_pins(unsigned pins) } static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ -struct platform_device *atmel_default_console_device; /* the serial console device */ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) { diff --git a/arch/arm/mach-at91/at91sam9g45_reset.S b/arch/arm/mach-at91/at91sam9g45_reset.S index 0468be10980b..9d457182c86c 100644 --- a/arch/arm/mach-at91/at91sam9g45_reset.S +++ b/arch/arm/mach-at91/at91sam9g45_reset.S @@ -12,7 +12,7 @@ #include <linux/linkage.h> #include <mach/hardware.h> -#include <mach/at91sam9_ddrsdr.h> +#include <mach/at91_ramc.h> #include <mach/at91_rstc.h> .arm @@ -20,9 +20,10 @@ .globl at91sam9g45_restart at91sam9g45_restart: - ldr r0, .at91_va_base_sdramc0 @ preload constants - ldr r1, =at91_rstc_base - ldr r1, [r1] + ldr r5, =at91_ramc_base @ preload constants + ldr r0, [r5] + ldr r4, =at91_rstc_base + ldr r1, [r4] mov r2, #1 mov r3, #AT91_DDRSDRC_LPCB_POWER_DOWN @@ -35,6 +36,3 @@ at91sam9g45_restart: str r4, [r1, #AT91_RSTC_CR] @ reset processor b . - -.at91_va_base_sdramc0: - .word AT91_VA_BASE_SYS + AT91_DDRSDRC0 diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index d2c91a841cb8..d9f2774f385e 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -11,9 +11,11 @@ #include <linux/module.h> +#include <asm/proc-fns.h> #include <asm/irq.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> +#include <asm/system_misc.h> #include <mach/cpu.h> #include <mach/at91_dbgu.h> #include <mach/at91sam9rl.h> @@ -287,12 +289,15 @@ static void __init at91sam9rl_ioremap_registers(void) { at91_ioremap_shdwc(AT91SAM9RL_BASE_SHDWC); at91_ioremap_rstc(AT91SAM9RL_BASE_RSTC); + at91_ioremap_ramc(0, AT91SAM9RL_BASE_SDRAMC, 512); at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC); + at91_ioremap_matrix(AT91SAM9RL_BASE_MATRIX); } static void __init at91sam9rl_initialize(void) { + arm_pm_idle = at91sam9_idle; arm_pm_restart = at91sam9_alt_restart; at91_extern_irq = (1 << AT91SAM9RL_ID_IRQ0); diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index 9be71c11d0f0..fe4ae22e8561 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -20,6 +20,7 @@ #include <mach/board.h> #include <mach/at91sam9rl.h> #include <mach/at91sam9rl_matrix.h> +#include <mach/at91_matrix.h> #include <mach/at91sam9_smc.h> #include <mach/at_hdmac.h> @@ -265,8 +266,8 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) if (!data) return; - csa = at91_sys_read(AT91_MATRIX_EBICSA); - at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); + csa = at91_matrix_read(AT91_MATRIX_EBICSA); + at91_matrix_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); /* enable pin */ if (gpio_is_valid(data->enable_pin)) @@ -418,6 +419,9 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) else cs_pin = spi_standard_cs[devices[i].chip_select]; + if (!gpio_is_valid(cs_pin)) + continue; + /* enable chip-select pin */ at91_set_gpio_output(cs_pin, 1); @@ -682,6 +686,8 @@ static struct resource rtt_resources[] = { .start = AT91SAM9RL_BASE_RTT, .end = AT91SAM9RL_BASE_RTT + SZ_16 - 1, .flags = IORESOURCE_MEM, + }, { + .flags = IORESOURCE_MEM, } }; @@ -689,11 +695,32 @@ static struct platform_device at91sam9rl_rtt_device = { .name = "at91_rtt", .id = 0, .resource = rtt_resources, - .num_resources = ARRAY_SIZE(rtt_resources), }; +#if IS_ENABLED(CONFIG_RTC_DRV_AT91SAM9) +static void __init at91_add_device_rtt_rtc(void) +{ + at91sam9rl_rtt_device.name = "rtc-at91sam9"; + /* + * The second resource is needed: + * GPBR will serve as the storage for RTC time offset + */ + at91sam9rl_rtt_device.num_resources = 2; + rtt_resources[1].start = AT91SAM9RL_BASE_GPBR + + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR; + rtt_resources[1].end = rtt_resources[1].start + 3; +} +#else +static void __init at91_add_device_rtt_rtc(void) +{ + /* Only one resource is needed: RTT not used as RTC */ + at91sam9rl_rtt_device.num_resources = 1; +} +#endif + static void __init at91_add_device_rtt(void) { + at91_add_device_rtt_rtc(); platform_device_register(&at91sam9rl_rtt_device); } @@ -1128,7 +1155,6 @@ static inline void configure_usart3_pins(unsigned pins) } static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ -struct platform_device *atmel_default_console_device; /* the serial console device */ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) { diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c new file mode 100644 index 000000000000..13c8cae60462 --- /dev/null +++ b/arch/arm/mach-at91/at91sam9x5.c @@ -0,0 +1,361 @@ +/* + * Chip-specific setup code for the AT91SAM9x5 family + * + * Copyright (C) 2010-2012 Atmel Corporation. + * + * Licensed under GPLv2 or later. + */ + +#include <linux/module.h> +#include <linux/dma-mapping.h> + +#include <asm/irq.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <mach/at91sam9x5.h> +#include <mach/at91_pmc.h> +#include <mach/cpu.h> +#include <mach/board.h> + +#include "soc.h" +#include "generic.h" +#include "clock.h" +#include "sam9_smc.h" + +/* -------------------------------------------------------------------- + * Clocks + * -------------------------------------------------------------------- */ + +/* + * The peripheral clocks. + */ +static struct clk pioAB_clk = { + .name = "pioAB_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_PIOAB, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioCD_clk = { + .name = "pioCD_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_PIOCD, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk smd_clk = { + .name = "smd_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_SMD, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart0_clk = { + .name = "usart0_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_USART0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart1_clk = { + .name = "usart1_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_USART1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart2_clk = { + .name = "usart2_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_USART2, + .type = CLK_TYPE_PERIPHERAL, +}; +/* USART3 clock - Only for sam9g25/sam9x25 */ +static struct clk usart3_clk = { + .name = "usart3_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_USART3, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twi0_clk = { + .name = "twi0_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_TWI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twi1_clk = { + .name = "twi1_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_TWI1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twi2_clk = { + .name = "twi2_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_TWI2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mmc0_clk = { + .name = "mci0_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_MCI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi0_clk = { + .name = "spi0_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_SPI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi1_clk = { + .name = "spi1_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_SPI1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk uart0_clk = { + .name = "uart0_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_UART0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk uart1_clk = { + .name = "uart1_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_UART1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk tcb0_clk = { + .name = "tcb0_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_TCB, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pwm_clk = { + .name = "pwm_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_PWM, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk adc_clk = { + .name = "adc_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_ADC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk dma0_clk = { + .name = "dma0_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_DMA0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk dma1_clk = { + .name = "dma1_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_DMA1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk uhphs_clk = { + .name = "uhphs", + .pmc_mask = 1 << AT91SAM9X5_ID_UHPHS, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk udphs_clk = { + .name = "udphs_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_UDPHS, + .type = CLK_TYPE_PERIPHERAL, +}; +/* emac0 clock - Only for sam9g25/sam9x25/sam9g35/sam9x35 */ +static struct clk macb0_clk = { + .name = "pclk", + .pmc_mask = 1 << AT91SAM9X5_ID_EMAC0, + .type = CLK_TYPE_PERIPHERAL, +}; +/* lcd clock - Only for sam9g15/sam9g35/sam9x35 */ +static struct clk lcdc_clk = { + .name = "lcdc_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_LCDC, + .type = CLK_TYPE_PERIPHERAL, +}; +/* isi clock - Only for sam9g25 */ +static struct clk isi_clk = { + .name = "isi_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_ISI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mmc1_clk = { + .name = "mci1_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_MCI1, + .type = CLK_TYPE_PERIPHERAL, +}; +/* emac1 clock - Only for sam9x25 */ +static struct clk macb1_clk = { + .name = "pclk", + .pmc_mask = 1 << AT91SAM9X5_ID_EMAC1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ssc_clk = { + .name = "ssc_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_SSC, + .type = CLK_TYPE_PERIPHERAL, +}; +/* can0 clock - Only for sam9x35 */ +static struct clk can0_clk = { + .name = "can0_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_CAN0, + .type = CLK_TYPE_PERIPHERAL, +}; +/* can1 clock - Only for sam9x35 */ +static struct clk can1_clk = { + .name = "can1_clk", + .pmc_mask = 1 << AT91SAM9X5_ID_CAN1, + .type = CLK_TYPE_PERIPHERAL, +}; + +static struct clk *periph_clocks[] __initdata = { + &pioAB_clk, + &pioCD_clk, + &smd_clk, + &usart0_clk, + &usart1_clk, + &usart2_clk, + &twi0_clk, + &twi1_clk, + &twi2_clk, + &mmc0_clk, + &spi0_clk, + &spi1_clk, + &uart0_clk, + &uart1_clk, + &tcb0_clk, + &pwm_clk, + &adc_clk, + &dma0_clk, + &dma1_clk, + &uhphs_clk, + &udphs_clk, + &mmc1_clk, + &ssc_clk, + // irq0 +}; + +static struct clk_lookup periph_clocks_lookups[] = { + /* lookup table for DT entries */ + CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck), + CLKDEV_CON_DEV_ID("usart", "f801c000.serial", &usart0_clk), + CLKDEV_CON_DEV_ID("usart", "f8020000.serial", &usart1_clk), + CLKDEV_CON_DEV_ID("usart", "f8024000.serial", &usart2_clk), + CLKDEV_CON_DEV_ID("usart", "f8028000.serial", &usart3_clk), + CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb0_clk), + CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk), + CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma0_clk), + CLKDEV_CON_DEV_ID("dma_clk", "ffffee00.dma-controller", &dma1_clk), + CLKDEV_CON_ID("pioA", &pioAB_clk), + CLKDEV_CON_ID("pioB", &pioAB_clk), + CLKDEV_CON_ID("pioC", &pioCD_clk), + CLKDEV_CON_ID("pioD", &pioCD_clk), + /* additional fake clock for macb_hclk */ + CLKDEV_CON_DEV_ID("hclk", "f802c000.ethernet", &macb0_clk), + CLKDEV_CON_DEV_ID("hclk", "f8030000.ethernet", &macb1_clk), + CLKDEV_CON_DEV_ID("hclk", "600000.ohci", &uhphs_clk), + CLKDEV_CON_DEV_ID("ohci_clk", "600000.ohci", &uhphs_clk), + CLKDEV_CON_DEV_ID("ehci_clk", "700000.ehci", &uhphs_clk), +}; + +/* + * The two programmable clocks. + * You must configure pin multiplexing to bring these signals out. + */ +static struct clk pck0 = { + .name = "pck0", + .pmc_mask = AT91_PMC_PCK0, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 0, +}; +static struct clk pck1 = { + .name = "pck1", + .pmc_mask = AT91_PMC_PCK1, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 1, +}; + +static void __init at91sam9x5_register_clocks(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) + clk_register(periph_clocks[i]); + + clkdev_add_table(periph_clocks_lookups, + ARRAY_SIZE(periph_clocks_lookups)); + + if (cpu_is_at91sam9g25() + || cpu_is_at91sam9x25()) + clk_register(&usart3_clk); + + if (cpu_is_at91sam9g25() + || cpu_is_at91sam9x25() + || cpu_is_at91sam9g35() + || cpu_is_at91sam9x35()) + clk_register(&macb0_clk); + + if (cpu_is_at91sam9g15() + || cpu_is_at91sam9g35() + || cpu_is_at91sam9x35()) + clk_register(&lcdc_clk); + + if (cpu_is_at91sam9g25()) + clk_register(&isi_clk); + + if (cpu_is_at91sam9x25()) + clk_register(&macb1_clk); + + if (cpu_is_at91sam9x25() + || cpu_is_at91sam9x35()) { + clk_register(&can0_clk); + clk_register(&can1_clk); + } + + clk_register(&pck0); + clk_register(&pck1); +} + +/* -------------------------------------------------------------------- + * AT91SAM9x5 processor initialization + * -------------------------------------------------------------------- */ + +static void __init at91sam9x5_map_io(void) +{ + at91_init_sram(0, AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE); +} + +void __init at91sam9x5_initialize(void) +{ + at91_extern_irq = (1 << AT91SAM9X5_ID_IRQ0); + + /* Register GPIO subsystem (using DT) */ + at91_gpio_init(NULL, 0); +} + +/* -------------------------------------------------------------------- + * Interrupt initialization + * -------------------------------------------------------------------- */ +/* + * The default interrupt priority levels (0 = lowest, 7 = highest). + */ +static unsigned int at91sam9x5_default_irq_priority[NR_AIC_IRQS] __initdata = { + 7, /* Advanced Interrupt Controller (FIQ) */ + 7, /* System Peripherals */ + 1, /* Parallel IO Controller A and B */ + 1, /* Parallel IO Controller C and D */ + 4, /* Soft Modem */ + 5, /* USART 0 */ + 5, /* USART 1 */ + 5, /* USART 2 */ + 5, /* USART 3 */ + 6, /* Two-Wire Interface 0 */ + 6, /* Two-Wire Interface 1 */ + 6, /* Two-Wire Interface 2 */ + 0, /* Multimedia Card Interface 0 */ + 5, /* Serial Peripheral Interface 0 */ + 5, /* Serial Peripheral Interface 1 */ + 5, /* UART 0 */ + 5, /* UART 1 */ + 0, /* Timer Counter 0, 1, 2, 3, 4 and 5 */ + 0, /* Pulse Width Modulation Controller */ + 0, /* ADC Controller */ + 0, /* DMA Controller 0 */ + 0, /* DMA Controller 1 */ + 2, /* USB Host High Speed port */ + 2, /* USB Device High speed port */ + 3, /* Ethernet MAC 0 */ + 3, /* LDC Controller or Image Sensor Interface */ + 0, /* Multimedia Card Interface 1 */ + 3, /* Ethernet MAC 1 */ + 4, /* Synchronous Serial Interface */ + 4, /* CAN Controller 0 */ + 4, /* CAN Controller 1 */ + 0, /* Advanced Interrupt Controller (IRQ0) */ +}; + +struct at91_init_soc __initdata at91sam9x5_soc = { + .map_io = at91sam9x5_map_io, + .default_irq_priority = at91sam9x5_default_irq_priority, + .register_clocks = at91sam9x5_register_clocks, + .init = at91sam9x5_initialize, +}; diff --git a/arch/arm/mach-at91/at91x40.c b/arch/arm/mach-at91/at91x40.c index 56ba3bd035ae..d62fe090d814 100644 --- a/arch/arm/mach-at91/at91x40.c +++ b/arch/arm/mach-at91/at91x40.c @@ -13,6 +13,8 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/irq.h> +#include <asm/proc-fns.h> +#include <asm/system_misc.h> #include <asm/mach/arch.h> #include <mach/at91x40.h> #include <mach/at91_st.h> @@ -37,8 +39,19 @@ unsigned long clk_get_rate(struct clk *clk) return AT91X40_MASTER_CLOCK; } +static void at91x40_idle(void) +{ + /* + * Disable the processor clock. The processor will be automatically + * re-enabled by an interrupt or by a reset. + */ + __raw_writel(AT91_PS_CR_CPU, AT91_PS_CR); + cpu_do_idle(); +} + void __init at91x40_initialize(unsigned long main_clock) { + arm_pm_idle = at91x40_idle; at91_extern_irq = (1 << AT91X40_ID_IRQ0) | (1 << AT91X40_ID_IRQ1) | (1 << AT91X40_ID_IRQ2); } diff --git a/arch/arm/mach-at91/at91x40_time.c b/arch/arm/mach-at91/at91x40_time.c index dfff2895f4b2..6ca680a1d5d1 100644 --- a/arch/arm/mach-at91/at91x40_time.c +++ b/arch/arm/mach-at91/at91x40_time.c @@ -28,6 +28,12 @@ #include <asm/mach/time.h> #include <mach/at91_tc.h> +#define at91_tc_read(field) \ + __raw_readl(AT91_TC + field) + +#define at91_tc_write(field, value) \ + __raw_writel(value, AT91_TC + field); + /* * 3 counter/timer units present. */ @@ -37,12 +43,12 @@ static unsigned long at91x40_gettimeoffset(void) { - return (at91_sys_read(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CV) * 1000000 / (AT91X40_MASTER_CLOCK / 128)); + return (at91_tc_read(AT91_TC_CLK1BASE + AT91_TC_CV) * 1000000 / (AT91X40_MASTER_CLOCK / 128)); } static irqreturn_t at91x40_timer_interrupt(int irq, void *dev_id) { - at91_sys_read(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_SR); + at91_tc_read(AT91_TC_CLK1BASE + AT91_TC_SR); timer_tick(); return IRQ_HANDLED; } @@ -57,20 +63,20 @@ void __init at91x40_timer_init(void) { unsigned int v; - at91_sys_write(AT91_TC + AT91_TC_BCR, 0); - v = at91_sys_read(AT91_TC + AT91_TC_BMR); + at91_tc_write(AT91_TC_BCR, 0); + v = at91_tc_read(AT91_TC_BMR); v = (v & ~AT91_TC_TC1XC1S) | AT91_TC_TC1XC1S_NONE; - at91_sys_write(AT91_TC + AT91_TC_BMR, v); + at91_tc_write(AT91_TC_BMR, v); - at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CCR, AT91_TC_CLKDIS); - at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CMR, (AT91_TC_TIMER_CLOCK4 | AT91_TC_CPCTRG)); - at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_IDR, 0xffffffff); - at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_RC, (AT91X40_MASTER_CLOCK / 128) / HZ - 1); - at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_IER, (1<<4)); + at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_CCR, AT91_TC_CLKDIS); + at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_CMR, (AT91_TC_TIMER_CLOCK4 | AT91_TC_CPCTRG)); + at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_IDR, 0xffffffff); + at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_RC, (AT91X40_MASTER_CLOCK / 128) / HZ - 1); + at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_IER, (1<<4)); setup_irq(AT91X40_ID_TC1, &at91x40_timer_irq); - at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CCR, (AT91_TC_SWTRG | AT91_TC_CLKEN)); + at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_CCR, (AT91_TC_SWTRG | AT91_TC_CLKEN)); } struct sys_timer at91x40_timer = { diff --git a/arch/arm/mach-at91/board-afeb-9260v1.c b/arch/arm/mach-at91/board-afeb-9260v1.c index 3bb40694b02d..161efbaa1029 100644 --- a/arch/arm/mach-at91/board-afeb-9260v1.c +++ b/arch/arm/mach-at91/board-afeb-9260v1.c @@ -138,6 +138,7 @@ static struct atmel_nand_data __initdata afeb9260_nand_data = { .rdy_pin = AT91_PIN_PC13, .enable_pin = AT91_PIN_PC14, .bus_width_16 = 0, + .ecc_mode = NAND_ECC_SOFT, .parts = afeb9260_nand_partition, .num_parts = ARRAY_SIZE(afeb9260_nand_partition), .det_pin = -EINVAL, diff --git a/arch/arm/mach-at91/board-cam60.c b/arch/arm/mach-at91/board-cam60.c index 8510e9e54988..c6d44ee0c77e 100644 --- a/arch/arm/mach-at91/board-cam60.c +++ b/arch/arm/mach-at91/board-cam60.c @@ -140,6 +140,7 @@ static struct atmel_nand_data __initdata cam60_nand_data = { .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PA9, .enable_pin = AT91_PIN_PA7, + .ecc_mode = NAND_ECC_SOFT, .parts = cam60_nand_partition, .num_parts = ARRAY_SIZE(cam60_nand_partition), }; diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c deleted file mode 100644 index ac3de4f7c31d..000000000000 --- a/arch/arm/mach-at91/board-cap9adk.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - * linux/arch/arm/mach-at91/board-cap9adk.c - * - * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com> - * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com> - * Copyright (C) 2005 SAN People - * Copyright (C) 2007 Atmel Corporation. - * - * 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/types.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/spi/spi.h> -#include <linux/spi/ads7846.h> -#include <linux/fb.h> -#include <linux/mtd/physmap.h> - -#include <video/atmel_lcdc.h> - -#include <mach/hardware.h> -#include <asm/setup.h> -#include <asm/mach-types.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> - -#include <mach/board.h> -#include <mach/at91cap9_matrix.h> -#include <mach/at91sam9_smc.h> -#include <mach/system_rev.h> - -#include "sam9_smc.h" -#include "generic.h" - - -static void __init cap9adk_init_early(void) -{ - /* Initialize processor: 12 MHz crystal */ - at91_initialize(12000000); - - /* Setup the LEDs: USER1 and USER2 LED for cpu/timer... */ - at91_init_leds(AT91_PIN_PA10, AT91_PIN_PA11); - /* ... POWER LED always on */ - at91_set_gpio_output(AT91_PIN_PC29, 1); - - /* Setup the serial ports and console */ - at91_register_uart(0, 0, 0); /* DBGU = ttyS0 */ - at91_set_serial_console(0); -} - -/* - * USB Host port - */ -static struct at91_usbh_data __initdata cap9adk_usbh_data = { - .ports = 2, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -/* - * USB HS Device port - */ -static struct usba_platform_data __initdata cap9adk_usba_udc_data = { - .vbus_pin = AT91_PIN_PB31, -}; - -/* - * ADS7846 Touchscreen - */ -#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) -static int ads7843_pendown_state(void) -{ - return !at91_get_gpio_value(AT91_PIN_PC4); /* Touchscreen PENIRQ */ -} - -static struct ads7846_platform_data ads_info = { - .model = 7843, - .x_min = 150, - .x_max = 3830, - .y_min = 190, - .y_max = 3830, - .vref_delay_usecs = 100, - .x_plate_ohms = 450, - .y_plate_ohms = 250, - .pressure_max = 15000, - .debounce_max = 1, - .debounce_rep = 0, - .debounce_tol = (~0), - .get_pendown_state = ads7843_pendown_state, -}; - -static void __init cap9adk_add_device_ts(void) -{ - at91_set_gpio_input(AT91_PIN_PC4, 1); /* Touchscreen PENIRQ */ - at91_set_gpio_input(AT91_PIN_PC5, 1); /* Touchscreen BUSY */ -} -#else -static void __init cap9adk_add_device_ts(void) {} -#endif - - -/* - * SPI devices. - */ -static struct spi_board_info cap9adk_spi_devices[] = { -#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) - { /* DataFlash card */ - .modalias = "mtd_dataflash", - .chip_select = 0, - .max_speed_hz = 15 * 1000 * 1000, - .bus_num = 0, - }, -#endif -#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) - { - .modalias = "ads7846", - .chip_select = 3, /* can be 2 or 3, depending on J2 jumper */ - .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */ - .bus_num = 0, - .platform_data = &ads_info, - .irq = AT91_PIN_PC4, - }, -#endif -}; - - -/* - * MCI (SD/MMC) - */ -static struct at91_mmc_data __initdata cap9adk_mmc_data = { - .wire4 = 1, - .det_pin = -EINVAL, - .wp_pin = -EINVAL, - .vcc_pin = -EINVAL, -}; - - -/* - * MACB Ethernet device - */ -static struct macb_platform_data __initdata cap9adk_macb_data = { - .phy_irq_pin = -EINVAL, - .is_rmii = 1, -}; - - -/* - * NAND flash - */ -static struct mtd_partition __initdata cap9adk_nand_partitions[] = { - { - .name = "NAND partition", - .offset = 0, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct atmel_nand_data __initdata cap9adk_nand_data = { - .ale = 21, - .cle = 22, - .det_pin = -EINVAL, - .rdy_pin = -EINVAL, - .enable_pin = AT91_PIN_PD15, - .parts = cap9adk_nand_partitions, - .num_parts = ARRAY_SIZE(cap9adk_nand_partitions), -}; - -static struct sam9_smc_config __initdata cap9adk_nand_smc_config = { - .ncs_read_setup = 1, - .nrd_setup = 2, - .ncs_write_setup = 1, - .nwe_setup = 2, - - .ncs_read_pulse = 6, - .nrd_pulse = 4, - .ncs_write_pulse = 6, - .nwe_pulse = 4, - - .read_cycle = 8, - .write_cycle = 8, - - .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, - .tdf_cycles = 1, -}; - -static void __init cap9adk_add_device_nand(void) -{ - unsigned long csa; - - csa = at91_sys_read(AT91_MATRIX_EBICSA); - at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V); - - cap9adk_nand_data.bus_width_16 = board_have_nand_16bit(); - /* setup bus-width (8 or 16) */ - if (cap9adk_nand_data.bus_width_16) - cap9adk_nand_smc_config.mode |= AT91_SMC_DBW_16; - else - cap9adk_nand_smc_config.mode |= AT91_SMC_DBW_8; - - /* configure chip-select 3 (NAND) */ - sam9_smc_configure(0, 3, &cap9adk_nand_smc_config); - - at91_add_device_nand(&cap9adk_nand_data); -} - - -/* - * NOR flash - */ -static struct mtd_partition cap9adk_nor_partitions[] = { - { - .name = "NOR partition", - .offset = 0, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct physmap_flash_data cap9adk_nor_data = { - .width = 2, - .parts = cap9adk_nor_partitions, - .nr_parts = ARRAY_SIZE(cap9adk_nor_partitions), -}; - -#define NOR_BASE AT91_CHIPSELECT_0 -#define NOR_SIZE SZ_8M - -static struct resource nor_flash_resources[] = { - { - .start = NOR_BASE, - .end = NOR_BASE + NOR_SIZE - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device cap9adk_nor_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &cap9adk_nor_data, - }, - .resource = nor_flash_resources, - .num_resources = ARRAY_SIZE(nor_flash_resources), -}; - -static struct sam9_smc_config __initdata cap9adk_nor_smc_config = { - .ncs_read_setup = 2, - .nrd_setup = 4, - .ncs_write_setup = 2, - .nwe_setup = 4, - - .ncs_read_pulse = 10, - .nrd_pulse = 8, - .ncs_write_pulse = 10, - .nwe_pulse = 8, - - .read_cycle = 16, - .write_cycle = 16, - - .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE | AT91_SMC_DBW_16, - .tdf_cycles = 1, -}; - -static __init void cap9adk_add_device_nor(void) -{ - unsigned long csa; - - csa = at91_sys_read(AT91_MATRIX_EBICSA); - at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V); - - /* configure chip-select 0 (NOR) */ - sam9_smc_configure(0, 0, &cap9adk_nor_smc_config); - - platform_device_register(&cap9adk_nor_flash); -} - - -/* - * LCD Controller - */ -#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) -static struct fb_videomode at91_tft_vga_modes[] = { - { - .name = "TX09D50VM1CCA @ 60", - .refresh = 60, - .xres = 240, .yres = 320, - .pixclock = KHZ2PICOS(4965), - - .left_margin = 1, .right_margin = 33, - .upper_margin = 1, .lower_margin = 0, - .hsync_len = 5, .vsync_len = 1, - - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED, - }, -}; - -static struct fb_monspecs at91fb_default_monspecs = { - .manufacturer = "HIT", - .monitor = "TX09D70VM1CCA", - - .modedb = at91_tft_vga_modes, - .modedb_len = ARRAY_SIZE(at91_tft_vga_modes), - .hfmin = 15000, - .hfmax = 64000, - .vfmin = 50, - .vfmax = 150, -}; - -#define AT91CAP9_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ - | ATMEL_LCDC_DISTYPE_TFT \ - | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) - -static void at91_lcdc_power_control(int on) -{ - if (on) - at91_set_gpio_value(AT91_PIN_PC0, 0); /* power up */ - else - at91_set_gpio_value(AT91_PIN_PC0, 1); /* power down */ -} - -/* Driver datas */ -static struct atmel_lcdfb_info __initdata cap9adk_lcdc_data = { - .default_bpp = 16, - .default_dmacon = ATMEL_LCDC_DMAEN, - .default_lcdcon2 = AT91CAP9_DEFAULT_LCDCON2, - .default_monspecs = &at91fb_default_monspecs, - .atmel_lcdfb_power_control = at91_lcdc_power_control, - .guard_time = 1, -}; - -#else -static struct atmel_lcdfb_info __initdata cap9adk_lcdc_data; -#endif - - -/* - * AC97 - */ -static struct ac97c_platform_data cap9adk_ac97_data = { - .reset_pin = -EINVAL, -}; - - -static void __init cap9adk_board_init(void) -{ - /* Serial */ - at91_add_device_serial(); - /* USB Host */ - at91_add_device_usbh(&cap9adk_usbh_data); - /* USB HS */ - at91_add_device_usba(&cap9adk_usba_udc_data); - /* SPI */ - at91_add_device_spi(cap9adk_spi_devices, ARRAY_SIZE(cap9adk_spi_devices)); - /* Touchscreen */ - cap9adk_add_device_ts(); - /* MMC */ - at91_add_device_mmc(1, &cap9adk_mmc_data); - /* Ethernet */ - at91_add_device_eth(&cap9adk_macb_data); - /* NAND */ - cap9adk_add_device_nand(); - /* NOR Flash */ - cap9adk_add_device_nor(); - /* I2C */ - at91_add_device_i2c(NULL, 0); - /* LCD Controller */ - at91_add_device_lcdc(&cap9adk_lcdc_data); - /* AC97 */ - at91_add_device_ac97(&cap9adk_ac97_data); -} - -MACHINE_START(AT91CAP9ADK, "Atmel AT91CAP9A-DK") - /* Maintainer: Stelian Pop <stelian.pop@leadtechdesign.com> */ - .timer = &at91sam926x_timer, - .map_io = at91_map_io, - .init_early = cap9adk_init_early, - .init_irq = at91_init_irq_default, - .init_machine = cap9adk_board_init, -MACHINE_END diff --git a/arch/arm/mach-at91/board-cpu9krea.c b/arch/arm/mach-at91/board-cpu9krea.c index 9ab3d1ea326d..5f3680e7c883 100644 --- a/arch/arm/mach-at91/board-cpu9krea.c +++ b/arch/arm/mach-at91/board-cpu9krea.c @@ -43,6 +43,7 @@ #include <mach/board.h> #include <mach/at91sam9_smc.h> #include <mach/at91sam9260_matrix.h> +#include <mach/at91_matrix.h> #include "sam9_smc.h" #include "generic.h" @@ -116,6 +117,7 @@ static struct atmel_nand_data __initdata cpu9krea_nand_data = { .enable_pin = AT91_PIN_PC14, .bus_width_16 = 0, .det_pin = -EINVAL, + .ecc_mode = NAND_ECC_SOFT, }; #ifdef CONFIG_MACH_CPU9260 @@ -238,8 +240,8 @@ static __init void cpu9krea_add_device_nor(void) { unsigned long csa; - csa = at91_sys_read(AT91_MATRIX_EBICSA); - at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_VDDIOMSEL_3_3V); + csa = at91_matrix_read(AT91_MATRIX_EBICSA); + at91_matrix_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_VDDIOMSEL_3_3V); /* configure chip-select 0 (NOR) */ sam9_smc_configure(0, 0, &cpu9krea_nor_smc_config); diff --git a/arch/arm/mach-at91/board-cpuat91.c b/arch/arm/mach-at91/board-cpuat91.c index 368e1427ad99..e094cc81fe25 100644 --- a/arch/arm/mach-at91/board-cpuat91.c +++ b/arch/arm/mach-at91/board-cpuat91.c @@ -38,6 +38,7 @@ #include <mach/board.h> #include <mach/at91rm9200_mc.h> +#include <mach/at91_ramc.h> #include <mach/cpu.h> #include "generic.h" diff --git a/arch/arm/mach-at91/board-dt.c b/arch/arm/mach-at91/board-dt.c index bb6b434ec0c1..c18d4d307801 100644 --- a/arch/arm/mach-at91/board-dt.c +++ b/arch/arm/mach-at91/board-dt.c @@ -15,14 +15,11 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/gpio.h> -#include <linux/irqdomain.h> +#include <linux/of.h> #include <linux/of_irq.h> #include <linux/of_platform.h> -#include <mach/hardware.h> #include <mach/board.h> -#include <mach/system_rev.h> -#include <mach/at91sam9_smc.h> #include <asm/setup.h> #include <asm/irq.h> @@ -30,85 +27,30 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include "sam9_smc.h" #include "generic.h" -static void __init ek_init_early(void) -{ - /* Initialize processor: 12.000 MHz crystal */ - at91_initialize(12000000); - - /* DGBU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* set serial console to ttyS0 (ie, DBGU) */ - at91_set_serial_console(0); -} - -/* det_pin is not connected */ -static struct atmel_nand_data __initdata ek_nand_data = { - .ale = 21, - .cle = 22, - .det_pin = -EINVAL, - .rdy_pin = AT91_PIN_PC8, - .enable_pin = AT91_PIN_PC14, -}; - -static struct sam9_smc_config __initdata ek_nand_smc_config = { - .ncs_read_setup = 0, - .nrd_setup = 2, - .ncs_write_setup = 0, - .nwe_setup = 2, - - .ncs_read_pulse = 4, - .nrd_pulse = 4, - .ncs_write_pulse = 4, - .nwe_pulse = 4, - - .read_cycle = 7, - .write_cycle = 7, +static const struct of_device_id irq_of_match[] __initconst = { - .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, - .tdf_cycles = 3, -}; - -static void __init ek_add_device_nand(void) -{ - ek_nand_data.bus_width_16 = board_have_nand_16bit(); - /* setup bus-width (8 or 16) */ - if (ek_nand_data.bus_width_16) - ek_nand_smc_config.mode |= AT91_SMC_DBW_16; - else - ek_nand_smc_config.mode |= AT91_SMC_DBW_8; - - /* configure chip-select 3 (NAND) */ - sam9_smc_configure(0, 3, &ek_nand_smc_config); - - at91_add_device_nand(&ek_nand_data); -} - -static const struct of_device_id aic_of_match[] __initconst = { - { .compatible = "atmel,at91rm9200-aic", }, - {}, + { .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init }, + { .compatible = "atmel,at91rm9200-gpio", .data = at91_gpio_of_irq_setup }, + { .compatible = "atmel,at91sam9x5-gpio", .data = at91_gpio_of_irq_setup }, + { /*sentinel*/ } }; static void __init at91_dt_init_irq(void) { - irq_domain_generate_simple(aic_of_match, 0xfffff000, 0); - at91_init_irq_default(); + of_irq_init(irq_of_match); } static void __init at91_dt_device_init(void) { of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); - - /* NAND */ - ek_add_device_nand(); } static const char *at91_dt_board_compat[] __initdata = { "atmel,at91sam9m10g45ek", + "atmel,at91sam9x5ek", "calao,usb-a9g20", NULL }; @@ -117,7 +59,7 @@ DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM (Device Tree)") /* Maintainer: Atmel */ .timer = &at91sam926x_timer, .map_io = at91_map_io, - .init_early = ek_init_early, + .init_early = at91_dt_initialize, .init_irq = at91_dt_init_irq, .init_machine = at91_dt_device_init, .dt_compat = at91_dt_board_compat, diff --git a/arch/arm/mach-at91/board-eco920.c b/arch/arm/mach-at91/board-eco920.c index 07ef35b0ec2c..f23aabef8551 100644 --- a/arch/arm/mach-at91/board-eco920.c +++ b/arch/arm/mach-at91/board-eco920.c @@ -26,6 +26,7 @@ #include <mach/board.h> #include <mach/at91rm9200_mc.h> +#include <mach/at91_ramc.h> #include <mach/cpu.h> #include "generic.h" @@ -110,7 +111,7 @@ static void __init eco920_board_init(void) at91_add_device_mmc(0, &eco920_mmc_data); platform_device_register(&eco920_flash); - at91_sys_write(AT91_SMC_CSR(7), AT91_SMC_RWHOLD_(1) + at91_ramc_write(0, AT91_SMC_CSR(7), AT91_SMC_RWHOLD_(1) | AT91_SMC_RWSETUP_(1) | AT91_SMC_DBW_8 | AT91_SMC_WSEN @@ -122,7 +123,7 @@ static void __init eco920_board_init(void) at91_set_deglitch(AT91_PIN_PA23, 1); /* Initialization of the Static Memory Controller for Chip Select 3 */ - at91_sys_write(AT91_SMC_CSR(3), + at91_ramc_write(0, AT91_SMC_CSR(3), AT91_SMC_DBW_16 | /* 16 bit */ AT91_SMC_WSEN | AT91_SMC_NWS_(5) | /* wait states */ diff --git a/arch/arm/mach-at91/board-flexibity.c b/arch/arm/mach-at91/board-flexibity.c index eec02cd57ced..1815152001f7 100644 --- a/arch/arm/mach-at91/board-flexibity.c +++ b/arch/arm/mach-at91/board-flexibity.c @@ -1,7 +1,7 @@ /* * linux/arch/arm/mach-at91/board-flexibity.c * - * Copyright (C) 2010 Flexibity + * Copyright (C) 2010-2011 Flexibity * Copyright (C) 2005 SAN People * Copyright (C) 2006 Atmel * @@ -62,6 +62,13 @@ static struct at91_udc_data __initdata flexibity_udc_data = { .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; +/* I2C devices */ +static struct i2c_board_info __initdata flexibity_i2c_devices[] = { + { + I2C_BOARD_INFO("ds1307", 0x68), + }, +}; + /* SPI devices */ static struct spi_board_info flexibity_spi_devices[] = { { /* DataFlash chip */ @@ -141,6 +148,9 @@ static void __init flexibity_board_init(void) at91_add_device_usbh(&flexibity_usbh_data); /* USB Device */ at91_add_device_udc(&flexibity_udc_data); + /* I2C */ + at91_add_device_i2c(flexibity_i2c_devices, + ARRAY_SIZE(flexibity_i2c_devices)); /* SPI */ at91_add_device_spi(flexibity_spi_devices, ARRAY_SIZE(flexibity_spi_devices)); diff --git a/arch/arm/mach-at91/board-kb9202.c b/arch/arm/mach-at91/board-kb9202.c index d75a4a2ad9c2..59b92aab9bcf 100644 --- a/arch/arm/mach-at91/board-kb9202.c +++ b/arch/arm/mach-at91/board-kb9202.c @@ -38,6 +38,7 @@ #include <mach/board.h> #include <mach/cpu.h> #include <mach/at91rm9200_mc.h> +#include <mach/at91_ramc.h> #include "generic.h" @@ -107,6 +108,7 @@ static struct atmel_nand_data __initdata kb9202_nand_data = { .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PC29, .enable_pin = AT91_PIN_PC28, + .ecc_mode = NAND_ECC_SOFT, .parts = kb9202_nand_partition, .num_parts = ARRAY_SIZE(kb9202_nand_partition), }; diff --git a/arch/arm/mach-at91/board-neocore926.c b/arch/arm/mach-at91/board-neocore926.c index 3f8617c0e04e..57d5f6a4726a 100644 --- a/arch/arm/mach-at91/board-neocore926.c +++ b/arch/arm/mach-at91/board-neocore926.c @@ -190,6 +190,7 @@ static struct atmel_nand_data __initdata neocore926_nand_data = { .rdy_pin = AT91_PIN_PB19, .rdy_pin_active_low = 1, .enable_pin = AT91_PIN_PD15, + .ecc_mode = NAND_ECC_SOFT, .parts = neocore926_nand_partition, .num_parts = ARRAY_SIZE(neocore926_nand_partition), .det_pin = -EINVAL, diff --git a/arch/arm/mach-at91/board-picotux200.c b/arch/arm/mach-at91/board-picotux200.c index ab024fa11d5c..59e35dd14863 100644 --- a/arch/arm/mach-at91/board-picotux200.c +++ b/arch/arm/mach-at91/board-picotux200.c @@ -39,6 +39,7 @@ #include <mach/board.h> #include <mach/at91rm9200_mc.h> +#include <mach/at91_ramc.h> #include "generic.h" diff --git a/arch/arm/mach-at91/board-qil-a9260.c b/arch/arm/mach-at91/board-qil-a9260.c index e029d220cb84..b6ed5ed7081a 100644 --- a/arch/arm/mach-at91/board-qil-a9260.c +++ b/arch/arm/mach-at91/board-qil-a9260.c @@ -138,6 +138,8 @@ static struct atmel_nand_data __initdata ek_nand_data = { .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PC13, .enable_pin = AT91_PIN_PC14, + .ecc_mode = NAND_ECC_SOFT, + .on_flash_bbt = 1, .parts = ek_nand_partition, .num_parts = ARRAY_SIZE(ek_nand_partition), }; diff --git a/arch/arm/mach-at91/board-rm9200dk.c b/arch/arm/mach-at91/board-rm9200dk.c index 782f37946af5..01332aa538b2 100644 --- a/arch/arm/mach-at91/board-rm9200dk.c +++ b/arch/arm/mach-at91/board-rm9200dk.c @@ -41,6 +41,7 @@ #include <mach/hardware.h> #include <mach/board.h> #include <mach/at91rm9200_mc.h> +#include <mach/at91_ramc.h> #include "generic.h" @@ -149,6 +150,8 @@ static struct atmel_nand_data __initdata dk_nand_data = { .det_pin = AT91_PIN_PB1, .rdy_pin = AT91_PIN_PC2, .enable_pin = -EINVAL, + .ecc_mode = NAND_ECC_SOFT, + .on_flash_bbt = 1, .parts = dk_nand_partition, .num_parts = ARRAY_SIZE(dk_nand_partition), }; diff --git a/arch/arm/mach-at91/board-rm9200ek.c b/arch/arm/mach-at91/board-rm9200ek.c index ef7c12a92246..11cbaa8946fe 100644 --- a/arch/arm/mach-at91/board-rm9200ek.c +++ b/arch/arm/mach-at91/board-rm9200ek.c @@ -41,6 +41,7 @@ #include <mach/hardware.h> #include <mach/board.h> #include <mach/at91rm9200_mc.h> +#include <mach/at91_ramc.h> #include "generic.h" diff --git a/arch/arm/mach-at91/board-sam9-l9260.c b/arch/arm/mach-at91/board-sam9-l9260.c index 84bce587735f..e8b116b6cba6 100644 --- a/arch/arm/mach-at91/board-sam9-l9260.c +++ b/arch/arm/mach-at91/board-sam9-l9260.c @@ -139,6 +139,7 @@ static struct atmel_nand_data __initdata ek_nand_data = { .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PC13, .enable_pin = AT91_PIN_PC14, + .ecc_mode = NAND_ECC_SOFT, .parts = ek_nand_partition, .num_parts = ARRAY_SIZE(ek_nand_partition), }; diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c index be8233bcabdc..d5aec55b0eb4 100644 --- a/arch/arm/mach-at91/board-sam9260ek.c +++ b/arch/arm/mach-at91/board-sam9260ek.c @@ -181,6 +181,8 @@ static struct atmel_nand_data __initdata ek_nand_data = { .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PC13, .enable_pin = AT91_PIN_PC14, + .ecc_mode = NAND_ECC_SOFT, + .on_flash_bbt = 1, .parts = ek_nand_partition, .num_parts = ARRAY_SIZE(ek_nand_partition), }; diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c index 40895072a1a7..c3f994462864 100644 --- a/arch/arm/mach-at91/board-sam9261ek.c +++ b/arch/arm/mach-at91/board-sam9261ek.c @@ -187,6 +187,8 @@ static struct atmel_nand_data __initdata ek_nand_data = { .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PC15, .enable_pin = AT91_PIN_PC14, + .ecc_mode = NAND_ECC_SOFT, + .on_flash_bbt = 1, .parts = ek_nand_partition, .num_parts = ARRAY_SIZE(ek_nand_partition), }; diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c index 29f66052fe63..2ffe50f3a9e9 100644 --- a/arch/arm/mach-at91/board-sam9263ek.c +++ b/arch/arm/mach-at91/board-sam9263ek.c @@ -74,6 +74,7 @@ static void __init ek_init_early(void) static struct at91_usbh_data __initdata ek_usbh_data = { .ports = 2, .vbus_pin = { AT91_PIN_PA24, AT91_PIN_PA21 }, + .vbus_pin_active_low = {1, 1}, .overcurrent_pin= {-EINVAL, -EINVAL}, }; @@ -187,6 +188,8 @@ static struct atmel_nand_data __initdata ek_nand_data = { .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PA22, .enable_pin = AT91_PIN_PD15, + .ecc_mode = NAND_ECC_SOFT, + .on_flash_bbt = 1, .parts = ek_nand_partition, .num_parts = ARRAY_SIZE(ek_nand_partition), }; diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c index 843d6286c6f4..8923ec9f5831 100644 --- a/arch/arm/mach-at91/board-sam9g20ek.c +++ b/arch/arm/mach-at91/board-sam9g20ek.c @@ -166,6 +166,8 @@ static struct atmel_nand_data __initdata ek_nand_data = { .rdy_pin = AT91_PIN_PC13, .enable_pin = AT91_PIN_PC14, .det_pin = -EINVAL, + .ecc_mode = NAND_ECC_SOFT, + .on_flash_bbt = 1, .parts = ek_nand_partition, .num_parts = ARRAY_SIZE(ek_nand_partition), }; diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c index ea0d1b9c2b7b..c88e908ddd82 100644 --- a/arch/arm/mach-at91/board-sam9m10g45ek.c +++ b/arch/arm/mach-at91/board-sam9m10g45ek.c @@ -24,11 +24,13 @@ #include <linux/gpio_keys.h> #include <linux/input.h> #include <linux/leds.h> -#include <linux/clk.h> #include <linux/atmel-mci.h> +#include <linux/delay.h> #include <mach/hardware.h> #include <video/atmel_lcdc.h> +#include <media/soc_camera.h> +#include <media/atmel-isi.h> #include <asm/setup.h> #include <asm/mach-types.h> @@ -69,6 +71,7 @@ static void __init ek_init_early(void) static struct at91_usbh_data __initdata ek_usbh_hs_data = { .ports = 2, .vbus_pin = {AT91_PIN_PD1, AT91_PIN_PD3}, + .vbus_pin_active_low = {1, 1}, .overcurrent_pin= {-EINVAL, -EINVAL}, }; @@ -146,6 +149,8 @@ static struct atmel_nand_data __initdata ek_nand_data = { .rdy_pin = AT91_PIN_PC8, .enable_pin = AT91_PIN_PC14, .det_pin = -EINVAL, + .ecc_mode = NAND_ECC_SOFT, + .on_flash_bbt = 1, .parts = ek_nand_partition, .num_parts = ARRAY_SIZE(ek_nand_partition), }; @@ -185,6 +190,71 @@ static void __init ek_add_device_nand(void) /* + * ISI + */ +static struct isi_platform_data __initdata isi_data = { + .frate = ISI_CFG1_FRATE_CAPTURE_ALL, + /* to use codec and preview path simultaneously */ + .full_mode = 1, + .data_width_flags = ISI_DATAWIDTH_8 | ISI_DATAWIDTH_10, + /* ISI_MCK is provided by programmable clock or external clock */ + .mck_hz = 25000000, +}; + + +/* + * soc-camera OV2640 + */ +#if defined(CONFIG_SOC_CAMERA_OV2640) || \ + defined(CONFIG_SOC_CAMERA_OV2640_MODULE) +static unsigned long isi_camera_query_bus_param(struct soc_camera_link *link) +{ + /* ISI board for ek using default 8-bits connection */ + return SOCAM_DATAWIDTH_8; +} + +static int i2c_camera_power(struct device *dev, int on) +{ + /* enable or disable the camera */ + pr_debug("%s: %s the camera\n", __func__, on ? "ENABLE" : "DISABLE"); + at91_set_gpio_output(AT91_PIN_PD13, !on); + + if (!on) + goto out; + + /* If enabled, give a reset impulse */ + at91_set_gpio_output(AT91_PIN_PD12, 0); + msleep(20); + at91_set_gpio_output(AT91_PIN_PD12, 1); + msleep(100); + +out: + return 0; +} + +static struct i2c_board_info i2c_camera = { + I2C_BOARD_INFO("ov2640", 0x30), +}; + +static struct soc_camera_link iclink_ov2640 = { + .bus_id = 0, + .board_info = &i2c_camera, + .i2c_adapter_id = 0, + .power = i2c_camera_power, + .query_bus_param = isi_camera_query_bus_param, +}; + +static struct platform_device isi_ov2640 = { + .name = "soc-camera-pdrv", + .id = 0, + .dev = { + .platform_data = &iclink_ov2640, + }, +}; +#endif + + +/* * LCD Controller */ #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) @@ -377,7 +447,12 @@ static struct gpio_led ek_pwm_led[] = { #endif }; - +static struct platform_device *devices[] __initdata = { +#if defined(CONFIG_SOC_CAMERA_OV2640) || \ + defined(CONFIG_SOC_CAMERA_OV2640_MODULE) + &isi_ov2640, +#endif +}; static void __init ek_board_init(void) { @@ -399,6 +474,8 @@ static void __init ek_board_init(void) ek_add_device_nand(); /* I2C */ at91_add_device_i2c(0, NULL, 0); + /* ISI, using programmable clock as ISI_MCK */ + at91_add_device_isi(&isi_data, true); /* LCD Controller */ at91_add_device_lcdc(&ek_lcdc_data); /* Touch Screen */ @@ -410,6 +487,8 @@ static void __init ek_board_init(void) /* LEDs */ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led)); + /* Other platform devices */ + platform_add_devices(devices, ARRAY_SIZE(devices)); } MACHINE_START(AT91SAM9M10G45EK, "Atmel AT91SAM9M10G45-EK") diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c index c1366d0032bf..b109ce2ba864 100644 --- a/arch/arm/mach-at91/board-sam9rlek.c +++ b/arch/arm/mach-at91/board-sam9rlek.c @@ -94,6 +94,8 @@ static struct atmel_nand_data __initdata ek_nand_data = { .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PD17, .enable_pin = AT91_PIN_PB6, + .ecc_mode = NAND_ECC_SOFT, + .on_flash_bbt = 1, .parts = ek_nand_partition, .num_parts = ARRAY_SIZE(ek_nand_partition), }; diff --git a/arch/arm/mach-at91/board-snapper9260.c b/arch/arm/mach-at91/board-snapper9260.c index 4770db08e5a6..ebc9d01ce742 100644 --- a/arch/arm/mach-at91/board-snapper9260.c +++ b/arch/arm/mach-at91/board-snapper9260.c @@ -110,6 +110,7 @@ static struct atmel_nand_data __initdata snapper9260_nand_data = { .bus_width_16 = 0, .enable_pin = -EINVAL, .det_pin = -EINVAL, + .ecc_mode = NAND_ECC_SOFT, }; static struct sam9_smc_config __initdata snapper9260_nand_smc_config = { @@ -145,11 +146,11 @@ static struct i2c_board_info __initdata snapper9260_i2c_devices[] = { /* Audio codec */ I2C_BOARD_INFO("tlv320aic23", 0x1a), }, - { +}; + +static struct i2c_board_info __initdata snapper9260_i2c_isl1208 = { /* RTC */ I2C_BOARD_INFO("isl1208", 0x6f), - .irq = gpio_to_irq(AT91_PIN_PA31), - }, }; static void __init snapper9260_add_device_nand(void) @@ -163,6 +164,10 @@ static void __init snapper9260_board_init(void) { at91_add_device_i2c(snapper9260_i2c_devices, ARRAY_SIZE(snapper9260_i2c_devices)); + + snapper9260_i2c_isl1208.irq = gpio_to_irq(AT91_PIN_PA31); + i2c_register_board_info(0, &snapper9260_i2c_isl1208, 1); + at91_add_device_serial(); at91_add_device_usbh(&snapper9260_usbh_data); at91_add_device_udc(&snapper9260_udc_data); diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c index 72eb3b4d9ab6..7640049410a0 100644 --- a/arch/arm/mach-at91/board-stamp9g20.c +++ b/arch/arm/mach-at91/board-stamp9g20.c @@ -86,6 +86,7 @@ static struct atmel_nand_data __initdata nand_data = { .enable_pin = AT91_PIN_PC14, .bus_width_16 = 0, .det_pin = -EINVAL, + .ecc_mode = NAND_ECC_SOFT, }; static struct sam9_smc_config __initdata nand_smc_config = { diff --git a/arch/arm/mach-at91/board-usb-a926x.c b/arch/arm/mach-at91/board-usb-a926x.c index 26c36fc2d1e5..b7483a3d0980 100644 --- a/arch/arm/mach-at91/board-usb-a926x.c +++ b/arch/arm/mach-at91/board-usb-a926x.c @@ -198,6 +198,8 @@ static struct atmel_nand_data __initdata ek_nand_data = { .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PA22, .enable_pin = AT91_PIN_PD15, + .ecc_mode = NAND_ECC_SOFT, + .on_flash_bbt = 1, .parts = ek_nand_partition, .num_parts = ARRAY_SIZE(ek_nand_partition), }; diff --git a/arch/arm/mach-at91/board-yl-9200.c b/arch/arm/mach-at91/board-yl-9200.c index bbd553e1cd93..38dd279d30b2 100644 --- a/arch/arm/mach-at91/board-yl-9200.c +++ b/arch/arm/mach-at91/board-yl-9200.c @@ -45,6 +45,7 @@ #include <mach/hardware.h> #include <mach/board.h> #include <mach/at91rm9200_mc.h> +#include <mach/at91_ramc.h> #include <mach/cpu.h> #include "generic.h" @@ -181,6 +182,7 @@ static struct atmel_nand_data __initdata yl9200_nand_data = { .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PC14, /* R/!B (Sheet10) */ .enable_pin = AT91_PIN_PC15, /* !CE (Sheet10) */ + .ecc_mode = NAND_ECC_SOFT, .parts = yl9200_nand_partition, .num_parts = ARRAY_SIZE(yl9200_nand_partition), }; @@ -393,7 +395,7 @@ static void yl9200_init_video(void) at91_set_A_periph(AT91_PIN_PC6, 0); /* Initialization of the Static Memory Controller for Chip Select 2 */ - at91_sys_write(AT91_SMC_CSR(2), AT91_SMC_DBW_16 /* 16 bit */ + at91_ramc_write(0, AT91_SMC_CSR(2), AT91_SMC_DBW_16 /* 16 bit */ | AT91_SMC_WSEN | AT91_SMC_NWS_(0x4) /* wait states */ | AT91_SMC_TDF_(0x100) /* float time */ ); diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index 61873f3aa92d..a0f4d7424cdc 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c @@ -23,14 +23,18 @@ #include <linux/delay.h> #include <linux/clk.h> #include <linux/io.h> +#include <linux/of_address.h> #include <mach/hardware.h> #include <mach/at91_pmc.h> #include <mach/cpu.h> +#include <asm/proc-fns.h> + #include "clock.h" #include "generic.h" +void __iomem *at91_pmc_base; /* * There's a lot more which can be done with clocks, including cpufreq @@ -47,26 +51,38 @@ /* * Chips have some kind of clocks : group them by functionality */ -#define cpu_has_utmi() ( cpu_is_at91cap9() \ - || cpu_is_at91sam9rl() \ - || cpu_is_at91sam9g45()) +#define cpu_has_utmi() ( cpu_is_at91sam9rl() \ + || cpu_is_at91sam9g45() \ + || cpu_is_at91sam9x5()) #define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \ - || cpu_is_at91sam9g45()) + || cpu_is_at91sam9g45() \ + || cpu_is_at91sam9x5()) #define cpu_has_300M_plla() (cpu_is_at91sam9g10()) #define cpu_has_pllb() (!(cpu_is_at91sam9rl() \ - || cpu_is_at91sam9g45())) + || cpu_is_at91sam9g45() \ + || cpu_is_at91sam9x5())) -#define cpu_has_upll() (cpu_is_at91sam9g45()) +#define cpu_has_upll() (cpu_is_at91sam9g45() \ + || cpu_is_at91sam9x5()) /* USB host HS & FS */ #define cpu_has_uhp() (!cpu_is_at91sam9rl()) /* USB device FS only */ #define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \ - || cpu_is_at91sam9g45())) + || cpu_is_at91sam9g45() \ + || cpu_is_at91sam9x5())) + +#define cpu_has_plladiv2() (cpu_is_at91sam9g45() \ + || cpu_is_at91sam9x5()) + +#define cpu_has_mdiv3() (cpu_is_at91sam9g45() \ + || cpu_is_at91sam9x5()) + +#define cpu_has_alt_prescaler() (cpu_is_at91sam9x5()) static LIST_HEAD(clocks); static DEFINE_SPINLOCK(clk_lock); @@ -111,11 +127,11 @@ static void pllb_mode(struct clk *clk, int is_on) value = 0; // REVISIT: Add work-around for AT91RM9200 Errata #26 ? - at91_sys_write(AT91_CKGR_PLLBR, value); + at91_pmc_write(AT91_CKGR_PLLBR, value); do { cpu_relax(); - } while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKB) != is_on); + } while ((at91_pmc_read(AT91_PMC_SR) & AT91_PMC_LOCKB) != is_on); } static struct clk pllb = { @@ -130,31 +146,24 @@ static struct clk pllb = { static void pmc_sys_mode(struct clk *clk, int is_on) { if (is_on) - at91_sys_write(AT91_PMC_SCER, clk->pmc_mask); + at91_pmc_write(AT91_PMC_SCER, clk->pmc_mask); else - at91_sys_write(AT91_PMC_SCDR, clk->pmc_mask); + at91_pmc_write(AT91_PMC_SCDR, clk->pmc_mask); } static void pmc_uckr_mode(struct clk *clk, int is_on) { - unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR); - - if (cpu_is_at91sam9g45()) { - if (is_on) - uckr |= AT91_PMC_BIASEN; - else - uckr &= ~AT91_PMC_BIASEN; - } + unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR); if (is_on) { is_on = AT91_PMC_LOCKU; - at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask); + at91_pmc_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask); } else - at91_sys_write(AT91_CKGR_UCKR, uckr & ~(clk->pmc_mask)); + at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(clk->pmc_mask)); do { cpu_relax(); - } while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKU) != is_on); + } while ((at91_pmc_read(AT91_PMC_SR) & AT91_PMC_LOCKU) != is_on); } /* USB function clocks (PLLB must be 48 MHz) */ @@ -190,9 +199,9 @@ struct clk mck = { static void pmc_periph_mode(struct clk *clk, int is_on) { if (is_on) - at91_sys_write(AT91_PMC_PCER, clk->pmc_mask); + at91_pmc_write(AT91_PMC_PCER, clk->pmc_mask); else - at91_sys_write(AT91_PMC_PCDR, clk->pmc_mask); + at91_pmc_write(AT91_PMC_PCDR, clk->pmc_mask); } static struct clk __init *at91_css_to_clk(unsigned long css) @@ -210,11 +219,24 @@ static struct clk __init *at91_css_to_clk(unsigned long css) return &utmi_clk; else if (cpu_has_pllb()) return &pllb; + break; + /* alternate PMC: can use master clock */ + case AT91_PMC_CSS_MASTER: + return &mck; } return NULL; } +static int pmc_prescaler_divider(u32 reg) +{ + if (cpu_has_alt_prescaler()) { + return 1 << ((reg & AT91_PMC_ALT_PRES) >> PMC_ALT_PRES_OFFSET); + } else { + return 1 << ((reg & AT91_PMC_PRES) >> PMC_PRES_OFFSET); + } +} + static void __clk_enable(struct clk *clk) { if (clk->parent) @@ -316,12 +338,22 @@ int clk_set_rate(struct clk *clk, unsigned long rate) { unsigned long flags; unsigned prescale; + unsigned long prescale_offset, css_mask; unsigned long actual; if (!clk_is_programmable(clk)) return -EINVAL; if (clk->users) return -EBUSY; + + if (cpu_has_alt_prescaler()) { + prescale_offset = PMC_ALT_PRES_OFFSET; + css_mask = AT91_PMC_ALT_PCKR_CSS; + } else { + prescale_offset = PMC_PRES_OFFSET; + css_mask = AT91_PMC_CSS; + } + spin_lock_irqsave(&clk_lock, flags); actual = clk->parent->rate_hz; @@ -329,10 +361,10 @@ int clk_set_rate(struct clk *clk, unsigned long rate) if (actual && actual <= rate) { u32 pckr; - pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); - pckr &= AT91_PMC_CSS; /* clock selection */ - pckr |= prescale << 2; - at91_sys_write(AT91_PMC_PCKR(clk->id), pckr); + pckr = at91_pmc_read(AT91_PMC_PCKR(clk->id)); + pckr &= css_mask; /* keep clock selection */ + pckr |= prescale << prescale_offset; + at91_pmc_write(AT91_PMC_PCKR(clk->id), pckr); clk->rate_hz = actual; break; } @@ -366,7 +398,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent) clk->rate_hz = parent->rate_hz; clk->parent = parent; - at91_sys_write(AT91_PMC_PCKR(clk->id), parent->id); + at91_pmc_write(AT91_PMC_PCKR(clk->id), parent->id); spin_unlock_irqrestore(&clk_lock, flags); return 0; @@ -378,11 +410,17 @@ static void __init init_programmable_clock(struct clk *clk) { struct clk *parent; u32 pckr; + unsigned int css_mask; + + if (cpu_has_alt_prescaler()) + css_mask = AT91_PMC_ALT_PCKR_CSS; + else + css_mask = AT91_PMC_CSS; - pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); - parent = at91_css_to_clk(pckr & AT91_PMC_CSS); + pckr = at91_pmc_read(AT91_PMC_PCKR(clk->id)); + parent = at91_css_to_clk(pckr & css_mask); clk->parent = parent; - clk->rate_hz = parent->rate_hz / (1 << ((pckr & AT91_PMC_PRES) >> 2)); + clk->rate_hz = parent->rate_hz / pmc_prescaler_divider(pckr); } #endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ @@ -396,19 +434,24 @@ static int at91_clk_show(struct seq_file *s, void *unused) u32 scsr, pcsr, uckr = 0, sr; struct clk *clk; - seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR)); - seq_printf(s, "PCSR = %8x\n", pcsr = at91_sys_read(AT91_PMC_PCSR)); - seq_printf(s, "MOR = %8x\n", at91_sys_read(AT91_CKGR_MOR)); - seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR)); - seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR)); + scsr = at91_pmc_read(AT91_PMC_SCSR); + pcsr = at91_pmc_read(AT91_PMC_PCSR); + sr = at91_pmc_read(AT91_PMC_SR); + seq_printf(s, "SCSR = %8x\n", scsr); + seq_printf(s, "PCSR = %8x\n", pcsr); + seq_printf(s, "MOR = %8x\n", at91_pmc_read(AT91_CKGR_MOR)); + seq_printf(s, "MCFR = %8x\n", at91_pmc_read(AT91_CKGR_MCFR)); + seq_printf(s, "PLLA = %8x\n", at91_pmc_read(AT91_CKGR_PLLAR)); if (cpu_has_pllb()) - seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR)); - if (cpu_has_utmi()) - seq_printf(s, "UCKR = %8x\n", uckr = at91_sys_read(AT91_CKGR_UCKR)); - seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR)); + seq_printf(s, "PLLB = %8x\n", at91_pmc_read(AT91_CKGR_PLLBR)); + if (cpu_has_utmi()) { + uckr = at91_pmc_read(AT91_CKGR_UCKR); + seq_printf(s, "UCKR = %8x\n", uckr); + } + seq_printf(s, "MCKR = %8x\n", at91_pmc_read(AT91_PMC_MCKR)); if (cpu_has_upll()) - seq_printf(s, "USB = %8x\n", at91_sys_read(AT91_PMC_USB)); - seq_printf(s, "SR = %8x\n", sr = at91_sys_read(AT91_PMC_SR)); + seq_printf(s, "USB = %8x\n", at91_pmc_read(AT91_PMC_USB)); + seq_printf(s, "SR = %8x\n", sr); seq_printf(s, "\n"); @@ -596,16 +639,14 @@ static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock) if (cpu_is_at91rm9200()) { uhpck.pmc_mask = AT91RM9200_PMC_UHP; udpck.pmc_mask = AT91RM9200_PMC_UDP; - at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); + at91_pmc_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20() || cpu_is_at91sam9g10()) { uhpck.pmc_mask = AT91SAM926x_PMC_UHP; udpck.pmc_mask = AT91SAM926x_PMC_UDP; - } else if (cpu_is_at91cap9()) { - uhpck.pmc_mask = AT91CAP9_PMC_UHP; } - at91_sys_write(AT91_CKGR_PLLBR, 0); + at91_pmc_write(AT91_CKGR_PLLBR, 0); udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); @@ -622,16 +663,16 @@ static void __init at91_upll_usbfs_clock_init(unsigned long main_clock) /* Setup divider by 10 to reach 48 MHz */ usbr |= ((10 - 1) << 8) & AT91_PMC_OHCIUSBDIV; - at91_sys_write(AT91_PMC_USB, usbr); + at91_pmc_write(AT91_PMC_USB, usbr); /* Now set uhpck values */ uhpck.parent = &utmi_clk; uhpck.pmc_mask = AT91SAM926x_PMC_UHP; uhpck.rate_hz = utmi_clk.rate_hz; - uhpck.rate_hz /= 1 + ((at91_sys_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8); + uhpck.rate_hz /= 1 + ((at91_pmc_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8); } -int __init at91_clock_init(unsigned long main_clock) +static int __init at91_pmc_init(unsigned long main_clock) { unsigned tmp, freq, mckr; int i; @@ -645,14 +686,14 @@ int __init at91_clock_init(unsigned long main_clock) */ if (!main_clock) { do { - tmp = at91_sys_read(AT91_CKGR_MCFR); + tmp = at91_pmc_read(AT91_CKGR_MCFR); } while (!(tmp & AT91_PMC_MAINRDY)); main_clock = (tmp & AT91_PMC_MAINF) * (AT91_SLOW_CLOCK / 16); } main_clk.rate_hz = main_clock; /* report if PLLA is more than mildly overclocked */ - plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR)); + plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_pmc_read(AT91_CKGR_PLLAR)); if (cpu_has_300M_plla()) { if (plla.rate_hz > 300000000) pll_overclock = true; @@ -666,8 +707,8 @@ int __init at91_clock_init(unsigned long main_clock) if (pll_overclock) pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000); - if (cpu_is_at91sam9g45()) { - mckr = at91_sys_read(AT91_PMC_MCKR); + if (cpu_has_plladiv2()) { + mckr = at91_pmc_read(AT91_PMC_MCKR); plla.rate_hz /= (1 << ((mckr & AT91_PMC_PLLADIV2) >> 12)); /* plla divisor by 2 */ } @@ -688,6 +729,10 @@ int __init at91_clock_init(unsigned long main_clock) * (obtain the USB High Speed 480 MHz when input is 12 MHz) */ utmi_clk.rate_hz = 40 * utmi_clk.parent->rate_hz; + + /* UTMI bias and PLL are managed at the same time */ + if (cpu_has_upll()) + utmi_clk.pmc_mask |= AT91_PMC_BIASEN; } /* @@ -703,10 +748,10 @@ int __init at91_clock_init(unsigned long main_clock) * MCK and CPU derive from one of those primary clocks. * For now, assume this parentage won't change. */ - mckr = at91_sys_read(AT91_PMC_MCKR); + mckr = at91_pmc_read(AT91_PMC_MCKR); mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS); freq = mck.parent->rate_hz; - freq /= (1 << ((mckr & AT91_PMC_PRES) >> 2)); /* prescale */ + freq /= pmc_prescaler_divider(mckr); /* prescale */ if (cpu_is_at91rm9200()) { mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ } else if (cpu_is_at91sam9g20()) { @@ -714,13 +759,19 @@ int __init at91_clock_init(unsigned long main_clock) freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */ if (mckr & AT91_PMC_PDIV) freq /= 2; /* processor clock division */ - } else if (cpu_is_at91sam9g45()) { + } else if (cpu_has_mdiv3()) { mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ? freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ } else { mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ } + if (cpu_has_alt_prescaler()) { + /* Programmable clocks can use MCK */ + mck.type |= CLK_TYPE_PRIMARY; + mck.id = 4; + } + /* Register the PMC's standard clocks */ for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) at91_clk_add(standard_pmc_clocks[i]); @@ -748,6 +799,55 @@ int __init at91_clock_init(unsigned long main_clock) return 0; } +#if defined(CONFIG_OF) +static struct of_device_id pmc_ids[] = { + { .compatible = "atmel,at91rm9200-pmc" }, + { /*sentinel*/ } +}; + +static struct of_device_id osc_ids[] = { + { .compatible = "atmel,osc" }, + { /*sentinel*/ } +}; + +int __init at91_dt_clock_init(void) +{ + struct device_node *np; + u32 main_clock = 0; + + np = of_find_matching_node(NULL, pmc_ids); + if (!np) + panic("unable to find compatible pmc node in dtb\n"); + + at91_pmc_base = of_iomap(np, 0); + if (!at91_pmc_base) + panic("unable to map pmc cpu registers\n"); + + of_node_put(np); + + /* retrieve the freqency of fixed clocks from device tree */ + np = of_find_matching_node(NULL, osc_ids); + if (np) { + u32 rate; + if (!of_property_read_u32(np, "clock-frequency", &rate)) + main_clock = rate; + } + + of_node_put(np); + + return at91_pmc_init(main_clock); +} +#endif + +int __init at91_clock_init(unsigned long main_clock) +{ + at91_pmc_base = ioremap(AT91_PMC, 256); + if (!at91_pmc_base) + panic("Impossible to ioremap AT91_PMC 0x%x\n", AT91_PMC); + + return at91_pmc_init(main_clock); +} + /* * Several unused clocks may be active. Turn them off. */ @@ -770,9 +870,15 @@ static int __init at91_clock_reset(void) pr_debug("Clocks: disable unused %s\n", clk->name); } - at91_sys_write(AT91_PMC_PCDR, pcdr); - at91_sys_write(AT91_PMC_SCDR, scdr); + at91_pmc_write(AT91_PMC_PCDR, pcdr); + at91_pmc_write(AT91_PMC_SCDR, scdr); return 0; } late_initcall(at91_clock_reset); + +void at91sam9_idle(void) +{ + at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK); + cpu_do_idle(); +} diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c index a851e6c98421..ece1f9aefb47 100644 --- a/arch/arm/mach-at91/cpuidle.c +++ b/arch/arm/mach-at91/cpuidle.c @@ -17,9 +17,10 @@ #include <linux/init.h> #include <linux/platform_device.h> #include <linux/cpuidle.h> -#include <asm/proc-fns.h> #include <linux/io.h> #include <linux/export.h> +#include <asm/proc-fns.h> +#include <asm/cpuidle.h> #include "pm.h" @@ -27,66 +28,39 @@ static DEFINE_PER_CPU(struct cpuidle_device, at91_cpuidle_device); -static struct cpuidle_driver at91_idle_driver = { - .name = "at91_idle", - .owner = THIS_MODULE, -}; - /* Actual code that puts the SoC in different idle states */ static int at91_enter_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { - struct timeval before, after; - int idle_time; - u32 saved_lpr; - - local_irq_disable(); - do_gettimeofday(&before); - if (index == 0) - /* Wait for interrupt state */ - cpu_do_idle(); - else if (index == 1) { - asm("b 1f; .align 5; 1:"); - asm("mcr p15, 0, r0, c7, c10, 4"); /* drain write buffer */ - saved_lpr = sdram_selfrefresh_enable(); - cpu_do_idle(); - sdram_selfrefresh_disable(saved_lpr); - } - do_gettimeofday(&after); - local_irq_enable(); - idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + - (after.tv_usec - before.tv_usec); + at91_standby(); - dev->last_residency = idle_time; return index; } +static struct cpuidle_driver at91_idle_driver = { + .name = "at91_idle", + .owner = THIS_MODULE, + .en_core_tk_irqen = 1, + .states[0] = ARM_CPUIDLE_WFI_STATE, + .states[1] = { + .enter = at91_enter_idle, + .exit_latency = 10, + .target_residency = 100000, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "RAM_SR", + .desc = "WFI and DDR Self Refresh", + }, + .state_count = AT91_MAX_STATES, +}; + /* Initialize CPU idle by registering the idle states */ static int at91_init_cpuidle(void) { struct cpuidle_device *device; - struct cpuidle_driver *driver = &at91_idle_driver; device = &per_cpu(at91_cpuidle_device, smp_processor_id()); device->state_count = AT91_MAX_STATES; - driver->state_count = AT91_MAX_STATES; - - /* Wait for interrupt state */ - driver->states[0].enter = at91_enter_idle; - driver->states[0].exit_latency = 1; - driver->states[0].target_residency = 10000; - driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID; - strcpy(driver->states[0].name, "WFI"); - strcpy(driver->states[0].desc, "Wait for interrupt"); - - /* Wait for interrupt and RAM self refresh state */ - driver->states[1].enter = at91_enter_idle; - driver->states[1].exit_latency = 10; - driver->states[1].target_residency = 10000; - driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID; - strcpy(driver->states[1].name, "RAM_SR"); - strcpy(driver->states[1].desc, "WFI and RAM Self Refresh"); cpuidle_register_driver(&at91_idle_driver); diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index 594133451c0c..dd9b346c451d 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h @@ -9,6 +9,7 @@ */ #include <linux/clkdev.h> +#include <linux/of.h> /* Map io */ extern void __init at91_map_io(void); @@ -19,15 +20,20 @@ extern void __init at91_init_sram(int bank, unsigned long base, extern void __init at91rm9200_set_type(int type); extern void __init at91_initialize(unsigned long main_clock); extern void __init at91x40_initialize(unsigned long main_clock); +extern void __init at91_dt_initialize(void); /* Interrupts */ extern void __init at91_init_irq_default(void); extern void __init at91_init_interrupts(unsigned int priority[]); extern void __init at91x40_init_interrupts(unsigned int priority[]); extern void __init at91_aic_init(unsigned int priority[]); +extern int __init at91_aic_of_init(struct device_node *node, + struct device_node *parent); + /* Timer */ struct sys_timer; +extern void at91rm9200_ioremap_st(u32 addr); extern struct sys_timer at91rm9200_timer; extern void at91sam926x_ioremap_pit(u32 addr); extern struct sys_timer at91sam926x_timer; @@ -45,9 +51,9 @@ extern void __init at91sam9261_set_console_clock(int id); extern void __init at91sam9263_set_console_clock(int id); extern void __init at91sam9rl_set_console_clock(int id); extern void __init at91sam9g45_set_console_clock(int id); -extern void __init at91cap9_set_console_clock(int id); #ifdef CONFIG_AT91_PMC_UNIT extern int __init at91_clock_init(unsigned long main_clock); +extern int __init at91_dt_clock_init(void); #else static int inline at91_clock_init(unsigned long main_clock) { return 0; } #endif @@ -57,6 +63,9 @@ struct device; extern void at91_irq_suspend(void); extern void at91_irq_resume(void); +/* idle */ +extern void at91sam9_idle(void); + /* reset */ extern void at91_ioremap_rstc(u32 base_addr); extern void at91sam9_alt_restart(char, const char *); @@ -65,6 +74,12 @@ extern void at91sam9g45_restart(char, const char *); /* shutdown */ extern void at91_ioremap_shdwc(u32 base_addr); +/* Matrix */ +extern void at91_ioremap_matrix(u32 base_addr); + +/* Ram Controler */ +extern void at91_ioremap_ramc(int id, u32 addr, u32 size); + /* GPIO */ #define AT91RM9200_PQFP 3 /* AT91RM9200 PQFP package has 3 banks */ #define AT91RM9200_BGA 4 /* AT91RM9200 BGA package has 4 banks */ @@ -75,5 +90,7 @@ struct at91_gpio_bank { }; extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks); extern void __init at91_gpio_irq_setup(void); +extern int __init at91_gpio_of_irq_setup(struct device_node *node, + struct device_node *parent); extern int at91_extern_irq; diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index 74d6783eeabb..325837a264c9 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -11,6 +11,7 @@ #include <linux/clk.h> #include <linux/errno.h> +#include <linux/device.h> #include <linux/gpio.h> #include <linux/interrupt.h> #include <linux/irq.h> @@ -20,6 +21,10 @@ #include <linux/list.h> #include <linux/module.h> #include <linux/io.h> +#include <linux/irqdomain.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/of_gpio.h> #include <mach/hardware.h> #include <mach/at91_pio.h> @@ -29,9 +34,12 @@ struct at91_gpio_chip { struct gpio_chip chip; struct at91_gpio_chip *next; /* Bank sharing same clock */ - int id; /* ID of register bank */ - void __iomem *regbase; /* Base of register bank */ + int pioc_hwirq; /* PIO bank interrupt identifier on AIC */ + int pioc_virq; /* PIO bank Linux virtual interrupt */ + int pioc_idx; /* PIO bank index */ + void __iomem *regbase; /* PIO bank virtual address */ struct clk *clock; /* associated clock */ + struct irq_domain *domain; /* associated irq domain */ }; #define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip) @@ -43,8 +51,9 @@ static int at91_gpiolib_direction_output(struct gpio_chip *chip, unsigned offset, int val); static int at91_gpiolib_direction_input(struct gpio_chip *chip, unsigned offset); +static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset); -#define AT91_GPIO_CHIP(name, base_gpio, nr_gpio) \ +#define AT91_GPIO_CHIP(name, nr_gpio) \ { \ .chip = { \ .label = name, \ @@ -53,20 +62,28 @@ static int at91_gpiolib_direction_input(struct gpio_chip *chip, .get = at91_gpiolib_get, \ .set = at91_gpiolib_set, \ .dbg_show = at91_gpiolib_dbg_show, \ - .base = base_gpio, \ + .to_irq = at91_gpiolib_to_irq, \ .ngpio = nr_gpio, \ }, \ } static struct at91_gpio_chip gpio_chip[] = { - AT91_GPIO_CHIP("pioA", 0x00, 32), - AT91_GPIO_CHIP("pioB", 0x20, 32), - AT91_GPIO_CHIP("pioC", 0x40, 32), - AT91_GPIO_CHIP("pioD", 0x60, 32), - AT91_GPIO_CHIP("pioE", 0x80, 32), + AT91_GPIO_CHIP("pioA", 32), + AT91_GPIO_CHIP("pioB", 32), + AT91_GPIO_CHIP("pioC", 32), + AT91_GPIO_CHIP("pioD", 32), + AT91_GPIO_CHIP("pioE", 32), }; static int gpio_banks; +static unsigned long at91_gpio_caps; + +/* All PIO controllers support PIO3 features */ +#define AT91_GPIO_CAP_PIO3 (1 << 0) + +#define has_pio3() (at91_gpio_caps & AT91_GPIO_CAP_PIO3) + +/*--------------------------------------------------------------------------*/ static inline void __iomem *pin_to_controller(unsigned pin) { @@ -83,6 +100,25 @@ static inline unsigned pin_to_mask(unsigned pin) } +static char peripheral_function(void __iomem *pio, unsigned mask) +{ + char ret = 'X'; + u8 select; + + if (pio) { + if (has_pio3()) { + select = !!(__raw_readl(pio + PIO_ABCDSR1) & mask); + select |= (!!(__raw_readl(pio + PIO_ABCDSR2) & mask) << 1); + ret = 'A' + select; + } else { + ret = __raw_readl(pio + PIO_ABSR) & mask ? + 'B' : 'A'; + } + } + + return ret; +} + /*--------------------------------------------------------------------------*/ /* Not all hardware capabilities are exposed through these calls; they @@ -130,7 +166,14 @@ int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup) __raw_writel(mask, pio + PIO_IDR); __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); - __raw_writel(mask, pio + PIO_ASR); + if (has_pio3()) { + __raw_writel(__raw_readl(pio + PIO_ABCDSR1) & ~mask, + pio + PIO_ABCDSR1); + __raw_writel(__raw_readl(pio + PIO_ABCDSR2) & ~mask, + pio + PIO_ABCDSR2); + } else { + __raw_writel(mask, pio + PIO_ASR); + } __raw_writel(mask, pio + PIO_PDR); return 0; } @@ -150,7 +193,14 @@ int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup) __raw_writel(mask, pio + PIO_IDR); __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); - __raw_writel(mask, pio + PIO_BSR); + if (has_pio3()) { + __raw_writel(__raw_readl(pio + PIO_ABCDSR1) | mask, + pio + PIO_ABCDSR1); + __raw_writel(__raw_readl(pio + PIO_ABCDSR2) & ~mask, + pio + PIO_ABCDSR2); + } else { + __raw_writel(mask, pio + PIO_BSR); + } __raw_writel(mask, pio + PIO_PDR); return 0; } @@ -158,8 +208,50 @@ EXPORT_SYMBOL(at91_set_B_periph); /* - * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and - * configure it for an input. + * mux the pin to the "C" internal peripheral role. + */ +int __init_or_module at91_set_C_periph(unsigned pin, int use_pullup) +{ + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio || !has_pio3()) + return -EINVAL; + + __raw_writel(mask, pio + PIO_IDR); + __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); + __raw_writel(__raw_readl(pio + PIO_ABCDSR1) & ~mask, pio + PIO_ABCDSR1); + __raw_writel(__raw_readl(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2); + __raw_writel(mask, pio + PIO_PDR); + return 0; +} +EXPORT_SYMBOL(at91_set_C_periph); + + +/* + * mux the pin to the "D" internal peripheral role. + */ +int __init_or_module at91_set_D_periph(unsigned pin, int use_pullup) +{ + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio || !has_pio3()) + return -EINVAL; + + __raw_writel(mask, pio + PIO_IDR); + __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); + __raw_writel(__raw_readl(pio + PIO_ABCDSR1) | mask, pio + PIO_ABCDSR1); + __raw_writel(__raw_readl(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2); + __raw_writel(mask, pio + PIO_PDR); + return 0; +} +EXPORT_SYMBOL(at91_set_D_periph); + + +/* + * mux the pin to the gpio controller (instead of "A", "B", "C" + * or "D" peripheral), and configure it for an input. */ int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup) { @@ -179,8 +271,8 @@ EXPORT_SYMBOL(at91_set_gpio_input); /* - * mux the pin to the gpio controller (instead of "A" or "B" peripheral), - * and configure it for an output. + * mux the pin to the gpio controller (instead of "A", "B", "C" + * or "D" peripheral), and configure it for an output. */ int __init_or_module at91_set_gpio_output(unsigned pin, int value) { @@ -210,12 +302,37 @@ int __init_or_module at91_set_deglitch(unsigned pin, int is_on) if (!pio) return -EINVAL; + + if (has_pio3() && is_on) + __raw_writel(mask, pio + PIO_IFSCDR); __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR)); return 0; } EXPORT_SYMBOL(at91_set_deglitch); /* + * enable/disable the debounce filter; + */ +int __init_or_module at91_set_debounce(unsigned pin, int is_on, int div) +{ + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio || !has_pio3()) + return -EINVAL; + + if (is_on) { + __raw_writel(mask, pio + PIO_IFSCER); + __raw_writel(div & PIO_SCDR_DIV, pio + PIO_SCDR); + __raw_writel(mask, pio + PIO_IFER); + } else { + __raw_writel(mask, pio + PIO_IFDR); + } + return 0; +} +EXPORT_SYMBOL(at91_set_debounce); + +/* * enable/disable the multi-driver; This is only valid for output and * allows the output pin to run as an open collector output. */ @@ -233,6 +350,41 @@ int __init_or_module at91_set_multi_drive(unsigned pin, int is_on) EXPORT_SYMBOL(at91_set_multi_drive); /* + * enable/disable the pull-down. + * If pull-up already enabled while calling the function, we disable it. + */ +int __init_or_module at91_set_pulldown(unsigned pin, int is_on) +{ + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio || !has_pio3()) + return -EINVAL; + + /* Disable pull-up anyway */ + __raw_writel(mask, pio + PIO_PUDR); + __raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR)); + return 0; +} +EXPORT_SYMBOL(at91_set_pulldown); + +/* + * disable Schmitt trigger + */ +int __init_or_module at91_disable_schmitt_trig(unsigned pin) +{ + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio || !has_pio3()) + return -EINVAL; + + __raw_writel(__raw_readl(pio + PIO_SCHMITT) | mask, pio + PIO_SCHMITT); + return 0; +} +EXPORT_SYMBOL(at91_disable_schmitt_trig); + +/* * assuming the pin is muxed as a gpio output, set its value. */ int at91_set_gpio_value(unsigned pin, int value) @@ -273,9 +425,9 @@ static u32 backups[MAX_GPIO_BANKS]; static int gpio_irq_set_wake(struct irq_data *d, unsigned state) { - unsigned pin = irq_to_gpio(d->irq); - unsigned mask = pin_to_mask(pin); - unsigned bank = pin / 32; + struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); + unsigned mask = 1 << d->hwirq; + unsigned bank = at91_gpio->pioc_idx; if (unlikely(bank >= MAX_GPIO_BANKS)) return -EINVAL; @@ -285,7 +437,7 @@ static int gpio_irq_set_wake(struct irq_data *d, unsigned state) else wakeups[bank] &= ~mask; - irq_set_irq_wake(gpio_chip[bank].id, state); + irq_set_irq_wake(at91_gpio->pioc_virq, state); return 0; } @@ -301,9 +453,10 @@ void at91_gpio_suspend(void) __raw_writel(backups[i], pio + PIO_IDR); __raw_writel(wakeups[i], pio + PIO_IER); - if (!wakeups[i]) + if (!wakeups[i]) { + clk_unprepare(gpio_chip[i].clock); clk_disable(gpio_chip[i].clock); - else { + } else { #ifdef CONFIG_PM_DEBUG printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]); #endif @@ -318,8 +471,10 @@ void at91_gpio_resume(void) for (i = 0; i < gpio_banks; i++) { void __iomem *pio = gpio_chip[i].regbase; - if (!wakeups[i]) - clk_enable(gpio_chip[i].clock); + if (!wakeups[i]) { + if (clk_prepare(gpio_chip[i].clock) == 0) + clk_enable(gpio_chip[i].clock); + } __raw_writel(wakeups[i], pio + PIO_IDR); __raw_writel(backups[i], pio + PIO_IER); @@ -335,7 +490,10 @@ void at91_gpio_resume(void) * To use any AT91_PIN_* as an externally triggered IRQ, first call * at91_set_gpio_input() then maybe enable its glitch filter. * Then just request_irq() with the pin ID; it works like any ARM IRQ - * handler, though it always triggers on rising and falling edges. + * handler. + * First implementation always triggers on rising and falling edges + * whereas the newer PIO3 can be additionally configured to trigger on + * level, edge with any polarity. * * Alternatively, certain pins may be used directly as IRQ0..IRQ6 after * configuring them with at91_set_a_periph() or at91_set_b_periph(). @@ -344,9 +502,9 @@ void at91_gpio_resume(void) static void gpio_irq_mask(struct irq_data *d) { - unsigned pin = irq_to_gpio(d->irq); - void __iomem *pio = pin_to_controller(pin); - unsigned mask = pin_to_mask(pin); + struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); + void __iomem *pio = at91_gpio->regbase; + unsigned mask = 1 << d->hwirq; if (pio) __raw_writel(mask, pio + PIO_IDR); @@ -354,9 +512,9 @@ static void gpio_irq_mask(struct irq_data *d) static void gpio_irq_unmask(struct irq_data *d) { - unsigned pin = irq_to_gpio(d->irq); - void __iomem *pio = pin_to_controller(pin); - unsigned mask = pin_to_mask(pin); + struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); + void __iomem *pio = at91_gpio->regbase; + unsigned mask = 1 << d->hwirq; if (pio) __raw_writel(mask, pio + PIO_IER); @@ -373,23 +531,66 @@ static int gpio_irq_type(struct irq_data *d, unsigned type) } } +/* Alternate irq type for PIO3 support */ +static int alt_gpio_irq_type(struct irq_data *d, unsigned type) +{ + struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); + void __iomem *pio = at91_gpio->regbase; + unsigned mask = 1 << d->hwirq; + + switch (type) { + case IRQ_TYPE_EDGE_RISING: + __raw_writel(mask, pio + PIO_ESR); + __raw_writel(mask, pio + PIO_REHLSR); + break; + case IRQ_TYPE_EDGE_FALLING: + __raw_writel(mask, pio + PIO_ESR); + __raw_writel(mask, pio + PIO_FELLSR); + break; + case IRQ_TYPE_LEVEL_LOW: + __raw_writel(mask, pio + PIO_LSR); + __raw_writel(mask, pio + PIO_FELLSR); + break; + case IRQ_TYPE_LEVEL_HIGH: + __raw_writel(mask, pio + PIO_LSR); + __raw_writel(mask, pio + PIO_REHLSR); + break; + case IRQ_TYPE_EDGE_BOTH: + /* + * disable additional interrupt modes: + * fall back to default behavior + */ + __raw_writel(mask, pio + PIO_AIMDR); + return 0; + case IRQ_TYPE_NONE: + default: + pr_warn("AT91: No type for irq %d\n", gpio_to_irq(d->irq)); + return -EINVAL; + } + + /* enable additional interrupt modes */ + __raw_writel(mask, pio + PIO_AIMER); + + return 0; +} + static struct irq_chip gpio_irqchip = { .name = "GPIO", .irq_disable = gpio_irq_mask, .irq_mask = gpio_irq_mask, .irq_unmask = gpio_irq_unmask, - .irq_set_type = gpio_irq_type, + /* .irq_set_type is set dynamically */ .irq_set_wake = gpio_irq_set_wake, }; static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) { - unsigned irq_pin; struct irq_data *idata = irq_desc_get_irq_data(desc); struct irq_chip *chip = irq_data_get_irq_chip(idata); struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata); void __iomem *pio = at91_gpio->regbase; - u32 isr; + unsigned long isr; + int n; /* temporarily mask (level sensitive) parent IRQ */ chip->irq_ack(idata); @@ -407,13 +608,10 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) continue; } - irq_pin = gpio_to_irq(at91_gpio->chip.base); - - while (isr) { - if (isr & 1) - generic_handle_irq(irq_pin); - irq_pin++; - isr >>= 1; + n = find_first_bit(&isr, BITS_PER_LONG); + while (n < BITS_PER_LONG) { + generic_handle_irq(irq_find_mapping(at91_gpio->domain, n)); + n = find_next_bit(&isr, BITS_PER_LONG, n + 1); } } chip->irq_unmask(idata); @@ -424,6 +622,33 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) #ifdef CONFIG_DEBUG_FS +static void gpio_printf(struct seq_file *s, void __iomem *pio, unsigned mask) +{ + char *trigger = NULL; + char *polarity = NULL; + + if (__raw_readl(pio + PIO_IMR) & mask) { + if (!has_pio3() || !(__raw_readl(pio + PIO_AIMMR) & mask )) { + trigger = "edge"; + polarity = "both"; + } else { + if (__raw_readl(pio + PIO_ELSR) & mask) { + trigger = "level"; + polarity = __raw_readl(pio + PIO_FRLHSR) & mask ? + "high" : "low"; + } else { + trigger = "edge"; + polarity = __raw_readl(pio + PIO_FRLHSR) & mask ? + "rising" : "falling"; + } + } + seq_printf(s, "IRQ:%s-%s\t", trigger, polarity); + } else { + seq_printf(s, "GPIO:%s\t\t", + __raw_readl(pio + PIO_PDSR) & mask ? "1" : "0"); + } +} + static int at91_gpio_show(struct seq_file *s, void *unused) { int bank, j; @@ -431,7 +656,7 @@ static int at91_gpio_show(struct seq_file *s, void *unused) /* print heading */ seq_printf(s, "Pin\t"); for (bank = 0; bank < gpio_banks; bank++) { - seq_printf(s, "PIO%c\t", 'A' + bank); + seq_printf(s, "PIO%c\t\t", 'A' + bank); }; seq_printf(s, "\n\n"); @@ -445,11 +670,10 @@ static int at91_gpio_show(struct seq_file *s, void *unused) unsigned mask = pin_to_mask(pin); if (__raw_readl(pio + PIO_PSR) & mask) - seq_printf(s, "GPIO:%s", __raw_readl(pio + PIO_PDSR) & mask ? "1" : "0"); + gpio_printf(s, pio, mask); else - seq_printf(s, "%s", __raw_readl(pio + PIO_ABSR) & mask ? "B" : "A"); - - seq_printf(s, "\t"); + seq_printf(s, "%c\t\t", + peripheral_function(pio, mask)); } seq_printf(s, "\n"); @@ -488,46 +712,152 @@ postcore_initcall(at91_gpio_debugfs_init); */ static struct lock_class_key gpio_lock_class; +#if defined(CONFIG_OF) +static int at91_gpio_irq_map(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw) +{ + struct at91_gpio_chip *at91_gpio = h->host_data; + + irq_set_lockdep_class(virq, &gpio_lock_class); + + /* + * Can use the "simple" and not "edge" handler since it's + * shorter, and the AIC handles interrupts sanely. + */ + irq_set_chip_and_handler(virq, &gpio_irqchip, + handle_simple_irq); + set_irq_flags(virq, IRQF_VALID); + irq_set_chip_data(virq, at91_gpio); + + return 0; +} + +static struct irq_domain_ops at91_gpio_ops = { + .map = at91_gpio_irq_map, + .xlate = irq_domain_xlate_twocell, +}; + +int __init at91_gpio_of_irq_setup(struct device_node *node, + struct device_node *parent) +{ + struct at91_gpio_chip *prev = NULL; + int alias_idx = of_alias_get_id(node, "gpio"); + struct at91_gpio_chip *at91_gpio = &gpio_chip[alias_idx]; + + /* Setup proper .irq_set_type function */ + if (has_pio3()) + gpio_irqchip.irq_set_type = alt_gpio_irq_type; + else + gpio_irqchip.irq_set_type = gpio_irq_type; + + /* Disable irqs of this PIO controller */ + __raw_writel(~0, at91_gpio->regbase + PIO_IDR); + + /* Setup irq domain */ + at91_gpio->domain = irq_domain_add_linear(node, at91_gpio->chip.ngpio, + &at91_gpio_ops, at91_gpio); + if (!at91_gpio->domain) + panic("at91_gpio.%d: couldn't allocate irq domain (DT).\n", + at91_gpio->pioc_idx); + + /* Setup chained handler */ + if (at91_gpio->pioc_idx) + prev = &gpio_chip[at91_gpio->pioc_idx - 1]; + + /* The toplevel handler handles one bank of GPIOs, except + * on some SoC it can handles up to three... + * We only set up the handler for the first of the list. + */ + if (prev && prev->next == at91_gpio) + return 0; + + at91_gpio->pioc_virq = irq_create_mapping(irq_find_host(parent), + at91_gpio->pioc_hwirq); + irq_set_chip_data(at91_gpio->pioc_virq, at91_gpio); + irq_set_chained_handler(at91_gpio->pioc_virq, gpio_irq_handler); + + return 0; +} +#else +int __init at91_gpio_of_irq_setup(struct device_node *node, + struct device_node *parent) +{ + return -EINVAL; +} +#endif + +/* + * irqdomain initialization: pile up irqdomains on top of AIC range + */ +static void __init at91_gpio_irqdomain(struct at91_gpio_chip *at91_gpio) +{ + int irq_base; + + irq_base = irq_alloc_descs(-1, 0, at91_gpio->chip.ngpio, 0); + if (irq_base < 0) + panic("at91_gpio.%d: error %d: couldn't allocate IRQ numbers.\n", + at91_gpio->pioc_idx, irq_base); + at91_gpio->domain = irq_domain_add_legacy(NULL, at91_gpio->chip.ngpio, + irq_base, 0, + &irq_domain_simple_ops, NULL); + if (!at91_gpio->domain) + panic("at91_gpio.%d: couldn't allocate irq domain.\n", + at91_gpio->pioc_idx); +} + /* * Called from the processor-specific init to enable GPIO interrupt support. */ void __init at91_gpio_irq_setup(void) { - unsigned pioc, irq = gpio_to_irq(0); + unsigned pioc; + int gpio_irqnbr = 0; struct at91_gpio_chip *this, *prev; + /* Setup proper .irq_set_type function */ + if (has_pio3()) + gpio_irqchip.irq_set_type = alt_gpio_irq_type; + else + gpio_irqchip.irq_set_type = gpio_irq_type; + for (pioc = 0, this = gpio_chip, prev = NULL; pioc++ < gpio_banks; prev = this, this++) { - unsigned id = this->id; - unsigned i; + int offset; __raw_writel(~0, this->regbase + PIO_IDR); - for (i = 0, irq = gpio_to_irq(this->chip.base); i < 32; - i++, irq++) { - irq_set_lockdep_class(irq, &gpio_lock_class); + /* setup irq domain for this GPIO controller */ + at91_gpio_irqdomain(this); + + for (offset = 0; offset < this->chip.ngpio; offset++) { + unsigned int virq = irq_find_mapping(this->domain, offset); + irq_set_lockdep_class(virq, &gpio_lock_class); /* * Can use the "simple" and not "edge" handler since it's * shorter, and the AIC handles interrupts sanely. */ - irq_set_chip_and_handler(irq, &gpio_irqchip, + irq_set_chip_and_handler(virq, &gpio_irqchip, handle_simple_irq); - set_irq_flags(irq, IRQF_VALID); + set_irq_flags(virq, IRQF_VALID); + irq_set_chip_data(virq, this); + + gpio_irqnbr++; } /* The toplevel handler handles one bank of GPIOs, except - * AT91SAM9263_ID_PIOCDE handles three... PIOC is first in - * the list, so we only set up that handler. + * on some SoC it can handles up to three... + * We only set up the handler for the first of the list. */ if (prev && prev->next == this) continue; - irq_set_chip_data(id, this); - irq_set_chained_handler(id, gpio_irq_handler); + this->pioc_virq = irq_create_mapping(NULL, this->pioc_hwirq); + irq_set_chip_data(this->pioc_virq, this); + irq_set_chained_handler(this->pioc_virq, gpio_irq_handler); } - pr_info("AT91: %d gpio irqs in %d banks\n", irq - gpio_to_irq(0), gpio_banks); + pr_info("AT91: %d gpio irqs in %d banks\n", gpio_irqnbr, gpio_banks); } /* gpiolib support */ @@ -593,48 +923,175 @@ static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) at91_get_gpio_value(pin) ? "set" : "clear"); else - seq_printf(s, "[periph %s]\n", - __raw_readl(pio + PIO_ABSR) & - mask ? "B" : "A"); + seq_printf(s, "[periph %c]\n", + peripheral_function(pio, mask)); } } } +static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset) +{ + struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); + int virq; + + if (offset < chip->ngpio) + virq = irq_create_mapping(at91_gpio->domain, offset); + else + virq = -ENXIO; + + dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n", + chip->label, offset + chip->base, virq); + return virq; +} + +static int __init at91_gpio_setup_clk(int idx) +{ + struct at91_gpio_chip *at91_gpio = &gpio_chip[idx]; + + /* retreive PIO controller's clock */ + at91_gpio->clock = clk_get_sys(NULL, at91_gpio->chip.label); + if (IS_ERR(at91_gpio->clock)) { + pr_err("at91_gpio.%d, failed to get clock, ignoring.\n", idx); + goto err; + } + + if (clk_prepare(at91_gpio->clock)) + goto clk_prep_err; + + /* enable PIO controller's clock */ + if (clk_enable(at91_gpio->clock)) { + pr_err("at91_gpio.%d, failed to enable clock, ignoring.\n", idx); + goto clk_err; + } + + return 0; + +clk_err: + clk_unprepare(at91_gpio->clock); +clk_prep_err: + clk_put(at91_gpio->clock); +err: + return -EINVAL; +} + +#ifdef CONFIG_OF_GPIO +static void __init of_at91_gpio_init_one(struct device_node *np) +{ + int alias_idx; + struct at91_gpio_chip *at91_gpio; + + if (!np) + return; + + alias_idx = of_alias_get_id(np, "gpio"); + if (alias_idx >= MAX_GPIO_BANKS) { + pr_err("at91_gpio, failed alias idx(%d) > MAX_GPIO_BANKS(%d), ignoring.\n", + alias_idx, MAX_GPIO_BANKS); + return; + } + + at91_gpio = &gpio_chip[alias_idx]; + at91_gpio->chip.base = alias_idx * at91_gpio->chip.ngpio; + + at91_gpio->regbase = of_iomap(np, 0); + if (!at91_gpio->regbase) { + pr_err("at91_gpio.%d, failed to map registers, ignoring.\n", + alias_idx); + return; + } + + /* Get the interrupts property */ + if (of_property_read_u32(np, "interrupts", &at91_gpio->pioc_hwirq)) { + pr_err("at91_gpio.%d, failed to get interrupts property, ignoring.\n", + alias_idx); + goto ioremap_err; + } + + /* Get capabilities from compatibility property */ + if (of_device_is_compatible(np, "atmel,at91sam9x5-gpio")) + at91_gpio_caps |= AT91_GPIO_CAP_PIO3; + + /* Setup clock */ + if (at91_gpio_setup_clk(alias_idx)) + goto ioremap_err; + + at91_gpio->chip.of_node = np; + gpio_banks = max(gpio_banks, alias_idx + 1); + at91_gpio->pioc_idx = alias_idx; + return; + +ioremap_err: + iounmap(at91_gpio->regbase); +} + +static int __init of_at91_gpio_init(void) +{ + struct device_node *np = NULL; + + /* + * This isn't ideal, but it gets things hooked up until this + * driver is converted into a platform_device + */ + for_each_compatible_node(np, NULL, "atmel,at91rm9200-gpio") + of_at91_gpio_init_one(np); + + return gpio_banks > 0 ? 0 : -EINVAL; +} +#else +static int __init of_at91_gpio_init(void) +{ + return -EINVAL; +} +#endif + +static void __init at91_gpio_init_one(int idx, u32 regbase, int pioc_hwirq) +{ + struct at91_gpio_chip *at91_gpio = &gpio_chip[idx]; + + at91_gpio->chip.base = idx * at91_gpio->chip.ngpio; + at91_gpio->pioc_hwirq = pioc_hwirq; + at91_gpio->pioc_idx = idx; + + at91_gpio->regbase = ioremap(regbase, 512); + if (!at91_gpio->regbase) { + pr_err("at91_gpio.%d, failed to map registers, ignoring.\n", idx); + return; + } + + if (at91_gpio_setup_clk(idx)) + goto ioremap_err; + + gpio_banks = max(gpio_banks, idx + 1); + return; + +ioremap_err: + iounmap(at91_gpio->regbase); +} + /* * Called from the processor-specific init to enable GPIO pin support. */ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) { - unsigned i; + unsigned i; struct at91_gpio_chip *at91_gpio, *last = NULL; BUG_ON(nr_banks > MAX_GPIO_BANKS); - gpio_banks = nr_banks; + if (of_at91_gpio_init() < 0) { + /* No GPIO controller found in device tree */ + for (i = 0; i < nr_banks; i++) + at91_gpio_init_one(i, data[i].regbase, data[i].id); + } - for (i = 0; i < nr_banks; i++) { + for (i = 0; i < gpio_banks; i++) { at91_gpio = &gpio_chip[i]; - at91_gpio->id = data[i].id; - at91_gpio->chip.base = i * 32; - - at91_gpio->regbase = ioremap(data[i].regbase, 512); - if (!at91_gpio->regbase) { - pr_err("at91_gpio.%d, failed to map registers, ignoring.\n", i); - continue; - } - - at91_gpio->clock = clk_get_sys(NULL, at91_gpio->chip.label); - if (!at91_gpio->clock) { - pr_err("at91_gpio.%d, failed to get clock, ignoring.\n", i); - continue; - } - - /* enable PIO controller's clock */ - clk_enable(at91_gpio->clock); - - /* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */ - if (last && last->id == at91_gpio->id) + /* + * GPIO controller are grouped on some SoC: + * PIOC, PIOD and PIOE can share the same IRQ line + */ + if (last && last->pioc_hwirq == at91_gpio->pioc_hwirq) last->next = at91_gpio; last = at91_gpio; diff --git a/arch/arm/mach-at91/include/mach/at91_matrix.h b/arch/arm/mach-at91/include/mach/at91_matrix.h new file mode 100644 index 000000000000..02fae9de746b --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_matrix.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 + */ + +#ifndef __MACH_AT91_MATRIX_H__ +#define __MACH_AT91_MATRIX_H__ + +#ifndef __ASSEMBLY__ +extern void __iomem *at91_matrix_base; + +#define at91_matrix_read(field) \ + __raw_readl(at91_matrix_base + field) + +#define at91_matrix_write(field, value) \ + __raw_writel(value, at91_matrix_base + field); + +#else +.extern at91_matrix_base +#endif + +#endif /* __MACH_AT91_MATRIX_H__ */ diff --git a/arch/arm/mach-at91/include/mach/at91_pio.h b/arch/arm/mach-at91/include/mach/at91_pio.h index c6a31bf8a5c6..732b11c37f1a 100644 --- a/arch/arm/mach-at91/include/mach/at91_pio.h +++ b/arch/arm/mach-at91/include/mach/at91_pio.h @@ -40,10 +40,35 @@ #define PIO_PUER 0x64 /* Pull-up Enable Register */ #define PIO_PUSR 0x68 /* Pull-up Status Register */ #define PIO_ASR 0x70 /* Peripheral A Select Register */ +#define PIO_ABCDSR1 0x70 /* Peripheral ABCD Select Register 1 [some sam9 only] */ #define PIO_BSR 0x74 /* Peripheral B Select Register */ +#define PIO_ABCDSR2 0x74 /* Peripheral ABCD Select Register 2 [some sam9 only] */ #define PIO_ABSR 0x78 /* AB Status Register */ +#define PIO_IFSCDR 0x80 /* Input Filter Slow Clock Disable Register */ +#define PIO_IFSCER 0x84 /* Input Filter Slow Clock Enable Register */ +#define PIO_IFSCSR 0x88 /* Input Filter Slow Clock Status Register */ +#define PIO_SCDR 0x8c /* Slow Clock Divider Debouncing Register */ +#define PIO_SCDR_DIV (0x3fff << 0) /* Slow Clock Divider Mask */ +#define PIO_PPDDR 0x90 /* Pad Pull-down Disable Register */ +#define PIO_PPDER 0x94 /* Pad Pull-down Enable Register */ +#define PIO_PPDSR 0x98 /* Pad Pull-down Status Register */ #define PIO_OWER 0xa0 /* Output Write Enable Register */ #define PIO_OWDR 0xa4 /* Output Write Disable Register */ #define PIO_OWSR 0xa8 /* Output Write Status Register */ +#define PIO_AIMER 0xb0 /* Additional Interrupt Modes Enable Register */ +#define PIO_AIMDR 0xb4 /* Additional Interrupt Modes Disable Register */ +#define PIO_AIMMR 0xb8 /* Additional Interrupt Modes Mask Register */ +#define PIO_ESR 0xc0 /* Edge Select Register */ +#define PIO_LSR 0xc4 /* Level Select Register */ +#define PIO_ELSR 0xc8 /* Edge/Level Status Register */ +#define PIO_FELLSR 0xd0 /* Falling Edge/Low Level Select Register */ +#define PIO_REHLSR 0xd4 /* Rising Edge/ High Level Select Register */ +#define PIO_FRLHSR 0xd8 /* Fall/Rise - Low/High Status Register */ +#define PIO_SCHMITT 0x100 /* Schmitt Trigger Register */ + +#define ABCDSR_PERIPH_A 0x0 +#define ABCDSR_PERIPH_B 0x1 +#define ABCDSR_PERIPH_C 0x2 +#define ABCDSR_PERIPH_D 0x3 #endif diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h index e46f93e34aab..36604782a78f 100644 --- a/arch/arm/mach-at91/include/mach/at91_pmc.h +++ b/arch/arm/mach-at91/include/mach/at91_pmc.h @@ -16,17 +16,27 @@ #ifndef AT91_PMC_H #define AT91_PMC_H -#define AT91_PMC_SCER (AT91_PMC + 0x00) /* System Clock Enable Register */ -#define AT91_PMC_SCDR (AT91_PMC + 0x04) /* System Clock Disable Register */ +#ifndef __ASSEMBLY__ +extern void __iomem *at91_pmc_base; -#define AT91_PMC_SCSR (AT91_PMC + 0x08) /* System Clock Status Register */ +#define at91_pmc_read(field) \ + __raw_readl(at91_pmc_base + field) + +#define at91_pmc_write(field, value) \ + __raw_writel(value, at91_pmc_base + field) +#else +.extern at91_aic_base +#endif + +#define AT91_PMC_SCER 0x00 /* System Clock Enable Register */ +#define AT91_PMC_SCDR 0x04 /* System Clock Disable Register */ + +#define AT91_PMC_SCSR 0x08 /* System Clock Status Register */ #define AT91_PMC_PCK (1 << 0) /* Processor Clock */ #define AT91RM9200_PMC_UDP (1 << 1) /* USB Devcice Port Clock [AT91RM9200 only] */ #define AT91RM9200_PMC_MCKUDP (1 << 2) /* USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only] */ -#define AT91CAP9_PMC_DDR (1 << 2) /* DDR Clock [CAP9 revC & some SAM9 only] */ #define AT91RM9200_PMC_UHP (1 << 4) /* USB Host Port Clock [AT91RM9200 only] */ #define AT91SAM926x_PMC_UHP (1 << 6) /* USB Host Port Clock [AT91SAM926x only] */ -#define AT91CAP9_PMC_UHP (1 << 6) /* USB Host Port Clock [AT91CAP9 only] */ #define AT91SAM926x_PMC_UDP (1 << 7) /* USB Devcice Port Clock [AT91SAM926x only] */ #define AT91_PMC_PCK0 (1 << 8) /* Programmable Clock 0 */ #define AT91_PMC_PCK1 (1 << 9) /* Programmable Clock 1 */ @@ -36,27 +46,31 @@ #define AT91_PMC_HCK0 (1 << 16) /* AHB Clock (USB host) [AT91SAM9261 only] */ #define AT91_PMC_HCK1 (1 << 17) /* AHB Clock (LCD) [AT91SAM9261 only] */ -#define AT91_PMC_PCER (AT91_PMC + 0x10) /* Peripheral Clock Enable Register */ -#define AT91_PMC_PCDR (AT91_PMC + 0x14) /* Peripheral Clock Disable Register */ -#define AT91_PMC_PCSR (AT91_PMC + 0x18) /* Peripheral Clock Status Register */ +#define AT91_PMC_PCER 0x10 /* Peripheral Clock Enable Register */ +#define AT91_PMC_PCDR 0x14 /* Peripheral Clock Disable Register */ +#define AT91_PMC_PCSR 0x18 /* Peripheral Clock Status Register */ -#define AT91_CKGR_UCKR (AT91_PMC + 0x1C) /* UTMI Clock Register [some SAM9, CAP9] */ +#define AT91_CKGR_UCKR 0x1C /* UTMI Clock Register [some SAM9] */ #define AT91_PMC_UPLLEN (1 << 16) /* UTMI PLL Enable */ #define AT91_PMC_UPLLCOUNT (0xf << 20) /* UTMI PLL Start-up Time */ #define AT91_PMC_BIASEN (1 << 24) /* UTMI BIAS Enable */ #define AT91_PMC_BIASCOUNT (0xf << 28) /* UTMI BIAS Start-up Time */ -#define AT91_CKGR_MOR (AT91_PMC + 0x20) /* Main Oscillator Register [not on SAM9RL] */ -#define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */ -#define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass [SAM9x, CAP9] */ -#define AT91_PMC_OSCOUNT (0xff << 8) /* Main Oscillator Start-up Time */ +#define AT91_CKGR_MOR 0x20 /* Main Oscillator Register [not on SAM9RL] */ +#define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */ +#define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass */ +#define AT91_PMC_MOSCRCEN (1 << 3) /* Main On-Chip RC Oscillator Enable [some SAM9] */ +#define AT91_PMC_OSCOUNT (0xff << 8) /* Main Oscillator Start-up Time */ +#define AT91_PMC_KEY (0x37 << 16) /* MOR Writing Key */ +#define AT91_PMC_MOSCSEL (1 << 24) /* Main Oscillator Selection [some SAM9] */ +#define AT91_PMC_CFDEN (1 << 25) /* Clock Failure Detector Enable [some SAM9] */ -#define AT91_CKGR_MCFR (AT91_PMC + 0x24) /* Main Clock Frequency Register */ +#define AT91_CKGR_MCFR 0x24 /* Main Clock Frequency Register */ #define AT91_PMC_MAINF (0xffff << 0) /* Main Clock Frequency */ #define AT91_PMC_MAINRDY (1 << 16) /* Main Clock Ready */ -#define AT91_CKGR_PLLAR (AT91_PMC + 0x28) /* PLL A Register */ -#define AT91_CKGR_PLLBR (AT91_PMC + 0x2c) /* PLL B Register */ +#define AT91_CKGR_PLLAR 0x28 /* PLL A Register */ +#define AT91_CKGR_PLLBR 0x2c /* PLL B Register */ #define AT91_PMC_DIV (0xff << 0) /* Divider */ #define AT91_PMC_PLLCOUNT (0x3f << 8) /* PLL Counter */ #define AT91_PMC_OUT (3 << 14) /* PLL Clock Frequency Range */ @@ -67,27 +81,37 @@ #define AT91_PMC_USBDIV_4 (2 << 28) #define AT91_PMC_USB96M (1 << 28) /* Divider by 2 Enable (PLLB only) */ -#define AT91_PMC_MCKR (AT91_PMC + 0x30) /* Master Clock Register */ +#define AT91_PMC_MCKR 0x30 /* Master Clock Register */ #define AT91_PMC_CSS (3 << 0) /* Master Clock Selection */ #define AT91_PMC_CSS_SLOW (0 << 0) #define AT91_PMC_CSS_MAIN (1 << 0) #define AT91_PMC_CSS_PLLA (2 << 0) #define AT91_PMC_CSS_PLLB (3 << 0) #define AT91_PMC_CSS_UPLL (3 << 0) /* [some SAM9 only] */ -#define AT91_PMC_PRES (7 << 2) /* Master Clock Prescaler */ -#define AT91_PMC_PRES_1 (0 << 2) -#define AT91_PMC_PRES_2 (1 << 2) -#define AT91_PMC_PRES_4 (2 << 2) -#define AT91_PMC_PRES_8 (3 << 2) -#define AT91_PMC_PRES_16 (4 << 2) -#define AT91_PMC_PRES_32 (5 << 2) -#define AT91_PMC_PRES_64 (6 << 2) +#define PMC_PRES_OFFSET 2 +#define AT91_PMC_PRES (7 << PMC_PRES_OFFSET) /* Master Clock Prescaler */ +#define AT91_PMC_PRES_1 (0 << PMC_PRES_OFFSET) +#define AT91_PMC_PRES_2 (1 << PMC_PRES_OFFSET) +#define AT91_PMC_PRES_4 (2 << PMC_PRES_OFFSET) +#define AT91_PMC_PRES_8 (3 << PMC_PRES_OFFSET) +#define AT91_PMC_PRES_16 (4 << PMC_PRES_OFFSET) +#define AT91_PMC_PRES_32 (5 << PMC_PRES_OFFSET) +#define AT91_PMC_PRES_64 (6 << PMC_PRES_OFFSET) +#define PMC_ALT_PRES_OFFSET 4 +#define AT91_PMC_ALT_PRES (7 << PMC_ALT_PRES_OFFSET) /* Master Clock Prescaler [alternate location] */ +#define AT91_PMC_ALT_PRES_1 (0 << PMC_ALT_PRES_OFFSET) +#define AT91_PMC_ALT_PRES_2 (1 << PMC_ALT_PRES_OFFSET) +#define AT91_PMC_ALT_PRES_4 (2 << PMC_ALT_PRES_OFFSET) +#define AT91_PMC_ALT_PRES_8 (3 << PMC_ALT_PRES_OFFSET) +#define AT91_PMC_ALT_PRES_16 (4 << PMC_ALT_PRES_OFFSET) +#define AT91_PMC_ALT_PRES_32 (5 << PMC_ALT_PRES_OFFSET) +#define AT91_PMC_ALT_PRES_64 (6 << PMC_ALT_PRES_OFFSET) #define AT91_PMC_MDIV (3 << 8) /* Master Clock Division */ #define AT91RM9200_PMC_MDIV_1 (0 << 8) /* [AT91RM9200 only] */ #define AT91RM9200_PMC_MDIV_2 (1 << 8) #define AT91RM9200_PMC_MDIV_3 (2 << 8) #define AT91RM9200_PMC_MDIV_4 (3 << 8) -#define AT91SAM9_PMC_MDIV_1 (0 << 8) /* [SAM9,CAP9 only] */ +#define AT91SAM9_PMC_MDIV_1 (0 << 8) /* [SAM9 only] */ #define AT91SAM9_PMC_MDIV_2 (1 << 8) #define AT91SAM9_PMC_MDIV_4 (2 << 8) #define AT91SAM9_PMC_MDIV_6 (3 << 8) /* [some SAM9 only] */ @@ -99,35 +123,55 @@ #define AT91_PMC_PLLADIV2_OFF (0 << 12) #define AT91_PMC_PLLADIV2_ON (1 << 12) -#define AT91_PMC_USB (AT91_PMC + 0x38) /* USB Clock Register [some SAM9 only] */ +#define AT91_PMC_USB 0x38 /* USB Clock Register [some SAM9 only] */ #define AT91_PMC_USBS (0x1 << 0) /* USB OHCI Input clock selection */ #define AT91_PMC_USBS_PLLA (0 << 0) #define AT91_PMC_USBS_UPLL (1 << 0) #define AT91_PMC_OHCIUSBDIV (0xF << 8) /* Divider for USB OHCI Clock */ -#define AT91_PMC_PCKR(n) (AT91_PMC + 0x40 + ((n) * 4)) /* Programmable Clock 0-N Registers */ +#define AT91_PMC_SMD 0x3c /* Soft Modem Clock Register [some SAM9 only] */ +#define AT91_PMC_SMDS (0x1 << 0) /* SMD input clock selection */ +#define AT91_PMC_SMD_DIV (0x1f << 8) /* SMD input clock divider */ +#define AT91_PMC_SMDDIV(n) (((n) << 8) & AT91_PMC_SMD_DIV) + +#define AT91_PMC_PCKR(n) (0x40 + ((n) * 4)) /* Programmable Clock 0-N Registers */ +#define AT91_PMC_ALT_PCKR_CSS (0x7 << 0) /* Programmable Clock Source Selection [alternate length] */ +#define AT91_PMC_CSS_MASTER (4 << 0) /* [some SAM9 only] */ #define AT91_PMC_CSSMCK (0x1 << 8) /* CSS or Master Clock Selection */ #define AT91_PMC_CSSMCK_CSS (0 << 8) #define AT91_PMC_CSSMCK_MCK (1 << 8) -#define AT91_PMC_IER (AT91_PMC + 0x60) /* Interrupt Enable Register */ -#define AT91_PMC_IDR (AT91_PMC + 0x64) /* Interrupt Disable Register */ -#define AT91_PMC_SR (AT91_PMC + 0x68) /* Status Register */ +#define AT91_PMC_IER 0x60 /* Interrupt Enable Register */ +#define AT91_PMC_IDR 0x64 /* Interrupt Disable Register */ +#define AT91_PMC_SR 0x68 /* Status Register */ #define AT91_PMC_MOSCS (1 << 0) /* MOSCS Flag */ #define AT91_PMC_LOCKA (1 << 1) /* PLLA Lock */ #define AT91_PMC_LOCKB (1 << 2) /* PLLB Lock */ #define AT91_PMC_MCKRDY (1 << 3) /* Master Clock */ -#define AT91_PMC_LOCKU (1 << 6) /* UPLL Lock [some SAM9, AT91CAP9 only] */ -#define AT91_PMC_OSCSEL (1 << 7) /* Slow Clock Oscillator [AT91CAP9 revC only] */ +#define AT91_PMC_LOCKU (1 << 6) /* UPLL Lock [some SAM9] */ #define AT91_PMC_PCK0RDY (1 << 8) /* Programmable Clock 0 */ #define AT91_PMC_PCK1RDY (1 << 9) /* Programmable Clock 1 */ #define AT91_PMC_PCK2RDY (1 << 10) /* Programmable Clock 2 */ #define AT91_PMC_PCK3RDY (1 << 11) /* Programmable Clock 3 */ -#define AT91_PMC_IMR (AT91_PMC + 0x6c) /* Interrupt Mask Register */ +#define AT91_PMC_MOSCSELS (1 << 16) /* Main Oscillator Selection [some SAM9] */ +#define AT91_PMC_MOSCRCS (1 << 17) /* Main On-Chip RC [some SAM9] */ +#define AT91_PMC_CFDEV (1 << 18) /* Clock Failure Detector Event [some SAM9] */ +#define AT91_PMC_IMR 0x6c /* Interrupt Mask Register */ + +#define AT91_PMC_PROT 0xe4 /* Write Protect Mode Register [some SAM9] */ +#define AT91_PMC_WPEN (0x1 << 0) /* Write Protect Enable */ +#define AT91_PMC_WPKEY (0xffffff << 8) /* Write Protect Key */ +#define AT91_PMC_PROTKEY (0x504d43 << 8) /* Activation Code */ -#define AT91_PMC_PROT (AT91_PMC + 0xe4) /* Protect Register [AT91CAP9 revC only] */ -#define AT91_PMC_PROTKEY 0x504d4301 /* Activation Code */ +#define AT91_PMC_WPSR 0xe8 /* Write Protect Status Register [some SAM9] */ +#define AT91_PMC_WPVS (0x1 << 0) /* Write Protect Violation Status */ +#define AT91_PMC_WPVSRC (0xffff << 8) /* Write Protect Violation Source */ -#define AT91_PMC_VER (AT91_PMC + 0xfc) /* PMC Module Version [AT91CAP9 only] */ +#define AT91_PMC_PCR 0x10c /* Peripheral Control Register [some SAM9] */ +#define AT91_PMC_PCR_PID (0x3f << 0) /* Peripheral ID */ +#define AT91_PMC_PCR_CMD (0x1 << 12) /* Command */ +#define AT91_PMC_PCR_DIV (0x3 << 16) /* Divisor Value */ +#define AT91_PMC_PCRDIV(n) (((n) << 16) & AT91_PMC_PCR_DIV) +#define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */ #endif diff --git a/arch/arm/mach-at91/include/mach/at91_ramc.h b/arch/arm/mach-at91/include/mach/at91_ramc.h new file mode 100644 index 000000000000..d8aeb278614e --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_ramc.h @@ -0,0 +1,32 @@ +/* + * Header file for the Atmel RAM Controller + * + * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 only + */ + +#ifndef __AT91_RAMC_H__ +#define __AT91_RAMC_H__ + +#ifndef __ASSEMBLY__ +extern void __iomem *at91_ramc_base[]; + +#define at91_ramc_read(id, field) \ + __raw_readl(at91_ramc_base[id] + field) + +#define at91_ramc_write(id, field, value) \ + __raw_writel(value, at91_ramc_base[id] + field) +#else +.extern at91_ramc_base +#endif + +#define AT91_MEMCTRL_MC 0 +#define AT91_MEMCTRL_SDRAMC 1 +#define AT91_MEMCTRL_DDRSDR 2 + +#include <mach/at91rm9200_sdramc.h> +#include <mach/at91sam9_ddrsdr.h> +#include <mach/at91sam9_sdramc.h> + +#endif /* __AT91_RAMC_H__ */ diff --git a/arch/arm/mach-at91/include/mach/at91_shdwc.h b/arch/arm/mach-at91/include/mach/at91_shdwc.h index 1d4fe822c77a..60478ea8bd46 100644 --- a/arch/arm/mach-at91/include/mach/at91_shdwc.h +++ b/arch/arm/mach-at91/include/mach/at91_shdwc.h @@ -36,9 +36,11 @@ extern void __iomem *at91_shdwc_base; #define AT91_SHDW_WKMODE0_HIGH 1 #define AT91_SHDW_WKMODE0_LOW 2 #define AT91_SHDW_WKMODE0_ANYLEVEL 3 -#define AT91_SHDW_CPTWK0 (0xf << 4) /* Counter On Wake Up 0 */ +#define AT91_SHDW_CPTWK0_MAX 0xf /* Maximum Counter On Wake Up 0 */ +#define AT91_SHDW_CPTWK0 (AT91_SHDW_CPTWK0_MAX << 4) /* Counter On Wake Up 0 */ #define AT91_SHDW_CPTWK0_(x) ((x) << 4) #define AT91_SHDW_RTTWKEN (1 << 16) /* Real Time Timer Wake-up Enable */ +#define AT91_SHDW_RTCWKEN (1 << 17) /* Real Time Clock Wake-up Enable */ #define AT91_SHDW_SR 0x08 /* Shut Down Status Register */ #define AT91_SHDW_WAKEUP0 (1 << 0) /* Wake-up 0 Status */ diff --git a/arch/arm/mach-at91/include/mach/at91_st.h b/arch/arm/mach-at91/include/mach/at91_st.h index 8847173e4101..969aac27109f 100644 --- a/arch/arm/mach-at91/include/mach/at91_st.h +++ b/arch/arm/mach-at91/include/mach/at91_st.h @@ -16,34 +16,46 @@ #ifndef AT91_ST_H #define AT91_ST_H -#define AT91_ST_CR (AT91_ST + 0x00) /* Control Register */ +#ifndef __ASSEMBLY__ +extern void __iomem *at91_st_base; + +#define at91_st_read(field) \ + __raw_readl(at91_st_base + field) + +#define at91_st_write(field, value) \ + __raw_writel(value, at91_st_base + field); +#else +.extern at91_st_base +#endif + +#define AT91_ST_CR 0x00 /* Control Register */ #define AT91_ST_WDRST (1 << 0) /* Watchdog Timer Restart */ -#define AT91_ST_PIMR (AT91_ST + 0x04) /* Period Interval Mode Register */ +#define AT91_ST_PIMR 0x04 /* Period Interval Mode Register */ #define AT91_ST_PIV (0xffff << 0) /* Period Interval Value */ -#define AT91_ST_WDMR (AT91_ST + 0x08) /* Watchdog Mode Register */ +#define AT91_ST_WDMR 0x08 /* Watchdog Mode Register */ #define AT91_ST_WDV (0xffff << 0) /* Watchdog Counter Value */ #define AT91_ST_RSTEN (1 << 16) /* Reset Enable */ #define AT91_ST_EXTEN (1 << 17) /* External Signal Assertion Enable */ -#define AT91_ST_RTMR (AT91_ST + 0x0c) /* Real-time Mode Register */ +#define AT91_ST_RTMR 0x0c /* Real-time Mode Register */ #define AT91_ST_RTPRES (0xffff << 0) /* Real-time Prescalar Value */ -#define AT91_ST_SR (AT91_ST + 0x10) /* Status Register */ +#define AT91_ST_SR 0x10 /* Status Register */ #define AT91_ST_PITS (1 << 0) /* Period Interval Timer Status */ #define AT91_ST_WDOVF (1 << 1) /* Watchdog Overflow */ #define AT91_ST_RTTINC (1 << 2) /* Real-time Timer Increment */ #define AT91_ST_ALMS (1 << 3) /* Alarm Status */ -#define AT91_ST_IER (AT91_ST + 0x14) /* Interrupt Enable Register */ -#define AT91_ST_IDR (AT91_ST + 0x18) /* Interrupt Disable Register */ -#define AT91_ST_IMR (AT91_ST + 0x1c) /* Interrupt Mask Register */ +#define AT91_ST_IER 0x14 /* Interrupt Enable Register */ +#define AT91_ST_IDR 0x18 /* Interrupt Disable Register */ +#define AT91_ST_IMR 0x1c /* Interrupt Mask Register */ -#define AT91_ST_RTAR (AT91_ST + 0x20) /* Real-time Alarm Register */ +#define AT91_ST_RTAR 0x20 /* Real-time Alarm Register */ #define AT91_ST_ALMV (0xfffff << 0) /* Alarm Value */ -#define AT91_ST_CRTR (AT91_ST + 0x24) /* Current Real-time Register */ +#define AT91_ST_CRTR 0x24 /* Current Real-time Register */ #define AT91_ST_CRTV (0xfffff << 0) /* Current Real-Time Value */ #endif diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h deleted file mode 100644 index 61d952902f2b..000000000000 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * arch/arm/mach-at91/include/mach/at91cap9.h - * - * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com> - * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com> - * Copyright (C) 2007 Atmel Corporation. - * - * Common definitions. - * Based on AT91CAP9 datasheet revision B (Preliminary). - * - * 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. - */ - -#ifndef AT91CAP9_H -#define AT91CAP9_H - -/* - * Peripheral identifiers/interrupts. - */ -#define AT91CAP9_ID_PIOABCD 2 /* Parallel IO Controller A, B, C and D */ -#define AT91CAP9_ID_MPB0 3 /* MP Block Peripheral 0 */ -#define AT91CAP9_ID_MPB1 4 /* MP Block Peripheral 1 */ -#define AT91CAP9_ID_MPB2 5 /* MP Block Peripheral 2 */ -#define AT91CAP9_ID_MPB3 6 /* MP Block Peripheral 3 */ -#define AT91CAP9_ID_MPB4 7 /* MP Block Peripheral 4 */ -#define AT91CAP9_ID_US0 8 /* USART 0 */ -#define AT91CAP9_ID_US1 9 /* USART 1 */ -#define AT91CAP9_ID_US2 10 /* USART 2 */ -#define AT91CAP9_ID_MCI0 11 /* Multimedia Card Interface 0 */ -#define AT91CAP9_ID_MCI1 12 /* Multimedia Card Interface 1 */ -#define AT91CAP9_ID_CAN 13 /* CAN */ -#define AT91CAP9_ID_TWI 14 /* Two-Wire Interface */ -#define AT91CAP9_ID_SPI0 15 /* Serial Peripheral Interface 0 */ -#define AT91CAP9_ID_SPI1 16 /* Serial Peripheral Interface 0 */ -#define AT91CAP9_ID_SSC0 17 /* Serial Synchronous Controller 0 */ -#define AT91CAP9_ID_SSC1 18 /* Serial Synchronous Controller 1 */ -#define AT91CAP9_ID_AC97C 19 /* AC97 Controller */ -#define AT91CAP9_ID_TCB 20 /* Timer Counter 0, 1 and 2 */ -#define AT91CAP9_ID_PWMC 21 /* Pulse Width Modulation Controller */ -#define AT91CAP9_ID_EMAC 22 /* Ethernet */ -#define AT91CAP9_ID_AESTDES 23 /* Advanced Encryption Standard, Triple DES */ -#define AT91CAP9_ID_ADC 24 /* Analog-to-Digital Converter */ -#define AT91CAP9_ID_ISI 25 /* Image Sensor Interface */ -#define AT91CAP9_ID_LCDC 26 /* LCD Controller */ -#define AT91CAP9_ID_DMA 27 /* DMA Controller */ -#define AT91CAP9_ID_UDPHS 28 /* USB High Speed Device Port */ -#define AT91CAP9_ID_UHP 29 /* USB Host Port */ -#define AT91CAP9_ID_IRQ0 30 /* Advanced Interrupt Controller (IRQ0) */ -#define AT91CAP9_ID_IRQ1 31 /* Advanced Interrupt Controller (IRQ1) */ - -/* - * User Peripheral physical base addresses. - */ -#define AT91CAP9_BASE_UDPHS 0xfff78000 -#define AT91CAP9_BASE_TCB0 0xfff7c000 -#define AT91CAP9_BASE_TC0 0xfff7c000 -#define AT91CAP9_BASE_TC1 0xfff7c040 -#define AT91CAP9_BASE_TC2 0xfff7c080 -#define AT91CAP9_BASE_MCI0 0xfff80000 -#define AT91CAP9_BASE_MCI1 0xfff84000 -#define AT91CAP9_BASE_TWI 0xfff88000 -#define AT91CAP9_BASE_US0 0xfff8c000 -#define AT91CAP9_BASE_US1 0xfff90000 -#define AT91CAP9_BASE_US2 0xfff94000 -#define AT91CAP9_BASE_SSC0 0xfff98000 -#define AT91CAP9_BASE_SSC1 0xfff9c000 -#define AT91CAP9_BASE_AC97C 0xfffa0000 -#define AT91CAP9_BASE_SPI0 0xfffa4000 -#define AT91CAP9_BASE_SPI1 0xfffa8000 -#define AT91CAP9_BASE_CAN 0xfffac000 -#define AT91CAP9_BASE_PWMC 0xfffb8000 -#define AT91CAP9_BASE_EMAC 0xfffbc000 -#define AT91CAP9_BASE_ADC 0xfffc0000 -#define AT91CAP9_BASE_ISI 0xfffc4000 - -/* - * System Peripherals (offset from AT91_BASE_SYS) - */ -#define AT91_BCRAMC (0xffffe400 - AT91_BASE_SYS) -#define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) -#define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) -#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) -#define AT91_GPBR (cpu_is_at91cap9_revB() ? \ - (0xfffffd50 - AT91_BASE_SYS) : \ - (0xfffffd60 - AT91_BASE_SYS)) - -#define AT91CAP9_BASE_ECC 0xffffe200 -#define AT91CAP9_BASE_DMA 0xffffec00 -#define AT91CAP9_BASE_SMC 0xffffe800 -#define AT91CAP9_BASE_DBGU AT91_BASE_DBGU1 -#define AT91CAP9_BASE_PIOA 0xfffff200 -#define AT91CAP9_BASE_PIOB 0xfffff400 -#define AT91CAP9_BASE_PIOC 0xfffff600 -#define AT91CAP9_BASE_PIOD 0xfffff800 -#define AT91CAP9_BASE_RSTC 0xfffffd00 -#define AT91CAP9_BASE_SHDWC 0xfffffd10 -#define AT91CAP9_BASE_RTT 0xfffffd20 -#define AT91CAP9_BASE_PIT 0xfffffd30 -#define AT91CAP9_BASE_WDT 0xfffffd40 - -#define AT91_USART0 AT91CAP9_BASE_US0 -#define AT91_USART1 AT91CAP9_BASE_US1 -#define AT91_USART2 AT91CAP9_BASE_US2 - - -/* - * Internal Memory. - */ -#define AT91CAP9_SRAM_BASE 0x00100000 /* Internal SRAM base address */ -#define AT91CAP9_SRAM_SIZE (32 * SZ_1K) /* Internal SRAM size (32Kb) */ - -#define AT91CAP9_ROM_BASE 0x00400000 /* Internal ROM base address */ -#define AT91CAP9_ROM_SIZE (32 * SZ_1K) /* Internal ROM size (32Kb) */ - -#define AT91CAP9_LCDC_BASE 0x00500000 /* LCD Controller */ -#define AT91CAP9_UDPHS_FIFO 0x00600000 /* USB High Speed Device Port */ -#define AT91CAP9_UHP_BASE 0x00700000 /* USB Host controller */ - -#endif diff --git a/arch/arm/mach-at91/include/mach/at91cap9_matrix.h b/arch/arm/mach-at91/include/mach/at91cap9_matrix.h deleted file mode 100644 index 4b9d4aff4b4f..000000000000 --- a/arch/arm/mach-at91/include/mach/at91cap9_matrix.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * arch/arm/mach-at91/include/mach/at91cap9_matrix.h - * - * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com> - * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com> - * Copyright (C) 2006 Atmel Corporation. - * - * Memory Controllers (MATRIX, EBI) - System peripherals registers. - * Based on AT91CAP9 datasheet revision B (Preliminary). - * - * 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. - */ - -#ifndef AT91CAP9_MATRIX_H -#define AT91CAP9_MATRIX_H - -#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */ -#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */ -#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */ -#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */ -#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */ -#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */ -#define AT91_MATRIX_MCFG6 (AT91_MATRIX + 0x18) /* Master Configuration Register 6 */ -#define AT91_MATRIX_MCFG7 (AT91_MATRIX + 0x1C) /* Master Configuration Register 7 */ -#define AT91_MATRIX_MCFG8 (AT91_MATRIX + 0x20) /* Master Configuration Register 8 */ -#define AT91_MATRIX_MCFG9 (AT91_MATRIX + 0x24) /* Master Configuration Register 9 */ -#define AT91_MATRIX_MCFG10 (AT91_MATRIX + 0x28) /* Master Configuration Register 10 */ -#define AT91_MATRIX_MCFG11 (AT91_MATRIX + 0x2C) /* Master Configuration Register 11 */ -#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */ -#define AT91_MATRIX_ULBT_INFINITE (0 << 0) -#define AT91_MATRIX_ULBT_SINGLE (1 << 0) -#define AT91_MATRIX_ULBT_FOUR (2 << 0) -#define AT91_MATRIX_ULBT_EIGHT (3 << 0) -#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) - -#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */ -#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */ -#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */ -#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */ -#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */ -#define AT91_MATRIX_SCFG5 (AT91_MATRIX + 0x54) /* Slave Configuration Register 5 */ -#define AT91_MATRIX_SCFG6 (AT91_MATRIX + 0x58) /* Slave Configuration Register 6 */ -#define AT91_MATRIX_SCFG7 (AT91_MATRIX + 0x5C) /* Slave Configuration Register 7 */ -#define AT91_MATRIX_SCFG8 (AT91_MATRIX + 0x60) /* Slave Configuration Register 8 */ -#define AT91_MATRIX_SCFG9 (AT91_MATRIX + 0x64) /* Slave Configuration Register 9 */ -#define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */ -#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */ -#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) -#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) -#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) -#define AT91_MATRIX_FIXED_DEFMSTR (0xf << 18) /* Fixed Index of Default Master */ -#define AT91_MATRIX_ARBT (3 << 24) /* Arbitration Type */ -#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) -#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) - -#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */ -#define AT91_MATRIX_PRBS0 (AT91_MATRIX + 0x84) /* Priority Register B for Slave 0 */ -#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */ -#define AT91_MATRIX_PRBS1 (AT91_MATRIX + 0x8C) /* Priority Register B for Slave 1 */ -#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */ -#define AT91_MATRIX_PRBS2 (AT91_MATRIX + 0x94) /* Priority Register B for Slave 2 */ -#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */ -#define AT91_MATRIX_PRBS3 (AT91_MATRIX + 0x9C) /* Priority Register B for Slave 3 */ -#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */ -#define AT91_MATRIX_PRBS4 (AT91_MATRIX + 0xA4) /* Priority Register B for Slave 4 */ -#define AT91_MATRIX_PRAS5 (AT91_MATRIX + 0xA8) /* Priority Register A for Slave 5 */ -#define AT91_MATRIX_PRBS5 (AT91_MATRIX + 0xAC) /* Priority Register B for Slave 5 */ -#define AT91_MATRIX_PRAS6 (AT91_MATRIX + 0xB0) /* Priority Register A for Slave 6 */ -#define AT91_MATRIX_PRBS6 (AT91_MATRIX + 0xB4) /* Priority Register B for Slave 6 */ -#define AT91_MATRIX_PRAS7 (AT91_MATRIX + 0xB8) /* Priority Register A for Slave 7 */ -#define AT91_MATRIX_PRBS7 (AT91_MATRIX + 0xBC) /* Priority Register B for Slave 7 */ -#define AT91_MATRIX_PRAS8 (AT91_MATRIX + 0xC0) /* Priority Register A for Slave 8 */ -#define AT91_MATRIX_PRBS8 (AT91_MATRIX + 0xC4) /* Priority Register B for Slave 8 */ -#define AT91_MATRIX_PRAS9 (AT91_MATRIX + 0xC8) /* Priority Register A for Slave 9 */ -#define AT91_MATRIX_PRBS9 (AT91_MATRIX + 0xCC) /* Priority Register B for Slave 9 */ -#define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */ -#define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */ -#define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */ -#define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */ -#define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */ -#define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */ -#define AT91_MATRIX_M6PR (3 << 24) /* Master 6 Priority */ -#define AT91_MATRIX_M7PR (3 << 28) /* Master 7 Priority */ -#define AT91_MATRIX_M8PR (3 << 0) /* Master 8 Priority (in Register B) */ -#define AT91_MATRIX_M9PR (3 << 4) /* Master 9 Priority (in Register B) */ -#define AT91_MATRIX_M10PR (3 << 8) /* Master 10 Priority (in Register B) */ -#define AT91_MATRIX_M11PR (3 << 12) /* Master 11 Priority (in Register B) */ - -#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */ -#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ -#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ -#define AT91_MATRIX_RCB2 (1 << 2) -#define AT91_MATRIX_RCB3 (1 << 3) -#define AT91_MATRIX_RCB4 (1 << 4) -#define AT91_MATRIX_RCB5 (1 << 5) -#define AT91_MATRIX_RCB6 (1 << 6) -#define AT91_MATRIX_RCB7 (1 << 7) -#define AT91_MATRIX_RCB8 (1 << 8) -#define AT91_MATRIX_RCB9 (1 << 9) -#define AT91_MATRIX_RCB10 (1 << 10) -#define AT91_MATRIX_RCB11 (1 << 11) - -#define AT91_MPBS0_SFR (AT91_MATRIX + 0x114) /* MPBlock Slave 0 Special Function Register */ -#define AT91_MPBS1_SFR (AT91_MATRIX + 0x11C) /* MPBlock Slave 1 Special Function Register */ - -#define AT91_MATRIX_UDPHS (AT91_MATRIX + 0x118) /* USBHS Special Function Register [AT91CAP9 only] */ -#define AT91_MATRIX_SELECT_UDPHS (0 << 31) /* select High Speed UDP */ -#define AT91_MATRIX_SELECT_UDP (1 << 31) /* select standard UDP */ -#define AT91_MATRIX_UDPHS_BYPASS_LOCK (1 << 30) /* bypass lock bit */ - -#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x120) /* EBI Chip Select Assignment Register */ -#define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */ -#define AT91_MATRIX_EBI_CS1A_SMC (0 << 1) -#define AT91_MATRIX_EBI_CS1A_BCRAMC (1 << 1) -#define AT91_MATRIX_EBI_CS3A (1 << 3) /* Chip Select 3 Assignment */ -#define AT91_MATRIX_EBI_CS3A_SMC (0 << 3) -#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3) -#define AT91_MATRIX_EBI_CS4A (1 << 4) /* Chip Select 4 Assignment */ -#define AT91_MATRIX_EBI_CS4A_SMC (0 << 4) -#define AT91_MATRIX_EBI_CS4A_SMC_CF1 (1 << 4) -#define AT91_MATRIX_EBI_CS5A (1 << 5) /* Chip Select 5 Assignment */ -#define AT91_MATRIX_EBI_CS5A_SMC (0 << 5) -#define AT91_MATRIX_EBI_CS5A_SMC_CF2 (1 << 5) -#define AT91_MATRIX_EBI_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */ -#define AT91_MATRIX_EBI_DQSPDC (1 << 9) /* Data Qualifier Strobe Pull-Down Configuration */ -#define AT91_MATRIX_EBI_VDDIOMSEL (1 << 16) /* Memory voltage selection */ -#define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16) -#define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16) - -#define AT91_MPBS2_SFR (AT91_MATRIX + 0x12C) /* MPBlock Slave 2 Special Function Register */ -#define AT91_MPBS3_SFR (AT91_MATRIX + 0x130) /* MPBlock Slave 3 Special Function Register */ -#define AT91_APB_SFR (AT91_MATRIX + 0x134) /* APB Bridge Special Function Register */ - -#endif diff --git a/arch/arm/mach-at91/include/mach/at91rm9200.h b/arch/arm/mach-at91/include/mach/at91rm9200.h index bacb51141819..603e6aac2a4f 100644 --- a/arch/arm/mach-at91/include/mach/at91rm9200.h +++ b/arch/arm/mach-at91/include/mach/at91rm9200.h @@ -77,26 +77,22 @@ /* - * System Peripherals (offset from AT91_BASE_SYS) + * System Peripherals */ -#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) /* Power Management Controller */ -#define AT91_ST (0xfffffd00 - AT91_BASE_SYS) /* System Timer */ -#define AT91_MC (0xffffff00 - AT91_BASE_SYS) /* Memory Controllers */ - #define AT91RM9200_BASE_DBGU AT91_BASE_DBGU0 /* Debug Unit */ #define AT91RM9200_BASE_PIOA 0xfffff400 /* PIO Controller A */ #define AT91RM9200_BASE_PIOB 0xfffff600 /* PIO Controller B */ #define AT91RM9200_BASE_PIOC 0xfffff800 /* PIO Controller C */ #define AT91RM9200_BASE_PIOD 0xfffffa00 /* PIO Controller D */ +#define AT91RM9200_BASE_ST 0xfffffd00 /* System Timer */ #define AT91RM9200_BASE_RTC 0xfffffe00 /* Real-Time Clock */ +#define AT91RM9200_BASE_MC 0xffffff00 /* Memory Controllers */ #define AT91_USART0 AT91RM9200_BASE_US0 #define AT91_USART1 AT91RM9200_BASE_US1 #define AT91_USART2 AT91RM9200_BASE_US2 #define AT91_USART3 AT91RM9200_BASE_US3 -#define AT91_MATRIX 0 /* not supported */ - /* * Internal Memory. */ diff --git a/arch/arm/mach-at91/include/mach/at91rm9200_mc.h b/arch/arm/mach-at91/include/mach/at91rm9200_mc.h index d34e4ed89349..aeaadfb452af 100644 --- a/arch/arm/mach-at91/include/mach/at91rm9200_mc.h +++ b/arch/arm/mach-at91/include/mach/at91rm9200_mc.h @@ -17,10 +17,10 @@ #define AT91RM9200_MC_H /* Memory Controller */ -#define AT91_MC_RCR (AT91_MC + 0x00) /* MC Remap Control Register */ +#define AT91_MC_RCR 0x00 /* MC Remap Control Register */ #define AT91_MC_RCB (1 << 0) /* Remap Command Bit */ -#define AT91_MC_ASR (AT91_MC + 0x04) /* MC Abort Status Register */ +#define AT91_MC_ASR 0x04 /* MC Abort Status Register */ #define AT91_MC_UNADD (1 << 0) /* Undefined Address Abort Status */ #define AT91_MC_MISADD (1 << 1) /* Misaligned Address Abort Status */ #define AT91_MC_ABTSZ (3 << 8) /* Abort Size Status */ @@ -40,16 +40,16 @@ #define AT91_MC_SVMST2 (1 << 26) /* Saved UHP Abort Source */ #define AT91_MC_SVMST3 (1 << 27) /* Saved EMAC Abort Source */ -#define AT91_MC_AASR (AT91_MC + 0x08) /* MC Abort Address Status Register */ +#define AT91_MC_AASR 0x08 /* MC Abort Address Status Register */ -#define AT91_MC_MPR (AT91_MC + 0x0c) /* MC Master Priority Register */ +#define AT91_MC_MPR 0x0c /* MC Master Priority Register */ #define AT91_MPR_MSTP0 (7 << 0) /* ARM920T Priority */ #define AT91_MPR_MSTP1 (7 << 4) /* PDC Priority */ #define AT91_MPR_MSTP2 (7 << 8) /* UHP Priority */ #define AT91_MPR_MSTP3 (7 << 12) /* EMAC Priority */ /* External Bus Interface (EBI) registers */ -#define AT91_EBI_CSA (AT91_MC + 0x60) /* Chip Select Assignment Register */ +#define AT91_EBI_CSA 0x60 /* Chip Select Assignment Register */ #define AT91_EBI_CS0A (1 << 0) /* Chip Select 0 Assignment */ #define AT91_EBI_CS0A_SMC (0 << 0) #define AT91_EBI_CS0A_BFC (1 << 0) @@ -66,7 +66,7 @@ #define AT91_EBI_DBPUC (1 << 0) /* Data Bus Pull-Up Configuration */ /* Static Memory Controller (SMC) registers */ -#define AT91_SMC_CSR(n) (AT91_MC + 0x70 + ((n) * 4))/* SMC Chip Select Register */ +#define AT91_SMC_CSR(n) (0x70 + ((n) * 4)) /* SMC Chip Select Register */ #define AT91_SMC_NWS (0x7f << 0) /* Number of Wait States */ #define AT91_SMC_NWS_(x) ((x) << 0) #define AT91_SMC_WSEN (1 << 7) /* Wait State Enable */ @@ -87,52 +87,8 @@ #define AT91_SMC_RWHOLD (7 << 28) /* Read & Write Signal Hold Time */ #define AT91_SMC_RWHOLD_(x) ((x) << 28) -/* SDRAM Controller registers */ -#define AT91_SDRAMC_MR (AT91_MC + 0x90) /* Mode Register */ -#define AT91_SDRAMC_MODE (0xf << 0) /* Command Mode */ -#define AT91_SDRAMC_MODE_NORMAL (0 << 0) -#define AT91_SDRAMC_MODE_NOP (1 << 0) -#define AT91_SDRAMC_MODE_PRECHARGE (2 << 0) -#define AT91_SDRAMC_MODE_LMR (3 << 0) -#define AT91_SDRAMC_MODE_REFRESH (4 << 0) -#define AT91_SDRAMC_DBW (1 << 4) /* Data Bus Width */ -#define AT91_SDRAMC_DBW_32 (0 << 4) -#define AT91_SDRAMC_DBW_16 (1 << 4) - -#define AT91_SDRAMC_TR (AT91_MC + 0x94) /* Refresh Timer Register */ -#define AT91_SDRAMC_COUNT (0xfff << 0) /* Refresh Timer Count */ - -#define AT91_SDRAMC_CR (AT91_MC + 0x98) /* Configuration Register */ -#define AT91_SDRAMC_NC (3 << 0) /* Number of Column Bits */ -#define AT91_SDRAMC_NC_8 (0 << 0) -#define AT91_SDRAMC_NC_9 (1 << 0) -#define AT91_SDRAMC_NC_10 (2 << 0) -#define AT91_SDRAMC_NC_11 (3 << 0) -#define AT91_SDRAMC_NR (3 << 2) /* Number of Row Bits */ -#define AT91_SDRAMC_NR_11 (0 << 2) -#define AT91_SDRAMC_NR_12 (1 << 2) -#define AT91_SDRAMC_NR_13 (2 << 2) -#define AT91_SDRAMC_NB (1 << 4) /* Number of Banks */ -#define AT91_SDRAMC_NB_2 (0 << 4) -#define AT91_SDRAMC_NB_4 (1 << 4) -#define AT91_SDRAMC_CAS (3 << 5) /* CAS Latency */ -#define AT91_SDRAMC_CAS_2 (2 << 5) -#define AT91_SDRAMC_TWR (0xf << 7) /* Write Recovery Delay */ -#define AT91_SDRAMC_TRC (0xf << 11) /* Row Cycle Delay */ -#define AT91_SDRAMC_TRP (0xf << 15) /* Row Precharge Delay */ -#define AT91_SDRAMC_TRCD (0xf << 19) /* Row to Column Delay */ -#define AT91_SDRAMC_TRAS (0xf << 23) /* Active to Precharge Delay */ -#define AT91_SDRAMC_TXSR (0xf << 27) /* Exit Self Refresh to Active Delay */ - -#define AT91_SDRAMC_SRR (AT91_MC + 0x9c) /* Self Refresh Register */ -#define AT91_SDRAMC_LPR (AT91_MC + 0xa0) /* Low Power Register */ -#define AT91_SDRAMC_IER (AT91_MC + 0xa4) /* Interrupt Enable Register */ -#define AT91_SDRAMC_IDR (AT91_MC + 0xa8) /* Interrupt Disable Register */ -#define AT91_SDRAMC_IMR (AT91_MC + 0xac) /* Interrupt Mask Register */ -#define AT91_SDRAMC_ISR (AT91_MC + 0xb0) /* Interrupt Status Register */ - /* Burst Flash Controller register */ -#define AT91_BFC_MR (AT91_MC + 0xc0) /* Mode Register */ +#define AT91_BFC_MR 0xc0 /* Mode Register */ #define AT91_BFC_BFCOM (3 << 0) /* Burst Flash Controller Operating Mode */ #define AT91_BFC_BFCOM_DISABLED (0 << 0) #define AT91_BFC_BFCOM_ASYNC (1 << 0) diff --git a/arch/arm/mach-at91/include/mach/at91rm9200_sdramc.h b/arch/arm/mach-at91/include/mach/at91rm9200_sdramc.h new file mode 100644 index 000000000000..aa047f458f1b --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91rm9200_sdramc.h @@ -0,0 +1,63 @@ +/* + * arch/arm/mach-at91/include/mach/at91rm9200_sdramc.h + * + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) SAN People + * + * Memory Controllers (SDRAMC only) - System peripherals registers. + * Based on AT91RM9200 datasheet revision E. + * + * 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. + */ + +#ifndef AT91RM9200_SDRAMC_H +#define AT91RM9200_SDRAMC_H + +/* SDRAM Controller registers */ +#define AT91RM9200_SDRAMC_MR 0x90 /* Mode Register */ +#define AT91RM9200_SDRAMC_MODE (0xf << 0) /* Command Mode */ +#define AT91RM9200_SDRAMC_MODE_NORMAL (0 << 0) +#define AT91RM9200_SDRAMC_MODE_NOP (1 << 0) +#define AT91RM9200_SDRAMC_MODE_PRECHARGE (2 << 0) +#define AT91RM9200_SDRAMC_MODE_LMR (3 << 0) +#define AT91RM9200_SDRAMC_MODE_REFRESH (4 << 0) +#define AT91RM9200_SDRAMC_DBW (1 << 4) /* Data Bus Width */ +#define AT91RM9200_SDRAMC_DBW_32 (0 << 4) +#define AT91RM9200_SDRAMC_DBW_16 (1 << 4) + +#define AT91RM9200_SDRAMC_TR 0x94 /* Refresh Timer Register */ +#define AT91RM9200_SDRAMC_COUNT (0xfff << 0) /* Refresh Timer Count */ + +#define AT91RM9200_SDRAMC_CR 0x98 /* Configuration Register */ +#define AT91RM9200_SDRAMC_NC (3 << 0) /* Number of Column Bits */ +#define AT91RM9200_SDRAMC_NC_8 (0 << 0) +#define AT91RM9200_SDRAMC_NC_9 (1 << 0) +#define AT91RM9200_SDRAMC_NC_10 (2 << 0) +#define AT91RM9200_SDRAMC_NC_11 (3 << 0) +#define AT91RM9200_SDRAMC_NR (3 << 2) /* Number of Row Bits */ +#define AT91RM9200_SDRAMC_NR_11 (0 << 2) +#define AT91RM9200_SDRAMC_NR_12 (1 << 2) +#define AT91RM9200_SDRAMC_NR_13 (2 << 2) +#define AT91RM9200_SDRAMC_NB (1 << 4) /* Number of Banks */ +#define AT91RM9200_SDRAMC_NB_2 (0 << 4) +#define AT91RM9200_SDRAMC_NB_4 (1 << 4) +#define AT91RM9200_SDRAMC_CAS (3 << 5) /* CAS Latency */ +#define AT91RM9200_SDRAMC_CAS_2 (2 << 5) +#define AT91RM9200_SDRAMC_TWR (0xf << 7) /* Write Recovery Delay */ +#define AT91RM9200_SDRAMC_TRC (0xf << 11) /* Row Cycle Delay */ +#define AT91RM9200_SDRAMC_TRP (0xf << 15) /* Row Precharge Delay */ +#define AT91RM9200_SDRAMC_TRCD (0xf << 19) /* Row to Column Delay */ +#define AT91RM9200_SDRAMC_TRAS (0xf << 23) /* Active to Precharge Delay */ +#define AT91RM9200_SDRAMC_TXSR (0xf << 27) /* Exit Self Refresh to Active Delay */ + +#define AT91RM9200_SDRAMC_SRR 0x9c /* Self Refresh Register */ +#define AT91RM9200_SDRAMC_LPR 0xa0 /* Low Power Register */ +#define AT91RM9200_SDRAMC_IER 0xa4 /* Interrupt Enable Register */ +#define AT91RM9200_SDRAMC_IDR 0xa8 /* Interrupt Disable Register */ +#define AT91RM9200_SDRAMC_IMR 0xac /* Interrupt Mask Register */ +#define AT91RM9200_SDRAMC_ISR 0xb0 /* Interrupt Status Register */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index fa5ca278adeb..08ae9afd00fe 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -78,15 +78,12 @@ #define AT91SAM9260_BASE_ADC 0xfffe0000 /* - * System Peripherals (offset from AT91_BASE_SYS) + * System Peripherals */ -#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) -#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) -#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) -#define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) - #define AT91SAM9260_BASE_ECC 0xffffe800 +#define AT91SAM9260_BASE_SDRAMC 0xffffea00 #define AT91SAM9260_BASE_SMC 0xffffec00 +#define AT91SAM9260_BASE_MATRIX 0xffffee00 #define AT91SAM9260_BASE_DBGU AT91_BASE_DBGU0 #define AT91SAM9260_BASE_PIOA 0xfffff400 #define AT91SAM9260_BASE_PIOB 0xfffff600 @@ -96,6 +93,7 @@ #define AT91SAM9260_BASE_RTT 0xfffffd20 #define AT91SAM9260_BASE_PIT 0xfffffd30 #define AT91SAM9260_BASE_WDT 0xfffffd40 +#define AT91SAM9260_BASE_GPBR 0xfffffd50 #define AT91_USART0 AT91SAM9260_BASE_US0 #define AT91_USART1 AT91SAM9260_BASE_US1 @@ -115,6 +113,8 @@ #define AT91SAM9260_SRAM0_SIZE SZ_4K /* Internal SRAM 0 size (4Kb) */ #define AT91SAM9260_SRAM1_BASE 0x00300000 /* Internal SRAM 1 base address */ #define AT91SAM9260_SRAM1_SIZE SZ_4K /* Internal SRAM 1 size (4Kb) */ +#define AT91SAM9260_SRAM_BASE 0x002FF000 /* Internal SRAM base address */ +#define AT91SAM9260_SRAM_SIZE SZ_8K /* Internal SRAM size (8Kb) */ #define AT91SAM9260_UHP_BASE 0x00500000 /* USB Host controller */ @@ -128,6 +128,8 @@ #define AT91SAM9G20_SRAM0_SIZE SZ_16K /* Internal SRAM 0 size (16Kb) */ #define AT91SAM9G20_SRAM1_BASE 0x00300000 /* Internal SRAM 1 base address */ #define AT91SAM9G20_SRAM1_SIZE SZ_16K /* Internal SRAM 1 size (16Kb) */ +#define AT91SAM9G20_SRAM_BASE 0x002FC000 /* Internal SRAM base address */ +#define AT91SAM9G20_SRAM_SIZE SZ_32K /* Internal SRAM size (32Kb) */ #define AT91SAM9G20_UHP_BASE 0x00500000 /* USB Host controller */ diff --git a/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h index 020f02ed921a..f459df420629 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h @@ -15,12 +15,12 @@ #ifndef AT91SAM9260_MATRIX_H #define AT91SAM9260_MATRIX_H -#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */ -#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */ -#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */ -#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */ -#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */ -#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */ +#define AT91_MATRIX_MCFG0 0x00 /* Master Configuration Register 0 */ +#define AT91_MATRIX_MCFG1 0x04 /* Master Configuration Register 1 */ +#define AT91_MATRIX_MCFG2 0x08 /* Master Configuration Register 2 */ +#define AT91_MATRIX_MCFG3 0x0C /* Master Configuration Register 3 */ +#define AT91_MATRIX_MCFG4 0x10 /* Master Configuration Register 4 */ +#define AT91_MATRIX_MCFG5 0x14 /* Master Configuration Register 5 */ #define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */ #define AT91_MATRIX_ULBT_INFINITE (0 << 0) #define AT91_MATRIX_ULBT_SINGLE (1 << 0) @@ -28,11 +28,11 @@ #define AT91_MATRIX_ULBT_EIGHT (3 << 0) #define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) -#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */ -#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */ -#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */ -#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */ -#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */ +#define AT91_MATRIX_SCFG0 0x40 /* Slave Configuration Register 0 */ +#define AT91_MATRIX_SCFG1 0x44 /* Slave Configuration Register 1 */ +#define AT91_MATRIX_SCFG2 0x48 /* Slave Configuration Register 2 */ +#define AT91_MATRIX_SCFG3 0x4C /* Slave Configuration Register 3 */ +#define AT91_MATRIX_SCFG4 0x50 /* Slave Configuration Register 4 */ #define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */ #define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */ #define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) @@ -43,11 +43,11 @@ #define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) #define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) -#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */ -#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */ -#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */ -#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */ -#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */ +#define AT91_MATRIX_PRAS0 0x80 /* Priority Register A for Slave 0 */ +#define AT91_MATRIX_PRAS1 0x88 /* Priority Register A for Slave 1 */ +#define AT91_MATRIX_PRAS2 0x90 /* Priority Register A for Slave 2 */ +#define AT91_MATRIX_PRAS3 0x98 /* Priority Register A for Slave 3 */ +#define AT91_MATRIX_PRAS4 0xA0 /* Priority Register A for Slave 4 */ #define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */ #define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */ #define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */ @@ -55,11 +55,11 @@ #define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */ #define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */ -#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */ +#define AT91_MATRIX_MRCR 0x100 /* Master Remap Control Register */ #define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ #define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ -#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x11C) /* EBI Chip Select Assignment Register */ +#define AT91_MATRIX_EBICSA 0x11C /* EBI Chip Select Assignment Register */ #define AT91_MATRIX_CS1A (1 << 1) /* Chip Select 1 Assignment */ #define AT91_MATRIX_CS1A_SMC (0 << 1) #define AT91_MATRIX_CS1A_SDRAMC (1 << 1) diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h index 7cde2d36570e..44fbdc12ee62 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -63,14 +63,11 @@ /* - * System Peripherals (offset from AT91_BASE_SYS) + * System Peripherals */ -#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) -#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) -#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) -#define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) - #define AT91SAM9261_BASE_SMC 0xffffec00 +#define AT91SAM9261_BASE_MATRIX 0xffffee00 +#define AT91SAM9261_BASE_SDRAMC 0xffffea00 #define AT91SAM9261_BASE_DBGU AT91_BASE_DBGU0 #define AT91SAM9261_BASE_PIOA 0xfffff400 #define AT91SAM9261_BASE_PIOB 0xfffff600 @@ -80,6 +77,7 @@ #define AT91SAM9261_BASE_RTT 0xfffffd20 #define AT91SAM9261_BASE_PIT 0xfffffd30 #define AT91SAM9261_BASE_WDT 0xfffffd40 +#define AT91SAM9261_BASE_GPBR 0xfffffd50 #define AT91_USART0 AT91SAM9261_BASE_US0 #define AT91_USART1 AT91SAM9261_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h index 69c6501915d9..a50cdf8b8ca4 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h @@ -15,15 +15,15 @@ #ifndef AT91SAM9261_MATRIX_H #define AT91SAM9261_MATRIX_H -#define AT91_MATRIX_MCFG (AT91_MATRIX + 0x00) /* Master Configuration Register */ +#define AT91_MATRIX_MCFG 0x00 /* Master Configuration Register */ #define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ #define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ -#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x04) /* Slave Configuration Register 0 */ -#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x08) /* Slave Configuration Register 1 */ -#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x0C) /* Slave Configuration Register 2 */ -#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x10) /* Slave Configuration Register 3 */ -#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x14) /* Slave Configuration Register 4 */ +#define AT91_MATRIX_SCFG0 0x04 /* Slave Configuration Register 0 */ +#define AT91_MATRIX_SCFG1 0x08 /* Slave Configuration Register 1 */ +#define AT91_MATRIX_SCFG2 0x0C /* Slave Configuration Register 2 */ +#define AT91_MATRIX_SCFG3 0x10 /* Slave Configuration Register 3 */ +#define AT91_MATRIX_SCFG4 0x14 /* Slave Configuration Register 4 */ #define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */ #define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */ #define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) @@ -31,7 +31,7 @@ #define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) #define AT91_MATRIX_FIXED_DEFMSTR (7 << 18) /* Fixed Index of Default Master */ -#define AT91_MATRIX_TCR (AT91_MATRIX + 0x24) /* TCM Configuration Register */ +#define AT91_MATRIX_TCR 0x24 /* TCM Configuration Register */ #define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */ #define AT91_MATRIX_ITCM_0 (0 << 0) #define AT91_MATRIX_ITCM_16 (5 << 0) @@ -43,7 +43,7 @@ #define AT91_MATRIX_DTCM_32 (6 << 4) #define AT91_MATRIX_DTCM_64 (7 << 4) -#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x30) /* EBI Chip Select Assignment Register */ +#define AT91_MATRIX_EBICSA 0x30 /* EBI Chip Select Assignment Register */ #define AT91_MATRIX_CS1A (1 << 1) /* Chip Select 1 Assignment */ #define AT91_MATRIX_CS1A_SMC (0 << 1) #define AT91_MATRIX_CS1A_SDRAMC (1 << 1) @@ -58,7 +58,7 @@ #define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5) #define AT91_MATRIX_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */ -#define AT91_MATRIX_USBPUCR (AT91_MATRIX + 0x34) /* USB Pad Pull-Up Control Register */ +#define AT91_MATRIX_USBPUCR 0x34 /* USB Pad Pull-Up Control Register */ #define AT91_MATRIX_USBPUCR_PUON (1 << 30) /* USB Device PAD Pull-up Enable */ #endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index 5949abda962b..d96cbb2e03c4 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -72,18 +72,15 @@ #define AT91SAM9263_BASE_2DGE 0xfffc8000 /* - * System Peripherals (offset from AT91_BASE_SYS) + * System Peripherals */ -#define AT91_SDRAMC0 (0xffffe200 - AT91_BASE_SYS) -#define AT91_SDRAMC1 (0xffffe800 - AT91_BASE_SYS) -#define AT91_MATRIX (0xffffec00 - AT91_BASE_SYS) -#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) -#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) - #define AT91SAM9263_BASE_ECC0 0xffffe000 +#define AT91SAM9263_BASE_SDRAMC0 0xffffe200 #define AT91SAM9263_BASE_SMC0 0xffffe400 #define AT91SAM9263_BASE_ECC1 0xffffe600 +#define AT91SAM9263_BASE_SDRAMC1 0xffffe800 #define AT91SAM9263_BASE_SMC1 0xffffea00 +#define AT91SAM9263_BASE_MATRIX 0xffffec00 #define AT91SAM9263_BASE_DBGU AT91_BASE_DBGU1 #define AT91SAM9263_BASE_PIOA 0xfffff200 #define AT91SAM9263_BASE_PIOB 0xfffff400 @@ -96,6 +93,7 @@ #define AT91SAM9263_BASE_PIT 0xfffffd30 #define AT91SAM9263_BASE_WDT 0xfffffd40 #define AT91SAM9263_BASE_RTT1 0xfffffd50 +#define AT91SAM9263_BASE_GPBR 0xfffffd60 #define AT91_USART0 AT91SAM9263_BASE_US0 #define AT91_USART1 AT91SAM9263_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9263_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9263_matrix.h index 9b3efd3eb2f3..ebb5fdb565e0 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263_matrix.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263_matrix.h @@ -15,15 +15,15 @@ #ifndef AT91SAM9263_MATRIX_H #define AT91SAM9263_MATRIX_H -#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */ -#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */ -#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */ -#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */ -#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */ -#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */ -#define AT91_MATRIX_MCFG6 (AT91_MATRIX + 0x18) /* Master Configuration Register 6 */ -#define AT91_MATRIX_MCFG7 (AT91_MATRIX + 0x1C) /* Master Configuration Register 7 */ -#define AT91_MATRIX_MCFG8 (AT91_MATRIX + 0x20) /* Master Configuration Register 8 */ +#define AT91_MATRIX_MCFG0 0x00 /* Master Configuration Register 0 */ +#define AT91_MATRIX_MCFG1 0x04 /* Master Configuration Register 1 */ +#define AT91_MATRIX_MCFG2 0x08 /* Master Configuration Register 2 */ +#define AT91_MATRIX_MCFG3 0x0C /* Master Configuration Register 3 */ +#define AT91_MATRIX_MCFG4 0x10 /* Master Configuration Register 4 */ +#define AT91_MATRIX_MCFG5 0x14 /* Master Configuration Register 5 */ +#define AT91_MATRIX_MCFG6 0x18 /* Master Configuration Register 6 */ +#define AT91_MATRIX_MCFG7 0x1C /* Master Configuration Register 7 */ +#define AT91_MATRIX_MCFG8 0x20 /* Master Configuration Register 8 */ #define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */ #define AT91_MATRIX_ULBT_INFINITE (0 << 0) #define AT91_MATRIX_ULBT_SINGLE (1 << 0) @@ -31,14 +31,14 @@ #define AT91_MATRIX_ULBT_EIGHT (3 << 0) #define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) -#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */ -#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */ -#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */ -#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */ -#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */ -#define AT91_MATRIX_SCFG5 (AT91_MATRIX + 0x54) /* Slave Configuration Register 5 */ -#define AT91_MATRIX_SCFG6 (AT91_MATRIX + 0x58) /* Slave Configuration Register 6 */ -#define AT91_MATRIX_SCFG7 (AT91_MATRIX + 0x5C) /* Slave Configuration Register 7 */ +#define AT91_MATRIX_SCFG0 0x40 /* Slave Configuration Register 0 */ +#define AT91_MATRIX_SCFG1 0x44 /* Slave Configuration Register 1 */ +#define AT91_MATRIX_SCFG2 0x48 /* Slave Configuration Register 2 */ +#define AT91_MATRIX_SCFG3 0x4C /* Slave Configuration Register 3 */ +#define AT91_MATRIX_SCFG4 0x50 /* Slave Configuration Register 4 */ +#define AT91_MATRIX_SCFG5 0x54 /* Slave Configuration Register 5 */ +#define AT91_MATRIX_SCFG6 0x58 /* Slave Configuration Register 6 */ +#define AT91_MATRIX_SCFG7 0x5C /* Slave Configuration Register 7 */ #define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */ #define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */ #define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) @@ -49,22 +49,22 @@ #define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) #define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) -#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */ -#define AT91_MATRIX_PRBS0 (AT91_MATRIX + 0x84) /* Priority Register B for Slave 0 */ -#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */ -#define AT91_MATRIX_PRBS1 (AT91_MATRIX + 0x8C) /* Priority Register B for Slave 1 */ -#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */ -#define AT91_MATRIX_PRBS2 (AT91_MATRIX + 0x94) /* Priority Register B for Slave 2 */ -#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */ -#define AT91_MATRIX_PRBS3 (AT91_MATRIX + 0x9C) /* Priority Register B for Slave 3 */ -#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */ -#define AT91_MATRIX_PRBS4 (AT91_MATRIX + 0xA4) /* Priority Register B for Slave 4 */ -#define AT91_MATRIX_PRAS5 (AT91_MATRIX + 0xA8) /* Priority Register A for Slave 5 */ -#define AT91_MATRIX_PRBS5 (AT91_MATRIX + 0xAC) /* Priority Register B for Slave 5 */ -#define AT91_MATRIX_PRAS6 (AT91_MATRIX + 0xB0) /* Priority Register A for Slave 6 */ -#define AT91_MATRIX_PRBS6 (AT91_MATRIX + 0xB4) /* Priority Register B for Slave 6 */ -#define AT91_MATRIX_PRAS7 (AT91_MATRIX + 0xB8) /* Priority Register A for Slave 7 */ -#define AT91_MATRIX_PRBS7 (AT91_MATRIX + 0xBC) /* Priority Register B for Slave 7 */ +#define AT91_MATRIX_PRAS0 0x80 /* Priority Register A for Slave 0 */ +#define AT91_MATRIX_PRBS0 0x84 /* Priority Register B for Slave 0 */ +#define AT91_MATRIX_PRAS1 0x88 /* Priority Register A for Slave 1 */ +#define AT91_MATRIX_PRBS1 0x8C /* Priority Register B for Slave 1 */ +#define AT91_MATRIX_PRAS2 0x90 /* Priority Register A for Slave 2 */ +#define AT91_MATRIX_PRBS2 0x94 /* Priority Register B for Slave 2 */ +#define AT91_MATRIX_PRAS3 0x98 /* Priority Register A for Slave 3 */ +#define AT91_MATRIX_PRBS3 0x9C /* Priority Register B for Slave 3 */ +#define AT91_MATRIX_PRAS4 0xA0 /* Priority Register A for Slave 4 */ +#define AT91_MATRIX_PRBS4 0xA4 /* Priority Register B for Slave 4 */ +#define AT91_MATRIX_PRAS5 0xA8 /* Priority Register A for Slave 5 */ +#define AT91_MATRIX_PRBS5 0xAC /* Priority Register B for Slave 5 */ +#define AT91_MATRIX_PRAS6 0xB0 /* Priority Register A for Slave 6 */ +#define AT91_MATRIX_PRBS6 0xB4 /* Priority Register B for Slave 6 */ +#define AT91_MATRIX_PRAS7 0xB8 /* Priority Register A for Slave 7 */ +#define AT91_MATRIX_PRBS7 0xBC /* Priority Register B for Slave 7 */ #define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */ #define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */ #define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */ @@ -75,7 +75,7 @@ #define AT91_MATRIX_M7PR (3 << 28) /* Master 7 Priority */ #define AT91_MATRIX_M8PR (3 << 0) /* Master 8 Priority (in Register B) */ -#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */ +#define AT91_MATRIX_MRCR 0x100 /* Master Remap Control Register */ #define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ #define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ #define AT91_MATRIX_RCB2 (1 << 2) @@ -86,7 +86,7 @@ #define AT91_MATRIX_RCB7 (1 << 7) #define AT91_MATRIX_RCB8 (1 << 8) -#define AT91_MATRIX_TCMR (AT91_MATRIX + 0x114) /* TCM Configuration Register */ +#define AT91_MATRIX_TCMR 0x114 /* TCM Configuration Register */ #define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */ #define AT91_MATRIX_ITCM_0 (0 << 0) #define AT91_MATRIX_ITCM_16 (5 << 0) @@ -96,7 +96,7 @@ #define AT91_MATRIX_DTCM_16 (5 << 4) #define AT91_MATRIX_DTCM_32 (6 << 4) -#define AT91_MATRIX_EBI0CSA (AT91_MATRIX + 0x120) /* EBI0 Chip Select Assignment Register */ +#define AT91_MATRIX_EBI0CSA 0x120 /* EBI0 Chip Select Assignment Register */ #define AT91_MATRIX_EBI0_CS1A (1 << 1) /* Chip Select 1 Assignment */ #define AT91_MATRIX_EBI0_CS1A_SMC (0 << 1) #define AT91_MATRIX_EBI0_CS1A_SDRAMC (1 << 1) @@ -114,7 +114,7 @@ #define AT91_MATRIX_EBI0_VDDIOMSEL_1_8V (0 << 16) #define AT91_MATRIX_EBI0_VDDIOMSEL_3_3V (1 << 16) -#define AT91_MATRIX_EBI1CSA (AT91_MATRIX + 0x124) /* EBI1 Chip Select Assignment Register */ +#define AT91_MATRIX_EBI1CSA 0x124 /* EBI1 Chip Select Assignment Register */ #define AT91_MATRIX_EBI1_CS1A (1 << 1) /* Chip Select 1 Assignment */ #define AT91_MATRIX_EBI1_CS1A_SMC (0 << 1) #define AT91_MATRIX_EBI1_CS1A_SDRAMC (1 << 1) diff --git a/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h index e2f8da8ce5bc..0210797abf2e 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h +++ b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h @@ -59,7 +59,6 @@ #define AT91_DDRSDRC_TRP (0xf << 16) /* Row precharge delay */ #define AT91_DDRSDRC_TRRD (0xf << 20) /* Active BankA to BankB */ #define AT91_DDRSDRC_TWTR (0x7 << 24) /* Internal Write to Read delay */ -#define AT91CAP9_DDRSDRC_TWTR (1 << 24) /* Internal Write to Read delay */ #define AT91_DDRSDRC_RED_WRRD (0x1 << 27) /* Reduce Write to Read Delay [SAM9 Only] */ #define AT91_DDRSDRC_TMRD (0xf << 28) /* Load mode to active/refresh delay */ @@ -76,7 +75,6 @@ #define AT91_DDRSDRC_TRTP (0x7 << 12) /* Read to Precharge delay */ #define AT91_DDRSDRC_LPR 0x1C /* Low Power Register */ -#define AT91CAP9_DDRSDRC_LPR 0x18 /* Low Power Register */ #define AT91_DDRSDRC_LPCB (3 << 0) /* Low-power Configurations */ #define AT91_DDRSDRC_LPCB_DISABLE 0 #define AT91_DDRSDRC_LPCB_SELF_REFRESH 1 @@ -94,11 +92,9 @@ #define AT91_DDRSDRC_UPD_MR (3 << 20) /* Update load mode register and extended mode register */ #define AT91_DDRSDRC_MDR 0x20 /* Memory Device Register */ -#define AT91CAP9_DDRSDRC_MDR 0x1C /* Memory Device Register */ #define AT91_DDRSDRC_MD (3 << 0) /* Memory Device Type */ #define AT91_DDRSDRC_MD_SDR 0 #define AT91_DDRSDRC_MD_LOW_POWER_SDR 1 -#define AT91CAP9_DDRSDRC_MD_DDR 2 #define AT91_DDRSDRC_MD_LOW_POWER_DDR 3 #define AT91_DDRSDRC_MD_DDR2 6 /* [SAM9 Only] */ #define AT91_DDRSDRC_DBW (1 << 4) /* Data Bus Width */ @@ -106,16 +102,10 @@ #define AT91_DDRSDRC_DBW_16BITS (1 << 4) #define AT91_DDRSDRC_DLL 0x24 /* DLL Information Register */ -#define AT91CAP9_DDRSDRC_DLL 0x20 /* DLL Information Register */ #define AT91_DDRSDRC_MDINC (1 << 0) /* Master Delay increment */ #define AT91_DDRSDRC_MDDEC (1 << 1) /* Master Delay decrement */ #define AT91_DDRSDRC_MDOVF (1 << 2) /* Master Delay Overflow */ -#define AT91CAP9_DDRSDRC_SDCOVF (1 << 3) /* Slave Delay Correction Overflow */ -#define AT91CAP9_DDRSDRC_SDCUDF (1 << 4) /* Slave Delay Correction Underflow */ -#define AT91CAP9_DDRSDRC_SDERF (1 << 5) /* Slave Delay Correction error */ #define AT91_DDRSDRC_MDVAL (0xff << 8) /* Master Delay value */ -#define AT91CAP9_DDRSDRC_SDVAL (0xff << 16) /* Slave Delay value */ -#define AT91CAP9_DDRSDRC_SDCVAL (0xff << 24) /* Slave Delay Correction value */ #define AT91_DDRSDRC_HS 0x2C /* High Speed Register [SAM9 Only] */ #define AT91_DDRSDRC_DIS_ATCP_RD (1 << 2) /* Anticip read access is disabled */ @@ -131,10 +121,4 @@ #define AT91_DDRSDRC_WPVS (1 << 0) /* Write protect violation status */ #define AT91_DDRSDRC_WPVSRC (0xffff << 8) /* Write protect violation source */ -/* Register access macros */ -#define at91_ramc_read(num, reg) \ - at91_sys_read(AT91_DDRSDRC##num + reg) -#define at91_ramc_write(num, reg, value) \ - at91_sys_write(AT91_DDRSDRC##num + reg, value) - #endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h b/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h index 100f5a592926..3d085a9a7450 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h +++ b/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h @@ -82,10 +82,4 @@ #define AT91_SDRAMC_MD_SDRAM 0 #define AT91_SDRAMC_MD_LOW_POWER_SDRAM 1 -/* Register access macros */ -#define at91_ramc_read(num, reg) \ - at91_sys_read(AT91_SDRAMC##num + reg) -#define at91_ramc_write(num, reg, value) \ - at91_sys_write(AT91_SDRAMC##num + reg, value) - #endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index dd9c95ea0862..d052abcff852 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -84,17 +84,14 @@ #define AT91SAM9G45_BASE_TC5 0xfffd4080 /* - * System Peripherals (offset from AT91_BASE_SYS) + * System Peripherals */ -#define AT91_DDRSDRC1 (0xffffe400 - AT91_BASE_SYS) -#define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) -#define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) -#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) -#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) - #define AT91SAM9G45_BASE_ECC 0xffffe200 +#define AT91SAM9G45_BASE_DDRSDRC1 0xffffe400 +#define AT91SAM9G45_BASE_DDRSDRC0 0xffffe600 #define AT91SAM9G45_BASE_DMA 0xffffec00 #define AT91SAM9G45_BASE_SMC 0xffffe800 +#define AT91SAM9G45_BASE_MATRIX 0xffffea00 #define AT91SAM9G45_BASE_DBGU AT91_BASE_DBGU1 #define AT91SAM9G45_BASE_PIOA 0xfffff200 #define AT91SAM9G45_BASE_PIOB 0xfffff400 @@ -107,6 +104,7 @@ #define AT91SAM9G45_BASE_PIT 0xfffffd30 #define AT91SAM9G45_BASE_WDT 0xfffffd40 #define AT91SAM9G45_BASE_RTC 0xfffffdb0 +#define AT91SAM9G45_BASE_GPBR 0xfffffd60 #define AT91_USART0 AT91SAM9G45_BASE_US0 #define AT91_USART1 AT91SAM9G45_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h index c972d60e0aeb..b76e2ed2fbc2 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h @@ -15,18 +15,18 @@ #ifndef AT91SAM9G45_MATRIX_H #define AT91SAM9G45_MATRIX_H -#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */ -#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */ -#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */ -#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */ -#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */ -#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */ -#define AT91_MATRIX_MCFG6 (AT91_MATRIX + 0x18) /* Master Configuration Register 6 */ -#define AT91_MATRIX_MCFG7 (AT91_MATRIX + 0x1C) /* Master Configuration Register 7 */ -#define AT91_MATRIX_MCFG8 (AT91_MATRIX + 0x20) /* Master Configuration Register 8 */ -#define AT91_MATRIX_MCFG9 (AT91_MATRIX + 0x24) /* Master Configuration Register 9 */ -#define AT91_MATRIX_MCFG10 (AT91_MATRIX + 0x28) /* Master Configuration Register 10 */ -#define AT91_MATRIX_MCFG11 (AT91_MATRIX + 0x2C) /* Master Configuration Register 11 */ +#define AT91_MATRIX_MCFG0 0x00 /* Master Configuration Register 0 */ +#define AT91_MATRIX_MCFG1 0x04 /* Master Configuration Register 1 */ +#define AT91_MATRIX_MCFG2 0x08 /* Master Configuration Register 2 */ +#define AT91_MATRIX_MCFG3 0x0C /* Master Configuration Register 3 */ +#define AT91_MATRIX_MCFG4 0x10 /* Master Configuration Register 4 */ +#define AT91_MATRIX_MCFG5 0x14 /* Master Configuration Register 5 */ +#define AT91_MATRIX_MCFG6 0x18 /* Master Configuration Register 6 */ +#define AT91_MATRIX_MCFG7 0x1C /* Master Configuration Register 7 */ +#define AT91_MATRIX_MCFG8 0x20 /* Master Configuration Register 8 */ +#define AT91_MATRIX_MCFG9 0x24 /* Master Configuration Register 9 */ +#define AT91_MATRIX_MCFG10 0x28 /* Master Configuration Register 10 */ +#define AT91_MATRIX_MCFG11 0x2C /* Master Configuration Register 11 */ #define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */ #define AT91_MATRIX_ULBT_INFINITE (0 << 0) #define AT91_MATRIX_ULBT_SINGLE (1 << 0) @@ -37,14 +37,14 @@ #define AT91_MATRIX_ULBT_SIXTYFOUR (6 << 0) #define AT91_MATRIX_ULBT_128 (7 << 0) -#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */ -#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */ -#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */ -#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */ -#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */ -#define AT91_MATRIX_SCFG5 (AT91_MATRIX + 0x54) /* Slave Configuration Register 5 */ -#define AT91_MATRIX_SCFG6 (AT91_MATRIX + 0x58) /* Slave Configuration Register 6 */ -#define AT91_MATRIX_SCFG7 (AT91_MATRIX + 0x5C) /* Slave Configuration Register 7 */ +#define AT91_MATRIX_SCFG0 0x40 /* Slave Configuration Register 0 */ +#define AT91_MATRIX_SCFG1 0x44 /* Slave Configuration Register 1 */ +#define AT91_MATRIX_SCFG2 0x48 /* Slave Configuration Register 2 */ +#define AT91_MATRIX_SCFG3 0x4C /* Slave Configuration Register 3 */ +#define AT91_MATRIX_SCFG4 0x50 /* Slave Configuration Register 4 */ +#define AT91_MATRIX_SCFG5 0x54 /* Slave Configuration Register 5 */ +#define AT91_MATRIX_SCFG6 0x58 /* Slave Configuration Register 6 */ +#define AT91_MATRIX_SCFG7 0x5C /* Slave Configuration Register 7 */ #define AT91_MATRIX_SLOT_CYCLE (0x1ff << 0) /* Maximum Number of Allowed Cycles for a Burst */ #define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */ #define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) @@ -52,22 +52,22 @@ #define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) #define AT91_MATRIX_FIXED_DEFMSTR (0xf << 18) /* Fixed Index of Default Master */ -#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */ -#define AT91_MATRIX_PRBS0 (AT91_MATRIX + 0x84) /* Priority Register B for Slave 0 */ -#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */ -#define AT91_MATRIX_PRBS1 (AT91_MATRIX + 0x8C) /* Priority Register B for Slave 1 */ -#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */ -#define AT91_MATRIX_PRBS2 (AT91_MATRIX + 0x94) /* Priority Register B for Slave 2 */ -#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */ -#define AT91_MATRIX_PRBS3 (AT91_MATRIX + 0x9C) /* Priority Register B for Slave 3 */ -#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */ -#define AT91_MATRIX_PRBS4 (AT91_MATRIX + 0xA4) /* Priority Register B for Slave 4 */ -#define AT91_MATRIX_PRAS5 (AT91_MATRIX + 0xA8) /* Priority Register A for Slave 5 */ -#define AT91_MATRIX_PRBS5 (AT91_MATRIX + 0xAC) /* Priority Register B for Slave 5 */ -#define AT91_MATRIX_PRAS6 (AT91_MATRIX + 0xB0) /* Priority Register A for Slave 6 */ -#define AT91_MATRIX_PRBS6 (AT91_MATRIX + 0xB4) /* Priority Register B for Slave 6 */ -#define AT91_MATRIX_PRAS7 (AT91_MATRIX + 0xB8) /* Priority Register A for Slave 7 */ -#define AT91_MATRIX_PRBS7 (AT91_MATRIX + 0xBC) /* Priority Register B for Slave 7 */ +#define AT91_MATRIX_PRAS0 0x80 /* Priority Register A for Slave 0 */ +#define AT91_MATRIX_PRBS0 0x84 /* Priority Register B for Slave 0 */ +#define AT91_MATRIX_PRAS1 0x88 /* Priority Register A for Slave 1 */ +#define AT91_MATRIX_PRBS1 0x8C /* Priority Register B for Slave 1 */ +#define AT91_MATRIX_PRAS2 0x90 /* Priority Register A for Slave 2 */ +#define AT91_MATRIX_PRBS2 0x94 /* Priority Register B for Slave 2 */ +#define AT91_MATRIX_PRAS3 0x98 /* Priority Register A for Slave 3 */ +#define AT91_MATRIX_PRBS3 0x9C /* Priority Register B for Slave 3 */ +#define AT91_MATRIX_PRAS4 0xA0 /* Priority Register A for Slave 4 */ +#define AT91_MATRIX_PRBS4 0xA4 /* Priority Register B for Slave 4 */ +#define AT91_MATRIX_PRAS5 0xA8 /* Priority Register A for Slave 5 */ +#define AT91_MATRIX_PRBS5 0xAC /* Priority Register B for Slave 5 */ +#define AT91_MATRIX_PRAS6 0xB0 /* Priority Register A for Slave 6 */ +#define AT91_MATRIX_PRBS6 0xB4 /* Priority Register B for Slave 6 */ +#define AT91_MATRIX_PRAS7 0xB8 /* Priority Register A for Slave 7 */ +#define AT91_MATRIX_PRBS7 0xBC /* Priority Register B for Slave 7 */ #define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */ #define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */ #define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */ @@ -81,7 +81,7 @@ #define AT91_MATRIX_M10PR (3 << 8) /* Master 10 Priority (in Register B) */ #define AT91_MATRIX_M11PR (3 << 12) /* Master 11 Priority (in Register B) */ -#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */ +#define AT91_MATRIX_MRCR 0x100 /* Master Remap Control Register */ #define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ #define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ #define AT91_MATRIX_RCB2 (1 << 2) @@ -95,7 +95,7 @@ #define AT91_MATRIX_RCB10 (1 << 10) #define AT91_MATRIX_RCB11 (1 << 11) -#define AT91_MATRIX_TCMR (AT91_MATRIX + 0x110) /* TCM Configuration Register */ +#define AT91_MATRIX_TCMR 0x110 /* TCM Configuration Register */ #define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */ #define AT91_MATRIX_ITCM_0 (0 << 0) #define AT91_MATRIX_ITCM_32 (6 << 0) @@ -107,12 +107,12 @@ #define AT91_MATRIX_TCM_NO_WS (0x0 << 11) #define AT91_MATRIX_TCM_ONE_WS (0x1 << 11) -#define AT91_MATRIX_VIDEO (AT91_MATRIX + 0x118) /* Video Mode Configuration Register */ +#define AT91_MATRIX_VIDEO 0x118 /* Video Mode Configuration Register */ #define AT91C_VDEC_SEL (0x1 << 0) /* Video Mode Selection */ #define AT91C_VDEC_SEL_OFF (0 << 0) #define AT91C_VDEC_SEL_ON (1 << 0) -#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x128) /* EBI Chip Select Assignment Register */ +#define AT91_MATRIX_EBICSA 0x128 /* EBI Chip Select Assignment Register */ #define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */ #define AT91_MATRIX_EBI_CS1A_SMC (0 << 1) #define AT91_MATRIX_EBI_CS1A_SDRAMC (1 << 1) @@ -138,13 +138,13 @@ #define AT91_MATRIX_EBI_DDR_IOSR_REDUCED (0 << 18) #define AT91_MATRIX_EBI_DDR_IOSR_NORMAL (1 << 18) -#define AT91_MATRIX_WPMR (AT91_MATRIX + 0x1E4) /* Write Protect Mode Register */ +#define AT91_MATRIX_WPMR 0x1E4 /* Write Protect Mode Register */ #define AT91_MATRIX_WPMR_WPEN (1 << 0) /* Write Protect ENable */ #define AT91_MATRIX_WPMR_WP_WPDIS (0 << 0) #define AT91_MATRIX_WPMR_WP_WPEN (1 << 0) #define AT91_MATRIX_WPMR_WPKEY (0xFFFFFF << 8) /* Write Protect KEY */ -#define AT91_MATRIX_WPSR (AT91_MATRIX + 0x1E8) /* Write Protect Status Register */ +#define AT91_MATRIX_WPSR 0x1E8 /* Write Protect Status Register */ #define AT91_MATRIX_WPSR_WPVS (1 << 0) /* Write Protect Violation Status */ #define AT91_MATRIX_WPSR_NO_WPV (0 << 0) #define AT91_MATRIX_WPSR_WPV (1 << 0) diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index d7bead7118da..e0073eb10144 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -69,15 +69,13 @@ /* * System Peripherals (offset from AT91_BASE_SYS) */ -#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) -#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) -#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS) -#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91SAM9RL_BASE_DMA 0xffffe600 #define AT91SAM9RL_BASE_ECC 0xffffe800 +#define AT91SAM9RL_BASE_SDRAMC 0xffffea00 #define AT91SAM9RL_BASE_SMC 0xffffec00 +#define AT91SAM9RL_BASE_MATRIX 0xffffee00 #define AT91SAM9RL_BASE_DBGU AT91_BASE_DBGU0 #define AT91SAM9RL_BASE_PIOA 0xfffff400 #define AT91SAM9RL_BASE_PIOB 0xfffff600 @@ -88,6 +86,7 @@ #define AT91SAM9RL_BASE_RTT 0xfffffd20 #define AT91SAM9RL_BASE_PIT 0xfffffd30 #define AT91SAM9RL_BASE_WDT 0xfffffd40 +#define AT91SAM9RL_BASE_GPBR 0xfffffd60 #define AT91SAM9RL_BASE_RTC 0xfffffe00 #define AT91_USART0 AT91SAM9RL_BASE_US0 diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9rl_matrix.h index 5f9149071fe5..6d160adadafc 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl_matrix.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl_matrix.h @@ -14,12 +14,12 @@ #ifndef AT91SAM9RL_MATRIX_H #define AT91SAM9RL_MATRIX_H -#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */ -#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */ -#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */ -#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */ -#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */ -#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */ +#define AT91_MATRIX_MCFG0 0x00 /* Master Configuration Register 0 */ +#define AT91_MATRIX_MCFG1 0x04 /* Master Configuration Register 1 */ +#define AT91_MATRIX_MCFG2 0x08 /* Master Configuration Register 2 */ +#define AT91_MATRIX_MCFG3 0x0C /* Master Configuration Register 3 */ +#define AT91_MATRIX_MCFG4 0x10 /* Master Configuration Register 4 */ +#define AT91_MATRIX_MCFG5 0x14 /* Master Configuration Register 5 */ #define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */ #define AT91_MATRIX_ULBT_INFINITE (0 << 0) #define AT91_MATRIX_ULBT_SINGLE (1 << 0) @@ -27,12 +27,12 @@ #define AT91_MATRIX_ULBT_EIGHT (3 << 0) #define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) -#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */ -#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */ -#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */ -#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */ -#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */ -#define AT91_MATRIX_SCFG5 (AT91_MATRIX + 0x54) /* Slave Configuration Register 5 */ +#define AT91_MATRIX_SCFG0 0x40 /* Slave Configuration Register 0 */ +#define AT91_MATRIX_SCFG1 0x44 /* Slave Configuration Register 1 */ +#define AT91_MATRIX_SCFG2 0x48 /* Slave Configuration Register 2 */ +#define AT91_MATRIX_SCFG3 0x4C /* Slave Configuration Register 3 */ +#define AT91_MATRIX_SCFG4 0x50 /* Slave Configuration Register 4 */ +#define AT91_MATRIX_SCFG5 0x54 /* Slave Configuration Register 5 */ #define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */ #define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */ #define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) @@ -43,12 +43,12 @@ #define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) #define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) -#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */ -#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */ -#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */ -#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */ -#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */ -#define AT91_MATRIX_PRAS5 (AT91_MATRIX + 0xA8) /* Priority Register A for Slave 5 */ +#define AT91_MATRIX_PRAS0 0x80 /* Priority Register A for Slave 0 */ +#define AT91_MATRIX_PRAS1 0x88 /* Priority Register A for Slave 1 */ +#define AT91_MATRIX_PRAS2 0x90 /* Priority Register A for Slave 2 */ +#define AT91_MATRIX_PRAS3 0x98 /* Priority Register A for Slave 3 */ +#define AT91_MATRIX_PRAS4 0xA0 /* Priority Register A for Slave 4 */ +#define AT91_MATRIX_PRAS5 0xA8 /* Priority Register A for Slave 5 */ #define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */ #define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */ #define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */ @@ -56,7 +56,7 @@ #define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */ #define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */ -#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */ +#define AT91_MATRIX_MRCR 0x100 /* Master Remap Control Register */ #define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ #define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ #define AT91_MATRIX_RCB2 (1 << 2) @@ -64,7 +64,7 @@ #define AT91_MATRIX_RCB4 (1 << 4) #define AT91_MATRIX_RCB5 (1 << 5) -#define AT91_MATRIX_TCMR (AT91_MATRIX + 0x114) /* TCM Configuration Register */ +#define AT91_MATRIX_TCMR 0x114 /* TCM Configuration Register */ #define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */ #define AT91_MATRIX_ITCM_0 (0 << 0) #define AT91_MATRIX_ITCM_16 (5 << 0) @@ -74,7 +74,7 @@ #define AT91_MATRIX_DTCM_16 (5 << 4) #define AT91_MATRIX_DTCM_32 (6 << 4) -#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x120) /* EBI0 Chip Select Assignment Register */ +#define AT91_MATRIX_EBICSA 0x120 /* EBI0 Chip Select Assignment Register */ #define AT91_MATRIX_CS1A (1 << 1) /* Chip Select 1 Assignment */ #define AT91_MATRIX_CS1A_SMC (0 << 1) #define AT91_MATRIX_CS1A_SDRAMC (1 << 1) diff --git a/arch/arm/mach-at91/include/mach/at91sam9x5.h b/arch/arm/mach-at91/include/mach/at91sam9x5.h new file mode 100644 index 000000000000..88e43d534cdf --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9x5.h @@ -0,0 +1,74 @@ +/* + * Chip-specific header file for the AT91SAM9x5 family + * + * Copyright (C) 2009-2012 Atmel Corporation. + * + * Common definitions. + * Based on AT91SAM9x5 datasheet. + * + * Licensed under GPLv2 or later. + */ + +#ifndef AT91SAM9X5_H +#define AT91SAM9X5_H + +/* + * Peripheral identifiers/interrupts. + */ +#define AT91SAM9X5_ID_PIOAB 2 /* Parallel I/O Controller A and B */ +#define AT91SAM9X5_ID_PIOCD 3 /* Parallel I/O Controller C and D */ +#define AT91SAM9X5_ID_SMD 4 /* SMD Soft Modem (SMD) */ +#define AT91SAM9X5_ID_USART0 5 /* USART 0 */ +#define AT91SAM9X5_ID_USART1 6 /* USART 1 */ +#define AT91SAM9X5_ID_USART2 7 /* USART 2 */ +#define AT91SAM9X5_ID_USART3 8 /* USART 3 */ +#define AT91SAM9X5_ID_TWI0 9 /* Two-Wire Interface 0 */ +#define AT91SAM9X5_ID_TWI1 10 /* Two-Wire Interface 1 */ +#define AT91SAM9X5_ID_TWI2 11 /* Two-Wire Interface 2 */ +#define AT91SAM9X5_ID_MCI0 12 /* High Speed Multimedia Card Interface 0 */ +#define AT91SAM9X5_ID_SPI0 13 /* Serial Peripheral Interface 0 */ +#define AT91SAM9X5_ID_SPI1 14 /* Serial Peripheral Interface 1 */ +#define AT91SAM9X5_ID_UART0 15 /* UART 0 */ +#define AT91SAM9X5_ID_UART1 16 /* UART 1 */ +#define AT91SAM9X5_ID_TCB 17 /* Timer Counter 0, 1, 2, 3, 4 and 5 */ +#define AT91SAM9X5_ID_PWM 18 /* Pulse Width Modulation Controller */ +#define AT91SAM9X5_ID_ADC 19 /* ADC Controller */ +#define AT91SAM9X5_ID_DMA0 20 /* DMA Controller 0 */ +#define AT91SAM9X5_ID_DMA1 21 /* DMA Controller 1 */ +#define AT91SAM9X5_ID_UHPHS 22 /* USB Host High Speed */ +#define AT91SAM9X5_ID_UDPHS 23 /* USB Device High Speed */ +#define AT91SAM9X5_ID_EMAC0 24 /* Ethernet MAC0 */ +#define AT91SAM9X5_ID_LCDC 25 /* LCD Controller */ +#define AT91SAM9X5_ID_ISI 25 /* Image Sensor Interface */ +#define AT91SAM9X5_ID_MCI1 26 /* High Speed Multimedia Card Interface 1 */ +#define AT91SAM9X5_ID_EMAC1 27 /* Ethernet MAC1 */ +#define AT91SAM9X5_ID_SSC 28 /* Synchronous Serial Controller */ +#define AT91SAM9X5_ID_CAN0 29 /* CAN Controller 0 */ +#define AT91SAM9X5_ID_CAN1 30 /* CAN Controller 1 */ +#define AT91SAM9X5_ID_IRQ0 31 /* Advanced Interrupt Controller */ + +/* + * User Peripheral physical base addresses. + */ +#define AT91SAM9X5_BASE_USART0 0xf801c000 +#define AT91SAM9X5_BASE_USART1 0xf8020000 +#define AT91SAM9X5_BASE_USART2 0xf8024000 + +/* + * Base addresses for early serial code (uncompress.h) + */ +#define AT91_DBGU AT91_BASE_DBGU0 +#define AT91_USART0 AT91SAM9X5_BASE_USART0 +#define AT91_USART1 AT91SAM9X5_BASE_USART1 +#define AT91_USART2 AT91SAM9X5_BASE_USART2 + +/* + * Internal Memory. + */ +#define AT91SAM9X5_SRAM_BASE 0x00300000 /* Internal SRAM base address */ +#define AT91SAM9X5_SRAM_SIZE SZ_32K /* Internal SRAM size (32Kb) */ + +#define AT91SAM9X5_ROM_BASE 0x00400000 /* Internal ROM base address */ +#define AT91SAM9X5_ROM_SIZE SZ_64K /* Internal ROM size (64Kb) */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h new file mode 100644 index 000000000000..a606d3966470 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h @@ -0,0 +1,53 @@ +/* + * Matrix-centric header file for the AT91SAM9x5 family + * + * Copyright (C) 2009-2012 Atmel Corporation. + * + * Only EBI related registers. + * Write Protect register definitions may be useful. + * + * Licensed under GPLv2 or later. + */ + +#ifndef AT91SAM9X5_MATRIX_H +#define AT91SAM9X5_MATRIX_H + +#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x120) /* EBI Chip Select Assignment Register */ +#define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */ +#define AT91_MATRIX_EBI_CS1A_SMC (0 << 1) +#define AT91_MATRIX_EBI_CS1A_SDRAMC (1 << 1) +#define AT91_MATRIX_EBI_CS3A (1 << 3) /* Chip Select 3 Assignment */ +#define AT91_MATRIX_EBI_CS3A_SMC (0 << 3) +#define AT91_MATRIX_EBI_CS3A_SMC_NANDFLASH (1 << 3) +#define AT91_MATRIX_EBI_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */ +#define AT91_MATRIX_EBI_DBPU_ON (0 << 8) +#define AT91_MATRIX_EBI_DBPU_OFF (1 << 8) +#define AT91_MATRIX_EBI_VDDIOMSEL (1 << 16) /* Memory voltage selection */ +#define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16) +#define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16) +#define AT91_MATRIX_EBI_EBI_IOSR (1 << 17) /* EBI I/O slew rate selection */ +#define AT91_MATRIX_EBI_EBI_IOSR_REDUCED (0 << 17) +#define AT91_MATRIX_EBI_EBI_IOSR_NORMAL (1 << 17) +#define AT91_MATRIX_EBI_DDR_IOSR (1 << 18) /* DDR2 dedicated port I/O slew rate selection */ +#define AT91_MATRIX_EBI_DDR_IOSR_REDUCED (0 << 18) +#define AT91_MATRIX_EBI_DDR_IOSR_NORMAL (1 << 18) +#define AT91_MATRIX_NFD0_SELECT (1 << 24) /* NAND Flash Data Bus Selection */ +#define AT91_MATRIX_NFD0_ON_D0 (0 << 24) +#define AT91_MATRIX_NFD0_ON_D16 (1 << 24) +#define AT91_MATRIX_DDR_MP_EN (1 << 25) /* DDR Multi-port Enable */ +#define AT91_MATRIX_MP_OFF (0 << 25) +#define AT91_MATRIX_MP_ON (1 << 25) + +#define AT91_MATRIX_WPMR (AT91_MATRIX + 0x1E4) /* Write Protect Mode Register */ +#define AT91_MATRIX_WPMR_WPEN (1 << 0) /* Write Protect ENable */ +#define AT91_MATRIX_WPMR_WP_WPDIS (0 << 0) +#define AT91_MATRIX_WPMR_WP_WPEN (1 << 0) +#define AT91_MATRIX_WPMR_WPKEY (0xFFFFFF << 8) /* Write Protect KEY */ + +#define AT91_MATRIX_WPSR (AT91_MATRIX + 0x1E8) /* Write Protect Status Register */ +#define AT91_MATRIX_WPSR_WPVS (1 << 0) /* Write Protect Violation Status */ +#define AT91_MATRIX_WPSR_NO_WPV (0 << 0) +#define AT91_MATRIX_WPSR_WPV (1 << 0) +#define AT91_MATRIX_WPSR_WPVSRC (0xFFFF << 8) /* Write Protect Violation Source */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91x40.h b/arch/arm/mach-at91/include/mach/at91x40.h index a57829f4fd18..90680217064e 100644 --- a/arch/arm/mach-at91/include/mach/at91x40.h +++ b/arch/arm/mach-at91/include/mach/at91x40.h @@ -28,18 +28,18 @@ #define AT91X40_ID_IRQ2 18 /* External IRQ 2 */ /* - * System Peripherals (offset from AT91_BASE_SYS) + * System Peripherals */ #define AT91_BASE_SYS 0xffc00000 -#define AT91_EBI (0xffe00000 - AT91_BASE_SYS) /* External Bus Interface */ -#define AT91_SF (0xfff00000 - AT91_BASE_SYS) /* Special Function */ -#define AT91_USART1 (0xfffcc000 - AT91_BASE_SYS) /* USART 1 */ -#define AT91_USART0 (0xfffd0000 - AT91_BASE_SYS) /* USART 0 */ -#define AT91_TC (0xfffe0000 - AT91_BASE_SYS) /* Timer Counter */ -#define AT91_PIOA (0xffff0000 - AT91_BASE_SYS) /* PIO Controller A */ -#define AT91_PS (0xffff4000 - AT91_BASE_SYS) /* Power Save */ -#define AT91_WD (0xffff8000 - AT91_BASE_SYS) /* Watchdog Timer */ +#define AT91_EBI 0xffe00000 /* External Bus Interface */ +#define AT91_SF 0xfff00000 /* Special Function */ +#define AT91_USART1 0xfffcc000 /* USART 1 */ +#define AT91_USART0 0xfffd0000 /* USART 0 */ +#define AT91_TC 0xfffe0000 /* Timer Counter */ +#define AT91_PIOA 0xffff0000 /* PIO Controller A */ +#define AT91_PS 0xffff4000 /* Power Save */ +#define AT91_WD 0xffff8000 /* Watchdog Timer */ /* * The AT91x40 series doesn't have a debug unit like the other AT91 parts. diff --git a/arch/arm/mach-at91/include/mach/at_hdmac.h b/arch/arm/mach-at91/include/mach/at_hdmac.h index 187cb58345c0..fff48d1a0f4e 100644 --- a/arch/arm/mach-at91/include/mach/at_hdmac.h +++ b/arch/arm/mach-at91/include/mach/at_hdmac.h @@ -24,18 +24,6 @@ struct at_dma_platform_data { }; /** - * enum at_dma_slave_width - DMA slave register access width. - * @AT_DMA_SLAVE_WIDTH_8BIT: Do 8-bit slave register accesses - * @AT_DMA_SLAVE_WIDTH_16BIT: Do 16-bit slave register accesses - * @AT_DMA_SLAVE_WIDTH_32BIT: Do 32-bit slave register accesses - */ -enum at_dma_slave_width { - AT_DMA_SLAVE_WIDTH_8BIT = 0, - AT_DMA_SLAVE_WIDTH_16BIT, - AT_DMA_SLAVE_WIDTH_32BIT, -}; - -/** * struct at_dma_slave - Controller-specific information about a slave * @dma_dev: required DMA master device * @tx_reg: physical address of data register used for @@ -48,9 +36,6 @@ enum at_dma_slave_width { */ struct at_dma_slave { struct device *dma_dev; - dma_addr_t tx_reg; - dma_addr_t rx_reg; - enum at_dma_slave_width reg_width; u32 cfg; u32 ctrla; }; diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h index 3b33f07b1e11..49a821192c65 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h @@ -41,6 +41,7 @@ #include <sound/atmel-ac97c.h> #include <linux/serial.h> #include <linux/platform_data/macb.h> +#include <linux/platform_data/atmel.h> /* USB Device */ struct at91_udc_data { @@ -85,31 +86,20 @@ extern void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *d extern void __init at91_add_device_eth(struct macb_platform_data *data); /* USB Host */ +#define AT91_MAX_USBH_PORTS 3 struct at91_usbh_data { - u8 ports; /* number of ports on root hub */ - int vbus_pin[2]; /* port power-control pin */ - u8 vbus_pin_active_low[2]; + int vbus_pin[AT91_MAX_USBH_PORTS]; /* port power-control pin */ + int overcurrent_pin[AT91_MAX_USBH_PORTS]; + u8 ports; /* number of ports on root hub */ u8 overcurrent_supported; - int overcurrent_pin[2]; - u8 overcurrent_status[2]; - u8 overcurrent_changed[2]; + u8 vbus_pin_active_low[AT91_MAX_USBH_PORTS]; + u8 overcurrent_status[AT91_MAX_USBH_PORTS]; + u8 overcurrent_changed[AT91_MAX_USBH_PORTS]; }; extern void __init at91_add_device_usbh(struct at91_usbh_data *data); extern void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data); extern void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data); - /* NAND / SmartMedia */ -struct atmel_nand_data { - int enable_pin; /* chip enable */ - int det_pin; /* card detect */ - int rdy_pin; /* ready/busy */ - u8 rdy_pin_active_low; /* rdy_pin value is inverted */ - u8 ale; /* address line number connected to ALE */ - u8 cle; /* address line number connected to CLE */ - u8 bus_width_16; /* buswidth is 16 bit */ - struct mtd_partition *parts; - unsigned int num_parts; -}; extern void __init at91_add_device_nand(struct atmel_nand_data *data); /* I2C*/ @@ -179,7 +169,9 @@ extern void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data); extern void __init at91_add_device_ac97(struct ac97c_platform_data *data); /* ISI */ -extern void __init at91_add_device_isi(void); +struct isi_platform_data; +extern void __init at91_add_device_isi(struct isi_platform_data *data, + bool use_pck_as_mck); /* Touchscreen Controller */ struct at91_tsadcc_data { diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h index f6ce936dba2b..0118c3338552 100644 --- a/arch/arm/mach-at91/include/mach/cpu.h +++ b/arch/arm/mach-at91/include/mach/cpu.h @@ -25,7 +25,6 @@ #define ARCH_ID_AT91SAM9G45MRL 0x819b05a2 /* aka 9G45-ES2 & non ES lots */ #define ARCH_ID_AT91SAM9G45ES 0x819b05a1 /* 9G45-ES (Engineering Sample) */ #define ARCH_ID_AT91SAM9X5 0x819a05a0 -#define ARCH_ID_AT91CAP9 0x039A03A0 #define ARCH_ID_AT91SAM9XE128 0x329973a0 #define ARCH_ID_AT91SAM9XE256 0x329a93a0 @@ -51,10 +50,6 @@ #define ARCH_FAMILY_AT91SAM9 0x01900000 #define ARCH_FAMILY_AT91SAM9XE 0x02900000 -/* PMC revision */ -#define ARCH_REVISION_CAP9_B 0x399 -#define ARCH_REVISION_CAP9_C 0x601 - /* RM9200 type */ #define ARCH_REVISON_9200_BGA (0 << 0) #define ARCH_REVISON_9200_PQFP (1 << 0) @@ -63,9 +58,6 @@ enum at91_soc_type { /* 920T */ AT91_SOC_RM9200, - /* CAP */ - AT91_SOC_CAP9, - /* SAM92xx */ AT91_SOC_SAM9260, AT91_SOC_SAM9261, AT91_SOC_SAM9263, @@ -86,9 +78,6 @@ enum at91_soc_subtype { /* RM9200 */ AT91_SOC_RM9200_BGA, AT91_SOC_RM9200_PQFP, - /* CAP9 */ - AT91_SOC_CAP9_REV_B, AT91_SOC_CAP9_REV_C, - /* SAM9260 */ AT91_SOC_SAM9XE, @@ -195,16 +184,6 @@ static inline int at91_soc_is_detected(void) #define cpu_is_at91sam9x25() (0) #endif -#ifdef CONFIG_ARCH_AT91CAP9 -#define cpu_is_at91cap9() (at91_soc_initdata.type == AT91_SOC_CAP9) -#define cpu_is_at91cap9_revB() (at91_soc_initdata.subtype == AT91_SOC_CAP9_REV_B) -#define cpu_is_at91cap9_revC() (at91_soc_initdata.subtype == AT91_SOC_CAP9_REV_C) -#else -#define cpu_is_at91cap9() (0) -#define cpu_is_at91cap9_revB() (0) -#define cpu_is_at91cap9_revC() (0) -#endif - /* * Since this is ARM, we will never run on any AVR32 CPU. But these * definitions may reduce clutter in common drivers. diff --git a/arch/arm/mach-at91/include/mach/entry-macro.S b/arch/arm/mach-at91/include/mach/entry-macro.S index 423eea0ed74c..903bf205a333 100644 --- a/arch/arm/mach-at91/include/mach/entry-macro.S +++ b/arch/arm/mach-at91/include/mach/entry-macro.S @@ -13,17 +13,11 @@ #include <mach/hardware.h> #include <mach/at91_aic.h> - .macro disable_fiq - .endm - .macro get_irqnr_preamble, base, tmp ldr \base, =at91_aic_base @ base virtual address of AIC peripheral ldr \base, [\base] .endm - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \irqnr, [\base, #AT91_AIC_IVR] @ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt) ldr \irqstat, [\base, #AT91_AIC_ISR] @ read interrupt source number diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h index e3fd225121c7..eed465ab0dd7 100644 --- a/arch/arm/mach-at91/include/mach/gpio.h +++ b/arch/arm/mach-at91/include/mach/gpio.h @@ -191,10 +191,15 @@ extern int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup); extern int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup); extern int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup); +extern int __init_or_module at91_set_C_periph(unsigned pin, int use_pullup); +extern int __init_or_module at91_set_D_periph(unsigned pin, int use_pullup); extern int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup); extern int __init_or_module at91_set_gpio_output(unsigned pin, int value); extern int __init_or_module at91_set_deglitch(unsigned pin, int is_on); +extern int __init_or_module at91_set_debounce(unsigned pin, int is_on, int div); extern int __init_or_module at91_set_multi_drive(unsigned pin, int is_on); +extern int __init_or_module at91_set_pulldown(unsigned pin, int is_on); +extern int __init_or_module at91_disable_schmitt_trig(unsigned pin); /* callable at any time */ extern int at91_set_gpio_value(unsigned pin, int value); @@ -204,18 +209,6 @@ extern int at91_get_gpio_value(unsigned pin); extern void at91_gpio_suspend(void); extern void at91_gpio_resume(void); -/*-------------------------------------------------------------------------*/ - -/* wrappers for "new style" GPIO calls. the old AT91-specific ones should - * eventually be removed (along with this errno.h inclusion), and the - * gpio request/free calls should probably be implemented. - */ - -#include <asm/errno.h> - -#define gpio_to_irq(gpio) (gpio + NR_AIC_IRQS) -#define irq_to_gpio(irq) (irq - NR_AIC_IRQS) - #endif /* __ASSEMBLY__ */ #endif diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h index 2d0e4e998566..e9e29a6c3868 100644 --- a/arch/arm/mach-at91/include/mach/hardware.h +++ b/arch/arm/mach-at91/include/mach/hardware.h @@ -19,7 +19,7 @@ /* DBGU base */ /* rm9200, 9260/9g20, 9261/9g10, 9rl */ #define AT91_BASE_DBGU0 0xfffff200 -/* 9263, 9g45, cap9 */ +/* 9263, 9g45 */ #define AT91_BASE_DBGU1 0xffffee00 #if defined(CONFIG_ARCH_AT91RM9200) @@ -34,8 +34,8 @@ #include <mach/at91sam9rl.h> #elif defined(CONFIG_ARCH_AT91SAM9G45) #include <mach/at91sam9g45.h> -#elif defined(CONFIG_ARCH_AT91CAP9) -#include <mach/at91cap9.h> +#elif defined(CONFIG_ARCH_AT91SAM9X5) +#include <mach/at91sam9x5.h> #elif defined(CONFIG_ARCH_AT91X40) #include <mach/at91x40.h> #else @@ -59,9 +59,10 @@ /* * On all at91 have the Advanced Interrupt Controller starts at address - * 0xfffff000 + * 0xfffff000 and the Power Management Controller starts at 0xfffffc00 */ #define AT91_AIC 0xfffff000 +#define AT91_PMC 0xfffffc00 /* * Peripheral identifiers/interrupts. diff --git a/arch/arm/mach-at91/include/mach/io.h b/arch/arm/mach-at91/include/mach/io.h index 4ca09ef7ca29..2d9ca0455745 100644 --- a/arch/arm/mach-at91/include/mach/io.h +++ b/arch/arm/mach-at91/include/mach/io.h @@ -21,29 +21,7 @@ #ifndef __ASM_ARCH_IO_H #define __ASM_ARCH_IO_H -#include <mach/hardware.h> - #define IO_SPACE_LIMIT 0xFFFFFFFF - -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#ifndef __ASSEMBLY__ - -static inline unsigned int at91_sys_read(unsigned int reg_offset) -{ - void __iomem *addr = (void __iomem *)AT91_VA_BASE_SYS; - - return __raw_readl(addr + reg_offset); -} - -static inline void at91_sys_write(unsigned int reg_offset, unsigned long value) -{ - void __iomem *addr = (void __iomem *)AT91_VA_BASE_SYS; - - __raw_writel(value, addr + reg_offset); -} - -#endif +#define __io(a) __typesafe_io(a) #endif diff --git a/arch/arm/mach-at91/include/mach/system.h b/arch/arm/mach-at91/include/mach/system.h deleted file mode 100644 index cbd64f3bcecd..000000000000 --- a/arch/arm/mach-at91/include/mach/system.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * arch/arm/mach-at91/include/mach/system.h - * - * Copyright (C) 2003 SAN People - * - * 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_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -#include <mach/hardware.h> -#include <mach/at91_st.h> -#include <mach/at91_dbgu.h> -#include <mach/at91_pmc.h> - -static inline void arch_idle(void) -{ - /* - * Disable the processor clock. The processor will be automatically - * re-enabled by an interrupt or by a reset. - */ -#ifdef AT91_PS - at91_sys_write(AT91_PS_CR, AT91_PS_CR_CPU); -#else - at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK); -#endif -#ifndef CONFIG_CPU_ARM920T - /* - * Set the processor (CP15) into 'Wait for Interrupt' mode. - * Post-RM9200 processors need this in conjunction with the above - * to save power when idle. - */ - cpu_do_idle(); -#endif -} - -#endif diff --git a/arch/arm/mach-at91/include/mach/system_rev.h b/arch/arm/mach-at91/include/mach/system_rev.h index ec164a4124c9..ef79a9aafc08 100644 --- a/arch/arm/mach-at91/include/mach/system_rev.h +++ b/arch/arm/mach-at91/include/mach/system_rev.h @@ -7,6 +7,8 @@ #ifndef __ARCH_SYSTEM_REV_H__ #define __ARCH_SYSTEM_REV_H__ +#include <asm/system_info.h> + /* * board revision encoding * mach specific diff --git a/arch/arm/mach-at91/include/mach/uncompress.h b/arch/arm/mach-at91/include/mach/uncompress.h index 0234fd9d20d6..4218647c1fcd 100644 --- a/arch/arm/mach-at91/include/mach/uncompress.h +++ b/arch/arm/mach-at91/include/mach/uncompress.h @@ -23,6 +23,7 @@ #include <linux/io.h> #include <linux/atmel_serial.h> +#include <mach/hardware.h> #if defined(CONFIG_AT91_EARLY_DBGU0) #define UART_OFFSET AT91_BASE_DBGU0 diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c index be6b639ecd7b..cfcfcbe36269 100644 --- a/arch/arm/mach-at91/irq.c +++ b/arch/arm/mach-at91/irq.c @@ -24,6 +24,12 @@ #include <linux/module.h> #include <linux/mm.h> #include <linux/types.h> +#include <linux/irq.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/irqdomain.h> +#include <linux/err.h> #include <mach/hardware.h> #include <asm/irq.h> @@ -34,22 +40,24 @@ #include <asm/mach/map.h> void __iomem *at91_aic_base; +static struct irq_domain *at91_aic_domain; +static struct device_node *at91_aic_np; static void at91_aic_mask_irq(struct irq_data *d) { /* Disable interrupt on AIC */ - at91_aic_write(AT91_AIC_IDCR, 1 << d->irq); + at91_aic_write(AT91_AIC_IDCR, 1 << d->hwirq); } static void at91_aic_unmask_irq(struct irq_data *d) { /* Enable interrupt on AIC */ - at91_aic_write(AT91_AIC_IECR, 1 << d->irq); + at91_aic_write(AT91_AIC_IECR, 1 << d->hwirq); } unsigned int at91_extern_irq; -#define is_extern_irq(irq) ((1 << (irq)) & at91_extern_irq) +#define is_extern_irq(hwirq) ((1 << (hwirq)) & at91_extern_irq) static int at91_aic_set_type(struct irq_data *d, unsigned type) { @@ -63,13 +71,13 @@ static int at91_aic_set_type(struct irq_data *d, unsigned type) srctype = AT91_AIC_SRCTYPE_RISING; break; case IRQ_TYPE_LEVEL_LOW: - if ((d->irq == AT91_ID_FIQ) || is_extern_irq(d->irq)) /* only supported on external interrupts */ + if ((d->hwirq == AT91_ID_FIQ) || is_extern_irq(d->hwirq)) /* only supported on external interrupts */ srctype = AT91_AIC_SRCTYPE_LOW; else return -EINVAL; break; case IRQ_TYPE_EDGE_FALLING: - if ((d->irq == AT91_ID_FIQ) || is_extern_irq(d->irq)) /* only supported on external interrupts */ + if ((d->hwirq == AT91_ID_FIQ) || is_extern_irq(d->hwirq)) /* only supported on external interrupts */ srctype = AT91_AIC_SRCTYPE_FALLING; else return -EINVAL; @@ -78,8 +86,8 @@ static int at91_aic_set_type(struct irq_data *d, unsigned type) return -EINVAL; } - smr = at91_aic_read(AT91_AIC_SMR(d->irq)) & ~AT91_AIC_SRCTYPE; - at91_aic_write(AT91_AIC_SMR(d->irq), smr | srctype); + smr = at91_aic_read(AT91_AIC_SMR(d->hwirq)) & ~AT91_AIC_SRCTYPE; + at91_aic_write(AT91_AIC_SMR(d->hwirq), smr | srctype); return 0; } @@ -90,13 +98,13 @@ static u32 backups; static int at91_aic_set_wake(struct irq_data *d, unsigned value) { - if (unlikely(d->irq >= 32)) + if (unlikely(d->hwirq >= NR_AIC_IRQS)) return -EINVAL; if (value) - wakeups |= (1 << d->irq); + wakeups |= (1 << d->hwirq); else - wakeups &= ~(1 << d->irq); + wakeups &= ~(1 << d->hwirq); return 0; } @@ -127,46 +135,112 @@ static struct irq_chip at91_aic_chip = { .irq_set_wake = at91_aic_set_wake, }; +static void __init at91_aic_hw_init(unsigned int spu_vector) +{ + int i; + + /* + * Perform 8 End Of Interrupt Command to make sure AIC + * will not Lock out nIRQ + */ + for (i = 0; i < 8; i++) + at91_aic_write(AT91_AIC_EOICR, 0); + + /* + * Spurious Interrupt ID in Spurious Vector Register. + * When there is no current interrupt, the IRQ Vector Register + * reads the value stored in AIC_SPU + */ + at91_aic_write(AT91_AIC_SPU, spu_vector); + + /* No debugging in AIC: Debug (Protect) Control Register */ + at91_aic_write(AT91_AIC_DCR, 0); + + /* Disable and clear all interrupts initially */ + at91_aic_write(AT91_AIC_IDCR, 0xFFFFFFFF); + at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF); +} + +#if defined(CONFIG_OF) +static int at91_aic_irq_map(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw) +{ + /* Put virq number in Source Vector Register */ + at91_aic_write(AT91_AIC_SVR(hw), virq); + + /* Active Low interrupt, without priority */ + at91_aic_write(AT91_AIC_SMR(hw), AT91_AIC_SRCTYPE_LOW); + + irq_set_chip_and_handler(virq, &at91_aic_chip, handle_level_irq); + set_irq_flags(virq, IRQF_VALID | IRQF_PROBE); + + return 0; +} + +static struct irq_domain_ops at91_aic_irq_ops = { + .map = at91_aic_irq_map, + .xlate = irq_domain_xlate_twocell, +}; + +int __init at91_aic_of_init(struct device_node *node, + struct device_node *parent) +{ + at91_aic_base = of_iomap(node, 0); + at91_aic_np = node; + + at91_aic_domain = irq_domain_add_linear(at91_aic_np, NR_AIC_IRQS, + &at91_aic_irq_ops, NULL); + if (!at91_aic_domain) + panic("Unable to add AIC irq domain (DT)\n"); + + irq_set_default_host(at91_aic_domain); + + at91_aic_hw_init(NR_AIC_IRQS); + + return 0; +} +#endif + /* * Initialize the AIC interrupt controller. */ void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS]) { unsigned int i; + int irq_base; at91_aic_base = ioremap(AT91_AIC, 512); - if (!at91_aic_base) - panic("Impossible to ioremap AT91_AIC\n"); + panic("Unable to ioremap AIC registers\n"); + + /* Add irq domain for AIC */ + irq_base = irq_alloc_descs(-1, 0, NR_AIC_IRQS, 0); + if (irq_base < 0) { + WARN(1, "Cannot allocate irq_descs, assuming pre-allocated\n"); + irq_base = 0; + } + at91_aic_domain = irq_domain_add_legacy(at91_aic_np, NR_AIC_IRQS, + irq_base, 0, + &irq_domain_simple_ops, NULL); + + if (!at91_aic_domain) + panic("Unable to add AIC irq domain\n"); + + irq_set_default_host(at91_aic_domain); /* * The IVR is used by macro get_irqnr_and_base to read and verify. * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred. */ for (i = 0; i < NR_AIC_IRQS; i++) { - /* Put irq number in Source Vector Register: */ + /* Put hardware irq number in Source Vector Register: */ at91_aic_write(AT91_AIC_SVR(i), i); /* Active Low interrupt, with the specified priority */ at91_aic_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]); irq_set_chip_and_handler(i, &at91_aic_chip, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); - - /* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */ - if (i < 8) - at91_aic_write(AT91_AIC_EOICR, 0); } - /* - * Spurious Interrupt ID in Spurious Vector Register is NR_AIC_IRQS - * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU - */ - at91_aic_write(AT91_AIC_SPU, NR_AIC_IRQS); - - /* No debugging in AIC: Debug (Protect) Control Register */ - at91_aic_write(AT91_AIC_DCR, 0); - - /* Disable and clear all interrupts initially */ - at91_aic_write(AT91_AIC_IDCR, 0xFFFFFFFF); - at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF); + at91_aic_hw_init(NR_AIC_IRQS); } diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 1606379ac284..f630250c6b87 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -136,7 +136,7 @@ static int at91_pm_verify_clocks(void) unsigned long scsr; int i; - scsr = at91_sys_read(AT91_PMC_SCSR); + scsr = at91_pmc_read(AT91_PMC_SCSR); /* USB must not be using PLLB */ if (cpu_is_at91rm9200()) { @@ -150,11 +150,6 @@ static int at91_pm_verify_clocks(void) pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); return 0; } - } else if (cpu_is_at91cap9()) { - if ((scsr & AT91CAP9_PMC_UHP) != 0) { - pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); - return 0; - } } #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS @@ -165,7 +160,7 @@ static int at91_pm_verify_clocks(void) if ((scsr & (AT91_PMC_PCK0 << i)) == 0) continue; - css = at91_sys_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS; + css = at91_pmc_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS; if (css != AT91_PMC_CSS_SLOW) { pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css); return 0; @@ -193,23 +188,23 @@ int at91_suspend_entering_slow_clock(void) EXPORT_SYMBOL(at91_suspend_entering_slow_clock); -static void (*slow_clock)(void); +static void (*slow_clock)(void __iomem *pmc, void __iomem *ramc0, + void __iomem *ramc1, int memctrl); #ifdef CONFIG_AT91_SLOW_CLOCK -extern void at91_slow_clock(void); +extern void at91_slow_clock(void __iomem *pmc, void __iomem *ramc0, + void __iomem *ramc1, int memctrl); extern u32 at91_slow_clock_sz; #endif - static int at91_pm_enter(suspend_state_t state) { - u32 saved_lpr; at91_gpio_suspend(); at91_irq_suspend(); pr_debug("AT91: PM - wake mask %08x, pm state %d\n", /* remember all the always-wake irqs */ - (at91_sys_read(AT91_PMC_PCSR) + (at91_pmc_read(AT91_PMC_PCSR) | (1 << AT91_ID_FIQ) | (1 << AT91_ID_SYS) | (at91_extern_irq)) @@ -234,11 +229,18 @@ static int at91_pm_enter(suspend_state_t state) * turning off the main oscillator; reverse on wakeup. */ if (slow_clock) { + int memctrl = AT91_MEMCTRL_SDRAMC; + + if (cpu_is_at91rm9200()) + memctrl = AT91_MEMCTRL_MC; + else if (cpu_is_at91sam9g45()) + memctrl = AT91_MEMCTRL_DDRSDR; #ifdef CONFIG_AT91_SLOW_CLOCK /* copy slow_clock handler to SRAM, and call it */ memcpy(slow_clock, at91_slow_clock, at91_slow_clock_sz); #endif - slow_clock(); + slow_clock(at91_pmc_base, at91_ramc_base[0], + at91_ramc_base[1], memctrl); break; } else { pr_info("AT91: PM - no slow clock mode enabled ...\n"); @@ -259,16 +261,7 @@ static int at91_pm_enter(suspend_state_t state) * For ARM 926 based chips, this requirement is weaker * as at91sam9 can access a RAM in self-refresh mode. */ - asm volatile ( "mov r0, #0\n\t" - "b 1f\n\t" - ".align 5\n\t" - "1: mcr p15, 0, r0, c7, c10, 4\n\t" - : /* no output */ - : /* no input */ - : "r0"); - saved_lpr = sdram_selfrefresh_enable(); - wait_for_interrupt_enable(); - sdram_selfrefresh_disable(saved_lpr); + at91_standby(); break; case PM_SUSPEND_ON: @@ -316,7 +309,7 @@ static int __init at91_pm_init(void) #ifdef CONFIG_ARCH_AT91RM9200 /* AT91RM9200 SDRAM low-power mode cannot be used with self-refresh. */ - at91_sys_write(AT91_SDRAMC_LPR, 0); + at91_ramc_write(0, AT91RM9200_SDRAMC_LPR, 0); #endif suspend_set_ops(&at91_pm_ops); diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h index 7eb40d24242f..89f56f3a802e 100644 --- a/arch/arm/mach-at91/pm.h +++ b/arch/arm/mach-at91/pm.h @@ -1,5 +1,19 @@ +/* + * AT91 Power Management + * + * Copyright (C) 2005 David Brownell + * + * 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. + */ +#ifndef __ARCH_ARM_MACH_AT91_PM +#define __ARCH_ARM_MACH_AT91_PM + +#include <mach/at91_ramc.h> #ifdef CONFIG_ARCH_AT91RM9200 -#include <mach/at91rm9200_mc.h> +#include <mach/at91rm9200_sdramc.h> /* * The AT91RM9200 goes into self-refresh mode with this command, and will @@ -11,51 +25,37 @@ * still in self-refresh is "not recommended", but seems to work. */ -static inline u32 sdram_selfrefresh_enable(void) +static inline void at91rm9200_standby(void) { - u32 saved_lpr = at91_sys_read(AT91_SDRAMC_LPR); - - at91_sys_write(AT91_SDRAMC_LPR, 0); - at91_sys_write(AT91_SDRAMC_SRR, 1); - return saved_lpr; + u32 lpr = at91_ramc_read(0, AT91RM9200_SDRAMC_LPR); + + asm volatile( + "b 1f\n\t" + ".align 5\n\t" + "1: mcr p15, 0, %0, c7, c10, 4\n\t" + " str %0, [%1, %2]\n\t" + " str %3, [%1, %4]\n\t" + " mcr p15, 0, %0, c7, c0, 4\n\t" + " str %5, [%1, %2]" + : + : "r" (0), "r" (AT91_BASE_SYS), "r" (AT91RM9200_SDRAMC_LPR), + "r" (1), "r" (AT91RM9200_SDRAMC_SRR), + "r" (lpr)); } -#define sdram_selfrefresh_disable(saved_lpr) at91_sys_write(AT91_SDRAMC_LPR, saved_lpr) -#define wait_for_interrupt_enable() asm volatile ("mcr p15, 0, %0, c7, c0, 4" \ - : : "r" (0)) - -#elif defined(CONFIG_ARCH_AT91CAP9) -#include <mach/at91sam9_ddrsdr.h> - - -static inline u32 sdram_selfrefresh_enable(void) -{ - u32 saved_lpr, lpr; - - saved_lpr = at91_ramc_read(0, AT91CAP9_DDRSDRC_LPR); - - lpr = saved_lpr & ~AT91_DDRSDRC_LPCB; - at91_ramc_write(0, AT91CAP9_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH); - return saved_lpr; -} - -#define sdram_selfrefresh_disable(saved_lpr) at91_ramc_write(0, AT91CAP9_DDRSDRC_LPR, saved_lpr) -#define wait_for_interrupt_enable() cpu_do_idle() +#define at91_standby at91rm9200_standby #elif defined(CONFIG_ARCH_AT91SAM9G45) -#include <mach/at91sam9_ddrsdr.h> /* We manage both DDRAM/SDRAM controllers, we need more than one value to * remember. */ -static u32 saved_lpr1; - -static inline u32 sdram_selfrefresh_enable(void) +static inline void at91sam9g45_standby(void) { - /* Those tow values allow us to delay self-refresh activation + /* Those two values allow us to delay self-refresh activation * to the maximum. */ u32 lpr0, lpr1; - u32 saved_lpr0; + u32 saved_lpr0, saved_lpr1; saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR); lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB; @@ -69,18 +69,15 @@ static inline u32 sdram_selfrefresh_enable(void) at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0); at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1); - return saved_lpr0; + cpu_do_idle(); + + at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0); + at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); } -#define sdram_selfrefresh_disable(saved_lpr0) \ - do { \ - at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0); \ - at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); \ - } while (0) -#define wait_for_interrupt_enable() cpu_do_idle() +#define at91_standby at91sam9g45_standby #else -#include <mach/at91sam9_sdramc.h> #ifdef CONFIG_ARCH_AT91SAM9263 /* @@ -90,18 +87,23 @@ static inline u32 sdram_selfrefresh_enable(void) #warning Assuming EB1 SDRAM controller is *NOT* used #endif -static inline u32 sdram_selfrefresh_enable(void) +static inline void at91sam9_standby(void) { u32 saved_lpr, lpr; saved_lpr = at91_ramc_read(0, AT91_SDRAMC_LPR); lpr = saved_lpr & ~AT91_SDRAMC_LPCB; - at91_ramc_write(0, AT91_SDRAMC_LPR, lpr | AT91_SDRAMC_LPCB_SELF_REFRESH); - return saved_lpr; + at91_ramc_write(0, AT91_SDRAMC_LPR, lpr | + AT91_SDRAMC_LPCB_SELF_REFRESH); + + cpu_do_idle(); + + at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr); } -#define sdram_selfrefresh_disable(saved_lpr) at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr) -#define wait_for_interrupt_enable() cpu_do_idle() +#define at91_standby at91sam9_standby + +#endif #endif diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S index 92dfb8461392..db5452123f17 100644 --- a/arch/arm/mach-at91/pm_slowclock.S +++ b/arch/arm/mach-at91/pm_slowclock.S @@ -15,15 +15,7 @@ #include <linux/linkage.h> #include <mach/hardware.h> #include <mach/at91_pmc.h> - -#if defined(CONFIG_ARCH_AT91RM9200) -#include <mach/at91rm9200_mc.h> -#elif defined(CONFIG_ARCH_AT91CAP9) \ - || defined(CONFIG_ARCH_AT91SAM9G45) -#include <mach/at91sam9_ddrsdr.h> -#else -#include <mach/at91sam9_sdramc.h> -#endif +#include <mach/at91_ramc.h> #ifdef CONFIG_ARCH_AT91SAM9263 @@ -47,17 +39,23 @@ #define PLLALOCK_TIMEOUT 1000 #define PLLBLOCK_TIMEOUT 1000 +pmc .req r0 +sdramc .req r1 +ramc1 .req r2 +memctrl .req r3 +tmp1 .req r4 +tmp2 .req r5 /* * Wait until master clock is ready (after switching master clock source) */ .macro wait_mckrdy - mov r4, #MCKRDY_TIMEOUT -1: sub r4, r4, #1 - cmp r4, #0 + mov tmp2, #MCKRDY_TIMEOUT +1: sub tmp2, tmp2, #1 + cmp tmp2, #0 beq 2f - ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] - tst r3, #AT91_PMC_MCKRDY + ldr tmp1, [pmc, #AT91_PMC_SR] + tst tmp1, #AT91_PMC_MCKRDY beq 1b 2: .endm @@ -66,12 +64,12 @@ * Wait until master oscillator has stabilized. */ .macro wait_moscrdy - mov r4, #MOSCRDY_TIMEOUT -1: sub r4, r4, #1 - cmp r4, #0 + mov tmp2, #MOSCRDY_TIMEOUT +1: sub tmp2, tmp2, #1 + cmp tmp2, #0 beq 2f - ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] - tst r3, #AT91_PMC_MOSCS + ldr tmp1, [pmc, #AT91_PMC_SR] + tst tmp1, #AT91_PMC_MOSCS beq 1b 2: .endm @@ -80,12 +78,12 @@ * Wait until PLLA has locked. */ .macro wait_pllalock - mov r4, #PLLALOCK_TIMEOUT -1: sub r4, r4, #1 - cmp r4, #0 + mov tmp2, #PLLALOCK_TIMEOUT +1: sub tmp2, tmp2, #1 + cmp tmp2, #0 beq 2f - ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] - tst r3, #AT91_PMC_LOCKA + ldr tmp1, [pmc, #AT91_PMC_SR] + tst tmp1, #AT91_PMC_LOCKA beq 1b 2: .endm @@ -94,80 +92,98 @@ * Wait until PLLB has locked. */ .macro wait_pllblock - mov r4, #PLLBLOCK_TIMEOUT -1: sub r4, r4, #1 - cmp r4, #0 + mov tmp2, #PLLBLOCK_TIMEOUT +1: sub tmp2, tmp2, #1 + cmp tmp2, #0 beq 2f - ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)] - tst r3, #AT91_PMC_LOCKB + ldr tmp1, [pmc, #AT91_PMC_SR] + tst tmp1, #AT91_PMC_LOCKB beq 1b 2: .endm .text +/* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc, + * void __iomem *ramc1, int memctrl) + */ ENTRY(at91_slow_clock) /* Save registers on stack */ - stmfd sp!, {r0 - r12, lr} + stmfd sp!, {r4 - r12, lr} /* * Register usage: - * R1 = Base address of AT91_PMC - * R2 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS) - * R3 = temporary register + * R0 = Base address of AT91_PMC + * R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS) + * R2 = Base address of second RAM Controller or 0 if not present + * R3 = Memory controller * R4 = temporary register - * R5 = Base address of second RAM Controller or 0 if not present + * R5 = temporary register */ - ldr r1, .at91_va_base_pmc - ldr r2, .at91_va_base_sdramc - ldr r5, .at91_va_base_ramc1 /* Drain write buffer */ - mov r0, #0 - mcr p15, 0, r0, c7, c10, 4 + mov tmp1, #0 + mcr p15, 0, tmp1, c7, c10, 4 + + cmp memctrl, #AT91_MEMCTRL_MC + bne ddr_sr_enable -#ifdef CONFIG_ARCH_AT91RM9200 + /* + * at91rm9200 Memory controller + */ /* Put SDRAM in self-refresh mode */ - mov r3, #1 - str r3, [r2, #AT91_SDRAMC_SRR] -#elif defined(CONFIG_ARCH_AT91CAP9) \ - || defined(CONFIG_ARCH_AT91SAM9G45) + mov tmp1, #1 + str tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR] + b sdr_sr_done + + /* + * DDRSDR Memory controller + */ +ddr_sr_enable: + cmp memctrl, #AT91_MEMCTRL_DDRSDR + bne sdr_sr_enable /* prepare for DDRAM self-refresh mode */ - ldr r3, [r2, #AT91_DDRSDRC_LPR] - str r3, .saved_sam9_lpr - bic r3, #AT91_DDRSDRC_LPCB - orr r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH + ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR] + str tmp1, .saved_sam9_lpr + bic tmp1, #AT91_DDRSDRC_LPCB + orr tmp1, #AT91_DDRSDRC_LPCB_SELF_REFRESH /* figure out if we use the second ram controller */ - cmp r5, #0 - ldrne r4, [r5, #AT91_DDRSDRC_LPR] - strne r4, .saved_sam9_lpr1 - bicne r4, #AT91_DDRSDRC_LPCB - orrne r4, #AT91_DDRSDRC_LPCB_SELF_REFRESH + cmp ramc1, #0 + ldrne tmp2, [ramc1, #AT91_DDRSDRC_LPR] + strne tmp2, .saved_sam9_lpr1 + bicne tmp2, #AT91_DDRSDRC_LPCB + orrne tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH /* Enable DDRAM self-refresh mode */ - str r3, [r2, #AT91_DDRSDRC_LPR] - strne r4, [r5, #AT91_DDRSDRC_LPR] -#else + str tmp1, [sdramc, #AT91_DDRSDRC_LPR] + strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] + + b sdr_sr_done + + /* + * SDRAMC Memory controller + */ +sdr_sr_enable: /* Enable SDRAM self-refresh mode */ - ldr r3, [r2, #AT91_SDRAMC_LPR] - str r3, .saved_sam9_lpr + ldr tmp1, [sdramc, #AT91_SDRAMC_LPR] + str tmp1, .saved_sam9_lpr - bic r3, #AT91_SDRAMC_LPCB - orr r3, #AT91_SDRAMC_LPCB_SELF_REFRESH - str r3, [r2, #AT91_SDRAMC_LPR] -#endif + bic tmp1, #AT91_SDRAMC_LPCB + orr tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH + str tmp1, [sdramc, #AT91_SDRAMC_LPR] +sdr_sr_done: /* Save Master clock setting */ - ldr r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] - str r3, .saved_mckr + ldr tmp1, [pmc, #AT91_PMC_MCKR] + str tmp1, .saved_mckr /* * Set the Master clock source to slow clock */ - bic r3, r3, #AT91_PMC_CSS - str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] + bic tmp1, tmp1, #AT91_PMC_CSS + str tmp1, [pmc, #AT91_PMC_MCKR] wait_mckrdy @@ -177,61 +193,61 @@ ENTRY(at91_slow_clock) * * See AT91RM9200 errata #27 and #28 for details. */ - mov r3, #0 - str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] + mov tmp1, #0 + str tmp1, [pmc, #AT91_PMC_MCKR] wait_mckrdy #endif /* Save PLLA setting and disable it */ - ldr r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] - str r3, .saved_pllar + ldr tmp1, [pmc, #AT91_CKGR_PLLAR] + str tmp1, .saved_pllar - mov r3, #AT91_PMC_PLLCOUNT - orr r3, r3, #(1 << 29) /* bit 29 always set */ - str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] + mov tmp1, #AT91_PMC_PLLCOUNT + orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */ + str tmp1, [pmc, #AT91_CKGR_PLLAR] /* Save PLLB setting and disable it */ - ldr r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] - str r3, .saved_pllbr + ldr tmp1, [pmc, #AT91_CKGR_PLLBR] + str tmp1, .saved_pllbr - mov r3, #AT91_PMC_PLLCOUNT - str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] + mov tmp1, #AT91_PMC_PLLCOUNT + str tmp1, [pmc, #AT91_CKGR_PLLBR] /* Turn off the main oscillator */ - ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] - bic r3, r3, #AT91_PMC_MOSCEN - str r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] + ldr tmp1, [pmc, #AT91_CKGR_MOR] + bic tmp1, tmp1, #AT91_PMC_MOSCEN + str tmp1, [pmc, #AT91_CKGR_MOR] /* Wait for interrupt */ - mcr p15, 0, r0, c7, c0, 4 + mcr p15, 0, tmp1, c7, c0, 4 /* Turn on the main oscillator */ - ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] - orr r3, r3, #AT91_PMC_MOSCEN - str r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] + ldr tmp1, [pmc, #AT91_CKGR_MOR] + orr tmp1, tmp1, #AT91_PMC_MOSCEN + str tmp1, [pmc, #AT91_CKGR_MOR] wait_moscrdy /* Restore PLLB setting */ - ldr r3, .saved_pllbr - str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] + ldr tmp1, .saved_pllbr + str tmp1, [pmc, #AT91_CKGR_PLLBR] - tst r3, #(AT91_PMC_MUL & 0xff0000) + tst tmp1, #(AT91_PMC_MUL & 0xff0000) bne 1f - tst r3, #(AT91_PMC_MUL & ~0xff0000) + tst tmp1, #(AT91_PMC_MUL & ~0xff0000) beq 2f 1: wait_pllblock 2: /* Restore PLLA setting */ - ldr r3, .saved_pllar - str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] + ldr tmp1, .saved_pllar + str tmp1, [pmc, #AT91_CKGR_PLLAR] - tst r3, #(AT91_PMC_MUL & 0xff0000) + tst tmp1, #(AT91_PMC_MUL & 0xff0000) bne 3f - tst r3, #(AT91_PMC_MUL & ~0xff0000) + tst tmp1, #(AT91_PMC_MUL & ~0xff0000) beq 4f 3: wait_pllalock @@ -244,11 +260,11 @@ ENTRY(at91_slow_clock) * * See AT91RM9200 errata #27 and #28 for details. */ - ldr r3, .saved_mckr - tst r3, #AT91_PMC_PRES + ldr tmp1, .saved_mckr + tst tmp1, #AT91_PMC_PRES beq 2f - and r3, r3, #AT91_PMC_PRES - str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] + and tmp1, tmp1, #AT91_PMC_PRES + str tmp1, [pmc, #AT91_PMC_MCKR] wait_mckrdy #endif @@ -256,32 +272,45 @@ ENTRY(at91_slow_clock) /* * Restore master clock setting */ -2: ldr r3, .saved_mckr - str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)] +2: ldr tmp1, .saved_mckr + str tmp1, [pmc, #AT91_PMC_MCKR] wait_mckrdy -#ifdef CONFIG_ARCH_AT91RM9200 - /* Do nothing - self-refresh is automatically disabled. */ -#elif defined(CONFIG_ARCH_AT91CAP9) \ - || defined(CONFIG_ARCH_AT91SAM9G45) + /* + * at91rm9200 Memory controller + * Do nothing - self-refresh is automatically disabled. + */ + cmp memctrl, #AT91_MEMCTRL_MC + beq ram_restored + + /* + * DDRSDR Memory controller + */ + cmp memctrl, #AT91_MEMCTRL_DDRSDR + bne sdr_en_restore /* Restore LPR on AT91 with DDRAM */ - ldr r3, .saved_sam9_lpr - str r3, [r2, #AT91_DDRSDRC_LPR] + ldr tmp1, .saved_sam9_lpr + str tmp1, [sdramc, #AT91_DDRSDRC_LPR] /* if we use the second ram controller */ - cmp r5, #0 - ldrne r4, .saved_sam9_lpr1 - strne r4, [r5, #AT91_DDRSDRC_LPR] + cmp ramc1, #0 + ldrne tmp2, .saved_sam9_lpr1 + strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] + + b ram_restored -#else + /* + * SDRAMC Memory controller + */ +sdr_en_restore: /* Restore LPR on AT91 with SDRAM */ - ldr r3, .saved_sam9_lpr - str r3, [r2, #AT91_SDRAMC_LPR] -#endif + ldr tmp1, .saved_sam9_lpr + str tmp1, [sdramc, #AT91_SDRAMC_LPR] +ram_restored: /* Restore registers, and return */ - ldmfd sp!, {r0 - r12, pc} + ldmfd sp!, {r4 - r12, pc} .saved_mckr: @@ -299,27 +328,5 @@ ENTRY(at91_slow_clock) .saved_sam9_lpr1: .word 0 -.at91_va_base_pmc: - .word AT91_VA_BASE_SYS + AT91_PMC - -#ifdef CONFIG_ARCH_AT91RM9200 -.at91_va_base_sdramc: - .word AT91_VA_BASE_SYS -#elif defined(CONFIG_ARCH_AT91CAP9) \ - || defined(CONFIG_ARCH_AT91SAM9G45) -.at91_va_base_sdramc: - .word AT91_VA_BASE_SYS + AT91_DDRSDRC0 -#else -.at91_va_base_sdramc: - .word AT91_VA_BASE_SYS + AT91_SDRAMC0 -#endif - -.at91_va_base_ramc1: -#if defined(CONFIG_ARCH_AT91SAM9G45) - .word AT91_VA_BASE_SYS + AT91_DDRSDRC1 -#else - .word 0 -#endif - ENTRY(at91_slow_clock_sz) .word .-at91_slow_clock diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index 69d3fc4c46f3..97cc04dc8073 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c @@ -9,7 +9,9 @@ #include <linux/io.h> #include <linux/mm.h> #include <linux/pm.h> +#include <linux/of_address.h> +#include <asm/system_misc.h> #include <asm/mach/map.h> #include <mach/hardware.h> @@ -51,6 +53,19 @@ void __init at91_init_interrupts(unsigned int *priority) at91_gpio_irq_setup(); } +void __iomem *at91_ramc_base[2]; + +void __init at91_ioremap_ramc(int id, u32 addr, u32 size) +{ + if (id < 0 || id > 1) { + pr_emerg("Wrong RAM controller id (%d), cannot continue\n", id); + BUG(); + } + at91_ramc_base[id] = ioremap(addr, size); + if (!at91_ramc_base[id]) + panic("Impossible to ioremap ramc.%d 0x%x\n", id, addr); +} + static struct map_desc sram_desc[2] __initdata; void __init at91_init_sram(int bank, unsigned long base, unsigned int length) @@ -86,20 +101,6 @@ static void __init soc_detect(u32 dbgu_base) socid = cidr & ~AT91_CIDR_VERSION; switch (socid) { - case ARCH_ID_AT91CAP9: { -#ifdef CONFIG_AT91_PMC_UNIT - u32 pmc_ver = at91_sys_read(AT91_PMC_VER); - - if (pmc_ver == ARCH_REVISION_CAP9_B) - at91_soc_initdata.subtype = AT91_SOC_CAP9_REV_B; - else if (pmc_ver == ARCH_REVISION_CAP9_C) - at91_soc_initdata.subtype = AT91_SOC_CAP9_REV_C; -#endif - at91_soc_initdata.type = AT91_SOC_CAP9; - at91_boot_soc = at91cap9_soc; - break; - } - case ARCH_ID_AT91RM9200: at91_soc_initdata.type = AT91_SOC_RM9200; at91_boot_soc = at91rm9200_soc; @@ -200,7 +201,6 @@ static void __init soc_detect(u32 dbgu_base) static const char *soc_name[] = { [AT91_SOC_RM9200] = "at91rm9200", - [AT91_SOC_CAP9] = "at91cap9", [AT91_SOC_SAM9260] = "at91sam9260", [AT91_SOC_SAM9261] = "at91sam9261", [AT91_SOC_SAM9263] = "at91sam9263", @@ -221,8 +221,6 @@ EXPORT_SYMBOL(at91_get_soc_type); static const char *soc_subtype_name[] = { [AT91_SOC_RM9200_BGA] = "at91rm9200 BGA", [AT91_SOC_RM9200_PQFP] = "at91rm9200 PQFP", - [AT91_SOC_CAP9_REV_B] = "at91cap9 revB", - [AT91_SOC_CAP9_REV_C] = "at91cap9 revC", [AT91_SOC_SAM9XE] = "at91sam9xe", [AT91_SOC_SAM9G45ES] = "at91sam9g45es", [AT91_SOC_SAM9M10] = "at91sam9m10", @@ -293,6 +291,159 @@ void __init at91_ioremap_rstc(u32 base_addr) panic("Impossible to ioremap at91_rstc_base\n"); } +void __iomem *at91_matrix_base; + +void __init at91_ioremap_matrix(u32 base_addr) +{ + at91_matrix_base = ioremap(base_addr, 512); + if (!at91_matrix_base) + panic("Impossible to ioremap at91_matrix_base\n"); +} + +#if defined(CONFIG_OF) +static struct of_device_id rstc_ids[] = { + { .compatible = "atmel,at91sam9260-rstc", .data = at91sam9_alt_restart }, + { .compatible = "atmel,at91sam9g45-rstc", .data = at91sam9g45_restart }, + { /*sentinel*/ } +}; + +static void at91_dt_rstc(void) +{ + struct device_node *np; + const struct of_device_id *of_id; + + np = of_find_matching_node(NULL, rstc_ids); + if (!np) + panic("unable to find compatible rstc node in dtb\n"); + + at91_rstc_base = of_iomap(np, 0); + if (!at91_rstc_base) + panic("unable to map rstc cpu registers\n"); + + of_id = of_match_node(rstc_ids, np); + if (!of_id) + panic("AT91: rtsc no restart function availlable\n"); + + arm_pm_restart = of_id->data; + + of_node_put(np); +} + +static struct of_device_id ramc_ids[] = { + { .compatible = "atmel,at91sam9260-sdramc" }, + { .compatible = "atmel,at91sam9g45-ddramc" }, + { /*sentinel*/ } +}; + +static void at91_dt_ramc(void) +{ + struct device_node *np; + + np = of_find_matching_node(NULL, ramc_ids); + if (!np) + panic("unable to find compatible ram conroller node in dtb\n"); + + at91_ramc_base[0] = of_iomap(np, 0); + if (!at91_ramc_base[0]) + panic("unable to map ramc[0] cpu registers\n"); + /* the controller may have 2 banks */ + at91_ramc_base[1] = of_iomap(np, 1); + + of_node_put(np); +} + +static struct of_device_id shdwc_ids[] = { + { .compatible = "atmel,at91sam9260-shdwc", }, + { .compatible = "atmel,at91sam9rl-shdwc", }, + { .compatible = "atmel,at91sam9x5-shdwc", }, + { /*sentinel*/ } +}; + +static const char *shdwc_wakeup_modes[] = { + [AT91_SHDW_WKMODE0_NONE] = "none", + [AT91_SHDW_WKMODE0_HIGH] = "high", + [AT91_SHDW_WKMODE0_LOW] = "low", + [AT91_SHDW_WKMODE0_ANYLEVEL] = "any", +}; + +const int at91_dtget_shdwc_wakeup_mode(struct device_node *np) +{ + const char *pm; + int err, i; + + err = of_property_read_string(np, "atmel,wakeup-mode", &pm); + if (err < 0) + return AT91_SHDW_WKMODE0_ANYLEVEL; + + for (i = 0; i < ARRAY_SIZE(shdwc_wakeup_modes); i++) + if (!strcasecmp(pm, shdwc_wakeup_modes[i])) + return i; + + return -ENODEV; +} + +static void at91_dt_shdwc(void) +{ + struct device_node *np; + int wakeup_mode; + u32 reg; + u32 mode = 0; + + np = of_find_matching_node(NULL, shdwc_ids); + if (!np) { + pr_debug("AT91: unable to find compatible shutdown (shdwc) conroller node in dtb\n"); + return; + } + + at91_shdwc_base = of_iomap(np, 0); + if (!at91_shdwc_base) + panic("AT91: unable to map shdwc cpu registers\n"); + + wakeup_mode = at91_dtget_shdwc_wakeup_mode(np); + if (wakeup_mode < 0) { + pr_warn("AT91: shdwc unknown wakeup mode\n"); + goto end; + } + + if (!of_property_read_u32(np, "atmel,wakeup-counter", ®)) { + if (reg > AT91_SHDW_CPTWK0_MAX) { + pr_warn("AT91: shdwc wakeup conter 0x%x > 0x%x reduce it to 0x%x\n", + reg, AT91_SHDW_CPTWK0_MAX, AT91_SHDW_CPTWK0_MAX); + reg = AT91_SHDW_CPTWK0_MAX; + } + mode |= AT91_SHDW_CPTWK0_(reg); + } + + if (of_property_read_bool(np, "atmel,wakeup-rtc-timer")) + mode |= AT91_SHDW_RTCWKEN; + + if (of_property_read_bool(np, "atmel,wakeup-rtt-timer")) + mode |= AT91_SHDW_RTTWKEN; + + at91_shdwc_write(AT91_SHDW_MR, wakeup_mode | mode); + +end: + pm_power_off = at91sam9_poweroff; + + of_node_put(np); +} + +void __init at91_dt_initialize(void) +{ + at91_dt_rstc(); + at91_dt_ramc(); + at91_dt_shdwc(); + + /* Init clock subsystem */ + at91_dt_clock_init(); + + /* Register the processor-specific clocks */ + at91_boot_soc.register_clocks(); + + at91_boot_soc.init(); +} +#endif + void __init at91_initialize(unsigned long main_clock) { at91_boot_soc.ioremap_registers(); diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h index 4588ae6f7acd..5db4aa45404a 100644 --- a/arch/arm/mach-at91/soc.h +++ b/arch/arm/mach-at91/soc.h @@ -13,7 +13,6 @@ struct at91_init_soc { }; extern struct at91_init_soc at91_boot_soc; -extern struct at91_init_soc at91cap9_soc; extern struct at91_init_soc at91rm9200_soc; extern struct at91_init_soc at91sam9260_soc; extern struct at91_init_soc at91sam9261_soc; @@ -27,10 +26,6 @@ static inline int at91_soc_is_enabled(void) return at91_boot_soc.init != NULL; } -#if !defined(CONFIG_ARCH_AT91CAP9) -#define at91cap9_soc at91_boot_soc -#endif - #if !defined(CONFIG_ARCH_AT91RM9200) #define at91rm9200_soc at91_boot_soc #endif diff --git a/arch/arm/mach-bcmring/core.c b/arch/arm/mach-bcmring/core.c index 6b67b7e8426c..22e4e0a28ad1 100644 --- a/arch/arm/mach-bcmring/core.c +++ b/arch/arm/mach-bcmring/core.c @@ -52,27 +52,8 @@ #include <mach/csp/chipcHw_inline.h> #include <mach/csp/tmrHw_reg.h> -#define AMBA_DEVICE(name, initname, base, plat, size) \ -static struct amba_device name##_device = { \ - .dev = { \ - .coherent_dma_mask = ~0, \ - .init_name = initname, \ - .platform_data = plat \ - }, \ - .res = { \ - .start = MM_ADDR_IO_##base, \ - .end = MM_ADDR_IO_##base + (size) - 1, \ - .flags = IORESOURCE_MEM \ - }, \ - .dma_mask = ~0, \ - .irq = { \ - IRQ_##base \ - } \ -} - - -AMBA_DEVICE(uartA, "uarta", UARTA, NULL, SZ_4K); -AMBA_DEVICE(uartB, "uartb", UARTB, NULL, SZ_4K); +static AMBA_APB_DEVICE(uartA, "uarta", MM_ADDR_IO_UARTA, { IRQ_UARTA }, NULL); +static AMBA_APB_DEVICE(uartB, "uartb", MM_ADDR_IO_UARTB, { IRQ_UARTB }, NULL); static struct clk pll1_clk = { .name = "PLL1", diff --git a/arch/arm/mach-bcmring/include/mach/entry-macro.S b/arch/arm/mach-bcmring/include/mach/entry-macro.S index 94c950d783ba..2f316f0e6e69 100644 --- a/arch/arm/mach-bcmring/include/mach/entry-macro.S +++ b/arch/arm/mach-bcmring/include/mach/entry-macro.S @@ -21,9 +21,6 @@ #include <mach/hardware.h> #include <mach/csp/mm_io.h> - .macro disable_fiq - .endm - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \base, =(MM_IO_BASE_INTC0) ldr \irqstat, [\base, #0] @ get status @@ -77,6 +74,3 @@ .macro get_irqnr_preamble, base, tmp .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-bcmring/include/mach/io.h b/arch/arm/mach-bcmring/include/mach/io.h deleted file mode 100644 index dae5e9b166ea..000000000000 --- a/arch/arm/mach-bcmring/include/mach/io.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * - * Copyright (C) 1999 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. - * - * 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_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -#include <mach/hardware.h> - -#define IO_SPACE_LIMIT 0xffffffff - -/* - * We don't actually have real ISA nor PCI buses, but there is so many - * drivers out there that might just work if we fake them... - */ -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#endif diff --git a/arch/arm/mach-bcmring/include/mach/system.h b/arch/arm/mach-bcmring/include/mach/system.h deleted file mode 100644 index cb78250db649..000000000000 --- a/arch/arm/mach-bcmring/include/mach/system.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * - * Copyright (C) 1999 ARM Limited - * Copyright (C) 2000 Deep Blue Solutions Ltd - * - * 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_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-clps711x/common.c b/arch/arm/mach-clps711x/common.c index ab1711b9b4d6..3c5b5bbf24e5 100644 --- a/arch/arm/mach-clps711x/common.c +++ b/arch/arm/mach-clps711x/common.c @@ -37,6 +37,7 @@ #include <asm/mach/map.h> #include <asm/mach/time.h> #include <asm/hardware/clps7111.h> +#include <asm/system_misc.h> /* * This maps the generic CLPS711x registers @@ -225,3 +226,19 @@ void clps711x_restart(char mode, const char *cmd) { soft_restart(0); } + +static void clps711x_idle(void) +{ + clps_writel(1, HALT); + __asm__ __volatile__( + "mov r0, r0\n\ + mov r0, r0"); +} + +static int __init clps711x_idle_init(void) +{ + arm_pm_idle = clps711x_idle; + return 0; +} + +arch_initcall(clps711x_idle_init); diff --git a/arch/arm/mach-clps711x/edb7211-mm.c b/arch/arm/mach-clps711x/edb7211-mm.c index 0bea1454ae03..4372f06c9929 100644 --- a/arch/arm/mach-clps711x/edb7211-mm.c +++ b/arch/arm/mach-clps711x/edb7211-mm.c @@ -21,6 +21,7 @@ */ #include <linux/kernel.h> #include <linux/init.h> +#include <linux/bug.h> #include <mach/hardware.h> #include <asm/page.h> diff --git a/arch/arm/mach-clps711x/include/mach/entry-macro.S b/arch/arm/mach-clps711x/include/mach/entry-macro.S index 90fa2f70489f..125af59d7a29 100644 --- a/arch/arm/mach-clps711x/include/mach/entry-macro.S +++ b/arch/arm/mach-clps711x/include/mach/entry-macro.S @@ -10,15 +10,9 @@ #include <mach/hardware.h> #include <asm/hardware/clps7111.h> - .macro disable_fiq - .endm - .macro get_irqnr_preamble, base, tmp .endm - .macro arch_ret_to_user, tmp1, tmp2 - .endm - #if (INTSR2 - INTSR1) != (INTMR2 - INTMR1) #error INTSR stride != INTMR stride #endif diff --git a/arch/arm/mach-clps711x/include/mach/io.h b/arch/arm/mach-clps711x/include/mach/io.h deleted file mode 100644 index 2e0b3ced8f07..000000000000 --- a/arch/arm/mach-clps711x/include/mach/io.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * arch/arm/mach-clps711x/include/mach/io.h - * - * Copyright (C) 1999 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. - * - * 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_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -/* - * We don't support ins[lb]/outs[lb]. Make them fault. - */ -#define __raw_readsb(p,d,l) do { *(int *)0 = 0; } while (0) -#define __raw_readsl(p,d,l) do { *(int *)0 = 0; } while (0) -#define __raw_writesb(p,d,l) do { *(int *)0 = 0; } while (0) -#define __raw_writesl(p,d,l) do { *(int *)0 = 0; } while (0) - -#endif diff --git a/arch/arm/mach-clps711x/include/mach/system.h b/arch/arm/mach-clps711x/include/mach/system.h deleted file mode 100644 index 23d6ef8c84da..000000000000 --- a/arch/arm/mach-clps711x/include/mach/system.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * arch/arm/mach-clps711x/include/mach/system.h - * - * Copyright (C) 2000 Deep Blue Solutions Ltd - * - * 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_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -#include <linux/io.h> -#include <mach/hardware.h> -#include <asm/hardware/clps7111.h> - -static inline void arch_idle(void) -{ - clps_writel(1, HALT); - __asm__ __volatile__( - "mov r0, r0\n\ - mov r0, r0"); -} - -#endif diff --git a/arch/arm/mach-clps711x/include/mach/uncompress.h b/arch/arm/mach-clps711x/include/mach/uncompress.h index 7164310dea7c..35ed731b9f16 100644 --- a/arch/arm/mach-clps711x/include/mach/uncompress.h +++ b/arch/arm/mach-clps711x/include/mach/uncompress.h @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <mach/io.h> #include <mach/hardware.h> #include <asm/hardware/clps7111.h> diff --git a/arch/arm/mach-clps711x/p720t-leds.c b/arch/arm/mach-clps711x/p720t-leds.c index 15121446efc8..dd9a6cdbeb02 100644 --- a/arch/arm/mach-clps711x/p720t-leds.c +++ b/arch/arm/mach-clps711x/p720t-leds.c @@ -25,7 +25,6 @@ #include <mach/hardware.h> #include <asm/leds.h> -#include <asm/system.h> #include <asm/mach-types.h> #include <asm/hardware/clps7111.h> diff --git a/arch/arm/mach-cns3xxx/core.c b/arch/arm/mach-cns3xxx/core.c index 941a308e1253..031805b1428d 100644 --- a/arch/arm/mach-cns3xxx/core.c +++ b/arch/arm/mach-cns3xxx/core.c @@ -72,13 +72,13 @@ void __init cns3xxx_map_io(void) /* used by entry-macro.S */ void __init cns3xxx_init_irq(void) { - gic_init(0, 29, __io(CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT), - __io(CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT)); + gic_init(0, 29, IOMEM(CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT), + IOMEM(CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT)); } void cns3xxx_power_off(void) { - u32 __iomem *pm_base = __io(CNS3XXX_PM_BASE_VIRT); + u32 __iomem *pm_base = IOMEM(CNS3XXX_PM_BASE_VIRT); u32 clkctrl; printk(KERN_INFO "powering system down...\n"); @@ -237,7 +237,7 @@ static void __init __cns3xxx_timer_init(unsigned int timer_irq) static void __init cns3xxx_timer_init(void) { - cns3xxx_tmr1 = __io(CNS3XXX_TIMER1_2_3_BASE_VIRT); + cns3xxx_tmr1 = IOMEM(CNS3XXX_TIMER1_2_3_BASE_VIRT); __cns3xxx_timer_init(IRQ_CNS3XXX_TIMER0); } diff --git a/arch/arm/mach-cns3xxx/devices.c b/arch/arm/mach-cns3xxx/devices.c index 79d1fb02c23f..1e40c99b015f 100644 --- a/arch/arm/mach-cns3xxx/devices.c +++ b/arch/arm/mach-cns3xxx/devices.c @@ -98,7 +98,7 @@ static struct platform_device cns3xxx_sdhci_pdev = { void __init cns3xxx_sdhci_init(void) { - u32 __iomem *gpioa = __io(CNS3XXX_MISC_BASE_VIRT + 0x0014); + u32 __iomem *gpioa = IOMEM(CNS3XXX_MISC_BASE_VIRT + 0x0014); u32 gpioa_pins = __raw_readl(gpioa); /* MMC/SD pins share with GPIOA */ diff --git a/arch/arm/mach-cns3xxx/include/mach/entry-macro.S b/arch/arm/mach-cns3xxx/include/mach/entry-macro.S deleted file mode 100644 index 01c57df5f716..000000000000 --- a/arch/arm/mach-cns3xxx/include/mach/entry-macro.S +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Low-level IRQ helper macros for Cavium Networks platforms - * - * Copyright 2008 Cavium Networks - * - * This file 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. - */ - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-cns3xxx/include/mach/io.h b/arch/arm/mach-cns3xxx/include/mach/io.h deleted file mode 100644 index 33b6fc1ece7c..000000000000 --- a/arch/arm/mach-cns3xxx/include/mach/io.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2008 Cavium Networks - * Copyright 2003 ARM Limited - * - * This file 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. - */ -#ifndef __MACH_IO_H -#define __MACH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#endif diff --git a/arch/arm/mach-cns3xxx/include/mach/system.h b/arch/arm/mach-cns3xxx/include/mach/system.h deleted file mode 100644 index 9e56b7dc133a..000000000000 --- a/arch/arm/mach-cns3xxx/include/mach/system.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2000 Deep Blue Solutions Ltd - * Copyright 2003 ARM Limited - * Copyright 2008 Cavium Networks - * - * This file 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. - */ - -#ifndef __MACH_SYSTEM_H -#define __MACH_SYSTEM_H - -#include <asm/proc-fns.h> - -static inline void arch_idle(void) -{ - /* - * This should do all the clock switching - * and wait for interrupt tricks - */ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-cns3xxx/pcie.c b/arch/arm/mach-cns3xxx/pcie.c index e159d69967c9..79d001f831e0 100644 --- a/arch/arm/mach-cns3xxx/pcie.c +++ b/arch/arm/mach-cns3xxx/pcie.c @@ -155,8 +155,8 @@ static int cns3xxx_pci_setup(int nr, struct pci_sys_data *sys) BUG_ON(request_resource(&iomem_resource, res_io) || request_resource(&iomem_resource, res_mem)); - pci_add_resource(&sys->resources, res_io); - pci_add_resource(&sys->resources, res_mem); + pci_add_resource_offset(&sys->resources, res_io, sys->io_offset); + pci_add_resource_offset(&sys->resources, res_mem, sys->mem_offset); return 1; } diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index d5088900af6c..a70de24d1cbc 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -36,6 +36,7 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> +#include <asm/system_info.h> #include <mach/cp_intc.h> #include <mach/da8xx.h> diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c index 275341f159fb..82ed753fb360 100644 --- a/arch/arm/mach-davinci/board-dm355-evm.c +++ b/arch/arm/mach-davinci/board-dm355-evm.c @@ -26,13 +26,14 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <mach/dm355.h> #include <mach/i2c.h> #include <mach/serial.h> #include <mach/nand.h> #include <mach/mmc.h> #include <mach/usb.h> +#include "davinci.h" + /* NOTE: this is geared for the standard config, with a socketed * 2 GByte Micron NAND (MT29F16G08FAA) using 128KB sectors. If you * swap chips, maybe with a different block size, partitioning may diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c index e99db28181ae..d74a8b3445fb 100644 --- a/arch/arm/mach-davinci/board-dm355-leopard.c +++ b/arch/arm/mach-davinci/board-dm355-leopard.c @@ -23,13 +23,14 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <mach/dm355.h> #include <mach/i2c.h> #include <mach/serial.h> #include <mach/nand.h> #include <mach/mmc.h> #include <mach/usb.h> +#include "davinci.h" + /* NOTE: this is geared for the standard config, with a socketed * 2 GByte Micron NAND (MT29F16G08FAA) using 128KB sectors. If you * swap chips, maybe with a different block size, partitioning may diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index 849311d3cb7c..5bce2b83bb4f 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -32,7 +32,6 @@ #include <asm/mach/arch.h> #include <mach/mux.h> -#include <mach/dm365.h> #include <mach/common.h> #include <mach/i2c.h> #include <mach/serial.h> @@ -42,6 +41,8 @@ #include <media/tvp514x.h> +#include "davinci.h" + static inline int have_imager(void) { /* REVISIT when it's supported, trigger via Kconfig */ diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index 1247ecdcf752..3683306e0245 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -30,7 +30,6 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <mach/dm644x.h> #include <mach/common.h> #include <mach/i2c.h> #include <mach/serial.h> @@ -40,6 +39,8 @@ #include <mach/usb.h> #include <mach/aemif.h> +#include "davinci.h" + #define DM644X_EVM_PHY_ID "davinci_mdio-0:01" #define LXT971_PHY_ID (0x001378e2) #define LXT971_PHY_MASK (0xfffffff0) @@ -189,7 +190,7 @@ static struct platform_device davinci_fb_device = { .num_resources = 0, }; -static struct tvp514x_platform_data tvp5146_pdata = { +static struct tvp514x_platform_data dm644xevm_tvp5146_pdata = { .clk_polarity = 0, .hs_polarity = 1, .vs_polarity = 1 @@ -197,7 +198,7 @@ static struct tvp514x_platform_data tvp5146_pdata = { #define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL) /* Inputs available at the TVP5146 */ -static struct v4l2_input tvp5146_inputs[] = { +static struct v4l2_input dm644xevm_tvp5146_inputs[] = { { .index = 0, .name = "Composite", @@ -217,7 +218,7 @@ static struct v4l2_input tvp5146_inputs[] = { * ouput that goes to vpfe. There is a one to one correspondence * with tvp5146_inputs */ -static struct vpfe_route tvp5146_routes[] = { +static struct vpfe_route dm644xevm_tvp5146_routes[] = { { .input = INPUT_CVBS_VI2B, .output = OUTPUT_10BIT_422_EMBEDDED_SYNC, @@ -228,13 +229,13 @@ static struct vpfe_route tvp5146_routes[] = { }, }; -static struct vpfe_subdev_info vpfe_sub_devs[] = { +static struct vpfe_subdev_info dm644xevm_vpfe_sub_devs[] = { { .name = "tvp5146", .grp_id = 0, - .num_inputs = ARRAY_SIZE(tvp5146_inputs), - .inputs = tvp5146_inputs, - .routes = tvp5146_routes, + .num_inputs = ARRAY_SIZE(dm644xevm_tvp5146_inputs), + .inputs = dm644xevm_tvp5146_inputs, + .routes = dm644xevm_tvp5146_routes, .can_route = 1, .ccdc_if_params = { .if_type = VPFE_BT656, @@ -243,15 +244,15 @@ static struct vpfe_subdev_info vpfe_sub_devs[] = { }, .board_info = { I2C_BOARD_INFO("tvp5146", 0x5d), - .platform_data = &tvp5146_pdata, + .platform_data = &dm644xevm_tvp5146_pdata, }, }, }; -static struct vpfe_config vpfe_cfg = { - .num_subdevs = ARRAY_SIZE(vpfe_sub_devs), +static struct vpfe_config dm644xevm_capture_cfg = { + .num_subdevs = ARRAY_SIZE(dm644xevm_vpfe_sub_devs), .i2c_adapter_id = 1, - .sub_devs = vpfe_sub_devs, + .sub_devs = dm644xevm_vpfe_sub_devs, .card_name = "DM6446 EVM", .ccdc = "DM6446 CCDC", }; @@ -612,6 +613,113 @@ static void __init evm_init_i2c(void) i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info)); } +#define VENC_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL) + +/* venc standard timings */ +static struct vpbe_enc_mode_info dm644xevm_enc_std_timing[] = { + { + .name = "ntsc", + .timings_type = VPBE_ENC_STD, + .timings = {V4L2_STD_525_60}, + .interlaced = 1, + .xres = 720, + .yres = 480, + .aspect = {11, 10}, + .fps = {30000, 1001}, + .left_margin = 0x79, + .upper_margin = 0x10, + }, + { + .name = "pal", + .timings_type = VPBE_ENC_STD, + .timings = {V4L2_STD_625_50}, + .interlaced = 1, + .xres = 720, + .yres = 576, + .aspect = {54, 59}, + .fps = {25, 1}, + .left_margin = 0x7e, + .upper_margin = 0x16, + }, +}; + +/* venc dv preset timings */ +static struct vpbe_enc_mode_info dm644xevm_enc_preset_timing[] = { + { + .name = "480p59_94", + .timings_type = VPBE_ENC_DV_PRESET, + .timings = {V4L2_DV_480P59_94}, + .interlaced = 0, + .xres = 720, + .yres = 480, + .aspect = {1, 1}, + .fps = {5994, 100}, + .left_margin = 0x80, + .upper_margin = 0x20, + }, + { + .name = "576p50", + .timings_type = VPBE_ENC_DV_PRESET, + .timings = {V4L2_DV_576P50}, + .interlaced = 0, + .xres = 720, + .yres = 576, + .aspect = {1, 1}, + .fps = {50, 1}, + .left_margin = 0x7e, + .upper_margin = 0x30, + }, +}; + +/* + * The outputs available from VPBE + encoders. Keep the order same + * as that of encoders. First those from venc followed by that from + * encoders. Index in the output refers to index on a particular encoder. + * Driver uses this index to pass it to encoder when it supports more + * than one output. Userspace applications use index of the array to + * set an output. + */ +static struct vpbe_output dm644xevm_vpbe_outputs[] = { + { + .output = { + .index = 0, + .name = "Composite", + .type = V4L2_OUTPUT_TYPE_ANALOG, + .std = VENC_STD_ALL, + .capabilities = V4L2_OUT_CAP_STD, + }, + .subdev_name = VPBE_VENC_SUBDEV_NAME, + .default_mode = "ntsc", + .num_modes = ARRAY_SIZE(dm644xevm_enc_std_timing), + .modes = dm644xevm_enc_std_timing, + }, + { + .output = { + .index = 1, + .name = "Component", + .type = V4L2_OUTPUT_TYPE_ANALOG, + .capabilities = V4L2_OUT_CAP_PRESETS, + }, + .subdev_name = VPBE_VENC_SUBDEV_NAME, + .default_mode = "480p59_94", + .num_modes = ARRAY_SIZE(dm644xevm_enc_preset_timing), + .modes = dm644xevm_enc_preset_timing, + }, +}; + +static struct vpbe_config dm644xevm_display_cfg = { + .module_name = "dm644x-vpbe-display", + .i2c_adapter_id = 1, + .osd = { + .module_name = VPBE_OSD_SUBDEV_NAME, + }, + .venc = { + .module_name = VPBE_VENC_SUBDEV_NAME, + }, + .num_outputs = ARRAY_SIZE(dm644xevm_vpbe_outputs), + .outputs = dm644xevm_vpbe_outputs, +}; + static struct platform_device *davinci_evm_devices[] __initdata = { &davinci_fb_device, &rtc_dev, @@ -624,8 +732,6 @@ static struct davinci_uart_config uart_config __initdata = { static void __init davinci_evm_map_io(void) { - /* setup input configuration for VPFE input devices */ - dm644x_set_vpfe_config(&vpfe_cfg); dm644x_init(); } @@ -697,6 +803,7 @@ static __init void davinci_evm_init(void) evm_init_i2c(); davinci_setup_mmc(0, &dm6446evm_mmc_config); + dm644x_init_video(&dm644xevm_capture_cfg, &dm644xevm_display_cfg); davinci_serial_init(&uart_config); dm644x_init_asp(&dm644x_evm_snd_data); diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index 872ac69fa049..d72ab948d630 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -36,7 +36,6 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <mach/dm646x.h> #include <mach/common.h> #include <mach/serial.h> #include <mach/i2c.h> @@ -45,6 +44,7 @@ #include <mach/cdce949.h> #include <mach/aemif.h> +#include "davinci.h" #include "clock.h" #define NAND_BLOCK_SIZE SZ_128K @@ -410,8 +410,6 @@ static struct davinci_i2c_platform_data i2c_pdata = { .bus_delay = 0 /* usec */, }; -#define VIDCLKCTL_OFFSET (DAVINCI_SYSTEM_MODULE_BASE + 0x38) -#define VSCLKDIS_OFFSET (DAVINCI_SYSTEM_MODULE_BASE + 0x6c) #define VCH2CLK_MASK (BIT_MASK(10) | BIT_MASK(9) | BIT_MASK(8)) #define VCH2CLK_SYSCLK8 (BIT(9)) #define VCH2CLK_AUXCLK (BIT(9) | BIT(8)) @@ -429,8 +427,6 @@ static struct davinci_i2c_platform_data i2c_pdata = { #define TVP5147_CH0 "tvp514x-0" #define TVP5147_CH1 "tvp514x-1" -static void __iomem *vpif_vidclkctl_reg; -static void __iomem *vpif_vsclkdis_reg; /* spin lock for updating above registers */ static spinlock_t vpif_reg_lock; @@ -441,14 +437,14 @@ static int set_vpif_clock(int mux_mode, int hd) int val = 0; int err = 0; - if (!vpif_vidclkctl_reg || !vpif_vsclkdis_reg || !cpld_client) + if (!cpld_client) return -ENXIO; /* disable the clock */ spin_lock_irqsave(&vpif_reg_lock, flags); - value = __raw_readl(vpif_vsclkdis_reg); + value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS)); value |= (VIDCH3CLK | VIDCH2CLK); - __raw_writel(value, vpif_vsclkdis_reg); + __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS)); spin_unlock_irqrestore(&vpif_reg_lock, flags); val = i2c_smbus_read_byte(cpld_client); @@ -464,7 +460,7 @@ static int set_vpif_clock(int mux_mode, int hd) if (err) return err; - value = __raw_readl(vpif_vidclkctl_reg); + value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL)); value &= ~(VCH2CLK_MASK); value &= ~(VCH3CLK_MASK); @@ -473,13 +469,13 @@ static int set_vpif_clock(int mux_mode, int hd) else value |= (VCH2CLK_AUXCLK | VCH3CLK_AUXCLK); - __raw_writel(value, vpif_vidclkctl_reg); + __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL)); spin_lock_irqsave(&vpif_reg_lock, flags); - value = __raw_readl(vpif_vsclkdis_reg); + value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS)); /* enable the clock */ value &= ~(VIDCH3CLK | VIDCH2CLK); - __raw_writel(value, vpif_vsclkdis_reg); + __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS)); spin_unlock_irqrestore(&vpif_reg_lock, flags); return 0; @@ -564,7 +560,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) int val; u32 value; - if (!vpif_vidclkctl_reg || !cpld_client) + if (!cpld_client) return -ENXIO; val = i2c_smbus_read_byte(cpld_client); @@ -572,7 +568,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) return val; spin_lock_irqsave(&vpif_reg_lock, flags); - value = __raw_readl(vpif_vidclkctl_reg); + value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL)); if (mux_mode) { val &= VPIF_INPUT_TWO_CHANNEL; value |= VIDCH1CLK; @@ -580,7 +576,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) val |= VPIF_INPUT_ONE_CHANNEL; value &= ~VIDCH1CLK; } - __raw_writel(value, vpif_vidclkctl_reg); + __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VIDCLKCTL)); spin_unlock_irqrestore(&vpif_reg_lock, flags); err = i2c_smbus_write_byte(cpld_client, val); @@ -674,12 +670,6 @@ static struct vpif_capture_config dm646x_vpif_capture_cfg = { static void __init evm_init_video(void) { - vpif_vidclkctl_reg = ioremap(VIDCLKCTL_OFFSET, 4); - vpif_vsclkdis_reg = ioremap(VSCLKDIS_OFFSET, 4); - if (!vpif_vidclkctl_reg || !vpif_vsclkdis_reg) { - pr_err("Can't map VPIF VIDCLKCTL or VSCLKDIS registers\n"); - return; - } spin_lock_init(&vpif_reg_lock); dm646x_setup_vpif(&dm646x_vpif_display_config, diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c index 8d34f513d415..a772bb45570a 100644 --- a/arch/arm/mach-davinci/board-neuros-osd2.c +++ b/arch/arm/mach-davinci/board-neuros-osd2.c @@ -30,7 +30,6 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <mach/dm644x.h> #include <mach/common.h> #include <mach/i2c.h> #include <mach/serial.h> @@ -39,6 +38,8 @@ #include <mach/mmc.h> #include <mach/usb.h> +#include "davinci.h" + #define NEUROS_OSD2_PHY_ID "davinci_mdio-0:01" #define LXT971_PHY_ID 0x001378e2 #define LXT971_PHY_MASK 0xfffffff0 diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c index 31da3c5b2ba3..76e675096104 100644 --- a/arch/arm/mach-davinci/board-sffsdr.c +++ b/arch/arm/mach-davinci/board-sffsdr.c @@ -35,13 +35,14 @@ #include <asm/mach/arch.h> #include <asm/mach/flash.h> -#include <mach/dm644x.h> #include <mach/common.h> #include <mach/i2c.h> #include <mach/serial.h> #include <mach/mux.h> #include <mach/usb.h> +#include "davinci.h" + #define SFFSDR_PHY_ID "davinci_mdio-0:01" static struct mtd_partition davinci_sffsdr_nandflash_partition[] = { /* U-Boot Environment: Block 0 diff --git a/arch/arm/mach-davinci/cpufreq.c b/arch/arm/mach-davinci/cpufreq.c index 5bba7070f271..031048fec9f5 100644 --- a/arch/arm/mach-davinci/cpufreq.c +++ b/arch/arm/mach-davinci/cpufreq.c @@ -95,7 +95,7 @@ static int davinci_target(struct cpufreq_policy *policy, if (freqs.old == freqs.new) return ret; - dev_dbg(&cpufreq.dev, "transition: %u --> %u\n", freqs.old, freqs.new); + dev_dbg(cpufreq.dev, "transition: %u --> %u\n", freqs.old, freqs.new); ret = cpufreq_frequency_table_target(policy, pdata->freq_table, freqs.new, relation, &idx); diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c index a30c7c5a6d83..9107691adbdb 100644 --- a/arch/arm/mach-davinci/cpuidle.c +++ b/arch/arm/mach-davinci/cpuidle.c @@ -18,6 +18,7 @@ #include <linux/io.h> #include <linux/export.h> #include <asm/proc-fns.h> +#include <asm/cpuidle.h> #include <mach/cpuidle.h> #include <mach/ddr2.h> @@ -30,12 +31,43 @@ struct davinci_ops { u32 flags; }; +/* Actual code that puts the SoC in different idle states */ +static int davinci_enter_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; + struct davinci_ops *ops = cpuidle_get_statedata(state_usage); + + if (ops && ops->enter) + ops->enter(ops->flags); + + index = cpuidle_wrap_enter(dev, drv, index, + arm_cpuidle_simple_enter); + + if (ops && ops->exit) + ops->exit(ops->flags); + + return index; +} + /* fields in davinci_ops.flags */ #define DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN BIT(0) static struct cpuidle_driver davinci_idle_driver = { - .name = "cpuidle-davinci", - .owner = THIS_MODULE, + .name = "cpuidle-davinci", + .owner = THIS_MODULE, + .en_core_tk_irqen = 1, + .states[0] = ARM_CPUIDLE_WFI_STATE, + .states[1] = { + .enter = davinci_enter_idle, + .exit_latency = 10, + .target_residency = 100000, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "DDR SR", + .desc = "WFI and DDR Self Refresh", + }, + .state_count = DAVINCI_CPUIDLE_MAX_STATES, }; static DEFINE_PER_CPU(struct cpuidle_device, davinci_cpuidle_device); @@ -77,41 +109,10 @@ static struct davinci_ops davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = { }, }; -/* Actual code that puts the SoC in different idle states */ -static int davinci_enter_idle(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index) -{ - struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; - struct davinci_ops *ops = cpuidle_get_statedata(state_usage); - struct timeval before, after; - int idle_time; - - local_irq_disable(); - do_gettimeofday(&before); - - if (ops && ops->enter) - ops->enter(ops->flags); - /* Wait for interrupt state */ - cpu_do_idle(); - if (ops && ops->exit) - ops->exit(ops->flags); - - do_gettimeofday(&after); - local_irq_enable(); - idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + - (after.tv_usec - before.tv_usec); - - dev->last_residency = idle_time; - - return index; -} - static int __init davinci_cpuidle_probe(struct platform_device *pdev) { int ret; struct cpuidle_device *device; - struct cpuidle_driver *driver = &davinci_idle_driver; struct davinci_cpuidle_config *pdata = pdev->dev.platform_data; device = &per_cpu(davinci_cpuidle_device, smp_processor_id()); @@ -123,27 +124,11 @@ static int __init davinci_cpuidle_probe(struct platform_device *pdev) ddr2_reg_base = pdata->ddr2_ctlr_base; - /* Wait for interrupt state */ - driver->states[0].enter = davinci_enter_idle; - driver->states[0].exit_latency = 1; - driver->states[0].target_residency = 10000; - driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID; - strcpy(driver->states[0].name, "WFI"); - strcpy(driver->states[0].desc, "Wait for interrupt"); - - /* Wait for interrupt and DDR self refresh state */ - driver->states[1].enter = davinci_enter_idle; - driver->states[1].exit_latency = 10; - driver->states[1].target_residency = 10000; - driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID; - strcpy(driver->states[1].name, "DDR SR"); - strcpy(driver->states[1].desc, "WFI and DDR Self Refresh"); if (pdata->ddr2_pdown) davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN; cpuidle_set_statedata(&device->states_usage[1], &davinci_states[1]); device->state_count = DAVINCI_CPUIDLE_MAX_STATES; - driver->state_count = DAVINCI_CPUIDLE_MAX_STATES; ret = cpuidle_register_driver(&davinci_idle_driver); if (ret) { diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 992c4c410185..b44dc844e15e 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -1026,7 +1026,7 @@ static int da850_round_armrate(struct clk *clk, unsigned long rate) } #endif -int da850_register_pm(struct platform_device *pdev) +int __init da850_register_pm(struct platform_device *pdev) { int ret; struct davinci_pm_config *pdata = pdev->dev.platform_data; diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h new file mode 100644 index 000000000000..3e519dad5bb9 --- /dev/null +++ b/arch/arm/mach-davinci/davinci.h @@ -0,0 +1,102 @@ +/* + * This file contains the processor specific definitions + * of the TI DM644x, DM355, DM365, and DM646x. + * + * Copyright (C) 2011 Texas Instruments Incorporated + * Copyright (c) 2007 Deep Root Systems, LLC + * + * 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 version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __DAVINCI_H +#define __DAVINCI_H + +#include <linux/clk.h> +#include <linux/videodev2.h> +#include <linux/davinci_emac.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> + +#include <mach/asp.h> +#include <mach/keyscan.h> +#include <mach/hardware.h> + +#include <media/davinci/vpfe_capture.h> +#include <media/davinci/vpif_types.h> +#include <media/davinci/vpss.h> +#include <media/davinci/vpbe_types.h> +#include <media/davinci/vpbe_venc.h> +#include <media/davinci/vpbe.h> +#include <media/davinci/vpbe_osd.h> + +#define DAVINCI_SYSTEM_MODULE_BASE 0x01c40000 +#define SYSMOD_VIDCLKCTL 0x38 +#define SYSMOD_VPSS_CLKCTL 0x44 +#define SYSMOD_VDD3P3VPWDN 0x48 +#define SYSMOD_VSCLKDIS 0x6c +#define SYSMOD_PUPDCTL1 0x7c + +extern void __iomem *davinci_sysmod_base; +#define DAVINCI_SYSMOD_VIRT(x) (davinci_sysmod_base + (x)) +void davinci_map_sysmod(void); + +/* DM355 base addresses */ +#define DM355_ASYNC_EMIF_CONTROL_BASE 0x01e10000 +#define DM355_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 + +#define ASP1_TX_EVT_EN 1 +#define ASP1_RX_EVT_EN 2 + +/* DM365 base addresses */ +#define DM365_ASYNC_EMIF_CONTROL_BASE 0x01d10000 +#define DM365_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 +#define DM365_ASYNC_EMIF_DATA_CE1_BASE 0x04000000 + +/* DM644x base addresses */ +#define DM644X_ASYNC_EMIF_CONTROL_BASE 0x01e00000 +#define DM644X_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 +#define DM644X_ASYNC_EMIF_DATA_CE1_BASE 0x04000000 +#define DM644X_ASYNC_EMIF_DATA_CE2_BASE 0x06000000 +#define DM644X_ASYNC_EMIF_DATA_CE3_BASE 0x08000000 + +/* DM646x base addresses */ +#define DM646X_ASYNC_EMIF_CONTROL_BASE 0x20008000 +#define DM646X_ASYNC_EMIF_CS2_SPACE_BASE 0x42000000 + +/* DM355 function declarations */ +void __init dm355_init(void); +void dm355_init_spi0(unsigned chipselect_mask, + struct spi_board_info *info, unsigned len); +void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata); +void dm355_set_vpfe_config(struct vpfe_config *cfg); + +/* DM365 function declarations */ +void __init dm365_init(void); +void __init dm365_init_asp(struct snd_platform_data *pdata); +void __init dm365_init_vc(struct snd_platform_data *pdata); +void __init dm365_init_ks(struct davinci_ks_platform_data *pdata); +void __init dm365_init_rtc(void); +void dm365_init_spi0(unsigned chipselect_mask, + struct spi_board_info *info, unsigned len); +void dm365_set_vpfe_config(struct vpfe_config *cfg); + +/* DM644x function declarations */ +void __init dm644x_init(void); +void __init dm644x_init_asp(struct snd_platform_data *pdata); +int __init dm644x_init_video(struct vpfe_config *, struct vpbe_config *); + +/* DM646x function declarations */ +void __init dm646x_init(void); +void __init dm646x_init_mcasp0(struct snd_platform_data *pdata); +void __init dm646x_init_mcasp1(struct snd_platform_data *pdata); +int __init dm646x_init_edma(struct edma_rsv_info *rsv); +void dm646x_video_init(void); +void dm646x_setup_vpif(struct vpif_display_config *, + struct vpif_capture_config *); +#endif /*__DAVINCI_H */ diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index 50c0156b4262..d2f9666284a7 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -23,6 +23,7 @@ #include <mach/mmc.h> #include <mach/time.h> +#include "davinci.h" #include "clock.h" #define DAVINCI_I2C_BASE 0x01C21000 @@ -33,8 +34,19 @@ #define DM365_MMCSD0_BASE 0x01D11000 #define DM365_MMCSD1_BASE 0x01D00000 -/* System control register offsets */ -#define DM64XX_VDD3P3V_PWDN 0x48 +void __iomem *davinci_sysmod_base; + +void davinci_map_sysmod(void) +{ + davinci_sysmod_base = ioremap_nocache(DAVINCI_SYSTEM_MODULE_BASE, + 0x800); + /* + * Throw a bug since a lot of board initialization code depends + * on system module availability. ioremap() failing this early + * need careful looking into anyway. + */ + BUG_ON(!davinci_sysmod_base); +} static struct resource i2c_resources[] = { { @@ -212,12 +224,12 @@ void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config) davinci_cfg_reg(DM355_SD1_DATA2); davinci_cfg_reg(DM355_SD1_DATA3); } else if (cpu_is_davinci_dm365()) { - void __iomem *pupdctl1 = - IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE + 0x7c); - /* Configure pull down control */ - __raw_writel((__raw_readl(pupdctl1) & ~0xfc0), - pupdctl1); + unsigned v; + + v = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_PUPDCTL1)); + __raw_writel(v & ~0xfc0, + DAVINCI_SYSMOD_VIRT(SYSMOD_PUPDCTL1)); mmcsd1_resources[0].start = DM365_MMCSD1_BASE; mmcsd1_resources[0].end = DM365_MMCSD1_BASE + @@ -246,11 +258,9 @@ void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config) mmcsd0_resources[2].start = IRQ_DM365_SDIOINT0; } else if (cpu_is_davinci_dm644x()) { /* REVISIT: should this be in board-init code? */ - void __iomem *base = - IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE); - /* Power-on 3.3V IO cells */ - __raw_writel(0, base + DM64XX_VDD3P3V_PWDN); + __raw_writel(0, + DAVINCI_SYSMOD_VIRT(SYSMOD_VDD3P3VPWDN)); /*Set up the pull regiter for MMC */ davinci_cfg_reg(DM644X_MSTK); } diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 19667cfc5de0..fd3d09aa6cde 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -18,7 +18,6 @@ #include <asm/mach/map.h> -#include <mach/dm355.h> #include <mach/cputype.h> #include <mach/edma.h> #include <mach/psc.h> @@ -31,6 +30,7 @@ #include <mach/spi.h> #include <mach/gpio-davinci.h> +#include "davinci.h" #include "clock.h" #include "mux.h" @@ -871,6 +871,7 @@ void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata) void __init dm355_init(void) { davinci_common_init(&davinci_soc_info_dm355); + davinci_map_sysmod(); } static int __init dm355_init_devices(void) diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index f15b435cc655..1a2e953082b3 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -21,7 +21,6 @@ #include <asm/mach/map.h> -#include <mach/dm365.h> #include <mach/cputype.h> #include <mach/edma.h> #include <mach/psc.h> @@ -35,11 +34,28 @@ #include <mach/spi.h> #include <mach/gpio-davinci.h> +#include "davinci.h" #include "clock.h" #include "mux.h" #define DM365_REF_FREQ 24000000 /* 24 MHz on the DM365 EVM */ +/* Base of key scan register bank */ +#define DM365_KEYSCAN_BASE 0x01c69400 + +#define DM365_RTC_BASE 0x01c69000 + +#define DAVINCI_DM365_VC_BASE 0x01d0c000 +#define DAVINCI_DMA_VC_TX 2 +#define DAVINCI_DMA_VC_RX 3 + +#define DM365_EMAC_BASE 0x01d07000 +#define DM365_EMAC_MDIO_BASE (DM365_EMAC_BASE + 0x4000) +#define DM365_EMAC_CNTRL_OFFSET 0x0000 +#define DM365_EMAC_CNTRL_MOD_OFFSET 0x3000 +#define DM365_EMAC_CNTRL_RAM_OFFSET 0x1000 +#define DM365_EMAC_CNTRL_RAM_SIZE 0x2000 + static struct pll_data pll1_data = { .num = 1, .phys_base = DAVINCI_PLL1_BASE, @@ -1122,6 +1138,7 @@ void __init dm365_init_rtc(void) void __init dm365_init(void) { davinci_common_init(&davinci_soc_info_dm365); + davinci_map_sysmod(); } static struct resource dm365_vpss_resources[] = { diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 43a48ee1917b..c8b866657fcb 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -15,7 +15,6 @@ #include <asm/mach/map.h> -#include <mach/dm644x.h> #include <mach/cputype.h> #include <mach/edma.h> #include <mach/irqs.h> @@ -27,6 +26,7 @@ #include <mach/asp.h> #include <mach/gpio-davinci.h> +#include "davinci.h" #include "clock.h" #include "mux.h" @@ -35,6 +35,13 @@ */ #define DM644X_REF_FREQ 27000000 +#define DM644X_EMAC_BASE 0x01c80000 +#define DM644X_EMAC_MDIO_BASE (DM644X_EMAC_BASE + 0x4000) +#define DM644X_EMAC_CNTRL_OFFSET 0x0000 +#define DM644X_EMAC_CNTRL_MOD_OFFSET 0x1000 +#define DM644X_EMAC_CNTRL_RAM_OFFSET 0x2000 +#define DM644X_EMAC_CNTRL_RAM_SIZE 0x2000 + static struct pll_data pll1_data = { .num = 1, .phys_base = DAVINCI_PLL1_BASE, @@ -587,13 +594,15 @@ static struct platform_device dm644x_asp_device = { .resource = dm644x_asp_resources, }; +#define DM644X_VPSS_BASE 0x01c73400 + static struct resource dm644x_vpss_resources[] = { { /* VPSS Base address */ .name = "vpss", - .start = 0x01c73400, - .end = 0x01c73400 + 0xff, - .flags = IORESOURCE_MEM, + .start = DM644X_VPSS_BASE, + .end = DM644X_VPSS_BASE + 0xff, + .flags = IORESOURCE_MEM, }, }; @@ -605,7 +614,7 @@ static struct platform_device dm644x_vpss_device = { .resource = dm644x_vpss_resources, }; -static struct resource vpfe_resources[] = { +static struct resource dm644x_vpfe_resources[] = { { .start = IRQ_VDINT0, .end = IRQ_VDINT0, @@ -618,7 +627,7 @@ static struct resource vpfe_resources[] = { }, }; -static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32); +static u64 dm644x_video_dma_mask = DMA_BIT_MASK(32); static struct resource dm644x_ccdc_resource[] = { /* CCDC Base address */ { @@ -634,27 +643,149 @@ static struct platform_device dm644x_ccdc_dev = { .num_resources = ARRAY_SIZE(dm644x_ccdc_resource), .resource = dm644x_ccdc_resource, .dev = { - .dma_mask = &vpfe_capture_dma_mask, + .dma_mask = &dm644x_video_dma_mask, .coherent_dma_mask = DMA_BIT_MASK(32), }, }; -static struct platform_device vpfe_capture_dev = { +static struct platform_device dm644x_vpfe_dev = { .name = CAPTURE_DRV_NAME, .id = -1, - .num_resources = ARRAY_SIZE(vpfe_resources), - .resource = vpfe_resources, + .num_resources = ARRAY_SIZE(dm644x_vpfe_resources), + .resource = dm644x_vpfe_resources, .dev = { - .dma_mask = &vpfe_capture_dma_mask, + .dma_mask = &dm644x_video_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +#define DM644X_OSD_BASE 0x01c72600 + +static struct resource dm644x_osd_resources[] = { + { + .start = DM644X_OSD_BASE, + .end = DM644X_OSD_BASE + 0x1ff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct osd_platform_data dm644x_osd_data = { + .vpbe_type = VPBE_VERSION_1, +}; + +static struct platform_device dm644x_osd_dev = { + .name = VPBE_OSD_SUBDEV_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(dm644x_osd_resources), + .resource = dm644x_osd_resources, + .dev = { + .dma_mask = &dm644x_video_dma_mask, .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &dm644x_osd_data, }, }; -void dm644x_set_vpfe_config(struct vpfe_config *cfg) +#define DM644X_VENC_BASE 0x01c72400 + +static struct resource dm644x_venc_resources[] = { + { + .start = DM644X_VENC_BASE, + .end = DM644X_VENC_BASE + 0x17f, + .flags = IORESOURCE_MEM, + }, +}; + +#define DM644X_VPSS_MUXSEL_PLL2_MODE BIT(0) +#define DM644X_VPSS_MUXSEL_VPBECLK_MODE BIT(1) +#define DM644X_VPSS_VENCLKEN BIT(3) +#define DM644X_VPSS_DACCLKEN BIT(4) + +static int dm644x_venc_setup_clock(enum vpbe_enc_timings_type type, + unsigned int mode) { - vpfe_capture_dev.dev.platform_data = cfg; + int ret = 0; + u32 v = DM644X_VPSS_VENCLKEN; + + switch (type) { + case VPBE_ENC_STD: + v |= DM644X_VPSS_DACCLKEN; + writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL)); + break; + case VPBE_ENC_DV_PRESET: + switch (mode) { + case V4L2_DV_480P59_94: + case V4L2_DV_576P50: + v |= DM644X_VPSS_MUXSEL_PLL2_MODE | + DM644X_VPSS_DACCLKEN; + writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL)); + break; + case V4L2_DV_720P60: + case V4L2_DV_1080I60: + case V4L2_DV_1080P30: + /* + * For HD, use external clock source since + * HD requires higher clock rate + */ + v |= DM644X_VPSS_MUXSEL_VPBECLK_MODE; + writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL)); + break; + default: + ret = -EINVAL; + break; + } + break; + default: + ret = -EINVAL; + } + + return ret; } +static struct resource dm644x_v4l2_disp_resources[] = { + { + .start = IRQ_VENCINT, + .end = IRQ_VENCINT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device dm644x_vpbe_display = { + .name = "vpbe-v4l2", + .id = -1, + .num_resources = ARRAY_SIZE(dm644x_v4l2_disp_resources), + .resource = dm644x_v4l2_disp_resources, + .dev = { + .dma_mask = &dm644x_video_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +static struct venc_platform_data dm644x_venc_pdata = { + .venc_type = VPBE_VERSION_1, + .setup_clock = dm644x_venc_setup_clock, +}; + +static struct platform_device dm644x_venc_dev = { + .name = VPBE_VENC_SUBDEV_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(dm644x_venc_resources), + .resource = dm644x_venc_resources, + .dev = { + .dma_mask = &dm644x_video_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &dm644x_venc_pdata, + }, +}; + +static struct platform_device dm644x_vpbe_dev = { + .name = "vpbe_controller", + .id = -1, + .dev = { + .dma_mask = &dm644x_video_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + /*----------------------------------------------------------------------*/ static struct map_desc dm644x_io_desc[] = { @@ -779,6 +910,35 @@ void __init dm644x_init_asp(struct snd_platform_data *pdata) void __init dm644x_init(void) { davinci_common_init(&davinci_soc_info_dm644x); + davinci_map_sysmod(); +} + +int __init dm644x_init_video(struct vpfe_config *vpfe_cfg, + struct vpbe_config *vpbe_cfg) +{ + if (vpfe_cfg || vpbe_cfg) + platform_device_register(&dm644x_vpss_device); + + if (vpfe_cfg) { + dm644x_vpfe_dev.dev.platform_data = vpfe_cfg; + platform_device_register(&dm644x_ccdc_dev); + platform_device_register(&dm644x_vpfe_dev); + /* Add ccdc clock aliases */ + clk_add_alias("master", dm644x_ccdc_dev.name, + "vpss_master", NULL); + clk_add_alias("slave", dm644x_ccdc_dev.name, + "vpss_slave", NULL); + } + + if (vpbe_cfg) { + dm644x_vpbe_dev.dev.platform_data = vpbe_cfg; + platform_device_register(&dm644x_osd_dev); + platform_device_register(&dm644x_venc_dev); + platform_device_register(&dm644x_vpbe_dev); + platform_device_register(&dm644x_vpbe_display); + } + + return 0; } static int __init dm644x_init_devices(void) @@ -786,9 +946,6 @@ static int __init dm644x_init_devices(void) if (!cpu_is_davinci_dm644x()) return 0; - /* Add ccdc clock aliases */ - clk_add_alias("master", dm644x_ccdc_dev.name, "vpss_master", NULL); - clk_add_alias("slave", dm644x_ccdc_dev.name, "vpss_slave", NULL); platform_device_register(&dm644x_edma_device); platform_device_register(&dm644x_mdio_device); @@ -796,10 +953,6 @@ static int __init dm644x_init_devices(void) clk_add_alias(NULL, dev_name(&dm644x_mdio_device.dev), NULL, &dm644x_emac_device.dev); - platform_device_register(&dm644x_vpss_device); - platform_device_register(&dm644x_ccdc_dev); - platform_device_register(&vpfe_capture_dev); - return 0; } postcore_initcall(dm644x_init_devices); diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 00f774394b16..9eb87c1d1edd 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -16,7 +16,6 @@ #include <asm/mach/map.h> -#include <mach/dm646x.h> #include <mach/cputype.h> #include <mach/edma.h> #include <mach/irqs.h> @@ -28,12 +27,11 @@ #include <mach/asp.h> #include <mach/gpio-davinci.h> +#include "davinci.h" #include "clock.h" #include "mux.h" #define DAVINCI_VPIF_BASE (0x01C12000) -#define VDD3P3V_PWDN_OFFSET (0x48) -#define VSCLKDIS_OFFSET (0x6C) #define VDD3P3V_VID_MASK (BIT_MASK(3) | BIT_MASK(2) | BIT_MASK(1) |\ BIT_MASK(0)) @@ -46,6 +44,13 @@ #define DM646X_REF_FREQ 27000000 #define DM646X_AUX_FREQ 24000000 +#define DM646X_EMAC_BASE 0x01c80000 +#define DM646X_EMAC_MDIO_BASE (DM646X_EMAC_BASE + 0x4000) +#define DM646X_EMAC_CNTRL_OFFSET 0x0000 +#define DM646X_EMAC_CNTRL_MOD_OFFSET 0x1000 +#define DM646X_EMAC_CNTRL_RAM_OFFSET 0x2000 +#define DM646X_EMAC_CNTRL_RAM_SIZE 0x2000 + static struct pll_data pll1_data = { .num = 1, .phys_base = DAVINCI_PLL1_BASE, @@ -873,15 +878,14 @@ void dm646x_setup_vpif(struct vpif_display_config *display_config, struct vpif_capture_config *capture_config) { unsigned int value; - void __iomem *base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE); - value = __raw_readl(base + VSCLKDIS_OFFSET); + value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS)); value &= ~VSCLKDIS_MASK; - __raw_writel(value, base + VSCLKDIS_OFFSET); + __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VSCLKDIS)); - value = __raw_readl(base + VDD3P3V_PWDN_OFFSET); + value = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_VDD3P3VPWDN)); value &= ~VDD3P3V_VID_MASK; - __raw_writel(value, base + VDD3P3V_PWDN_OFFSET); + __raw_writel(value, DAVINCI_SYSMOD_VIRT(SYSMOD_VDD3P3VPWDN)); davinci_cfg_reg(DM646X_STSOMUX_DISABLE); davinci_cfg_reg(DM646X_STSIMUX_DISABLE); @@ -905,6 +909,7 @@ int __init dm646x_init_edma(struct edma_rsv_info *rsv) void __init dm646x_init(void) { davinci_common_init(&davinci_soc_info_dm646x); + davinci_map_sysmod(); } static int __init dm646x_init_devices(void) diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c index da90103a313d..fd33919c95d4 100644 --- a/arch/arm/mach-davinci/dma.c +++ b/arch/arm/mach-davinci/dma.c @@ -1508,12 +1508,8 @@ static int __init edma_probe(struct platform_device *pdev) goto fail; } - /* Everything lives on transfer controller 1 until otherwise - * specified. This way, long transfers on the low priority queue - * started by the codec engine will not cause audio defects. - */ for (i = 0; i < edma_cc[j]->num_channels; i++) - map_dmach_queue(j, i, EVENTQ_1); + map_dmach_queue(j, i, info[j]->default_queue); queue_tc_mapping = info[j]->queue_tc_mapping; queue_priority_mapping = info[j]->queue_priority_mapping; diff --git a/arch/arm/mach-davinci/include/mach/dm355.h b/arch/arm/mach-davinci/include/mach/dm355.h deleted file mode 100644 index 36dff4a0ce3f..000000000000 --- a/arch/arm/mach-davinci/include/mach/dm355.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Chip specific defines for DM355 SoC - * - * Author: Kevin Hilman, Deep Root Systems, LLC - * - * 2007 (c) Deep Root Systems, LLC. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - */ -#ifndef __ASM_ARCH_DM355_H -#define __ASM_ARCH_DM355_H - -#include <mach/hardware.h> -#include <mach/asp.h> -#include <media/davinci/vpfe_capture.h> - -#define DM355_ASYNC_EMIF_CONTROL_BASE 0x01E10000 -#define DM355_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 - -#define ASP1_TX_EVT_EN 1 -#define ASP1_RX_EVT_EN 2 - -struct spi_board_info; - -void __init dm355_init(void); -void dm355_init_spi0(unsigned chipselect_mask, - struct spi_board_info *info, unsigned len); -void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata); -void dm355_set_vpfe_config(struct vpfe_config *cfg); - -#endif /* __ASM_ARCH_DM355_H */ diff --git a/arch/arm/mach-davinci/include/mach/dm365.h b/arch/arm/mach-davinci/include/mach/dm365.h index 2563bf4e93a1..b9bf3d6a4423 100644 --- a/arch/arm/mach-davinci/include/mach/dm365.h +++ b/arch/arm/mach-davinci/include/mach/dm365.h @@ -1,52 +1 @@ -/* - * Copyright (C) 2009 Texas Instruments Incorporated - * - * 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 version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef __ASM_ARCH_DM365_H -#define __ASM_ARCH_DM665_H - -#include <linux/platform_device.h> -#include <linux/davinci_emac.h> -#include <mach/hardware.h> -#include <mach/asp.h> -#include <mach/keyscan.h> -#include <media/davinci/vpfe_capture.h> - -#define DM365_EMAC_BASE (0x01D07000) -#define DM365_EMAC_MDIO_BASE (DM365_EMAC_BASE + 0x4000) -#define DM365_EMAC_CNTRL_OFFSET (0x0000) -#define DM365_EMAC_CNTRL_MOD_OFFSET (0x3000) -#define DM365_EMAC_CNTRL_RAM_OFFSET (0x1000) -#define DM365_EMAC_CNTRL_RAM_SIZE (0x2000) - -/* Base of key scan register bank */ -#define DM365_KEYSCAN_BASE (0x01C69400) - -#define DM365_RTC_BASE (0x01C69000) - -#define DAVINCI_DM365_VC_BASE (0x01D0C000) -#define DAVINCI_DMA_VC_TX 2 -#define DAVINCI_DMA_VC_RX 3 - -#define DM365_ASYNC_EMIF_CONTROL_BASE 0x01D10000 -#define DM365_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 -#define DM365_ASYNC_EMIF_DATA_CE1_BASE 0x04000000 - -void __init dm365_init(void); -void __init dm365_init_asp(struct snd_platform_data *pdata); -void __init dm365_init_vc(struct snd_platform_data *pdata); -void __init dm365_init_ks(struct davinci_ks_platform_data *pdata); -void __init dm365_init_rtc(void); -void dm365_init_spi0(unsigned chipselect_mask, - struct spi_board_info *info, unsigned len); - -void dm365_set_vpfe_config(struct vpfe_config *cfg); -#endif /* __ASM_ARCH_DM365_H */ +/* empty, remove once unused */ diff --git a/arch/arm/mach-davinci/include/mach/dm644x.h b/arch/arm/mach-davinci/include/mach/dm644x.h deleted file mode 100644 index 5a1b26d4e68b..000000000000 --- a/arch/arm/mach-davinci/include/mach/dm644x.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file contains the processor specific definitions - * of the TI DM644x. - * - * Copyright (C) 2008 Texas Instruments. - * - * 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_DM644X_H -#define __ASM_ARCH_DM644X_H - -#include <linux/davinci_emac.h> -#include <mach/hardware.h> -#include <mach/asp.h> -#include <media/davinci/vpfe_capture.h> - -#define DM644X_EMAC_BASE (0x01C80000) -#define DM644X_EMAC_MDIO_BASE (DM644X_EMAC_BASE + 0x4000) -#define DM644X_EMAC_CNTRL_OFFSET (0x0000) -#define DM644X_EMAC_CNTRL_MOD_OFFSET (0x1000) -#define DM644X_EMAC_CNTRL_RAM_OFFSET (0x2000) -#define DM644X_EMAC_CNTRL_RAM_SIZE (0x2000) - -#define DM644X_ASYNC_EMIF_CONTROL_BASE 0x01E00000 -#define DM644X_ASYNC_EMIF_DATA_CE0_BASE 0x02000000 -#define DM644X_ASYNC_EMIF_DATA_CE1_BASE 0x04000000 -#define DM644X_ASYNC_EMIF_DATA_CE2_BASE 0x06000000 -#define DM644X_ASYNC_EMIF_DATA_CE3_BASE 0x08000000 - -void __init dm644x_init(void); -void __init dm644x_init_asp(struct snd_platform_data *pdata); -void dm644x_set_vpfe_config(struct vpfe_config *cfg); - -#endif /* __ASM_ARCH_DM644X_H */ diff --git a/arch/arm/mach-davinci/include/mach/dm646x.h b/arch/arm/mach-davinci/include/mach/dm646x.h index a8ee6c9f0bb0..b9bf3d6a4423 100644 --- a/arch/arm/mach-davinci/include/mach/dm646x.h +++ b/arch/arm/mach-davinci/include/mach/dm646x.h @@ -1,41 +1 @@ -/* - * Chip specific defines for DM646x SoC - * - * Author: Kevin Hilman, Deep Root Systems, LLC - * - * 2007 (c) Deep Root Systems, LLC. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - */ -#ifndef __ASM_ARCH_DM646X_H -#define __ASM_ARCH_DM646X_H - -#include <mach/hardware.h> -#include <mach/asp.h> -#include <linux/i2c.h> -#include <linux/videodev2.h> -#include <linux/davinci_emac.h> -#include <media/davinci/vpif_types.h> - -#define DM646X_EMAC_BASE (0x01C80000) -#define DM646X_EMAC_MDIO_BASE (DM646X_EMAC_BASE + 0x4000) -#define DM646X_EMAC_CNTRL_OFFSET (0x0000) -#define DM646X_EMAC_CNTRL_MOD_OFFSET (0x1000) -#define DM646X_EMAC_CNTRL_RAM_OFFSET (0x2000) -#define DM646X_EMAC_CNTRL_RAM_SIZE (0x2000) - -#define DM646X_ASYNC_EMIF_CONTROL_BASE 0x20008000 -#define DM646X_ASYNC_EMIF_CS2_SPACE_BASE 0x42000000 - -void __init dm646x_init(void); -void __init dm646x_init_mcasp0(struct snd_platform_data *pdata); -void __init dm646x_init_mcasp1(struct snd_platform_data *pdata); -int __init dm646x_init_edma(struct edma_rsv_info *rsv); - -void dm646x_video_init(void); - -void dm646x_setup_vpif(struct vpif_display_config *, - struct vpif_capture_config *); - -#endif /* __ASM_ARCH_DM646X_H */ +/* empty, remove once unused */ diff --git a/arch/arm/mach-davinci/include/mach/edma.h b/arch/arm/mach-davinci/include/mach/edma.h index 20c77f29bf0f..7e84c906ceff 100644 --- a/arch/arm/mach-davinci/include/mach/edma.h +++ b/arch/arm/mach-davinci/include/mach/edma.h @@ -250,6 +250,11 @@ struct edma_soc_info { unsigned n_slot; unsigned n_tc; unsigned n_cc; + /* + * Default queue is expected to be a low-priority queue. + * This way, long transfers on the default queue started + * by the codec engine will not cause audio defects. + */ enum dma_event_q default_queue; /* Resource reservation for other cores */ diff --git a/arch/arm/mach-davinci/include/mach/entry-macro.S b/arch/arm/mach-davinci/include/mach/entry-macro.S index e14c0dc0e12c..768b3c060214 100644 --- a/arch/arm/mach-davinci/include/mach/entry-macro.S +++ b/arch/arm/mach-davinci/include/mach/entry-macro.S @@ -8,20 +8,13 @@ * is licensed "as is" without any warranty of any kind, whether express * or implied. */ -#include <mach/io.h> #include <mach/irqs.h> - .macro disable_fiq - .endm - .macro get_irqnr_preamble, base, tmp ldr \base, =davinci_intc_base ldr \base, [\base] .endm - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp #if defined(CONFIG_AINTC) && defined(CONFIG_CP_INTC) ldr \tmp, =davinci_intc_type diff --git a/arch/arm/mach-davinci/include/mach/hardware.h b/arch/arm/mach-davinci/include/mach/hardware.h index 414e0b93e741..2184691ebc2f 100644 --- a/arch/arm/mach-davinci/include/mach/hardware.h +++ b/arch/arm/mach-davinci/include/mach/hardware.h @@ -19,8 +19,6 @@ * and the chip/board init code should then explicitly include * <chipname>.h */ -#define DAVINCI_SYSTEM_MODULE_BASE 0x01C40000 - /* * I/O mapping */ @@ -32,10 +30,4 @@ #define __IO_ADDRESS(x) ((x) + IO_OFFSET) #define IO_ADDRESS(pa) IOMEM(__IO_ADDRESS(pa)) -#ifdef __ASSEMBLER__ -#define IOMEM(x) x -#else -#define IOMEM(x) ((void __force __iomem *)(x)) -#endif - #endif /* __ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/mach-davinci/include/mach/io.h b/arch/arm/mach-davinci/include/mach/io.h deleted file mode 100644 index b2267d1e1a71..000000000000 --- a/arch/arm/mach-davinci/include/mach/io.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * DaVinci IO address definitions - * - * Copied from include/asm/arm/arch-omap/io.h - * - * 2007 (c) MontaVista Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - */ -#ifndef __ASM_ARCH_IO_H -#define __ASM_ARCH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -/* - * We don't actually have real ISA nor PCI buses, but there is so many - * drivers out there that might just work if we fake them... - */ -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) -#define __mem_isa(a) (a) - -#endif /* __ASM_ARCH_IO_H */ diff --git a/arch/arm/mach-davinci/include/mach/system.h b/arch/arm/mach-davinci/include/mach/system.h deleted file mode 100644 index fcb7a015aba5..000000000000 --- a/arch/arm/mach-davinci/include/mach/system.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * DaVinci system defines - * - * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> - * - * 2007 (c) MontaVista Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - */ -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -#include <mach/common.h> - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif /* __ASM_ARCH_SYSTEM_H */ diff --git a/arch/arm/mach-davinci/include/mach/uncompress.h b/arch/arm/mach-davinci/include/mach/uncompress.h index 9dc7cf9664fe..da2fb2c2155a 100644 --- a/arch/arm/mach-davinci/include/mach/uncompress.h +++ b/arch/arm/mach-davinci/include/mach/uncompress.h @@ -25,6 +25,8 @@ #include <mach/serial.h> +#define IOMEM(x) ((void __force __iomem *)(x)) + u32 *uart; /* PORT_16C550A, in polled non-fifo mode */ diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c index e1969ce904dc..75da315b6587 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c @@ -19,11 +19,14 @@ #include <linux/err.h> #include <linux/platform_device.h> -#include <mach/hardware.h> +#include <asm/sched_clock.h> #include <asm/mach/irq.h> #include <asm/mach/time.h> + #include <mach/cputype.h> +#include <mach/hardware.h> #include <mach/time.h> + #include "clock.h" static struct clock_event_device clockevent_davinci; @@ -272,19 +275,9 @@ static cycle_t read_cycles(struct clocksource *cs) return (cycles_t)timer32_read(t); } -/* - * Kernel assumes that sched_clock can be called early but may not have - * things ready yet. - */ -static cycle_t read_dummy(struct clocksource *cs) -{ - return 0; -} - - static struct clocksource clocksource_davinci = { .rating = 300, - .read = read_dummy, + .read = read_cycles, .mask = CLOCKSOURCE_MASK(32), .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; @@ -292,12 +285,9 @@ static struct clocksource clocksource_davinci = { /* * Overwrite weak default sched_clock with something more precise */ -unsigned long long notrace sched_clock(void) +static u32 notrace davinci_read_sched_clock(void) { - const cycle_t cyc = clocksource_davinci.read(&clocksource_davinci); - - return clocksource_cyc2ns(cyc, clocksource_davinci.mult, - clocksource_davinci.shift); + return timer32_read(&timers[TID_CLOCKSOURCE]); } /* @@ -397,12 +387,14 @@ static void __init davinci_timer_init(void) davinci_clock_tick_rate = clk_get_rate(timer_clk); /* setup clocksource */ - clocksource_davinci.read = read_cycles; clocksource_davinci.name = id_to_name[clocksource_id]; if (clocksource_register_hz(&clocksource_davinci, davinci_clock_tick_rate)) printk(err, clocksource_davinci.name); + setup_sched_clock(davinci_read_sched_clock, 32, + davinci_clock_tick_rate); + /* setup clockevent */ clockevent_davinci.name = id_to_name[timers[TID_CLOCKEVENT].id]; clockevent_davinci.mult = div_sc(davinci_clock_tick_rate, NSEC_PER_SEC, diff --git a/arch/arm/mach-dove/addr-map.c b/arch/arm/mach-dove/addr-map.c index 98b8c83b09ab..2a06c0163418 100644 --- a/arch/arm/mach-dove/addr-map.c +++ b/arch/arm/mach-dove/addr-map.c @@ -14,6 +14,7 @@ #include <linux/io.h> #include <asm/mach/arch.h> #include <asm/setup.h> +#include <mach/dove.h> #include <plat/addr-map.h> #include "common.h" diff --git a/arch/arm/mach-dove/include/mach/entry-macro.S b/arch/arm/mach-dove/include/mach/entry-macro.S index e84c78c2a8b7..72d622baaad3 100644 --- a/arch/arm/mach-dove/include/mach/entry-macro.S +++ b/arch/arm/mach-dove/include/mach/entry-macro.S @@ -10,12 +10,6 @@ #include <mach/bridge-regs.h> - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_preamble, base, tmp ldr \base, =IRQ_VIRT_BASE .endm diff --git a/arch/arm/mach-dove/include/mach/io.h b/arch/arm/mach-dove/include/mach/io.h index eb4936ff90ad..29c8b85355a5 100644 --- a/arch/arm/mach-dove/include/mach/io.h +++ b/arch/arm/mach-dove/include/mach/io.h @@ -15,6 +15,5 @@ #define __io(a) ((void __iomem *)(((a) - DOVE_PCIE0_IO_BUS_BASE) + \ DOVE_PCIE0_IO_VIRT_BASE)) -#define __mem_pci(a) (a) #endif diff --git a/arch/arm/mach-dove/include/mach/system.h b/arch/arm/mach-dove/include/mach/system.h deleted file mode 100644 index 3027954f6162..000000000000 --- a/arch/arm/mach-dove/include/mach/system.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * arch/arm/mach-dove/include/mach/system.h - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-dove/pcie.c b/arch/arm/mach-dove/pcie.c index 52e96d397ba8..48a032005ea3 100644 --- a/arch/arm/mach-dove/pcie.c +++ b/arch/arm/mach-dove/pcie.c @@ -69,7 +69,7 @@ static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys) pp->res[0].flags = IORESOURCE_IO; if (request_resource(&ioport_resource, &pp->res[0])) panic("Request PCIe IO resource failed\n"); - pci_add_resource(&sys->resources, &pp->res[0]); + pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset); /* * IORESOURCE_MEM @@ -88,7 +88,7 @@ static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys) pp->res[1].flags = IORESOURCE_MEM; if (request_resource(&iomem_resource, &pp->res[1])) panic("Request PCIe Memory resource failed\n"); - pci_add_resource(&sys->resources, &pp->res[1]); + pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset); return 1; } diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c index 294aad07f7a0..6f8068692edf 100644 --- a/arch/arm/mach-ebsa110/core.c +++ b/arch/arm/mach-ebsa110/core.c @@ -22,7 +22,7 @@ #include <asm/mach-types.h> #include <asm/pgtable.h> #include <asm/page.h> -#include <asm/system.h> +#include <asm/system_misc.h> #include <asm/mach/arch.h> #include <asm/mach/irq.h> @@ -30,10 +30,7 @@ #include <asm/mach/time.h> -#define IRQ_MASK 0xfe000000 /* read */ -#define IRQ_MSET 0xfe000000 /* write */ -#define IRQ_STAT 0xff000000 /* read */ -#define IRQ_MCLR 0xff000000 /* write */ +#include "core.h" static void ebsa110_mask_irq(struct irq_data *d) { @@ -79,22 +76,22 @@ static struct map_desc ebsa110_io_desc[] __initdata = { { /* IRQ_STAT/IRQ_MCLR */ .virtual = IRQ_STAT, .pfn = __phys_to_pfn(TRICK4_PHYS), - .length = PGDIR_SIZE, + .length = TRICK4_SIZE, .type = MT_DEVICE }, { /* IRQ_MASK/IRQ_MSET */ .virtual = IRQ_MASK, .pfn = __phys_to_pfn(TRICK3_PHYS), - .length = PGDIR_SIZE, + .length = TRICK3_SIZE, .type = MT_DEVICE }, { /* SOFT_BASE */ .virtual = SOFT_BASE, .pfn = __phys_to_pfn(TRICK1_PHYS), - .length = PGDIR_SIZE, + .length = TRICK1_SIZE, .type = MT_DEVICE }, { /* PIT_BASE */ .virtual = PIT_BASE, .pfn = __phys_to_pfn(TRICK0_PHYS), - .length = PGDIR_SIZE, + .length = TRICK0_SIZE, .type = MT_DEVICE }, @@ -119,6 +116,20 @@ static void __init ebsa110_map_io(void) iotable_init(ebsa110_io_desc, ARRAY_SIZE(ebsa110_io_desc)); } +static void __iomem *ebsa110_ioremap_caller(unsigned long cookie, size_t size, + unsigned int flags, void *caller) +{ + return (void __iomem *)cookie; +} + +static void ebsa110_iounmap(volatile void __iomem *io_addr) +{} + +static void __init ebsa110_init_early(void) +{ + arch_ioremap_caller = ebsa110_ioremap_caller; + arch_iounmap = ebsa110_iounmap; +} #define PIT_CTRL (PIT_BASE + 0x0d) #define PIT_T2 (PIT_BASE + 0x09) @@ -271,8 +282,33 @@ static struct platform_device *ebsa110_devices[] = { &am79c961_device, }; +/* + * EBSA110 idling methodology: + * + * We can not execute the "wait for interrupt" instruction since that + * will stop our MCLK signal (which provides the clock for the glue + * logic, and therefore the timer interrupt). + * + * Instead, we spin, polling the IRQ_STAT register for the occurrence + * of any interrupt with core clock down to the memory clock. + */ +static void ebsa110_idle(void) +{ + const char *irq_stat = (char *)0xff000000; + + /* disable clock switching */ + asm volatile ("mcr p15, 0, ip, c15, c2, 2" : : : "cc"); + + /* wait for an interrupt to occur */ + while (!*irq_stat); + + /* enable clock switching */ + asm volatile ("mcr p15, 0, ip, c15, c1, 2" : : : "cc"); +} + static int __init ebsa110_init(void) { + arm_pm_idle = ebsa110_idle; return platform_add_devices(ebsa110_devices, ARRAY_SIZE(ebsa110_devices)); } @@ -290,6 +326,7 @@ MACHINE_START(EBSA110, "EBSA110") .reserve_lp2 = 1, .restart_mode = 's', .map_io = ebsa110_map_io, + .init_early = ebsa110_init_early, .init_irq = ebsa110_init_irq, .timer = &ebsa110_timer, .restart = ebsa110_restart, diff --git a/arch/arm/mach-ebsa110/core.h b/arch/arm/mach-ebsa110/core.h new file mode 100644 index 000000000000..c93c9e43012d --- /dev/null +++ b/arch/arm/mach-ebsa110/core.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 1996-2000 Russell King. + * + * 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. + * + * This file contains the core hardware definitions of the EBSA-110. + */ +#ifndef CORE_H +#define CORE_H + +/* Physical addresses/sizes */ +#define ISAMEM_PHYS 0xe0000000 +#define ISAMEM_SIZE 0x10000000 + +#define ISAIO_PHYS 0xf0000000 +#define ISAIO_SIZE PGDIR_SIZE + +#define TRICK0_PHYS 0xf2000000 +#define TRICK0_SIZE PGDIR_SIZE +#define TRICK1_PHYS 0xf2400000 +#define TRICK1_SIZE PGDIR_SIZE +#define TRICK2_PHYS 0xf2800000 +#define TRICK3_PHYS 0xf2c00000 +#define TRICK3_SIZE PGDIR_SIZE +#define TRICK4_PHYS 0xf3000000 +#define TRICK4_SIZE PGDIR_SIZE +#define TRICK5_PHYS 0xf3400000 +#define TRICK6_PHYS 0xf3800000 +#define TRICK7_PHYS 0xf3c00000 + +/* Virtual addresses */ +#define PIT_BASE 0xfc000000 /* trick 0 */ +#define SOFT_BASE 0xfd000000 /* trick 1 */ +#define IRQ_MASK 0xfe000000 /* trick 3 - read */ +#define IRQ_MSET 0xfe000000 /* trick 3 - write */ +#define IRQ_STAT 0xff000000 /* trick 4 - read */ +#define IRQ_MCLR 0xff000000 /* trick 4 - write */ + +#endif diff --git a/arch/arm/mach-ebsa110/include/mach/entry-macro.S b/arch/arm/mach-ebsa110/include/mach/entry-macro.S index cc3e5992f6b3..14b110de78a9 100644 --- a/arch/arm/mach-ebsa110/include/mach/entry-macro.S +++ b/arch/arm/mach-ebsa110/include/mach/entry-macro.S @@ -12,16 +12,10 @@ #define IRQ_STAT 0xff000000 /* read */ - .macro disable_fiq - .endm - .macro get_irqnr_preamble, base, tmp mov \base, #IRQ_STAT .endm - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_and_base, irqnr, stat, base, tmp ldrb \stat, [\base] @ get interrupts mov \irqnr, #0 diff --git a/arch/arm/mach-ebsa110/include/mach/hardware.h b/arch/arm/mach-ebsa110/include/mach/hardware.h index 4b2fb7743909..f4e5407bd004 100644 --- a/arch/arm/mach-ebsa110/include/mach/hardware.h +++ b/arch/arm/mach-ebsa110/include/mach/hardware.h @@ -12,48 +12,9 @@ #ifndef __ASM_ARCH_HARDWARE_H #define __ASM_ARCH_HARDWARE_H -/* - * The EBSA110 has a weird "ISA IO" region: - * - * Region 0 (addr = 0xf0000000 + io << 2) - * -------------------------------------------------------- - * Physical region IO region - * f0000fe0 - f0000ffc 3f8 - 3ff ttyS0 - * f0000e60 - f0000e64 398 - 399 - * f0000de0 - f0000dfc 378 - 37f lp0 - * f0000be0 - f0000bfc 2f8 - 2ff ttyS1 - * - * Region 1 (addr = 0xf0000000 + (io & ~1) << 1 + (io & 1)) - * -------------------------------------------------------- - * Physical region IO region - * f00014f1 a79 pnp write data - * f00007c0 - f00007c1 3e0 - 3e1 pcmcia - * f00004f1 279 pnp address - * f0000440 - f000046c 220 - 236 eth0 - * f0000405 203 pnp read data - */ - -#define ISAMEM_PHYS 0xe0000000 -#define ISAMEM_SIZE 0x10000000 - -#define ISAIO_PHYS 0xf0000000 -#define ISAIO_SIZE PGDIR_SIZE - -#define TRICK0_PHYS 0xf2000000 -#define TRICK1_PHYS 0xf2400000 -#define TRICK2_PHYS 0xf2800000 -#define TRICK3_PHYS 0xf2c00000 -#define TRICK4_PHYS 0xf3000000 -#define TRICK5_PHYS 0xf3400000 -#define TRICK6_PHYS 0xf3800000 -#define TRICK7_PHYS 0xf3c00000 - #define ISAMEM_BASE 0xe0000000 #define ISAIO_BASE 0xf0000000 -#define PIT_BASE 0xfc000000 -#define SOFT_BASE 0xfd000000 - /* * RAM definitions */ diff --git a/arch/arm/mach-ebsa110/include/mach/io.h b/arch/arm/mach-ebsa110/include/mach/io.h index 44679db672fb..11bb0799424b 100644 --- a/arch/arm/mach-ebsa110/include/mach/io.h +++ b/arch/arm/mach-ebsa110/include/mach/io.h @@ -62,15 +62,6 @@ void __writel(u32 val, void __iomem *addr); #define writew(v,b) __writew(v,b) #define writel(v,b) __writel(v,b) -static inline void __iomem *__arch_ioremap(unsigned long cookie, size_t size, - unsigned int flags) -{ - return (void __iomem *)cookie; -} - -#define __arch_ioremap __arch_ioremap -#define __arch_iounmap(cookie) do { } while (0) - extern void insb(unsigned int port, void *buf, int sz); extern void insw(unsigned int port, void *buf, int sz); extern void insl(unsigned int port, void *buf, int sz); diff --git a/arch/arm/mach-ebsa110/include/mach/system.h b/arch/arm/mach-ebsa110/include/mach/system.h deleted file mode 100644 index 2e4af65edb6f..000000000000 --- a/arch/arm/mach-ebsa110/include/mach/system.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * arch/arm/mach-ebsa110/include/mach/system.h - * - * Copyright (C) 1996-2000 Russell King. - * - * 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. - */ -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -/* - * EBSA110 idling methodology: - * - * We can not execute the "wait for interrupt" instruction since that - * will stop our MCLK signal (which provides the clock for the glue - * logic, and therefore the timer interrupt). - * - * Instead, we spin, polling the IRQ_STAT register for the occurrence - * of any interrupt with core clock down to the memory clock. - */ -static inline void arch_idle(void) -{ - const char *irq_stat = (char *)0xff000000; - - /* disable clock switching */ - asm volatile ("mcr p15, 0, ip, c15, c2, 2" : : : "cc"); - - /* wait for an interrupt to occur */ - while (!*irq_stat); - - /* enable clock switching */ - asm volatile ("mcr p15, 0, ip, c15, c1, 2" : : : "cc"); -} - -#endif diff --git a/arch/arm/mach-ebsa110/io.c b/arch/arm/mach-ebsa110/io.c index c52e3047a7eb..756cc377a73d 100644 --- a/arch/arm/mach-ebsa110/io.c +++ b/arch/arm/mach-ebsa110/io.c @@ -177,6 +177,26 @@ void writesl(void __iomem *addr, const void *data, int len) } EXPORT_SYMBOL(writesl); +/* + * The EBSA110 has a weird "ISA IO" region: + * + * Region 0 (addr = 0xf0000000 + io << 2) + * -------------------------------------------------------- + * Physical region IO region + * f0000fe0 - f0000ffc 3f8 - 3ff ttyS0 + * f0000e60 - f0000e64 398 - 399 + * f0000de0 - f0000dfc 378 - 37f lp0 + * f0000be0 - f0000bfc 2f8 - 2ff ttyS1 + * + * Region 1 (addr = 0xf0000000 + (io & ~1) << 1 + (io & 1)) + * -------------------------------------------------------- + * Physical region IO region + * f00014f1 a79 pnp write data + * f00007c0 - f00007c1 3e0 - 3e1 pcmcia + * f00004f1 279 pnp address + * f0000440 - f000046c 220 - 236 eth0 + * f0000405 203 pnp read data + */ #define SUPERIO_PORT(p) \ (((p) >> 3) == (0x3f8 >> 3) || \ ((p) >> 3) == (0x2f8 >> 3) || \ diff --git a/arch/arm/mach-ebsa110/leds.c b/arch/arm/mach-ebsa110/leds.c index 6a6ea57c2a4e..99e14e362500 100644 --- a/arch/arm/mach-ebsa110/leds.c +++ b/arch/arm/mach-ebsa110/leds.c @@ -17,9 +17,10 @@ #include <mach/hardware.h> #include <asm/leds.h> -#include <asm/system.h> #include <asm/mach-types.h> +#include "core.h" + static spinlock_t leds_lock; static void ebsa110_leds_event(led_event_t ledevt) diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile index 574209d9e246..0dc51f9462de 100644 --- a/arch/arm/mach-ep93xx/Makefile +++ b/arch/arm/mach-ep93xx/Makefile @@ -8,6 +8,9 @@ obj- := obj-$(CONFIG_EP93XX_DMA) += dma.o +obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o +AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312 + obj-$(CONFIG_MACH_ADSSPHERE) += adssphere.o obj-$(CONFIG_MACH_EDB93XX) += edb93xx.o obj-$(CONFIG_MACH_GESBC9312) += gesbc9312.o diff --git a/arch/arm/mach-ep93xx/adssphere.c b/arch/arm/mach-ep93xx/adssphere.c index 681e939407d4..2d45947a3034 100644 --- a/arch/arm/mach-ep93xx/adssphere.c +++ b/arch/arm/mach-ep93xx/adssphere.c @@ -20,6 +20,7 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> +#include "soc.h" static struct ep93xx_eth_data __initdata adssphere_eth_data = { .phy_id = 1, diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c index ca4de7105097..c95dbce2468e 100644 --- a/arch/arm/mach-ep93xx/clock.c +++ b/arch/arm/mach-ep93xx/clock.c @@ -25,6 +25,7 @@ #include <asm/div64.h> +#include "soc.h" struct clk { struct clk *parent; diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index b5c1dae8327f..8d2589588713 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -46,6 +46,7 @@ #include <asm/hardware/vic.h> +#include "soc.h" /************************************************************************* * Static I/O mappings that are needed for all EP93xx platforms @@ -204,7 +205,6 @@ void ep93xx_syscon_swlocked_write(unsigned int val, void __iomem *reg) spin_unlock_irqrestore(&syscon_swlock, flags); } -EXPORT_SYMBOL(ep93xx_syscon_swlocked_write); void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits) { @@ -221,7 +221,6 @@ void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits) spin_unlock_irqrestore(&syscon_swlock, flags); } -EXPORT_SYMBOL(ep93xx_devcfg_set_clear); /** * ep93xx_chip_revision() - returns the EP93xx chip revision @@ -279,48 +278,14 @@ static struct amba_pl010_data ep93xx_uart_data = { .set_mctrl = ep93xx_uart_set_mctrl, }; -static struct amba_device uart1_device = { - .dev = { - .init_name = "apb:uart1", - .platform_data = &ep93xx_uart_data, - }, - .res = { - .start = EP93XX_UART1_PHYS_BASE, - .end = EP93XX_UART1_PHYS_BASE + 0x0fff, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_EP93XX_UART1, NO_IRQ }, - .periphid = 0x00041010, -}; - -static struct amba_device uart2_device = { - .dev = { - .init_name = "apb:uart2", - .platform_data = &ep93xx_uart_data, - }, - .res = { - .start = EP93XX_UART2_PHYS_BASE, - .end = EP93XX_UART2_PHYS_BASE + 0x0fff, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_EP93XX_UART2, NO_IRQ }, - .periphid = 0x00041010, -}; +static AMBA_APB_DEVICE(uart1, "apb:uart1", 0x00041010, EP93XX_UART1_PHYS_BASE, + { IRQ_EP93XX_UART1 }, &ep93xx_uart_data); -static struct amba_device uart3_device = { - .dev = { - .init_name = "apb:uart3", - .platform_data = &ep93xx_uart_data, - }, - .res = { - .start = EP93XX_UART3_PHYS_BASE, - .end = EP93XX_UART3_PHYS_BASE + 0x0fff, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_EP93XX_UART3, NO_IRQ }, - .periphid = 0x00041010, -}; +static AMBA_APB_DEVICE(uart2, "apb:uart2", 0x00041010, EP93XX_UART2_PHYS_BASE, + { IRQ_EP93XX_UART2 }, &ep93xx_uart_data); +static AMBA_APB_DEVICE(uart3, "apb:uart3", 0x00041010, EP93XX_UART3_PHYS_BASE, + { IRQ_EP93XX_UART3 }, &ep93xx_uart_data); static struct resource ep93xx_rtc_resource[] = { { @@ -682,9 +647,19 @@ static struct platform_device ep93xx_fb_device = { .resource = ep93xx_fb_resource, }; +/* The backlight use a single register in the framebuffer's register space */ +#define EP93XX_RASTER_REG_BRIGHTNESS 0x20 + +static struct resource ep93xx_bl_resources[] = { + DEFINE_RES_MEM(EP93XX_RASTER_PHYS_BASE + + EP93XX_RASTER_REG_BRIGHTNESS, 0x04), +}; + static struct platform_device ep93xx_bl_device = { .name = "ep93xx-bl", .id = -1, + .num_resources = ARRAY_SIZE(ep93xx_bl_resources), + .resource = ep93xx_bl_resources, }; /** @@ -879,11 +854,32 @@ void __init ep93xx_register_ac97(void) platform_device_register(&ep93xx_pcm_device); } +/************************************************************************* + * EP93xx Watchdog + *************************************************************************/ +static struct resource ep93xx_wdt_resources[] = { + DEFINE_RES_MEM(EP93XX_WATCHDOG_PHYS_BASE, 0x08), +}; + +static struct platform_device ep93xx_wdt_device = { + .name = "ep93xx-wdt", + .id = -1, + .num_resources = ARRAY_SIZE(ep93xx_wdt_resources), + .resource = ep93xx_wdt_resources, +}; + void __init ep93xx_init_devices(void) { /* Disallow access to MaverickCrunch initially */ ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA); + /* Default all ports to GPIO */ + ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_KEYS | + EP93XX_SYSCON_DEVCFG_GONK | + EP93XX_SYSCON_DEVCFG_EONIDE | + EP93XX_SYSCON_DEVCFG_GONIDE | + EP93XX_SYSCON_DEVCFG_HONIDE); + /* Get the GPIO working early, other devices need it */ platform_device_register(&ep93xx_gpio_device); @@ -894,6 +890,7 @@ void __init ep93xx_init_devices(void) platform_device_register(&ep93xx_rtc_device); platform_device_register(&ep93xx_ohci_device); platform_device_register(&ep93xx_leds); + platform_device_register(&ep93xx_wdt_device); } void ep93xx_restart(char mode, const char *cmd) diff --git a/arch/arm/kernel/crunch-bits.S b/arch/arm/mach-ep93xx/crunch-bits.S index 0ec9bb48fab9..0ec9bb48fab9 100644 --- a/arch/arm/kernel/crunch-bits.S +++ b/arch/arm/mach-ep93xx/crunch-bits.S diff --git a/arch/arm/kernel/crunch.c b/arch/arm/mach-ep93xx/crunch.c index 25ef223ba7f3..74753e2df603 100644 --- a/arch/arm/kernel/crunch.c +++ b/arch/arm/mach-ep93xx/crunch.c @@ -16,9 +16,11 @@ #include <linux/sched.h> #include <linux/init.h> #include <linux/io.h> -#include <mach/ep93xx-regs.h> + #include <asm/thread_notify.h> +#include "soc.h" + struct crunch_state *crunch_owner; void crunch_task_release(struct thread_info *thread) diff --git a/arch/arm/mach-ep93xx/dma.c b/arch/arm/mach-ep93xx/dma.c index 5a2570881255..16976d7bdc8a 100644 --- a/arch/arm/mach-ep93xx/dma.c +++ b/arch/arm/mach-ep93xx/dma.c @@ -28,6 +28,8 @@ #include <mach/dma.h> #include <mach/hardware.h> +#include "soc.h" + #define DMA_CHANNEL(_name, _base, _irq) \ { .name = (_name), .base = (_base), .irq = (_irq) } diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c index d115653edca3..da9047d726f0 100644 --- a/arch/arm/mach-ep93xx/edb93xx.c +++ b/arch/arm/mach-ep93xx/edb93xx.c @@ -43,6 +43,7 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> +#include "soc.h" static void __init edb93xx_register_flash(void) { diff --git a/arch/arm/mach-ep93xx/gesbc9312.c b/arch/arm/mach-ep93xx/gesbc9312.c index af46970dc58e..fcdffbe49dcc 100644 --- a/arch/arm/mach-ep93xx/gesbc9312.c +++ b/arch/arm/mach-ep93xx/gesbc9312.c @@ -20,6 +20,7 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> +#include "soc.h" static struct ep93xx_eth_data __initdata gesbc9312_eth_data = { .phy_id = 1, diff --git a/arch/arm/mach-ep93xx/include/mach/entry-macro.S b/arch/arm/mach-ep93xx/include/mach/entry-macro.S deleted file mode 100644 index 9be6edcf9045..000000000000 --- a/arch/arm/mach-ep93xx/include/mach/entry-macro.S +++ /dev/null @@ -1,17 +0,0 @@ -/* - * arch/arm/mach-ep93xx/include/mach/entry-macro.S - * IRQ demultiplexing for EP93xx - * - * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> - * - * 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. - */ - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h index c4a7b84ef06d..c64d74246602 100644 --- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h +++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h @@ -6,40 +6,6 @@ #define __ASM_ARCH_EP93XX_REGS_H /* - * EP93xx Physical Memory Map: - * - * The ASDO pin is sampled at system reset to select a synchronous or - * asynchronous boot configuration. When ASDO is "1" (i.e. pulled-up) - * the synchronous boot mode is selected. When ASDO is "0" (i.e - * pulled-down) the asynchronous boot mode is selected. - * - * In synchronous boot mode nSDCE3 is decoded starting at physical address - * 0x00000000 and nCS0 is decoded starting at 0xf0000000. For asynchronous - * boot mode they are swapped with nCS0 decoded at 0x00000000 ann nSDCE3 - * decoded at 0xf0000000. - * - * There is known errata for the EP93xx dealing with External Memory - * Configurations. Please refer to "AN273: EP93xx Silicon Rev E Design - * Guidelines" for more information. This document can be found at: - * - * http://www.cirrus.com/en/pubs/appNote/AN273REV4.pdf - */ - -#define EP93XX_CS0_PHYS_BASE_ASYNC 0x00000000 /* ASDO Pin = 0 */ -#define EP93XX_SDCE3_PHYS_BASE_SYNC 0x00000000 /* ASDO Pin = 1 */ -#define EP93XX_CS1_PHYS_BASE 0x10000000 -#define EP93XX_CS2_PHYS_BASE 0x20000000 -#define EP93XX_CS3_PHYS_BASE 0x30000000 -#define EP93XX_PCMCIA_PHYS_BASE 0x40000000 -#define EP93XX_CS6_PHYS_BASE 0x60000000 -#define EP93XX_CS7_PHYS_BASE 0x70000000 -#define EP93XX_SDCE0_PHYS_BASE 0xc0000000 -#define EP93XX_SDCE1_PHYS_BASE 0xd0000000 -#define EP93XX_SDCE2_PHYS_BASE 0xe0000000 -#define EP93XX_SDCE3_PHYS_BASE_ASYNC 0xf0000000 /* ASDO Pin = 0 */ -#define EP93XX_CS0_PHYS_BASE_SYNC 0xf0000000 /* ASDO Pin = 1 */ - -/* * EP93xx linux memory map: * * virt phys size @@ -62,58 +28,7 @@ #define EP93XX_APB_PHYS(x) (EP93XX_APB_PHYS_BASE + (x)) #define EP93XX_APB_IOMEM(x) IOMEM(EP93XX_APB_VIRT_BASE + (x)) - -/* AHB peripherals */ -#define EP93XX_DMA_BASE EP93XX_AHB_IOMEM(0x00000000) - -#define EP93XX_ETHERNET_PHYS_BASE EP93XX_AHB_PHYS(0x00010000) -#define EP93XX_ETHERNET_BASE EP93XX_AHB_IOMEM(0x00010000) - -#define EP93XX_USB_PHYS_BASE EP93XX_AHB_PHYS(0x00020000) -#define EP93XX_USB_BASE EP93XX_AHB_IOMEM(0x00020000) - -#define EP93XX_RASTER_PHYS_BASE EP93XX_AHB_PHYS(0x00030000) -#define EP93XX_RASTER_BASE EP93XX_AHB_IOMEM(0x00030000) - -#define EP93XX_GRAPHICS_ACCEL_BASE EP93XX_AHB_IOMEM(0x00040000) - -#define EP93XX_SDRAM_CONTROLLER_BASE EP93XX_AHB_IOMEM(0x00060000) - -#define EP93XX_PCMCIA_CONTROLLER_BASE EP93XX_AHB_IOMEM(0x00080000) - -#define EP93XX_BOOT_ROM_BASE EP93XX_AHB_IOMEM(0x00090000) - -#define EP93XX_IDE_BASE EP93XX_AHB_IOMEM(0x000a0000) - -#define EP93XX_VIC1_BASE EP93XX_AHB_IOMEM(0x000b0000) - -#define EP93XX_VIC2_BASE EP93XX_AHB_IOMEM(0x000c0000) - - -/* APB peripherals */ -#define EP93XX_TIMER_BASE EP93XX_APB_IOMEM(0x00010000) - -#define EP93XX_I2S_PHYS_BASE EP93XX_APB_PHYS(0x00020000) -#define EP93XX_I2S_BASE EP93XX_APB_IOMEM(0x00020000) - -#define EP93XX_SECURITY_BASE EP93XX_APB_IOMEM(0x00030000) - -#define EP93XX_GPIO_PHYS_BASE EP93XX_APB_PHYS(0x00040000) -#define EP93XX_GPIO_BASE EP93XX_APB_IOMEM(0x00040000) -#define EP93XX_GPIO_REG(x) (EP93XX_GPIO_BASE + (x)) -#define EP93XX_GPIO_F_INT_STATUS EP93XX_GPIO_REG(0x5c) -#define EP93XX_GPIO_A_INT_STATUS EP93XX_GPIO_REG(0xa0) -#define EP93XX_GPIO_B_INT_STATUS EP93XX_GPIO_REG(0xbc) -#define EP93XX_GPIO_EEDRIVE EP93XX_GPIO_REG(0xc8) - -#define EP93XX_AAC_PHYS_BASE EP93XX_APB_PHYS(0x00080000) -#define EP93XX_AAC_BASE EP93XX_APB_IOMEM(0x00080000) - -#define EP93XX_SPI_PHYS_BASE EP93XX_APB_PHYS(0x000a0000) -#define EP93XX_SPI_BASE EP93XX_APB_IOMEM(0x000a0000) - -#define EP93XX_IRDA_BASE EP93XX_APB_IOMEM(0x000b0000) - +/* APB UARTs */ #define EP93XX_UART1_PHYS_BASE EP93XX_APB_PHYS(0x000c0000) #define EP93XX_UART1_BASE EP93XX_APB_IOMEM(0x000c0000) @@ -123,108 +38,4 @@ #define EP93XX_UART3_PHYS_BASE EP93XX_APB_PHYS(0x000e0000) #define EP93XX_UART3_BASE EP93XX_APB_IOMEM(0x000e0000) -#define EP93XX_KEY_MATRIX_PHYS_BASE EP93XX_APB_PHYS(0x000f0000) -#define EP93XX_KEY_MATRIX_BASE EP93XX_APB_IOMEM(0x000f0000) - -#define EP93XX_ADC_BASE EP93XX_APB_IOMEM(0x00100000) -#define EP93XX_TOUCHSCREEN_BASE EP93XX_APB_IOMEM(0x00100000) - -#define EP93XX_PWM_PHYS_BASE EP93XX_APB_PHYS(0x00110000) -#define EP93XX_PWM_BASE EP93XX_APB_IOMEM(0x00110000) - -#define EP93XX_RTC_PHYS_BASE EP93XX_APB_PHYS(0x00120000) -#define EP93XX_RTC_BASE EP93XX_APB_IOMEM(0x00120000) - -#define EP93XX_SYSCON_BASE EP93XX_APB_IOMEM(0x00130000) -#define EP93XX_SYSCON_REG(x) (EP93XX_SYSCON_BASE + (x)) -#define EP93XX_SYSCON_POWER_STATE EP93XX_SYSCON_REG(0x00) -#define EP93XX_SYSCON_PWRCNT EP93XX_SYSCON_REG(0x04) -#define EP93XX_SYSCON_PWRCNT_FIR_EN (1<<31) -#define EP93XX_SYSCON_PWRCNT_UARTBAUD (1<<29) -#define EP93XX_SYSCON_PWRCNT_USH_EN (1<<28) -#define EP93XX_SYSCON_PWRCNT_DMA_M2M1 (1<<27) -#define EP93XX_SYSCON_PWRCNT_DMA_M2M0 (1<<26) -#define EP93XX_SYSCON_PWRCNT_DMA_M2P8 (1<<25) -#define EP93XX_SYSCON_PWRCNT_DMA_M2P9 (1<<24) -#define EP93XX_SYSCON_PWRCNT_DMA_M2P6 (1<<23) -#define EP93XX_SYSCON_PWRCNT_DMA_M2P7 (1<<22) -#define EP93XX_SYSCON_PWRCNT_DMA_M2P4 (1<<21) -#define EP93XX_SYSCON_PWRCNT_DMA_M2P5 (1<<20) -#define EP93XX_SYSCON_PWRCNT_DMA_M2P2 (1<<19) -#define EP93XX_SYSCON_PWRCNT_DMA_M2P3 (1<<18) -#define EP93XX_SYSCON_PWRCNT_DMA_M2P0 (1<<17) -#define EP93XX_SYSCON_PWRCNT_DMA_M2P1 (1<<16) -#define EP93XX_SYSCON_HALT EP93XX_SYSCON_REG(0x08) -#define EP93XX_SYSCON_STANDBY EP93XX_SYSCON_REG(0x0c) -#define EP93XX_SYSCON_CLKSET1 EP93XX_SYSCON_REG(0x20) -#define EP93XX_SYSCON_CLKSET1_NBYP1 (1<<23) -#define EP93XX_SYSCON_CLKSET2 EP93XX_SYSCON_REG(0x24) -#define EP93XX_SYSCON_CLKSET2_NBYP2 (1<<19) -#define EP93XX_SYSCON_CLKSET2_PLL2_EN (1<<18) -#define EP93XX_SYSCON_DEVCFG EP93XX_SYSCON_REG(0x80) -#define EP93XX_SYSCON_DEVCFG_SWRST (1<<31) -#define EP93XX_SYSCON_DEVCFG_D1ONG (1<<30) -#define EP93XX_SYSCON_DEVCFG_D0ONG (1<<29) -#define EP93XX_SYSCON_DEVCFG_IONU2 (1<<28) -#define EP93XX_SYSCON_DEVCFG_GONK (1<<27) -#define EP93XX_SYSCON_DEVCFG_TONG (1<<26) -#define EP93XX_SYSCON_DEVCFG_MONG (1<<25) -#define EP93XX_SYSCON_DEVCFG_U3EN (1<<24) -#define EP93XX_SYSCON_DEVCFG_CPENA (1<<23) -#define EP93XX_SYSCON_DEVCFG_A2ONG (1<<22) -#define EP93XX_SYSCON_DEVCFG_A1ONG (1<<21) -#define EP93XX_SYSCON_DEVCFG_U2EN (1<<20) -#define EP93XX_SYSCON_DEVCFG_EXVC (1<<19) -#define EP93XX_SYSCON_DEVCFG_U1EN (1<<18) -#define EP93XX_SYSCON_DEVCFG_TIN (1<<17) -#define EP93XX_SYSCON_DEVCFG_HC3IN (1<<15) -#define EP93XX_SYSCON_DEVCFG_HC3EN (1<<14) -#define EP93XX_SYSCON_DEVCFG_HC1IN (1<<13) -#define EP93XX_SYSCON_DEVCFG_HC1EN (1<<12) -#define EP93XX_SYSCON_DEVCFG_HONIDE (1<<11) -#define EP93XX_SYSCON_DEVCFG_GONIDE (1<<10) -#define EP93XX_SYSCON_DEVCFG_PONG (1<<9) -#define EP93XX_SYSCON_DEVCFG_EONIDE (1<<8) -#define EP93XX_SYSCON_DEVCFG_I2SONSSP (1<<7) -#define EP93XX_SYSCON_DEVCFG_I2SONAC97 (1<<6) -#define EP93XX_SYSCON_DEVCFG_RASONP3 (1<<4) -#define EP93XX_SYSCON_DEVCFG_RAS (1<<3) -#define EP93XX_SYSCON_DEVCFG_ADCPD (1<<2) -#define EP93XX_SYSCON_DEVCFG_KEYS (1<<1) -#define EP93XX_SYSCON_DEVCFG_SHENA (1<<0) -#define EP93XX_SYSCON_VIDCLKDIV EP93XX_SYSCON_REG(0x84) -#define EP93XX_SYSCON_CLKDIV_ENABLE (1<<15) -#define EP93XX_SYSCON_CLKDIV_ESEL (1<<14) -#define EP93XX_SYSCON_CLKDIV_PSEL (1<<13) -#define EP93XX_SYSCON_CLKDIV_PDIV_SHIFT 8 -#define EP93XX_SYSCON_I2SCLKDIV EP93XX_SYSCON_REG(0x8c) -#define EP93XX_SYSCON_I2SCLKDIV_SENA (1<<31) -#define EP93XX_SYSCON_I2SCLKDIV_ORIDE (1<<29) -#define EP93XX_SYSCON_I2SCLKDIV_SPOL (1<<19) -#define EP93XX_I2SCLKDIV_SDIV (1 << 16) -#define EP93XX_I2SCLKDIV_LRDIV32 (0 << 17) -#define EP93XX_I2SCLKDIV_LRDIV64 (1 << 17) -#define EP93XX_I2SCLKDIV_LRDIV128 (2 << 17) -#define EP93XX_I2SCLKDIV_LRDIV_MASK (3 << 17) -#define EP93XX_SYSCON_KEYTCHCLKDIV EP93XX_SYSCON_REG(0x90) -#define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN (1<<31) -#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV (1<<16) -#define EP93XX_SYSCON_KEYTCHCLKDIV_KEN (1<<15) -#define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV (1<<0) -#define EP93XX_SYSCON_SYSCFG EP93XX_SYSCON_REG(0x9c) -#define EP93XX_SYSCON_SYSCFG_REV_MASK (0xf0000000) -#define EP93XX_SYSCON_SYSCFG_REV_SHIFT (28) -#define EP93XX_SYSCON_SYSCFG_SBOOT (1<<8) -#define EP93XX_SYSCON_SYSCFG_LCSN7 (1<<7) -#define EP93XX_SYSCON_SYSCFG_LCSN6 (1<<6) -#define EP93XX_SYSCON_SYSCFG_LASDO (1<<5) -#define EP93XX_SYSCON_SYSCFG_LEEDA (1<<4) -#define EP93XX_SYSCON_SYSCFG_LEECLK (1<<3) -#define EP93XX_SYSCON_SYSCFG_LCSN2 (1<<1) -#define EP93XX_SYSCON_SYSCFG_LCSN1 (1<<0) -#define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0) - -#define EP93XX_WATCHDOG_BASE EP93XX_APB_IOMEM(0x00140000) - - #endif diff --git a/arch/arm/mach-ep93xx/include/mach/gpio-ep93xx.h b/arch/arm/mach-ep93xx/include/mach/gpio-ep93xx.h index 8aff2ea35877..6d7c571a519f 100644 --- a/arch/arm/mach-ep93xx/include/mach/gpio-ep93xx.h +++ b/arch/arm/mach-ep93xx/include/mach/gpio-ep93xx.h @@ -3,6 +3,16 @@ #ifndef __GPIO_EP93XX_H #define __GPIO_EP93XX_H +#include <mach/ep93xx-regs.h> + +#define EP93XX_GPIO_PHYS_BASE EP93XX_APB_PHYS(0x00040000) +#define EP93XX_GPIO_BASE EP93XX_APB_IOMEM(0x00040000) +#define EP93XX_GPIO_REG(x) (EP93XX_GPIO_BASE + (x)) +#define EP93XX_GPIO_F_INT_STATUS EP93XX_GPIO_REG(0x5c) +#define EP93XX_GPIO_A_INT_STATUS EP93XX_GPIO_REG(0xa0) +#define EP93XX_GPIO_B_INT_STATUS EP93XX_GPIO_REG(0xbc) +#define EP93XX_GPIO_EEDRIVE EP93XX_GPIO_REG(0xc8) + /* GPIO port A. */ #define EP93XX_GPIO_LINE_A(x) ((x) + 0) #define EP93XX_GPIO_LINE_EGPIO0 EP93XX_GPIO_LINE_A(0) diff --git a/arch/arm/mach-ep93xx/include/mach/hardware.h b/arch/arm/mach-ep93xx/include/mach/hardware.h index 4df842897eae..efcd47815a91 100644 --- a/arch/arm/mach-ep93xx/include/mach/hardware.h +++ b/arch/arm/mach-ep93xx/include/mach/hardware.h @@ -5,7 +5,6 @@ #ifndef __ASM_ARCH_HARDWARE_H #define __ASM_ARCH_HARDWARE_H -#include <mach/ep93xx-regs.h> #include <mach/platform.h> /* diff --git a/arch/arm/mach-ep93xx/include/mach/io.h b/arch/arm/mach-ep93xx/include/mach/io.h deleted file mode 100644 index 594b77f21054..000000000000 --- a/arch/arm/mach-ep93xx/include/mach/io.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * arch/arm/mach-ep93xx/include/mach/io.h - */ - -#ifndef __ASM_MACH_IO_H -#define __ASM_MACH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -#define __io(p) __typesafe_io(p) -#define __mem_pci(p) (p) - -/* - * A typesafe __io() variation for variable initialisers - */ -#ifdef __ASSEMBLER__ -#define IOMEM(p) p -#else -#define IOMEM(p) ((void __iomem __force *)(p)) -#endif - -#endif /* __ASM_MACH_IO_H */ diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h index ad63d4be693f..602bd87fd0ab 100644 --- a/arch/arm/mach-ep93xx/include/mach/platform.h +++ b/arch/arm/mach-ep93xx/include/mach/platform.h @@ -21,20 +21,6 @@ struct ep93xx_eth_data void ep93xx_map_io(void); void ep93xx_init_irq(void); -/* EP93xx System Controller software locked register write */ -void ep93xx_syscon_swlocked_write(unsigned int val, void __iomem *reg); -void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits); - -static inline void ep93xx_devcfg_set_bits(unsigned int bits) -{ - ep93xx_devcfg_set_clear(bits, 0x00); -} - -static inline void ep93xx_devcfg_clear_bits(unsigned int bits) -{ - ep93xx_devcfg_set_clear(0x00, bits); -} - #define EP93XX_CHIP_REV_D0 3 #define EP93XX_CHIP_REV_D1 4 #define EP93XX_CHIP_REV_E0 5 diff --git a/arch/arm/mach-ep93xx/include/mach/system.h b/arch/arm/mach-ep93xx/include/mach/system.h deleted file mode 100644 index b5bec7cb9b52..000000000000 --- a/arch/arm/mach-ep93xx/include/mach/system.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * arch/arm/mach-ep93xx/include/mach/system.h - */ -static inline void arch_idle(void) -{ - cpu_do_idle(); -} diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c index 7b98084f0c97..dc431c5f04ce 100644 --- a/arch/arm/mach-ep93xx/micro9.c +++ b/arch/arm/mach-ep93xx/micro9.c @@ -22,6 +22,7 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> +#include "soc.h" /************************************************************************* * Micro9 NOR Flash diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c index f4e553eca21c..f40c2987e545 100644 --- a/arch/arm/mach-ep93xx/simone.c +++ b/arch/arm/mach-ep93xx/simone.c @@ -29,6 +29,8 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> +#include "soc.h" + static struct ep93xx_eth_data __initdata simone_eth_data = { .phy_id = 1, }; diff --git a/arch/arm/mach-ep93xx/snappercl15.c b/arch/arm/mach-ep93xx/snappercl15.c index fd846331ddff..0c00852ef160 100644 --- a/arch/arm/mach-ep93xx/snappercl15.c +++ b/arch/arm/mach-ep93xx/snappercl15.c @@ -35,6 +35,8 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> +#include "soc.h" + #define SNAPPERCL15_NAND_BASE (EP93XX_CS7_PHYS_BASE + SZ_16M) #define SNAPPERCL15_NAND_WPN (1 << 8) /* Write protect (active low) */ diff --git a/arch/arm/mach-ep93xx/soc.h b/arch/arm/mach-ep93xx/soc.h new file mode 100644 index 000000000000..979fba722926 --- /dev/null +++ b/arch/arm/mach-ep93xx/soc.h @@ -0,0 +1,213 @@ +/* + * arch/arm/mach-ep93xx/soc.h + * + * Copyright (C) 2012 Open Kernel Labs <www.ok-labs.com> + * Copyright (C) 2012 Ryan Mallon <rmallon@gmail.com> + * + * 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. + */ + +#ifndef _EP93XX_SOC_H +#define _EP93XX_SOC_H + +#include <mach/ep93xx-regs.h> + +/* + * EP93xx Physical Memory Map: + * + * The ASDO pin is sampled at system reset to select a synchronous or + * asynchronous boot configuration. When ASDO is "1" (i.e. pulled-up) + * the synchronous boot mode is selected. When ASDO is "0" (i.e + * pulled-down) the asynchronous boot mode is selected. + * + * In synchronous boot mode nSDCE3 is decoded starting at physical address + * 0x00000000 and nCS0 is decoded starting at 0xf0000000. For asynchronous + * boot mode they are swapped with nCS0 decoded at 0x00000000 ann nSDCE3 + * decoded at 0xf0000000. + * + * There is known errata for the EP93xx dealing with External Memory + * Configurations. Please refer to "AN273: EP93xx Silicon Rev E Design + * Guidelines" for more information. This document can be found at: + * + * http://www.cirrus.com/en/pubs/appNote/AN273REV4.pdf + */ + +#define EP93XX_CS0_PHYS_BASE_ASYNC 0x00000000 /* ASDO Pin = 0 */ +#define EP93XX_SDCE3_PHYS_BASE_SYNC 0x00000000 /* ASDO Pin = 1 */ +#define EP93XX_CS1_PHYS_BASE 0x10000000 +#define EP93XX_CS2_PHYS_BASE 0x20000000 +#define EP93XX_CS3_PHYS_BASE 0x30000000 +#define EP93XX_PCMCIA_PHYS_BASE 0x40000000 +#define EP93XX_CS6_PHYS_BASE 0x60000000 +#define EP93XX_CS7_PHYS_BASE 0x70000000 +#define EP93XX_SDCE0_PHYS_BASE 0xc0000000 +#define EP93XX_SDCE1_PHYS_BASE 0xd0000000 +#define EP93XX_SDCE2_PHYS_BASE 0xe0000000 +#define EP93XX_SDCE3_PHYS_BASE_ASYNC 0xf0000000 /* ASDO Pin = 0 */ +#define EP93XX_CS0_PHYS_BASE_SYNC 0xf0000000 /* ASDO Pin = 1 */ + +/* AHB peripherals */ +#define EP93XX_DMA_BASE EP93XX_AHB_IOMEM(0x00000000) + +#define EP93XX_ETHERNET_PHYS_BASE EP93XX_AHB_PHYS(0x00010000) +#define EP93XX_ETHERNET_BASE EP93XX_AHB_IOMEM(0x00010000) + +#define EP93XX_USB_PHYS_BASE EP93XX_AHB_PHYS(0x00020000) +#define EP93XX_USB_BASE EP93XX_AHB_IOMEM(0x00020000) + +#define EP93XX_RASTER_PHYS_BASE EP93XX_AHB_PHYS(0x00030000) +#define EP93XX_RASTER_BASE EP93XX_AHB_IOMEM(0x00030000) + +#define EP93XX_GRAPHICS_ACCEL_BASE EP93XX_AHB_IOMEM(0x00040000) + +#define EP93XX_SDRAM_CONTROLLER_BASE EP93XX_AHB_IOMEM(0x00060000) + +#define EP93XX_PCMCIA_CONTROLLER_BASE EP93XX_AHB_IOMEM(0x00080000) + +#define EP93XX_BOOT_ROM_BASE EP93XX_AHB_IOMEM(0x00090000) + +#define EP93XX_IDE_BASE EP93XX_AHB_IOMEM(0x000a0000) + +#define EP93XX_VIC1_BASE EP93XX_AHB_IOMEM(0x000b0000) + +#define EP93XX_VIC2_BASE EP93XX_AHB_IOMEM(0x000c0000) + +/* APB peripherals */ +#define EP93XX_TIMER_BASE EP93XX_APB_IOMEM(0x00010000) + +#define EP93XX_I2S_PHYS_BASE EP93XX_APB_PHYS(0x00020000) +#define EP93XX_I2S_BASE EP93XX_APB_IOMEM(0x00020000) + +#define EP93XX_SECURITY_BASE EP93XX_APB_IOMEM(0x00030000) + +#define EP93XX_AAC_PHYS_BASE EP93XX_APB_PHYS(0x00080000) +#define EP93XX_AAC_BASE EP93XX_APB_IOMEM(0x00080000) + +#define EP93XX_SPI_PHYS_BASE EP93XX_APB_PHYS(0x000a0000) +#define EP93XX_SPI_BASE EP93XX_APB_IOMEM(0x000a0000) + +#define EP93XX_IRDA_BASE EP93XX_APB_IOMEM(0x000b0000) + +#define EP93XX_KEY_MATRIX_PHYS_BASE EP93XX_APB_PHYS(0x000f0000) +#define EP93XX_KEY_MATRIX_BASE EP93XX_APB_IOMEM(0x000f0000) + +#define EP93XX_ADC_BASE EP93XX_APB_IOMEM(0x00100000) +#define EP93XX_TOUCHSCREEN_BASE EP93XX_APB_IOMEM(0x00100000) + +#define EP93XX_PWM_PHYS_BASE EP93XX_APB_PHYS(0x00110000) +#define EP93XX_PWM_BASE EP93XX_APB_IOMEM(0x00110000) + +#define EP93XX_RTC_PHYS_BASE EP93XX_APB_PHYS(0x00120000) +#define EP93XX_RTC_BASE EP93XX_APB_IOMEM(0x00120000) + +#define EP93XX_WATCHDOG_PHYS_BASE EP93XX_APB_PHYS(0x00140000) +#define EP93XX_WATCHDOG_BASE EP93XX_APB_IOMEM(0x00140000) + +/* System controller */ +#define EP93XX_SYSCON_BASE EP93XX_APB_IOMEM(0x00130000) +#define EP93XX_SYSCON_REG(x) (EP93XX_SYSCON_BASE + (x)) +#define EP93XX_SYSCON_POWER_STATE EP93XX_SYSCON_REG(0x00) +#define EP93XX_SYSCON_PWRCNT EP93XX_SYSCON_REG(0x04) +#define EP93XX_SYSCON_PWRCNT_FIR_EN (1<<31) +#define EP93XX_SYSCON_PWRCNT_UARTBAUD (1<<29) +#define EP93XX_SYSCON_PWRCNT_USH_EN (1<<28) +#define EP93XX_SYSCON_PWRCNT_DMA_M2M1 (1<<27) +#define EP93XX_SYSCON_PWRCNT_DMA_M2M0 (1<<26) +#define EP93XX_SYSCON_PWRCNT_DMA_M2P8 (1<<25) +#define EP93XX_SYSCON_PWRCNT_DMA_M2P9 (1<<24) +#define EP93XX_SYSCON_PWRCNT_DMA_M2P6 (1<<23) +#define EP93XX_SYSCON_PWRCNT_DMA_M2P7 (1<<22) +#define EP93XX_SYSCON_PWRCNT_DMA_M2P4 (1<<21) +#define EP93XX_SYSCON_PWRCNT_DMA_M2P5 (1<<20) +#define EP93XX_SYSCON_PWRCNT_DMA_M2P2 (1<<19) +#define EP93XX_SYSCON_PWRCNT_DMA_M2P3 (1<<18) +#define EP93XX_SYSCON_PWRCNT_DMA_M2P0 (1<<17) +#define EP93XX_SYSCON_PWRCNT_DMA_M2P1 (1<<16) +#define EP93XX_SYSCON_HALT EP93XX_SYSCON_REG(0x08) +#define EP93XX_SYSCON_STANDBY EP93XX_SYSCON_REG(0x0c) +#define EP93XX_SYSCON_CLKSET1 EP93XX_SYSCON_REG(0x20) +#define EP93XX_SYSCON_CLKSET1_NBYP1 (1<<23) +#define EP93XX_SYSCON_CLKSET2 EP93XX_SYSCON_REG(0x24) +#define EP93XX_SYSCON_CLKSET2_NBYP2 (1<<19) +#define EP93XX_SYSCON_CLKSET2_PLL2_EN (1<<18) +#define EP93XX_SYSCON_DEVCFG EP93XX_SYSCON_REG(0x80) +#define EP93XX_SYSCON_DEVCFG_SWRST (1<<31) +#define EP93XX_SYSCON_DEVCFG_D1ONG (1<<30) +#define EP93XX_SYSCON_DEVCFG_D0ONG (1<<29) +#define EP93XX_SYSCON_DEVCFG_IONU2 (1<<28) +#define EP93XX_SYSCON_DEVCFG_GONK (1<<27) +#define EP93XX_SYSCON_DEVCFG_TONG (1<<26) +#define EP93XX_SYSCON_DEVCFG_MONG (1<<25) +#define EP93XX_SYSCON_DEVCFG_U3EN (1<<24) +#define EP93XX_SYSCON_DEVCFG_CPENA (1<<23) +#define EP93XX_SYSCON_DEVCFG_A2ONG (1<<22) +#define EP93XX_SYSCON_DEVCFG_A1ONG (1<<21) +#define EP93XX_SYSCON_DEVCFG_U2EN (1<<20) +#define EP93XX_SYSCON_DEVCFG_EXVC (1<<19) +#define EP93XX_SYSCON_DEVCFG_U1EN (1<<18) +#define EP93XX_SYSCON_DEVCFG_TIN (1<<17) +#define EP93XX_SYSCON_DEVCFG_HC3IN (1<<15) +#define EP93XX_SYSCON_DEVCFG_HC3EN (1<<14) +#define EP93XX_SYSCON_DEVCFG_HC1IN (1<<13) +#define EP93XX_SYSCON_DEVCFG_HC1EN (1<<12) +#define EP93XX_SYSCON_DEVCFG_HONIDE (1<<11) +#define EP93XX_SYSCON_DEVCFG_GONIDE (1<<10) +#define EP93XX_SYSCON_DEVCFG_PONG (1<<9) +#define EP93XX_SYSCON_DEVCFG_EONIDE (1<<8) +#define EP93XX_SYSCON_DEVCFG_I2SONSSP (1<<7) +#define EP93XX_SYSCON_DEVCFG_I2SONAC97 (1<<6) +#define EP93XX_SYSCON_DEVCFG_RASONP3 (1<<4) +#define EP93XX_SYSCON_DEVCFG_RAS (1<<3) +#define EP93XX_SYSCON_DEVCFG_ADCPD (1<<2) +#define EP93XX_SYSCON_DEVCFG_KEYS (1<<1) +#define EP93XX_SYSCON_DEVCFG_SHENA (1<<0) +#define EP93XX_SYSCON_VIDCLKDIV EP93XX_SYSCON_REG(0x84) +#define EP93XX_SYSCON_CLKDIV_ENABLE (1<<15) +#define EP93XX_SYSCON_CLKDIV_ESEL (1<<14) +#define EP93XX_SYSCON_CLKDIV_PSEL (1<<13) +#define EP93XX_SYSCON_CLKDIV_PDIV_SHIFT 8 +#define EP93XX_SYSCON_I2SCLKDIV EP93XX_SYSCON_REG(0x8c) +#define EP93XX_SYSCON_I2SCLKDIV_SENA (1<<31) +#define EP93XX_SYSCON_I2SCLKDIV_ORIDE (1<<29) +#define EP93XX_SYSCON_I2SCLKDIV_SPOL (1<<19) +#define EP93XX_I2SCLKDIV_SDIV (1 << 16) +#define EP93XX_I2SCLKDIV_LRDIV32 (0 << 17) +#define EP93XX_I2SCLKDIV_LRDIV64 (1 << 17) +#define EP93XX_I2SCLKDIV_LRDIV128 (2 << 17) +#define EP93XX_I2SCLKDIV_LRDIV_MASK (3 << 17) +#define EP93XX_SYSCON_KEYTCHCLKDIV EP93XX_SYSCON_REG(0x90) +#define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN (1<<31) +#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV (1<<16) +#define EP93XX_SYSCON_KEYTCHCLKDIV_KEN (1<<15) +#define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV (1<<0) +#define EP93XX_SYSCON_SYSCFG EP93XX_SYSCON_REG(0x9c) +#define EP93XX_SYSCON_SYSCFG_REV_MASK (0xf0000000) +#define EP93XX_SYSCON_SYSCFG_REV_SHIFT (28) +#define EP93XX_SYSCON_SYSCFG_SBOOT (1<<8) +#define EP93XX_SYSCON_SYSCFG_LCSN7 (1<<7) +#define EP93XX_SYSCON_SYSCFG_LCSN6 (1<<6) +#define EP93XX_SYSCON_SYSCFG_LASDO (1<<5) +#define EP93XX_SYSCON_SYSCFG_LEEDA (1<<4) +#define EP93XX_SYSCON_SYSCFG_LEECLK (1<<3) +#define EP93XX_SYSCON_SYSCFG_LCSN2 (1<<1) +#define EP93XX_SYSCON_SYSCFG_LCSN1 (1<<0) +#define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0) + +/* EP93xx System Controller software locked register write */ +void ep93xx_syscon_swlocked_write(unsigned int val, void __iomem *reg); +void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits); + +static inline void ep93xx_devcfg_set_bits(unsigned int bits) +{ + ep93xx_devcfg_set_clear(bits, 0x00); +} + +static inline void ep93xx_devcfg_clear_bits(unsigned int bits) +{ + ep93xx_devcfg_set_clear(0x00, bits); +} + +#endif /* _EP93XX_SOC_H */ diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c index 79f8ecf07a19..5ea790942e94 100644 --- a/arch/arm/mach-ep93xx/ts72xx.c +++ b/arch/arm/mach-ep93xx/ts72xx.c @@ -28,6 +28,7 @@ #include <asm/mach/map.h> #include <asm/mach/arch.h> +#include "soc.h" static struct map_desc ts72xx_io_desc[] __initdata = { { diff --git a/arch/arm/mach-ep93xx/vision_ep9307.c b/arch/arm/mach-ep93xx/vision_ep9307.c index d67d0b4feb6f..ba156eb225e8 100644 --- a/arch/arm/mach-ep93xx/vision_ep9307.c +++ b/arch/arm/mach-ep93xx/vision_ep9307.c @@ -39,6 +39,8 @@ #include <asm/mach/map.h> #include <asm/mach/arch.h> +#include "soc.h" + /************************************************************************* * Static I/O mappings for the FPGA *************************************************************************/ diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index dfad6538b273..e81c35f936b5 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -11,18 +11,19 @@ if ARCH_EXYNOS menu "SAMSUNG EXYNOS SoCs Support" -choice - prompt "EXYNOS System Type" - default ARCH_EXYNOS4 - config ARCH_EXYNOS4 bool "SAMSUNG EXYNOS4" + default y select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 help Samsung EXYNOS4 SoCs based systems -endchoice +config ARCH_EXYNOS5 + bool "SAMSUNG EXYNOS5" + select HAVE_SMP + help + Samsung EXYNOS5 (Cortex-A15) SoC based systems comment "EXYNOS SoCs" @@ -42,6 +43,7 @@ config SOC_EXYNOS4212 bool "SAMSUNG EXYNOS4212" default y depends on ARCH_EXYNOS4 + select SAMSUNG_DMADEV select S5P_PM if PM select S5P_SLEEP if PM help @@ -51,9 +53,17 @@ config SOC_EXYNOS4412 bool "SAMSUNG EXYNOS4412" default y depends on ARCH_EXYNOS4 + select SAMSUNG_DMADEV help Enable EXYNOS4412 SoC support +config SOC_EXYNOS5250 + bool "SAMSUNG EXYNOS5250" + default y + depends on ARCH_EXYNOS5 + help + Enable EXYNOS5250 SoC support + config EXYNOS4_MCT bool default y @@ -179,7 +189,9 @@ config MACH_SMDKV310 select S5P_DEV_FIMC1 select S5P_DEV_FIMC2 select S5P_DEV_FIMC3 + select S5P_DEV_G2D select S5P_DEV_I2C_HDMIPHY + select S5P_DEV_JPEG select S5P_DEV_MFC select S5P_DEV_TV select S5P_DEV_USB_EHCI @@ -225,7 +237,9 @@ config MACH_UNIVERSAL_C210 select S5P_DEV_FIMC1 select S5P_DEV_FIMC2 select S5P_DEV_FIMC3 + select S5P_DEV_G2D select S5P_DEV_CSIS0 + select S5P_DEV_JPEG select S5P_DEV_FIMD0 select S3C_DEV_HSMMC select S3C_DEV_HSMMC2 @@ -262,11 +276,14 @@ config MACH_NURI select S3C_DEV_I2C1 select S3C_DEV_I2C3 select S3C_DEV_I2C5 + select S3C_DEV_I2C6 select S5P_DEV_CSIS0 + select S5P_DEV_JPEG select S5P_DEV_FIMC0 select S5P_DEV_FIMC1 select S5P_DEV_FIMC2 select S5P_DEV_FIMC3 + select S5P_DEV_G2D select S5P_DEV_MFC select S5P_DEV_USB_EHCI select S5P_SETUP_MIPIPHY @@ -276,6 +293,7 @@ config MACH_NURI select EXYNOS4_SETUP_I2C1 select EXYNOS4_SETUP_I2C3 select EXYNOS4_SETUP_I2C5 + select EXYNOS4_SETUP_I2C6 select EXYNOS4_SETUP_SDHCI select EXYNOS4_SETUP_USB_PHY select S5P_SETUP_MIPIPHY @@ -296,7 +314,9 @@ config MACH_ORIGEN select S5P_DEV_FIMC2 select S5P_DEV_FIMC3 select S5P_DEV_FIMD0 + select S5P_DEV_G2D select S5P_DEV_I2C_HDMIPHY + select S5P_DEV_JPEG select S5P_DEV_MFC select S5P_DEV_TV select S5P_DEV_USB_EHCI @@ -325,6 +345,7 @@ config MACH_SMDK4212 select SAMSUNG_DEV_BACKLIGHT select SAMSUNG_DEV_KEYPAD select SAMSUNG_DEV_PWM + select EXYNOS4_DEV_DMA select EXYNOS4_SETUP_I2C1 select EXYNOS4_SETUP_I2C3 select EXYNOS4_SETUP_I2C7 @@ -343,10 +364,11 @@ config MACH_SMDK4412 Machine support for Samsung SMDK4412 endif -comment "Flattened Device Tree based board for Exynos4 based SoC" +comment "Flattened Device Tree based board for EXYNOS SoCs" config MACH_EXYNOS4_DT bool "Samsung Exynos4 Machine using device tree" + depends on ARCH_EXYNOS4 select CPU_EXYNOS4210 select USE_OF select ARM_AMBA @@ -357,6 +379,16 @@ config MACH_EXYNOS4_DT Note: This is under development and not all peripherals can be supported with this machine file. +config MACH_EXYNOS5_DT + bool "SAMSUNG EXYNOS5 Machine using device tree" + depends on ARCH_EXYNOS5 + select SOC_EXYNOS5250 + select USE_OF + select ARM_AMBA + help + Machine support for Samsung Exynos4 machine with device tree enabled. + Select this if a fdt blob is available for the EXYNOS4 SoC based board. + if ARCH_EXYNOS4 comment "Configuration for HSMMC 8-bit bus width" diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile index d9191f9a7af8..8631840d1b5e 100644 --- a/arch/arm/mach-exynos/Makefile +++ b/arch/arm/mach-exynos/Makefile @@ -12,7 +12,9 @@ obj- := # Core -obj-$(CONFIG_ARCH_EXYNOS4) += common.o clock.o +obj-$(CONFIG_ARCH_EXYNOS) += common.o +obj-$(CONFIG_ARCH_EXYNOS4) += clock-exynos4.o +obj-$(CONFIG_ARCH_EXYNOS5) += clock-exynos5.o obj-$(CONFIG_CPU_EXYNOS4210) += clock-exynos4210.o obj-$(CONFIG_SOC_EXYNOS4212) += clock-exynos4212.o @@ -41,9 +43,11 @@ obj-$(CONFIG_MACH_SMDK4212) += mach-smdk4x12.o obj-$(CONFIG_MACH_SMDK4412) += mach-smdk4x12.o obj-$(CONFIG_MACH_EXYNOS4_DT) += mach-exynos4-dt.o +obj-$(CONFIG_MACH_EXYNOS5_DT) += mach-exynos5-dt.o # device support +obj-y += dev-uart.o obj-$(CONFIG_ARCH_EXYNOS4) += dev-audio.o obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o @@ -51,7 +55,7 @@ obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o obj-$(CONFIG_EXYNOS4_DEV_DMA) += dma.o obj-$(CONFIG_EXYNOS4_DEV_USB_OHCI) += dev-ohci.o -obj-$(CONFIG_ARCH_EXYNOS4) += setup-i2c0.o +obj-$(CONFIG_ARCH_EXYNOS) += setup-i2c0.o obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o obj-$(CONFIG_EXYNOS4_SETUP_FIMD0) += setup-fimd0.o obj-$(CONFIG_EXYNOS4_SETUP_I2C1) += setup-i2c1.o diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c new file mode 100644 index 000000000000..df54c2a92225 --- /dev/null +++ b/arch/arm/mach-exynos/clock-exynos4.c @@ -0,0 +1,1581 @@ +/* + * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * EXYNOS4 - Clock support + * + * 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 <linux/kernel.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/syscore_ops.h> + +#include <plat/cpu-freq.h> +#include <plat/clock.h> +#include <plat/cpu.h> +#include <plat/pll.h> +#include <plat/s5p-clock.h> +#include <plat/clock-clksrc.h> +#include <plat/pm.h> + +#include <mach/map.h> +#include <mach/regs-clock.h> +#include <mach/sysmmu.h> + +#include "common.h" +#include "clock-exynos4.h" + +#ifdef CONFIG_PM_SLEEP +static struct sleep_save exynos4_clock_save[] = { + SAVE_ITEM(EXYNOS4_CLKDIV_LEFTBUS), + SAVE_ITEM(EXYNOS4_CLKGATE_IP_LEFTBUS), + SAVE_ITEM(EXYNOS4_CLKDIV_RIGHTBUS), + SAVE_ITEM(EXYNOS4_CLKGATE_IP_RIGHTBUS), + SAVE_ITEM(EXYNOS4_CLKSRC_TOP0), + SAVE_ITEM(EXYNOS4_CLKSRC_TOP1), + SAVE_ITEM(EXYNOS4_CLKSRC_CAM), + SAVE_ITEM(EXYNOS4_CLKSRC_TV), + SAVE_ITEM(EXYNOS4_CLKSRC_MFC), + SAVE_ITEM(EXYNOS4_CLKSRC_G3D), + SAVE_ITEM(EXYNOS4_CLKSRC_LCD0), + SAVE_ITEM(EXYNOS4_CLKSRC_MAUDIO), + SAVE_ITEM(EXYNOS4_CLKSRC_FSYS), + SAVE_ITEM(EXYNOS4_CLKSRC_PERIL0), + SAVE_ITEM(EXYNOS4_CLKSRC_PERIL1), + SAVE_ITEM(EXYNOS4_CLKDIV_CAM), + SAVE_ITEM(EXYNOS4_CLKDIV_TV), + SAVE_ITEM(EXYNOS4_CLKDIV_MFC), + SAVE_ITEM(EXYNOS4_CLKDIV_G3D), + SAVE_ITEM(EXYNOS4_CLKDIV_LCD0), + SAVE_ITEM(EXYNOS4_CLKDIV_MAUDIO), + SAVE_ITEM(EXYNOS4_CLKDIV_FSYS0), + SAVE_ITEM(EXYNOS4_CLKDIV_FSYS1), + SAVE_ITEM(EXYNOS4_CLKDIV_FSYS2), + SAVE_ITEM(EXYNOS4_CLKDIV_FSYS3), + SAVE_ITEM(EXYNOS4_CLKDIV_PERIL0), + SAVE_ITEM(EXYNOS4_CLKDIV_PERIL1), + SAVE_ITEM(EXYNOS4_CLKDIV_PERIL2), + SAVE_ITEM(EXYNOS4_CLKDIV_PERIL3), + SAVE_ITEM(EXYNOS4_CLKDIV_PERIL4), + SAVE_ITEM(EXYNOS4_CLKDIV_PERIL5), + SAVE_ITEM(EXYNOS4_CLKDIV_TOP), + SAVE_ITEM(EXYNOS4_CLKSRC_MASK_TOP), + SAVE_ITEM(EXYNOS4_CLKSRC_MASK_CAM), + SAVE_ITEM(EXYNOS4_CLKSRC_MASK_TV), + SAVE_ITEM(EXYNOS4_CLKSRC_MASK_LCD0), + SAVE_ITEM(EXYNOS4_CLKSRC_MASK_MAUDIO), + SAVE_ITEM(EXYNOS4_CLKSRC_MASK_FSYS), + SAVE_ITEM(EXYNOS4_CLKSRC_MASK_PERIL0), + SAVE_ITEM(EXYNOS4_CLKSRC_MASK_PERIL1), + SAVE_ITEM(EXYNOS4_CLKDIV2_RATIO), + SAVE_ITEM(EXYNOS4_CLKGATE_SCLKCAM), + SAVE_ITEM(EXYNOS4_CLKGATE_IP_CAM), + SAVE_ITEM(EXYNOS4_CLKGATE_IP_TV), + SAVE_ITEM(EXYNOS4_CLKGATE_IP_MFC), + SAVE_ITEM(EXYNOS4_CLKGATE_IP_G3D), + SAVE_ITEM(EXYNOS4_CLKGATE_IP_LCD0), + SAVE_ITEM(EXYNOS4_CLKGATE_IP_FSYS), + SAVE_ITEM(EXYNOS4_CLKGATE_IP_GPS), + SAVE_ITEM(EXYNOS4_CLKGATE_IP_PERIL), + SAVE_ITEM(EXYNOS4_CLKGATE_BLOCK), + SAVE_ITEM(EXYNOS4_CLKSRC_MASK_DMC), + SAVE_ITEM(EXYNOS4_CLKSRC_DMC), + SAVE_ITEM(EXYNOS4_CLKDIV_DMC0), + SAVE_ITEM(EXYNOS4_CLKDIV_DMC1), + SAVE_ITEM(EXYNOS4_CLKGATE_IP_DMC), + SAVE_ITEM(EXYNOS4_CLKSRC_CPU), + SAVE_ITEM(EXYNOS4_CLKDIV_CPU), + SAVE_ITEM(EXYNOS4_CLKDIV_CPU + 0x4), + SAVE_ITEM(EXYNOS4_CLKGATE_SCLKCPU), + SAVE_ITEM(EXYNOS4_CLKGATE_IP_CPU), +}; +#endif + +static struct clk exynos4_clk_sclk_hdmi27m = { + .name = "sclk_hdmi27m", + .rate = 27000000, +}; + +static struct clk exynos4_clk_sclk_hdmiphy = { + .name = "sclk_hdmiphy", +}; + +static struct clk exynos4_clk_sclk_usbphy0 = { + .name = "sclk_usbphy0", + .rate = 27000000, +}; + +static struct clk exynos4_clk_sclk_usbphy1 = { + .name = "sclk_usbphy1", +}; + +static struct clk dummy_apb_pclk = { + .name = "apb_pclk", + .id = -1, +}; + +static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_TOP, clk, enable); +} + +static int exynos4_clksrc_mask_cam_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_CAM, clk, enable); +} + +static int exynos4_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_LCD0, clk, enable); +} + +int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_FSYS, clk, enable); +} + +static int exynos4_clksrc_mask_peril0_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_PERIL0, clk, enable); +} + +static int exynos4_clksrc_mask_peril1_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_PERIL1, clk, enable); +} + +static int exynos4_clk_ip_mfc_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS4_CLKGATE_IP_MFC, clk, enable); +} + +static int exynos4_clksrc_mask_tv_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_TV, clk, enable); +} + +static int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS4_CLKGATE_IP_CAM, clk, enable); +} + +static int exynos4_clk_ip_tv_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS4_CLKGATE_IP_TV, clk, enable); +} + +static int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS4_CLKGATE_IP_IMAGE, clk, enable); +} + +static int exynos4_clk_ip_lcd0_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS4_CLKGATE_IP_LCD0, clk, enable); +} + +int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS4210_CLKGATE_IP_LCD1, clk, enable); +} + +int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS4_CLKGATE_IP_FSYS, clk, enable); +} + +static int exynos4_clk_ip_peril_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS4_CLKGATE_IP_PERIL, clk, enable); +} + +static int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS4_CLKGATE_IP_PERIR, clk, enable); +} + +static int exynos4_clk_hdmiphy_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable); +} + +static int exynos4_clk_dac_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P_DAC_PHY_CONTROL, clk, enable); +} + +/* Core list of CMU_CPU side */ + +static struct clksrc_clk exynos4_clk_mout_apll = { + .clk = { + .name = "mout_apll", + }, + .sources = &clk_src_apll, + .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 0, .size = 1 }, +}; + +static struct clksrc_clk exynos4_clk_sclk_apll = { + .clk = { + .name = "sclk_apll", + .parent = &exynos4_clk_mout_apll.clk, + }, + .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 24, .size = 3 }, +}; + +static struct clksrc_clk exynos4_clk_mout_epll = { + .clk = { + .name = "mout_epll", + }, + .sources = &clk_src_epll, + .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 4, .size = 1 }, +}; + +struct clksrc_clk exynos4_clk_mout_mpll = { + .clk = { + .name = "mout_mpll", + }, + .sources = &clk_src_mpll, + + /* reg_src will be added in each SoCs' clock */ +}; + +static struct clk *exynos4_clkset_moutcore_list[] = { + [0] = &exynos4_clk_mout_apll.clk, + [1] = &exynos4_clk_mout_mpll.clk, +}; + +static struct clksrc_sources exynos4_clkset_moutcore = { + .sources = exynos4_clkset_moutcore_list, + .nr_sources = ARRAY_SIZE(exynos4_clkset_moutcore_list), +}; + +static struct clksrc_clk exynos4_clk_moutcore = { + .clk = { + .name = "moutcore", + }, + .sources = &exynos4_clkset_moutcore, + .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 16, .size = 1 }, +}; + +static struct clksrc_clk exynos4_clk_coreclk = { + .clk = { + .name = "core_clk", + .parent = &exynos4_clk_moutcore.clk, + }, + .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 0, .size = 3 }, +}; + +static struct clksrc_clk exynos4_clk_armclk = { + .clk = { + .name = "armclk", + .parent = &exynos4_clk_coreclk.clk, + }, +}; + +static struct clksrc_clk exynos4_clk_aclk_corem0 = { + .clk = { + .name = "aclk_corem0", + .parent = &exynos4_clk_coreclk.clk, + }, + .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 4, .size = 3 }, +}; + +static struct clksrc_clk exynos4_clk_aclk_cores = { + .clk = { + .name = "aclk_cores", + .parent = &exynos4_clk_coreclk.clk, + }, + .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 4, .size = 3 }, +}; + +static struct clksrc_clk exynos4_clk_aclk_corem1 = { + .clk = { + .name = "aclk_corem1", + .parent = &exynos4_clk_coreclk.clk, + }, + .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 8, .size = 3 }, +}; + +static struct clksrc_clk exynos4_clk_periphclk = { + .clk = { + .name = "periphclk", + .parent = &exynos4_clk_coreclk.clk, + }, + .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 12, .size = 3 }, +}; + +/* Core list of CMU_CORE side */ + +static struct clk *exynos4_clkset_corebus_list[] = { + [0] = &exynos4_clk_mout_mpll.clk, + [1] = &exynos4_clk_sclk_apll.clk, +}; + +struct clksrc_sources exynos4_clkset_mout_corebus = { + .sources = exynos4_clkset_corebus_list, + .nr_sources = ARRAY_SIZE(exynos4_clkset_corebus_list), +}; + +static struct clksrc_clk exynos4_clk_mout_corebus = { + .clk = { + .name = "mout_corebus", + }, + .sources = &exynos4_clkset_mout_corebus, + .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 4, .size = 1 }, +}; + +static struct clksrc_clk exynos4_clk_sclk_dmc = { + .clk = { + .name = "sclk_dmc", + .parent = &exynos4_clk_mout_corebus.clk, + }, + .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 12, .size = 3 }, +}; + +static struct clksrc_clk exynos4_clk_aclk_cored = { + .clk = { + .name = "aclk_cored", + .parent = &exynos4_clk_sclk_dmc.clk, + }, + .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 16, .size = 3 }, +}; + +static struct clksrc_clk exynos4_clk_aclk_corep = { + .clk = { + .name = "aclk_corep", + .parent = &exynos4_clk_aclk_cored.clk, + }, + .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 20, .size = 3 }, +}; + +static struct clksrc_clk exynos4_clk_aclk_acp = { + .clk = { + .name = "aclk_acp", + .parent = &exynos4_clk_mout_corebus.clk, + }, + .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 0, .size = 3 }, +}; + +static struct clksrc_clk exynos4_clk_pclk_acp = { + .clk = { + .name = "pclk_acp", + .parent = &exynos4_clk_aclk_acp.clk, + }, + .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 4, .size = 3 }, +}; + +/* Core list of CMU_TOP side */ + +struct clk *exynos4_clkset_aclk_top_list[] = { + [0] = &exynos4_clk_mout_mpll.clk, + [1] = &exynos4_clk_sclk_apll.clk, +}; + +static struct clksrc_sources exynos4_clkset_aclk = { + .sources = exynos4_clkset_aclk_top_list, + .nr_sources = ARRAY_SIZE(exynos4_clkset_aclk_top_list), +}; + +static struct clksrc_clk exynos4_clk_aclk_200 = { + .clk = { + .name = "aclk_200", + }, + .sources = &exynos4_clkset_aclk, + .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 12, .size = 1 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 0, .size = 3 }, +}; + +static struct clksrc_clk exynos4_clk_aclk_100 = { + .clk = { + .name = "aclk_100", + }, + .sources = &exynos4_clkset_aclk, + .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 16, .size = 1 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 4, .size = 4 }, +}; + +static struct clksrc_clk exynos4_clk_aclk_160 = { + .clk = { + .name = "aclk_160", + }, + .sources = &exynos4_clkset_aclk, + .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 20, .size = 1 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 8, .size = 3 }, +}; + +struct clksrc_clk exynos4_clk_aclk_133 = { + .clk = { + .name = "aclk_133", + }, + .sources = &exynos4_clkset_aclk, + .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 24, .size = 1 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 12, .size = 3 }, +}; + +static struct clk *exynos4_clkset_vpllsrc_list[] = { + [0] = &clk_fin_vpll, + [1] = &exynos4_clk_sclk_hdmi27m, +}; + +static struct clksrc_sources exynos4_clkset_vpllsrc = { + .sources = exynos4_clkset_vpllsrc_list, + .nr_sources = ARRAY_SIZE(exynos4_clkset_vpllsrc_list), +}; + +static struct clksrc_clk exynos4_clk_vpllsrc = { + .clk = { + .name = "vpll_src", + .enable = exynos4_clksrc_mask_top_ctrl, + .ctrlbit = (1 << 0), + }, + .sources = &exynos4_clkset_vpllsrc, + .reg_src = { .reg = EXYNOS4_CLKSRC_TOP1, .shift = 0, .size = 1 }, +}; + +static struct clk *exynos4_clkset_sclk_vpll_list[] = { + [0] = &exynos4_clk_vpllsrc.clk, + [1] = &clk_fout_vpll, +}; + +static struct clksrc_sources exynos4_clkset_sclk_vpll = { + .sources = exynos4_clkset_sclk_vpll_list, + .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_vpll_list), +}; + +static struct clksrc_clk exynos4_clk_sclk_vpll = { + .clk = { + .name = "sclk_vpll", + }, + .sources = &exynos4_clkset_sclk_vpll, + .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 8, .size = 1 }, +}; + +static struct clk exynos4_init_clocks_off[] = { + { + .name = "timers", + .parent = &exynos4_clk_aclk_100.clk, + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1<<24), + }, { + .name = "csis", + .devname = "s5p-mipi-csis.0", + .enable = exynos4_clk_ip_cam_ctrl, + .ctrlbit = (1 << 4), + }, { + .name = "csis", + .devname = "s5p-mipi-csis.1", + .enable = exynos4_clk_ip_cam_ctrl, + .ctrlbit = (1 << 5), + }, { + .name = "jpeg", + .id = 0, + .enable = exynos4_clk_ip_cam_ctrl, + .ctrlbit = (1 << 6), + }, { + .name = "fimc", + .devname = "exynos4-fimc.0", + .enable = exynos4_clk_ip_cam_ctrl, + .ctrlbit = (1 << 0), + }, { + .name = "fimc", + .devname = "exynos4-fimc.1", + .enable = exynos4_clk_ip_cam_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "fimc", + .devname = "exynos4-fimc.2", + .enable = exynos4_clk_ip_cam_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = "fimc", + .devname = "exynos4-fimc.3", + .enable = exynos4_clk_ip_cam_ctrl, + .ctrlbit = (1 << 3), + }, { + .name = "hsmmc", + .devname = "s3c-sdhci.0", + .parent = &exynos4_clk_aclk_133.clk, + .enable = exynos4_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 5), + }, { + .name = "hsmmc", + .devname = "s3c-sdhci.1", + .parent = &exynos4_clk_aclk_133.clk, + .enable = exynos4_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 6), + }, { + .name = "hsmmc", + .devname = "s3c-sdhci.2", + .parent = &exynos4_clk_aclk_133.clk, + .enable = exynos4_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 7), + }, { + .name = "hsmmc", + .devname = "s3c-sdhci.3", + .parent = &exynos4_clk_aclk_133.clk, + .enable = exynos4_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 8), + }, { + .name = "dwmmc", + .parent = &exynos4_clk_aclk_133.clk, + .enable = exynos4_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 9), + }, { + .name = "dac", + .devname = "s5p-sdo", + .enable = exynos4_clk_ip_tv_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = "mixer", + .devname = "s5p-mixer", + .enable = exynos4_clk_ip_tv_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "vp", + .devname = "s5p-mixer", + .enable = exynos4_clk_ip_tv_ctrl, + .ctrlbit = (1 << 0), + }, { + .name = "hdmi", + .devname = "exynos4-hdmi", + .enable = exynos4_clk_ip_tv_ctrl, + .ctrlbit = (1 << 3), + }, { + .name = "hdmiphy", + .devname = "exynos4-hdmi", + .enable = exynos4_clk_hdmiphy_ctrl, + .ctrlbit = (1 << 0), + }, { + .name = "dacphy", + .devname = "s5p-sdo", + .enable = exynos4_clk_dac_ctrl, + .ctrlbit = (1 << 0), + }, { + .name = "adc", + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1 << 15), + }, { + .name = "keypad", + .enable = exynos4_clk_ip_perir_ctrl, + .ctrlbit = (1 << 16), + }, { + .name = "rtc", + .enable = exynos4_clk_ip_perir_ctrl, + .ctrlbit = (1 << 15), + }, { + .name = "watchdog", + .parent = &exynos4_clk_aclk_100.clk, + .enable = exynos4_clk_ip_perir_ctrl, + .ctrlbit = (1 << 14), + }, { + .name = "usbhost", + .enable = exynos4_clk_ip_fsys_ctrl , + .ctrlbit = (1 << 12), + }, { + .name = "otg", + .enable = exynos4_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 13), + }, { + .name = "spi", + .devname = "s3c64xx-spi.0", + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1 << 16), + }, { + .name = "spi", + .devname = "s3c64xx-spi.1", + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1 << 17), + }, { + .name = "spi", + .devname = "s3c64xx-spi.2", + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1 << 18), + }, { + .name = "iis", + .devname = "samsung-i2s.0", + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1 << 19), + }, { + .name = "iis", + .devname = "samsung-i2s.1", + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1 << 20), + }, { + .name = "iis", + .devname = "samsung-i2s.2", + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1 << 21), + }, { + .name = "ac97", + .devname = "samsung-ac97", + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1 << 27), + }, { + .name = "fimg2d", + .enable = exynos4_clk_ip_image_ctrl, + .ctrlbit = (1 << 0), + }, { + .name = "mfc", + .devname = "s5p-mfc", + .enable = exynos4_clk_ip_mfc_ctrl, + .ctrlbit = (1 << 0), + }, { + .name = "i2c", + .devname = "s3c2440-i2c.0", + .parent = &exynos4_clk_aclk_100.clk, + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1 << 6), + }, { + .name = "i2c", + .devname = "s3c2440-i2c.1", + .parent = &exynos4_clk_aclk_100.clk, + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1 << 7), + }, { + .name = "i2c", + .devname = "s3c2440-i2c.2", + .parent = &exynos4_clk_aclk_100.clk, + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1 << 8), + }, { + .name = "i2c", + .devname = "s3c2440-i2c.3", + .parent = &exynos4_clk_aclk_100.clk, + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1 << 9), + }, { + .name = "i2c", + .devname = "s3c2440-i2c.4", + .parent = &exynos4_clk_aclk_100.clk, + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1 << 10), + }, { + .name = "i2c", + .devname = "s3c2440-i2c.5", + .parent = &exynos4_clk_aclk_100.clk, + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1 << 11), + }, { + .name = "i2c", + .devname = "s3c2440-i2c.6", + .parent = &exynos4_clk_aclk_100.clk, + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1 << 12), + }, { + .name = "i2c", + .devname = "s3c2440-i2c.7", + .parent = &exynos4_clk_aclk_100.clk, + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1 << 13), + }, { + .name = "i2c", + .devname = "s3c2440-hdmiphy-i2c", + .parent = &exynos4_clk_aclk_100.clk, + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1 << 14), + }, { + .name = "SYSMMU_MDMA", + .enable = exynos4_clk_ip_image_ctrl, + .ctrlbit = (1 << 5), + }, { + .name = "SYSMMU_FIMC0", + .enable = exynos4_clk_ip_cam_ctrl, + .ctrlbit = (1 << 7), + }, { + .name = "SYSMMU_FIMC1", + .enable = exynos4_clk_ip_cam_ctrl, + .ctrlbit = (1 << 8), + }, { + .name = "SYSMMU_FIMC2", + .enable = exynos4_clk_ip_cam_ctrl, + .ctrlbit = (1 << 9), + }, { + .name = "SYSMMU_FIMC3", + .enable = exynos4_clk_ip_cam_ctrl, + .ctrlbit = (1 << 10), + }, { + .name = "SYSMMU_JPEG", + .enable = exynos4_clk_ip_cam_ctrl, + .ctrlbit = (1 << 11), + }, { + .name = "SYSMMU_FIMD0", + .enable = exynos4_clk_ip_lcd0_ctrl, + .ctrlbit = (1 << 4), + }, { + .name = "SYSMMU_FIMD1", + .enable = exynos4_clk_ip_lcd1_ctrl, + .ctrlbit = (1 << 4), + }, { + .name = "SYSMMU_PCIe", + .enable = exynos4_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 18), + }, { + .name = "SYSMMU_G2D", + .enable = exynos4_clk_ip_image_ctrl, + .ctrlbit = (1 << 3), + }, { + .name = "SYSMMU_ROTATOR", + .enable = exynos4_clk_ip_image_ctrl, + .ctrlbit = (1 << 4), + }, { + .name = "SYSMMU_TV", + .enable = exynos4_clk_ip_tv_ctrl, + .ctrlbit = (1 << 4), + }, { + .name = "SYSMMU_MFC_L", + .enable = exynos4_clk_ip_mfc_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "SYSMMU_MFC_R", + .enable = exynos4_clk_ip_mfc_ctrl, + .ctrlbit = (1 << 2), + } +}; + +static struct clk exynos4_init_clocks_on[] = { + { + .name = "uart", + .devname = "s5pv210-uart.0", + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1 << 0), + }, { + .name = "uart", + .devname = "s5pv210-uart.1", + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "uart", + .devname = "s5pv210-uart.2", + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = "uart", + .devname = "s5pv210-uart.3", + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1 << 3), + }, { + .name = "uart", + .devname = "s5pv210-uart.4", + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1 << 4), + }, { + .name = "uart", + .devname = "s5pv210-uart.5", + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1 << 5), + } +}; + +static struct clk exynos4_clk_pdma0 = { + .name = "dma", + .devname = "dma-pl330.0", + .enable = exynos4_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 0), +}; + +static struct clk exynos4_clk_pdma1 = { + .name = "dma", + .devname = "dma-pl330.1", + .enable = exynos4_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 1), +}; + +static struct clk exynos4_clk_mdma1 = { + .name = "dma", + .devname = "dma-pl330.2", + .enable = exynos4_clk_ip_image_ctrl, + .ctrlbit = ((1 << 8) | (1 << 5) | (1 << 2)), +}; + +static struct clk exynos4_clk_fimd0 = { + .name = "fimd", + .devname = "exynos4-fb.0", + .enable = exynos4_clk_ip_lcd0_ctrl, + .ctrlbit = (1 << 0), +}; + +struct clk *exynos4_clkset_group_list[] = { + [0] = &clk_ext_xtal_mux, + [1] = &clk_xusbxti, + [2] = &exynos4_clk_sclk_hdmi27m, + [3] = &exynos4_clk_sclk_usbphy0, + [4] = &exynos4_clk_sclk_usbphy1, + [5] = &exynos4_clk_sclk_hdmiphy, + [6] = &exynos4_clk_mout_mpll.clk, + [7] = &exynos4_clk_mout_epll.clk, + [8] = &exynos4_clk_sclk_vpll.clk, +}; + +struct clksrc_sources exynos4_clkset_group = { + .sources = exynos4_clkset_group_list, + .nr_sources = ARRAY_SIZE(exynos4_clkset_group_list), +}; + +static struct clk *exynos4_clkset_mout_g2d0_list[] = { + [0] = &exynos4_clk_mout_mpll.clk, + [1] = &exynos4_clk_sclk_apll.clk, +}; + +static struct clksrc_sources exynos4_clkset_mout_g2d0 = { + .sources = exynos4_clkset_mout_g2d0_list, + .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g2d0_list), +}; + +static struct clksrc_clk exynos4_clk_mout_g2d0 = { + .clk = { + .name = "mout_g2d0", + }, + .sources = &exynos4_clkset_mout_g2d0, + .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 0, .size = 1 }, +}; + +static struct clk *exynos4_clkset_mout_g2d1_list[] = { + [0] = &exynos4_clk_mout_epll.clk, + [1] = &exynos4_clk_sclk_vpll.clk, +}; + +static struct clksrc_sources exynos4_clkset_mout_g2d1 = { + .sources = exynos4_clkset_mout_g2d1_list, + .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g2d1_list), +}; + +static struct clksrc_clk exynos4_clk_mout_g2d1 = { + .clk = { + .name = "mout_g2d1", + }, + .sources = &exynos4_clkset_mout_g2d1, + .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 4, .size = 1 }, +}; + +static struct clk *exynos4_clkset_mout_g2d_list[] = { + [0] = &exynos4_clk_mout_g2d0.clk, + [1] = &exynos4_clk_mout_g2d1.clk, +}; + +static struct clksrc_sources exynos4_clkset_mout_g2d = { + .sources = exynos4_clkset_mout_g2d_list, + .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g2d_list), +}; + +static struct clk *exynos4_clkset_mout_mfc0_list[] = { + [0] = &exynos4_clk_mout_mpll.clk, + [1] = &exynos4_clk_sclk_apll.clk, +}; + +static struct clksrc_sources exynos4_clkset_mout_mfc0 = { + .sources = exynos4_clkset_mout_mfc0_list, + .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_mfc0_list), +}; + +static struct clksrc_clk exynos4_clk_mout_mfc0 = { + .clk = { + .name = "mout_mfc0", + }, + .sources = &exynos4_clkset_mout_mfc0, + .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 0, .size = 1 }, +}; + +static struct clk *exynos4_clkset_mout_mfc1_list[] = { + [0] = &exynos4_clk_mout_epll.clk, + [1] = &exynos4_clk_sclk_vpll.clk, +}; + +static struct clksrc_sources exynos4_clkset_mout_mfc1 = { + .sources = exynos4_clkset_mout_mfc1_list, + .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_mfc1_list), +}; + +static struct clksrc_clk exynos4_clk_mout_mfc1 = { + .clk = { + .name = "mout_mfc1", + }, + .sources = &exynos4_clkset_mout_mfc1, + .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 4, .size = 1 }, +}; + +static struct clk *exynos4_clkset_mout_mfc_list[] = { + [0] = &exynos4_clk_mout_mfc0.clk, + [1] = &exynos4_clk_mout_mfc1.clk, +}; + +static struct clksrc_sources exynos4_clkset_mout_mfc = { + .sources = exynos4_clkset_mout_mfc_list, + .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_mfc_list), +}; + +static struct clk *exynos4_clkset_sclk_dac_list[] = { + [0] = &exynos4_clk_sclk_vpll.clk, + [1] = &exynos4_clk_sclk_hdmiphy, +}; + +static struct clksrc_sources exynos4_clkset_sclk_dac = { + .sources = exynos4_clkset_sclk_dac_list, + .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_dac_list), +}; + +static struct clksrc_clk exynos4_clk_sclk_dac = { + .clk = { + .name = "sclk_dac", + .enable = exynos4_clksrc_mask_tv_ctrl, + .ctrlbit = (1 << 8), + }, + .sources = &exynos4_clkset_sclk_dac, + .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 8, .size = 1 }, +}; + +static struct clksrc_clk exynos4_clk_sclk_pixel = { + .clk = { + .name = "sclk_pixel", + .parent = &exynos4_clk_sclk_vpll.clk, + }, + .reg_div = { .reg = EXYNOS4_CLKDIV_TV, .shift = 0, .size = 4 }, +}; + +static struct clk *exynos4_clkset_sclk_hdmi_list[] = { + [0] = &exynos4_clk_sclk_pixel.clk, + [1] = &exynos4_clk_sclk_hdmiphy, +}; + +static struct clksrc_sources exynos4_clkset_sclk_hdmi = { + .sources = exynos4_clkset_sclk_hdmi_list, + .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_hdmi_list), +}; + +static struct clksrc_clk exynos4_clk_sclk_hdmi = { + .clk = { + .name = "sclk_hdmi", + .enable = exynos4_clksrc_mask_tv_ctrl, + .ctrlbit = (1 << 0), + }, + .sources = &exynos4_clkset_sclk_hdmi, + .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 0, .size = 1 }, +}; + +static struct clk *exynos4_clkset_sclk_mixer_list[] = { + [0] = &exynos4_clk_sclk_dac.clk, + [1] = &exynos4_clk_sclk_hdmi.clk, +}; + +static struct clksrc_sources exynos4_clkset_sclk_mixer = { + .sources = exynos4_clkset_sclk_mixer_list, + .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_mixer_list), +}; + +static struct clksrc_clk exynos4_clk_sclk_mixer = { + .clk = { + .name = "sclk_mixer", + .enable = exynos4_clksrc_mask_tv_ctrl, + .ctrlbit = (1 << 4), + }, + .sources = &exynos4_clkset_sclk_mixer, + .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 4, .size = 1 }, +}; + +static struct clksrc_clk *exynos4_sclk_tv[] = { + &exynos4_clk_sclk_dac, + &exynos4_clk_sclk_pixel, + &exynos4_clk_sclk_hdmi, + &exynos4_clk_sclk_mixer, +}; + +static struct clksrc_clk exynos4_clk_dout_mmc0 = { + .clk = { + .name = "dout_mmc0", + }, + .sources = &exynos4_clkset_group, + .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 0, .size = 4 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 0, .size = 4 }, +}; + +static struct clksrc_clk exynos4_clk_dout_mmc1 = { + .clk = { + .name = "dout_mmc1", + }, + .sources = &exynos4_clkset_group, + .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 4, .size = 4 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 16, .size = 4 }, +}; + +static struct clksrc_clk exynos4_clk_dout_mmc2 = { + .clk = { + .name = "dout_mmc2", + }, + .sources = &exynos4_clkset_group, + .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 8, .size = 4 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 0, .size = 4 }, +}; + +static struct clksrc_clk exynos4_clk_dout_mmc3 = { + .clk = { + .name = "dout_mmc3", + }, + .sources = &exynos4_clkset_group, + .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 12, .size = 4 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 16, .size = 4 }, +}; + +static struct clksrc_clk exynos4_clk_dout_mmc4 = { + .clk = { + .name = "dout_mmc4", + }, + .sources = &exynos4_clkset_group, + .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 16, .size = 4 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS3, .shift = 0, .size = 4 }, +}; + +static struct clksrc_clk exynos4_clksrcs[] = { + { + .clk = { + .name = "sclk_pwm", + .enable = exynos4_clksrc_mask_peril0_ctrl, + .ctrlbit = (1 << 24), + }, + .sources = &exynos4_clkset_group, + .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 24, .size = 4 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL3, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "sclk_csis", + .devname = "s5p-mipi-csis.0", + .enable = exynos4_clksrc_mask_cam_ctrl, + .ctrlbit = (1 << 24), + }, + .sources = &exynos4_clkset_group, + .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 24, .size = 4 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 24, .size = 4 }, + }, { + .clk = { + .name = "sclk_csis", + .devname = "s5p-mipi-csis.1", + .enable = exynos4_clksrc_mask_cam_ctrl, + .ctrlbit = (1 << 28), + }, + .sources = &exynos4_clkset_group, + .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 28, .size = 4 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 28, .size = 4 }, + }, { + .clk = { + .name = "sclk_cam0", + .enable = exynos4_clksrc_mask_cam_ctrl, + .ctrlbit = (1 << 16), + }, + .sources = &exynos4_clkset_group, + .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 16, .size = 4 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 16, .size = 4 }, + }, { + .clk = { + .name = "sclk_cam1", + .enable = exynos4_clksrc_mask_cam_ctrl, + .ctrlbit = (1 << 20), + }, + .sources = &exynos4_clkset_group, + .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 20, .size = 4 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 20, .size = 4 }, + }, { + .clk = { + .name = "sclk_fimc", + .devname = "exynos4-fimc.0", + .enable = exynos4_clksrc_mask_cam_ctrl, + .ctrlbit = (1 << 0), + }, + .sources = &exynos4_clkset_group, + .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 0, .size = 4 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "sclk_fimc", + .devname = "exynos4-fimc.1", + .enable = exynos4_clksrc_mask_cam_ctrl, + .ctrlbit = (1 << 4), + }, + .sources = &exynos4_clkset_group, + .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 4, .size = 4 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 4, .size = 4 }, + }, { + .clk = { + .name = "sclk_fimc", + .devname = "exynos4-fimc.2", + .enable = exynos4_clksrc_mask_cam_ctrl, + .ctrlbit = (1 << 8), + }, + .sources = &exynos4_clkset_group, + .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 8, .size = 4 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 8, .size = 4 }, + }, { + .clk = { + .name = "sclk_fimc", + .devname = "exynos4-fimc.3", + .enable = exynos4_clksrc_mask_cam_ctrl, + .ctrlbit = (1 << 12), + }, + .sources = &exynos4_clkset_group, + .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 12, .size = 4 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 12, .size = 4 }, + }, { + .clk = { + .name = "sclk_fimd", + .devname = "exynos4-fb.0", + .enable = exynos4_clksrc_mask_lcd0_ctrl, + .ctrlbit = (1 << 0), + }, + .sources = &exynos4_clkset_group, + .reg_src = { .reg = EXYNOS4_CLKSRC_LCD0, .shift = 0, .size = 4 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_LCD0, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "sclk_fimg2d", + }, + .sources = &exynos4_clkset_mout_g2d, + .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 8, .size = 1 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_IMAGE, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "sclk_mfc", + .devname = "s5p-mfc", + }, + .sources = &exynos4_clkset_mout_mfc, + .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 8, .size = 1 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_MFC, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "sclk_dwmmc", + .parent = &exynos4_clk_dout_mmc4.clk, + .enable = exynos4_clksrc_mask_fsys_ctrl, + .ctrlbit = (1 << 16), + }, + .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS3, .shift = 8, .size = 8 }, + } +}; + +static struct clksrc_clk exynos4_clk_sclk_uart0 = { + .clk = { + .name = "uclk1", + .devname = "exynos4210-uart.0", + .enable = exynos4_clksrc_mask_peril0_ctrl, + .ctrlbit = (1 << 0), + }, + .sources = &exynos4_clkset_group, + .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 0, .size = 4 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 0, .size = 4 }, +}; + +static struct clksrc_clk exynos4_clk_sclk_uart1 = { + .clk = { + .name = "uclk1", + .devname = "exynos4210-uart.1", + .enable = exynos4_clksrc_mask_peril0_ctrl, + .ctrlbit = (1 << 4), + }, + .sources = &exynos4_clkset_group, + .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 4, .size = 4 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 4, .size = 4 }, +}; + +static struct clksrc_clk exynos4_clk_sclk_uart2 = { + .clk = { + .name = "uclk1", + .devname = "exynos4210-uart.2", + .enable = exynos4_clksrc_mask_peril0_ctrl, + .ctrlbit = (1 << 8), + }, + .sources = &exynos4_clkset_group, + .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 8, .size = 4 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 8, .size = 4 }, +}; + +static struct clksrc_clk exynos4_clk_sclk_uart3 = { + .clk = { + .name = "uclk1", + .devname = "exynos4210-uart.3", + .enable = exynos4_clksrc_mask_peril0_ctrl, + .ctrlbit = (1 << 12), + }, + .sources = &exynos4_clkset_group, + .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 12, .size = 4 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 12, .size = 4 }, +}; + +static struct clksrc_clk exynos4_clk_sclk_mmc0 = { + .clk = { + .name = "sclk_mmc", + .devname = "s3c-sdhci.0", + .parent = &exynos4_clk_dout_mmc0.clk, + .enable = exynos4_clksrc_mask_fsys_ctrl, + .ctrlbit = (1 << 0), + }, + .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 8, .size = 8 }, +}; + +static struct clksrc_clk exynos4_clk_sclk_mmc1 = { + .clk = { + .name = "sclk_mmc", + .devname = "s3c-sdhci.1", + .parent = &exynos4_clk_dout_mmc1.clk, + .enable = exynos4_clksrc_mask_fsys_ctrl, + .ctrlbit = (1 << 4), + }, + .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 24, .size = 8 }, +}; + +static struct clksrc_clk exynos4_clk_sclk_mmc2 = { + .clk = { + .name = "sclk_mmc", + .devname = "s3c-sdhci.2", + .parent = &exynos4_clk_dout_mmc2.clk, + .enable = exynos4_clksrc_mask_fsys_ctrl, + .ctrlbit = (1 << 8), + }, + .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 8, .size = 8 }, +}; + +static struct clksrc_clk exynos4_clk_sclk_mmc3 = { + .clk = { + .name = "sclk_mmc", + .devname = "s3c-sdhci.3", + .parent = &exynos4_clk_dout_mmc3.clk, + .enable = exynos4_clksrc_mask_fsys_ctrl, + .ctrlbit = (1 << 12), + }, + .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 24, .size = 8 }, +}; + +static struct clksrc_clk exynos4_clk_sclk_spi0 = { + .clk = { + .name = "sclk_spi", + .devname = "s3c64xx-spi.0", + .enable = exynos4_clksrc_mask_peril1_ctrl, + .ctrlbit = (1 << 16), + }, + .sources = &exynos4_clkset_group, + .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 16, .size = 4 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 0, .size = 4 }, +}; + +static struct clksrc_clk exynos4_clk_sclk_spi1 = { + .clk = { + .name = "sclk_spi", + .devname = "s3c64xx-spi.1", + .enable = exynos4_clksrc_mask_peril1_ctrl, + .ctrlbit = (1 << 20), + }, + .sources = &exynos4_clkset_group, + .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 20, .size = 4 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 16, .size = 4 }, +}; + +static struct clksrc_clk exynos4_clk_sclk_spi2 = { + .clk = { + .name = "sclk_spi", + .devname = "s3c64xx-spi.2", + .enable = exynos4_clksrc_mask_peril1_ctrl, + .ctrlbit = (1 << 24), + }, + .sources = &exynos4_clkset_group, + .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 24, .size = 4 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL2, .shift = 0, .size = 4 }, +}; + +/* Clock initialization code */ +static struct clksrc_clk *exynos4_sysclks[] = { + &exynos4_clk_mout_apll, + &exynos4_clk_sclk_apll, + &exynos4_clk_mout_epll, + &exynos4_clk_mout_mpll, + &exynos4_clk_moutcore, + &exynos4_clk_coreclk, + &exynos4_clk_armclk, + &exynos4_clk_aclk_corem0, + &exynos4_clk_aclk_cores, + &exynos4_clk_aclk_corem1, + &exynos4_clk_periphclk, + &exynos4_clk_mout_corebus, + &exynos4_clk_sclk_dmc, + &exynos4_clk_aclk_cored, + &exynos4_clk_aclk_corep, + &exynos4_clk_aclk_acp, + &exynos4_clk_pclk_acp, + &exynos4_clk_vpllsrc, + &exynos4_clk_sclk_vpll, + &exynos4_clk_aclk_200, + &exynos4_clk_aclk_100, + &exynos4_clk_aclk_160, + &exynos4_clk_aclk_133, + &exynos4_clk_dout_mmc0, + &exynos4_clk_dout_mmc1, + &exynos4_clk_dout_mmc2, + &exynos4_clk_dout_mmc3, + &exynos4_clk_dout_mmc4, + &exynos4_clk_mout_mfc0, + &exynos4_clk_mout_mfc1, +}; + +static struct clk *exynos4_clk_cdev[] = { + &exynos4_clk_pdma0, + &exynos4_clk_pdma1, + &exynos4_clk_mdma1, + &exynos4_clk_fimd0, +}; + +static struct clksrc_clk *exynos4_clksrc_cdev[] = { + &exynos4_clk_sclk_uart0, + &exynos4_clk_sclk_uart1, + &exynos4_clk_sclk_uart2, + &exynos4_clk_sclk_uart3, + &exynos4_clk_sclk_mmc0, + &exynos4_clk_sclk_mmc1, + &exynos4_clk_sclk_mmc2, + &exynos4_clk_sclk_mmc3, + &exynos4_clk_sclk_spi0, + &exynos4_clk_sclk_spi1, + &exynos4_clk_sclk_spi2, + +}; + +static struct clk_lookup exynos4_clk_lookup[] = { + CLKDEV_INIT("exynos4210-uart.0", "clk_uart_baud0", &exynos4_clk_sclk_uart0.clk), + CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &exynos4_clk_sclk_uart1.clk), + CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &exynos4_clk_sclk_uart2.clk), + CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &exynos4_clk_sclk_uart3.clk), + CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &exynos4_clk_sclk_mmc0.clk), + CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &exynos4_clk_sclk_mmc1.clk), + CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &exynos4_clk_sclk_mmc2.clk), + CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &exynos4_clk_sclk_mmc3.clk), + CLKDEV_INIT("exynos4-fb.0", "lcd", &exynos4_clk_fimd0), + CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos4_clk_pdma0), + CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos4_clk_pdma1), + CLKDEV_INIT("dma-pl330.2", "apb_pclk", &exynos4_clk_mdma1), + CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk0", &exynos4_clk_sclk_spi0.clk), + CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk0", &exynos4_clk_sclk_spi1.clk), + CLKDEV_INIT("s3c64xx-spi.2", "spi_busclk0", &exynos4_clk_sclk_spi2.clk), +}; + +static int xtal_rate; + +static unsigned long exynos4_fout_apll_get_rate(struct clk *clk) +{ + if (soc_is_exynos4210()) + return s5p_get_pll45xx(xtal_rate, __raw_readl(EXYNOS4_APLL_CON0), + pll_4508); + else if (soc_is_exynos4212() || soc_is_exynos4412()) + return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS4_APLL_CON0)); + else + return 0; +} + +static struct clk_ops exynos4_fout_apll_ops = { + .get_rate = exynos4_fout_apll_get_rate, +}; + +static u32 exynos4_vpll_div[][8] = { + { 54000000, 3, 53, 3, 1024, 0, 17, 0 }, + { 108000000, 3, 53, 2, 1024, 0, 17, 0 }, +}; + +static unsigned long exynos4_vpll_get_rate(struct clk *clk) +{ + return clk->rate; +} + +static int exynos4_vpll_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned int vpll_con0, vpll_con1 = 0; + unsigned int i; + + /* Return if nothing changed */ + if (clk->rate == rate) + return 0; + + vpll_con0 = __raw_readl(EXYNOS4_VPLL_CON0); + vpll_con0 &= ~(0x1 << 27 | \ + PLL90XX_MDIV_MASK << PLL46XX_MDIV_SHIFT | \ + PLL90XX_PDIV_MASK << PLL46XX_PDIV_SHIFT | \ + PLL90XX_SDIV_MASK << PLL46XX_SDIV_SHIFT); + + vpll_con1 = __raw_readl(EXYNOS4_VPLL_CON1); + vpll_con1 &= ~(PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT | \ + PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT | \ + PLL4650C_KDIV_MASK << PLL46XX_KDIV_SHIFT); + + for (i = 0; i < ARRAY_SIZE(exynos4_vpll_div); i++) { + if (exynos4_vpll_div[i][0] == rate) { + vpll_con0 |= exynos4_vpll_div[i][1] << PLL46XX_PDIV_SHIFT; + vpll_con0 |= exynos4_vpll_div[i][2] << PLL46XX_MDIV_SHIFT; + vpll_con0 |= exynos4_vpll_div[i][3] << PLL46XX_SDIV_SHIFT; + vpll_con1 |= exynos4_vpll_div[i][4] << PLL46XX_KDIV_SHIFT; + vpll_con1 |= exynos4_vpll_div[i][5] << PLL46XX_MFR_SHIFT; + vpll_con1 |= exynos4_vpll_div[i][6] << PLL46XX_MRR_SHIFT; + vpll_con0 |= exynos4_vpll_div[i][7] << 27; + break; + } + } + + if (i == ARRAY_SIZE(exynos4_vpll_div)) { + printk(KERN_ERR "%s: Invalid Clock VPLL Frequency\n", + __func__); + return -EINVAL; + } + + __raw_writel(vpll_con0, EXYNOS4_VPLL_CON0); + __raw_writel(vpll_con1, EXYNOS4_VPLL_CON1); + + /* Wait for VPLL lock */ + while (!(__raw_readl(EXYNOS4_VPLL_CON0) & (1 << PLL46XX_LOCKED_SHIFT))) + continue; + + clk->rate = rate; + return 0; +} + +static struct clk_ops exynos4_vpll_ops = { + .get_rate = exynos4_vpll_get_rate, + .set_rate = exynos4_vpll_set_rate, +}; + +void __init_or_cpufreq exynos4_setup_clocks(void) +{ + struct clk *xtal_clk; + unsigned long apll = 0; + unsigned long mpll = 0; + unsigned long epll = 0; + unsigned long vpll = 0; + unsigned long vpllsrc; + unsigned long xtal; + unsigned long armclk; + unsigned long sclk_dmc; + unsigned long aclk_200; + unsigned long aclk_100; + unsigned long aclk_160; + unsigned long aclk_133; + unsigned int ptr; + + printk(KERN_DEBUG "%s: registering clocks\n", __func__); + + xtal_clk = clk_get(NULL, "xtal"); + BUG_ON(IS_ERR(xtal_clk)); + + xtal = clk_get_rate(xtal_clk); + + xtal_rate = xtal; + + clk_put(xtal_clk); + + printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal); + + if (soc_is_exynos4210()) { + apll = s5p_get_pll45xx(xtal, __raw_readl(EXYNOS4_APLL_CON0), + pll_4508); + mpll = s5p_get_pll45xx(xtal, __raw_readl(EXYNOS4_MPLL_CON0), + pll_4508); + epll = s5p_get_pll46xx(xtal, __raw_readl(EXYNOS4_EPLL_CON0), + __raw_readl(EXYNOS4_EPLL_CON1), pll_4600); + + vpllsrc = clk_get_rate(&exynos4_clk_vpllsrc.clk); + vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(EXYNOS4_VPLL_CON0), + __raw_readl(EXYNOS4_VPLL_CON1), pll_4650c); + } else if (soc_is_exynos4212() || soc_is_exynos4412()) { + apll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS4_APLL_CON0)); + mpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS4_MPLL_CON0)); + epll = s5p_get_pll36xx(xtal, __raw_readl(EXYNOS4_EPLL_CON0), + __raw_readl(EXYNOS4_EPLL_CON1)); + + vpllsrc = clk_get_rate(&exynos4_clk_vpllsrc.clk); + vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(EXYNOS4_VPLL_CON0), + __raw_readl(EXYNOS4_VPLL_CON1)); + } else { + /* nothing */ + } + + clk_fout_apll.ops = &exynos4_fout_apll_ops; + clk_fout_mpll.rate = mpll; + clk_fout_epll.rate = epll; + clk_fout_vpll.ops = &exynos4_vpll_ops; + clk_fout_vpll.rate = vpll; + + printk(KERN_INFO "EXYNOS4: PLL settings, A=%ld, M=%ld, E=%ld V=%ld", + apll, mpll, epll, vpll); + + armclk = clk_get_rate(&exynos4_clk_armclk.clk); + sclk_dmc = clk_get_rate(&exynos4_clk_sclk_dmc.clk); + + aclk_200 = clk_get_rate(&exynos4_clk_aclk_200.clk); + aclk_100 = clk_get_rate(&exynos4_clk_aclk_100.clk); + aclk_160 = clk_get_rate(&exynos4_clk_aclk_160.clk); + aclk_133 = clk_get_rate(&exynos4_clk_aclk_133.clk); + + printk(KERN_INFO "EXYNOS4: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n" + "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n", + armclk, sclk_dmc, aclk_200, + aclk_100, aclk_160, aclk_133); + + clk_f.rate = armclk; + clk_h.rate = sclk_dmc; + clk_p.rate = aclk_100; + + for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clksrcs); ptr++) + s3c_set_clksrc(&exynos4_clksrcs[ptr], true); +} + +static struct clk *exynos4_clks[] __initdata = { + &exynos4_clk_sclk_hdmi27m, + &exynos4_clk_sclk_hdmiphy, + &exynos4_clk_sclk_usbphy0, + &exynos4_clk_sclk_usbphy1, +}; + +#ifdef CONFIG_PM_SLEEP +static int exynos4_clock_suspend(void) +{ + s3c_pm_do_save(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save)); + return 0; +} + +static void exynos4_clock_resume(void) +{ + s3c_pm_do_restore_core(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save)); +} + +#else +#define exynos4_clock_suspend NULL +#define exynos4_clock_resume NULL +#endif + +static struct syscore_ops exynos4_clock_syscore_ops = { + .suspend = exynos4_clock_suspend, + .resume = exynos4_clock_resume, +}; + +void __init exynos4_register_clocks(void) +{ + int ptr; + + s3c24xx_register_clocks(exynos4_clks, ARRAY_SIZE(exynos4_clks)); + + for (ptr = 0; ptr < ARRAY_SIZE(exynos4_sysclks); ptr++) + s3c_register_clksrc(exynos4_sysclks[ptr], 1); + + for (ptr = 0; ptr < ARRAY_SIZE(exynos4_sclk_tv); ptr++) + s3c_register_clksrc(exynos4_sclk_tv[ptr], 1); + + for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clksrc_cdev); ptr++) + s3c_register_clksrc(exynos4_clksrc_cdev[ptr], 1); + + s3c_register_clksrc(exynos4_clksrcs, ARRAY_SIZE(exynos4_clksrcs)); + s3c_register_clocks(exynos4_init_clocks_on, ARRAY_SIZE(exynos4_init_clocks_on)); + + s3c24xx_register_clocks(exynos4_clk_cdev, ARRAY_SIZE(exynos4_clk_cdev)); + for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clk_cdev); ptr++) + s3c_disable_clocks(exynos4_clk_cdev[ptr], 1); + + s3c_register_clocks(exynos4_init_clocks_off, ARRAY_SIZE(exynos4_init_clocks_off)); + s3c_disable_clocks(exynos4_init_clocks_off, ARRAY_SIZE(exynos4_init_clocks_off)); + clkdev_add_table(exynos4_clk_lookup, ARRAY_SIZE(exynos4_clk_lookup)); + + register_syscore_ops(&exynos4_clock_syscore_ops); + s3c24xx_register_clock(&dummy_apb_pclk); + + s3c_pwmclk_init(); +} diff --git a/arch/arm/mach-exynos/clock-exynos4.h b/arch/arm/mach-exynos/clock-exynos4.h new file mode 100644 index 000000000000..cb71c29c14d1 --- /dev/null +++ b/arch/arm/mach-exynos/clock-exynos4.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Header file for exynos4 clock support + * + * 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. +*/ + +#ifndef __ASM_ARCH_CLOCK_H +#define __ASM_ARCH_CLOCK_H __FILE__ + +#include <linux/clk.h> + +extern struct clksrc_clk exynos4_clk_aclk_133; +extern struct clksrc_clk exynos4_clk_mout_mpll; + +extern struct clksrc_sources exynos4_clkset_mout_corebus; +extern struct clksrc_sources exynos4_clkset_group; + +extern struct clk *exynos4_clkset_aclk_top_list[]; +extern struct clk *exynos4_clkset_group_list[]; + +extern int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable); +extern int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable); +extern int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable); + +#endif /* __ASM_ARCH_CLOCK_H */ diff --git a/arch/arm/mach-exynos/clock-exynos4210.c b/arch/arm/mach-exynos/clock-exynos4210.c index 13312ccb2d93..3b131e4b6ef5 100644 --- a/arch/arm/mach-exynos/clock-exynos4210.c +++ b/arch/arm/mach-exynos/clock-exynos4210.c @@ -1,7 +1,5 @@ /* - * linux/arch/arm/mach-exynos4/clock-exynos4210.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. * http://www.samsung.com * * EXYNOS4210 - Clock support @@ -28,20 +26,20 @@ #include <mach/hardware.h> #include <mach/map.h> #include <mach/regs-clock.h> -#include <mach/exynos4-clock.h> #include "common.h" +#include "clock-exynos4.h" #ifdef CONFIG_PM_SLEEP static struct sleep_save exynos4210_clock_save[] = { - SAVE_ITEM(S5P_CLKSRC_IMAGE), - SAVE_ITEM(S5P_CLKSRC_LCD1), - SAVE_ITEM(S5P_CLKDIV_IMAGE), - SAVE_ITEM(S5P_CLKDIV_LCD1), - SAVE_ITEM(S5P_CLKSRC_MASK_LCD1), - SAVE_ITEM(S5P_CLKGATE_IP_IMAGE_4210), - SAVE_ITEM(S5P_CLKGATE_IP_LCD1), - SAVE_ITEM(S5P_CLKGATE_IP_PERIR_4210), + SAVE_ITEM(EXYNOS4_CLKSRC_IMAGE), + SAVE_ITEM(EXYNOS4_CLKDIV_IMAGE), + SAVE_ITEM(EXYNOS4210_CLKSRC_LCD1), + SAVE_ITEM(EXYNOS4210_CLKDIV_LCD1), + SAVE_ITEM(EXYNOS4210_CLKSRC_MASK_LCD1), + SAVE_ITEM(EXYNOS4210_CLKGATE_IP_IMAGE), + SAVE_ITEM(EXYNOS4210_CLKGATE_IP_LCD1), + SAVE_ITEM(EXYNOS4210_CLKGATE_IP_PERIR), }; #endif @@ -51,7 +49,7 @@ static struct clksrc_clk *sysclks[] = { static int exynos4_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable) { - return s5p_gatectrl(S5P_CLKSRC_MASK_LCD1, clk, enable); + return s5p_gatectrl(EXYNOS4210_CLKSRC_MASK_LCD1, clk, enable); } static struct clksrc_clk clksrcs[] = { @@ -62,9 +60,9 @@ static struct clksrc_clk clksrcs[] = { .enable = exynos4_clksrc_mask_fsys_ctrl, .ctrlbit = (1 << 24), }, - .sources = &clkset_mout_corebus, - .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 24, .size = 1 }, - .reg_div = { .reg = S5P_CLKDIV_FSYS0, .shift = 20, .size = 4 }, + .sources = &exynos4_clkset_mout_corebus, + .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 24, .size = 1 }, + .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS0, .shift = 20, .size = 4 }, }, { .clk = { .name = "sclk_fimd", @@ -72,9 +70,9 @@ static struct clksrc_clk clksrcs[] = { .enable = exynos4_clksrc_mask_lcd1_ctrl, .ctrlbit = (1 << 0), }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_LCD1, .shift = 0, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_LCD1, .shift = 0, .size = 4 }, + .sources = &exynos4_clkset_group, + .reg_src = { .reg = EXYNOS4210_CLKSRC_LCD1, .shift = 0, .size = 4 }, + .reg_div = { .reg = EXYNOS4210_CLKDIV_LCD1, .shift = 0, .size = 4 }, }, }; @@ -82,13 +80,13 @@ static struct clk init_clocks_off[] = { { .name = "sataphy", .id = -1, - .parent = &clk_aclk_133.clk, + .parent = &exynos4_clk_aclk_133.clk, .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit = (1 << 3), }, { .name = "sata", .id = -1, - .parent = &clk_aclk_133.clk, + .parent = &exynos4_clk_aclk_133.clk, .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit = (1 << 10), }, { @@ -117,7 +115,7 @@ static void exynos4210_clock_resume(void) #define exynos4210_clock_resume NULL #endif -struct syscore_ops exynos4210_clock_syscore_ops = { +static struct syscore_ops exynos4210_clock_syscore_ops = { .suspend = exynos4210_clock_suspend, .resume = exynos4210_clock_resume, }; @@ -126,9 +124,9 @@ void __init exynos4210_register_clocks(void) { int ptr; - clk_mout_mpll.reg_src.reg = S5P_CLKSRC_CPU; - clk_mout_mpll.reg_src.shift = 8; - clk_mout_mpll.reg_src.size = 1; + exynos4_clk_mout_mpll.reg_src.reg = EXYNOS4_CLKSRC_CPU; + exynos4_clk_mout_mpll.reg_src.shift = 8; + exynos4_clk_mout_mpll.reg_src.size = 1; for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) s3c_register_clksrc(sysclks[ptr], 1); diff --git a/arch/arm/mach-exynos/clock-exynos4212.c b/arch/arm/mach-exynos/clock-exynos4212.c index 48af28566fa1..3ecc01e06f74 100644 --- a/arch/arm/mach-exynos/clock-exynos4212.c +++ b/arch/arm/mach-exynos/clock-exynos4212.c @@ -1,7 +1,5 @@ /* - * linux/arch/arm/mach-exynos4/clock-exynos4212.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. * http://www.samsung.com * * EXYNOS4212 - Clock support @@ -28,22 +26,22 @@ #include <mach/hardware.h> #include <mach/map.h> #include <mach/regs-clock.h> -#include <mach/exynos4-clock.h> #include "common.h" +#include "clock-exynos4.h" #ifdef CONFIG_PM_SLEEP static struct sleep_save exynos4212_clock_save[] = { - SAVE_ITEM(S5P_CLKSRC_IMAGE), - SAVE_ITEM(S5P_CLKDIV_IMAGE), - SAVE_ITEM(S5P_CLKGATE_IP_IMAGE_4212), - SAVE_ITEM(S5P_CLKGATE_IP_PERIR_4212), + SAVE_ITEM(EXYNOS4_CLKSRC_IMAGE), + SAVE_ITEM(EXYNOS4_CLKDIV_IMAGE), + SAVE_ITEM(EXYNOS4212_CLKGATE_IP_IMAGE), + SAVE_ITEM(EXYNOS4212_CLKGATE_IP_PERIR), }; #endif static struct clk *clk_src_mpll_user_list[] = { [0] = &clk_fin_mpll, - [1] = &clk_mout_mpll.clk, + [1] = &exynos4_clk_mout_mpll.clk, }; static struct clksrc_sources clk_src_mpll_user = { @@ -56,7 +54,7 @@ static struct clksrc_clk clk_mout_mpll_user = { .name = "mout_mpll_user", }, .sources = &clk_src_mpll_user, - .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 24, .size = 1 }, + .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 24, .size = 1 }, }; static struct clksrc_clk *sysclks[] = { @@ -89,7 +87,7 @@ static void exynos4212_clock_resume(void) #define exynos4212_clock_resume NULL #endif -struct syscore_ops exynos4212_clock_syscore_ops = { +static struct syscore_ops exynos4212_clock_syscore_ops = { .suspend = exynos4212_clock_suspend, .resume = exynos4212_clock_resume, }; @@ -99,15 +97,15 @@ void __init exynos4212_register_clocks(void) int ptr; /* usbphy1 is removed */ - clkset_group_list[4] = NULL; + exynos4_clkset_group_list[4] = NULL; /* mout_mpll_user is used */ - clkset_group_list[6] = &clk_mout_mpll_user.clk; - clkset_aclk_top_list[0] = &clk_mout_mpll_user.clk; + exynos4_clkset_group_list[6] = &clk_mout_mpll_user.clk; + exynos4_clkset_aclk_top_list[0] = &clk_mout_mpll_user.clk; - clk_mout_mpll.reg_src.reg = S5P_CLKSRC_DMC; - clk_mout_mpll.reg_src.shift = 12; - clk_mout_mpll.reg_src.size = 1; + exynos4_clk_mout_mpll.reg_src.reg = EXYNOS4_CLKSRC_DMC; + exynos4_clk_mout_mpll.reg_src.shift = 12; + exynos4_clk_mout_mpll.reg_src.size = 1; for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) s3c_register_clksrc(sysclks[ptr], 1); diff --git a/arch/arm/mach-exynos/clock-exynos5.c b/arch/arm/mach-exynos/clock-exynos5.c new file mode 100644 index 000000000000..d013982d0f8e --- /dev/null +++ b/arch/arm/mach-exynos/clock-exynos5.c @@ -0,0 +1,1247 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Clock support for EXYNOS5 SoCs + * + * 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 <linux/kernel.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/syscore_ops.h> + +#include <plat/cpu-freq.h> +#include <plat/clock.h> +#include <plat/cpu.h> +#include <plat/pll.h> +#include <plat/s5p-clock.h> +#include <plat/clock-clksrc.h> +#include <plat/pm.h> + +#include <mach/map.h> +#include <mach/regs-clock.h> +#include <mach/sysmmu.h> + +#include "common.h" + +#ifdef CONFIG_PM_SLEEP +static struct sleep_save exynos5_clock_save[] = { + /* will be implemented */ +}; +#endif + +static struct clk exynos5_clk_sclk_dptxphy = { + .name = "sclk_dptx", +}; + +static struct clk exynos5_clk_sclk_hdmi24m = { + .name = "sclk_hdmi24m", + .rate = 24000000, +}; + +static struct clk exynos5_clk_sclk_hdmi27m = { + .name = "sclk_hdmi27m", + .rate = 27000000, +}; + +static struct clk exynos5_clk_sclk_hdmiphy = { + .name = "sclk_hdmiphy", +}; + +static struct clk exynos5_clk_sclk_usbphy = { + .name = "sclk_usbphy", + .rate = 48000000, +}; + +static int exynos5_clksrc_mask_top_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_TOP, clk, enable); +} + +static int exynos5_clksrc_mask_disp1_0_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_DISP1_0, clk, enable); +} + +static int exynos5_clksrc_mask_fsys_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_FSYS, clk, enable); +} + +static int exynos5_clksrc_mask_gscl_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_GSCL, clk, enable); +} + +static int exynos5_clksrc_mask_peric0_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_PERIC0, clk, enable); +} + +static int exynos5_clk_ip_core_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS5_CLKGATE_IP_CORE, clk, enable); +} + +static int exynos5_clk_ip_disp1_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS5_CLKGATE_IP_DISP1, clk, enable); +} + +static int exynos5_clk_ip_fsys_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS5_CLKGATE_IP_FSYS, clk, enable); +} + +static int exynos5_clk_block_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS5_CLKGATE_BLOCK, clk, enable); +} + +static int exynos5_clk_ip_gen_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS5_CLKGATE_IP_GEN, clk, enable); +} + +static int exynos5_clk_ip_gps_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS5_CLKGATE_IP_GPS, clk, enable); +} + +static int exynos5_clk_ip_mfc_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS5_CLKGATE_IP_MFC, clk, enable); +} + +static int exynos5_clk_ip_peric_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS5_CLKGATE_IP_PERIC, clk, enable); +} + +static int exynos5_clk_ip_peris_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS5_CLKGATE_IP_PERIS, clk, enable); +} + +/* Core list of CMU_CPU side */ + +static struct clksrc_clk exynos5_clk_mout_apll = { + .clk = { + .name = "mout_apll", + }, + .sources = &clk_src_apll, + .reg_src = { .reg = EXYNOS5_CLKSRC_CPU, .shift = 0, .size = 1 }, +}; + +static struct clksrc_clk exynos5_clk_sclk_apll = { + .clk = { + .name = "sclk_apll", + .parent = &exynos5_clk_mout_apll.clk, + }, + .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 24, .size = 3 }, +}; + +static struct clksrc_clk exynos5_clk_mout_bpll = { + .clk = { + .name = "mout_bpll", + }, + .sources = &clk_src_bpll, + .reg_src = { .reg = EXYNOS5_CLKSRC_CDREX, .shift = 0, .size = 1 }, +}; + +static struct clk *exynos5_clk_src_bpll_user_list[] = { + [0] = &clk_fin_mpll, + [1] = &exynos5_clk_mout_bpll.clk, +}; + +static struct clksrc_sources exynos5_clk_src_bpll_user = { + .sources = exynos5_clk_src_bpll_user_list, + .nr_sources = ARRAY_SIZE(exynos5_clk_src_bpll_user_list), +}; + +static struct clksrc_clk exynos5_clk_mout_bpll_user = { + .clk = { + .name = "mout_bpll_user", + }, + .sources = &exynos5_clk_src_bpll_user, + .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 24, .size = 1 }, +}; + +static struct clksrc_clk exynos5_clk_mout_cpll = { + .clk = { + .name = "mout_cpll", + }, + .sources = &clk_src_cpll, + .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 8, .size = 1 }, +}; + +static struct clksrc_clk exynos5_clk_mout_epll = { + .clk = { + .name = "mout_epll", + }, + .sources = &clk_src_epll, + .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 12, .size = 1 }, +}; + +struct clksrc_clk exynos5_clk_mout_mpll = { + .clk = { + .name = "mout_mpll", + }, + .sources = &clk_src_mpll, + .reg_src = { .reg = EXYNOS5_CLKSRC_CORE1, .shift = 8, .size = 1 }, +}; + +static struct clk *exynos_clkset_vpllsrc_list[] = { + [0] = &clk_fin_vpll, + [1] = &exynos5_clk_sclk_hdmi27m, +}; + +static struct clksrc_sources exynos5_clkset_vpllsrc = { + .sources = exynos_clkset_vpllsrc_list, + .nr_sources = ARRAY_SIZE(exynos_clkset_vpllsrc_list), +}; + +static struct clksrc_clk exynos5_clk_vpllsrc = { + .clk = { + .name = "vpll_src", + .enable = exynos5_clksrc_mask_top_ctrl, + .ctrlbit = (1 << 0), + }, + .sources = &exynos5_clkset_vpllsrc, + .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 0, .size = 1 }, +}; + +static struct clk *exynos5_clkset_sclk_vpll_list[] = { + [0] = &exynos5_clk_vpllsrc.clk, + [1] = &clk_fout_vpll, +}; + +static struct clksrc_sources exynos5_clkset_sclk_vpll = { + .sources = exynos5_clkset_sclk_vpll_list, + .nr_sources = ARRAY_SIZE(exynos5_clkset_sclk_vpll_list), +}; + +static struct clksrc_clk exynos5_clk_sclk_vpll = { + .clk = { + .name = "sclk_vpll", + }, + .sources = &exynos5_clkset_sclk_vpll, + .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 16, .size = 1 }, +}; + +static struct clksrc_clk exynos5_clk_sclk_pixel = { + .clk = { + .name = "sclk_pixel", + .parent = &exynos5_clk_sclk_vpll.clk, + }, + .reg_div = { .reg = EXYNOS5_CLKDIV_DISP1_0, .shift = 28, .size = 4 }, +}; + +static struct clk *exynos5_clkset_sclk_hdmi_list[] = { + [0] = &exynos5_clk_sclk_pixel.clk, + [1] = &exynos5_clk_sclk_hdmiphy, +}; + +static struct clksrc_sources exynos5_clkset_sclk_hdmi = { + .sources = exynos5_clkset_sclk_hdmi_list, + .nr_sources = ARRAY_SIZE(exynos5_clkset_sclk_hdmi_list), +}; + +static struct clksrc_clk exynos5_clk_sclk_hdmi = { + .clk = { + .name = "sclk_hdmi", + .enable = exynos5_clksrc_mask_disp1_0_ctrl, + .ctrlbit = (1 << 20), + }, + .sources = &exynos5_clkset_sclk_hdmi, + .reg_src = { .reg = EXYNOS5_CLKSRC_DISP1_0, .shift = 20, .size = 1 }, +}; + +static struct clksrc_clk *exynos5_sclk_tv[] = { + &exynos5_clk_sclk_pixel, + &exynos5_clk_sclk_hdmi, +}; + +static struct clk *exynos5_clk_src_mpll_user_list[] = { + [0] = &clk_fin_mpll, + [1] = &exynos5_clk_mout_mpll.clk, +}; + +static struct clksrc_sources exynos5_clk_src_mpll_user = { + .sources = exynos5_clk_src_mpll_user_list, + .nr_sources = ARRAY_SIZE(exynos5_clk_src_mpll_user_list), +}; + +static struct clksrc_clk exynos5_clk_mout_mpll_user = { + .clk = { + .name = "mout_mpll_user", + }, + .sources = &exynos5_clk_src_mpll_user, + .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 20, .size = 1 }, +}; + +static struct clk *exynos5_clkset_mout_cpu_list[] = { + [0] = &exynos5_clk_mout_apll.clk, + [1] = &exynos5_clk_mout_mpll.clk, +}; + +static struct clksrc_sources exynos5_clkset_mout_cpu = { + .sources = exynos5_clkset_mout_cpu_list, + .nr_sources = ARRAY_SIZE(exynos5_clkset_mout_cpu_list), +}; + +static struct clksrc_clk exynos5_clk_mout_cpu = { + .clk = { + .name = "mout_cpu", + }, + .sources = &exynos5_clkset_mout_cpu, + .reg_src = { .reg = EXYNOS5_CLKSRC_CPU, .shift = 16, .size = 1 }, +}; + +static struct clksrc_clk exynos5_clk_dout_armclk = { + .clk = { + .name = "dout_armclk", + .parent = &exynos5_clk_mout_cpu.clk, + }, + .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 0, .size = 3 }, +}; + +static struct clksrc_clk exynos5_clk_dout_arm2clk = { + .clk = { + .name = "dout_arm2clk", + .parent = &exynos5_clk_dout_armclk.clk, + }, + .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 28, .size = 3 }, +}; + +static struct clk exynos5_clk_armclk = { + .name = "armclk", + .parent = &exynos5_clk_dout_arm2clk.clk, +}; + +/* Core list of CMU_CDREX side */ + +static struct clk *exynos5_clkset_cdrex_list[] = { + [0] = &exynos5_clk_mout_mpll.clk, + [1] = &exynos5_clk_mout_bpll.clk, +}; + +static struct clksrc_sources exynos5_clkset_cdrex = { + .sources = exynos5_clkset_cdrex_list, + .nr_sources = ARRAY_SIZE(exynos5_clkset_cdrex_list), +}; + +static struct clksrc_clk exynos5_clk_cdrex = { + .clk = { + .name = "clk_cdrex", + }, + .sources = &exynos5_clkset_cdrex, + .reg_src = { .reg = EXYNOS5_CLKSRC_CDREX, .shift = 4, .size = 1 }, + .reg_div = { .reg = EXYNOS5_CLKDIV_CDREX, .shift = 16, .size = 3 }, +}; + +static struct clksrc_clk exynos5_clk_aclk_acp = { + .clk = { + .name = "aclk_acp", + .parent = &exynos5_clk_mout_mpll.clk, + }, + .reg_div = { .reg = EXYNOS5_CLKDIV_ACP, .shift = 0, .size = 3 }, +}; + +static struct clksrc_clk exynos5_clk_pclk_acp = { + .clk = { + .name = "pclk_acp", + .parent = &exynos5_clk_aclk_acp.clk, + }, + .reg_div = { .reg = EXYNOS5_CLKDIV_ACP, .shift = 4, .size = 3 }, +}; + +/* Core list of CMU_TOP side */ + +struct clk *exynos5_clkset_aclk_top_list[] = { + [0] = &exynos5_clk_mout_mpll_user.clk, + [1] = &exynos5_clk_mout_bpll_user.clk, +}; + +struct clksrc_sources exynos5_clkset_aclk = { + .sources = exynos5_clkset_aclk_top_list, + .nr_sources = ARRAY_SIZE(exynos5_clkset_aclk_top_list), +}; + +static struct clksrc_clk exynos5_clk_aclk_400 = { + .clk = { + .name = "aclk_400", + }, + .sources = &exynos5_clkset_aclk, + .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 20, .size = 1 }, + .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 }, +}; + +struct clk *exynos5_clkset_aclk_333_166_list[] = { + [0] = &exynos5_clk_mout_cpll.clk, + [1] = &exynos5_clk_mout_mpll_user.clk, +}; + +struct clksrc_sources exynos5_clkset_aclk_333_166 = { + .sources = exynos5_clkset_aclk_333_166_list, + .nr_sources = ARRAY_SIZE(exynos5_clkset_aclk_333_166_list), +}; + +static struct clksrc_clk exynos5_clk_aclk_333 = { + .clk = { + .name = "aclk_333", + }, + .sources = &exynos5_clkset_aclk_333_166, + .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 16, .size = 1 }, + .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 20, .size = 3 }, +}; + +static struct clksrc_clk exynos5_clk_aclk_166 = { + .clk = { + .name = "aclk_166", + }, + .sources = &exynos5_clkset_aclk_333_166, + .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 8, .size = 1 }, + .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 8, .size = 3 }, +}; + +static struct clksrc_clk exynos5_clk_aclk_266 = { + .clk = { + .name = "aclk_266", + .parent = &exynos5_clk_mout_mpll_user.clk, + }, + .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 16, .size = 3 }, +}; + +static struct clksrc_clk exynos5_clk_aclk_200 = { + .clk = { + .name = "aclk_200", + }, + .sources = &exynos5_clkset_aclk, + .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 12, .size = 1 }, + .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 12, .size = 3 }, +}; + +static struct clksrc_clk exynos5_clk_aclk_66_pre = { + .clk = { + .name = "aclk_66_pre", + .parent = &exynos5_clk_mout_mpll_user.clk, + }, + .reg_div = { .reg = EXYNOS5_CLKDIV_TOP1, .shift = 24, .size = 3 }, +}; + +static struct clksrc_clk exynos5_clk_aclk_66 = { + .clk = { + .name = "aclk_66", + .parent = &exynos5_clk_aclk_66_pre.clk, + }, + .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 0, .size = 3 }, +}; + +static struct clk exynos5_init_clocks_off[] = { + { + .name = "timers", + .parent = &exynos5_clk_aclk_66.clk, + .enable = exynos5_clk_ip_peric_ctrl, + .ctrlbit = (1 << 24), + }, { + .name = "rtc", + .parent = &exynos5_clk_aclk_66.clk, + .enable = exynos5_clk_ip_peris_ctrl, + .ctrlbit = (1 << 20), + }, { + .name = "hsmmc", + .devname = "s3c-sdhci.0", + .parent = &exynos5_clk_aclk_200.clk, + .enable = exynos5_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 12), + }, { + .name = "hsmmc", + .devname = "s3c-sdhci.1", + .parent = &exynos5_clk_aclk_200.clk, + .enable = exynos5_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 13), + }, { + .name = "hsmmc", + .devname = "s3c-sdhci.2", + .parent = &exynos5_clk_aclk_200.clk, + .enable = exynos5_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 14), + }, { + .name = "hsmmc", + .devname = "s3c-sdhci.3", + .parent = &exynos5_clk_aclk_200.clk, + .enable = exynos5_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 15), + }, { + .name = "dwmci", + .parent = &exynos5_clk_aclk_200.clk, + .enable = exynos5_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 16), + }, { + .name = "sata", + .devname = "ahci", + .enable = exynos5_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 6), + }, { + .name = "sata_phy", + .enable = exynos5_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 24), + }, { + .name = "sata_phy_i2c", + .enable = exynos5_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 25), + }, { + .name = "mfc", + .devname = "s5p-mfc", + .enable = exynos5_clk_ip_mfc_ctrl, + .ctrlbit = (1 << 0), + }, { + .name = "hdmi", + .devname = "exynos4-hdmi", + .enable = exynos5_clk_ip_disp1_ctrl, + .ctrlbit = (1 << 6), + }, { + .name = "mixer", + .devname = "s5p-mixer", + .enable = exynos5_clk_ip_disp1_ctrl, + .ctrlbit = (1 << 5), + }, { + .name = "jpeg", + .enable = exynos5_clk_ip_gen_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = "dsim0", + .enable = exynos5_clk_ip_disp1_ctrl, + .ctrlbit = (1 << 3), + }, { + .name = "iis", + .devname = "samsung-i2s.1", + .enable = exynos5_clk_ip_peric_ctrl, + .ctrlbit = (1 << 20), + }, { + .name = "iis", + .devname = "samsung-i2s.2", + .enable = exynos5_clk_ip_peric_ctrl, + .ctrlbit = (1 << 21), + }, { + .name = "pcm", + .devname = "samsung-pcm.1", + .enable = exynos5_clk_ip_peric_ctrl, + .ctrlbit = (1 << 22), + }, { + .name = "pcm", + .devname = "samsung-pcm.2", + .enable = exynos5_clk_ip_peric_ctrl, + .ctrlbit = (1 << 23), + }, { + .name = "spdif", + .devname = "samsung-spdif", + .enable = exynos5_clk_ip_peric_ctrl, + .ctrlbit = (1 << 26), + }, { + .name = "ac97", + .devname = "samsung-ac97", + .enable = exynos5_clk_ip_peric_ctrl, + .ctrlbit = (1 << 27), + }, { + .name = "usbhost", + .enable = exynos5_clk_ip_fsys_ctrl , + .ctrlbit = (1 << 18), + }, { + .name = "usbotg", + .enable = exynos5_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 7), + }, { + .name = "gps", + .enable = exynos5_clk_ip_gps_ctrl, + .ctrlbit = ((1 << 3) | (1 << 2) | (1 << 0)), + }, { + .name = "nfcon", + .enable = exynos5_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 22), + }, { + .name = "iop", + .enable = exynos5_clk_ip_fsys_ctrl, + .ctrlbit = ((1 << 30) | (1 << 26) | (1 << 23)), + }, { + .name = "core_iop", + .enable = exynos5_clk_ip_core_ctrl, + .ctrlbit = ((1 << 21) | (1 << 3)), + }, { + .name = "mcu_iop", + .enable = exynos5_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 0), + }, { + .name = "i2c", + .devname = "s3c2440-i2c.0", + .parent = &exynos5_clk_aclk_66.clk, + .enable = exynos5_clk_ip_peric_ctrl, + .ctrlbit = (1 << 6), + }, { + .name = "i2c", + .devname = "s3c2440-i2c.1", + .parent = &exynos5_clk_aclk_66.clk, + .enable = exynos5_clk_ip_peric_ctrl, + .ctrlbit = (1 << 7), + }, { + .name = "i2c", + .devname = "s3c2440-i2c.2", + .parent = &exynos5_clk_aclk_66.clk, + .enable = exynos5_clk_ip_peric_ctrl, + .ctrlbit = (1 << 8), + }, { + .name = "i2c", + .devname = "s3c2440-i2c.3", + .parent = &exynos5_clk_aclk_66.clk, + .enable = exynos5_clk_ip_peric_ctrl, + .ctrlbit = (1 << 9), + }, { + .name = "i2c", + .devname = "s3c2440-i2c.4", + .parent = &exynos5_clk_aclk_66.clk, + .enable = exynos5_clk_ip_peric_ctrl, + .ctrlbit = (1 << 10), + }, { + .name = "i2c", + .devname = "s3c2440-i2c.5", + .parent = &exynos5_clk_aclk_66.clk, + .enable = exynos5_clk_ip_peric_ctrl, + .ctrlbit = (1 << 11), + }, { + .name = "i2c", + .devname = "s3c2440-i2c.6", + .parent = &exynos5_clk_aclk_66.clk, + .enable = exynos5_clk_ip_peric_ctrl, + .ctrlbit = (1 << 12), + }, { + .name = "i2c", + .devname = "s3c2440-i2c.7", + .parent = &exynos5_clk_aclk_66.clk, + .enable = exynos5_clk_ip_peric_ctrl, + .ctrlbit = (1 << 13), + }, { + .name = "i2c", + .devname = "s3c2440-hdmiphy-i2c", + .parent = &exynos5_clk_aclk_66.clk, + .enable = exynos5_clk_ip_peric_ctrl, + .ctrlbit = (1 << 14), + } +}; + +static struct clk exynos5_init_clocks_on[] = { + { + .name = "uart", + .devname = "s5pv210-uart.0", + .enable = exynos5_clk_ip_peric_ctrl, + .ctrlbit = (1 << 0), + }, { + .name = "uart", + .devname = "s5pv210-uart.1", + .enable = exynos5_clk_ip_peric_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "uart", + .devname = "s5pv210-uart.2", + .enable = exynos5_clk_ip_peric_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = "uart", + .devname = "s5pv210-uart.3", + .enable = exynos5_clk_ip_peric_ctrl, + .ctrlbit = (1 << 3), + }, { + .name = "uart", + .devname = "s5pv210-uart.4", + .enable = exynos5_clk_ip_peric_ctrl, + .ctrlbit = (1 << 4), + }, { + .name = "uart", + .devname = "s5pv210-uart.5", + .enable = exynos5_clk_ip_peric_ctrl, + .ctrlbit = (1 << 5), + } +}; + +static struct clk exynos5_clk_pdma0 = { + .name = "dma", + .devname = "dma-pl330.0", + .enable = exynos5_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 1), +}; + +static struct clk exynos5_clk_pdma1 = { + .name = "dma", + .devname = "dma-pl330.1", + .enable = exynos5_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 1), +}; + +static struct clk exynos5_clk_mdma1 = { + .name = "dma", + .devname = "dma-pl330.2", + .enable = exynos5_clk_ip_gen_ctrl, + .ctrlbit = (1 << 4), +}; + +struct clk *exynos5_clkset_group_list[] = { + [0] = &clk_ext_xtal_mux, + [1] = NULL, + [2] = &exynos5_clk_sclk_hdmi24m, + [3] = &exynos5_clk_sclk_dptxphy, + [4] = &exynos5_clk_sclk_usbphy, + [5] = &exynos5_clk_sclk_hdmiphy, + [6] = &exynos5_clk_mout_mpll_user.clk, + [7] = &exynos5_clk_mout_epll.clk, + [8] = &exynos5_clk_sclk_vpll.clk, + [9] = &exynos5_clk_mout_cpll.clk, +}; + +struct clksrc_sources exynos5_clkset_group = { + .sources = exynos5_clkset_group_list, + .nr_sources = ARRAY_SIZE(exynos5_clkset_group_list), +}; + +/* Possible clock sources for aclk_266_gscl_sub Mux */ +static struct clk *clk_src_gscl_266_list[] = { + [0] = &clk_ext_xtal_mux, + [1] = &exynos5_clk_aclk_266.clk, +}; + +static struct clksrc_sources clk_src_gscl_266 = { + .sources = clk_src_gscl_266_list, + .nr_sources = ARRAY_SIZE(clk_src_gscl_266_list), +}; + +static struct clksrc_clk exynos5_clk_dout_mmc0 = { + .clk = { + .name = "dout_mmc0", + }, + .sources = &exynos5_clkset_group, + .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 0, .size = 4 }, + .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 0, .size = 4 }, +}; + +static struct clksrc_clk exynos5_clk_dout_mmc1 = { + .clk = { + .name = "dout_mmc1", + }, + .sources = &exynos5_clkset_group, + .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 4, .size = 4 }, + .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 16, .size = 4 }, +}; + +static struct clksrc_clk exynos5_clk_dout_mmc2 = { + .clk = { + .name = "dout_mmc2", + }, + .sources = &exynos5_clkset_group, + .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 8, .size = 4 }, + .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 0, .size = 4 }, +}; + +static struct clksrc_clk exynos5_clk_dout_mmc3 = { + .clk = { + .name = "dout_mmc3", + }, + .sources = &exynos5_clkset_group, + .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 12, .size = 4 }, + .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 16, .size = 4 }, +}; + +static struct clksrc_clk exynos5_clk_dout_mmc4 = { + .clk = { + .name = "dout_mmc4", + }, + .sources = &exynos5_clkset_group, + .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 16, .size = 4 }, + .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS3, .shift = 0, .size = 4 }, +}; + +static struct clksrc_clk exynos5_clk_sclk_uart0 = { + .clk = { + .name = "uclk1", + .devname = "exynos4210-uart.0", + .enable = exynos5_clksrc_mask_peric0_ctrl, + .ctrlbit = (1 << 0), + }, + .sources = &exynos5_clkset_group, + .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 0, .size = 4 }, + .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 0, .size = 4 }, +}; + +static struct clksrc_clk exynos5_clk_sclk_uart1 = { + .clk = { + .name = "uclk1", + .devname = "exynos4210-uart.1", + .enable = exynos5_clksrc_mask_peric0_ctrl, + .ctrlbit = (1 << 4), + }, + .sources = &exynos5_clkset_group, + .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 4, .size = 4 }, + .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 4, .size = 4 }, +}; + +static struct clksrc_clk exynos5_clk_sclk_uart2 = { + .clk = { + .name = "uclk1", + .devname = "exynos4210-uart.2", + .enable = exynos5_clksrc_mask_peric0_ctrl, + .ctrlbit = (1 << 8), + }, + .sources = &exynos5_clkset_group, + .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 8, .size = 4 }, + .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 8, .size = 4 }, +}; + +static struct clksrc_clk exynos5_clk_sclk_uart3 = { + .clk = { + .name = "uclk1", + .devname = "exynos4210-uart.3", + .enable = exynos5_clksrc_mask_peric0_ctrl, + .ctrlbit = (1 << 12), + }, + .sources = &exynos5_clkset_group, + .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 12, .size = 4 }, + .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 12, .size = 4 }, +}; + +static struct clksrc_clk exynos5_clk_sclk_mmc0 = { + .clk = { + .name = "sclk_mmc", + .devname = "s3c-sdhci.0", + .parent = &exynos5_clk_dout_mmc0.clk, + .enable = exynos5_clksrc_mask_fsys_ctrl, + .ctrlbit = (1 << 0), + }, + .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 8, .size = 8 }, +}; + +static struct clksrc_clk exynos5_clk_sclk_mmc1 = { + .clk = { + .name = "sclk_mmc", + .devname = "s3c-sdhci.1", + .parent = &exynos5_clk_dout_mmc1.clk, + .enable = exynos5_clksrc_mask_fsys_ctrl, + .ctrlbit = (1 << 4), + }, + .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 24, .size = 8 }, +}; + +static struct clksrc_clk exynos5_clk_sclk_mmc2 = { + .clk = { + .name = "sclk_mmc", + .devname = "s3c-sdhci.2", + .parent = &exynos5_clk_dout_mmc2.clk, + .enable = exynos5_clksrc_mask_fsys_ctrl, + .ctrlbit = (1 << 8), + }, + .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 8, .size = 8 }, +}; + +static struct clksrc_clk exynos5_clk_sclk_mmc3 = { + .clk = { + .name = "sclk_mmc", + .devname = "s3c-sdhci.3", + .parent = &exynos5_clk_dout_mmc3.clk, + .enable = exynos5_clksrc_mask_fsys_ctrl, + .ctrlbit = (1 << 12), + }, + .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 24, .size = 8 }, +}; + +static struct clksrc_clk exynos5_clksrcs[] = { + { + .clk = { + .name = "sclk_dwmci", + .parent = &exynos5_clk_dout_mmc4.clk, + .enable = exynos5_clksrc_mask_fsys_ctrl, + .ctrlbit = (1 << 16), + }, + .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS3, .shift = 8, .size = 8 }, + }, { + .clk = { + .name = "sclk_fimd", + .devname = "s3cfb.1", + .enable = exynos5_clksrc_mask_disp1_0_ctrl, + .ctrlbit = (1 << 0), + }, + .sources = &exynos5_clkset_group, + .reg_src = { .reg = EXYNOS5_CLKSRC_DISP1_0, .shift = 0, .size = 4 }, + .reg_div = { .reg = EXYNOS5_CLKDIV_DISP1_0, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "aclk_266_gscl", + }, + .sources = &clk_src_gscl_266, + .reg_src = { .reg = EXYNOS5_CLKSRC_TOP3, .shift = 8, .size = 1 }, + }, { + .clk = { + .name = "sclk_g3d", + .devname = "mali-t604.0", + .enable = exynos5_clk_block_ctrl, + .ctrlbit = (1 << 1), + }, + .sources = &exynos5_clkset_aclk, + .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 20, .size = 1 }, + .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 }, + }, { + .clk = { + .name = "sclk_gscl_wrap", + .devname = "s5p-mipi-csis.0", + .enable = exynos5_clksrc_mask_gscl_ctrl, + .ctrlbit = (1 << 24), + }, + .sources = &exynos5_clkset_group, + .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 24, .size = 4 }, + .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 24, .size = 4 }, + }, { + .clk = { + .name = "sclk_gscl_wrap", + .devname = "s5p-mipi-csis.1", + .enable = exynos5_clksrc_mask_gscl_ctrl, + .ctrlbit = (1 << 28), + }, + .sources = &exynos5_clkset_group, + .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 28, .size = 4 }, + .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 28, .size = 4 }, + }, { + .clk = { + .name = "sclk_cam0", + .enable = exynos5_clksrc_mask_gscl_ctrl, + .ctrlbit = (1 << 16), + }, + .sources = &exynos5_clkset_group, + .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 16, .size = 4 }, + .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 16, .size = 4 }, + }, { + .clk = { + .name = "sclk_cam1", + .enable = exynos5_clksrc_mask_gscl_ctrl, + .ctrlbit = (1 << 20), + }, + .sources = &exynos5_clkset_group, + .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 20, .size = 4 }, + .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 20, .size = 4 }, + }, { + .clk = { + .name = "sclk_jpeg", + .parent = &exynos5_clk_mout_cpll.clk, + }, + .reg_div = { .reg = EXYNOS5_CLKDIV_GEN, .shift = 4, .size = 3 }, + }, +}; + +/* Clock initialization code */ +static struct clksrc_clk *exynos5_sysclks[] = { + &exynos5_clk_mout_apll, + &exynos5_clk_sclk_apll, + &exynos5_clk_mout_bpll, + &exynos5_clk_mout_bpll_user, + &exynos5_clk_mout_cpll, + &exynos5_clk_mout_epll, + &exynos5_clk_mout_mpll, + &exynos5_clk_mout_mpll_user, + &exynos5_clk_vpllsrc, + &exynos5_clk_sclk_vpll, + &exynos5_clk_mout_cpu, + &exynos5_clk_dout_armclk, + &exynos5_clk_dout_arm2clk, + &exynos5_clk_cdrex, + &exynos5_clk_aclk_400, + &exynos5_clk_aclk_333, + &exynos5_clk_aclk_266, + &exynos5_clk_aclk_200, + &exynos5_clk_aclk_166, + &exynos5_clk_aclk_66_pre, + &exynos5_clk_aclk_66, + &exynos5_clk_dout_mmc0, + &exynos5_clk_dout_mmc1, + &exynos5_clk_dout_mmc2, + &exynos5_clk_dout_mmc3, + &exynos5_clk_dout_mmc4, + &exynos5_clk_aclk_acp, + &exynos5_clk_pclk_acp, +}; + +static struct clk *exynos5_clk_cdev[] = { + &exynos5_clk_pdma0, + &exynos5_clk_pdma1, + &exynos5_clk_mdma1, +}; + +static struct clksrc_clk *exynos5_clksrc_cdev[] = { + &exynos5_clk_sclk_uart0, + &exynos5_clk_sclk_uart1, + &exynos5_clk_sclk_uart2, + &exynos5_clk_sclk_uart3, + &exynos5_clk_sclk_mmc0, + &exynos5_clk_sclk_mmc1, + &exynos5_clk_sclk_mmc2, + &exynos5_clk_sclk_mmc3, +}; + +static struct clk_lookup exynos5_clk_lookup[] = { + CLKDEV_INIT("exynos4210-uart.0", "clk_uart_baud0", &exynos5_clk_sclk_uart0.clk), + CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &exynos5_clk_sclk_uart1.clk), + CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &exynos5_clk_sclk_uart2.clk), + CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &exynos5_clk_sclk_uart3.clk), + CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &exynos5_clk_sclk_mmc0.clk), + CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &exynos5_clk_sclk_mmc1.clk), + CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &exynos5_clk_sclk_mmc2.clk), + CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &exynos5_clk_sclk_mmc3.clk), + CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos5_clk_pdma0), + CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos5_clk_pdma1), + CLKDEV_INIT("dma-pl330.2", "apb_pclk", &exynos5_clk_mdma1), +}; + +static unsigned long exynos5_epll_get_rate(struct clk *clk) +{ + return clk->rate; +} + +static struct clk *exynos5_clks[] __initdata = { + &exynos5_clk_sclk_hdmi27m, + &exynos5_clk_sclk_hdmiphy, + &clk_fout_bpll, + &clk_fout_cpll, + &exynos5_clk_armclk, +}; + +static u32 epll_div[][6] = { + { 192000000, 0, 48, 3, 1, 0 }, + { 180000000, 0, 45, 3, 1, 0 }, + { 73728000, 1, 73, 3, 3, 47710 }, + { 67737600, 1, 90, 4, 3, 20762 }, + { 49152000, 0, 49, 3, 3, 9961 }, + { 45158400, 0, 45, 3, 3, 10381 }, + { 180633600, 0, 45, 3, 1, 10381 }, +}; + +static int exynos5_epll_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned int epll_con, epll_con_k; + unsigned int i; + unsigned int tmp; + unsigned int epll_rate; + unsigned int locktime; + unsigned int lockcnt; + + /* Return if nothing changed */ + if (clk->rate == rate) + return 0; + + if (clk->parent) + epll_rate = clk_get_rate(clk->parent); + else + epll_rate = clk_ext_xtal_mux.rate; + + if (epll_rate != 24000000) { + pr_err("Invalid Clock : recommended clock is 24MHz.\n"); + return -EINVAL; + } + + epll_con = __raw_readl(EXYNOS5_EPLL_CON0); + epll_con &= ~(0x1 << 27 | \ + PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT | \ + PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT | \ + PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT); + + for (i = 0; i < ARRAY_SIZE(epll_div); i++) { + if (epll_div[i][0] == rate) { + epll_con_k = epll_div[i][5] << 0; + epll_con |= epll_div[i][1] << 27; + epll_con |= epll_div[i][2] << PLL46XX_MDIV_SHIFT; + epll_con |= epll_div[i][3] << PLL46XX_PDIV_SHIFT; + epll_con |= epll_div[i][4] << PLL46XX_SDIV_SHIFT; + break; + } + } + + if (i == ARRAY_SIZE(epll_div)) { + printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", + __func__); + return -EINVAL; + } + + epll_rate /= 1000000; + + /* 3000 max_cycls : specification data */ + locktime = 3000 / epll_rate * epll_div[i][3]; + lockcnt = locktime * 10000 / (10000 / epll_rate); + + __raw_writel(lockcnt, EXYNOS5_EPLL_LOCK); + + __raw_writel(epll_con, EXYNOS5_EPLL_CON0); + __raw_writel(epll_con_k, EXYNOS5_EPLL_CON1); + + do { + tmp = __raw_readl(EXYNOS5_EPLL_CON0); + } while (!(tmp & 0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT)); + + clk->rate = rate; + + return 0; +} + +static struct clk_ops exynos5_epll_ops = { + .get_rate = exynos5_epll_get_rate, + .set_rate = exynos5_epll_set_rate, +}; + +static int xtal_rate; + +static unsigned long exynos5_fout_apll_get_rate(struct clk *clk) +{ + return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS5_APLL_CON0)); +} + +static struct clk_ops exynos5_fout_apll_ops = { + .get_rate = exynos5_fout_apll_get_rate, +}; + +#ifdef CONFIG_PM +static int exynos5_clock_suspend(void) +{ + s3c_pm_do_save(exynos5_clock_save, ARRAY_SIZE(exynos5_clock_save)); + + return 0; +} + +static void exynos5_clock_resume(void) +{ + s3c_pm_do_restore_core(exynos5_clock_save, ARRAY_SIZE(exynos5_clock_save)); +} +#else +#define exynos5_clock_suspend NULL +#define exynos5_clock_resume NULL +#endif + +struct syscore_ops exynos5_clock_syscore_ops = { + .suspend = exynos5_clock_suspend, + .resume = exynos5_clock_resume, +}; + +void __init_or_cpufreq exynos5_setup_clocks(void) +{ + struct clk *xtal_clk; + unsigned long apll; + unsigned long bpll; + unsigned long cpll; + unsigned long mpll; + unsigned long epll; + unsigned long vpll; + unsigned long vpllsrc; + unsigned long xtal; + unsigned long armclk; + unsigned long mout_cdrex; + unsigned long aclk_400; + unsigned long aclk_333; + unsigned long aclk_266; + unsigned long aclk_200; + unsigned long aclk_166; + unsigned long aclk_66; + unsigned int ptr; + + printk(KERN_DEBUG "%s: registering clocks\n", __func__); + + xtal_clk = clk_get(NULL, "xtal"); + BUG_ON(IS_ERR(xtal_clk)); + + xtal = clk_get_rate(xtal_clk); + + xtal_rate = xtal; + + clk_put(xtal_clk); + + printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal); + + apll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_APLL_CON0)); + bpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_BPLL_CON0)); + cpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_CPLL_CON0)); + mpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_MPLL_CON0)); + epll = s5p_get_pll36xx(xtal, __raw_readl(EXYNOS5_EPLL_CON0), + __raw_readl(EXYNOS5_EPLL_CON1)); + + vpllsrc = clk_get_rate(&exynos5_clk_vpllsrc.clk); + vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(EXYNOS5_VPLL_CON0), + __raw_readl(EXYNOS5_VPLL_CON1)); + + clk_fout_apll.ops = &exynos5_fout_apll_ops; + clk_fout_bpll.rate = bpll; + clk_fout_cpll.rate = cpll; + clk_fout_mpll.rate = mpll; + clk_fout_epll.rate = epll; + clk_fout_vpll.rate = vpll; + + printk(KERN_INFO "EXYNOS5: PLL settings, A=%ld, B=%ld, C=%ld\n" + "M=%ld, E=%ld V=%ld", + apll, bpll, cpll, mpll, epll, vpll); + + armclk = clk_get_rate(&exynos5_clk_armclk); + mout_cdrex = clk_get_rate(&exynos5_clk_cdrex.clk); + + aclk_400 = clk_get_rate(&exynos5_clk_aclk_400.clk); + aclk_333 = clk_get_rate(&exynos5_clk_aclk_333.clk); + aclk_266 = clk_get_rate(&exynos5_clk_aclk_266.clk); + aclk_200 = clk_get_rate(&exynos5_clk_aclk_200.clk); + aclk_166 = clk_get_rate(&exynos5_clk_aclk_166.clk); + aclk_66 = clk_get_rate(&exynos5_clk_aclk_66.clk); + + printk(KERN_INFO "EXYNOS5: ARMCLK=%ld, CDREX=%ld, ACLK400=%ld\n" + "ACLK333=%ld, ACLK266=%ld, ACLK200=%ld\n" + "ACLK166=%ld, ACLK66=%ld\n", + armclk, mout_cdrex, aclk_400, + aclk_333, aclk_266, aclk_200, + aclk_166, aclk_66); + + + clk_fout_epll.ops = &exynos5_epll_ops; + + if (clk_set_parent(&exynos5_clk_mout_epll.clk, &clk_fout_epll)) + printk(KERN_ERR "Unable to set parent %s of clock %s.\n", + clk_fout_epll.name, exynos5_clk_mout_epll.clk.name); + + clk_set_rate(&exynos5_clk_sclk_apll.clk, 100000000); + clk_set_rate(&exynos5_clk_aclk_266.clk, 300000000); + + clk_set_rate(&exynos5_clk_aclk_acp.clk, 267000000); + clk_set_rate(&exynos5_clk_pclk_acp.clk, 134000000); + + for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clksrcs); ptr++) + s3c_set_clksrc(&exynos5_clksrcs[ptr], true); +} + +void __init exynos5_register_clocks(void) +{ + int ptr; + + s3c24xx_register_clocks(exynos5_clks, ARRAY_SIZE(exynos5_clks)); + + for (ptr = 0; ptr < ARRAY_SIZE(exynos5_sysclks); ptr++) + s3c_register_clksrc(exynos5_sysclks[ptr], 1); + + for (ptr = 0; ptr < ARRAY_SIZE(exynos5_sclk_tv); ptr++) + s3c_register_clksrc(exynos5_sclk_tv[ptr], 1); + + for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clksrc_cdev); ptr++) + s3c_register_clksrc(exynos5_clksrc_cdev[ptr], 1); + + s3c_register_clksrc(exynos5_clksrcs, ARRAY_SIZE(exynos5_clksrcs)); + s3c_register_clocks(exynos5_init_clocks_on, ARRAY_SIZE(exynos5_init_clocks_on)); + + s3c24xx_register_clocks(exynos5_clk_cdev, ARRAY_SIZE(exynos5_clk_cdev)); + for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clk_cdev); ptr++) + s3c_disable_clocks(exynos5_clk_cdev[ptr], 1); + + s3c_register_clocks(exynos5_init_clocks_off, ARRAY_SIZE(exynos5_init_clocks_off)); + s3c_disable_clocks(exynos5_init_clocks_off, ARRAY_SIZE(exynos5_init_clocks_off)); + clkdev_add_table(exynos5_clk_lookup, ARRAY_SIZE(exynos5_clk_lookup)); + + register_syscore_ops(&exynos5_clock_syscore_ops); + s3c_pwmclk_init(); +} diff --git a/arch/arm/mach-exynos/clock.c b/arch/arm/mach-exynos/clock.c deleted file mode 100644 index 187287aa57ab..000000000000 --- a/arch/arm/mach-exynos/clock.c +++ /dev/null @@ -1,1564 +0,0 @@ -/* linux/arch/arm/mach-exynos4/clock.c - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * EXYNOS4 - Clock support - * - * 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 <linux/kernel.h> -#include <linux/err.h> -#include <linux/io.h> -#include <linux/syscore_ops.h> - -#include <plat/cpu-freq.h> -#include <plat/clock.h> -#include <plat/cpu.h> -#include <plat/pll.h> -#include <plat/s5p-clock.h> -#include <plat/clock-clksrc.h> -#include <plat/pm.h> - -#include <mach/map.h> -#include <mach/regs-clock.h> -#include <mach/sysmmu.h> -#include <mach/exynos4-clock.h> - -#include "common.h" - -#ifdef CONFIG_PM_SLEEP -static struct sleep_save exynos4_clock_save[] = { - SAVE_ITEM(S5P_CLKDIV_LEFTBUS), - SAVE_ITEM(S5P_CLKGATE_IP_LEFTBUS), - SAVE_ITEM(S5P_CLKDIV_RIGHTBUS), - SAVE_ITEM(S5P_CLKGATE_IP_RIGHTBUS), - SAVE_ITEM(S5P_CLKSRC_TOP0), - SAVE_ITEM(S5P_CLKSRC_TOP1), - SAVE_ITEM(S5P_CLKSRC_CAM), - SAVE_ITEM(S5P_CLKSRC_TV), - SAVE_ITEM(S5P_CLKSRC_MFC), - SAVE_ITEM(S5P_CLKSRC_G3D), - SAVE_ITEM(S5P_CLKSRC_LCD0), - SAVE_ITEM(S5P_CLKSRC_MAUDIO), - SAVE_ITEM(S5P_CLKSRC_FSYS), - SAVE_ITEM(S5P_CLKSRC_PERIL0), - SAVE_ITEM(S5P_CLKSRC_PERIL1), - SAVE_ITEM(S5P_CLKDIV_CAM), - SAVE_ITEM(S5P_CLKDIV_TV), - SAVE_ITEM(S5P_CLKDIV_MFC), - SAVE_ITEM(S5P_CLKDIV_G3D), - SAVE_ITEM(S5P_CLKDIV_LCD0), - SAVE_ITEM(S5P_CLKDIV_MAUDIO), - SAVE_ITEM(S5P_CLKDIV_FSYS0), - SAVE_ITEM(S5P_CLKDIV_FSYS1), - SAVE_ITEM(S5P_CLKDIV_FSYS2), - SAVE_ITEM(S5P_CLKDIV_FSYS3), - SAVE_ITEM(S5P_CLKDIV_PERIL0), - SAVE_ITEM(S5P_CLKDIV_PERIL1), - SAVE_ITEM(S5P_CLKDIV_PERIL2), - SAVE_ITEM(S5P_CLKDIV_PERIL3), - SAVE_ITEM(S5P_CLKDIV_PERIL4), - SAVE_ITEM(S5P_CLKDIV_PERIL5), - SAVE_ITEM(S5P_CLKDIV_TOP), - SAVE_ITEM(S5P_CLKSRC_MASK_TOP), - SAVE_ITEM(S5P_CLKSRC_MASK_CAM), - SAVE_ITEM(S5P_CLKSRC_MASK_TV), - SAVE_ITEM(S5P_CLKSRC_MASK_LCD0), - SAVE_ITEM(S5P_CLKSRC_MASK_MAUDIO), - SAVE_ITEM(S5P_CLKSRC_MASK_FSYS), - SAVE_ITEM(S5P_CLKSRC_MASK_PERIL0), - SAVE_ITEM(S5P_CLKSRC_MASK_PERIL1), - SAVE_ITEM(S5P_CLKDIV2_RATIO), - SAVE_ITEM(S5P_CLKGATE_SCLKCAM), - SAVE_ITEM(S5P_CLKGATE_IP_CAM), - SAVE_ITEM(S5P_CLKGATE_IP_TV), - SAVE_ITEM(S5P_CLKGATE_IP_MFC), - SAVE_ITEM(S5P_CLKGATE_IP_G3D), - SAVE_ITEM(S5P_CLKGATE_IP_LCD0), - SAVE_ITEM(S5P_CLKGATE_IP_FSYS), - SAVE_ITEM(S5P_CLKGATE_IP_GPS), - SAVE_ITEM(S5P_CLKGATE_IP_PERIL), - SAVE_ITEM(S5P_CLKGATE_BLOCK), - SAVE_ITEM(S5P_CLKSRC_MASK_DMC), - SAVE_ITEM(S5P_CLKSRC_DMC), - SAVE_ITEM(S5P_CLKDIV_DMC0), - SAVE_ITEM(S5P_CLKDIV_DMC1), - SAVE_ITEM(S5P_CLKGATE_IP_DMC), - SAVE_ITEM(S5P_CLKSRC_CPU), - SAVE_ITEM(S5P_CLKDIV_CPU), - SAVE_ITEM(S5P_CLKDIV_CPU + 0x4), - SAVE_ITEM(S5P_CLKGATE_SCLKCPU), - SAVE_ITEM(S5P_CLKGATE_IP_CPU), -}; -#endif - -struct clk clk_sclk_hdmi27m = { - .name = "sclk_hdmi27m", - .rate = 27000000, -}; - -struct clk clk_sclk_hdmiphy = { - .name = "sclk_hdmiphy", -}; - -struct clk clk_sclk_usbphy0 = { - .name = "sclk_usbphy0", - .rate = 27000000, -}; - -struct clk clk_sclk_usbphy1 = { - .name = "sclk_usbphy1", -}; - -static struct clk dummy_apb_pclk = { - .name = "apb_pclk", - .id = -1, -}; - -static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable); -} - -static int exynos4_clksrc_mask_cam_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLKSRC_MASK_CAM, clk, enable); -} - -static int exynos4_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLKSRC_MASK_LCD0, clk, enable); -} - -int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLKSRC_MASK_FSYS, clk, enable); -} - -static int exynos4_clksrc_mask_peril0_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL0, clk, enable); -} - -static int exynos4_clksrc_mask_peril1_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL1, clk, enable); -} - -static int exynos4_clk_ip_mfc_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLKGATE_IP_MFC, clk, enable); -} - -static int exynos4_clksrc_mask_tv_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLKSRC_MASK_TV, clk, enable); -} - -static int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLKGATE_IP_CAM, clk, enable); -} - -static int exynos4_clk_ip_tv_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLKGATE_IP_TV, clk, enable); -} - -static int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLKGATE_IP_IMAGE, clk, enable); -} - -static int exynos4_clk_ip_lcd0_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLKGATE_IP_LCD0, clk, enable); -} - -int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLKGATE_IP_LCD1, clk, enable); -} - -int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLKGATE_IP_FSYS, clk, enable); -} - -static int exynos4_clk_ip_peril_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable); -} - -static int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLKGATE_IP_PERIR, clk, enable); -} - -static int exynos4_clk_hdmiphy_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable); -} - -static int exynos4_clk_dac_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_DAC_PHY_CONTROL, clk, enable); -} - -/* Core list of CMU_CPU side */ - -static struct clksrc_clk clk_mout_apll = { - .clk = { - .name = "mout_apll", - }, - .sources = &clk_src_apll, - .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 0, .size = 1 }, -}; - -struct clksrc_clk clk_sclk_apll = { - .clk = { - .name = "sclk_apll", - .parent = &clk_mout_apll.clk, - }, - .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 24, .size = 3 }, -}; - -struct clksrc_clk clk_mout_epll = { - .clk = { - .name = "mout_epll", - }, - .sources = &clk_src_epll, - .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 4, .size = 1 }, -}; - -struct clksrc_clk clk_mout_mpll = { - .clk = { - .name = "mout_mpll", - }, - .sources = &clk_src_mpll, - - /* reg_src will be added in each SoCs' clock */ -}; - -static struct clk *clkset_moutcore_list[] = { - [0] = &clk_mout_apll.clk, - [1] = &clk_mout_mpll.clk, -}; - -static struct clksrc_sources clkset_moutcore = { - .sources = clkset_moutcore_list, - .nr_sources = ARRAY_SIZE(clkset_moutcore_list), -}; - -static struct clksrc_clk clk_moutcore = { - .clk = { - .name = "moutcore", - }, - .sources = &clkset_moutcore, - .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 16, .size = 1 }, -}; - -static struct clksrc_clk clk_coreclk = { - .clk = { - .name = "core_clk", - .parent = &clk_moutcore.clk, - }, - .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 0, .size = 3 }, -}; - -static struct clksrc_clk clk_armclk = { - .clk = { - .name = "armclk", - .parent = &clk_coreclk.clk, - }, -}; - -static struct clksrc_clk clk_aclk_corem0 = { - .clk = { - .name = "aclk_corem0", - .parent = &clk_coreclk.clk, - }, - .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 }, -}; - -static struct clksrc_clk clk_aclk_cores = { - .clk = { - .name = "aclk_cores", - .parent = &clk_coreclk.clk, - }, - .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 }, -}; - -static struct clksrc_clk clk_aclk_corem1 = { - .clk = { - .name = "aclk_corem1", - .parent = &clk_coreclk.clk, - }, - .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 8, .size = 3 }, -}; - -static struct clksrc_clk clk_periphclk = { - .clk = { - .name = "periphclk", - .parent = &clk_coreclk.clk, - }, - .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 12, .size = 3 }, -}; - -/* Core list of CMU_CORE side */ - -struct clk *clkset_corebus_list[] = { - [0] = &clk_mout_mpll.clk, - [1] = &clk_sclk_apll.clk, -}; - -struct clksrc_sources clkset_mout_corebus = { - .sources = clkset_corebus_list, - .nr_sources = ARRAY_SIZE(clkset_corebus_list), -}; - -static struct clksrc_clk clk_mout_corebus = { - .clk = { - .name = "mout_corebus", - }, - .sources = &clkset_mout_corebus, - .reg_src = { .reg = S5P_CLKSRC_DMC, .shift = 4, .size = 1 }, -}; - -static struct clksrc_clk clk_sclk_dmc = { - .clk = { - .name = "sclk_dmc", - .parent = &clk_mout_corebus.clk, - }, - .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 12, .size = 3 }, -}; - -static struct clksrc_clk clk_aclk_cored = { - .clk = { - .name = "aclk_cored", - .parent = &clk_sclk_dmc.clk, - }, - .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 16, .size = 3 }, -}; - -static struct clksrc_clk clk_aclk_corep = { - .clk = { - .name = "aclk_corep", - .parent = &clk_aclk_cored.clk, - }, - .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 20, .size = 3 }, -}; - -static struct clksrc_clk clk_aclk_acp = { - .clk = { - .name = "aclk_acp", - .parent = &clk_mout_corebus.clk, - }, - .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 0, .size = 3 }, -}; - -static struct clksrc_clk clk_pclk_acp = { - .clk = { - .name = "pclk_acp", - .parent = &clk_aclk_acp.clk, - }, - .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 4, .size = 3 }, -}; - -/* Core list of CMU_TOP side */ - -struct clk *clkset_aclk_top_list[] = { - [0] = &clk_mout_mpll.clk, - [1] = &clk_sclk_apll.clk, -}; - -struct clksrc_sources clkset_aclk = { - .sources = clkset_aclk_top_list, - .nr_sources = ARRAY_SIZE(clkset_aclk_top_list), -}; - -static struct clksrc_clk clk_aclk_200 = { - .clk = { - .name = "aclk_200", - }, - .sources = &clkset_aclk, - .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 12, .size = 1 }, - .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 0, .size = 3 }, -}; - -static struct clksrc_clk clk_aclk_100 = { - .clk = { - .name = "aclk_100", - }, - .sources = &clkset_aclk, - .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 16, .size = 1 }, - .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 4, .size = 4 }, -}; - -static struct clksrc_clk clk_aclk_160 = { - .clk = { - .name = "aclk_160", - }, - .sources = &clkset_aclk, - .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 20, .size = 1 }, - .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 8, .size = 3 }, -}; - -struct clksrc_clk clk_aclk_133 = { - .clk = { - .name = "aclk_133", - }, - .sources = &clkset_aclk, - .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 24, .size = 1 }, - .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 12, .size = 3 }, -}; - -static struct clk *clkset_vpllsrc_list[] = { - [0] = &clk_fin_vpll, - [1] = &clk_sclk_hdmi27m, -}; - -static struct clksrc_sources clkset_vpllsrc = { - .sources = clkset_vpllsrc_list, - .nr_sources = ARRAY_SIZE(clkset_vpllsrc_list), -}; - -static struct clksrc_clk clk_vpllsrc = { - .clk = { - .name = "vpll_src", - .enable = exynos4_clksrc_mask_top_ctrl, - .ctrlbit = (1 << 0), - }, - .sources = &clkset_vpllsrc, - .reg_src = { .reg = S5P_CLKSRC_TOP1, .shift = 0, .size = 1 }, -}; - -static struct clk *clkset_sclk_vpll_list[] = { - [0] = &clk_vpllsrc.clk, - [1] = &clk_fout_vpll, -}; - -static struct clksrc_sources clkset_sclk_vpll = { - .sources = clkset_sclk_vpll_list, - .nr_sources = ARRAY_SIZE(clkset_sclk_vpll_list), -}; - -struct clksrc_clk clk_sclk_vpll = { - .clk = { - .name = "sclk_vpll", - }, - .sources = &clkset_sclk_vpll, - .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 8, .size = 1 }, -}; - -static struct clk init_clocks_off[] = { - { - .name = "timers", - .parent = &clk_aclk_100.clk, - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1<<24), - }, { - .name = "csis", - .devname = "s5p-mipi-csis.0", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 4), - }, { - .name = "csis", - .devname = "s5p-mipi-csis.1", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 5), - }, { - .name = "fimc", - .devname = "exynos4-fimc.0", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 0), - }, { - .name = "fimc", - .devname = "exynos4-fimc.1", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 1), - }, { - .name = "fimc", - .devname = "exynos4-fimc.2", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 2), - }, { - .name = "fimc", - .devname = "exynos4-fimc.3", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 3), - }, { - .name = "fimd", - .devname = "exynos4-fb.0", - .enable = exynos4_clk_ip_lcd0_ctrl, - .ctrlbit = (1 << 0), - }, { - .name = "hsmmc", - .devname = "s3c-sdhci.0", - .parent = &clk_aclk_133.clk, - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 5), - }, { - .name = "hsmmc", - .devname = "s3c-sdhci.1", - .parent = &clk_aclk_133.clk, - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 6), - }, { - .name = "hsmmc", - .devname = "s3c-sdhci.2", - .parent = &clk_aclk_133.clk, - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 7), - }, { - .name = "hsmmc", - .devname = "s3c-sdhci.3", - .parent = &clk_aclk_133.clk, - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 8), - }, { - .name = "dwmmc", - .parent = &clk_aclk_133.clk, - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 9), - }, { - .name = "dac", - .devname = "s5p-sdo", - .enable = exynos4_clk_ip_tv_ctrl, - .ctrlbit = (1 << 2), - }, { - .name = "mixer", - .devname = "s5p-mixer", - .enable = exynos4_clk_ip_tv_ctrl, - .ctrlbit = (1 << 1), - }, { - .name = "vp", - .devname = "s5p-mixer", - .enable = exynos4_clk_ip_tv_ctrl, - .ctrlbit = (1 << 0), - }, { - .name = "hdmi", - .devname = "exynos4-hdmi", - .enable = exynos4_clk_ip_tv_ctrl, - .ctrlbit = (1 << 3), - }, { - .name = "hdmiphy", - .devname = "exynos4-hdmi", - .enable = exynos4_clk_hdmiphy_ctrl, - .ctrlbit = (1 << 0), - }, { - .name = "dacphy", - .devname = "s5p-sdo", - .enable = exynos4_clk_dac_ctrl, - .ctrlbit = (1 << 0), - }, { - .name = "adc", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 15), - }, { - .name = "keypad", - .enable = exynos4_clk_ip_perir_ctrl, - .ctrlbit = (1 << 16), - }, { - .name = "rtc", - .enable = exynos4_clk_ip_perir_ctrl, - .ctrlbit = (1 << 15), - }, { - .name = "watchdog", - .parent = &clk_aclk_100.clk, - .enable = exynos4_clk_ip_perir_ctrl, - .ctrlbit = (1 << 14), - }, { - .name = "usbhost", - .enable = exynos4_clk_ip_fsys_ctrl , - .ctrlbit = (1 << 12), - }, { - .name = "otg", - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 13), - }, { - .name = "spi", - .devname = "s3c64xx-spi.0", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 16), - }, { - .name = "spi", - .devname = "s3c64xx-spi.1", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 17), - }, { - .name = "spi", - .devname = "s3c64xx-spi.2", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 18), - }, { - .name = "iis", - .devname = "samsung-i2s.0", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 19), - }, { - .name = "iis", - .devname = "samsung-i2s.1", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 20), - }, { - .name = "iis", - .devname = "samsung-i2s.2", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 21), - }, { - .name = "ac97", - .devname = "samsung-ac97", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 27), - }, { - .name = "fimg2d", - .enable = exynos4_clk_ip_image_ctrl, - .ctrlbit = (1 << 0), - }, { - .name = "mfc", - .devname = "s5p-mfc", - .enable = exynos4_clk_ip_mfc_ctrl, - .ctrlbit = (1 << 0), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.0", - .parent = &clk_aclk_100.clk, - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 6), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.1", - .parent = &clk_aclk_100.clk, - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 7), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.2", - .parent = &clk_aclk_100.clk, - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 8), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.3", - .parent = &clk_aclk_100.clk, - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 9), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.4", - .parent = &clk_aclk_100.clk, - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 10), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.5", - .parent = &clk_aclk_100.clk, - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 11), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.6", - .parent = &clk_aclk_100.clk, - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 12), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.7", - .parent = &clk_aclk_100.clk, - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 13), - }, { - .name = "i2c", - .devname = "s3c2440-hdmiphy-i2c", - .parent = &clk_aclk_100.clk, - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 14), - }, { - .name = "SYSMMU_MDMA", - .enable = exynos4_clk_ip_image_ctrl, - .ctrlbit = (1 << 5), - }, { - .name = "SYSMMU_FIMC0", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 7), - }, { - .name = "SYSMMU_FIMC1", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 8), - }, { - .name = "SYSMMU_FIMC2", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 9), - }, { - .name = "SYSMMU_FIMC3", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 10), - }, { - .name = "SYSMMU_JPEG", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 11), - }, { - .name = "SYSMMU_FIMD0", - .enable = exynos4_clk_ip_lcd0_ctrl, - .ctrlbit = (1 << 4), - }, { - .name = "SYSMMU_FIMD1", - .enable = exynos4_clk_ip_lcd1_ctrl, - .ctrlbit = (1 << 4), - }, { - .name = "SYSMMU_PCIe", - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 18), - }, { - .name = "SYSMMU_G2D", - .enable = exynos4_clk_ip_image_ctrl, - .ctrlbit = (1 << 3), - }, { - .name = "SYSMMU_ROTATOR", - .enable = exynos4_clk_ip_image_ctrl, - .ctrlbit = (1 << 4), - }, { - .name = "SYSMMU_TV", - .enable = exynos4_clk_ip_tv_ctrl, - .ctrlbit = (1 << 4), - }, { - .name = "SYSMMU_MFC_L", - .enable = exynos4_clk_ip_mfc_ctrl, - .ctrlbit = (1 << 1), - }, { - .name = "SYSMMU_MFC_R", - .enable = exynos4_clk_ip_mfc_ctrl, - .ctrlbit = (1 << 2), - } -}; - -static struct clk init_clocks[] = { - { - .name = "uart", - .devname = "s5pv210-uart.0", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 0), - }, { - .name = "uart", - .devname = "s5pv210-uart.1", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 1), - }, { - .name = "uart", - .devname = "s5pv210-uart.2", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 2), - }, { - .name = "uart", - .devname = "s5pv210-uart.3", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 3), - }, { - .name = "uart", - .devname = "s5pv210-uart.4", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 4), - }, { - .name = "uart", - .devname = "s5pv210-uart.5", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 5), - } -}; - -static struct clk clk_pdma0 = { - .name = "dma", - .devname = "dma-pl330.0", - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 0), -}; - -static struct clk clk_pdma1 = { - .name = "dma", - .devname = "dma-pl330.1", - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 1), -}; - -struct clk *clkset_group_list[] = { - [0] = &clk_ext_xtal_mux, - [1] = &clk_xusbxti, - [2] = &clk_sclk_hdmi27m, - [3] = &clk_sclk_usbphy0, - [4] = &clk_sclk_usbphy1, - [5] = &clk_sclk_hdmiphy, - [6] = &clk_mout_mpll.clk, - [7] = &clk_mout_epll.clk, - [8] = &clk_sclk_vpll.clk, -}; - -struct clksrc_sources clkset_group = { - .sources = clkset_group_list, - .nr_sources = ARRAY_SIZE(clkset_group_list), -}; - -static struct clk *clkset_mout_g2d0_list[] = { - [0] = &clk_mout_mpll.clk, - [1] = &clk_sclk_apll.clk, -}; - -static struct clksrc_sources clkset_mout_g2d0 = { - .sources = clkset_mout_g2d0_list, - .nr_sources = ARRAY_SIZE(clkset_mout_g2d0_list), -}; - -static struct clksrc_clk clk_mout_g2d0 = { - .clk = { - .name = "mout_g2d0", - }, - .sources = &clkset_mout_g2d0, - .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 0, .size = 1 }, -}; - -static struct clk *clkset_mout_g2d1_list[] = { - [0] = &clk_mout_epll.clk, - [1] = &clk_sclk_vpll.clk, -}; - -static struct clksrc_sources clkset_mout_g2d1 = { - .sources = clkset_mout_g2d1_list, - .nr_sources = ARRAY_SIZE(clkset_mout_g2d1_list), -}; - -static struct clksrc_clk clk_mout_g2d1 = { - .clk = { - .name = "mout_g2d1", - }, - .sources = &clkset_mout_g2d1, - .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 4, .size = 1 }, -}; - -static struct clk *clkset_mout_g2d_list[] = { - [0] = &clk_mout_g2d0.clk, - [1] = &clk_mout_g2d1.clk, -}; - -static struct clksrc_sources clkset_mout_g2d = { - .sources = clkset_mout_g2d_list, - .nr_sources = ARRAY_SIZE(clkset_mout_g2d_list), -}; - -static struct clk *clkset_mout_mfc0_list[] = { - [0] = &clk_mout_mpll.clk, - [1] = &clk_sclk_apll.clk, -}; - -static struct clksrc_sources clkset_mout_mfc0 = { - .sources = clkset_mout_mfc0_list, - .nr_sources = ARRAY_SIZE(clkset_mout_mfc0_list), -}; - -static struct clksrc_clk clk_mout_mfc0 = { - .clk = { - .name = "mout_mfc0", - }, - .sources = &clkset_mout_mfc0, - .reg_src = { .reg = S5P_CLKSRC_MFC, .shift = 0, .size = 1 }, -}; - -static struct clk *clkset_mout_mfc1_list[] = { - [0] = &clk_mout_epll.clk, - [1] = &clk_sclk_vpll.clk, -}; - -static struct clksrc_sources clkset_mout_mfc1 = { - .sources = clkset_mout_mfc1_list, - .nr_sources = ARRAY_SIZE(clkset_mout_mfc1_list), -}; - -static struct clksrc_clk clk_mout_mfc1 = { - .clk = { - .name = "mout_mfc1", - }, - .sources = &clkset_mout_mfc1, - .reg_src = { .reg = S5P_CLKSRC_MFC, .shift = 4, .size = 1 }, -}; - -static struct clk *clkset_mout_mfc_list[] = { - [0] = &clk_mout_mfc0.clk, - [1] = &clk_mout_mfc1.clk, -}; - -static struct clksrc_sources clkset_mout_mfc = { - .sources = clkset_mout_mfc_list, - .nr_sources = ARRAY_SIZE(clkset_mout_mfc_list), -}; - -static struct clk *clkset_sclk_dac_list[] = { - [0] = &clk_sclk_vpll.clk, - [1] = &clk_sclk_hdmiphy, -}; - -static struct clksrc_sources clkset_sclk_dac = { - .sources = clkset_sclk_dac_list, - .nr_sources = ARRAY_SIZE(clkset_sclk_dac_list), -}; - -static struct clksrc_clk clk_sclk_dac = { - .clk = { - .name = "sclk_dac", - .enable = exynos4_clksrc_mask_tv_ctrl, - .ctrlbit = (1 << 8), - }, - .sources = &clkset_sclk_dac, - .reg_src = { .reg = S5P_CLKSRC_TV, .shift = 8, .size = 1 }, -}; - -static struct clksrc_clk clk_sclk_pixel = { - .clk = { - .name = "sclk_pixel", - .parent = &clk_sclk_vpll.clk, - }, - .reg_div = { .reg = S5P_CLKDIV_TV, .shift = 0, .size = 4 }, -}; - -static struct clk *clkset_sclk_hdmi_list[] = { - [0] = &clk_sclk_pixel.clk, - [1] = &clk_sclk_hdmiphy, -}; - -static struct clksrc_sources clkset_sclk_hdmi = { - .sources = clkset_sclk_hdmi_list, - .nr_sources = ARRAY_SIZE(clkset_sclk_hdmi_list), -}; - -static struct clksrc_clk clk_sclk_hdmi = { - .clk = { - .name = "sclk_hdmi", - .enable = exynos4_clksrc_mask_tv_ctrl, - .ctrlbit = (1 << 0), - }, - .sources = &clkset_sclk_hdmi, - .reg_src = { .reg = S5P_CLKSRC_TV, .shift = 0, .size = 1 }, -}; - -static struct clk *clkset_sclk_mixer_list[] = { - [0] = &clk_sclk_dac.clk, - [1] = &clk_sclk_hdmi.clk, -}; - -static struct clksrc_sources clkset_sclk_mixer = { - .sources = clkset_sclk_mixer_list, - .nr_sources = ARRAY_SIZE(clkset_sclk_mixer_list), -}; - -static struct clksrc_clk clk_sclk_mixer = { - .clk = { - .name = "sclk_mixer", - .enable = exynos4_clksrc_mask_tv_ctrl, - .ctrlbit = (1 << 4), - }, - .sources = &clkset_sclk_mixer, - .reg_src = { .reg = S5P_CLKSRC_TV, .shift = 4, .size = 1 }, -}; - -static struct clksrc_clk *sclk_tv[] = { - &clk_sclk_dac, - &clk_sclk_pixel, - &clk_sclk_hdmi, - &clk_sclk_mixer, -}; - -static struct clksrc_clk clk_dout_mmc0 = { - .clk = { - .name = "dout_mmc0", - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 0, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 0, .size = 4 }, -}; - -static struct clksrc_clk clk_dout_mmc1 = { - .clk = { - .name = "dout_mmc1", - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 4, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 16, .size = 4 }, -}; - -static struct clksrc_clk clk_dout_mmc2 = { - .clk = { - .name = "dout_mmc2", - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 8, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 0, .size = 4 }, -}; - -static struct clksrc_clk clk_dout_mmc3 = { - .clk = { - .name = "dout_mmc3", - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 12, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 16, .size = 4 }, -}; - -static struct clksrc_clk clk_dout_mmc4 = { - .clk = { - .name = "dout_mmc4", - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 16, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 0, .size = 4 }, -}; - -static struct clksrc_clk clksrcs[] = { - { - .clk = { - .name = "sclk_pwm", - .enable = exynos4_clksrc_mask_peril0_ctrl, - .ctrlbit = (1 << 24), - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 24, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_PERIL3, .shift = 0, .size = 4 }, - }, { - .clk = { - .name = "sclk_csis", - .devname = "s5p-mipi-csis.0", - .enable = exynos4_clksrc_mask_cam_ctrl, - .ctrlbit = (1 << 24), - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 24, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 24, .size = 4 }, - }, { - .clk = { - .name = "sclk_csis", - .devname = "s5p-mipi-csis.1", - .enable = exynos4_clksrc_mask_cam_ctrl, - .ctrlbit = (1 << 28), - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 28, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 28, .size = 4 }, - }, { - .clk = { - .name = "sclk_cam0", - .enable = exynos4_clksrc_mask_cam_ctrl, - .ctrlbit = (1 << 16), - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 16, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 16, .size = 4 }, - }, { - .clk = { - .name = "sclk_cam1", - .enable = exynos4_clksrc_mask_cam_ctrl, - .ctrlbit = (1 << 20), - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 20, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 20, .size = 4 }, - }, { - .clk = { - .name = "sclk_fimc", - .devname = "exynos4-fimc.0", - .enable = exynos4_clksrc_mask_cam_ctrl, - .ctrlbit = (1 << 0), - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 0, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 0, .size = 4 }, - }, { - .clk = { - .name = "sclk_fimc", - .devname = "exynos4-fimc.1", - .enable = exynos4_clksrc_mask_cam_ctrl, - .ctrlbit = (1 << 4), - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 4, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 4, .size = 4 }, - }, { - .clk = { - .name = "sclk_fimc", - .devname = "exynos4-fimc.2", - .enable = exynos4_clksrc_mask_cam_ctrl, - .ctrlbit = (1 << 8), - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 8, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 8, .size = 4 }, - }, { - .clk = { - .name = "sclk_fimc", - .devname = "exynos4-fimc.3", - .enable = exynos4_clksrc_mask_cam_ctrl, - .ctrlbit = (1 << 12), - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 12, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 12, .size = 4 }, - }, { - .clk = { - .name = "sclk_fimd", - .devname = "exynos4-fb.0", - .enable = exynos4_clksrc_mask_lcd0_ctrl, - .ctrlbit = (1 << 0), - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_LCD0, .shift = 0, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_LCD0, .shift = 0, .size = 4 }, - }, { - .clk = { - .name = "sclk_fimg2d", - }, - .sources = &clkset_mout_g2d, - .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 8, .size = 1 }, - .reg_div = { .reg = S5P_CLKDIV_IMAGE, .shift = 0, .size = 4 }, - }, { - .clk = { - .name = "sclk_mfc", - .devname = "s5p-mfc", - }, - .sources = &clkset_mout_mfc, - .reg_src = { .reg = S5P_CLKSRC_MFC, .shift = 8, .size = 1 }, - .reg_div = { .reg = S5P_CLKDIV_MFC, .shift = 0, .size = 4 }, - }, { - .clk = { - .name = "sclk_dwmmc", - .parent = &clk_dout_mmc4.clk, - .enable = exynos4_clksrc_mask_fsys_ctrl, - .ctrlbit = (1 << 16), - }, - .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 8, .size = 8 }, - } -}; - -static struct clksrc_clk clk_sclk_uart0 = { - .clk = { - .name = "uclk1", - .devname = "exynos4210-uart.0", - .enable = exynos4_clksrc_mask_peril0_ctrl, - .ctrlbit = (1 << 0), - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 0, .size = 4 }, -}; - -static struct clksrc_clk clk_sclk_uart1 = { - .clk = { - .name = "uclk1", - .devname = "exynos4210-uart.1", - .enable = exynos4_clksrc_mask_peril0_ctrl, - .ctrlbit = (1 << 4), - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 4, .size = 4 }, -}; - -static struct clksrc_clk clk_sclk_uart2 = { - .clk = { - .name = "uclk1", - .devname = "exynos4210-uart.2", - .enable = exynos4_clksrc_mask_peril0_ctrl, - .ctrlbit = (1 << 8), - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 8, .size = 4 }, -}; - -static struct clksrc_clk clk_sclk_uart3 = { - .clk = { - .name = "uclk1", - .devname = "exynos4210-uart.3", - .enable = exynos4_clksrc_mask_peril0_ctrl, - .ctrlbit = (1 << 12), - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 }, -}; - -static struct clksrc_clk clk_sclk_mmc0 = { - .clk = { - .name = "sclk_mmc", - .devname = "s3c-sdhci.0", - .parent = &clk_dout_mmc0.clk, - .enable = exynos4_clksrc_mask_fsys_ctrl, - .ctrlbit = (1 << 0), - }, - .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 8, .size = 8 }, -}; - -static struct clksrc_clk clk_sclk_mmc1 = { - .clk = { - .name = "sclk_mmc", - .devname = "s3c-sdhci.1", - .parent = &clk_dout_mmc1.clk, - .enable = exynos4_clksrc_mask_fsys_ctrl, - .ctrlbit = (1 << 4), - }, - .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 24, .size = 8 }, -}; - -static struct clksrc_clk clk_sclk_mmc2 = { - .clk = { - .name = "sclk_mmc", - .devname = "s3c-sdhci.2", - .parent = &clk_dout_mmc2.clk, - .enable = exynos4_clksrc_mask_fsys_ctrl, - .ctrlbit = (1 << 8), - }, - .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 8, .size = 8 }, -}; - -static struct clksrc_clk clk_sclk_mmc3 = { - .clk = { - .name = "sclk_mmc", - .devname = "s3c-sdhci.3", - .parent = &clk_dout_mmc3.clk, - .enable = exynos4_clksrc_mask_fsys_ctrl, - .ctrlbit = (1 << 12), - }, - .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 24, .size = 8 }, -}; - -static struct clksrc_clk clk_sclk_spi0 = { - .clk = { - .name = "sclk_spi", - .devname = "s3c64xx-spi.0", - .enable = exynos4_clksrc_mask_peril1_ctrl, - .ctrlbit = (1 << 16), - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 16, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 0, .size = 4 }, -}; - -static struct clksrc_clk clk_sclk_spi1 = { - .clk = { - .name = "sclk_spi", - .devname = "s3c64xx-spi.1", - .enable = exynos4_clksrc_mask_peril1_ctrl, - .ctrlbit = (1 << 20), - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 20, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 16, .size = 4 }, -}; - -static struct clksrc_clk clk_sclk_spi2 = { - .clk = { - .name = "sclk_spi", - .devname = "s3c64xx-spi.2", - .enable = exynos4_clksrc_mask_peril1_ctrl, - .ctrlbit = (1 << 24), - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 24, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_PERIL2, .shift = 0, .size = 4 }, -}; - -/* Clock initialization code */ -static struct clksrc_clk *sysclks[] = { - &clk_mout_apll, - &clk_sclk_apll, - &clk_mout_epll, - &clk_mout_mpll, - &clk_moutcore, - &clk_coreclk, - &clk_armclk, - &clk_aclk_corem0, - &clk_aclk_cores, - &clk_aclk_corem1, - &clk_periphclk, - &clk_mout_corebus, - &clk_sclk_dmc, - &clk_aclk_cored, - &clk_aclk_corep, - &clk_aclk_acp, - &clk_pclk_acp, - &clk_vpllsrc, - &clk_sclk_vpll, - &clk_aclk_200, - &clk_aclk_100, - &clk_aclk_160, - &clk_aclk_133, - &clk_dout_mmc0, - &clk_dout_mmc1, - &clk_dout_mmc2, - &clk_dout_mmc3, - &clk_dout_mmc4, - &clk_mout_mfc0, - &clk_mout_mfc1, -}; - -static struct clk *clk_cdev[] = { - &clk_pdma0, - &clk_pdma1, -}; - -static struct clksrc_clk *clksrc_cdev[] = { - &clk_sclk_uart0, - &clk_sclk_uart1, - &clk_sclk_uart2, - &clk_sclk_uart3, - &clk_sclk_mmc0, - &clk_sclk_mmc1, - &clk_sclk_mmc2, - &clk_sclk_mmc3, - &clk_sclk_spi0, - &clk_sclk_spi1, - &clk_sclk_spi2, - -}; - -static struct clk_lookup exynos4_clk_lookup[] = { - CLKDEV_INIT("exynos4210-uart.0", "clk_uart_baud0", &clk_sclk_uart0.clk), - CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &clk_sclk_uart1.clk), - CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &clk_sclk_uart2.clk), - CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &clk_sclk_uart3.clk), - CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk), - CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk), - CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk), - CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &clk_sclk_mmc3.clk), - CLKDEV_INIT("dma-pl330.0", "apb_pclk", &clk_pdma0), - CLKDEV_INIT("dma-pl330.1", "apb_pclk", &clk_pdma1), - CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk0", &clk_sclk_spi0.clk), - CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk0", &clk_sclk_spi1.clk), - CLKDEV_INIT("s3c64xx-spi.2", "spi_busclk0", &clk_sclk_spi2.clk), -}; - -static int xtal_rate; - -static unsigned long exynos4_fout_apll_get_rate(struct clk *clk) -{ - if (soc_is_exynos4210()) - return s5p_get_pll45xx(xtal_rate, __raw_readl(S5P_APLL_CON0), - pll_4508); - else if (soc_is_exynos4212() || soc_is_exynos4412()) - return s5p_get_pll35xx(xtal_rate, __raw_readl(S5P_APLL_CON0)); - else - return 0; -} - -static struct clk_ops exynos4_fout_apll_ops = { - .get_rate = exynos4_fout_apll_get_rate, -}; - -static u32 vpll_div[][8] = { - { 54000000, 3, 53, 3, 1024, 0, 17, 0 }, - { 108000000, 3, 53, 2, 1024, 0, 17, 0 }, -}; - -static unsigned long exynos4_vpll_get_rate(struct clk *clk) -{ - return clk->rate; -} - -static int exynos4_vpll_set_rate(struct clk *clk, unsigned long rate) -{ - unsigned int vpll_con0, vpll_con1 = 0; - unsigned int i; - - /* Return if nothing changed */ - if (clk->rate == rate) - return 0; - - vpll_con0 = __raw_readl(S5P_VPLL_CON0); - vpll_con0 &= ~(0x1 << 27 | \ - PLL90XX_MDIV_MASK << PLL46XX_MDIV_SHIFT | \ - PLL90XX_PDIV_MASK << PLL46XX_PDIV_SHIFT | \ - PLL90XX_SDIV_MASK << PLL46XX_SDIV_SHIFT); - - vpll_con1 = __raw_readl(S5P_VPLL_CON1); - vpll_con1 &= ~(PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT | \ - PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT | \ - PLL4650C_KDIV_MASK << PLL46XX_KDIV_SHIFT); - - for (i = 0; i < ARRAY_SIZE(vpll_div); i++) { - if (vpll_div[i][0] == rate) { - vpll_con0 |= vpll_div[i][1] << PLL46XX_PDIV_SHIFT; - vpll_con0 |= vpll_div[i][2] << PLL46XX_MDIV_SHIFT; - vpll_con0 |= vpll_div[i][3] << PLL46XX_SDIV_SHIFT; - vpll_con1 |= vpll_div[i][4] << PLL46XX_KDIV_SHIFT; - vpll_con1 |= vpll_div[i][5] << PLL46XX_MFR_SHIFT; - vpll_con1 |= vpll_div[i][6] << PLL46XX_MRR_SHIFT; - vpll_con0 |= vpll_div[i][7] << 27; - break; - } - } - - if (i == ARRAY_SIZE(vpll_div)) { - printk(KERN_ERR "%s: Invalid Clock VPLL Frequency\n", - __func__); - return -EINVAL; - } - - __raw_writel(vpll_con0, S5P_VPLL_CON0); - __raw_writel(vpll_con1, S5P_VPLL_CON1); - - /* Wait for VPLL lock */ - while (!(__raw_readl(S5P_VPLL_CON0) & (1 << PLL46XX_LOCKED_SHIFT))) - continue; - - clk->rate = rate; - return 0; -} - -static struct clk_ops exynos4_vpll_ops = { - .get_rate = exynos4_vpll_get_rate, - .set_rate = exynos4_vpll_set_rate, -}; - -void __init_or_cpufreq exynos4_setup_clocks(void) -{ - struct clk *xtal_clk; - unsigned long apll = 0; - unsigned long mpll = 0; - unsigned long epll = 0; - unsigned long vpll = 0; - unsigned long vpllsrc; - unsigned long xtal; - unsigned long armclk; - unsigned long sclk_dmc; - unsigned long aclk_200; - unsigned long aclk_100; - unsigned long aclk_160; - unsigned long aclk_133; - unsigned int ptr; - - printk(KERN_DEBUG "%s: registering clocks\n", __func__); - - xtal_clk = clk_get(NULL, "xtal"); - BUG_ON(IS_ERR(xtal_clk)); - - xtal = clk_get_rate(xtal_clk); - - xtal_rate = xtal; - - clk_put(xtal_clk); - - printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal); - - if (soc_is_exynos4210()) { - apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON0), - pll_4508); - mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON0), - pll_4508); - epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON0), - __raw_readl(S5P_EPLL_CON1), pll_4600); - - vpllsrc = clk_get_rate(&clk_vpllsrc.clk); - vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0), - __raw_readl(S5P_VPLL_CON1), pll_4650c); - } else if (soc_is_exynos4212() || soc_is_exynos4412()) { - apll = s5p_get_pll35xx(xtal, __raw_readl(S5P_APLL_CON0)); - mpll = s5p_get_pll35xx(xtal, __raw_readl(S5P_MPLL_CON0)); - epll = s5p_get_pll36xx(xtal, __raw_readl(S5P_EPLL_CON0), - __raw_readl(S5P_EPLL_CON1)); - - vpllsrc = clk_get_rate(&clk_vpllsrc.clk); - vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(S5P_VPLL_CON0), - __raw_readl(S5P_VPLL_CON1)); - } else { - /* nothing */ - } - - clk_fout_apll.ops = &exynos4_fout_apll_ops; - clk_fout_mpll.rate = mpll; - clk_fout_epll.rate = epll; - clk_fout_vpll.ops = &exynos4_vpll_ops; - clk_fout_vpll.rate = vpll; - - printk(KERN_INFO "EXYNOS4: PLL settings, A=%ld, M=%ld, E=%ld V=%ld", - apll, mpll, epll, vpll); - - armclk = clk_get_rate(&clk_armclk.clk); - sclk_dmc = clk_get_rate(&clk_sclk_dmc.clk); - - aclk_200 = clk_get_rate(&clk_aclk_200.clk); - aclk_100 = clk_get_rate(&clk_aclk_100.clk); - aclk_160 = clk_get_rate(&clk_aclk_160.clk); - aclk_133 = clk_get_rate(&clk_aclk_133.clk); - - printk(KERN_INFO "EXYNOS4: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n" - "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n", - armclk, sclk_dmc, aclk_200, - aclk_100, aclk_160, aclk_133); - - clk_f.rate = armclk; - clk_h.rate = sclk_dmc; - clk_p.rate = aclk_100; - - for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) - s3c_set_clksrc(&clksrcs[ptr], true); -} - -static struct clk *clks[] __initdata = { - &clk_sclk_hdmi27m, - &clk_sclk_hdmiphy, - &clk_sclk_usbphy0, - &clk_sclk_usbphy1, -}; - -#ifdef CONFIG_PM_SLEEP -static int exynos4_clock_suspend(void) -{ - s3c_pm_do_save(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save)); - return 0; -} - -static void exynos4_clock_resume(void) -{ - s3c_pm_do_restore_core(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save)); -} - -#else -#define exynos4_clock_suspend NULL -#define exynos4_clock_resume NULL -#endif - -struct syscore_ops exynos4_clock_syscore_ops = { - .suspend = exynos4_clock_suspend, - .resume = exynos4_clock_resume, -}; - -void __init exynos4_register_clocks(void) -{ - int ptr; - - s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); - - for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) - s3c_register_clksrc(sysclks[ptr], 1); - - for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++) - s3c_register_clksrc(sclk_tv[ptr], 1); - - for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++) - s3c_register_clksrc(clksrc_cdev[ptr], 1); - - s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); - s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); - - s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev)); - for (ptr = 0; ptr < ARRAY_SIZE(clk_cdev); ptr++) - s3c_disable_clocks(clk_cdev[ptr], 1); - - s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); - s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); - clkdev_add_table(exynos4_clk_lookup, ARRAY_SIZE(exynos4_clk_lookup)); - - register_syscore_ops(&exynos4_clock_syscore_ops); - s3c24xx_register_clock(&dummy_apb_pclk); - - s3c_pwmclk_init(); -} diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c index 6de298c5d2d3..8614aab47cc0 100644 --- a/arch/arm/mach-exynos/common.c +++ b/arch/arm/mach-exynos/common.c @@ -26,10 +26,12 @@ #include <asm/hardware/gic.h> #include <asm/mach/map.h> #include <asm/mach/irq.h> +#include <asm/cacheflush.h> #include <mach/regs-irq.h> #include <mach/regs-pmu.h> #include <mach/regs-gpio.h> +#include <mach/pmu.h> #include <plat/cpu.h> #include <plat/clock.h> @@ -45,10 +47,20 @@ #include <plat/regs-serial.h> #include "common.h" +#define L2_AUX_VAL 0x7C470001 +#define L2_AUX_MASK 0xC200ffff static const char name_exynos4210[] = "EXYNOS4210"; static const char name_exynos4212[] = "EXYNOS4212"; static const char name_exynos4412[] = "EXYNOS4412"; +static const char name_exynos5250[] = "EXYNOS5250"; + +static void exynos4_map_io(void); +static void exynos5_map_io(void); +static void exynos4_init_clocks(int xtal); +static void exynos5_init_clocks(int xtal); +static void exynos_init_uarts(struct s3c2410_uartcfg *cfg, int no); +static int exynos_init(void); static struct cpu_table cpu_ids[] __initdata = { { @@ -56,7 +68,7 @@ static struct cpu_table cpu_ids[] __initdata = { .idmask = EXYNOS4_CPU_MASK, .map_io = exynos4_map_io, .init_clocks = exynos4_init_clocks, - .init_uarts = exynos4_init_uarts, + .init_uarts = exynos_init_uarts, .init = exynos_init, .name = name_exynos4210, }, { @@ -64,7 +76,7 @@ static struct cpu_table cpu_ids[] __initdata = { .idmask = EXYNOS4_CPU_MASK, .map_io = exynos4_map_io, .init_clocks = exynos4_init_clocks, - .init_uarts = exynos4_init_uarts, + .init_uarts = exynos_init_uarts, .init = exynos_init, .name = name_exynos4212, }, { @@ -72,9 +84,17 @@ static struct cpu_table cpu_ids[] __initdata = { .idmask = EXYNOS4_CPU_MASK, .map_io = exynos4_map_io, .init_clocks = exynos4_init_clocks, - .init_uarts = exynos4_init_uarts, + .init_uarts = exynos_init_uarts, .init = exynos_init, .name = name_exynos4412, + }, { + .idcode = EXYNOS5250_SOC_ID, + .idmask = EXYNOS5_SOC_MASK, + .map_io = exynos5_map_io, + .init_clocks = exynos5_init_clocks, + .init_uarts = exynos_init_uarts, + .init = exynos_init, + .name = name_exynos5250, }, }; @@ -83,10 +103,14 @@ static struct cpu_table cpu_ids[] __initdata = { static struct map_desc exynos_iodesc[] __initdata = { { .virtual = (unsigned long)S5P_VA_CHIPID, - .pfn = __phys_to_pfn(EXYNOS4_PA_CHIPID), + .pfn = __phys_to_pfn(EXYNOS_PA_CHIPID), .length = SZ_4K, .type = MT_DEVICE, - }, { + }, +}; + +static struct map_desc exynos4_iodesc[] __initdata = { + { .virtual = (unsigned long)S3C_VA_SYS, .pfn = __phys_to_pfn(EXYNOS4_PA_SYSCON), .length = SZ_64K, @@ -136,11 +160,7 @@ static struct map_desc exynos_iodesc[] __initdata = { .pfn = __phys_to_pfn(EXYNOS4_PA_UART), .length = SZ_512K, .type = MT_DEVICE, - }, -}; - -static struct map_desc exynos4_iodesc[] __initdata = { - { + }, { .virtual = (unsigned long)S5P_VA_CMU, .pfn = __phys_to_pfn(EXYNOS4_PA_CMU), .length = SZ_128K, @@ -156,24 +176,14 @@ static struct map_desc exynos4_iodesc[] __initdata = { .length = SZ_4K, .type = MT_DEVICE, }, { - .virtual = (unsigned long)S5P_VA_GPIO1, - .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO1), - .length = SZ_4K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S5P_VA_GPIO2, - .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO2), - .length = SZ_4K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S5P_VA_GPIO3, - .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO3), - .length = SZ_256, - .type = MT_DEVICE, - }, { .virtual = (unsigned long)S5P_VA_DMC0, .pfn = __phys_to_pfn(EXYNOS4_PA_DMC0), - .length = SZ_4K, + .length = SZ_64K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_DMC1, + .pfn = __phys_to_pfn(EXYNOS4_PA_DMC1), + .length = SZ_64K, .type = MT_DEVICE, }, { .virtual = (unsigned long)S3C_VA_USB_HSPHY, @@ -201,19 +211,80 @@ static struct map_desc exynos4_iodesc1[] __initdata = { }, }; -static void exynos_idle(void) -{ - if (!need_resched()) - cpu_do_idle(); - - local_irq_enable(); -} +static struct map_desc exynos5_iodesc[] __initdata = { + { + .virtual = (unsigned long)S3C_VA_SYS, + .pfn = __phys_to_pfn(EXYNOS5_PA_SYSCON), + .length = SZ_64K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C_VA_TIMER, + .pfn = __phys_to_pfn(EXYNOS5_PA_TIMER), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C_VA_WATCHDOG, + .pfn = __phys_to_pfn(EXYNOS5_PA_WATCHDOG), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_SROMC, + .pfn = __phys_to_pfn(EXYNOS5_PA_SROMC), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_SYSTIMER, + .pfn = __phys_to_pfn(EXYNOS5_PA_SYSTIMER), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_SYSRAM, + .pfn = __phys_to_pfn(EXYNOS5_PA_SYSRAM), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_CMU, + .pfn = __phys_to_pfn(EXYNOS5_PA_CMU), + .length = 144 * SZ_1K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_PMU, + .pfn = __phys_to_pfn(EXYNOS5_PA_PMU), + .length = SZ_64K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_COMBINER_BASE, + .pfn = __phys_to_pfn(EXYNOS5_PA_COMBINER), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C_VA_UART, + .pfn = __phys_to_pfn(EXYNOS5_PA_UART), + .length = SZ_512K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_GIC_CPU, + .pfn = __phys_to_pfn(EXYNOS5_PA_GIC_CPU), + .length = SZ_64K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_GIC_DIST, + .pfn = __phys_to_pfn(EXYNOS5_PA_GIC_DIST), + .length = SZ_64K, + .type = MT_DEVICE, + }, +}; void exynos4_restart(char mode, const char *cmd) { __raw_writel(0x1, S5P_SWRESET); } +void exynos5_restart(char mode, const char *cmd) +{ + __raw_writel(0x1, EXYNOS_SWRESET); +} + /* * exynos_map_io * @@ -233,7 +304,7 @@ void __init exynos_init_io(struct map_desc *mach_desc, int size) s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids)); } -void __init exynos4_map_io(void) +static void __init exynos4_map_io(void) { iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc)); @@ -264,7 +335,22 @@ void __init exynos4_map_io(void) s5p_hdmi_setname("exynos4-hdmi"); } -void __init exynos4_init_clocks(int xtal) +static void __init exynos5_map_io(void) +{ + iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc)); + + s3c_device_i2c0.resource[0].start = EXYNOS5_PA_IIC(0); + s3c_device_i2c0.resource[0].end = EXYNOS5_PA_IIC(0) + SZ_4K - 1; + s3c_device_i2c0.resource[1].start = EXYNOS5_IRQ_IIC; + s3c_device_i2c0.resource[1].end = EXYNOS5_IRQ_IIC; + + /* The I2C bus controllers are directly compatible with s3c2440 */ + s3c_i2c0_setname("s3c2440-i2c"); + s3c_i2c1_setname("s3c2440-i2c"); + s3c_i2c2_setname("s3c2440-i2c"); +} + +static void __init exynos4_init_clocks(int xtal) { printk(KERN_DEBUG "%s: initializing clocks\n", __func__); @@ -280,6 +366,17 @@ void __init exynos4_init_clocks(int xtal) exynos4_setup_clocks(); } +static void __init exynos5_init_clocks(int xtal) +{ + printk(KERN_DEBUG "%s: initializing clocks\n", __func__); + + s3c24xx_register_baseclocks(xtal); + s5p_register_clocks(xtal); + + exynos5_register_clocks(); + exynos5_setup_clocks(); +} + #define COMBINER_ENABLE_SET 0x0 #define COMBINER_ENABLE_CLEAR 0x4 #define COMBINER_INT_STATUS 0xC @@ -353,7 +450,14 @@ static struct irq_chip combiner_chip = { static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq) { - if (combiner_nr >= MAX_COMBINER_NR) + unsigned int max_nr; + + if (soc_is_exynos5250()) + max_nr = EXYNOS5_MAX_COMBINER_NR; + else + max_nr = EXYNOS4_MAX_COMBINER_NR; + + if (combiner_nr >= max_nr) BUG(); if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0) BUG(); @@ -364,8 +468,14 @@ static void __init combiner_init(unsigned int combiner_nr, void __iomem *base, unsigned int irq_start) { unsigned int i; + unsigned int max_nr; - if (combiner_nr >= MAX_COMBINER_NR) + if (soc_is_exynos5250()) + max_nr = EXYNOS5_MAX_COMBINER_NR; + else + max_nr = EXYNOS4_MAX_COMBINER_NR; + + if (combiner_nr >= max_nr) BUG(); combiner_data[combiner_nr].base = base; @@ -408,8 +518,28 @@ void __init exynos4_init_irq(void) of_irq_init(exynos4_dt_irq_match); #endif - for (irq = 0; irq < MAX_COMBINER_NR; irq++) { + for (irq = 0; irq < EXYNOS4_MAX_COMBINER_NR; irq++) { + + combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq), + COMBINER_IRQ(irq, 0)); + combiner_cascade_irq(irq, IRQ_SPI(irq)); + } + + /* + * The parameters of s5p_init_irq() are for VIC init. + * Theses parameters should be NULL and 0 because EXYNOS4 + * uses GIC instead of VIC. + */ + s5p_init_irq(NULL, 0); +} + +void __init exynos5_init_irq(void) +{ + int irq; + + gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); + for (irq = 0; irq < EXYNOS5_MAX_COMBINER_NR; irq++) { combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq), COMBINER_IRQ(irq, 0)); combiner_cascade_irq(irq, IRQ_SPI(irq)); @@ -428,55 +558,120 @@ struct bus_type exynos4_subsys = { .dev_name = "exynos4-core", }; +struct bus_type exynos5_subsys = { + .name = "exynos5-core", + .dev_name = "exynos5-core", +}; + static struct device exynos4_dev = { .bus = &exynos4_subsys, }; -static int __init exynos4_core_init(void) +static struct device exynos5_dev = { + .bus = &exynos5_subsys, +}; + +static int __init exynos_core_init(void) { - return subsys_system_register(&exynos4_subsys, NULL); + if (soc_is_exynos5250()) + return subsys_system_register(&exynos5_subsys, NULL); + else + return subsys_system_register(&exynos4_subsys, NULL); } -core_initcall(exynos4_core_init); +core_initcall(exynos_core_init); #ifdef CONFIG_CACHE_L2X0 static int __init exynos4_l2x0_cache_init(void) { - /* TAG, Data Latency Control: 2cycle */ - __raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL); + int ret; - if (soc_is_exynos4210()) - __raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); - else if (soc_is_exynos4212() || soc_is_exynos4412()) - __raw_writel(0x120, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); + if (soc_is_exynos5250()) + return 0; + + ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK); + if (!ret) { + l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs); + clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long)); + return 0; + } + + if (!(__raw_readl(S5P_VA_L2CC + L2X0_CTRL) & 0x1)) { + l2x0_saved_regs.phy_base = EXYNOS4_PA_L2CC; + /* TAG, Data Latency Control: 2 cycles */ + l2x0_saved_regs.tag_latency = 0x110; + + if (soc_is_exynos4212() || soc_is_exynos4412()) + l2x0_saved_regs.data_latency = 0x120; + else + l2x0_saved_regs.data_latency = 0x110; - /* L2X0 Prefetch Control */ - __raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL); + l2x0_saved_regs.prefetch_ctrl = 0x30000007; + l2x0_saved_regs.pwr_ctrl = + (L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN); - /* L2X0 Power Control */ - __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN, - S5P_VA_L2CC + L2X0_POWER_CTRL); + l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs); - l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff); + __raw_writel(l2x0_saved_regs.tag_latency, + S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL); + __raw_writel(l2x0_saved_regs.data_latency, + S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); + /* L2X0 Prefetch Control */ + __raw_writel(l2x0_saved_regs.prefetch_ctrl, + S5P_VA_L2CC + L2X0_PREFETCH_CTRL); + + /* L2X0 Power Control */ + __raw_writel(l2x0_saved_regs.pwr_ctrl, + S5P_VA_L2CC + L2X0_POWER_CTRL); + + clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long)); + clean_dcache_area(&l2x0_saved_regs, sizeof(struct l2x0_regs)); + } + + l2x0_init(S5P_VA_L2CC, L2_AUX_VAL, L2_AUX_MASK); return 0; } - early_initcall(exynos4_l2x0_cache_init); #endif -int __init exynos_init(void) +static int __init exynos5_l2_cache_init(void) { - printk(KERN_INFO "EXYNOS: Initializing architecture\n"); + unsigned int val; + + if (!soc_is_exynos5250()) + return 0; + + asm volatile("mrc p15, 0, %0, c1, c0, 0\n" + "bic %0, %0, #(1 << 2)\n" /* cache disable */ + "mcr p15, 0, %0, c1, c0, 0\n" + "mrc p15, 1, %0, c9, c0, 2\n" + : "=r"(val)); + + val |= (1 << 9) | (1 << 5) | (2 << 6) | (2 << 0); + + asm volatile("mcr p15, 1, %0, c9, c0, 2\n" : : "r"(val)); + asm volatile("mrc p15, 0, %0, c1, c0, 0\n" + "orr %0, %0, #(1 << 2)\n" /* cache enable */ + "mcr p15, 0, %0, c1, c0, 0\n" + : : "r"(val)); + + return 0; +} +early_initcall(exynos5_l2_cache_init); - /* set idle function */ - pm_idle = exynos_idle; +static int __init exynos_init(void) +{ + printk(KERN_INFO "EXYNOS: Initializing architecture\n"); - return device_register(&exynos4_dev); + if (soc_is_exynos5250()) + return device_register(&exynos5_dev); + else + return device_register(&exynos4_dev); } /* uart registration process */ -void __init exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no) +static void __init exynos_init_uarts(struct s3c2410_uartcfg *cfg, int no) { struct s3c2410_uartcfg *tcfg = cfg; u32 ucnt; @@ -484,69 +679,138 @@ void __init exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no) for (ucnt = 0; ucnt < no; ucnt++, tcfg++) tcfg->has_fracval = 1; - s3c24xx_init_uartdevs("exynos4210-uart", s5p_uart_resources, cfg, no); + if (soc_is_exynos5250()) + s3c24xx_init_uartdevs("exynos4210-uart", exynos5_uart_resources, cfg, no); + else + s3c24xx_init_uartdevs("exynos4210-uart", exynos4_uart_resources, cfg, no); } +static void __iomem *exynos_eint_base; + static DEFINE_SPINLOCK(eint_lock); static unsigned int eint0_15_data[16]; -static unsigned int exynos4_get_irq_nr(unsigned int number) +static inline int exynos4_irq_to_gpio(unsigned int irq) { - u32 ret = 0; + if (irq < IRQ_EINT(0)) + return -EINVAL; - switch (number) { - case 0 ... 3: - ret = (number + IRQ_EINT0); - break; - case 4 ... 7: - ret = (number + (IRQ_EINT4 - 4)); - break; - case 8 ... 15: - ret = (number + (IRQ_EINT8 - 8)); - break; - default: - printk(KERN_ERR "number available : %d\n", number); - } + irq -= IRQ_EINT(0); + if (irq < 8) + return EXYNOS4_GPX0(irq); + + irq -= 8; + if (irq < 8) + return EXYNOS4_GPX1(irq); + + irq -= 8; + if (irq < 8) + return EXYNOS4_GPX2(irq); - return ret; + irq -= 8; + if (irq < 8) + return EXYNOS4_GPX3(irq); + + return -EINVAL; } -static inline void exynos4_irq_eint_mask(struct irq_data *data) +static inline int exynos5_irq_to_gpio(unsigned int irq) +{ + if (irq < IRQ_EINT(0)) + return -EINVAL; + + irq -= IRQ_EINT(0); + if (irq < 8) + return EXYNOS5_GPX0(irq); + + irq -= 8; + if (irq < 8) + return EXYNOS5_GPX1(irq); + + irq -= 8; + if (irq < 8) + return EXYNOS5_GPX2(irq); + + irq -= 8; + if (irq < 8) + return EXYNOS5_GPX3(irq); + + return -EINVAL; +} + +static unsigned int exynos4_eint0_15_src_int[16] = { + EXYNOS4_IRQ_EINT0, + EXYNOS4_IRQ_EINT1, + EXYNOS4_IRQ_EINT2, + EXYNOS4_IRQ_EINT3, + EXYNOS4_IRQ_EINT4, + EXYNOS4_IRQ_EINT5, + EXYNOS4_IRQ_EINT6, + EXYNOS4_IRQ_EINT7, + EXYNOS4_IRQ_EINT8, + EXYNOS4_IRQ_EINT9, + EXYNOS4_IRQ_EINT10, + EXYNOS4_IRQ_EINT11, + EXYNOS4_IRQ_EINT12, + EXYNOS4_IRQ_EINT13, + EXYNOS4_IRQ_EINT14, + EXYNOS4_IRQ_EINT15, +}; + +static unsigned int exynos5_eint0_15_src_int[16] = { + EXYNOS5_IRQ_EINT0, + EXYNOS5_IRQ_EINT1, + EXYNOS5_IRQ_EINT2, + EXYNOS5_IRQ_EINT3, + EXYNOS5_IRQ_EINT4, + EXYNOS5_IRQ_EINT5, + EXYNOS5_IRQ_EINT6, + EXYNOS5_IRQ_EINT7, + EXYNOS5_IRQ_EINT8, + EXYNOS5_IRQ_EINT9, + EXYNOS5_IRQ_EINT10, + EXYNOS5_IRQ_EINT11, + EXYNOS5_IRQ_EINT12, + EXYNOS5_IRQ_EINT13, + EXYNOS5_IRQ_EINT14, + EXYNOS5_IRQ_EINT15, +}; +static inline void exynos_irq_eint_mask(struct irq_data *data) { u32 mask; spin_lock(&eint_lock); - mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq))); - mask |= eint_irq_to_bit(data->irq); - __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq))); + mask = __raw_readl(EINT_MASK(exynos_eint_base, data->irq)); + mask |= EINT_OFFSET_BIT(data->irq); + __raw_writel(mask, EINT_MASK(exynos_eint_base, data->irq)); spin_unlock(&eint_lock); } -static void exynos4_irq_eint_unmask(struct irq_data *data) +static void exynos_irq_eint_unmask(struct irq_data *data) { u32 mask; spin_lock(&eint_lock); - mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq))); - mask &= ~(eint_irq_to_bit(data->irq)); - __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq))); + mask = __raw_readl(EINT_MASK(exynos_eint_base, data->irq)); + mask &= ~(EINT_OFFSET_BIT(data->irq)); + __raw_writel(mask, EINT_MASK(exynos_eint_base, data->irq)); spin_unlock(&eint_lock); } -static inline void exynos4_irq_eint_ack(struct irq_data *data) +static inline void exynos_irq_eint_ack(struct irq_data *data) { - __raw_writel(eint_irq_to_bit(data->irq), - S5P_EINT_PEND(EINT_REG_NR(data->irq))); + __raw_writel(EINT_OFFSET_BIT(data->irq), + EINT_PEND(exynos_eint_base, data->irq)); } -static void exynos4_irq_eint_maskack(struct irq_data *data) +static void exynos_irq_eint_maskack(struct irq_data *data) { - exynos4_irq_eint_mask(data); - exynos4_irq_eint_ack(data); + exynos_irq_eint_mask(data); + exynos_irq_eint_ack(data); } -static int exynos4_irq_eint_set_type(struct irq_data *data, unsigned int type) +static int exynos_irq_eint_set_type(struct irq_data *data, unsigned int type) { int offs = EINT_OFFSET(data->irq); int shift; @@ -583,39 +847,27 @@ static int exynos4_irq_eint_set_type(struct irq_data *data, unsigned int type) mask = 0x7 << shift; spin_lock(&eint_lock); - ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq))); + ctrl = __raw_readl(EINT_CON(exynos_eint_base, data->irq)); ctrl &= ~mask; ctrl |= newvalue << shift; - __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq))); + __raw_writel(ctrl, EINT_CON(exynos_eint_base, data->irq)); spin_unlock(&eint_lock); - switch (offs) { - case 0 ... 7: - s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE); - break; - case 8 ... 15: - s3c_gpio_cfgpin(EINT_GPIO_1(offs & 0x7), EINT_MODE); - break; - case 16 ... 23: - s3c_gpio_cfgpin(EINT_GPIO_2(offs & 0x7), EINT_MODE); - break; - case 24 ... 31: - s3c_gpio_cfgpin(EINT_GPIO_3(offs & 0x7), EINT_MODE); - break; - default: - printk(KERN_ERR "No such irq number %d", offs); - } + if (soc_is_exynos5250()) + s3c_gpio_cfgpin(exynos5_irq_to_gpio(data->irq), S3C_GPIO_SFN(0xf)); + else + s3c_gpio_cfgpin(exynos4_irq_to_gpio(data->irq), S3C_GPIO_SFN(0xf)); return 0; } -static struct irq_chip exynos4_irq_eint = { - .name = "exynos4-eint", - .irq_mask = exynos4_irq_eint_mask, - .irq_unmask = exynos4_irq_eint_unmask, - .irq_mask_ack = exynos4_irq_eint_maskack, - .irq_ack = exynos4_irq_eint_ack, - .irq_set_type = exynos4_irq_eint_set_type, +static struct irq_chip exynos_irq_eint = { + .name = "exynos-eint", + .irq_mask = exynos_irq_eint_mask, + .irq_unmask = exynos_irq_eint_unmask, + .irq_mask_ack = exynos_irq_eint_maskack, + .irq_ack = exynos_irq_eint_ack, + .irq_set_type = exynos_irq_eint_set_type, #ifdef CONFIG_PM .irq_set_wake = s3c_irqext_wake, #endif @@ -630,12 +882,12 @@ static struct irq_chip exynos4_irq_eint = { * * Each EINT pend/mask registers handle eight of them. */ -static inline void exynos4_irq_demux_eint(unsigned int start) +static inline void exynos_irq_demux_eint(unsigned int start) { unsigned int irq; - u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start))); - u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start))); + u32 status = __raw_readl(EINT_PEND(exynos_eint_base, start)); + u32 mask = __raw_readl(EINT_MASK(exynos_eint_base, start)); status &= ~mask; status &= 0xff; @@ -647,16 +899,16 @@ static inline void exynos4_irq_demux_eint(unsigned int start) } } -static void exynos4_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) +static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) { struct irq_chip *chip = irq_get_chip(irq); chained_irq_enter(chip, desc); - exynos4_irq_demux_eint(IRQ_EINT(16)); - exynos4_irq_demux_eint(IRQ_EINT(24)); + exynos_irq_demux_eint(IRQ_EINT(16)); + exynos_irq_demux_eint(IRQ_EINT(24)); chained_irq_exit(chip, desc); } -static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc) +static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc) { u32 *irq_data = irq_get_handler_data(irq); struct irq_chip *chip = irq_get_chip(irq); @@ -673,27 +925,44 @@ static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc) chained_irq_exit(chip, desc); } -int __init exynos4_init_irq_eint(void) +static int __init exynos_init_irq_eint(void) { int irq; + if (soc_is_exynos5250()) + exynos_eint_base = ioremap(EXYNOS5_PA_GPIO1, SZ_4K); + else + exynos_eint_base = ioremap(EXYNOS4_PA_GPIO2, SZ_4K); + + if (exynos_eint_base == NULL) { + pr_err("unable to ioremap for EINT base address\n"); + return -ENOMEM; + } + for (irq = 0 ; irq <= 31 ; irq++) { - irq_set_chip_and_handler(IRQ_EINT(irq), &exynos4_irq_eint, + irq_set_chip_and_handler(IRQ_EINT(irq), &exynos_irq_eint, handle_level_irq); set_irq_flags(IRQ_EINT(irq), IRQF_VALID); } - irq_set_chained_handler(IRQ_EINT16_31, exynos4_irq_demux_eint16_31); + irq_set_chained_handler(EXYNOS_IRQ_EINT16_31, exynos_irq_demux_eint16_31); for (irq = 0 ; irq <= 15 ; irq++) { eint0_15_data[irq] = IRQ_EINT(irq); - irq_set_handler_data(exynos4_get_irq_nr(irq), - &eint0_15_data[irq]); - irq_set_chained_handler(exynos4_get_irq_nr(irq), - exynos4_irq_eint0_15); + if (soc_is_exynos5250()) { + irq_set_handler_data(exynos5_eint0_15_src_int[irq], + &eint0_15_data[irq]); + irq_set_chained_handler(exynos5_eint0_15_src_int[irq], + exynos_irq_eint0_15); + } else { + irq_set_handler_data(exynos4_eint0_15_src_int[irq], + &eint0_15_data[irq]); + irq_set_chained_handler(exynos4_eint0_15_src_int[irq], + exynos_irq_eint0_15); + } } return 0; } -arch_initcall(exynos4_init_irq_eint); +arch_initcall(exynos_init_irq_eint); diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h index 1ac49de0f398..677b5467df18 100644 --- a/arch/arm/mach-exynos/common.h +++ b/arch/arm/mach-exynos/common.h @@ -12,30 +12,44 @@ #ifndef __ARCH_ARM_MACH_EXYNOS_COMMON_H #define __ARCH_ARM_MACH_EXYNOS_COMMON_H +extern struct sys_timer exynos4_timer; + void exynos_init_io(struct map_desc *mach_desc, int size); void exynos4_init_irq(void); +void exynos5_init_irq(void); +void exynos4_restart(char mode, const char *cmd); +void exynos5_restart(char mode, const char *cmd); +#ifdef CONFIG_ARCH_EXYNOS4 void exynos4_register_clocks(void); void exynos4_setup_clocks(void); -void exynos4210_register_clocks(void); -void exynos4212_register_clocks(void); +#else +#define exynos4_register_clocks() +#define exynos4_setup_clocks() +#endif -void exynos4_restart(char mode, const char *cmd); +#ifdef CONFIG_ARCH_EXYNOS5 +void exynos5_register_clocks(void); +void exynos5_setup_clocks(void); -extern struct sys_timer exynos4_timer; +#else +#define exynos5_register_clocks() +#define exynos5_setup_clocks() +#endif + +#ifdef CONFIG_CPU_EXYNOS4210 +void exynos4210_register_clocks(void); -#ifdef CONFIG_ARCH_EXYNOS -extern int exynos_init(void); -extern void exynos4_map_io(void); -extern void exynos4_init_clocks(int xtal); -extern void exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no); +#else +#define exynos4210_register_clocks() +#endif + +#ifdef CONFIG_SOC_EXYNOS4212 +void exynos4212_register_clocks(void); #else -#define exynos4_init_clocks NULL -#define exynos4_init_uarts NULL -#define exynos4_map_io NULL -#define exynos_init NULL +#define exynos4212_register_clocks() #endif #endif /* __ARCH_ARM_MACH_EXYNOS_COMMON_H */ diff --git a/arch/arm/mach-exynos/cpuidle.c b/arch/arm/mach-exynos/cpuidle.c index 4ebb382c5979..33ab4e7558af 100644 --- a/arch/arm/mach-exynos/cpuidle.c +++ b/arch/arm/mach-exynos/cpuidle.c @@ -11,25 +11,53 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/cpuidle.h> +#include <linux/cpu_pm.h> #include <linux/io.h> #include <linux/export.h> #include <linux/time.h> #include <asm/proc-fns.h> +#include <asm/smp_scu.h> +#include <asm/suspend.h> +#include <asm/unified.h> +#include <mach/regs-pmu.h> +#include <mach/pmu.h> + +#include <plat/cpu.h> + +#define REG_DIRECTGO_ADDR (samsung_rev() == EXYNOS4210_REV_1_1 ? \ + S5P_INFORM7 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \ + (S5P_VA_SYSRAM + 0x24) : S5P_INFORM0)) +#define REG_DIRECTGO_FLAG (samsung_rev() == EXYNOS4210_REV_1_1 ? \ + S5P_INFORM6 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \ + (S5P_VA_SYSRAM + 0x20) : S5P_INFORM1)) + +#define S5P_CHECK_AFTR 0xFCBA0D10 static int exynos4_enter_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index); +static int exynos4_enter_lowpower(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index); -static struct cpuidle_state exynos4_cpuidle_set[] = { +static struct cpuidle_state exynos4_cpuidle_set[] __initdata = { [0] = { .enter = exynos4_enter_idle, .exit_latency = 1, .target_residency = 100000, .flags = CPUIDLE_FLAG_TIME_VALID, - .name = "IDLE", + .name = "C0", .desc = "ARM clock gating(WFI)", }, + [1] = { + .enter = exynos4_enter_lowpower, + .exit_latency = 300, + .target_residency = 100000, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "C1", + .desc = "ARM power down", + }, }; static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device); @@ -39,9 +67,102 @@ static struct cpuidle_driver exynos4_idle_driver = { .owner = THIS_MODULE, }; +/* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */ +static void exynos4_set_wakeupmask(void) +{ + __raw_writel(0x0000ff3e, S5P_WAKEUP_MASK); +} + +static unsigned int g_pwr_ctrl, g_diag_reg; + +static void save_cpu_arch_register(void) +{ + /*read power control register*/ + asm("mrc p15, 0, %0, c15, c0, 0" : "=r"(g_pwr_ctrl) : : "cc"); + /*read diagnostic register*/ + asm("mrc p15, 0, %0, c15, c0, 1" : "=r"(g_diag_reg) : : "cc"); + return; +} + +static void restore_cpu_arch_register(void) +{ + /*write power control register*/ + asm("mcr p15, 0, %0, c15, c0, 0" : : "r"(g_pwr_ctrl) : "cc"); + /*write diagnostic register*/ + asm("mcr p15, 0, %0, c15, c0, 1" : : "r"(g_diag_reg) : "cc"); + return; +} + +static int idle_finisher(unsigned long flags) +{ + cpu_do_idle(); + return 1; +} + +static int exynos4_enter_core0_aftr(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + struct timeval before, after; + int idle_time; + unsigned long tmp; + + local_irq_disable(); + do_gettimeofday(&before); + + exynos4_set_wakeupmask(); + + /* Set value of power down register for aftr mode */ + exynos4_sys_powerdown_conf(SYS_AFTR); + + __raw_writel(virt_to_phys(s3c_cpu_resume), REG_DIRECTGO_ADDR); + __raw_writel(S5P_CHECK_AFTR, REG_DIRECTGO_FLAG); + + save_cpu_arch_register(); + + /* Setting Central Sequence Register for power down mode */ + tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION); + tmp &= ~S5P_CENTRAL_LOWPWR_CFG; + __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); + + cpu_pm_enter(); + cpu_suspend(0, idle_finisher); + +#ifdef CONFIG_SMP + scu_enable(S5P_VA_SCU); +#endif + cpu_pm_exit(); + + restore_cpu_arch_register(); + + /* + * If PMU failed while entering sleep mode, WFI will be + * ignored by PMU and then exiting cpu_do_idle(). + * S5P_CENTRAL_LOWPWR_CFG bit will not be set automatically + * in this situation. + */ + tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION); + if (!(tmp & S5P_CENTRAL_LOWPWR_CFG)) { + tmp |= S5P_CENTRAL_LOWPWR_CFG; + __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); + } + + /* Clear wakeup state register */ + __raw_writel(0x0, S5P_WAKEUP_STAT); + + do_gettimeofday(&after); + + local_irq_enable(); + idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + + (after.tv_usec - before.tv_usec); + + dev->last_residency = idle_time; + return index; +} + static int exynos4_enter_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, - int index) + int index) { struct timeval before, after; int idle_time; @@ -60,6 +181,22 @@ static int exynos4_enter_idle(struct cpuidle_device *dev, return index; } +static int exynos4_enter_lowpower(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + int new_index = index; + + /* This mode only can be entered when other core's are offline */ + if (num_online_cpus() > 1) + new_index = drv->safe_state_index; + + if (new_index == 0) + return exynos4_enter_idle(dev, drv, new_index); + else + return exynos4_enter_core0_aftr(dev, drv, new_index); +} + static int __init exynos4_init_cpuidle(void) { int i, max_cpuidle_state, cpu_id; @@ -74,19 +211,25 @@ static int __init exynos4_init_cpuidle(void) memcpy(&drv->states[i], &exynos4_cpuidle_set[i], sizeof(struct cpuidle_state)); } + drv->safe_state_index = 0; cpuidle_register_driver(&exynos4_idle_driver); for_each_cpu(cpu_id, cpu_online_mask) { device = &per_cpu(exynos4_cpuidle_device, cpu_id); device->cpu = cpu_id; - device->state_count = drv->state_count; + if (cpu_id == 0) + device->state_count = (sizeof(exynos4_cpuidle_set) / + sizeof(struct cpuidle_state)); + else + device->state_count = 1; /* Support IDLE only */ if (cpuidle_register_device(device)) { printk(KERN_ERR "CPUidle register device failed\n,"); return -EIO; } } + return 0; } device_initcall(exynos4_init_cpuidle); diff --git a/arch/arm/mach-exynos/dev-ahci.c b/arch/arm/mach-exynos/dev-ahci.c index f57a3de8e1d2..50ce5b0adcf1 100644 --- a/arch/arm/mach-exynos/dev-ahci.c +++ b/arch/arm/mach-exynos/dev-ahci.c @@ -242,8 +242,8 @@ static struct resource exynos4_ahci_resource[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = IRQ_SATA, - .end = IRQ_SATA, + .start = EXYNOS4_IRQ_SATA, + .end = EXYNOS4_IRQ_SATA, .flags = IORESOURCE_IRQ, }, }; diff --git a/arch/arm/mach-exynos/dev-audio.c b/arch/arm/mach-exynos/dev-audio.c index 5a9f9c2e53bf..7199e1ae79b4 100644 --- a/arch/arm/mach-exynos/dev-audio.c +++ b/arch/arm/mach-exynos/dev-audio.c @@ -304,8 +304,8 @@ static struct resource exynos4_ac97_resource[] = { .flags = IORESOURCE_DMA, }, [4] = { - .start = IRQ_AC97, - .end = IRQ_AC97, + .start = EXYNOS4_IRQ_AC97, + .end = EXYNOS4_IRQ_AC97, .flags = IORESOURCE_IRQ, }, }; diff --git a/arch/arm/mach-exynos/dev-uart.c b/arch/arm/mach-exynos/dev-uart.c new file mode 100644 index 000000000000..2e85c022fd16 --- /dev/null +++ b/arch/arm/mach-exynos/dev-uart.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Base EXYNOS UART resource and device definitions + * + * 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 <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/ioport.h> +#include <linux/platform_device.h> + +#include <asm/mach/arch.h> +#include <asm/mach/irq.h> +#include <mach/hardware.h> +#include <mach/map.h> + +#include <plat/devs.h> + +#define EXYNOS_UART_RESOURCE(_series, _nr) \ +static struct resource exynos##_series##_uart##_nr##_resource[] = { \ + [0] = DEFINE_RES_MEM(EXYNOS##_series##_PA_UART##_nr, EXYNOS##_series##_SZ_UART), \ + [1] = DEFINE_RES_IRQ(EXYNOS##_series##_IRQ_UART##_nr), \ +}; + +EXYNOS_UART_RESOURCE(4, 0) +EXYNOS_UART_RESOURCE(4, 1) +EXYNOS_UART_RESOURCE(4, 2) +EXYNOS_UART_RESOURCE(4, 3) + +struct s3c24xx_uart_resources exynos4_uart_resources[] __initdata = { + [0] = { + .resources = exynos4_uart0_resource, + .nr_resources = ARRAY_SIZE(exynos4_uart0_resource), + }, + [1] = { + .resources = exynos4_uart1_resource, + .nr_resources = ARRAY_SIZE(exynos4_uart1_resource), + }, + [2] = { + .resources = exynos4_uart2_resource, + .nr_resources = ARRAY_SIZE(exynos4_uart2_resource), + }, + [3] = { + .resources = exynos4_uart3_resource, + .nr_resources = ARRAY_SIZE(exynos4_uart3_resource), + }, +}; + +EXYNOS_UART_RESOURCE(5, 0) +EXYNOS_UART_RESOURCE(5, 1) +EXYNOS_UART_RESOURCE(5, 2) +EXYNOS_UART_RESOURCE(5, 3) + +struct s3c24xx_uart_resources exynos5_uart_resources[] __initdata = { + [0] = { + .resources = exynos5_uart0_resource, + .nr_resources = ARRAY_SIZE(exynos5_uart0_resource), + }, + [1] = { + .resources = exynos5_uart1_resource, + .nr_resources = ARRAY_SIZE(exynos5_uart0_resource), + }, + [2] = { + .resources = exynos5_uart2_resource, + .nr_resources = ARRAY_SIZE(exynos5_uart2_resource), + }, + [3] = { + .resources = exynos5_uart3_resource, + .nr_resources = ARRAY_SIZE(exynos5_uart3_resource), + }, +}; diff --git a/arch/arm/mach-exynos/dma.c b/arch/arm/mach-exynos/dma.c index b10fcd270f07..69aaa4503205 100644 --- a/arch/arm/mach-exynos/dma.c +++ b/arch/arm/mach-exynos/dma.c @@ -29,14 +29,13 @@ #include <asm/irq.h> #include <plat/devs.h> #include <plat/irqs.h> +#include <plat/cpu.h> #include <mach/map.h> #include <mach/irqs.h> #include <mach/dma.h> -static u64 dma_dmamask = DMA_BIT_MASK(32); - -u8 pdma0_peri[] = { +static u8 exynos4210_pdma0_peri[] = { DMACH_PCM0_RX, DMACH_PCM0_TX, DMACH_PCM2_RX, @@ -69,28 +68,47 @@ u8 pdma0_peri[] = { DMACH_AC97_PCMOUT, }; -struct dma_pl330_platdata exynos4_pdma0_pdata = { - .nr_valid_peri = ARRAY_SIZE(pdma0_peri), - .peri_id = pdma0_peri, +static u8 exynos4212_pdma0_peri[] = { + DMACH_PCM0_RX, + DMACH_PCM0_TX, + DMACH_PCM2_RX, + DMACH_PCM2_TX, + DMACH_MIPI_HSI0, + DMACH_MIPI_HSI1, + DMACH_SPI0_RX, + DMACH_SPI0_TX, + DMACH_SPI2_RX, + DMACH_SPI2_TX, + DMACH_I2S0S_TX, + DMACH_I2S0_RX, + DMACH_I2S0_TX, + DMACH_I2S2_RX, + DMACH_I2S2_TX, + DMACH_UART0_RX, + DMACH_UART0_TX, + DMACH_UART2_RX, + DMACH_UART2_TX, + DMACH_UART4_RX, + DMACH_UART4_TX, + DMACH_SLIMBUS0_RX, + DMACH_SLIMBUS0_TX, + DMACH_SLIMBUS2_RX, + DMACH_SLIMBUS2_TX, + DMACH_SLIMBUS4_RX, + DMACH_SLIMBUS4_TX, + DMACH_AC97_MICIN, + DMACH_AC97_PCMIN, + DMACH_AC97_PCMOUT, + DMACH_MIPI_HSI4, + DMACH_MIPI_HSI5, }; -struct amba_device exynos4_device_pdma0 = { - .dev = { - .init_name = "dma-pl330.0", - .dma_mask = &dma_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &exynos4_pdma0_pdata, - }, - .res = { - .start = EXYNOS4_PA_PDMA0, - .end = EXYNOS4_PA_PDMA0 + SZ_4K, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_PDMA0, NO_IRQ}, - .periphid = 0x00041330, -}; +struct dma_pl330_platdata exynos4_pdma0_pdata; + +static AMBA_AHB_DEVICE(exynos4_pdma0, "dma-pl330.0", 0x00041330, + EXYNOS4_PA_PDMA0, {EXYNOS4_IRQ_PDMA0}, &exynos4_pdma0_pdata); -u8 pdma1_peri[] = { +static u8 exynos4210_pdma1_peri[] = { DMACH_PCM0_RX, DMACH_PCM0_TX, DMACH_PCM1_RX, @@ -118,39 +136,94 @@ u8 pdma1_peri[] = { DMACH_SLIMBUS5_TX, }; -struct dma_pl330_platdata exynos4_pdma1_pdata = { - .nr_valid_peri = ARRAY_SIZE(pdma1_peri), - .peri_id = pdma1_peri, +static u8 exynos4212_pdma1_peri[] = { + DMACH_PCM0_RX, + DMACH_PCM0_TX, + DMACH_PCM1_RX, + DMACH_PCM1_TX, + DMACH_MIPI_HSI2, + DMACH_MIPI_HSI3, + DMACH_SPI1_RX, + DMACH_SPI1_TX, + DMACH_I2S0S_TX, + DMACH_I2S0_RX, + DMACH_I2S0_TX, + DMACH_I2S1_RX, + DMACH_I2S1_TX, + DMACH_UART0_RX, + DMACH_UART0_TX, + DMACH_UART1_RX, + DMACH_UART1_TX, + DMACH_UART3_RX, + DMACH_UART3_TX, + DMACH_SLIMBUS1_RX, + DMACH_SLIMBUS1_TX, + DMACH_SLIMBUS3_RX, + DMACH_SLIMBUS3_TX, + DMACH_SLIMBUS5_RX, + DMACH_SLIMBUS5_TX, + DMACH_SLIMBUS0AUX_RX, + DMACH_SLIMBUS0AUX_TX, + DMACH_SPDIF, + DMACH_MIPI_HSI6, + DMACH_MIPI_HSI7, }; -struct amba_device exynos4_device_pdma1 = { - .dev = { - .init_name = "dma-pl330.1", - .dma_mask = &dma_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &exynos4_pdma1_pdata, - }, - .res = { - .start = EXYNOS4_PA_PDMA1, - .end = EXYNOS4_PA_PDMA1 + SZ_4K, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_PDMA1, NO_IRQ}, - .periphid = 0x00041330, +static struct dma_pl330_platdata exynos4_pdma1_pdata; + +static AMBA_AHB_DEVICE(exynos4_pdma1, "dma-pl330.1", 0x00041330, + EXYNOS4_PA_PDMA1, {EXYNOS4_IRQ_PDMA1}, &exynos4_pdma1_pdata); + +static u8 mdma_peri[] = { + DMACH_MTOM_0, + DMACH_MTOM_1, + DMACH_MTOM_2, + DMACH_MTOM_3, + DMACH_MTOM_4, + DMACH_MTOM_5, + DMACH_MTOM_6, + DMACH_MTOM_7, +}; + +static struct dma_pl330_platdata exynos4_mdma1_pdata = { + .nr_valid_peri = ARRAY_SIZE(mdma_peri), + .peri_id = mdma_peri, }; +static AMBA_AHB_DEVICE(exynos4_mdma1, "dma-pl330.2", 0x00041330, + EXYNOS4_PA_MDMA1, {EXYNOS4_IRQ_MDMA1}, &exynos4_mdma1_pdata); + static int __init exynos4_dma_init(void) { if (of_have_populated_dt()) return 0; + if (soc_is_exynos4210()) { + exynos4_pdma0_pdata.nr_valid_peri = + ARRAY_SIZE(exynos4210_pdma0_peri); + exynos4_pdma0_pdata.peri_id = exynos4210_pdma0_peri; + exynos4_pdma1_pdata.nr_valid_peri = + ARRAY_SIZE(exynos4210_pdma1_peri); + exynos4_pdma1_pdata.peri_id = exynos4210_pdma1_peri; + } else if (soc_is_exynos4212() || soc_is_exynos4412()) { + exynos4_pdma0_pdata.nr_valid_peri = + ARRAY_SIZE(exynos4212_pdma0_peri); + exynos4_pdma0_pdata.peri_id = exynos4212_pdma0_peri; + exynos4_pdma1_pdata.nr_valid_peri = + ARRAY_SIZE(exynos4212_pdma1_peri); + exynos4_pdma1_pdata.peri_id = exynos4212_pdma1_peri; + } + dma_cap_set(DMA_SLAVE, exynos4_pdma0_pdata.cap_mask); dma_cap_set(DMA_CYCLIC, exynos4_pdma0_pdata.cap_mask); - amba_device_register(&exynos4_device_pdma0, &iomem_resource); + amba_device_register(&exynos4_pdma0_device, &iomem_resource); dma_cap_set(DMA_SLAVE, exynos4_pdma1_pdata.cap_mask); dma_cap_set(DMA_CYCLIC, exynos4_pdma1_pdata.cap_mask); - amba_device_register(&exynos4_device_pdma1, &iomem_resource); + amba_device_register(&exynos4_pdma1_device, &iomem_resource); + + dma_cap_set(DMA_MEMCPY, exynos4_mdma1_pdata.cap_mask); + amba_device_register(&exynos4_mdma1_device, &iomem_resource); return 0; } diff --git a/arch/arm/mach-exynos/hotplug.c b/arch/arm/mach-exynos/hotplug.c index dd1ad55524c9..9c17a0a43858 100644 --- a/arch/arm/mach-exynos/hotplug.c +++ b/arch/arm/mach-exynos/hotplug.c @@ -16,6 +16,7 @@ #include <linux/io.h> #include <asm/cacheflush.h> +#include <asm/cp15.h> #include <asm/smp_plat.h> #include <mach/regs-pmu.h> diff --git a/arch/arm/mach-exynos/include/mach/cpufreq.h b/arch/arm/mach-exynos/include/mach/cpufreq.h index 3df27f2d5034..7517c3f417af 100644 --- a/arch/arm/mach-exynos/include/mach/cpufreq.h +++ b/arch/arm/mach-exynos/include/mach/cpufreq.h @@ -32,3 +32,5 @@ struct exynos_dvfs_info { }; extern int exynos4210_cpufreq_init(struct exynos_dvfs_info *); +extern int exynos4x12_cpufreq_init(struct exynos_dvfs_info *); +extern int exynos5250_cpufreq_init(struct exynos_dvfs_info *); diff --git a/arch/arm/mach-exynos/include/mach/debug-macro.S b/arch/arm/mach-exynos/include/mach/debug-macro.S index 6cacf16a67a6..e0c86ea475e7 100644 --- a/arch/arm/mach-exynos/include/mach/debug-macro.S +++ b/arch/arm/mach-exynos/include/mach/debug-macro.S @@ -21,8 +21,12 @@ */ .macro addruart, rp, rv, tmp - ldr \rp, = S3C_PA_UART - ldr \rv, = S3C_VA_UART + mrc p15, 0, \tmp, c0, c0, 0 + and \tmp, \tmp, #0xf0 + teq \tmp, #0xf0 @@ A15 + ldreq \rp, =EXYNOS5_PA_UART + movne \rp, #EXYNOS4_PA_UART @@ EXYNOS4 + ldr \rv, =S3C_VA_UART #if CONFIG_DEBUG_S3C_UART != 0 add \rp, \rp, #(0x10000 * CONFIG_DEBUG_S3C_UART) add \rv, \rv, #(0x10000 * CONFIG_DEBUG_S3C_UART) diff --git a/arch/arm/mach-exynos/include/mach/entry-macro.S b/arch/arm/mach-exynos/include/mach/entry-macro.S deleted file mode 100644 index 3ba4f547534b..000000000000 --- a/arch/arm/mach-exynos/include/mach/entry-macro.S +++ /dev/null @@ -1,16 +0,0 @@ -/* arch/arm/mach-exynos4/include/mach/entry-macro.S - * - * Cloned from arch/arm/mach-realview/include/mach/entry-macro.S - * - * Low-level IRQ helper macros for EXYNOS4 platforms - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. -*/ - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-exynos/include/mach/exynos4-clock.h b/arch/arm/mach-exynos/include/mach/exynos4-clock.h deleted file mode 100644 index a07fcbf55251..000000000000 --- a/arch/arm/mach-exynos/include/mach/exynos4-clock.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * linux/arch/arm/mach-exynos4/include/mach/exynos4-clock.h - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Header file for exynos4 clock support - * - * 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. -*/ - -#ifndef __ASM_ARCH_CLOCK_H -#define __ASM_ARCH_CLOCK_H __FILE__ - -#include <linux/clk.h> - -extern struct clk clk_sclk_hdmi27m; -extern struct clk clk_sclk_usbphy0; -extern struct clk clk_sclk_usbphy1; -extern struct clk clk_sclk_hdmiphy; - -extern struct clksrc_clk clk_sclk_apll; -extern struct clksrc_clk clk_mout_mpll; -extern struct clksrc_clk clk_aclk_133; -extern struct clksrc_clk clk_mout_epll; -extern struct clksrc_clk clk_sclk_vpll; - -extern struct clk *clkset_corebus_list[]; -extern struct clksrc_sources clkset_mout_corebus; - -extern struct clk *clkset_aclk_top_list[]; -extern struct clksrc_sources clkset_aclk; - -extern struct clk *clkset_group_list[]; -extern struct clksrc_sources clkset_group; - -extern int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable); -extern int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable); -extern int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable); - -#endif /* __ASM_ARCH_CLOCK_H */ diff --git a/arch/arm/mach-exynos/include/mach/gpio.h b/arch/arm/mach-exynos/include/mach/gpio.h index 80523ca9bb49..d7498afe036a 100644 --- a/arch/arm/mach-exynos/include/mach/gpio.h +++ b/arch/arm/mach-exynos/include/mach/gpio.h @@ -1,9 +1,8 @@ -/* linux/arch/arm/mach-exynos4/include/mach/gpio.h - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. +/* + * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd. * http://www.samsung.com * - * EXYNOS4 - GPIO lib support + * EXYNOS - GPIO lib support * * 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 @@ -13,9 +12,13 @@ #ifndef __ASM_ARCH_GPIO_H #define __ASM_ARCH_GPIO_H __FILE__ -/* Practically, GPIO banks up to GPZ are the configurable gpio banks */ +/* Macro for EXYNOS GPIO numbering */ + +#define EXYNOS_GPIO_NEXT(__gpio) \ + ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1) + +/* EXYNOS4 GPIO bank sizes */ -/* GPIO bank sizes */ #define EXYNOS4_GPIO_A0_NR (8) #define EXYNOS4_GPIO_A1_NR (6) #define EXYNOS4_GPIO_B_NR (8) @@ -54,52 +57,50 @@ #define EXYNOS4_GPIO_Y6_NR (8) #define EXYNOS4_GPIO_Z_NR (7) -/* GPIO bank numbers */ - -#define EXYNOS4_GPIO_NEXT(__gpio) \ - ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1) +/* EXYNOS4 GPIO bank numbers */ -enum s5p_gpio_number { +enum exynos4_gpio_number { EXYNOS4_GPIO_A0_START = 0, - EXYNOS4_GPIO_A1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_A0), - EXYNOS4_GPIO_B_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_A1), - EXYNOS4_GPIO_C0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_B), - EXYNOS4_GPIO_C1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_C0), - EXYNOS4_GPIO_D0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_C1), - EXYNOS4_GPIO_D1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_D0), - EXYNOS4_GPIO_E0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_D1), - EXYNOS4_GPIO_E1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E0), - EXYNOS4_GPIO_E2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E1), - EXYNOS4_GPIO_E3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E2), - EXYNOS4_GPIO_E4_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E3), - EXYNOS4_GPIO_F0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E4), - EXYNOS4_GPIO_F1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F0), - EXYNOS4_GPIO_F2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F1), - EXYNOS4_GPIO_F3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F2), - EXYNOS4_GPIO_J0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F3), - EXYNOS4_GPIO_J1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_J0), - EXYNOS4_GPIO_K0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_J1), - EXYNOS4_GPIO_K1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K0), - EXYNOS4_GPIO_K2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K1), - EXYNOS4_GPIO_K3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K2), - EXYNOS4_GPIO_L0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K3), - EXYNOS4_GPIO_L1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L0), - EXYNOS4_GPIO_L2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L1), - EXYNOS4_GPIO_X0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L2), - EXYNOS4_GPIO_X1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X0), - EXYNOS4_GPIO_X2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X1), - EXYNOS4_GPIO_X3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X2), - EXYNOS4_GPIO_Y0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X3), - EXYNOS4_GPIO_Y1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y0), - EXYNOS4_GPIO_Y2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y1), - EXYNOS4_GPIO_Y3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y2), - EXYNOS4_GPIO_Y4_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y3), - EXYNOS4_GPIO_Y5_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y4), - EXYNOS4_GPIO_Y6_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y5), - EXYNOS4_GPIO_Z_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y6), + EXYNOS4_GPIO_A1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_A0), + EXYNOS4_GPIO_B_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_A1), + EXYNOS4_GPIO_C0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_B), + EXYNOS4_GPIO_C1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_C0), + EXYNOS4_GPIO_D0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_C1), + EXYNOS4_GPIO_D1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_D0), + EXYNOS4_GPIO_E0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_D1), + EXYNOS4_GPIO_E1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E0), + EXYNOS4_GPIO_E2_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E1), + EXYNOS4_GPIO_E3_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E2), + EXYNOS4_GPIO_E4_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E3), + EXYNOS4_GPIO_F0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E4), + EXYNOS4_GPIO_F1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_F0), + EXYNOS4_GPIO_F2_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_F1), + EXYNOS4_GPIO_F3_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_F2), + EXYNOS4_GPIO_J0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_F3), + EXYNOS4_GPIO_J1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_J0), + EXYNOS4_GPIO_K0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_J1), + EXYNOS4_GPIO_K1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_K0), + EXYNOS4_GPIO_K2_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_K1), + EXYNOS4_GPIO_K3_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_K2), + EXYNOS4_GPIO_L0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_K3), + EXYNOS4_GPIO_L1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_L0), + EXYNOS4_GPIO_L2_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_L1), + EXYNOS4_GPIO_X0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_L2), + EXYNOS4_GPIO_X1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_X0), + EXYNOS4_GPIO_X2_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_X1), + EXYNOS4_GPIO_X3_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_X2), + EXYNOS4_GPIO_Y0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_X3), + EXYNOS4_GPIO_Y1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y0), + EXYNOS4_GPIO_Y2_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y1), + EXYNOS4_GPIO_Y3_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y2), + EXYNOS4_GPIO_Y4_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y3), + EXYNOS4_GPIO_Y5_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y4), + EXYNOS4_GPIO_Y6_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y5), + EXYNOS4_GPIO_Z_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y6), }; /* EXYNOS4 GPIO number definitions */ + #define EXYNOS4_GPA0(_nr) (EXYNOS4_GPIO_A0_START + (_nr)) #define EXYNOS4_GPA1(_nr) (EXYNOS4_GPIO_A1_START + (_nr)) #define EXYNOS4_GPB(_nr) (EXYNOS4_GPIO_B_START + (_nr)) @@ -139,11 +140,147 @@ enum s5p_gpio_number { #define EXYNOS4_GPZ(_nr) (EXYNOS4_GPIO_Z_START + (_nr)) /* the end of the EXYNOS4 specific gpios */ + #define EXYNOS4_GPIO_END (EXYNOS4_GPZ(EXYNOS4_GPIO_Z_NR) + 1) -#define S3C_GPIO_END EXYNOS4_GPIO_END -/* define the number of gpios we need to the one after the GPZ() range */ -#define ARCH_NR_GPIOS (EXYNOS4_GPZ(EXYNOS4_GPIO_Z_NR) + \ - CONFIG_SAMSUNG_GPIO_EXTRA + 1) +/* EXYNOS5 GPIO bank sizes */ + +#define EXYNOS5_GPIO_A0_NR (8) +#define EXYNOS5_GPIO_A1_NR (6) +#define EXYNOS5_GPIO_A2_NR (8) +#define EXYNOS5_GPIO_B0_NR (5) +#define EXYNOS5_GPIO_B1_NR (5) +#define EXYNOS5_GPIO_B2_NR (4) +#define EXYNOS5_GPIO_B3_NR (4) +#define EXYNOS5_GPIO_C0_NR (7) +#define EXYNOS5_GPIO_C1_NR (7) +#define EXYNOS5_GPIO_C2_NR (7) +#define EXYNOS5_GPIO_C3_NR (7) +#define EXYNOS5_GPIO_D0_NR (8) +#define EXYNOS5_GPIO_D1_NR (8) +#define EXYNOS5_GPIO_Y0_NR (6) +#define EXYNOS5_GPIO_Y1_NR (4) +#define EXYNOS5_GPIO_Y2_NR (6) +#define EXYNOS5_GPIO_Y3_NR (8) +#define EXYNOS5_GPIO_Y4_NR (8) +#define EXYNOS5_GPIO_Y5_NR (8) +#define EXYNOS5_GPIO_Y6_NR (8) +#define EXYNOS5_GPIO_X0_NR (8) +#define EXYNOS5_GPIO_X1_NR (8) +#define EXYNOS5_GPIO_X2_NR (8) +#define EXYNOS5_GPIO_X3_NR (8) +#define EXYNOS5_GPIO_E0_NR (8) +#define EXYNOS5_GPIO_E1_NR (2) +#define EXYNOS5_GPIO_F0_NR (4) +#define EXYNOS5_GPIO_F1_NR (4) +#define EXYNOS5_GPIO_G0_NR (8) +#define EXYNOS5_GPIO_G1_NR (8) +#define EXYNOS5_GPIO_G2_NR (2) +#define EXYNOS5_GPIO_H0_NR (4) +#define EXYNOS5_GPIO_H1_NR (8) +#define EXYNOS5_GPIO_V0_NR (8) +#define EXYNOS5_GPIO_V1_NR (8) +#define EXYNOS5_GPIO_V2_NR (8) +#define EXYNOS5_GPIO_V3_NR (8) +#define EXYNOS5_GPIO_V4_NR (2) +#define EXYNOS5_GPIO_Z_NR (7) + +/* EXYNOS5 GPIO bank numbers */ + +enum exynos5_gpio_number { + EXYNOS5_GPIO_A0_START = 0, + EXYNOS5_GPIO_A1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_A0), + EXYNOS5_GPIO_A2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_A1), + EXYNOS5_GPIO_B0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_A2), + EXYNOS5_GPIO_B1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_B0), + EXYNOS5_GPIO_B2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_B1), + EXYNOS5_GPIO_B3_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_B2), + EXYNOS5_GPIO_C0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_B3), + EXYNOS5_GPIO_C1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C0), + EXYNOS5_GPIO_C2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C1), + EXYNOS5_GPIO_C3_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C2), + EXYNOS5_GPIO_D0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C3), + EXYNOS5_GPIO_D1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_D0), + EXYNOS5_GPIO_Y0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_D1), + EXYNOS5_GPIO_Y1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y0), + EXYNOS5_GPIO_Y2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y1), + EXYNOS5_GPIO_Y3_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y2), + EXYNOS5_GPIO_Y4_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y3), + EXYNOS5_GPIO_Y5_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y4), + EXYNOS5_GPIO_Y6_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y5), + EXYNOS5_GPIO_X0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y6), + EXYNOS5_GPIO_X1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_X0), + EXYNOS5_GPIO_X2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_X1), + EXYNOS5_GPIO_X3_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_X2), + EXYNOS5_GPIO_E0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_X3), + EXYNOS5_GPIO_E1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_E0), + EXYNOS5_GPIO_F0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_E1), + EXYNOS5_GPIO_F1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_F0), + EXYNOS5_GPIO_G0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_F1), + EXYNOS5_GPIO_G1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_G0), + EXYNOS5_GPIO_G2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_G1), + EXYNOS5_GPIO_H0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_G2), + EXYNOS5_GPIO_H1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_H0), + EXYNOS5_GPIO_V0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_H1), + EXYNOS5_GPIO_V1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V0), + EXYNOS5_GPIO_V2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V1), + EXYNOS5_GPIO_V3_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V2), + EXYNOS5_GPIO_V4_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V3), + EXYNOS5_GPIO_Z_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V4), +}; + +/* EXYNOS5 GPIO number definitions */ + +#define EXYNOS5_GPA0(_nr) (EXYNOS5_GPIO_A0_START + (_nr)) +#define EXYNOS5_GPA1(_nr) (EXYNOS5_GPIO_A1_START + (_nr)) +#define EXYNOS5_GPA2(_nr) (EXYNOS5_GPIO_A2_START + (_nr)) +#define EXYNOS5_GPB0(_nr) (EXYNOS5_GPIO_B0_START + (_nr)) +#define EXYNOS5_GPB1(_nr) (EXYNOS5_GPIO_B1_START + (_nr)) +#define EXYNOS5_GPB2(_nr) (EXYNOS5_GPIO_B2_START + (_nr)) +#define EXYNOS5_GPB3(_nr) (EXYNOS5_GPIO_B3_START + (_nr)) +#define EXYNOS5_GPC0(_nr) (EXYNOS5_GPIO_C0_START + (_nr)) +#define EXYNOS5_GPC1(_nr) (EXYNOS5_GPIO_C1_START + (_nr)) +#define EXYNOS5_GPC2(_nr) (EXYNOS5_GPIO_C2_START + (_nr)) +#define EXYNOS5_GPC3(_nr) (EXYNOS5_GPIO_C3_START + (_nr)) +#define EXYNOS5_GPD0(_nr) (EXYNOS5_GPIO_D0_START + (_nr)) +#define EXYNOS5_GPD1(_nr) (EXYNOS5_GPIO_D1_START + (_nr)) +#define EXYNOS5_GPY0(_nr) (EXYNOS5_GPIO_Y0_START + (_nr)) +#define EXYNOS5_GPY1(_nr) (EXYNOS5_GPIO_Y1_START + (_nr)) +#define EXYNOS5_GPY2(_nr) (EXYNOS5_GPIO_Y2_START + (_nr)) +#define EXYNOS5_GPY3(_nr) (EXYNOS5_GPIO_Y3_START + (_nr)) +#define EXYNOS5_GPY4(_nr) (EXYNOS5_GPIO_Y4_START + (_nr)) +#define EXYNOS5_GPY5(_nr) (EXYNOS5_GPIO_Y5_START + (_nr)) +#define EXYNOS5_GPY6(_nr) (EXYNOS5_GPIO_Y6_START + (_nr)) +#define EXYNOS5_GPX0(_nr) (EXYNOS5_GPIO_X0_START + (_nr)) +#define EXYNOS5_GPX1(_nr) (EXYNOS5_GPIO_X1_START + (_nr)) +#define EXYNOS5_GPX2(_nr) (EXYNOS5_GPIO_X2_START + (_nr)) +#define EXYNOS5_GPX3(_nr) (EXYNOS5_GPIO_X3_START + (_nr)) +#define EXYNOS5_GPE0(_nr) (EXYNOS5_GPIO_E0_START + (_nr)) +#define EXYNOS5_GPE1(_nr) (EXYNOS5_GPIO_E1_START + (_nr)) +#define EXYNOS5_GPF0(_nr) (EXYNOS5_GPIO_F0_START + (_nr)) +#define EXYNOS5_GPF1(_nr) (EXYNOS5_GPIO_F1_START + (_nr)) +#define EXYNOS5_GPG0(_nr) (EXYNOS5_GPIO_G0_START + (_nr)) +#define EXYNOS5_GPG1(_nr) (EXYNOS5_GPIO_G1_START + (_nr)) +#define EXYNOS5_GPG2(_nr) (EXYNOS5_GPIO_G2_START + (_nr)) +#define EXYNOS5_GPH0(_nr) (EXYNOS5_GPIO_H0_START + (_nr)) +#define EXYNOS5_GPH1(_nr) (EXYNOS5_GPIO_H1_START + (_nr)) +#define EXYNOS5_GPV0(_nr) (EXYNOS5_GPIO_V0_START + (_nr)) +#define EXYNOS5_GPV1(_nr) (EXYNOS5_GPIO_V1_START + (_nr)) +#define EXYNOS5_GPV2(_nr) (EXYNOS5_GPIO_V2_START + (_nr)) +#define EXYNOS5_GPV3(_nr) (EXYNOS5_GPIO_V3_START + (_nr)) +#define EXYNOS5_GPV4(_nr) (EXYNOS5_GPIO_V4_START + (_nr)) +#define EXYNOS5_GPZ(_nr) (EXYNOS5_GPIO_Z_START + (_nr)) + +/* the end of the EXYNOS5 specific gpios */ + +#define EXYNOS5_GPIO_END (EXYNOS5_GPZ(EXYNOS5_GPIO_Z_NR) + 1) + +/* actually, EXYNOS5_GPIO_END is bigger than EXYNOS4 */ + +#define S3C_GPIO_END (EXYNOS5_GPIO_END) + +/* define the number of gpios */ + +#define ARCH_NR_GPIOS (CONFIG_SAMSUNG_GPIO_EXTRA + S3C_GPIO_END) #endif /* __ASM_ARCH_GPIO_H */ diff --git a/arch/arm/mach-exynos/include/mach/io.h b/arch/arm/mach-exynos/include/mach/io.h deleted file mode 100644 index d5478d247535..000000000000 --- a/arch/arm/mach-exynos/include/mach/io.h +++ /dev/null @@ -1,26 +0,0 @@ -/* linux/arch/arm/mach-exynos4/include/mach/io.h - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Copyright 2008-2010 Ben Dooks <ben-linux@fluff.org> - * - * Based on arch/arm/mach-s5p6442/include/mach/io.h - * - * Default IO routines for EXYNOS4 - * - * 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. -*/ - -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H __FILE__ - -/* No current ISA/PCI bus support. */ -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#define IO_SPACE_LIMIT (0xFFFFFFFF) - -#endif /* __ASM_ARM_ARCH_IO_H */ diff --git a/arch/arm/mach-exynos/include/mach/irqs.h b/arch/arm/mach-exynos/include/mach/irqs.h index f77bce04789a..591e78521a9f 100644 --- a/arch/arm/mach-exynos/include/mach/irqs.h +++ b/arch/arm/mach-exynos/include/mach/irqs.h @@ -1,9 +1,8 @@ -/* linux/arch/arm/mach-exynos4/include/mach/irqs.h - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. +/* + * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd. * http://www.samsung.com * - * EXYNOS4 - IRQ definitions + * EXYNOS - IRQ definitions * * 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 @@ -17,158 +16,452 @@ /* PPI: Private Peripheral Interrupt */ -#define IRQ_PPI(x) (x+16) - -#define IRQ_MCT_LOCALTIMER IRQ_PPI(12) +#define IRQ_PPI(x) (x + 16) /* SPI: Shared Peripheral Interrupt */ -#define IRQ_SPI(x) (x+32) - -#define IRQ_EINT0 IRQ_SPI(16) -#define IRQ_EINT1 IRQ_SPI(17) -#define IRQ_EINT2 IRQ_SPI(18) -#define IRQ_EINT3 IRQ_SPI(19) -#define IRQ_EINT4 IRQ_SPI(20) -#define IRQ_EINT5 IRQ_SPI(21) -#define IRQ_EINT6 IRQ_SPI(22) -#define IRQ_EINT7 IRQ_SPI(23) -#define IRQ_EINT8 IRQ_SPI(24) -#define IRQ_EINT9 IRQ_SPI(25) -#define IRQ_EINT10 IRQ_SPI(26) -#define IRQ_EINT11 IRQ_SPI(27) -#define IRQ_EINT12 IRQ_SPI(28) -#define IRQ_EINT13 IRQ_SPI(29) -#define IRQ_EINT14 IRQ_SPI(30) -#define IRQ_EINT15 IRQ_SPI(31) -#define IRQ_EINT16_31 IRQ_SPI(32) - -#define IRQ_PDMA0 IRQ_SPI(35) -#define IRQ_PDMA1 IRQ_SPI(36) -#define IRQ_TIMER0_VIC IRQ_SPI(37) -#define IRQ_TIMER1_VIC IRQ_SPI(38) -#define IRQ_TIMER2_VIC IRQ_SPI(39) -#define IRQ_TIMER3_VIC IRQ_SPI(40) -#define IRQ_TIMER4_VIC IRQ_SPI(41) -#define IRQ_MCT_L0 IRQ_SPI(42) -#define IRQ_WDT IRQ_SPI(43) -#define IRQ_RTC_ALARM IRQ_SPI(44) -#define IRQ_RTC_TIC IRQ_SPI(45) -#define IRQ_GPIO_XB IRQ_SPI(46) -#define IRQ_GPIO_XA IRQ_SPI(47) -#define IRQ_MCT_L1 IRQ_SPI(48) - -#define IRQ_UART0 IRQ_SPI(52) -#define IRQ_UART1 IRQ_SPI(53) -#define IRQ_UART2 IRQ_SPI(54) -#define IRQ_UART3 IRQ_SPI(55) -#define IRQ_UART4 IRQ_SPI(56) -#define IRQ_MCT_G0 IRQ_SPI(57) -#define IRQ_IIC IRQ_SPI(58) -#define IRQ_IIC1 IRQ_SPI(59) -#define IRQ_IIC2 IRQ_SPI(60) -#define IRQ_IIC3 IRQ_SPI(61) -#define IRQ_IIC4 IRQ_SPI(62) -#define IRQ_IIC5 IRQ_SPI(63) -#define IRQ_IIC6 IRQ_SPI(64) -#define IRQ_IIC7 IRQ_SPI(65) -#define IRQ_SPI0 IRQ_SPI(66) -#define IRQ_SPI1 IRQ_SPI(67) -#define IRQ_SPI2 IRQ_SPI(68) - -#define IRQ_USB_HOST IRQ_SPI(70) -#define IRQ_USB_HSOTG IRQ_SPI(71) -#define IRQ_MODEM_IF IRQ_SPI(72) -#define IRQ_HSMMC0 IRQ_SPI(73) -#define IRQ_HSMMC1 IRQ_SPI(74) -#define IRQ_HSMMC2 IRQ_SPI(75) -#define IRQ_HSMMC3 IRQ_SPI(76) -#define IRQ_DWMCI IRQ_SPI(77) - -#define IRQ_MIPI_CSIS0 IRQ_SPI(78) -#define IRQ_MIPI_CSIS1 IRQ_SPI(80) - -#define IRQ_ONENAND_AUDI IRQ_SPI(82) -#define IRQ_ROTATOR IRQ_SPI(83) -#define IRQ_FIMC0 IRQ_SPI(84) -#define IRQ_FIMC1 IRQ_SPI(85) -#define IRQ_FIMC2 IRQ_SPI(86) -#define IRQ_FIMC3 IRQ_SPI(87) -#define IRQ_JPEG IRQ_SPI(88) -#define IRQ_2D IRQ_SPI(89) -#define IRQ_PCIE IRQ_SPI(90) - -#define IRQ_MIXER IRQ_SPI(91) -#define IRQ_HDMI IRQ_SPI(92) -#define IRQ_IIC_HDMIPHY IRQ_SPI(93) -#define IRQ_MFC IRQ_SPI(94) -#define IRQ_SDO IRQ_SPI(95) - -#define IRQ_AUDIO_SS IRQ_SPI(96) -#define IRQ_I2S0 IRQ_SPI(97) -#define IRQ_I2S1 IRQ_SPI(98) -#define IRQ_I2S2 IRQ_SPI(99) -#define IRQ_AC97 IRQ_SPI(100) - -#define IRQ_SPDIF IRQ_SPI(104) -#define IRQ_ADC0 IRQ_SPI(105) -#define IRQ_PEN0 IRQ_SPI(106) -#define IRQ_ADC1 IRQ_SPI(107) -#define IRQ_PEN1 IRQ_SPI(108) -#define IRQ_KEYPAD IRQ_SPI(109) -#define IRQ_PMU IRQ_SPI(110) -#define IRQ_GPS IRQ_SPI(111) -#define IRQ_INTFEEDCTRL_SSS IRQ_SPI(112) -#define IRQ_SLIMBUS IRQ_SPI(113) - -#define IRQ_TSI IRQ_SPI(115) -#define IRQ_SATA IRQ_SPI(116) - -#define MAX_IRQ_IN_COMBINER 8 -#define COMBINER_GROUP(x) ((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(128)) -#define COMBINER_IRQ(x, y) (COMBINER_GROUP(x) + y) - -#define IRQ_SYSMMU_MDMA0_0 COMBINER_IRQ(4, 0) -#define IRQ_SYSMMU_SSS_0 COMBINER_IRQ(4, 1) -#define IRQ_SYSMMU_FIMC0_0 COMBINER_IRQ(4, 2) -#define IRQ_SYSMMU_FIMC1_0 COMBINER_IRQ(4, 3) -#define IRQ_SYSMMU_FIMC2_0 COMBINER_IRQ(4, 4) -#define IRQ_SYSMMU_FIMC3_0 COMBINER_IRQ(4, 5) -#define IRQ_SYSMMU_JPEG_0 COMBINER_IRQ(4, 6) -#define IRQ_SYSMMU_2D_0 COMBINER_IRQ(4, 7) - -#define IRQ_SYSMMU_ROTATOR_0 COMBINER_IRQ(5, 0) -#define IRQ_SYSMMU_MDMA1_0 COMBINER_IRQ(5, 1) -#define IRQ_SYSMMU_LCD0_M0_0 COMBINER_IRQ(5, 2) -#define IRQ_SYSMMU_LCD1_M1_0 COMBINER_IRQ(5, 3) -#define IRQ_SYSMMU_TV_M0_0 COMBINER_IRQ(5, 4) -#define IRQ_SYSMMU_MFC_M0_0 COMBINER_IRQ(5, 5) -#define IRQ_SYSMMU_MFC_M1_0 COMBINER_IRQ(5, 6) -#define IRQ_SYSMMU_PCIE_0 COMBINER_IRQ(5, 7) - -#define IRQ_FIMD0_FIFO COMBINER_IRQ(11, 0) -#define IRQ_FIMD0_VSYNC COMBINER_IRQ(11, 1) -#define IRQ_FIMD0_SYSTEM COMBINER_IRQ(11, 2) - -#define MAX_COMBINER_NR 16 - -#define IRQ_ADC IRQ_ADC0 -#define IRQ_TC IRQ_PEN0 - -#define S5P_IRQ_EINT_BASE COMBINER_IRQ(MAX_COMBINER_NR, 0) - -#define S5P_EINT_BASE1 (S5P_IRQ_EINT_BASE + 0) -#define S5P_EINT_BASE2 (S5P_IRQ_EINT_BASE + 16) - -/* optional GPIO interrupts */ -#define S5P_GPIOINT_BASE (S5P_IRQ_EINT_BASE + 32) -#define IRQ_GPIO1_NR_GROUPS 16 -#define IRQ_GPIO2_NR_GROUPS 9 -#define IRQ_GPIO_END (S5P_GPIOINT_BASE + S5P_GPIOINT_COUNT) - -#define IRQ_TIMER_BASE (IRQ_GPIO_END + 64) +#define IRQ_SPI(x) (x + 32) + +/* COMBINER */ + +#define MAX_IRQ_IN_COMBINER 8 +#define COMBINER_GROUP(x) ((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(128)) +#define COMBINER_IRQ(x, y) (COMBINER_GROUP(x) + y) + +/* For EXYNOS4 and EXYNOS5 */ + +#define EXYNOS_IRQ_MCT_LOCALTIMER IRQ_PPI(12) + +#define EXYNOS_IRQ_EINT16_31 IRQ_SPI(32) + +/* For EXYNOS4 SoCs */ + +#define EXYNOS4_IRQ_EINT0 IRQ_SPI(16) +#define EXYNOS4_IRQ_EINT1 IRQ_SPI(17) +#define EXYNOS4_IRQ_EINT2 IRQ_SPI(18) +#define EXYNOS4_IRQ_EINT3 IRQ_SPI(19) +#define EXYNOS4_IRQ_EINT4 IRQ_SPI(20) +#define EXYNOS4_IRQ_EINT5 IRQ_SPI(21) +#define EXYNOS4_IRQ_EINT6 IRQ_SPI(22) +#define EXYNOS4_IRQ_EINT7 IRQ_SPI(23) +#define EXYNOS4_IRQ_EINT8 IRQ_SPI(24) +#define EXYNOS4_IRQ_EINT9 IRQ_SPI(25) +#define EXYNOS4_IRQ_EINT10 IRQ_SPI(26) +#define EXYNOS4_IRQ_EINT11 IRQ_SPI(27) +#define EXYNOS4_IRQ_EINT12 IRQ_SPI(28) +#define EXYNOS4_IRQ_EINT13 IRQ_SPI(29) +#define EXYNOS4_IRQ_EINT14 IRQ_SPI(30) +#define EXYNOS4_IRQ_EINT15 IRQ_SPI(31) + +#define EXYNOS4_IRQ_MDMA0 IRQ_SPI(33) +#define EXYNOS4_IRQ_MDMA1 IRQ_SPI(34) +#define EXYNOS4_IRQ_PDMA0 IRQ_SPI(35) +#define EXYNOS4_IRQ_PDMA1 IRQ_SPI(36) +#define EXYNOS4_IRQ_TIMER0_VIC IRQ_SPI(37) +#define EXYNOS4_IRQ_TIMER1_VIC IRQ_SPI(38) +#define EXYNOS4_IRQ_TIMER2_VIC IRQ_SPI(39) +#define EXYNOS4_IRQ_TIMER3_VIC IRQ_SPI(40) +#define EXYNOS4_IRQ_TIMER4_VIC IRQ_SPI(41) +#define EXYNOS4_IRQ_MCT_L0 IRQ_SPI(42) +#define EXYNOS4_IRQ_WDT IRQ_SPI(43) +#define EXYNOS4_IRQ_RTC_ALARM IRQ_SPI(44) +#define EXYNOS4_IRQ_RTC_TIC IRQ_SPI(45) +#define EXYNOS4_IRQ_GPIO_XB IRQ_SPI(46) +#define EXYNOS4_IRQ_GPIO_XA IRQ_SPI(47) +#define EXYNOS4_IRQ_MCT_L1 IRQ_SPI(48) + +#define EXYNOS4_IRQ_UART0 IRQ_SPI(52) +#define EXYNOS4_IRQ_UART1 IRQ_SPI(53) +#define EXYNOS4_IRQ_UART2 IRQ_SPI(54) +#define EXYNOS4_IRQ_UART3 IRQ_SPI(55) +#define EXYNOS4_IRQ_UART4 IRQ_SPI(56) +#define EXYNOS4_IRQ_MCT_G0 IRQ_SPI(57) +#define EXYNOS4_IRQ_IIC IRQ_SPI(58) +#define EXYNOS4_IRQ_IIC1 IRQ_SPI(59) +#define EXYNOS4_IRQ_IIC2 IRQ_SPI(60) +#define EXYNOS4_IRQ_IIC3 IRQ_SPI(61) +#define EXYNOS4_IRQ_IIC4 IRQ_SPI(62) +#define EXYNOS4_IRQ_IIC5 IRQ_SPI(63) +#define EXYNOS4_IRQ_IIC6 IRQ_SPI(64) +#define EXYNOS4_IRQ_IIC7 IRQ_SPI(65) +#define EXYNOS4_IRQ_SPI0 IRQ_SPI(66) +#define EXYNOS4_IRQ_SPI1 IRQ_SPI(67) +#define EXYNOS4_IRQ_SPI2 IRQ_SPI(68) + +#define EXYNOS4_IRQ_USB_HOST IRQ_SPI(70) +#define EXYNOS4_IRQ_USB_HSOTG IRQ_SPI(71) +#define EXYNOS4_IRQ_MODEM_IF IRQ_SPI(72) +#define EXYNOS4_IRQ_HSMMC0 IRQ_SPI(73) +#define EXYNOS4_IRQ_HSMMC1 IRQ_SPI(74) +#define EXYNOS4_IRQ_HSMMC2 IRQ_SPI(75) +#define EXYNOS4_IRQ_HSMMC3 IRQ_SPI(76) +#define EXYNOS4_IRQ_DWMCI IRQ_SPI(77) + +#define EXYNOS4_IRQ_MIPI_CSIS0 IRQ_SPI(78) +#define EXYNOS4_IRQ_MIPI_CSIS1 IRQ_SPI(80) + +#define EXYNOS4_IRQ_ONENAND_AUDI IRQ_SPI(82) +#define EXYNOS4_IRQ_ROTATOR IRQ_SPI(83) +#define EXYNOS4_IRQ_FIMC0 IRQ_SPI(84) +#define EXYNOS4_IRQ_FIMC1 IRQ_SPI(85) +#define EXYNOS4_IRQ_FIMC2 IRQ_SPI(86) +#define EXYNOS4_IRQ_FIMC3 IRQ_SPI(87) +#define EXYNOS4_IRQ_JPEG IRQ_SPI(88) +#define EXYNOS4_IRQ_2D IRQ_SPI(89) +#define EXYNOS4_IRQ_PCIE IRQ_SPI(90) + +#define EXYNOS4_IRQ_MIXER IRQ_SPI(91) +#define EXYNOS4_IRQ_HDMI IRQ_SPI(92) +#define EXYNOS4_IRQ_IIC_HDMIPHY IRQ_SPI(93) +#define EXYNOS4_IRQ_MFC IRQ_SPI(94) +#define EXYNOS4_IRQ_SDO IRQ_SPI(95) + +#define EXYNOS4_IRQ_AUDIO_SS IRQ_SPI(96) +#define EXYNOS4_IRQ_I2S0 IRQ_SPI(97) +#define EXYNOS4_IRQ_I2S1 IRQ_SPI(98) +#define EXYNOS4_IRQ_I2S2 IRQ_SPI(99) +#define EXYNOS4_IRQ_AC97 IRQ_SPI(100) + +#define EXYNOS4_IRQ_SPDIF IRQ_SPI(104) +#define EXYNOS4_IRQ_ADC0 IRQ_SPI(105) +#define EXYNOS4_IRQ_PEN0 IRQ_SPI(106) +#define EXYNOS4_IRQ_ADC1 IRQ_SPI(107) +#define EXYNOS4_IRQ_PEN1 IRQ_SPI(108) +#define EXYNOS4_IRQ_KEYPAD IRQ_SPI(109) +#define EXYNOS4_IRQ_PMU IRQ_SPI(110) +#define EXYNOS4_IRQ_GPS IRQ_SPI(111) +#define EXYNOS4_IRQ_INTFEEDCTRL_SSS IRQ_SPI(112) +#define EXYNOS4_IRQ_SLIMBUS IRQ_SPI(113) + +#define EXYNOS4_IRQ_TSI IRQ_SPI(115) +#define EXYNOS4_IRQ_SATA IRQ_SPI(116) + +#define EXYNOS4_IRQ_SYSMMU_MDMA0_0 COMBINER_IRQ(4, 0) +#define EXYNOS4_IRQ_SYSMMU_SSS_0 COMBINER_IRQ(4, 1) +#define EXYNOS4_IRQ_SYSMMU_FIMC0_0 COMBINER_IRQ(4, 2) +#define EXYNOS4_IRQ_SYSMMU_FIMC1_0 COMBINER_IRQ(4, 3) +#define EXYNOS4_IRQ_SYSMMU_FIMC2_0 COMBINER_IRQ(4, 4) +#define EXYNOS4_IRQ_SYSMMU_FIMC3_0 COMBINER_IRQ(4, 5) +#define EXYNOS4_IRQ_SYSMMU_JPEG_0 COMBINER_IRQ(4, 6) +#define EXYNOS4_IRQ_SYSMMU_2D_0 COMBINER_IRQ(4, 7) + +#define EXYNOS4_IRQ_SYSMMU_ROTATOR_0 COMBINER_IRQ(5, 0) +#define EXYNOS4_IRQ_SYSMMU_MDMA1_0 COMBINER_IRQ(5, 1) +#define EXYNOS4_IRQ_SYSMMU_LCD0_M0_0 COMBINER_IRQ(5, 2) +#define EXYNOS4_IRQ_SYSMMU_LCD1_M1_0 COMBINER_IRQ(5, 3) +#define EXYNOS4_IRQ_SYSMMU_TV_M0_0 COMBINER_IRQ(5, 4) +#define EXYNOS4_IRQ_SYSMMU_MFC_M0_0 COMBINER_IRQ(5, 5) +#define EXYNOS4_IRQ_SYSMMU_MFC_M1_0 COMBINER_IRQ(5, 6) +#define EXYNOS4_IRQ_SYSMMU_PCIE_0 COMBINER_IRQ(5, 7) + +#define EXYNOS4_IRQ_FIMD0_FIFO COMBINER_IRQ(11, 0) +#define EXYNOS4_IRQ_FIMD0_VSYNC COMBINER_IRQ(11, 1) +#define EXYNOS4_IRQ_FIMD0_SYSTEM COMBINER_IRQ(11, 2) + +#define EXYNOS4_MAX_COMBINER_NR 16 + +#define EXYNOS4_IRQ_GPIO1_NR_GROUPS 16 +#define EXYNOS4_IRQ_GPIO2_NR_GROUPS 9 + +/* + * For Compatibility: + * the default is for EXYNOS4, and + * for exynos5, should be re-mapped at function + */ + +#define IRQ_TIMER0_VIC EXYNOS4_IRQ_TIMER0_VIC +#define IRQ_TIMER1_VIC EXYNOS4_IRQ_TIMER1_VIC +#define IRQ_TIMER2_VIC EXYNOS4_IRQ_TIMER2_VIC +#define IRQ_TIMER3_VIC EXYNOS4_IRQ_TIMER3_VIC +#define IRQ_TIMER4_VIC EXYNOS4_IRQ_TIMER4_VIC + +#define IRQ_WDT EXYNOS4_IRQ_WDT +#define IRQ_RTC_ALARM EXYNOS4_IRQ_RTC_ALARM +#define IRQ_RTC_TIC EXYNOS4_IRQ_RTC_TIC +#define IRQ_GPIO_XB EXYNOS4_IRQ_GPIO_XB +#define IRQ_GPIO_XA EXYNOS4_IRQ_GPIO_XA + +#define IRQ_IIC EXYNOS4_IRQ_IIC +#define IRQ_IIC1 EXYNOS4_IRQ_IIC1 +#define IRQ_IIC3 EXYNOS4_IRQ_IIC3 +#define IRQ_IIC5 EXYNOS4_IRQ_IIC5 +#define IRQ_IIC6 EXYNOS4_IRQ_IIC6 +#define IRQ_IIC7 EXYNOS4_IRQ_IIC7 + +#define IRQ_USB_HOST EXYNOS4_IRQ_USB_HOST + +#define IRQ_HSMMC0 EXYNOS4_IRQ_HSMMC0 +#define IRQ_HSMMC1 EXYNOS4_IRQ_HSMMC1 +#define IRQ_HSMMC2 EXYNOS4_IRQ_HSMMC2 +#define IRQ_HSMMC3 EXYNOS4_IRQ_HSMMC3 + +#define IRQ_MIPI_CSIS0 EXYNOS4_IRQ_MIPI_CSIS0 + +#define IRQ_ONENAND_AUDI EXYNOS4_IRQ_ONENAND_AUDI + +#define IRQ_FIMC0 EXYNOS4_IRQ_FIMC0 +#define IRQ_FIMC1 EXYNOS4_IRQ_FIMC1 +#define IRQ_FIMC2 EXYNOS4_IRQ_FIMC2 +#define IRQ_FIMC3 EXYNOS4_IRQ_FIMC3 +#define IRQ_JPEG EXYNOS4_IRQ_JPEG +#define IRQ_2D EXYNOS4_IRQ_2D + +#define IRQ_MIXER EXYNOS4_IRQ_MIXER +#define IRQ_HDMI EXYNOS4_IRQ_HDMI +#define IRQ_IIC_HDMIPHY EXYNOS4_IRQ_IIC_HDMIPHY +#define IRQ_MFC EXYNOS4_IRQ_MFC +#define IRQ_SDO EXYNOS4_IRQ_SDO + +#define IRQ_I2S0 EXYNOS4_IRQ_I2S0 + +#define IRQ_ADC EXYNOS4_IRQ_ADC0 +#define IRQ_TC EXYNOS4_IRQ_PEN0 + +#define IRQ_KEYPAD EXYNOS4_IRQ_KEYPAD +#define IRQ_PMU EXYNOS4_IRQ_PMU + +#define IRQ_SYSMMU_MDMA0_0 EXYNOS4_IRQ_SYSMMU_MDMA0_0 +#define IRQ_SYSMMU_SSS_0 EXYNOS4_IRQ_SYSMMU_SSS_0 +#define IRQ_SYSMMU_FIMC0_0 EXYNOS4_IRQ_SYSMMU_FIMC0_0 +#define IRQ_SYSMMU_FIMC1_0 EXYNOS4_IRQ_SYSMMU_FIMC1_0 +#define IRQ_SYSMMU_FIMC2_0 EXYNOS4_IRQ_SYSMMU_FIMC2_0 +#define IRQ_SYSMMU_FIMC3_0 EXYNOS4_IRQ_SYSMMU_FIMC3_0 +#define IRQ_SYSMMU_JPEG_0 EXYNOS4_IRQ_SYSMMU_JPEG_0 +#define IRQ_SYSMMU_2D_0 EXYNOS4_IRQ_SYSMMU_2D_0 + +#define IRQ_SYSMMU_ROTATOR_0 EXYNOS4_IRQ_SYSMMU_ROTATOR_0 +#define IRQ_SYSMMU_MDMA1_0 EXYNOS4_IRQ_SYSMMU_MDMA1_0 +#define IRQ_SYSMMU_LCD0_M0_0 EXYNOS4_IRQ_SYSMMU_LCD0_M0_0 +#define IRQ_SYSMMU_LCD1_M1_0 EXYNOS4_IRQ_SYSMMU_LCD1_M1_0 +#define IRQ_SYSMMU_TV_M0_0 EXYNOS4_IRQ_SYSMMU_TV_M0_0 +#define IRQ_SYSMMU_MFC_M0_0 EXYNOS4_IRQ_SYSMMU_MFC_M0_0 +#define IRQ_SYSMMU_MFC_M1_0 EXYNOS4_IRQ_SYSMMU_MFC_M1_0 +#define IRQ_SYSMMU_PCIE_0 EXYNOS4_IRQ_SYSMMU_PCIE_0 + +#define IRQ_FIMD0_FIFO EXYNOS4_IRQ_FIMD0_FIFO +#define IRQ_FIMD0_VSYNC EXYNOS4_IRQ_FIMD0_VSYNC +#define IRQ_FIMD0_SYSTEM EXYNOS4_IRQ_FIMD0_SYSTEM + +#define IRQ_GPIO1_NR_GROUPS EXYNOS4_IRQ_GPIO1_NR_GROUPS +#define IRQ_GPIO2_NR_GROUPS EXYNOS4_IRQ_GPIO2_NR_GROUPS + +/* For EXYNOS5 SoCs */ + +#define EXYNOS5_IRQ_MDMA0 IRQ_SPI(33) +#define EXYNOS5_IRQ_PDMA0 IRQ_SPI(34) +#define EXYNOS5_IRQ_PDMA1 IRQ_SPI(35) +#define EXYNOS5_IRQ_TIMER0_VIC IRQ_SPI(36) +#define EXYNOS5_IRQ_TIMER1_VIC IRQ_SPI(37) +#define EXYNOS5_IRQ_TIMER2_VIC IRQ_SPI(38) +#define EXYNOS5_IRQ_TIMER3_VIC IRQ_SPI(39) +#define EXYNOS5_IRQ_TIMER4_VIC IRQ_SPI(40) +#define EXYNOS5_IRQ_RTIC IRQ_SPI(41) +#define EXYNOS5_IRQ_WDT IRQ_SPI(42) +#define EXYNOS5_IRQ_RTC_ALARM IRQ_SPI(43) +#define EXYNOS5_IRQ_RTC_TIC IRQ_SPI(44) +#define EXYNOS5_IRQ_GPIO_XB IRQ_SPI(45) +#define EXYNOS5_IRQ_GPIO_XA IRQ_SPI(46) +#define EXYNOS5_IRQ_GPIO IRQ_SPI(47) +#define EXYNOS5_IRQ_IEM_IEC IRQ_SPI(48) +#define EXYNOS5_IRQ_IEM_APC IRQ_SPI(49) +#define EXYNOS5_IRQ_GPIO_C2C IRQ_SPI(50) +#define EXYNOS5_IRQ_UART0 IRQ_SPI(51) +#define EXYNOS5_IRQ_UART1 IRQ_SPI(52) +#define EXYNOS5_IRQ_UART2 IRQ_SPI(53) +#define EXYNOS5_IRQ_UART3 IRQ_SPI(54) +#define EXYNOS5_IRQ_UART4 IRQ_SPI(55) +#define EXYNOS5_IRQ_IIC IRQ_SPI(56) +#define EXYNOS5_IRQ_IIC1 IRQ_SPI(57) +#define EXYNOS5_IRQ_IIC2 IRQ_SPI(58) +#define EXYNOS5_IRQ_IIC3 IRQ_SPI(59) +#define EXYNOS5_IRQ_IIC4 IRQ_SPI(60) +#define EXYNOS5_IRQ_IIC5 IRQ_SPI(61) +#define EXYNOS5_IRQ_IIC6 IRQ_SPI(62) +#define EXYNOS5_IRQ_IIC7 IRQ_SPI(63) +#define EXYNOS5_IRQ_IIC_HDMIPHY IRQ_SPI(64) +#define EXYNOS5_IRQ_TMU IRQ_SPI(65) +#define EXYNOS5_IRQ_FIQ_0 IRQ_SPI(66) +#define EXYNOS5_IRQ_FIQ_1 IRQ_SPI(67) +#define EXYNOS5_IRQ_SPI0 IRQ_SPI(68) +#define EXYNOS5_IRQ_SPI1 IRQ_SPI(69) +#define EXYNOS5_IRQ_SPI2 IRQ_SPI(70) +#define EXYNOS5_IRQ_USB_HOST IRQ_SPI(71) +#define EXYNOS5_IRQ_USB3_DRD IRQ_SPI(72) +#define EXYNOS5_IRQ_MIPI_HSI IRQ_SPI(73) +#define EXYNOS5_IRQ_USB_HSOTG IRQ_SPI(74) +#define EXYNOS5_IRQ_HSMMC0 IRQ_SPI(75) +#define EXYNOS5_IRQ_HSMMC1 IRQ_SPI(76) +#define EXYNOS5_IRQ_HSMMC2 IRQ_SPI(77) +#define EXYNOS5_IRQ_HSMMC3 IRQ_SPI(78) +#define EXYNOS5_IRQ_MIPICSI0 IRQ_SPI(79) +#define EXYNOS5_IRQ_MIPICSI1 IRQ_SPI(80) +#define EXYNOS5_IRQ_EFNFCON_DMA_ABORT IRQ_SPI(81) +#define EXYNOS5_IRQ_MIPIDSI0 IRQ_SPI(82) +#define EXYNOS5_IRQ_ROTATOR IRQ_SPI(84) +#define EXYNOS5_IRQ_GSC0 IRQ_SPI(85) +#define EXYNOS5_IRQ_GSC1 IRQ_SPI(86) +#define EXYNOS5_IRQ_GSC2 IRQ_SPI(87) +#define EXYNOS5_IRQ_GSC3 IRQ_SPI(88) +#define EXYNOS5_IRQ_JPEG IRQ_SPI(89) +#define EXYNOS5_IRQ_EFNFCON_DMA IRQ_SPI(90) +#define EXYNOS5_IRQ_2D IRQ_SPI(91) +#define EXYNOS5_IRQ_SFMC0 IRQ_SPI(92) +#define EXYNOS5_IRQ_SFMC1 IRQ_SPI(93) +#define EXYNOS5_IRQ_MIXER IRQ_SPI(94) +#define EXYNOS5_IRQ_HDMI IRQ_SPI(95) +#define EXYNOS5_IRQ_MFC IRQ_SPI(96) +#define EXYNOS5_IRQ_AUDIO_SS IRQ_SPI(97) +#define EXYNOS5_IRQ_I2S0 IRQ_SPI(98) +#define EXYNOS5_IRQ_I2S1 IRQ_SPI(99) +#define EXYNOS5_IRQ_I2S2 IRQ_SPI(100) +#define EXYNOS5_IRQ_AC97 IRQ_SPI(101) +#define EXYNOS5_IRQ_PCM0 IRQ_SPI(102) +#define EXYNOS5_IRQ_PCM1 IRQ_SPI(103) +#define EXYNOS5_IRQ_PCM2 IRQ_SPI(104) +#define EXYNOS5_IRQ_SPDIF IRQ_SPI(105) +#define EXYNOS5_IRQ_ADC0 IRQ_SPI(106) + +#define EXYNOS5_IRQ_SATA_PHY IRQ_SPI(108) +#define EXYNOS5_IRQ_SATA_PMEMREQ IRQ_SPI(109) +#define EXYNOS5_IRQ_CAM_C IRQ_SPI(110) +#define EXYNOS5_IRQ_EAGLE_PMU IRQ_SPI(111) +#define EXYNOS5_IRQ_INTFEEDCTRL_SSS IRQ_SPI(112) +#define EXYNOS5_IRQ_DP1_INTP1 IRQ_SPI(113) +#define EXYNOS5_IRQ_CEC IRQ_SPI(114) +#define EXYNOS5_IRQ_SATA IRQ_SPI(115) +#define EXYNOS5_IRQ_NFCON IRQ_SPI(116) + +#define EXYNOS5_IRQ_MMC44 IRQ_SPI(123) +#define EXYNOS5_IRQ_MDMA1 IRQ_SPI(124) +#define EXYNOS5_IRQ_FIMC_LITE0 IRQ_SPI(125) +#define EXYNOS5_IRQ_FIMC_LITE1 IRQ_SPI(126) +#define EXYNOS5_IRQ_RP_TIMER IRQ_SPI(127) + +#define EXYNOS5_IRQ_PMU COMBINER_IRQ(1, 2) +#define EXYNOS5_IRQ_PMU_CPU1 COMBINER_IRQ(1, 6) + +#define EXYNOS5_IRQ_SYSMMU_GSC0_0 COMBINER_IRQ(2, 0) +#define EXYNOS5_IRQ_SYSMMU_GSC0_1 COMBINER_IRQ(2, 1) +#define EXYNOS5_IRQ_SYSMMU_GSC1_0 COMBINER_IRQ(2, 2) +#define EXYNOS5_IRQ_SYSMMU_GSC1_1 COMBINER_IRQ(2, 3) +#define EXYNOS5_IRQ_SYSMMU_GSC2_0 COMBINER_IRQ(2, 4) +#define EXYNOS5_IRQ_SYSMMU_GSC2_1 COMBINER_IRQ(2, 5) +#define EXYNOS5_IRQ_SYSMMU_GSC3_0 COMBINER_IRQ(2, 6) +#define EXYNOS5_IRQ_SYSMMU_GSC3_1 COMBINER_IRQ(2, 7) + +#define EXYNOS5_IRQ_SYSMMU_FIMD1_0 COMBINER_IRQ(3, 2) +#define EXYNOS5_IRQ_SYSMMU_FIMD1_1 COMBINER_IRQ(3, 3) +#define EXYNOS5_IRQ_SYSMMU_LITE0_0 COMBINER_IRQ(3, 4) +#define EXYNOS5_IRQ_SYSMMU_LITE0_1 COMBINER_IRQ(3, 5) +#define EXYNOS5_IRQ_SYSMMU_SCALERPISP_0 COMBINER_IRQ(3, 6) +#define EXYNOS5_IRQ_SYSMMU_SCALERPISP_1 COMBINER_IRQ(3, 7) + +#define EXYNOS5_IRQ_SYSMMU_ROTATOR_0 COMBINER_IRQ(4, 0) +#define EXYNOS5_IRQ_SYSMMU_ROTATOR_1 COMBINER_IRQ(4, 1) +#define EXYNOS5_IRQ_SYSMMU_JPEG_0 COMBINER_IRQ(4, 2) +#define EXYNOS5_IRQ_SYSMMU_JPEG_1 COMBINER_IRQ(4, 3) + +#define EXYNOS5_IRQ_SYSMMU_FD_0 COMBINER_IRQ(5, 0) +#define EXYNOS5_IRQ_SYSMMU_FD_1 COMBINER_IRQ(5, 1) +#define EXYNOS5_IRQ_SYSMMU_SCALERCISP_0 COMBINER_IRQ(5, 2) +#define EXYNOS5_IRQ_SYSMMU_SCALERCISP_1 COMBINER_IRQ(5, 3) +#define EXYNOS5_IRQ_SYSMMU_MCUISP_0 COMBINER_IRQ(5, 4) +#define EXYNOS5_IRQ_SYSMMU_MCUISP_1 COMBINER_IRQ(5, 5) +#define EXYNOS5_IRQ_SYSMMU_3DNR_0 COMBINER_IRQ(5, 6) +#define EXYNOS5_IRQ_SYSMMU_3DNR_1 COMBINER_IRQ(5, 7) + +#define EXYNOS5_IRQ_SYSMMU_ARM_0 COMBINER_IRQ(6, 0) +#define EXYNOS5_IRQ_SYSMMU_ARM_1 COMBINER_IRQ(6, 1) +#define EXYNOS5_IRQ_SYSMMU_MFC_L_0 COMBINER_IRQ(6, 2) +#define EXYNOS5_IRQ_SYSMMU_MFC_L_1 COMBINER_IRQ(6, 3) +#define EXYNOS5_IRQ_SYSMMU_RTIC_0 COMBINER_IRQ(6, 4) +#define EXYNOS5_IRQ_SYSMMU_RTIC_1 COMBINER_IRQ(6, 5) +#define EXYNOS5_IRQ_SYSMMU_SSS_0 COMBINER_IRQ(6, 6) +#define EXYNOS5_IRQ_SYSMMU_SSS_1 COMBINER_IRQ(6, 7) + +#define EXYNOS5_IRQ_SYSMMU_MDMA0_0 COMBINER_IRQ(7, 0) +#define EXYNOS5_IRQ_SYSMMU_MDMA0_1 COMBINER_IRQ(7, 1) +#define EXYNOS5_IRQ_SYSMMU_MDMA1_0 COMBINER_IRQ(7, 2) +#define EXYNOS5_IRQ_SYSMMU_MDMA1_1 COMBINER_IRQ(7, 3) +#define EXYNOS5_IRQ_SYSMMU_TV_0 COMBINER_IRQ(7, 4) +#define EXYNOS5_IRQ_SYSMMU_TV_1 COMBINER_IRQ(7, 5) +#define EXYNOS5_IRQ_SYSMMU_GPSX_0 COMBINER_IRQ(7, 6) +#define EXYNOS5_IRQ_SYSMMU_GPSX_1 COMBINER_IRQ(7, 7) + +#define EXYNOS5_IRQ_SYSMMU_MFC_R_0 COMBINER_IRQ(8, 5) +#define EXYNOS5_IRQ_SYSMMU_MFC_R_1 COMBINER_IRQ(8, 6) + +#define EXYNOS5_IRQ_SYSMMU_DIS1_0 COMBINER_IRQ(9, 4) +#define EXYNOS5_IRQ_SYSMMU_DIS1_1 COMBINER_IRQ(9, 5) + +#define EXYNOS5_IRQ_DP COMBINER_IRQ(10, 3) +#define EXYNOS5_IRQ_SYSMMU_DIS0_0 COMBINER_IRQ(10, 4) +#define EXYNOS5_IRQ_SYSMMU_DIS0_1 COMBINER_IRQ(10, 5) +#define EXYNOS5_IRQ_SYSMMU_ISP_0 COMBINER_IRQ(10, 6) +#define EXYNOS5_IRQ_SYSMMU_ISP_1 COMBINER_IRQ(10, 7) + +#define EXYNOS5_IRQ_SYSMMU_ODC_0 COMBINER_IRQ(11, 0) +#define EXYNOS5_IRQ_SYSMMU_ODC_1 COMBINER_IRQ(11, 1) +#define EXYNOS5_IRQ_SYSMMU_DRC_0 COMBINER_IRQ(11, 6) +#define EXYNOS5_IRQ_SYSMMU_DRC_1 COMBINER_IRQ(11, 7) + +#define EXYNOS5_IRQ_FIMD1_FIFO COMBINER_IRQ(18, 4) +#define EXYNOS5_IRQ_FIMD1_VSYNC COMBINER_IRQ(18, 5) +#define EXYNOS5_IRQ_FIMD1_SYSTEM COMBINER_IRQ(18, 6) + +#define EXYNOS5_IRQ_EINT0 COMBINER_IRQ(23, 0) +#define EXYNOS5_IRQ_MCT_L0 COMBINER_IRQ(23, 1) +#define EXYNOS5_IRQ_MCT_L1 COMBINER_IRQ(23, 2) +#define EXYNOS5_IRQ_MCT_G0 COMBINER_IRQ(23, 3) +#define EXYNOS5_IRQ_MCT_G1 COMBINER_IRQ(23, 4) +#define EXYNOS5_IRQ_MCT_G2 COMBINER_IRQ(23, 5) +#define EXYNOS5_IRQ_MCT_G3 COMBINER_IRQ(23, 6) + +#define EXYNOS5_IRQ_EINT1 COMBINER_IRQ(24, 0) +#define EXYNOS5_IRQ_SYSMMU_LITE1_0 COMBINER_IRQ(24, 1) +#define EXYNOS5_IRQ_SYSMMU_LITE1_1 COMBINER_IRQ(24, 2) +#define EXYNOS5_IRQ_SYSMMU_2D_0 COMBINER_IRQ(24, 5) +#define EXYNOS5_IRQ_SYSMMU_2D_1 COMBINER_IRQ(24, 6) + +#define EXYNOS5_IRQ_EINT2 COMBINER_IRQ(25, 0) +#define EXYNOS5_IRQ_EINT3 COMBINER_IRQ(25, 1) + +#define EXYNOS5_IRQ_EINT4 COMBINER_IRQ(26, 0) +#define EXYNOS5_IRQ_EINT5 COMBINER_IRQ(26, 1) + +#define EXYNOS5_IRQ_EINT6 COMBINER_IRQ(27, 0) +#define EXYNOS5_IRQ_EINT7 COMBINER_IRQ(27, 1) + +#define EXYNOS5_IRQ_EINT8 COMBINER_IRQ(28, 0) +#define EXYNOS5_IRQ_EINT9 COMBINER_IRQ(28, 1) + +#define EXYNOS5_IRQ_EINT10 COMBINER_IRQ(29, 0) +#define EXYNOS5_IRQ_EINT11 COMBINER_IRQ(29, 1) + +#define EXYNOS5_IRQ_EINT12 COMBINER_IRQ(30, 0) +#define EXYNOS5_IRQ_EINT13 COMBINER_IRQ(30, 1) + +#define EXYNOS5_IRQ_EINT14 COMBINER_IRQ(31, 0) +#define EXYNOS5_IRQ_EINT15 COMBINER_IRQ(31, 1) + +#define EXYNOS5_MAX_COMBINER_NR 32 + +#define EXYNOS5_IRQ_GPIO1_NR_GROUPS 13 +#define EXYNOS5_IRQ_GPIO2_NR_GROUPS 9 +#define EXYNOS5_IRQ_GPIO3_NR_GROUPS 5 +#define EXYNOS5_IRQ_GPIO4_NR_GROUPS 1 + +#define MAX_COMBINER_NR (EXYNOS4_MAX_COMBINER_NR > EXYNOS5_MAX_COMBINER_NR ? \ + EXYNOS4_MAX_COMBINER_NR : EXYNOS5_MAX_COMBINER_NR) + +#define S5P_EINT_BASE1 COMBINER_IRQ(MAX_COMBINER_NR, 0) +#define S5P_EINT_BASE2 (S5P_EINT_BASE1 + 16) +#define S5P_GPIOINT_BASE (S5P_EINT_BASE1 + 32) +#define IRQ_GPIO_END (S5P_GPIOINT_BASE + S5P_GPIOINT_COUNT) +#define IRQ_TIMER_BASE (IRQ_GPIO_END + 64) /* Set the default NR_IRQS */ -#define NR_IRQS (IRQ_TIMER_BASE + IRQ_TIMER_COUNT) + +#define NR_IRQS (IRQ_TIMER_BASE + IRQ_TIMER_COUNT) #endif /* __ASM_ARCH_IRQS_H */ diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h index c754a22a2bb3..6e6d11ff352a 100644 --- a/arch/arm/mach-exynos/include/mach/map.h +++ b/arch/arm/mach-exynos/include/mach/map.h @@ -25,12 +25,17 @@ #define EXYNOS4_PA_SYSRAM0 0x02025000 #define EXYNOS4_PA_SYSRAM1 0x02020000 +#define EXYNOS5_PA_SYSRAM 0x02020000 #define EXYNOS4_PA_FIMC0 0x11800000 #define EXYNOS4_PA_FIMC1 0x11810000 #define EXYNOS4_PA_FIMC2 0x11820000 #define EXYNOS4_PA_FIMC3 0x11830000 +#define EXYNOS4_PA_JPEG 0x11840000 + +#define EXYNOS4_PA_G2D 0x12800000 + #define EXYNOS4_PA_I2S0 0x03830000 #define EXYNOS4_PA_I2S1 0xE3100000 #define EXYNOS4_PA_I2S2 0xE2A00000 @@ -44,32 +49,50 @@ #define EXYNOS4_PA_ONENAND 0x0C000000 #define EXYNOS4_PA_ONENAND_DMA 0x0C600000 -#define EXYNOS4_PA_CHIPID 0x10000000 +#define EXYNOS_PA_CHIPID 0x10000000 #define EXYNOS4_PA_SYSCON 0x10010000 +#define EXYNOS5_PA_SYSCON 0x10050100 + #define EXYNOS4_PA_PMU 0x10020000 +#define EXYNOS5_PA_PMU 0x10040000 + #define EXYNOS4_PA_CMU 0x10030000 +#define EXYNOS5_PA_CMU 0x10010000 #define EXYNOS4_PA_SYSTIMER 0x10050000 +#define EXYNOS5_PA_SYSTIMER 0x101C0000 + #define EXYNOS4_PA_WATCHDOG 0x10060000 +#define EXYNOS5_PA_WATCHDOG 0x101D0000 + #define EXYNOS4_PA_RTC 0x10070000 #define EXYNOS4_PA_KEYPAD 0x100A0000 #define EXYNOS4_PA_DMC0 0x10400000 +#define EXYNOS4_PA_DMC1 0x10410000 #define EXYNOS4_PA_COMBINER 0x10440000 +#define EXYNOS5_PA_COMBINER 0x10440000 #define EXYNOS4_PA_GIC_CPU 0x10480000 #define EXYNOS4_PA_GIC_DIST 0x10490000 +#define EXYNOS5_PA_GIC_CPU 0x10480000 +#define EXYNOS5_PA_GIC_DIST 0x10490000 #define EXYNOS4_PA_COREPERI 0x10500000 #define EXYNOS4_PA_TWD 0x10500600 #define EXYNOS4_PA_L2CC 0x10502000 -#define EXYNOS4_PA_MDMA 0x10810000 +#define EXYNOS4_PA_MDMA0 0x10810000 +#define EXYNOS4_PA_MDMA1 0x12840000 #define EXYNOS4_PA_PDMA0 0x12680000 #define EXYNOS4_PA_PDMA1 0x12690000 +#define EXYNOS5_PA_MDMA0 0x10800000 +#define EXYNOS5_PA_MDMA1 0x11C10000 +#define EXYNOS5_PA_PDMA0 0x121A0000 +#define EXYNOS5_PA_PDMA1 0x121B0000 #define EXYNOS4_PA_SYSMMU_MDMA 0x10A40000 #define EXYNOS4_PA_SYSMMU_SSS 0x10A50000 @@ -91,10 +114,13 @@ #define EXYNOS4_PA_SPI1 0x13930000 #define EXYNOS4_PA_SPI2 0x13940000 - #define EXYNOS4_PA_GPIO1 0x11400000 #define EXYNOS4_PA_GPIO2 0x11000000 #define EXYNOS4_PA_GPIO3 0x03860000 +#define EXYNOS5_PA_GPIO1 0x11400000 +#define EXYNOS5_PA_GPIO2 0x13400000 +#define EXYNOS5_PA_GPIO3 0x10D10000 +#define EXYNOS5_PA_GPIO4 0x03860000 #define EXYNOS4_PA_MIPI_CSIS0 0x11880000 #define EXYNOS4_PA_MIPI_CSIS1 0x11890000 @@ -109,6 +135,7 @@ #define EXYNOS4_PA_SATAPHY_CTRL 0x126B0000 #define EXYNOS4_PA_SROMC 0x12570000 +#define EXYNOS5_PA_SROMC 0x12250000 #define EXYNOS4_PA_EHCI 0x12580000 #define EXYNOS4_PA_OHCI 0x12590000 @@ -116,6 +143,7 @@ #define EXYNOS4_PA_MFC 0x13400000 #define EXYNOS4_PA_UART 0x13800000 +#define EXYNOS5_PA_UART 0x12C00000 #define EXYNOS4_PA_VP 0x12C00000 #define EXYNOS4_PA_MIXER 0x12C10000 @@ -124,6 +152,7 @@ #define EXYNOS4_PA_IIC_HDMIPHY 0x138E0000 #define EXYNOS4_PA_IIC(x) (0x13860000 + ((x) * 0x10000)) +#define EXYNOS5_PA_IIC(x) (0x12C60000 + ((x) * 0x10000)) #define EXYNOS4_PA_ADC 0x13910000 #define EXYNOS4_PA_ADC1 0x13911000 @@ -133,8 +162,10 @@ #define EXYNOS4_PA_SPDIF 0x139B0000 #define EXYNOS4_PA_TIMER 0x139D0000 +#define EXYNOS5_PA_TIMER 0x12DD0000 #define EXYNOS4_PA_SDRAM 0x40000000 +#define EXYNOS5_PA_SDRAM 0x40000000 /* Compatibiltiy Defines */ @@ -152,7 +183,6 @@ #define S3C_PA_IIC7 EXYNOS4_PA_IIC(7) #define S3C_PA_RTC EXYNOS4_PA_RTC #define S3C_PA_WDT EXYNOS4_PA_WATCHDOG -#define S3C_PA_UART EXYNOS4_PA_UART #define S3C_PA_SPI0 EXYNOS4_PA_SPI0 #define S3C_PA_SPI1 EXYNOS4_PA_SPI1 #define S3C_PA_SPI2 EXYNOS4_PA_SPI2 @@ -162,6 +192,8 @@ #define S5P_PA_FIMC1 EXYNOS4_PA_FIMC1 #define S5P_PA_FIMC2 EXYNOS4_PA_FIMC2 #define S5P_PA_FIMC3 EXYNOS4_PA_FIMC3 +#define S5P_PA_JPEG EXYNOS4_PA_JPEG +#define S5P_PA_G2D EXYNOS4_PA_G2D #define S5P_PA_FIMD0 EXYNOS4_PA_FIMD0 #define S5P_PA_HDMI EXYNOS4_PA_HDMI #define S5P_PA_IIC_HDMIPHY EXYNOS4_PA_IIC_HDMIPHY @@ -181,15 +213,18 @@ /* Compatibility UART */ -#define S3C_VA_UARTx(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET)) +#define EXYNOS4_PA_UART0 0x13800000 +#define EXYNOS4_PA_UART1 0x13810000 +#define EXYNOS4_PA_UART2 0x13820000 +#define EXYNOS4_PA_UART3 0x13830000 +#define EXYNOS4_SZ_UART SZ_256 -#define S5P_PA_UART(x) (EXYNOS4_PA_UART + ((x) * S3C_UART_OFFSET)) -#define S5P_PA_UART0 S5P_PA_UART(0) -#define S5P_PA_UART1 S5P_PA_UART(1) -#define S5P_PA_UART2 S5P_PA_UART(2) -#define S5P_PA_UART3 S5P_PA_UART(3) -#define S5P_PA_UART4 S5P_PA_UART(4) +#define EXYNOS5_PA_UART0 0x12C00000 +#define EXYNOS5_PA_UART1 0x12C10000 +#define EXYNOS5_PA_UART2 0x12C20000 +#define EXYNOS5_PA_UART3 0x12C30000 +#define EXYNOS5_SZ_UART SZ_256 -#define S5P_SZ_UART SZ_256 +#define S3C_VA_UARTx(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET)) #endif /* __ASM_ARCH_MAP_H */ diff --git a/arch/arm/mach-exynos/include/mach/pmu.h b/arch/arm/mach-exynos/include/mach/pmu.h index 632dd5630138..e76b7faba66b 100644 --- a/arch/arm/mach-exynos/include/mach/pmu.h +++ b/arch/arm/mach-exynos/include/mach/pmu.h @@ -22,11 +22,13 @@ enum sys_powerdown { NUM_SYS_POWERDOWN, }; +extern unsigned long l2x0_regs_phys; struct exynos4_pmu_conf { void __iomem *reg; unsigned int val[NUM_SYS_POWERDOWN]; }; extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode); +extern void s3c_cpu_resume(void); #endif /* __ASM_ARCH_PMU_H */ diff --git a/arch/arm/mach-exynos/include/mach/regs-clock.h b/arch/arm/mach-exynos/include/mach/regs-clock.h index 6c37ebe94829..d9578a58ae7f 100644 --- a/arch/arm/mach-exynos/include/mach/regs-clock.h +++ b/arch/arm/mach-exynos/include/mach/regs-clock.h @@ -16,195 +16,315 @@ #include <plat/cpu.h> #include <mach/map.h> -#define S5P_CLKREG(x) (S5P_VA_CMU + (x)) - -#define S5P_CLKDIV_LEFTBUS S5P_CLKREG(0x04500) -#define S5P_CLKDIV_STAT_LEFTBUS S5P_CLKREG(0x04600) -#define S5P_CLKGATE_IP_LEFTBUS S5P_CLKREG(0x04800) - -#define S5P_CLKDIV_RIGHTBUS S5P_CLKREG(0x08500) -#define S5P_CLKDIV_STAT_RIGHTBUS S5P_CLKREG(0x08600) -#define S5P_CLKGATE_IP_RIGHTBUS S5P_CLKREG(0x08800) - -#define S5P_EPLL_LOCK S5P_CLKREG(0x0C010) -#define S5P_VPLL_LOCK S5P_CLKREG(0x0C020) - -#define S5P_EPLL_CON0 S5P_CLKREG(0x0C110) -#define S5P_EPLL_CON1 S5P_CLKREG(0x0C114) -#define S5P_VPLL_CON0 S5P_CLKREG(0x0C120) -#define S5P_VPLL_CON1 S5P_CLKREG(0x0C124) - -#define S5P_CLKSRC_TOP0 S5P_CLKREG(0x0C210) -#define S5P_CLKSRC_TOP1 S5P_CLKREG(0x0C214) -#define S5P_CLKSRC_CAM S5P_CLKREG(0x0C220) -#define S5P_CLKSRC_TV S5P_CLKREG(0x0C224) -#define S5P_CLKSRC_MFC S5P_CLKREG(0x0C228) -#define S5P_CLKSRC_G3D S5P_CLKREG(0x0C22C) -#define S5P_CLKSRC_IMAGE S5P_CLKREG(0x0C230) -#define S5P_CLKSRC_LCD0 S5P_CLKREG(0x0C234) -#define S5P_CLKSRC_MAUDIO S5P_CLKREG(0x0C23C) -#define S5P_CLKSRC_FSYS S5P_CLKREG(0x0C240) -#define S5P_CLKSRC_PERIL0 S5P_CLKREG(0x0C250) -#define S5P_CLKSRC_PERIL1 S5P_CLKREG(0x0C254) - -#define S5P_CLKSRC_MASK_TOP S5P_CLKREG(0x0C310) -#define S5P_CLKSRC_MASK_CAM S5P_CLKREG(0x0C320) -#define S5P_CLKSRC_MASK_TV S5P_CLKREG(0x0C324) -#define S5P_CLKSRC_MASK_LCD0 S5P_CLKREG(0x0C334) -#define S5P_CLKSRC_MASK_MAUDIO S5P_CLKREG(0x0C33C) -#define S5P_CLKSRC_MASK_FSYS S5P_CLKREG(0x0C340) -#define S5P_CLKSRC_MASK_PERIL0 S5P_CLKREG(0x0C350) -#define S5P_CLKSRC_MASK_PERIL1 S5P_CLKREG(0x0C354) - -#define S5P_CLKDIV_TOP S5P_CLKREG(0x0C510) -#define S5P_CLKDIV_CAM S5P_CLKREG(0x0C520) -#define S5P_CLKDIV_TV S5P_CLKREG(0x0C524) -#define S5P_CLKDIV_MFC S5P_CLKREG(0x0C528) -#define S5P_CLKDIV_G3D S5P_CLKREG(0x0C52C) -#define S5P_CLKDIV_IMAGE S5P_CLKREG(0x0C530) -#define S5P_CLKDIV_LCD0 S5P_CLKREG(0x0C534) -#define S5P_CLKDIV_MAUDIO S5P_CLKREG(0x0C53C) -#define S5P_CLKDIV_FSYS0 S5P_CLKREG(0x0C540) -#define S5P_CLKDIV_FSYS1 S5P_CLKREG(0x0C544) -#define S5P_CLKDIV_FSYS2 S5P_CLKREG(0x0C548) -#define S5P_CLKDIV_FSYS3 S5P_CLKREG(0x0C54C) -#define S5P_CLKDIV_PERIL0 S5P_CLKREG(0x0C550) -#define S5P_CLKDIV_PERIL1 S5P_CLKREG(0x0C554) -#define S5P_CLKDIV_PERIL2 S5P_CLKREG(0x0C558) -#define S5P_CLKDIV_PERIL3 S5P_CLKREG(0x0C55C) -#define S5P_CLKDIV_PERIL4 S5P_CLKREG(0x0C560) -#define S5P_CLKDIV_PERIL5 S5P_CLKREG(0x0C564) -#define S5P_CLKDIV2_RATIO S5P_CLKREG(0x0C580) - -#define S5P_CLKDIV_STAT_TOP S5P_CLKREG(0x0C610) - -#define S5P_CLKGATE_SCLKCAM S5P_CLKREG(0x0C820) -#define S5P_CLKGATE_IP_CAM S5P_CLKREG(0x0C920) -#define S5P_CLKGATE_IP_TV S5P_CLKREG(0x0C924) -#define S5P_CLKGATE_IP_MFC S5P_CLKREG(0x0C928) -#define S5P_CLKGATE_IP_G3D S5P_CLKREG(0x0C92C) -#define S5P_CLKGATE_IP_IMAGE (soc_is_exynos4210() ? \ - S5P_CLKREG(0x0C930) : \ - S5P_CLKREG(0x04930)) -#define S5P_CLKGATE_IP_IMAGE_4210 S5P_CLKREG(0x0C930) -#define S5P_CLKGATE_IP_IMAGE_4212 S5P_CLKREG(0x04930) -#define S5P_CLKGATE_IP_LCD0 S5P_CLKREG(0x0C934) -#define S5P_CLKGATE_IP_FSYS S5P_CLKREG(0x0C940) -#define S5P_CLKGATE_IP_GPS S5P_CLKREG(0x0C94C) -#define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x0C950) -#define S5P_CLKGATE_IP_PERIR (soc_is_exynos4210() ? \ - S5P_CLKREG(0x0C960) : \ - S5P_CLKREG(0x08960)) -#define S5P_CLKGATE_IP_PERIR_4210 S5P_CLKREG(0x0C960) -#define S5P_CLKGATE_IP_PERIR_4212 S5P_CLKREG(0x08960) -#define S5P_CLKGATE_BLOCK S5P_CLKREG(0x0C970) - -#define S5P_CLKSRC_MASK_DMC S5P_CLKREG(0x10300) -#define S5P_CLKSRC_DMC S5P_CLKREG(0x10200) -#define S5P_CLKDIV_DMC0 S5P_CLKREG(0x10500) -#define S5P_CLKDIV_DMC1 S5P_CLKREG(0x10504) -#define S5P_CLKDIV_STAT_DMC0 S5P_CLKREG(0x10600) -#define S5P_CLKGATE_IP_DMC S5P_CLKREG(0x10900) - -#define S5P_APLL_LOCK S5P_CLKREG(0x14000) -#define S5P_MPLL_LOCK (soc_is_exynos4210() ? \ - S5P_CLKREG(0x14004) : \ - S5P_CLKREG(0x10008)) -#define S5P_APLL_CON0 S5P_CLKREG(0x14100) -#define S5P_APLL_CON1 S5P_CLKREG(0x14104) -#define S5P_MPLL_CON0 (soc_is_exynos4210() ? \ - S5P_CLKREG(0x14108) : \ - S5P_CLKREG(0x10108)) -#define S5P_MPLL_CON1 (soc_is_exynos4210() ? \ - S5P_CLKREG(0x1410C) : \ - S5P_CLKREG(0x1010C)) - -#define S5P_CLKSRC_CPU S5P_CLKREG(0x14200) -#define S5P_CLKMUX_STATCPU S5P_CLKREG(0x14400) - -#define S5P_CLKDIV_CPU S5P_CLKREG(0x14500) -#define S5P_CLKDIV_CPU1 S5P_CLKREG(0x14504) -#define S5P_CLKDIV_STATCPU S5P_CLKREG(0x14600) -#define S5P_CLKDIV_STATCPU1 S5P_CLKREG(0x14604) - -#define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x14800) -#define S5P_CLKGATE_IP_CPU S5P_CLKREG(0x14900) - -#define S5P_APLL_LOCKTIME (0x1C20) /* 300us */ - -#define S5P_APLLCON0_ENABLE_SHIFT (31) -#define S5P_APLLCON0_LOCKED_SHIFT (29) -#define S5P_APLL_VAL_1000 ((250 << 16) | (6 << 8) | 1) -#define S5P_APLL_VAL_800 ((200 << 16) | (6 << 8) | 1) - -#define S5P_EPLLCON0_ENABLE_SHIFT (31) -#define S5P_EPLLCON0_LOCKED_SHIFT (29) - -#define S5P_VPLLCON0_ENABLE_SHIFT (31) -#define S5P_VPLLCON0_LOCKED_SHIFT (29) - -#define S5P_CLKSRC_CPU_MUXCORE_SHIFT (16) -#define S5P_CLKMUX_STATCPU_MUXCORE_MASK (0x7 << S5P_CLKSRC_CPU_MUXCORE_SHIFT) - -#define S5P_CLKDIV_CPU0_CORE_SHIFT (0) -#define S5P_CLKDIV_CPU0_CORE_MASK (0x7 << S5P_CLKDIV_CPU0_CORE_SHIFT) -#define S5P_CLKDIV_CPU0_COREM0_SHIFT (4) -#define S5P_CLKDIV_CPU0_COREM0_MASK (0x7 << S5P_CLKDIV_CPU0_COREM0_SHIFT) -#define S5P_CLKDIV_CPU0_COREM1_SHIFT (8) -#define S5P_CLKDIV_CPU0_COREM1_MASK (0x7 << S5P_CLKDIV_CPU0_COREM1_SHIFT) -#define S5P_CLKDIV_CPU0_PERIPH_SHIFT (12) -#define S5P_CLKDIV_CPU0_PERIPH_MASK (0x7 << S5P_CLKDIV_CPU0_PERIPH_SHIFT) -#define S5P_CLKDIV_CPU0_ATB_SHIFT (16) -#define S5P_CLKDIV_CPU0_ATB_MASK (0x7 << S5P_CLKDIV_CPU0_ATB_SHIFT) -#define S5P_CLKDIV_CPU0_PCLKDBG_SHIFT (20) -#define S5P_CLKDIV_CPU0_PCLKDBG_MASK (0x7 << S5P_CLKDIV_CPU0_PCLKDBG_SHIFT) -#define S5P_CLKDIV_CPU0_APLL_SHIFT (24) -#define S5P_CLKDIV_CPU0_APLL_MASK (0x7 << S5P_CLKDIV_CPU0_APLL_SHIFT) - -#define S5P_CLKDIV_DMC0_ACP_SHIFT (0) -#define S5P_CLKDIV_DMC0_ACP_MASK (0x7 << S5P_CLKDIV_DMC0_ACP_SHIFT) -#define S5P_CLKDIV_DMC0_ACPPCLK_SHIFT (4) -#define S5P_CLKDIV_DMC0_ACPPCLK_MASK (0x7 << S5P_CLKDIV_DMC0_ACPPCLK_SHIFT) -#define S5P_CLKDIV_DMC0_DPHY_SHIFT (8) -#define S5P_CLKDIV_DMC0_DPHY_MASK (0x7 << S5P_CLKDIV_DMC0_DPHY_SHIFT) -#define S5P_CLKDIV_DMC0_DMC_SHIFT (12) -#define S5P_CLKDIV_DMC0_DMC_MASK (0x7 << S5P_CLKDIV_DMC0_DMC_SHIFT) -#define S5P_CLKDIV_DMC0_DMCD_SHIFT (16) -#define S5P_CLKDIV_DMC0_DMCD_MASK (0x7 << S5P_CLKDIV_DMC0_DMCD_SHIFT) -#define S5P_CLKDIV_DMC0_DMCP_SHIFT (20) -#define S5P_CLKDIV_DMC0_DMCP_MASK (0x7 << S5P_CLKDIV_DMC0_DMCP_SHIFT) -#define S5P_CLKDIV_DMC0_COPY2_SHIFT (24) -#define S5P_CLKDIV_DMC0_COPY2_MASK (0x7 << S5P_CLKDIV_DMC0_COPY2_SHIFT) -#define S5P_CLKDIV_DMC0_CORETI_SHIFT (28) -#define S5P_CLKDIV_DMC0_CORETI_MASK (0x7 << S5P_CLKDIV_DMC0_CORETI_SHIFT) - -#define S5P_CLKDIV_TOP_ACLK200_SHIFT (0) -#define S5P_CLKDIV_TOP_ACLK200_MASK (0x7 << S5P_CLKDIV_TOP_ACLK200_SHIFT) -#define S5P_CLKDIV_TOP_ACLK100_SHIFT (4) -#define S5P_CLKDIV_TOP_ACLK100_MASK (0xf << S5P_CLKDIV_TOP_ACLK100_SHIFT) -#define S5P_CLKDIV_TOP_ACLK160_SHIFT (8) -#define S5P_CLKDIV_TOP_ACLK160_MASK (0x7 << S5P_CLKDIV_TOP_ACLK160_SHIFT) -#define S5P_CLKDIV_TOP_ACLK133_SHIFT (12) -#define S5P_CLKDIV_TOP_ACLK133_MASK (0x7 << S5P_CLKDIV_TOP_ACLK133_SHIFT) -#define S5P_CLKDIV_TOP_ONENAND_SHIFT (16) -#define S5P_CLKDIV_TOP_ONENAND_MASK (0x7 << S5P_CLKDIV_TOP_ONENAND_SHIFT) - -#define S5P_CLKDIV_BUS_GDLR_SHIFT (0) -#define S5P_CLKDIV_BUS_GDLR_MASK (0x7 << S5P_CLKDIV_BUS_GDLR_SHIFT) -#define S5P_CLKDIV_BUS_GPLR_SHIFT (4) -#define S5P_CLKDIV_BUS_GPLR_MASK (0x7 << S5P_CLKDIV_BUS_GPLR_SHIFT) +#define EXYNOS_CLKREG(x) (S5P_VA_CMU + (x)) + +#define EXYNOS4_CLKDIV_LEFTBUS EXYNOS_CLKREG(0x04500) +#define EXYNOS4_CLKDIV_STAT_LEFTBUS EXYNOS_CLKREG(0x04600) +#define EXYNOS4_CLKGATE_IP_LEFTBUS EXYNOS_CLKREG(0x04800) + +#define EXYNOS4_CLKDIV_RIGHTBUS EXYNOS_CLKREG(0x08500) +#define EXYNOS4_CLKDIV_STAT_RIGHTBUS EXYNOS_CLKREG(0x08600) +#define EXYNOS4_CLKGATE_IP_RIGHTBUS EXYNOS_CLKREG(0x08800) + +#define EXYNOS4_EPLL_LOCK EXYNOS_CLKREG(0x0C010) +#define EXYNOS4_VPLL_LOCK EXYNOS_CLKREG(0x0C020) + +#define EXYNOS4_EPLL_CON0 EXYNOS_CLKREG(0x0C110) +#define EXYNOS4_EPLL_CON1 EXYNOS_CLKREG(0x0C114) +#define EXYNOS4_VPLL_CON0 EXYNOS_CLKREG(0x0C120) +#define EXYNOS4_VPLL_CON1 EXYNOS_CLKREG(0x0C124) + +#define EXYNOS4_CLKSRC_TOP0 EXYNOS_CLKREG(0x0C210) +#define EXYNOS4_CLKSRC_TOP1 EXYNOS_CLKREG(0x0C214) +#define EXYNOS4_CLKSRC_CAM EXYNOS_CLKREG(0x0C220) +#define EXYNOS4_CLKSRC_TV EXYNOS_CLKREG(0x0C224) +#define EXYNOS4_CLKSRC_MFC EXYNOS_CLKREG(0x0C228) +#define EXYNOS4_CLKSRC_G3D EXYNOS_CLKREG(0x0C22C) +#define EXYNOS4_CLKSRC_IMAGE EXYNOS_CLKREG(0x0C230) +#define EXYNOS4_CLKSRC_LCD0 EXYNOS_CLKREG(0x0C234) +#define EXYNOS4_CLKSRC_MAUDIO EXYNOS_CLKREG(0x0C23C) +#define EXYNOS4_CLKSRC_FSYS EXYNOS_CLKREG(0x0C240) +#define EXYNOS4_CLKSRC_PERIL0 EXYNOS_CLKREG(0x0C250) +#define EXYNOS4_CLKSRC_PERIL1 EXYNOS_CLKREG(0x0C254) + +#define EXYNOS4_CLKSRC_MASK_TOP EXYNOS_CLKREG(0x0C310) +#define EXYNOS4_CLKSRC_MASK_CAM EXYNOS_CLKREG(0x0C320) +#define EXYNOS4_CLKSRC_MASK_TV EXYNOS_CLKREG(0x0C324) +#define EXYNOS4_CLKSRC_MASK_LCD0 EXYNOS_CLKREG(0x0C334) +#define EXYNOS4_CLKSRC_MASK_MAUDIO EXYNOS_CLKREG(0x0C33C) +#define EXYNOS4_CLKSRC_MASK_FSYS EXYNOS_CLKREG(0x0C340) +#define EXYNOS4_CLKSRC_MASK_PERIL0 EXYNOS_CLKREG(0x0C350) +#define EXYNOS4_CLKSRC_MASK_PERIL1 EXYNOS_CLKREG(0x0C354) + +#define EXYNOS4_CLKDIV_TOP EXYNOS_CLKREG(0x0C510) +#define EXYNOS4_CLKDIV_CAM EXYNOS_CLKREG(0x0C520) +#define EXYNOS4_CLKDIV_TV EXYNOS_CLKREG(0x0C524) +#define EXYNOS4_CLKDIV_MFC EXYNOS_CLKREG(0x0C528) +#define EXYNOS4_CLKDIV_G3D EXYNOS_CLKREG(0x0C52C) +#define EXYNOS4_CLKDIV_IMAGE EXYNOS_CLKREG(0x0C530) +#define EXYNOS4_CLKDIV_LCD0 EXYNOS_CLKREG(0x0C534) +#define EXYNOS4_CLKDIV_MAUDIO EXYNOS_CLKREG(0x0C53C) +#define EXYNOS4_CLKDIV_FSYS0 EXYNOS_CLKREG(0x0C540) +#define EXYNOS4_CLKDIV_FSYS1 EXYNOS_CLKREG(0x0C544) +#define EXYNOS4_CLKDIV_FSYS2 EXYNOS_CLKREG(0x0C548) +#define EXYNOS4_CLKDIV_FSYS3 EXYNOS_CLKREG(0x0C54C) +#define EXYNOS4_CLKDIV_PERIL0 EXYNOS_CLKREG(0x0C550) +#define EXYNOS4_CLKDIV_PERIL1 EXYNOS_CLKREG(0x0C554) +#define EXYNOS4_CLKDIV_PERIL2 EXYNOS_CLKREG(0x0C558) +#define EXYNOS4_CLKDIV_PERIL3 EXYNOS_CLKREG(0x0C55C) +#define EXYNOS4_CLKDIV_PERIL4 EXYNOS_CLKREG(0x0C560) +#define EXYNOS4_CLKDIV_PERIL5 EXYNOS_CLKREG(0x0C564) +#define EXYNOS4_CLKDIV2_RATIO EXYNOS_CLKREG(0x0C580) + +#define EXYNOS4_CLKDIV_STAT_TOP EXYNOS_CLKREG(0x0C610) +#define EXYNOS4_CLKDIV_STAT_MFC EXYNOS_CLKREG(0x0C628) + +#define EXYNOS4_CLKGATE_SCLKCAM EXYNOS_CLKREG(0x0C820) +#define EXYNOS4_CLKGATE_IP_CAM EXYNOS_CLKREG(0x0C920) +#define EXYNOS4_CLKGATE_IP_TV EXYNOS_CLKREG(0x0C924) +#define EXYNOS4_CLKGATE_IP_MFC EXYNOS_CLKREG(0x0C928) +#define EXYNOS4_CLKGATE_IP_G3D EXYNOS_CLKREG(0x0C92C) +#define EXYNOS4_CLKGATE_IP_IMAGE (soc_is_exynos4210() ? \ + EXYNOS_CLKREG(0x0C930) : \ + EXYNOS_CLKREG(0x04930)) +#define EXYNOS4210_CLKGATE_IP_IMAGE EXYNOS_CLKREG(0x0C930) +#define EXYNOS4212_CLKGATE_IP_IMAGE EXYNOS_CLKREG(0x04930) +#define EXYNOS4_CLKGATE_IP_LCD0 EXYNOS_CLKREG(0x0C934) +#define EXYNOS4_CLKGATE_IP_FSYS EXYNOS_CLKREG(0x0C940) +#define EXYNOS4_CLKGATE_IP_GPS EXYNOS_CLKREG(0x0C94C) +#define EXYNOS4_CLKGATE_IP_PERIL EXYNOS_CLKREG(0x0C950) +#define EXYNOS4_CLKGATE_IP_PERIR (soc_is_exynos4210() ? \ + EXYNOS_CLKREG(0x0C960) : \ + EXYNOS_CLKREG(0x08960)) +#define EXYNOS4210_CLKGATE_IP_PERIR EXYNOS_CLKREG(0x0C960) +#define EXYNOS4212_CLKGATE_IP_PERIR EXYNOS_CLKREG(0x08960) +#define EXYNOS4_CLKGATE_BLOCK EXYNOS_CLKREG(0x0C970) + +#define EXYNOS4_CLKSRC_MASK_DMC EXYNOS_CLKREG(0x10300) +#define EXYNOS4_CLKSRC_DMC EXYNOS_CLKREG(0x10200) +#define EXYNOS4_CLKDIV_DMC0 EXYNOS_CLKREG(0x10500) +#define EXYNOS4_CLKDIV_DMC1 EXYNOS_CLKREG(0x10504) +#define EXYNOS4_CLKDIV_STAT_DMC0 EXYNOS_CLKREG(0x10600) +#define EXYNOS4_CLKDIV_STAT_DMC1 EXYNOS_CLKREG(0x10604) +#define EXYNOS4_CLKGATE_IP_DMC EXYNOS_CLKREG(0x10900) + +#define EXYNOS4_DMC_PAUSE_CTRL EXYNOS_CLKREG(0x11094) +#define EXYNOS4_DMC_PAUSE_ENABLE (1 << 0) + +#define EXYNOS4_APLL_LOCK EXYNOS_CLKREG(0x14000) +#define EXYNOS4_MPLL_LOCK (soc_is_exynos4210() ? \ + EXYNOS_CLKREG(0x14004) : \ + EXYNOS_CLKREG(0x10008)) +#define EXYNOS4_APLL_CON0 EXYNOS_CLKREG(0x14100) +#define EXYNOS4_APLL_CON1 EXYNOS_CLKREG(0x14104) +#define EXYNOS4_MPLL_CON0 (soc_is_exynos4210() ? \ + EXYNOS_CLKREG(0x14108) : \ + EXYNOS_CLKREG(0x10108)) +#define EXYNOS4_MPLL_CON1 (soc_is_exynos4210() ? \ + EXYNOS_CLKREG(0x1410C) : \ + EXYNOS_CLKREG(0x1010C)) + +#define EXYNOS4_CLKSRC_CPU EXYNOS_CLKREG(0x14200) +#define EXYNOS4_CLKMUX_STATCPU EXYNOS_CLKREG(0x14400) + +#define EXYNOS4_CLKDIV_CPU EXYNOS_CLKREG(0x14500) +#define EXYNOS4_CLKDIV_CPU1 EXYNOS_CLKREG(0x14504) +#define EXYNOS4_CLKDIV_STATCPU EXYNOS_CLKREG(0x14600) +#define EXYNOS4_CLKDIV_STATCPU1 EXYNOS_CLKREG(0x14604) + +#define EXYNOS4_CLKGATE_SCLKCPU EXYNOS_CLKREG(0x14800) +#define EXYNOS4_CLKGATE_IP_CPU EXYNOS_CLKREG(0x14900) + +#define EXYNOS4_APLL_LOCKTIME (0x1C20) /* 300us */ + +#define EXYNOS4_APLLCON0_ENABLE_SHIFT (31) +#define EXYNOS4_APLLCON0_LOCKED_SHIFT (29) +#define EXYNOS4_APLL_VAL_1000 ((250 << 16) | (6 << 8) | 1) +#define EXYNOS4_APLL_VAL_800 ((200 << 16) | (6 << 8) | 1) + +#define EXYNOS4_EPLLCON0_ENABLE_SHIFT (31) +#define EXYNOS4_EPLLCON0_LOCKED_SHIFT (29) + +#define EXYNOS4_VPLLCON0_ENABLE_SHIFT (31) +#define EXYNOS4_VPLLCON0_LOCKED_SHIFT (29) + +#define EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT (16) +#define EXYNOS4_CLKMUX_STATCPU_MUXCORE_MASK (0x7 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT) + +#define EXYNOS4_CLKDIV_CPU0_CORE_SHIFT (0) +#define EXYNOS4_CLKDIV_CPU0_CORE_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_CORE_SHIFT) +#define EXYNOS4_CLKDIV_CPU0_COREM0_SHIFT (4) +#define EXYNOS4_CLKDIV_CPU0_COREM0_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_COREM0_SHIFT) +#define EXYNOS4_CLKDIV_CPU0_COREM1_SHIFT (8) +#define EXYNOS4_CLKDIV_CPU0_COREM1_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_COREM1_SHIFT) +#define EXYNOS4_CLKDIV_CPU0_PERIPH_SHIFT (12) +#define EXYNOS4_CLKDIV_CPU0_PERIPH_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_PERIPH_SHIFT) +#define EXYNOS4_CLKDIV_CPU0_ATB_SHIFT (16) +#define EXYNOS4_CLKDIV_CPU0_ATB_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_ATB_SHIFT) +#define EXYNOS4_CLKDIV_CPU0_PCLKDBG_SHIFT (20) +#define EXYNOS4_CLKDIV_CPU0_PCLKDBG_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_PCLKDBG_SHIFT) +#define EXYNOS4_CLKDIV_CPU0_APLL_SHIFT (24) +#define EXYNOS4_CLKDIV_CPU0_APLL_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_APLL_SHIFT) +#define EXYNOS4_CLKDIV_CPU0_CORE2_SHIFT 28 +#define EXYNOS4_CLKDIV_CPU0_CORE2_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_CORE2_SHIFT) + +#define EXYNOS4_CLKDIV_CPU1_COPY_SHIFT 0 +#define EXYNOS4_CLKDIV_CPU1_COPY_MASK (0x7 << EXYNOS4_CLKDIV_CPU1_COPY_SHIFT) +#define EXYNOS4_CLKDIV_CPU1_HPM_SHIFT 4 +#define EXYNOS4_CLKDIV_CPU1_HPM_MASK (0x7 << EXYNOS4_CLKDIV_CPU1_HPM_SHIFT) +#define EXYNOS4_CLKDIV_CPU1_CORES_SHIFT 8 +#define EXYNOS4_CLKDIV_CPU1_CORES_MASK (0x7 << EXYNOS4_CLKDIV_CPU1_CORES_SHIFT) + +#define EXYNOS4_CLKDIV_DMC0_ACP_SHIFT (0) +#define EXYNOS4_CLKDIV_DMC0_ACP_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_ACP_SHIFT) +#define EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT (4) +#define EXYNOS4_CLKDIV_DMC0_ACPPCLK_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT) +#define EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT (8) +#define EXYNOS4_CLKDIV_DMC0_DPHY_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT) +#define EXYNOS4_CLKDIV_DMC0_DMC_SHIFT (12) +#define EXYNOS4_CLKDIV_DMC0_DMC_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_DMC_SHIFT) +#define EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT (16) +#define EXYNOS4_CLKDIV_DMC0_DMCD_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT) +#define EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT (20) +#define EXYNOS4_CLKDIV_DMC0_DMCP_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT) +#define EXYNOS4_CLKDIV_DMC0_COPY2_SHIFT (24) +#define EXYNOS4_CLKDIV_DMC0_COPY2_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_COPY2_SHIFT) +#define EXYNOS4_CLKDIV_DMC0_CORETI_SHIFT (28) +#define EXYNOS4_CLKDIV_DMC0_CORETI_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_CORETI_SHIFT) + +#define EXYNOS4_CLKDIV_DMC1_G2D_ACP_SHIFT (0) +#define EXYNOS4_CLKDIV_DMC1_G2D_ACP_MASK (0xf << EXYNOS4_CLKDIV_DMC1_G2D_ACP_SHIFT) +#define EXYNOS4_CLKDIV_DMC1_C2C_SHIFT (4) +#define EXYNOS4_CLKDIV_DMC1_C2C_MASK (0x7 << EXYNOS4_CLKDIV_DMC1_C2C_SHIFT) +#define EXYNOS4_CLKDIV_DMC1_PWI_SHIFT (8) +#define EXYNOS4_CLKDIV_DMC1_PWI_MASK (0xf << EXYNOS4_CLKDIV_DMC1_PWI_SHIFT) +#define EXYNOS4_CLKDIV_DMC1_C2CACLK_SHIFT (12) +#define EXYNOS4_CLKDIV_DMC1_C2CACLK_MASK (0x7 << EXYNOS4_CLKDIV_DMC1_C2CACLK_SHIFT) +#define EXYNOS4_CLKDIV_DMC1_DVSEM_SHIFT (16) +#define EXYNOS4_CLKDIV_DMC1_DVSEM_MASK (0x7f << EXYNOS4_CLKDIV_DMC1_DVSEM_SHIFT) +#define EXYNOS4_CLKDIV_DMC1_DPM_SHIFT (24) +#define EXYNOS4_CLKDIV_DMC1_DPM_MASK (0x7f << EXYNOS4_CLKDIV_DMC1_DPM_SHIFT) + +#define EXYNOS4_CLKDIV_MFC_SHIFT (0) +#define EXYNOS4_CLKDIV_MFC_MASK (0x7 << EXYNOS4_CLKDIV_MFC_SHIFT) + +#define EXYNOS4_CLKDIV_TOP_ACLK200_SHIFT (0) +#define EXYNOS4_CLKDIV_TOP_ACLK200_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ACLK200_SHIFT) +#define EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT (4) +#define EXYNOS4_CLKDIV_TOP_ACLK100_MASK (0xF << EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT) +#define EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT (8) +#define EXYNOS4_CLKDIV_TOP_ACLK160_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT) +#define EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT (12) +#define EXYNOS4_CLKDIV_TOP_ACLK133_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT) +#define EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT (16) +#define EXYNOS4_CLKDIV_TOP_ONENAND_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT) +#define EXYNOS4_CLKDIV_TOP_ACLK266_GPS_SHIFT (20) +#define EXYNOS4_CLKDIV_TOP_ACLK266_GPS_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ACLK266_GPS_SHIFT) +#define EXYNOS4_CLKDIV_TOP_ACLK400_MCUISP_SHIFT (24) +#define EXYNOS4_CLKDIV_TOP_ACLK400_MCUISP_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ACLK400_MCUISP_SHIFT) + +#define EXYNOS4_CLKDIV_BUS_GDLR_SHIFT (0) +#define EXYNOS4_CLKDIV_BUS_GDLR_MASK (0x7 << EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) +#define EXYNOS4_CLKDIV_BUS_GPLR_SHIFT (4) +#define EXYNOS4_CLKDIV_BUS_GPLR_MASK (0x7 << EXYNOS4_CLKDIV_BUS_GPLR_SHIFT) + +#define EXYNOS4_CLKDIV_CAM_FIMC0_SHIFT (0) +#define EXYNOS4_CLKDIV_CAM_FIMC0_MASK (0xf << EXYNOS4_CLKDIV_CAM_FIMC0_SHIFT) +#define EXYNOS4_CLKDIV_CAM_FIMC1_SHIFT (4) +#define EXYNOS4_CLKDIV_CAM_FIMC1_MASK (0xf << EXYNOS4_CLKDIV_CAM_FIMC1_SHIFT) +#define EXYNOS4_CLKDIV_CAM_FIMC2_SHIFT (8) +#define EXYNOS4_CLKDIV_CAM_FIMC2_MASK (0xf << EXYNOS4_CLKDIV_CAM_FIMC2_SHIFT) +#define EXYNOS4_CLKDIV_CAM_FIMC3_SHIFT (12) +#define EXYNOS4_CLKDIV_CAM_FIMC3_MASK (0xf << EXYNOS4_CLKDIV_CAM_FIMC3_SHIFT) /* Only for EXYNOS4210 */ -#define S5P_CLKSRC_LCD1 S5P_CLKREG(0x0C238) -#define S5P_CLKSRC_MASK_LCD1 S5P_CLKREG(0x0C338) -#define S5P_CLKDIV_LCD1 S5P_CLKREG(0x0C538) -#define S5P_CLKGATE_IP_LCD1 S5P_CLKREG(0x0C938) +#define EXYNOS4210_CLKSRC_LCD1 EXYNOS_CLKREG(0x0C238) +#define EXYNOS4210_CLKSRC_MASK_LCD1 EXYNOS_CLKREG(0x0C338) +#define EXYNOS4210_CLKDIV_LCD1 EXYNOS_CLKREG(0x0C538) +#define EXYNOS4210_CLKGATE_IP_LCD1 EXYNOS_CLKREG(0x0C938) + +/* Only for EXYNOS4212 */ + +#define EXYNOS4_CLKDIV_CAM1 EXYNOS_CLKREG(0x0C568) + +#define EXYNOS4_CLKDIV_STAT_CAM1 EXYNOS_CLKREG(0x0C668) + +#define EXYNOS4_CLKDIV_CAM1_JPEG_SHIFT (0) +#define EXYNOS4_CLKDIV_CAM1_JPEG_MASK (0xf << EXYNOS4_CLKDIV_CAM1_JPEG_SHIFT) + +/* For EXYNOS5250 */ + +#define EXYNOS5_APLL_LOCK EXYNOS_CLKREG(0x00000) +#define EXYNOS5_APLL_CON0 EXYNOS_CLKREG(0x00100) +#define EXYNOS5_CLKSRC_CPU EXYNOS_CLKREG(0x00200) +#define EXYNOS5_CLKMUX_STATCPU EXYNOS_CLKREG(0x00400) +#define EXYNOS5_CLKDIV_CPU0 EXYNOS_CLKREG(0x00500) +#define EXYNOS5_CLKDIV_CPU1 EXYNOS_CLKREG(0x00504) +#define EXYNOS5_CLKDIV_STATCPU0 EXYNOS_CLKREG(0x00600) +#define EXYNOS5_CLKDIV_STATCPU1 EXYNOS_CLKREG(0x00604) + +#define EXYNOS5_MPLL_CON0 EXYNOS_CLKREG(0x04100) +#define EXYNOS5_CLKSRC_CORE1 EXYNOS_CLKREG(0x04204) + +#define EXYNOS5_CLKGATE_IP_CORE EXYNOS_CLKREG(0x04900) + +#define EXYNOS5_CLKDIV_ACP EXYNOS_CLKREG(0x08500) + +#define EXYNOS5_CLKSRC_TOP2 EXYNOS_CLKREG(0x10218) +#define EXYNOS5_EPLL_CON0 EXYNOS_CLKREG(0x10130) +#define EXYNOS5_EPLL_CON1 EXYNOS_CLKREG(0x10134) +#define EXYNOS5_VPLL_CON0 EXYNOS_CLKREG(0x10140) +#define EXYNOS5_VPLL_CON1 EXYNOS_CLKREG(0x10144) +#define EXYNOS5_CPLL_CON0 EXYNOS_CLKREG(0x10120) + +#define EXYNOS5_CLKSRC_TOP0 EXYNOS_CLKREG(0x10210) +#define EXYNOS5_CLKSRC_TOP3 EXYNOS_CLKREG(0x1021C) +#define EXYNOS5_CLKSRC_GSCL EXYNOS_CLKREG(0x10220) +#define EXYNOS5_CLKSRC_DISP1_0 EXYNOS_CLKREG(0x1022C) +#define EXYNOS5_CLKSRC_FSYS EXYNOS_CLKREG(0x10244) +#define EXYNOS5_CLKSRC_PERIC0 EXYNOS_CLKREG(0x10250) + +#define EXYNOS5_CLKSRC_MASK_TOP EXYNOS_CLKREG(0x10310) +#define EXYNOS5_CLKSRC_MASK_GSCL EXYNOS_CLKREG(0x10320) +#define EXYNOS5_CLKSRC_MASK_DISP1_0 EXYNOS_CLKREG(0x1032C) +#define EXYNOS5_CLKSRC_MASK_FSYS EXYNOS_CLKREG(0x10340) +#define EXYNOS5_CLKSRC_MASK_PERIC0 EXYNOS_CLKREG(0x10350) + +#define EXYNOS5_CLKDIV_TOP0 EXYNOS_CLKREG(0x10510) +#define EXYNOS5_CLKDIV_TOP1 EXYNOS_CLKREG(0x10514) +#define EXYNOS5_CLKDIV_GSCL EXYNOS_CLKREG(0x10520) +#define EXYNOS5_CLKDIV_DISP1_0 EXYNOS_CLKREG(0x1052C) +#define EXYNOS5_CLKDIV_GEN EXYNOS_CLKREG(0x1053C) +#define EXYNOS5_CLKDIV_FSYS0 EXYNOS_CLKREG(0x10548) +#define EXYNOS5_CLKDIV_FSYS1 EXYNOS_CLKREG(0x1054C) +#define EXYNOS5_CLKDIV_FSYS2 EXYNOS_CLKREG(0x10550) +#define EXYNOS5_CLKDIV_FSYS3 EXYNOS_CLKREG(0x10554) +#define EXYNOS5_CLKDIV_PERIC0 EXYNOS_CLKREG(0x10558) + +#define EXYNOS5_CLKGATE_IP_ACP EXYNOS_CLKREG(0x08800) +#define EXYNOS5_CLKGATE_IP_GSCL EXYNOS_CLKREG(0x10920) +#define EXYNOS5_CLKGATE_IP_DISP1 EXYNOS_CLKREG(0x10928) +#define EXYNOS5_CLKGATE_IP_MFC EXYNOS_CLKREG(0x1092C) +#define EXYNOS5_CLKGATE_IP_GEN EXYNOS_CLKREG(0x10934) +#define EXYNOS5_CLKGATE_IP_FSYS EXYNOS_CLKREG(0x10944) +#define EXYNOS5_CLKGATE_IP_GPS EXYNOS_CLKREG(0x1094C) +#define EXYNOS5_CLKGATE_IP_PERIC EXYNOS_CLKREG(0x10950) +#define EXYNOS5_CLKGATE_IP_PERIS EXYNOS_CLKREG(0x10960) +#define EXYNOS5_CLKGATE_BLOCK EXYNOS_CLKREG(0x10980) + +#define EXYNOS5_BPLL_CON0 EXYNOS_CLKREG(0x20110) +#define EXYNOS5_CLKSRC_CDREX EXYNOS_CLKREG(0x20200) +#define EXYNOS5_CLKDIV_CDREX EXYNOS_CLKREG(0x20500) + +#define EXYNOS5_EPLL_LOCK EXYNOS_CLKREG(0x10030) + +#define EXYNOS5_EPLLCON0_LOCKED_SHIFT (29) /* Compatibility defines and inclusion */ #include <mach/regs-pmu.h> -#define S5P_EPLL_CON S5P_EPLL_CON0 +#define S5P_EPLL_CON EXYNOS4_EPLL_CON0 #endif /* __ASM_ARCH_REGS_CLOCK_H */ diff --git a/arch/arm/mach-exynos/include/mach/regs-gpio.h b/arch/arm/mach-exynos/include/mach/regs-gpio.h index 1401b21663a5..e4b5b60dcb85 100644 --- a/arch/arm/mach-exynos/include/mach/regs-gpio.h +++ b/arch/arm/mach-exynos/include/mach/regs-gpio.h @@ -16,6 +16,15 @@ #include <mach/map.h> #include <mach/irqs.h> +#define EINT_REG_NR(x) (EINT_OFFSET(x) >> 3) +#define EINT_CON(b, x) (b + 0xE00 + (EINT_REG_NR(x) * 4)) +#define EINT_FLTCON(b, x) (b + 0xE80 + (EINT_REG_NR(x) * 4)) +#define EINT_MASK(b, x) (b + 0xF00 + (EINT_REG_NR(x) * 4)) +#define EINT_PEND(b, x) (b + 0xF40 + (EINT_REG_NR(x) * 4)) + +#define EINT_OFFSET_BIT(x) (1 << (EINT_OFFSET(x) & 0x7)) + +/* compatibility for plat-s5p/irq-pm.c */ #define EXYNOS4_EINT40CON (S5P_VA_GPIO2 + 0xE00) #define S5P_EINT_CON(x) (EXYNOS4_EINT40CON + ((x) * 0x4)) @@ -28,15 +37,4 @@ #define EXYNOS4_EINT40PEND (S5P_VA_GPIO2 + 0xF40) #define S5P_EINT_PEND(x) (EXYNOS4_EINT40PEND + ((x) * 0x4)) -#define EINT_REG_NR(x) (EINT_OFFSET(x) >> 3) - -#define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7)) - -#define EINT_MODE S3C_GPIO_SFN(0xf) - -#define EINT_GPIO_0(x) EXYNOS4_GPX0(x) -#define EINT_GPIO_1(x) EXYNOS4_GPX1(x) -#define EINT_GPIO_2(x) EXYNOS4_GPX2(x) -#define EINT_GPIO_3(x) EXYNOS4_GPX3(x) - #endif /* __ASM_ARCH_REGS_GPIO_H */ diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h index 4fff8e938fec..4c53f38b5a9e 100644 --- a/arch/arm/mach-exynos/include/mach/regs-pmu.h +++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h @@ -31,6 +31,7 @@ #define S5P_USE_STANDBYWFE_ISP_ARM (1 << 26) #define S5P_SWRESET S5P_PMUREG(0x0400) +#define EXYNOS_SWRESET S5P_PMUREG(0x0400) #define S5P_WAKEUP_STAT S5P_PMUREG(0x0600) #define S5P_EINT_WAKEUP_MASK S5P_PMUREG(0x0604) diff --git a/arch/arm/mach-exynos/include/mach/system.h b/arch/arm/mach-exynos/include/mach/system.h deleted file mode 100644 index 0063a6de3dc8..000000000000 --- a/arch/arm/mach-exynos/include/mach/system.h +++ /dev/null @@ -1,20 +0,0 @@ -/* linux/arch/arm/mach-exynos4/include/mach/system.h - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * EXYNOS4 - system support header - * - * 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. -*/ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H __FILE__ - -static void arch_idle(void) -{ - /* nothing here yet */ -} -#endif /* __ASM_ARCH_SYSTEM_H */ diff --git a/arch/arm/mach-exynos/include/mach/uncompress.h b/arch/arm/mach-exynos/include/mach/uncompress.h index 21d97bcd9acb..2979995d5a6a 100644 --- a/arch/arm/mach-exynos/include/mach/uncompress.h +++ b/arch/arm/mach-exynos/include/mach/uncompress.h @@ -1,9 +1,8 @@ -/* linux/arch/arm/mach-exynos4/include/mach/uncompress.h - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. +/* + * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd. * http://www.samsung.com * - * EXYNOS4 - uncompress code + * EXYNOS - uncompress code * * 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 @@ -13,12 +12,35 @@ #ifndef __ASM_ARCH_UNCOMPRESS_H #define __ASM_ARCH_UNCOMPRESS_H __FILE__ +#include <asm/mach-types.h> + #include <mach/map.h> + +volatile u8 *uart_base; + #include <plat/uncompress.h> +static unsigned int __raw_readl(unsigned int ptr) +{ + return *((volatile unsigned int *)ptr); +} + static void arch_detect_cpu(void) { - /* we do not need to do any cpu detection here at the moment. */ + u32 chip_id = __raw_readl(EXYNOS_PA_CHIPID); + + /* + * product_id is bits 31:12 + * bits 23:20 describe the exynosX family + * + */ + chip_id >>= 20; + chip_id &= 0xf; + + if (chip_id == 0x5) + uart_base = (volatile u8 *)EXYNOS5_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT); + else + uart_base = (volatile u8 *)EXYNOS4_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT); /* * For preventing FIFO overrun or infinite loop of UART console, diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c index e6b02fdf1b09..8245f1c761d9 100644 --- a/arch/arm/mach-exynos/mach-exynos4-dt.c +++ b/arch/arm/mach-exynos/mach-exynos4-dt.c @@ -37,13 +37,13 @@ * data from the device tree. */ static const struct of_dev_auxdata exynos4210_auxdata_lookup[] __initconst = { - OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART0, + OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART0, "exynos4210-uart.0", NULL), - OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART1, + OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART1, "exynos4210-uart.1", NULL), - OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART2, + OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART2, "exynos4210-uart.2", NULL), - OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART3, + OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART3, "exynos4210-uart.3", NULL), OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(0), "exynos4-sdhci.0", NULL), diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c new file mode 100644 index 000000000000..4711c8920e37 --- /dev/null +++ b/arch/arm/mach-exynos/mach-exynos5-dt.c @@ -0,0 +1,78 @@ +/* + * SAMSUNG EXYNOS5250 Flattened Device Tree enabled machine + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.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. +*/ + +#include <linux/of_platform.h> +#include <linux/serial_core.h> + +#include <asm/mach/arch.h> +#include <asm/hardware/gic.h> +#include <mach/map.h> + +#include <plat/cpu.h> +#include <plat/regs-serial.h> + +#include "common.h" + +/* + * The following lookup table is used to override device names when devices + * are registered from device tree. This is temporarily added to enable + * device tree support addition for the EXYNOS5 architecture. + * + * For drivers that require platform data to be provided from the machine + * file, a platform data pointer can also be supplied along with the + * devices names. Usually, the platform data elements that cannot be parsed + * from the device tree by the drivers (example: function pointers) are + * supplied. But it should be noted that this is a temporary mechanism and + * at some point, the drivers should be capable of parsing all the platform + * data from the device tree. + */ +static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = { + OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART0, + "exynos4210-uart.0", NULL), + OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART1, + "exynos4210-uart.1", NULL), + OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART2, + "exynos4210-uart.2", NULL), + OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART3, + "exynos4210-uart.3", NULL), + OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA0, "dma-pl330.0", NULL), + OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.1", NULL), + OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_MDMA1, "dma-pl330.2", NULL), + {}, +}; + +static void __init exynos5250_dt_map_io(void) +{ + exynos_init_io(NULL, 0); + s3c24xx_init_clocks(24000000); +} + +static void __init exynos5250_dt_machine_init(void) +{ + of_platform_populate(NULL, of_default_bus_match_table, + exynos5250_auxdata_lookup, NULL); +} + +static char const *exynos5250_dt_compat[] __initdata = { + "samsung,exynos5250", + NULL +}; + +DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)") + /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ + .init_irq = exynos5_init_irq, + .map_io = exynos5250_dt_map_io, + .handle_irq = gic_handle_irq, + .init_machine = exynos5250_dt_machine_init, + .timer = &exynos4_timer, + .dt_compat = exynos5250_dt_compat, + .restart = exynos5_restart, +MACHINE_END diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c index aa37179d776c..b4f1f902ce6d 100644 --- a/arch/arm/mach-exynos/mach-nuri.c +++ b/arch/arm/mach-exynos/mach-nuri.c @@ -28,6 +28,7 @@ #include <video/platform_lcd.h> #include <media/m5mols.h> +#include <media/s5k6aa.h> #include <media/s5p_fimc.h> #include <media/v4l2-mediabus.h> @@ -75,6 +76,7 @@ enum fixed_regulator_id { FIXED_REG_ID_MAX8903, FIXED_REG_ID_CAM_A28V, FIXED_REG_ID_CAM_12V, + FIXED_REG_ID_CAM_VT_15V, }; static struct s3c2410_uartcfg nuri_uartcfgs[] __initdata = { @@ -109,13 +111,13 @@ static struct s3c_sdhci_platdata nuri_hsmmc0_data __initdata = { .max_width = 8, .host_caps = (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | - MMC_CAP_DISABLE | MMC_CAP_ERASE), + MMC_CAP_ERASE), .cd_type = S3C_SDHCI_CD_PERMANENT, .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, }; static struct regulator_consumer_supply emmc_supplies[] = { - REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"), + REGULATOR_SUPPLY("vmmc", "exynos4-sdhci.0"), REGULATOR_SUPPLY("vmmc", "dw_mmc"), }; @@ -148,8 +150,7 @@ static struct platform_device emmc_fixed_voltage = { static struct s3c_sdhci_platdata nuri_hsmmc2_data __initdata = { .max_width = 4, .host_caps = MMC_CAP_4_BIT_DATA | - MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | - MMC_CAP_DISABLE, + MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, .ext_cd_gpio = EXYNOS4_GPX3(3), /* XEINT_27 */ .ext_cd_gpio_invert = 1, .cd_type = S3C_SDHCI_CD_GPIO, @@ -306,49 +307,7 @@ static struct i2c_board_info i2c1_devs[] __initdata = { }; /* TSP */ -static u8 mxt_init_vals[] = { - /* MXT_GEN_COMMAND(6) */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* MXT_GEN_POWER(7) */ - 0x20, 0xff, 0x32, - /* MXT_GEN_ACQUIRE(8) */ - 0x0a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x23, - /* MXT_TOUCH_MULTI(9) */ - 0x00, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, - /* MXT_TOUCH_KEYARRAY(15) */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x00, - /* MXT_SPT_GPIOPWM(19) */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* MXT_PROCI_GRIPFACE(20) */ - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x04, - 0x0f, 0x0a, - /* MXT_PROCG_NOISE(22) */ - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00, - 0x00, 0x05, 0x0f, 0x19, 0x23, 0x2d, 0x03, - /* MXT_TOUCH_PROXIMITY(23) */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, - /* MXT_PROCI_ONETOUCH(24) */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* MXT_SPT_SELFTEST(25) */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - /* MXT_PROCI_TWOTOUCH(27) */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* MXT_SPT_CTECONFIG(28) */ - 0x00, 0x00, 0x02, 0x08, 0x10, 0x00, -}; - static struct mxt_platform_data mxt_platform_data = { - .config = mxt_init_vals, - .config_length = ARRAY_SIZE(mxt_init_vals), - .x_line = 18, .y_line = 11, .x_size = 1024, @@ -399,6 +358,9 @@ static struct regulator_consumer_supply __initdata max8997_ldo4_[] = { static struct regulator_consumer_supply __initdata max8997_ldo5_[] = { REGULATOR_SUPPLY("vhsic", "modemctl"), /* MODEM */ }; +static struct regulator_consumer_supply nuri_max8997_ldo6_consumer[] = { + REGULATOR_SUPPLY("vdd_reg", "6-003c"), /* S5K6AA camera */ +}; static struct regulator_consumer_supply __initdata max8997_ldo7_[] = { REGULATOR_SUPPLY("dig_18", "0-001f"), /* HCD803 */ }; @@ -413,7 +375,7 @@ static struct regulator_consumer_supply __initdata max8997_ldo12_[] = { REGULATOR_SUPPLY("vddio", "6-003c"), /* HDC802 */ }; static struct regulator_consumer_supply __initdata max8997_ldo13_[] = { - REGULATOR_SUPPLY("vmmc", "s3c-sdhci.2"), /* TFLASH */ + REGULATOR_SUPPLY("vmmc", "exynos4-sdhci.2"), /* TFLASH */ }; static struct regulator_consumer_supply __initdata max8997_ldo14_[] = { REGULATOR_SUPPLY("inmotor", "max8997-haptic"), @@ -431,7 +393,7 @@ static struct regulator_consumer_supply __initdata max8997_buck1_[] = { REGULATOR_SUPPLY("vdd_arm", NULL), /* CPUFREQ */ }; static struct regulator_consumer_supply __initdata max8997_buck2_[] = { - REGULATOR_SUPPLY("vdd_int", NULL), /* CPUFREQ */ + REGULATOR_SUPPLY("vdd_int", "exynos4210-busfreq.0"), /* CPUFREQ */ }; static struct regulator_consumer_supply __initdata max8997_buck3_[] = { REGULATOR_SUPPLY("vdd", "mali_dev.0"), /* G3D of Exynos 4 */ @@ -546,6 +508,8 @@ static struct regulator_init_data __initdata max8997_ldo6_data = { .enabled = 1, }, }, + .num_consumer_supplies = ARRAY_SIZE(nuri_max8997_ldo6_consumer), + .consumer_supplies = nuri_max8997_ldo6_consumer, }; static struct regulator_init_data __initdata max8997_ldo7_data = { @@ -565,7 +529,7 @@ static struct regulator_init_data __initdata max8997_ldo7_data = { static struct regulator_init_data __initdata max8997_ldo8_data = { .constraints = { - .name = "VUSB/VDAC_3.3V_C210", + .name = "VUSB+VDAC_3.3V_C210", .min_uV = 3300000, .max_uV = 3300000, .valid_ops_mask = REGULATOR_CHANGE_STATUS, @@ -742,7 +706,7 @@ static struct regulator_init_data __initdata max8997_buck2_data = { .constraints = { .name = "VINT_1.1V_C210", .min_uV = 900000, - .max_uV = 1100000, + .max_uV = 1200000, .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, .always_on = 1, .state_mem = { @@ -957,7 +921,6 @@ static struct max8997_platform_data __initdata nuri_max8997_pdata = { .regulators = nuri_max8997_regulators, .buck125_gpios = { EXYNOS4_GPX0(5), EXYNOS4_GPX0(6), EXYNOS4_GPL0(0) }, - .buck2_gpiodvs = true, .buck1_voltage[0] = 1350000, /* 1.35V */ .buck1_voltage[1] = 1300000, /* 1.3V */ @@ -1116,7 +1079,30 @@ static void __init nuri_ehci_init(void) } /* CAMERA */ +static struct regulator_consumer_supply cam_vt_cam15_supply = + REGULATOR_SUPPLY("vdd_core", "6-003c"); + +static struct regulator_init_data cam_vt_cam15_reg_init_data = { + .constraints = { .valid_ops_mask = REGULATOR_CHANGE_STATUS }, + .num_consumer_supplies = 1, + .consumer_supplies = &cam_vt_cam15_supply, +}; + +static struct fixed_voltage_config cam_vt_cam15_fixed_voltage_cfg = { + .supply_name = "VT_CAM_1.5V", + .microvolts = 1500000, + .gpio = EXYNOS4_GPE2(2), /* VT_CAM_1.5V_EN */ + .enable_high = 1, + .init_data = &cam_vt_cam15_reg_init_data, +}; + +static struct platform_device cam_vt_cam15_fixed_rdev = { + .name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_VT_15V, + .dev = { .platform_data = &cam_vt_cam15_fixed_voltage_cfg }, +}; + static struct regulator_consumer_supply cam_vdda_supply[] = { + REGULATOR_SUPPLY("vdda", "6-003c"), REGULATOR_SUPPLY("a_sensor", "0-001f"), }; @@ -1173,6 +1159,21 @@ static struct s5p_platform_mipi_csis mipi_csis_platdata = { #define GPIO_CAM_MEGA_RST EXYNOS4_GPY3(7) /* ISP_RESET */ #define GPIO_CAM_8M_ISP_INT EXYNOS4_GPL2(5) +#define GPIO_CAM_VT_NSTBY EXYNOS4_GPL2(0) +#define GPIO_CAM_VT_NRST EXYNOS4_GPL2(1) + +static struct s5k6aa_platform_data s5k6aa_pldata = { + .mclk_frequency = 24000000UL, + .gpio_reset = { GPIO_CAM_VT_NRST, 0 }, + .gpio_stby = { GPIO_CAM_VT_NSTBY, 0 }, + .bus_type = V4L2_MBUS_PARALLEL, + .horiz_flip = 1, +}; + +static struct i2c_board_info s5k6aa_board_info = { + I2C_BOARD_INFO("S5K6AA", 0x3c), + .platform_data = &s5k6aa_pldata, +}; static struct m5mols_platform_data m5mols_platdata = { .gpio_reset = GPIO_CAM_MEGA_RST, @@ -1185,6 +1186,13 @@ static struct i2c_board_info m5mols_board_info = { static struct s5p_fimc_isp_info nuri_camera_sensors[] = { { + .flags = V4L2_MBUS_PCLK_SAMPLE_RISING | + V4L2_MBUS_VSYNC_ACTIVE_LOW, + .bus_type = FIMC_ITU_601, + .board_info = &s5k6aa_board_info, + .clk_frequency = 24000000UL, + .i2c_bus_num = 6, + }, { .flags = V4L2_MBUS_PCLK_SAMPLE_FALLING | V4L2_MBUS_VSYNC_ACTIVE_LOW, .bus_type = FIMC_MIPI_CSI2, @@ -1200,11 +1208,13 @@ static struct s5p_platform_fimc fimc_md_platdata = { }; static struct gpio nuri_camera_gpios[] = { + { GPIO_CAM_VT_NSTBY, GPIOF_OUT_INIT_LOW, "CAM_VGA_NSTBY" }, + { GPIO_CAM_VT_NRST, GPIOF_OUT_INIT_LOW, "CAM_VGA_NRST" }, { GPIO_CAM_8M_ISP_INT, GPIOF_IN, "8M_ISP_INT" }, { GPIO_CAM_MEGA_RST, GPIOF_OUT_INIT_LOW, "CAM_8M_NRST" }, }; -static void nuri_camera_init(void) +static void __init nuri_camera_init(void) { s3c_set_platdata(&mipi_csis_platdata, sizeof(mipi_csis_platdata), &s5p_device_mipi_csis0); @@ -1224,6 +1234,8 @@ static void nuri_camera_init(void) pr_err("%s: Failed to configure 8M_ISP_INT GPIO\n", __func__); /* Free GPIOs controlled directly by the sensor drivers. */ + gpio_free(GPIO_CAM_VT_NRST); + gpio_free(GPIO_CAM_VT_NSTBY); gpio_free(GPIO_CAM_MEGA_RST); if (exynos4_fimc_setup_gpio(S5P_CAMPORT_A)) { @@ -1234,15 +1246,27 @@ static void nuri_camera_init(void) s5p_gpio_set_drvstr(EXYNOS4_GPJ1(3), S5P_GPIO_DRVSTR_LV4); } +static struct s3c2410_platform_i2c nuri_i2c6_platdata __initdata = { + .frequency = 400000U, + .sda_delay = 200, + .bus_num = 6, +}; + static struct s3c2410_platform_i2c nuri_i2c0_platdata __initdata = { .frequency = 400000U, .sda_delay = 200, }; +/* DEVFREQ controlling memory/bus */ +static struct platform_device exynos4_bus_devfreq = { + .name = "exynos4210-busfreq", +}; + static struct platform_device *nuri_devices[] __initdata = { /* Samsung Platform Devices */ &s3c_device_i2c5, /* PMIC should initialize first */ &s3c_device_i2c0, + &s3c_device_i2c6, &emmc_fixed_voltage, &s5p_device_mipi_csis0, &s5p_device_fimc0, @@ -1259,6 +1283,8 @@ static struct platform_device *nuri_devices[] __initdata = { &s3c_device_i2c3, &i2c9_gpio, &s3c_device_adc, + &s5p_device_g2d, + &s5p_device_jpeg, &s3c_device_rtc, &s5p_device_mfc, &s5p_device_mfc_l, @@ -1271,12 +1297,15 @@ static struct platform_device *nuri_devices[] __initdata = { &nuri_backlight_device, &max8903_fixed_reg_dev, &nuri_max8903_device, + &cam_vt_cam15_fixed_rdev, &cam_vdda_fixed_rdev, &cam_8m_12v_fixed_rdev, + &exynos4_bus_devfreq, }; static void __init nuri_map_io(void) { + clk_xusbxti.rate = 24000000; exynos_init_io(NULL, 0); s3c24xx_init_clocks(24000000); s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs)); @@ -1302,13 +1331,13 @@ static void __init nuri_machine_init(void) i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs)); i2c9_devs[I2C9_MAX17042].irq = gpio_to_irq(EXYNOS4_GPX2(3)); i2c_register_board_info(9, i2c9_devs, ARRAY_SIZE(i2c9_devs)); + s3c_i2c6_set_platdata(&nuri_i2c6_platdata); s5p_fimd0_set_platdata(&nuri_fb_pdata); nuri_camera_init(); nuri_ehci_init(); - clk_xusbxti.rate = 24000000; /* Last */ platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices)); diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c index fa5c4a59b0aa..878d4c99142d 100644 --- a/arch/arm/mach-exynos/mach-origen.c +++ b/arch/arm/mach-exynos/mach-origen.c @@ -20,6 +20,7 @@ #include <linux/regulator/machine.h> #include <linux/mfd/max8997.h> #include <linux/lcd.h> +#include <linux/rfkill-gpio.h> #include <asm/mach/arch.h> #include <asm/hardware/gic.h> @@ -235,6 +236,7 @@ static struct regulator_init_data __initdata max8997_ldo9_data = { .min_uV = 2800000, .max_uV = 2800000, .apply_uV = 1, + .always_on = 1, .valid_ops_mask = REGULATOR_CHANGE_STATUS, .state_mem = { .disabled = 1, @@ -278,6 +280,7 @@ static struct regulator_init_data __initdata max8997_ldo14_data = { .min_uV = 1800000, .max_uV = 1800000, .apply_uV = 1, + .always_on = 1, .valid_ops_mask = REGULATOR_CHANGE_STATUS, .state_mem = { .disabled = 1, @@ -293,6 +296,7 @@ static struct regulator_init_data __initdata max8997_ldo17_data = { .min_uV = 3300000, .max_uV = 3300000, .apply_uV = 1, + .always_on = 1, .valid_ops_mask = REGULATOR_CHANGE_STATUS, .state_mem = { .disabled = 1, @@ -412,7 +416,7 @@ static struct max8997_regulator_data __initdata origen_max8997_regulators[] = { { MAX8997_BUCK7, &max8997_buck7_data }, }; -struct max8997_platform_data __initdata origen_max8997_pdata = { +static struct max8997_platform_data __initdata origen_max8997_pdata = { .num_regulators = ARRAY_SIZE(origen_max8997_regulators), .regulators = origen_max8997_regulators, @@ -602,6 +606,23 @@ static struct s3c_fb_platdata origen_lcd_pdata __initdata = { .setup_gpio = exynos4_fimd0_gpio_setup_24bpp, }; +/* Bluetooth rfkill gpio platform data */ +struct rfkill_gpio_platform_data origen_bt_pdata = { + .reset_gpio = EXYNOS4_GPX2(2), + .shutdown_gpio = -1, + .type = RFKILL_TYPE_BLUETOOTH, + .name = "origen-bt", +}; + +/* Bluetooth Platform device */ +static struct platform_device origen_device_bluetooth = { + .name = "rfkill_gpio", + .id = -1, + .dev = { + .platform_data = &origen_bt_pdata, + }, +}; + static struct platform_device *origen_devices[] __initdata = { &s3c_device_hsmmc2, &s3c_device_hsmmc0, @@ -613,9 +634,12 @@ static struct platform_device *origen_devices[] __initdata = { &s5p_device_fimc1, &s5p_device_fimc2, &s5p_device_fimc3, + &s5p_device_fimc_md, &s5p_device_fimd0, + &s5p_device_g2d, &s5p_device_hdmi, &s5p_device_i2c_hdmiphy, + &s5p_device_jpeg, &s5p_device_mfc, &s5p_device_mfc_l, &s5p_device_mfc_r, @@ -623,6 +647,7 @@ static struct platform_device *origen_devices[] __initdata = { &exynos4_device_ohci, &origen_device_gpiokeys, &origen_lcd_hv070wsa, + &origen_device_bluetooth, }; /* LCD Backlight data */ @@ -636,6 +661,16 @@ static struct platform_pwm_backlight_data origen_bl_data = { .pwm_period_ns = 1000, }; +static void __init origen_bt_setup(void) +{ + gpio_request(EXYNOS4_GPA0(0), "GPIO BT_UART"); + /* 4 UART Pins configuration */ + s3c_gpio_cfgrange_nopull(EXYNOS4_GPA0(0), 4, S3C_GPIO_SFN(2)); + /* Setup BT Reset, this gpio will be requesed by rfkill-gpio */ + s3c_gpio_cfgpin(EXYNOS4_GPX2(2), S3C_GPIO_OUTPUT); + s3c_gpio_setpull(EXYNOS4_GPX2(2), S3C_GPIO_PULL_NONE); +} + static void s5p_tv_setup(void) { /* Direct HPD to HDMI chip */ @@ -689,6 +724,8 @@ static void __init origen_machine_init(void) platform_add_devices(origen_devices, ARRAY_SIZE(origen_devices)); samsung_bl_set(&origen_bl_gpio_info, &origen_bl_data); + + origen_bt_setup(); } MACHINE_START(ORIGEN, "ORIGEN") diff --git a/arch/arm/mach-exynos/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c index 5258b8563676..83b91fa777c1 100644 --- a/arch/arm/mach-exynos/mach-smdkv310.c +++ b/arch/arm/mach-exynos/mach-smdkv310.c @@ -270,6 +270,9 @@ static struct platform_device *smdkv310_devices[] __initdata = { &s5p_device_fimc1, &s5p_device_fimc2, &s5p_device_fimc3, + &s5p_device_fimc_md, + &s5p_device_g2d, + &s5p_device_jpeg, &exynos4_device_ac97, &exynos4_device_i2s0, &exynos4_device_ohci, diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c index b2d495b31094..7ebf79c2ab34 100644 --- a/arch/arm/mach-exynos/mach-universal_c210.c +++ b/arch/arm/mach-exynos/mach-universal_c210.c @@ -29,6 +29,7 @@ #include <asm/mach-types.h> #include <plat/regs-serial.h> +#include <plat/clock.h> #include <plat/cpu.h> #include <plat/devs.h> #include <plat/iic.h> @@ -47,6 +48,7 @@ #include <media/v4l2-mediabus.h> #include <media/s5p_fimc.h> #include <media/m5mols.h> +#include <media/s5k6aa.h> #include "common.h" @@ -123,8 +125,10 @@ static struct regulator_consumer_supply lp3974_buck1_consumer = static struct regulator_consumer_supply lp3974_buck2_consumer = REGULATOR_SUPPLY("vddg3d", NULL); -static struct regulator_consumer_supply lp3974_buck3_consumer = - REGULATOR_SUPPLY("vdet", "s5p-sdo"); +static struct regulator_consumer_supply lp3974_buck3_consumer[] = { + REGULATOR_SUPPLY("vdet", "s5p-sdo"), + REGULATOR_SUPPLY("vdd_reg", "0-003c"), +}; static struct regulator_init_data lp3974_buck1_data = { .constraints = { @@ -169,8 +173,8 @@ static struct regulator_init_data lp3974_buck3_data = { .enabled = 1, }, }, - .num_consumer_supplies = 1, - .consumer_supplies = &lp3974_buck3_consumer, + .num_consumer_supplies = ARRAY_SIZE(lp3974_buck3_consumer), + .consumer_supplies = lp3974_buck3_consumer, }; static struct regulator_init_data lp3974_buck4_data = { @@ -303,6 +307,9 @@ static struct regulator_init_data lp3974_ldo8_data = { .consumer_supplies = lp3974_ldo8_consumer, }; +static struct regulator_consumer_supply lp3974_ldo9_consumer = + REGULATOR_SUPPLY("vddio", "0-003c"); + static struct regulator_init_data lp3974_ldo9_data = { .constraints = { .name = "VCC_2.8V", @@ -314,6 +321,8 @@ static struct regulator_init_data lp3974_ldo9_data = { .enabled = 1, }, }, + .num_consumer_supplies = 1, + .consumer_supplies = &lp3974_ldo9_consumer, }; static struct regulator_init_data lp3974_ldo10_data = { @@ -412,6 +421,7 @@ static struct regulator_init_data lp3974_ldo15_data = { }; static struct regulator_consumer_supply lp3974_ldo16_consumer[] = { + REGULATOR_SUPPLY("vdda", "0-003c"), REGULATOR_SUPPLY("a_sensor", "0-001f"), }; @@ -736,14 +746,13 @@ static struct platform_device universal_gpio_keys = { static struct s3c_sdhci_platdata universal_hsmmc0_data __initdata = { .max_width = 8, .host_caps = (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA | - MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | - MMC_CAP_DISABLE), + MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), .cd_type = S3C_SDHCI_CD_PERMANENT, .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, }; static struct regulator_consumer_supply mmc0_supplies[] = { - REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"), + REGULATOR_SUPPLY("vmmc", "exynos4-sdhci.0"), }; static struct regulator_init_data mmc0_fixed_voltage_init_data = { @@ -775,8 +784,7 @@ static struct platform_device mmc0_fixed_voltage = { static struct s3c_sdhci_platdata universal_hsmmc2_data __initdata = { .max_width = 4, .host_caps = MMC_CAP_4_BIT_DATA | - MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | - MMC_CAP_DISABLE, + MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, .ext_cd_gpio = EXYNOS4_GPX3(4), /* XEINT_28 */ .ext_cd_gpio_invert = 1, .cd_type = S3C_SDHCI_CD_GPIO, @@ -787,8 +795,7 @@ static struct s3c_sdhci_platdata universal_hsmmc2_data __initdata = { static struct s3c_sdhci_platdata universal_hsmmc3_data __initdata = { .max_width = 4, .host_caps = MMC_CAP_4_BIT_DATA | - MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | - MMC_CAP_DISABLE, + MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, .cd_type = S3C_SDHCI_CD_EXTERNAL, }; @@ -819,6 +826,8 @@ static struct s3c_fb_pd_win universal_fb_win0 = { }, .max_bpp = 32, .default_bpp = 16, + .virtual_x = 480, + .virtual_y = 2 * 800, }; static struct s3c_fb_platdata universal_lcd_pdata __initdata = { @@ -830,6 +839,28 @@ static struct s3c_fb_platdata universal_lcd_pdata __initdata = { .setup_gpio = exynos4_fimd0_gpio_setup_24bpp, }; +static struct regulator_consumer_supply cam_vt_dio_supply = + REGULATOR_SUPPLY("vdd_core", "0-003c"); + +static struct regulator_init_data cam_vt_dio_reg_init_data = { + .constraints = { .valid_ops_mask = REGULATOR_CHANGE_STATUS }, + .num_consumer_supplies = 1, + .consumer_supplies = &cam_vt_dio_supply, +}; + +static struct fixed_voltage_config cam_vt_dio_fixed_voltage_cfg = { + .supply_name = "CAM_VT_D_IO", + .microvolts = 2800000, + .gpio = EXYNOS4_GPE2(1), /* CAM_PWR_EN2 */ + .enable_high = 1, + .init_data = &cam_vt_dio_reg_init_data, +}; + +static struct platform_device cam_vt_dio_fixed_reg_dev = { + .name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_VT_DIO, + .dev = { .platform_data = &cam_vt_dio_fixed_voltage_cfg }, +}; + static struct regulator_consumer_supply cam_i_core_supply = REGULATOR_SUPPLY("core", "0-001f"); @@ -885,6 +916,28 @@ static struct s5p_platform_mipi_csis mipi_csis_platdata = { #define GPIO_CAM_LEVEL_EN(n) EXYNOS4_GPE4(n + 3) #define GPIO_CAM_8M_ISP_INT EXYNOS4_GPX1(5) /* XEINT_13 */ #define GPIO_CAM_MEGA_nRST EXYNOS4_GPE2(5) +#define GPIO_CAM_VGA_NRST EXYNOS4_GPE4(7) +#define GPIO_CAM_VGA_NSTBY EXYNOS4_GPE4(6) + +static int s5k6aa_set_power(int on) +{ + gpio_set_value(GPIO_CAM_LEVEL_EN(2), !!on); + return 0; +} + +static struct s5k6aa_platform_data s5k6aa_platdata = { + .mclk_frequency = 21600000UL, + .gpio_reset = { GPIO_CAM_VGA_NRST, 0 }, + .gpio_stby = { GPIO_CAM_VGA_NSTBY, 0 }, + .bus_type = V4L2_MBUS_PARALLEL, + .horiz_flip = 1, + .set_power = s5k6aa_set_power, +}; + +static struct i2c_board_info s5k6aa_board_info = { + I2C_BOARD_INFO("S5K6AA", 0x3C), + .platform_data = &s5k6aa_platdata, +}; static int m5mols_set_power(struct device *dev, int on) { @@ -909,6 +962,14 @@ static struct s5p_fimc_isp_info universal_camera_sensors[] = { .mux_id = 0, .flags = V4L2_MBUS_PCLK_SAMPLE_FALLING | V4L2_MBUS_VSYNC_ACTIVE_LOW, + .bus_type = FIMC_ITU_601, + .board_info = &s5k6aa_board_info, + .i2c_bus_num = 0, + .clk_frequency = 24000000UL, + }, { + .mux_id = 0, + .flags = V4L2_MBUS_PCLK_SAMPLE_FALLING | + V4L2_MBUS_VSYNC_ACTIVE_LOW, .bus_type = FIMC_MIPI_CSI2, .board_info = &m5mols_board_info, .i2c_bus_num = 0, @@ -927,9 +988,11 @@ static struct gpio universal_camera_gpios[] = { { GPIO_CAM_LEVEL_EN(2), GPIOF_OUT_INIT_LOW, "CAM_LVL_EN2" }, { GPIO_CAM_8M_ISP_INT, GPIOF_IN, "8M_ISP_INT" }, { GPIO_CAM_MEGA_nRST, GPIOF_OUT_INIT_LOW, "CAM_8M_NRST" }, + { GPIO_CAM_VGA_NRST, GPIOF_OUT_INIT_LOW, "CAM_VGA_NRST" }, + { GPIO_CAM_VGA_NSTBY, GPIOF_OUT_INIT_LOW, "CAM_VGA_NSTBY" }, }; -static void universal_camera_init(void) +static void __init universal_camera_init(void) { s3c_set_platdata(&mipi_csis_platdata, sizeof(mipi_csis_platdata), &s5p_device_mipi_csis0); @@ -950,6 +1013,8 @@ static void universal_camera_init(void) /* Free GPIOs controlled directly by the sensor drivers. */ gpio_free(GPIO_CAM_MEGA_nRST); gpio_free(GPIO_CAM_8M_ISP_INT); + gpio_free(GPIO_CAM_VGA_NRST); + gpio_free(GPIO_CAM_VGA_NSTBY); if (exynos4_fimc_setup_gpio(S5P_CAMPORT_A)) pr_err("Camera port A setup failed\n"); @@ -962,6 +1027,7 @@ static struct platform_device *universal_devices[] __initdata = { &s5p_device_fimc1, &s5p_device_fimc2, &s5p_device_fimc3, + &s5p_device_g2d, &mmc0_fixed_voltage, &s3c_device_hsmmc0, &s3c_device_hsmmc2, @@ -980,9 +1046,11 @@ static struct platform_device *universal_devices[] __initdata = { &universal_gpio_keys, &s5p_device_onenand, &s5p_device_fimd0, + &s5p_device_jpeg, &s5p_device_mfc, &s5p_device_mfc_l, &s5p_device_mfc_r, + &cam_vt_dio_fixed_reg_dev, &cam_i_core_fixed_reg_dev, &cam_s_if_fixed_reg_dev, &s5p_device_fimc_md, @@ -990,12 +1058,13 @@ static struct platform_device *universal_devices[] __initdata = { static void __init universal_map_io(void) { + clk_xusbxti.rate = 24000000; exynos_init_io(NULL, 0); s3c24xx_init_clocks(24000000); s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs)); } -void s5p_tv_setup(void) +static void s5p_tv_setup(void) { /* direct HPD to HDMI chip */ gpio_request_one(EXYNOS4_GPX3(7), GPIOF_IN, "hpd-plug"); diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c index 85b5527d0918..897d9a9cf226 100644 --- a/arch/arm/mach-exynos/mct.c +++ b/arch/arm/mach-exynos/mct.c @@ -21,6 +21,7 @@ #include <linux/percpu.h> #include <asm/hardware/gic.h> +#include <asm/localtimer.h> #include <plat/cpu.h> @@ -29,12 +30,13 @@ #include <mach/regs-mct.h> #include <asm/mach/time.h> +#define TICK_BASE_CNT 1 + enum { MCT_INT_SPI, MCT_INT_PPI }; -static unsigned long clk_cnt_per_tick; static unsigned long clk_rate; static unsigned int mct_int_type; @@ -205,11 +207,14 @@ static int exynos4_comp_set_next_event(unsigned long cycles, static void exynos4_comp_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { + unsigned long cycles_per_jiffy; exynos4_mct_comp0_stop(); switch (mode) { case CLOCK_EVT_MODE_PERIODIC: - exynos4_mct_comp0_start(mode, clk_cnt_per_tick); + cycles_per_jiffy = + (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift); + exynos4_mct_comp0_start(mode, cycles_per_jiffy); break; case CLOCK_EVT_MODE_ONESHOT: @@ -248,9 +253,7 @@ static struct irqaction mct_comp_event_irq = { static void exynos4_clockevent_init(void) { - clk_cnt_per_tick = clk_rate / 2 / HZ; - - clockevents_calc_mult_shift(&mct_comp_device, clk_rate / 2, 5); + clockevents_calc_mult_shift(&mct_comp_device, clk_rate, 5); mct_comp_device.max_delta_ns = clockevent_delta2ns(0xffffffff, &mct_comp_device); mct_comp_device.min_delta_ns = @@ -258,7 +261,10 @@ static void exynos4_clockevent_init(void) mct_comp_device.cpumask = cpumask_of(0); clockevents_register_device(&mct_comp_device); - setup_irq(IRQ_MCT_G0, &mct_comp_event_irq); + if (soc_is_exynos5250()) + setup_irq(EXYNOS5_IRQ_MCT_G0, &mct_comp_event_irq); + else + setup_irq(EXYNOS4_IRQ_MCT_G0, &mct_comp_event_irq); } #ifdef CONFIG_LOCAL_TIMERS @@ -314,12 +320,15 @@ static inline void exynos4_tick_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); + unsigned long cycles_per_jiffy; exynos4_mct_tick_stop(mevt); switch (mode) { case CLOCK_EVT_MODE_PERIODIC: - exynos4_mct_tick_start(clk_cnt_per_tick, mevt); + cycles_per_jiffy = + (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift); + exynos4_mct_tick_start(cycles_per_jiffy, mevt); break; case CLOCK_EVT_MODE_ONESHOT: @@ -375,7 +384,7 @@ static struct irqaction mct_tick1_event_irq = { .handler = exynos4_mct_tick_isr, }; -static void exynos4_mct_tick_init(struct clock_event_device *evt) +static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt) { struct mct_clock_event_device *mevt; unsigned int cpu = smp_processor_id(); @@ -393,7 +402,7 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt) evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; evt->rating = 450; - clockevents_calc_mult_shift(evt, clk_rate / 2, 5); + clockevents_calc_mult_shift(evt, clk_rate / (TICK_BASE_CNT + 1), 5); evt->max_delta_ns = clockevent_delta2ns(0x7fffffff, evt); evt->min_delta_ns = @@ -401,33 +410,27 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt) clockevents_register_device(evt); - exynos4_mct_write(0x1, mevt->base + MCT_L_TCNTB_OFFSET); + exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET); if (mct_int_type == MCT_INT_SPI) { if (cpu == 0) { mct_tick0_event_irq.dev_id = mevt; - evt->irq = IRQ_MCT_L0; - setup_irq(IRQ_MCT_L0, &mct_tick0_event_irq); + evt->irq = EXYNOS4_IRQ_MCT_L0; + setup_irq(EXYNOS4_IRQ_MCT_L0, &mct_tick0_event_irq); } else { mct_tick1_event_irq.dev_id = mevt; - evt->irq = IRQ_MCT_L1; - setup_irq(IRQ_MCT_L1, &mct_tick1_event_irq); - irq_set_affinity(IRQ_MCT_L1, cpumask_of(1)); + evt->irq = EXYNOS4_IRQ_MCT_L1; + setup_irq(EXYNOS4_IRQ_MCT_L1, &mct_tick1_event_irq); + irq_set_affinity(EXYNOS4_IRQ_MCT_L1, cpumask_of(1)); } } else { - enable_percpu_irq(IRQ_MCT_LOCALTIMER, 0); + enable_percpu_irq(EXYNOS_IRQ_MCT_LOCALTIMER, 0); } -} - -/* Setup the local clock events for a CPU */ -int __cpuinit local_timer_setup(struct clock_event_device *evt) -{ - exynos4_mct_tick_init(evt); return 0; } -void local_timer_stop(struct clock_event_device *evt) +static void exynos4_local_timer_stop(struct clock_event_device *evt) { unsigned int cpu = smp_processor_id(); evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); @@ -437,8 +440,13 @@ void local_timer_stop(struct clock_event_device *evt) else remove_irq(evt->irq, &mct_tick1_event_irq); else - disable_percpu_irq(IRQ_MCT_LOCALTIMER); + disable_percpu_irq(EXYNOS_IRQ_MCT_LOCALTIMER); } + +static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = { + .setup = exynos4_local_timer_setup, + .stop = exynos4_local_timer_stop, +}; #endif /* CONFIG_LOCAL_TIMERS */ static void __init exynos4_timer_resources(void) @@ -452,12 +460,14 @@ static void __init exynos4_timer_resources(void) if (mct_int_type == MCT_INT_PPI) { int err; - err = request_percpu_irq(IRQ_MCT_LOCALTIMER, + err = request_percpu_irq(EXYNOS_IRQ_MCT_LOCALTIMER, exynos4_mct_tick_isr, "MCT", &percpu_mct_tick); WARN(err, "MCT: can't request IRQ %d (%d)\n", - IRQ_MCT_LOCALTIMER, err); + EXYNOS_IRQ_MCT_LOCALTIMER, err); } + + local_timer_register(&exynos4_mct_tick_ops); #endif /* CONFIG_LOCAL_TIMERS */ } diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index 0f2035a1eb6e..36c3984aaa47 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c @@ -166,7 +166,10 @@ void __init smp_init_cpus(void) void __iomem *scu_base = scu_base_addr(); unsigned int i, ncores; - ncores = scu_base ? scu_get_core_count(scu_base) : 1; + if (soc_is_exynos5250()) + ncores = 2; + else + ncores = scu_base ? scu_get_core_count(scu_base) : 1; /* sanity check */ if (ncores > nr_cpu_ids) { @@ -183,8 +186,8 @@ void __init smp_init_cpus(void) void __init platform_smp_prepare_cpus(unsigned int max_cpus) { - - scu_enable(scu_base_addr()); + if (!soc_is_exynos5250()) + scu_enable(scu_base_addr()); /* * Write the address of secondary startup into the diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index e19013051772..428cfeb57724 100644 --- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c @@ -38,29 +38,29 @@ #include <mach/pmu.h> static struct sleep_save exynos4_set_clksrc[] = { - { .reg = S5P_CLKSRC_MASK_TOP , .val = 0x00000001, }, - { .reg = S5P_CLKSRC_MASK_CAM , .val = 0x11111111, }, - { .reg = S5P_CLKSRC_MASK_TV , .val = 0x00000111, }, - { .reg = S5P_CLKSRC_MASK_LCD0 , .val = 0x00001111, }, - { .reg = S5P_CLKSRC_MASK_MAUDIO , .val = 0x00000001, }, - { .reg = S5P_CLKSRC_MASK_FSYS , .val = 0x01011111, }, - { .reg = S5P_CLKSRC_MASK_PERIL0 , .val = 0x01111111, }, - { .reg = S5P_CLKSRC_MASK_PERIL1 , .val = 0x01110111, }, - { .reg = S5P_CLKSRC_MASK_DMC , .val = 0x00010000, }, + { .reg = EXYNOS4_CLKSRC_MASK_TOP , .val = 0x00000001, }, + { .reg = EXYNOS4_CLKSRC_MASK_CAM , .val = 0x11111111, }, + { .reg = EXYNOS4_CLKSRC_MASK_TV , .val = 0x00000111, }, + { .reg = EXYNOS4_CLKSRC_MASK_LCD0 , .val = 0x00001111, }, + { .reg = EXYNOS4_CLKSRC_MASK_MAUDIO , .val = 0x00000001, }, + { .reg = EXYNOS4_CLKSRC_MASK_FSYS , .val = 0x01011111, }, + { .reg = EXYNOS4_CLKSRC_MASK_PERIL0 , .val = 0x01111111, }, + { .reg = EXYNOS4_CLKSRC_MASK_PERIL1 , .val = 0x01110111, }, + { .reg = EXYNOS4_CLKSRC_MASK_DMC , .val = 0x00010000, }, }; static struct sleep_save exynos4210_set_clksrc[] = { - { .reg = S5P_CLKSRC_MASK_LCD1 , .val = 0x00001111, }, + { .reg = EXYNOS4210_CLKSRC_MASK_LCD1 , .val = 0x00001111, }, }; static struct sleep_save exynos4_epll_save[] = { - SAVE_ITEM(S5P_EPLL_CON0), - SAVE_ITEM(S5P_EPLL_CON1), + SAVE_ITEM(EXYNOS4_EPLL_CON0), + SAVE_ITEM(EXYNOS4_EPLL_CON1), }; static struct sleep_save exynos4_vpll_save[] = { - SAVE_ITEM(S5P_VPLL_CON0), - SAVE_ITEM(S5P_VPLL_CON1), + SAVE_ITEM(EXYNOS4_VPLL_CON0), + SAVE_ITEM(EXYNOS4_VPLL_CON1), }; static struct sleep_save exynos4_core_save[] = { @@ -155,13 +155,6 @@ static struct sleep_save exynos4_core_save[] = { SAVE_ITEM(S5P_SROM_BC3), }; -static struct sleep_save exynos4_l2cc_save[] = { - SAVE_ITEM(S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL), - SAVE_ITEM(S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL), - SAVE_ITEM(S5P_VA_L2CC + L2X0_PREFETCH_CTRL), - SAVE_ITEM(S5P_VA_L2CC + L2X0_POWER_CTRL), - SAVE_ITEM(S5P_VA_L2CC + L2X0_AUX_CTRL), -}; /* For Cortex-A9 Diagnostic and Power control register */ static unsigned int save_arm_register[2]; @@ -182,7 +175,6 @@ static void exynos4_pm_prepare(void) u32 tmp; s3c_pm_do_save(exynos4_core_save, ARRAY_SIZE(exynos4_core_save)); - s3c_pm_do_save(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save)); s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save)); s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save)); @@ -239,7 +231,7 @@ static void exynos4_restore_pll(void) locktime = (3000 / pll_in_rate) * p_div; lockcnt = locktime * 10000 / (10000 / pll_in_rate); - __raw_writel(lockcnt, S5P_EPLL_LOCK); + __raw_writel(lockcnt, EXYNOS4_EPLL_LOCK); s3c_pm_do_restore_core(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save)); @@ -257,7 +249,7 @@ static void exynos4_restore_pll(void) locktime = 750; lockcnt = locktime * 10000 / (10000 / pll_in_rate); - __raw_writel(lockcnt, S5P_VPLL_LOCK); + __raw_writel(lockcnt, EXYNOS4_VPLL_LOCK); s3c_pm_do_restore_core(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save)); @@ -268,14 +260,14 @@ static void exynos4_restore_pll(void) do { if (epll_wait) { - pll_con = __raw_readl(S5P_EPLL_CON0); - if (pll_con & (1 << S5P_EPLLCON0_LOCKED_SHIFT)) + pll_con = __raw_readl(EXYNOS4_EPLL_CON0); + if (pll_con & (1 << EXYNOS4_EPLLCON0_LOCKED_SHIFT)) epll_wait = 0; } if (vpll_wait) { - pll_con = __raw_readl(S5P_VPLL_CON0); - if (pll_con & (1 << S5P_VPLLCON0_LOCKED_SHIFT)) + pll_con = __raw_readl(EXYNOS4_VPLL_CON0); + if (pll_con & (1 << EXYNOS4_VPLLCON0_LOCKED_SHIFT)) vpll_wait = 0; } } while (epll_wait || vpll_wait); @@ -388,13 +380,6 @@ static void exynos4_pm_resume(void) scu_enable(S5P_VA_SCU); #endif -#ifdef CONFIG_CACHE_L2X0 - s3c_pm_do_restore_core(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save)); - outer_inv_all(); - /* enable L2X0*/ - writel_relaxed(1, S5P_VA_L2CC + L2X0_CTRL); -#endif - early_wakeup: return; } diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c index 0b04af2b13cc..13b306808b42 100644 --- a/arch/arm/mach-exynos/pm_domains.c +++ b/arch/arm/mach-exynos/pm_domains.c @@ -183,6 +183,12 @@ static __init int exynos4_pm_init_power_domain(void) #ifdef CONFIG_S5P_DEV_CSIS1 exynos_pm_add_dev_to_genpd(&s5p_device_mipi_csis1, &exynos4_pd_cam); #endif +#ifdef CONFIG_S5P_DEV_G2D + exynos_pm_add_dev_to_genpd(&s5p_device_g2d, &exynos4_pd_lcd0); +#endif +#ifdef CONFIG_S5P_DEV_JPEG + exynos_pm_add_dev_to_genpd(&s5p_device_jpeg, &exynos4_pd_cam); +#endif return 0; } arch_initcall(exynos4_pm_init_power_domain); diff --git a/arch/arm/mach-exynos/setup-i2c0.c b/arch/arm/mach-exynos/setup-i2c0.c index d395bd17c38b..b90d94c17f7c 100644 --- a/arch/arm/mach-exynos/setup-i2c0.c +++ b/arch/arm/mach-exynos/setup-i2c0.c @@ -1,7 +1,5 @@ /* - * linux/arch/arm/mach-exynos4/setup-i2c0.c - * - * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * Copyright (c) 2009-2012 Samsung Electronics Co., Ltd. * http://www.samsung.com/ * * I2C0 GPIO configuration. @@ -18,9 +16,14 @@ struct platform_device; /* don't need the contents */ #include <linux/gpio.h> #include <plat/iic.h> #include <plat/gpio-cfg.h> +#include <plat/cpu.h> void s3c_i2c0_cfg_gpio(struct platform_device *dev) { + if (soc_is_exynos5250()) + /* will be implemented with gpio function */ + return; + s3c_gpio_cfgall_range(EXYNOS4_GPD1(0), 2, S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); } diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c index 41978ee4f9d0..3e6aaa6361da 100644 --- a/arch/arm/mach-footbridge/common.c +++ b/arch/arm/mach-footbridge/common.c @@ -21,6 +21,7 @@ #include <asm/irq.h> #include <asm/mach-types.h> #include <asm/setup.h> +#include <asm/system_misc.h> #include <asm/hardware/dec21285.h> #include <asm/mach/irq.h> diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c index 121ad1d4fa39..3b54196447c7 100644 --- a/arch/arm/mach-footbridge/dc21285-timer.c +++ b/arch/arm/mach-footbridge/dc21285-timer.c @@ -14,6 +14,7 @@ #include <asm/hardware/dec21285.h> #include <asm/mach/time.h> +#include <asm/system_info.h> #include "common.h" diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c index f685650c25d7..e17e11de4f5e 100644 --- a/arch/arm/mach-footbridge/dc21285.c +++ b/arch/arm/mach-footbridge/dc21285.c @@ -21,7 +21,6 @@ #include <video/vga.h> #include <asm/irq.h> -#include <asm/system.h> #include <asm/mach/pci.h> #include <asm/hardware/dec21285.h> @@ -275,11 +274,13 @@ int __init dc21285_setup(int nr, struct pci_sys_data *sys) allocate_resource(&iomem_resource, &res[0], 0x40000000, 0x80000000, 0xffffffff, 0x40000000, NULL, NULL); - pci_add_resource(&sys->resources, &ioport_resource); - pci_add_resource(&sys->resources, &res[0]); - pci_add_resource(&sys->resources, &res[1]); sys->mem_offset = DC21285_PCI_MEM; + pci_add_resource_offset(&sys->resources, + &ioport_resource, sys->io_offset); + pci_add_resource_offset(&sys->resources, &res[0], sys->mem_offset); + pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset); + return 1; } diff --git a/arch/arm/mach-footbridge/ebsa285-leds.c b/arch/arm/mach-footbridge/ebsa285-leds.c index 4e10090cd87f..5bd266754b95 100644 --- a/arch/arm/mach-footbridge/ebsa285-leds.c +++ b/arch/arm/mach-footbridge/ebsa285-leds.c @@ -24,7 +24,6 @@ #include <mach/hardware.h> #include <asm/leds.h> #include <asm/mach-types.h> -#include <asm/system.h> #define LED_STATE_ENABLED 1 #define LED_STATE_CLAIMED 2 diff --git a/arch/arm/mach-footbridge/include/mach/entry-macro.S b/arch/arm/mach-footbridge/include/mach/entry-macro.S index d3847be0c667..dabbd5c54a78 100644 --- a/arch/arm/mach-footbridge/include/mach/entry-macro.S +++ b/arch/arm/mach-footbridge/include/mach/entry-macro.S @@ -14,9 +14,6 @@ .equ dc21285_high, ARMCSR_BASE & 0xff000000 .equ dc21285_low, ARMCSR_BASE & 0x00ffffff - .macro disable_fiq - .endm - .macro get_irqnr_preamble, base, tmp mov \base, #dc21285_high .if dc21285_low @@ -24,9 +21,6 @@ .endif .endm - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \irqstat, [\base, #0x180] @ get interrupts diff --git a/arch/arm/mach-footbridge/include/mach/io.h b/arch/arm/mach-footbridge/include/mach/io.h index 15a70396c27d..aba531eebbc6 100644 --- a/arch/arm/mach-footbridge/include/mach/io.h +++ b/arch/arm/mach-footbridge/include/mach/io.h @@ -27,18 +27,5 @@ * Translation of various region addresses to virtual addresses */ #define __io(a) ((void __iomem *)(PCIO_BASE + (a))) -#if 1 -#define __mem_pci(a) (a) -#else - -static inline void __iomem *___mem_pci(void __iomem *p) -{ - unsigned long a = (unsigned long)p; - BUG_ON(a <= 0xc0000000 || a >= 0xe0000000); - return p; -} - -#define __mem_pci(a) ___mem_pci(a) -#endif #endif diff --git a/arch/arm/mach-footbridge/include/mach/system.h b/arch/arm/mach-footbridge/include/mach/system.h deleted file mode 100644 index a174a5841bc2..000000000000 --- a/arch/arm/mach-footbridge/include/mach/system.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/arm/mach-footbridge/include/mach/system.h - * - * Copyright (C) 1996-1999 Russell King. - * - * 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. - */ -static inline void arch_idle(void) -{ - cpu_do_idle(); -} diff --git a/arch/arm/mach-footbridge/netwinder-hw.c b/arch/arm/mach-footbridge/netwinder-hw.c index 80a1c5cc9071..cac9f67e7da7 100644 --- a/arch/arm/mach-footbridge/netwinder-hw.c +++ b/arch/arm/mach-footbridge/netwinder-hw.c @@ -17,6 +17,7 @@ #include <asm/leds.h> #include <asm/mach-types.h> #include <asm/setup.h> +#include <asm/system_misc.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-footbridge/netwinder-leds.c b/arch/arm/mach-footbridge/netwinder-leds.c index e57102e871fc..5a2bd89cbdca 100644 --- a/arch/arm/mach-footbridge/netwinder-leds.c +++ b/arch/arm/mach-footbridge/netwinder-leds.c @@ -24,7 +24,6 @@ #include <mach/hardware.h> #include <asm/leds.h> #include <asm/mach-types.h> -#include <asm/system.h> #define LED_STATE_ENABLED 1 #define LED_STATE_CLAIMED 2 diff --git a/arch/arm/mach-gemini/Makefile b/arch/arm/mach-gemini/Makefile index c5b24b95a76e..7355c0bbcb5e 100644 --- a/arch/arm/mach-gemini/Makefile +++ b/arch/arm/mach-gemini/Makefile @@ -4,7 +4,7 @@ # Object file lists. -obj-y := irq.o mm.o time.o devices.o gpio.o +obj-y := irq.o mm.o time.o devices.o gpio.o idle.o # Board-specific support obj-$(CONFIG_MACH_NAS4220B) += board-nas4220b.o diff --git a/arch/arm/mach-gemini/idle.c b/arch/arm/mach-gemini/idle.c new file mode 100644 index 000000000000..92bbd6bb600a --- /dev/null +++ b/arch/arm/mach-gemini/idle.c @@ -0,0 +1,29 @@ +/* + * arch/arm/mach-gemini/idle.c + */ + +#include <linux/init.h> +#include <asm/system.h> +#include <asm/proc-fns.h> + +static void gemini_idle(void) +{ + /* + * Because of broken hardware we have to enable interrupts or the CPU + * will never wakeup... Acctualy it is not very good to enable + * interrupts first since scheduler can miss a tick, but there is + * no other way around this. Platforms that needs it for power saving + * should call enable_hlt() in init code, since by default it is + * disabled. + */ + local_irq_enable(); + cpu_do_idle(); +} + +static int __init gemini_idle_init(void) +{ + arm_pm_idle = gemini_idle; + return 0; +} + +arch_initcall(gemini_idle_init); diff --git a/arch/arm/mach-gemini/include/mach/entry-macro.S b/arch/arm/mach-gemini/include/mach/entry-macro.S index 1624f91a2b8b..f044e430bfa4 100644 --- a/arch/arm/mach-gemini/include/mach/entry-macro.S +++ b/arch/arm/mach-gemini/include/mach/entry-macro.S @@ -12,15 +12,9 @@ #define IRQ_STATUS 0x14 - .macro disable_fiq - .endm - .macro get_irqnr_preamble, base, tmp .endm - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \irqstat, =IO_ADDRESS(GEMINI_INTERRUPT_BASE + IRQ_STATUS) ldr \irqnr, [\irqstat] diff --git a/arch/arm/mach-gemini/include/mach/io.h b/arch/arm/mach-gemini/include/mach/io.h deleted file mode 100644 index c548056b98b2..000000000000 --- a/arch/arm/mach-gemini/include/mach/io.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (C) 2001-2006 Storlink, Corp. - * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> - * - * 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. - */ -#ifndef __MACH_IO_H -#define __MACH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#endif /* __MACH_IO_H */ diff --git a/arch/arm/mach-gemini/include/mach/system.h b/arch/arm/mach-gemini/include/mach/system.h index 4d9c1f872472..a33b5a1f8ab4 100644 --- a/arch/arm/mach-gemini/include/mach/system.h +++ b/arch/arm/mach-gemini/include/mach/system.h @@ -14,20 +14,6 @@ #include <mach/hardware.h> #include <mach/global_reg.h> -static inline void arch_idle(void) -{ - /* - * Because of broken hardware we have to enable interrupts or the CPU - * will never wakeup... Acctualy it is not very good to enable - * interrupts here since scheduler can miss a tick, but there is - * no other way around this. Platforms that needs it for power saving - * should call enable_hlt() in init code, since by default it is - * disabled. - */ - local_irq_enable(); - cpu_do_idle(); -} - static inline void arch_reset(char mode, const char *cmd) { __raw_writel(RESET_GLOBAL | RESET_CPU1, diff --git a/arch/arm/mach-gemini/irq.c b/arch/arm/mach-gemini/irq.c index 9485a8fdf851..ca70e5fcc7ac 100644 --- a/arch/arm/mach-gemini/irq.c +++ b/arch/arm/mach-gemini/irq.c @@ -73,8 +73,8 @@ void __init gemini_init_irq(void) unsigned int i, mode = 0, level = 0; /* - * Disable arch_idle() by default since it is buggy - * For more info see arch/arm/mach-gemini/include/mach/system.h + * Disable the idle handler by default since it is buggy + * For more info see arch/arm/mach-gemini/idle.c */ disable_hlt(); diff --git a/arch/arm/mach-h720x/common.c b/arch/arm/mach-h720x/common.c index f8a2f6bb5483..aa1331e86bcf 100644 --- a/arch/arm/mach-h720x/common.c +++ b/arch/arm/mach-h720x/common.c @@ -24,6 +24,7 @@ #include <asm/dma.h> #include <mach/hardware.h> #include <asm/irq.h> +#include <asm/system_misc.h> #include <asm/mach/irq.h> #include <asm/mach/map.h> #include <mach/irqs.h> @@ -247,3 +248,21 @@ void h720x_restart(char mode, const char *cmd) { CPU_REG (PMU_BASE, PMU_STAT) |= PMU_WARMRESET; } + +static void h720x__idle(void) +{ + CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_IDLE; + nop(); + nop(); + CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_RUN; + nop(); + nop(); +} + +static int __init h720x_idle_init(void) +{ + arm_pm_idle = h720x__idle; + return 0; +} + +arch_initcall(h720x_idle_init); diff --git a/arch/arm/mach-h720x/include/mach/entry-macro.S b/arch/arm/mach-h720x/include/mach/entry-macro.S index c3948e5ba4a0..75267fad7012 100644 --- a/arch/arm/mach-h720x/include/mach/entry-macro.S +++ b/arch/arm/mach-h720x/include/mach/entry-macro.S @@ -8,15 +8,9 @@ * warranty of any kind, whether express or implied. */ - .macro disable_fiq - .endm - .macro get_irqnr_preamble, base, tmp .endm - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp #if defined (CONFIG_CPU_H7201) || defined (CONFIG_CPU_H7202) @ we could use the id register on H7202, but this is not diff --git a/arch/arm/mach-h720x/include/mach/io.h b/arch/arm/mach-h720x/include/mach/io.h deleted file mode 100644 index 2c8659c21a93..000000000000 --- a/arch/arm/mach-h720x/include/mach/io.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * arch/arm/mach-h720x/include/mach/io.h - * - * Copyright (C) 2000 Steve Hill (sjhill@cotw.com) - * - * Changelog: - * - * 09-19-2001 JJKIM - * Created from arch/arm/mach-l7200/include/mach/io.h - * - * 03-27-2003 Robert Schwebel <r.schwebel@pengutronix.de>: - * re-unified header files for h720x - */ -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#endif diff --git a/arch/arm/mach-h720x/include/mach/system.h b/arch/arm/mach-h720x/include/mach/system.h deleted file mode 100644 index 16ac46e239aa..000000000000 --- a/arch/arm/mach-h720x/include/mach/system.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * arch/arm/mach-h720x/include/mach/system.h - * - * Copyright (C) 2001-2002 Jungjun Kim, Hynix Semiconductor Inc. - * - * 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. - * arch/arm/mach-h720x/include/mach/system.h - * - */ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H -#include <mach/hardware.h> - -static void arch_idle(void) -{ - CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_IDLE; - nop(); - nop(); - CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_RUN; - nop(); - nop(); -} - -#endif diff --git a/arch/arm/mach-highbank/Makefile b/arch/arm/mach-highbank/Makefile index 986958a5a720..f8437dd238c2 100644 --- a/arch/arm/mach-highbank/Makefile +++ b/arch/arm/mach-highbank/Makefile @@ -1,6 +1,5 @@ obj-y := clock.o highbank.o system.o obj-$(CONFIG_DEBUG_HIGHBANK_UART) += lluart.o obj-$(CONFIG_SMP) += platsmp.o -obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o obj-$(CONFIG_PM_SLEEP) += pm.o diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c index 8394d512a402..410a112bb52e 100644 --- a/arch/arm/mach-highbank/highbank.c +++ b/arch/arm/mach-highbank/highbank.c @@ -27,6 +27,7 @@ #include <asm/cacheflush.h> #include <asm/smp_plat.h> #include <asm/smp_scu.h> +#include <asm/smp_twd.h> #include <asm/hardware/arm_timer.h> #include <asm/hardware/timer-sp.h> #include <asm/hardware/gic.h> @@ -34,7 +35,6 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/time.h> -#include <mach/irqs.h> #include "core.h" #include "sysregs.h" @@ -109,8 +109,10 @@ static void __init highbank_timer_init(void) highbank_clocks_init(); - sp804_clocksource_init(timer_base + 0x20, "timer1"); + sp804_clocksource_and_sched_clock_init(timer_base + 0x20, "timer1"); sp804_clockevents_init(timer_base, irq, "timer0"); + + twd_local_timer_of_register(); } static struct sys_timer highbank_timer = { diff --git a/arch/arm/mach-highbank/include/mach/entry-macro.S b/arch/arm/mach-highbank/include/mach/entry-macro.S deleted file mode 100644 index a14f9e62ca92..000000000000 --- a/arch/arm/mach-highbank/include/mach/entry-macro.S +++ /dev/null @@ -1,5 +0,0 @@ - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-highbank/include/mach/io.h b/arch/arm/mach-highbank/include/mach/io.h deleted file mode 100644 index 70cfa3ba7697..000000000000 --- a/arch/arm/mach-highbank/include/mach/io.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __MACH_IO_H -#define __MACH_IO_H - -#define __io(a) ({ (void)(a); __typesafe_io(0); }) -#define __mem_pci(a) (a) - -#endif diff --git a/arch/arm/mach-highbank/include/mach/irqs.h b/arch/arm/mach-highbank/include/mach/irqs.h deleted file mode 100644 index 9746aab14e9a..000000000000 --- a/arch/arm/mach-highbank/include/mach/irqs.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __MACH_IRQS_H -#define __MACH_IRQS_H - -#define NR_IRQS 192 - -#endif diff --git a/arch/arm/mach-highbank/include/mach/memory.h b/arch/arm/mach-highbank/include/mach/memory.h deleted file mode 100644 index 40a8c178f10d..000000000000 --- a/arch/arm/mach-highbank/include/mach/memory.h +++ /dev/null @@ -1 +0,0 @@ -/* empty */ diff --git a/arch/arm/mach-highbank/localtimer.c b/arch/arm/mach-highbank/localtimer.c deleted file mode 100644 index 5a00e7945fdf..000000000000 --- a/arch/arm/mach-highbank/localtimer.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2010-2011 Calxeda, Inc. - * Based on localtimer.c, Copyright (C) 2002 ARM Ltd. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. - */ -#include <linux/init.h> -#include <linux/clockchips.h> -#include <linux/of.h> -#include <linux/of_address.h> -#include <linux/of_irq.h> - -#include <asm/smp_twd.h> - -/* - * Setup the local clock events for a CPU. - */ -int __cpuinit local_timer_setup(struct clock_event_device *evt) -{ - struct device_node *np; - - np = of_find_compatible_node(NULL, NULL, "arm,smp-twd"); - if (!twd_base) { - twd_base = of_iomap(np, 0); - WARN_ON(!twd_base); - } - evt->irq = irq_of_parse_and_map(np, 0); - twd_timer_setup(evt); - return 0; -} diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 3919fba52ac8..7561eca131b0 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -1,6 +1,3 @@ -config IMX_HAVE_DMA_V1 - bool - config HAVE_IMX_GPC bool @@ -38,7 +35,6 @@ config SOC_IMX1 bool select ARCH_MX1 select CPU_ARM920T - select IMX_HAVE_DMA_V1 select IMX_HAVE_IOMUX_V1 select MXC_AVIC @@ -46,7 +42,6 @@ config SOC_IMX21 bool select MACH_MX21 select CPU_ARM926T - select IMX_HAVE_DMA_V1 select IMX_HAVE_IOMUX_V1 select MXC_AVIC @@ -61,7 +56,6 @@ config SOC_IMX27 bool select MACH_MX27 select CPU_ARM926T - select IMX_HAVE_DMA_V1 select IMX_HAVE_IOMUX_V1 select MXC_AVIC @@ -298,6 +292,7 @@ config MACH_MX27_3DS select IMX_HAVE_PLATFORM_IMX_I2C select IMX_HAVE_PLATFORM_IMX_KEYPAD select IMX_HAVE_PLATFORM_IMX_UART + select IMX_HAVE_PLATFORM_MX2_CAMERA select IMX_HAVE_PLATFORM_MXC_EHCI select IMX_HAVE_PLATFORM_MXC_MMC select IMX_HAVE_PLATFORM_SPI_IMX @@ -314,8 +309,10 @@ config MACH_IMX27_VISSTRIM_M10 select IMX_HAVE_PLATFORM_IMX_I2C select IMX_HAVE_PLATFORM_IMX_SSI select IMX_HAVE_PLATFORM_IMX_UART - select IMX_HAVE_PLATFORM_MXC_MMC + select IMX_HAVE_PLATFORM_MX2_CAMERA select IMX_HAVE_PLATFORM_MXC_EHCI + select IMX_HAVE_PLATFORM_MXC_MMC + select LEDS_GPIO_REGISTER help Include support for Visstrim_m10 platform and its different variants. This includes specific configurations for the board and its @@ -370,6 +367,14 @@ config MACH_IMX27IPCAM Include support for IMX27 IPCAM platform. This includes specific configurations for the board and its peripherals. +config MACH_IMX27_DT + bool "Support i.MX27 platforms from device tree" + select SOC_IMX27 + select USE_OF + help + Include support for Freescale i.MX27 based platforms + using the device tree for discovery + endif if ARCH_IMX_V6_V7 @@ -486,6 +491,7 @@ config MACH_MX31MOBOARD bool "Support mx31moboard platforms (EPFL Mobots group)" select SOC_IMX31 select IMX_HAVE_PLATFORM_FSL_USB2_UDC + select IMX_HAVE_PLATFORM_IMX2_WDT select IMX_HAVE_PLATFORM_IMX_I2C select IMX_HAVE_PLATFORM_IMX_UART select IMX_HAVE_PLATFORM_IPU_CORE diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 55db9c488f2b..ab939c5046c3 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -1,5 +1,3 @@ -obj-$(CONFIG_IMX_HAVE_DMA_V1) += dma-v1.o - obj-$(CONFIG_SOC_IMX1) += clock-imx1.o mm-imx1.o obj-$(CONFIG_SOC_IMX21) += clock-imx21.o mm-imx21.o @@ -8,8 +6,8 @@ obj-$(CONFIG_SOC_IMX25) += clock-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o obj-$(CONFIG_SOC_IMX27) += clock-imx27.o mm-imx27.o ehci-imx27.o -obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clock-imx31.o iomux-imx31.o ehci-imx31.o -obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o +obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clock-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o +obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o pm-imx3.o obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clock-mx51-mx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o @@ -41,6 +39,7 @@ obj-$(CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD) += eukrea_mbimx27-baseboard.o obj-$(CONFIG_MACH_PCA100) += mach-pca100.o obj-$(CONFIG_MACH_MXT_TD60) += mach-mxt_td60.o obj-$(CONFIG_MACH_IMX27IPCAM) += mach-imx27ipcam.o +obj-$(CONFIG_MACH_IMX27_DT) += imx27-dt.o # i.MX31 based machines obj-$(CONFIG_MACH_MX31ADS) += mach-mx31ads.o @@ -71,7 +70,6 @@ obj-$(CONFIG_CPU_V7) += head-v7.o AFLAGS_head-v7.o :=-Wa,-march=armv7-a obj-$(CONFIG_SMP) += platsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o -obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o mach-imx6q.o ifeq ($(CONFIG_PM),y) diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot index 6dfdbcc83afd..3851d8a27875 100644 --- a/arch/arm/mach-imx/Makefile.boot +++ b/arch/arm/mach-imx/Makefile.boot @@ -38,5 +38,8 @@ zreladdr-$(CONFIG_SOC_IMX6Q) += 0x10008000 params_phys-$(CONFIG_SOC_IMX6Q) := 0x10000100 initrd_phys-$(CONFIG_SOC_IMX6Q) := 0x10800000 +dtb-$(CONFIG_MACH_IMX51_DT) += imx51-babbage.dtb +dtb-$(CONFIG_MACH_IMX53_DT) += imx53-ard.dtb imx53-evk.dtb \ + imx53-qsb.dtb imx53-smd.dtb dtb-$(CONFIG_SOC_IMX6Q) += imx6q-arm2.dtb \ imx6q-sabrelite.dtb diff --git a/arch/arm/mach-imx/clock-imx27.c b/arch/arm/mach-imx/clock-imx27.c index dc2d7a511d9b..98e04f5a87dd 100644 --- a/arch/arm/mach-imx/clock-imx27.c +++ b/arch/arm/mach-imx/clock-imx27.c @@ -22,6 +22,7 @@ #include <linux/io.h> #include <linux/module.h> #include <linux/clkdev.h> +#include <linux/of.h> #include <asm/div64.h> @@ -661,6 +662,7 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK(NULL, "dma", dma_clk) _REGISTER_CLOCK(NULL, "rtic", rtic_clk) _REGISTER_CLOCK(NULL, "brom", brom_clk) + _REGISTER_CLOCK(NULL, "emma", emma_clk) _REGISTER_CLOCK("m2m-emmaprp.0", NULL, emma_clk) _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk) _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk) @@ -764,3 +766,20 @@ int __init mx27_clocks_init(unsigned long fref) return 0; } +#ifdef CONFIG_OF +int __init mx27_clocks_init_dt(void) +{ + struct device_node *np; + u32 fref = 26000000; /* default */ + + for_each_compatible_node(np, NULL, "fixed-clock") { + if (!of_device_is_compatible(np, "fsl,imx-osc26m")) + continue; + + if (!of_property_read_u32(np, "clock-frequency", &fref)) + break; + } + + return mx27_clocks_init(fref); +} +#endif diff --git a/arch/arm/mach-imx/clock-imx31.c b/arch/arm/mach-imx/clock-imx31.c index 988a28178d4c..3a943cd4159f 100644 --- a/arch/arm/mach-imx/clock-imx31.c +++ b/arch/arm/mach-imx/clock-imx31.c @@ -32,7 +32,7 @@ #include <mach/mx31.h> #include <mach/common.h> -#include "crmregs-imx31.h" +#include "crmregs-imx3.h" #define PRE_DIV_MIN_FREQ 10000000 /* Minimum Frequency after Predivider */ diff --git a/arch/arm/mach-imx/clock-imx35.c b/arch/arm/mach-imx/clock-imx35.c index ac8238caecb9..e56c1a83eee3 100644 --- a/arch/arm/mach-imx/clock-imx35.c +++ b/arch/arm/mach-imx/clock-imx35.c @@ -27,23 +27,7 @@ #include <mach/hardware.h> #include <mach/common.h> -#define CCM_BASE MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR) - -#define CCM_CCMR 0x00 -#define CCM_PDR0 0x04 -#define CCM_PDR1 0x08 -#define CCM_PDR2 0x0C -#define CCM_PDR3 0x10 -#define CCM_PDR4 0x14 -#define CCM_RCSR 0x18 -#define CCM_MPCTL 0x1C -#define CCM_PPCTL 0x20 -#define CCM_ACMR 0x24 -#define CCM_COSR 0x28 -#define CCM_CGR0 0x2C -#define CCM_CGR1 0x30 -#define CCM_CGR2 0x34 -#define CCM_CGR3 0x38 +#include "crmregs-imx3.h" #ifdef HAVE_SET_RATE_SUPPORT static void calc_dividers(u32 div, u32 *pre, u32 *post, u32 maxpost) @@ -111,14 +95,14 @@ static void calc_dividers_3_3(u32 div, u32 *pre, u32 *post) static unsigned long get_rate_mpll(void) { - ulong mpctl = __raw_readl(CCM_BASE + CCM_MPCTL); + ulong mpctl = __raw_readl(MX35_CCM_MPCTL); return mxc_decode_pll(mpctl, 24000000); } static unsigned long get_rate_ppll(void) { - ulong ppctl = __raw_readl(CCM_BASE + CCM_PPCTL); + ulong ppctl = __raw_readl(MX35_CCM_PPCTL); return mxc_decode_pll(ppctl, 24000000); } @@ -148,7 +132,7 @@ static struct arm_ahb_div clk_consumer[] = { static unsigned long get_rate_arm(void) { - unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0); + unsigned long pdr0 = __raw_readl(MXC_CCM_PDR0); struct arm_ahb_div *aad; unsigned long fref = get_rate_mpll(); @@ -161,7 +145,7 @@ static unsigned long get_rate_arm(void) static unsigned long get_rate_ahb(struct clk *clk) { - unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0); + unsigned long pdr0 = __raw_readl(MXC_CCM_PDR0); struct arm_ahb_div *aad; unsigned long fref = get_rate_arm(); @@ -177,8 +161,8 @@ static unsigned long get_rate_ipg(struct clk *clk) static unsigned long get_rate_uart(struct clk *clk) { - unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3); - unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4); + unsigned long pdr3 = __raw_readl(MX35_CCM_PDR3); + unsigned long pdr4 = __raw_readl(MX35_CCM_PDR4); unsigned long div = ((pdr4 >> 10) & 0x3f) + 1; if (pdr3 & (1 << 14)) @@ -189,7 +173,7 @@ static unsigned long get_rate_uart(struct clk *clk) static unsigned long get_rate_sdhc(struct clk *clk) { - unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3); + unsigned long pdr3 = __raw_readl(MX35_CCM_PDR3); unsigned long div, rate; if (pdr3 & (1 << 6)) @@ -215,7 +199,7 @@ static unsigned long get_rate_sdhc(struct clk *clk) static unsigned long get_rate_mshc(struct clk *clk) { - unsigned long pdr1 = __raw_readl(CCM_BASE + CCM_PDR1); + unsigned long pdr1 = __raw_readl(MXC_CCM_PDR1); unsigned long div1, div2, rate; if (pdr1 & (1 << 7)) @@ -231,7 +215,7 @@ static unsigned long get_rate_mshc(struct clk *clk) static unsigned long get_rate_ssi(struct clk *clk) { - unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2); + unsigned long pdr2 = __raw_readl(MX35_CCM_PDR2); unsigned long div1, div2, rate; if (pdr2 & (1 << 6)) @@ -256,7 +240,7 @@ static unsigned long get_rate_ssi(struct clk *clk) static unsigned long get_rate_csi(struct clk *clk) { - unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2); + unsigned long pdr2 = __raw_readl(MX35_CCM_PDR2); unsigned long rate; if (pdr2 & (1 << 7)) @@ -269,7 +253,7 @@ static unsigned long get_rate_csi(struct clk *clk) static unsigned long get_rate_otg(struct clk *clk) { - unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4); + unsigned long pdr4 = __raw_readl(MX35_CCM_PDR4); unsigned long rate; if (pdr4 & (1 << 9)) @@ -282,8 +266,8 @@ static unsigned long get_rate_otg(struct clk *clk) static unsigned long get_rate_ipg_per(struct clk *clk) { - unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0); - unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4); + unsigned long pdr0 = __raw_readl(MXC_CCM_PDR0); + unsigned long pdr4 = __raw_readl(MX35_CCM_PDR4); unsigned long div; if (pdr0 & (1 << 26)) { @@ -297,7 +281,7 @@ static unsigned long get_rate_ipg_per(struct clk *clk) static unsigned long get_rate_hsp(struct clk *clk) { - unsigned long hsp_podf = (__raw_readl(CCM_BASE + CCM_PDR0) >> 20) & 0x03; + unsigned long hsp_podf = (__raw_readl(MXC_CCM_PDR0) >> 20) & 0x03; unsigned long fref = get_rate_mpll(); if (fref > 400 * 1000 * 1000) { @@ -345,7 +329,7 @@ static void clk_cgr_disable(struct clk *clk) #define DEFINE_CLOCK(name, i, er, es, gr, sr) \ static struct clk name = { \ .id = i, \ - .enable_reg = CCM_BASE + er, \ + .enable_reg = er, \ .enable_shift = es, \ .get_rate = gr, \ .set_rate = sr, \ @@ -353,59 +337,59 @@ static void clk_cgr_disable(struct clk *clk) .disable = clk_cgr_disable, \ } -DEFINE_CLOCK(asrc_clk, 0, CCM_CGR0, 0, NULL, NULL); -DEFINE_CLOCK(pata_clk, 0, CCM_CGR0, 2, get_rate_ipg, NULL); -/* DEFINE_CLOCK(audmux_clk, 0, CCM_CGR0, 4, NULL, NULL); */ -DEFINE_CLOCK(can1_clk, 0, CCM_CGR0, 6, get_rate_ipg, NULL); -DEFINE_CLOCK(can2_clk, 1, CCM_CGR0, 8, get_rate_ipg, NULL); -DEFINE_CLOCK(cspi1_clk, 0, CCM_CGR0, 10, get_rate_ipg, NULL); -DEFINE_CLOCK(cspi2_clk, 1, CCM_CGR0, 12, get_rate_ipg, NULL); -DEFINE_CLOCK(ect_clk, 0, CCM_CGR0, 14, get_rate_ipg, NULL); -DEFINE_CLOCK(edio_clk, 0, CCM_CGR0, 16, NULL, NULL); -DEFINE_CLOCK(emi_clk, 0, CCM_CGR0, 18, get_rate_ipg, NULL); -DEFINE_CLOCK(epit1_clk, 0, CCM_CGR0, 20, get_rate_ipg, NULL); -DEFINE_CLOCK(epit2_clk, 1, CCM_CGR0, 22, get_rate_ipg, NULL); -DEFINE_CLOCK(esai_clk, 0, CCM_CGR0, 24, NULL, NULL); -DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGR0, 26, get_rate_sdhc, NULL); -DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGR0, 28, get_rate_sdhc, NULL); -DEFINE_CLOCK(esdhc3_clk, 2, CCM_CGR0, 30, get_rate_sdhc, NULL); - -DEFINE_CLOCK(fec_clk, 0, CCM_CGR1, 0, get_rate_ipg, NULL); -DEFINE_CLOCK(gpio1_clk, 0, CCM_CGR1, 2, NULL, NULL); -DEFINE_CLOCK(gpio2_clk, 1, CCM_CGR1, 4, NULL, NULL); -DEFINE_CLOCK(gpio3_clk, 2, CCM_CGR1, 6, NULL, NULL); -DEFINE_CLOCK(gpt_clk, 0, CCM_CGR1, 8, get_rate_ipg, NULL); -DEFINE_CLOCK(i2c1_clk, 0, CCM_CGR1, 10, get_rate_ipg_per, NULL); -DEFINE_CLOCK(i2c2_clk, 1, CCM_CGR1, 12, get_rate_ipg_per, NULL); -DEFINE_CLOCK(i2c3_clk, 2, CCM_CGR1, 14, get_rate_ipg_per, NULL); -DEFINE_CLOCK(iomuxc_clk, 0, CCM_CGR1, 16, NULL, NULL); -DEFINE_CLOCK(ipu_clk, 0, CCM_CGR1, 18, get_rate_hsp, NULL); -DEFINE_CLOCK(kpp_clk, 0, CCM_CGR1, 20, get_rate_ipg, NULL); -DEFINE_CLOCK(mlb_clk, 0, CCM_CGR1, 22, get_rate_ahb, NULL); -DEFINE_CLOCK(mshc_clk, 0, CCM_CGR1, 24, get_rate_mshc, NULL); -DEFINE_CLOCK(owire_clk, 0, CCM_CGR1, 26, get_rate_ipg_per, NULL); -DEFINE_CLOCK(pwm_clk, 0, CCM_CGR1, 28, get_rate_ipg_per, NULL); -DEFINE_CLOCK(rngc_clk, 0, CCM_CGR1, 30, get_rate_ipg, NULL); - -DEFINE_CLOCK(rtc_clk, 0, CCM_CGR2, 0, get_rate_ipg, NULL); -DEFINE_CLOCK(rtic_clk, 0, CCM_CGR2, 2, get_rate_ahb, NULL); -DEFINE_CLOCK(scc_clk, 0, CCM_CGR2, 4, get_rate_ipg, NULL); -DEFINE_CLOCK(sdma_clk, 0, CCM_CGR2, 6, NULL, NULL); -DEFINE_CLOCK(spba_clk, 0, CCM_CGR2, 8, get_rate_ipg, NULL); -DEFINE_CLOCK(spdif_clk, 0, CCM_CGR2, 10, NULL, NULL); -DEFINE_CLOCK(ssi1_clk, 0, CCM_CGR2, 12, get_rate_ssi, NULL); -DEFINE_CLOCK(ssi2_clk, 1, CCM_CGR2, 14, get_rate_ssi, NULL); -DEFINE_CLOCK(uart1_clk, 0, CCM_CGR2, 16, get_rate_uart, NULL); -DEFINE_CLOCK(uart2_clk, 1, CCM_CGR2, 18, get_rate_uart, NULL); -DEFINE_CLOCK(uart3_clk, 2, CCM_CGR2, 20, get_rate_uart, NULL); -DEFINE_CLOCK(usbotg_clk, 0, CCM_CGR2, 22, get_rate_otg, NULL); -DEFINE_CLOCK(wdog_clk, 0, CCM_CGR2, 24, NULL, NULL); -DEFINE_CLOCK(max_clk, 0, CCM_CGR2, 26, NULL, NULL); -DEFINE_CLOCK(audmux_clk, 0, CCM_CGR2, 30, NULL, NULL); - -DEFINE_CLOCK(csi_clk, 0, CCM_CGR3, 0, get_rate_csi, NULL); -DEFINE_CLOCK(iim_clk, 0, CCM_CGR3, 2, NULL, NULL); -DEFINE_CLOCK(gpu2d_clk, 0, CCM_CGR3, 4, NULL, NULL); +DEFINE_CLOCK(asrc_clk, 0, MX35_CCM_CGR0, 0, NULL, NULL); +DEFINE_CLOCK(pata_clk, 0, MX35_CCM_CGR0, 2, get_rate_ipg, NULL); +/* DEFINE_CLOCK(audmux_clk, 0, MX35_CCM_CGR0, 4, NULL, NULL); */ +DEFINE_CLOCK(can1_clk, 0, MX35_CCM_CGR0, 6, get_rate_ipg, NULL); +DEFINE_CLOCK(can2_clk, 1, MX35_CCM_CGR0, 8, get_rate_ipg, NULL); +DEFINE_CLOCK(cspi1_clk, 0, MX35_CCM_CGR0, 10, get_rate_ipg, NULL); +DEFINE_CLOCK(cspi2_clk, 1, MX35_CCM_CGR0, 12, get_rate_ipg, NULL); +DEFINE_CLOCK(ect_clk, 0, MX35_CCM_CGR0, 14, get_rate_ipg, NULL); +DEFINE_CLOCK(edio_clk, 0, MX35_CCM_CGR0, 16, NULL, NULL); +DEFINE_CLOCK(emi_clk, 0, MX35_CCM_CGR0, 18, get_rate_ipg, NULL); +DEFINE_CLOCK(epit1_clk, 0, MX35_CCM_CGR0, 20, get_rate_ipg, NULL); +DEFINE_CLOCK(epit2_clk, 1, MX35_CCM_CGR0, 22, get_rate_ipg, NULL); +DEFINE_CLOCK(esai_clk, 0, MX35_CCM_CGR0, 24, NULL, NULL); +DEFINE_CLOCK(esdhc1_clk, 0, MX35_CCM_CGR0, 26, get_rate_sdhc, NULL); +DEFINE_CLOCK(esdhc2_clk, 1, MX35_CCM_CGR0, 28, get_rate_sdhc, NULL); +DEFINE_CLOCK(esdhc3_clk, 2, MX35_CCM_CGR0, 30, get_rate_sdhc, NULL); + +DEFINE_CLOCK(fec_clk, 0, MX35_CCM_CGR1, 0, get_rate_ipg, NULL); +DEFINE_CLOCK(gpio1_clk, 0, MX35_CCM_CGR1, 2, NULL, NULL); +DEFINE_CLOCK(gpio2_clk, 1, MX35_CCM_CGR1, 4, NULL, NULL); +DEFINE_CLOCK(gpio3_clk, 2, MX35_CCM_CGR1, 6, NULL, NULL); +DEFINE_CLOCK(gpt_clk, 0, MX35_CCM_CGR1, 8, get_rate_ipg, NULL); +DEFINE_CLOCK(i2c1_clk, 0, MX35_CCM_CGR1, 10, get_rate_ipg_per, NULL); +DEFINE_CLOCK(i2c2_clk, 1, MX35_CCM_CGR1, 12, get_rate_ipg_per, NULL); +DEFINE_CLOCK(i2c3_clk, 2, MX35_CCM_CGR1, 14, get_rate_ipg_per, NULL); +DEFINE_CLOCK(iomuxc_clk, 0, MX35_CCM_CGR1, 16, NULL, NULL); +DEFINE_CLOCK(ipu_clk, 0, MX35_CCM_CGR1, 18, get_rate_hsp, NULL); +DEFINE_CLOCK(kpp_clk, 0, MX35_CCM_CGR1, 20, get_rate_ipg, NULL); +DEFINE_CLOCK(mlb_clk, 0, MX35_CCM_CGR1, 22, get_rate_ahb, NULL); +DEFINE_CLOCK(mshc_clk, 0, MX35_CCM_CGR1, 24, get_rate_mshc, NULL); +DEFINE_CLOCK(owire_clk, 0, MX35_CCM_CGR1, 26, get_rate_ipg_per, NULL); +DEFINE_CLOCK(pwm_clk, 0, MX35_CCM_CGR1, 28, get_rate_ipg_per, NULL); +DEFINE_CLOCK(rngc_clk, 0, MX35_CCM_CGR1, 30, get_rate_ipg, NULL); + +DEFINE_CLOCK(rtc_clk, 0, MX35_CCM_CGR2, 0, get_rate_ipg, NULL); +DEFINE_CLOCK(rtic_clk, 0, MX35_CCM_CGR2, 2, get_rate_ahb, NULL); +DEFINE_CLOCK(scc_clk, 0, MX35_CCM_CGR2, 4, get_rate_ipg, NULL); +DEFINE_CLOCK(sdma_clk, 0, MX35_CCM_CGR2, 6, NULL, NULL); +DEFINE_CLOCK(spba_clk, 0, MX35_CCM_CGR2, 8, get_rate_ipg, NULL); +DEFINE_CLOCK(spdif_clk, 0, MX35_CCM_CGR2, 10, NULL, NULL); +DEFINE_CLOCK(ssi1_clk, 0, MX35_CCM_CGR2, 12, get_rate_ssi, NULL); +DEFINE_CLOCK(ssi2_clk, 1, MX35_CCM_CGR2, 14, get_rate_ssi, NULL); +DEFINE_CLOCK(uart1_clk, 0, MX35_CCM_CGR2, 16, get_rate_uart, NULL); +DEFINE_CLOCK(uart2_clk, 1, MX35_CCM_CGR2, 18, get_rate_uart, NULL); +DEFINE_CLOCK(uart3_clk, 2, MX35_CCM_CGR2, 20, get_rate_uart, NULL); +DEFINE_CLOCK(usbotg_clk, 0, MX35_CCM_CGR2, 22, get_rate_otg, NULL); +DEFINE_CLOCK(wdog_clk, 0, MX35_CCM_CGR2, 24, NULL, NULL); +DEFINE_CLOCK(max_clk, 0, MX35_CCM_CGR2, 26, NULL, NULL); +DEFINE_CLOCK(audmux_clk, 0, MX35_CCM_CGR2, 30, NULL, NULL); + +DEFINE_CLOCK(csi_clk, 0, MX35_CCM_CGR3, 0, get_rate_csi, NULL); +DEFINE_CLOCK(iim_clk, 0, MX35_CCM_CGR3, 2, NULL, NULL); +DEFINE_CLOCK(gpu2d_clk, 0, MX35_CCM_CGR3, 4, NULL, NULL); DEFINE_CLOCK(usbahb_clk, 0, 0, 0, get_rate_ahb, NULL); @@ -422,7 +406,7 @@ static unsigned long get_rate_nfc(struct clk *clk) { unsigned long div1; - div1 = (__raw_readl(CCM_BASE + CCM_PDR4) >> 28) + 1; + div1 = (__raw_readl(MX35_CCM_PDR4) >> 28) + 1; return get_rate_ahb(NULL) / div1; } @@ -499,7 +483,7 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk) _REGISTER_CLOCK(NULL, "max", max_clk) _REGISTER_CLOCK(NULL, "audmux", audmux_clk) - _REGISTER_CLOCK(NULL, "csi", csi_clk) + _REGISTER_CLOCK("mx3-camera.0", NULL, csi_clk) _REGISTER_CLOCK(NULL, "iim", iim_clk) _REGISTER_CLOCK(NULL, "gpu2d", gpu2d_clk) _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) @@ -518,11 +502,11 @@ int __init mx35_clocks_init() /* Turn off all clocks except the ones we need to survive, namely: * EMI, GPIO1/2/3, GPT, IOMUX, MAX and eventually uart */ - __raw_writel((3 << 18), CCM_BASE + CCM_CGR0); + __raw_writel((3 << 18), MX35_CCM_CGR0); __raw_writel((3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 16), - CCM_BASE + CCM_CGR1); - __raw_writel(cgr2, CCM_BASE + CCM_CGR2); - __raw_writel(0, CCM_BASE + CCM_CGR3); + MX35_CCM_CGR1); + __raw_writel(cgr2, MX35_CCM_CGR2); + __raw_writel(0, MX35_CCM_CGR3); clk_enable(&iim_clk); imx_print_silicon_rev("i.MX35", mx35_revision()); @@ -533,7 +517,7 @@ int __init mx35_clocks_init() * extra clocks turned on, otherwise the MX35 boot ROM code will * hang after a watchdog reset. */ - if (!(__raw_readl(CCM_BASE + CCM_RCSR) & (3 << 10))) { + if (!(__raw_readl(MX35_CCM_RCSR) & (3 << 10))) { /* Additionally turn on UART1, SCC, and IIM clocks */ clk_enable(&iim_clk); clk_enable(&uart1_clk); diff --git a/arch/arm/mach-imx/clock-imx6q.c b/arch/arm/mach-imx/clock-imx6q.c index 2d88f8b9a454..111c328f5420 100644 --- a/arch/arm/mach-imx/clock-imx6q.c +++ b/arch/arm/mach-imx/clock-imx6q.c @@ -329,6 +329,12 @@ #define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26) #define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27) +#define BP_CCOSR_CKO1_EN 7 +#define BP_CCOSR_CKO1_PODF 4 +#define BM_CCOSR_CKO1_PODF (0x7 << 4) +#define BP_CCOSR_CKO1_SEL 0 +#define BM_CCOSR_CKO1_SEL (0xf << 0) + #define FREQ_480M 480000000 #define FREQ_528M 528000000 #define FREQ_594M 594000000 @@ -393,6 +399,7 @@ static struct clk ipu1_di1_clk; static struct clk ipu2_di0_clk; static struct clk ipu2_di1_clk; static struct clk enfc_clk; +static struct clk cko1_clk; static struct clk dummy_clk = {}; static unsigned long external_high_reference; @@ -938,6 +945,24 @@ static void _clk_disable(struct clk *clk) writel_relaxed(reg, clk->enable_reg); } +static int _clk_enable_1b(struct clk *clk) +{ + u32 reg; + reg = readl_relaxed(clk->enable_reg); + reg |= 0x1 << clk->enable_shift; + writel_relaxed(reg, clk->enable_reg); + + return 0; +} + +static void _clk_disable_1b(struct clk *clk) +{ + u32 reg; + reg = readl_relaxed(clk->enable_reg); + reg &= ~(0x1 << clk->enable_shift); + writel_relaxed(reg, clk->enable_reg); +} + struct divider { struct clk *clk; void __iomem *reg; @@ -983,6 +1008,7 @@ DEF_CLK_DIV1(ipu2_di0_pre_div, &ipu2_di0_pre_clk, CSCDR2, IPU2_DI0_PRE); DEF_CLK_DIV1(ipu2_di1_pre_div, &ipu2_di1_pre_clk, CSCDR2, IPU2_DI1_PRE); DEF_CLK_DIV1(ipu1_div, &ipu1_clk, CSCDR3, IPU1_HSP); DEF_CLK_DIV1(ipu2_div, &ipu2_clk, CSCDR3, IPU2_HSP); +DEF_CLK_DIV1(cko1_div, &cko1_clk, CCOSR, CKO1); #define DEF_CLK_DIV2(d, c, r, b) \ static struct divider d = { \ @@ -1038,6 +1064,7 @@ static struct divider *dividers[] = { &enfc_div, &spdif_div, &asrc_serial_div, + &cko1_div, }; static unsigned long ldb_di_clk_get_rate(struct clk *clk) @@ -1625,6 +1652,32 @@ DEF_IPU_DI_MUX(CSCDR2, 2, 1); DEF_IPU_MUX(1); DEF_IPU_MUX(2); +static struct multiplexer cko1_mux = { + .clk = &cko1_clk, + .reg = CCOSR, + .bp = BP_CCOSR_CKO1_SEL, + .bm = BM_CCOSR_CKO1_SEL, + .parents = { + &pll3_usb_otg, + &pll2_bus, + &pll1_sys, + &pll5_video, + &dummy_clk, + &axi_clk, + &enfc_clk, + &ipu1_di0_clk, + &ipu1_di1_clk, + &ipu2_di0_clk, + &ipu2_di1_clk, + &ahb_clk, + &ipg_clk, + &ipg_perclk, + &ckil_clk, + &pll4_audio, + NULL + }, +}; + static struct multiplexer *multiplexers[] = { &axi_mux, &periph_mux, @@ -1667,6 +1720,7 @@ static struct multiplexer *multiplexers[] = { &ipu2_di1_mux, &ipu1_mux, &ipu2_mux, + &cko1_mux, }; static int _clk_set_parent(struct clk *clk, struct clk *parent) @@ -1690,7 +1744,7 @@ static int _clk_set_parent(struct clk *clk, struct clk *parent) break; i++; } - if (!m->parents[i]) + if (!m->parents[i] || m->parents[i] == &dummy_clk) return -EINVAL; val = readl_relaxed(m->reg); @@ -1745,6 +1799,20 @@ DEF_NG_CLK(asrc_serial_clk, &pll3_usb_otg); .secondary = s, \ } +#define DEF_CLK_1B(name, er, es, p, s) \ + static struct clk name = { \ + .enable_reg = er, \ + .enable_shift = es, \ + .enable = _clk_enable_1b, \ + .disable = _clk_disable_1b, \ + .get_rate = _clk_get_rate, \ + .set_rate = _clk_set_rate, \ + .round_rate = _clk_round_rate, \ + .set_parent = _clk_set_parent, \ + .parent = p, \ + .secondary = s, \ + } + DEF_CLK(aips_tz1_clk, CCGR0, CG0, &ahb_clk, NULL); DEF_CLK(aips_tz2_clk, CCGR0, CG1, &ahb_clk, NULL); DEF_CLK(apbh_dma_clk, CCGR0, CG2, &ahb_clk, NULL); @@ -1811,6 +1879,7 @@ DEF_CLK(usdhc4_clk, CCGR6, CG4, &pll2_pfd_400m, NULL); DEF_CLK(emi_slow_clk, CCGR6, CG5, &axi_clk, NULL); DEF_CLK(vdo_axi_clk, CCGR6, CG6, &axi_clk, NULL); DEF_CLK(vpu_clk, CCGR6, CG7, &axi_clk, NULL); +DEF_CLK_1B(cko1_clk, CCOSR, BP_CCOSR_CKO1_EN, &pll2_bus, NULL); static int pcie_clk_enable(struct clk *clk) { @@ -1922,6 +1991,7 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK(NULL, "gpmi_io_clk", gpmi_io_clk), _REGISTER_CLOCK(NULL, "usboh3_clk", usboh3_clk), _REGISTER_CLOCK(NULL, "sata_clk", sata_clk), + _REGISTER_CLOCK(NULL, "cko1_clk", cko1_clk), }; int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) @@ -2029,6 +2099,8 @@ int __init mx6q_clocks_init(void) clk_set_rate(&usdhc3_clk, 49500000); clk_set_rate(&usdhc4_clk, 49500000); + clk_set_parent(&cko1_clk, &ahb_clk); + np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt"); base = of_iomap(np, 0); WARN_ON(!base); diff --git a/arch/arm/mach-imx/cpu-imx5.c b/arch/arm/mach-imx/cpu-imx5.c index 5e2e7a843860..aa15c517d06e 100644 --- a/arch/arm/mach-imx/cpu-imx5.c +++ b/arch/arm/mach-imx/cpu-imx5.c @@ -149,39 +149,3 @@ int mx50_revision(void) return mx5_cpu_rev; } EXPORT_SYMBOL(mx50_revision); - -static int __init post_cpu_init(void) -{ - unsigned int reg; - void __iomem *base; - - if (cpu_is_mx51() || cpu_is_mx53()) { - if (cpu_is_mx51()) - base = MX51_IO_ADDRESS(MX51_AIPS1_BASE_ADDR); - else - base = MX53_IO_ADDRESS(MX53_AIPS1_BASE_ADDR); - - __raw_writel(0x0, base + 0x40); - __raw_writel(0x0, base + 0x44); - __raw_writel(0x0, base + 0x48); - __raw_writel(0x0, base + 0x4C); - reg = __raw_readl(base + 0x50) & 0x00FFFFFF; - __raw_writel(reg, base + 0x50); - - if (cpu_is_mx51()) - base = MX51_IO_ADDRESS(MX51_AIPS2_BASE_ADDR); - else - base = MX53_IO_ADDRESS(MX53_AIPS2_BASE_ADDR); - - __raw_writel(0x0, base + 0x40); - __raw_writel(0x0, base + 0x44); - __raw_writel(0x0, base + 0x48); - __raw_writel(0x0, base + 0x4C); - reg = __raw_readl(base + 0x50) & 0x00FFFFFF; - __raw_writel(reg, base + 0x50); - } - - return 0; -} - -postcore_initcall(post_cpu_init); diff --git a/arch/arm/mach-imx/cpu_op-mx51.c b/arch/arm/mach-imx/cpu_op-mx51.c index 9d34c3d4c024..7b92cd6da6d3 100644 --- a/arch/arm/mach-imx/cpu_op-mx51.c +++ b/arch/arm/mach-imx/cpu_op-mx51.c @@ -11,6 +11,7 @@ * http://www.gnu.org/copyleft/gpl.html */ +#include <linux/bug.h> #include <linux/types.h> #include <mach/hardware.h> #include <linux/kernel.h> diff --git a/arch/arm/mach-imx/crmregs-imx31.h b/arch/arm/mach-imx/crmregs-imx3.h index 37a8a07beda3..53141273df45 100644 --- a/arch/arm/mach-imx/crmregs-imx31.h +++ b/arch/arm/mach-imx/crmregs-imx3.h @@ -24,23 +24,36 @@ #define CKIH_CLK_FREQ_27MHZ 27000000 #define CKIL_CLK_FREQ 32768 -#define MXC_CCM_BASE MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR) +#define MXC_CCM_BASE (cpu_is_mx31() ? \ +MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR) : MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR)) /* Register addresses */ #define MXC_CCM_CCMR (MXC_CCM_BASE + 0x00) #define MXC_CCM_PDR0 (MXC_CCM_BASE + 0x04) #define MXC_CCM_PDR1 (MXC_CCM_BASE + 0x08) +#define MX35_CCM_PDR2 (MXC_CCM_BASE + 0x0C) #define MXC_CCM_RCSR (MXC_CCM_BASE + 0x0C) +#define MX35_CCM_PDR3 (MXC_CCM_BASE + 0x10) #define MXC_CCM_MPCTL (MXC_CCM_BASE + 0x10) +#define MX35_CCM_PDR4 (MXC_CCM_BASE + 0x14) #define MXC_CCM_UPCTL (MXC_CCM_BASE + 0x14) +#define MX35_CCM_RCSR (MXC_CCM_BASE + 0x18) #define MXC_CCM_SRPCTL (MXC_CCM_BASE + 0x18) +#define MX35_CCM_MPCTL (MXC_CCM_BASE + 0x1C) #define MXC_CCM_COSR (MXC_CCM_BASE + 0x1C) +#define MX35_CCM_PPCTL (MXC_CCM_BASE + 0x20) #define MXC_CCM_CGR0 (MXC_CCM_BASE + 0x20) +#define MX35_CCM_ACMR (MXC_CCM_BASE + 0x24) #define MXC_CCM_CGR1 (MXC_CCM_BASE + 0x24) +#define MX35_CCM_COSR (MXC_CCM_BASE + 0x28) #define MXC_CCM_CGR2 (MXC_CCM_BASE + 0x28) +#define MX35_CCM_CGR0 (MXC_CCM_BASE + 0x2C) #define MXC_CCM_WIMR (MXC_CCM_BASE + 0x2C) +#define MX35_CCM_CGR1 (MXC_CCM_BASE + 0x30) #define MXC_CCM_LDC (MXC_CCM_BASE + 0x30) +#define MX35_CCM_CGR2 (MXC_CCM_BASE + 0x34) #define MXC_CCM_DCVR0 (MXC_CCM_BASE + 0x34) +#define MX35_CCM_CGR3 (MXC_CCM_BASE + 0x38) #define MXC_CCM_DCVR1 (MXC_CCM_BASE + 0x38) #define MXC_CCM_DCVR2 (MXC_CCM_BASE + 0x3C) #define MXC_CCM_DCVR3 (MXC_CCM_BASE + 0x40) @@ -64,6 +77,7 @@ #define MXC_CCM_CCMR_SSI2S_MASK (0x3 << 21) #define MXC_CCM_CCMR_LPM_OFFSET 14 #define MXC_CCM_CCMR_LPM_MASK (0x3 << 14) +#define MXC_CCM_CCMR_LPM_WAIT_MX35 (0x1 << 14) #define MXC_CCM_CCMR_FIRS_OFFSET 11 #define MXC_CCM_CCMR_FIRS_MASK (0x3 << 11) #define MXC_CCM_CCMR_UPE (1 << 9) diff --git a/arch/arm/mach-imx/dma-v1.c b/arch/arm/mach-imx/dma-v1.c deleted file mode 100644 index 42afc29a7da8..000000000000 --- a/arch/arm/mach-imx/dma-v1.c +++ /dev/null @@ -1,846 +0,0 @@ -/* - * linux/arch/arm/plat-mxc/dma-v1.c - * - * i.MX DMA registration and IRQ dispatching - * - * Copyright 2006 Pavel Pisa <pisa@cmp.felk.cvut.cz> - * Copyright 2008 Juergen Beisert, <kernel@pengutronix.de> - * Copyright 2008 Sascha Hauer, <s.hauer@pengutronix.de> - * - * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/interrupt.h> -#include <linux/err.h> -#include <linux/errno.h> -#include <linux/clk.h> -#include <linux/scatterlist.h> -#include <linux/io.h> - -#include <asm/system.h> -#include <asm/irq.h> -#include <mach/hardware.h> -#include <mach/dma-v1.h> - -#define DMA_DCR 0x00 /* Control Register */ -#define DMA_DISR 0x04 /* Interrupt status Register */ -#define DMA_DIMR 0x08 /* Interrupt mask Register */ -#define DMA_DBTOSR 0x0c /* Burst timeout status Register */ -#define DMA_DRTOSR 0x10 /* Request timeout Register */ -#define DMA_DSESR 0x14 /* Transfer Error Status Register */ -#define DMA_DBOSR 0x18 /* Buffer overflow status Register */ -#define DMA_DBTOCR 0x1c /* Burst timeout control Register */ -#define DMA_WSRA 0x40 /* W-Size Register A */ -#define DMA_XSRA 0x44 /* X-Size Register A */ -#define DMA_YSRA 0x48 /* Y-Size Register A */ -#define DMA_WSRB 0x4c /* W-Size Register B */ -#define DMA_XSRB 0x50 /* X-Size Register B */ -#define DMA_YSRB 0x54 /* Y-Size Register B */ -#define DMA_SAR(x) (0x80 + ((x) << 6)) /* Source Address Registers */ -#define DMA_DAR(x) (0x84 + ((x) << 6)) /* Destination Address Registers */ -#define DMA_CNTR(x) (0x88 + ((x) << 6)) /* Count Registers */ -#define DMA_CCR(x) (0x8c + ((x) << 6)) /* Control Registers */ -#define DMA_RSSR(x) (0x90 + ((x) << 6)) /* Request source select Registers */ -#define DMA_BLR(x) (0x94 + ((x) << 6)) /* Burst length Registers */ -#define DMA_RTOR(x) (0x98 + ((x) << 6)) /* Request timeout Registers */ -#define DMA_BUCR(x) (0x98 + ((x) << 6)) /* Bus Utilization Registers */ -#define DMA_CCNR(x) (0x9C + ((x) << 6)) /* Channel counter Registers */ - -#define DCR_DRST (1<<1) -#define DCR_DEN (1<<0) -#define DBTOCR_EN (1<<15) -#define DBTOCR_CNT(x) ((x) & 0x7fff) -#define CNTR_CNT(x) ((x) & 0xffffff) -#define CCR_ACRPT (1<<14) -#define CCR_DMOD_LINEAR (0x0 << 12) -#define CCR_DMOD_2D (0x1 << 12) -#define CCR_DMOD_FIFO (0x2 << 12) -#define CCR_DMOD_EOBFIFO (0x3 << 12) -#define CCR_SMOD_LINEAR (0x0 << 10) -#define CCR_SMOD_2D (0x1 << 10) -#define CCR_SMOD_FIFO (0x2 << 10) -#define CCR_SMOD_EOBFIFO (0x3 << 10) -#define CCR_MDIR_DEC (1<<9) -#define CCR_MSEL_B (1<<8) -#define CCR_DSIZ_32 (0x0 << 6) -#define CCR_DSIZ_8 (0x1 << 6) -#define CCR_DSIZ_16 (0x2 << 6) -#define CCR_SSIZ_32 (0x0 << 4) -#define CCR_SSIZ_8 (0x1 << 4) -#define CCR_SSIZ_16 (0x2 << 4) -#define CCR_REN (1<<3) -#define CCR_RPT (1<<2) -#define CCR_FRC (1<<1) -#define CCR_CEN (1<<0) -#define RTOR_EN (1<<15) -#define RTOR_CLK (1<<14) -#define RTOR_PSC (1<<13) - -/* - * struct imx_dma_channel - i.MX specific DMA extension - * @name: name specified by DMA client - * @irq_handler: client callback for end of transfer - * @err_handler: client callback for error condition - * @data: clients context data for callbacks - * @dma_mode: direction of the transfer %DMA_MODE_READ or %DMA_MODE_WRITE - * @sg: pointer to the actual read/written chunk for scatter-gather emulation - * @resbytes: total residual number of bytes to transfer - * (it can be lower or same as sum of SG mapped chunk sizes) - * @sgcount: number of chunks to be read/written - * - * Structure is used for IMX DMA processing. It would be probably good - * @struct dma_struct in the future for external interfacing and use - * @struct imx_dma_channel only as extension to it. - */ - -struct imx_dma_channel { - const char *name; - void (*irq_handler) (int, void *); - void (*err_handler) (int, void *, int errcode); - void (*prog_handler) (int, void *, struct scatterlist *); - void *data; - unsigned int dma_mode; - struct scatterlist *sg; - unsigned int resbytes; - int dma_num; - - int in_use; - - u32 ccr_from_device; - u32 ccr_to_device; - - struct timer_list watchdog; - - int hw_chaining; -}; - -static void __iomem *imx_dmav1_baseaddr; - -static void imx_dmav1_writel(unsigned val, unsigned offset) -{ - __raw_writel(val, imx_dmav1_baseaddr + offset); -} - -static unsigned imx_dmav1_readl(unsigned offset) -{ - return __raw_readl(imx_dmav1_baseaddr + offset); -} - -static struct imx_dma_channel imx_dma_channels[IMX_DMA_CHANNELS]; - -static struct clk *dma_clk; - -static int imx_dma_hw_chain(struct imx_dma_channel *imxdma) -{ - if (cpu_is_mx27()) - return imxdma->hw_chaining; - else - return 0; -} - -/* - * imx_dma_sg_next - prepare next chunk for scatter-gather DMA emulation - */ -static inline int imx_dma_sg_next(int channel, struct scatterlist *sg) -{ - struct imx_dma_channel *imxdma = &imx_dma_channels[channel]; - unsigned long now; - - if (!imxdma->name) { - printk(KERN_CRIT "%s: called for not allocated channel %d\n", - __func__, channel); - return 0; - } - - now = min(imxdma->resbytes, sg->length); - if (imxdma->resbytes != IMX_DMA_LENGTH_LOOP) - imxdma->resbytes -= now; - - if ((imxdma->dma_mode & DMA_MODE_MASK) == DMA_MODE_READ) - imx_dmav1_writel(sg->dma_address, DMA_DAR(channel)); - else - imx_dmav1_writel(sg->dma_address, DMA_SAR(channel)); - - imx_dmav1_writel(now, DMA_CNTR(channel)); - - pr_debug("imxdma%d: next sg chunk dst 0x%08x, src 0x%08x, " - "size 0x%08x\n", channel, - imx_dmav1_readl(DMA_DAR(channel)), - imx_dmav1_readl(DMA_SAR(channel)), - imx_dmav1_readl(DMA_CNTR(channel))); - - return now; -} - -/** - * imx_dma_setup_single - setup i.MX DMA channel for linear memory to/from - * device transfer - * - * @channel: i.MX DMA channel number - * @dma_address: the DMA/physical memory address of the linear data block - * to transfer - * @dma_length: length of the data block in bytes - * @dev_addr: physical device port address - * @dmamode: DMA transfer mode, %DMA_MODE_READ from the device to the memory - * or %DMA_MODE_WRITE from memory to the device - * - * Return value: if incorrect parameters are provided -%EINVAL. - * Zero indicates success. - */ -int -imx_dma_setup_single(int channel, dma_addr_t dma_address, - unsigned int dma_length, unsigned int dev_addr, - unsigned int dmamode) -{ - struct imx_dma_channel *imxdma = &imx_dma_channels[channel]; - - imxdma->sg = NULL; - imxdma->dma_mode = dmamode; - - if (!dma_address) { - printk(KERN_ERR "imxdma%d: imx_dma_setup_single null address\n", - channel); - return -EINVAL; - } - - if (!dma_length) { - printk(KERN_ERR "imxdma%d: imx_dma_setup_single zero length\n", - channel); - return -EINVAL; - } - - if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) { - pr_debug("imxdma%d: %s dma_addressg=0x%08x dma_length=%d " - "dev_addr=0x%08x for read\n", - channel, __func__, (unsigned int)dma_address, - dma_length, dev_addr); - - imx_dmav1_writel(dev_addr, DMA_SAR(channel)); - imx_dmav1_writel(dma_address, DMA_DAR(channel)); - imx_dmav1_writel(imxdma->ccr_from_device, DMA_CCR(channel)); - } else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) { - pr_debug("imxdma%d: %s dma_addressg=0x%08x dma_length=%d " - "dev_addr=0x%08x for write\n", - channel, __func__, (unsigned int)dma_address, - dma_length, dev_addr); - - imx_dmav1_writel(dma_address, DMA_SAR(channel)); - imx_dmav1_writel(dev_addr, DMA_DAR(channel)); - imx_dmav1_writel(imxdma->ccr_to_device, - DMA_CCR(channel)); - } else { - printk(KERN_ERR "imxdma%d: imx_dma_setup_single bad dmamode\n", - channel); - return -EINVAL; - } - - imx_dmav1_writel(dma_length, DMA_CNTR(channel)); - - return 0; -} -EXPORT_SYMBOL(imx_dma_setup_single); - -/** - * imx_dma_setup_sg - setup i.MX DMA channel SG list to/from device transfer - * @channel: i.MX DMA channel number - * @sg: pointer to the scatter-gather list/vector - * @sgcount: scatter-gather list hungs count - * @dma_length: total length of the transfer request in bytes - * @dev_addr: physical device port address - * @dmamode: DMA transfer mode, %DMA_MODE_READ from the device to the memory - * or %DMA_MODE_WRITE from memory to the device - * - * The function sets up DMA channel state and registers to be ready for - * transfer specified by provided parameters. The scatter-gather emulation - * is set up according to the parameters. - * - * The full preparation of the transfer requires setup of more register - * by the caller before imx_dma_enable() can be called. - * - * %BLR(channel) holds transfer burst length in bytes, 0 means 64 bytes - * - * %RSSR(channel) has to be set to the DMA request line source %DMA_REQ_xxx - * - * %CCR(channel) has to specify transfer parameters, the next settings is - * typical for linear or simple scatter-gather transfers if %DMA_MODE_READ is - * specified - * - * %CCR_DMOD_LINEAR | %CCR_DSIZ_32 | %CCR_SMOD_FIFO | %CCR_SSIZ_x - * - * The typical setup for %DMA_MODE_WRITE is specified by next options - * combination - * - * %CCR_SMOD_LINEAR | %CCR_SSIZ_32 | %CCR_DMOD_FIFO | %CCR_DSIZ_x - * - * Be careful here and do not mistakenly mix source and target device - * port sizes constants, they are really different: - * %CCR_SSIZ_8, %CCR_SSIZ_16, %CCR_SSIZ_32, - * %CCR_DSIZ_8, %CCR_DSIZ_16, %CCR_DSIZ_32 - * - * Return value: if incorrect parameters are provided -%EINVAL. - * Zero indicates success. - */ -int -imx_dma_setup_sg(int channel, - struct scatterlist *sg, unsigned int sgcount, - unsigned int dma_length, unsigned int dev_addr, - unsigned int dmamode) -{ - struct imx_dma_channel *imxdma = &imx_dma_channels[channel]; - - if (imxdma->in_use) - return -EBUSY; - - imxdma->sg = sg; - imxdma->dma_mode = dmamode; - imxdma->resbytes = dma_length; - - if (!sg || !sgcount) { - printk(KERN_ERR "imxdma%d: imx_dma_setup_sg empty sg list\n", - channel); - return -EINVAL; - } - - if (!sg->length) { - printk(KERN_ERR "imxdma%d: imx_dma_setup_sg zero length\n", - channel); - return -EINVAL; - } - - if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) { - pr_debug("imxdma%d: %s sg=%p sgcount=%d total length=%d " - "dev_addr=0x%08x for read\n", - channel, __func__, sg, sgcount, dma_length, dev_addr); - - imx_dmav1_writel(dev_addr, DMA_SAR(channel)); - imx_dmav1_writel(imxdma->ccr_from_device, DMA_CCR(channel)); - } else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) { - pr_debug("imxdma%d: %s sg=%p sgcount=%d total length=%d " - "dev_addr=0x%08x for write\n", - channel, __func__, sg, sgcount, dma_length, dev_addr); - - imx_dmav1_writel(dev_addr, DMA_DAR(channel)); - imx_dmav1_writel(imxdma->ccr_to_device, DMA_CCR(channel)); - } else { - printk(KERN_ERR "imxdma%d: imx_dma_setup_sg bad dmamode\n", - channel); - return -EINVAL; - } - - imx_dma_sg_next(channel, sg); - - return 0; -} -EXPORT_SYMBOL(imx_dma_setup_sg); - -int -imx_dma_config_channel(int channel, unsigned int config_port, - unsigned int config_mem, unsigned int dmareq, int hw_chaining) -{ - struct imx_dma_channel *imxdma = &imx_dma_channels[channel]; - u32 dreq = 0; - - imxdma->hw_chaining = 0; - - if (hw_chaining) { - imxdma->hw_chaining = 1; - if (!imx_dma_hw_chain(imxdma)) - return -EINVAL; - } - - if (dmareq) - dreq = CCR_REN; - - imxdma->ccr_from_device = config_port | (config_mem << 2) | dreq; - imxdma->ccr_to_device = config_mem | (config_port << 2) | dreq; - - imx_dmav1_writel(dmareq, DMA_RSSR(channel)); - - return 0; -} -EXPORT_SYMBOL(imx_dma_config_channel); - -void imx_dma_config_burstlen(int channel, unsigned int burstlen) -{ - imx_dmav1_writel(burstlen, DMA_BLR(channel)); -} -EXPORT_SYMBOL(imx_dma_config_burstlen); - -/** - * imx_dma_setup_handlers - setup i.MX DMA channel end and error notification - * handlers - * @channel: i.MX DMA channel number - * @irq_handler: the pointer to the function called if the transfer - * ends successfully - * @err_handler: the pointer to the function called if the premature - * end caused by error occurs - * @data: user specified value to be passed to the handlers - */ -int -imx_dma_setup_handlers(int channel, - void (*irq_handler) (int, void *), - void (*err_handler) (int, void *, int), - void *data) -{ - struct imx_dma_channel *imxdma = &imx_dma_channels[channel]; - unsigned long flags; - - if (!imxdma->name) { - printk(KERN_CRIT "%s: called for not allocated channel %d\n", - __func__, channel); - return -ENODEV; - } - - local_irq_save(flags); - imx_dmav1_writel(1 << channel, DMA_DISR); - imxdma->irq_handler = irq_handler; - imxdma->err_handler = err_handler; - imxdma->data = data; - local_irq_restore(flags); - return 0; -} -EXPORT_SYMBOL(imx_dma_setup_handlers); - -/** - * imx_dma_setup_progression_handler - setup i.MX DMA channel progression - * handlers - * @channel: i.MX DMA channel number - * @prog_handler: the pointer to the function called if the transfer progresses - */ -int -imx_dma_setup_progression_handler(int channel, - void (*prog_handler) (int, void*, struct scatterlist*)) -{ - struct imx_dma_channel *imxdma = &imx_dma_channels[channel]; - unsigned long flags; - - if (!imxdma->name) { - printk(KERN_CRIT "%s: called for not allocated channel %d\n", - __func__, channel); - return -ENODEV; - } - - local_irq_save(flags); - imxdma->prog_handler = prog_handler; - local_irq_restore(flags); - return 0; -} -EXPORT_SYMBOL(imx_dma_setup_progression_handler); - -/** - * imx_dma_enable - function to start i.MX DMA channel operation - * @channel: i.MX DMA channel number - * - * The channel has to be allocated by driver through imx_dma_request() - * or imx_dma_request_by_prio() function. - * The transfer parameters has to be set to the channel registers through - * call of the imx_dma_setup_single() or imx_dma_setup_sg() function - * and registers %BLR(channel), %RSSR(channel) and %CCR(channel) has to - * be set prior this function call by the channel user. - */ -void imx_dma_enable(int channel) -{ - struct imx_dma_channel *imxdma = &imx_dma_channels[channel]; - unsigned long flags; - - pr_debug("imxdma%d: imx_dma_enable\n", channel); - - if (!imxdma->name) { - printk(KERN_CRIT "%s: called for not allocated channel %d\n", - __func__, channel); - return; - } - - if (imxdma->in_use) - return; - - local_irq_save(flags); - - imx_dmav1_writel(1 << channel, DMA_DISR); - imx_dmav1_writel(imx_dmav1_readl(DMA_DIMR) & ~(1 << channel), DMA_DIMR); - imx_dmav1_writel(imx_dmav1_readl(DMA_CCR(channel)) | CCR_CEN | - CCR_ACRPT, DMA_CCR(channel)); - - if ((cpu_is_mx21() || cpu_is_mx27()) && - imxdma->sg && imx_dma_hw_chain(imxdma)) { - imxdma->sg = sg_next(imxdma->sg); - if (imxdma->sg) { - u32 tmp; - imx_dma_sg_next(channel, imxdma->sg); - tmp = imx_dmav1_readl(DMA_CCR(channel)); - imx_dmav1_writel(tmp | CCR_RPT | CCR_ACRPT, - DMA_CCR(channel)); - } - } - imxdma->in_use = 1; - - local_irq_restore(flags); -} -EXPORT_SYMBOL(imx_dma_enable); - -/** - * imx_dma_disable - stop, finish i.MX DMA channel operatin - * @channel: i.MX DMA channel number - */ -void imx_dma_disable(int channel) -{ - struct imx_dma_channel *imxdma = &imx_dma_channels[channel]; - unsigned long flags; - - pr_debug("imxdma%d: imx_dma_disable\n", channel); - - if (imx_dma_hw_chain(imxdma)) - del_timer(&imxdma->watchdog); - - local_irq_save(flags); - imx_dmav1_writel(imx_dmav1_readl(DMA_DIMR) | (1 << channel), DMA_DIMR); - imx_dmav1_writel(imx_dmav1_readl(DMA_CCR(channel)) & ~CCR_CEN, - DMA_CCR(channel)); - imx_dmav1_writel(1 << channel, DMA_DISR); - imxdma->in_use = 0; - local_irq_restore(flags); -} -EXPORT_SYMBOL(imx_dma_disable); - -static void imx_dma_watchdog(unsigned long chno) -{ - struct imx_dma_channel *imxdma = &imx_dma_channels[chno]; - - imx_dmav1_writel(0, DMA_CCR(chno)); - imxdma->in_use = 0; - imxdma->sg = NULL; - - if (imxdma->err_handler) - imxdma->err_handler(chno, imxdma->data, IMX_DMA_ERR_TIMEOUT); -} - -static irqreturn_t dma_err_handler(int irq, void *dev_id) -{ - int i, disr; - struct imx_dma_channel *imxdma; - unsigned int err_mask; - int errcode; - - disr = imx_dmav1_readl(DMA_DISR); - - err_mask = imx_dmav1_readl(DMA_DBTOSR) | - imx_dmav1_readl(DMA_DRTOSR) | - imx_dmav1_readl(DMA_DSESR) | - imx_dmav1_readl(DMA_DBOSR); - - if (!err_mask) - return IRQ_HANDLED; - - imx_dmav1_writel(disr & err_mask, DMA_DISR); - - for (i = 0; i < IMX_DMA_CHANNELS; i++) { - if (!(err_mask & (1 << i))) - continue; - imxdma = &imx_dma_channels[i]; - errcode = 0; - - if (imx_dmav1_readl(DMA_DBTOSR) & (1 << i)) { - imx_dmav1_writel(1 << i, DMA_DBTOSR); - errcode |= IMX_DMA_ERR_BURST; - } - if (imx_dmav1_readl(DMA_DRTOSR) & (1 << i)) { - imx_dmav1_writel(1 << i, DMA_DRTOSR); - errcode |= IMX_DMA_ERR_REQUEST; - } - if (imx_dmav1_readl(DMA_DSESR) & (1 << i)) { - imx_dmav1_writel(1 << i, DMA_DSESR); - errcode |= IMX_DMA_ERR_TRANSFER; - } - if (imx_dmav1_readl(DMA_DBOSR) & (1 << i)) { - imx_dmav1_writel(1 << i, DMA_DBOSR); - errcode |= IMX_DMA_ERR_BUFFER; - } - if (imxdma->name && imxdma->err_handler) { - imxdma->err_handler(i, imxdma->data, errcode); - continue; - } - - imx_dma_channels[i].sg = NULL; - - printk(KERN_WARNING - "DMA timeout on channel %d (%s) -%s%s%s%s\n", - i, imxdma->name, - errcode & IMX_DMA_ERR_BURST ? " burst" : "", - errcode & IMX_DMA_ERR_REQUEST ? " request" : "", - errcode & IMX_DMA_ERR_TRANSFER ? " transfer" : "", - errcode & IMX_DMA_ERR_BUFFER ? " buffer" : ""); - } - return IRQ_HANDLED; -} - -static void dma_irq_handle_channel(int chno) -{ - struct imx_dma_channel *imxdma = &imx_dma_channels[chno]; - - if (!imxdma->name) { - /* - * IRQ for an unregistered DMA channel: - * let's clear the interrupts and disable it. - */ - printk(KERN_WARNING - "spurious IRQ for DMA channel %d\n", chno); - return; - } - - if (imxdma->sg) { - u32 tmp; - struct scatterlist *current_sg = imxdma->sg; - imxdma->sg = sg_next(imxdma->sg); - - if (imxdma->sg) { - imx_dma_sg_next(chno, imxdma->sg); - - tmp = imx_dmav1_readl(DMA_CCR(chno)); - - if (imx_dma_hw_chain(imxdma)) { - /* FIXME: The timeout should probably be - * configurable - */ - mod_timer(&imxdma->watchdog, - jiffies + msecs_to_jiffies(500)); - - tmp |= CCR_CEN | CCR_RPT | CCR_ACRPT; - imx_dmav1_writel(tmp, DMA_CCR(chno)); - } else { - imx_dmav1_writel(tmp & ~CCR_CEN, DMA_CCR(chno)); - tmp |= CCR_CEN; - } - - imx_dmav1_writel(tmp, DMA_CCR(chno)); - - if (imxdma->prog_handler) - imxdma->prog_handler(chno, imxdma->data, - current_sg); - - return; - } - - if (imx_dma_hw_chain(imxdma)) { - del_timer(&imxdma->watchdog); - return; - } - } - - imx_dmav1_writel(0, DMA_CCR(chno)); - imxdma->in_use = 0; - if (imxdma->irq_handler) - imxdma->irq_handler(chno, imxdma->data); -} - -static irqreturn_t dma_irq_handler(int irq, void *dev_id) -{ - int i, disr; - - if (cpu_is_mx21() || cpu_is_mx27()) - dma_err_handler(irq, dev_id); - - disr = imx_dmav1_readl(DMA_DISR); - - pr_debug("imxdma: dma_irq_handler called, disr=0x%08x\n", - disr); - - imx_dmav1_writel(disr, DMA_DISR); - for (i = 0; i < IMX_DMA_CHANNELS; i++) { - if (disr & (1 << i)) - dma_irq_handle_channel(i); - } - - return IRQ_HANDLED; -} - -/** - * imx_dma_request - request/allocate specified channel number - * @channel: i.MX DMA channel number - * @name: the driver/caller own non-%NULL identification - */ -int imx_dma_request(int channel, const char *name) -{ - struct imx_dma_channel *imxdma = &imx_dma_channels[channel]; - unsigned long flags; - int ret = 0; - - /* basic sanity checks */ - if (!name) - return -EINVAL; - - if (channel >= IMX_DMA_CHANNELS) { - printk(KERN_CRIT "%s: called for non-existed channel %d\n", - __func__, channel); - return -EINVAL; - } - - local_irq_save(flags); - if (imxdma->name) { - local_irq_restore(flags); - return -EBUSY; - } - memset(imxdma, 0, sizeof(*imxdma)); - imxdma->name = name; - local_irq_restore(flags); /* request_irq() can block */ - - if (cpu_is_mx21() || cpu_is_mx27()) { - ret = request_irq(MX2x_INT_DMACH0 + channel, - dma_irq_handler, 0, "DMA", NULL); - if (ret) { - imxdma->name = NULL; - pr_crit("Can't register IRQ %d for DMA channel %d\n", - MX2x_INT_DMACH0 + channel, channel); - return ret; - } - init_timer(&imxdma->watchdog); - imxdma->watchdog.function = &imx_dma_watchdog; - imxdma->watchdog.data = channel; - } - - return ret; -} -EXPORT_SYMBOL(imx_dma_request); - -/** - * imx_dma_free - release previously acquired channel - * @channel: i.MX DMA channel number - */ -void imx_dma_free(int channel) -{ - unsigned long flags; - struct imx_dma_channel *imxdma = &imx_dma_channels[channel]; - - if (!imxdma->name) { - printk(KERN_CRIT - "%s: trying to free free channel %d\n", - __func__, channel); - return; - } - - local_irq_save(flags); - /* Disable interrupts */ - imx_dma_disable(channel); - imxdma->name = NULL; - - if (cpu_is_mx21() || cpu_is_mx27()) - free_irq(MX2x_INT_DMACH0 + channel, NULL); - - local_irq_restore(flags); -} -EXPORT_SYMBOL(imx_dma_free); - -/** - * imx_dma_request_by_prio - find and request some of free channels best - * suiting requested priority - * @channel: i.MX DMA channel number - * @name: the driver/caller own non-%NULL identification - * - * This function tries to find a free channel in the specified priority group - * if the priority cannot be achieved it tries to look for free channel - * in the higher and then even lower priority groups. - * - * Return value: If there is no free channel to allocate, -%ENODEV is returned. - * On successful allocation channel is returned. - */ -int imx_dma_request_by_prio(const char *name, enum imx_dma_prio prio) -{ - int i; - int best; - - switch (prio) { - case (DMA_PRIO_HIGH): - best = 8; - break; - case (DMA_PRIO_MEDIUM): - best = 4; - break; - case (DMA_PRIO_LOW): - default: - best = 0; - break; - } - - for (i = best; i < IMX_DMA_CHANNELS; i++) - if (!imx_dma_request(i, name)) - return i; - - for (i = best - 1; i >= 0; i--) - if (!imx_dma_request(i, name)) - return i; - - printk(KERN_ERR "%s: no free DMA channel found\n", __func__); - - return -ENODEV; -} -EXPORT_SYMBOL(imx_dma_request_by_prio); - -static int __init imx_dma_init(void) -{ - int ret = 0; - int i; - - if (cpu_is_mx1()) - imx_dmav1_baseaddr = MX1_IO_ADDRESS(MX1_DMA_BASE_ADDR); - else if (cpu_is_mx21()) - imx_dmav1_baseaddr = MX21_IO_ADDRESS(MX21_DMA_BASE_ADDR); - else if (cpu_is_mx27()) - imx_dmav1_baseaddr = MX27_IO_ADDRESS(MX27_DMA_BASE_ADDR); - else - return 0; - - dma_clk = clk_get(NULL, "dma"); - if (IS_ERR(dma_clk)) - return PTR_ERR(dma_clk); - clk_enable(dma_clk); - - /* reset DMA module */ - imx_dmav1_writel(DCR_DRST, DMA_DCR); - - if (cpu_is_mx1()) { - ret = request_irq(MX1_DMA_INT, dma_irq_handler, 0, "DMA", NULL); - if (ret) { - pr_crit("Wow! Can't register IRQ for DMA\n"); - return ret; - } - - ret = request_irq(MX1_DMA_ERR, dma_err_handler, 0, "DMA", NULL); - if (ret) { - pr_crit("Wow! Can't register ERRIRQ for DMA\n"); - free_irq(MX1_DMA_INT, NULL); - return ret; - } - } - - /* enable DMA module */ - imx_dmav1_writel(DCR_DEN, DMA_DCR); - - /* clear all interrupts */ - imx_dmav1_writel((1 << IMX_DMA_CHANNELS) - 1, DMA_DISR); - - /* disable interrupts */ - imx_dmav1_writel((1 << IMX_DMA_CHANNELS) - 1, DMA_DIMR); - - for (i = 0; i < IMX_DMA_CHANNELS; i++) { - imx_dma_channels[i].sg = NULL; - imx_dma_channels[i].dma_num = i; - } - - return ret; -} - -arch_initcall(imx_dma_init); diff --git a/arch/arm/mach-imx/imx27-dt.c b/arch/arm/mach-imx/imx27-dt.c new file mode 100644 index 000000000000..861ceb8232d6 --- /dev/null +++ b/arch/arm/mach-imx/imx27-dt.c @@ -0,0 +1,89 @@ +/* + * Copyright 2012 Sascha Hauer, Pengutronix + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include <linux/irq.h> +#include <linux/irqdomain.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h> +#include <asm/mach/arch.h> +#include <asm/mach/time.h> +#include <mach/common.h> +#include <mach/mx27.h> + +static const struct of_dev_auxdata imx27_auxdata_lookup[] __initconst = { + OF_DEV_AUXDATA("fsl,imx27-uart", MX27_UART1_BASE_ADDR, "imx21-uart.0", NULL), + OF_DEV_AUXDATA("fsl,imx27-uart", MX27_UART2_BASE_ADDR, "imx21-uart.1", NULL), + OF_DEV_AUXDATA("fsl,imx27-uart", MX27_UART3_BASE_ADDR, "imx21-uart.2", NULL), + OF_DEV_AUXDATA("fsl,imx27-fec", MX27_FEC_BASE_ADDR, "imx27-fec.0", NULL), + OF_DEV_AUXDATA("fsl,imx27-i2c", MX27_I2C1_BASE_ADDR, "imx-i2c.0", NULL), + OF_DEV_AUXDATA("fsl,imx27-i2c", MX27_I2C2_BASE_ADDR, "imx-i2c.1", NULL), + OF_DEV_AUXDATA("fsl,imx27-cspi", MX27_CSPI1_BASE_ADDR, "imx27-cspi.0", NULL), + OF_DEV_AUXDATA("fsl,imx27-cspi", MX27_CSPI2_BASE_ADDR, "imx27-cspi.1", NULL), + OF_DEV_AUXDATA("fsl,imx27-cspi", MX27_CSPI3_BASE_ADDR, "imx27-cspi.2", NULL), + OF_DEV_AUXDATA("fsl,imx27-wdt", MX27_WDOG_BASE_ADDR, "imx2-wdt.0", NULL), + { /* sentinel */ } +}; + +static int __init imx27_avic_add_irq_domain(struct device_node *np, + struct device_node *interrupt_parent) +{ + irq_domain_add_simple(np, 0); + return 0; +} + +static int __init imx27_gpio_add_irq_domain(struct device_node *np, + struct device_node *interrupt_parent) +{ + static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS; + + irq_domain_add_simple(np, gpio_irq_base); + + return 0; +} + +static const struct of_device_id imx27_irq_match[] __initconst = { + { .compatible = "fsl,imx27-avic", .data = imx27_avic_add_irq_domain, }, + { .compatible = "fsl,imx27-gpio", .data = imx27_gpio_add_irq_domain, }, + { /* sentinel */ } +}; + +static void __init imx27_dt_init(void) +{ + of_irq_init(imx27_irq_match); + + of_platform_populate(NULL, of_default_bus_match_table, + imx27_auxdata_lookup, NULL); +} + +static void __init imx27_timer_init(void) +{ + mx27_clocks_init_dt(); +} + +static struct sys_timer imx27_timer = { + .init = imx27_timer_init, +}; + +static const char *imx27_dt_board_compat[] __initdata = { + "fsl,imx27", + NULL +}; + +DT_MACHINE_START(IMX27_DT, "Freescale i.MX27 (Device Tree Support)") + .map_io = mx27_map_io, + .init_early = imx27_init_early, + .init_irq = mx27_init_irq, + .handle_irq = imx27_handle_irq, + .timer = &imx27_timer, + .init_machine = imx27_dt_init, + .dt_compat = imx27_dt_board_compat, + .restart = mxc_restart, +MACHINE_END diff --git a/arch/arm/mach-imx/imx51-dt.c b/arch/arm/mach-imx/imx51-dt.c index 1e03ef42faa0..5cca573964f0 100644 --- a/arch/arm/mach-imx/imx51-dt.c +++ b/arch/arm/mach-imx/imx51-dt.c @@ -104,6 +104,7 @@ static struct sys_timer imx51_timer = { static const char *imx51_dt_board_compat[] __initdata = { "fsl,imx51-babbage", + "fsl,imx51", NULL }; diff --git a/arch/arm/mach-imx/imx53-dt.c b/arch/arm/mach-imx/imx53-dt.c index fd5be0f20fbb..4172279b3900 100644 --- a/arch/arm/mach-imx/imx53-dt.c +++ b/arch/arm/mach-imx/imx53-dt.c @@ -114,6 +114,7 @@ static const char *imx53_dt_board_compat[] __initdata = { "fsl,imx53-evk", "fsl,imx53-qsb", "fsl,imx53-smd", + "fsl,imx53", NULL }; diff --git a/arch/arm/mach-imx/include/mach/dma-v1.h b/arch/arm/mach-imx/include/mach/dma-v1.h deleted file mode 100644 index ac6fd713828a..000000000000 --- a/arch/arm/mach-imx/include/mach/dma-v1.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * linux/arch/arm/mach-imx/include/mach/dma-v1.h - * - * i.MX DMA registration and IRQ dispatching - * - * Copyright 2006 Pavel Pisa <pisa@cmp.felk.cvut.cz> - * Copyright 2008 Juergen Beisert, <kernel@pengutronix.de> - * Copyright 2008 Sascha Hauer, <s.hauer@pengutronix.de> - * - * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#ifndef __MACH_DMA_V1_H__ -#define __MACH_DMA_V1_H__ - -#define imx_has_dma_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27()) - -#include <mach/dma.h> - -#define IMX_DMA_CHANNELS 16 - -#define DMA_MODE_READ 0 -#define DMA_MODE_WRITE 1 -#define DMA_MODE_MASK 1 - -#define MX1_DMA_REG(offset) MX1_IO_ADDRESS(MX1_DMA_BASE_ADDR + (offset)) - -/* DMA Interrupt Mask Register */ -#define MX1_DMA_DIMR MX1_DMA_REG(0x08) - -/* Channel Control Register */ -#define MX1_DMA_CCR(x) MX1_DMA_REG(0x8c + ((x) << 6)) - -#define IMX_DMA_MEMSIZE_32 (0 << 4) -#define IMX_DMA_MEMSIZE_8 (1 << 4) -#define IMX_DMA_MEMSIZE_16 (2 << 4) -#define IMX_DMA_TYPE_LINEAR (0 << 10) -#define IMX_DMA_TYPE_2D (1 << 10) -#define IMX_DMA_TYPE_FIFO (2 << 10) - -#define IMX_DMA_ERR_BURST (1 << 0) -#define IMX_DMA_ERR_REQUEST (1 << 1) -#define IMX_DMA_ERR_TRANSFER (1 << 2) -#define IMX_DMA_ERR_BUFFER (1 << 3) -#define IMX_DMA_ERR_TIMEOUT (1 << 4) - -int -imx_dma_config_channel(int channel, unsigned int config_port, - unsigned int config_mem, unsigned int dmareq, int hw_chaining); - -void -imx_dma_config_burstlen(int channel, unsigned int burstlen); - -int -imx_dma_setup_single(int channel, dma_addr_t dma_address, - unsigned int dma_length, unsigned int dev_addr, - unsigned int dmamode); - - -/* - * Use this flag as the dma_length argument to imx_dma_setup_sg() - * to create an endless running dma loop. The end of the scatterlist - * must be linked to the beginning for this to work. - */ -#define IMX_DMA_LENGTH_LOOP ((unsigned int)-1) - -int -imx_dma_setup_sg(int channel, struct scatterlist *sg, - unsigned int sgcount, unsigned int dma_length, - unsigned int dev_addr, unsigned int dmamode); - -int -imx_dma_setup_handlers(int channel, - void (*irq_handler) (int, void *), - void (*err_handler) (int, void *, int), void *data); - -int -imx_dma_setup_progression_handler(int channel, - void (*prog_handler) (int, void*, struct scatterlist*)); - -void imx_dma_enable(int channel); - -void imx_dma_disable(int channel); - -int imx_dma_request(int channel, const char *name); - -void imx_dma_free(int channel); - -int imx_dma_request_by_prio(const char *name, enum imx_dma_prio prio); - -#endif /* __MACH_DMA_V1_H__ */ diff --git a/arch/arm/mach-imx/lluart.c b/arch/arm/mach-imx/lluart.c index d4ab6f29a766..0213f8dcee81 100644 --- a/arch/arm/mach-imx/lluart.c +++ b/arch/arm/mach-imx/lluart.c @@ -17,7 +17,7 @@ #include <mach/hardware.h> static struct map_desc imx_lluart_desc = { -#ifdef CONFIG_DEBUG_IMX6Q_UART +#ifdef CONFIG_DEBUG_IMX6Q_UART4 .virtual = MX6Q_IO_P2V(MX6Q_UART4_BASE_ADDR), .pfn = __phys_to_pfn(MX6Q_UART4_BASE_ADDR), .length = MX6Q_UART4_SIZE, diff --git a/arch/arm/mach-imx/localtimer.c b/arch/arm/mach-imx/localtimer.c deleted file mode 100644 index 3a163515d41f..000000000000 --- a/arch/arm/mach-imx/localtimer.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. - * Copyright 2011 Linaro Ltd. - * - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#include <linux/init.h> -#include <linux/clockchips.h> -#include <linux/of_address.h> -#include <linux/of_irq.h> -#include <asm/smp_twd.h> - -/* - * Setup the local clock events for a CPU. - */ -int __cpuinit local_timer_setup(struct clock_event_device *evt) -{ - struct device_node *np; - - np = of_find_compatible_node(NULL, NULL, "arm,smp-twd"); - if (!twd_base) { - twd_base = of_iomap(np, 0); - WARN_ON(!twd_base); - } - evt->irq = irq_of_parse_and_map(np, 0); - twd_timer_setup(evt); - - return 0; -} diff --git a/arch/arm/mach-imx/mach-armadillo5x0.c b/arch/arm/mach-imx/mach-armadillo5x0.c index e4f426a09899..c650145d1646 100644 --- a/arch/arm/mach-imx/mach-armadillo5x0.c +++ b/arch/arm/mach-imx/mach-armadillo5x0.c @@ -38,6 +38,8 @@ #include <linux/usb/otg.h> #include <linux/usb/ulpi.h> #include <linux/delay.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/fixed.h> #include <mach/hardware.h> #include <asm/mach-types.h> @@ -51,7 +53,7 @@ #include <mach/ulpi.h> #include "devices-imx31.h" -#include "crmregs-imx31.h" +#include "crmregs-imx3.h" static int armadillo5x0_pins[] = { /* UART1 */ @@ -479,6 +481,11 @@ static struct platform_device *devices[] __initdata = { &armadillo5x0_smc911x_device, }; +static struct regulator_consumer_supply dummy_supplies[] = { + REGULATOR_SUPPLY("vdd33a", "smsc911x"), + REGULATOR_SUPPLY("vddvario", "smsc911x"), +}; + /* * Perform board specific initializations */ @@ -489,6 +496,8 @@ static void __init armadillo5x0_init(void) mxc_iomux_setup_multiple_pins(armadillo5x0_pins, ARRAY_SIZE(armadillo5x0_pins), "armadillo5x0"); + regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); + platform_add_devices(devices, ARRAY_SIZE(devices)); imx_add_gpio_keys(&armadillo5x0_button_data); imx31_add_imx_i2c1(NULL); diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c index 428459fbca4b..f7b074f496f0 100644 --- a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c +++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c @@ -30,6 +30,10 @@ #include <linux/input.h> #include <linux/gpio.h> #include <linux/delay.h> +#include <linux/dma-mapping.h> +#include <linux/leds.h> +#include <linux/memblock.h> +#include <media/soc_camera.h> #include <sound/tlv320aic32x4.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -39,6 +43,8 @@ #include "devices-imx27.h" +#define TVP5150_RSTN (GPIO_PORTC + 18) +#define TVP5150_PWDN (GPIO_PORTC + 19) #define OTG_PHY_CS_GPIO (GPIO_PORTF + 17) #define SDHC1_IRQ IRQ_GPIOB(25) @@ -100,8 +106,99 @@ static const int visstrim_m10_pins[] __initconst = { PE1_PF_USBOTG_STP, PB23_PF_USB_PWR, PB24_PF_USB_OC, + /* CSI */ + PB10_PF_CSI_D0, + PB11_PF_CSI_D1, + PB12_PF_CSI_D2, + PB13_PF_CSI_D3, + PB14_PF_CSI_D4, + PB15_PF_CSI_MCLK, + PB16_PF_CSI_PIXCLK, + PB17_PF_CSI_D5, + PB18_PF_CSI_D6, + PB19_PF_CSI_D7, + PB20_PF_CSI_VSYNC, + PB21_PF_CSI_HSYNC, }; +/* Camera */ +static int visstrim_camera_power(struct device *dev, int on) +{ + gpio_set_value(TVP5150_PWDN, on); + + return 0; +}; + +static int visstrim_camera_reset(struct device *dev) +{ + gpio_set_value(TVP5150_RSTN, 0); + ndelay(500); + gpio_set_value(TVP5150_RSTN, 1); + + return 0; +}; + +static struct i2c_board_info visstrim_i2c_camera = { + I2C_BOARD_INFO("tvp5150", 0x5d), +}; + +static struct soc_camera_link iclink_tvp5150 = { + .bus_id = 0, + .board_info = &visstrim_i2c_camera, + .i2c_adapter_id = 0, + .power = visstrim_camera_power, + .reset = visstrim_camera_reset, +}; + +static struct mx2_camera_platform_data visstrim_camera = { + .flags = MX2_CAMERA_CCIR | MX2_CAMERA_CCIR_INTERLACE | + MX2_CAMERA_SWAP16 | MX2_CAMERA_PCLK_SAMPLE_RISING, + .clk = 100000, +}; + +static phys_addr_t mx2_camera_base __initdata; +#define MX2_CAMERA_BUF_SIZE SZ_8M + +static void __init visstrim_camera_init(void) +{ + struct platform_device *pdev; + int dma; + + /* Initialize tvp5150 gpios */ + mxc_gpio_mode(TVP5150_RSTN | GPIO_GPIO | GPIO_OUT); + mxc_gpio_mode(TVP5150_PWDN | GPIO_GPIO | GPIO_OUT); + gpio_set_value(TVP5150_RSTN, 1); + gpio_set_value(TVP5150_PWDN, 0); + ndelay(1); + + gpio_set_value(TVP5150_PWDN, 1); + ndelay(1); + gpio_set_value(TVP5150_RSTN, 0); + ndelay(500); + gpio_set_value(TVP5150_RSTN, 1); + ndelay(200000); + + pdev = imx27_add_mx2_camera(&visstrim_camera); + if (IS_ERR(pdev)) + return; + + dma = dma_declare_coherent_memory(&pdev->dev, + mx2_camera_base, mx2_camera_base, + MX2_CAMERA_BUF_SIZE, + DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE); + if (!(dma & DMA_MEMORY_MAP)) + return; +} + +static void __init visstrim_reserve(void) +{ + /* reserve 4 MiB for mx2-camera */ + mx2_camera_base = memblock_alloc(MX2_CAMERA_BUF_SIZE, + MX2_CAMERA_BUF_SIZE); + memblock_free(mx2_camera_base, MX2_CAMERA_BUF_SIZE); + memblock_remove(mx2_camera_base, MX2_CAMERA_BUF_SIZE); +} + /* GPIOs used as events for applications */ static struct gpio_keys_button visstrim_gpio_keys[] = { { @@ -136,6 +233,35 @@ static const struct gpio_keys_platform_data .nbuttons = ARRAY_SIZE(visstrim_gpio_keys), }; +/* led */ +static const struct gpio_led visstrim_m10_leds[] __initconst = { + { + .name = "visstrim:ld0", + .default_trigger = "nand-disk", + .gpio = (GPIO_PORTC + 29), + }, + { + .name = "visstrim:ld1", + .default_trigger = "nand-disk", + .gpio = (GPIO_PORTC + 24), + }, + { + .name = "visstrim:ld2", + .default_trigger = "nand-disk", + .gpio = (GPIO_PORTC + 28), + }, + { + .name = "visstrim:ld3", + .default_trigger = "nand-disk", + .gpio = (GPIO_PORTC + 25), + }, +}; + +static const struct gpio_led_platform_data visstrim_m10_led_data __initconst = { + .leds = visstrim_m10_leds, + .num_leds = ARRAY_SIZE(visstrim_m10_leds), +}; + /* Visstrim_SM10 has a microSD slot connected to sdhc1 */ static int visstrim_m10_sdhc1_init(struct device *dev, irq_handler_t detect_irq, void *data) @@ -216,6 +342,9 @@ static struct i2c_board_info visstrim_m10_i2c_devices[] = { { I2C_BOARD_INFO("tlv320aic32x4", 0x18), .platform_data = &visstrim_m10_aic32x4_pdata, + }, + { + I2C_BOARD_INFO("m41t00", 0x68), } }; @@ -254,16 +383,21 @@ static void __init visstrim_m10_board_init(void) imx27_add_imx_ssi(0, &visstrim_m10_ssi_pdata); imx27_add_imx_uart0(&uart_pdata); - i2c_register_board_info(0, visstrim_m10_i2c_devices, - ARRAY_SIZE(visstrim_m10_i2c_devices)); imx27_add_imx_i2c(0, &visstrim_m10_i2c_data); imx27_add_imx_i2c(1, &visstrim_m10_i2c_data); + i2c_register_board_info(0, visstrim_m10_i2c_devices, + ARRAY_SIZE(visstrim_m10_i2c_devices)); + imx27_add_mxc_mmc(0, &visstrim_m10_sdhc_pdata); imx27_add_mxc_ehci_otg(&visstrim_m10_usbotg_pdata); imx27_add_fec(NULL); imx_add_gpio_keys(&visstrim_gpio_keys_platform_data); platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); imx_add_platform_device("mx27vis", 0, NULL, 0, NULL, 0); + platform_device_register_resndata(NULL, "soc-camera-pdrv", 0, NULL, 0, + &iclink_tvp5150, sizeof(iclink_tvp5150)); + gpio_led_register_device(0, &visstrim_m10_led_data); + visstrim_camera_init(); } static void __init visstrim_m10_timer_init(void) @@ -277,6 +411,7 @@ static struct sys_timer visstrim_m10_timer = { MACHINE_START(IMX27_VISSTRIM_M10, "Vista Silicon Visstrim_M10") .atag_offset = 0x100, + .reserve = visstrim_reserve, .map_io = mx27_map_io, .init_early = imx27_init_early, .init_irq = mx27_init_irq, diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 6075d4d62dd6..da6c1d9af768 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -21,10 +21,12 @@ #include <linux/of_platform.h> #include <linux/phy.h> #include <linux/micrel_phy.h> +#include <asm/smp_twd.h> #include <asm/hardware/cache-l2x0.h> #include <asm/hardware/gic.h> #include <asm/mach/arch.h> #include <asm/mach/time.h> +#include <asm/system_misc.h> #include <mach/common.h> #include <mach/hardware.h> @@ -120,6 +122,7 @@ static void __init imx6q_init_irq(void) static void __init imx6q_timer_init(void) { mx6q_clocks_init(); + twd_local_timer_of_register(); } static struct sys_timer imx6q_timer = { @@ -129,6 +132,7 @@ static struct sys_timer imx6q_timer = { static const char *imx6q_dt_compat[] __initdata = { "fsl,imx6q-arm2", "fsl,imx6q-sabrelite", + "fsl,imx6q", NULL, }; diff --git a/arch/arm/mach-imx/mach-kzm_arm11_01.c b/arch/arm/mach-imx/mach-kzm_arm11_01.c index fc78e8071cd1..15a26e908260 100644 --- a/arch/arm/mach-imx/mach-kzm_arm11_01.c +++ b/arch/arm/mach-imx/mach-kzm_arm11_01.c @@ -24,6 +24,8 @@ #include <linux/serial_8250.h> #include <linux/smsc911x.h> #include <linux/types.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/fixed.h> #include <asm/irq.h> #include <asm/mach-types.h> @@ -166,6 +168,11 @@ static struct platform_device kzm_smsc9118_device = { }, }; +static struct regulator_consumer_supply dummy_supplies[] = { + REGULATOR_SUPPLY("vdd33a", "smsc911x"), + REGULATOR_SUPPLY("vddvario", "smsc911x"), +}; + static int __init kzm_init_smsc9118(void) { /* @@ -175,6 +182,8 @@ static int __init kzm_init_smsc9118(void) gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2), "smsc9118-int"); gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2)); + regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); + return platform_device_register(&kzm_smsc9118_device); } #else diff --git a/arch/arm/mach-imx/mach-mx21ads.c b/arch/arm/mach-imx/mach-mx21ads.c index 8d9f95514b1f..e432d4acee1f 100644 --- a/arch/arm/mach-imx/mach-mx21ads.c +++ b/arch/arm/mach-imx/mach-mx21ads.c @@ -37,8 +37,8 @@ #define MX21ADS_REG_ADDR(offset) (void __force __iomem *) \ (MX21ADS_MMIO_BASE_ADDR + (offset)) +#define MX21ADS_CS8900A_MMIO_SIZE 0x200000 #define MX21ADS_CS8900A_IRQ IRQ_GPIOE(11) -#define MX21ADS_CS8900A_IOBASE_REG MX21ADS_REG_ADDR(0x000000) #define MX21ADS_ST16C255_IOBASE_REG MX21ADS_REG_ADDR(0x200000) #define MX21ADS_VERSION_REG MX21ADS_REG_ADDR(0x400000) #define MX21ADS_IO_REG MX21ADS_REG_ADDR(0x800000) @@ -159,6 +159,18 @@ static struct platform_device mx21ads_nor_mtd_device = { .resource = &mx21ads_flash_resource, }; +static const struct resource mx21ads_cs8900_resources[] __initconst = { + DEFINE_RES_MEM(MX21_CS1_BASE_ADDR, MX21ADS_CS8900A_MMIO_SIZE), + DEFINE_RES_IRQ(MX21ADS_CS8900A_IRQ), +}; + +static const struct platform_device_info mx21ads_cs8900_devinfo __initconst = { + .name = "cs89x0", + .id = 0, + .res = mx21ads_cs8900_resources, + .num_res = ARRAY_SIZE(mx21ads_cs8900_resources), +}; + static const struct imxuart_platform_data uart_pdata_rts __initconst = { .flags = IMXUART_HAVE_RTSCTS, }; @@ -292,6 +304,8 @@ static void __init mx21ads_board_init(void) imx21_add_mxc_nand(&mx21ads_nand_board_info); platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); + platform_device_register_full( + (struct platform_device_info *)&mx21ads_cs8900_devinfo); } static void __init mx21ads_timer_init(void) diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c index 18f35816706a..c6d385c52257 100644 --- a/arch/arm/mach-imx/mach-mx27_3ds.c +++ b/arch/arm/mach-imx/mach-mx27_3ds.c @@ -31,6 +31,8 @@ #include <linux/regulator/machine.h> #include <linux/spi/l4f00242t03.h> +#include <media/soc_camera.h> + #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/time.h> @@ -52,6 +54,8 @@ #define SD1_CD IMX_GPIO_NR(2, 26) #define LCD_RESET IMX_GPIO_NR(1, 3) #define LCD_ENABLE IMX_GPIO_NR(1, 31) +#define CSI_PWRDWN IMX_GPIO_NR(4, 19) +#define CSI_RESET IMX_GPIO_NR(3, 6) static const int mx27pdk_pins[] __initconst = { /* UART1 */ @@ -141,6 +145,26 @@ static const int mx27pdk_pins[] __initconst = { PA30_PF_CONTRAST, LCD_ENABLE | GPIO_GPIO | GPIO_OUT, LCD_RESET | GPIO_GPIO | GPIO_OUT, + /* CSI */ + PB10_PF_CSI_D0, + PB11_PF_CSI_D1, + PB12_PF_CSI_D2, + PB13_PF_CSI_D3, + PB14_PF_CSI_D4, + PB15_PF_CSI_MCLK, + PB16_PF_CSI_PIXCLK, + PB17_PF_CSI_D5, + PB18_PF_CSI_D6, + PB19_PF_CSI_D7, + PB20_PF_CSI_VSYNC, + PB21_PF_CSI_HSYNC, + CSI_PWRDWN | GPIO_GPIO | GPIO_OUT, + CSI_RESET | GPIO_GPIO | GPIO_OUT, +}; + +static struct gpio mx27_3ds_camera_gpios[] = { + { CSI_PWRDWN, GPIOF_OUT_INIT_HIGH, "camera-power" }, + { CSI_RESET, GPIOF_OUT_INIT_HIGH, "camera-reset" }, }; static const struct imxuart_platform_data uart_pdata __initconst = { @@ -242,6 +266,7 @@ static struct regulator_init_data gpo_init = { static struct regulator_consumer_supply vmmc1_consumers[] = { REGULATOR_SUPPLY("vcore", "spi0.0"), + REGULATOR_SUPPLY("cmos_2v8", "soc-camera-pdrv.0"), }; static struct regulator_init_data vmmc1_init = { @@ -270,6 +295,22 @@ static struct regulator_init_data vgen_init = { .consumer_supplies = vgen_consumers, }; +static struct regulator_consumer_supply vvib_consumers[] = { + REGULATOR_SUPPLY("cmos_vcore", "soc-camera-pdrv.0"), +}; + +static struct regulator_init_data vvib_init = { + .constraints = { + .min_uV = 1300000, + .max_uV = 1300000, + .apply_uV = 1, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(vvib_consumers), + .consumer_supplies = vvib_consumers, +}; + static struct mc13xxx_regulator_init_data mx27_3ds_regulators[] = { { .id = MC13783_REG_VMMC1, @@ -283,6 +324,9 @@ static struct mc13xxx_regulator_init_data mx27_3ds_regulators[] = { }, { .id = MC13783_REG_GPO3, /* Turn on 3.3V */ .init_data = &gpo_init, + }, { + .id = MC13783_REG_VVIB, /* Power OV2640 */ + .init_data = &vvib_init, }, }; @@ -311,6 +355,51 @@ static const struct spi_imx_master spi2_pdata __initconst = { .num_chipselect = ARRAY_SIZE(spi2_chipselect), }; +static int mx27_3ds_camera_power(struct device *dev, int on) +{ + /* enable or disable the camera */ + pr_debug("%s: %s the camera\n", __func__, on ? "ENABLE" : "DISABLE"); + gpio_set_value(CSI_PWRDWN, on ? 0 : 1); + + if (!on) + goto out; + + /* If enabled, give a reset impulse */ + gpio_set_value(CSI_RESET, 0); + msleep(20); + gpio_set_value(CSI_RESET, 1); + msleep(100); + +out: + return 0; +} + +static struct i2c_board_info mx27_3ds_i2c_camera = { + I2C_BOARD_INFO("ov2640", 0x30), +}; + +static struct regulator_bulk_data mx27_3ds_camera_regs[] = { + { .supply = "cmos_vcore" }, + { .supply = "cmos_2v8" }, +}; + +static struct soc_camera_link iclink_ov2640 = { + .bus_id = 0, + .board_info = &mx27_3ds_i2c_camera, + .i2c_adapter_id = 0, + .power = mx27_3ds_camera_power, + .regulators = mx27_3ds_camera_regs, + .num_regulators = ARRAY_SIZE(mx27_3ds_camera_regs), +}; + +static struct platform_device mx27_3ds_ov2640 = { + .name = "soc-camera-pdrv", + .id = 0, + .dev = { + .platform_data = &iclink_ov2640, + }, +}; + static struct imx_fb_videomode mx27_3ds_modes[] = { { /* 480x640 @ 60 Hz */ .mode = { @@ -367,12 +456,21 @@ static struct spi_board_info mx27_3ds_spi_devs[] __initdata = { }, }; +static struct platform_device *devices[] __initdata = { + &mx27_3ds_ov2640, +}; + +static const struct mx2_camera_platform_data mx27_3ds_cam_pdata __initconst = { + .clk = 26000000, +}; + static const struct imxi2c_platform_data mx27_3ds_i2c0_data __initconst = { .bitrate = 100000, }; static void __init mx27pdk_init(void) { + int ret; imx27_soc_init(); mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins), @@ -404,7 +502,17 @@ static void __init mx27pdk_init(void) if (mxc_expio_init(MX27_CS5_BASE_ADDR, EXPIO_PARENT_INT)) pr_warn("Init of the debugboard failed, all devices on the debugboard are unusable.\n"); imx27_add_imx_i2c(0, &mx27_3ds_i2c0_data); + platform_add_devices(devices, ARRAY_SIZE(devices)); imx27_add_imx_fb(&mx27_3ds_fb_data); + + ret = gpio_request_array(mx27_3ds_camera_gpios, + ARRAY_SIZE(mx27_3ds_camera_gpios)); + if (ret) { + pr_err("Failed to request camera gpios"); + iclink_ov2640.power = NULL; + } + + imx27_add_mx2_camera(&mx27_3ds_cam_pdata); } static void __init mx27pdk_timer_init(void) diff --git a/arch/arm/mach-imx/mach-mx31ads.c b/arch/arm/mach-imx/mach-mx31ads.c index 4917aab0e253..4518e5448227 100644 --- a/arch/arm/mach-imx/mach-mx31ads.c +++ b/arch/arm/mach-imx/mach-mx31ads.c @@ -28,7 +28,6 @@ #include <asm/memory.h> #include <asm/mach/map.h> #include <mach/common.h> -#include <mach/board-mx31ads.h> #include <mach/iomux-mx3.h> #ifdef CONFIG_MACH_MX31ADS_WM1133_EV1 @@ -39,6 +38,9 @@ #include "devices-imx31.h" +/* Base address of PBC controller */ +#define PBC_BASE_ADDRESS MX31_CS4_BASE_ADDR_VIRT + /* PBC Board interrupt status register */ #define PBC_INTSTATUS 0x000016 @@ -62,6 +64,7 @@ #define PBC_INTMASK_CLEAR_REG (PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS) #define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_4) +#define MXC_EXP_IO_BASE MXC_BOARD_IRQ_START #define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE) #define EXPIO_INT_XUART_INTA (MXC_EXP_IO_BASE + 10) @@ -69,6 +72,10 @@ #define MXC_MAX_EXP_IO_LINES 16 +/* CS8900 */ +#define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8) +#define CS4_CS8900_MMIO_START 0x20000 + /* * The serial port definition structure. */ @@ -101,11 +108,29 @@ static struct platform_device serial_device = { }, }; +static const struct resource mx31ads_cs8900_resources[] __initconst = { + DEFINE_RES_MEM(MX31_CS4_BASE_ADDR + CS4_CS8900_MMIO_START, SZ_64K), + DEFINE_RES_IRQ(EXPIO_INT_ENET_INT), +}; + +static const struct platform_device_info mx31ads_cs8900_devinfo __initconst = { + .name = "cs89x0", + .id = 0, + .res = mx31ads_cs8900_resources, + .num_res = ARRAY_SIZE(mx31ads_cs8900_resources), +}; + static int __init mxc_init_extuart(void) { return platform_device_register(&serial_device); } +static void __init mxc_init_ext_ethernet(void) +{ + platform_device_register_full( + (struct platform_device_info *)&mx31ads_cs8900_devinfo); +} + static const struct imxuart_platform_data uart_pdata __initconst = { .flags = IMXUART_HAVE_RTSCTS, }; @@ -492,12 +517,15 @@ static void __init mxc_init_audio(void) mxc_iomux_setup_multiple_pins(ssi_pins, ARRAY_SIZE(ssi_pins), "ssi"); } -/* static mappings */ +/* + * Static mappings, starting from the CS4 start address up to the start address + * of the CS8900. + */ static struct map_desc mx31ads_io_desc[] __initdata = { { .virtual = MX31_CS4_BASE_ADDR_VIRT, .pfn = __phys_to_pfn(MX31_CS4_BASE_ADDR), - .length = MX31_CS4_SIZE / 2, + .length = CS4_CS8900_MMIO_START, .type = MT_DEVICE }, }; @@ -522,6 +550,7 @@ static void __init mx31ads_init(void) mxc_init_imx_uart(); mxc_init_i2c(); mxc_init_audio(); + mxc_init_ext_ethernet(); } static void __init mx31ads_timer_init(void) diff --git a/arch/arm/mach-imx/mach-mx31lilly.c b/arch/arm/mach-imx/mach-mx31lilly.c index 02401bbd6d53..83714b0cc290 100644 --- a/arch/arm/mach-imx/mach-mx31lilly.c +++ b/arch/arm/mach-imx/mach-mx31lilly.c @@ -34,6 +34,8 @@ #include <linux/mfd/mc13783.h> #include <linux/usb/otg.h> #include <linux/usb/ulpi.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/fixed.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -242,6 +244,11 @@ static struct platform_device *devices[] __initdata = { static int mx31lilly_baseboard; core_param(mx31lilly_baseboard, mx31lilly_baseboard, int, 0444); +static struct regulator_consumer_supply dummy_supplies[] = { + REGULATOR_SUPPLY("vdd33a", "smsc911x"), + REGULATOR_SUPPLY("vddvario", "smsc911x"), +}; + static void __init mx31lilly_board_init(void) { imx31_soc_init(); @@ -280,6 +287,8 @@ static void __init mx31lilly_board_init(void) imx31_add_spi_imx1(&spi1_pdata); spi_register_board_info(&mc13783_dev, 1); + regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); + platform_add_devices(devices, ARRAY_SIZE(devices)); /* USB */ diff --git a/arch/arm/mach-imx/mach-mx31lite.c b/arch/arm/mach-imx/mach-mx31lite.c index ef80751712e7..0abef5f13df5 100644 --- a/arch/arm/mach-imx/mach-mx31lite.c +++ b/arch/arm/mach-imx/mach-mx31lite.c @@ -29,6 +29,8 @@ #include <linux/usb/ulpi.h> #include <linux/mtd/physmap.h> #include <linux/delay.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/fixed.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -226,6 +228,11 @@ void __init mx31lite_map_io(void) static int mx31lite_baseboard; core_param(mx31lite_baseboard, mx31lite_baseboard, int, 0444); +static struct regulator_consumer_supply dummy_supplies[] = { + REGULATOR_SUPPLY("vdd33a", "smsc911x"), + REGULATOR_SUPPLY("vddvario", "smsc911x"), +}; + static void __init mx31lite_init(void) { int ret; @@ -259,6 +266,8 @@ static void __init mx31lite_init(void) if (usbh2_pdata.otg) imx31_add_mxc_ehci_hs(2, &usbh2_pdata); + regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); + /* SMSC9117 IRQ pin */ ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_SFS6), "sms9117-irq"); if (ret) diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c index f225262b5c38..f17a15f28316 100644 --- a/arch/arm/mach-imx/mach-mx31moboard.c +++ b/arch/arm/mach-imx/mach-mx31moboard.c @@ -507,7 +507,7 @@ static void mx31moboard_poweroff(void) struct clk *clk = clk_get_sys("imx2-wdt.0", NULL); if (!IS_ERR(clk)) - clk_enable(clk); + clk_prepare_enable(clk); mxc_iomux_mode(MX31_PIN_WATCHDOG_RST__WATCHDOG_RST); @@ -530,6 +530,8 @@ static void __init mx31moboard_init(void) platform_add_devices(devices, ARRAY_SIZE(devices)); gpio_led_register_device(-1, &mx31moboard_led_pdata); + imx31_add_imx2_wdt(NULL); + imx31_add_imx_uart0(&uart0_pdata); imx31_add_imx_uart4(&uart4_pdata); @@ -590,7 +592,7 @@ static void __init mx31moboard_reserve(void) } MACHINE_START(MX31MOBOARD, "EPFL Mobots mx31moboard") - /* Maintainer: Valentin Longchamp, EPFL Mobots group */ + /* Maintainer: Philippe Retornaz, EPFL Mobots group */ .atag_offset = 0x100, .reserve = mx31moboard_reserve, .map_io = mx31_map_io, diff --git a/arch/arm/mach-imx/mach-mx35_3ds.c b/arch/arm/mach-imx/mach-mx35_3ds.c index 0af6c9c5b3fd..6ae51c6b95b7 100644 --- a/arch/arm/mach-imx/mach-mx35_3ds.c +++ b/arch/arm/mach-imx/mach-mx35_3ds.c @@ -4,6 +4,11 @@ * * Author: Fabio Estevam <fabio.estevam@freescale.com> * + * Copyright (C) 2011 Meprolight, Ltd. + * Alex Gershgorin <alexg@meprolight.com> + * + * Modified from i.MX31 3-Stack Development System + * * 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 @@ -34,15 +39,102 @@ #include <asm/mach/arch.h> #include <asm/mach/time.h> #include <asm/mach/map.h> +#include <asm/memblock.h> #include <mach/hardware.h> #include <mach/common.h> #include <mach/iomux-mx35.h> #include <mach/irqs.h> #include <mach/3ds_debugboard.h> +#include <video/platform_lcd.h> + +#include <media/soc_camera.h> #include "devices-imx35.h" +#define GPIO_MC9S08DZ60_GPS_ENABLE 0 +#define GPIO_MC9S08DZ60_HDD_ENABLE 4 +#define GPIO_MC9S08DZ60_WIFI_ENABLE 5 +#define GPIO_MC9S08DZ60_LCD_ENABLE 6 +#define GPIO_MC9S08DZ60_SPEAKER_ENABLE 8 + +static const struct fb_videomode fb_modedb[] = { + { + /* 800x480 @ 55 Hz */ + .name = "Ceramate-CLAA070VC01", + .refresh = 55, + .xres = 800, + .yres = 480, + .pixclock = 40000, + .left_margin = 40, + .right_margin = 40, + .upper_margin = 5, + .lower_margin = 5, + .hsync_len = 20, + .vsync_len = 10, + .sync = FB_SYNC_OE_ACT_HIGH, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, + }, +}; + +static const struct ipu_platform_data mx3_ipu_data __initconst = { + .irq_base = MXC_IPU_IRQ_START, +}; + +static struct mx3fb_platform_data mx3fb_pdata __initdata = { + .name = "Ceramate-CLAA070VC01", + .mode = fb_modedb, + .num_modes = ARRAY_SIZE(fb_modedb), +}; + +static struct i2c_board_info __initdata i2c_devices_3ds[] = { + { + I2C_BOARD_INFO("mc9s08dz60", 0x69), + }, +}; + +static int lcd_power_gpio = -ENXIO; + +static int mc9s08dz60_gpiochip_match(struct gpio_chip *chip, + const void *data) +{ + return !strcmp(chip->label, data); +} + +static void mx35_3ds_lcd_set_power( + struct plat_lcd_data *pd, unsigned int power) +{ + struct gpio_chip *chip; + + if (!gpio_is_valid(lcd_power_gpio)) { + chip = gpiochip_find( + "mc9s08dz60", mc9s08dz60_gpiochip_match); + if (chip) { + lcd_power_gpio = + chip->base + GPIO_MC9S08DZ60_LCD_ENABLE; + if (gpio_request(lcd_power_gpio, "lcd_power") < 0) { + pr_err("error: gpio already requested!\n"); + lcd_power_gpio = -ENXIO; + } + } else { + pr_err("error: didn't find mc9s08dz60 gpio chip\n"); + } + } + + if (gpio_is_valid(lcd_power_gpio)) + gpio_set_value_cansleep(lcd_power_gpio, power); +} + +static struct plat_lcd_data mx35_3ds_lcd_data = { + .set_power = mx35_3ds_lcd_set_power, +}; + +static struct platform_device mx35_3ds_lcd = { + .name = "platform-lcd", + .dev.platform_data = &mx35_3ds_lcd_data, +}; + #define EXPIO_PARENT_INT gpio_to_irq(IMX_GPIO_NR(1, 1)) static const struct imxuart_platform_data uart_pdata __initconst = { @@ -120,6 +212,109 @@ static iomux_v3_cfg_t mx35pdk_pads[] = { /* I2C1 */ MX35_PAD_I2C1_CLK__I2C1_SCL, MX35_PAD_I2C1_DAT__I2C1_SDA, + /* Display */ + MX35_PAD_LD0__IPU_DISPB_DAT_0, + MX35_PAD_LD1__IPU_DISPB_DAT_1, + MX35_PAD_LD2__IPU_DISPB_DAT_2, + MX35_PAD_LD3__IPU_DISPB_DAT_3, + MX35_PAD_LD4__IPU_DISPB_DAT_4, + MX35_PAD_LD5__IPU_DISPB_DAT_5, + MX35_PAD_LD6__IPU_DISPB_DAT_6, + MX35_PAD_LD7__IPU_DISPB_DAT_7, + MX35_PAD_LD8__IPU_DISPB_DAT_8, + MX35_PAD_LD9__IPU_DISPB_DAT_9, + MX35_PAD_LD10__IPU_DISPB_DAT_10, + MX35_PAD_LD11__IPU_DISPB_DAT_11, + MX35_PAD_LD12__IPU_DISPB_DAT_12, + MX35_PAD_LD13__IPU_DISPB_DAT_13, + MX35_PAD_LD14__IPU_DISPB_DAT_14, + MX35_PAD_LD15__IPU_DISPB_DAT_15, + MX35_PAD_LD16__IPU_DISPB_DAT_16, + MX35_PAD_LD17__IPU_DISPB_DAT_17, + MX35_PAD_D3_HSYNC__IPU_DISPB_D3_HSYNC, + MX35_PAD_D3_FPSHIFT__IPU_DISPB_D3_CLK, + MX35_PAD_D3_DRDY__IPU_DISPB_D3_DRDY, + MX35_PAD_CONTRAST__IPU_DISPB_CONTR, + MX35_PAD_D3_VSYNC__IPU_DISPB_D3_VSYNC, + MX35_PAD_D3_REV__IPU_DISPB_D3_REV, + MX35_PAD_D3_CLS__IPU_DISPB_D3_CLS, + /* CSI */ + MX35_PAD_TX1__IPU_CSI_D_6, + MX35_PAD_TX0__IPU_CSI_D_7, + MX35_PAD_CSI_D8__IPU_CSI_D_8, + MX35_PAD_CSI_D9__IPU_CSI_D_9, + MX35_PAD_CSI_D10__IPU_CSI_D_10, + MX35_PAD_CSI_D11__IPU_CSI_D_11, + MX35_PAD_CSI_D12__IPU_CSI_D_12, + MX35_PAD_CSI_D13__IPU_CSI_D_13, + MX35_PAD_CSI_D14__IPU_CSI_D_14, + MX35_PAD_CSI_D15__IPU_CSI_D_15, + MX35_PAD_CSI_HSYNC__IPU_CSI_HSYNC, + MX35_PAD_CSI_MCLK__IPU_CSI_MCLK, + MX35_PAD_CSI_PIXCLK__IPU_CSI_PIXCLK, + MX35_PAD_CSI_VSYNC__IPU_CSI_VSYNC, +}; + +/* + * Camera support +*/ +static phys_addr_t mx3_camera_base __initdata; +#define MX35_3DS_CAMERA_BUF_SIZE SZ_8M + +static const struct mx3_camera_pdata mx35_3ds_camera_pdata __initconst = { + .flags = MX3_CAMERA_DATAWIDTH_8, + .mclk_10khz = 2000, +}; + +static int __init imx35_3ds_init_camera(void) +{ + int dma, ret = -ENOMEM; + struct platform_device *pdev = + imx35_alloc_mx3_camera(&mx35_3ds_camera_pdata); + + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + + if (!mx3_camera_base) + goto err; + + dma = dma_declare_coherent_memory(&pdev->dev, + mx3_camera_base, mx3_camera_base, + MX35_3DS_CAMERA_BUF_SIZE, + DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE); + + if (!(dma & DMA_MEMORY_MAP)) + goto err; + + ret = platform_device_add(pdev); + if (ret) +err: + platform_device_put(pdev); + + return ret; +} + +static const struct ipu_platform_data mx35_3ds_ipu_data __initconst = { + .irq_base = MXC_IPU_IRQ_START, +}; + +static struct i2c_board_info mx35_3ds_i2c_camera = { + I2C_BOARD_INFO("ov2640", 0x30), +}; + +static struct soc_camera_link iclink_ov2640 = { + .bus_id = 0, + .board_info = &mx35_3ds_i2c_camera, + .i2c_adapter_id = 0, + .power = NULL, +}; + +static struct platform_device mx35_3ds_ov2640 = { + .name = "soc-camera-pdrv", + .id = 0, + .dev = { + .platform_data = &iclink_ov2640, + }, }; static int mx35_3ds_otg_init(struct platform_device *pdev) @@ -179,6 +374,8 @@ static const struct imxi2c_platform_data mx35_3ds_i2c0_data __initconst = { */ static void __init mx35_3ds_init(void) { + struct platform_device *imx35_fb_pdev; + imx35_soc_init(); mxc_iomux_v3_setup_multiple_pads(mx35pdk_pads, ARRAY_SIZE(mx35pdk_pads)); @@ -204,6 +401,17 @@ static void __init mx35_3ds_init(void) pr_warn("Init of the debugboard failed, all " "devices on the debugboard are unusable.\n"); imx35_add_imx_i2c0(&mx35_3ds_i2c0_data); + + i2c_register_board_info( + 0, i2c_devices_3ds, ARRAY_SIZE(i2c_devices_3ds)); + + imx35_add_ipu_core(&mx35_3ds_ipu_data); + platform_device_register(&mx35_3ds_ov2640); + imx35_3ds_init_camera(); + + imx35_fb_pdev = imx35_add_mx3_sdc_fb(&mx3fb_pdata); + mx35_3ds_lcd.dev.parent = &imx35_fb_pdev->dev; + platform_device_register(&mx35_3ds_lcd); } static void __init mx35pdk_timer_init(void) @@ -215,6 +423,13 @@ struct sys_timer mx35pdk_timer = { .init = mx35pdk_timer_init, }; +static void __init mx35_3ds_reserve(void) +{ + /* reserve MX35_3DS_CAMERA_BUF_SIZE bytes for mx3-camera */ + mx3_camera_base = arm_memblock_steal(MX35_3DS_CAMERA_BUF_SIZE, + MX35_3DS_CAMERA_BUF_SIZE); +} + MACHINE_START(MX35_3DS, "Freescale MX35PDK") /* Maintainer: Freescale Semiconductor, Inc */ .atag_offset = 0x100, @@ -224,5 +439,6 @@ MACHINE_START(MX35_3DS, "Freescale MX35PDK") .handle_irq = imx35_handle_irq, .timer = &mx35pdk_timer, .init_machine = mx35_3ds_init, + .reserve = mx35_3ds_reserve, .restart = mxc_restart, MACHINE_END diff --git a/arch/arm/mach-imx/mach-mx51_efikamx.c b/arch/arm/mach-imx/mach-mx51_efikamx.c index 3a5ed2dd885a..586e9f822124 100644 --- a/arch/arm/mach-imx/mach-mx51_efikamx.c +++ b/arch/arm/mach-imx/mach-mx51_efikamx.c @@ -33,6 +33,7 @@ #include <mach/iomux-mx51.h> #include <asm/setup.h> +#include <asm/system_info.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/time.h> diff --git a/arch/arm/mach-imx/mach-mx51_efikasb.c b/arch/arm/mach-imx/mach-mx51_efikasb.c index ea5f65b0381a..24aded9e109f 100644 --- a/arch/arm/mach-imx/mach-mx51_efikasb.c +++ b/arch/arm/mach-imx/mach-mx51_efikasb.c @@ -36,6 +36,7 @@ #include <mach/iomux-mx51.h> #include <asm/setup.h> +#include <asm/system_info.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/time.h> diff --git a/arch/arm/mach-imx/mach-mx53_ard.c b/arch/arm/mach-imx/mach-mx53_ard.c index 753f4fc9ec04..05641980dc5e 100644 --- a/arch/arm/mach-imx/mach-mx53_ard.c +++ b/arch/arm/mach-imx/mach-mx53_ard.c @@ -23,6 +23,8 @@ #include <linux/delay.h> #include <linux/gpio.h> #include <linux/smsc911x.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/fixed.h> #include <mach/common.h> #include <mach/hardware.h> @@ -214,6 +216,11 @@ static int weim_cs_config(void) return 0; } +static struct regulator_consumer_supply dummy_supplies[] = { + REGULATOR_SUPPLY("vdd33a", "smsc911x"), + REGULATOR_SUPPLY("vddvario", "smsc911x"), +}; + void __init imx53_ard_common_init(void) { mxc_iomux_v3_setup_multiple_pads(mx53_ard_pads, @@ -232,6 +239,7 @@ static void __init mx53_ard_board_init(void) imx53_ard_common_init(); mx53_ard_io_init(); + regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); platform_add_devices(devices, ARRAY_SIZE(devices)); imx53_add_sdhci_esdhc_imx(0, &mx53_ard_sd1_data); diff --git a/arch/arm/mach-imx/mach-pcm038.c b/arch/arm/mach-imx/mach-pcm038.c index 16f126da9f8f..2f3debe2a113 100644 --- a/arch/arm/mach-imx/mach-pcm038.c +++ b/arch/arm/mach-imx/mach-pcm038.c @@ -233,7 +233,7 @@ static struct regulator_init_data sdhc1_data = { static struct regulator_consumer_supply cam_consumers[] = { { - .dev = NULL, + .dev_name = NULL, .supply = "imx_cam_vcc", }, }; diff --git a/arch/arm/mach-imx/mm-imx3.c b/arch/arm/mach-imx/mm-imx3.c index 2530c151b7b3..74127389e7ab 100644 --- a/arch/arm/mach-imx/mm-imx3.c +++ b/arch/arm/mach-imx/mm-imx3.c @@ -21,6 +21,7 @@ #include <linux/err.h> #include <asm/pgtable.h> +#include <asm/system_misc.h> #include <asm/hardware/cache-l2x0.h> #include <asm/mach/map.h> @@ -34,35 +35,35 @@ static void imx3_idle(void) { unsigned long reg = 0; - if (!need_resched()) - __asm__ __volatile__( - /* disable I and D cache */ - "mrc p15, 0, %0, c1, c0, 0\n" - "bic %0, %0, #0x00001000\n" - "bic %0, %0, #0x00000004\n" - "mcr p15, 0, %0, c1, c0, 0\n" - /* invalidate I cache */ - "mov %0, #0\n" - "mcr p15, 0, %0, c7, c5, 0\n" - /* clear and invalidate D cache */ - "mov %0, #0\n" - "mcr p15, 0, %0, c7, c14, 0\n" - /* WFI */ - "mov %0, #0\n" - "mcr p15, 0, %0, c7, c0, 4\n" - "nop\n" "nop\n" "nop\n" "nop\n" - "nop\n" "nop\n" "nop\n" - /* enable I and D cache */ - "mrc p15, 0, %0, c1, c0, 0\n" - "orr %0, %0, #0x00001000\n" - "orr %0, %0, #0x00000004\n" - "mcr p15, 0, %0, c1, c0, 0\n" - : "=r" (reg)); - local_irq_enable(); + mx3_cpu_lp_set(MX3_WAIT); + + __asm__ __volatile__( + /* disable I and D cache */ + "mrc p15, 0, %0, c1, c0, 0\n" + "bic %0, %0, #0x00001000\n" + "bic %0, %0, #0x00000004\n" + "mcr p15, 0, %0, c1, c0, 0\n" + /* invalidate I cache */ + "mov %0, #0\n" + "mcr p15, 0, %0, c7, c5, 0\n" + /* clear and invalidate D cache */ + "mov %0, #0\n" + "mcr p15, 0, %0, c7, c14, 0\n" + /* WFI */ + "mov %0, #0\n" + "mcr p15, 0, %0, c7, c0, 4\n" + "nop\n" "nop\n" "nop\n" "nop\n" + "nop\n" "nop\n" "nop\n" + /* enable I and D cache */ + "mrc p15, 0, %0, c1, c0, 0\n" + "orr %0, %0, #0x00001000\n" + "orr %0, %0, #0x00000004\n" + "mcr p15, 0, %0, c1, c0, 0\n" + : "=r" (reg)); } -static void __iomem *imx3_ioremap(unsigned long phys_addr, size_t size, - unsigned int mtype) +static void __iomem *imx3_ioremap_caller(unsigned long phys_addr, size_t size, + unsigned int mtype, void *caller) { if (mtype == MT_DEVICE) { /* @@ -75,10 +76,10 @@ static void __iomem *imx3_ioremap(unsigned long phys_addr, size_t size, mtype = MT_DEVICE_NONSHARED; } - return __arm_ioremap(phys_addr, size, mtype); + return __arm_ioremap_caller(phys_addr, size, mtype, caller); } -void imx3_init_l2x0(void) +void __init imx3_init_l2x0(void) { void __iomem *l2x0_base; void __iomem *clkctl_base; @@ -134,8 +135,8 @@ void __init imx31_init_early(void) { mxc_set_cpu_type(MXC_CPU_MX31); mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR)); - pm_idle = imx3_idle; - imx_ioremap = imx3_ioremap; + arch_ioremap_caller = imx3_ioremap_caller; + arm_pm_idle = imx3_idle; } void __init mx31_init_irq(void) @@ -179,6 +180,10 @@ void __init imx31_soc_init(void) } imx_add_imx_sdma("imx31-sdma", MX31_SDMA_BASE_ADDR, MX31_INT_SDMA, &imx31_sdma_pdata); + + imx_set_aips(MX31_IO_ADDRESS(MX31_AIPS1_BASE_ADDR)); + imx_set_aips(MX31_IO_ADDRESS(MX31_AIPS2_BASE_ADDR)); + platform_device_register_simple("imx31-audmux", 0, imx31_audmux_res, ARRAY_SIZE(imx31_audmux_res)); } @@ -203,8 +208,8 @@ void __init imx35_init_early(void) mxc_set_cpu_type(MXC_CPU_MX35); mxc_iomux_v3_init(MX35_IO_ADDRESS(MX35_IOMUXC_BASE_ADDR)); mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR)); - pm_idle = imx3_idle; - imx_ioremap = imx3_ioremap; + arm_pm_idle = imx3_idle; + arch_ioremap_caller = imx3_ioremap_caller; } void __init mx35_init_irq(void) @@ -269,6 +274,11 @@ void __init imx35_soc_init(void) } imx_add_imx_sdma("imx35-sdma", MX35_SDMA_BASE_ADDR, MX35_INT_SDMA, &imx35_sdma_pdata); + + /* Setup AIPS registers */ + imx_set_aips(MX35_IO_ADDRESS(MX35_AIPS1_BASE_ADDR)); + imx_set_aips(MX35_IO_ADDRESS(MX35_AIPS2_BASE_ADDR)); + /* i.mx35 has the i.mx31 type audmux */ platform_device_register_simple("imx31-audmux", 0, imx35_audmux_res, ARRAY_SIZE(imx35_audmux_res)); diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c index 90d7880bb372..05250aed61fb 100644 --- a/arch/arm/mach-imx/mm-imx5.c +++ b/arch/arm/mach-imx/mm-imx5.c @@ -15,6 +15,7 @@ #include <linux/init.h> #include <linux/clk.h> +#include <asm/system_misc.h> #include <asm/mach/map.h> #include <mach/hardware.h> @@ -26,23 +27,17 @@ static struct clk *gpc_dvfs_clk; static void imx5_idle(void) { - if (!need_resched()) { - /* gpc clock is needed for SRPG */ - if (gpc_dvfs_clk == NULL) { - gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs"); - if (IS_ERR(gpc_dvfs_clk)) - goto err0; - } - clk_enable(gpc_dvfs_clk); - mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); - if (tzic_enable_wake()) - goto err1; - cpu_do_idle(); -err1: - clk_disable(gpc_dvfs_clk); + /* gpc clock is needed for SRPG */ + if (gpc_dvfs_clk == NULL) { + gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs"); + if (IS_ERR(gpc_dvfs_clk)) + return; } -err0: - local_irq_enable(); + clk_enable(gpc_dvfs_clk); + mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); + if (tzic_enable_wake() != 0) + cpu_do_idle(); + clk_disable(gpc_dvfs_clk); } /* @@ -108,7 +103,7 @@ void __init imx51_init_early(void) mxc_set_cpu_type(MXC_CPU_MX51); mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR)); mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR)); - pm_idle = imx5_idle; + arm_pm_idle = imx5_idle; } void __init imx53_init_early(void) @@ -207,6 +202,11 @@ void __init imx51_soc_init(void) /* i.mx51 has the i.mx35 type sdma */ imx_add_imx_sdma("imx35-sdma", MX51_SDMA_BASE_ADDR, MX51_INT_SDMA, &imx51_sdma_pdata); + + /* Setup AIPS registers */ + imx_set_aips(MX51_IO_ADDRESS(MX51_AIPS1_BASE_ADDR)); + imx_set_aips(MX51_IO_ADDRESS(MX51_AIPS2_BASE_ADDR)); + /* i.mx51 has the i.mx31 type audmux */ platform_device_register_simple("imx31-audmux", 0, imx51_audmux_res, ARRAY_SIZE(imx51_audmux_res)); @@ -225,6 +225,11 @@ void __init imx53_soc_init(void) /* i.mx53 has the i.mx35 type sdma */ imx_add_imx_sdma("imx35-sdma", MX53_SDMA_BASE_ADDR, MX53_INT_SDMA, &imx53_sdma_pdata); + + /* Setup AIPS registers */ + imx_set_aips(MX53_IO_ADDRESS(MX53_AIPS1_BASE_ADDR)); + imx_set_aips(MX53_IO_ADDRESS(MX53_AIPS2_BASE_ADDR)); + /* i.mx53 has the i.mx31 type audmux */ platform_device_register_simple("imx31-audmux", 0, imx53_audmux_res, ARRAY_SIZE(imx53_audmux_res)); diff --git a/arch/arm/mach-imx/pm-imx27.c b/arch/arm/mach-imx/pm-imx27.c index e455d2f855bf..6fcffa7db978 100644 --- a/arch/arm/mach-imx/pm-imx27.c +++ b/arch/arm/mach-imx/pm-imx27.c @@ -10,7 +10,6 @@ #include <linux/kernel.h> #include <linux/suspend.h> #include <linux/io.h> -#include <mach/system.h> #include <mach/hardware.h> static int mx27_suspend_enter(suspend_state_t state) @@ -23,7 +22,7 @@ static int mx27_suspend_enter(suspend_state_t state) cscr &= 0xFFFFFFFC; __raw_writel(cscr, MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR)); /* Executes WFI */ - arch_idle(); + cpu_do_idle(); break; default: diff --git a/arch/arm/mach-imx/pm-imx3.c b/arch/arm/mach-imx/pm-imx3.c new file mode 100644 index 000000000000..b3752439632e --- /dev/null +++ b/arch/arm/mach-imx/pm-imx3.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#include <linux/io.h> +#include <mach/common.h> +#include <mach/hardware.h> +#include <mach/devices-common.h> +#include "crmregs-imx3.h" + +/* + * Set cpu low power mode before WFI instruction. This function is called + * mx3 because it can be used for mx31 and mx35. + * Currently only WAIT_MODE is supported. + */ +void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode) +{ + int reg = __raw_readl(MXC_CCM_CCMR); + reg &= ~MXC_CCM_CCMR_LPM_MASK; + + switch (mode) { + case MX3_WAIT: + if (cpu_is_mx35()) + reg |= MXC_CCM_CCMR_LPM_WAIT_MX35; + __raw_writel(reg, MXC_CCM_CCMR); + break; + default: + pr_err("Unknown cpu power mode: %d\n", mode); + return; + } +} diff --git a/arch/arm/mach-imx/pm-imx5.c b/arch/arm/mach-imx/pm-imx5.c index 6dc093448057..e26a9cb05ed8 100644 --- a/arch/arm/mach-imx/pm-imx5.c +++ b/arch/arm/mach-imx/pm-imx5.c @@ -89,7 +89,7 @@ void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) static int mx5_suspend_prepare(void) { - return clk_enable(gpc_dvfs_clk); + return clk_prepare_enable(gpc_dvfs_clk); } static int mx5_suspend_enter(suspend_state_t state) @@ -119,7 +119,7 @@ static int mx5_suspend_enter(suspend_state_t state) static void mx5_suspend_finish(void) { - clk_disable(gpc_dvfs_clk); + clk_disable_unprepare(gpc_dvfs_clk); } static int mx5_pm_valid(suspend_state_t state) diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 019f0ab08f66..eaf6c6366ffa 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -25,9 +25,9 @@ #include <mach/hardware.h> #include <mach/platform.h> -#include <asm/irq.h> #include <mach/cm.h> -#include <asm/system.h> +#include <mach/irqs.h> + #include <asm/leds.h> #include <asm/mach-types.h> #include <asm/mach/time.h> @@ -35,67 +35,23 @@ static struct amba_pl010_data integrator_uart_data; -static struct amba_device rtc_device = { - .dev = { - .init_name = "mb:15", - }, - .res = { - .start = INTEGRATOR_RTC_BASE, - .end = INTEGRATOR_RTC_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_RTCINT, NO_IRQ }, -}; +#define INTEGRATOR_RTC_IRQ { IRQ_RTCINT } +#define INTEGRATOR_UART0_IRQ { IRQ_UARTINT0 } +#define INTEGRATOR_UART1_IRQ { IRQ_UARTINT1 } +#define KMI0_IRQ { IRQ_KMIINT0 } +#define KMI1_IRQ { IRQ_KMIINT1 } -static struct amba_device uart0_device = { - .dev = { - .init_name = "mb:16", - .platform_data = &integrator_uart_data, - }, - .res = { - .start = INTEGRATOR_UART0_BASE, - .end = INTEGRATOR_UART0_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_UARTINT0, NO_IRQ }, -}; +static AMBA_APB_DEVICE(rtc, "mb:15", 0, + INTEGRATOR_RTC_BASE, INTEGRATOR_RTC_IRQ, NULL); -static struct amba_device uart1_device = { - .dev = { - .init_name = "mb:17", - .platform_data = &integrator_uart_data, - }, - .res = { - .start = INTEGRATOR_UART1_BASE, - .end = INTEGRATOR_UART1_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_UARTINT1, NO_IRQ }, -}; +static AMBA_APB_DEVICE(uart0, "mb:16", 0, + INTEGRATOR_UART0_BASE, INTEGRATOR_UART0_IRQ, &integrator_uart_data); -static struct amba_device kmi0_device = { - .dev = { - .init_name = "mb:18", - }, - .res = { - .start = KMI0_BASE, - .end = KMI0_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_KMIINT0, NO_IRQ }, -}; +static AMBA_APB_DEVICE(uart1, "mb:17", 0, + INTEGRATOR_UART1_BASE, INTEGRATOR_UART1_IRQ, &integrator_uart_data); -static struct amba_device kmi1_device = { - .dev = { - .init_name = "mb:19", - }, - .res = { - .start = KMI1_BASE, - .end = KMI1_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_KMIINT1, NO_IRQ }, -}; +static AMBA_APB_DEVICE(kmi0, "mb:18", 0, KMI0_BASE, KMI0_IRQ, NULL); +static AMBA_APB_DEVICE(kmi1, "mb:19", 0, KMI1_BASE, KMI1_IRQ, NULL); static struct amba_device *amba_devs[] __initdata = { &rtc_device, diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index 8cbb75a96bd4..3e538da6cb1f 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c @@ -401,24 +401,21 @@ static int impd1_probe(struct lm_device *dev) pc_base = dev->resource.start + idev->offset; - d = kzalloc(sizeof(struct amba_device), GFP_KERNEL); + d = amba_device_alloc(NULL, pc_base, SZ_4K); if (!d) continue; dev_set_name(&d->dev, "lm%x:%5.5lx", dev->id, idev->offset >> 12); d->dev.parent = &dev->dev; - d->res.start = dev->resource.start + idev->offset; - d->res.end = d->res.start + SZ_4K - 1; - d->res.flags = IORESOURCE_MEM; d->irq[0] = dev->irq; d->irq[1] = dev->irq; d->periphid = idev->id; d->dev.platform_data = idev->platform_data; - ret = amba_device_register(d, &dev->resource); + ret = amba_device_add(d, &dev->resource); if (ret) { dev_err(&d->dev, "unable to register device: %d\n", ret); - kfree(d); + amba_device_put(d); } } diff --git a/arch/arm/mach-integrator/include/mach/entry-macro.S b/arch/arm/mach-integrator/include/mach/entry-macro.S index 3d029c9f3ef6..5cc7b85ad9df 100644 --- a/arch/arm/mach-integrator/include/mach/entry-macro.S +++ b/arch/arm/mach-integrator/include/mach/entry-macro.S @@ -11,15 +11,9 @@ #include <mach/platform.h> #include <mach/irqs.h> - .macro disable_fiq - .endm - .macro get_irqnr_preamble, base, tmp .endm - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp /* FIXME: should not be using soo many LDRs here */ ldr \base, =IO_ADDRESS(INTEGRATOR_IC_BASE) diff --git a/arch/arm/mach-integrator/include/mach/io.h b/arch/arm/mach-integrator/include/mach/io.h index 37beed3fa3ed..8de70de3dd0a 100644 --- a/arch/arm/mach-integrator/include/mach/io.h +++ b/arch/arm/mach-integrator/include/mach/io.h @@ -29,6 +29,5 @@ #define PCI_IO_VADDR 0xee000000 #define __io(a) ((void __iomem *)(PCI_IO_VADDR + (a))) -#define __mem_pci(a) (a) #endif diff --git a/arch/arm/mach-integrator/include/mach/irqs.h b/arch/arm/mach-integrator/include/mach/irqs.h index 1fbe6d190222..a19a1a2fcf6b 100644 --- a/arch/arm/mach-integrator/include/mach/irqs.h +++ b/arch/arm/mach-integrator/include/mach/irqs.h @@ -78,5 +78,6 @@ #define IRQ_SIC_CP_LMINT7 46 #define IRQ_SIC_END 46 -#define NR_IRQS 47 +#define NR_IRQS_INTEGRATOR_AP 34 +#define NR_IRQS_INTEGRATOR_CP 47 diff --git a/arch/arm/mach-integrator/include/mach/system.h b/arch/arm/mach-integrator/include/mach/system.h deleted file mode 100644 index 901514eba4a6..000000000000 --- a/arch/arm/mach-integrator/include/mach/system.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * arch/arm/mach-integrator/include/mach/system.h - * - * Copyright (C) 1999 ARM Limited - * Copyright (C) 2000 Deep Blue Solutions Ltd - * - * 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_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - /* - * This should do all the clock switching - * and wait for interrupt tricks - */ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 21a1d6cbef40..871f148ffd72 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -38,12 +38,13 @@ #include <mach/hardware.h> #include <mach/platform.h> #include <asm/hardware/arm_timer.h> -#include <asm/irq.h> #include <asm/setup.h> #include <asm/param.h> /* HZ */ #include <asm/mach-types.h> +#include <asm/sched_clock.h> #include <mach/lm.h> +#include <mach/irqs.h> #include <asm/mach/arch.h> #include <asm/mach/irq.h> @@ -325,6 +326,11 @@ static void __init ap_init(void) static unsigned long timer_reload; +static u32 notrace integrator_read_sched_clock(void) +{ + return -readl((void __iomem *) TIMER2_VA_BASE + TIMER_VALUE); +} + static void integrator_clocksource_init(unsigned long inrate) { void __iomem *base = (void __iomem *)TIMER2_VA_BASE; @@ -341,6 +347,7 @@ static void integrator_clocksource_init(unsigned long inrate) clocksource_mmio_init(base + TIMER_VALUE, "timer2", rate, 200, 16, clocksource_mmio_readl_down); + setup_sched_clock(integrator_read_sched_clock, 16, rate); } static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE; @@ -468,6 +475,7 @@ MACHINE_START(INTEGRATOR, "ARM-Integrator") .atag_offset = 0x100, .reserve = integrator_reserve, .map_io = ap_map_io, + .nr_irqs = NR_IRQS_INTEGRATOR_AP, .init_early = integrator_init_early, .init_irq = ap_init_irq, .timer = &ap_timer, diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index a8b6aa6003f3..48a115a91d9d 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -26,7 +26,6 @@ #include <mach/hardware.h> #include <mach/platform.h> -#include <asm/irq.h> #include <asm/setup.h> #include <asm/mach-types.h> #include <asm/hardware/arm_timer.h> @@ -34,6 +33,7 @@ #include <mach/cm.h> #include <mach/lm.h> +#include <mach/irqs.h> #include <asm/mach/arch.h> #include <asm/mach/irq.h> @@ -347,32 +347,14 @@ static struct mmci_platform_data mmc_data = { .gpio_cd = -1, }; -static struct amba_device mmc_device = { - .dev = { - .init_name = "mb:1c", - .platform_data = &mmc_data, - }, - .res = { - .start = INTEGRATOR_CP_MMC_BASE, - .end = INTEGRATOR_CP_MMC_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 }, - .periphid = 0, -}; +#define INTEGRATOR_CP_MMC_IRQS { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 } +#define INTEGRATOR_CP_AACI_IRQS { IRQ_CP_AACIINT } -static struct amba_device aaci_device = { - .dev = { - .init_name = "mb:1d", - }, - .res = { - .start = INTEGRATOR_CP_AACI_BASE, - .end = INTEGRATOR_CP_AACI_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_CP_AACIINT, NO_IRQ }, - .periphid = 0, -}; +static AMBA_APB_DEVICE(mmc, "mb:1c", 0, INTEGRATOR_CP_MMC_BASE, + INTEGRATOR_CP_MMC_IRQS, &mmc_data); + +static AMBA_APB_DEVICE(aaci, "mb:1d", 0, INTEGRATOR_CP_AACI_BASE, + INTEGRATOR_CP_AACI_IRQS, NULL); /* @@ -425,21 +407,8 @@ static struct clcd_board clcd_data = { .remove = versatile_clcd_remove_dma, }; -static struct amba_device clcd_device = { - .dev = { - .init_name = "mb:c0", - .coherent_dma_mask = ~0, - .platform_data = &clcd_data, - }, - .res = { - .start = INTCP_PA_CLCD_BASE, - .end = INTCP_PA_CLCD_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .dma_mask = ~0, - .irq = { IRQ_CP_CLCDCINT, NO_IRQ }, - .periphid = 0, -}; +static AMBA_AHB_DEVICE(clcd, "mb:c0", 0, INTCP_PA_CLCD_BASE, + { IRQ_CP_CLCDCINT }, &clcd_data); static struct amba_device *amba_devs[] __initdata = { &mmc_device, @@ -495,6 +464,7 @@ MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") .atag_offset = 0x100, .reserve = integrator_reserve, .map_io = intcp_map_io, + .nr_irqs = NR_IRQS_INTEGRATOR_CP, .init_early = intcp_init_early, .init_irq = intcp_init_irq, .timer = &cp_timer, diff --git a/arch/arm/mach-integrator/leds.c b/arch/arm/mach-integrator/leds.c index 28be186adb89..466defa97842 100644 --- a/arch/arm/mach-integrator/leds.c +++ b/arch/arm/mach-integrator/leds.c @@ -29,7 +29,6 @@ #include <mach/hardware.h> #include <mach/platform.h> #include <asm/leds.h> -#include <asm/system.h> #include <asm/mach-types.h> #include <mach/cm.h> diff --git a/arch/arm/mach-integrator/pci.c b/arch/arm/mach-integrator/pci.c index 520b6bf81bb1..f1ca9c122861 100644 --- a/arch/arm/mach-integrator/pci.c +++ b/arch/arm/mach-integrator/pci.c @@ -26,11 +26,11 @@ #include <linux/interrupt.h> #include <linux/init.h> -#include <asm/irq.h> -#include <asm/system.h> #include <asm/mach/pci.h> #include <asm/mach-types.h> +#include <mach/irqs.h> + /* * A small note about bridges and interrupts. The DECchip 21050 (and * later) adheres to the PCI-PCI bridge specification. This says that diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index 3c82566acece..67e6f9a9d1a0 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c @@ -30,9 +30,9 @@ #include <mach/hardware.h> #include <mach/platform.h> -#include <asm/irq.h> +#include <mach/irqs.h> + #include <asm/signal.h> -#include <asm/system.h> #include <asm/mach/pci.h> #include <asm/irq_regs.h> @@ -378,9 +378,10 @@ static int __init pci_v3_setup_resources(struct pci_sys_data *sys) * the mem resource for this bus * the prefetch mem resource for this bus */ - pci_add_resource(&sys->resources, &ioport_resource); - pci_add_resource(&sys->resources, &non_mem); - pci_add_resource(&sys->resources, &pre_mem); + pci_add_resource_offset(&sys->resources, + &ioport_resource, sys->io_offset); + pci_add_resource_offset(&sys->resources, &non_mem, sys->mem_offset); + pci_add_resource_offset(&sys->resources, &pre_mem, sys->mem_offset); return 1; } diff --git a/arch/arm/mach-iop13xx/include/mach/entry-macro.S b/arch/arm/mach-iop13xx/include/mach/entry-macro.S index a624a7870c64..1a2d603488d8 100644 --- a/arch/arm/mach-iop13xx/include/mach/entry-macro.S +++ b/arch/arm/mach-iop13xx/include/mach/entry-macro.S @@ -16,9 +16,6 @@ * Place - Suite 330, Boston, MA 02111-1307 USA. * */ - .macro disable_fiq - .endm - .macro get_irqnr_preamble, base, tmp mrc p15, 0, \tmp, c15, c1, 0 orr \tmp, \tmp, #(1 << 6) diff --git a/arch/arm/mach-iop13xx/include/mach/io.h b/arch/arm/mach-iop13xx/include/mach/io.h index dffb234bb967..f13188518025 100644 --- a/arch/arm/mach-iop13xx/include/mach/io.h +++ b/arch/arm/mach-iop13xx/include/mach/io.h @@ -22,20 +22,7 @@ #define IO_SPACE_LIMIT 0xffffffff #define __io(a) __iop13xx_io(a) -#define __mem_pci(a) (a) -#define __mem_isa(a) (a) extern void __iomem * __iop13xx_io(unsigned long io_addr); -extern void __iomem *__iop13xx_ioremap(unsigned long cookie, size_t size, - unsigned int mtype); -extern void __iop13xx_iounmap(void __iomem *addr); - -extern u32 iop13xx_atue_mem_base; -extern u32 iop13xx_atux_mem_base; -extern size_t iop13xx_atue_mem_size; -extern size_t iop13xx_atux_mem_size; - -#define __arch_ioremap __iop13xx_ioremap -#define __arch_iounmap __iop13xx_iounmap #endif diff --git a/arch/arm/mach-iop13xx/include/mach/iop13xx.h b/arch/arm/mach-iop13xx/include/mach/iop13xx.h index 07e9ff7adafb..e190dcd7d72d 100644 --- a/arch/arm/mach-iop13xx/include/mach/iop13xx.h +++ b/arch/arm/mach-iop13xx/include/mach/iop13xx.h @@ -5,6 +5,7 @@ /* The ATU offsets can change based on the strapping */ extern u32 iop13xx_atux_pmmr_offset; extern u32 iop13xx_atue_pmmr_offset; +void iop13xx_init_early(void); void iop13xx_init_irq(void); void iop13xx_map_io(void); void iop13xx_platform_init(void); diff --git a/arch/arm/mach-iop13xx/include/mach/system.h b/arch/arm/mach-iop13xx/include/mach/system.h deleted file mode 100644 index 1f31ed3f8ae2..000000000000 --- a/arch/arm/mach-iop13xx/include/mach/system.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/arm/mach-iop13xx/include/mach/system.h - * - * Copyright (C) 2004 Intel Corp. - * - * 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. - */ -static inline void arch_idle(void) -{ - cpu_do_idle(); -} diff --git a/arch/arm/mach-iop13xx/io.c b/arch/arm/mach-iop13xx/io.c index 48642e66c566..3c364198db9c 100644 --- a/arch/arm/mach-iop13xx/io.c +++ b/arch/arm/mach-iop13xx/io.c @@ -21,6 +21,8 @@ #include <linux/io.h> #include <mach/hardware.h> +#include "pci.h" + void * __iomem __iop13xx_io(unsigned long io_addr) { void __iomem * io_virt; @@ -40,8 +42,8 @@ void * __iomem __iop13xx_io(unsigned long io_addr) } EXPORT_SYMBOL(__iop13xx_io); -void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size, - unsigned int mtype) +static void __iomem *__iop13xx_ioremap_caller(unsigned long cookie, + size_t size, unsigned int mtype, void *caller) { void __iomem * retval; @@ -76,17 +78,14 @@ void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size, break; default: retval = __arm_ioremap_caller(cookie, size, mtype, - __builtin_return_address(0)); + caller); } return retval; } -EXPORT_SYMBOL(__iop13xx_ioremap); -void __iop13xx_iounmap(void __iomem *addr) +static void __iop13xx_iounmap(volatile void __iomem *addr) { - extern void __iounmap(volatile void __iomem *addr); - if (iop13xx_atue_mem_base) if (addr >= (void __iomem *) iop13xx_atue_mem_base && addr < (void __iomem *) (iop13xx_atue_mem_base + @@ -110,4 +109,9 @@ void __iop13xx_iounmap(void __iomem *addr) skip: return; } -EXPORT_SYMBOL(__iop13xx_iounmap); + +void __init iop13xx_init_early(void) +{ + arch_ioremap_caller = __iop13xx_ioremap_caller; + arch_iounmap = __iop13xx_iounmap; +} diff --git a/arch/arm/mach-iop13xx/iq81340mc.c b/arch/arm/mach-iop13xx/iq81340mc.c index abaee8833588..5c96b73e6964 100644 --- a/arch/arm/mach-iop13xx/iq81340mc.c +++ b/arch/arm/mach-iop13xx/iq81340mc.c @@ -92,6 +92,7 @@ static struct sys_timer iq81340mc_timer = { MACHINE_START(IQ81340MC, "Intel IQ81340MC") /* Maintainer: Dan Williams <dan.j.williams@intel.com> */ .atag_offset = 0x100, + .init_early = iop13xx_init_early, .map_io = iop13xx_map_io, .init_irq = iop13xx_init_irq, .timer = &iq81340mc_timer, diff --git a/arch/arm/mach-iop13xx/iq81340sc.c b/arch/arm/mach-iop13xx/iq81340sc.c index 690916a09dc6..aa4dd750135a 100644 --- a/arch/arm/mach-iop13xx/iq81340sc.c +++ b/arch/arm/mach-iop13xx/iq81340sc.c @@ -94,6 +94,7 @@ static struct sys_timer iq81340sc_timer = { MACHINE_START(IQ81340SC, "Intel IQ81340SC") /* Maintainer: Dan Williams <dan.j.williams@intel.com> */ .atag_offset = 0x100, + .init_early = iop13xx_init_early, .map_io = iop13xx_map_io, .init_irq = iop13xx_init_irq, .timer = &iq81340sc_timer, diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c index b8f5a8736511..861cb12ef436 100644 --- a/arch/arm/mach-iop13xx/pci.c +++ b/arch/arm/mach-iop13xx/pci.c @@ -1084,8 +1084,8 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys) request_resource(&ioport_resource, &res[0]); request_resource(&iomem_resource, &res[1]); - pci_add_resource(&sys->resources, &res[0]); - pci_add_resource(&sys->resources, &res[1]); + pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset); + pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset); return 1; } diff --git a/arch/arm/mach-iop13xx/pci.h b/arch/arm/mach-iop13xx/pci.h new file mode 100644 index 000000000000..c70cf5b41e31 --- /dev/null +++ b/arch/arm/mach-iop13xx/pci.h @@ -0,0 +1,6 @@ +#include <linux/types.h> + +extern u32 iop13xx_atue_mem_base; +extern u32 iop13xx_atux_mem_base; +extern size_t iop13xx_atue_mem_size; +extern size_t iop13xx_atux_mem_size; diff --git a/arch/arm/mach-iop32x/include/mach/entry-macro.S b/arch/arm/mach-iop32x/include/mach/entry-macro.S index b02fb56bafcc..ea13ae02d9b1 100644 --- a/arch/arm/mach-iop32x/include/mach/entry-macro.S +++ b/arch/arm/mach-iop32x/include/mach/entry-macro.S @@ -9,9 +9,6 @@ */ #include <mach/iop32x.h> - .macro disable_fiq - .endm - .macro get_irqnr_preamble, base, tmp mrc p15, 0, \tmp, c15, c1, 0 orr \tmp, \tmp, #(1 << 6) diff --git a/arch/arm/mach-iop32x/include/mach/io.h b/arch/arm/mach-iop32x/include/mach/io.h index 2d88264b9863..e2ada265bb8d 100644 --- a/arch/arm/mach-iop32x/include/mach/io.h +++ b/arch/arm/mach-iop32x/include/mach/io.h @@ -15,6 +15,5 @@ #define IO_SPACE_LIMIT 0xffffffff #define __io(p) ((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p)) -#define __mem_pci(a) (a) #endif diff --git a/arch/arm/mach-iop32x/include/mach/system.h b/arch/arm/mach-iop32x/include/mach/system.h deleted file mode 100644 index 4a88727bca98..000000000000 --- a/arch/arm/mach-iop32x/include/mach/system.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/arm/mach-iop32x/include/mach/system.h - * - * Copyright (C) 2001 MontaVista Software, Inc. - * - * 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. - */ -static inline void arch_idle(void) -{ - cpu_do_idle(); -} diff --git a/arch/arm/mach-iop33x/include/mach/entry-macro.S b/arch/arm/mach-iop33x/include/mach/entry-macro.S index 4e1f7282b354..0a398fe1fba4 100644 --- a/arch/arm/mach-iop33x/include/mach/entry-macro.S +++ b/arch/arm/mach-iop33x/include/mach/entry-macro.S @@ -9,9 +9,6 @@ */ #include <mach/iop33x.h> - .macro disable_fiq - .endm - .macro get_irqnr_preamble, base, tmp mrc p15, 0, \tmp, c15, c1, 0 orr \tmp, \tmp, #(1 << 6) diff --git a/arch/arm/mach-iop33x/include/mach/io.h b/arch/arm/mach-iop33x/include/mach/io.h index a8a66fc8fbdb..f7c1b6595660 100644 --- a/arch/arm/mach-iop33x/include/mach/io.h +++ b/arch/arm/mach-iop33x/include/mach/io.h @@ -15,6 +15,5 @@ #define IO_SPACE_LIMIT 0xffffffff #define __io(p) ((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p)) -#define __mem_pci(a) (a) #endif diff --git a/arch/arm/mach-iop33x/include/mach/system.h b/arch/arm/mach-iop33x/include/mach/system.h deleted file mode 100644 index 4f98e765397c..000000000000 --- a/arch/arm/mach-iop33x/include/mach/system.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/arm/mach-iop33x/include/mach/system.h - * - * Copyright (C) 2001 MontaVista Software, Inc. - * - * 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. - */ -static inline void arch_idle(void) -{ - cpu_do_idle(); -} diff --git a/arch/arm/mach-iop33x/uart.c b/arch/arm/mach-iop33x/uart.c index cdae24e46eea..bbf54d794ce8 100644 --- a/arch/arm/mach-iop33x/uart.c +++ b/arch/arm/mach-iop33x/uart.c @@ -22,7 +22,6 @@ #include <asm/page.h> #include <asm/mach/map.h> #include <asm/setup.h> -#include <asm/system.h> #include <asm/memory.h> #include <mach/hardware.h> #include <asm/hardware/iop3xx.h> diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c index 81c45370a4e6..f214cdff01cb 100644 --- a/arch/arm/mach-ixp2000/core.c +++ b/arch/arm/mach-ixp2000/core.c @@ -32,7 +32,6 @@ #include <asm/memory.h> #include <mach/hardware.h> #include <asm/irq.h> -#include <asm/system.h> #include <asm/tlbflush.h> #include <asm/pgtable.h> diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c index e872d238cd0f..4867f408617c 100644 --- a/arch/arm/mach-ixp2000/enp2611.c +++ b/arch/arm/mach-ixp2000/enp2611.c @@ -36,7 +36,6 @@ #include <asm/irq.h> #include <asm/pgtable.h> #include <asm/page.h> -#include <asm/system.h> #include <mach/hardware.h> #include <asm/mach-types.h> diff --git a/arch/arm/mach-ixp2000/include/mach/entry-macro.S b/arch/arm/mach-ixp2000/include/mach/entry-macro.S index 5850ffc8c751..c4444dff9202 100644 --- a/arch/arm/mach-ixp2000/include/mach/entry-macro.S +++ b/arch/arm/mach-ixp2000/include/mach/entry-macro.S @@ -9,15 +9,9 @@ */ #include <mach/irqs.h> - .macro disable_fiq - .endm - .macro get_irqnr_preamble, base, tmp .endm - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp mov \irqnr, #0x0 @clear out irqnr as default diff --git a/arch/arm/mach-ixp2000/include/mach/io.h b/arch/arm/mach-ixp2000/include/mach/io.h index 859e584914d9..f6552d6f35ab 100644 --- a/arch/arm/mach-ixp2000/include/mach/io.h +++ b/arch/arm/mach-ixp2000/include/mach/io.h @@ -18,7 +18,6 @@ #include <mach/hardware.h> #define IO_SPACE_LIMIT 0xffffffff -#define __mem_pci(a) (a) /* * The A? revisions of the IXP2000s assert byte lanes for PCI I/O diff --git a/arch/arm/mach-ixp2000/include/mach/system.h b/arch/arm/mach-ixp2000/include/mach/system.h deleted file mode 100644 index a7fb08b2b8e7..000000000000 --- a/arch/arm/mach-ixp2000/include/mach/system.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * arch/arm/mach-ixp2000/include/mach/system.h - * - * Copyright (C) 2002 Intel Corp. - * Copyricht (C) 2003-2005 MontaVista Software, Inc. - * - * 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. - */ -static inline void arch_idle(void) -{ - cpu_do_idle(); -} diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c index f53e911ec94a..915ad49e3b8f 100644 --- a/arch/arm/mach-ixp2000/ixdp2400.c +++ b/arch/arm/mach-ixp2000/ixdp2400.c @@ -29,7 +29,6 @@ #include <asm/irq.h> #include <asm/pgtable.h> #include <asm/page.h> -#include <asm/system.h> #include <mach/hardware.h> #include <asm/mach-types.h> @@ -134,11 +133,11 @@ static void ixdp2400_pci_postinit(void) if (ixdp2x00_master_npu()) { dev = pci_get_bus_and_slot(1, IXDP2400_SLAVE_ENET_DEVFN); - pci_remove_bus_device(dev); + pci_stop_and_remove_bus_device(dev); pci_dev_put(dev); } else { dev = pci_get_bus_and_slot(1, IXDP2400_MASTER_ENET_DEVFN); - pci_remove_bus_device(dev); + pci_stop_and_remove_bus_device(dev); pci_dev_put(dev); ixdp2x00_slave_pci_postinit(); diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c index a2e7c393e74f..a9f1819ea049 100644 --- a/arch/arm/mach-ixp2000/ixdp2800.c +++ b/arch/arm/mach-ixp2000/ixdp2800.c @@ -29,7 +29,6 @@ #include <asm/irq.h> #include <asm/pgtable.h> #include <asm/page.h> -#include <asm/system.h> #include <mach/hardware.h> #include <asm/mach-types.h> @@ -262,14 +261,14 @@ int __init ixdp2800_pci_init(void) pci_common_init(&ixdp2800_pci); if (ixdp2x00_master_npu()) { dev = pci_get_bus_and_slot(1, IXDP2800_SLAVE_ENET_DEVFN); - pci_remove_bus_device(dev); + pci_stop_and_remove_bus_device(dev); pci_dev_put(dev); ixdp2800_master_enable_slave(); ixdp2800_master_wait_for_slave_bus_scan(); } else { dev = pci_get_bus_and_slot(1, IXDP2800_MASTER_ENET_DEVFN); - pci_remove_bus_device(dev); + pci_stop_and_remove_bus_device(dev); pci_dev_put(dev); } } diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c index 634b6c852f68..421e38dc0fac 100644 --- a/arch/arm/mach-ixp2000/ixdp2x00.c +++ b/arch/arm/mach-ixp2000/ixdp2x00.c @@ -30,7 +30,6 @@ #include <asm/irq.h> #include <asm/pgtable.h> #include <asm/page.h> -#include <asm/system.h> #include <mach/hardware.h> #include <asm/mach-types.h> @@ -239,12 +238,12 @@ void ixdp2x00_slave_pci_postinit(void) * Remove PMC device is there is one */ if((dev = pci_get_bus_and_slot(1, IXDP2X00_PMC_DEVFN))) { - pci_remove_bus_device(dev); + pci_stop_and_remove_bus_device(dev); pci_dev_put(dev); } dev = pci_get_bus_and_slot(0, IXDP2X00_21555_DEVFN); - pci_remove_bus_device(dev); + pci_stop_and_remove_bus_device(dev); pci_dev_put(dev); } diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c index 7632beadabf6..5196c39cdba4 100644 --- a/arch/arm/mach-ixp2000/ixdp2x01.c +++ b/arch/arm/mach-ixp2000/ixdp2x01.c @@ -34,7 +34,6 @@ #include <asm/irq.h> #include <asm/pgtable.h> #include <asm/page.h> -#include <asm/system.h> #include <mach/hardware.h> #include <asm/mach-types.h> diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c index 626fda435aa9..9c02de932fac 100644 --- a/arch/arm/mach-ixp2000/pci.c +++ b/arch/arm/mach-ixp2000/pci.c @@ -26,7 +26,6 @@ #include <linux/io.h> #include <asm/irq.h> -#include <asm/system.h> #include <mach/hardware.h> #include <asm/mach/pci.h> @@ -243,8 +242,10 @@ int ixp2000_pci_setup(int nr, struct pci_sys_data *sys) if (nr >= 1) return 0; - pci_add_resource(&sys->resources, &ixp2000_pci_io_space); - pci_add_resource(&sys->resources, &ixp2000_pci_mem_space); + pci_add_resource_offset(&sys->resources, + &ixp2000_pci_io_space, sys->io_offset); + pci_add_resource_offset(&sys->resources, + &ixp2000_pci_mem_space, sys->mem_offset); return 1; } diff --git a/arch/arm/mach-ixp23xx/core.c b/arch/arm/mach-ixp23xx/core.c index 0923bb905cc0..d34542425990 100644 --- a/arch/arm/mach-ixp23xx/core.c +++ b/arch/arm/mach-ixp23xx/core.c @@ -34,9 +34,9 @@ #include <asm/memory.h> #include <mach/hardware.h> #include <asm/irq.h> -#include <asm/system.h> #include <asm/tlbflush.h> #include <asm/pgtable.h> +#include <asm/system_misc.h> #include <asm/mach/map.h> #include <asm/mach/time.h> @@ -441,6 +441,9 @@ static struct platform_device *ixp23xx_devices[] __initdata = { void __init ixp23xx_sys_init(void) { + /* by default, the idle code is disabled */ + disable_hlt(); + *IXP23XX_EXP_UNIT_FUSE |= 0xf; platform_add_devices(ixp23xx_devices, ARRAY_SIZE(ixp23xx_devices)); } diff --git a/arch/arm/mach-ixp23xx/espresso.c b/arch/arm/mach-ixp23xx/espresso.c index 8f2487e1fc4e..d142d45dea12 100644 --- a/arch/arm/mach-ixp23xx/espresso.c +++ b/arch/arm/mach-ixp23xx/espresso.c @@ -32,7 +32,6 @@ #include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/irq.h> -#include <asm/system.h> #include <asm/tlbflush.h> #include <asm/pgtable.h> diff --git a/arch/arm/mach-ixp23xx/include/mach/entry-macro.S b/arch/arm/mach-ixp23xx/include/mach/entry-macro.S index 3f5338a7bbdd..3fd2cb984e42 100644 --- a/arch/arm/mach-ixp23xx/include/mach/entry-macro.S +++ b/arch/arm/mach-ixp23xx/include/mach/entry-macro.S @@ -2,15 +2,9 @@ * arch/arm/mach-ixp23xx/include/mach/entry-macro.S */ - .macro disable_fiq - .endm - .macro get_irqnr_preamble, base, tmp .endm - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \irqnr, =(IXP23XX_INTC_VIRT + IXP23XX_INTR_IRQ_ENC_ST_OFFSET) ldr \irqnr, [\irqnr] @ get interrupt number diff --git a/arch/arm/mach-ixp23xx/include/mach/io.h b/arch/arm/mach-ixp23xx/include/mach/io.h index 4ce4353b9f72..a7aceb55c130 100644 --- a/arch/arm/mach-ixp23xx/include/mach/io.h +++ b/arch/arm/mach-ixp23xx/include/mach/io.h @@ -18,6 +18,5 @@ #define IO_SPACE_LIMIT 0xffffffff #define __io(p) ((void __iomem*)((p) + IXP23XX_PCI_IO_VIRT)) -#define __mem_pci(a) (a) #endif diff --git a/arch/arm/mach-ixp23xx/include/mach/system.h b/arch/arm/mach-ixp23xx/include/mach/system.h deleted file mode 100644 index 277dda7334b9..000000000000 --- a/arch/arm/mach-ixp23xx/include/mach/system.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * arch/arm/mach-ixp23xx/include/mach/system.h - * - * Copyright (C) 2003 Intel Corporation. - * - * 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. - */ -static inline void arch_idle(void) -{ -#if 0 - if (!hlt_counter) - cpu_do_idle(); -#endif -} diff --git a/arch/arm/mach-ixp23xx/ixdp2351.c b/arch/arm/mach-ixp23xx/ixdp2351.c index 5d5dd3e8d069..b0e07db5ceaf 100644 --- a/arch/arm/mach-ixp23xx/ixdp2351.c +++ b/arch/arm/mach-ixp23xx/ixdp2351.c @@ -36,7 +36,6 @@ #include <asm/memory.h> #include <mach/hardware.h> #include <asm/mach-types.h> -#include <asm/system.h> #include <asm/tlbflush.h> #include <asm/pgtable.h> diff --git a/arch/arm/mach-ixp23xx/pci.c b/arch/arm/mach-ixp23xx/pci.c index 25b5c462cea2..911f5a58e006 100644 --- a/arch/arm/mach-ixp23xx/pci.c +++ b/arch/arm/mach-ixp23xx/pci.c @@ -28,7 +28,6 @@ #include <asm/irq.h> #include <asm/sizes.h> -#include <asm/system.h> #include <asm/mach/pci.h> #include <mach/hardware.h> @@ -281,8 +280,10 @@ int ixp23xx_pci_setup(int nr, struct pci_sys_data *sys) if (nr >= 1) return 0; - pci_add_resource(&sys->resources, &ixp23xx_pci_io_space); - pci_add_resource(&sys->resources, &ixp23xx_pci_mem_space); + pci_add_resource_offset(&sys->resources, + &ixp23xx_pci_io_space, sys->io_offset); + pci_add_resource_offset(&sys->resources, + &ixp23xx_pci_mem_space, sys->mem_offset); return 1; } diff --git a/arch/arm/mach-ixp23xx/roadrunner.c b/arch/arm/mach-ixp23xx/roadrunner.c index 377283fc658c..eaaa3fa9fd05 100644 --- a/arch/arm/mach-ixp23xx/roadrunner.c +++ b/arch/arm/mach-ixp23xx/roadrunner.c @@ -36,7 +36,6 @@ #include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/irq.h> -#include <asm/system.h> #include <asm/tlbflush.h> #include <asm/pgtable.h> diff --git a/arch/arm/mach-ixp4xx/avila-setup.c b/arch/arm/mach-ixp4xx/avila-setup.c index a7277ad470a5..90e42e9982cb 100644 --- a/arch/arm/mach-ixp4xx/avila-setup.c +++ b/arch/arm/mach-ixp4xx/avila-setup.c @@ -165,6 +165,7 @@ static void __init avila_init(void) MACHINE_START(AVILA, "Gateworks Avila Network Platform") /* Maintainer: Deepak Saxena <dsaxena@plexity.net> */ .map_io = ixp4xx_map_io, + .init_early = ixp4xx_init_early, .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, .atag_offset = 0x100, @@ -184,6 +185,7 @@ MACHINE_END MACHINE_START(LOFT, "Giant Shoulder Inc Loft board") /* Maintainer: Tom Billman <kernel@giantshoulderinc.com> */ .map_io = ixp4xx_map_io, + .init_early = ixp4xx_init_early, .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, .atag_offset = 0x100, diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index 5eff15f24bc2..d5719eb42591 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c @@ -32,7 +32,6 @@ #include <asm/cputype.h> #include <asm/irq.h> #include <asm/sizes.h> -#include <asm/system.h> #include <asm/mach/pci.h> #include <mach/hardware.h> @@ -472,8 +471,8 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys) request_resource(&ioport_resource, &res[0]); request_resource(&iomem_resource, &res[1]); - pci_add_resource(&sys->resources, &res[0]); - pci_add_resource(&sys->resources, &res[1]); + pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset); + pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset); platform_notify = ixp4xx_pci_platform_notify; platform_notify_remove = ixp4xx_pci_platform_notify_remove; diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 3841ab4146ba..ebbd7fc90eb4 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -31,11 +31,13 @@ #include <mach/udc.h> #include <mach/hardware.h> +#include <mach/io.h> #include <asm/uaccess.h> #include <asm/pgtable.h> #include <asm/page.h> #include <asm/irq.h> #include <asm/sched_clock.h> +#include <asm/system_misc.h> #include <asm/mach/map.h> #include <asm/mach/irq.h> @@ -236,6 +238,12 @@ void __init ixp4xx_init_irq(void) { int i = 0; + /* + * ixp4xx does not implement the XScale PWRMODE register + * so it must not call cpu_do_idle(). + */ + disable_hlt(); + /* Route all sources to IRQ instead of FIQ */ *IXP4XX_ICLR = 0x0; @@ -511,3 +519,35 @@ void ixp4xx_restart(char mode, const char *cmd) *IXP4XX_OSWE = IXP4XX_WDT_RESET_ENABLE | IXP4XX_WDT_COUNT_ENABLE; } } + +#ifdef CONFIG_IXP4XX_INDIRECT_PCI +/* + * In the case of using indirect PCI, we simply return the actual PCI + * address and our read/write implementation use that to drive the + * access registers. If something outside of PCI is ioremap'd, we + * fallback to the default. + */ + +static void __iomem *ixp4xx_ioremap_caller(unsigned long addr, size_t size, + unsigned int mtype, void *caller) +{ + if (!is_pci_memory(addr)) + return __arm_ioremap_caller(addr, size, mtype, caller); + + return (void __iomem *)addr; +} + +static void ixp4xx_iounmap(void __iomem *addr) +{ + if (!is_pci_memory((__force u32)addr)) + __iounmap(addr); +} + +void __init ixp4xx_init_early(void) +{ + arch_ioremap_caller = ixp4xx_ioremap_caller; + arch_iounmap = ixp4xx_iounmap; +} +#else +void __init ixp4xx_init_early(void) {} +#endif diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c index a74f86ce8bcc..1b83110028d6 100644 --- a/arch/arm/mach-ixp4xx/coyote-setup.c +++ b/arch/arm/mach-ixp4xx/coyote-setup.c @@ -110,6 +110,7 @@ static void __init coyote_init(void) MACHINE_START(ADI_COYOTE, "ADI Engineering Coyote") /* Maintainer: MontaVista Software, Inc. */ .map_io = ixp4xx_map_io, + .init_early = ixp4xx_init_early, .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, .atag_offset = 0x100, @@ -129,6 +130,7 @@ MACHINE_END MACHINE_START(IXDPG425, "Intel IXDPG425") /* Maintainer: MontaVista Software, Inc. */ .map_io = ixp4xx_map_io, + .init_early = ixp4xx_init_early, .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, .atag_offset = 0x100, diff --git a/arch/arm/mach-ixp4xx/dsmg600-setup.c b/arch/arm/mach-ixp4xx/dsmg600-setup.c index 67be177b336a..97a0af8f1955 100644 --- a/arch/arm/mach-ixp4xx/dsmg600-setup.c +++ b/arch/arm/mach-ixp4xx/dsmg600-setup.c @@ -280,6 +280,7 @@ MACHINE_START(DSMG600, "D-Link DSM-G600 RevA") /* Maintainer: www.nslu2-linux.org */ .atag_offset = 0x100, .map_io = ixp4xx_map_io, + .init_early = ixp4xx_init_early, .init_irq = ixp4xx_init_irq, .timer = &dsmg600_timer, .init_machine = dsmg600_init, diff --git a/arch/arm/mach-ixp4xx/fsg-setup.c b/arch/arm/mach-ixp4xx/fsg-setup.c index 6d5818285af8..9175a25a7511 100644 --- a/arch/arm/mach-ixp4xx/fsg-setup.c +++ b/arch/arm/mach-ixp4xx/fsg-setup.c @@ -270,6 +270,7 @@ static void __init fsg_init(void) MACHINE_START(FSG, "Freecom FSG-3") /* Maintainer: www.nslu2-linux.org */ .map_io = ixp4xx_map_io, + .init_early = ixp4xx_init_early, .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, .atag_offset = 0x100, diff --git a/arch/arm/mach-ixp4xx/gateway7001-setup.c b/arch/arm/mach-ixp4xx/gateway7001-setup.c index 7ecf9b28f1c0..033c71758953 100644 --- a/arch/arm/mach-ixp4xx/gateway7001-setup.c +++ b/arch/arm/mach-ixp4xx/gateway7001-setup.c @@ -97,6 +97,7 @@ static void __init gateway7001_init(void) MACHINE_START(GATEWAY7001, "Gateway 7001 AP") /* Maintainer: Imre Kaloz <kaloz@openwrt.org> */ .map_io = ixp4xx_map_io, + .init_early = ixp4xx_init_early, .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, .atag_offset = 0x100, diff --git a/arch/arm/mach-ixp4xx/goramo_mlr.c b/arch/arm/mach-ixp4xx/goramo_mlr.c index c0e3d69a8aec..46bb924962ee 100644 --- a/arch/arm/mach-ixp4xx/goramo_mlr.c +++ b/arch/arm/mach-ixp4xx/goramo_mlr.c @@ -12,7 +12,6 @@ #include <linux/pci.h> #include <linux/serial_8250.h> #include <asm/mach-types.h> -#include <asm/system.h> #include <asm/mach/arch.h> #include <asm/mach/flash.h> #include <asm/mach/pci.h> @@ -497,6 +496,7 @@ subsys_initcall(gmlr_pci_init); MACHINE_START(GORAMO_MLR, "MultiLink") /* Maintainer: Krzysztof Halasa */ .map_io = ixp4xx_map_io, + .init_early = ixp4xx_init_early, .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, .atag_offset = 0x100, diff --git a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c index a23f89391458..18ebc6be7969 100644 --- a/arch/arm/mach-ixp4xx/gtwx5715-setup.c +++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c @@ -165,6 +165,7 @@ static void __init gtwx5715_init(void) MACHINE_START(GTWX5715, "Gemtek GTWX5715 (Linksys WRV54G)") /* Maintainer: George Joseph */ .map_io = ixp4xx_map_io, + .init_early = ixp4xx_init_early, .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, .atag_offset = 0x100, diff --git a/arch/arm/mach-ixp4xx/include/mach/entry-macro.S b/arch/arm/mach-ixp4xx/include/mach/entry-macro.S index f2e14e94ed15..79adf83e2c3d 100644 --- a/arch/arm/mach-ixp4xx/include/mach/entry-macro.S +++ b/arch/arm/mach-ixp4xx/include/mach/entry-macro.S @@ -9,15 +9,9 @@ */ #include <mach/hardware.h> - .macro disable_fiq - .endm - .macro get_irqnr_preamble, base, tmp .endm - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \irqstat, =(IXP4XX_INTC_BASE_VIRT+IXP4XX_ICIP_OFFSET) ldr \irqstat, [\irqstat] @ get interrupts diff --git a/arch/arm/mach-ixp4xx/include/mach/hardware.h b/arch/arm/mach-ixp4xx/include/mach/hardware.h index c30e7e923a73..034bb2a1b805 100644 --- a/arch/arm/mach-ixp4xx/include/mach/hardware.h +++ b/arch/arm/mach-ixp4xx/include/mach/hardware.h @@ -23,8 +23,6 @@ #define PCIBIOS_MAX_MEM 0x4BFFFFFF #endif -#define ARCH_HAS_DMA_SET_COHERENT_MASK - /* Register locations and bits */ #include "ixp4xx-regs.h" diff --git a/arch/arm/mach-ixp4xx/include/mach/io.h b/arch/arm/mach-ixp4xx/include/mach/io.h index ffb9d6afb89f..5cf30d1b78d2 100644 --- a/arch/arm/mach-ixp4xx/include/mach/io.h +++ b/arch/arm/mach-ixp4xx/include/mach/io.h @@ -39,11 +39,7 @@ extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data); * but in some cases the performance hit is acceptable. In addition, you * cannot mmap() PCI devices in this case. */ -#ifndef CONFIG_IXP4XX_INDIRECT_PCI - -#define __mem_pci(a) (a) - -#else +#ifdef CONFIG_IXP4XX_INDIRECT_PCI /* * In the case of using indirect PCI, we simply return the actual PCI @@ -57,24 +53,6 @@ static inline int is_pci_memory(u32 addr) return (addr >= PCIBIOS_MIN_MEM) && (addr <= 0x4FFFFFFF); } -static inline void __iomem * __indirect_ioremap(unsigned long addr, size_t size, - unsigned int mtype) -{ - if (!is_pci_memory(addr)) - return __arm_ioremap(addr, size, mtype); - - return (void __iomem *)addr; -} - -static inline void __indirect_iounmap(void __iomem *addr) -{ - if (!is_pci_memory((__force u32)addr)) - __iounmap(addr); -} - -#define __arch_ioremap __indirect_ioremap -#define __arch_iounmap __indirect_iounmap - #define writeb(v, p) __indirect_writeb(v, p) #define writew(v, p) __indirect_writew(v, p) #define writel(v, p) __indirect_writel(v, p) diff --git a/arch/arm/mach-ixp4xx/include/mach/platform.h b/arch/arm/mach-ixp4xx/include/mach/platform.h index df9250bbf13d..b66bedc64de1 100644 --- a/arch/arm/mach-ixp4xx/include/mach/platform.h +++ b/arch/arm/mach-ixp4xx/include/mach/platform.h @@ -121,6 +121,7 @@ extern unsigned long ixp4xx_timer_freq; * Functions used by platform-level setup code */ extern void ixp4xx_map_io(void); +extern void ixp4xx_init_early(void); extern void ixp4xx_init_irq(void); extern void ixp4xx_sys_init(void); extern void ixp4xx_timer_init(void); diff --git a/arch/arm/mach-ixp4xx/include/mach/system.h b/arch/arm/mach-ixp4xx/include/mach/system.h deleted file mode 100644 index 140a9bef4466..000000000000 --- a/arch/arm/mach-ixp4xx/include/mach/system.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/arm/mach-ixp4xx/include/mach/system.h - * - * Copyright (C) 2002 Intel Corporation. - * - * 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. - * - */ -static inline void arch_idle(void) -{ - /* ixp4xx does not implement the XScale PWRMODE register, - * so it must not call cpu_do_idle() here. - */ -#if 0 - cpu_do_idle(); -#endif -} diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c index 8a38b39999f8..3d742aee1773 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-setup.c +++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c @@ -254,6 +254,7 @@ static void __init ixdp425_init(void) MACHINE_START(IXDP425, "Intel IXDP425 Development Platform") /* Maintainer: MontaVista Software, Inc. */ .map_io = ixp4xx_map_io, + .init_early = ixp4xx_init_early, .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, .atag_offset = 0x100, @@ -269,6 +270,7 @@ MACHINE_END MACHINE_START(IXDP465, "Intel IXDP465 Development Platform") /* Maintainer: MontaVista Software, Inc. */ .map_io = ixp4xx_map_io, + .init_early = ixp4xx_init_early, .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, .atag_offset = 0x100, @@ -283,6 +285,7 @@ MACHINE_END MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform") /* Maintainer: MontaVista Software, Inc. */ .map_io = ixp4xx_map_io, + .init_early = ixp4xx_init_early, .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, .atag_offset = 0x100, @@ -297,6 +300,7 @@ MACHINE_END MACHINE_START(KIXRP435, "Intel KIXRP435 Reference Platform") /* Maintainer: MontaVista Software, Inc. */ .map_io = ixp4xx_map_io, + .init_early = ixp4xx_init_early, .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, .atag_offset = 0x100, diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c index 1010eb7b0083..33cb0955b6bf 100644 --- a/arch/arm/mach-ixp4xx/nas100d-setup.c +++ b/arch/arm/mach-ixp4xx/nas100d-setup.c @@ -315,6 +315,7 @@ MACHINE_START(NAS100D, "Iomega NAS 100d") /* Maintainer: www.nslu2-linux.org */ .atag_offset = 0x100, .map_io = ixp4xx_map_io, + .init_early = ixp4xx_init_early, .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, .init_machine = nas100d_init, diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c index aa355c360d57..e2903faaebb3 100644 --- a/arch/arm/mach-ixp4xx/nslu2-setup.c +++ b/arch/arm/mach-ixp4xx/nslu2-setup.c @@ -301,6 +301,7 @@ MACHINE_START(NSLU2, "Linksys NSLU2") /* Maintainer: www.nslu2-linux.org */ .atag_offset = 0x100, .map_io = ixp4xx_map_io, + .init_early = ixp4xx_init_early, .init_irq = ixp4xx_init_irq, .timer = &nslu2_timer, .init_machine = nslu2_init, diff --git a/arch/arm/mach-ixp4xx/omixp-setup.c b/arch/arm/mach-ixp4xx/omixp-setup.c index 0940869fcfdd..158ddb79821d 100644 --- a/arch/arm/mach-ixp4xx/omixp-setup.c +++ b/arch/arm/mach-ixp4xx/omixp-setup.c @@ -243,6 +243,7 @@ static void __init omixp_init(void) MACHINE_START(DEVIXP, "Omicron DEVIXP") .atag_offset = 0x100, .map_io = ixp4xx_map_io, + .init_early = ixp4xx_init_early, .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, .init_machine = omixp_init, @@ -254,6 +255,7 @@ MACHINE_END MACHINE_START(MICCPT, "Omicron MICCPT") .atag_offset = 0x100, .map_io = ixp4xx_map_io, + .init_early = ixp4xx_init_early, .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, .init_machine = omixp_init, @@ -268,6 +270,7 @@ MACHINE_END MACHINE_START(MIC256, "Omicron MIC256") .atag_offset = 0x100, .map_io = ixp4xx_map_io, + .init_early = ixp4xx_init_early, .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, .init_machine = omixp_init, diff --git a/arch/arm/mach-ixp4xx/vulcan-setup.c b/arch/arm/mach-ixp4xx/vulcan-setup.c index 9dec20683291..2798f435aaf4 100644 --- a/arch/arm/mach-ixp4xx/vulcan-setup.c +++ b/arch/arm/mach-ixp4xx/vulcan-setup.c @@ -237,6 +237,7 @@ static void __init vulcan_init(void) MACHINE_START(ARCOM_VULCAN, "Arcom/Eurotech Vulcan") /* Maintainer: Marc Zyngier <maz@misterjones.org> */ .map_io = ixp4xx_map_io, + .init_early = ixp4xx_init_early, .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, .atag_offset = 0x100, diff --git a/arch/arm/mach-ixp4xx/wg302v2-setup.c b/arch/arm/mach-ixp4xx/wg302v2-setup.c index 5ac0f0a0fd8c..a785175b115b 100644 --- a/arch/arm/mach-ixp4xx/wg302v2-setup.c +++ b/arch/arm/mach-ixp4xx/wg302v2-setup.c @@ -98,6 +98,7 @@ static void __init wg302v2_init(void) MACHINE_START(WG302V2, "Netgear WG302 v2 / WAG302 v2") /* Maintainer: Imre Kaloz <kaloz@openwrt.org> */ .map_io = ixp4xx_map_io, + .init_early = ixp4xx_init_early, .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, .atag_offset = 0x100, diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig index 7fc603b46891..90ceab761929 100644 --- a/arch/arm/mach-kirkwood/Kconfig +++ b/arch/arm/mach-kirkwood/Kconfig @@ -44,6 +44,20 @@ config MACH_GURUPLUG Say 'Y' here if you want your kernel to support the Marvell GuruPlug Reference Board. +config ARCH_KIRKWOOD_DT + bool "Marvell Kirkwood Flattened Device Tree" + select USE_OF + help + Say 'Y' here if you want your kernel to support the + Marvell Kirkwood using flattened device tree. + +config MACH_DREAMPLUG_DT + bool "Marvell DreamPlug (Flattened Device Tree)" + select ARCH_KIRKWOOD_DT + help + Say 'Y' here if you want your kernel to support the + Marvell DreamPlug (Flattened Device Tree). + config MACH_TS219 bool "QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and TS-219P+ Turbo NAS" help diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile index 5dcaa81a2ec3..e299a9576bf0 100644 --- a/arch/arm/mach-kirkwood/Makefile +++ b/arch/arm/mach-kirkwood/Makefile @@ -20,3 +20,5 @@ obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o obj-$(CONFIG_MACH_T5325) += t5325-setup.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o +obj-$(CONFIG_ARCH_KIRKWOOD_DT) += board-dt.o +obj-$(CONFIG_MACH_DREAMPLUG_DT) += board-dreamplug.o diff --git a/arch/arm/mach-kirkwood/Makefile.boot b/arch/arm/mach-kirkwood/Makefile.boot index 760a0efe7580..16f938522304 100644 --- a/arch/arm/mach-kirkwood/Makefile.boot +++ b/arch/arm/mach-kirkwood/Makefile.boot @@ -1,3 +1,5 @@ zreladdr-y += 0x00008000 params_phys-y := 0x00000100 initrd_phys-y := 0x00800000 + +dtb-$(CONFIG_MACH_DREAMPLUG_DT) += kirkwood-dreamplug.dtb diff --git a/arch/arm/mach-kirkwood/board-dreamplug.c b/arch/arm/mach-kirkwood/board-dreamplug.c new file mode 100644 index 000000000000..985453994dd3 --- /dev/null +++ b/arch/arm/mach-kirkwood/board-dreamplug.c @@ -0,0 +1,152 @@ +/* + * Copyright 2012 (C), Jason Cooper <jason@lakedaemon.net> + * + * arch/arm/mach-kirkwood/board-dreamplug.c + * + * Marvell DreamPlug Reference Board Init for drivers not converted to + * flattened device tree yet. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/mtd/partitions.h> +#include <linux/ata_platform.h> +#include <linux/mv643xx_eth.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_fdt.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h> +#include <linux/gpio.h> +#include <linux/leds.h> +#include <linux/mtd/physmap.h> +#include <linux/spi/flash.h> +#include <linux/spi/spi.h> +#include <linux/spi/orion_spi.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <mach/kirkwood.h> +#include <mach/bridge-regs.h> +#include <plat/mvsdio.h> +#include "common.h" +#include "mpp.h" + +struct mtd_partition dreamplug_partitions[] = { + { + .name = "u-boot", + .size = SZ_512K, + .offset = 0, + }, + { + .name = "u-boot env", + .size = SZ_64K, + .offset = SZ_512K + SZ_512K, + }, + { + .name = "dtb", + .size = SZ_64K, + .offset = SZ_512K + SZ_512K + SZ_512K, + }, +}; + +static const struct flash_platform_data dreamplug_spi_slave_data = { + .type = "mx25l1606e", + .name = "spi_flash", + .parts = dreamplug_partitions, + .nr_parts = ARRAY_SIZE(dreamplug_partitions), +}; + +static struct spi_board_info __initdata dreamplug_spi_slave_info[] = { + { + .modalias = "m25p80", + .platform_data = &dreamplug_spi_slave_data, + .irq = -1, + .max_speed_hz = 50000000, + .bus_num = 0, + .chip_select = 0, + }, +}; + +static struct mv643xx_eth_platform_data dreamplug_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(0), +}; + +static struct mv643xx_eth_platform_data dreamplug_ge01_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(1), +}; + +static struct mv_sata_platform_data dreamplug_sata_data = { + .n_ports = 1, +}; + +static struct mvsdio_platform_data dreamplug_mvsdio_data = { + /* unfortunately the CD signal has not been connected */ +}; + +static struct gpio_led dreamplug_led_pins[] = { + { + .name = "dreamplug:blue:bluetooth", + .gpio = 47, + .active_low = 1, + }, + { + .name = "dreamplug:green:wifi", + .gpio = 48, + .active_low = 1, + }, + { + .name = "dreamplug:green:wifi_ap", + .gpio = 49, + .active_low = 1, + }, +}; + +static struct gpio_led_platform_data dreamplug_led_data = { + .leds = dreamplug_led_pins, + .num_leds = ARRAY_SIZE(dreamplug_led_pins), +}; + +static struct platform_device dreamplug_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &dreamplug_led_data, + } +}; + +static unsigned int dreamplug_mpp_config[] __initdata = { + MPP0_SPI_SCn, + MPP1_SPI_MOSI, + MPP2_SPI_SCK, + MPP3_SPI_MISO, + MPP47_GPIO, /* Bluetooth LED */ + MPP48_GPIO, /* Wifi LED */ + MPP49_GPIO, /* Wifi AP LED */ + 0 +}; + +void __init dreamplug_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_mpp_conf(dreamplug_mpp_config); + + spi_register_board_info(dreamplug_spi_slave_info, + ARRAY_SIZE(dreamplug_spi_slave_info)); + kirkwood_spi_init(); + + kirkwood_ehci_init(); + kirkwood_ge00_init(&dreamplug_ge00_data); + kirkwood_ge01_init(&dreamplug_ge01_data); + kirkwood_sata_init(&dreamplug_sata_data); + kirkwood_sdio_init(&dreamplug_mvsdio_data); + + platform_device_register(&dreamplug_leds); +} diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c new file mode 100644 index 000000000000..1c672d9e6656 --- /dev/null +++ b/arch/arm/mach-kirkwood/board-dt.c @@ -0,0 +1,75 @@ +/* + * Copyright 2012 (C), Jason Cooper <jason@lakedaemon.net> + * + * arch/arm/mach-kirkwood/board-dt.c + * + * Flattened Device Tree board initialization + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <mach/bridge-regs.h> +#include "common.h" + +static struct of_device_id kirkwood_dt_match_table[] __initdata = { + { .compatible = "simple-bus", }, + { } +}; + +static void __init kirkwood_dt_init(void) +{ + pr_info("Kirkwood: %s, TCLK=%d.\n", kirkwood_id(), kirkwood_tclk); + + /* + * Disable propagation of mbus errors to the CPU local bus, + * as this causes mbus errors (which can occur for example + * for PCI aborts) to throw CPU aborts, which we're not set + * up to deal with. + */ + writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG); + + kirkwood_setup_cpu_mbus(); + +#ifdef CONFIG_CACHE_FEROCEON_L2 + kirkwood_l2_init(); +#endif + + /* internal devices that every board has */ + kirkwood_wdt_init(); + kirkwood_xor0_init(); + kirkwood_xor1_init(); + kirkwood_crypto_init(); + +#ifdef CONFIG_KEXEC + kexec_reinit = kirkwood_enable_pcie; +#endif + + if (of_machine_is_compatible("globalscale,dreamplug")) + dreamplug_init(); + + of_platform_populate(NULL, kirkwood_dt_match_table, NULL, NULL); +} + +static const char *kirkwood_dt_board_compat[] = { + "globalscale,dreamplug", + NULL +}; + +DT_MACHINE_START(KIRKWOOD_DT, "Marvell Kirkwood (Flattened Device Tree)") + /* Maintainer: Jason Cooper <jason@lakedaemon.net> */ + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .timer = &kirkwood_timer, + .init_machine = kirkwood_dt_init, + .restart = kirkwood_restart, + .dt_compat = kirkwood_dt_board_compat, +MACHINE_END diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 77d4852e19f2..a02cae881f2f 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -279,7 +279,7 @@ void __init kirkwood_crypto_init(void) /***************************************************************************** * XOR0 ****************************************************************************/ -static void __init kirkwood_xor0_init(void) +void __init kirkwood_xor0_init(void) { kirkwood_clk_ctrl |= CGC_XOR0; @@ -291,7 +291,7 @@ static void __init kirkwood_xor0_init(void) /***************************************************************************** * XOR1 ****************************************************************************/ -static void __init kirkwood_xor1_init(void) +void __init kirkwood_xor1_init(void) { kirkwood_clk_ctrl |= CGC_XOR1; @@ -303,7 +303,7 @@ static void __init kirkwood_xor1_init(void) /***************************************************************************** * Watchdog ****************************************************************************/ -static void __init kirkwood_wdt_init(void) +void __init kirkwood_wdt_init(void) { orion_wdt_init(kirkwood_tclk); } @@ -392,7 +392,7 @@ void __init kirkwood_audio_init(void) /* * Identify device ID and revision. */ -static char * __init kirkwood_id(void) +char * __init kirkwood_id(void) { u32 dev, rev; @@ -435,7 +435,7 @@ static char * __init kirkwood_id(void) } } -static void __init kirkwood_l2_init(void) +void __init kirkwood_l2_init(void) { #ifdef CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH writel(readl(L2_CONFIG_REG) | L2_WRITETHROUGH, L2_CONFIG_REG); @@ -450,7 +450,6 @@ void __init kirkwood_init(void) { printk(KERN_INFO "Kirkwood: %s, TCLK=%d.\n", kirkwood_id(), kirkwood_tclk); - kirkwood_i2s_data.tclk = kirkwood_tclk; /* * Disable propagation of mbus errors to the CPU local bus, diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h index 9071a397136d..fa8e7689c436 100644 --- a/arch/arm/mach-kirkwood/common.h +++ b/arch/arm/mach-kirkwood/common.h @@ -51,6 +51,21 @@ void kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, int (*dev void kirkwood_audio_init(void); void kirkwood_restart(char, const char *); +/* board init functions for boards not fully converted to fdt */ +#ifdef CONFIG_MACH_DREAMPLUG_DT +void dreamplug_init(void); +#else +static inline void dreamplug_init(void) {}; +#endif + +/* early init functions not converted to fdt yet */ +char *kirkwood_id(void); +void kirkwood_l2_init(void); +void kirkwood_wdt_init(void); +void kirkwood_xor0_init(void); +void kirkwood_xor1_init(void); +void kirkwood_crypto_init(void); + extern int kirkwood_tclk; extern struct sys_timer kirkwood_timer; diff --git a/arch/arm/mach-kirkwood/cpuidle.c b/arch/arm/mach-kirkwood/cpuidle.c index 7088180b018b..0f1710941878 100644 --- a/arch/arm/mach-kirkwood/cpuidle.c +++ b/arch/arm/mach-kirkwood/cpuidle.c @@ -20,77 +20,47 @@ #include <linux/io.h> #include <linux/export.h> #include <asm/proc-fns.h> +#include <asm/cpuidle.h> #include <mach/kirkwood.h> #define KIRKWOOD_MAX_STATES 2 -static struct cpuidle_driver kirkwood_idle_driver = { - .name = "kirkwood_idle", - .owner = THIS_MODULE, -}; - -static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device); - /* Actual code that puts the SoC in different idle states */ static int kirkwood_enter_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { - struct timeval before, after; - int idle_time; - - local_irq_disable(); - do_gettimeofday(&before); - if (index == 0) - /* Wait for interrupt state */ - cpu_do_idle(); - else if (index == 1) { - /* - * Following write will put DDR in self refresh. - * Note that we have 256 cycles before DDR puts it - * self in self-refresh, so the wait-for-interrupt - * call afterwards won't get the DDR from self refresh - * mode. - */ - writel(0x7, DDR_OPERATION_BASE); - cpu_do_idle(); - } - do_gettimeofday(&after); - local_irq_enable(); - idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + - (after.tv_usec - before.tv_usec); - - /* Update last residency */ - dev->last_residency = idle_time; + writel(0x7, DDR_OPERATION_BASE); + cpu_do_idle(); return index; } +static struct cpuidle_driver kirkwood_idle_driver = { + .name = "kirkwood_idle", + .owner = THIS_MODULE, + .en_core_tk_irqen = 1, + .states[0] = ARM_CPUIDLE_WFI_STATE, + .states[1] = { + .enter = kirkwood_enter_idle, + .exit_latency = 10, + .target_residency = 100000, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "DDR SR", + .desc = "WFI and DDR Self Refresh", + }, + .state_count = KIRKWOOD_MAX_STATES, +}; + +static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device); + /* Initialize CPU idle by registering the idle states */ static int kirkwood_init_cpuidle(void) { struct cpuidle_device *device; - struct cpuidle_driver *driver = &kirkwood_idle_driver; device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id()); device->state_count = KIRKWOOD_MAX_STATES; - driver->state_count = KIRKWOOD_MAX_STATES; - - /* Wait for interrupt state */ - driver->states[0].enter = kirkwood_enter_idle; - driver->states[0].exit_latency = 1; - driver->states[0].target_residency = 10000; - driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID; - strcpy(driver->states[0].name, "WFI"); - strcpy(driver->states[0].desc, "Wait for interrupt"); - - /* Wait for interrupt and DDR self refresh state */ - driver->states[1].enter = kirkwood_enter_idle; - driver->states[1].exit_latency = 10; - driver->states[1].target_residency = 10000; - driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID; - strcpy(driver->states[1].name, "DDR SR"); - strcpy(driver->states[1].desc, "WFI and DDR Self Refresh"); cpuidle_register_driver(&kirkwood_idle_driver); if (cpuidle_register_device(device)) { diff --git a/arch/arm/mach-kirkwood/include/mach/entry-macro.S b/arch/arm/mach-kirkwood/include/mach/entry-macro.S index 8939d36f893c..82db29f7af8f 100644 --- a/arch/arm/mach-kirkwood/include/mach/entry-macro.S +++ b/arch/arm/mach-kirkwood/include/mach/entry-macro.S @@ -10,12 +10,6 @@ #include <mach/bridge-regs.h> - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_preamble, base, tmp ldr \base, =IRQ_VIRT_BASE .endm diff --git a/arch/arm/mach-kirkwood/include/mach/io.h b/arch/arm/mach-kirkwood/include/mach/io.h index 49dd0cb5e166..5d0ab61700d2 100644 --- a/arch/arm/mach-kirkwood/include/mach/io.h +++ b/arch/arm/mach-kirkwood/include/mach/io.h @@ -20,7 +20,5 @@ static inline void __iomem *__io(unsigned long addr) } #define __io(a) __io(a) -#define __mem_pci(a) (a) - #endif diff --git a/arch/arm/mach-kirkwood/include/mach/system.h b/arch/arm/mach-kirkwood/include/mach/system.h deleted file mode 100644 index 5fddde002b5e..000000000000 --- a/arch/arm/mach-kirkwood/include/mach/system.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * arch/arm/mach-kirkwood/include/mach/system.h - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c index a066a6d8d9d2..f56a0118c1bb 100644 --- a/arch/arm/mach-kirkwood/pcie.c +++ b/arch/arm/mach-kirkwood/pcie.c @@ -198,9 +198,9 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys) if (request_resource(&iomem_resource, &pp->res[1])) panic("Request PCIe%d Memory resource failed\n", index); - pci_add_resource(&sys->resources, &pp->res[0]); - pci_add_resource(&sys->resources, &pp->res[1]); sys->io_offset = 0; + pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset); + pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset); /* * Generic PCIe unit setup. diff --git a/arch/arm/mach-ks8695/include/mach/entry-macro.S b/arch/arm/mach-ks8695/include/mach/entry-macro.S index b4fe0c11c6ce..8315b34f32ff 100644 --- a/arch/arm/mach-ks8695/include/mach/entry-macro.S +++ b/arch/arm/mach-ks8695/include/mach/entry-macro.S @@ -14,16 +14,10 @@ #include <mach/hardware.h> #include <mach/regs-irq.h> - .macro disable_fiq - .endm - .macro get_irqnr_preamble, base, tmp ldr \base, =KS8695_IRQ_VA @ Base address of interrupt controller .endm - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \irqstat, [\base, #KS8695_INTMS] @ Mask Status register diff --git a/arch/arm/mach-ks8695/include/mach/io.h b/arch/arm/mach-ks8695/include/mach/io.h deleted file mode 100644 index a7a63ac3ba4e..000000000000 --- a/arch/arm/mach-ks8695/include/mach/io.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/arm/mach-ks8695/include/mach/io.h - * - * Copyright (C) 2006 Andrew Victor - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __ASM_ARCH_IO_H -#define __ASM_ARCH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#endif diff --git a/arch/arm/mach-ks8695/include/mach/system.h b/arch/arm/mach-ks8695/include/mach/system.h deleted file mode 100644 index 59fe992395bf..000000000000 --- a/arch/arm/mach-ks8695/include/mach/system.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * arch/arm/mach-s3c2410/include/mach/system.h - * - * Copyright (C) 2006 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * - * KS8695 - System function defines and includes - * - * 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. - */ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static void arch_idle(void) -{ - /* - * This should do all the clock switching - * and wait for interrupt tricks, - */ - cpu_do_idle(); - -} - -#endif diff --git a/arch/arm/mach-ks8695/pci.c b/arch/arm/mach-ks8695/pci.c index b26f992071df..acc701435817 100644 --- a/arch/arm/mach-ks8695/pci.c +++ b/arch/arm/mach-ks8695/pci.c @@ -169,8 +169,8 @@ static int __init ks8695_pci_setup(int nr, struct pci_sys_data *sys) request_resource(&iomem_resource, &pci_mem); request_resource(&ioport_resource, &pci_io); - pci_add_resource(&sys->resources, &pci_io); - pci_add_resource(&sys->resources, &pci_mem); + pci_add_resource_offset(&sys->resources, &pci_io, sys->io_offset); + pci_add_resource_offset(&sys->resources, &pci_mem, sys->mem_offset); /* Assign and enable processor bridge */ ks8695_local_writeconfig(PCI_BASE_ADDRESS_0, KS8695_PCIMEM_PA); diff --git a/arch/arm/mach-ks8695/time.c b/arch/arm/mach-ks8695/time.c index 37dfcd5bd2ad..ec783a3070ae 100644 --- a/arch/arm/mach-ks8695/time.c +++ b/arch/arm/mach-ks8695/time.c @@ -27,6 +27,7 @@ #include <linux/io.h> #include <asm/mach/time.h> +#include <asm/system_misc.h> #include <mach/regs-timer.h> #include <mach/regs-irq.h> diff --git a/arch/arm/mach-lpc32xx/Kconfig b/arch/arm/mach-lpc32xx/Kconfig index fde663508696..75946ac89ee9 100644 --- a/arch/arm/mach-lpc32xx/Kconfig +++ b/arch/arm/mach-lpc32xx/Kconfig @@ -29,5 +29,30 @@ config ARCH_LPC32XX_UART6_SELECT endmenu +menu "LPC32XX chip components" + +config ARCH_LPC32XX_IRAM_FOR_NET + bool "Use IRAM for network buffers" + default y + help + Say Y here to use the LPC internal fast IRAM (i.e. 256KB SRAM) as + network buffer. If the total combined required buffer sizes is + larger than the size of IRAM, then SDRAM will be used instead. + + This can be enabled safely if the IRAM is not intended for other + uses. + +config ARCH_LPC32XX_MII_SUPPORT + bool "Check to enable MII support or leave disabled for RMII support" + help + Say Y here to enable MII support, or N for RMII support. Regardless of + which support is selected, the ethernet interface driver needs to be + selected in the device driver networking section. + + The PHY3250 reference board uses RMII, so users of this board should + say N. + +endmenu + endif diff --git a/arch/arm/mach-lpc32xx/clock.c b/arch/arm/mach-lpc32xx/clock.c index 1e027514096d..2fc24ca12054 100644 --- a/arch/arm/mach-lpc32xx/clock.c +++ b/arch/arm/mach-lpc32xx/clock.c @@ -82,10 +82,12 @@ * will also impact the individual peripheral rates. */ +#include <linux/export.h> #include <linux/kernel.h> #include <linux/list.h> #include <linux/errno.h> #include <linux/device.h> +#include <linux/delay.h> #include <linux/err.h> #include <linux/clk.h> #include <linux/amba/bus.h> @@ -97,9 +99,12 @@ #include "clock.h" #include "common.h" +static DEFINE_SPINLOCK(global_clkregs_lock); + +static int usb_pll_enable, usb_pll_valid; + static struct clk clk_armpll; static struct clk clk_usbpll; -static DEFINE_MUTEX(clkm_lock); /* * Post divider values for PLLs based on selected register value @@ -127,7 +132,7 @@ static struct clk osc_32KHz = { static int local_pll397_enable(struct clk *clk, int enable) { u32 reg; - unsigned long timeout = 1 + msecs_to_jiffies(10); + unsigned long timeout = jiffies + msecs_to_jiffies(10); reg = __raw_readl(LPC32XX_CLKPWR_PLL397_CTRL); @@ -142,7 +147,7 @@ static int local_pll397_enable(struct clk *clk, int enable) /* Wait for PLL397 lock */ while (((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) & LPC32XX_CLKPWR_SYSCTRL_PLL397_STS) == 0) && - (timeout > jiffies)) + time_before(jiffies, timeout)) cpu_relax(); if ((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) & @@ -156,7 +161,7 @@ static int local_pll397_enable(struct clk *clk, int enable) static int local_oscmain_enable(struct clk *clk, int enable) { u32 reg; - unsigned long timeout = 1 + msecs_to_jiffies(10); + unsigned long timeout = jiffies + msecs_to_jiffies(10); reg = __raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL); @@ -171,7 +176,7 @@ static int local_oscmain_enable(struct clk *clk, int enable) /* Wait for main oscillator to start */ while (((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) & LPC32XX_CLKPWR_MOSC_DISABLE) != 0) && - (timeout > jiffies)) + time_before(jiffies, timeout)) cpu_relax(); if ((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) & @@ -382,30 +387,62 @@ static u32 local_clk_usbpll_setup(struct clk_pll_setup *pHCLKPllSetup) static int local_usbpll_enable(struct clk *clk, int enable) { u32 reg; - int ret = -ENODEV; - unsigned long timeout = 1 + msecs_to_jiffies(10); + int ret = 0; + unsigned long timeout = jiffies + msecs_to_jiffies(20); reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); - if (enable == 0) { - reg &= ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN1 | - LPC32XX_CLKPWR_USBCTRL_CLK_EN2); - __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); - } else if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP) { + __raw_writel(reg & ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN2 | + LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP), + LPC32XX_CLKPWR_USB_CTRL); + __raw_writel(reg & ~LPC32XX_CLKPWR_USBCTRL_CLK_EN1, + LPC32XX_CLKPWR_USB_CTRL); + + if (enable && usb_pll_valid && usb_pll_enable) { + ret = -ENODEV; + /* + * If the PLL rate has been previously set, then the rate + * in the PLL register is valid and can be enabled here. + * Otherwise, it needs to be enabled as part of setrate. + */ + + /* + * Gate clock into PLL + */ reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN1; __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); - /* Wait for PLL lock */ - while ((timeout > jiffies) & (ret == -ENODEV)) { + /* + * Enable PLL + */ + reg |= LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP; + __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); + + /* + * Wait for PLL to lock + */ + while (time_before(jiffies, timeout) && (ret == -ENODEV)) { reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_STS) ret = 0; + else + udelay(10); } + /* + * Gate clock from PLL if PLL is locked + */ if (ret == 0) { - reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN2; - __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); + __raw_writel(reg | LPC32XX_CLKPWR_USBCTRL_CLK_EN2, + LPC32XX_CLKPWR_USB_CTRL); + } else { + __raw_writel(reg & ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN1 | + LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP), + LPC32XX_CLKPWR_USB_CTRL); } + } else if ((enable == 0) && usb_pll_valid && usb_pll_enable) { + usb_pll_valid = 0; + usb_pll_enable = 0; } return ret; @@ -423,7 +460,7 @@ static unsigned long local_usbpll_round_rate(struct clk *clk, */ rate = rate * 1000; - clkin = clk->parent->rate; + clkin = clk->get_rate(clk); usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) & LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1; clkin = clkin / usbdiv; @@ -437,7 +474,8 @@ static unsigned long local_usbpll_round_rate(struct clk *clk, static int local_usbpll_set_rate(struct clk *clk, unsigned long rate) { - u32 clkin, reg, usbdiv; + int ret = -ENODEV; + u32 clkin, usbdiv; struct clk_pll_setup pllsetup; /* @@ -446,7 +484,7 @@ static int local_usbpll_set_rate(struct clk *clk, unsigned long rate) */ rate = rate * 1000; - clkin = clk->get_rate(clk); + clkin = clk->get_rate(clk->parent); usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) & LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1; clkin = clkin / usbdiv; @@ -455,22 +493,25 @@ static int local_usbpll_set_rate(struct clk *clk, unsigned long rate) if (local_clk_find_pll_cfg(clkin, rate, &pllsetup) == 0) return -EINVAL; + /* + * Disable PLL clocks during PLL change + */ local_usbpll_enable(clk, 0); - - reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); - reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN1; - __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); - - pllsetup.analog_on = 1; + pllsetup.analog_on = 0; local_clk_usbpll_setup(&pllsetup); - clk->rate = clk_check_pll_setup(clkin, &pllsetup); + /* + * Start USB PLL and check PLL status + */ + + usb_pll_valid = 1; + usb_pll_enable = 1; - reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); - reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN2; - __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); + ret = local_usbpll_enable(clk, 1); + if (ret >= 0) + clk->rate = clk_check_pll_setup(clkin, &pllsetup); - return 0; + return ret; } static struct clk clk_usbpll = { @@ -719,6 +760,41 @@ static struct clk clk_tsc = { .get_rate = local_return_parent_rate, }; +static int adc_onoff_enable(struct clk *clk, int enable) +{ + u32 tmp; + u32 divider; + + /* Use PERIPH_CLOCK */ + tmp = __raw_readl(LPC32XX_CLKPWR_ADC_CLK_CTRL_1); + tmp |= LPC32XX_CLKPWR_ADCCTRL1_PCLK_SEL; + /* + * Set clock divider so that we have equal to or less than + * 4.5MHz clock at ADC + */ + divider = clk->get_rate(clk) / 4500000 + 1; + tmp |= divider; + __raw_writel(tmp, LPC32XX_CLKPWR_ADC_CLK_CTRL_1); + + /* synchronize rate of this clock w/ actual HW setting */ + clk->rate = clk->get_rate(clk->parent) / divider; + + if (enable == 0) + __raw_writel(0, clk->enable_reg); + else + __raw_writel(clk->enable_mask, clk->enable_reg); + + return 0; +} + +static struct clk clk_adc = { + .parent = &clk_pclk, + .enable = adc_onoff_enable, + .enable_reg = LPC32XX_CLKPWR_ADC_CLK_CTRL, + .enable_mask = LPC32XX_CLKPWR_ADC32CLKCTRL_CLK_EN, + .get_rate = local_return_parent_rate, +}; + static int mmc_onoff_enable(struct clk *clk, int enable) { u32 tmp; @@ -891,20 +967,8 @@ static struct clk clk_lcd = { .enable_mask = LPC32XX_CLKPWR_LCDCTRL_CLK_EN, }; -static inline void clk_lock(void) -{ - mutex_lock(&clkm_lock); -} - -static inline void clk_unlock(void) -{ - mutex_unlock(&clkm_lock); -} - static void local_clk_disable(struct clk *clk) { - WARN_ON(clk->usecount == 0); - /* Don't attempt to disable clock if it has no users */ if (clk->usecount > 0) { clk->usecount--; @@ -947,10 +1011,11 @@ static int local_clk_enable(struct clk *clk) int clk_enable(struct clk *clk) { int ret; + unsigned long flags; - clk_lock(); + spin_lock_irqsave(&global_clkregs_lock, flags); ret = local_clk_enable(clk); - clk_unlock(); + spin_unlock_irqrestore(&global_clkregs_lock, flags); return ret; } @@ -961,9 +1026,11 @@ EXPORT_SYMBOL(clk_enable); */ void clk_disable(struct clk *clk) { - clk_lock(); + unsigned long flags; + + spin_lock_irqsave(&global_clkregs_lock, flags); local_clk_disable(clk); - clk_unlock(); + spin_unlock_irqrestore(&global_clkregs_lock, flags); } EXPORT_SYMBOL(clk_disable); @@ -972,13 +1039,7 @@ EXPORT_SYMBOL(clk_disable); */ unsigned long clk_get_rate(struct clk *clk) { - unsigned long rate; - - clk_lock(); - rate = clk->get_rate(clk); - clk_unlock(); - - return rate; + return clk->get_rate(clk); } EXPORT_SYMBOL(clk_get_rate); @@ -994,11 +1055,8 @@ int clk_set_rate(struct clk *clk, unsigned long rate) * the actual rate set as part of the peripheral dividers * instead of high level clock control */ - if (clk->set_rate) { - clk_lock(); + if (clk->set_rate) ret = clk->set_rate(clk, rate); - clk_unlock(); - } return ret; } @@ -1009,15 +1067,11 @@ EXPORT_SYMBOL(clk_set_rate); */ long clk_round_rate(struct clk *clk, unsigned long rate) { - clk_lock(); - if (clk->round_rate) rate = clk->round_rate(clk, rate); else rate = clk->get_rate(clk); - clk_unlock(); - return rate; } EXPORT_SYMBOL(clk_round_rate); @@ -1075,11 +1129,12 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("dev:ssp1", NULL, clk_ssp1) _REGISTER_CLOCK("lpc32xx_keys.0", NULL, clk_kscan) _REGISTER_CLOCK("lpc32xx-nand.0", "nand_ck", clk_nand) - _REGISTER_CLOCK("tbd", "i2s0_ck", clk_i2s0) - _REGISTER_CLOCK("tbd", "i2s1_ck", clk_i2s1) + _REGISTER_CLOCK("lpc32xx-adc", NULL, clk_adc) + _REGISTER_CLOCK(NULL, "i2s0_ck", clk_i2s0) + _REGISTER_CLOCK(NULL, "i2s1_ck", clk_i2s1) _REGISTER_CLOCK("ts-lpc32xx", NULL, clk_tsc) - _REGISTER_CLOCK("dev:mmc0", "MCLK", clk_mmc) - _REGISTER_CLOCK("lpc-net.0", NULL, clk_net) + _REGISTER_CLOCK("dev:mmc0", NULL, clk_mmc) + _REGISTER_CLOCK("lpc-eth.0", NULL, clk_net) _REGISTER_CLOCK("dev:clcd", NULL, clk_lcd) _REGISTER_CLOCK("lpc32xx_udc", "ck_usbd", clk_usbd) _REGISTER_CLOCK("lpc32xx_rtc", NULL, clk_rtc) diff --git a/arch/arm/mach-lpc32xx/common.c b/arch/arm/mach-lpc32xx/common.c index 369b152896cd..bbbf063a74c2 100644 --- a/arch/arm/mach-lpc32xx/common.c +++ b/arch/arm/mach-lpc32xx/common.c @@ -138,6 +138,75 @@ struct platform_device lpc32xx_rtc_device = { }; /* + * ADC support + */ +static struct resource adc_resources[] = { + { + .start = LPC32XX_ADC_BASE, + .end = LPC32XX_ADC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_LPC32XX_TS_IRQ, + .end = IRQ_LPC32XX_TS_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device lpc32xx_adc_device = { + .name = "lpc32xx-adc", + .id = -1, + .num_resources = ARRAY_SIZE(adc_resources), + .resource = adc_resources, +}; + +/* + * USB support + */ +/* The dmamask must be set for OHCI to work */ +static u64 ohci_dmamask = ~(u32) 0; +static struct resource ohci_resources[] = { + { + .start = IO_ADDRESS(LPC32XX_USB_BASE), + .end = IO_ADDRESS(LPC32XX_USB_BASE + 0x100 - 1), + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_LPC32XX_USB_HOST, + .flags = IORESOURCE_IRQ, + }, +}; +struct platform_device lpc32xx_ohci_device = { + .name = "usb-ohci", + .id = -1, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = 0xFFFFFFFF, + }, + .num_resources = ARRAY_SIZE(ohci_resources), + .resource = ohci_resources, +}; + +/* + * Network Support + */ +static struct resource net_resources[] = { + [0] = DEFINE_RES_MEM(LPC32XX_ETHERNET_BASE, SZ_4K), + [1] = DEFINE_RES_MEM(LPC32XX_IRAM_BASE, SZ_128K), + [2] = DEFINE_RES_IRQ(IRQ_LPC32XX_ETHERNET), +}; + +static u64 lpc32xx_mac_dma_mask = 0xffffffffUL; +struct platform_device lpc32xx_net_device = { + .name = "lpc-eth", + .id = 0, + .dev = { + .dma_mask = &lpc32xx_mac_dma_mask, + .coherent_dma_mask = 0xffffffffUL, + }, + .num_resources = ARRAY_SIZE(net_resources), + .resource = net_resources, +}; + +/* * Returns the unique ID for the device */ void lpc32xx_get_uid(u32 devid[4]) diff --git a/arch/arm/mach-lpc32xx/common.h b/arch/arm/mach-lpc32xx/common.h index 4b4e700343c1..68e45e8c9486 100644 --- a/arch/arm/mach-lpc32xx/common.h +++ b/arch/arm/mach-lpc32xx/common.h @@ -19,6 +19,7 @@ #ifndef __LPC32XX_COMMON_H #define __LPC32XX_COMMON_H +#include <mach/board.h> #include <linux/platform_device.h> /* @@ -29,7 +30,10 @@ extern struct platform_device lpc32xx_i2c0_device; extern struct platform_device lpc32xx_i2c1_device; extern struct platform_device lpc32xx_i2c2_device; extern struct platform_device lpc32xx_tsc_device; +extern struct platform_device lpc32xx_adc_device; extern struct platform_device lpc32xx_rtc_device; +extern struct platform_device lpc32xx_ohci_device; +extern struct platform_device lpc32xx_net_device; /* * Other arch specific structures and functions @@ -65,9 +69,7 @@ extern u32 clk_get_pclk_div(void); */ extern void lpc32xx_get_uid(u32 devid[4]); -extern void lpc32xx_watchdog_reset(void); extern u32 lpc32xx_return_iram_size(void); - /* * Pointers used for sizing and copying suspend function data */ diff --git a/arch/arm/mach-lpc32xx/include/mach/system.h b/arch/arm/mach-lpc32xx/include/mach/board.h index bf176c991520..52531ca7bd1d 100644 --- a/arch/arm/mach-lpc32xx/include/mach/system.h +++ b/arch/arm/mach-lpc32xx/include/mach/board.h @@ -1,5 +1,5 @@ /* - * arch/arm/mach-lpc32xx/include/mach/system.h + * arm/arch/mach-lpc32xx/include/mach/board.h * * Author: Kevin Wells <kevin.wells@nxp.com> * @@ -16,12 +16,9 @@ * GNU General Public License for more details. */ -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H +#ifndef __ASM_ARCH_BOARD_H +#define __ASM_ARCH_BOARD_H -static void arch_idle(void) -{ - cpu_do_idle(); -} +extern u32 lpc32xx_return_iram_size(void); -#endif +#endif /* __ASM_ARCH_BOARD_H */ diff --git a/arch/arm/mach-lpc32xx/include/mach/entry-macro.S b/arch/arm/mach-lpc32xx/include/mach/entry-macro.S index b725f6c93975..24ca11b377c8 100644 --- a/arch/arm/mach-lpc32xx/include/mach/entry-macro.S +++ b/arch/arm/mach-lpc32xx/include/mach/entry-macro.S @@ -21,16 +21,10 @@ #define LPC32XX_INTC_MASKED_STATUS_OFS 0x8 - .macro disable_fiq - .endm - .macro get_irqnr_preamble, base, tmp ldr \base, =IO_ADDRESS(LPC32XX_MIC_BASE) .endm - .macro arch_ret_to_user, tmp1, tmp2 - .endm - /* * Return IRQ number in irqnr. Also return processor Z flag status in CPSR * as set if an interrupt is pending. diff --git a/arch/arm/mach-lpc32xx/include/mach/io.h b/arch/arm/mach-lpc32xx/include/mach/io.h deleted file mode 100644 index 9b59ab5cef89..000000000000 --- a/arch/arm/mach-lpc32xx/include/mach/io.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * arch/arm/mach-lpc32xx/include/mach/io.h - * - * Author: Kevin Wells <kevin.wells@nxp.com> - * - * Copyright (C) 2010 NXP Semiconductors - * - * 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 __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#endif diff --git a/arch/arm/mach-lpc32xx/include/mach/platform.h b/arch/arm/mach-lpc32xx/include/mach/platform.h index 14ea8d1aadb5..c584f5bb164f 100644 --- a/arch/arm/mach-lpc32xx/include/mach/platform.h +++ b/arch/arm/mach-lpc32xx/include/mach/platform.h @@ -591,42 +591,42 @@ /* * Timer/counter register offsets */ -#define LCP32XX_TIMER_IR(x) io_p2v((x) + 0x00) -#define LCP32XX_TIMER_TCR(x) io_p2v((x) + 0x04) -#define LCP32XX_TIMER_TC(x) io_p2v((x) + 0x08) -#define LCP32XX_TIMER_PR(x) io_p2v((x) + 0x0C) -#define LCP32XX_TIMER_PC(x) io_p2v((x) + 0x10) -#define LCP32XX_TIMER_MCR(x) io_p2v((x) + 0x14) -#define LCP32XX_TIMER_MR0(x) io_p2v((x) + 0x18) -#define LCP32XX_TIMER_MR1(x) io_p2v((x) + 0x1C) -#define LCP32XX_TIMER_MR2(x) io_p2v((x) + 0x20) -#define LCP32XX_TIMER_MR3(x) io_p2v((x) + 0x24) -#define LCP32XX_TIMER_CCR(x) io_p2v((x) + 0x28) -#define LCP32XX_TIMER_CR0(x) io_p2v((x) + 0x2C) -#define LCP32XX_TIMER_CR1(x) io_p2v((x) + 0x30) -#define LCP32XX_TIMER_CR2(x) io_p2v((x) + 0x34) -#define LCP32XX_TIMER_CR3(x) io_p2v((x) + 0x38) -#define LCP32XX_TIMER_EMR(x) io_p2v((x) + 0x3C) -#define LCP32XX_TIMER_CTCR(x) io_p2v((x) + 0x70) +#define LPC32XX_TIMER_IR(x) io_p2v((x) + 0x00) +#define LPC32XX_TIMER_TCR(x) io_p2v((x) + 0x04) +#define LPC32XX_TIMER_TC(x) io_p2v((x) + 0x08) +#define LPC32XX_TIMER_PR(x) io_p2v((x) + 0x0C) +#define LPC32XX_TIMER_PC(x) io_p2v((x) + 0x10) +#define LPC32XX_TIMER_MCR(x) io_p2v((x) + 0x14) +#define LPC32XX_TIMER_MR0(x) io_p2v((x) + 0x18) +#define LPC32XX_TIMER_MR1(x) io_p2v((x) + 0x1C) +#define LPC32XX_TIMER_MR2(x) io_p2v((x) + 0x20) +#define LPC32XX_TIMER_MR3(x) io_p2v((x) + 0x24) +#define LPC32XX_TIMER_CCR(x) io_p2v((x) + 0x28) +#define LPC32XX_TIMER_CR0(x) io_p2v((x) + 0x2C) +#define LPC32XX_TIMER_CR1(x) io_p2v((x) + 0x30) +#define LPC32XX_TIMER_CR2(x) io_p2v((x) + 0x34) +#define LPC32XX_TIMER_CR3(x) io_p2v((x) + 0x38) +#define LPC32XX_TIMER_EMR(x) io_p2v((x) + 0x3C) +#define LPC32XX_TIMER_CTCR(x) io_p2v((x) + 0x70) /* * ir register definitions */ -#define LCP32XX_TIMER_CNTR_MTCH_BIT(n) (1 << ((n) & 0x3)) -#define LCP32XX_TIMER_CNTR_CAPT_BIT(n) (1 << (4 + ((n) & 0x3))) +#define LPC32XX_TIMER_CNTR_MTCH_BIT(n) (1 << ((n) & 0x3)) +#define LPC32XX_TIMER_CNTR_CAPT_BIT(n) (1 << (4 + ((n) & 0x3))) /* * tcr register definitions */ -#define LCP32XX_TIMER_CNTR_TCR_EN 0x1 -#define LCP32XX_TIMER_CNTR_TCR_RESET 0x2 +#define LPC32XX_TIMER_CNTR_TCR_EN 0x1 +#define LPC32XX_TIMER_CNTR_TCR_RESET 0x2 /* * mcr register definitions */ -#define LCP32XX_TIMER_CNTR_MCR_MTCH(n) (0x1 << ((n) * 3)) -#define LCP32XX_TIMER_CNTR_MCR_RESET(n) (0x1 << (((n) * 3) + 1)) -#define LCP32XX_TIMER_CNTR_MCR_STOP(n) (0x1 << (((n) * 3) + 2)) +#define LPC32XX_TIMER_CNTR_MCR_MTCH(n) (0x1 << ((n) * 3)) +#define LPC32XX_TIMER_CNTR_MCR_RESET(n) (0x1 << (((n) * 3) + 1)) +#define LPC32XX_TIMER_CNTR_MCR_STOP(n) (0x1 << (((n) * 3) + 2)) /* * Standard UART register offsets @@ -690,5 +690,8 @@ #define LPC32XX_GPIO_P1_MUX_SET _GPREG(0x130) #define LPC32XX_GPIO_P1_MUX_CLR _GPREG(0x134) #define LPC32XX_GPIO_P1_MUX_STATE _GPREG(0x138) +#define LPC32XX_GPIO_P2_MUX_SET _GPREG(0x028) +#define LPC32XX_GPIO_P2_MUX_CLR _GPREG(0x02C) +#define LPC32XX_GPIO_P2_MUX_STATE _GPREG(0x030) #endif diff --git a/arch/arm/mach-lpc32xx/irq.c b/arch/arm/mach-lpc32xx/irq.c index c74de01ab5b6..d080cb1123dd 100644 --- a/arch/arm/mach-lpc32xx/irq.c +++ b/arch/arm/mach-lpc32xx/irq.c @@ -150,6 +150,10 @@ static const struct lpc32xx_event_info lpc32xx_events[NR_IRQS] = { .event_group = &lpc32xx_event_int_regs, .mask = LPC32XX_CLKPWR_INTSRC_KEY_BIT, }, + [IRQ_LPC32XX_ETHERNET] = { + .event_group = &lpc32xx_event_int_regs, + .mask = LPC32XX_CLKPWR_INTSRC_MAC_BIT, + }, [IRQ_LPC32XX_USB_OTG_ATX] = { .event_group = &lpc32xx_event_int_regs, .mask = LPC32XX_CLKPWR_INTSRC_USBATXINT_BIT, diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c index bfee5b455105..7f7401ec7487 100644 --- a/arch/arm/mach-lpc32xx/phy3250.c +++ b/arch/arm/mach-lpc32xx/phy3250.c @@ -37,6 +37,7 @@ #include <mach/hardware.h> #include <mach/platform.h> +#include <mach/board.h> #include <mach/gpio-lpc32xx.h> #include "common.h" @@ -149,20 +150,8 @@ static struct clcd_board lpc32xx_clcd_data = { .remove = lpc32xx_clcd_remove, }; -static struct amba_device lpc32xx_clcd_device = { - .dev = { - .coherent_dma_mask = ~0, - .init_name = "dev:clcd", - .platform_data = &lpc32xx_clcd_data, - }, - .res = { - .start = LPC32XX_LCD_BASE, - .end = (LPC32XX_LCD_BASE + SZ_4K - 1), - .flags = IORESOURCE_MEM, - }, - .dma_mask = ~0, - .irq = {IRQ_LPC32XX_LCD, NO_IRQ}, -}; +static AMBA_AHB_DEVICE(lpc32xx_clcd, "dev:clcd", 0, + LPC32XX_LCD_BASE, { IRQ_LPC32XX_LCD }, &lpc32xx_clcd_data); /* * AMBA SSP (SPI) @@ -191,20 +180,8 @@ static struct pl022_ssp_controller lpc32xx_ssp0_data = { .enable_dma = 0, }; -static struct amba_device lpc32xx_ssp0_device = { - .dev = { - .coherent_dma_mask = ~0, - .init_name = "dev:ssp0", - .platform_data = &lpc32xx_ssp0_data, - }, - .res = { - .start = LPC32XX_SSP0_BASE, - .end = (LPC32XX_SSP0_BASE + SZ_4K - 1), - .flags = IORESOURCE_MEM, - }, - .dma_mask = ~0, - .irq = {IRQ_LPC32XX_SSP0, NO_IRQ}, -}; +static AMBA_APB_DEVICE(lpc32xx_ssp0, "dev:ssp0", 0, + LPC32XX_SSP0_BASE, { IRQ_LPC32XX_SSP0 }, &lpc32xx_ssp0_data); /* AT25 driver registration */ static int __init phy3250_spi_board_register(void) @@ -271,11 +248,16 @@ static struct platform_device lpc32xx_gpio_led_device = { }; static struct platform_device *phy3250_devs[] __initdata = { + &lpc32xx_rtc_device, + &lpc32xx_tsc_device, &lpc32xx_i2c0_device, &lpc32xx_i2c1_device, &lpc32xx_i2c2_device, &lpc32xx_watchdog_device, &lpc32xx_gpio_led_device, + &lpc32xx_adc_device, + &lpc32xx_ohci_device, + &lpc32xx_net_device, }; static struct amba_device *amba_devs[] __initdata = { diff --git a/arch/arm/mach-lpc32xx/pm.c b/arch/arm/mach-lpc32xx/pm.c index b9c80597b7bf..207e81275ff0 100644 --- a/arch/arm/mach-lpc32xx/pm.c +++ b/arch/arm/mach-lpc32xx/pm.c @@ -13,7 +13,7 @@ /* * LPC32XX CPU and system power management * - * The LCP32XX has three CPU modes for controlling system power: run, + * The LPC32XX has three CPU modes for controlling system power: run, * direct-run, and halt modes. When switching between halt and run modes, * the CPU transistions through direct-run mode. For Linux, direct-run * mode is not used in normal operation. Halt mode is used when the diff --git a/arch/arm/mach-lpc32xx/timer.c b/arch/arm/mach-lpc32xx/timer.c index b42c909bbeeb..c40667c33161 100644 --- a/arch/arm/mach-lpc32xx/timer.c +++ b/arch/arm/mach-lpc32xx/timer.c @@ -34,11 +34,11 @@ static int lpc32xx_clkevt_next_event(unsigned long delta, struct clock_event_device *dev) { - __raw_writel(LCP32XX_TIMER_CNTR_TCR_RESET, - LCP32XX_TIMER_TCR(LPC32XX_TIMER0_BASE)); - __raw_writel(delta, LCP32XX_TIMER_PR(LPC32XX_TIMER0_BASE)); - __raw_writel(LCP32XX_TIMER_CNTR_TCR_EN, - LCP32XX_TIMER_TCR(LPC32XX_TIMER0_BASE)); + __raw_writel(LPC32XX_TIMER_CNTR_TCR_RESET, + LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE)); + __raw_writel(delta, LPC32XX_TIMER_PR(LPC32XX_TIMER0_BASE)); + __raw_writel(LPC32XX_TIMER_CNTR_TCR_EN, + LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE)); return 0; } @@ -58,7 +58,7 @@ static void lpc32xx_clkevt_mode(enum clock_event_mode mode, * disable the timer to wait for the first call to * set_next_event(). */ - __raw_writel(0, LCP32XX_TIMER_TCR(LPC32XX_TIMER0_BASE)); + __raw_writel(0, LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE)); break; case CLOCK_EVT_MODE_UNUSED: @@ -81,8 +81,8 @@ static irqreturn_t lpc32xx_timer_interrupt(int irq, void *dev_id) struct clock_event_device *evt = &lpc32xx_clkevt; /* Clear match */ - __raw_writel(LCP32XX_TIMER_CNTR_MTCH_BIT(0), - LCP32XX_TIMER_IR(LPC32XX_TIMER0_BASE)); + __raw_writel(LPC32XX_TIMER_CNTR_MTCH_BIT(0), + LPC32XX_TIMER_IR(LPC32XX_TIMER0_BASE)); evt->event_handler(evt); @@ -128,14 +128,14 @@ static void __init lpc32xx_timer_init(void) clkrate = clkrate / clk_get_pclk_div(); /* Initial timer setup */ - __raw_writel(0, LCP32XX_TIMER_TCR(LPC32XX_TIMER0_BASE)); - __raw_writel(LCP32XX_TIMER_CNTR_MTCH_BIT(0), - LCP32XX_TIMER_IR(LPC32XX_TIMER0_BASE)); - __raw_writel(1, LCP32XX_TIMER_MR0(LPC32XX_TIMER0_BASE)); - __raw_writel(LCP32XX_TIMER_CNTR_MCR_MTCH(0) | - LCP32XX_TIMER_CNTR_MCR_STOP(0) | - LCP32XX_TIMER_CNTR_MCR_RESET(0), - LCP32XX_TIMER_MCR(LPC32XX_TIMER0_BASE)); + __raw_writel(0, LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE)); + __raw_writel(LPC32XX_TIMER_CNTR_MTCH_BIT(0), + LPC32XX_TIMER_IR(LPC32XX_TIMER0_BASE)); + __raw_writel(1, LPC32XX_TIMER_MR0(LPC32XX_TIMER0_BASE)); + __raw_writel(LPC32XX_TIMER_CNTR_MCR_MTCH(0) | + LPC32XX_TIMER_CNTR_MCR_STOP(0) | + LPC32XX_TIMER_CNTR_MCR_RESET(0), + LPC32XX_TIMER_MCR(LPC32XX_TIMER0_BASE)); /* Setup tick interrupt */ setup_irq(IRQ_LPC32XX_TIMER0, &lpc32xx_timer_irq); @@ -151,14 +151,14 @@ static void __init lpc32xx_timer_init(void) clockevents_register_device(&lpc32xx_clkevt); /* Use timer1 as clock source. */ - __raw_writel(LCP32XX_TIMER_CNTR_TCR_RESET, - LCP32XX_TIMER_TCR(LPC32XX_TIMER1_BASE)); - __raw_writel(0, LCP32XX_TIMER_PR(LPC32XX_TIMER1_BASE)); - __raw_writel(0, LCP32XX_TIMER_MCR(LPC32XX_TIMER1_BASE)); - __raw_writel(LCP32XX_TIMER_CNTR_TCR_EN, - LCP32XX_TIMER_TCR(LPC32XX_TIMER1_BASE)); - - clocksource_mmio_init(LCP32XX_TIMER_TC(LPC32XX_TIMER1_BASE), + __raw_writel(LPC32XX_TIMER_CNTR_TCR_RESET, + LPC32XX_TIMER_TCR(LPC32XX_TIMER1_BASE)); + __raw_writel(0, LPC32XX_TIMER_PR(LPC32XX_TIMER1_BASE)); + __raw_writel(0, LPC32XX_TIMER_MCR(LPC32XX_TIMER1_BASE)); + __raw_writel(LPC32XX_TIMER_CNTR_TCR_EN, + LPC32XX_TIMER_TCR(LPC32XX_TIMER1_BASE)); + + clocksource_mmio_init(LPC32XX_TIMER_TC(LPC32XX_TIMER1_BASE), "lpc32xx_clksrc", clkrate, 300, 32, clocksource_mmio_readl_up); } diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig index 323d4c9e9f44..5a90b9a3ab6e 100644 --- a/arch/arm/mach-mmp/Kconfig +++ b/arch/arm/mach-mmp/Kconfig @@ -2,6 +2,16 @@ if ARCH_MMP menu "Marvell PXA168/910/MMP2 Implmentations" +config MACH_MMP_DT + bool "Support MMP2 platforms from device tree" + select CPU_PXA168 + select CPU_PXA910 + select USE_OF + help + Include support for Marvell MMP2 based platforms using + the device tree. Needn't select any other machine while + MACH_MMP_DT is enabled. + config MACH_ASPENITE bool "Marvell's PXA168 Aspenite Development Board" select CPU_PXA168 diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile index ba254a71691a..4fc0ff5dc96d 100644 --- a/arch/arm/mach-mmp/Makefile +++ b/arch/arm/mach-mmp/Makefile @@ -18,5 +18,6 @@ obj-$(CONFIG_MACH_TTC_DKB) += ttc_dkb.o obj-$(CONFIG_MACH_BROWNSTONE) += brownstone.o obj-$(CONFIG_MACH_FLINT) += flint.o obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o +obj-$(CONFIG_MACH_MMP_DT) += mmp-dt.o obj-$(CONFIG_MACH_TETON_BGA) += teton_bga.o obj-$(CONFIG_MACH_GPLUGD) += gplugd.o diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c index 3588a5584153..bf5d8e195c3e 100644 --- a/arch/arm/mach-mmp/aspenite.c +++ b/arch/arm/mach-mmp/aspenite.c @@ -23,6 +23,7 @@ #include <mach/addr-map.h> #include <mach/mfp-pxa168.h> #include <mach/pxa168.h> +#include <mach/irqs.h> #include <video/pxa168fb.h> #include <linux/input.h> #include <plat/pxa27x_keypad.h> @@ -239,7 +240,7 @@ static void __init common_init(void) MACHINE_START(ASPENITE, "PXA168-based Aspenite Development Platform") .map_io = mmp_map_io, - .nr_irqs = IRQ_BOARD_START, + .nr_irqs = MMP_NR_IRQS, .init_irq = pxa168_init_irq, .timer = &pxa168_timer, .init_machine = common_init, @@ -248,7 +249,7 @@ MACHINE_END MACHINE_START(ZYLONITE2, "PXA168-based Zylonite2 Development Platform") .map_io = mmp_map_io, - .nr_irqs = IRQ_BOARD_START, + .nr_irqs = MMP_NR_IRQS, .init_irq = pxa168_init_irq, .timer = &pxa168_timer, .init_machine = common_init, diff --git a/arch/arm/mach-mmp/avengers_lite.c b/arch/arm/mach-mmp/avengers_lite.c index b148a9dc5a44..603542ae6fbd 100644 --- a/arch/arm/mach-mmp/avengers_lite.c +++ b/arch/arm/mach-mmp/avengers_lite.c @@ -43,6 +43,7 @@ static void __init avengers_lite_init(void) MACHINE_START(AVENGERS_LITE, "PXA168 Avengers lite Development Platform") .map_io = mmp_map_io, + .nr_irqs = MMP_NR_IRQS, .init_irq = pxa168_init_irq, .timer = &pxa168_timer, .init_machine = avengers_lite_init, diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c index d839fe6421e6..5cb769cd26d9 100644 --- a/arch/arm/mach-mmp/brownstone.c +++ b/arch/arm/mach-mmp/brownstone.c @@ -28,7 +28,7 @@ #include "common.h" -#define BROWNSTONE_NR_IRQS (IRQ_BOARD_START + 40) +#define BROWNSTONE_NR_IRQS (MMP_NR_IRQS + 40) #define GPIO_5V_ENABLE (89) @@ -158,7 +158,7 @@ static struct platform_device brownstone_v_5vp_device = { }; static struct max8925_platform_data brownstone_max8925_info = { - .irq_base = IRQ_BOARD_START, + .irq_base = MMP_NR_IRQS, }; static struct i2c_board_info brownstone_twsi1_info[] = { diff --git a/arch/arm/mach-mmp/common.c b/arch/arm/mach-mmp/common.c index 062b5b93c50e..9292b7966e3b 100644 --- a/arch/arm/mach-mmp/common.c +++ b/arch/arm/mach-mmp/common.c @@ -14,6 +14,7 @@ #include <asm/page.h> #include <asm/mach/map.h> +#include <asm/system_misc.h> #include <mach/addr-map.h> #include <mach/cputype.h> diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c index 2ee8cd7829dd..8059cc0905c6 100644 --- a/arch/arm/mach-mmp/flint.c +++ b/arch/arm/mach-mmp/flint.c @@ -23,10 +23,11 @@ #include <mach/addr-map.h> #include <mach/mfp-mmp2.h> #include <mach/mmp2.h> +#include <mach/irqs.h> #include "common.h" -#define FLINT_NR_IRQS (IRQ_BOARD_START + 48) +#define FLINT_NR_IRQS (MMP_NR_IRQS + 48) static unsigned long flint_pin_config[] __initdata = { /* UART1 */ diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c index 87765467de63..f516e74ce0d5 100644 --- a/arch/arm/mach-mmp/gplugd.c +++ b/arch/arm/mach-mmp/gplugd.c @@ -191,7 +191,7 @@ static void __init gplugd_init(void) MACHINE_START(GPLUGD, "PXA168-based GuruPlug Display (gplugD) Platform") .map_io = mmp_map_io, - .nr_irqs = IRQ_BOARD_START, + .nr_irqs = MMP_NR_IRQS, .init_irq = pxa168_init_irq, .timer = &pxa168_timer, .init_machine = gplugd_init, diff --git a/arch/arm/mach-mmp/include/mach/addr-map.h b/arch/arm/mach-mmp/include/mach/addr-map.h index 3e404acd6ff4..b1ece08174e8 100644 --- a/arch/arm/mach-mmp/include/mach/addr-map.h +++ b/arch/arm/mach-mmp/include/mach/addr-map.h @@ -11,12 +11,6 @@ #ifndef __ASM_MACH_ADDR_MAP_H #define __ASM_MACH_ADDR_MAP_H -#ifndef __ASSEMBLER__ -#define IOMEM(x) ((void __iomem *)(x)) -#else -#define IOMEM(x) (x) -#endif - /* APB - Application Subsystem Peripheral Bus * * NOTE: the DMA controller registers are actually on the AXI fabric #1 diff --git a/arch/arm/mach-mmp/include/mach/entry-macro.S b/arch/arm/mach-mmp/include/mach/entry-macro.S index c42d9d4e892d..9cff9e7a2b26 100644 --- a/arch/arm/mach-mmp/include/mach/entry-macro.S +++ b/arch/arm/mach-mmp/include/mach/entry-macro.S @@ -8,12 +8,6 @@ #include <mach/regs-icu.h> - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_preamble, base, tmp mrc p15, 0, \tmp, c0, c0, 0 @ CPUID and \tmp, \tmp, #0xff00 diff --git a/arch/arm/mach-mmp/include/mach/io.h b/arch/arm/mach-mmp/include/mach/io.h deleted file mode 100644 index e7adf3d012c1..000000000000 --- a/arch/arm/mach-mmp/include/mach/io.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * linux/arch/arm/mach-mmp/include/mach/io.h - * - * 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. - */ - -#ifndef __ASM_MACH_IO_H -#define __ASM_MACH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -/* - * We don't actually have real ISA nor PCI buses, but there is so many - * drivers out there that might just work if we fake them... - */ -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#endif /* __ASM_MACH_IO_H */ diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h index 34635a0bbb59..d0e746626a3d 100644 --- a/arch/arm/mach-mmp/include/mach/irqs.h +++ b/arch/arm/mach-mmp/include/mach/irqs.h @@ -223,7 +223,6 @@ #define MMP_GPIO_TO_IRQ(gpio) (IRQ_GPIO_START + (gpio)) #define IRQ_BOARD_START (IRQ_GPIO_START + MMP_NR_BUILTIN_GPIO) - -#define NR_IRQS (IRQ_BOARD_START) +#define MMP_NR_IRQS IRQ_BOARD_START #endif /* __ASM_MACH_IRQS_H */ diff --git a/arch/arm/mach-mmp/include/mach/pxa910.h b/arch/arm/mach-mmp/include/mach/pxa910.h index 4de13abef7bb..e2e1f1e5e124 100644 --- a/arch/arm/mach-mmp/include/mach/pxa910.h +++ b/arch/arm/mach-mmp/include/mach/pxa910.h @@ -22,6 +22,7 @@ extern struct pxa_device_desc pxa910_device_pwm4; extern struct pxa_device_desc pxa910_device_nand; extern struct platform_device pxa910_device_gpio; +extern struct platform_device pxa910_device_rtc; static inline int pxa910_add_uart(int id) { diff --git a/arch/arm/mach-mmp/include/mach/regs-apbc.h b/arch/arm/mach-mmp/include/mach/regs-apbc.h index 1a96585336ba..8a37fb003655 100644 --- a/arch/arm/mach-mmp/include/mach/regs-apbc.h +++ b/arch/arm/mach-mmp/include/mach/regs-apbc.h @@ -57,6 +57,7 @@ #define APBC_PXA910_SSP1 APBC_REG(0x01c) #define APBC_PXA910_SSP2 APBC_REG(0x020) #define APBC_PXA910_IPC APBC_REG(0x024) +#define APBC_PXA910_RTC APBC_REG(0x028) #define APBC_PXA910_TWSI0 APBC_REG(0x02c) #define APBC_PXA910_KPC APBC_REG(0x030) #define APBC_PXA910_TIMERS APBC_REG(0x034) diff --git a/arch/arm/mach-mmp/include/mach/regs-rtc.h b/arch/arm/mach-mmp/include/mach/regs-rtc.h new file mode 100644 index 000000000000..5bff886a3941 --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/regs-rtc.h @@ -0,0 +1,23 @@ +#ifndef __ASM_MACH_REGS_RTC_H +#define __ASM_MACH_REGS_RTC_H + +#include <mach/addr-map.h> + +#define RTC_VIRT_BASE (APB_VIRT_BASE + 0x10000) +#define RTC_REG(x) (*((volatile u32 __iomem *)(RTC_VIRT_BASE + (x)))) + +/* + * Real Time Clock + */ + +#define RCNR RTC_REG(0x00) /* RTC Count Register */ +#define RTAR RTC_REG(0x04) /* RTC Alarm Register */ +#define RTSR RTC_REG(0x08) /* RTC Status Register */ +#define RTTR RTC_REG(0x0C) /* RTC Timer Trim Register */ + +#define RTSR_HZE (1 << 3) /* HZ interrupt enable */ +#define RTSR_ALE (1 << 2) /* RTC alarm interrupt enable */ +#define RTSR_HZ (1 << 1) /* HZ rising-edge detected */ +#define RTSR_AL (1 << 0) /* RTC alarm detected */ + +#endif /* __ASM_MACH_REGS_RTC_H */ diff --git a/arch/arm/mach-mmp/include/mach/system.h b/arch/arm/mach-mmp/include/mach/system.h deleted file mode 100644 index 1d001eab81e1..000000000000 --- a/arch/arm/mach-mmp/include/mach/system.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * linux/arch/arm/mach-mmp/include/mach/system.h - * - * 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. - */ - -#ifndef __ASM_MACH_SYSTEM_H -#define __ASM_MACH_SYSTEM_H - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} -#endif /* __ASM_MACH_SYSTEM_H */ diff --git a/arch/arm/mach-mmp/irq-mmp2.c b/arch/arm/mach-mmp/irq-mmp2.c index d21c5441a3d0..7895d277421e 100644 --- a/arch/arm/mach-mmp/irq-mmp2.c +++ b/arch/arm/mach-mmp/irq-mmp2.c @@ -15,6 +15,7 @@ #include <linux/irq.h> #include <linux/io.h> +#include <mach/irqs.h> #include <mach/regs-icu.h> #include <mach/mmp2.h> diff --git a/arch/arm/mach-mmp/jasper.c b/arch/arm/mach-mmp/jasper.c index 96cf5c8fe47d..ff73249884d0 100644 --- a/arch/arm/mach-mmp/jasper.c +++ b/arch/arm/mach-mmp/jasper.c @@ -19,6 +19,7 @@ #include <linux/mfd/max8925.h> #include <linux/interrupt.h> +#include <mach/irqs.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <mach/addr-map.h> @@ -27,7 +28,7 @@ #include "common.h" -#define JASPER_NR_IRQS (IRQ_BOARD_START + 48) +#define JASPER_NR_IRQS (MMP_NR_IRQS + 48) static unsigned long jasper_pin_config[] __initdata = { /* UART1 */ @@ -135,7 +136,7 @@ static struct max8925_power_pdata jasper_power_data = { static struct max8925_platform_data jasper_max8925_info = { .backlight = &jasper_backlight_data, .power = &jasper_power_data, - .irq_base = IRQ_BOARD_START, + .irq_base = MMP_NR_IRQS, }; static struct i2c_board_info jasper_twsi1_info[] = { diff --git a/arch/arm/mach-mmp/mmp-dt.c b/arch/arm/mach-mmp/mmp-dt.c new file mode 100644 index 000000000000..67075395e400 --- /dev/null +++ b/arch/arm/mach-mmp/mmp-dt.c @@ -0,0 +1,75 @@ +/* + * linux/arch/arm/mach-mmp/mmp-dt.c + * + * Copyright (C) 2012 Marvell Technology Group Ltd. + * Author: Haojian Zhuang <haojian.zhuang@marvell.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 + * publishhed by the Free Software Foundation. + */ + +#include <linux/irq.h> +#include <linux/irqdomain.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h> +#include <asm/mach/arch.h> +#include <mach/irqs.h> + +#include "common.h" + +extern struct sys_timer pxa168_timer; +extern void __init icu_init_irq(void); + +static const struct of_dev_auxdata mmp_auxdata_lookup[] __initconst = { + OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.0", NULL), + OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4018000, "pxa2xx-uart.1", NULL), + OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4026000, "pxa2xx-uart.2", NULL), + OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4011000, "pxa2xx-i2c.0", NULL), + OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4025000, "pxa2xx-i2c.1", NULL), + OF_DEV_AUXDATA("mrvl,mmp-gpio", 0xd4019000, "pxa-gpio", NULL), + OF_DEV_AUXDATA("mrvl,mmp-rtc", 0xd4010000, "sa1100-rtc", NULL), + {} +}; + +static int __init mmp_intc_add_irq_domain(struct device_node *np, + struct device_node *parent) +{ + irq_domain_add_simple(np, 0); + return 0; +} + +static int __init mmp_gpio_add_irq_domain(struct device_node *np, + struct device_node *parent) +{ + irq_domain_add_simple(np, IRQ_GPIO_START); + return 0; +} + +static const struct of_device_id mmp_irq_match[] __initconst = { + { .compatible = "mrvl,mmp-intc", .data = mmp_intc_add_irq_domain, }, + { .compatible = "mrvl,mmp-gpio", .data = mmp_gpio_add_irq_domain, }, + {} +}; + +static void __init mmp_dt_init(void) +{ + + of_irq_init(mmp_irq_match); + + of_platform_populate(NULL, of_default_bus_match_table, + mmp_auxdata_lookup, NULL); +} + +static const char *pxa168_dt_board_compat[] __initdata = { + "mrvl,pxa168-aspenite", + NULL, +}; + +DT_MACHINE_START(PXA168_DT, "Marvell PXA168 (Device Tree Support)") + .map_io = mmp_map_io, + .init_irq = icu_init_irq, + .timer = &pxa168_timer, + .init_machine = mmp_dt_init, + .dt_compat = pxa168_dt_board_compat, +MACHINE_END diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c index 617c60a170a4..c709a24a9d25 100644 --- a/arch/arm/mach-mmp/mmp2.c +++ b/arch/arm/mach-mmp/mmp2.c @@ -223,6 +223,7 @@ struct resource mmp2_resource_gpio[] = { }, { .start = IRQ_MMP2_GPIO, .end = IRQ_MMP2_GPIO, + .name = "gpio_mux", .flags = IORESOURCE_IRQ, }, }; diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c index ada1213982b4..b24d2c32cba9 100644 --- a/arch/arm/mach-mmp/pxa168.c +++ b/arch/arm/mach-mmp/pxa168.c @@ -16,6 +16,7 @@ #include <linux/platform_device.h> #include <asm/mach/time.h> +#include <asm/system_misc.h> #include <mach/addr-map.h> #include <mach/cputype.h> #include <mach/regs-apbc.h> @@ -64,6 +65,7 @@ static APBC_CLK(ssp4, PXA168_SSP4, 4, 0); static APBC_CLK(ssp5, PXA168_SSP5, 4, 0); static APBC_CLK(gpio, PXA168_GPIO, 0, 13000000); static APBC_CLK(keypad, PXA168_KPC, 0, 32000); +static APBC_CLK(rtc, PXA168_RTC, 8, 32768); static APMU_CLK(nand, NAND, 0x19b, 156000000); static APMU_CLK(lcd, LCD, 0x7f, 312000000); @@ -92,6 +94,7 @@ static struct clk_lookup pxa168_clkregs[] = { INIT_CLKREG(&clk_keypad, "pxa27x-keypad", NULL), INIT_CLKREG(&clk_eth, "pxa168-eth", "MFUCLK"), INIT_CLKREG(&clk_usb, "pxa168-ehci", "PXA168-USBCLK"), + INIT_CLKREG(&clk_rtc, "sa1100-rtc", NULL), }; static int __init pxa168_init(void) @@ -166,6 +169,7 @@ struct resource pxa168_resource_gpio[] = { }, { .start = IRQ_PXA168_GPIOX, .end = IRQ_PXA168_GPIOX, + .name = "gpio_mux", .flags = IORESOURCE_IRQ, }, }; diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c index 3241a25784d0..43f8bcc29b67 100644 --- a/arch/arm/mach-mmp/pxa910.c +++ b/arch/arm/mach-mmp/pxa910.c @@ -92,6 +92,7 @@ static APBC_CLK(pwm2, PXA910_PWM2, 1, 13000000); static APBC_CLK(pwm3, PXA910_PWM3, 1, 13000000); static APBC_CLK(pwm4, PXA910_PWM4, 1, 13000000); static APBC_CLK(gpio, PXA910_GPIO, 0, 13000000); +static APBC_CLK(rtc, PXA910_RTC, 8, 32768); static APMU_CLK(nand, NAND, 0x19b, 156000000); static APMU_CLK(u2o, USB, 0x1b, 480000000); @@ -109,6 +110,7 @@ static struct clk_lookup pxa910_clkregs[] = { INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL), INIT_CLKREG(&clk_gpio, "pxa-gpio", NULL), INIT_CLKREG(&clk_u2o, "pxa-u2o", "U2OCLK"), + INIT_CLKREG(&clk_rtc, "sa1100-rtc", NULL), }; static int __init pxa910_init(void) @@ -173,6 +175,7 @@ struct resource pxa910_resource_gpio[] = { }, { .start = IRQ_PXA910_AP_GPIO, .end = IRQ_PXA910_AP_GPIO, + .name = "gpio_mux", .flags = IORESOURCE_IRQ, }, }; @@ -183,3 +186,28 @@ struct platform_device pxa910_device_gpio = { .num_resources = ARRAY_SIZE(pxa910_resource_gpio), .resource = pxa910_resource_gpio, }; + +static struct resource pxa910_resource_rtc[] = { + { + .start = 0xd4010000, + .end = 0xd401003f, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_PXA910_RTC_INT, + .end = IRQ_PXA910_RTC_INT, + .name = "rtc 1Hz", + .flags = IORESOURCE_IRQ, + }, { + .start = IRQ_PXA910_RTC_ALARM, + .end = IRQ_PXA910_RTC_ALARM, + .name = "rtc alarm", + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device pxa910_device_rtc = { + .name = "sa1100-rtc", + .id = -1, + .num_resources = ARRAY_SIZE(pxa910_resource_rtc), + .resource = pxa910_resource_rtc, +}; diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c index bc97170125bf..b28f9084dfff 100644 --- a/arch/arm/mach-mmp/tavorevb.c +++ b/arch/arm/mach-mmp/tavorevb.c @@ -101,6 +101,7 @@ static void __init tavorevb_init(void) MACHINE_START(TAVOREVB, "PXA910 Evaluation Board (aka TavorEVB)") .map_io = mmp_map_io, + .nr_irqs = MMP_NR_IRQS, .init_irq = pxa910_init_irq, .timer = &pxa910_timer, .init_machine = tavorevb_init, diff --git a/arch/arm/mach-mmp/teton_bga.c b/arch/arm/mach-mmp/teton_bga.c index 0523e422990e..42bef6674ecf 100644 --- a/arch/arm/mach-mmp/teton_bga.c +++ b/arch/arm/mach-mmp/teton_bga.c @@ -26,6 +26,7 @@ #include <mach/mfp-pxa168.h> #include <mach/pxa168.h> #include <mach/teton_bga.h> +#include <mach/irqs.h> #include "common.h" @@ -83,7 +84,7 @@ static void __init teton_bga_init(void) MACHINE_START(TETON_BGA, "PXA168-based Teton BGA Development Platform") .map_io = mmp_map_io, - .nr_irqs = IRQ_BOARD_START, + .nr_irqs = MMP_NR_IRQS, .init_irq = pxa168_init_irq, .timer = &pxa168_timer, .init_machine = teton_bga_init, diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c index 5ac5d5832e45..3fc9ed21f97d 100644 --- a/arch/arm/mach-mmp/ttc_dkb.c +++ b/arch/arm/mach-mmp/ttc_dkb.c @@ -38,7 +38,7 @@ * 16 board interrupts -- PCA9575 GPIO expander * 24 board interrupts -- 88PM860x PMIC */ -#define TTCDKB_NR_IRQS (IRQ_BOARD_START + 16 + 16 + 24) +#define TTCDKB_NR_IRQS (MMP_NR_IRQS + 16 + 16 + 24) static unsigned long ttc_dkb_pin_config[] __initdata = { /* UART2 */ @@ -124,13 +124,14 @@ static struct platform_device ttc_dkb_device_onenand = { static struct platform_device *ttc_dkb_devices[] = { &pxa910_device_gpio, + &pxa910_device_rtc, &ttc_dkb_device_onenand, }; static struct pca953x_platform_data max7312_data[] = { { .gpio_base = TTCDKB_GPIO_EXT0(0), - .irq_base = IRQ_BOARD_START, + .irq_base = MMP_NR_IRQS, }, }; diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c index a60ab6d04ec5..26aac363a064 100644 --- a/arch/arm/mach-msm/board-halibut.c +++ b/arch/arm/mach-msm/board-halibut.c @@ -68,6 +68,11 @@ static struct platform_device *devices[] __initdata = { extern struct sys_timer msm_timer; +static void __init halibut_init_early(void) +{ + arch_ioremap_caller = __msm_ioremap_caller; +} + static void __init halibut_init_irq(void) { msm_init_irq(); @@ -81,9 +86,6 @@ static void __init halibut_init(void) static void __init halibut_fixup(struct tag *tags, char **cmdline, struct meminfo *mi) { - mi->nr_banks=1; - mi->bank[0].start = PHYS_OFFSET; - mi->bank[0].size = (101*1024*1024); } static void __init halibut_map_io(void) @@ -96,6 +98,7 @@ MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)") .atag_offset = 0x100, .fixup = halibut_fixup, .map_io = halibut_map_io, + .init_early = halibut_init_early, .init_irq = halibut_init_irq, .init_machine = halibut_init, .timer = &msm_timer, diff --git a/arch/arm/mach-msm/board-sapphire.c b/arch/arm/mach-msm/board-sapphire.c index 97b8191d9d38..4a8ea0d40b6f 100644 --- a/arch/arm/mach-msm/board-sapphire.c +++ b/arch/arm/mach-msm/board-sapphire.c @@ -27,7 +27,6 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/flash.h> -#include <asm/system.h> #include <mach/system.h> #include <mach/vreg.h> #include <mach/board.h> diff --git a/arch/arm/mach-msm/board-trout-panel.c b/arch/arm/mach-msm/board-trout-panel.c index 25105c1027fe..89bf6b426699 100644 --- a/arch/arm/mach-msm/board-trout-panel.c +++ b/arch/arm/mach-msm/board-trout-panel.c @@ -12,6 +12,7 @@ #include <asm/io.h> #include <asm/mach-types.h> +#include <asm/system_info.h> #include <mach/msm_fb.h> #include <mach/vreg.h> diff --git a/arch/arm/mach-msm/board-trout.c b/arch/arm/mach-msm/board-trout.c index 6b9b227c87c5..d4060a37e23d 100644 --- a/arch/arm/mach-msm/board-trout.c +++ b/arch/arm/mach-msm/board-trout.c @@ -19,6 +19,7 @@ #include <linux/platform_device.h> #include <linux/clkdev.h> +#include <asm/system_info.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -43,6 +44,11 @@ static struct platform_device *devices[] __initdata = { extern struct sys_timer msm_timer; +static void __init trout_init_early(void) +{ + arch_ioremap_caller = __msm_ioremap_caller; +} + static void __init trout_init_irq(void) { msm_init_irq(); @@ -96,6 +102,7 @@ MACHINE_START(TROUT, "HTC Dream") .atag_offset = 0x100, .fixup = trout_fixup, .map_io = trout_map_io, + .init_early = trout_init_early, .init_irq = trout_init_irq, .init_machine = trout_init, .timer = &msm_timer, diff --git a/arch/arm/mach-msm/idle.S b/arch/arm/mach-msm/idle.S deleted file mode 100644 index 6a94f0527137..000000000000 --- a/arch/arm/mach-msm/idle.S +++ /dev/null @@ -1,36 +0,0 @@ -/* arch/arm/mach-msm/include/mach/idle.S - * - * Idle processing for MSM7K - work around bugs with SWFI. - * - * Copyright (c) 2007 QUALCOMM Incorporated. - * Copyright (C) 2007 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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/linkage.h> -#include <asm/assembler.h> - -ENTRY(arch_idle) -#ifdef CONFIG_MSM7X00A_IDLE - mrc p15, 0, r1, c1, c0, 0 /* read current CR */ - bic r0, r1, #(1 << 2) /* clear dcache bit */ - bic r0, r0, #(1 << 12) /* clear icache bit */ - mcr p15, 0, r0, c1, c0, 0 /* disable d/i cache */ - - mov r0, #0 /* prepare wfi value */ - mcr p15, 0, r0, c7, c10, 0 /* flush the cache */ - mcr p15, 0, r0, c7, c10, 4 /* memory barrier */ - mcr p15, 0, r0, c7, c0, 4 /* wait for interrupt */ - - mcr p15, 0, r1, c1, c0, 0 /* restore d/i cache */ -#endif - mov pc, lr diff --git a/arch/arm/mach-msm/idle.c b/arch/arm/mach-msm/idle.c new file mode 100644 index 000000000000..0c9e13c65743 --- /dev/null +++ b/arch/arm/mach-msm/idle.c @@ -0,0 +1,49 @@ +/* arch/arm/mach-msm/idle.c + * + * Idle processing for MSM7K - work around bugs with SWFI. + * + * Copyright (c) 2007 QUALCOMM Incorporated. + * Copyright (C) 2007 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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 <asm/system.h> + +static void msm_idle(void) +{ +#ifdef CONFIG_MSM7X00A_IDLE + asm volatile ( + + "mrc p15, 0, r1, c1, c0, 0 /* read current CR */ \n\t" + "bic r0, r1, #(1 << 2) /* clear dcache bit */ \n\t" + "bic r0, r0, #(1 << 12) /* clear icache bit */ \n\t" + "mcr p15, 0, r0, c1, c0, 0 /* disable d/i cache */ \n\t" + + "mov r0, #0 /* prepare wfi value */ \n\t" + "mcr p15, 0, r0, c7, c10, 0 /* flush the cache */ \n\t" + "mcr p15, 0, r0, c7, c10, 4 /* memory barrier */ \n\t" + "mcr p15, 0, r0, c7, c0, 4 /* wait for interrupt */ \n\t" + + "mcr p15, 0, r1, c1, c0, 0 /* restore d/i cache */ \n\t" + + : : : "r0","r1" ); +#endif +} + +static int __init msm_idle_init(void) +{ + arm_pm_idle = msm_idle; + return 0; +} + +arch_initcall(msm_idle_init); diff --git a/arch/arm/mach-msm/include/mach/entry-macro.S b/arch/arm/mach-msm/include/mach/entry-macro.S index 41f7003ef34f..f2ae9087f654 100644 --- a/arch/arm/mach-msm/include/mach/entry-macro.S +++ b/arch/arm/mach-msm/include/mach/entry-macro.S @@ -16,12 +16,6 @@ * */ - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm - #if !defined(CONFIG_ARM_GIC) #include <mach/msm_iomap.h> diff --git a/arch/arm/mach-msm/include/mach/io.h b/arch/arm/mach-msm/include/mach/io.h deleted file mode 100644 index dc1b928745e9..000000000000 --- a/arch/arm/mach-msm/include/mach/io.h +++ /dev/null @@ -1,36 +0,0 @@ -/* arch/arm/mach-msm/include/mach/io.h - * - * Copyright (C) 2007 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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 __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -#define __arch_ioremap __msm_ioremap -#define __arch_iounmap __iounmap - -void __iomem *__msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype); - -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -void msm_map_qsd8x50_io(void); -void msm_map_msm7x30_io(void); -void msm_map_msm8x60_io(void); -void msm_map_msm8960_io(void); - -extern unsigned int msm_shared_ram_phys; - -#endif diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h index 8af46123dab6..6c4046c21296 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h @@ -38,12 +38,6 @@ * */ -#ifdef __ASSEMBLY__ -#define IOMEM(x) x -#else -#define IOMEM(x) ((void __force __iomem *)(x)) -#endif - #define MSM_VIC_BASE IOMEM(0xE0000000) #define MSM_VIC_PHYS 0xC0000000 #define MSM_VIC_SIZE SZ_4K @@ -111,5 +105,11 @@ #define MSM_AD5_PHYS 0xAC000000 #define MSM_AD5_SIZE (SZ_1M*13) +#ifndef __ASSEMBLY__ + +extern void __iomem *__msm_ioremap_caller(unsigned long phys_addr, size_t size, + unsigned int mtype, void *caller); + +#endif #endif diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h index 198202c267c8..f944fe65a657 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h @@ -100,4 +100,8 @@ #define MSM_HSUSB_PHYS 0xA3600000 #define MSM_HSUSB_SIZE SZ_1K +#ifndef __ASSEMBLY__ +extern void msm_map_msm7x30_io(void); +#endif + #endif diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8960.h b/arch/arm/mach-msm/include/mach/msm_iomap-8960.h index 800b55767e6b..a1752c0284fc 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-8960.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-8960.h @@ -50,4 +50,8 @@ #define MSM_DEBUG_UART_PHYS 0x16440000 #endif +#ifndef __ASSEMBLY__ +extern void msm_map_msm8960_io(void); +#endif + #endif diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h index 0faa894729b7..da77cc1d545d 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h @@ -122,4 +122,8 @@ #define MSM_SDC4_PHYS 0xA0600000 #define MSM_SDC4_SIZE SZ_4K +#ifndef __ASSEMBLY__ +extern void msm_map_qsd8x50_io(void); +#endif + #endif diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h index 54e12caa8d86..5aed57dc808c 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h @@ -67,4 +67,8 @@ #define MSM_DEBUG_UART_PHYS 0x19C40000 #endif +#ifndef __ASSEMBLY__ +extern void msm_map_msm8x60_io(void); +#endif + #endif diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h index 90682f4599d3..00afdfb8c38f 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap.h @@ -37,12 +37,6 @@ * */ -#ifdef __ASSEMBLY__ -#define IOMEM(x) x -#else -#define IOMEM(x) ((void __force __iomem *)(x)) -#endif - #if defined(CONFIG_ARCH_MSM7X30) #include "msm_iomap-7x30.h" #elif defined(CONFIG_ARCH_QSD8X50) diff --git a/arch/arm/mach-msm/include/mach/system.h b/arch/arm/mach-msm/include/mach/system.h index 311db2b35da0..f5fb2ec87ffe 100644 --- a/arch/arm/mach-msm/include/mach/system.h +++ b/arch/arm/mach-msm/include/mach/system.h @@ -12,7 +12,6 @@ * GNU General Public License for more details. * */ -void arch_idle(void); /* low level hardware reset hook -- for example, hitting the * PSHOLD line on the PMIC to hard reset the system diff --git a/arch/arm/mach-msm/include/mach/uncompress.h b/arch/arm/mach-msm/include/mach/uncompress.h index 169a84007456..c14011fe832d 100644 --- a/arch/arm/mach-msm/include/mach/uncompress.h +++ b/arch/arm/mach-msm/include/mach/uncompress.h @@ -16,6 +16,7 @@ #ifndef __ASM_ARCH_MSM_UNCOMPRESS_H #define __ASM_ARCH_MSM_UNCOMPRESS_H +#include <asm/barrier.h> #include <asm/processor.h> #include <mach/msm_iomap.h> diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c index 578b04e42deb..a1e7b1168850 100644 --- a/arch/arm/mach-msm/io.c +++ b/arch/arm/mach-msm/io.c @@ -172,8 +172,8 @@ void __init msm_map_msm7x30_io(void) } #endif /* CONFIG_ARCH_MSM7X30 */ -void __iomem * -__msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype) +void __iomem *__msm_ioremap_caller(unsigned long phys_addr, size_t size, + unsigned int mtype, void *caller) { if (mtype == MT_DEVICE) { /* The peripherals in the 88000000 - D0000000 range @@ -184,7 +184,5 @@ __msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype) mtype = MT_DEVICE_NONSHARED; } - return __arm_ioremap_caller(phys_addr, size, mtype, - __builtin_return_address(0)); + return __arm_ioremap_caller(phys_addr, size, mtype, caller); } -EXPORT_SYMBOL(__msm_ioremap); diff --git a/arch/arm/mach-msm/proc_comm.c b/arch/arm/mach-msm/proc_comm.c index 67e701c7f183..9980dc736e7b 100644 --- a/arch/arm/mach-msm/proc_comm.c +++ b/arch/arm/mach-msm/proc_comm.c @@ -121,7 +121,7 @@ int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2) * and unknown state. This function should be called early to * wait on the ARM9. */ -void __init proc_comm_boot_wait(void) +void __devinit proc_comm_boot_wait(void) { void __iomem *base = MSM_SHARED_RAM_BASE; diff --git a/arch/arm/mach-msm/smd_debug.c b/arch/arm/mach-msm/smd_debug.c index 0c56a5aaf588..c56df9e932ae 100644 --- a/arch/arm/mach-msm/smd_debug.c +++ b/arch/arm/mach-msm/smd_debug.c @@ -203,15 +203,9 @@ static ssize_t debug_read(struct file *file, char __user *buf, return simple_read_from_buffer(buf, count, ppos, debug_buffer, bsize); } -static int debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - static const struct file_operations debug_ops = { .read = debug_read, - .open = debug_open, + .open = simple_open, .llseek = default_llseek, }; diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index 11d0d8f2656c..812808254936 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -24,6 +24,7 @@ #include <asm/mach/time.h> #include <asm/hardware/gic.h> #include <asm/localtimer.h> +#include <asm/sched_clock.h> #include <mach/msm_iomap.h> #include <mach/cpu.h> @@ -105,12 +106,12 @@ static union { static void __iomem *source_base; -static cycle_t msm_read_timer_count(struct clocksource *cs) +static notrace cycle_t msm_read_timer_count(struct clocksource *cs) { return readl_relaxed(source_base + TIMER_COUNT_VAL); } -static cycle_t msm_read_timer_count_shift(struct clocksource *cs) +static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs) { /* * Shift timer count down by a constant due to unreliable lower bits @@ -127,6 +128,50 @@ static struct clocksource msm_clocksource = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; +#ifdef CONFIG_LOCAL_TIMERS +static int __cpuinit msm_local_timer_setup(struct clock_event_device *evt) +{ + /* Use existing clock_event for cpu 0 */ + if (!smp_processor_id()) + return 0; + + writel_relaxed(0, event_base + TIMER_ENABLE); + writel_relaxed(0, event_base + TIMER_CLEAR); + writel_relaxed(~0, event_base + TIMER_MATCH_VAL); + evt->irq = msm_clockevent.irq; + evt->name = "local_timer"; + evt->features = msm_clockevent.features; + evt->rating = msm_clockevent.rating; + evt->set_mode = msm_timer_set_mode; + evt->set_next_event = msm_timer_set_next_event; + evt->shift = msm_clockevent.shift; + evt->mult = div_sc(GPT_HZ, NSEC_PER_SEC, evt->shift); + evt->max_delta_ns = clockevent_delta2ns(0xf0000000, evt); + evt->min_delta_ns = clockevent_delta2ns(4, evt); + + *__this_cpu_ptr(msm_evt.percpu_evt) = evt; + clockevents_register_device(evt); + enable_percpu_irq(evt->irq, 0); + return 0; +} + +static void msm_local_timer_stop(struct clock_event_device *evt) +{ + evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); + disable_percpu_irq(evt->irq); +} + +static struct local_timer_ops msm_local_timer_ops __cpuinitdata = { + .setup = msm_local_timer_setup, + .stop = msm_local_timer_stop, +}; +#endif /* CONFIG_LOCAL_TIMERS */ + +static notrace u32 msm_sched_clock_read(void) +{ + return msm_clocksource.read(&msm_clocksource); +} + static void __init msm_timer_init(void) { struct clock_event_device *ce = &msm_clockevent; @@ -173,8 +218,12 @@ static void __init msm_timer_init(void) *__this_cpu_ptr(msm_evt.percpu_evt) = ce; res = request_percpu_irq(ce->irq, msm_timer_interrupt, ce->name, msm_evt.percpu_evt); - if (!res) + if (!res) { enable_percpu_irq(ce->irq, 0); +#ifdef CONFIG_LOCAL_TIMERS + local_timer_register(&msm_local_timer_ops); +#endif + } } else { msm_evt.evt = ce; res = request_irq(ce->irq, msm_timer_interrupt, @@ -189,42 +238,10 @@ err: res = clocksource_register_hz(cs, dgt_hz); if (res) pr_err("clocksource_register failed\n"); + setup_sched_clock(msm_sched_clock_read, + cpu_is_msm7x01() ? 32 - MSM_DGT_SHIFT : 32, dgt_hz); } -#ifdef CONFIG_LOCAL_TIMERS -int __cpuinit local_timer_setup(struct clock_event_device *evt) -{ - /* Use existing clock_event for cpu 0 */ - if (!smp_processor_id()) - return 0; - - writel_relaxed(0, event_base + TIMER_ENABLE); - writel_relaxed(0, event_base + TIMER_CLEAR); - writel_relaxed(~0, event_base + TIMER_MATCH_VAL); - evt->irq = msm_clockevent.irq; - evt->name = "local_timer"; - evt->features = msm_clockevent.features; - evt->rating = msm_clockevent.rating; - evt->set_mode = msm_timer_set_mode; - evt->set_next_event = msm_timer_set_next_event; - evt->shift = msm_clockevent.shift; - evt->mult = div_sc(GPT_HZ, NSEC_PER_SEC, evt->shift); - evt->max_delta_ns = clockevent_delta2ns(0xf0000000, evt); - evt->min_delta_ns = clockevent_delta2ns(4, evt); - - *__this_cpu_ptr(msm_evt.percpu_evt) = evt; - clockevents_register_device(evt); - enable_percpu_irq(evt->irq, 0); - return 0; -} - -void local_timer_stop(struct clock_event_device *evt) -{ - evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); - disable_percpu_irq(evt->irq); -} -#endif /* CONFIG_LOCAL_TIMERS */ - struct sys_timer msm_timer = { .init = msm_timer_init }; diff --git a/arch/arm/mach-mv78xx0/include/mach/entry-macro.S b/arch/arm/mach-mv78xx0/include/mach/entry-macro.S index 66ae2d29e773..6b1f088e0597 100644 --- a/arch/arm/mach-mv78xx0/include/mach/entry-macro.S +++ b/arch/arm/mach-mv78xx0/include/mach/entry-macro.S @@ -10,12 +10,6 @@ #include <mach/bridge-regs.h> - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_preamble, base, tmp ldr \base, =IRQ_VIRT_BASE .endm diff --git a/arch/arm/mach-mv78xx0/include/mach/io.h b/arch/arm/mach-mv78xx0/include/mach/io.h index 450e0e1ad092..c7d9d00d8fc1 100644 --- a/arch/arm/mach-mv78xx0/include/mach/io.h +++ b/arch/arm/mach-mv78xx0/include/mach/io.h @@ -20,7 +20,5 @@ static inline void __iomem *__io(unsigned long addr) } #define __io(a) __io(a) -#define __mem_pci(a) (a) - #endif diff --git a/arch/arm/mach-mv78xx0/include/mach/system.h b/arch/arm/mach-mv78xx0/include/mach/system.h deleted file mode 100644 index 8c3a5387cec7..000000000000 --- a/arch/arm/mach-mv78xx0/include/mach/system.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * arch/arm/mach-mv78xx0/include/mach/system.h - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-mv78xx0/pcie.c b/arch/arm/mach-mv78xx0/pcie.c index 8459f6d7d8ca..df3e38055a24 100644 --- a/arch/arm/mach-mv78xx0/pcie.c +++ b/arch/arm/mach-mv78xx0/pcie.c @@ -155,8 +155,8 @@ static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys) orion_pcie_set_local_bus_nr(pp->base, sys->busnr); orion_pcie_setup(pp->base); - pci_add_resource(&sys->resources, &pp->res[0]); - pci_add_resource(&sys->resources, &pp->res[1]); + pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset); + pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset); return 1; } diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig index cf00b3e3be85..c57f9964a713 100644 --- a/arch/arm/mach-mxs/Kconfig +++ b/arch/arm/mach-mxs/Kconfig @@ -83,6 +83,18 @@ config MODULE_M28 select MXS_HAVE_PLATFORM_MXSFB select MXS_OCOTP +config MODULE_APX4 + bool + select SOC_IMX28 + select LEDS_GPIO_REGISTER + select MXS_HAVE_AMBA_DUART + select MXS_HAVE_PLATFORM_AUART + select MXS_HAVE_PLATFORM_FEC + select MXS_HAVE_PLATFORM_MXS_I2C + select MXS_HAVE_PLATFORM_MXS_MMC + select MXS_HAVE_PLATFORM_MXS_SAIF + select MXS_OCOTP + config MACH_TX28 bool "Ka-Ro TX28 module" select MODULE_TX28 @@ -91,4 +103,8 @@ config MACH_M28EVK bool "Support DENX M28EVK Platform" select MODULE_M28 +config MACH_APX4DEVKIT + bool "Support Bluegiga APX4 Development Kit" + select MODULE_APX4 + endif diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile index 8c93b24896bf..908bf9a567f1 100644 --- a/arch/arm/mach-mxs/Makefile +++ b/arch/arm/mach-mxs/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_MACH_STMP378X_DEVB) += mach-stmp378x_devb.o obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o obj-$(CONFIG_MACH_M28EVK) += mach-m28evk.o +obj-$(CONFIG_MACH_APX4DEVKIT) += mach-apx4devkit.o obj-$(CONFIG_MODULE_TX28) += module-tx28.o obj-$(CONFIG_MACH_TX28) += mach-tx28.o diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c index e12e11231dc7..e3ac52c34019 100644 --- a/arch/arm/mach-mxs/clock-mx23.c +++ b/arch/arm/mach-mxs/clock-mx23.c @@ -223,7 +223,6 @@ static int cpu_clk_set_rate(struct clk *clk, unsigned long rate) { u32 reg, bm_busy, div_max, d, f, div, frac; unsigned long diff, parent_rate, calc_rate; - int i; parent_rate = clk_get_rate(clk->parent); @@ -275,14 +274,7 @@ static int cpu_clk_set_rate(struct clk *clk, unsigned long rate) reg |= div << BP_CLKCTRL_CPU_DIV_CPU; __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU); - for (i = 10000; i; i--) - if (!(__raw_readl(CLKCTRL_BASE_ADDR + - HW_CLKCTRL_CPU) & bm_busy)) - break; - if (!i) { - pr_err("%s: divider writing timeout\n", __func__); - return -ETIMEDOUT; - } + mxs_clkctrl_timeout(HW_CLKCTRL_CPU, bm_busy); return 0; } @@ -292,7 +284,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \ { \ u32 reg, div_max, div; \ unsigned long parent_rate; \ - int i; \ \ parent_rate = clk_get_rate(clk->parent); \ div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \ @@ -310,15 +301,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \ } \ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \ \ - for (i = 10000; i; i--) \ - if (!(__raw_readl(CLKCTRL_BASE_ADDR + \ - HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY)) \ - break; \ - if (!i) { \ - pr_err("%s: divider writing timeout\n", __func__); \ - return -ETIMEDOUT; \ - } \ - \ + mxs_clkctrl_timeout(HW_CLKCTRL_##dr, BM_CLKCTRL_##dr##_BUSY); \ return 0; \ } @@ -456,12 +439,13 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("mxs-pwm.3", NULL, pwm_clk) _REGISTER_CLOCK("mxs-pwm.4", NULL, pwm_clk) _REGISTER_CLOCK("imx23-fb", NULL, lcdif_clk) + _REGISTER_CLOCK("imx23-gpmi-nand", NULL, gpmi_clk) }; static int clk_misc_init(void) { u32 reg; - int i; + int ret; /* Fix up parent per register setting */ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ); @@ -510,14 +494,7 @@ static int clk_misc_init(void) reg |= 3 << BP_CLKCTRL_HBUS_DIV; __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS); - for (i = 10000; i; i--) - if (!(__raw_readl(CLKCTRL_BASE_ADDR + - HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_BUSY)) - break; - if (!i) { - pr_err("%s: divider writing timeout\n", __func__); - return -ETIMEDOUT; - } + ret = mxs_clkctrl_timeout(HW_CLKCTRL_HBUS, BM_CLKCTRL_HBUS_BUSY); /* Gate off cpu clock in WFI for power saving */ __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT, @@ -532,7 +509,7 @@ static int clk_misc_init(void) reg |= 30 << BP_CLKCTRL_FRAC_IOFRAC; __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC); - return 0; + return ret; } int __init mx23_clocks_init(void) diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c index 5d68e4152220..cea29c99e214 100644 --- a/arch/arm/mach-mxs/clock-mx28.c +++ b/arch/arm/mach-mxs/clock-mx28.c @@ -322,7 +322,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \ { \ u32 reg, bm_busy, div_max, d, f, div, frac; \ unsigned long diff, parent_rate, calc_rate; \ - int i; \ \ div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \ bm_busy = BM_CLKCTRL_##dr##_BUSY; \ @@ -396,16 +395,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \ } \ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \ \ - for (i = 10000; i; i--) \ - if (!(__raw_readl(CLKCTRL_BASE_ADDR + \ - HW_CLKCTRL_##dr) & bm_busy)) \ - break; \ - if (!i) { \ - pr_err("%s: divider writing timeout\n", __func__); \ - return -ETIMEDOUT; \ - } \ - \ - return 0; \ + return mxs_clkctrl_timeout(HW_CLKCTRL_##dr, bm_busy); \ } _CLK_SET_RATE(cpu_clk, CPU, FRAC0, CPU) @@ -421,7 +411,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \ { \ u32 reg, div_max, div; \ unsigned long parent_rate; \ - int i; \ \ parent_rate = clk_get_rate(clk->parent); \ div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \ @@ -439,16 +428,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \ } \ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \ \ - for (i = 10000; i; i--) \ - if (!(__raw_readl(CLKCTRL_BASE_ADDR + \ - HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY)) \ - break; \ - if (!i) { \ - pr_err("%s: divider writing timeout\n", __func__); \ - return -ETIMEDOUT; \ - } \ - \ - return 0; \ + return mxs_clkctrl_timeout(HW_CLKCTRL_##dr, BM_CLKCTRL_##dr##_BUSY);\ } _CLK_SET_RATE1(xbus_clk, XBUS) @@ -461,7 +441,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \ u32 reg; \ u64 lrate; \ unsigned long parent_rate; \ - int i; \ \ parent_rate = clk_get_rate(clk->parent); \ if (rate > parent_rate) \ @@ -477,18 +456,13 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \ reg &= ~BM_CLKCTRL_##rs##_DIV; \ reg |= div << BP_CLKCTRL_##rs##_DIV; \ - __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \ - \ - for (i = 10000; i; i--) \ - if (!(__raw_readl(CLKCTRL_BASE_ADDR + \ - HW_CLKCTRL_##rs) & BM_CLKCTRL_##rs##_BUSY)) \ - break; \ - if (!i) { \ - pr_err("%s: divider writing timeout\n", __func__); \ - return -ETIMEDOUT; \ + if (reg & (1 << clk->enable_shift)) { \ + pr_err("%s: clock is gated\n", __func__); \ + return -EINVAL; \ } \ + __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \ \ - return 0; \ + return mxs_clkctrl_timeout(HW_CLKCTRL_##rs, BM_CLKCTRL_##rs##_BUSY);\ } _CLK_SET_RATE_SAIF(saif0_clk, SAIF0) @@ -643,6 +617,7 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("duart", NULL, uart_clk) _REGISTER_CLOCK("imx28-fec.0", NULL, fec_clk) _REGISTER_CLOCK("imx28-fec.1", NULL, fec_clk) + _REGISTER_CLOCK("imx28-gpmi-nand", NULL, gpmi_clk) _REGISTER_CLOCK("mxs-auart.0", NULL, uart_clk) _REGISTER_CLOCK("mxs-auart.1", NULL, uart_clk) _REGISTER_CLOCK("mxs-auart.2", NULL, uart_clk) @@ -654,6 +629,8 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk) _REGISTER_CLOCK("mxs-mmc.0", NULL, ssp0_clk) _REGISTER_CLOCK("mxs-mmc.1", NULL, ssp1_clk) + _REGISTER_CLOCK("mxs-mmc.2", NULL, ssp2_clk) + _REGISTER_CLOCK("mxs-mmc.3", NULL, ssp3_clk) _REGISTER_CLOCK("flexcan.0", NULL, can0_clk) _REGISTER_CLOCK("flexcan.1", NULL, can1_clk) _REGISTER_CLOCK(NULL, "usb0", usb0_clk) @@ -676,7 +653,7 @@ static struct clk_lookup lookups[] = { static int clk_misc_init(void) { u32 reg; - int i; + int ret; /* Fix up parent per register setting */ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ); @@ -756,14 +733,7 @@ static int clk_misc_init(void) reg |= 3 << BP_CLKCTRL_HBUS_DIV; __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS); - for (i = 10000; i; i--) - if (!(__raw_readl(CLKCTRL_BASE_ADDR + - HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_ASM_BUSY)) - break; - if (!i) { - pr_err("%s: divider writing timeout\n", __func__); - return -ETIMEDOUT; - } + ret = mxs_clkctrl_timeout(HW_CLKCTRL_HBUS, BM_CLKCTRL_HBUS_ASM_BUSY); /* Gate off cpu clock in WFI for power saving */ __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT, @@ -790,7 +760,7 @@ static int clk_misc_init(void) reg |= 30 << BP_CLKCTRL_FRAC0_IO0FRAC; __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0); - return 0; + return ret; } int __init mx28_clocks_init(void) @@ -803,6 +773,8 @@ int __init mx28_clocks_init(void) */ clk_set_parent(&ssp0_clk, &ref_io0_clk); clk_set_parent(&ssp1_clk, &ref_io0_clk); + clk_set_parent(&ssp2_clk, &ref_io1_clk); + clk_set_parent(&ssp3_clk, &ref_io1_clk); clk_prepare_enable(&cpu_clk); clk_prepare_enable(&hbus_clk); diff --git a/arch/arm/mach-mxs/devices-mx23.h b/arch/arm/mach-mxs/devices-mx23.h index 3fa651d2c994..4d1329d59287 100644 --- a/arch/arm/mach-mxs/devices-mx23.h +++ b/arch/arm/mach-mxs/devices-mx23.h @@ -21,6 +21,10 @@ extern const struct mxs_auart_data mx23_auart_data[] __initconst; #define mx23_add_auart0() mx23_add_auart(0) #define mx23_add_auart1() mx23_add_auart(1) +extern const struct mxs_gpmi_nand_data mx23_gpmi_nand_data __initconst; +#define mx23_add_gpmi_nand(pdata) \ + mxs_add_gpmi_nand(pdata, &mx23_gpmi_nand_data) + extern const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst; #define mx23_add_mxs_mmc(id, pdata) \ mxs_add_mxs_mmc(&mx23_mxs_mmc_data[id], pdata) diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h index 4f50094e293d..9dbeae130842 100644 --- a/arch/arm/mach-mxs/devices-mx28.h +++ b/arch/arm/mach-mxs/devices-mx28.h @@ -34,6 +34,10 @@ extern const struct mxs_flexcan_data mx28_flexcan_data[] __initconst; #define mx28_add_flexcan0(pdata) mx28_add_flexcan(0, pdata) #define mx28_add_flexcan1(pdata) mx28_add_flexcan(1, pdata) +extern const struct mxs_gpmi_nand_data mx28_gpmi_nand_data __initconst; +#define mx28_add_gpmi_nand(pdata) \ + mxs_add_gpmi_nand(pdata, &mx28_gpmi_nand_data) + extern const struct mxs_mxs_i2c_data mx28_mxs_i2c_data[] __initconst; #define mx28_add_mxs_i2c(id) mxs_add_mxs_i2c(&mx28_mxs_i2c_data[id]) diff --git a/arch/arm/mach-mxs/devices.c b/arch/arm/mach-mxs/devices.c index fe3e847930c9..01faffec3064 100644 --- a/arch/arm/mach-mxs/devices.c +++ b/arch/arm/mach-mxs/devices.c @@ -77,16 +77,18 @@ err: int __init mxs_add_amba_device(const struct amba_device *dev) { - struct amba_device *adev = kmalloc(sizeof(*adev), GFP_KERNEL); + struct amba_device *adev = amba_device_alloc(dev->dev.init_name, + dev->res.start, resource_size(&dev->res)); if (!adev) { pr_err("%s: failed to allocate memory", __func__); return -ENOMEM; } - *adev = *dev; + adev->irq[0] = dev->irq[0]; + adev->irq[1] = dev->irq[1]; - return amba_device_register(adev, &iomem_resource); + return amba_device_add(adev, &iomem_resource); } struct device mxs_apbh_bus = { diff --git a/arch/arm/mach-mxs/devices/Kconfig b/arch/arm/mach-mxs/devices/Kconfig index 18b6bf526a27..b8913df4cfa2 100644 --- a/arch/arm/mach-mxs/devices/Kconfig +++ b/arch/arm/mach-mxs/devices/Kconfig @@ -12,6 +12,9 @@ config MXS_HAVE_PLATFORM_FLEXCAN select HAVE_CAN_FLEXCAN if CAN bool +config MXS_HAVE_PLATFORM_GPMI_NAND + bool + config MXS_HAVE_PLATFORM_MXS_I2C bool diff --git a/arch/arm/mach-mxs/devices/Makefile b/arch/arm/mach-mxs/devices/Makefile index f52e3e53baec..c8f5c9541a30 100644 --- a/arch/arm/mach-mxs/devices/Makefile +++ b/arch/arm/mach-mxs/devices/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_MXS_HAVE_PLATFORM_AUART) += platform-auart.o obj-y += platform-dma.o obj-$(CONFIG_MXS_HAVE_PLATFORM_FEC) += platform-fec.o obj-$(CONFIG_MXS_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o +obj-$(CONFIG_MXS_HAVE_PLATFORM_GPMI_NAND) += platform-gpmi-nand.o obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_I2C) += platform-mxs-i2c.o obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_MMC) += platform-mxs-mmc.o obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_PWM) += platform-mxs-pwm.o diff --git a/arch/arm/mach-mxs/devices/amba-duart.c b/arch/arm/mach-mxs/devices/amba-duart.c index a559db09b49c..a5479f766046 100644 --- a/arch/arm/mach-mxs/devices/amba-duart.c +++ b/arch/arm/mach-mxs/devices/amba-duart.c @@ -23,7 +23,7 @@ const struct amba_device name##_device __initconst = { \ .end = (soc ## _DUART_BASE_ADDR) + SZ_8K - 1, \ .flags = IORESOURCE_MEM, \ }, \ - .irq = {soc ## _INT_DUART, NO_IRQ}, \ + .irq = {soc ## _INT_DUART}, \ } #ifdef CONFIG_SOC_IMX23 diff --git a/arch/arm/mach-mxs/devices/platform-gpmi-nand.c b/arch/arm/mach-mxs/devices/platform-gpmi-nand.c new file mode 100644 index 000000000000..3e22df5944a8 --- /dev/null +++ b/arch/arm/mach-mxs/devices/platform-gpmi-nand.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include <asm/sizes.h> +#include <mach/mx23.h> +#include <mach/mx28.h> +#include <mach/devices-common.h> +#include <linux/dma-mapping.h> + +#ifdef CONFIG_SOC_IMX23 +const struct mxs_gpmi_nand_data mx23_gpmi_nand_data __initconst = { + .devid = "imx23-gpmi-nand", + .res = { + /* GPMI */ + DEFINE_RES_MEM_NAMED(MX23_GPMI_BASE_ADDR, SZ_8K, + GPMI_NAND_GPMI_REGS_ADDR_RES_NAME), + DEFINE_RES_IRQ_NAMED(MX23_INT_GPMI_ATTENTION, + GPMI_NAND_GPMI_INTERRUPT_RES_NAME), + /* BCH */ + DEFINE_RES_MEM_NAMED(MX23_BCH_BASE_ADDR, SZ_8K, + GPMI_NAND_BCH_REGS_ADDR_RES_NAME), + DEFINE_RES_IRQ_NAMED(MX23_INT_BCH, + GPMI_NAND_BCH_INTERRUPT_RES_NAME), + /* DMA */ + DEFINE_RES_NAMED(MX23_DMA_GPMI0, + MX23_DMA_GPMI3 - MX23_DMA_GPMI0 + 1, + GPMI_NAND_DMA_CHANNELS_RES_NAME, + IORESOURCE_DMA), + DEFINE_RES_IRQ_NAMED(MX23_INT_GPMI_DMA, + GPMI_NAND_DMA_INTERRUPT_RES_NAME), + }, +}; +#endif + +#ifdef CONFIG_SOC_IMX28 +const struct mxs_gpmi_nand_data mx28_gpmi_nand_data __initconst = { + .devid = "imx28-gpmi-nand", + .res = { + /* GPMI */ + DEFINE_RES_MEM_NAMED(MX28_GPMI_BASE_ADDR, SZ_8K, + GPMI_NAND_GPMI_REGS_ADDR_RES_NAME), + DEFINE_RES_IRQ_NAMED(MX28_INT_GPMI, + GPMI_NAND_GPMI_INTERRUPT_RES_NAME), + /* BCH */ + DEFINE_RES_MEM_NAMED(MX28_BCH_BASE_ADDR, SZ_8K, + GPMI_NAND_BCH_REGS_ADDR_RES_NAME), + DEFINE_RES_IRQ_NAMED(MX28_INT_BCH, + GPMI_NAND_BCH_INTERRUPT_RES_NAME), + /* DMA */ + DEFINE_RES_NAMED(MX28_DMA_GPMI0, + MX28_DMA_GPMI7 - MX28_DMA_GPMI0 + 1, + GPMI_NAND_DMA_CHANNELS_RES_NAME, + IORESOURCE_DMA), + DEFINE_RES_IRQ_NAMED(MX28_INT_GPMI_DMA, + GPMI_NAND_DMA_INTERRUPT_RES_NAME), + }, +}; +#endif + +struct platform_device *__init +mxs_add_gpmi_nand(const struct gpmi_nand_platform_data *pdata, + const struct mxs_gpmi_nand_data *data) +{ + return mxs_add_platform_device_dmamask(data->devid, -1, + data->res, GPMI_NAND_RES_SIZE, + pdata, sizeof(*pdata), DMA_BIT_MASK(32)); +} diff --git a/arch/arm/mach-mxs/devices/platform-mxs-mmc.c b/arch/arm/mach-mxs/devices/platform-mxs-mmc.c index 382dacbeca21..bef9d923f54e 100644 --- a/arch/arm/mach-mxs/devices/platform-mxs-mmc.c +++ b/arch/arm/mach-mxs/devices/platform-mxs-mmc.c @@ -41,6 +41,8 @@ const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst = { const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst = { mxs_mxs_mmc_data_entry(MX28, 0, 0), mxs_mxs_mmc_data_entry(MX28, 1, 1), + mxs_mxs_mmc_data_entry(MX28, 2, 2), + mxs_mxs_mmc_data_entry(MX28, 3, 3), }; #endif diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h index e1237ab25862..c50c3ea28a9d 100644 --- a/arch/arm/mach-mxs/include/mach/common.h +++ b/arch/arm/mach-mxs/include/mach/common.h @@ -31,4 +31,6 @@ extern void mx28_init_irq(void); extern void icoll_init_irq(void); +extern int mxs_clkctrl_timeout(unsigned int reg_offset, unsigned int mask); + #endif /* __MACH_MXS_COMMON_H__ */ diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h index dc369c1239fc..f2e383955d88 100644 --- a/arch/arm/mach-mxs/include/mach/devices-common.h +++ b/arch/arm/mach-mxs/include/mach/devices-common.h @@ -66,6 +66,16 @@ struct platform_device *__init mxs_add_flexcan( const struct mxs_flexcan_data *data, const struct flexcan_platform_data *pdata); +/* gpmi-nand */ +#include <linux/mtd/gpmi-nand.h> +struct mxs_gpmi_nand_data { + const char *devid; + const struct resource res[GPMI_NAND_RES_SIZE]; +}; +struct platform_device *__init +mxs_add_gpmi_nand(const struct gpmi_nand_platform_data *pdata, + const struct mxs_gpmi_nand_data *data); + /* i2c */ struct mxs_mxs_i2c_data { int id; diff --git a/arch/arm/mach-mxs/include/mach/digctl.h b/arch/arm/mach-mxs/include/mach/digctl.h index 49a888c65d6d..17964066303f 100644 --- a/arch/arm/mach-mxs/include/mach/digctl.h +++ b/arch/arm/mach-mxs/include/mach/digctl.h @@ -18,4 +18,5 @@ #define HW_DIGCTL_CTRL 0x0 #define BP_DIGCTL_CTRL_SAIF_CLKMUX 10 #define BM_DIGCTL_CTRL_SAIF_CLKMUX (0x3 << 10) +#define HW_DIGCTL_CHIPID 0x310 #endif diff --git a/arch/arm/mach-mxs/include/mach/dma.h b/arch/arm/mach-mxs/include/mach/dma.h deleted file mode 100644 index 203d7c4a3e11..000000000000 --- a/arch/arm/mach-mxs/include/mach/dma.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved. - * - * 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. - */ - -#ifndef __MACH_MXS_DMA_H__ -#define __MACH_MXS_DMA_H__ - -#include <linux/dmaengine.h> - -struct mxs_dma_data { - int chan_irq; -}; - -static inline int mxs_dma_is_apbh(struct dma_chan *chan) -{ - return !strcmp(dev_name(chan->device->dev), "mxs-dma-apbh"); -} - -static inline int mxs_dma_is_apbx(struct dma_chan *chan) -{ - return !strcmp(dev_name(chan->device->dev), "mxs-dma-apbx"); -} - -#endif /* __MACH_MXS_DMA_H__ */ diff --git a/arch/arm/mach-mxs/include/mach/entry-macro.S b/arch/arm/mach-mxs/include/mach/entry-macro.S index 9f0da12e657a..0c14259705b9 100644 --- a/arch/arm/mach-mxs/include/mach/entry-macro.S +++ b/arch/arm/mach-mxs/include/mach/entry-macro.S @@ -23,9 +23,6 @@ #define MXS_ICOLL_VBASE MXS_IO_ADDRESS(MXS_ICOLL_BASE_ADDR) #define HW_ICOLL_STAT_OFFSET 0x70 - .macro disable_fiq - .endm - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \irqnr, [\base, #HW_ICOLL_STAT_OFFSET] cmp \irqnr, #0x7F @@ -36,6 +33,3 @@ .macro get_irqnr_preamble, base, tmp ldr \base, =MXS_ICOLL_VBASE .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-mxs/include/mach/hardware.h b/arch/arm/mach-mxs/include/mach/hardware.h index 53e89a09bf0d..4c0e8a64d8c7 100644 --- a/arch/arm/mach-mxs/include/mach/hardware.h +++ b/arch/arm/mach-mxs/include/mach/hardware.h @@ -20,10 +20,4 @@ #ifndef __MACH_MXS_HARDWARE_H__ #define __MACH_MXS_HARDWARE_H__ -#ifdef __ASSEMBLER__ -#define IOMEM(addr) (addr) -#else -#define IOMEM(addr) ((void __force __iomem *)(addr)) -#endif - #endif /* __MACH_MXS_HARDWARE_H__ */ diff --git a/arch/arm/mach-mxs/include/mach/io.h b/arch/arm/mach-mxs/include/mach/io.h deleted file mode 100644 index 289b7227e072..000000000000 --- a/arch/arm/mach-mxs/include/mach/io.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -/* - * 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. - */ - -#ifndef __MACH_MXS_IO_H__ -#define __MACH_MXS_IO_H__ - -/* Allow IO space to be anywhere in the memory */ -#define IO_SPACE_LIMIT 0xffffffff - -/* io address mapping macro */ -#define __io(a) __typesafe_io(a) - -#define __mem_pci(a) (a) - -#endif /* __MACH_MXS_IO_H__ */ diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h index bde5f6634747..7d4fb6d0afda 100644 --- a/arch/arm/mach-mxs/include/mach/mxs.h +++ b/arch/arm/mach-mxs/include/mach/mxs.h @@ -23,22 +23,10 @@ #include <linux/io.h> #endif #include <asm/mach-types.h> +#include <mach/digctl.h> #include <mach/hardware.h> /* - * MXS CPU types - */ -#define cpu_is_mx23() ( \ - machine_is_mx23evk() || \ - machine_is_stmp378x() || \ - 0) -#define cpu_is_mx28() ( \ - machine_is_mx28evk() || \ - machine_is_m28evk() || \ - machine_is_tx28() || \ - 0) - -/* * IO addresses common to MXS-based */ #define MXS_IO_BASE_ADDR 0x80000000 @@ -109,6 +97,21 @@ static inline void __mxs_togl(u32 mask, void __iomem *reg) { __raw_writel(mask, reg + MXS_TOG_ADDR); } + +/* + * MXS CPU types + */ +#define MXS_CHIPID (MXS_IO_ADDRESS(MXS_DIGCTL_BASE_ADDR) + HW_DIGCTL_CHIPID) + +static inline int cpu_is_mx23(void) +{ + return ((__raw_readl(MXS_CHIPID) >> 16) == 0x3780); +} + +static inline int cpu_is_mx28(void) +{ + return ((__raw_readl(MXS_CHIPID) >> 16) == 0x2800); +} #endif #endif /* __MACH_MXS_H__ */ diff --git a/arch/arm/mach-mxs/include/mach/system.h b/arch/arm/mach-mxs/include/mach/system.h deleted file mode 100644 index e7ad1bb29423..000000000000 --- a/arch/arm/mach-mxs/include/mach/system.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 1999 ARM Limited - * Copyright (C) 2000 Deep Blue Solutions Ltd - * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved. - * - * 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_MXS_SYSTEM_H__ -#define __MACH_MXS_SYSTEM_H__ - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif /* __MACH_MXS_SYSTEM_H__ */ diff --git a/arch/arm/mach-mxs/include/mach/uncompress.h b/arch/arm/mach-mxs/include/mach/uncompress.h index 67776746f143..ef2811495446 100644 --- a/arch/arm/mach-mxs/include/mach/uncompress.h +++ b/arch/arm/mach-mxs/include/mach/uncompress.h @@ -18,8 +18,6 @@ #ifndef __MACH_MXS_UNCOMPRESS_H__ #define __MACH_MXS_UNCOMPRESS_H__ -#include <asm/mach-types.h> - unsigned long mxs_duart_base; #define MXS_DUART(x) (*(volatile unsigned long *)(mxs_duart_base + (x))) @@ -55,16 +53,17 @@ static inline void flush(void) #define MX23_DUART_BASE_ADDR 0x80070000 #define MX28_DUART_BASE_ADDR 0x80074000 +#define MXS_DIGCTL_CHIPID 0x8001c310 static inline void __arch_decomp_setup(unsigned long arch_id) { - switch (arch_id) { - case MACH_TYPE_MX23EVK: + u16 chipid = (*(volatile unsigned long *) MXS_DIGCTL_CHIPID) >> 16; + + switch (chipid) { + case 0x3780: mxs_duart_base = MX23_DUART_BASE_ADDR; break; - case MACH_TYPE_MX28EVK: - case MACH_TYPE_M28EVK: - case MACH_TYPE_TX28: + case 0x2800: mxs_duart_base = MX28_DUART_BASE_ADDR; break; default: diff --git a/arch/arm/mach-mxs/mach-apx4devkit.c b/arch/arm/mach-mxs/mach-apx4devkit.c new file mode 100644 index 000000000000..48a7fab571a6 --- /dev/null +++ b/arch/arm/mach-mxs/mach-apx4devkit.c @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2011-2012 + * Lauri Hintsala, Bluegiga, <lauri.hintsala@bluegiga.com> + * Veli-Pekka Peltola, Bluegiga, <veli-pekka.peltola@bluegiga.com> + * + * based on: mach-mx28evk.c + * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved. + * + * 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/delay.h> +#include <linux/platform_device.h> +#include <linux/gpio.h> +#include <linux/leds.h> +#include <linux/clk.h> +#include <linux/i2c.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/fixed.h> +#include <linux/micrel_phy.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/time.h> + +#include <mach/common.h> +#include <mach/digctl.h> +#include <mach/iomux-mx28.h> + +#include "devices-mx28.h" + +#define APX4DEVKIT_GPIO_USERLED MXS_GPIO_NR(3, 28) + +static const iomux_cfg_t apx4devkit_pads[] __initconst = { + /* duart */ + MX28_PAD_PWM0__DUART_RX | MXS_PAD_CTRL, + MX28_PAD_PWM1__DUART_TX | MXS_PAD_CTRL, + + /* auart0 */ + MX28_PAD_AUART0_RX__AUART0_RX | MXS_PAD_CTRL, + MX28_PAD_AUART0_TX__AUART0_TX | MXS_PAD_CTRL, + MX28_PAD_AUART0_CTS__AUART0_CTS | MXS_PAD_CTRL, + MX28_PAD_AUART0_RTS__AUART0_RTS | MXS_PAD_CTRL, + + /* auart1 */ + MX28_PAD_AUART1_RX__AUART1_RX | MXS_PAD_CTRL, + MX28_PAD_AUART1_TX__AUART1_TX | MXS_PAD_CTRL, + + /* auart2 */ + MX28_PAD_SSP2_SCK__AUART2_RX | MXS_PAD_CTRL, + MX28_PAD_SSP2_MOSI__AUART2_TX | MXS_PAD_CTRL, + + /* auart3 */ + MX28_PAD_SSP2_MISO__AUART3_RX | MXS_PAD_CTRL, + MX28_PAD_SSP2_SS0__AUART3_TX | MXS_PAD_CTRL, + +#define MXS_PAD_FEC (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP) + /* fec0 */ + MX28_PAD_ENET0_MDC__ENET0_MDC | MXS_PAD_FEC, + MX28_PAD_ENET0_MDIO__ENET0_MDIO | MXS_PAD_FEC, + MX28_PAD_ENET0_RX_EN__ENET0_RX_EN | MXS_PAD_FEC, + MX28_PAD_ENET0_RXD0__ENET0_RXD0 | MXS_PAD_FEC, + MX28_PAD_ENET0_RXD1__ENET0_RXD1 | MXS_PAD_FEC, + MX28_PAD_ENET0_TX_EN__ENET0_TX_EN | MXS_PAD_FEC, + MX28_PAD_ENET0_TXD0__ENET0_TXD0 | MXS_PAD_FEC, + MX28_PAD_ENET0_TXD1__ENET0_TXD1 | MXS_PAD_FEC, + MX28_PAD_ENET_CLK__CLKCTRL_ENET | MXS_PAD_FEC, + + /* i2c */ + MX28_PAD_I2C0_SCL__I2C0_SCL, + MX28_PAD_I2C0_SDA__I2C0_SDA, + + /* mmc0 */ + MX28_PAD_SSP0_DATA0__SSP0_D0 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_SSP0_DATA1__SSP0_D1 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_SSP0_DATA2__SSP0_D2 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_SSP0_DATA3__SSP0_D3 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_SSP0_DATA4__SSP0_D4 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_SSP0_DATA5__SSP0_D5 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_SSP0_DATA6__SSP0_D6 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_SSP0_DATA7__SSP0_D7 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_SSP0_CMD__SSP0_CMD | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), + MX28_PAD_SSP0_SCK__SSP0_SCK | + (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), + + /* led */ + MX28_PAD_PWM3__GPIO_3_28 | MXS_PAD_CTRL, + + /* saif0 & saif1 */ + MX28_PAD_SAIF0_MCLK__SAIF0_MCLK | + (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK | + (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK | + (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0 | + (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_SAIF1_SDATA0__SAIF1_SDATA0 | + (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +}; + +/* led */ +static const struct gpio_led apx4devkit_leds[] __initconst = { + { + .name = "user-led", + .default_trigger = "heartbeat", + .gpio = APX4DEVKIT_GPIO_USERLED, + }, +}; + +static const struct gpio_led_platform_data apx4devkit_led_data __initconst = { + .leds = apx4devkit_leds, + .num_leds = ARRAY_SIZE(apx4devkit_leds), +}; + +static const struct fec_platform_data mx28_fec_pdata __initconst = { + .phy = PHY_INTERFACE_MODE_RMII, +}; + +static const struct mxs_mmc_platform_data apx4devkit_mmc_pdata __initconst = { + .wp_gpio = -EINVAL, + .flags = SLOTF_4_BIT_CAPABLE, +}; + +static const struct i2c_board_info apx4devkit_i2c_boardinfo[] __initconst = { + { I2C_BOARD_INFO("sgtl5000", 0x0a) }, /* ASoC */ + { I2C_BOARD_INFO("pcf8563", 0x51) }, /* RTC */ +}; + +#if defined(CONFIG_REGULATOR_FIXED_VOLTAGE) || \ + defined(CONFIG_REGULATOR_FIXED_VOLTAGE_MODULE) +static struct regulator_consumer_supply apx4devkit_audio_consumer_supplies[] = { + REGULATOR_SUPPLY("VDDA", "0-000a"), + REGULATOR_SUPPLY("VDDIO", "0-000a"), +}; + +static struct regulator_init_data apx4devkit_vdd_reg_init_data = { + .constraints = { + .name = "3V3", + .always_on = 1, + }, + .consumer_supplies = apx4devkit_audio_consumer_supplies, + .num_consumer_supplies = ARRAY_SIZE(apx4devkit_audio_consumer_supplies), +}; + +static struct fixed_voltage_config apx4devkit_vdd_pdata = { + .supply_name = "board-3V3", + .microvolts = 3300000, + .gpio = -EINVAL, + .enabled_at_boot = 1, + .init_data = &apx4devkit_vdd_reg_init_data, +}; + +static struct platform_device apx4devkit_voltage_regulator = { + .name = "reg-fixed-voltage", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &apx4devkit_vdd_pdata, + }, +}; + +static void __init apx4devkit_add_regulators(void) +{ + platform_device_register(&apx4devkit_voltage_regulator); +} +#else +static void __init apx4devkit_add_regulators(void) {} +#endif + +static const struct mxs_saif_platform_data + apx4devkit_mxs_saif_pdata[] __initconst = { + /* working on EXTMSTR0 mode (saif0 master, saif1 slave) */ + { + .master_mode = 1, + .master_id = 0, + }, { + .master_mode = 0, + .master_id = 0, + }, +}; + +static int apx4devkit_phy_fixup(struct phy_device *phy) +{ + phy->dev_flags |= MICREL_PHY_50MHZ_CLK; + return 0; +} + +static void __init apx4devkit_init(void) +{ + mxs_iomux_setup_multiple_pads(apx4devkit_pads, + ARRAY_SIZE(apx4devkit_pads)); + + mx28_add_duart(); + mx28_add_auart0(); + mx28_add_auart1(); + mx28_add_auart2(); + mx28_add_auart3(); + + /* + * Register fixup for the Micrel KS8031 PHY clock + * (shares same ID with KS8051) + */ + phy_register_fixup_for_uid(PHY_ID_KS8051, MICREL_PHY_ID_MASK, + apx4devkit_phy_fixup); + + mx28_add_fec(0, &mx28_fec_pdata); + + mx28_add_mxs_mmc(0, &apx4devkit_mmc_pdata); + + gpio_led_register_device(0, &apx4devkit_led_data); + + mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0); + mx28_add_saif(0, &apx4devkit_mxs_saif_pdata[0]); + mx28_add_saif(1, &apx4devkit_mxs_saif_pdata[1]); + + apx4devkit_add_regulators(); + + mx28_add_mxs_i2c(0); + i2c_register_board_info(0, apx4devkit_i2c_boardinfo, + ARRAY_SIZE(apx4devkit_i2c_boardinfo)); + + mxs_add_platform_device("mxs-sgtl5000", 0, NULL, 0, NULL, 0); +} + +static void __init apx4devkit_timer_init(void) +{ + mx28_clocks_init(); +} + +static struct sys_timer apx4devkit_timer = { + .init = apx4devkit_timer_init, +}; + +MACHINE_START(APX4DEVKIT, "Bluegiga APX4 Development Kit") + .map_io = mx28_map_io, + .init_irq = mx28_init_irq, + .timer = &apx4devkit_timer, + .init_machine = apx4devkit_init, + .restart = mxs_restart, +MACHINE_END diff --git a/arch/arm/mach-mxs/mach-m28evk.c b/arch/arm/mach-mxs/mach-m28evk.c index 2f2758230edf..06d79963611c 100644 --- a/arch/arm/mach-mxs/mach-m28evk.c +++ b/arch/arm/mach-mxs/mach-m28evk.c @@ -247,18 +247,15 @@ static int __init m28evk_fec_get_mac(void) u32 val; const u32 *ocotp = mxs_get_ocotp(); - if (!ocotp) { - pr_err("%s: timeout when reading fec mac from OCOTP\n", - __func__); + if (!ocotp) return -ETIMEDOUT; - } /* * OCOTP only stores the last 4 octets for each mac address, * so hard-code DENX OUI (C0:E5:4E) here. */ for (i = 0; i < 2; i++) { - val = ocotp[i * 4]; + val = ocotp[i]; mx28_fec_pdata[i].mac[0] = 0xC0; mx28_fec_pdata[i].mac[1] = 0xE5; mx28_fec_pdata[i].mac[2] = 0x4E; diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c index fdb0a5664dd6..e386c142f93c 100644 --- a/arch/arm/mach-mxs/mach-mx28evk.c +++ b/arch/arm/mach-mxs/mach-mx28evk.c @@ -223,7 +223,6 @@ static const struct gpio_led_platform_data mx28evk_led_data __initconst = { /* fec */ static void __init mx28evk_fec_reset(void) { - int ret; struct clk *clk; /* Enable fec phy clock */ @@ -231,32 +230,7 @@ static void __init mx28evk_fec_reset(void) if (!IS_ERR(clk)) clk_prepare_enable(clk); - /* Power up fec phy */ - ret = gpio_request(MX28EVK_FEC_PHY_POWER, "fec-phy-power"); - if (ret) { - pr_err("Failed to request gpio fec-phy-%s: %d\n", "power", ret); - return; - } - - ret = gpio_direction_output(MX28EVK_FEC_PHY_POWER, 0); - if (ret) { - pr_err("Failed to drive gpio fec-phy-%s: %d\n", "power", ret); - return; - } - - /* Reset fec phy */ - ret = gpio_request(MX28EVK_FEC_PHY_RESET, "fec-phy-reset"); - if (ret) { - pr_err("Failed to request gpio fec-phy-%s: %d\n", "reset", ret); - return; - } - - gpio_direction_output(MX28EVK_FEC_PHY_RESET, 0); - if (ret) { - pr_err("Failed to drive gpio fec-phy-%s: %d\n", "reset", ret); - return; - } - + gpio_set_value(MX28EVK_FEC_PHY_RESET, 0); mdelay(1); gpio_set_value(MX28EVK_FEC_PHY_RESET, 1); } @@ -278,14 +252,14 @@ static int __init mx28evk_fec_get_mac(void) const u32 *ocotp = mxs_get_ocotp(); if (!ocotp) - goto error; + return -ETIMEDOUT; /* * OCOTP only stores the last 4 octets for each mac address, * so hard-code Freescale OUI (00:04:9f) here. */ for (i = 0; i < 2; i++) { - val = ocotp[i * 4]; + val = ocotp[i]; mx28_fec_pdata[i].mac[0] = 0x00; mx28_fec_pdata[i].mac[1] = 0x04; mx28_fec_pdata[i].mac[2] = 0x9f; @@ -295,10 +269,6 @@ static int __init mx28evk_fec_get_mac(void) } return 0; - -error: - pr_err("%s: timeout when reading fec mac from OCOTP\n", __func__); - return -ETIMEDOUT; } /* @@ -417,9 +387,14 @@ static void __init mx28evk_add_regulators(void) static void __init mx28evk_add_regulators(void) {} #endif -static struct gpio mx28evk_lcd_gpios[] = { +static const struct gpio mx28evk_gpios[] __initconst = { { MX28EVK_LCD_ENABLE, GPIOF_OUT_INIT_HIGH, "lcd-enable" }, { MX28EVK_BL_ENABLE, GPIOF_OUT_INIT_HIGH, "bl-enable" }, + { MX28EVK_FLEXCAN_SWITCH, GPIOF_DIR_OUT, "flexcan-switch" }, + { MX28EVK_MMC0_SLOT_POWER, GPIOF_OUT_INIT_LOW, "mmc0-slot-power" }, + { MX28EVK_MMC1_SLOT_POWER, GPIOF_OUT_INIT_LOW, "mmc1-slot-power" }, + { MX28EVK_FEC_PHY_POWER, GPIOF_OUT_INIT_LOW, "fec-phy-power" }, + { MX28EVK_FEC_PHY_RESET, GPIOF_DIR_OUT, "fec-phy-reset" }, }; static const struct mxs_saif_platform_data @@ -447,25 +422,18 @@ static void __init mx28evk_init(void) if (mx28evk_fec_get_mac()) pr_warn("%s: failed on fec mac setup\n", __func__); + ret = gpio_request_array(mx28evk_gpios, ARRAY_SIZE(mx28evk_gpios)); + if (ret) + pr_err("One or more GPIOs failed to be requested: %d\n", ret); + mx28evk_fec_reset(); mx28_add_fec(0, &mx28_fec_pdata[0]); mx28_add_fec(1, &mx28_fec_pdata[1]); - ret = gpio_request_one(MX28EVK_FLEXCAN_SWITCH, GPIOF_DIR_OUT, - "flexcan-switch"); - if (ret) { - pr_err("failed to request gpio flexcan-switch: %d\n", ret); - } else { - mx28_add_flexcan(0, &mx28evk_flexcan_pdata[0]); - mx28_add_flexcan(1, &mx28evk_flexcan_pdata[1]); - } + mx28_add_flexcan(0, &mx28evk_flexcan_pdata[0]); + mx28_add_flexcan(1, &mx28evk_flexcan_pdata[1]); - ret = gpio_request_array(mx28evk_lcd_gpios, - ARRAY_SIZE(mx28evk_lcd_gpios)); - if (ret) - pr_warn("failed to request gpio pins for lcd: %d\n", ret); - else - mx28_add_mxsfb(&mx28evk_mxsfb_pdata); + mx28_add_mxsfb(&mx28evk_mxsfb_pdata); mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0); mx28_add_saif(0, &mx28evk_mxs_saif_pdata[0]); @@ -480,20 +448,8 @@ static void __init mx28evk_init(void) mxs_add_platform_device("mxs-sgtl5000", 0, NULL, 0, NULL, 0); - /* power on mmc slot by writing 0 to the gpio */ - ret = gpio_request_one(MX28EVK_MMC0_SLOT_POWER, GPIOF_OUT_INIT_LOW, - "mmc0-slot-power"); - if (ret) - pr_warn("failed to request gpio mmc0-slot-power: %d\n", ret); - else - mx28_add_mxs_mmc(0, &mx28evk_mmc_pdata[0]); - - ret = gpio_request_one(MX28EVK_MMC1_SLOT_POWER, GPIOF_OUT_INIT_LOW, - "mmc1-slot-power"); - if (ret) - pr_warn("failed to request gpio mmc1-slot-power: %d\n", ret); - else - mx28_add_mxs_mmc(1, &mx28evk_mmc_pdata[1]); + mx28_add_mxs_mmc(0, &mx28evk_mmc_pdata[0]); + mx28_add_mxs_mmc(1, &mx28evk_mmc_pdata[1]); mx28_add_rtc_stmp3xxx(); diff --git a/arch/arm/mach-mxs/pm.c b/arch/arm/mach-mxs/pm.c index fb042da29bda..a9b4bbcdafb4 100644 --- a/arch/arm/mach-mxs/pm.c +++ b/arch/arm/mach-mxs/pm.c @@ -15,13 +15,12 @@ #include <linux/kernel.h> #include <linux/suspend.h> #include <linux/io.h> -#include <mach/system.h> static int mxs_suspend_enter(suspend_state_t state) { switch (state) { case PM_SUSPEND_MEM: - arch_idle(); + cpu_do_idle(); break; default: diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c index 54f91ad1c965..80ac1fca8a00 100644 --- a/arch/arm/mach-mxs/system.c +++ b/arch/arm/mach-mxs/system.c @@ -25,7 +25,7 @@ #include <linux/module.h> #include <asm/proc-fns.h> -#include <asm/system.h> +#include <asm/system_misc.h> #include <mach/mxs.h> #include <mach/common.h> @@ -37,6 +37,8 @@ #define MXS_MODULE_CLKGATE (1 << 30) #define MXS_MODULE_SFTRST (1 << 31) +#define CLKCTRL_TIMEOUT 10 /* 10 ms */ + static void __iomem *mxs_clkctrl_reset_addr; /* @@ -137,3 +139,17 @@ error: return -ETIMEDOUT; } EXPORT_SYMBOL(mxs_reset_block); + +int mxs_clkctrl_timeout(unsigned int reg_offset, unsigned int mask) +{ + unsigned long timeout = jiffies + msecs_to_jiffies(CLKCTRL_TIMEOUT); + while (readl_relaxed(MXS_IO_ADDRESS(MXS_CLKCTRL_BASE_ADDR) + + reg_offset) & mask) { + if (time_after(jiffies, timeout)) { + pr_err("Timeout at CLKCTRL + 0x%x\n", reg_offset); + return -ETIMEDOUT; + } + } + + return 0; +} diff --git a/arch/arm/mach-netx/fb.c b/arch/arm/mach-netx/fb.c index b9913234bbf6..2cdf6ef69bee 100644 --- a/arch/arm/mach-netx/fb.c +++ b/arch/arm/mach-netx/fb.c @@ -92,18 +92,7 @@ void clk_put(struct clk *clk) { } -static struct amba_device fb_device = { - .dev = { - .init_name = "fb", - .coherent_dma_mask = ~0, - }, - .res = { - .start = 0x00104000, - .end = 0x00104fff, - .flags = IORESOURCE_MEM, - }, - .irq = { NETX_IRQ_LCD, NO_IRQ }, -}; +static AMBA_AHB_DEVICE(fb, "fb", 0, 0x00104000, { NETX_IRQ_LCD }, NULL); int netx_fb_init(struct clcd_board *board, struct clcd_panel *panel) { diff --git a/arch/arm/mach-netx/generic.c b/arch/arm/mach-netx/generic.c index 59e67979f197..aa627465d914 100644 --- a/arch/arm/mach-netx/generic.c +++ b/arch/arm/mach-netx/generic.c @@ -168,7 +168,7 @@ void __init netx_init_irq(void) { int irq; - vic_init(__io(io_p2v(NETX_PA_VIC)), 0, ~0, 0); + vic_init(io_p2v(NETX_PA_VIC), 0, ~0, 0); for (irq = NETX_IRQ_HIF_CHAINED(0); irq <= NETX_IRQ_HIF_LAST; irq++) { irq_set_chip_and_handler(irq, &netx_hif_chip, diff --git a/arch/arm/mach-netx/include/mach/entry-macro.S b/arch/arm/mach-netx/include/mach/entry-macro.S deleted file mode 100644 index 6e9f1cbe1634..000000000000 --- a/arch/arm/mach-netx/include/mach/entry-macro.S +++ /dev/null @@ -1,26 +0,0 @@ -/* - * arch/arm/mach-netx/include/mach/entry-macro.S - * - * Low-level IRQ helper macros for Hilscher netX based platforms - * - * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix - * - * 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. - * - * 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 - */ - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-netx/include/mach/hardware.h b/arch/arm/mach-netx/include/mach/hardware.h index 517a2bd37842..b661af2f2145 100644 --- a/arch/arm/mach-netx/include/mach/hardware.h +++ b/arch/arm/mach-netx/include/mach/hardware.h @@ -33,7 +33,7 @@ #define XMAC_MEM_SIZE 0x1000 #define SRAM_MEM_SIZE 0x8000 -#define io_p2v(x) ((x) - NETX_IO_PHYS + NETX_IO_VIRT) +#define io_p2v(x) IOMEM((x) - NETX_IO_PHYS + NETX_IO_VIRT) #define io_v2p(x) ((x) - NETX_IO_VIRT + NETX_IO_PHYS) #endif diff --git a/arch/arm/mach-netx/include/mach/io.h b/arch/arm/mach-netx/include/mach/io.h deleted file mode 100644 index c3921cb3b6a6..000000000000 --- a/arch/arm/mach-netx/include/mach/io.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * arch/arm/mach-netx/include/mach/io.h - * - * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix - * - * 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. - * - * 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_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#endif diff --git a/arch/arm/mach-netx/include/mach/netx-regs.h b/arch/arm/mach-netx/include/mach/netx-regs.h index 5a03e7ccb01a..fdde22b58ac3 100644 --- a/arch/arm/mach-netx/include/mach/netx-regs.h +++ b/arch/arm/mach-netx/include/mach/netx-regs.h @@ -115,7 +115,7 @@ *********************************/ /* Registers */ -#define NETX_SYSTEM_REG(ofs) __io(NETX_VA_SYSTEM + (ofs)) +#define NETX_SYSTEM_REG(ofs) IOMEM(NETX_VA_SYSTEM + (ofs)) #define NETX_SYSTEM_BOO_SR NETX_SYSTEM_REG(0x00) #define NETX_SYSTEM_IOC_CR NETX_SYSTEM_REG(0x04) #define NETX_SYSTEM_IOC_MR NETX_SYSTEM_REG(0x08) @@ -185,7 +185,7 @@ *******************************/ /* Registers */ -#define NETX_GPIO_REG(ofs) __io(NETX_VA_GPIO + (ofs)) +#define NETX_GPIO_REG(ofs) IOMEM(NETX_VA_GPIO + (ofs)) #define NETX_GPIO_CFG(gpio) NETX_GPIO_REG(0x0 + ((gpio)<<2)) #define NETX_GPIO_THRESHOLD_CAPTURE(gpio) NETX_GPIO_REG(0x40 + ((gpio)<<2)) #define NETX_GPIO_COUNTER_CTRL(counter) NETX_GPIO_REG(0x80 + ((counter)<<2)) @@ -230,7 +230,7 @@ *******************************/ /* Registers */ -#define NETX_PIO_REG(ofs) __io(NETX_VA_PIO + (ofs)) +#define NETX_PIO_REG(ofs) IOMEM(NETX_VA_PIO + (ofs)) #define NETX_PIO_INPIO NETX_PIO_REG(0x0) #define NETX_PIO_OUTPIO NETX_PIO_REG(0x4) #define NETX_PIO_OEPIO NETX_PIO_REG(0x8) @@ -240,7 +240,7 @@ *******************************/ /* Registers */ -#define NETX_MIIMU __io(NETX_VA_MIIMU) +#define NETX_MIIMU IOMEM(NETX_VA_MIIMU) /* Bits */ #define MIIMU_SNRDY (1<<0) @@ -317,7 +317,7 @@ *******************************/ /* Registers */ -#define NETX_PFIFO_REG(ofs) __io(NETX_VA_PFIFO + (ofs)) +#define NETX_PFIFO_REG(ofs) IOMEM(NETX_VA_PFIFO + (ofs)) #define NETX_PFIFO_BASE(pfifo) NETX_PFIFO_REG(0x00 + ((pfifo)<<2)) #define NETX_PFIFO_BORDER_BASE(pfifo) NETX_PFIFO_REG(0x80 + ((pfifo)<<2)) #define NETX_PFIFO_RESET NETX_PFIFO_REG(0x100) @@ -334,7 +334,7 @@ *******************************/ /* Registers */ -#define NETX_MEMCR_REG(ofs) __io(NETX_VA_MEMCR + (ofs)) +#define NETX_MEMCR_REG(ofs) IOMEM(NETX_VA_MEMCR + (ofs)) #define NETX_MEMCR_SRAM_CTRL(cs) NETX_MEMCR_REG(0x0 + 4 * (cs)) /* SRAM for CS 0..2 */ #define NETX_MEMCR_SDRAM_CFG_CTRL NETX_MEMCR_REG(0x40) #define NETX_MEMCR_SDRAM_TIMING_CTRL NETX_MEMCR_REG(0x44) @@ -355,7 +355,7 @@ *******************************/ /* Registers */ -#define NETX_DPMAS_REG(ofs) __io(NETX_VA_DPMAS + (ofs)) +#define NETX_DPMAS_REG(ofs) IOMEM(NETX_VA_DPMAS + (ofs)) #define NETX_DPMAS_SYS_STAT NETX_DPMAS_REG(0x4d8) #define NETX_DPMAS_INT_STAT NETX_DPMAS_REG(0x4e0) #define NETX_DPMAS_INT_EN NETX_DPMAS_REG(0x4f0) @@ -425,7 +425,7 @@ /******************************* * I2C * *******************************/ -#define NETX_I2C_REG(ofs) __io(NETX_VA_I2C, (ofs)) +#define NETX_I2C_REG(ofs) IOMEM(NETX_VA_I2C, (ofs)) #define NETX_I2C_CTRL NETX_I2C_REG(0x0) #define NETX_I2C_DATA NETX_I2C_REG(0x4) diff --git a/arch/arm/mach-netx/include/mach/system.h b/arch/arm/mach-netx/include/mach/system.h deleted file mode 100644 index b38fa36d58c4..000000000000 --- a/arch/arm/mach-netx/include/mach/system.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * arch/arm/mach-netx/include/mach/system.h - * - * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix - * - * 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. - * - * 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_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif - diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c index 7c878bf00340..58cacafcf662 100644 --- a/arch/arm/mach-nomadik/board-nhk8815.c +++ b/arch/arm/mach-nomadik/board-nhk8815.c @@ -27,11 +27,11 @@ #include <asm/mach/arch.h> #include <asm/mach/irq.h> #include <asm/mach/flash.h> +#include <asm/mach/time.h> #include <plat/gpio-nomadik.h> #include <plat/mtu.h> -#include <mach/setup.h> #include <mach/nand.h> #include <mach/fsmc.h> @@ -185,20 +185,11 @@ static void __init nhk8815_onenand_init(void) #endif } -#define __MEM_4K_RESOURCE(x) \ - .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM} +static AMBA_APB_DEVICE(uart0, "uart0", 0, NOMADIK_UART0_BASE, + { IRQ_UART0 }, NULL); -static struct amba_device uart0_device = { - .dev = { .init_name = "uart0" }, - __MEM_4K_RESOURCE(NOMADIK_UART0_BASE), - .irq = {IRQ_UART0, NO_IRQ}, -}; - -static struct amba_device uart1_device = { - .dev = { .init_name = "uart1" }, - __MEM_4K_RESOURCE(NOMADIK_UART1_BASE), - .irq = {IRQ_UART1, NO_IRQ}, -}; +static AMBA_APB_DEVICE(uart1, "uart1", 0, NOMADIK_UART1_BASE, + { IRQ_UART1 }, NULL); static struct amba_device *amba_devs[] __initdata = { &uart0_device, @@ -255,10 +246,7 @@ static void __init nomadik_timer_init(void) src_cr |= SRC_CR_INIT_VAL; writel(src_cr, io_p2v(NOMADIK_SRC_BASE)); - /* Save global pointer to mtu, used by platform timer code */ - mtu_base = io_p2v(NOMADIK_MTU0_BASE); - - nmdk_timer_init(); + nmdk_timer_init(io_p2v(NOMADIK_MTU0_BASE)); } static struct sys_timer nomadik_timer = { diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c index 65df7b4fdd3e..27f43a46985e 100644 --- a/arch/arm/mach-nomadik/cpu-8815.c +++ b/arch/arm/mach-nomadik/cpu-8815.c @@ -97,12 +97,7 @@ static struct platform_device cpu8815_platform_gpio[] = { GPIO_DEVICE(3), }; -static struct amba_device cpu8815_amba_rng = { - .dev = { - .init_name = "rng", - }, - __MEM_4K_RESOURCE(NOMADIK_RNG_BASE), -}; +static AMBA_APB_DEVICE(cpu8815_amba_rng, "rng", 0, NOMADIK_RNG_BASE, { }, NULL); static struct platform_device *platform_devs[] __initdata = { cpu8815_platform_gpio + 0, @@ -112,7 +107,7 @@ static struct platform_device *platform_devs[] __initdata = { }; static struct amba_device *amba_devs[] __initdata = { - &cpu8815_amba_rng + &cpu8815_amba_rng_device }; static int __init cpu8815_init(void) diff --git a/arch/arm/mach-nomadik/include/mach/entry-macro.S b/arch/arm/mach-nomadik/include/mach/entry-macro.S deleted file mode 100644 index 98ea1c1fbbab..000000000000 --- a/arch/arm/mach-nomadik/include/mach/entry-macro.S +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Low-level IRQ helper macros for Nomadik platforms - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-nomadik/include/mach/io.h b/arch/arm/mach-nomadik/include/mach/io.h deleted file mode 100644 index 2e1eca1b8243..000000000000 --- a/arch/arm/mach-nomadik/include/mach/io.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * arch/arm/mach-nomadik/include/mach/io.h (copied from mach-sa1100) - * - * Copyright (C) 1997-1999 Russell King - * - * Modifications: - * 06-12-1997 RMK Created. - * 07-04-1999 RMK Major cleanup - */ -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -/* - * We don't actually have real ISA nor PCI buses, but there is so many - * drivers out there that might just work if we fake them... - */ -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#endif diff --git a/arch/arm/mach-nomadik/include/mach/setup.h b/arch/arm/mach-nomadik/include/mach/setup.h deleted file mode 100644 index bcaeaf41c053..000000000000 --- a/arch/arm/mach-nomadik/include/mach/setup.h +++ /dev/null @@ -1,19 +0,0 @@ - -/* - * These symbols are needed for board-specific files to call their - * own cpu-specific files - */ - -#ifndef __ASM_ARCH_SETUP_H -#define __ASM_ARCH_SETUP_H - -#include <asm/mach/time.h> -#include <linux/init.h> - -#ifdef CONFIG_NOMADIK_8815 - -extern void nmdk_timer_init(void); - -#endif /* NOMADIK_8815 */ - -#endif /* __ASM_ARCH_SETUP_H */ diff --git a/arch/arm/mach-nomadik/include/mach/system.h b/arch/arm/mach-nomadik/include/mach/system.h deleted file mode 100644 index 25e198b8976c..000000000000 --- a/arch/arm/mach-nomadik/include/mach/system.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * mach-nomadik/include/mach/system.h - * - * Copyright (C) 2008 STMicroelectronics - * - * 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_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - /* - * This should do all the clock switching - * and wait for interrupt tricks - */ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig index 922ab0dc2bcd..dfab466ebd1d 100644 --- a/arch/arm/mach-omap1/Kconfig +++ b/arch/arm/mach-omap1/Kconfig @@ -152,6 +152,10 @@ config MACH_AMS_DELTA bool "Amstrad E3 (Delta)" depends on ARCH_OMAP1 && ARCH_OMAP15XX select FIQ + select GPIO_GENERIC_PLATFORM + select LEDS_GPIO_REGISTER + select REGULATOR + select REGULATOR_FIXED_VOLTAGE help Support for the Amstrad E3 (codename Delta) videophone. Say Y here if you have such a device. diff --git a/arch/arm/mach-omap1/ams-delta-fiq-handler.S b/arch/arm/mach-omap1/ams-delta-fiq-handler.S index c1c5fb6a5b4c..a051cb8ae57f 100644 --- a/arch/arm/mach-omap1/ams-delta-fiq-handler.S +++ b/arch/arm/mach-omap1/ams-delta-fiq-handler.S @@ -14,12 +14,14 @@ */ #include <linux/linkage.h> +#include <asm/assembler.h> -#include <plat/io.h> #include <plat/board-ams-delta.h> #include <mach/ams-delta-fiq.h> +#include "iomap.h" + /* * GPIO related definitions, copied from arch/arm/plat-omap/gpio.c. * Unfortunately, those were not placed in a separate header file. diff --git a/arch/arm/mach-omap1/ams-delta-fiq.c b/arch/arm/mach-omap1/ams-delta-fiq.c index 152b32c15e28..fcce7ff37630 100644 --- a/arch/arm/mach-omap1/ams-delta-fiq.c +++ b/arch/arm/mach-omap1/ams-delta-fiq.c @@ -22,6 +22,7 @@ #include <plat/board-ams-delta.h> #include <asm/fiq.h> + #include <mach/ams-delta-fiq.h> static struct fiq_handler fh = { diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c index e0e8245f3c9f..c1b681ef4cba 100644 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ b/arch/arm/mach-omap1/board-ams-delta.c @@ -11,6 +11,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include <linux/basic_mmio_gpio.h> #include <linux/gpio.h> #include <linux/kernel.h> #include <linux/init.h> @@ -18,31 +19,33 @@ #include <linux/interrupt.h> #include <linux/leds.h> #include <linux/platform_device.h> +#include <linux/regulator/consumer.h> +#include <linux/regulator/fixed.h> +#include <linux/regulator/machine.h> #include <linux/serial_8250.h> #include <linux/export.h> #include <linux/omapfb.h> +#include <linux/io.h> #include <media/soc_camera.h> #include <asm/serial.h> -#include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <plat/io.h> #include <plat/board-ams-delta.h> #include <plat/keypad.h> #include <plat/mux.h> #include <plat/usb.h> #include <plat/board.h> -#include "common.h" -#include <mach/camera.h> +#include <mach/hardware.h> #include <mach/ams-delta-fiq.h> +#include <mach/camera.h> -static u8 ams_delta_latch1_reg; -static u16 ams_delta_latch2_reg; +#include "iomap.h" +#include "common.h" static const unsigned int ams_delta_keymap[] = { KEY(0, 0, KEY_F1), /* Advert */ @@ -122,54 +125,188 @@ static const unsigned int ams_delta_keymap[] = { KEY(7, 3, KEY_LEFTCTRL), /* Vol down */ }; -void ams_delta_latch1_write(u8 mask, u8 value) -{ - ams_delta_latch1_reg &= ~mask; - ams_delta_latch1_reg |= value; - *(volatile __u8 *) AMS_DELTA_LATCH1_VIRT = ams_delta_latch1_reg; -} - -void ams_delta_latch2_write(u16 mask, u16 value) -{ - ams_delta_latch2_reg &= ~mask; - ams_delta_latch2_reg |= value; - *(volatile __u16 *) AMS_DELTA_LATCH2_VIRT = ams_delta_latch2_reg; -} +#define LATCH1_PHYS 0x01000000 +#define LATCH1_VIRT 0xEA000000 +#define MODEM_PHYS 0x04000000 +#define MODEM_VIRT 0xEB000000 +#define LATCH2_PHYS 0x08000000 +#define LATCH2_VIRT 0xEC000000 static struct map_desc ams_delta_io_desc[] __initdata = { /* AMS_DELTA_LATCH1 */ { - .virtual = AMS_DELTA_LATCH1_VIRT, - .pfn = __phys_to_pfn(AMS_DELTA_LATCH1_PHYS), + .virtual = LATCH1_VIRT, + .pfn = __phys_to_pfn(LATCH1_PHYS), .length = 0x01000000, .type = MT_DEVICE }, /* AMS_DELTA_LATCH2 */ { - .virtual = AMS_DELTA_LATCH2_VIRT, - .pfn = __phys_to_pfn(AMS_DELTA_LATCH2_PHYS), + .virtual = LATCH2_VIRT, + .pfn = __phys_to_pfn(LATCH2_PHYS), .length = 0x01000000, .type = MT_DEVICE }, /* AMS_DELTA_MODEM */ { - .virtual = AMS_DELTA_MODEM_VIRT, - .pfn = __phys_to_pfn(AMS_DELTA_MODEM_PHYS), + .virtual = MODEM_VIRT, + .pfn = __phys_to_pfn(MODEM_PHYS), .length = 0x01000000, .type = MT_DEVICE } }; -static struct omap_lcd_config ams_delta_lcd_config = { +static struct omap_lcd_config ams_delta_lcd_config __initdata = { .ctrl_name = "internal", }; -static struct omap_usb_config ams_delta_usb_config __initdata = { +static struct omap_usb_config ams_delta_usb_config = { .register_host = 1, .hmc_mode = 16, .pins[0] = 2, }; +#define LATCH1_GPIO_BASE 232 +#define LATCH1_NGPIO 8 + +static struct resource latch1_resources[] = { + [0] = { + .name = "dat", + .start = LATCH1_PHYS, + .end = LATCH1_PHYS + (LATCH1_NGPIO - 1) / 8, + .flags = IORESOURCE_MEM, + }, +}; + +static struct bgpio_pdata latch1_pdata = { + .base = LATCH1_GPIO_BASE, + .ngpio = LATCH1_NGPIO, +}; + +static struct platform_device latch1_gpio_device = { + .name = "basic-mmio-gpio", + .id = 0, + .resource = latch1_resources, + .num_resources = ARRAY_SIZE(latch1_resources), + .dev = { + .platform_data = &latch1_pdata, + }, +}; + +static struct resource latch2_resources[] = { + [0] = { + .name = "dat", + .start = LATCH2_PHYS, + .end = LATCH2_PHYS + (AMS_DELTA_LATCH2_NGPIO - 1) / 8, + .flags = IORESOURCE_MEM, + }, +}; + +static struct bgpio_pdata latch2_pdata = { + .base = AMS_DELTA_LATCH2_GPIO_BASE, + .ngpio = AMS_DELTA_LATCH2_NGPIO, +}; + +static struct platform_device latch2_gpio_device = { + .name = "basic-mmio-gpio", + .id = 1, + .resource = latch2_resources, + .num_resources = ARRAY_SIZE(latch2_resources), + .dev = { + .platform_data = &latch2_pdata, + }, +}; + +static const struct gpio latch_gpios[] __initconst = { + { + .gpio = LATCH1_GPIO_BASE + 6, + .flags = GPIOF_OUT_INIT_LOW, + .label = "dockit1", + }, + { + .gpio = LATCH1_GPIO_BASE + 7, + .flags = GPIOF_OUT_INIT_LOW, + .label = "dockit2", + }, + { + .gpio = AMS_DELTA_GPIO_PIN_SCARD_RSTIN, + .flags = GPIOF_OUT_INIT_LOW, + .label = "scard_rstin", + }, + { + .gpio = AMS_DELTA_GPIO_PIN_SCARD_CMDVCC, + .flags = GPIOF_OUT_INIT_LOW, + .label = "scard_cmdvcc", + }, + { + .gpio = AMS_DELTA_GPIO_PIN_MODEM_CODEC, + .flags = GPIOF_OUT_INIT_LOW, + .label = "modem_codec", + }, + { + .gpio = AMS_DELTA_LATCH2_GPIO_BASE + 14, + .flags = GPIOF_OUT_INIT_LOW, + .label = "hookflash1", + }, + { + .gpio = AMS_DELTA_LATCH2_GPIO_BASE + 15, + .flags = GPIOF_OUT_INIT_LOW, + .label = "hookflash2", + }, +}; + +static struct regulator_consumer_supply modem_nreset_consumers[] = { + REGULATOR_SUPPLY("RESET#", "serial8250.1"), + REGULATOR_SUPPLY("POR", "cx20442-codec"), +}; + +static struct regulator_init_data modem_nreset_data = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(modem_nreset_consumers), + .consumer_supplies = modem_nreset_consumers, +}; + +static struct fixed_voltage_config modem_nreset_config = { + .supply_name = "modem_nreset", + .microvolts = 3300000, + .gpio = AMS_DELTA_GPIO_PIN_MODEM_NRESET, + .startup_delay = 25000, + .enable_high = 1, + .enabled_at_boot = 1, + .init_data = &modem_nreset_data, +}; + +static struct platform_device modem_nreset_device = { + .name = "reg-fixed-voltage", + .id = -1, + .dev = { + .platform_data = &modem_nreset_config, + }, +}; + +struct modem_private_data { + struct regulator *regulator; +}; + +static struct modem_private_data modem_priv; + +void ams_delta_latch_write(int base, int ngpio, u16 mask, u16 value) +{ + int bit = 0; + u16 bitpos = 1 << bit; + + for (; bit < ngpio; bit++, bitpos = bitpos << 1) { + if (!(mask & bitpos)) + continue; + else + gpio_set_value(base + bit, (value & bitpos) != 0); + } +} +EXPORT_SYMBOL(ams_delta_latch_write); + static struct resource ams_delta_nand_resources[] = { [0] = { .start = OMAP1_MPUIO_BASE, @@ -199,7 +336,7 @@ static const struct matrix_keymap_data ams_delta_keymap_data = { .keymap_size = ARRAY_SIZE(ams_delta_keymap), }; -static struct omap_kp_platform_data ams_delta_kp_data __initdata = { +static struct omap_kp_platform_data ams_delta_kp_data = { .rows = 8, .cols = 8, .keymap_data = &ams_delta_keymap_data, @@ -221,9 +358,45 @@ static struct platform_device ams_delta_lcd_device = { .id = -1, }; -static struct platform_device ams_delta_led_device = { - .name = "ams-delta-led", - .id = -1 +static const struct gpio_led gpio_leds[] __initconst = { + { + .name = "camera", + .gpio = LATCH1_GPIO_BASE + 0, + .default_state = LEDS_GPIO_DEFSTATE_OFF, +#ifdef CONFIG_LEDS_TRIGGERS + .default_trigger = "ams_delta_camera", +#endif + }, + { + .name = "advert", + .gpio = LATCH1_GPIO_BASE + 1, + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, + { + .name = "email", + .gpio = LATCH1_GPIO_BASE + 2, + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, + { + .name = "handsfree", + .gpio = LATCH1_GPIO_BASE + 3, + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, + { + .name = "voicemail", + .gpio = LATCH1_GPIO_BASE + 4, + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, + { + .name = "voice", + .gpio = LATCH1_GPIO_BASE + 5, + .default_state = LEDS_GPIO_DEFSTATE_OFF, + }, +}; + +static const struct gpio_led_platform_data leds_pdata __initconst = { + .leds = gpio_leds, + .num_leds = ARRAY_SIZE(gpio_leds), }; static struct i2c_board_info ams_delta_camera_board_info[] = { @@ -272,13 +445,17 @@ static struct omap1_cam_platform_data ams_delta_camera_platform_data = { }; static struct platform_device *ams_delta_devices[] __initdata = { - &ams_delta_nand_device, + &latch1_gpio_device, + &latch2_gpio_device, &ams_delta_kp_device, - &ams_delta_lcd_device, - &ams_delta_led_device, &ams_delta_camera_device, }; +static struct platform_device *late_devices[] __initdata = { + &ams_delta_nand_device, + &ams_delta_lcd_device, +}; + static void __init ams_delta_init(void) { /* mux pins for uarts */ @@ -302,15 +479,13 @@ static void __init ams_delta_init(void) omap_serial_init(); omap_register_i2c_bus(1, 100, NULL, 0); - /* Clear latch2 (NAND, LCD, modem enable) */ - ams_delta_latch2_write(~0, 0); - omap1_usb_init(&ams_delta_usb_config); omap1_set_camera_info(&ams_delta_camera_platform_data); #ifdef CONFIG_LEDS_TRIGGERS led_trigger_register_simple("ams_delta_camera", &ams_delta_camera_led_trigger); #endif + gpio_led_register_device(-1, &leds_pdata); platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices)); ams_delta_init_fiq(); @@ -320,16 +495,34 @@ static void __init ams_delta_init(void) omapfb_set_lcd_config(&ams_delta_lcd_config); } +static void modem_pm(struct uart_port *port, unsigned int state, unsigned old) +{ + struct modem_private_data *priv = port->private_data; + + if (IS_ERR(priv->regulator)) + return; + + if (state == old) + return; + + if (state == 0) + regulator_enable(priv->regulator); + else if (old == 0) + regulator_disable(priv->regulator); +} + static struct plat_serial8250_port ams_delta_modem_ports[] = { { - .membase = IOMEM(AMS_DELTA_MODEM_VIRT), - .mapbase = AMS_DELTA_MODEM_PHYS, + .membase = IOMEM(MODEM_VIRT), + .mapbase = MODEM_PHYS, .irq = -EINVAL, /* changed later */ .flags = UPF_BOOT_AUTOCONF, .irqflags = IRQF_TRIGGER_RISING, .iotype = UPIO_MEM, .regshift = 1, .uartclk = BASE_BAUD * 16, + .pm = modem_pm, + .private_data = &modem_priv, }, { }, }; @@ -342,13 +535,27 @@ static struct platform_device ams_delta_modem_device = { }, }; -static int __init ams_delta_modem_init(void) +static int __init late_init(void) { int err; if (!machine_is_ams_delta()) return -ENODEV; + err = gpio_request_array(latch_gpios, ARRAY_SIZE(latch_gpios)); + if (err) { + pr_err("Couldn't take over latch1/latch2 GPIO pins\n"); + return err; + } + + platform_add_devices(late_devices, ARRAY_SIZE(late_devices)); + + err = platform_device_register(&modem_nreset_device); + if (err) { + pr_err("Couldn't register the modem regulator device\n"); + return err; + } + omap_cfg_reg(M14_1510_GPIO2); ams_delta_modem_ports[0].irq = gpio_to_irq(AMS_DELTA_GPIO_PIN_MODEM_IRQ); @@ -360,13 +567,35 @@ static int __init ams_delta_modem_init(void) } gpio_direction_input(AMS_DELTA_GPIO_PIN_MODEM_IRQ); - ams_delta_latch2_write( - AMS_DELTA_LATCH2_MODEM_NRESET | AMS_DELTA_LATCH2_MODEM_CODEC, - AMS_DELTA_LATCH2_MODEM_NRESET | AMS_DELTA_LATCH2_MODEM_CODEC); + /* Initialize the modem_nreset regulator consumer before use */ + modem_priv.regulator = ERR_PTR(-ENODEV); + + ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC, + AMS_DELTA_LATCH2_MODEM_CODEC); - return platform_device_register(&ams_delta_modem_device); + err = platform_device_register(&ams_delta_modem_device); + if (err) + goto gpio_free; + + /* + * Once the modem device is registered, the modem_nreset + * regulator can be requested on behalf of that device. + */ + modem_priv.regulator = regulator_get(&ams_delta_modem_device.dev, + "RESET#"); + if (IS_ERR(modem_priv.regulator)) { + err = PTR_ERR(modem_priv.regulator); + goto unregister; + } + return 0; + +unregister: + platform_device_unregister(&ams_delta_modem_device); +gpio_free: + gpio_free(AMS_DELTA_GPIO_PIN_MODEM_IRQ); + return err; } -arch_initcall(ams_delta_modem_init); +late_initcall(late_init); static void __init ams_delta_map_io(void) { @@ -385,6 +614,3 @@ MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)") .timer = &omap1_timer, .restart = omap1_restart, MACHINE_END - -EXPORT_SYMBOL(ams_delta_latch1_write); -EXPORT_SYMBOL(ams_delta_latch2_write); diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c index 7afaf3c5bdc6..80bd43c7f4ec 100644 --- a/arch/arm/mach-omap1/board-fsample.c +++ b/arch/arm/mach-omap1/board-fsample.c @@ -23,7 +23,6 @@ #include <linux/smc91x.h> #include <linux/omapfb.h> -#include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -33,9 +32,13 @@ #include <plat/flash.h> #include <plat/fpga.h> #include <plat/keypad.h> -#include "common.h" #include <plat/board.h> +#include <mach/hardware.h> + +#include "iomap.h" +#include "common.h" + /* fsample is pretty close to p2-sample */ #define fsample_cpld_read(reg) __raw_readb(reg) diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index af2be8c12c07..553a2e535764 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c @@ -32,8 +32,6 @@ #include <linux/smc91x.h> #include <linux/omapfb.h> -#include <mach/hardware.h> - #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -44,9 +42,11 @@ #include <plat/irda.h> #include <plat/usb.h> #include <plat/keypad.h> -#include "common.h" #include <plat/flash.h> +#include <mach/hardware.h> + +#include "common.h" #include "board-h2.h" /* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */ @@ -245,8 +245,6 @@ static struct resource h2_smc91x_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = OMAP_GPIO_IRQ(0), - .end = OMAP_GPIO_IRQ(0), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, }, }; @@ -359,11 +357,9 @@ static struct tps65010_board tps_board = { static struct i2c_board_info __initdata h2_i2c_board_info[] = { { I2C_BOARD_INFO("tps65010", 0x48), - .irq = OMAP_GPIO_IRQ(58), .platform_data = &tps_board, }, { I2C_BOARD_INFO("isp1301_omap", 0x2d), - .irq = OMAP_GPIO_IRQ(2), }, }; @@ -428,8 +424,12 @@ static void __init h2_init(void) omap_cfg_reg(E19_1610_KBR4); omap_cfg_reg(N19_1610_KBR5); + h2_smc91x_resources[1].start = gpio_to_irq(0); + h2_smc91x_resources[1].end = gpio_to_irq(0); platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices)); omap_serial_init(); + h2_i2c_board_info[0].irq = gpio_to_irq(58); + h2_i2c_board_info[1].irq = gpio_to_irq(2); omap_register_i2c_bus(1, 100, h2_i2c_board_info, ARRAY_SIZE(h2_i2c_board_info)); omap1_usb_init(&h2_usb_config); diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index 7cfd25b90735..4c19f4c06851 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c @@ -34,21 +34,21 @@ #include <asm/setup.h> #include <asm/page.h> -#include <mach/hardware.h> - #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <mach/irqs.h> #include <plat/mux.h> #include <plat/tc.h> #include <plat/usb.h> #include <plat/keypad.h> #include <plat/dma.h> -#include "common.h" #include <plat/flash.h> +#include <mach/hardware.h> +#include <mach/irqs.h> + +#include "common.h" #include "board-h3.h" /* In OMAP1710 H3 the Ethernet is directly connected to CS1 */ @@ -247,8 +247,6 @@ static struct resource smc91x_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = OMAP_GPIO_IRQ(40), - .end = OMAP_GPIO_IRQ(40), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, }, }; @@ -338,7 +336,6 @@ static struct spi_board_info h3_spi_board_info[] __initdata = { .modalias = "tsc2101", .bus_num = 2, .chip_select = 0, - .irq = OMAP_GPIO_IRQ(H3_TS_GPIO), .max_speed_hz = 16000000, /* .platform_data = &tsc_platform_data, */ }, @@ -374,11 +371,9 @@ static struct omap_lcd_config h3_lcd_config __initdata = { static struct i2c_board_info __initdata h3_i2c_board_info[] = { { I2C_BOARD_INFO("tps65013", 0x48), - /* .irq = OMAP_GPIO_IRQ(??), */ }, { I2C_BOARD_INFO("isp1301_omap", 0x2d), - .irq = OMAP_GPIO_IRQ(14), }, }; @@ -420,10 +415,14 @@ static void __init h3_init(void) omap_cfg_reg(E19_1610_KBR4); omap_cfg_reg(N19_1610_KBR5); + smc91x_resources[1].start = gpio_to_irq(40); + smc91x_resources[1].end = gpio_to_irq(40); platform_add_devices(devices, ARRAY_SIZE(devices)); + h3_spi_board_info[0].irq = gpio_to_irq(H3_TS_GPIO); spi_register_board_info(h3_spi_board_info, ARRAY_SIZE(h3_spi_board_info)); omap_serial_init(); + h3_i2c_board_info[1].irq = gpio_to_irq(14); omap_register_i2c_bus(1, 100, h3_i2c_board_info, ARRAY_SIZE(h3_i2c_board_info)); omap1_usb_init(&h3_usb_config); diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c index af2afcf24f75..60c06ee23855 100644 --- a/arch/arm/mach-omap1/board-htcherald.c +++ b/arch/arm/mach-omap1/board-htcherald.c @@ -27,7 +27,7 @@ #include <linux/init.h> #include <linux/platform_device.h> #include <linux/input.h> -#include <linux/io.h> +#include <linux/delay.h> #include <linux/gpio.h> #include <linux/gpio_keys.h> #include <linux/i2c.h> @@ -42,7 +42,6 @@ #include <asm/mach/arch.h> #include <plat/omap7xx.h> -#include "common.h" #include <plat/board.h> #include <plat/keypad.h> #include <plat/usb.h> @@ -50,7 +49,7 @@ #include <mach/irqs.h> -#include <linux/delay.h> +#include "common.h" /* LCD register definition */ #define OMAP_LCDC_CONTROL (0xfffec000 + 0x00) @@ -325,8 +324,6 @@ static struct platform_device gpio_leds_device = { static struct resource htcpld_resources[] = { [0] = { - .start = OMAP_GPIO_IRQ(HTCHERALD_GIRQ_BTNS), - .end = OMAP_GPIO_IRQ(HTCHERALD_GIRQ_BTNS), .flags = IORESOURCE_IRQ, }, }; @@ -451,7 +448,6 @@ static struct spi_board_info __initdata htcherald_spi_board_info[] = { { .modalias = "ads7846", .platform_data = &htcherald_ts_platform_data, - .irq = OMAP_GPIO_IRQ(HTCHERALD_GPIO_TS), .max_speed_hz = 2500000, .bus_num = 2, .chip_select = 1, @@ -577,6 +573,8 @@ static void __init htcherald_init(void) printk(KERN_INFO "HTC Herald init.\n"); /* Do board initialization before we register all the devices */ + htcpld_resources[0].start = gpio_to_irq(HTCHERALD_GIRQ_BTNS); + htcpld_resources[0].end = gpio_to_irq(HTCHERALD_GIRQ_BTNS); platform_add_devices(devices, ARRAY_SIZE(devices)); htcherald_disable_watchdog(); @@ -584,6 +582,7 @@ static void __init htcherald_init(void) htcherald_usb_enable(); omap1_usb_init(&htcherald_usb_config); + htcherald_spi_board_info[0].irq = gpio_to_irq(HTCHERALD_GPIO_TS); spi_register_board_info(htcherald_spi_board_info, ARRAY_SIZE(htcherald_spi_board_info)); diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c index 1d5ab6606b9f..67d7fd57a692 100644 --- a/arch/arm/mach-omap1/board-innovator.c +++ b/arch/arm/mach-omap1/board-innovator.c @@ -27,7 +27,6 @@ #include <linux/smc91x.h> #include <linux/omapfb.h> -#include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -38,9 +37,13 @@ #include <plat/tc.h> #include <plat/usb.h> #include <plat/keypad.h> -#include "common.h" #include <plat/mmc.h> +#include <mach/hardware.h> + +#include "iomap.h" +#include "common.h" + /* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */ #define INNOVATOR1610_ETHR_START 0x04000300 @@ -245,8 +248,6 @@ static struct resource innovator1610_smc91x_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = OMAP_GPIO_IRQ(0), - .end = OMAP_GPIO_IRQ(0), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, }, }; @@ -406,6 +407,8 @@ static void __init innovator_init(void) #endif #ifdef CONFIG_ARCH_OMAP16XX if (!cpu_is_omap1510()) { + innovator1610_smc91x_resources[1].start = gpio_to_irq(0); + innovator1610_smc91x_resources[1].end = gpio_to_irq(0); platform_add_devices(innovator1610_devices, ARRAY_SIZE(innovator1610_devices)); } #endif diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index 9b6332a31fb6..d21dcc2fbc5a 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -21,7 +21,6 @@ #include <linux/workqueue.h> #include <linux/delay.h> -#include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -30,11 +29,14 @@ #include <plat/usb.h> #include <plat/board.h> #include <plat/keypad.h> -#include "common.h" #include <plat/lcd_mipid.h> #include <plat/mmc.h> #include <plat/clock.h> +#include <mach/hardware.h> + +#include "common.h" + #define ADS7846_PENDOWN_GPIO 15 static const unsigned int nokia770_keymap[] = { @@ -145,7 +147,6 @@ static struct spi_board_info nokia770_spi_board_info[] __initdata = { .bus_num = 2, .chip_select = 0, .max_speed_hz = 2500000, - .irq = OMAP_GPIO_IRQ(15), .platform_data = &nokia770_ads7846_platform_data, }, }; @@ -235,6 +236,7 @@ static void __init omap_nokia770_init(void) omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004); platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices)); + nokia770_spi_board_info[1].irq = gpio_to_irq(15); spi_register_board_info(nokia770_spi_board_info, ARRAY_SIZE(nokia770_spi_board_info)); omap_serial_init(); diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index ef874655fbd3..a5f85dda3f69 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -35,15 +35,11 @@ #include <linux/leds.h> #include <linux/smc91x.h> #include <linux/omapfb.h> - #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/mtd/physmap.h> - #include <linux/i2c/tps65010.h> -#include <mach/hardware.h> - #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -52,6 +48,9 @@ #include <plat/usb.h> #include <plat/mux.h> #include <plat/tc.h> + +#include <mach/hardware.h> + #include "common.h" /* At OMAP5912 OSK the Ethernet is directly connected to CS1 */ @@ -130,8 +129,6 @@ static struct resource osk5912_smc91x_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = OMAP_GPIO_IRQ(0), - .end = OMAP_GPIO_IRQ(0), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, }, }; @@ -148,8 +145,6 @@ static struct platform_device osk5912_smc91x_device = { static struct resource osk5912_cf_resources[] = { [0] = { - .start = OMAP_GPIO_IRQ(62), - .end = OMAP_GPIO_IRQ(62), .flags = IORESOURCE_IRQ, }, }; @@ -241,7 +236,6 @@ static struct tps65010_board tps_board = { static struct i2c_board_info __initdata osk_i2c_board_info[] = { { I2C_BOARD_INFO("tps65010", 0x48), - .irq = OMAP_GPIO_IRQ(OMAP_MPUIO(1)), .platform_data = &tps_board, }, @@ -409,7 +403,6 @@ static struct spi_board_info __initdata mistral_boardinfo[] = { { /* MicroWire (bus 2) CS0 has an ads7846e */ .modalias = "ads7846", .platform_data = &mistral_ts_info, - .irq = OMAP_GPIO_IRQ(4), .max_speed_hz = 120000 /* max sample rate at 3V */ * 26 /* command + data + overhead */, .bus_num = 2, @@ -472,6 +465,7 @@ static void __init osk_mistral_init(void) gpio_direction_input(4); irq_set_irq_type(gpio_to_irq(4), IRQ_TYPE_EDGE_FALLING); + mistral_boardinfo[0].irq = gpio_to_irq(4); spi_register_board_info(mistral_boardinfo, ARRAY_SIZE(mistral_boardinfo)); @@ -543,6 +537,10 @@ static void __init osk_init(void) osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys(); osk_flash_resource.end += SZ_32M - 1; + osk5912_smc91x_resources[1].start = gpio_to_irq(0); + osk5912_smc91x_resources[1].end = gpio_to_irq(0); + osk5912_cf_resources[0].start = gpio_to_irq(62); + osk5912_cf_resources[0].end = gpio_to_irq(62); platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices)); l = omap_readl(USB_TRANSCEIVER_CTRL); @@ -557,6 +555,7 @@ static void __init osk_init(void) gpio_direction_input(OMAP_MPUIO(1)); omap_serial_init(); + osk_i2c_board_info[0].irq = gpio_to_irq(OMAP_MPUIO(1)); omap_register_i2c_bus(1, 400, osk_i2c_board_info, ARRAY_SIZE(osk_i2c_board_info)); osk_mistral_init(); diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c index 612342cb2a2d..a60e6c22f816 100644 --- a/arch/arm/mach-omap1/board-palmte.c +++ b/arch/arm/mach-omap1/board-palmte.c @@ -29,7 +29,6 @@ #include <linux/apm-emulation.h> #include <linux/omapfb.h> -#include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -42,6 +41,9 @@ #include <plat/board.h> #include <plat/irda.h> #include <plat/keypad.h> + +#include <mach/hardware.h> + #include "common.h" #define PALMTE_USBDETECT_GPIO 0 @@ -215,7 +217,6 @@ static struct spi_board_info palmte_spi_info[] __initdata = { .modalias = "tsc2102", .bus_num = 2, /* uWire (officially) */ .chip_select = 0, /* As opposed to 3 */ - .irq = OMAP_GPIO_IRQ(PALMTE_PINTDAV_GPIO), .max_speed_hz = 8000000, }, }; @@ -249,6 +250,7 @@ static void __init omap_palmte_init(void) platform_add_devices(palmte_devices, ARRAY_SIZE(palmte_devices)); + palmte_spi_info[0].irq = gpio_to_irq(PALMTE_PINTDAV_GPIO); spi_register_board_info(palmte_spi_info, ARRAY_SIZE(palmte_spi_info)); palmte_misc_gpio_setup(); omap_serial_init(); diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c index b63350bc88fd..8d854878547b 100644 --- a/arch/arm/mach-omap1/board-palmtt.c +++ b/arch/arm/mach-omap1/board-palmtt.c @@ -25,8 +25,9 @@ #include <linux/mtd/physmap.h> #include <linux/leds.h> #include <linux/omapfb.h> +#include <linux/spi/spi.h> +#include <linux/spi/ads7846.h> -#include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -40,10 +41,10 @@ #include <plat/board.h> #include <plat/irda.h> #include <plat/keypad.h> -#include "common.h" -#include <linux/spi/spi.h> -#include <linux/spi/ads7846.h> +#include <mach/hardware.h> + +#include "common.h" #define PALMTT_USBDETECT_GPIO 0 #define PALMTT_CABLE_GPIO 1 @@ -256,7 +257,6 @@ static struct spi_board_info __initdata palmtt_boardinfo[] = { /* MicroWire (bus 2) CS0 has an ads7846e */ .modalias = "ads7846", .platform_data = &palmtt_ts_info, - .irq = OMAP_GPIO_IRQ(6), .max_speed_hz = 120000 /* max sample rate at 3V */ * 26 /* command + data + overhead */, .bus_num = 2, @@ -297,6 +297,7 @@ static void __init omap_palmtt_init(void) platform_add_devices(palmtt_devices, ARRAY_SIZE(palmtt_devices)); + palmtt_boardinfo[0].irq = gpio_to_irq(6); spi_register_board_info(palmtt_boardinfo,ARRAY_SIZE(palmtt_boardinfo)); omap_serial_init(); omap1_usb_init(&palmtt_usb_config); diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c index 9924c70af09f..a2c5abcd7c84 100644 --- a/arch/arm/mach-omap1/board-palmz71.c +++ b/arch/arm/mach-omap1/board-palmz71.c @@ -28,8 +28,9 @@ #include <linux/mtd/partitions.h> #include <linux/mtd/physmap.h> #include <linux/omapfb.h> +#include <linux/spi/spi.h> +#include <linux/spi/ads7846.h> -#include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -42,10 +43,10 @@ #include <plat/board.h> #include <plat/irda.h> #include <plat/keypad.h> -#include "common.h" -#include <linux/spi/spi.h> -#include <linux/spi/ads7846.h> +#include <mach/hardware.h> + +#include "common.h" #define PALMZ71_USBDETECT_GPIO 0 #define PALMZ71_PENIRQ_GPIO 6 @@ -223,7 +224,6 @@ static struct spi_board_info __initdata palmz71_boardinfo[] = { { /* MicroWire (bus 2) CS0 has an ads7846e */ .modalias = "ads7846", .platform_data = &palmz71_ts_info, - .irq = OMAP_GPIO_IRQ(PALMZ71_PENIRQ_GPIO), .max_speed_hz = 120000 /* max sample rate at 3V */ * 26 /* command + data + overhead */, .bus_num = 2, @@ -312,6 +312,7 @@ omap_palmz71_init(void) platform_add_devices(devices, ARRAY_SIZE(devices)); + palmz71_boardinfo[0].irq = gpio_to_irq(PALMZ71_PENIRQ_GPIO); spi_register_board_info(palmz71_boardinfo, ARRAY_SIZE(palmz71_boardinfo)); omap1_usb_init(&palmz71_usb_config); diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c index 8e0153447c6d..76d4ee05a814 100644 --- a/arch/arm/mach-omap1/board-perseus2.c +++ b/arch/arm/mach-omap1/board-perseus2.c @@ -23,7 +23,6 @@ #include <linux/smc91x.h> #include <linux/omapfb.h> -#include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -33,9 +32,13 @@ #include <plat/fpga.h> #include <plat/flash.h> #include <plat/keypad.h> -#include "common.h" #include <plat/board.h> +#include <mach/hardware.h> + +#include "iomap.h" +#include "common.h" + static const unsigned int p2_keymap[] = { KEY(0, 0, KEY_UP), KEY(1, 0, KEY_RIGHT), diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c index 0c76e12337d9..f34cb74a9f41 100644 --- a/arch/arm/mach-omap1/board-sx1.c +++ b/arch/arm/mach-omap1/board-sx1.c @@ -29,7 +29,6 @@ #include <linux/export.h> #include <linux/omapfb.h> -#include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -41,10 +40,13 @@ #include <plat/usb.h> #include <plat/tc.h> #include <plat/board.h> -#include "common.h" #include <plat/keypad.h> #include <plat/board-sx1.h> +#include <mach/hardware.h> + +#include "common.h" + /* Write to I2C device */ int sx1_i2c_write_byte(u8 devaddr, u8 regoffset, u8 value) { diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c index f83a502dc93c..37232d04233f 100644 --- a/arch/arm/mach-omap1/board-voiceblue.c +++ b/arch/arm/mach-omap1/board-voiceblue.c @@ -27,22 +27,23 @@ #include <linux/smc91x.h> #include <linux/export.h> -#include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <plat/board-voiceblue.h> -#include "common.h" #include <plat/flash.h> #include <plat/mux.h> #include <plat/tc.h> #include <plat/usb.h> +#include <mach/hardware.h> + +#include "common.h" + static struct plat_serial8250_port voiceblue_ports[] = { { .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x40000), - .irq = OMAP_GPIO_IRQ(12), .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, .iotype = UPIO_MEM, .regshift = 1, @@ -50,7 +51,6 @@ static struct plat_serial8250_port voiceblue_ports[] = { }, { .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x50000), - .irq = OMAP_GPIO_IRQ(13), .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, .iotype = UPIO_MEM, .regshift = 1, @@ -58,7 +58,6 @@ static struct plat_serial8250_port voiceblue_ports[] = { }, { .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x60000), - .irq = OMAP_GPIO_IRQ(14), .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, .iotype = UPIO_MEM, .regshift = 1, @@ -66,7 +65,6 @@ static struct plat_serial8250_port voiceblue_ports[] = { }, { .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x70000), - .irq = OMAP_GPIO_IRQ(15), .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, .iotype = UPIO_MEM, .regshift = 1, @@ -78,9 +76,6 @@ static struct plat_serial8250_port voiceblue_ports[] = { static struct platform_device serial_device = { .name = "serial8250", .id = PLAT8250_DEV_PLATFORM1, - .dev = { - .platform_data = voiceblue_ports, - }, }; static int __init ext_uart_init(void) @@ -88,6 +83,11 @@ static int __init ext_uart_init(void) if (!machine_is_voiceblue()) return -ENODEV; + voiceblue_ports[0].irq = gpio_to_irq(12); + voiceblue_ports[1].irq = gpio_to_irq(13); + voiceblue_ports[2].irq = gpio_to_irq(14); + voiceblue_ports[3].irq = gpio_to_irq(15); + serial_device.dev.platform_data = voiceblue_ports; return platform_device_register(&serial_device); } arch_initcall(ext_uart_init); @@ -126,8 +126,6 @@ static struct resource voiceblue_smc91x_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = OMAP_GPIO_IRQ(8), - .end = OMAP_GPIO_IRQ(8), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, }, }; @@ -273,6 +271,8 @@ static void __init voiceblue_init(void) irq_set_irq_type(gpio_to_irq(14), IRQ_TYPE_EDGE_RISING); irq_set_irq_type(gpio_to_irq(15), IRQ_TYPE_EDGE_RISING); + voiceblue_smc91x_resources[1].start = gpio_to_irq(8); + voiceblue_smc91x_resources[1].end = gpio_to_irq(8); platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices)); omap_board_config = voiceblue_config; omap_board_config_size = ARRAY_SIZE(voiceblue_config); diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index 0c50df05d135..67382ddd8c83 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -15,8 +15,8 @@ #include <linux/list.h> #include <linux/errno.h> #include <linux/err.h> -#include <linux/clk.h> #include <linux/io.h> +#include <linux/clk.h> #include <linux/clkdev.h> #include <asm/mach-types.h> @@ -27,6 +27,9 @@ #include <plat/sram.h> #include <plat/clkdev_omap.h> +#include <mach/hardware.h> + +#include "iomap.h" #include "clock.h" #include "opp.h" diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c index 94699a82a734..c6ce93f71d08 100644 --- a/arch/arm/mach-omap1/clock_data.c +++ b/arch/arm/mach-omap1/clock_data.c @@ -15,10 +15,10 @@ */ #include <linux/kernel.h> +#include <linux/io.h> #include <linux/clk.h> #include <linux/cpufreq.h> #include <linux/delay.h> -#include <linux/io.h> #include <asm/mach-types.h> /* for machine_is_* */ @@ -28,6 +28,9 @@ #include <plat/sram.h> /* for omap_sram_reprogram_clock() */ #include <plat/usb.h> /* for OTG_BASE */ +#include <mach/hardware.h> + +#include "iomap.h" #include "clock.h" /* Some ARM_IDLECT1 bit shifts - used in struct arm_idlect1_clk */ diff --git a/arch/arm/mach-omap1/common.h b/arch/arm/mach-omap1/common.h index a9a5146dd2d4..af658ad338ec 100644 --- a/arch/arm/mach-omap1/common.h +++ b/arch/arm/mach-omap1/common.h @@ -58,5 +58,6 @@ void omap1_restart(char, const char *); extern struct sys_timer omap1_timer; extern bool omap_32k_timer_init(void); +extern void __init omap_init_consistent_dma_size(void); #endif /* __ARCH_ARM_MACH_OMAP1_COMMON_H */ diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c index 187b2fe132e9..dcd8ddbec2bb 100644 --- a/arch/arm/mach-omap1/devices.c +++ b/arch/arm/mach-omap1/devices.c @@ -15,20 +15,20 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/platform_device.h> -#include <linux/io.h> #include <linux/spi/spi.h> -#include <mach/camera.h> -#include <mach/hardware.h> #include <asm/mach/map.h> -#include "common.h" #include <plat/tc.h> #include <plat/board.h> #include <plat/mux.h> #include <plat/mmc.h> #include <plat/omap7xx.h> +#include <mach/camera.h> +#include <mach/hardware.h> + +#include "common.h" #include "clock.h" /*-------------------------------------------------------------------------*/ diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c index f5a52204b89f..3ef7d52316b4 100644 --- a/arch/arm/mach-omap1/dma.c +++ b/arch/arm/mach-omap1/dma.c @@ -19,11 +19,11 @@ */ #include <linux/err.h> -#include <linux/io.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/init.h> #include <linux/device.h> +#include <linux/io.h> #include <plat/dma.h> #include <plat/tc.h> diff --git a/arch/arm/mach-omap1/flash.c b/arch/arm/mach-omap1/flash.c index 1749cb37dda0..401eb3c080c2 100644 --- a/arch/arm/mach-omap1/flash.c +++ b/arch/arm/mach-omap1/flash.c @@ -6,29 +6,23 @@ * published by the Free Software Foundation. */ +#include <linux/io.h> #include <linux/mtd/mtd.h> #include <linux/mtd/map.h> -#include <plat/io.h> #include <plat/tc.h> #include <plat/flash.h> +#include <mach/hardware.h> + void omap1_set_vpp(struct platform_device *pdev, int enable) { - static int count; u32 l; - if (enable) { - if (count++ == 0) { - l = omap_readl(EMIFS_CONFIG); - l |= OMAP_EMIFS_CONFIG_WP; - omap_writel(l, EMIFS_CONFIG); - } - } else { - if (count && (--count == 0)) { - l = omap_readl(EMIFS_CONFIG); - l &= ~OMAP_EMIFS_CONFIG_WP; - omap_writel(l, EMIFS_CONFIG); - } - } + l = omap_readl(EMIFS_CONFIG); + if (enable) + l |= OMAP_EMIFS_CONFIG_WP; + else + l &= ~OMAP_EMIFS_CONFIG_WP; + omap_writel(l, EMIFS_CONFIG); } diff --git a/arch/arm/mach-omap1/fpga.c b/arch/arm/mach-omap1/fpga.c index 0a17a1a7e00d..76c67b3f9f61 100644 --- a/arch/arm/mach-omap1/fpga.c +++ b/arch/arm/mach-omap1/fpga.c @@ -24,12 +24,15 @@ #include <linux/errno.h> #include <linux/io.h> -#include <mach/hardware.h> #include <asm/irq.h> #include <asm/mach/irq.h> #include <plat/fpga.h> +#include <mach/hardware.h> + +#include "iomap.h" + static void fpga_mask_irq(struct irq_data *d) { unsigned int irq = d->irq - OMAP_FPGA_IRQ_BASE; diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c index 399da4ce017b..634903ef8292 100644 --- a/arch/arm/mach-omap1/gpio15xx.c +++ b/arch/arm/mach-omap1/gpio15xx.c @@ -42,11 +42,12 @@ static struct omap_gpio_reg_offs omap15xx_mpuio_regs = { .irqstatus = OMAP_MPUIO_GPIO_INT, .irqenable = OMAP_MPUIO_GPIO_MASKIT, .irqenable_inv = true, + .irqctrl = OMAP_MPUIO_GPIO_INT_EDGE, }; static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = { .virtual_irq_start = IH_MPUIO_BASE, - .bank_type = METHOD_MPUIO, + .is_mpuio = true, .bank_width = 16, .bank_stride = 1, .regs = &omap15xx_mpuio_regs, @@ -83,11 +84,12 @@ static struct omap_gpio_reg_offs omap15xx_gpio_regs = { .irqstatus = OMAP1510_GPIO_INT_STATUS, .irqenable = OMAP1510_GPIO_INT_MASK, .irqenable_inv = true, + .irqctrl = OMAP1510_GPIO_INT_CONTROL, + .pinctrl = OMAP1510_GPIO_PIN_CONTROL, }; static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = { .virtual_irq_start = IH_GPIO_BASE, - .bank_type = METHOD_GPIO_1510, .bank_width = 16, .regs = &omap15xx_gpio_regs, }; @@ -115,7 +117,6 @@ static int __init omap15xx_gpio_init(void) platform_device_register(&omap15xx_mpu_gpio); platform_device_register(&omap15xx_gpio); - gpio_bank_count = 2; return 0; } postcore_initcall(omap15xx_gpio_init); diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c index 0f399bd0e70e..1fb3b9ad496e 100644 --- a/arch/arm/mach-omap1/gpio16xx.c +++ b/arch/arm/mach-omap1/gpio16xx.c @@ -24,6 +24,9 @@ #define OMAP1610_GPIO4_BASE 0xfffbbc00 #define OMAP1_MPUIO_VBASE OMAP1_MPUIO_BASE +/* smart idle, enable wakeup */ +#define SYSCONFIG_WORD 0x14 + /* mpu gpio */ static struct __initdata resource omap16xx_mpu_gpio_resources[] = { { @@ -45,11 +48,12 @@ static struct omap_gpio_reg_offs omap16xx_mpuio_regs = { .irqstatus = OMAP_MPUIO_GPIO_INT, .irqenable = OMAP_MPUIO_GPIO_MASKIT, .irqenable_inv = true, + .irqctrl = OMAP_MPUIO_GPIO_INT_EDGE, }; static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = { .virtual_irq_start = IH_MPUIO_BASE, - .bank_type = METHOD_MPUIO, + .is_mpuio = true, .bank_width = 16, .bank_stride = 1, .regs = &omap16xx_mpuio_regs, @@ -89,11 +93,13 @@ static struct omap_gpio_reg_offs omap16xx_gpio_regs = { .irqenable = OMAP1610_GPIO_IRQENABLE1, .set_irqenable = OMAP1610_GPIO_SET_IRQENABLE1, .clr_irqenable = OMAP1610_GPIO_CLEAR_IRQENABLE1, + .wkup_en = OMAP1610_GPIO_WAKEUPENABLE, + .edgectrl1 = OMAP1610_GPIO_EDGE_CTRL1, + .edgectrl2 = OMAP1610_GPIO_EDGE_CTRL2, }; static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = { .virtual_irq_start = IH_GPIO_BASE, - .bank_type = METHOD_GPIO_1610, .bank_width = 16, .regs = &omap16xx_gpio_regs, }; @@ -123,7 +129,6 @@ static struct __initdata resource omap16xx_gpio2_resources[] = { static struct __initdata omap_gpio_platform_data omap16xx_gpio2_config = { .virtual_irq_start = IH_GPIO_BASE + 16, - .bank_type = METHOD_GPIO_1610, .bank_width = 16, .regs = &omap16xx_gpio_regs, }; @@ -153,7 +158,6 @@ static struct __initdata resource omap16xx_gpio3_resources[] = { static struct __initdata omap_gpio_platform_data omap16xx_gpio3_config = { .virtual_irq_start = IH_GPIO_BASE + 32, - .bank_type = METHOD_GPIO_1610, .bank_width = 16, .regs = &omap16xx_gpio_regs, }; @@ -183,7 +187,6 @@ static struct __initdata resource omap16xx_gpio4_resources[] = { static struct __initdata omap_gpio_platform_data omap16xx_gpio4_config = { .virtual_irq_start = IH_GPIO_BASE + 48, - .bank_type = METHOD_GPIO_1610, .bank_width = 16, .regs = &omap16xx_gpio_regs, }; @@ -214,14 +217,42 @@ static struct __initdata platform_device * omap16xx_gpio_dev[] = { static int __init omap16xx_gpio_init(void) { int i; + void __iomem *base; + struct resource *res; + struct platform_device *pdev; + struct omap_gpio_platform_data *pdata; if (!cpu_is_omap16xx()) return -EINVAL; - for (i = 0; i < ARRAY_SIZE(omap16xx_gpio_dev); i++) - platform_device_register(omap16xx_gpio_dev[i]); + /* + * Enable system clock for GPIO module. + * The CAM_CLK_CTRL *is* really the right place. + */ + omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, + ULPD_CAM_CLK_CTRL); + + for (i = 0; i < ARRAY_SIZE(omap16xx_gpio_dev); i++) { + pdev = omap16xx_gpio_dev[i]; + pdata = pdev->dev.platform_data; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (unlikely(!res)) { + dev_err(&pdev->dev, "Invalid mem resource.\n"); + return -ENODEV; + } - gpio_bank_count = ARRAY_SIZE(omap16xx_gpio_dev); + base = ioremap(res->start, resource_size(res)); + if (unlikely(!base)) { + dev_err(&pdev->dev, "ioremap failed.\n"); + return -ENOMEM; + } + + __raw_writel(SYSCONFIG_WORD, base + OMAP1610_GPIO_SYSCONFIG); + iounmap(base); + + platform_device_register(omap16xx_gpio_dev[i]); + } return 0; } diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c index 5ab63eab0ff5..4771d6b68b96 100644 --- a/arch/arm/mach-omap1/gpio7xx.c +++ b/arch/arm/mach-omap1/gpio7xx.c @@ -47,12 +47,13 @@ static struct omap_gpio_reg_offs omap7xx_mpuio_regs = { .irqstatus = OMAP_MPUIO_GPIO_INT / 2, .irqenable = OMAP_MPUIO_GPIO_MASKIT / 2, .irqenable_inv = true, + .irqctrl = OMAP_MPUIO_GPIO_INT_EDGE >> 1, }; static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = { .virtual_irq_start = IH_MPUIO_BASE, - .bank_type = METHOD_MPUIO, - .bank_width = 32, + .is_mpuio = true, + .bank_width = 16, .bank_stride = 2, .regs = &omap7xx_mpuio_regs, }; @@ -88,11 +89,11 @@ static struct omap_gpio_reg_offs omap7xx_gpio_regs = { .irqstatus = OMAP7XX_GPIO_INT_STATUS, .irqenable = OMAP7XX_GPIO_INT_MASK, .irqenable_inv = true, + .irqctrl = OMAP7XX_GPIO_INT_CONTROL, }; static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = { .virtual_irq_start = IH_GPIO_BASE, - .bank_type = METHOD_GPIO_7XX, .bank_width = 32, .regs = &omap7xx_gpio_regs, }; @@ -122,7 +123,6 @@ static struct __initdata resource omap7xx_gpio2_resources[] = { static struct __initdata omap_gpio_platform_data omap7xx_gpio2_config = { .virtual_irq_start = IH_GPIO_BASE + 32, - .bank_type = METHOD_GPIO_7XX, .bank_width = 32, .regs = &omap7xx_gpio_regs, }; @@ -152,7 +152,6 @@ static struct __initdata resource omap7xx_gpio3_resources[] = { static struct __initdata omap_gpio_platform_data omap7xx_gpio3_config = { .virtual_irq_start = IH_GPIO_BASE + 64, - .bank_type = METHOD_GPIO_7XX, .bank_width = 32, .regs = &omap7xx_gpio_regs, }; @@ -182,7 +181,6 @@ static struct __initdata resource omap7xx_gpio4_resources[] = { static struct __initdata omap_gpio_platform_data omap7xx_gpio4_config = { .virtual_irq_start = IH_GPIO_BASE + 96, - .bank_type = METHOD_GPIO_7XX, .bank_width = 32, .regs = &omap7xx_gpio_regs, }; @@ -212,7 +210,6 @@ static struct __initdata resource omap7xx_gpio5_resources[] = { static struct __initdata omap_gpio_platform_data omap7xx_gpio5_config = { .virtual_irq_start = IH_GPIO_BASE + 128, - .bank_type = METHOD_GPIO_7XX, .bank_width = 32, .regs = &omap7xx_gpio_regs, }; @@ -242,7 +239,6 @@ static struct __initdata resource omap7xx_gpio6_resources[] = { static struct __initdata omap_gpio_platform_data omap7xx_gpio6_config = { .virtual_irq_start = IH_GPIO_BASE + 160, - .bank_type = METHOD_GPIO_7XX, .bank_width = 32, .regs = &omap7xx_gpio_regs, }; @@ -282,8 +278,6 @@ static int __init omap7xx_gpio_init(void) for (i = 0; i < ARRAY_SIZE(omap7xx_gpio_dev); i++) platform_device_register(omap7xx_gpio_dev[i]); - gpio_bank_count = ARRAY_SIZE(omap7xx_gpio_dev); - return 0; } postcore_initcall(omap7xx_gpio_init); diff --git a/arch/arm/mach-omap1/id.c b/arch/arm/mach-omap1/id.c index a0e3560b39db..2b28e1da14b0 100644 --- a/arch/arm/mach-omap1/id.c +++ b/arch/arm/mach-omap1/id.c @@ -15,8 +15,12 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/io.h> +#include <asm/system_info.h> + #include <plat/cpu.h> +#include <mach/hardware.h> + #define OMAP_DIE_ID_0 0xfffe1800 #define OMAP_DIE_ID_1 0xfffe1804 #define OMAP_PRODUCTION_ID_0 0xfffe2000 diff --git a/arch/arm/mach-omap1/include/mach/entry-macro.S b/arch/arm/mach-omap1/include/mach/entry-macro.S index bfb4fb1d7382..88f08cab1717 100644 --- a/arch/arm/mach-omap1/include/mach/entry-macro.S +++ b/arch/arm/mach-omap1/include/mach/entry-macro.S @@ -9,20 +9,15 @@ * License version 2. This program is licensed "as is" without any * warranty of any kind, whether express or implied. */ + #include <mach/hardware.h> -#include <mach/io.h> #include <mach/irqs.h> -#include <asm/hardware/gic.h> - .macro disable_fiq - .endm +#include "../../iomap.h" .macro get_irqnr_preamble, base, tmp .endm - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \base, =OMAP1_IO_ADDRESS(OMAP_IH1_BASE) ldr \irqnr, [\base, #IRQ_ITR_REG_OFFSET] diff --git a/arch/arm/mach-omap1/include/mach/hardware.h b/arch/arm/mach-omap1/include/mach/hardware.h index a3f6287b2007..01e35fa106b8 100644 --- a/arch/arm/mach-omap1/include/mach/hardware.h +++ b/arch/arm/mach-omap1/include/mach/hardware.h @@ -2,4 +2,40 @@ * arch/arm/mach-omap1/include/mach/hardware.h */ +#ifndef __MACH_HARDWARE_H +#define __MACH_HARDWARE_H + +#ifndef __ASSEMBLER__ +/* + * NOTE: Please use ioremap + __raw_read/write where possible instead of these + */ +extern u8 omap_readb(u32 pa); +extern u16 omap_readw(u32 pa); +extern u32 omap_readl(u32 pa); +extern void omap_writeb(u8 v, u32 pa); +extern void omap_writew(u16 v, u32 pa); +extern void omap_writel(u32 v, u32 pa); + +#include <plat/tc.h> + +/* Almost all documentation for chip and board memory maps assumes + * BM is clear. Most devel boards have a switch to control booting + * from NOR flash (using external chipselect 3) rather than mask ROM, + * which uses BM to interchange the physical CS0 and CS3 addresses. + */ +static inline u32 omap_cs0m_phys(void) +{ + return (omap_readl(EMIFS_CONFIG) & OMAP_EMIFS_CONFIG_BM) + ? OMAP_CS3_PHYS : 0; +} + +static inline u32 omap_cs3_phys(void) +{ + return (omap_readl(EMIFS_CONFIG) & OMAP_EMIFS_CONFIG_BM) + ? 0 : OMAP_CS3_PHYS; +} + +#endif +#endif + #include <plat/hardware.h> diff --git a/arch/arm/mach-omap1/include/mach/io.h b/arch/arm/mach-omap1/include/mach/io.h index 57bdf74a3e64..ce4f8005b26f 100644 --- a/arch/arm/mach-omap1/include/mach/io.h +++ b/arch/arm/mach-omap1/include/mach/io.h @@ -1,5 +1,45 @@ /* * arch/arm/mach-omap1/include/mach/io.h + * + * IO definitions for TI OMAP processors and boards + * + * Copied from arch/arm/mach-sa1100/include/mach/io.h + * Copyright (C) 1997-1999 Russell King + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Modifications: + * 06-12-1997 RMK Created. + * 07-04-1999 RMK Major cleanup */ -#include <plat/io.h> +#ifndef __ASM_ARM_ARCH_IO_H +#define __ASM_ARM_ARCH_IO_H + +#define IO_SPACE_LIMIT 0xffffffff + +/* + * We don't actually have real ISA nor PCI buses, but there is so many + * drivers out there that might just work if we fake them... + */ +#define __io(a) __typesafe_io(a) + +#endif diff --git a/arch/arm/mach-omap1/include/mach/memory.h b/arch/arm/mach-omap1/include/mach/memory.h index c6337645ba8a..901082def9bd 100644 --- a/arch/arm/mach-omap1/include/mach/memory.h +++ b/arch/arm/mach-omap1/include/mach/memory.h @@ -18,7 +18,8 @@ * Note that the is_lbus_device() test is not very efficient on 1510 * because of the strncmp(). */ -#ifdef CONFIG_ARCH_OMAP15XX +#if defined(CONFIG_ARCH_OMAP15XX) && !defined(__ASSEMBLER__) +#include <plat/cpu.h> /* * OMAP-1510 Local Bus address offset diff --git a/arch/arm/mach-omap1/include/mach/system.h b/arch/arm/mach-omap1/include/mach/system.h deleted file mode 100644 index a6c1b3a16dfc..000000000000 --- a/arch/arm/mach-omap1/include/mach/system.h +++ /dev/null @@ -1,5 +0,0 @@ -/* - * arch/arm/mach-omap1/include/mach/system.h - */ - -#include <plat/system.h> diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c index 8e55b6fb3478..d969a7203d14 100644 --- a/arch/arm/mach-omap1/io.c +++ b/arch/arm/mach-omap1/io.c @@ -15,9 +15,12 @@ #include <asm/tlb.h> #include <asm/mach/map.h> + #include <plat/mux.h> #include <plat/tc.h> +#include "iomap.h" +#include "common.h" #include "clock.h" extern void omap_check_revision(void); @@ -118,7 +121,7 @@ void __init omap16xx_map_io(void) /* * Common low-level hardware init for omap1. */ -void omap1_init_early(void) +void __init omap1_init_early(void) { omap_check_revision(); diff --git a/arch/arm/mach-omap1/iomap.h b/arch/arm/mach-omap1/iomap.h new file mode 100644 index 000000000000..330c4716b028 --- /dev/null +++ b/arch/arm/mach-omap1/iomap.h @@ -0,0 +1,36 @@ +/* + * IO mappings for OMAP1 + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define OMAP1_IO_OFFSET 0x01000000 /* Virtual IO = 0xfefb0000 */ +#define OMAP1_IO_ADDRESS(pa) IOMEM((pa) - OMAP1_IO_OFFSET) + +/* + * ---------------------------------------------------------------------------- + * Omap1 specific IO mapping + * ---------------------------------------------------------------------------- + */ + +#define OMAP1_IO_PHYS 0xFFFB0000 +#define OMAP1_IO_SIZE 0x40000 +#define OMAP1_IO_VIRT (OMAP1_IO_PHYS - OMAP1_IO_OFFSET) diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c index e5b104b7fce6..4448114fab72 100644 --- a/arch/arm/mach-omap1/irq.c +++ b/arch/arm/mach-omap1/irq.c @@ -42,11 +42,13 @@ #include <linux/interrupt.h> #include <linux/io.h> -#include <mach/hardware.h> #include <asm/irq.h> #include <asm/mach/irq.h> + #include <plat/cpu.h> +#include <mach/hardware.h> + #define IRQ_BANK(irq) ((irq) >> 5) #define IRQ_BIT(irq) ((irq) & 0x1f) diff --git a/arch/arm/mach-omap1/lcd_dma.c b/arch/arm/mach-omap1/lcd_dma.c index 4c5ce7d829c2..86ace9aaa663 100644 --- a/arch/arm/mach-omap1/lcd_dma.c +++ b/arch/arm/mach-omap1/lcd_dma.c @@ -27,9 +27,10 @@ #include <linux/interrupt.h> #include <linux/io.h> +#include <plat/dma.h> + #include <mach/hardware.h> #include <mach/lcdc.h> -#include <plat/dma.h> int omap_lcd_dma_running(void) { diff --git a/arch/arm/mach-omap1/leds-h2p2-debug.c b/arch/arm/mach-omap1/leds-h2p2-debug.c index 4b818eb9f911..f6b14a14a957 100644 --- a/arch/arm/mach-omap1/leds-h2p2-debug.c +++ b/arch/arm/mach-omap1/leds-h2p2-debug.c @@ -17,7 +17,6 @@ #include <mach/hardware.h> #include <asm/leds.h> -#include <asm/system.h> #include <asm/mach-types.h> #include <plat/fpga.h> diff --git a/arch/arm/mach-omap1/leds-innovator.c b/arch/arm/mach-omap1/leds-innovator.c index 9b99c2894623..3a066ee8d02c 100644 --- a/arch/arm/mach-omap1/leds-innovator.c +++ b/arch/arm/mach-omap1/leds-innovator.c @@ -5,7 +5,6 @@ #include <mach/hardware.h> #include <asm/leds.h> -#include <asm/system.h> #include "leds.h" diff --git a/arch/arm/mach-omap1/leds-osk.c b/arch/arm/mach-omap1/leds-osk.c index da09f4364979..936ed426b84f 100644 --- a/arch/arm/mach-omap1/leds-osk.c +++ b/arch/arm/mach-omap1/leds-osk.c @@ -8,7 +8,6 @@ #include <mach/hardware.h> #include <asm/leds.h> -#include <asm/system.h> #include "leds.h" diff --git a/arch/arm/mach-omap1/mcbsp.c b/arch/arm/mach-omap1/mcbsp.c index 3e8410a99990..adf00975b9bb 100644 --- a/arch/arm/mach-omap1/mcbsp.c +++ b/arch/arm/mach-omap1/mcbsp.c @@ -19,12 +19,15 @@ #include <linux/platform_device.h> #include <linux/slab.h> -#include <mach/irqs.h> #include <plat/dma.h> #include <plat/mux.h> #include <plat/cpu.h> #include <plat/mcbsp.h> +#include <mach/irqs.h> + +#include "iomap.h" + #define DPS_RSTCT2_PER_EN (1 << 0) #define DSP_RSTCT2_WD_PER_EN (1 << 1) diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c index 5fdef7a34828..087dba0df47e 100644 --- a/arch/arm/mach-omap1/mux.c +++ b/arch/arm/mach-omap1/mux.c @@ -27,7 +27,6 @@ #include <linux/io.h> #include <linux/spinlock.h> -#include <asm/system.h> #include <plat/mux.h> diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c index 89ea20ca0ccc..f66c32912b22 100644 --- a/arch/arm/mach-omap1/pm.c +++ b/arch/arm/mach-omap1/pm.c @@ -42,14 +42,14 @@ #include <linux/sysfs.h> #include <linux/module.h> #include <linux/io.h> +#include <linux/atomic.h> +#include <asm/system_misc.h> #include <asm/irq.h> -#include <linux/atomic.h> #include <asm/mach/time.h> #include <asm/mach/irq.h> #include <plat/cpu.h> -#include <mach/irqs.h> #include <plat/clock.h> #include <plat/sram.h> #include <plat/tc.h> @@ -57,6 +57,9 @@ #include <plat/dma.h> #include <plat/dmtimer.h> +#include <mach/irqs.h> + +#include "iomap.h" #include "pm.h" static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE]; @@ -108,13 +111,7 @@ void omap1_pm_idle(void) __u32 use_idlect1 = arm_idlect1_mask; int do_sleep = 0; - local_irq_disable(); local_fiq_disable(); - if (need_resched()) { - local_fiq_enable(); - local_irq_enable(); - return; - } #if defined(CONFIG_OMAP_MPU_TIMER) && !defined(CONFIG_OMAP_DM_TIMER) #warning Enable 32kHz OS timer in order to allow sleep states in idle @@ -157,14 +154,12 @@ void omap1_pm_idle(void) omap_writel(saved_idlect1, ARM_IDLECT1); local_fiq_enable(); - local_irq_enable(); return; } omap_sram_suspend(omap_readl(ARM_IDLECT1), omap_readl(ARM_IDLECT2)); local_fiq_enable(); - local_irq_enable(); } /* @@ -583,8 +578,6 @@ static void omap_pm_init_proc(void) #endif /* DEBUG && CONFIG_PROC_FS */ -static void (*saved_idle)(void) = NULL; - /* * omap_pm_prepare - Do preliminary suspend work. * @@ -592,8 +585,7 @@ static void (*saved_idle)(void) = NULL; static int omap_pm_prepare(void) { /* We cannot sleep in idle until we have resumed */ - saved_idle = pm_idle; - pm_idle = NULL; + disable_hlt(); return 0; } @@ -630,7 +622,7 @@ static int omap_pm_enter(suspend_state_t state) static void omap_pm_finish(void) { - pm_idle = saved_idle; + enable_hlt(); } @@ -687,7 +679,7 @@ static int __init omap_pm_init(void) return -ENODEV; } - pm_idle = omap1_pm_idle; + arm_pm_idle = omap1_pm_idle; if (cpu_is_omap7xx()) setup_irq(INT_7XX_WAKE_UP_REQ, &omap_wakeup_irq); diff --git a/arch/arm/mach-omap1/reset.c b/arch/arm/mach-omap1/reset.c index 91d199b64979..f255b153b863 100644 --- a/arch/arm/mach-omap1/reset.c +++ b/arch/arm/mach-omap1/reset.c @@ -4,9 +4,10 @@ #include <linux/kernel.h> #include <linux/io.h> -#include <mach/hardware.h> #include <plat/prcm.h> +#include <mach/hardware.h> + void omap1_restart(char mode, const char *cmd) { /* diff --git a/arch/arm/mach-omap1/sleep.S b/arch/arm/mach-omap1/sleep.S index c875bdc902c5..0e628743bd03 100644 --- a/arch/arm/mach-omap1/sleep.S +++ b/arch/arm/mach-omap1/sleep.S @@ -33,8 +33,10 @@ */ #include <linux/linkage.h> + #include <asm/assembler.h> -#include <mach/io.h> + +#include "iomap.h" #include "pm.h" .text diff --git a/arch/arm/mach-omap1/sram.S b/arch/arm/mach-omap1/sram.S index 692587d07ea5..00e9d9e9adf1 100644 --- a/arch/arm/mach-omap1/sram.S +++ b/arch/arm/mach-omap1/sram.S @@ -9,10 +9,13 @@ */ #include <linux/linkage.h> + #include <asm/assembler.h> -#include <mach/io.h> + #include <mach/hardware.h> +#include "iomap.h" + .text /* diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c index b8faffa44f9e..4d8dd9a1b04c 100644 --- a/arch/arm/mach-omap1/time.c +++ b/arch/arm/mach-omap1/time.c @@ -44,15 +44,15 @@ #include <linux/clockchips.h> #include <linux/io.h> -#include <asm/system.h> -#include <mach/hardware.h> #include <asm/leds.h> #include <asm/irq.h> #include <asm/sched_clock.h> +#include <mach/hardware.h> #include <asm/mach/irq.h> #include <asm/mach/time.h> +#include "iomap.h" #include "common.h" #ifdef CONFIG_OMAP_MPU_TIMER diff --git a/arch/arm/mach-omap1/timer32k.c b/arch/arm/mach-omap1/timer32k.c index 9a54ef4dcf5e..325b9a0aa4a0 100644 --- a/arch/arm/mach-omap1/timer32k.c +++ b/arch/arm/mach-omap1/timer32k.c @@ -46,15 +46,17 @@ #include <linux/clockchips.h> #include <linux/io.h> -#include <asm/system.h> -#include <mach/hardware.h> #include <asm/leds.h> #include <asm/irq.h> #include <asm/mach/irq.h> #include <asm/mach/time.h> -#include "common.h" + #include <plat/dmtimer.h> +#include <mach/hardware.h> + +#include "common.h" + /* * --------------------------------------------------------------------------- * 32KHz OS timer diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index e20c8ab80b0e..8141b76283a6 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -32,7 +32,7 @@ config ARCH_OMAP3 depends on ARCH_OMAP2PLUS default y select CPU_V7 - select USB_ARCH_HAS_EHCI + select USB_ARCH_HAS_EHCI if USB_SUPPORT select ARCH_HAS_OPP select PM_OPP if PM select ARM_CPU_SUSPEND if PM @@ -52,7 +52,7 @@ config ARCH_OMAP4 select ARM_ERRATA_720789 select ARCH_HAS_OPP select PM_OPP if PM - select USB_ARCH_HAS_EHCI + select USB_ARCH_HAS_EHCI if USB_SUPPORT select ARM_CPU_SUSPEND if PM comment "OMAP Core Type" @@ -117,7 +117,6 @@ comment "OMAP Board Type" config MACH_OMAP_GENERIC bool "Generic OMAP2+ board" depends on ARCH_OMAP2PLUS - select USE_OF default y help Support for generic TI OMAP2+ boards using Flattened Device Tree. @@ -245,10 +244,11 @@ config MACH_NOKIA_N8X0 select MACH_NOKIA_N810_WIMAX config MACH_NOKIA_RM680 - bool "Nokia RM-680 board" + bool "Nokia RM-680/696 board" depends on ARCH_OMAP3 default y select OMAP_PACKAGE_CBB + select MACH_NOKIA_RM696 config MACH_NOKIA_RX51 bool "Nokia RX-51 board" diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 06326a6e460d..49f92bc1c311 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -4,7 +4,7 @@ # Common support obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer.o pm.o \ - common.o gpio.o dma.o wd_timer.o display.o + common.o gpio.o dma.o wd_timer.o display.o i2c.o omap-2-3-common = irq.o sdrc.o hwmod-common = omap_hwmod.o \ @@ -25,7 +25,6 @@ obj-$(CONFIG_TWL4030_CORE) += omap_twl.o # SMP support ONLY available for OMAP4 obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o -obj-$(CONFIG_LOCAL_TIMERS) += timer-mpu.o obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o obj-$(CONFIG_ARCH_OMAP4) += omap4-common.o omap-wakeupgen.o \ sleep44xx.o @@ -184,9 +183,6 @@ obj-$(CONFIG_OMAP_IOMMU) += iommu2.o iommu-$(CONFIG_OMAP_IOMMU) := omap-iommu.o obj-y += $(iommu-m) $(iommu-y) -i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o -obj-y += $(i2c-omap-m) $(i2c-omap-y) - ifneq ($(CONFIG_TIDSPBRIDGE),) obj-y += dsp.o endif @@ -270,6 +266,11 @@ obj-y += $(smc91x-m) $(smc91x-y) smsc911x-$(CONFIG_SMSC911X) := gpmc-smsc911x.o obj-y += $(smsc911x-m) $(smsc911x-y) -obj-$(CONFIG_ARCH_OMAP4) += hwspinlock.o +ifneq ($(CONFIG_HWSPINLOCK_OMAP),) +obj-y += hwspinlock.o +endif + +emac-$(CONFIG_TI_DAVINCI_EMAC) := am35xx-emac.o +obj-y += $(emac-m) $(emac-y) obj-y += common-board-devices.o twl-common.o diff --git a/arch/arm/mach-omap2/am35xx-emac.c b/arch/arm/mach-omap2/am35xx-emac.c new file mode 100644 index 000000000000..1f97e7475206 --- /dev/null +++ b/arch/arm/mach-omap2/am35xx-emac.c @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2011 Ilya Yanok, Emcraft Systems + * + * Based on mach-omap2/board-am3517evm.c + * Copyright (C) 2009 Texas Instruments Incorporated + * Author: Ranjith Lohithakshan <ranjithl@ti.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 + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, + * whether express or implied; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include <linux/clk.h> +#include <linux/davinci_emac.h> +#include <linux/platform_device.h> +#include <plat/irqs.h> +#include <mach/am35xx.h> + +#include "control.h" + +static struct mdio_platform_data am35xx_emac_mdio_pdata; + +static struct resource am35xx_emac_mdio_resources[] = { + DEFINE_RES_MEM(AM35XX_IPSS_EMAC_BASE + AM35XX_EMAC_MDIO_OFFSET, SZ_4K), +}; + +static struct platform_device am35xx_emac_mdio_device = { + .name = "davinci_mdio", + .id = 0, + .num_resources = ARRAY_SIZE(am35xx_emac_mdio_resources), + .resource = am35xx_emac_mdio_resources, + .dev.platform_data = &am35xx_emac_mdio_pdata, +}; + +static void am35xx_enable_emac_int(void) +{ + u32 regval; + + regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); + regval = (regval | AM35XX_CPGMAC_C0_RX_PULSE_CLR | + AM35XX_CPGMAC_C0_TX_PULSE_CLR | + AM35XX_CPGMAC_C0_MISC_PULSE_CLR | + AM35XX_CPGMAC_C0_RX_THRESH_CLR); + omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR); + regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); +} + +static void am35xx_disable_emac_int(void) +{ + u32 regval; + + regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); + regval = (regval | AM35XX_CPGMAC_C0_RX_PULSE_CLR | + AM35XX_CPGMAC_C0_TX_PULSE_CLR); + omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR); + regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); +} + +static struct emac_platform_data am35xx_emac_pdata = { + .ctrl_reg_offset = AM35XX_EMAC_CNTRL_OFFSET, + .ctrl_mod_reg_offset = AM35XX_EMAC_CNTRL_MOD_OFFSET, + .ctrl_ram_offset = AM35XX_EMAC_CNTRL_RAM_OFFSET, + .ctrl_ram_size = AM35XX_EMAC_CNTRL_RAM_SIZE, + .hw_ram_addr = AM35XX_EMAC_HW_RAM_ADDR, + .version = EMAC_VERSION_2, + .interrupt_enable = am35xx_enable_emac_int, + .interrupt_disable = am35xx_disable_emac_int, +}; + +static struct resource am35xx_emac_resources[] = { + DEFINE_RES_MEM(AM35XX_IPSS_EMAC_BASE, 0x30000), + DEFINE_RES_IRQ(INT_35XX_EMAC_C0_RXTHRESH_IRQ), + DEFINE_RES_IRQ(INT_35XX_EMAC_C0_RX_PULSE_IRQ), + DEFINE_RES_IRQ(INT_35XX_EMAC_C0_TX_PULSE_IRQ), + DEFINE_RES_IRQ(INT_35XX_EMAC_C0_MISC_PULSE_IRQ), +}; + +static struct platform_device am35xx_emac_device = { + .name = "davinci_emac", + .id = -1, + .num_resources = ARRAY_SIZE(am35xx_emac_resources), + .resource = am35xx_emac_resources, + .dev = { + .platform_data = &am35xx_emac_pdata, + }, +}; + +void __init am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en) +{ + unsigned int regval; + int err; + + am35xx_emac_pdata.rmii_en = rmii_en; + am35xx_emac_mdio_pdata.bus_freq = mdio_bus_freq; + err = platform_device_register(&am35xx_emac_device); + if (err) { + pr_err("AM35x: failed registering EMAC device: %d\n", err); + return; + } + + err = platform_device_register(&am35xx_emac_mdio_device); + if (err) { + pr_err("AM35x: failed registering EMAC MDIO device: %d\n", err); + platform_device_unregister(&am35xx_emac_device); + return; + } + + regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); + regval = regval & (~(AM35XX_CPGMACSS_SW_RST)); + omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET); + regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); +} diff --git a/arch/arm/mach-omap2/am35xx-emac.h b/arch/arm/mach-omap2/am35xx-emac.h new file mode 100644 index 000000000000..15c6f9ce59a2 --- /dev/null +++ b/arch/arm/mach-omap2/am35xx-emac.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2011 Ilya Yanok, Emcraft Systems + * + * 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. + */ + +#define AM35XX_DEFAULT_MDIO_FREQUENCY 1000000 + +#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE) +void am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en); +#else +static inline void am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en) {} +#endif diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index 7370983f809f..e658f835d0de 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -230,12 +230,12 @@ static struct i2c_board_info __initdata sdp2430_i2c1_boardinfo[] = { { I2C_BOARD_INFO("isp1301_omap", 0x2D), .flags = I2C_CLIENT_WAKE, - .irq = OMAP_GPIO_IRQ(78), }, }; static int __init omap2430_i2c_init(void) { + sdp2430_i2c1_boardinfo[0].irq = gpio_to_irq(78); omap_register_i2c_bus(1, 100, sdp2430_i2c1_boardinfo, ARRAY_SIZE(sdp2430_i2c1_boardinfo)); omap_pmic_init(2, 100, "twl4030", INT_24XX_SYS_NIRQ, @@ -279,7 +279,7 @@ static void __init omap_2430sdp_init(void) platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices)); omap_serial_init(); omap_sdrc_init(NULL, NULL); - omap2_hsmmc_init(mmc); + omap_hsmmc_init(mmc); omap2_usbfs_init(&sdp2430_usb_config); omap_mux_init_signal("usb0hs_stp", OMAP_PULL_ENA | OMAP_PULL_UP); diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index 383717ba63b9..da75f239873e 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -232,11 +232,13 @@ static struct omap2_hsmmc_info mmc[] = { */ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, .gpio_wp = 4, + .deferred = true, }, { .mmc = 2, .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, .gpio_wp = 7, + .deferred = true, }, {} /* Terminator */ }; @@ -249,7 +251,7 @@ static int sdp3430_twl_gpio_setup(struct device *dev, */ mmc[0].gpio_cd = gpio + 0; mmc[1].gpio_cd = gpio + 1; - omap2_hsmmc_init(mmc); + omap_hsmmc_late_init(mmc); /* gpio + 7 is "sub_lcd_en_bkl" (output/PWM1) */ gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "sub_lcd_en_bkl"); @@ -606,6 +608,7 @@ static void __init omap_3430sdp_init(void) omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); omap_board_config = sdp3430_config; omap_board_config_size = ARRAY_SIZE(sdp3430_config); + omap_hsmmc_init(mmc); omap3430_i2c_init(); omap_display_init(&sdp3430_dss_data); if (omap_rev() > OMAP3430_REV_ES1_0) diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 44cf1893829a..a39fc4bbd2b8 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -324,7 +324,10 @@ static struct spi_board_info sdp4430_spi_board_info[] __initdata = { .bus_num = 1, .chip_select = 0, .max_speed_hz = 24000000, - .irq = ETH_KS8851_IRQ, + /* + * .irq is set to gpio_to_irq(ETH_KS8851_IRQ) + * in omap_4430sdp_init + */ }, }; @@ -487,21 +490,22 @@ static struct platform_device omap_vwlan_device = { static int omap4_twl6030_hsmmc_late_init(struct device *dev) { - int ret = 0; + int irq = 0; struct platform_device *pdev = container_of(dev, struct platform_device, dev); struct omap_mmc_platform_data *pdata = dev->platform_data; /* Setting MMC1 Card detect Irq */ if (pdev->id == 0) { - ret = twl6030_mmc_card_detect_config(); - if (ret) + irq = twl6030_mmc_card_detect_config(); + if (irq < 0) { pr_err("Failed configuring MMC1 card detect\n"); - pdata->slots[0].card_detect_irq = TWL6030_IRQ_BASE + - MMCDETECT_INTR_OFFSET; + return irq; + } + pdata->slots[0].card_detect_irq = irq; pdata->slots[0].card_detect = twl6030_mmc_card_detect; } - return ret; + return 0; } static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev) @@ -521,9 +525,9 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers) { struct omap2_hsmmc_info *c; - omap2_hsmmc_init(controllers); + omap_hsmmc_init(controllers); for (c = controllers; c->mmc; c++) - omap4_twl6030_hsmmc_set_late_init(c->dev); + omap4_twl6030_hsmmc_set_late_init(&c->pdev->dev); return 0; } @@ -903,7 +907,6 @@ static void __init omap4_sdp4430_wifi_mux_init(void) } static struct wl12xx_platform_data omap4_sdp4430_wlan_data __initdata = { - .irq = OMAP_GPIO_IRQ(GPIO_WIFI_IRQ), .board_ref_clock = WL12XX_REFCLOCK_26, .board_tcxo_clock = WL12XX_TCXOCLOCK_26, }; @@ -913,6 +916,7 @@ static void __init omap4_sdp4430_wifi_init(void) int ret; omap4_sdp4430_wifi_mux_init(); + omap4_sdp4430_wlan_data.irq = gpio_to_irq(GPIO_WIFI_IRQ); ret = wl12xx_set_platform_data(&omap4_sdp4430_wlan_data); if (ret) pr_err("Error setting wl12xx data: %d\n", ret); diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 4b1cfe32e6ba..3645285a3e2b 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -39,124 +39,11 @@ #include <video/omap-panel-generic-dpi.h> #include <video/omap-panel-dvi.h> +#include "am35xx-emac.h" #include "mux.h" #include "control.h" #include "hsmmc.h" -#define AM35XX_EVM_MDIO_FREQUENCY (1000000) - -static struct mdio_platform_data am3517_evm_mdio_pdata = { - .bus_freq = AM35XX_EVM_MDIO_FREQUENCY, -}; - -static struct resource am3517_mdio_resources[] = { - { - .start = AM35XX_IPSS_EMAC_BASE + AM35XX_EMAC_MDIO_OFFSET, - .end = AM35XX_IPSS_EMAC_BASE + AM35XX_EMAC_MDIO_OFFSET + - SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device am3517_mdio_device = { - .name = "davinci_mdio", - .id = 0, - .num_resources = ARRAY_SIZE(am3517_mdio_resources), - .resource = am3517_mdio_resources, - .dev.platform_data = &am3517_evm_mdio_pdata, -}; - -static struct emac_platform_data am3517_evm_emac_pdata = { - .rmii_en = 1, -}; - -static struct resource am3517_emac_resources[] = { - { - .start = AM35XX_IPSS_EMAC_BASE, - .end = AM35XX_IPSS_EMAC_BASE + 0x2FFFF, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_35XX_EMAC_C0_RXTHRESH_IRQ, - .end = INT_35XX_EMAC_C0_RXTHRESH_IRQ, - .flags = IORESOURCE_IRQ, - }, - { - .start = INT_35XX_EMAC_C0_RX_PULSE_IRQ, - .end = INT_35XX_EMAC_C0_RX_PULSE_IRQ, - .flags = IORESOURCE_IRQ, - }, - { - .start = INT_35XX_EMAC_C0_TX_PULSE_IRQ, - .end = INT_35XX_EMAC_C0_TX_PULSE_IRQ, - .flags = IORESOURCE_IRQ, - }, - { - .start = INT_35XX_EMAC_C0_MISC_PULSE_IRQ, - .end = INT_35XX_EMAC_C0_MISC_PULSE_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device am3517_emac_device = { - .name = "davinci_emac", - .id = -1, - .num_resources = ARRAY_SIZE(am3517_emac_resources), - .resource = am3517_emac_resources, -}; - -static void am3517_enable_ethernet_int(void) -{ - u32 regval; - - regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); - regval = (regval | AM35XX_CPGMAC_C0_RX_PULSE_CLR | - AM35XX_CPGMAC_C0_TX_PULSE_CLR | - AM35XX_CPGMAC_C0_MISC_PULSE_CLR | - AM35XX_CPGMAC_C0_RX_THRESH_CLR); - omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR); - regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); -} - -static void am3517_disable_ethernet_int(void) -{ - u32 regval; - - regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); - regval = (regval | AM35XX_CPGMAC_C0_RX_PULSE_CLR | - AM35XX_CPGMAC_C0_TX_PULSE_CLR); - omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR); - regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); -} - -static void am3517_evm_ethernet_init(struct emac_platform_data *pdata) -{ - unsigned int regval; - - pdata->ctrl_reg_offset = AM35XX_EMAC_CNTRL_OFFSET; - pdata->ctrl_mod_reg_offset = AM35XX_EMAC_CNTRL_MOD_OFFSET; - pdata->ctrl_ram_offset = AM35XX_EMAC_CNTRL_RAM_OFFSET; - pdata->ctrl_ram_size = AM35XX_EMAC_CNTRL_RAM_SIZE; - pdata->version = EMAC_VERSION_2; - pdata->hw_ram_addr = AM35XX_EMAC_HW_RAM_ADDR; - pdata->interrupt_enable = am3517_enable_ethernet_int; - pdata->interrupt_disable = am3517_disable_ethernet_int; - am3517_emac_device.dev.platform_data = pdata; - platform_device_register(&am3517_emac_device); - platform_device_register(&am3517_mdio_device); - clk_add_alias(NULL, dev_name(&am3517_mdio_device.dev), - NULL, &am3517_emac_device.dev); - - regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); - regval = regval & (~(AM35XX_CPGMACSS_SW_RST)); - omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET); - regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); - - return ; -} - - - #define LCD_PANEL_PWR 176 #define LCD_PANEL_BKLIGHT_PWR 182 #define LCD_PANEL_PWM 181 @@ -498,13 +385,13 @@ static void __init am3517_evm_init(void) i2c_register_board_info(1, am3517evm_i2c1_boardinfo, ARRAY_SIZE(am3517evm_i2c1_boardinfo)); /*Ethernet*/ - am3517_evm_ethernet_init(&am3517_evm_emac_pdata); + am35xx_emac_init(AM35XX_DEFAULT_MDIO_FREQUENCY, 1); /* MUSB */ am3517_evm_musb_init(); /* MMC init function */ - omap2_hsmmc_init(mmc); + omap_hsmmc_init(mmc); } MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM") diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c index ac773829941f..768ece2e9c3b 100644 --- a/arch/arm/mach-omap2/board-apollon.c +++ b/arch/arm/mach-omap2/board-apollon.c @@ -136,8 +136,6 @@ static struct resource apollon_smc91x_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ), - .end = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, }, }; @@ -341,6 +339,8 @@ static void __init omap_apollon_init(void) * You have to mux them off in device drivers later on * if not needed. */ + apollon_smc91x_resources[1].start = gpio_to_irq(APOLLON_ETHR_GPIO_IRQ); + apollon_smc91x_resources[1].end = gpio_to_irq(APOLLON_ETHR_GPIO_IRQ); platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices)); omap_serial_init(); omap_sdrc_init(NULL, NULL); diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index d73316ed4207..909a8b91b564 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -26,6 +26,7 @@ #include <linux/i2c/at24.h> #include <linux/i2c/twl.h> +#include <linux/regulator/fixed.h> #include <linux/regulator/machine.h> #include <linux/mmc/host.h> @@ -81,8 +82,23 @@ static struct omap_smsc911x_platform_data sb_t35_smsc911x_cfg = { .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS, }; +static struct regulator_consumer_supply cm_t35_smsc911x_supplies[] = { + REGULATOR_SUPPLY("vddvario", "smsc911x.0"), + REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), +}; + +static struct regulator_consumer_supply sb_t35_smsc911x_supplies[] = { + REGULATOR_SUPPLY("vddvario", "smsc911x.1"), + REGULATOR_SUPPLY("vdd33a", "smsc911x.1"), +}; + static void __init cm_t35_init_ethernet(void) { + regulator_register_fixed(0, cm_t35_smsc911x_supplies, + ARRAY_SIZE(cm_t35_smsc911x_supplies)); + regulator_register_fixed(1, sb_t35_smsc911x_supplies, + ARRAY_SIZE(sb_t35_smsc911x_supplies)); + gpmc_smsc911x_init(&cm_t35_smsc911x_cfg); gpmc_smsc911x_init(&sb_t35_smsc911x_cfg); } @@ -280,7 +296,6 @@ static struct omap_dss_board_info cm_t35_dss_data = { static struct omap2_mcspi_device_config tdo24m_mcspi_config = { .turbo_mode = 0, - .single_channel = 1, /* 0: slave, 1: master */ }; static struct tdo24m_platform_data tdo24m_config = { @@ -413,7 +428,7 @@ static struct omap2_hsmmc_info mmc[] = { .caps = MMC_CAP_4_BIT_DATA, .gpio_cd = -EINVAL, .gpio_wp = -EINVAL, - + .deferred = true, }, { .mmc = 2, @@ -471,7 +486,7 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio, /* gpio + 0 is "mmc0_cd" (input/IRQ) */ mmc[0].gpio_cd = gpio + 0; - omap2_hsmmc_init(mmc); + omap_hsmmc_late_init(mmc); return 0; } @@ -639,6 +654,7 @@ static void __init cm_t3x_common_init(void) omap_serial_init(); omap_sdrc_init(mt46h32m32lf6_sdrc_params, mt46h32m32lf6_sdrc_params); + omap_hsmmc_init(mmc); cm_t35_init_i2c(); omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL); cm_t35_init_ethernet(); diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c index f36d694d2159..9e66e167e4f3 100644 --- a/arch/arm/mach-omap2/board-cm-t3517.c +++ b/arch/arm/mach-omap2/board-cm-t3517.c @@ -49,6 +49,7 @@ #include "mux.h" #include "control.h" #include "common-board-devices.h" +#include "am35xx-emac.h" #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) static struct gpio_led cm_t3517_leds[] = { @@ -291,6 +292,7 @@ static void __init cm_t3517_init(void) cm_t3517_init_rtc(); cm_t3517_init_usbh(); cm_t3517_init_hecc(); + am35xx_emac_init(AM35XX_DEFAULT_MDIO_FREQUENCY, 1); } MACHINE_START(CM_T3517, "Compulab CM-T3517") diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c index e873063f4fda..a2010f07de31 100644 --- a/arch/arm/mach-omap2/board-devkit8000.c +++ b/arch/arm/mach-omap2/board-devkit8000.c @@ -100,6 +100,7 @@ static struct omap2_hsmmc_info mmc[] = { .mmc = 1, .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, .gpio_wp = 29, + .deferred = true, }, {} /* Terminator */ }; @@ -228,7 +229,7 @@ static int devkit8000_twl_gpio_setup(struct device *dev, /* gpio + 0 is "mmc0_cd" (input/IRQ) */ mmc[0].gpio_cd = gpio + 0; - omap2_hsmmc_init(mmc); + omap_hsmmc_late_init(mmc); /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; @@ -410,7 +411,6 @@ static struct resource omap_dm9000_resources[] = { .flags = IORESOURCE_MEM, }, [2] = { - .start = OMAP_GPIO_IRQ(OMAP_DM9000_GPIO_IRQ), .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW, }, }; @@ -636,7 +636,9 @@ static void __init devkit8000_init(void) omap_dm9000_init(); + omap_hsmmc_init(mmc); devkit8000_i2c_init(); + omap_dm9000_resources[2].start = gpio_to_irq(OMAP_DM9000_GPIO_IRQ); platform_add_devices(devkit8000_devices, ARRAY_SIZE(devkit8000_devices)); diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index 30a6f527510c..0349fd2b68d8 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -189,7 +189,7 @@ unmap: * * @return - void. */ -void board_flash_init(struct flash_partitions partition_info[], +void __init board_flash_init(struct flash_partitions partition_info[], char chip_sel_board[][GPMC_CS_NUM], int nand_type) { u8 cs = 0; diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 45fdfe2bd9d5..74e1687b5170 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -12,6 +12,7 @@ * published by the Free Software Foundation. */ #include <linux/io.h> +#include <linux/of_irq.h> #include <linux/of_platform.h> #include <linux/irqdomain.h> #include <linux/i2c/twl.h> @@ -24,33 +25,23 @@ #include "common.h" #include "common-board-devices.h" -/* - * XXX: Still needed to boot until the i2c & twl driver is adapted to - * device-tree - */ -#ifdef CONFIG_ARCH_OMAP4 -static struct twl4030_platform_data sdp4430_twldata = { - .irq_base = TWL6030_IRQ_BASE, - .irq_end = TWL6030_IRQ_END, -}; - -static void __init omap4_i2c_init(void) -{ - omap4_pmic_init("twl6030", &sdp4430_twldata); -} +#if !(defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)) +#define omap_intc_of_init NULL +#endif +#ifndef CONFIG_ARCH_OMAP4 +#define gic_of_init NULL #endif -#ifdef CONFIG_ARCH_OMAP3 -static struct twl4030_platform_data beagle_twldata = { - .irq_base = TWL4030_IRQ_BASE, - .irq_end = TWL4030_IRQ_END, +static struct of_device_id irq_match[] __initdata = { + { .compatible = "ti,omap2-intc", .data = omap_intc_of_init, }, + { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, }, + { } }; -static void __init omap3_i2c_init(void) +static void __init omap_init_irq(void) { - omap3_pmic_init("twl4030", &beagle_twldata); + of_irq_init(irq_match); } -#endif static struct of_device_id omap_dt_match_table[] __initdata = { { .compatible = "simple-bus", }, @@ -58,51 +49,24 @@ static struct of_device_id omap_dt_match_table[] __initdata = { { } }; -static struct of_device_id intc_match[] __initdata = { - { .compatible = "ti,omap3-intc", }, - { .compatible = "arm,cortex-a9-gic", }, - { } -}; - static void __init omap_generic_init(void) { - struct device_node *node = of_find_matching_node(NULL, intc_match); - if (node) - irq_domain_add_legacy(node, 32, 0, 0, &irq_domain_simple_ops, NULL); - omap_sdrc_init(NULL, NULL); of_platform_populate(NULL, omap_dt_match_table, NULL, NULL); } -#ifdef CONFIG_ARCH_OMAP4 -static void __init omap4_init(void) -{ - omap4_i2c_init(); - omap_generic_init(); -} -#endif - -#ifdef CONFIG_ARCH_OMAP3 -static void __init omap3_init(void) -{ - omap3_i2c_init(); - omap_generic_init(); -} -#endif - -#if defined(CONFIG_SOC_OMAP2420) +#ifdef CONFIG_SOC_OMAP2420 static const char *omap242x_boards_compat[] __initdata = { "ti,omap2420", NULL, }; DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)") - .atag_offset = 0x100, .reserve = omap_reserve, .map_io = omap242x_map_io, .init_early = omap2420_init_early, - .init_irq = omap2_init_irq, + .init_irq = omap_init_irq, .handle_irq = omap2_intc_handle_irq, .init_machine = omap_generic_init, .timer = &omap2_timer, @@ -111,18 +75,17 @@ DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)") MACHINE_END #endif -#if defined(CONFIG_SOC_OMAP2430) +#ifdef CONFIG_SOC_OMAP2430 static const char *omap243x_boards_compat[] __initdata = { "ti,omap2430", NULL, }; DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)") - .atag_offset = 0x100, .reserve = omap_reserve, .map_io = omap243x_map_io, .init_early = omap2430_init_early, - .init_irq = omap2_init_irq, + .init_irq = omap_init_irq, .handle_irq = omap2_intc_handle_irq, .init_machine = omap_generic_init, .timer = &omap2_timer, @@ -131,18 +94,33 @@ DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)") MACHINE_END #endif -#if defined(CONFIG_ARCH_OMAP3) +#ifdef CONFIG_ARCH_OMAP3 +static struct twl4030_platform_data beagle_twldata = { + .irq_base = TWL4030_IRQ_BASE, + .irq_end = TWL4030_IRQ_END, +}; + +static void __init omap3_i2c_init(void) +{ + omap3_pmic_init("twl4030", &beagle_twldata); +} + +static void __init omap3_init(void) +{ + omap3_i2c_init(); + omap_generic_init(); +} + static const char *omap3_boards_compat[] __initdata = { "ti,omap3", NULL, }; DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)") - .atag_offset = 0x100, .reserve = omap_reserve, .map_io = omap3_map_io, .init_early = omap3430_init_early, - .init_irq = omap3_init_irq, + .init_irq = omap_init_irq, .handle_irq = omap3_intc_handle_irq, .init_machine = omap3_init, .timer = &omap3_timer, @@ -151,18 +129,33 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)") MACHINE_END #endif -#if defined(CONFIG_ARCH_OMAP4) +#ifdef CONFIG_ARCH_OMAP4 +static struct twl4030_platform_data sdp4430_twldata = { + .irq_base = TWL6030_IRQ_BASE, + .irq_end = TWL6030_IRQ_END, +}; + +static void __init omap4_i2c_init(void) +{ + omap4_pmic_init("twl6030", &sdp4430_twldata); +} + +static void __init omap4_init(void) +{ + omap4_i2c_init(); + omap_generic_init(); +} + static const char *omap4_boards_compat[] __initdata = { "ti,omap4", NULL, }; DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)") - .atag_offset = 0x100, .reserve = omap_reserve, .map_io = omap4_map_io, .init_early = omap4430_init_early, - .init_irq = gic_init_irq, + .init_irq = omap_init_irq, .handle_irq = gic_handle_irq, .init_machine = omap4_init, .timer = &omap4_timer, diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index 54af800d143c..0bbbabe28fcc 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c @@ -348,7 +348,6 @@ static struct at24_platform_data m24c01 = { static struct i2c_board_info __initdata h4_i2c_board_info[] = { { I2C_BOARD_INFO("isp1301_omap", 0x2d), - .irq = OMAP_GPIO_IRQ(125), }, { /* EEPROM on mainboard */ I2C_BOARD_INFO("24c01", 0x52), @@ -377,6 +376,7 @@ static void __init omap_h4_init(void) */ board_mkp_init(); + h4_i2c_board_info[0].irq = gpio_to_irq(125); i2c_register_board_info(1, h4_i2c_board_info, ARRAY_SIZE(h4_i2c_board_info)); diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index a59ace0ed560..930c0d380435 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c @@ -295,6 +295,7 @@ static struct omap2_hsmmc_info mmc[] = { .caps = MMC_CAP_4_BIT_DATA, .gpio_cd = -EINVAL, .gpio_wp = -EINVAL, + .deferred = true, }, #if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE) { @@ -402,7 +403,7 @@ static int igep_twl_gpio_setup(struct device *dev, /* gpio + 0 is "mmc0_cd" (input/IRQ) */ mmc[0].gpio_cd = gpio + 0; - omap2_hsmmc_init(mmc); + omap_hsmmc_late_init(mmc); /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */ #if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE) @@ -633,12 +634,21 @@ static void __init igep_wlan_bt_init(void) static inline void __init igep_wlan_bt_init(void) { } #endif +static struct regulator_consumer_supply dummy_supplies[] = { + REGULATOR_SUPPLY("vddvario", "smsc911x.0"), + REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), +}; + static void __init igep_init(void) { + regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); /* Get IGEP2 hardware revision */ igep2_get_revision(); + + omap_hsmmc_init(mmc); + /* Register I2C busses and drivers */ igep_i2c_init(); platform_add_devices(igep_devices, ARRAY_SIZE(igep_devices)); diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c index 2d2a61f7dcbf..1b6049567ab4 100644 --- a/arch/arm/mach-omap2/board-ldp.c +++ b/arch/arm/mach-omap2/board-ldp.c @@ -22,12 +22,12 @@ #include <linux/err.h> #include <linux/clk.h> #include <linux/spi/spi.h> +#include <linux/regulator/fixed.h> #include <linux/regulator/machine.h> #include <linux/i2c/twl.h> #include <linux/io.h> #include <linux/smsc911x.h> #include <linux/mmc/host.h> -#include <linux/gpio.h> #include <mach/hardware.h> #include <asm/mach-types.h> @@ -411,8 +411,14 @@ static struct mtd_partition ldp_nand_partitions[] = { }; +static struct regulator_consumer_supply dummy_supplies[] = { + REGULATOR_SUPPLY("vddvario", "smsc911x.0"), + REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), +}; + static void __init omap_ldp_init(void) { + regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); ldp_init_smsc911x(); omap_i2c_init(); @@ -424,7 +430,7 @@ static void __init omap_ldp_init(void) board_nand_init(ldp_nand_partitions, ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS, 0); - omap2_hsmmc_init(mmc); + omap_hsmmc_init(mmc); ldp_display_init(); } diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index 672262717601..518091c5f77c 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -36,10 +36,6 @@ #include "mux.h" -static int slot1_cover_open; -static int slot2_cover_open; -static struct device *mmc_device; - #define TUSB6010_ASYNC_CS 1 #define TUSB6010_SYNC_CS 4 #define TUSB6010_GPIO_INT 58 @@ -137,7 +133,6 @@ static void __init n8x0_usb_init(void) {} static struct omap2_mcspi_device_config p54spi_mcspi_config = { .turbo_mode = 0, - .single_channel = 1, }; static struct spi_board_info n800_spi_board_info[] __initdata = { @@ -211,6 +206,10 @@ static struct omap_onenand_platform_data board_onenand_data[] = { #define N810_EMMC_VSD_GPIO 23 #define N810_EMMC_VIO_GPIO 9 +static int slot1_cover_open; +static int slot2_cover_open; +static struct device *mmc_device; + static int n8x0_mmc_switch_slot(struct device *dev, int slot) { #ifdef CONFIG_MMC_DEBUG diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 7ffcd2839e7b..7be8d659d91d 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -253,6 +253,7 @@ static struct omap2_hsmmc_info mmc[] = { .mmc = 1, .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, .gpio_wp = -EINVAL, + .deferred = true, }, {} /* Terminator */ }; @@ -272,12 +273,10 @@ static int beagle_twl_gpio_setup(struct device *dev, { int r; - if (beagle_config.mmc1_gpio_wp != -EINVAL) - omap_mux_init_gpio(beagle_config.mmc1_gpio_wp, OMAP_PIN_INPUT); mmc[0].gpio_wp = beagle_config.mmc1_gpio_wp; /* gpio + 0 is "mmc0_cd" (input/IRQ) */ mmc[0].gpio_cd = gpio + 0; - omap2_hsmmc_init(mmc); + omap_hsmmc_late_init(mmc); /* * TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, XM active @@ -521,6 +520,11 @@ static void __init omap3_beagle_init(void) { omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); omap3_beagle_init_rev(); + + if (beagle_config.mmc1_gpio_wp != -EINVAL) + omap_mux_init_gpio(beagle_config.mmc1_gpio_wp, OMAP_PIN_INPUT); + omap_hsmmc_init(mmc); + omap3_beagle_i2c_init(); gpio_buttons[0].gpio = beagle_config.usr_button_gpio; diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index c877236a8442..49df12735b41 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c @@ -114,15 +114,6 @@ static struct omap_smsc911x_platform_data smsc911x_cfg = { static inline void __init omap3evm_init_smsc911x(void) { - struct clk *l3ck; - unsigned int rate; - - l3ck = clk_get(NULL, "l3_ck"); - if (IS_ERR(l3ck)) - rate = 100000000; - else - rate = clk_get_rate(l3ck); - /* Configure ethernet controller reset gpio */ if (cpu_is_omap3430()) { if (get_omap3_evm_rev() == OMAP3EVM_BOARD_GEN_1) @@ -317,6 +308,7 @@ static struct omap2_hsmmc_info mmc[] = { .caps = MMC_CAP_4_BIT_DATA, .gpio_cd = -EINVAL, .gpio_wp = 63, + .deferred = true, }, #ifdef CONFIG_WL12XX_PLATFORM_DATA { @@ -361,9 +353,8 @@ static int omap3evm_twl_gpio_setup(struct device *dev, int r, lcd_bl_en; /* gpio + 0 is "mmc0_cd" (input/IRQ) */ - omap_mux_init_gpio(63, OMAP_PIN_INPUT); mmc[0].gpio_cd = gpio + 0; - omap2_hsmmc_init(mmc); + omap_hsmmc_late_init(mmc); /* * Most GPIOs are for USB OTG. Some are mostly sent to @@ -487,7 +478,6 @@ static struct platform_device omap3evm_wlan_regulator = { }; struct wl12xx_platform_data omap3evm_wlan_data __initdata = { - .irq = OMAP_GPIO_IRQ(OMAP3EVM_WLAN_IRQ_GPIO), .board_ref_clock = WL12XX_REFCLOCK_38, /* 38.4 MHz */ }; #endif @@ -623,6 +613,7 @@ static void __init omap3_evm_wl12xx_init(void) int ret; /* WL12xx WLAN Init */ + omap3evm_wlan_data.irq = gpio_to_irq(OMAP3EVM_WLAN_IRQ_GPIO); ret = wl12xx_set_platform_data(&omap3evm_wlan_data); if (ret) pr_err("error setting wl12xx data: %d\n", ret); @@ -632,9 +623,15 @@ static void __init omap3_evm_wl12xx_init(void) #endif } +static struct regulator_consumer_supply dummy_supplies[] = { + REGULATOR_SUPPLY("vddvario", "smsc911x.0"), + REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), +}; + static void __init omap3_evm_init(void) { omap3_evm_get_revision(); + regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); if (cpu_is_omap3630()) omap3_mux_init(omap36x_board_mux, OMAP_PACKAGE_CBB); @@ -644,6 +641,9 @@ static void __init omap3_evm_init(void) omap_board_config = omap3_evm_config; omap_board_config_size = ARRAY_SIZE(omap3_evm_config); + omap_mux_init_gpio(63, OMAP_PIN_INPUT); + omap_hsmmc_init(mmc); + omap3_evm_i2c_init(); omap_display_init(&omap3_evm_dss_data); diff --git a/arch/arm/mach-omap2/board-omap3logic.c b/arch/arm/mach-omap2/board-omap3logic.c index 4198dd017d8f..9b3c141ff51b 100644 --- a/arch/arm/mach-omap2/board-omap3logic.c +++ b/arch/arm/mach-omap2/board-omap3logic.c @@ -23,6 +23,7 @@ #include <linux/io.h> #include <linux/gpio.h> +#include <linux/regulator/fixed.h> #include <linux/regulator/machine.h> #include <linux/i2c/twl.h> @@ -128,7 +129,7 @@ static void __init board_mmc_init(void) return; } - omap2_hsmmc_init(board_mmc_info); + omap_hsmmc_init(board_mmc_info); } static struct omap_smsc911x_platform_data __initdata board_smsc911x_data = { @@ -188,8 +189,14 @@ static struct omap_board_mux board_mux[] __initdata = { }; #endif +static struct regulator_consumer_supply dummy_supplies[] = { + REGULATOR_SUPPLY("vddvario", "smsc911x.0"), + REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), +}; + static void __init omap3logic_init(void) { + regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); omap3torpedo_fix_pbias_voltage(); omap3logic_i2c_init(); @@ -205,6 +212,7 @@ static void __init omap3logic_init(void) MACHINE_START(OMAP3_TORPEDO, "Logic OMAP3 Torpedo board") .atag_offset = 0x100, + .reserve = omap_reserve, .map_io = omap3_map_io, .init_early = omap35xx_init_early, .init_irq = omap3_init_irq, @@ -216,6 +224,7 @@ MACHINE_END MACHINE_START(OMAP3530_LV_SOM, "OMAP Logic 3530 LV SOM board") .atag_offset = 0x100, + .reserve = omap_reserve, .map_io = omap3_map_io, .init_early = omap35xx_init_early, .init_irq = omap3_init_irq, diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index 1644b73017fc..33d995d0f075 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c @@ -121,6 +121,11 @@ static struct platform_device pandora_leds_gpio = { }, }; +static struct platform_device pandora_backlight = { + .name = "pandora-backlight", + .id = -1, +}; + #define GPIO_BUTTON(gpio_num, ev_type, ev_code, act_low, descr) \ { \ .gpio = gpio_num, \ @@ -273,6 +278,7 @@ static struct omap2_hsmmc_info omap3pandora_mmc[] = { .gpio_cd = -EINVAL, .gpio_wp = 126, .ext_clock = 0, + .deferred = true, }, { .mmc = 2, @@ -281,6 +287,7 @@ static struct omap2_hsmmc_info omap3pandora_mmc[] = { .gpio_wp = 127, .ext_clock = 1, .transceiver = true, + .deferred = true, }, { .mmc = 3, @@ -300,7 +307,7 @@ static int omap3pandora_twl_gpio_setup(struct device *dev, /* gpio + {0,1} is "mmc{0,1}_cd" (input/IRQ) */ omap3pandora_mmc[0].gpio_cd = gpio + 0; omap3pandora_mmc[1].gpio_cd = gpio + 1; - omap2_hsmmc_init(omap3pandora_mmc); + omap_hsmmc_late_init(omap3pandora_mmc); /* gpio + 13 drives 32kHz buffer for wifi module */ gpio_32khz = gpio + 13; @@ -343,7 +350,7 @@ static struct regulator_consumer_supply pandora_vcc_lcd_supply[] = { }; static struct regulator_consumer_supply pandora_usb_phy_supply[] = { - REGULATOR_SUPPLY("hsusb0", "ehci-omap.0"), + REGULATOR_SUPPLY("hsusb1", "ehci-omap.0"), }; /* ads7846 on SPI and 2 nub controllers on I2C */ @@ -476,6 +483,10 @@ static struct platform_device pandora_vwlan_device = { static struct twl4030_bci_platform_data pandora_bci_data; +static struct twl4030_power_data pandora_power_data = { + .use_poweroff = true, +}; + static struct twl4030_platform_data omap3pandora_twldata = { .gpio = &omap3pandora_gpio_data, .vmmc1 = &pandora_vmmc1, @@ -486,6 +497,7 @@ static struct twl4030_platform_data omap3pandora_twldata = { .vsim = &pandora_vsim, .keypad = &pandora_kp_data, .bci = &pandora_bci_data, + .power = &pandora_power_data, }; static struct i2c_board_info __initdata omap3pandora_i2c3_boardinfo[] = { @@ -557,17 +569,18 @@ static struct platform_device *omap3pandora_devices[] __initdata = { &pandora_leds_gpio, &pandora_keys_gpio, &pandora_vwlan_device, + &pandora_backlight, }; static const struct usbhs_omap_board_data usbhs_bdata __initconst = { - .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, - .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, + .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, + .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, .phy_reset = true, - .reset_gpio_port[0] = 16, - .reset_gpio_port[1] = -EINVAL, + .reset_gpio_port[0] = -EINVAL, + .reset_gpio_port[1] = 16, .reset_gpio_port[2] = -EINVAL }; @@ -580,6 +593,7 @@ static struct omap_board_mux board_mux[] __initdata = { static void __init omap3pandora_init(void) { omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); + omap_hsmmc_init(omap3pandora_mmc); omap3pandora_i2c_init(); pandora_wl1251_init(); platform_add_devices(omap3pandora_devices, diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c index cb089a46f62f..4dffc95bddd2 100644 --- a/arch/arm/mach-omap2/board-omap3stalker.c +++ b/arch/arm/mach-omap2/board-omap3stalker.c @@ -24,6 +24,7 @@ #include <linux/input.h> #include <linux/gpio_keys.h> +#include <linux/regulator/fixed.h> #include <linux/regulator/machine.h> #include <linux/i2c/twl.h> #include <linux/mmc/host.h> @@ -72,15 +73,6 @@ static struct omap_smsc911x_platform_data smsc911x_cfg = { static inline void __init omap3stalker_init_eth(void) { - struct clk *l3ck; - unsigned int rate; - - l3ck = clk_get(NULL, "l3_ck"); - if (IS_ERR(l3ck)) - rate = 100000000; - else - rate = clk_get_rate(l3ck); - omap_mux_init_gpio(19, OMAP_PIN_INPUT_PULLUP); gpmc_smsc911x_init(&smsc911x_cfg); } @@ -209,10 +201,11 @@ static struct regulator_init_data omap3stalker_vsim = { static struct omap2_hsmmc_info mmc[] = { { - .mmc = 1, - .caps = MMC_CAP_4_BIT_DATA, - .gpio_cd = -EINVAL, - .gpio_wp = 23, + .mmc = 1, + .caps = MMC_CAP_4_BIT_DATA, + .gpio_cd = -EINVAL, + .gpio_wp = 23, + .deferred = true, }, {} /* Terminator */ }; @@ -282,9 +275,8 @@ omap3stalker_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio) { /* gpio + 0 is "mmc0_cd" (input/IRQ) */ - omap_mux_init_gpio(23, OMAP_PIN_INPUT); mmc[0].gpio_cd = gpio + 0; - omap2_hsmmc_init(mmc); + omap_hsmmc_late_init(mmc); /* * Most GPIOs are for USB OTG. Some are mostly sent to @@ -419,12 +411,21 @@ static struct omap_board_mux board_mux[] __initdata = { }; #endif +static struct regulator_consumer_supply dummy_supplies[] = { + REGULATOR_SUPPLY("vddvario", "smsc911x.0"), + REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), +}; + static void __init omap3_stalker_init(void) { + regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); omap3_mux_init(board_mux, OMAP_PACKAGE_CUS); omap_board_config = omap3_stalker_config; omap_board_config_size = ARRAY_SIZE(omap3_stalker_config); + omap_mux_init_gpio(23, OMAP_PIN_INPUT); + omap_hsmmc_init(mmc); + omap3_stalker_i2c_init(); platform_add_devices(omap3_stalker_devices, diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c index a0b851aafcca..ae2251fa4a69 100644 --- a/arch/arm/mach-omap2/board-omap3touchbook.c +++ b/arch/arm/mach-omap2/board-omap3touchbook.c @@ -42,6 +42,7 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/flash.h> +#include <asm/system_info.h> #include <plat/board.h> #include "common.h" @@ -100,6 +101,7 @@ static struct omap2_hsmmc_info mmc[] = { .mmc = 1, .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, .gpio_wp = 29, + .deferred = true, }, {} /* Terminator */ }; @@ -117,15 +119,9 @@ static struct gpio_led gpio_leds[]; static int touchbook_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio) { - if (system_rev >= 0x20 && system_rev <= 0x34301000) { - omap_mux_init_gpio(23, OMAP_PIN_INPUT); - mmc[0].gpio_wp = 23; - } else { - omap_mux_init_gpio(29, OMAP_PIN_INPUT); - } /* gpio + 0 is "mmc0_cd" (input/IRQ) */ mmc[0].gpio_cd = gpio + 0; - omap2_hsmmc_init(mmc); + omap_hsmmc_late_init(mmc); /* REVISIT: need ehci-omap hooks for external VBUS * power switch and overcurrent detect @@ -351,6 +347,14 @@ static void __init omap3_touchbook_init(void) pm_power_off = omap3_touchbook_poweroff; + if (system_rev >= 0x20 && system_rev <= 0x34301000) { + omap_mux_init_gpio(23, OMAP_PIN_INPUT); + mmc[0].gpio_wp = 23; + } else { + omap_mux_init_gpio(29, OMAP_PIN_INPUT); + } + omap_hsmmc_init(mmc); + omap3_touchbook_i2c_init(); platform_add_devices(omap3_touchbook_devices, ARRAY_SIZE(omap3_touchbook_devices)); diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index e4415917693f..d8c0e89f0126 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -116,10 +116,16 @@ static struct platform_device panda_abe_audio = { }, }; +static struct platform_device btwilink_device = { + .name = "btwilink", + .id = -1, +}; + static struct platform_device *panda_devices[] __initdata = { &leds_gpio, &wl1271_device, &panda_abe_audio, + &btwilink_device, }; static const struct usbhs_omap_board_data usbhs_bdata __initconst = { @@ -225,14 +231,13 @@ static struct platform_device omap_vwlan_device = { }; struct wl12xx_platform_data omap_panda_wlan_data __initdata = { - .irq = OMAP_GPIO_IRQ(GPIO_WIFI_IRQ), /* PANDA ref clock is 38.4 MHz */ .board_ref_clock = 2, }; static int omap4_twl6030_hsmmc_late_init(struct device *dev) { - int ret = 0; + int irq = 0; struct platform_device *pdev = container_of(dev, struct platform_device, dev); struct omap_mmc_platform_data *pdata = dev->platform_data; @@ -243,14 +248,15 @@ static int omap4_twl6030_hsmmc_late_init(struct device *dev) } /* Setting MMC1 Card detect Irq */ if (pdev->id == 0) { - ret = twl6030_mmc_card_detect_config(); - if (ret) + irq = twl6030_mmc_card_detect_config(); + if (irq < 0) { dev_err(dev, "%s: Error card detect config(%d)\n", - __func__, ret); - else - pdata->slots[0].card_detect = twl6030_mmc_card_detect; + __func__, irq); + return irq; + } + pdata->slots[0].card_detect = twl6030_mmc_card_detect; } - return ret; + return 0; } static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev) @@ -271,9 +277,9 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers) { struct omap2_hsmmc_info *c; - omap2_hsmmc_init(controllers); + omap_hsmmc_init(controllers); for (c = controllers; c->mmc; c++) - omap4_twl6030_hsmmc_set_late_init(c->dev); + omap4_twl6030_hsmmc_set_late_init(&c->pdev->dev); return 0; } @@ -504,7 +510,7 @@ static struct omap_dss_board_info omap4_panda_dss_data = { .default_device = &omap4_panda_dvi_device, }; -void omap4_panda_display_init(void) +void __init omap4_panda_display_init(void) { int r; @@ -551,6 +557,7 @@ static void __init omap4_panda_init(void) package = OMAP_PACKAGE_CBL; omap4_mux_init(board_mux, NULL, package); + omap_panda_wlan_data.irq = gpio_to_irq(GPIO_WIFI_IRQ); ret = wl12xx_set_platform_data(&omap_panda_wlan_data); if (ret) pr_err("error setting wl12xx data: %d\n", ret); diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c index 52c0cef77165..33aa3910b09e 100644 --- a/arch/arm/mach-omap2/board-overo.c +++ b/arch/arm/mach-omap2/board-overo.c @@ -407,8 +407,6 @@ static inline void __init overo_init_keys(void) { return; } static int overo_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio) { - omap2_hsmmc_init(mmc); - #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; @@ -500,11 +498,20 @@ static struct gpio overo_bt_gpios[] __initdata = { { OVERO_GPIO_BT_NRESET, GPIOF_OUT_INIT_HIGH, "lcd bl enable" }, }; +static struct regulator_consumer_supply dummy_supplies[] = { + REGULATOR_SUPPLY("vddvario", "smsc911x.0"), + REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), + REGULATOR_SUPPLY("vddvario", "smsc911x.1"), + REGULATOR_SUPPLY("vdd33a", "smsc911x.1"), +}; + static void __init overo_init(void) { int ret; + regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); + omap_hsmmc_init(mmc); overo_i2c_init(); omap_display_init(&overo_dss_data); omap_serial_init(); diff --git a/arch/arm/mach-omap2/board-rm680.c b/arch/arm/mach-omap2/board-rm680.c index 8678b386c6a2..ae53d71f0ce0 100644 --- a/arch/arm/mach-omap2/board-rm680.c +++ b/arch/arm/mach-omap2/board-rm680.c @@ -1,5 +1,5 @@ /* - * Board support file for Nokia RM-680. + * Board support file for Nokia RM-680/696. * * Copyright (C) 2010 Nokia * @@ -120,7 +120,7 @@ static void __init rm680_peripherals_init(void) ARRAY_SIZE(rm680_peripherals_devices)); rm680_i2c_init(); gpmc_onenand_init(board_onenand_data); - omap2_hsmmc_init(mmc); + omap_hsmmc_init(mmc); } #ifdef CONFIG_OMAP_MUX @@ -154,3 +154,15 @@ MACHINE_START(NOKIA_RM680, "Nokia RM-680 board") .timer = &omap3_timer, .restart = omap_prcm_restart, MACHINE_END + +MACHINE_START(NOKIA_RM696, "Nokia RM-696 board") + .atag_offset = 0x100, + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = omap3630_init_early, + .init_irq = omap3_init_irq, + .handle_irq = omap3_intc_handle_irq, + .init_machine = rm680_init, + .timer = &omap3_timer, + .restart = omap_prcm_restart, +MACHINE_END diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index acb4e77b39ef..d87ee0612098 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -25,6 +25,7 @@ #include <linux/gpio_keys.h> #include <linux/mmc/host.h> #include <linux/power/isp1704_charger.h> +#include <asm/system_info.h> #include <plat/mcspi.h> #include <plat/board.h> @@ -138,17 +139,14 @@ static struct lp5523_platform_data rx51_lp5523_platform_data = { static struct omap2_mcspi_device_config wl1251_mcspi_config = { .turbo_mode = 0, - .single_channel = 1, }; static struct omap2_mcspi_device_config mipid_mcspi_config = { .turbo_mode = 0, - .single_channel = 1, }; static struct omap2_mcspi_device_config tsc2005_mcspi_config = { .turbo_mode = 0, - .single_channel = 1, }; static struct spi_board_info rx51_peripherals_spi_board_info[] __initdata = { @@ -172,7 +170,6 @@ static struct spi_board_info rx51_peripherals_spi_board_info[] __initdata = { .modalias = "tsc2005", .bus_num = 1, .chip_select = 0, - .irq = OMAP_GPIO_IRQ(RX51_TSC2005_IRQ_GPIO), .max_speed_hz = 6000000, .controller_data = &tsc2005_mcspi_config, .platform_data = &tsc2005_pdata, @@ -1105,6 +1102,11 @@ static struct tsc2005_platform_data tsc2005_pdata = { .esd_timeout_ms = 8000, }; +static struct gpio rx51_tsc2005_gpios[] __initdata = { + { RX51_TSC2005_IRQ_GPIO, GPIOF_IN, "tsc2005 IRQ" }, + { RX51_TSC2005_RESET_GPIO, GPIOF_OUT_INIT_HIGH, "tsc2005 reset" }, +}; + static void rx51_tsc2005_set_reset(bool enable) { gpio_set_value(RX51_TSC2005_RESET_GPIO, enable); @@ -1114,20 +1116,20 @@ static void __init rx51_init_tsc2005(void) { int r; - r = gpio_request_one(RX51_TSC2005_IRQ_GPIO, GPIOF_IN, "tsc2005 IRQ"); - if (r < 0) { - printk(KERN_ERR "unable to get %s GPIO\n", "tsc2005 IRQ"); - rx51_peripherals_spi_board_info[RX51_SPI_TSC2005].irq = 0; - } + omap_mux_init_gpio(RX51_TSC2005_RESET_GPIO, OMAP_PIN_OUTPUT); + omap_mux_init_gpio(RX51_TSC2005_IRQ_GPIO, OMAP_PIN_INPUT_PULLUP); - r = gpio_request_one(RX51_TSC2005_RESET_GPIO, GPIOF_OUT_INIT_HIGH, - "tsc2005 reset"); - if (r >= 0) { - tsc2005_pdata.set_reset = rx51_tsc2005_set_reset; - } else { - printk(KERN_ERR "unable to get %s GPIO\n", "tsc2005 reset"); + r = gpio_request_array(rx51_tsc2005_gpios, + ARRAY_SIZE(rx51_tsc2005_gpios)); + if (r < 0) { + printk(KERN_ERR "tsc2005 board initialization failed\n"); tsc2005_pdata.esd_timeout_ms = 0; + return; } + + tsc2005_pdata.set_reset = rx51_tsc2005_set_reset; + rx51_peripherals_spi_board_info[RX51_SPI_TSC2005].irq = + gpio_to_irq(RX51_TSC2005_IRQ_GPIO); } void __init rx51_peripherals_init(void) @@ -1145,7 +1147,7 @@ void __init rx51_peripherals_init(void) partition = omap_mux_get("core"); if (partition) - omap2_hsmmc_init(mmc); + omap_hsmmc_init(mmc); rx51_charger_init(); } diff --git a/arch/arm/mach-omap2/board-zoom-debugboard.c b/arch/arm/mach-omap2/board-zoom-debugboard.c index 369c2eb7715b..f64f44173061 100644 --- a/arch/arm/mach-omap2/board-zoom-debugboard.c +++ b/arch/arm/mach-omap2/board-zoom-debugboard.c @@ -14,6 +14,9 @@ #include <linux/smsc911x.h> #include <linux/interrupt.h> +#include <linux/regulator/fixed.h> +#include <linux/regulator/machine.h> + #include <plat/gpmc.h> #include <plat/gpmc-smsc911x.h> @@ -43,7 +46,6 @@ static inline void __init zoom_init_smsc911x(void) static struct plat_serial8250_port serial_platform_data[] = { { .mapbase = ZOOM_UART_BASE, - .irq = OMAP_GPIO_IRQ(102), .flags = UPF_BOOT_AUTOCONF|UPF_IOREMAP|UPF_SHARE_IRQ, .irqflags = IRQF_SHARED | IRQF_TRIGGER_RISING, .iotype = UPIO_MEM, @@ -89,6 +91,8 @@ static inline void __init zoom_init_quaduart(void) if (gpio_request_one(quart_gpio, GPIOF_IN, "TL16CP754C GPIO") < 0) printk(KERN_ERR "Failed to request GPIO%d for TL16CP754C\n", quart_gpio); + + serial_platform_data[0].irq = gpio_to_irq(102); } static inline int omap_zoom_debugboard_detect(void) @@ -116,11 +120,17 @@ static struct platform_device *zoom_devices[] __initdata = { &zoom_debugboard_serial_device, }; +static struct regulator_consumer_supply dummy_supplies[] = { + REGULATOR_SUPPLY("vddvario", "smsc911x.0"), + REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), +}; + int __init zoom_debugboard_init(void) { if (!omap_zoom_debugboard_detect()) return 0; + regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); zoom_init_smsc911x(); zoom_init_quaduart(); return platform_add_devices(zoom_devices, ARRAY_SIZE(zoom_devices)); diff --git a/arch/arm/mach-omap2/board-zoom-display.c b/arch/arm/mach-omap2/board-zoom-display.c index d4683ba5f721..a43a765dd092 100644 --- a/arch/arm/mach-omap2/board-zoom-display.c +++ b/arch/arm/mach-omap2/board-zoom-display.c @@ -55,6 +55,7 @@ static void zoom_panel_disable_lcd(struct omap_dss_device *dssdev) static int zoom_set_bl_intensity(struct omap_dss_device *dssdev, int level) { +#ifdef CONFIG_TWL4030_CORE unsigned char c; u8 mux_pwm, enb_pwm; @@ -90,6 +91,9 @@ static int zoom_set_bl_intensity(struct omap_dss_device *dssdev, int level) c = ((50 * (100 - level)) / 100) + 1; twl_i2c_write_u8(TWL4030_MODULE_PWM1, 0x7F, TWL_LED_PWMOFF); twl_i2c_write_u8(TWL4030_MODULE_PWM1, c, TWL_LED_PWMON); +#else + pr_warn("Backlight not enabled\n"); +#endif return 0; } @@ -117,7 +121,6 @@ static struct omap_dss_board_info zoom_dss_data = { static struct omap2_mcspi_device_config dss_lcd_mcspi_config = { .turbo_mode = 1, - .single_channel = 1, /* 0: slave, 1: master */ }; static struct spi_board_info nec_8048_spi_board_info[] __initdata = { diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c index c126461836ac..b797cb279618 100644 --- a/arch/arm/mach-omap2/board-zoom-peripherals.c +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c @@ -193,7 +193,6 @@ static struct platform_device omap_vwlan_device = { }; static struct wl12xx_platform_data omap_zoom_wlan_data __initdata = { - .irq = OMAP_GPIO_IRQ(OMAP_ZOOM_WLAN_IRQ_GPIO), /* ZOOM ref clock is 26 MHz */ .board_ref_clock = 1, }; @@ -205,6 +204,7 @@ static struct omap2_hsmmc_info mmc[] = { .caps = MMC_CAP_4_BIT_DATA, .gpio_wp = -EINVAL, .power_saving = true, + .deferred = true, }, { .name = "internal", @@ -233,7 +233,7 @@ static int zoom_twl_gpio_setup(struct device *dev, /* gpio + 0 is "mmc0_cd" (input/IRQ) */ mmc[0].gpio_cd = gpio + 0; - omap2_hsmmc_init(mmc); + omap_hsmmc_late_init(mmc); ret = gpio_request_one(LCD_PANEL_ENABLE_GPIO, GPIOF_OUT_INIT_LOW, "lcd enable"); @@ -296,11 +296,15 @@ static void enable_board_wakeup_source(void) void __init zoom_peripherals_init(void) { - int ret = wl12xx_set_platform_data(&omap_zoom_wlan_data); + int ret; + + omap_zoom_wlan_data.irq = gpio_to_irq(OMAP_ZOOM_WLAN_IRQ_GPIO); + ret = wl12xx_set_platform_data(&omap_zoom_wlan_data); if (ret) pr_err("error setting wl12xx data: %d\n", ret); + omap_hsmmc_init(mmc); omap_i2c_init(); platform_device_register(&omap_vwlan_device); usb_musb_init(NULL); diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c index 39f9d5a58d0c..3d9d746b221a 100644 --- a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c +++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c @@ -33,6 +33,7 @@ #include <linux/cpufreq.h> #include <linux/slab.h> +#include <plat/cpu.h> #include <plat/clock.h> #include <plat/sram.h> #include <plat/sdrc.h> @@ -164,83 +165,3 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate) return 0; } - -#ifdef CONFIG_CPU_FREQ -/* - * Walk PRCM rate table and fillout cpufreq freq_table - * XXX This should be replaced by an OPP layer in the near future - */ -static struct cpufreq_frequency_table *freq_table; - -void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table) -{ - const struct prcm_config *prcm; - int i = 0; - int tbl_sz = 0; - - if (!cpu_is_omap24xx()) - return; - - for (prcm = rate_table; prcm->mpu_speed; prcm++) { - if (!(prcm->flags & cpu_mask)) - continue; - if (prcm->xtal_speed != sclk->rate) - continue; - - /* don't put bypass rates in table */ - if (prcm->dpll_speed == prcm->xtal_speed) - continue; - - tbl_sz++; - } - - /* - * XXX Ensure that we're doing what CPUFreq expects for this error - * case and the following one - */ - if (tbl_sz == 0) { - pr_warning("%s: no matching entries in rate_table\n", - __func__); - return; - } - - /* Include the CPUFREQ_TABLE_END terminator entry */ - tbl_sz++; - - freq_table = kzalloc(sizeof(struct cpufreq_frequency_table) * tbl_sz, - GFP_ATOMIC); - if (!freq_table) { - pr_err("%s: could not kzalloc frequency table\n", __func__); - return; - } - - for (prcm = rate_table; prcm->mpu_speed; prcm++) { - if (!(prcm->flags & cpu_mask)) - continue; - if (prcm->xtal_speed != sclk->rate) - continue; - - /* don't put bypass rates in table */ - if (prcm->dpll_speed == prcm->xtal_speed) - continue; - - freq_table[i].index = i; - freq_table[i].frequency = prcm->mpu_speed / 1000; - i++; - } - - freq_table[i].index = i; - freq_table[i].frequency = CPUFREQ_TABLE_END; - - *table = &freq_table[0]; -} - -void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table) -{ - if (!cpu_is_omap24xx()) - return; - - kfree(freq_table); -} - -#endif diff --git a/arch/arm/mach-omap2/clkt_clksel.c b/arch/arm/mach-omap2/clkt_clksel.c index e25364de028a..04d551b1f7f7 100644 --- a/arch/arm/mach-omap2/clkt_clksel.c +++ b/arch/arm/mach-omap2/clkt_clksel.c @@ -43,6 +43,7 @@ #include <linux/errno.h> #include <linux/clk.h> #include <linux/io.h> +#include <linux/bug.h> #include <plat/clock.h> diff --git a/arch/arm/mach-omap2/clkt_dpll.c b/arch/arm/mach-omap2/clkt_dpll.c index e069a9be93df..cd7fd0f91149 100644 --- a/arch/arm/mach-omap2/clkt_dpll.c +++ b/arch/arm/mach-omap2/clkt_dpll.c @@ -22,6 +22,7 @@ #include <asm/div64.h> #include <plat/clock.h> +#include <plat/cpu.h> #include "clock.h" #include "cm-regbits-24xx.h" diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index f57ed5baeccf..d9f4931513f9 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -536,10 +536,5 @@ struct clk_functions omap2_clk_functions = { .clk_set_rate = omap2_clk_set_rate, .clk_set_parent = omap2_clk_set_parent, .clk_disable_unused = omap2_clk_disable_unused, -#ifdef CONFIG_CPU_FREQ - /* These will be removed when the OPP code is integrated */ - .clk_init_cpufreq_table = omap2_clk_init_cpufreq_table, - .clk_exit_cpufreq_table = omap2_clk_exit_cpufreq_table, -#endif }; diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index b8c2a686481c..a1bb23a23351 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -146,14 +146,6 @@ extern const struct clksel_rate gpt_sys_rates[]; extern const struct clksel_rate gfx_l3_rates[]; extern const struct clksel_rate dsp_ick_rates[]; -#if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_CPU_FREQ) -extern void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table); -extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table); -#else -#define omap2_clk_init_cpufreq_table 0 -#define omap2_clk_exit_cpufreq_table 0 -#endif - extern const struct clkops clkops_omap2_iclk_dflt_wait; extern const struct clkops clkops_omap2_iclk_dflt; extern const struct clkops clkops_omap2_iclk_idle_only; diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c index 61ad3855f10a..bace9308a4db 100644 --- a/arch/arm/mach-omap2/clock2420_data.c +++ b/arch/arm/mach-omap2/clock2420_data.c @@ -14,11 +14,14 @@ */ #include <linux/kernel.h> +#include <linux/io.h> #include <linux/clk.h> #include <linux/list.h> +#include <plat/hardware.h> #include <plat/clkdev_omap.h> +#include "iomap.h" #include "clock.h" #include "clock2xxx.h" #include "opp2xxx.h" diff --git a/arch/arm/mach-omap2/clock2430.c b/arch/arm/mach-omap2/clock2430.c index d87bc9cb2a36..dfda9a3f2cb2 100644 --- a/arch/arm/mach-omap2/clock2430.c +++ b/arch/arm/mach-omap2/clock2430.c @@ -21,8 +21,10 @@ #include <linux/clk.h> #include <linux/io.h> +#include <plat/hardware.h> #include <plat/clock.h> +#include "iomap.h" #include "clock.h" #include "clock2xxx.h" #include "cm2xxx_3xxx.h" diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c index 0cc12879e7b9..3b4d09a50399 100644 --- a/arch/arm/mach-omap2/clock2430_data.c +++ b/arch/arm/mach-omap2/clock2430_data.c @@ -17,8 +17,10 @@ #include <linux/clk.h> #include <linux/list.h> +#include <plat/hardware.h> #include <plat/clkdev_omap.h> +#include "iomap.h" #include "clock.h" #include "clock2xxx.h" #include "opp2xxx.h" diff --git a/arch/arm/mach-omap2/clock2xxx.c b/arch/arm/mach-omap2/clock2xxx.c index 80bb0f0e92e6..12500097378d 100644 --- a/arch/arm/mach-omap2/clock2xxx.c +++ b/arch/arm/mach-omap2/clock2xxx.c @@ -22,6 +22,7 @@ #include <linux/clk.h> #include <linux/io.h> +#include <plat/cpu.h> #include <plat/clock.h> #include "clock.h" diff --git a/arch/arm/mach-omap2/clock3xxx.c b/arch/arm/mach-omap2/clock3xxx.c index 952c3e01c9eb..794d82702c85 100644 --- a/arch/arm/mach-omap2/clock3xxx.c +++ b/arch/arm/mach-omap2/clock3xxx.c @@ -21,6 +21,7 @@ #include <linux/clk.h> #include <linux/io.h> +#include <plat/hardware.h> #include <plat/clock.h> #include "clock.h" diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index d75e5f6b8a01..f4a626f7c79e 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -19,15 +19,17 @@ #include <linux/kernel.h> #include <linux/clk.h> #include <linux/list.h> +#include <linux/io.h> +#include <plat/hardware.h> #include <plat/clkdev_omap.h> +#include "iomap.h" #include "clock.h" #include "clock3xxx.h" #include "clock34xx.h" #include "clock36xx.h" #include "clock3517.h" - #include "cm2xxx_3xxx.h" #include "cm-regbits-34xx.h" #include "prm2xxx_3xxx.h" @@ -745,7 +747,7 @@ static struct clk dpll4_m3_ck = { .parent = &dpll4_ck, .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430_CLKSEL_TV_MASK, + .clksel_mask = OMAP3630_CLKSEL_TV_MASK, .clksel = dpll4_clksel, .clkdm_name = "dpll4_clkdm", .recalc = &omap2_clksel_recalc, @@ -830,7 +832,7 @@ static struct clk dpll4_m4_ck = { .parent = &dpll4_ck, .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430_CLKSEL_DSS1_MASK, + .clksel_mask = OMAP3630_CLKSEL_DSS1_MASK, .clksel = dpll4_clksel, .clkdm_name = "dpll4_clkdm", .recalc = &omap2_clksel_recalc, @@ -857,7 +859,7 @@ static struct clk dpll4_m5_ck = { .parent = &dpll4_ck, .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_CLKSEL), - .clksel_mask = OMAP3430_CLKSEL_CAM_MASK, + .clksel_mask = OMAP3630_CLKSEL_CAM_MASK, .clksel = dpll4_clksel, .clkdm_name = "dpll4_clkdm", .set_rate = &omap2_clksel_set_rate, @@ -884,7 +886,7 @@ static struct clk dpll4_m6_ck = { .parent = &dpll4_ck, .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1), - .clksel_mask = OMAP3430_DIV_DPLL4_MASK, + .clksel_mask = OMAP3630_DIV_DPLL4_MASK, .clksel = dpll4_clksel, .clkdm_name = "dpll4_clkdm", .recalc = &omap2_clksel_recalc, @@ -1392,6 +1394,7 @@ static struct clk cpefuse_fck = { .name = "cpefuse_fck", .ops = &clkops_omap2_dflt, .parent = &sys_ck, + .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3), .enable_bit = OMAP3430ES2_EN_CPEFUSE_SHIFT, .recalc = &followparent_recalc, @@ -1401,6 +1404,7 @@ static struct clk ts_fck = { .name = "ts_fck", .ops = &clkops_omap2_dflt, .parent = &omap_32k_fck, + .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3), .enable_bit = OMAP3430ES2_EN_TS_SHIFT, .recalc = &followparent_recalc, @@ -1410,6 +1414,7 @@ static struct clk usbtll_fck = { .name = "usbtll_fck", .ops = &clkops_omap2_dflt_wait, .parent = &dpll5_m2_ck, + .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3), .enable_bit = OMAP3430ES2_EN_USBTLL_SHIFT, .recalc = &followparent_recalc, @@ -1615,6 +1620,7 @@ static struct clk fshostusb_fck = { .name = "fshostusb_fck", .ops = &clkops_omap2_dflt_wait, .parent = &core_48m_fck, + .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP3430ES1_EN_FSHOSTUSB_SHIFT, .recalc = &followparent_recalc, @@ -2041,6 +2047,7 @@ static struct clk omapctrl_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_OMAPCTRL_SHIFT, .flags = ENABLE_ON_INIT, + .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -2092,6 +2099,7 @@ static struct clk usb_l4_ick = { .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL), .clksel_mask = OMAP3430ES1_CLKSEL_FSHOSTUSB_MASK, .clksel = usb_l4_clksel, + .clkdm_name = "core_l4_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -3465,8 +3473,8 @@ static struct omap_clk omap3xxx_clks[] = { CLK(NULL, "ipss_ick", &ipss_ick, CK_AM35XX), CLK(NULL, "rmii_ck", &rmii_ck, CK_AM35XX), CLK(NULL, "pclk_ck", &pclk_ck, CK_AM35XX), - CLK("davinci_emac", "emac_clk", &emac_ick, CK_AM35XX), - CLK("davinci_emac", "phy_clk", &emac_fck, CK_AM35XX), + CLK("davinci_emac", NULL, &emac_ick, CK_AM35XX), + CLK("davinci_mdio.0", NULL, &emac_fck, CK_AM35XX), CLK("vpfe-capture", "master", &vpfe_ick, CK_AM35XX), CLK("vpfe-capture", "slave", &vpfe_fck, CK_AM35XX), CLK("musb-am35x", "ick", &hsotgusb_ick_am35xx, CK_AM35XX), diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index 08e86d793a1f..fa6ea65ad44b 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c @@ -26,8 +26,12 @@ #include <linux/kernel.h> #include <linux/list.h> #include <linux/clk.h> +#include <linux/io.h> + +#include <plat/hardware.h> #include <plat/clkdev_omap.h> +#include "iomap.h" #include "clock.h" #include "clock44xx.h" #include "cm1_44xx.h" @@ -953,8 +957,8 @@ static struct dpll_data dpll_usb_dd = { .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), .autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_USB, .idlest_reg = OMAP4430_CM_IDLEST_DPLL_USB, - .mult_mask = OMAP4430_DPLL_MULT_MASK, - .div1_mask = OMAP4430_DPLL_DIV_MASK, + .mult_mask = OMAP4430_DPLL_MULT_USB_MASK, + .div1_mask = OMAP4430_DPLL_DIV_0_7_MASK, .enable_mask = OMAP4430_DPLL_EN_MASK, .autoidle_mask = OMAP4430_AUTO_DPLL_MODE_MASK, .idlest_mask = OMAP4430_ST_DPLL_CLK_MASK, @@ -974,6 +978,7 @@ static struct clk dpll_usb_ck = { .recalc = &omap3_dpll_recalc, .round_rate = &omap2_dpll_round_rate, .set_rate = &omap3_noncore_dpll_set_rate, + .clkdm_name = "l3_init_clkdm", }; static struct clk dpll_usb_clkdcoldo_ck = { diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c index 9299ac291d28..bd7ed13515cc 100644 --- a/arch/arm/mach-omap2/clockdomains44xx_data.c +++ b/arch/arm/mach-omap2/clockdomains44xx_data.c @@ -390,7 +390,7 @@ static struct clockdomain emu_sys_44xx_clkdm = { .prcm_partition = OMAP4430_PRM_PARTITION, .cm_inst = OMAP4430_PRM_EMU_CM_INST, .clkdm_offs = OMAP4430_PRM_EMU_CM_EMU_CDOFFS, - .flags = CLKDM_CAN_HWSUP, + .flags = CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP, }; static struct clockdomain l3_dma_44xx_clkdm = { diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.c b/arch/arm/mach-omap2/cm2xxx_3xxx.c index 04d39cdd2112..389f9f8b570c 100644 --- a/arch/arm/mach-omap2/cm2xxx_3xxx.c +++ b/arch/arm/mach-omap2/cm2xxx_3xxx.c @@ -18,8 +18,10 @@ #include <linux/err.h> #include <linux/io.h> -#include "common.h" +#include <plat/hardware.h> +#include "iomap.h" +#include "common.h" #include "cm.h" #include "cm2xxx_3xxx.h" #include "cm-regbits-24xx.h" diff --git a/arch/arm/mach-omap2/cm44xx.c b/arch/arm/mach-omap2/cm44xx.c index 6a836303252c..535d66e2822c 100644 --- a/arch/arm/mach-omap2/cm44xx.c +++ b/arch/arm/mach-omap2/cm44xx.c @@ -18,8 +18,8 @@ #include <linux/err.h> #include <linux/io.h> +#include "iomap.h" #include "common.h" - #include "cm.h" #include "cm1_44xx.h" #include "cm2_44xx.h" diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c index 6204deaf85b1..bd8810c3753f 100644 --- a/arch/arm/mach-omap2/cminst44xx.c +++ b/arch/arm/mach-omap2/cminst44xx.c @@ -20,8 +20,8 @@ #include <linux/err.h> #include <linux/io.h> +#include "iomap.h" #include "common.h" - #include "cm.h" #include "cm1_44xx.h" #include "cm2_44xx.h" diff --git a/arch/arm/mach-omap2/common-board-devices.c b/arch/arm/mach-omap2/common-board-devices.c index bcb0c5817167..1706ebcec08d 100644 --- a/arch/arm/mach-omap2/common-board-devices.c +++ b/arch/arm/mach-omap2/common-board-devices.c @@ -33,7 +33,6 @@ defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) static struct omap2_mcspi_device_config ads7846_mcspi_config = { .turbo_mode = 0, - .single_channel = 1, /* 0: slave, 1: master */ }; static struct ads7846_platform_data ads7846_config = { @@ -76,13 +75,15 @@ void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce, gpio_set_debounce(gpio_pendown, gpio_debounce); } - ads7846_config.gpio_pendown = gpio_pendown; - spi_bi->bus_num = bus_num; - spi_bi->irq = OMAP_GPIO_IRQ(gpio_pendown); + spi_bi->irq = gpio_to_irq(gpio_pendown); - if (board_pdata) + if (board_pdata) { + board_pdata->gpio_pendown = gpio_pendown; spi_bi->platform_data = board_pdata; + } else { + ads7846_config.gpio_pendown = gpio_pendown; + } spi_register_board_info(&ads7846_spi_board_info, 1); } diff --git a/arch/arm/mach-omap2/common.c b/arch/arm/mach-omap2/common.c index aaf421178c91..1549c11000d3 100644 --- a/arch/arm/mach-omap2/common.c +++ b/arch/arm/mach-omap2/common.c @@ -17,12 +17,13 @@ #include <linux/clk.h> #include <linux/io.h> -#include "common.h" +#include <plat/hardware.h> #include <plat/board.h> #include <plat/mux.h> - #include <plat/clock.h> +#include "iomap.h" +#include "common.h" #include "sdrc.h" #include "control.h" diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 7e9338e8d684..57da7f406e28 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -134,6 +134,8 @@ void omap4_map_io(void); void ti81xx_map_io(void); void omap_barriers_init(void); +extern void __init omap_init_consistent_dma_size(void); + /** * omap_test_timeout - busy-loop, testing a condition * @cond: condition to test until it evaluates to true @@ -175,6 +177,18 @@ void omap3_intc_handle_irq(struct pt_regs *regs); extern void __iomem *omap4_get_l2cache_base(void); #endif +struct device_node; +#ifdef CONFIG_OF +int __init omap_intc_of_init(struct device_node *node, + struct device_node *parent); +#else +int __init omap_intc_of_init(struct device_node *node, + struct device_node *parent) +{ + return 0; +} +#endif + #ifdef CONFIG_SMP extern void __iomem *omap4_get_scu_base(void); #else @@ -236,5 +250,10 @@ static inline u32 omap4_mpuss_read_prev_context_state(void) return 0; } #endif + +struct omap_sdrc_params; +extern void omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0, + struct omap_sdrc_params *sdrc_cs1); + #endif /* __ASSEMBLER__ */ #endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */ diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c index 114c037e433c..08e674bb0417 100644 --- a/arch/arm/mach-omap2/control.c +++ b/arch/arm/mach-omap2/control.c @@ -15,9 +15,11 @@ #include <linux/kernel.h> #include <linux/io.h> -#include "common.h" +#include <plat/hardware.h> #include <plat/sdrc.h> +#include "iomap.h" +#include "common.h" #include "cm-regbits-34xx.h" #include "prm-regbits-34xx.h" #include "prm2xxx_3xxx.h" diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h index 0ba68d3764bc..a406fd045ce1 100644 --- a/arch/arm/mach-omap2/control.h +++ b/arch/arm/mach-omap2/control.h @@ -16,7 +16,6 @@ #ifndef __ARCH_ARM_MACH_OMAP2_CONTROL_H #define __ARCH_ARM_MACH_OMAP2_CONTROL_H -#include <mach/io.h> #include <mach/ctrl_module_core_44xx.h> #include <mach/ctrl_module_wkup_44xx.h> #include <mach/ctrl_module_pad_core_44xx.h> @@ -339,6 +338,11 @@ #define AM35XX_VPFE_PCLK_SW_RST BIT(4) /* + * CONTROL AM33XX STATUS register + */ +#define AM33XX_CONTROL_STATUS 0x040 + +/* * CONTROL OMAP STATUS register to identify OMAP3 features */ #define OMAP3_CONTROL_OMAP_STATUS 0x044c diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index 464cffde58fe..535866489ce3 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -87,29 +87,14 @@ static int _cpuidle_deny_idle(struct powerdomain *pwrdm, return 0; } -/** - * omap3_enter_idle - Programs OMAP3 to enter the specified state - * @dev: cpuidle device - * @drv: cpuidle driver - * @index: the index of state to be entered - * - * Called from the CPUidle framework to program the device to the - * specified target state selected by the governor. - */ -static int omap3_enter_idle(struct cpuidle_device *dev, +static int __omap3_enter_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { struct omap3_idle_statedata *cx = cpuidle_get_statedata(&dev->states_usage[index]); - struct timespec ts_preidle, ts_postidle, ts_idle; u32 mpu_state = cx->mpu_state, core_state = cx->core_state; - int idle_time; - - /* Used to keep track of the total time in idle */ - getnstimeofday(&ts_preidle); - local_irq_disable(); local_fiq_disable(); pwrdm_set_next_pwrst(mpu_pd, mpu_state); @@ -148,22 +133,29 @@ static int omap3_enter_idle(struct cpuidle_device *dev, } return_sleep_time: - getnstimeofday(&ts_postidle); - ts_idle = timespec_sub(ts_postidle, ts_preidle); - local_irq_enable(); local_fiq_enable(); - idle_time = ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * \ - USEC_PER_SEC; - - /* Update cpuidle counters */ - dev->last_residency = idle_time; - return index; } /** + * omap3_enter_idle - Programs OMAP3 to enter the specified state + * @dev: cpuidle device + * @drv: cpuidle driver + * @index: the index of state to be entered + * + * Called from the CPUidle framework to program the device to the + * specified target state selected by the governor. + */ +static inline int omap3_enter_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + return cpuidle_wrap_enter(dev, drv, index, __omap3_enter_idle); +} + +/** * next_valid_state - Find next valid C-state * @dev: cpuidle device * @drv: cpuidle driver diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c index 72e018b9b260..f386cbe9c889 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -62,15 +62,9 @@ static int omap4_enter_idle(struct cpuidle_device *dev, { struct omap4_idle_statedata *cx = cpuidle_get_statedata(&dev->states_usage[index]); - struct timespec ts_preidle, ts_postidle, ts_idle; u32 cpu1_state; - int idle_time; int cpu_id = smp_processor_id(); - /* Used to keep track of the total time in idle */ - getnstimeofday(&ts_preidle); - - local_irq_disable(); local_fiq_disable(); /* @@ -128,26 +122,17 @@ static int omap4_enter_idle(struct cpuidle_device *dev, if (index > 0) clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id); - getnstimeofday(&ts_postidle); - ts_idle = timespec_sub(ts_postidle, ts_preidle); - - local_irq_enable(); local_fiq_enable(); - idle_time = ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * \ - USEC_PER_SEC; - - /* Update cpuidle counters */ - dev->last_residency = idle_time; - return index; } DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev); struct cpuidle_driver omap4_idle_driver = { - .name = "omap4_idle", - .owner = THIS_MODULE, + .name = "omap4_idle", + .owner = THIS_MODULE, + .en_core_tk_irqen = 1, }; static inline void _fill_cstate(struct cpuidle_driver *drv, diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index f713818be06f..e4336035c0ea 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -25,7 +25,7 @@ #include <asm/mach/map.h> #include <asm/pmu.h> -#include <plat/tc.h> +#include "iomap.h" #include <plat/board.h> #include <plat/mmc.h> #include <plat/dma.h> @@ -276,7 +276,7 @@ int __init omap4_keyboard_init(struct omap4_keypad_platform_data } #if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE) -static inline void omap_init_mbox(void) +static inline void __init omap_init_mbox(void) { struct omap_hwmod *oh; struct platform_device *pdev; @@ -316,7 +316,7 @@ static inline void omap_init_audio(void) {} #if defined(CONFIG_SND_OMAP_SOC_MCPDM) || \ defined(CONFIG_SND_OMAP_SOC_MCPDM_MODULE) -static void omap_init_mcpdm(void) +static void __init omap_init_mcpdm(void) { struct omap_hwmod *oh; struct platform_device *pdev; @@ -337,7 +337,7 @@ static inline void omap_init_mcpdm(void) {} #if defined(CONFIG_SND_OMAP_SOC_DMIC) || \ defined(CONFIG_SND_OMAP_SOC_DMIC_MODULE) -static void omap_init_dmic(void) +static void __init omap_init_dmic(void) { struct omap_hwmod *oh; struct platform_device *pdev; @@ -359,7 +359,7 @@ static inline void omap_init_dmic(void) {} #include <plat/mcspi.h> -static int omap_mcspi_init(struct omap_hwmod *oh, void *unused) +static int __init omap_mcspi_init(struct omap_hwmod *oh, void *unused) { struct platform_device *pdev; char *name = "omap2_mcspi"; @@ -633,9 +633,7 @@ void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data) /*-------------------------------------------------------------------------*/ #if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE) -#if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_SOC_OMAP3430) #define OMAP_HDQ_BASE 0x480B2000 -#endif static struct resource omap_hdq_resources[] = { { .start = OMAP_HDQ_BASE, @@ -658,7 +656,10 @@ static struct platform_device omap_hdq_dev = { }; static inline void omap_hdq_init(void) { - (void) platform_device_register(&omap_hdq_dev); + if (cpu_is_omap2420()) + return; + + platform_device_register(&omap_hdq_dev); } #else static inline void omap_hdq_init(void) {} diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 3677b1f58b85..db5a88a36c63 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -30,6 +30,7 @@ #include <plat/omap-pm.h> #include "common.h" +#include "iomap.h" #include "mux.h" #include "control.h" #include "display.h" @@ -98,7 +99,7 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = { { "dss_hdmi", "omapdss_hdmi", -1 }, }; -static void omap4_hdmi_mux_pads(enum omap_hdmi_flags flags) +static void __init omap4_hdmi_mux_pads(enum omap_hdmi_flags flags) { u32 reg; u16 control_i2c_1; @@ -157,7 +158,7 @@ static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes) return 0; } -int omap_hdmi_init(enum omap_hdmi_flags flags) +int __init omap_hdmi_init(enum omap_hdmi_flags flags) { if (cpu_is_omap44xx()) omap4_hdmi_mux_pads(flags); diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c index a59a45a0096e..b19d8496c16e 100644 --- a/arch/arm/mach-omap2/dma.c +++ b/arch/arm/mach-omap2/dma.c @@ -227,7 +227,7 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused) dma_stride = OMAP2_DMA_STRIDE; dma_common_ch_start = CSDP; - if (cpu_is_omap3630() || cpu_is_omap4430()) + if (cpu_is_omap3630() || cpu_is_omap44xx()) dma_common_ch_end = CCDN; else dma_common_ch_end = CCFN; diff --git a/arch/arm/mach-omap2/emu.c b/arch/arm/mach-omap2/emu.c index 9c442e290ccb..e28e761b7ab9 100644 --- a/arch/arm/mach-omap2/emu.c +++ b/arch/arm/mach-omap2/emu.c @@ -21,6 +21,10 @@ #include <linux/clk.h> #include <linux/err.h> +#include <mach/hardware.h> + +#include "iomap.h" + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Alexander Shishkin"); @@ -30,29 +34,8 @@ MODULE_AUTHOR("Alexander Shishkin"); #define ETB_BASE (L4_EMU_34XX_PHYS + 0x1b000) #define DAPCTL (L4_EMU_34XX_PHYS + 0x1d000) -static struct amba_device omap3_etb_device = { - .dev = { - .init_name = "etb", - }, - .res = { - .start = ETB_BASE, - .end = ETB_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .periphid = 0x000bb907, -}; - -static struct amba_device omap3_etm_device = { - .dev = { - .init_name = "etm", - }, - .res = { - .start = ETM_BASE, - .end = ETM_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .periphid = 0x102bb921, -}; +static AMBA_APB_DEVICE(omap3_etb, "etb", 0x000bb907, ETB_BASE, { }, NULL); +static AMBA_APB_DEVICE(omap3_etm, "etm", 0x102bb921, ETM_BASE, { }, NULL); static int __init emu_init(void) { @@ -66,4 +49,3 @@ static int __init emu_init(void) } subsys_initcall(emu_init); - diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c index 8cbfbc2918ce..2f994e5194e8 100644 --- a/arch/arm/mach-omap2/gpio.c +++ b/arch/arm/mach-omap2/gpio.c @@ -23,14 +23,18 @@ #include <plat/omap_hwmod.h> #include <plat/omap_device.h> +#include <plat/omap-pm.h> -static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) +#include "powerdomain.h" + +static int __init omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) { struct platform_device *pdev; struct omap_gpio_platform_data *pdata; struct omap_gpio_dev_attr *dev_attr; char *name = "omap_gpio"; int id; + struct powerdomain *pwrdm; /* * extract the device id from name field available in the @@ -52,7 +56,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata->bank_width = dev_attr->bank_width; pdata->dbck_flag = dev_attr->dbck_flag; pdata->virtual_irq_start = IH_GPIO_BASE + 32 * (id - 1); - + pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count; pdata->regs = kzalloc(sizeof(struct omap_gpio_reg_offs), GFP_KERNEL); if (!pdata) { pr_err("gpio%d: Memory allocation failed\n", id); @@ -61,8 +65,15 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) switch (oh->class->rev) { case 0: + if (id == 1) + /* non-wakeup GPIO pins for OMAP2 Bank1 */ + pdata->non_wakeup_gpios = 0xe203ffc0; + else if (id == 2) + /* non-wakeup GPIO pins for OMAP2 Bank2 */ + pdata->non_wakeup_gpios = 0x08700040; + /* fall through */ + case 1: - pdata->bank_type = METHOD_GPIO_24XX; pdata->regs->revision = OMAP24XX_GPIO_REVISION; pdata->regs->direction = OMAP24XX_GPIO_OE; pdata->regs->datain = OMAP24XX_GPIO_DATAIN; @@ -72,13 +83,19 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata->regs->irqstatus = OMAP24XX_GPIO_IRQSTATUS1; pdata->regs->irqstatus2 = OMAP24XX_GPIO_IRQSTATUS2; pdata->regs->irqenable = OMAP24XX_GPIO_IRQENABLE1; + pdata->regs->irqenable2 = OMAP24XX_GPIO_IRQENABLE2; pdata->regs->set_irqenable = OMAP24XX_GPIO_SETIRQENABLE1; pdata->regs->clr_irqenable = OMAP24XX_GPIO_CLEARIRQENABLE1; pdata->regs->debounce = OMAP24XX_GPIO_DEBOUNCE_VAL; pdata->regs->debounce_en = OMAP24XX_GPIO_DEBOUNCE_EN; + pdata->regs->ctrl = OMAP24XX_GPIO_CTRL; + pdata->regs->wkup_en = OMAP24XX_GPIO_WAKE_EN; + pdata->regs->leveldetect0 = OMAP24XX_GPIO_LEVELDETECT0; + pdata->regs->leveldetect1 = OMAP24XX_GPIO_LEVELDETECT1; + pdata->regs->risingdetect = OMAP24XX_GPIO_RISINGDETECT; + pdata->regs->fallingdetect = OMAP24XX_GPIO_FALLINGDETECT; break; case 2: - pdata->bank_type = METHOD_GPIO_44XX; pdata->regs->revision = OMAP4_GPIO_REVISION; pdata->regs->direction = OMAP4_GPIO_OE; pdata->regs->datain = OMAP4_GPIO_DATAIN; @@ -88,10 +105,17 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata->regs->irqstatus = OMAP4_GPIO_IRQSTATUS0; pdata->regs->irqstatus2 = OMAP4_GPIO_IRQSTATUS1; pdata->regs->irqenable = OMAP4_GPIO_IRQSTATUSSET0; + pdata->regs->irqenable2 = OMAP4_GPIO_IRQSTATUSSET1; pdata->regs->set_irqenable = OMAP4_GPIO_IRQSTATUSSET0; pdata->regs->clr_irqenable = OMAP4_GPIO_IRQSTATUSCLR0; pdata->regs->debounce = OMAP4_GPIO_DEBOUNCINGTIME; pdata->regs->debounce_en = OMAP4_GPIO_DEBOUNCENABLE; + pdata->regs->ctrl = OMAP4_GPIO_CTRL; + pdata->regs->wkup_en = OMAP4_GPIO_IRQWAKEN0; + pdata->regs->leveldetect0 = OMAP4_GPIO_LEVELDETECT0; + pdata->regs->leveldetect1 = OMAP4_GPIO_LEVELDETECT1; + pdata->regs->risingdetect = OMAP4_GPIO_RISINGDETECT; + pdata->regs->fallingdetect = OMAP4_GPIO_FALLINGDETECT; break; default: WARN(1, "Invalid gpio bank_type\n"); @@ -99,6 +123,9 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) return -EINVAL; } + pwrdm = omap_hwmod_get_pwrdm(oh); + pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm); + pdev = omap_device_build(name, id - 1, oh, pdata, sizeof(*pdata), NULL, 0, false); kfree(pdata); @@ -109,9 +136,6 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) return PTR_ERR(pdev); } - omap_device_disable_idle_on_suspend(pdev); - - gpio_bank_count++; return 0; } diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c index 8ad210bda9a9..386dec8d2351 100644 --- a/arch/arm/mach-omap2/gpmc-nand.c +++ b/arch/arm/mach-omap2/gpmc-nand.c @@ -16,6 +16,7 @@ #include <asm/mach/flash.h> +#include <plat/cpu.h> #include <plat/nand.h> #include <plat/board.h> #include <plat/gpmc.h> diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c index 5cdce10d6183..385b3e02c4a6 100644 --- a/arch/arm/mach-omap2/gpmc-onenand.c +++ b/arch/arm/mach-omap2/gpmc-onenand.c @@ -18,6 +18,7 @@ #include <asm/mach/flash.h> +#include <plat/cpu.h> #include <plat/onenand.h> #include <plat/board.h> #include <plat/gpmc.h> diff --git a/arch/arm/mach-omap2/gpmc-smsc911x.c b/arch/arm/mach-omap2/gpmc-smsc911x.c index bbb870c04a5e..b6c77be3e8f7 100644 --- a/arch/arm/mach-omap2/gpmc-smsc911x.c +++ b/arch/arm/mach-omap2/gpmc-smsc911x.c @@ -19,15 +19,11 @@ #include <linux/interrupt.h> #include <linux/io.h> #include <linux/smsc911x.h> -#include <linux/regulator/fixed.h> -#include <linux/regulator/machine.h> #include <plat/board.h> #include <plat/gpmc.h> #include <plat/gpmc-smsc911x.h> -static struct omap_smsc911x_platform_data *gpmc_cfg; - static struct resource gpmc_smsc911x_resources[] = { [0] = { .flags = IORESOURCE_MEM, @@ -41,51 +37,6 @@ static struct smsc911x_platform_config gpmc_smsc911x_config = { .phy_interface = PHY_INTERFACE_MODE_MII, .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, - .flags = SMSC911X_USE_16BIT, -}; - -static struct regulator_consumer_supply gpmc_smsc911x_supply[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x.0"), - REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), -}; - -/* Generic regulator definition to satisfy smsc911x */ -static struct regulator_init_data gpmc_smsc911x_reg_init_data = { - .constraints = { - .min_uV = 3300000, - .max_uV = 3300000, - .valid_modes_mask = REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .valid_ops_mask = REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(gpmc_smsc911x_supply), - .consumer_supplies = gpmc_smsc911x_supply, -}; - -static struct fixed_voltage_config gpmc_smsc911x_fixed_reg_data = { - .supply_name = "gpmc_smsc911x", - .microvolts = 3300000, - .gpio = -EINVAL, - .startup_delay = 0, - .enable_high = 0, - .enabled_at_boot = 1, - .init_data = &gpmc_smsc911x_reg_init_data, -}; - -/* - * Platform device id of 42 is a temporary fix to avoid conflicts - * with other reg-fixed-voltage devices. The real fix should - * involve the driver core providing a way of dynamically - * assigning a unique id on registration for platform devices - * in the same name space. - */ -static struct platform_device gpmc_smsc911x_regulator = { - .name = "reg-fixed-voltage", - .id = 42, - .dev = { - .platform_data = &gpmc_smsc911x_fixed_reg_data, - }, }; /* @@ -93,20 +44,12 @@ static struct platform_device gpmc_smsc911x_regulator = { * assume that pin multiplexing is done in the board-*.c file, * or in the bootloader. */ -void __init gpmc_smsc911x_init(struct omap_smsc911x_platform_data *board_data) +void __init gpmc_smsc911x_init(struct omap_smsc911x_platform_data *gpmc_cfg) { struct platform_device *pdev; unsigned long cs_mem_base; int ret; - gpmc_cfg = board_data; - - ret = platform_device_register(&gpmc_smsc911x_regulator); - if (ret < 0) { - pr_err("Unable to register smsc911x regulators: %d\n", ret); - return; - } - if (gpmc_cs_request(gpmc_cfg->cs, SZ_16M, &cs_mem_base) < 0) { pr_err("Failed to request GPMC mem region\n"); return; @@ -136,8 +79,7 @@ void __init gpmc_smsc911x_init(struct omap_smsc911x_platform_data *board_data) gpio_set_value(gpmc_cfg->gpio_reset, 1); } - if (gpmc_cfg->flags) - gpmc_smsc911x_config.flags = gpmc_cfg->flags; + gpmc_smsc911x_config.flags = gpmc_cfg->flags ? : SMSC911X_USE_16BIT; pdev = platform_device_register_resndata(NULL, "smsc911x", gpmc_cfg->id, gpmc_smsc911x_resources, ARRAY_SIZE(gpmc_smsc911x_resources), diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index dfffbbf4c009..00d510858e28 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -888,6 +888,7 @@ int gpmc_enable_hwecc(int cs, int mode, int dev_width, int ecc_size) gpmc_write_reg(GPMC_ECC_CONFIG, val); return 0; } +EXPORT_SYMBOL_GPL(gpmc_enable_hwecc); /** * gpmc_calculate_ecc - generate non-inverted ecc bytes @@ -918,3 +919,4 @@ int gpmc_calculate_ecc(int cs, const u_char *dat, u_char *ecc_code) gpmc_ecc_used = -EINVAL; return 0; } +EXPORT_SYMBOL_GPL(gpmc_calculate_ecc); diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index 19dd1657245c..b0268eaffe13 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -293,8 +293,8 @@ static inline void omap_hsmmc_mux(struct omap_mmc_platform_data *mmc_controller, } } -static int omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, - struct omap_mmc_platform_data *mmc) +static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, + struct omap_mmc_platform_data *mmc) { char *hc_name; @@ -316,6 +316,7 @@ static int omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, mmc->slots[0].pm_caps = c->pm_caps; mmc->slots[0].internal_clock = !c->ext_clock; mmc->dma_mask = 0xffffffff; + mmc->max_freq = c->max_freq; if (cpu_is_omap44xx()) mmc->reg_offset = OMAP4_MMC_REG_OFFSET; else @@ -429,66 +430,138 @@ static int omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, } static int omap_hsmmc_done; + +void omap_hsmmc_late_init(struct omap2_hsmmc_info *c) +{ + struct platform_device *pdev; + struct omap_mmc_platform_data *mmc_pdata; + int res; + + if (omap_hsmmc_done != 1) + return; + + omap_hsmmc_done++; + + for (; c->mmc; c++) { + if (!c->deferred) + continue; + + pdev = c->pdev; + if (!pdev) + continue; + + mmc_pdata = pdev->dev.platform_data; + if (!mmc_pdata) + continue; + + mmc_pdata->slots[0].switch_pin = c->gpio_cd; + mmc_pdata->slots[0].gpio_wp = c->gpio_wp; + + res = omap_device_register(pdev); + if (res) + pr_err("Could not late init MMC %s\n", + c->name); + } +} + #define MAX_OMAP_MMC_HWMOD_NAME_LEN 16 -void omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr) +static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo, + int ctrl_nr) { struct omap_hwmod *oh; + struct omap_hwmod *ohs[1]; + struct omap_device *od; struct platform_device *pdev; char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN]; struct omap_mmc_platform_data *mmc_data; struct omap_mmc_dev_attr *mmc_dev_attr; char *name; - int l; + int res; mmc_data = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL); if (!mmc_data) { pr_err("Cannot allocate memory for mmc device!\n"); - goto done; + return; } - if (omap_hsmmc_pdata_init(hsmmcinfo, mmc_data) < 0) { - pr_err("%s fails!\n", __func__); - goto done; - } + res = omap_hsmmc_pdata_init(hsmmcinfo, mmc_data); + if (res < 0) + goto free_mmc; + omap_hsmmc_mux(mmc_data, (ctrl_nr - 1)); name = "omap_hsmmc"; - - l = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN, + res = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN, "mmc%d", ctrl_nr); - WARN(l >= MAX_OMAP_MMC_HWMOD_NAME_LEN, + WARN(res >= MAX_OMAP_MMC_HWMOD_NAME_LEN, "String buffer overflow in MMC%d device setup\n", ctrl_nr); + oh = omap_hwmod_lookup(oh_name); if (!oh) { pr_err("Could not look up %s\n", oh_name); - kfree(mmc_data->slots[0].name); - goto done; + goto free_name; } - + ohs[0] = oh; if (oh->dev_attr != NULL) { mmc_dev_attr = oh->dev_attr; mmc_data->controller_flags = mmc_dev_attr->flags; + /* + * erratum 2.1.1.128 doesn't apply if board has + * a transceiver is attached + */ + if (hsmmcinfo->transceiver) + mmc_data->controller_flags &= + ~OMAP_HSMMC_BROKEN_MULTIBLOCK_READ; } - pdev = omap_device_build(name, ctrl_nr - 1, oh, mmc_data, - sizeof(struct omap_mmc_platform_data), NULL, 0, false); - if (IS_ERR(pdev)) { - WARN(1, "Can't build omap_device for %s:%s.\n", name, oh->name); - kfree(mmc_data->slots[0].name); - goto done; + pdev = platform_device_alloc(name, ctrl_nr - 1); + if (!pdev) { + pr_err("Could not allocate pdev for %s\n", name); + goto free_name; } - /* - * return device handle to board setup code - * required to populate for regulator framework structure - */ - hsmmcinfo->dev = &pdev->dev; + dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); + + od = omap_device_alloc(pdev, ohs, 1, NULL, 0); + if (!od) { + pr_err("Could not allocate od for %s\n", name); + goto put_pdev; + } + + res = platform_device_add_data(pdev, mmc_data, + sizeof(struct omap_mmc_platform_data)); + if (res) { + pr_err("Could not add pdata for %s\n", name); + goto put_pdev; + } + + hsmmcinfo->pdev = pdev; + + if (hsmmcinfo->deferred) + goto free_mmc; + + res = omap_device_register(pdev); + if (res) { + pr_err("Could not register od for %s\n", name); + goto free_od; + } + + goto free_mmc; + +free_od: + omap_device_delete(od); + +put_pdev: + platform_device_put(pdev); + +free_name: + kfree(mmc_data->slots[0].name); -done: +free_mmc: kfree(mmc_data); } -void omap2_hsmmc_init(struct omap2_hsmmc_info *controllers) +void __init omap_hsmmc_init(struct omap2_hsmmc_info *controllers) { u32 reg; @@ -521,7 +594,7 @@ void omap2_hsmmc_init(struct omap2_hsmmc_info *controllers) } for (; controllers->mmc; controllers++) - omap_init_hsmmc(controllers, controllers->mmc); + omap_hsmmc_init_one(controllers, controllers->mmc); } diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h index c4409730c4bb..7f2e790e0929 100644 --- a/arch/arm/mach-omap2/hsmmc.h +++ b/arch/arm/mach-omap2/hsmmc.h @@ -21,11 +21,14 @@ struct omap2_hsmmc_info { bool no_off; /* power_saving and power is not to go off */ bool no_off_init; /* no power off when not in MMC sleep state */ bool vcc_aux_disable_is_sleep; /* Regulator off remapped to sleep */ + bool deferred; /* mmc needs a deferred probe */ int gpio_cd; /* or -EINVAL */ int gpio_wp; /* or -EINVAL */ char *name; /* or NULL for default */ - struct device *dev; /* returned: pointer to mmc adapter */ + struct platform_device *pdev; /* mmc controller instance */ int ocr_mask; /* temporary HACK */ + int max_freq; /* maximum clock, if constrained by external + * circuitry, or 0 for default */ /* Remux (pad configuration) when powering on/off */ void (*remux)(struct device *dev, int slot, int power_on); /* init some special card */ @@ -34,11 +37,16 @@ struct omap2_hsmmc_info { #if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) -void omap2_hsmmc_init(struct omap2_hsmmc_info *); +void omap_hsmmc_init(struct omap2_hsmmc_info *); +void omap_hsmmc_late_init(struct omap2_hsmmc_info *); #else -static inline void omap2_hsmmc_init(struct omap2_hsmmc_info *info) +static inline void omap_hsmmc_init(struct omap2_hsmmc_info *info) +{ +} + +static inline void omap_hsmmc_late_init(struct omap2_hsmmc_info *info) { } diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 719ee423abe2..0e79b7bc6aa4 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -29,7 +29,7 @@ #include "control.h" static unsigned int omap_revision; - +static const char *cpu_rev; u32 omap_features; unsigned int omap_rev(void) @@ -44,6 +44,8 @@ int omap_type(void) if (cpu_is_omap24xx()) { val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS); + } else if (cpu_is_am33xx()) { + val = omap_ctrl_readl(AM33XX_CONTROL_STATUS); } else if (cpu_is_omap34xx()) { val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS); } else if (cpu_is_omap44xx()) { @@ -112,7 +114,7 @@ void omap_get_die_id(struct omap_die_id *odi) odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_3); } -static void __init omap24xx_check_revision(void) +void __init omap2xxx_check_revision(void) { int i, j; u32 idcode, prod_id; @@ -166,13 +168,63 @@ static void __init omap24xx_check_revision(void) pr_info("\n"); } +#define OMAP3_SHOW_FEATURE(feat) \ + if (omap3_has_ ##feat()) \ + printk(#feat" "); + +static void __init omap3_cpuinfo(void) +{ + const char *cpu_name; + + /* + * OMAP3430 and OMAP3530 are assumed to be same. + * + * OMAP3525, OMAP3515 and OMAP3503 can be detected only based + * on available features. Upon detection, update the CPU id + * and CPU class bits. + */ + if (cpu_is_omap3630()) { + cpu_name = "OMAP3630"; + } else if (cpu_is_omap3517()) { + /* AM35xx devices */ + cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505"; + } else if (cpu_is_ti816x()) { + cpu_name = "TI816X"; + } else if (cpu_is_am335x()) { + cpu_name = "AM335X"; + } else if (cpu_is_ti814x()) { + cpu_name = "TI814X"; + } else if (omap3_has_iva() && omap3_has_sgx()) { + /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */ + cpu_name = "OMAP3430/3530"; + } else if (omap3_has_iva()) { + cpu_name = "OMAP3525"; + } else if (omap3_has_sgx()) { + cpu_name = "OMAP3515"; + } else { + cpu_name = "OMAP3503"; + } + + /* Print verbose information */ + pr_info("%s ES%s (", cpu_name, cpu_rev); + + OMAP3_SHOW_FEATURE(l2cache); + OMAP3_SHOW_FEATURE(iva); + OMAP3_SHOW_FEATURE(sgx); + OMAP3_SHOW_FEATURE(neon); + OMAP3_SHOW_FEATURE(isp); + OMAP3_SHOW_FEATURE(192mhz_clk); + + printk(")\n"); +} + #define OMAP3_CHECK_FEATURE(status,feat) \ if (((status & OMAP3_ ##feat## _MASK) \ >> OMAP3_ ##feat## _SHIFT) != FEAT_ ##feat## _NONE) { \ omap_features |= OMAP3_HAS_ ##feat; \ } -static void __init omap3_check_features(void) +void __init omap3xxx_check_features(void) { u32 status; @@ -199,9 +251,11 @@ static void __init omap3_check_features(void) * TODO: Get additional info (where applicable) * e.g. Size of L2 cache. */ + + omap3_cpuinfo(); } -static void __init omap4_check_features(void) +void __init omap4xxx_check_features(void) { u32 si_type; @@ -226,12 +280,13 @@ static void __init omap4_check_features(void) } } -static void __init ti81xx_check_features(void) +void __init ti81xx_check_features(void) { omap_features = OMAP3_HAS_NEON; + omap3_cpuinfo(); } -static void __init omap3_check_revision(const char **cpu_rev) +void __init omap3xxx_check_revision(void) { u32 cpuid, idcode; u16 hawkeye; @@ -245,7 +300,7 @@ static void __init omap3_check_revision(const char **cpu_rev) cpuid = read_cpuid(CPUID_ID); if ((((cpuid >> 4) & 0xfff) == 0xc08) && ((cpuid & 0xf) == 0x0)) { omap_revision = OMAP3430_REV_ES1_0; - *cpu_rev = "1.0"; + cpu_rev = "1.0"; return; } @@ -266,26 +321,26 @@ static void __init omap3_check_revision(const char **cpu_rev) case 0: /* Take care of early samples */ case 1: omap_revision = OMAP3430_REV_ES2_0; - *cpu_rev = "2.0"; + cpu_rev = "2.0"; break; case 2: omap_revision = OMAP3430_REV_ES2_1; - *cpu_rev = "2.1"; + cpu_rev = "2.1"; break; case 3: omap_revision = OMAP3430_REV_ES3_0; - *cpu_rev = "3.0"; + cpu_rev = "3.0"; break; case 4: omap_revision = OMAP3430_REV_ES3_1; - *cpu_rev = "3.1"; + cpu_rev = "3.1"; break; case 7: /* FALLTHROUGH */ default: /* Use the latest known revision as default */ omap_revision = OMAP3430_REV_ES3_1_2; - *cpu_rev = "3.1.2"; + cpu_rev = "3.1.2"; } break; case 0xb868: @@ -298,13 +353,13 @@ static void __init omap3_check_revision(const char **cpu_rev) switch (rev) { case 0: omap_revision = OMAP3517_REV_ES1_0; - *cpu_rev = "1.0"; + cpu_rev = "1.0"; break; case 1: /* FALLTHROUGH */ default: omap_revision = OMAP3517_REV_ES1_1; - *cpu_rev = "1.1"; + cpu_rev = "1.1"; } break; case 0xb891: @@ -313,36 +368,36 @@ static void __init omap3_check_revision(const char **cpu_rev) switch(rev) { case 0: /* Take care of early samples */ omap_revision = OMAP3630_REV_ES1_0; - *cpu_rev = "1.0"; + cpu_rev = "1.0"; break; case 1: omap_revision = OMAP3630_REV_ES1_1; - *cpu_rev = "1.1"; + cpu_rev = "1.1"; break; case 2: /* FALLTHROUGH */ default: omap_revision = OMAP3630_REV_ES1_2; - *cpu_rev = "1.2"; + cpu_rev = "1.2"; } break; case 0xb81e: switch (rev) { case 0: omap_revision = TI8168_REV_ES1_0; - *cpu_rev = "1.0"; + cpu_rev = "1.0"; break; case 1: /* FALLTHROUGH */ default: omap_revision = TI8168_REV_ES1_1; - *cpu_rev = "1.1"; + cpu_rev = "1.1"; break; } break; case 0xb944: omap_revision = AM335X_REV_ES1_0; - *cpu_rev = "1.0"; + cpu_rev = "1.0"; break; case 0xb8f2: switch (rev) { @@ -350,29 +405,29 @@ static void __init omap3_check_revision(const char **cpu_rev) /* FALLTHROUGH */ case 1: omap_revision = TI8148_REV_ES1_0; - *cpu_rev = "1.0"; + cpu_rev = "1.0"; break; case 2: omap_revision = TI8148_REV_ES2_0; - *cpu_rev = "2.0"; + cpu_rev = "2.0"; break; case 3: /* FALLTHROUGH */ default: omap_revision = TI8148_REV_ES2_1; - *cpu_rev = "2.1"; + cpu_rev = "2.1"; break; } break; default: /* Unknown default to latest silicon rev as default */ omap_revision = OMAP3630_REV_ES1_2; - *cpu_rev = "1.2"; + cpu_rev = "1.2"; pr_warn("Warning: unknown chip type; assuming OMAP3630ES1.2\n"); } } -static void __init omap4_check_revision(void) +void __init omap4xxx_check_revision(void) { u32 idcode; u16 hawkeye; @@ -445,89 +500,6 @@ static void __init omap4_check_revision(void) ((omap_rev() >> 12) & 0xf), ((omap_rev() >> 8) & 0xf)); } -#define OMAP3_SHOW_FEATURE(feat) \ - if (omap3_has_ ##feat()) \ - printk(#feat" "); - -static void __init omap3_cpuinfo(const char *cpu_rev) -{ - const char *cpu_name; - - /* - * OMAP3430 and OMAP3530 are assumed to be same. - * - * OMAP3525, OMAP3515 and OMAP3503 can be detected only based - * on available features. Upon detection, update the CPU id - * and CPU class bits. - */ - if (cpu_is_omap3630()) { - cpu_name = "OMAP3630"; - } else if (cpu_is_omap3517()) { - /* AM35xx devices */ - cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505"; - } else if (cpu_is_ti816x()) { - cpu_name = "TI816X"; - } else if (cpu_is_am335x()) { - cpu_name = "AM335X"; - } else if (cpu_is_ti814x()) { - cpu_name = "TI814X"; - } else if (omap3_has_iva() && omap3_has_sgx()) { - /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */ - cpu_name = "OMAP3430/3530"; - } else if (omap3_has_iva()) { - cpu_name = "OMAP3525"; - } else if (omap3_has_sgx()) { - cpu_name = "OMAP3515"; - } else { - cpu_name = "OMAP3503"; - } - - /* Print verbose information */ - pr_info("%s ES%s (", cpu_name, cpu_rev); - - OMAP3_SHOW_FEATURE(l2cache); - OMAP3_SHOW_FEATURE(iva); - OMAP3_SHOW_FEATURE(sgx); - OMAP3_SHOW_FEATURE(neon); - OMAP3_SHOW_FEATURE(isp); - OMAP3_SHOW_FEATURE(192mhz_clk); - - printk(")\n"); -} - -/* - * Try to detect the exact revision of the omap we're running on - */ -void __init omap2_check_revision(void) -{ - const char *cpu_rev; - - /* - * At this point we have an idea about the processor revision set - * earlier with omap2_set_globals_tap(). - */ - if (cpu_is_omap24xx()) { - omap24xx_check_revision(); - } else if (cpu_is_omap34xx()) { - omap3_check_revision(&cpu_rev); - - /* TI81XX doesn't have feature register */ - if (!cpu_is_ti81xx()) - omap3_check_features(); - else - ti81xx_check_features(); - - omap3_cpuinfo(cpu_rev); - return; - } else if (cpu_is_omap44xx()) { - omap4_check_revision(); - omap4_check_features(); - return; - } else { - pr_err("OMAP revision unknown, please fix!\n"); - } -} - /* * Set up things for map_io and processor detection later on. Gets called * pretty much first thing from board init. For multi-omap, this gets diff --git a/arch/arm/mach-omap2/include/mach/barriers.h b/arch/arm/mach-omap2/include/mach/barriers.h index 4fa72c7cc7cd..1c582a8592b9 100644 --- a/arch/arm/mach-omap2/include/mach/barriers.h +++ b/arch/arm/mach-omap2/include/mach/barriers.h @@ -22,6 +22,8 @@ #ifndef __MACH_BARRIERS_H #define __MACH_BARRIERS_H +#include <asm/outercache.h> + extern void omap_bus_sync(void); #define rmb() dsb() diff --git a/arch/arm/mach-omap2/include/mach/entry-macro.S b/arch/arm/mach-omap2/include/mach/entry-macro.S deleted file mode 100644 index 56964a0c4c7e..000000000000 --- a/arch/arm/mach-omap2/include/mach/entry-macro.S +++ /dev/null @@ -1,18 +0,0 @@ -/* - * arch/arm/plat-omap/include/mach/entry-macro.S - * - * Low-level IRQ helper macros for OMAP-based platforms - * - * Copyright (C) 2009 Texas Instruments - * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-omap2/include/mach/io.h b/arch/arm/mach-omap2/include/mach/io.h deleted file mode 100644 index fd78f31aa1ad..000000000000 --- a/arch/arm/mach-omap2/include/mach/io.h +++ /dev/null @@ -1,5 +0,0 @@ -/* - * arch/arm/mach-omap2/include/mach/io.h - */ - -#include <plat/io.h> diff --git a/arch/arm/mach-omap2/include/mach/system.h b/arch/arm/mach-omap2/include/mach/system.h deleted file mode 100644 index d488721ab90b..000000000000 --- a/arch/arm/mach-omap2/include/mach/system.h +++ /dev/null @@ -1,5 +0,0 @@ -/* - * arch/arm/mach-omap2/include/mach/system.h - */ - -#include <plat/system.h> diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index e501b4972a64..065bd768987c 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -23,33 +23,30 @@ #include <linux/clk.h> #include <asm/tlb.h> - #include <asm/mach/map.h> #include <plat/sram.h> #include <plat/sdrc.h> #include <plat/serial.h> - -#include "clock2xxx.h" -#include "clock3xxx.h" -#include "clock44xx.h" - -#include "common.h" #include <plat/omap-pm.h> +#include <plat/omap_hwmod.h> +#include <plat/multi.h> + +#include "iomap.h" #include "voltage.h" #include "powerdomain.h" - #include "clockdomain.h" -#include <plat/omap_hwmod.h> -#include <plat/multi.h> #include "common.h" +#include "clock2xxx.h" +#include "clock3xxx.h" +#include "clock44xx.h" /* * The machine specific code may provide the extra mapping besides the * default mapping provided here. */ -#ifdef CONFIG_ARCH_OMAP2 +#if defined(CONFIG_SOC_OMAP2420) || defined(CONFIG_SOC_OMAP2430) static struct map_desc omap24xx_io_desc[] __initdata = { { .virtual = L3_24XX_VIRT, @@ -351,7 +348,6 @@ static int _set_hwmod_postsetup_state(struct omap_hwmod *oh, void *data) static void __init omap_common_init_early(void) { - omap2_check_revision(); omap_init_consistent_dma_size(); } @@ -392,6 +388,7 @@ static void __init omap_hwmod_init_postsetup(void) void __init omap2420_init_early(void) { omap2_set_globals_242x(); + omap2xxx_check_revision(); omap_common_init_early(); omap2xxx_voltagedomains_init(); omap242x_powerdomains_init(); @@ -406,6 +403,7 @@ void __init omap2420_init_early(void) void __init omap2430_init_early(void) { omap2_set_globals_243x(); + omap2xxx_check_revision(); omap_common_init_early(); omap2xxx_voltagedomains_init(); omap243x_powerdomains_init(); @@ -424,6 +422,8 @@ void __init omap2430_init_early(void) void __init omap3_init_early(void) { omap2_set_globals_3xxx(); + omap3xxx_check_revision(); + omap3xxx_check_features(); omap_common_init_early(); omap3xxx_voltagedomains_init(); omap3xxx_powerdomains_init(); @@ -456,6 +456,8 @@ void __init am35xx_init_early(void) void __init ti81xx_init_early(void) { omap2_set_globals_ti81xx(); + omap3xxx_check_revision(); + ti81xx_check_features(); omap_common_init_early(); omap3xxx_voltagedomains_init(); omap3xxx_powerdomains_init(); @@ -470,6 +472,8 @@ void __init ti81xx_init_early(void) void __init omap4430_init_early(void) { omap2_set_globals_443x(); + omap4xxx_check_revision(); + omap4xxx_check_features(); omap_common_init_early(); omap44xx_voltagedomains_init(); omap44xx_powerdomains_init(); @@ -490,43 +494,3 @@ void __init omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0, _omap2_init_reprogram_sdrc(); } } - -/* - * NOTE: Please use ioremap + __raw_read/write where possible instead of these - */ - -u8 omap_readb(u32 pa) -{ - return __raw_readb(OMAP2_L4_IO_ADDRESS(pa)); -} -EXPORT_SYMBOL(omap_readb); - -u16 omap_readw(u32 pa) -{ - return __raw_readw(OMAP2_L4_IO_ADDRESS(pa)); -} -EXPORT_SYMBOL(omap_readw); - -u32 omap_readl(u32 pa) -{ - return __raw_readl(OMAP2_L4_IO_ADDRESS(pa)); -} -EXPORT_SYMBOL(omap_readl); - -void omap_writeb(u8 v, u32 pa) -{ - __raw_writeb(v, OMAP2_L4_IO_ADDRESS(pa)); -} -EXPORT_SYMBOL(omap_writeb); - -void omap_writew(u16 v, u32 pa) -{ - __raw_writew(v, OMAP2_L4_IO_ADDRESS(pa)); -} -EXPORT_SYMBOL(omap_writew); - -void omap_writel(u32 v, u32 pa) -{ - __raw_writel(v, OMAP2_L4_IO_ADDRESS(pa)); -} -EXPORT_SYMBOL(omap_writel); diff --git a/arch/arm/plat-omap/include/plat/io.h b/arch/arm/mach-omap2/iomap.h index 0696bae1818b..0812b154f5b5 100644 --- a/arch/arm/plat-omap/include/plat/io.h +++ b/arch/arm/mach-omap2/iomap.h @@ -1,13 +1,5 @@ /* - * arch/arm/plat-omap/include/mach/io.h - * - * IO definitions for TI OMAP processors and boards - * - * Copied from arch/arm/mach-sa1100/include/mach/io.h - * Copyright (C) 1997-1999 Russell King - * - * Copyright (C) 2009 Texas Instruments - * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> + * IO mappings for OMAP2+ * * 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 @@ -25,48 +17,14 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * 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., + * 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., * 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Modifications: - * 06-12-1997 RMK Created. - * 07-04-1999 RMK Major cleanup - */ - -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -#include <mach/hardware.h> - -#define IO_SPACE_LIMIT 0xffffffff - -/* - * We don't actually have real ISA nor PCI buses, but there is so many - * drivers out there that might just work if we fake them... */ -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -/* - * ---------------------------------------------------------------------------- - * I/O mapping - * ---------------------------------------------------------------------------- - */ - -#ifdef __ASSEMBLER__ -#define IOMEM(x) (x) -#else -#define IOMEM(x) ((void __force __iomem *)(x)) -#endif - -#define OMAP1_IO_OFFSET 0x01000000 /* Virtual IO = 0xfefb0000 */ -#define OMAP1_IO_ADDRESS(pa) IOMEM((pa) - OMAP1_IO_OFFSET) #define OMAP2_L3_IO_OFFSET 0x90000000 #define OMAP2_L3_IO_ADDRESS(pa) IOMEM((pa) + OMAP2_L3_IO_OFFSET) /* L3 */ - #define OMAP2_L4_IO_OFFSET 0xb2000000 #define OMAP2_L4_IO_ADDRESS(pa) IOMEM((pa) + OMAP2_L4_IO_OFFSET) /* L4 */ @@ -87,16 +45,6 @@ /* * ---------------------------------------------------------------------------- - * Omap1 specific IO mapping - * ---------------------------------------------------------------------------- - */ - -#define OMAP1_IO_PHYS 0xFFFB0000 -#define OMAP1_IO_SIZE 0x40000 -#define OMAP1_IO_VIRT (OMAP1_IO_PHYS - OMAP1_IO_OFFSET) - -/* - * ---------------------------------------------------------------------------- * Omap2 specific IO mapping * ---------------------------------------------------------------------------- */ @@ -247,31 +195,3 @@ /* 0x4e000000 --> 0xfd300000 */ #define OMAP44XX_DMM_SIZE SZ_1M #define OMAP44XX_DMM_VIRT (OMAP44XX_EMIF2_VIRT + OMAP44XX_EMIF2_SIZE) -/* - * ---------------------------------------------------------------------------- - * Omap specific register access - * ---------------------------------------------------------------------------- - */ - -#ifndef __ASSEMBLER__ - -/* - * NOTE: Please use ioremap + __raw_read/write where possible instead of these - */ - -extern u8 omap_readb(u32 pa); -extern u16 omap_readw(u32 pa); -extern u32 omap_readl(u32 pa); -extern void omap_writeb(u8 v, u32 pa); -extern void omap_writew(u16 v, u32 pa); -extern void omap_writel(u32 v, u32 pa); - -struct omap_sdrc_params; -extern void omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0, - struct omap_sdrc_params *sdrc_cs1); - -extern void __init omap_init_consistent_dma_size(void); - -#endif - -#endif diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c index 1fef061f7927..65f0d2571c9a 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c @@ -11,13 +11,20 @@ * for more details. */ #include <linux/kernel.h> +#include <linux/module.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/io.h> -#include <mach/hardware.h> + #include <asm/exception.h> #include <asm/mach/irq.h> +#include <linux/irqdomain.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <mach/hardware.h> + +#include "iomap.h" /* selected INTC register offsets */ @@ -57,6 +64,8 @@ static struct omap_irq_bank { }, }; +static struct irq_domain *domain; + /* Structure to save interrupt controller context */ struct omap3_intc_regs { u32 sysconfig; @@ -147,17 +156,27 @@ omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num) IRQ_NOREQUEST | IRQ_NOPROBE, 0); } -static void __init omap_init_irq(u32 base, int nr_irqs) +static void __init omap_init_irq(u32 base, int nr_irqs, + struct device_node *node) { void __iomem *omap_irq_base; unsigned long nr_of_irqs = 0; unsigned int nr_banks = 0; - int i, j; + int i, j, irq_base; omap_irq_base = ioremap(base, SZ_4K); if (WARN_ON(!omap_irq_base)) return; + irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0); + if (irq_base < 0) { + pr_warn("Couldn't allocate IRQ numbers\n"); + irq_base = 0; + } + + domain = irq_domain_add_legacy(node, nr_irqs, irq_base, 0, + &irq_domain_simple_ops, NULL); + for (i = 0; i < ARRAY_SIZE(irq_banks); i++) { struct omap_irq_bank *bank = irq_banks + i; @@ -166,36 +185,36 @@ static void __init omap_init_irq(u32 base, int nr_irqs) /* Static mapping, never released */ bank->base_reg = ioremap(base, SZ_4K); if (!bank->base_reg) { - printk(KERN_ERR "Could not ioremap irq bank%i\n", i); + pr_err("Could not ioremap irq bank%i\n", i); continue; } omap_irq_bank_init_one(bank); for (j = 0; j < bank->nr_irqs; j += 32) - omap_alloc_gc(bank->base_reg + j, j, 32); + omap_alloc_gc(bank->base_reg + j, j + irq_base, 32); nr_of_irqs += bank->nr_irqs; nr_banks++; } - printk(KERN_INFO "Total of %ld interrupts on %d active controller%s\n", - nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : ""); + pr_info("Total of %ld interrupts on %d active controller%s\n", + nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : ""); } void __init omap2_init_irq(void) { - omap_init_irq(OMAP24XX_IC_BASE, 96); + omap_init_irq(OMAP24XX_IC_BASE, 96, NULL); } void __init omap3_init_irq(void) { - omap_init_irq(OMAP34XX_IC_BASE, 96); + omap_init_irq(OMAP34XX_IC_BASE, 96, NULL); } void __init ti81xx_init_irq(void) { - omap_init_irq(OMAP34XX_IC_BASE, 128); + omap_init_irq(OMAP34XX_IC_BASE, 128, NULL); } static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs *regs) @@ -225,8 +244,10 @@ out: irqnr = readl_relaxed(base_addr + INTCPS_SIR_IRQ_OFFSET); irqnr &= ACTIVEIRQ_MASK; - if (irqnr) + if (irqnr) { + irqnr = irq_find_mapping(domain, irqnr); handle_IRQ(irqnr, regs); + } } while (irqnr); } @@ -236,6 +257,28 @@ asmlinkage void __exception_irq_entry omap2_intc_handle_irq(struct pt_regs *regs omap_intc_handle_irq(base_addr, regs); } +int __init omap_intc_of_init(struct device_node *node, + struct device_node *parent) +{ + struct resource res; + u32 nr_irqs = 96; + + if (WARN_ON(!node)) + return -ENODEV; + + if (of_address_to_resource(node, 0, &res)) { + WARN(1, "unable to get intc registers\n"); + return -EINVAL; + } + + if (of_property_read_u32(node, "ti,intc-size", &nr_irqs)) + pr_warn("unable to get intc-size, default to %d\n", nr_irqs); + + omap_init_irq(res.start, nr_irqs, of_node_get(node)); + + return 0; +} + #ifdef CONFIG_ARCH_OMAP3 static struct omap3_intc_regs intc_context[ARRAY_SIZE(irq_banks)]; diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index ecc039e794db..577cb77db26c 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c @@ -158,7 +158,7 @@ static int omap3_enable_st_clock(unsigned int id, bool enable) return 0; } -static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused) +static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused) { int id, count = 1; char *name = "omap-mcbsp"; diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index 611a0e3d54ca..65c33911341f 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -35,7 +35,6 @@ #include <linux/irq.h> #include <linux/interrupt.h> -#include <asm/system.h> #include <plat/omap_hwmod.h> @@ -100,8 +99,8 @@ void omap_mux_write_array(struct omap_mux_partition *partition, static char *omap_mux_options; -static int _omap_mux_init_gpio(struct omap_mux_partition *partition, - int gpio, int val) +static int __init _omap_mux_init_gpio(struct omap_mux_partition *partition, + int gpio, int val) { struct omap_mux_entry *e; struct omap_mux *gpio_mux = NULL; @@ -145,7 +144,7 @@ static int _omap_mux_init_gpio(struct omap_mux_partition *partition, return 0; } -int omap_mux_init_gpio(int gpio, int val) +int __init omap_mux_init_gpio(int gpio, int val) { struct omap_mux_partition *partition; int ret; @@ -159,9 +158,9 @@ int omap_mux_init_gpio(int gpio, int val) return -ENODEV; } -static int _omap_mux_get_by_name(struct omap_mux_partition *partition, - const char *muxname, - struct omap_mux **found_mux) +static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition, + const char *muxname, + struct omap_mux **found_mux) { struct omap_mux *mux = NULL; struct omap_mux_entry *e; @@ -218,7 +217,7 @@ static int _omap_mux_get_by_name(struct omap_mux_partition *partition, return -ENODEV; } -static int +static int __init omap_mux_get_by_name(const char *muxname, struct omap_mux_partition **found_partition, struct omap_mux **found_mux) @@ -240,7 +239,7 @@ omap_mux_get_by_name(const char *muxname, return -ENODEV; } -int omap_mux_init_signal(const char *muxname, int val) +int __init omap_mux_init_signal(const char *muxname, int val) { struct omap_mux_partition *partition = NULL; struct omap_mux *mux = NULL; diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h index 2132308ad1e4..69fe060a0b75 100644 --- a/arch/arm/mach-omap2/mux.h +++ b/arch/arm/mach-omap2/mux.h @@ -246,7 +246,7 @@ static inline void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state) { } -static struct omap_board_mux *board_mux __initdata __maybe_unused; +static struct omap_board_mux *board_mux __maybe_unused; #endif diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c index adbe4d8c7caf..56c345b8b931 100644 --- a/arch/arm/mach-omap2/omap-hotplug.c +++ b/arch/arm/mach-omap2/omap-hotplug.c @@ -33,7 +33,7 @@ int platform_cpu_kill(unsigned int cpu) * platform-specific code to shutdown a CPU * Called with IRQs disabled */ -void platform_cpu_die(unsigned int cpu) +void __ref platform_cpu_die(unsigned int cpu) { unsigned int this_cpu; diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index 1d5d01056558..13670aa84e58 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -46,7 +46,6 @@ #include <asm/cacheflush.h> #include <asm/tlbflush.h> #include <asm/smp_scu.h> -#include <asm/system.h> #include <asm/pgalloc.h> #include <asm/suspend.h> #include <asm/hardware/cache-l2x0.h> @@ -263,12 +262,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) * In MPUSS OSWR or device OFF, interrupt controller contest is lost. */ mpuss_clear_prev_logic_pwrst(); - pwrdm_clear_all_prev_pwrst(mpuss_pd); if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) && (pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF)) save_state = 2; - clear_cpu_prev_pwrst(cpu); cpu_clear_prev_logic_pwrst(cpu); set_cpu_next_pwrst(cpu, power_state); set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume)); @@ -300,7 +297,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) * @cpu : CPU ID * @power_state: CPU low power state. */ -int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) +int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) { unsigned int cpu_state = 0; diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index c1bf3ef0ba02..deffbf1c9627 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -23,11 +23,12 @@ #include <asm/cacheflush.h> #include <asm/hardware/gic.h> #include <asm/smp_scu.h> + #include <mach/hardware.h> #include <mach/omap-secure.h> +#include "iomap.h" #include "common.h" - #include "clockdomain.h" /* SCU base address */ diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index d3d8971d7f30..42cd7fb52414 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -43,7 +43,6 @@ static void __iomem *wakeupgen_base; static void __iomem *sar_base; -static DEFINE_PER_CPU(u32 [NR_REG_BANKS], irqmasks); static DEFINE_SPINLOCK(wakeupgen_lock); static unsigned int irq_target_cpu[NR_IRQS]; @@ -67,14 +66,6 @@ static inline void sar_writel(u32 val, u32 offset, u8 idx) __raw_writel(val, sar_base + offset + (idx * 4)); } -static void _wakeupgen_set_all(unsigned int cpu, unsigned int reg) -{ - u8 i; - - for (i = 0; i < NR_REG_BANKS; i++) - wakeupgen_writel(reg, i, cpu); -} - static inline int _wakeupgen_get_irq_info(u32 irq, u32 *bit_posn, u8 *reg_index) { unsigned int spi_irq; @@ -130,22 +121,6 @@ static void _wakeupgen_set(unsigned int irq, unsigned int cpu) wakeupgen_writel(val, i, cpu); } -static void _wakeupgen_save_masks(unsigned int cpu) -{ - u8 i; - - for (i = 0; i < NR_REG_BANKS; i++) - per_cpu(irqmasks, cpu)[i] = wakeupgen_readl(i, cpu); -} - -static void _wakeupgen_restore_masks(unsigned int cpu) -{ - u8 i; - - for (i = 0; i < NR_REG_BANKS; i++) - wakeupgen_writel(per_cpu(irqmasks, cpu)[i], i, cpu); -} - /* * Architecture specific Mask extension */ @@ -170,6 +145,33 @@ static void wakeupgen_unmask(struct irq_data *d) spin_unlock_irqrestore(&wakeupgen_lock, flags); } +#ifdef CONFIG_HOTPLUG_CPU +static DEFINE_PER_CPU(u32 [NR_REG_BANKS], irqmasks); + +static void _wakeupgen_save_masks(unsigned int cpu) +{ + u8 i; + + for (i = 0; i < NR_REG_BANKS; i++) + per_cpu(irqmasks, cpu)[i] = wakeupgen_readl(i, cpu); +} + +static void _wakeupgen_restore_masks(unsigned int cpu) +{ + u8 i; + + for (i = 0; i < NR_REG_BANKS; i++) + wakeupgen_writel(per_cpu(irqmasks, cpu)[i], i, cpu); +} + +static void _wakeupgen_set_all(unsigned int cpu, unsigned int reg) +{ + u8 i; + + for (i = 0; i < NR_REG_BANKS; i++) + wakeupgen_writel(reg, i, cpu); +} + /* * Mask or unmask all interrupts on given CPU. * 0 = Mask all interrupts on the 'cpu' @@ -191,6 +193,7 @@ static void wakeupgen_irqmask_all(unsigned int cpu, unsigned int set) } spin_unlock_irqrestore(&wakeupgen_lock, flags); } +#endif #ifdef CONFIG_CPU_PM /* diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index eba6cd3816f5..2c27fdb61e66 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -1395,7 +1395,7 @@ static int _read_hardreset(struct omap_hwmod *oh, const char *name) */ static int _ocp_softreset(struct omap_hwmod *oh) { - u32 v; + u32 v, softrst_mask; int c = 0; int ret = 0; @@ -1427,11 +1427,13 @@ static int _ocp_softreset(struct omap_hwmod *oh) oh->class->sysc->syss_offs) & SYSS_RESETDONE_MASK), MAX_MODULE_SOFTRESET_WAIT, c); - else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) + else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) { + softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift); omap_test_timeout(!(omap_hwmod_read(oh, oh->class->sysc->sysc_offs) - & SYSC_TYPE2_SOFTRESET_MASK), + & softrst_mask), MAX_MODULE_SOFTRESET_WAIT, c); + } if (c == MAX_MODULE_SOFTRESET_WAIT) pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n", @@ -1477,6 +1479,11 @@ static int _reset(struct omap_hwmod *oh) ret = (oh->class->reset) ? oh->class->reset(oh) : _ocp_softreset(oh); + if (oh->class->sysc) { + _update_sysc_cache(oh); + _enable_sysc(oh); + } + return ret; } @@ -1786,20 +1793,9 @@ static int _setup(struct omap_hwmod *oh, void *data) return 0; } - if (!(oh->flags & HWMOD_INIT_NO_RESET)) { + if (!(oh->flags & HWMOD_INIT_NO_RESET)) _reset(oh); - /* - * OCP_SYSCONFIG bits need to be reprogrammed after a softreset. - * The _enable() function should be split to - * avoid the rewrite of the OCP_SYSCONFIG register. - */ - if (oh->class->sysc) { - _update_sysc_cache(oh); - _enable_sysc(oh); - } - } - postsetup_state = oh->_postsetup_state; if (postsetup_state == _HWMOD_STATE_UNKNOWN) postsetup_state = _HWMOD_STATE_ENABLED; @@ -1907,20 +1903,10 @@ void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs) */ int omap_hwmod_softreset(struct omap_hwmod *oh) { - u32 v; - int ret; - - if (!oh || !(oh->_sysc_cache)) + if (!oh) return -EINVAL; - v = oh->_sysc_cache; - ret = _set_softreset(oh, &v); - if (ret) - goto error; - _write_sysconfig(v, oh); - -error: - return ret; + return _ocp_softreset(oh); } /** @@ -2463,26 +2449,28 @@ int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh, * @oh: struct omap_hwmod * * * Sets the module OCP socket ENAWAKEUP bit to allow the module to - * send wakeups to the PRCM. Eventually this should sets PRCM wakeup - * registers to cause the PRCM to receive wakeup events from the - * module. Does not set any wakeup routing registers beyond this - * point - if the module is to wake up any other module or subsystem, - * that must be set separately. Called by omap_device code. Returns - * -EINVAL on error or 0 upon success. + * send wakeups to the PRCM, and enable I/O ring wakeup events for + * this IP block if it has dynamic mux entries. Eventually this + * should set PRCM wakeup registers to cause the PRCM to receive + * wakeup events from the module. Does not set any wakeup routing + * registers beyond this point - if the module is to wake up any other + * module or subsystem, that must be set separately. Called by + * omap_device code. Returns -EINVAL on error or 0 upon success. */ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh) { unsigned long flags; u32 v; - if (!oh->class->sysc || - !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) - return -EINVAL; - spin_lock_irqsave(&oh->_lock, flags); - v = oh->_sysc_cache; - _enable_wakeup(oh, &v); - _write_sysconfig(v, oh); + + if (oh->class->sysc && + (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) { + v = oh->_sysc_cache; + _enable_wakeup(oh, &v); + _write_sysconfig(v, oh); + } + _set_idle_ioring_wakeup(oh, true); spin_unlock_irqrestore(&oh->_lock, flags); @@ -2494,26 +2482,28 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh) * @oh: struct omap_hwmod * * * Clears the module OCP socket ENAWAKEUP bit to prevent the module - * from sending wakeups to the PRCM. Eventually this should clear - * PRCM wakeup registers to cause the PRCM to ignore wakeup events - * from the module. Does not set any wakeup routing registers beyond - * this point - if the module is to wake up any other module or - * subsystem, that must be set separately. Called by omap_device - * code. Returns -EINVAL on error or 0 upon success. + * from sending wakeups to the PRCM, and disable I/O ring wakeup + * events for this IP block if it has dynamic mux entries. Eventually + * this should clear PRCM wakeup registers to cause the PRCM to ignore + * wakeup events from the module. Does not set any wakeup routing + * registers beyond this point - if the module is to wake up any other + * module or subsystem, that must be set separately. Called by + * omap_device code. Returns -EINVAL on error or 0 upon success. */ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh) { unsigned long flags; u32 v; - if (!oh->class->sysc || - !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) - return -EINVAL; - spin_lock_irqsave(&oh->_lock, flags); - v = oh->_sysc_cache; - _disable_wakeup(oh, &v); - _write_sysconfig(v, oh); + + if (oh->class->sysc && + (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) { + v = oh->_sysc_cache; + _disable_wakeup(oh, &v); + _write_sysconfig(v, oh); + } + _set_idle_ioring_wakeup(oh, false); spin_unlock_irqrestore(&oh->_lock, flags); diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 3c8dd928628e..34b9766d1d23 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -29,6 +29,7 @@ #include "omap_hwmod_common_data.h" +#include "smartreflex.h" #include "prm-regbits-34xx.h" #include "cm-regbits-34xx.h" #include "wd_timer.h" @@ -376,6 +377,16 @@ static struct omap_hwmod_ocp_if omap3_l4_core__i2c3 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +static struct omap_hwmod_irq_info omap3_smartreflex_mpu_irqs[] = { + { .irq = 18}, + { .irq = -1 } +}; + +static struct omap_hwmod_irq_info omap3_smartreflex_core_irqs[] = { + { .irq = 19}, + { .irq = -1 } +}; + /* L4 CORE -> SR1 interface */ static struct omap_hwmod_addr_space omap3_sr1_addr_space[] = { { @@ -2664,6 +2675,10 @@ static struct omap_hwmod_class omap36xx_smartreflex_hwmod_class = { }; /* SR1 */ +static struct omap_smartreflex_dev_attr sr1_dev_attr = { + .sensor_voltdm_name = "mpu_iva", +}; + static struct omap_hwmod_ocp_if *omap3_sr1_slaves[] = { &omap3_l4_core__sr1, }; @@ -2672,7 +2687,6 @@ static struct omap_hwmod omap34xx_sr1_hwmod = { .name = "sr1_hwmod", .class = &omap34xx_smartreflex_hwmod_class, .main_clk = "sr1_fck", - .vdd_name = "mpu_iva", .prcm = { .omap2 = { .prcm_reg_id = 1, @@ -2684,6 +2698,8 @@ static struct omap_hwmod omap34xx_sr1_hwmod = { }, .slaves = omap3_sr1_slaves, .slaves_cnt = ARRAY_SIZE(omap3_sr1_slaves), + .dev_attr = &sr1_dev_attr, + .mpu_irqs = omap3_smartreflex_mpu_irqs, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; @@ -2691,7 +2707,6 @@ static struct omap_hwmod omap36xx_sr1_hwmod = { .name = "sr1_hwmod", .class = &omap36xx_smartreflex_hwmod_class, .main_clk = "sr1_fck", - .vdd_name = "mpu_iva", .prcm = { .omap2 = { .prcm_reg_id = 1, @@ -2703,9 +2718,15 @@ static struct omap_hwmod omap36xx_sr1_hwmod = { }, .slaves = omap3_sr1_slaves, .slaves_cnt = ARRAY_SIZE(omap3_sr1_slaves), + .dev_attr = &sr1_dev_attr, + .mpu_irqs = omap3_smartreflex_mpu_irqs, }; /* SR2 */ +static struct omap_smartreflex_dev_attr sr2_dev_attr = { + .sensor_voltdm_name = "core", +}; + static struct omap_hwmod_ocp_if *omap3_sr2_slaves[] = { &omap3_l4_core__sr2, }; @@ -2714,7 +2735,6 @@ static struct omap_hwmod omap34xx_sr2_hwmod = { .name = "sr2_hwmod", .class = &omap34xx_smartreflex_hwmod_class, .main_clk = "sr2_fck", - .vdd_name = "core", .prcm = { .omap2 = { .prcm_reg_id = 1, @@ -2726,6 +2746,8 @@ static struct omap_hwmod omap34xx_sr2_hwmod = { }, .slaves = omap3_sr2_slaves, .slaves_cnt = ARRAY_SIZE(omap3_sr2_slaves), + .dev_attr = &sr2_dev_attr, + .mpu_irqs = omap3_smartreflex_core_irqs, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; @@ -2733,7 +2755,6 @@ static struct omap_hwmod omap36xx_sr2_hwmod = { .name = "sr2_hwmod", .class = &omap36xx_smartreflex_hwmod_class, .main_clk = "sr2_fck", - .vdd_name = "core", .prcm = { .omap2 = { .prcm_reg_id = 1, @@ -2745,6 +2766,8 @@ static struct omap_hwmod omap36xx_sr2_hwmod = { }, .slaves = omap3_sr2_slaves, .slaves_cnt = ARRAY_SIZE(omap3_sr2_slaves), + .dev_attr = &sr2_dev_attr, + .mpu_irqs = omap3_smartreflex_core_irqs, }; /* diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index ef0524c10a84..cc9bd106a854 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -28,12 +28,12 @@ #include <plat/mcspi.h> #include <plat/mcbsp.h> #include <plat/mmc.h> -#include <plat/i2c.h> #include <plat/dmtimer.h> #include <plat/common.h> #include "omap_hwmod_common_data.h" +#include "smartreflex.h" #include "cm1_44xx.h" #include "cm2_44xx.h" #include "prm44xx.h" @@ -2996,6 +2996,11 @@ static struct omap_hwmod_ocp_if *omap44xx_mcbsp1_slaves[] = { &omap44xx_l4_abe__mcbsp1_dma, }; +static struct omap_hwmod_opt_clk mcbsp1_opt_clks[] = { + { .role = "pad_fck", .clk = "pad_clks_ck" }, + { .role = "prcm_clk", .clk = "mcbsp1_sync_mux_ck" }, +}; + static struct omap_hwmod omap44xx_mcbsp1_hwmod = { .name = "mcbsp1", .class = &omap44xx_mcbsp_hwmod_class, @@ -3012,6 +3017,8 @@ static struct omap_hwmod omap44xx_mcbsp1_hwmod = { }, .slaves = omap44xx_mcbsp1_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp1_slaves), + .opt_clks = mcbsp1_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp1_opt_clks), }; /* mcbsp2 */ @@ -3071,6 +3078,11 @@ static struct omap_hwmod_ocp_if *omap44xx_mcbsp2_slaves[] = { &omap44xx_l4_abe__mcbsp2_dma, }; +static struct omap_hwmod_opt_clk mcbsp2_opt_clks[] = { + { .role = "pad_fck", .clk = "pad_clks_ck" }, + { .role = "prcm_clk", .clk = "mcbsp2_sync_mux_ck" }, +}; + static struct omap_hwmod omap44xx_mcbsp2_hwmod = { .name = "mcbsp2", .class = &omap44xx_mcbsp_hwmod_class, @@ -3087,6 +3099,8 @@ static struct omap_hwmod omap44xx_mcbsp2_hwmod = { }, .slaves = omap44xx_mcbsp2_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp2_slaves), + .opt_clks = mcbsp2_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp2_opt_clks), }; /* mcbsp3 */ @@ -3146,6 +3160,11 @@ static struct omap_hwmod_ocp_if *omap44xx_mcbsp3_slaves[] = { &omap44xx_l4_abe__mcbsp3_dma, }; +static struct omap_hwmod_opt_clk mcbsp3_opt_clks[] = { + { .role = "pad_fck", .clk = "pad_clks_ck" }, + { .role = "prcm_clk", .clk = "mcbsp3_sync_mux_ck" }, +}; + static struct omap_hwmod omap44xx_mcbsp3_hwmod = { .name = "mcbsp3", .class = &omap44xx_mcbsp_hwmod_class, @@ -3162,6 +3181,8 @@ static struct omap_hwmod omap44xx_mcbsp3_hwmod = { }, .slaves = omap44xx_mcbsp3_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp3_slaves), + .opt_clks = mcbsp3_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp3_opt_clks), }; /* mcbsp4 */ @@ -3200,6 +3221,11 @@ static struct omap_hwmod_ocp_if *omap44xx_mcbsp4_slaves[] = { &omap44xx_l4_per__mcbsp4, }; +static struct omap_hwmod_opt_clk mcbsp4_opt_clks[] = { + { .role = "pad_fck", .clk = "pad_clks_ck" }, + { .role = "prcm_clk", .clk = "mcbsp4_sync_mux_ck" }, +}; + static struct omap_hwmod omap44xx_mcbsp4_hwmod = { .name = "mcbsp4", .class = &omap44xx_mcbsp_hwmod_class, @@ -3216,6 +3242,8 @@ static struct omap_hwmod omap44xx_mcbsp4_hwmod = { }, .slaves = omap44xx_mcbsp4_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp4_slaves), + .opt_clks = mcbsp4_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(mcbsp4_opt_clks), }; /* @@ -3963,6 +3991,10 @@ static struct omap_hwmod_class omap44xx_smartreflex_hwmod_class = { }; /* smartreflex_core */ +static struct omap_smartreflex_dev_attr smartreflex_core_dev_attr = { + .sensor_voltdm_name = "core", +}; + static struct omap_hwmod omap44xx_smartreflex_core_hwmod; static struct omap_hwmod_irq_info omap44xx_smartreflex_core_irqs[] = { { .irq = 19 + OMAP44XX_IRQ_GIC_START }, @@ -3999,7 +4031,6 @@ static struct omap_hwmod omap44xx_smartreflex_core_hwmod = { .mpu_irqs = omap44xx_smartreflex_core_irqs, .main_clk = "smartreflex_core_fck", - .vdd_name = "core", .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET, @@ -4009,9 +4040,14 @@ static struct omap_hwmod omap44xx_smartreflex_core_hwmod = { }, .slaves = omap44xx_smartreflex_core_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_slaves), + .dev_attr = &smartreflex_core_dev_attr, }; /* smartreflex_iva */ +static struct omap_smartreflex_dev_attr smartreflex_iva_dev_attr = { + .sensor_voltdm_name = "iva", +}; + static struct omap_hwmod omap44xx_smartreflex_iva_hwmod; static struct omap_hwmod_irq_info omap44xx_smartreflex_iva_irqs[] = { { .irq = 102 + OMAP44XX_IRQ_GIC_START }, @@ -4047,7 +4083,6 @@ static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = { .clkdm_name = "l4_ao_clkdm", .mpu_irqs = omap44xx_smartreflex_iva_irqs, .main_clk = "smartreflex_iva_fck", - .vdd_name = "iva", .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET, @@ -4057,9 +4092,14 @@ static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = { }, .slaves = omap44xx_smartreflex_iva_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_slaves), + .dev_attr = &smartreflex_iva_dev_attr, }; /* smartreflex_mpu */ +static struct omap_smartreflex_dev_attr smartreflex_mpu_dev_attr = { + .sensor_voltdm_name = "mpu", +}; + static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod; static struct omap_hwmod_irq_info omap44xx_smartreflex_mpu_irqs[] = { { .irq = 18 + OMAP44XX_IRQ_GIC_START }, @@ -4095,7 +4135,6 @@ static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = { .clkdm_name = "l4_ao_clkdm", .mpu_irqs = omap44xx_smartreflex_mpu_irqs, .main_clk = "smartreflex_mpu_fck", - .vdd_name = "mpu", .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET, @@ -4105,6 +4144,7 @@ static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = { }, .slaves = omap44xx_smartreflex_mpu_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_slaves), + .dev_attr = &smartreflex_mpu_dev_attr, }; /* diff --git a/arch/arm/mach-omap2/opp.c b/arch/arm/mach-omap2/opp.c index 9262a6b47702..de6d46451746 100644 --- a/arch/arm/mach-omap2/opp.c +++ b/arch/arm/mach-omap2/opp.c @@ -64,10 +64,10 @@ int __init omap_init_opp_table(struct omap_opp_def *opp_def, } oh = omap_hwmod_lookup(opp_def->hwmod_name); if (!oh || !oh->od) { - pr_warn("%s: no hwmod or odev for %s, [%d] " + pr_debug("%s: no hwmod or odev for %s, [%d] " "cannot add OPPs.\n", __func__, opp_def->hwmod_name, i); - return -EINVAL; + continue; } dev = &oh->od->pdev->dev; diff --git a/arch/arm/mach-omap2/opp2420_data.c b/arch/arm/mach-omap2/opp2420_data.c index e6dda694fd5c..5037e76e4e23 100644 --- a/arch/arm/mach-omap2/opp2420_data.c +++ b/arch/arm/mach-omap2/opp2420_data.c @@ -28,6 +28,8 @@ * http://repository.maemo.org/pool/diablo/free/k/kernel-source-diablo/ */ +#include <plat/hardware.h> + #include "opp2xxx.h" #include "sdrc.h" #include "clock.h" diff --git a/arch/arm/mach-omap2/opp2430_data.c b/arch/arm/mach-omap2/opp2430_data.c index 1b9596ae201e..750805c528d8 100644 --- a/arch/arm/mach-omap2/opp2430_data.c +++ b/arch/arm/mach-omap2/opp2430_data.c @@ -26,6 +26,8 @@ * This is technically part of the OMAP2xxx clock code. */ +#include <plat/hardware.h> + #include "opp2xxx.h" #include "sdrc.h" #include "clock.h" diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index 4411163e012d..814bcd901596 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c @@ -220,8 +220,8 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *dir) return 0; d = debugfs_create_dir(pwrdm->name, (struct dentry *)dir); - - (void) debugfs_create_file("suspend", S_IRUGO|S_IWUSR, d, + if (!(IS_ERR_OR_NULL(d))) + (void) debugfs_create_file("suspend", S_IRUGO|S_IWUSR, d, (void *)pwrdm, &pwrdm_suspend_fops); return 0; @@ -264,7 +264,7 @@ static int __init pm_dbg_init(void) return 0; d = debugfs_create_dir("pm_debug", NULL); - if (IS_ERR(d)) + if (IS_ERR_OR_NULL(d)) return PTR_ERR(d); (void) debugfs_create_file("count", S_IRUGO, diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 5a65dd04aa38..d0c1c9695996 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -15,11 +15,15 @@ #include <linux/err.h> #include <linux/opp.h> #include <linux/export.h> +#include <linux/suspend.h> + +#include <asm/system_misc.h> #include <plat/omap-pm.h> #include <plat/omap_device.h> #include "common.h" +#include "prcm-common.h" #include "voltage.h" #include "powerdomain.h" #include "clockdomain.h" @@ -28,7 +32,13 @@ static struct omap_device_pm_latency *pm_lats; -static int _init_omap_device(char *name) +/* + * omap_pm_suspend: points to a function that does the SoC-specific + * suspend work + */ +int (*omap_pm_suspend)(void); + +static int __init _init_omap_device(char *name) { struct omap_hwmod *oh; struct platform_device *pdev; @@ -49,7 +59,7 @@ static int _init_omap_device(char *name) /* * Build omap_devices for processors and bus. */ -static void omap2_init_processor_devices(void) +static void __init omap2_init_processor_devices(void) { _init_omap_device("mpu"); if (omap3_has_iva()) @@ -68,32 +78,41 @@ static void omap2_init_processor_devices(void) #define FORCEWAKEUP_SWITCH 0 #define LOWPOWERSTATE_SWITCH 1 +int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused) +{ + if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO) + clkdm_allow_idle(clkdm); + else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP && + atomic_read(&clkdm->usecount) == 0) + clkdm_sleep(clkdm); + return 0; +} + /* * This sets pwrdm state (other than mpu & core. Currently only ON & * RET are supported. */ -int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state) +int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 pwrst) { - u32 cur_state; - int sleep_switch = -1; - int ret = 0; - int hwsup = 0; + u8 curr_pwrst, next_pwrst; + int sleep_switch = -1, ret = 0, hwsup = 0; - if (pwrdm == NULL || IS_ERR(pwrdm)) + if (!pwrdm || IS_ERR(pwrdm)) return -EINVAL; - while (!(pwrdm->pwrsts & (1 << state))) { - if (state == PWRDM_POWER_OFF) + while (!(pwrdm->pwrsts & (1 << pwrst))) { + if (pwrst == PWRDM_POWER_OFF) return ret; - state--; + pwrst--; } - cur_state = pwrdm_read_next_pwrst(pwrdm); - if (cur_state == state) + next_pwrst = pwrdm_read_next_pwrst(pwrdm); + if (next_pwrst == pwrst) return ret; - if (pwrdm_read_pwrst(pwrdm) < PWRDM_POWER_ON) { - if ((pwrdm_read_pwrst(pwrdm) > state) && + curr_pwrst = pwrdm_read_pwrst(pwrdm); + if (curr_pwrst < PWRDM_POWER_ON) { + if ((curr_pwrst > pwrst) && (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) { sleep_switch = LOWPOWERSTATE_SWITCH; } else { @@ -103,12 +122,10 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state) } } - ret = pwrdm_set_next_pwrst(pwrdm, state); - if (ret) { - pr_err("%s: unable to set state of powerdomain: %s\n", + ret = pwrdm_set_next_pwrst(pwrdm, pwrst); + if (ret) + pr_err("%s: unable to set power state of powerdomain: %s\n", __func__, pwrdm->name); - goto err; - } switch (sleep_switch) { case FORCEWAKEUP_SWITCH: @@ -119,16 +136,16 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state) break; case LOWPOWERSTATE_SWITCH: pwrdm_set_lowpwrstchange(pwrdm); + pwrdm_wait_transition(pwrdm); + pwrdm_state_switch(pwrdm); break; - default: - return ret; } - pwrdm_state_switch(pwrdm); -err: return ret; } + + /* * This API is to be called during init to set the various voltage * domains to the voltage as per the opp table. Typically we boot up @@ -199,6 +216,56 @@ exit: return -EINVAL; } +#ifdef CONFIG_SUSPEND +static int omap_pm_enter(suspend_state_t suspend_state) +{ + int ret = 0; + + if (!omap_pm_suspend) + return -ENOENT; /* XXX doublecheck */ + + switch (suspend_state) { + case PM_SUSPEND_STANDBY: + case PM_SUSPEND_MEM: + ret = omap_pm_suspend(); + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static int omap_pm_begin(suspend_state_t state) +{ + disable_hlt(); + if (cpu_is_omap34xx()) + omap_prcm_irq_prepare(); + return 0; +} + +static void omap_pm_end(void) +{ + enable_hlt(); + return; +} + +static void omap_pm_finish(void) +{ + if (cpu_is_omap34xx()) + omap_prcm_irq_complete(); +} + +static const struct platform_suspend_ops omap_pm_ops = { + .begin = omap_pm_begin, + .end = omap_pm_end, + .enter = omap_pm_enter, + .finish = omap_pm_finish, + .valid = suspend_valid_only_mem, +}; + +#endif /* CONFIG_SUSPEND */ + static void __init omap3_init_voltages(void) { if (!cpu_is_omap34xx()) @@ -230,6 +297,14 @@ postcore_initcall(omap2_common_pm_init); static int __init omap2_common_pm_late_init(void) { + /* + * In the case of DT, the PMIC and SR initialization will be done using + * a completely different mechanism. + * Disable this part if a DT blob is available. + */ + if (of_have_populated_dt()) + return 0; + /* Init the voltage layer */ omap_pmic_late_init(); omap_voltage_late_init(); @@ -241,6 +316,10 @@ static int __init omap2_common_pm_late_init(void) /* Smartreflex device init */ omap_devinit_smartreflex(); +#ifdef CONFIG_SUSPEND + suspend_set_ops(&omap_pm_ops); +#endif + return 0; } late_initcall(omap2_common_pm_late_init); diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index b737b11e4499..36fa90b6ece8 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -18,10 +18,11 @@ extern void *omap3_secure_ram_storage; extern void omap3_pm_off_mode_enable(int); extern void omap_sram_idle(void); -extern int omap3_can_sleep(void); extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state); extern int omap3_idle_init(void); extern int omap4_idle_init(void); +extern int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused); +extern int (*omap_pm_suspend)(void); #if defined(CONFIG_PM_OPP) extern int omap3_opp_init(void); diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index 23de98d03841..95442b69ae27 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -26,7 +26,6 @@ #include <linux/module.h> #include <linux/delay.h> #include <linux/clk.h> -#include <linux/io.h> #include <linux/irq.h> #include <linux/time.h> #include <linux/gpio.h> @@ -34,13 +33,15 @@ #include <asm/mach/time.h> #include <asm/mach/irq.h> #include <asm/mach-types.h> +#include <asm/system_misc.h> -#include <mach/irqs.h> #include <plat/clock.h> #include <plat/sram.h> #include <plat/dma.h> #include <plat/board.h> +#include <mach/irqs.h> + #include "common.h" #include "prm2xxx_3xxx.h" #include "prm-regbits-24xx.h" @@ -49,23 +50,9 @@ #include "sdrc.h" #include "pm.h" #include "control.h" - #include "powerdomain.h" #include "clockdomain.h" -#ifdef CONFIG_SUSPEND -static suspend_state_t suspend_state = PM_SUSPEND_ON; -static inline bool is_suspending(void) -{ - return (suspend_state != PM_SUSPEND_ON); -} -#else -static inline bool is_suspending(void) -{ - return false; -} -#endif - static void (*omap2_sram_idle)(void); static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl, void __iomem *sdrc_power); @@ -85,7 +72,7 @@ static int omap2_fclks_active(void) return (f1 | f2) ? 1 : 0; } -static void omap2_enter_full_retention(void) +static int omap2_enter_full_retention(void) { u32 l; @@ -148,6 +135,8 @@ no_sleep: /* Mask future PRCM-to-MPU interrupts */ omap2_prm_write_mod_reg(0x0, OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET); + + return 0; } static int omap2_i2c_active(void) @@ -226,7 +215,6 @@ static int omap2_can_sleep(void) static void omap2_pm_idle(void) { - local_irq_disable(); local_fiq_disable(); if (!omap2_can_sleep()) { @@ -243,78 +231,6 @@ static void omap2_pm_idle(void) out: local_fiq_enable(); - local_irq_enable(); -} - -#ifdef CONFIG_SUSPEND -static int omap2_pm_begin(suspend_state_t state) -{ - disable_hlt(); - suspend_state = state; - return 0; -} - -static int omap2_pm_suspend(void) -{ - u32 wken_wkup, mir1; - - wken_wkup = omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); - wken_wkup &= ~OMAP24XX_EN_GPT1_MASK; - omap2_prm_write_mod_reg(wken_wkup, WKUP_MOD, PM_WKEN); - - /* Mask GPT1 */ - mir1 = omap_readl(0x480fe0a4); - omap_writel(1 << 5, 0x480fe0ac); - - omap2_enter_full_retention(); - - omap_writel(mir1, 0x480fe0a4); - omap2_prm_write_mod_reg(wken_wkup, WKUP_MOD, PM_WKEN); - - return 0; -} - -static int omap2_pm_enter(suspend_state_t state) -{ - int ret = 0; - - switch (state) { - case PM_SUSPEND_STANDBY: - case PM_SUSPEND_MEM: - ret = omap2_pm_suspend(); - break; - default: - ret = -EINVAL; - } - - return ret; -} - -static void omap2_pm_end(void) -{ - suspend_state = PM_SUSPEND_ON; - enable_hlt(); -} - -static const struct platform_suspend_ops omap_pm_ops = { - .begin = omap2_pm_begin, - .enter = omap2_pm_enter, - .end = omap2_pm_end, - .valid = suspend_valid_only_mem, -}; -#else -static const struct platform_suspend_ops __initdata omap_pm_ops; -#endif /* CONFIG_SUSPEND */ - -/* XXX This function should be shareable between OMAP2xxx and OMAP3 */ -static int __init clkdms_setup(struct clockdomain *clkdm, void *unused) -{ - if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO) - clkdm_allow_idle(clkdm); - else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP && - atomic_read(&clkdm->usecount) == 0) - clkdm_sleep(clkdm); - return 0; } static void __init prcm_setup_regs(void) @@ -358,9 +274,13 @@ static void __init prcm_setup_regs(void) clkdm_sleep(gfx_clkdm); /* Enable hardware-supervised idle for all clkdms */ - clkdm_for_each(clkdms_setup, NULL); + clkdm_for_each(omap_pm_clkdms_setup, NULL); clkdm_add_wkdep(mpu_clkdm, wkup_clkdm); +#ifdef CONFIG_SUSPEND + omap_pm_suspend = omap2_enter_full_retention; +#endif + /* REVISIT: Configure number of 32 kHz clock cycles for sys_clk * stabilisation */ omap2_prm_write_mod_reg(15 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD, @@ -461,8 +381,7 @@ static int __init omap2_pm_init(void) omap24xx_cpu_suspend_sz); } - suspend_set_ops(&omap_pm_ops); - pm_idle = omap2_pm_idle; + arm_pm_idle = omap2_pm_idle; return 0; } diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index fc6987578920..703bd1099259 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -31,6 +31,7 @@ #include <trace/events/power.h> #include <asm/suspend.h> +#include <asm/system_misc.h> #include <plat/sram.h> #include "clockdomain.h" @@ -50,10 +51,6 @@ #include "sdrc.h" #include "control.h" -#ifdef CONFIG_SUSPEND -static suspend_state_t suspend_state = PM_SUSPEND_ON; -#endif - /* pm34xx errata defined in pm.h */ u16 pm34xx_errata; @@ -75,16 +72,6 @@ static struct powerdomain *mpu_pwrdm, *neon_pwrdm; static struct powerdomain *core_pwrdm, *per_pwrdm; static struct powerdomain *cam_pwrdm; -static inline void omap3_per_save_context(void) -{ - omap_gpio_save_context(); -} - -static inline void omap3_per_restore_context(void) -{ - omap_gpio_restore_context(); -} - static void omap3_enable_io_chain(void) { int timeout = 0; @@ -166,8 +153,7 @@ static void omap3_save_secure_ram_context(void) pwrdm_set_next_pwrst(mpu_pwrdm, mpu_next_state); /* Following is for error tracking, it should not happen */ if (ret) { - printk(KERN_ERR "save_secure_sram() returns %08x\n", - ret); + pr_err("save_secure_sram() returns %08x\n", ret); while (1) ; } @@ -290,11 +276,6 @@ void omap_sram_idle(void) int core_prev_state, per_prev_state; u32 sdrc_pwr = 0; - pwrdm_clear_all_prev_pwrst(mpu_pwrdm); - pwrdm_clear_all_prev_pwrst(neon_pwrdm); - pwrdm_clear_all_prev_pwrst(core_pwrdm); - pwrdm_clear_all_prev_pwrst(per_pwrdm); - mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm); switch (mpu_next_state) { case PWRDM_POWER_ON: @@ -307,7 +288,7 @@ void omap_sram_idle(void) break; default: /* Invalid state */ - printk(KERN_ERR "Invalid mpu state in sram_idle\n"); + pr_err("Invalid mpu state in sram_idle\n"); return; } @@ -332,8 +313,6 @@ void omap_sram_idle(void) if (per_next_state < PWRDM_POWER_ON) { per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0; omap2_gpio_prepare_for_idle(per_going_off); - if (per_next_state == PWRDM_POWER_OFF) - omap3_per_save_context(); } /* CORE */ @@ -399,8 +378,6 @@ void omap_sram_idle(void) if (per_next_state < PWRDM_POWER_ON) { per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm); omap2_gpio_resume_after_idle(); - if (per_prev_state == PWRDM_POWER_OFF) - omap3_per_restore_context(); } /* Disable IO-PAD and IO-CHAIN wakeup */ @@ -418,10 +395,9 @@ void omap_sram_idle(void) static void omap3_pm_idle(void) { - local_irq_disable(); local_fiq_disable(); - if (omap_irq_pending() || need_resched()) + if (omap_irq_pending()) goto out; trace_power_start(POWER_CSTATE, 1, smp_processor_id()); @@ -434,7 +410,6 @@ static void omap3_pm_idle(void) out: local_fiq_enable(); - local_irq_enable(); } #ifdef CONFIG_SUSPEND @@ -463,66 +438,21 @@ restore: list_for_each_entry(pwrst, &pwrst_list, node) { state = pwrdm_read_prev_pwrst(pwrst->pwrdm); if (state > pwrst->next_state) { - printk(KERN_INFO "Powerdomain (%s) didn't enter " - "target state %d\n", + pr_info("Powerdomain (%s) didn't enter " + "target state %d\n", pwrst->pwrdm->name, pwrst->next_state); ret = -1; } omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state); } if (ret) - printk(KERN_ERR "Could not enter target state in pm_suspend\n"); + pr_err("Could not enter target state in pm_suspend\n"); else - printk(KERN_INFO "Successfully put all powerdomains " - "to target state\n"); + pr_info("Successfully put all powerdomains to target state\n"); return ret; } -static int omap3_pm_enter(suspend_state_t unused) -{ - int ret = 0; - - switch (suspend_state) { - case PM_SUSPEND_STANDBY: - case PM_SUSPEND_MEM: - ret = omap3_pm_suspend(); - break; - default: - ret = -EINVAL; - } - - return ret; -} - -/* Hooks to enable / disable UART interrupts during suspend */ -static int omap3_pm_begin(suspend_state_t state) -{ - disable_hlt(); - suspend_state = state; - omap_prcm_irq_prepare(); - return 0; -} - -static void omap3_pm_end(void) -{ - suspend_state = PM_SUSPEND_ON; - enable_hlt(); - return; -} - -static void omap3_pm_finish(void) -{ - omap_prcm_irq_complete(); -} - -static const struct platform_suspend_ops omap_pm_ops = { - .begin = omap3_pm_begin, - .end = omap3_pm_end, - .enter = omap3_pm_enter, - .finish = omap3_pm_finish, - .valid = suspend_valid_only_mem, -}; #endif /* CONFIG_SUSPEND */ @@ -743,21 +673,6 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) } /* - * Enable hw supervised mode for all clockdomains if it's - * supported. Initiate sleep transition for other clockdomains, if - * they are not used - */ -static int __init clkdms_setup(struct clockdomain *clkdm, void *unused) -{ - if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO) - clkdm_allow_idle(clkdm); - else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP && - atomic_read(&clkdm->usecount) == 0) - clkdm_sleep(clkdm); - return 0; -} - -/* * Push functions to SRAM * * The minimum set of functions is pushed to SRAM for execution: @@ -817,21 +732,22 @@ static int __init omap3_pm_init(void) if (ret) { pr_err("pm: Failed to request pm_io irq\n"); - goto err1; + goto err2; } ret = pwrdm_for_each(pwrdms_setup, NULL); if (ret) { - printk(KERN_ERR "Failed to setup powerdomains\n"); - goto err2; + pr_err("Failed to setup powerdomains\n"); + goto err3; } - (void) clkdm_for_each(clkdms_setup, NULL); + (void) clkdm_for_each(omap_pm_clkdms_setup, NULL); mpu_pwrdm = pwrdm_lookup("mpu_pwrdm"); if (mpu_pwrdm == NULL) { - printk(KERN_ERR "Failed to get mpu_pwrdm\n"); - goto err2; + pr_err("Failed to get mpu_pwrdm\n"); + ret = -EINVAL; + goto err3; } neon_pwrdm = pwrdm_lookup("neon_pwrdm"); @@ -845,10 +761,10 @@ static int __init omap3_pm_init(void) core_clkdm = clkdm_lookup("core_clkdm"); #ifdef CONFIG_SUSPEND - suspend_set_ops(&omap_pm_ops); -#endif /* CONFIG_SUSPEND */ + omap_pm_suspend = omap3_pm_suspend; +#endif - pm_idle = omap3_pm_idle; + arm_pm_idle = omap3_pm_idle; omap3_idle_init(); /* @@ -864,8 +780,8 @@ static int __init omap3_pm_init(void) omap3_secure_ram_storage = kmalloc(0x803F, GFP_KERNEL); if (!omap3_secure_ram_storage) - printk(KERN_ERR "Memory allocation failed when" - "allocating for secure sram context\n"); + pr_err("Memory allocation failed when " + "allocating for secure sram context\n"); local_irq_disable(); local_fiq_disable(); @@ -879,14 +795,17 @@ static int __init omap3_pm_init(void) } omap3_save_scratchpad_contents(); -err1: return ret; -err2: - free_irq(INT_34XX_PRCM_MPU_IRQ, NULL); + +err3: list_for_each_entry_safe(pwrst, tmp, &pwrst_list, node) { list_del(&pwrst->node); kfree(pwrst); } + free_irq(omap_prcm_event_to_irq("io"), omap3_pm_init); +err2: + free_irq(omap_prcm_event_to_irq("wkup"), NULL); +err1: return ret; } diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index c264ef7219c1..885625352429 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -16,6 +16,7 @@ #include <linux/list.h> #include <linux/err.h> #include <linux/slab.h> +#include <asm/system_misc.h> #include "common.h" #include "clockdomain.h" @@ -83,59 +84,8 @@ static int omap4_pm_suspend(void) return 0; } - -static int omap4_pm_enter(suspend_state_t suspend_state) -{ - int ret = 0; - - switch (suspend_state) { - case PM_SUSPEND_STANDBY: - case PM_SUSPEND_MEM: - ret = omap4_pm_suspend(); - break; - default: - ret = -EINVAL; - } - - return ret; -} - -static int omap4_pm_begin(suspend_state_t state) -{ - disable_hlt(); - return 0; -} - -static void omap4_pm_end(void) -{ - enable_hlt(); - return; -} - -static const struct platform_suspend_ops omap_pm_ops = { - .begin = omap4_pm_begin, - .end = omap4_pm_end, - .enter = omap4_pm_enter, - .valid = suspend_valid_only_mem, -}; #endif /* CONFIG_SUSPEND */ -/* - * Enable hardware supervised mode for all clockdomains if it's - * supported. Initiate sleep transition for other clockdomains, if - * they are not used - */ -static int __init clkdms_setup(struct clockdomain *clkdm, void *unused) -{ - if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO) - clkdm_allow_idle(clkdm); - else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP && - atomic_read(&clkdm->usecount) == 0) - clkdm_sleep(clkdm); - return 0; -} - - static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) { struct power_state *pwrst; @@ -173,18 +123,16 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) * omap_default_idle - OMAP4 default ilde routine.' * * Implements OMAP4 memory, IO ordering requirements which can't be addressed - * with default arch_idle() hook. Used by all CPUs with !CONFIG_CPUIDLE and + * with default cpu_do_idle() hook. Used by all CPUs with !CONFIG_CPUIDLE and * by secondary CPU with CONFIG_CPUIDLE. */ static void omap_default_idle(void) { - local_irq_disable(); local_fiq_disable(); omap_do_wfi(); local_fiq_enable(); - local_irq_enable(); } /** @@ -196,7 +144,7 @@ static void omap_default_idle(void) static int __init omap4_pm_init(void) { int ret; - struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm; + struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm, *l4wkup; struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per_clkdm; if (!cpu_is_omap44xx()) @@ -220,14 +168,19 @@ static int __init omap4_pm_init(void) * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as * expected. The hardware recommendation is to enable static * dependencies for these to avoid system lock ups or random crashes. + * The L4 wakeup depedency is added to workaround the OCP sync hardware + * BUG with 32K synctimer which lead to incorrect timer value read + * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which + * are part of L4 wakeup clockdomain. */ mpuss_clkdm = clkdm_lookup("mpuss_clkdm"); emif_clkdm = clkdm_lookup("l3_emif_clkdm"); l3_1_clkdm = clkdm_lookup("l3_1_clkdm"); l3_2_clkdm = clkdm_lookup("l3_2_clkdm"); l4_per_clkdm = clkdm_lookup("l4_per_clkdm"); + l4wkup = clkdm_lookup("l4_wkup_clkdm"); ducati_clkdm = clkdm_lookup("ducati_clkdm"); - if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || + if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || (!l4wkup) || (!l3_2_clkdm) || (!ducati_clkdm) || (!l4_per_clkdm)) goto err2; @@ -235,6 +188,7 @@ static int __init omap4_pm_init(void) ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm); ret |= clkdm_add_wkdep(mpuss_clkdm, l3_2_clkdm); ret |= clkdm_add_wkdep(mpuss_clkdm, l4_per_clkdm); + ret |= clkdm_add_wkdep(mpuss_clkdm, l4wkup); ret |= clkdm_add_wkdep(ducati_clkdm, l3_1_clkdm); ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm); if (ret) { @@ -249,14 +203,14 @@ static int __init omap4_pm_init(void) goto err2; } - (void) clkdm_for_each(clkdms_setup, NULL); + (void) clkdm_for_each(omap_pm_clkdms_setup, NULL); #ifdef CONFIG_SUSPEND - suspend_set_ops(&omap_pm_ops); -#endif /* CONFIG_SUSPEND */ + omap_pm_suspend = omap4_pm_suspend; +#endif - /* Overwrite the default arch_idle() */ - pm_idle = omap_default_idle; + /* Overwrite the default cpu_do_idle() */ + arm_pm_idle = omap_default_idle; omap4_idle_init(); diff --git a/arch/arm/mach-omap2/powerdomain-common.c b/arch/arm/mach-omap2/powerdomain-common.c index f97afff68d6d..c0aeabfcf009 100644 --- a/arch/arm/mach-omap2/powerdomain-common.c +++ b/arch/arm/mach-omap2/powerdomain-common.c @@ -13,6 +13,7 @@ #include <linux/errno.h> #include <linux/kernel.h> +#include <linux/bug.h> #include "pm.h" #include "cm.h" #include "cm-regbits-34xx.h" diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index 8a18d1bd61c8..96ad3dbeac34 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c @@ -972,7 +972,13 @@ int pwrdm_wait_transition(struct powerdomain *pwrdm) int pwrdm_state_switch(struct powerdomain *pwrdm) { - return _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW); + int ret; + + ret = pwrdm_wait_transition(pwrdm); + if (!ret) + ret = _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW); + + return ret; } int pwrdm_clkdm_state_switch(struct clockdomain *clkdm) diff --git a/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c b/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c index 6a17e4ca1d79..0f0a9f1592fe 100644 --- a/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c +++ b/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c @@ -15,6 +15,7 @@ #include <linux/io.h> #include <linux/errno.h> #include <linux/delay.h> +#include <linux/bug.h> #include <plat/prcm.h> diff --git a/arch/arm/mach-omap2/powerdomain44xx.c b/arch/arm/mach-omap2/powerdomain44xx.c index a7880af4b3d9..601325b852a4 100644 --- a/arch/arm/mach-omap2/powerdomain44xx.c +++ b/arch/arm/mach-omap2/powerdomain44xx.c @@ -15,6 +15,7 @@ #include <linux/io.h> #include <linux/errno.h> #include <linux/delay.h> +#include <linux/bug.h> #include "powerdomain.h" #include <plat/prcm.h> diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c index 8ef26daeed68..b7ea468eea32 100644 --- a/arch/arm/mach-omap2/powerdomains3xxx_data.c +++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c @@ -13,6 +13,7 @@ #include <linux/kernel.h> #include <linux/init.h> +#include <linux/bug.h> #include <plat/cpu.h> diff --git a/arch/arm/mach-omap2/prcm_mpu44xx.c b/arch/arm/mach-omap2/prcm_mpu44xx.c index ca669b50f390..928dbd4f20ed 100644 --- a/arch/arm/mach-omap2/prcm_mpu44xx.c +++ b/arch/arm/mach-omap2/prcm_mpu44xx.c @@ -15,8 +15,8 @@ #include <linux/err.h> #include <linux/io.h> +#include "iomap.h" #include "common.h" - #include "prcm_mpu44xx.h" #include "cm-regbits-44xx.h" diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index a1d6154dc120..f106d21ff581 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c @@ -17,11 +17,12 @@ #include <linux/err.h> #include <linux/io.h> -#include "common.h" #include <plat/cpu.h> #include <plat/irqs.h> #include <plat/prcm.h> +#include "iomap.h" +#include "common.h" #include "vp.h" #include "prm44xx.h" #include "prm-regbits-44xx.h" @@ -146,8 +147,9 @@ static inline u32 _read_pending_irq_reg(u16 irqen_offs, u16 irqst_offs) u32 mask, st; /* XXX read mask from RAM? */ - mask = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, irqen_offs); - st = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, irqst_offs); + mask = omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, + irqen_offs); + st = omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, irqst_offs); return mask & st; } @@ -179,7 +181,7 @@ void omap44xx_prm_read_pending_irqs(unsigned long *events) */ void omap44xx_prm_ocp_barrier(void) { - omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, + omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, OMAP4_REVISION_PRM_OFFSET); } @@ -197,19 +199,19 @@ void omap44xx_prm_ocp_barrier(void) void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask) { saved_mask[0] = - omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, + omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, OMAP4_PRM_IRQSTATUS_MPU_OFFSET); saved_mask[1] = - omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, + omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET); - omap4_prm_write_inst_reg(0, OMAP4430_PRM_DEVICE_INST, + omap4_prm_write_inst_reg(0, OMAP4430_PRM_OCP_SOCKET_INST, OMAP4_PRM_IRQENABLE_MPU_OFFSET); - omap4_prm_write_inst_reg(0, OMAP4430_PRM_DEVICE_INST, + omap4_prm_write_inst_reg(0, OMAP4430_PRM_OCP_SOCKET_INST, OMAP4_PRM_IRQENABLE_MPU_2_OFFSET); /* OCP barrier */ - omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, + omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, OMAP4_REVISION_PRM_OFFSET); } @@ -225,9 +227,9 @@ void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask) */ void omap44xx_prm_restore_irqen(u32 *saved_mask) { - omap4_prm_write_inst_reg(saved_mask[0], OMAP4430_PRM_DEVICE_INST, + omap4_prm_write_inst_reg(saved_mask[0], OMAP4430_PRM_OCP_SOCKET_INST, OMAP4_PRM_IRQENABLE_MPU_OFFSET); - omap4_prm_write_inst_reg(saved_mask[1], OMAP4430_PRM_DEVICE_INST, + omap4_prm_write_inst_reg(saved_mask[1], OMAP4430_PRM_OCP_SOCKET_INST, OMAP4_PRM_IRQENABLE_MPU_2_OFFSET); } diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index 860118ab43e2..d28f848897d6 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c @@ -24,7 +24,6 @@ #include <linux/interrupt.h> #include <linux/slab.h> -#include <mach/system.h> #include <plat/common.h> #include <plat/prcm.h> #include <plat/irqs.h> @@ -291,7 +290,7 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) goto err; } - for (i = 0; i <= irq_setup->nr_regs; i++) { + for (i = 0; i < irq_setup->nr_regs; i++) { gc = irq_alloc_generic_chip("PRCM", 1, irq_setup->base_irq + i * 32, prm_base, handle_level_irq); diff --git a/arch/arm/mach-omap2/prminst44xx.c b/arch/arm/mach-omap2/prminst44xx.c index f6de5bc6b12a..9b3898a3ac9b 100644 --- a/arch/arm/mach-omap2/prminst44xx.c +++ b/arch/arm/mach-omap2/prminst44xx.c @@ -16,8 +16,8 @@ #include <linux/err.h> #include <linux/io.h> +#include "iomap.h" #include "common.h" - #include "prm44xx.h" #include "prminst44xx.h" #include "prm-regbits-44xx.h" diff --git a/arch/arm/mach-omap2/sdram-nokia.c b/arch/arm/mach-omap2/sdram-nokia.c index 7479d7ea1379..845c4fd2b125 100644 --- a/arch/arm/mach-omap2/sdram-nokia.c +++ b/arch/arm/mach-omap2/sdram-nokia.c @@ -17,7 +17,6 @@ #include <linux/err.h> #include <linux/io.h> -#include <plat/io.h> #include "common.h" #include <plat/clock.h> #include <plat/sdrc.h> diff --git a/arch/arm/mach-omap2/sdrc2xxx.c b/arch/arm/mach-omap2/sdrc2xxx.c index 791a63cdceb2..1133bb2f632b 100644 --- a/arch/arm/mach-omap2/sdrc2xxx.c +++ b/arch/arm/mach-omap2/sdrc2xxx.c @@ -24,13 +24,15 @@ #include <linux/clk.h> #include <linux/io.h> -#include "common.h" +#include <plat/hardware.h> #include <plat/clock.h> #include <plat/sram.h> +#include <plat/sdrc.h> +#include "iomap.h" +#include "common.h" #include "prm2xxx_3xxx.h" #include "clock.h" -#include <plat/sdrc.h> #include "sdrc.h" /* Memory timing, DLL mode flags */ diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index f590afc1f673..0cdd359a128e 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -54,11 +54,9 @@ struct omap_uart_state { int num; - int can_sleep; struct list_head node; struct omap_hwmod *oh; - struct platform_device *pdev; }; static LIST_HEAD(uart_list); @@ -381,8 +379,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata, oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt); - uart->pdev = pdev; - oh->dev_attr = uart; if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads) diff --git a/arch/arm/mach-omap2/sleep24xx.S b/arch/arm/mach-omap2/sleep24xx.S index b5071a47ec39..d4bf904d84ab 100644 --- a/arch/arm/mach-omap2/sleep24xx.S +++ b/arch/arm/mach-omap2/sleep24xx.S @@ -27,7 +27,6 @@ #include <linux/linkage.h> #include <asm/assembler.h> -#include <mach/io.h> #include <plat/omap24xx.h> diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index f2ea1bd1c691..1f62f23673fb 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -23,10 +23,13 @@ * MA 02111-1307 USA */ #include <linux/linkage.h> + #include <asm/assembler.h> + +#include <plat/hardware.h> #include <plat/sram.h> -#include <mach/io.h> +#include "iomap.h" #include "cm2xxx_3xxx.h" #include "prm2xxx_3xxx.h" #include "sdrc.h" diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S index abd283400490..9f6b83d1b193 100644 --- a/arch/arm/mach-omap2/sleep44xx.S +++ b/arch/arm/mach-omap2/sleep44xx.S @@ -10,7 +10,6 @@ */ #include <linux/linkage.h> -#include <asm/system.h> #include <asm/smp_scu.h> #include <asm/memory.h> #include <asm/hardware/cache-l2x0.h> diff --git a/arch/arm/mach-omap2/smartreflex-class3.c b/arch/arm/mach-omap2/smartreflex-class3.c index 53d9d0a5b39d..955566eefac4 100644 --- a/arch/arm/mach-omap2/smartreflex-class3.c +++ b/arch/arm/mach-omap2/smartreflex-class3.c @@ -29,6 +29,7 @@ static int sr_class3_enable(struct voltagedomain *voltdm) static int sr_class3_disable(struct voltagedomain *voltdm, int is_volt_reset) { + sr_disable_errgen(voltdm); omap_vp_disable(voltdm); sr_disable(voltdm); if (is_volt_reset) diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index 7e755bb0ffc4..008fbd7b9352 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -36,6 +36,12 @@ #define SR_DISABLE_TIMEOUT 200 struct omap_sr { + struct list_head node; + struct platform_device *pdev; + struct omap_sr_nvalue_table *nvalue_table; + struct voltagedomain *voltdm; + struct dentry *dbg_dir; + unsigned int irq; int srid; int ip_type; int nvalue_count; @@ -49,13 +55,7 @@ struct omap_sr { u32 senp_avgweight; u32 senp_mod; u32 senn_mod; - unsigned int irq; void __iomem *base; - struct platform_device *pdev; - struct list_head node; - struct omap_sr_nvalue_table *nvalue_table; - struct voltagedomain *voltdm; - struct dentry *dbg_dir; }; /* sr_list contains all the instances of smartreflex module */ @@ -74,10 +74,6 @@ static inline void sr_modify_reg(struct omap_sr *sr, unsigned offset, u32 mask, u32 value) { u32 reg_val; - u32 errconfig_offs = 0, errconfig_mask = 0; - - reg_val = __raw_readl(sr->base + offset); - reg_val &= ~mask; /* * Smartreflex error config register is special as it contains @@ -88,16 +84,15 @@ static inline void sr_modify_reg(struct omap_sr *sr, unsigned offset, u32 mask, * if they are currently set, but does allow the caller to write * those bits. */ - if (sr->ip_type == SR_TYPE_V1) { - errconfig_offs = ERRCONFIG_V1; - errconfig_mask = ERRCONFIG_STATUS_V1_MASK; - } else if (sr->ip_type == SR_TYPE_V2) { - errconfig_offs = ERRCONFIG_V2; - errconfig_mask = ERRCONFIG_VPBOUNDINTST_V2; - } + if (sr->ip_type == SR_TYPE_V1 && offset == ERRCONFIG_V1) + mask |= ERRCONFIG_STATUS_V1_MASK; + else if (sr->ip_type == SR_TYPE_V2 && offset == ERRCONFIG_V2) + mask |= ERRCONFIG_VPBOUNDINTST_V2; + + reg_val = __raw_readl(sr->base + offset); + reg_val &= ~mask; - if (offset == errconfig_offs) - reg_val &= ~errconfig_mask; + value &= mask; reg_val |= value; @@ -128,21 +123,28 @@ static struct omap_sr *_sr_lookup(struct voltagedomain *voltdm) static irqreturn_t sr_interrupt(int irq, void *data) { - struct omap_sr *sr_info = (struct omap_sr *)data; + struct omap_sr *sr_info = data; u32 status = 0; - if (sr_info->ip_type == SR_TYPE_V1) { + switch (sr_info->ip_type) { + case SR_TYPE_V1: /* Read the status bits */ status = sr_read_reg(sr_info, ERRCONFIG_V1); /* Clear them by writing back */ sr_write_reg(sr_info, ERRCONFIG_V1, status); - } else if (sr_info->ip_type == SR_TYPE_V2) { + break; + case SR_TYPE_V2: /* Read the status bits */ status = sr_read_reg(sr_info, IRQSTATUS); /* Clear them by writing back */ sr_write_reg(sr_info, IRQSTATUS, status); + break; + default: + dev_err(&sr_info->pdev->dev, "UNKNOWN IP type %d\n", + sr_info->ip_type); + return IRQ_NONE; } if (sr_class->notify) @@ -166,6 +168,7 @@ static void sr_set_clk_length(struct omap_sr *sr) __func__); return; } + sys_clk_speed = clk_get_rate(sys_ck); clk_put(sys_ck); @@ -267,7 +270,7 @@ static int sr_late_init(struct omap_sr *sr_info) goto error; } ret = request_irq(sr_info->irq, sr_interrupt, - 0, name, (void *)sr_info); + 0, name, sr_info); if (ret) goto error; disable_irq(sr_info->irq); @@ -288,12 +291,15 @@ error: "not function as desired\n", __func__); kfree(name); kfree(sr_info); + return ret; } static void sr_v1_disable(struct omap_sr *sr) { int timeout = 0; + int errconf_val = ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST | + ERRCONFIG_MCUBOUNDINTST; /* Enable MCUDisableAcknowledge interrupt */ sr_modify_reg(sr, ERRCONFIG_V1, @@ -302,13 +308,13 @@ static void sr_v1_disable(struct omap_sr *sr) /* SRCONFIG - disable SR */ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0); - /* Disable all other SR interrupts and clear the status */ + /* Disable all other SR interrupts and clear the status as needed */ + if (sr_read_reg(sr, ERRCONFIG_V1) & ERRCONFIG_VPBOUNDINTST_V1) + errconf_val |= ERRCONFIG_VPBOUNDINTST_V1; sr_modify_reg(sr, ERRCONFIG_V1, (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_VPBOUNDINTEN_V1), - (ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST | - ERRCONFIG_MCUBOUNDINTST | - ERRCONFIG_VPBOUNDINTST_V1)); + errconf_val); /* * Wait for SR to be disabled. @@ -337,9 +343,17 @@ static void sr_v2_disable(struct omap_sr *sr) /* SRCONFIG - disable SR */ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0); - /* Disable all other SR interrupts and clear the status */ - sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2, + /* + * Disable all other SR interrupts and clear the status + * write to status register ONLY on need basis - only if status + * is set. + */ + if (sr_read_reg(sr, ERRCONFIG_V2) & ERRCONFIG_VPBOUNDINTST_V2) + sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2, ERRCONFIG_VPBOUNDINTST_V2); + else + sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2, + 0x0); sr_write_reg(sr, IRQENABLE_CLR, (IRQENABLE_MCUACCUMINT | IRQENABLE_MCUVALIDINT | IRQENABLE_MCUBOUNDSINT)); @@ -398,15 +412,16 @@ static u32 sr_retrieve_nvalue(struct omap_sr *sr, u32 efuse_offs) */ int sr_configure_errgen(struct voltagedomain *voltdm) { - u32 sr_config, sr_errconfig, errconfig_offs, vpboundint_en; - u32 vpboundint_st, senp_en = 0, senn_en = 0; + u32 sr_config, sr_errconfig, errconfig_offs; + u32 vpboundint_en, vpboundint_st; + u32 senp_en = 0, senn_en = 0; u8 senp_shift, senn_shift; struct omap_sr *sr = _sr_lookup(voltdm); if (IS_ERR(sr)) { pr_warning("%s: omap_sr struct for sr_%s not found\n", __func__, voltdm->name); - return -EINVAL; + return PTR_ERR(sr); } if (!sr->clk_length) @@ -418,20 +433,23 @@ int sr_configure_errgen(struct voltagedomain *voltdm) sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) | SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN; - if (sr->ip_type == SR_TYPE_V1) { + switch (sr->ip_type) { + case SR_TYPE_V1: sr_config |= SRCONFIG_DELAYCTRL; senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT; senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT; errconfig_offs = ERRCONFIG_V1; vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1; vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1; - } else if (sr->ip_type == SR_TYPE_V2) { + break; + case SR_TYPE_V2: senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT; senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT; errconfig_offs = ERRCONFIG_V2; vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2; vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2; - } else { + break; + default: dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" "module without specifying the ip\n", __func__); return -EINVAL; @@ -447,8 +465,55 @@ int sr_configure_errgen(struct voltagedomain *voltdm) sr_errconfig); /* Enabling the interrupts if the ERROR module is used */ - sr_modify_reg(sr, errconfig_offs, - vpboundint_en, (vpboundint_en | vpboundint_st)); + sr_modify_reg(sr, errconfig_offs, (vpboundint_en | vpboundint_st), + vpboundint_en); + + return 0; +} + +/** + * sr_disable_errgen() - Disables SmartReflex AVS module's errgen component + * @voltdm: VDD pointer to which the SR module to be configured belongs to. + * + * This API is to be called from the smartreflex class driver to + * disable the error generator module inside the smartreflex module. + * + * Returns 0 on success and error value in case of failure. + */ +int sr_disable_errgen(struct voltagedomain *voltdm) +{ + u32 errconfig_offs; + u32 vpboundint_en, vpboundint_st; + struct omap_sr *sr = _sr_lookup(voltdm); + + if (IS_ERR(sr)) { + pr_warning("%s: omap_sr struct for sr_%s not found\n", + __func__, voltdm->name); + return PTR_ERR(sr); + } + + switch (sr->ip_type) { + case SR_TYPE_V1: + errconfig_offs = ERRCONFIG_V1; + vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1; + vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1; + break; + case SR_TYPE_V2: + errconfig_offs = ERRCONFIG_V2; + vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2; + vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2; + break; + default: + dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" + "module without specifying the ip\n", __func__); + return -EINVAL; + } + + /* Disable the interrupts of ERROR module */ + sr_modify_reg(sr, errconfig_offs, vpboundint_en | vpboundint_st, 0); + + /* Disable the Sensor and errorgen */ + sr_modify_reg(sr, SRCONFIG, SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN, 0); return 0; } @@ -475,7 +540,7 @@ int sr_configure_minmax(struct voltagedomain *voltdm) if (IS_ERR(sr)) { pr_warning("%s: omap_sr struct for sr_%s not found\n", __func__, voltdm->name); - return -EINVAL; + return PTR_ERR(sr); } if (!sr->clk_length) @@ -488,14 +553,17 @@ int sr_configure_minmax(struct voltagedomain *voltdm) SRCONFIG_SENENABLE | (sr->accum_data << SRCONFIG_ACCUMDATA_SHIFT); - if (sr->ip_type == SR_TYPE_V1) { + switch (sr->ip_type) { + case SR_TYPE_V1: sr_config |= SRCONFIG_DELAYCTRL; senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT; senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT; - } else if (sr->ip_type == SR_TYPE_V2) { + break; + case SR_TYPE_V2: senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT; senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT; - } else { + break; + default: dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" "module without specifying the ip\n", __func__); return -EINVAL; @@ -511,20 +579,27 @@ int sr_configure_minmax(struct voltagedomain *voltdm) * Enabling the interrupts if MINMAXAVG module is used. * TODO: check if all the interrupts are mandatory */ - if (sr->ip_type == SR_TYPE_V1) { + switch (sr->ip_type) { + case SR_TYPE_V1: sr_modify_reg(sr, ERRCONFIG_V1, (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUBOUNDINTEN), (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUVALIDINTST | ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_MCUBOUNDINTST)); - } else if (sr->ip_type == SR_TYPE_V2) { + break; + case SR_TYPE_V2: sr_write_reg(sr, IRQSTATUS, IRQSTATUS_MCUACCUMINT | IRQSTATUS_MCVALIDINT | IRQSTATUS_MCBOUNDSINT | IRQSTATUS_MCUDISABLEACKINT); sr_write_reg(sr, IRQENABLE_SET, IRQENABLE_MCUACCUMINT | IRQENABLE_MCUVALIDINT | IRQENABLE_MCUBOUNDSINT | IRQENABLE_MCUDISABLEACKINT); + break; + default: + dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex" + "module without specifying the ip\n", __func__); + return -EINVAL; } return 0; @@ -543,15 +618,15 @@ int sr_configure_minmax(struct voltagedomain *voltdm) */ int sr_enable(struct voltagedomain *voltdm, unsigned long volt) { - u32 nvalue_reciprocal; struct omap_volt_data *volt_data; struct omap_sr *sr = _sr_lookup(voltdm); + u32 nvalue_reciprocal; int ret; if (IS_ERR(sr)) { pr_warning("%s: omap_sr struct for sr_%s not found\n", __func__, voltdm->name); - return -EINVAL; + return PTR_ERR(sr); } volt_data = omap_voltage_get_voltdata(sr->voltdm, volt); @@ -559,7 +634,7 @@ int sr_enable(struct voltagedomain *voltdm, unsigned long volt) if (IS_ERR(volt_data)) { dev_warn(&sr->pdev->dev, "%s: Unable to get voltage table" "for nominal voltage %ld\n", __func__, volt); - return -ENODATA; + return PTR_ERR(volt_data); } nvalue_reciprocal = sr_retrieve_nvalue(sr, volt_data->sr_efuse_offs); @@ -617,10 +692,17 @@ void sr_disable(struct voltagedomain *voltdm) * disable the clocks. */ if (sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE) { - if (sr->ip_type == SR_TYPE_V1) + switch (sr->ip_type) { + case SR_TYPE_V1: sr_v1_disable(sr); - else if (sr->ip_type == SR_TYPE_V2) + break; + case SR_TYPE_V2: sr_v2_disable(sr); + break; + default: + dev_err(&sr->pdev->dev, "UNKNOWN IP type %d\n", + sr->ip_type); + } } pm_runtime_put_sync_suspend(&sr->pdev->dev); @@ -779,10 +861,10 @@ void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data) sr_pmic_data = pmic_data; } -/* PM Debug Fs enteries to enable disable smartreflex. */ +/* PM Debug FS entries to enable and disable smartreflex. */ static int omap_sr_autocomp_show(void *data, u64 *val) { - struct omap_sr *sr_info = (struct omap_sr *) data; + struct omap_sr *sr_info = data; if (!sr_info) { pr_warning("%s: omap_sr struct not found\n", __func__); @@ -796,7 +878,7 @@ static int omap_sr_autocomp_show(void *data, u64 *val) static int omap_sr_autocomp_store(void *data, u64 val) { - struct omap_sr *sr_info = (struct omap_sr *) data; + struct omap_sr *sr_info = data; if (!sr_info) { pr_warning("%s: omap_sr struct not found\n", __func__); @@ -804,7 +886,7 @@ static int omap_sr_autocomp_store(void *data, u64 val) } /* Sanity check */ - if (val && (val != 1)) { + if (val > 1) { pr_warning("%s: Invalid argument %lld\n", __func__, val); return -EINVAL; } @@ -821,11 +903,11 @@ static int omap_sr_autocomp_store(void *data, u64 val) } DEFINE_SIMPLE_ATTRIBUTE(pm_sr_fops, omap_sr_autocomp_show, - omap_sr_autocomp_store, "%llu\n"); + omap_sr_autocomp_store, "%llu\n"); static int __init omap_sr_probe(struct platform_device *pdev) { - struct omap_sr *sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL); + struct omap_sr *sr_info; struct omap_sr_data *pdata = pdev->dev.platform_data; struct resource *mem, *irq; struct dentry *nvalue_dir; @@ -833,12 +915,15 @@ static int __init omap_sr_probe(struct platform_device *pdev) int i, ret = 0; char *name; + sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL); if (!sr_info) { dev_err(&pdev->dev, "%s: unable to allocate sr_info\n", __func__); return -ENOMEM; } + platform_set_drvdata(pdev, sr_info); + if (!pdata) { dev_err(&pdev->dev, "%s: platform data missing\n", __func__); ret = -EINVAL; @@ -904,7 +989,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) dev_info(&pdev->dev, "%s: SmartReflex driver initialized\n", __func__); if (!sr_dbg_dir) { sr_dbg_dir = debugfs_create_dir("smartreflex", NULL); - if (!sr_dbg_dir) { + if (IS_ERR_OR_NULL(sr_dbg_dir)) { ret = PTR_ERR(sr_dbg_dir); pr_err("%s:sr debugfs dir creation failed(%d)\n", __func__, ret); @@ -921,7 +1006,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) } sr_info->dbg_dir = debugfs_create_dir(name, sr_dbg_dir); kfree(name); - if (IS_ERR(sr_info->dbg_dir)) { + if (IS_ERR_OR_NULL(sr_info->dbg_dir)) { dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n", __func__); ret = PTR_ERR(sr_info->dbg_dir); @@ -938,7 +1023,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) &sr_info->err_minlimit); nvalue_dir = debugfs_create_dir("nvalue", sr_info->dbg_dir); - if (IS_ERR(nvalue_dir)) { + if (IS_ERR_OR_NULL(nvalue_dir)) { dev_err(&pdev->dev, "%s: Unable to create debugfs directory" "for n-values\n", __func__); ret = PTR_ERR(nvalue_dir); @@ -994,7 +1079,7 @@ static int __devexit omap_sr_remove(struct platform_device *pdev) if (IS_ERR(sr_info)) { dev_warn(&pdev->dev, "%s: omap_sr struct not found\n", __func__); - return -EINVAL; + return PTR_ERR(sr_info); } if (sr_info->autocomp_active) @@ -1011,8 +1096,32 @@ static int __devexit omap_sr_remove(struct platform_device *pdev) return 0; } +static void __devexit omap_sr_shutdown(struct platform_device *pdev) +{ + struct omap_sr_data *pdata = pdev->dev.platform_data; + struct omap_sr *sr_info; + + if (!pdata) { + dev_err(&pdev->dev, "%s: platform data missing\n", __func__); + return; + } + + sr_info = _sr_lookup(pdata->voltdm); + if (IS_ERR(sr_info)) { + dev_warn(&pdev->dev, "%s: omap_sr struct not found\n", + __func__); + return; + } + + if (sr_info->autocomp_active) + sr_stop_vddautocomp(sr_info); + + return; +} + static struct platform_driver smartreflex_driver = { - .remove = omap_sr_remove, + .remove = __devexit_p(omap_sr_remove), + .shutdown = __devexit_p(omap_sr_shutdown), .driver = { .name = "smartreflex", }, @@ -1042,12 +1151,12 @@ static int __init sr_init(void) return 0; } +late_initcall(sr_init); static void __exit sr_exit(void) { platform_driver_unregister(&smartreflex_driver); } -late_initcall(sr_init); module_exit(sr_exit); MODULE_DESCRIPTION("OMAP Smartreflex Driver"); diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h index 5f35b9e25556..5809141171f8 100644 --- a/arch/arm/mach-omap2/smartreflex.h +++ b/arch/arm/mach-omap2/smartreflex.h @@ -152,6 +152,15 @@ struct omap_sr_pmic_data { void (*sr_pmic_init) (void); }; +/** + * struct omap_smartreflex_dev_attr - Smartreflex Device attribute. + * + * @sensor_voltdm_name: Name of voltdomain of SR instance + */ +struct omap_smartreflex_dev_attr { + const char *sensor_voltdm_name; +}; + #ifdef CONFIG_OMAP_SMARTREFLEX /* * The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR. @@ -231,6 +240,7 @@ void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data); int sr_enable(struct voltagedomain *voltdm, unsigned long volt); void sr_disable(struct voltagedomain *voltdm); int sr_configure_errgen(struct voltagedomain *voltdm); +int sr_disable_errgen(struct voltagedomain *voltdm); int sr_configure_minmax(struct voltagedomain *voltdm); /* API to register the smartreflex class driver with the smartreflex driver */ diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c index 9f43fcc05d3e..a503e1e8358c 100644 --- a/arch/arm/mach-omap2/sr_device.c +++ b/arch/arm/mach-omap2/sr_device.c @@ -69,11 +69,12 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data, sr_data->nvalue_count = count; } -static int sr_dev_init(struct omap_hwmod *oh, void *user) +static int __init sr_dev_init(struct omap_hwmod *oh, void *user) { struct omap_sr_data *sr_data; struct platform_device *pdev; struct omap_volt_data *volt_data; + struct omap_smartreflex_dev_attr *sr_dev_attr; char *name = "smartreflex"; static int i; @@ -84,9 +85,11 @@ static int sr_dev_init(struct omap_hwmod *oh, void *user) return -ENOMEM; } - if (!oh->vdd_name) { + sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr; + if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) { pr_err("%s: No voltage domain specified for %s." - "Cannot initialize\n", __func__, oh->name); + "Cannot initialize\n", __func__, + oh->name); goto exit; } @@ -94,10 +97,10 @@ static int sr_dev_init(struct omap_hwmod *oh, void *user) sr_data->senn_mod = 0x1; sr_data->senp_mod = 0x1; - sr_data->voltdm = voltdm_lookup(oh->vdd_name); + sr_data->voltdm = voltdm_lookup(sr_dev_attr->sensor_voltdm_name); if (IS_ERR(sr_data->voltdm)) { pr_err("%s: Unable to get voltage domain pointer for VDD %s\n", - __func__, oh->vdd_name); + __func__, sr_dev_attr->sensor_voltdm_name); goto exit; } diff --git a/arch/arm/mach-omap2/sram242x.S b/arch/arm/mach-omap2/sram242x.S index ff9b9dbcb30e..ee0bfcc1410f 100644 --- a/arch/arm/mach-omap2/sram242x.S +++ b/arch/arm/mach-omap2/sram242x.S @@ -29,10 +29,12 @@ * These crashes may be intermittent. */ #include <linux/linkage.h> + #include <asm/assembler.h> -#include <mach/io.h> + #include <mach/hardware.h> +#include "iomap.h" #include "prm2xxx_3xxx.h" #include "cm2xxx_3xxx.h" #include "sdrc.h" diff --git a/arch/arm/mach-omap2/sram243x.S b/arch/arm/mach-omap2/sram243x.S index 76730209fa0e..d4d39ef04769 100644 --- a/arch/arm/mach-omap2/sram243x.S +++ b/arch/arm/mach-omap2/sram243x.S @@ -29,10 +29,12 @@ * These crashes may be intermittent. */ #include <linux/linkage.h> + #include <asm/assembler.h> -#include <mach/io.h> + #include <mach/hardware.h> +#include "iomap.h" #include "prm2xxx_3xxx.h" #include "cm2xxx_3xxx.h" #include "sdrc.h" diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S index 6f5849aaa7c0..df5a21322b0a 100644 --- a/arch/arm/mach-omap2/sram34xx.S +++ b/arch/arm/mach-omap2/sram34xx.S @@ -26,11 +26,12 @@ * MA 02111-1307 USA */ #include <linux/linkage.h> + #include <asm/assembler.h> -#include <mach/hardware.h> -#include <mach/io.h> +#include <mach/hardware.h> +#include "iomap.h" #include "sdrc.h" #include "cm2xxx_3xxx.h" diff --git a/arch/arm/mach-omap2/timer-mpu.c b/arch/arm/mach-omap2/timer-mpu.c deleted file mode 100644 index 31c0ac4cd66a..000000000000 --- a/arch/arm/mach-omap2/timer-mpu.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * The MPU local timer source file. In OMAP4, both cortex-a9 cores have - * own timer in it's MPU domain. These timers will be driving the - * linux kernel SMP tick framework when active. These timers are not - * part of the wake up domain. - * - * Copyright (C) 2009 Texas Instruments, Inc. - * - * Author: - * Santosh Shilimkar <santosh.shilimkar@ti.com> - * - * This file is based on arm realview smp platform file. - * Copyright (C) 2002 ARM Ltd. - * - * 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 <linux/init.h> -#include <linux/smp.h> -#include <linux/clockchips.h> -#include <asm/irq.h> -#include <asm/smp_twd.h> -#include <asm/localtimer.h> - -/* - * Setup the local clock events for a CPU. - */ -int __cpuinit local_timer_setup(struct clock_event_device *evt) -{ - /* Local timers are not supprted on OMAP4430 ES1.0 */ - if (omap_rev() == OMAP4430_REV_ES1_0) - return -ENXIO; - - evt->irq = OMAP44XX_IRQ_LOCALTIMER; - twd_timer_setup(evt); - return 0; -} - diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 5c9acea95761..c512bac69ec5 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -39,7 +39,7 @@ #include <asm/mach/time.h> #include <plat/dmtimer.h> -#include <asm/localtimer.h> +#include <asm/smp_twd.h> #include <asm/sched_clock.h> #include "common.h" #include <plat/omap_hwmod.h> @@ -324,14 +324,26 @@ OMAP_SYS_TIMER(3_secure) #endif #ifdef CONFIG_ARCH_OMAP4 -static void __init omap4_timer_init(void) -{ #ifdef CONFIG_LOCAL_TIMERS - twd_base = ioremap(OMAP44XX_LOCAL_TWD_BASE, SZ_256); - BUG_ON(!twd_base); +static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, + OMAP44XX_LOCAL_TWD_BASE, + OMAP44XX_IRQ_LOCALTIMER); #endif + +static void __init omap4_timer_init(void) +{ omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE); omap2_gp_clocksource_init(2, OMAP4_MPU_SOURCE); +#ifdef CONFIG_LOCAL_TIMERS + /* Local timers are not supprted on OMAP4430 ES1.0 */ + if (omap_rev() != OMAP4430_REV_ES1_0) { + int err; + + err = twd_local_timer_register(&twd_local_timer); + if (err) + pr_err("twd_local_timer_register failed %d\n", err); + } +#endif } OMAP_SYS_TIMER(4) #endif diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c index f51348dafafd..dde8a11f47d5 100644 --- a/arch/arm/mach-omap2/usb-host.c +++ b/arch/arm/mach-omap2/usb-host.c @@ -54,7 +54,7 @@ static struct omap_device_pm_latency omap_uhhtll_latency[] = { /* * setup_ehci_io_mux - initialize IO pad mux for USBHOST */ -static void setup_ehci_io_mux(const enum usbhs_omap_port_mode *port_mode) +static void __init setup_ehci_io_mux(const enum usbhs_omap_port_mode *port_mode) { switch (port_mode[0]) { case OMAP_EHCI_PORT_MODE_PHY: @@ -197,7 +197,8 @@ static void setup_ehci_io_mux(const enum usbhs_omap_port_mode *port_mode) return; } -static void setup_4430ehci_io_mux(const enum usbhs_omap_port_mode *port_mode) +static +void __init setup_4430ehci_io_mux(const enum usbhs_omap_port_mode *port_mode) { switch (port_mode[0]) { case OMAP_EHCI_PORT_MODE_PHY: @@ -315,7 +316,7 @@ static void setup_4430ehci_io_mux(const enum usbhs_omap_port_mode *port_mode) } } -static void setup_ohci_io_mux(const enum usbhs_omap_port_mode *port_mode) +static void __init setup_ohci_io_mux(const enum usbhs_omap_port_mode *port_mode) { switch (port_mode[0]) { case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: @@ -412,7 +413,8 @@ static void setup_ohci_io_mux(const enum usbhs_omap_port_mode *port_mode) } } -static void setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode) +static +void __init setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode) { switch (port_mode[0]) { case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c index 175b7d86d86a..84da34f9a7cf 100644 --- a/arch/arm/mach-omap2/vc.c +++ b/arch/arm/mach-omap2/vc.c @@ -10,6 +10,7 @@ #include <linux/kernel.h> #include <linux/delay.h> #include <linux/init.h> +#include <linux/bug.h> #include <plat/cpu.h> diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c index 0df88820978d..f95c1bad9dc6 100644 --- a/arch/arm/mach-omap2/vp.c +++ b/arch/arm/mach-omap2/vp.c @@ -61,8 +61,8 @@ void __init omap_vp_init(struct voltagedomain *voltdm) vddmin = voltdm->pmic->vp_vddmin; vddmax = voltdm->pmic->vp_vddmax; - waittime = ((voltdm->pmic->step_size / voltdm->pmic->slew_rate) * - sys_clk_rate) / 1000; + waittime = DIV_ROUND_UP(voltdm->pmic->step_size * sys_clk_rate, + 1000 * voltdm->pmic->slew_rate); vstepmin = voltdm->pmic->vp_vstepmin; vstepmax = voltdm->pmic->vp_vstepmax; diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index 5dad38ec00ea..24481666d2cd 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c @@ -21,6 +21,7 @@ #include <net/dsa.h> #include <asm/page.h> #include <asm/setup.h> +#include <asm/system_misc.h> #include <asm/timex.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> diff --git a/arch/arm/mach-orion5x/common.h b/arch/arm/mach-orion5x/common.h index d2513ac79ff5..2e6454c8d4ba 100644 --- a/arch/arm/mach-orion5x/common.h +++ b/arch/arm/mach-orion5x/common.h @@ -57,5 +57,14 @@ struct meminfo; struct tag; extern void __init tag_fixup_mem32(struct tag *, char **, struct meminfo *); +/***************************************************************************** + * Helpers to access Orion registers + ****************************************************************************/ +/* + * These are not preempt-safe. Locks, if needed, must be taken + * care of by the caller. + */ +#define orion5x_setbits(r, mask) writel(readl(r) | (mask), (r)) +#define orion5x_clrbits(r, mask) writel(readl(r) & ~(mask), (r)) #endif diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c index 91b0f4788597..c3ed15b8ea25 100644 --- a/arch/arm/mach-orion5x/dns323-setup.c +++ b/arch/arm/mach-orion5x/dns323-setup.c @@ -32,6 +32,7 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/pci.h> +#include <asm/system_info.h> #include <mach/orion5x.h> #include "common.h" #include "mpp.h" diff --git a/arch/arm/mach-orion5x/include/mach/entry-macro.S b/arch/arm/mach-orion5x/include/mach/entry-macro.S index d658992e5401..79eb502a1e64 100644 --- a/arch/arm/mach-orion5x/include/mach/entry-macro.S +++ b/arch/arm/mach-orion5x/include/mach/entry-macro.S @@ -10,12 +10,6 @@ #include <mach/bridge-regs.h> - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_preamble, base, tmp ldr \base, =MAIN_IRQ_CAUSE .endm diff --git a/arch/arm/mach-orion5x/include/mach/io.h b/arch/arm/mach-orion5x/include/mach/io.h deleted file mode 100644 index e9d9afdc2659..000000000000 --- a/arch/arm/mach-orion5x/include/mach/io.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * arch/arm/mach-orion5x/include/mach/io.h - * - * Tzachi Perelstein <tzachi@marvell.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __ASM_ARCH_IO_H -#define __ASM_ARCH_IO_H - -#include "orion5x.h" - -#define IO_SPACE_LIMIT 0xffffffff - -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - - -/***************************************************************************** - * Helpers to access Orion registers - ****************************************************************************/ -/* - * These are not preempt-safe. Locks, if needed, must be taken - * care of by the caller. - */ -#define orion5x_setbits(r, mask) writel(readl(r) | (mask), (r)) -#define orion5x_clrbits(r, mask) writel(readl(r) & ~(mask), (r)) - - -#endif diff --git a/arch/arm/mach-orion5x/include/mach/system.h b/arch/arm/mach-orion5x/include/mach/system.h deleted file mode 100644 index 825a2650cefa..000000000000 --- a/arch/arm/mach-orion5x/include/mach/system.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/arm/mach-orion5x/include/mach/system.h - * - * Tzachi Perelstein <tzachi@marvell.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-orion5x/ls-chl-setup.c b/arch/arm/mach-orion5x/ls-chl-setup.c index 527213169db0..0c9e413b5805 100644 --- a/arch/arm/mach-orion5x/ls-chl-setup.c +++ b/arch/arm/mach-orion5x/ls-chl-setup.c @@ -22,7 +22,6 @@ #include <linux/gpio.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <asm/system.h> #include <mach/orion5x.h> #include "common.h" #include "mpp.h" diff --git a/arch/arm/mach-orion5x/ls_hgl-setup.c b/arch/arm/mach-orion5x/ls_hgl-setup.c index 9a8697b97dd7..c1b5d8a58037 100644 --- a/arch/arm/mach-orion5x/ls_hgl-setup.c +++ b/arch/arm/mach-orion5x/ls_hgl-setup.c @@ -21,7 +21,6 @@ #include <linux/gpio.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <asm/system.h> #include <mach/orion5x.h> #include "common.h" #include "mpp.h" diff --git a/arch/arm/mach-orion5x/lsmini-setup.c b/arch/arm/mach-orion5x/lsmini-setup.c index 09c73659f467..949eaa8f12e3 100644 --- a/arch/arm/mach-orion5x/lsmini-setup.c +++ b/arch/arm/mach-orion5x/lsmini-setup.c @@ -21,7 +21,6 @@ #include <linux/gpio.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <asm/system.h> #include <mach/orion5x.h> #include "common.h" #include "mpp.h" diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c index 09a045f0c406..cb19e1661bb3 100644 --- a/arch/arm/mach-orion5x/pci.c +++ b/arch/arm/mach-orion5x/pci.c @@ -19,6 +19,7 @@ #include <asm/mach/pci.h> #include <plat/pcie.h> #include <plat/addr-map.h> +#include <mach/orion5x.h> #include "common.h" /***************************************************************************** @@ -171,13 +172,14 @@ static int __init pcie_setup(struct pci_sys_data *sys) /* * IORESOURCE_IO */ + sys->io_offset = 0; res[0].name = "PCIe I/O Space"; res[0].flags = IORESOURCE_IO; res[0].start = ORION5X_PCIE_IO_BUS_BASE; res[0].end = res[0].start + ORION5X_PCIE_IO_SIZE - 1; if (request_resource(&ioport_resource, &res[0])) panic("Request PCIe IO resource failed\n"); - pci_add_resource(&sys->resources, &res[0]); + pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset); /* * IORESOURCE_MEM @@ -188,9 +190,7 @@ static int __init pcie_setup(struct pci_sys_data *sys) res[1].end = res[1].start + ORION5X_PCIE_MEM_SIZE - 1; if (request_resource(&iomem_resource, &res[1])) panic("Request PCIe Memory resource failed\n"); - pci_add_resource(&sys->resources, &res[1]); - - sys->io_offset = 0; + pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset); return 1; } @@ -499,13 +499,14 @@ static int __init pci_setup(struct pci_sys_data *sys) /* * IORESOURCE_IO */ + sys->io_offset = 0; res[0].name = "PCI I/O Space"; res[0].flags = IORESOURCE_IO; res[0].start = ORION5X_PCI_IO_BUS_BASE; res[0].end = res[0].start + ORION5X_PCI_IO_SIZE - 1; if (request_resource(&ioport_resource, &res[0])) panic("Request PCI IO resource failed\n"); - pci_add_resource(&sys->resources, &res[0]); + pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset); /* * IORESOURCE_MEM @@ -516,9 +517,7 @@ static int __init pci_setup(struct pci_sys_data *sys) res[1].end = res[1].start + ORION5X_PCI_MEM_SIZE - 1; if (request_resource(&iomem_resource, &res[1])) panic("Request PCI Memory resource failed\n"); - pci_add_resource(&sys->resources, &res[1]); - - sys->io_offset = 0; + pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset); return 1; } diff --git a/arch/arm/mach-orion5x/tsx09-common.c b/arch/arm/mach-orion5x/tsx09-common.c index c9abb8fbfa70..7189827d641d 100644 --- a/arch/arm/mach-orion5x/tsx09-common.c +++ b/arch/arm/mach-orion5x/tsx09-common.c @@ -15,6 +15,7 @@ #include <linux/mv643xx_eth.h> #include <linux/timex.h> #include <linux/serial_reg.h> +#include <mach/orion5x.h> #include "tsx09-common.h" #include "common.h" diff --git a/arch/arm/mach-picoxcell/include/mach/entry-macro.S b/arch/arm/mach-picoxcell/include/mach/entry-macro.S deleted file mode 100644 index 9b505ac00be9..000000000000 --- a/arch/arm/mach-picoxcell/include/mach/entry-macro.S +++ /dev/null @@ -1,16 +0,0 @@ -/* - * entry-macro.S - * - * Copyright (c) 2011 Picochip Ltd., Jamie Iles - * - * Low-level IRQ helper macros for picoXcell platforms - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-picoxcell/include/mach/io.h b/arch/arm/mach-picoxcell/include/mach/io.h deleted file mode 100644 index 7573ec7d10a3..000000000000 --- a/arch/arm/mach-picoxcell/include/mach/io.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2011 Picochip Ltd., Jamie Iles - * - * 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 __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -/* No ioports, but needed for driver compatibility. */ -#define __io(a) __typesafe_io(a) -/* No PCI possible on picoxcell. */ -#define __mem_pci(a) (a) - -#endif /* __ASM_ARM_ARCH_IO_H */ diff --git a/arch/arm/mach-picoxcell/include/mach/irqs.h b/arch/arm/mach-picoxcell/include/mach/irqs.h deleted file mode 100644 index 59eac1ee2820..000000000000 --- a/arch/arm/mach-picoxcell/include/mach/irqs.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2011 Picochip Ltd., Jamie Iles - * - * 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_IRQS_H -#define __MACH_IRQS_H - -/* We dynamically allocate our irq_desc's. */ -#define NR_IRQS 0 - -#endif /* __MACH_IRQS_H */ diff --git a/arch/arm/mach-picoxcell/include/mach/system.h b/arch/arm/mach-picoxcell/include/mach/system.h deleted file mode 100644 index 1a5d8cb57df4..000000000000 --- a/arch/arm/mach-picoxcell/include/mach/system.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2011 Picochip Ltd., Jamie Iles - * - * 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 __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - /* - * This should do all the clock switching and wait for interrupt - * tricks. - */ - cpu_do_idle(); -} - -#endif /* __ASM_ARCH_SYSTEM_H */ diff --git a/arch/arm/mach-pnx4008/core.c b/arch/arm/mach-pnx4008/core.c index 4cfb40b2ec19..be4c92858509 100644 --- a/arch/arm/mach-pnx4008/core.c +++ b/arch/arm/mach-pnx4008/core.c @@ -32,7 +32,7 @@ #include <asm/mach-types.h> #include <asm/pgtable.h> #include <asm/page.h> -#include <asm/system.h> +#include <asm/system_misc.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> diff --git a/arch/arm/mach-pnx4008/dma.c b/arch/arm/mach-pnx4008/dma.c index 7fa4bf2e2125..a4739e9fb2fb 100644 --- a/arch/arm/mach-pnx4008/dma.c +++ b/arch/arm/mach-pnx4008/dma.c @@ -24,7 +24,6 @@ #include <linux/io.h> #include <linux/gfp.h> -#include <asm/system.h> #include <mach/hardware.h> #include <mach/dma.h> #include <asm/dma-mapping.h> diff --git a/arch/arm/mach-pnx4008/include/mach/entry-macro.S b/arch/arm/mach-pnx4008/include/mach/entry-macro.S index db7eeebf30d7..77a555846719 100644 --- a/arch/arm/mach-pnx4008/include/mach/entry-macro.S +++ b/arch/arm/mach-pnx4008/include/mach/entry-macro.S @@ -25,15 +25,9 @@ #define SIC1_BASE_INT 32 #define SIC2_BASE_INT 64 - .macro disable_fiq - .endm - .macro get_irqnr_preamble, base, tmp .endm - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp /* decode the MIC interrupt numbers */ ldr \base, =IO_ADDRESS(PNX4008_INTCTRLMIC_BASE) diff --git a/arch/arm/mach-pnx4008/include/mach/io.h b/arch/arm/mach-pnx4008/include/mach/io.h deleted file mode 100644 index cbf0904540ea..000000000000 --- a/arch/arm/mach-pnx4008/include/mach/io.h +++ /dev/null @@ -1,21 +0,0 @@ - -/* - * arch/arm/mach-pnx4008/include/mach/io.h - * - * Author: Dmitry Chigirev <chigirev@ru.mvista.com> - * - * 2005 (c) MontaVista Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - */ - -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#endif diff --git a/arch/arm/mach-pnx4008/include/mach/system.h b/arch/arm/mach-pnx4008/include/mach/system.h deleted file mode 100644 index 60cfe7188091..000000000000 --- a/arch/arm/mach-pnx4008/include/mach/system.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * arch/arm/mach-pnx4008/include/mach/system.h - * - * Copyright (C) 2003 Philips Semiconductors - * Copyright (C) 2005 MontaVista Software, Inc. - * - * 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_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-pnx4008/irq.c b/arch/arm/mach-pnx4008/irq.c index 7608c7a288cf..41e4201972d5 100644 --- a/arch/arm/mach-pnx4008/irq.c +++ b/arch/arm/mach-pnx4008/irq.c @@ -28,7 +28,6 @@ #include <asm/setup.h> #include <asm/pgtable.h> #include <asm/page.h> -#include <asm/system.h> #include <asm/mach/arch.h> #include <asm/mach/irq.h> #include <asm/mach/map.h> diff --git a/arch/arm/mach-pnx4008/time.c b/arch/arm/mach-pnx4008/time.c index 0c8aad4bb0dc..0cfe8af3d3be 100644 --- a/arch/arm/mach-pnx4008/time.c +++ b/arch/arm/mach-pnx4008/time.c @@ -24,7 +24,6 @@ #include <linux/irq.h> #include <linux/io.h> -#include <asm/system.h> #include <mach/hardware.h> #include <asm/leds.h> #include <asm/mach/time.h> diff --git a/arch/arm/mach-prima2/include/mach/entry-macro.S b/arch/arm/mach-prima2/include/mach/entry-macro.S index 1c8a50f102a7..86434e7a5be9 100644 --- a/arch/arm/mach-prima2/include/mach/entry-macro.S +++ b/arch/arm/mach-prima2/include/mach/entry-macro.S @@ -20,10 +20,3 @@ cmp \irqnr, #0x40 @ the irq num can't be larger than 0x3f movges \irqnr, #0 .endm - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm - diff --git a/arch/arm/mach-prima2/include/mach/io.h b/arch/arm/mach-prima2/include/mach/io.h deleted file mode 100644 index 6c31e9ec279e..000000000000 --- a/arch/arm/mach-prima2/include/mach/io.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * arch/arm/mach-prima2/include/mach/io.h - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - * - * Licensed under GPLv2 or later. - */ - -#ifndef __MACH_PRIMA2_IO_H -#define __MACH_PRIMA2_IO_H - -#define IO_SPACE_LIMIT ((resource_size_t)0) - -#define __mem_pci(a) (a) - -#endif diff --git a/arch/arm/mach-prima2/include/mach/system.h b/arch/arm/mach-prima2/include/mach/system.h deleted file mode 100644 index 2c7d2a9d0c92..000000000000 --- a/arch/arm/mach-prima2/include/mach/system.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * arch/arm/mach-prima2/include/mach/system.h - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - * - * Licensed under GPLv2 or later. - */ - -#ifndef __MACH_SYSTEM_H__ -#define __MACH_SYSTEM_H__ - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-prima2/timer.c b/arch/arm/mach-prima2/timer.c index b7a6091ce791..0d024b1e916d 100644 --- a/arch/arm/mach-prima2/timer.c +++ b/arch/arm/mach-prima2/timer.c @@ -18,6 +18,7 @@ #include <linux/of.h> #include <linux/of_address.h> #include <mach/map.h> +#include <asm/sched_clock.h> #include <asm/mach/time.h> #define SIRFSOC_TIMER_COUNTER_LO 0x0000 @@ -165,21 +166,9 @@ static struct irqaction sirfsoc_timer_irq = { }; /* Overwrite weak default sched_clock with more precise one */ -unsigned long long notrace sched_clock(void) +static u32 notrace sirfsoc_read_sched_clock(void) { - static int is_mapped; - - /* - * sched_clock is called earlier than .init of sys_timer - * if we map timer memory in .init of sys_timer, system - * will panic due to illegal memory access - */ - if (!is_mapped) { - sirfsoc_of_timer_map(); - is_mapped = 1; - } - - return sirfsoc_timer_read(NULL) * (NSEC_PER_SEC / CLOCK_TICK_RATE); + return (u32)(sirfsoc_timer_read(NULL) & 0xffffffff); } static void __init sirfsoc_clockevent_init(void) @@ -210,6 +199,8 @@ static void __init sirfsoc_timer_init(void) BUG_ON(rate < CLOCK_TICK_RATE); BUG_ON(rate % CLOCK_TICK_RATE); + sirfsoc_of_timer_map(); + writel_relaxed(rate / CLOCK_TICK_RATE / 2 - 1, sirfsoc_timer_base + SIRFSOC_TIMER_DIV); writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO); writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); @@ -217,6 +208,8 @@ static void __init sirfsoc_timer_init(void) BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE)); + setup_sched_clock(sirfsoc_read_sched_clock, 32, CLOCK_TICK_RATE); + BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq)); sirfsoc_clockevent_init(); diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 61d3c72ded84..fe2d1f80ef50 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -108,10 +108,12 @@ config CSB726_CSB701 config MACH_ARMCORE bool "CompuLab CM-X255/CM-X270 modules" + select ARCH_HAS_DMA_SET_COHERENT_MASK if PCI select PXA27x select IWMMXT select PXA25x select MIGHT_HAVE_PCI + select NEED_MACH_IO_H if PCI config MACH_EM_X270 bool "CompuLab EM-x270 platform" diff --git a/arch/arm/mach-pxa/capc7117.c b/arch/arm/mach-pxa/capc7117.c index c91727d1fe09..9a8760b72913 100644 --- a/arch/arm/mach-pxa/capc7117.c +++ b/arch/arm/mach-pxa/capc7117.c @@ -150,6 +150,7 @@ MACHINE_START(CAPC7117, "Embedian CAPC-7117 evaluation kit based on the MXM-8x10 CoM") .atag_offset = 0x100, .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa3xx_init_irq, .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/clock-pxa2xx.c b/arch/arm/mach-pxa/clock-pxa2xx.c index 1d5859d9a0e3..9ee2ad6a0a07 100644 --- a/arch/arm/mach-pxa/clock-pxa2xx.c +++ b/arch/arm/mach-pxa/clock-pxa2xx.c @@ -9,6 +9,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> +#include <linux/io.h> #include <linux/syscore_ops.h> #include <mach/pxa2xx-regs.h> diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index 4b981b82d2a5..313274016277 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -44,6 +44,7 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/setup.h> +#include <asm/system_info.h> #include <mach/pxa300.h> #include <mach/pxa27x-udc.h> @@ -713,7 +714,6 @@ struct da9030_battery_info cm_x300_battery_info = { static struct regulator_consumer_supply buck2_consumers[] = { { - .dev = NULL, .supply = "vcc_core", }, }; @@ -853,6 +853,7 @@ static void __init cm_x300_fixup(struct tag *tags, char **cmdline, MACHINE_START(CM_X300, "CM-X300 module") .atag_offset = 0x100, .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa3xx_init_irq, .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/colibri-pxa270.c b/arch/arm/mach-pxa/colibri-pxa270.c index 29d5d541f602..b2f227d36125 100644 --- a/arch/arm/mach-pxa/colibri-pxa270.c +++ b/arch/arm/mach-pxa/colibri-pxa270.c @@ -310,6 +310,7 @@ MACHINE_START(COLIBRI, "Toradex Colibri PXA270") .atag_offset = 0x100, .init_machine = colibri_pxa270_init, .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, @@ -320,6 +321,7 @@ MACHINE_START(INCOME, "Income s.r.o. SH-Dmaster PXA270 SBC") .atag_offset = 0x100, .init_machine = colibri_pxa270_income_init, .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/colibri-pxa300.c b/arch/arm/mach-pxa/colibri-pxa300.c index 0846d210cb05..bb6def8ec979 100644 --- a/arch/arm/mach-pxa/colibri-pxa300.c +++ b/arch/arm/mach-pxa/colibri-pxa300.c @@ -186,6 +186,7 @@ MACHINE_START(COLIBRI300, "Toradex Colibri PXA300") .atag_offset = 0x100, .init_machine = colibri_pxa300_init, .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa3xx_init_irq, .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/colibri-pxa320.c b/arch/arm/mach-pxa/colibri-pxa320.c index 6ad3359063af..d88e7b37f1da 100644 --- a/arch/arm/mach-pxa/colibri-pxa320.c +++ b/arch/arm/mach-pxa/colibri-pxa320.c @@ -256,6 +256,7 @@ MACHINE_START(COLIBRI320, "Toradex Colibri PXA320") .atag_offset = 0x100, .init_machine = colibri_pxa320_init, .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa3xx_init_irq, .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/colibri-pxa3xx.c b/arch/arm/mach-pxa/colibri-pxa3xx.c index 2b8ca0de8a3d..68cc75fac219 100644 --- a/arch/arm/mach-pxa/colibri-pxa3xx.c +++ b/arch/arm/mach-pxa/colibri-pxa3xx.c @@ -18,6 +18,7 @@ #include <asm/mach-types.h> #include <mach/hardware.h> #include <asm/sizes.h> +#include <asm/system_info.h> #include <asm/mach/arch.h> #include <asm/mach/irq.h> #include <mach/pxa3xx-regs.h> diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 11f1e735966e..c1fe32db4755 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -40,7 +40,6 @@ #include <asm/mach-types.h> #include <mach/hardware.h> #include <asm/irq.h> -#include <asm/system.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -730,6 +729,7 @@ static void __init fixup_corgi(struct tag *tags, char **cmdline, MACHINE_START(CORGI, "SHARP Corgi") .fixup = fixup_corgi, .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, .handle_irq = pxa25x_handle_irq, .init_machine = corgi_init, @@ -742,6 +742,7 @@ MACHINE_END MACHINE_START(SHEPHERD, "SHARP Shepherd") .fixup = fixup_corgi, .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, .handle_irq = pxa25x_handle_irq, .init_machine = corgi_init, @@ -754,6 +755,7 @@ MACHINE_END MACHINE_START(HUSKY, "SHARP Husky") .fixup = fixup_corgi, .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, .handle_irq = pxa25x_handle_irq, .init_machine = corgi_init, diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c index 39e265cfc86d..048c4299473c 100644 --- a/arch/arm/mach-pxa/corgi_pm.c +++ b/arch/arm/mach-pxa/corgi_pm.c @@ -19,6 +19,7 @@ #include <linux/interrupt.h> #include <linux/platform_device.h> #include <linux/apm-emulation.h> +#include <linux/io.h> #include <asm/irq.h> #include <asm/mach-types.h> diff --git a/arch/arm/mach-pxa/cpufreq-pxa3xx.c b/arch/arm/mach-pxa/cpufreq-pxa3xx.c index 88fbec05ec50..b85b4ab7aac6 100644 --- a/arch/arm/mach-pxa/cpufreq-pxa3xx.c +++ b/arch/arm/mach-pxa/cpufreq-pxa3xx.c @@ -15,6 +15,7 @@ #include <linux/init.h> #include <linux/cpufreq.h> #include <linux/slab.h> +#include <linux/io.h> #include <mach/pxa3xx-regs.h> diff --git a/arch/arm/mach-pxa/csb726.c b/arch/arm/mach-pxa/csb726.c index fb5a51d834e5..67f0de37f46e 100644 --- a/arch/arm/mach-pxa/csb726.c +++ b/arch/arm/mach-pxa/csb726.c @@ -274,6 +274,7 @@ static void __init csb726_init(void) MACHINE_START(CSB726, "Cogent CSB726") .atag_offset = 0x100, .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .init_machine = csb726_init, diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index 5bc13121eac5..166eee5b8a70 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -12,6 +12,7 @@ #include <mach/pxafb.h> #include <mach/mmc.h> #include <mach/irda.h> +#include <mach/irqs.h> #include <mach/ohci.h> #include <plat/pxa27x_keypad.h> #include <mach/camera.h> @@ -406,20 +407,17 @@ static struct resource pxa_rtc_resources[] = { [1] = { .start = IRQ_RTC1Hz, .end = IRQ_RTC1Hz, + .name = "rtc 1Hz", .flags = IORESOURCE_IRQ, }, [2] = { .start = IRQ_RTCAlrm, .end = IRQ_RTCAlrm, + .name = "rtc alarm", .flags = IORESOURCE_IRQ, }, }; -struct platform_device sa1100_device_rtc = { - .name = "sa1100-rtc", - .id = -1, -}; - struct platform_device pxa_device_rtc = { .name = "pxa-rtc", .id = -1, @@ -427,6 +425,27 @@ struct platform_device pxa_device_rtc = { .resource = pxa_rtc_resources, }; +static struct resource sa1100_rtc_resources[] = { + { + .start = IRQ_RTC1Hz, + .end = IRQ_RTC1Hz, + .name = "rtc 1Hz", + .flags = IORESOURCE_IRQ, + }, { + .start = IRQ_RTCAlrm, + .end = IRQ_RTCAlrm, + .name = "rtc alarm", + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device sa1100_device_rtc = { + .name = "sa1100-rtc", + .id = -1, + .num_resources = ARRAY_SIZE(sa1100_rtc_resources), + .resource = sa1100_rtc_resources, +}; + static struct resource pxa_ac97_resources[] = { [0] = { .start = 0x40500000, diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index d80c0ba9a095..16ec557b8e43 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -1083,19 +1083,19 @@ static void __init em_x270_userspace_consumers_init(void) } /* DA9030 related initializations */ -#define REGULATOR_CONSUMER(_name, _dev, _supply) \ +#define REGULATOR_CONSUMER(_name, _dev_name, _supply) \ static struct regulator_consumer_supply _name##_consumers[] = { \ { \ - .dev = _dev, \ + .dev_name = _dev_name, \ .supply = _supply, \ }, \ } -REGULATOR_CONSUMER(ldo3, &em_x270_gps_userspace_consumer.dev, "vcc gps"); +REGULATOR_CONSUMER(ldo3, "reg-userspace-consumer.0", "vcc gps"); REGULATOR_CONSUMER(ldo5, NULL, "vcc cam"); -REGULATOR_CONSUMER(ldo10, &pxa_device_mci.dev, "vcc sdio"); +REGULATOR_CONSUMER(ldo10, "pxa2xx-mci", "vcc sdio"); REGULATOR_CONSUMER(ldo12, NULL, "vcc usb"); -REGULATOR_CONSUMER(ldo19, &em_x270_gprs_userspace_consumer.dev, "vcc gprs"); +REGULATOR_CONSUMER(ldo19, "reg-userspace-consumer.1", "vcc gprs"); REGULATOR_CONSUMER(buck2, NULL, "vcc_core"); #define REGULATOR_INIT(_ldo, _min_uV, _max_uV, _ops_mask) \ @@ -1301,6 +1301,7 @@ static void __init em_x270_init(void) MACHINE_START(EM_X270, "Compulab EM-X270") .atag_offset = 0x100, .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, @@ -1311,6 +1312,7 @@ MACHINE_END MACHINE_START(EXEDA, "Compulab eXeda") .atag_offset = 0x100, .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index 5432ecb15def..42254175fcf4 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -22,7 +22,6 @@ #include <linux/init.h> #include <mach/hardware.h> -#include <asm/system.h> #include <asm/mach/map.h> #include <asm/mach-types.h> diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c index ac3b1cef4751..e529a35a44ce 100644 --- a/arch/arm/mach-pxa/gumstix.c +++ b/arch/arm/mach-pxa/gumstix.c @@ -235,6 +235,7 @@ static void __init gumstix_init(void) MACHINE_START(GUMSTIX, "Gumstix") .atag_offset = 0x100, /* match u-boot bi_boot_params */ .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/h5000.c b/arch/arm/mach-pxa/h5000.c index fde6b4c873c4..e7dec589f014 100644 --- a/arch/arm/mach-pxa/h5000.c +++ b/arch/arm/mach-pxa/h5000.c @@ -205,6 +205,7 @@ static void __init h5000_init(void) MACHINE_START(H5400, "HP iPAQ H5000") .atag_offset = 0x100, .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/himalaya.c b/arch/arm/mach-pxa/himalaya.c index 26d069a9f900..2962de898da9 100644 --- a/arch/arm/mach-pxa/himalaya.c +++ b/arch/arm/mach-pxa/himalaya.c @@ -160,6 +160,7 @@ static void __init himalaya_init(void) MACHINE_START(HIMALAYA, "HTC Himalaya") .atag_offset = 0x100, .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, .handle_irq = pxa25x_handle_irq, .init_machine = himalaya_init, diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c index 208eef1c0485..b83b95a29503 100644 --- a/arch/arm/mach-pxa/hx4700.c +++ b/arch/arm/mach-pxa/hx4700.c @@ -28,7 +28,8 @@ #include <linux/mtd/physmap.h> #include <linux/pda_power.h> #include <linux/pwm_backlight.h> -#include <linux/regulator/bq24022.h> +#include <linux/regulator/driver.h> +#include <linux/regulator/gpio-regulator.h> #include <linux/regulator/machine.h> #include <linux/regulator/max1586.h> #include <linux/spi/ads7846.h> @@ -97,9 +98,9 @@ static unsigned long hx4700_pin_config[] __initdata = { /* BTUART */ GPIO42_BTUART_RXD, - GPIO43_BTUART_TXD, + GPIO43_BTUART_TXD_LPM_LOW, GPIO44_BTUART_CTS, - GPIO45_BTUART_RTS, + GPIO45_BTUART_RTS_LPM_LOW, /* PWM 1 (Backlight) */ GPIO17_PWM1_OUT, @@ -245,6 +246,21 @@ static u16 asic3_gpio_config[] = { ASIC3_GPIOD15_nPIOW, }; +static struct asic3_led asic3_leds[ASIC3_NUM_LEDS] = { + [0] = { + .name = "hx4700:amber", + .default_trigger = "ds2760-battery.0-charging-blink-full-solid", + }, + [1] = { + .name = "hx4700:green", + .default_trigger = "unused", + }, + [2] = { + .name = "hx4700:blue", + .default_trigger = "hx4700-radio", + }, +}; + static struct resource asic3_resources[] = { /* GPIO part */ [0] = { @@ -275,6 +291,7 @@ static struct asic3_platform_data asic3_platform_data = { .gpio_config_num = ARRAY_SIZE(asic3_gpio_config), .irq_base = IRQ_BOARD_START, .gpio_base = HX4700_ASIC3_GPIO_BASE, + .leds = asic3_leds, }; static struct platform_device asic3 = { @@ -664,11 +681,9 @@ static struct platform_device power_supply = { static struct regulator_consumer_supply bq24022_consumers[] = { { - .dev = &gpio_vbus.dev, .supply = "vbus_draw", }, { - .dev = &power_supply.dev, .supply = "ac_draw", }, }; @@ -682,14 +697,34 @@ static struct regulator_init_data bq24022_init_data = { .consumer_supplies = bq24022_consumers, }; -static struct bq24022_mach_info bq24022_info = { - .gpio_nce = GPIO72_HX4700_BQ24022_nCHARGE_EN, - .gpio_iset2 = GPIO96_HX4700_BQ24022_ISET2, - .init_data = &bq24022_init_data, +static struct gpio bq24022_gpios[] = { + { GPIO96_HX4700_BQ24022_ISET2, GPIOF_OUT_INIT_LOW, "bq24022_iset2" }, +}; + +static struct gpio_regulator_state bq24022_states[] = { + { .value = 100000, .gpios = (0 << 0) }, + { .value = 500000, .gpios = (1 << 0) }, +}; + +static struct gpio_regulator_config bq24022_info = { + .supply_name = "bq24022", + + .enable_gpio = GPIO72_HX4700_BQ24022_nCHARGE_EN, + .enable_high = 0, + .enabled_at_boot = 0, + + .gpios = bq24022_gpios, + .nr_gpios = ARRAY_SIZE(bq24022_gpios), + + .states = bq24022_states, + .nr_states = ARRAY_SIZE(bq24022_states), + + .type = REGULATOR_CURRENT, + .init_data = &bq24022_init_data, }; static struct platform_device bq24022 = { - .name = "bq24022", + .name = "gpio-regulator", .id = -1, .dev = { .platform_data = &bq24022_info, @@ -705,10 +740,9 @@ static void hx4700_set_vpp(struct platform_device *pdev, int vpp) gpio_set_value(GPIO91_HX4700_FLASH_VPEN, vpp); } -static struct resource strataflash_resource = { - .start = PXA_CS0_PHYS, - .end = PXA_CS0_PHYS + SZ_128M - 1, - .flags = IORESOURCE_MEM, +static struct resource strataflash_resource[] = { + [0] = DEFINE_RES_MEM(PXA_CS0_PHYS, SZ_64M), + [1] = DEFINE_RES_MEM(PXA_CS0_PHYS + SZ_64M, SZ_64M), }; static struct physmap_flash_data strataflash_data = { @@ -719,8 +753,8 @@ static struct physmap_flash_data strataflash_data = { static struct platform_device strataflash = { .name = "physmap-flash", .id = -1, - .resource = &strataflash_resource, - .num_resources = 1, + .resource = strataflash_resource, + .num_resources = ARRAY_SIZE(strataflash_resource), .dev = { .platform_data = &strataflash_data, }, @@ -788,17 +822,6 @@ static struct platform_device audio = { /* - * PCMCIA - */ - -static struct platform_device pcmcia = { - .name = "hx4700-pcmcia", - .dev = { - .parent = &asic3.dev, - }, -}; - -/* * Platform devices */ @@ -814,7 +837,6 @@ static struct platform_device *devices[] __initdata = { &power_supply, &strataflash, &audio, - &pcmcia, }; static struct gpio global_gpios[] = { @@ -830,7 +852,6 @@ static struct gpio global_gpios[] = { { GPIO32_HX4700_RS232_ON, GPIOF_OUT_INIT_HIGH, "RS232_ON" }, { GPIO71_HX4700_ASIC3_nRESET, GPIOF_OUT_INIT_HIGH, "ASIC3_nRESET" }, { GPIO82_HX4700_EUART_RESET, GPIOF_OUT_INIT_HIGH, "EUART_RESET" }, - { GPIO105_HX4700_nIR_ON, GPIOF_OUT_INIT_HIGH, "nIR_EN" }, }; static void __init hx4700_init(void) diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c index 67400192ed3b..1d02eabc9c65 100644 --- a/arch/arm/mach-pxa/icontrol.c +++ b/arch/arm/mach-pxa/icontrol.c @@ -193,6 +193,7 @@ static void __init icontrol_init(void) MACHINE_START(ICONTROL, "iControl/SafeTcam boards using Embedian MXM-8x10 CoM") .atag_offset = 0x100, .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa3xx_init_irq, .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c index 8af1840e12cc..6ff466bd43e8 100644 --- a/arch/arm/mach-pxa/idp.c +++ b/arch/arm/mach-pxa/idp.c @@ -195,6 +195,7 @@ static void __init idp_map_io(void) MACHINE_START(PXA_IDP, "Vibren PXA255 IDP") /* Maintainer: Vibren Technologies */ .map_io = idp_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/include/mach/balloon3.h b/arch/arm/mach-pxa/include/mach/balloon3.h index f02fa1e6ba86..954641e6c8b1 100644 --- a/arch/arm/mach-pxa/include/mach/balloon3.h +++ b/arch/arm/mach-pxa/include/mach/balloon3.h @@ -174,7 +174,6 @@ enum balloon3_features { #define BALLOON3_AUX_NIRQ PXA_GPIO_TO_IRQ(BALLOON3_GPIO_AUX_NIRQ) #define BALLOON3_CODEC_IRQ PXA_GPIO_TO_IRQ(BALLOON3_GPIO_CODEC_IRQ) -#define BALLOON3_S0_CD_IRQ PXA_GPIO_TO_IRQ(BALLOON3_GPIO_S0_CD) #define BALLOON3_NR_IRQS (IRQ_BOARD_START + 16) diff --git a/arch/arm/mach-pxa/include/mach/entry-macro.S b/arch/arm/mach-pxa/include/mach/entry-macro.S deleted file mode 100644 index 260c0c17692a..000000000000 --- a/arch/arm/mach-pxa/include/mach/entry-macro.S +++ /dev/null @@ -1,15 +0,0 @@ -/* - * arch/arm/mach-pxa/include/mach/entry-macro.S - * - * Low-level IRQ helper macros for PXA-based platforms - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-pxa/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h index 8184669dde28..56d92e5cad85 100644 --- a/arch/arm/mach-pxa/include/mach/hardware.h +++ b/arch/arm/mach-pxa/include/mach/hardware.h @@ -40,7 +40,6 @@ #define io_p2v(x) IOMEM(0xf2000000 + ((x) & 0x01ffffff) + (((x) & 0x1c000000) >> 1)) #ifndef __ASSEMBLY__ -# define IOMEM(x) ((void __iomem *)(x)) # define __REG(x) (*((volatile u32 __iomem *)io_p2v(x))) /* With indexed regs we don't want to feed the index through io_p2v() @@ -52,7 +51,6 @@ #else -# define IOMEM(x) x # define __REG(x) io_p2v(x) # define __PREG(x) io_v2p(x) @@ -337,8 +335,4 @@ extern unsigned int get_memclk_frequency_10khz(void); extern unsigned long get_clock_tick_rate(void); #endif -#if defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI) -#define ARCH_HAS_DMA_SET_COHERENT_MASK -#endif - #endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/mach-pxa/include/mach/io.h b/arch/arm/mach-pxa/include/mach/io.h index fdca3be47d9b..cd78b7fe3567 100644 --- a/arch/arm/mach-pxa/include/mach/io.h +++ b/arch/arm/mach-pxa/include/mach/io.h @@ -6,8 +6,6 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H -#include <mach/hardware.h> - #define IO_SPACE_LIMIT 0xffffffff /* @@ -15,6 +13,5 @@ * drivers out there that might just work if we fake them... */ #define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) #endif diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h index 32975adf3ca4..8765782dd955 100644 --- a/arch/arm/mach-pxa/include/mach/irqs.h +++ b/arch/arm/mach-pxa/include/mach/irqs.h @@ -100,7 +100,7 @@ */ #define IRQ_BOARD_START (PXA_GPIO_IRQ_BASE + PXA_NR_BUILTIN_GPIO) -#define NR_IRQS (IRQ_BOARD_START) +#define PXA_NR_IRQS (IRQ_BOARD_START) #ifndef __ASSEMBLY__ struct irq_data; diff --git a/arch/arm/mach-pxa/include/mach/mainstone.h b/arch/arm/mach-pxa/include/mach/mainstone.h index 4c2d11cd824d..1bfc4e822a41 100644 --- a/arch/arm/mach-pxa/include/mach/mainstone.h +++ b/arch/arm/mach-pxa/include/mach/mainstone.h @@ -13,6 +13,8 @@ #ifndef ASM_ARCH_MAINSTONE_H #define ASM_ARCH_MAINSTONE_H +#include <mach/irqs.h> + #define MST_ETH_PHYS PXA_CS4_PHYS #define MST_FPGA_PHYS PXA_CS2_PHYS diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h b/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h index ec0f0b0b6744..a65867209aa0 100644 --- a/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h +++ b/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h @@ -158,7 +158,9 @@ #define GPIO44_BTUART_CTS MFP_CFG_IN(GPIO44, AF1) #define GPIO42_BTUART_RXD MFP_CFG_IN(GPIO42, AF1) #define GPIO45_BTUART_RTS MFP_CFG_OUT(GPIO45, AF2, DRIVE_HIGH) +#define GPIO45_BTUART_RTS_LPM_LOW MFP_CFG_OUT(GPIO45, AF2, DRIVE_LOW) #define GPIO43_BTUART_TXD MFP_CFG_OUT(GPIO43, AF2, DRIVE_HIGH) +#define GPIO43_BTUART_TXD_LPM_LOW MFP_CFG_OUT(GPIO43, AF2, DRIVE_LOW) /* STUART */ #define GPIO46_STUART_RXD MFP_CFG_IN(GPIO46, AF2) diff --git a/arch/arm/mach-pxa/include/mach/system.h b/arch/arm/mach-pxa/include/mach/system.h deleted file mode 100644 index c5afacd3cc0b..000000000000 --- a/arch/arm/mach-pxa/include/mach/system.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * arch/arm/mach-pxa/include/mach/system.h - * - * Author: Nicolas Pitre - * Created: Jun 15, 2001 - * Copyright: MontaVista Software Inc. - * - * 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. - */ -static inline void arch_idle(void) -{ - cpu_do_idle(); -} diff --git a/arch/arm/mach-pxa/leds-idp.c b/arch/arm/mach-pxa/leds-idp.c index 8b9c17142d5a..06b060025d11 100644 --- a/arch/arm/mach-pxa/leds-idp.c +++ b/arch/arm/mach-pxa/leds-idp.c @@ -16,7 +16,6 @@ #include <mach/hardware.h> #include <asm/leds.h> -#include <asm/system.h> #include <mach/pxa25x.h> #include <mach/idp.h> diff --git a/arch/arm/mach-pxa/leds-lubbock.c b/arch/arm/mach-pxa/leds-lubbock.c index e26d5efe1969..0bd85c884a7c 100644 --- a/arch/arm/mach-pxa/leds-lubbock.c +++ b/arch/arm/mach-pxa/leds-lubbock.c @@ -15,7 +15,6 @@ #include <mach/hardware.h> #include <asm/leds.h> -#include <asm/system.h> #include <mach/pxa25x.h> #include <mach/lubbock.h> diff --git a/arch/arm/mach-pxa/leds-mainstone.c b/arch/arm/mach-pxa/leds-mainstone.c index db4af5eee8b2..4058ab340fe6 100644 --- a/arch/arm/mach-pxa/leds-mainstone.c +++ b/arch/arm/mach-pxa/leds-mainstone.c @@ -14,7 +14,6 @@ #include <mach/hardware.h> #include <asm/leds.h> -#include <asm/system.h> #include <mach/pxa27x.h> #include <mach/mainstone.h> diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 6ebd276aebeb..6bb3f47b1f14 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -223,6 +223,7 @@ static struct resource sa1111_resources[] = { static struct sa1111_platform_data sa1111_info = { .irq_base = LUBBOCK_SA1111_IRQ_BASE, + .disable_devs = SA1111_DEVID_SAC, }; static struct platform_device sa1111_device = { diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index 3d6baf91396c..8de0651d7efb 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -25,7 +25,8 @@ #include <linux/mtd/physmap.h> #include <linux/pda_power.h> #include <linux/pwm_backlight.h> -#include <linux/regulator/bq24022.h> +#include <linux/regulator/driver.h> +#include <linux/regulator/gpio-regulator.h> #include <linux/regulator/machine.h> #include <linux/usb/gpio_vbus.h> #include <linux/i2c/pxa-i2c.h> @@ -33,6 +34,7 @@ #include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> +#include <asm/system_info.h> #include <mach/pxa27x.h> #include <mach/magician.h> @@ -578,11 +580,9 @@ static struct platform_device power_supply = { static struct regulator_consumer_supply bq24022_consumers[] = { { - .dev = &gpio_vbus.dev, .supply = "vbus_draw", }, { - .dev = &power_supply.dev, .supply = "ac_draw", }, }; @@ -596,14 +596,34 @@ static struct regulator_init_data bq24022_init_data = { .consumer_supplies = bq24022_consumers, }; -static struct bq24022_mach_info bq24022_info = { - .gpio_nce = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN, - .gpio_iset2 = EGPIO_MAGICIAN_BQ24022_ISET2, - .init_data = &bq24022_init_data, +static struct gpio bq24022_gpios[] = { + { EGPIO_MAGICIAN_BQ24022_ISET2, GPIOF_OUT_INIT_LOW, "bq24022_iset2" }, +}; + +static struct gpio_regulator_state bq24022_states[] = { + { .value = 100000, .gpios = (0 << 0) }, + { .value = 500000, .gpios = (1 << 0) }, +}; + +static struct gpio_regulator_config bq24022_info = { + .supply_name = "bq24022", + + .enable_gpio = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN, + .enable_high = 0, + .enabled_at_boot = 0, + + .gpios = bq24022_gpios, + .nr_gpios = ARRAY_SIZE(bq24022_gpios), + + .states = bq24022_states, + .nr_states = ARRAY_SIZE(bq24022_states), + + .type = REGULATOR_CURRENT, + .init_data = &bq24022_init_data, }; static struct platform_device bq24022 = { - .name = "bq24022", + .name = "gpio-regulator", .id = -1, .dev = { .platform_data = &bq24022_info, diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c index 29b62afc6f7c..b0a842887780 100644 --- a/arch/arm/mach-pxa/mfp-pxa2xx.c +++ b/arch/arm/mach-pxa/mfp-pxa2xx.c @@ -17,6 +17,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> +#include <linux/io.h> #include <linux/syscore_ops.h> #include <mach/pxa2xx-regs.h> diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c index e80a3db735c2..061d57009cee 100644 --- a/arch/arm/mach-pxa/mioa701.c +++ b/arch/arm/mach-pxa/mioa701.c @@ -758,6 +758,7 @@ MACHINE_START(MIOA701, "MIO A701") .atag_offset = 0x100, .restart_mode = 's', .map_io = &pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = &pxa27x_init_irq, .handle_irq = &pxa27x_handle_irq, .init_machine = mioa701_machine_init, diff --git a/arch/arm/mach-pxa/mp900.c b/arch/arm/mach-pxa/mp900.c index 169bf8f97af0..152efbf093f6 100644 --- a/arch/arm/mach-pxa/mp900.c +++ b/arch/arm/mach-pxa/mp900.c @@ -95,6 +95,7 @@ MACHINE_START(NEC_MP900, "MobilePro900/C") .atag_offset = 0x220100, .timer = &pxa_timer, .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, .handle_irq = pxa25x_handle_irq, .init_machine = mp900c_init, diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c index 1fa80f4f80c8..31e0433d83ba 100644 --- a/arch/arm/mach-pxa/palmld.c +++ b/arch/arm/mach-pxa/palmld.c @@ -344,6 +344,7 @@ static void __init palmld_init(void) MACHINE_START(PALMLD, "Palm LifeDrive") .atag_offset = 0x100, .map_io = palmld_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c index 5ba14316bd9c..0f6bd4fcfa3b 100644 --- a/arch/arm/mach-pxa/palmt5.c +++ b/arch/arm/mach-pxa/palmt5.c @@ -205,6 +205,7 @@ MACHINE_START(PALMT5, "Palm Tungsten|T5") .atag_offset = 0x100, .map_io = pxa27x_map_io, .reserve = palmt5_reserve, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c index 29b51b40f09d..e2d97eed07a7 100644 --- a/arch/arm/mach-pxa/palmtc.c +++ b/arch/arm/mach-pxa/palmtc.c @@ -539,6 +539,7 @@ static void __init palmtc_init(void) MACHINE_START(PALMTC, "Palm Tungsten|C") .atag_offset = 0x100, .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c index 5ebf49acb827..c054827c567f 100644 --- a/arch/arm/mach-pxa/palmte2.c +++ b/arch/arm/mach-pxa/palmte2.c @@ -358,6 +358,7 @@ static void __init palmte2_init(void) MACHINE_START(PALMTE2, "Palm Tungsten|E2") .atag_offset = 0x100, .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c index ec8249156c08..fbdebee39a53 100644 --- a/arch/arm/mach-pxa/palmtreo.c +++ b/arch/arm/mach-pxa/palmtreo.c @@ -448,6 +448,7 @@ MACHINE_START(TREO680, "Palm Treo 680") .atag_offset = 0x100, .map_io = pxa27x_map_io, .reserve = treo_reserve, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, @@ -461,6 +462,7 @@ MACHINE_START(CENTRO, "Palm Centro 685") .atag_offset = 0x100, .map_io = pxa27x_map_io, .reserve = treo_reserve, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c index 6170d76dfba8..9507605ed547 100644 --- a/arch/arm/mach-pxa/palmtx.c +++ b/arch/arm/mach-pxa/palmtx.c @@ -366,6 +366,7 @@ static void __init palmtx_init(void) MACHINE_START(PALMTX, "Palm T|X") .atag_offset = 0x100, .map_io = palmtx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c index b2dff9d415eb..a97b59965bb9 100644 --- a/arch/arm/mach-pxa/palmz72.c +++ b/arch/arm/mach-pxa/palmz72.c @@ -401,6 +401,7 @@ static void __init palmz72_init(void) MACHINE_START(PALMZ72, "Palm Zire72") .atag_offset = 0x100, .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index 744baee12c0c..89d98c832189 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -34,7 +34,6 @@ #include <asm/mach-types.h> #include <asm/irq.h> #include <asm/setup.h> -#include <asm/system.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> diff --git a/arch/arm/mach-pxa/pxa2xx.c b/arch/arm/mach-pxa/pxa2xx.c index 868270421b8c..f8ec85450c42 100644 --- a/arch/arm/mach-pxa/pxa2xx.c +++ b/arch/arm/mach-pxa/pxa2xx.c @@ -13,6 +13,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/device.h> +#include <linux/io.h> #include <mach/hardware.h> #include <mach/pxa2xx-regs.h> diff --git a/arch/arm/mach-pxa/pxa300.c b/arch/arm/mach-pxa/pxa300.c index 40bb16501d86..17cbc0c7bdb8 100644 --- a/arch/arm/mach-pxa/pxa300.c +++ b/arch/arm/mach-pxa/pxa300.c @@ -16,6 +16,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/platform_device.h> +#include <linux/io.h> #include <mach/pxa300.h> diff --git a/arch/arm/mach-pxa/pxa320.c b/arch/arm/mach-pxa/pxa320.c index 8d614ecd8e99..6dc99d4f2dc6 100644 --- a/arch/arm/mach-pxa/pxa320.c +++ b/arch/arm/mach-pxa/pxa320.c @@ -16,6 +16,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/platform_device.h> +#include <linux/io.h> #include <mach/pxa320.h> diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 3918a672238e..dffb7e813d98 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -31,6 +31,7 @@ #include <mach/pm.h> #include <mach/dma.h> #include <mach/smemc.h> +#include <mach/irqs.h> #include "generic.h" #include "devices.h" @@ -89,6 +90,7 @@ static struct clk_lookup pxa3xx_clkregs[] = { INIT_CLKREG(&clk_pxa3xx_mmc2, "pxa2xx-mci.1", NULL), INIT_CLKREG(&clk_pxa3xx_smemc, "pxa2xx-pcmcia", NULL), INIT_CLKREG(&clk_pxa3xx_gpio, "pxa-gpio", NULL), + INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL), }; #ifdef CONFIG_PM diff --git a/arch/arm/mach-pxa/pxa95x.c b/arch/arm/mach-pxa/pxa95x.c index 5ce434b95e87..47601f80e6e7 100644 --- a/arch/arm/mach-pxa/pxa95x.c +++ b/arch/arm/mach-pxa/pxa95x.c @@ -231,6 +231,7 @@ static struct clk_lookup pxa95x_clkregs[] = { INIT_CLKREG(&clk_pxa95x_pwm0, "pxa27x-pwm.0", NULL), INIT_CLKREG(&clk_pxa95x_pwm1, "pxa27x-pwm.1", NULL), INIT_CLKREG(&clk_pxa95x_gpio, "pxa-gpio", NULL), + INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL), }; void __init pxa95x_init_irq(void) diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c index 22818c7694a8..5905ed130e94 100644 --- a/arch/arm/mach-pxa/raumfeld.c +++ b/arch/arm/mach-pxa/raumfeld.c @@ -43,6 +43,8 @@ #include <linux/regulator/consumer.h> #include <linux/delay.h> +#include <asm/system_info.h> + #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -1090,6 +1092,7 @@ MACHINE_START(RAUMFELD_RC, "Raumfeld Controller") .atag_offset = 0x100, .init_machine = raumfeld_controller_init, .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa3xx_init_irq, .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, @@ -1102,6 +1105,7 @@ MACHINE_START(RAUMFELD_CONNECTOR, "Raumfeld Connector") .atag_offset = 0x100, .init_machine = raumfeld_connector_init, .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa3xx_init_irq, .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, @@ -1114,6 +1118,7 @@ MACHINE_START(RAUMFELD_SPEAKER, "Raumfeld Speaker") .atag_offset = 0x100, .init_machine = raumfeld_speaker_init, .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa3xx_init_irq, .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/reset.c b/arch/arm/mach-pxa/reset.c index c8497b00cdfe..b4528899ef08 100644 --- a/arch/arm/mach-pxa/reset.c +++ b/arch/arm/mach-pxa/reset.c @@ -9,6 +9,7 @@ #include <linux/gpio.h> #include <linux/io.h> #include <asm/proc-fns.h> +#include <asm/system_misc.h> #include <mach/regs-ost.h> #include <mach/reset.h> diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c index 0fe354efb931..86c95a5d8533 100644 --- a/arch/arm/mach-pxa/saar.c +++ b/arch/arm/mach-pxa/saar.c @@ -598,6 +598,7 @@ MACHINE_START(SAAR, "PXA930 Handheld Platform (aka SAAR)") /* Maintainer: Eric Miao <eric.miao@marvell.com> */ .atag_offset = 0x100, .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa3xx_init_irq, .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c index 30989baf7f2a..bdf4cb88ca0a 100644 --- a/arch/arm/mach-pxa/sharpsl_pm.c +++ b/arch/arm/mach-pxa/sharpsl_pm.c @@ -24,6 +24,7 @@ #include <linux/leds.h> #include <linux/suspend.h> #include <linux/gpio.h> +#include <linux/io.h> #include <asm/mach-types.h> #include <mach/pm.h> diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index abf355d0c92f..df2ab0fb2ace 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -984,6 +984,7 @@ MACHINE_START(SPITZ, "SHARP Spitz") .restart_mode = 'g', .fixup = spitz_fixup, .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .init_machine = spitz_init, @@ -997,6 +998,7 @@ MACHINE_START(BORZOI, "SHARP Borzoi") .restart_mode = 'g', .fixup = spitz_fixup, .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .init_machine = spitz_init, @@ -1010,6 +1012,7 @@ MACHINE_START(AKITA, "SHARP Akita") .restart_mode = 'g', .fixup = spitz_fixup, .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .init_machine = spitz_init, diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c index b0656e158d90..4cd645e29b64 100644 --- a/arch/arm/mach-pxa/stargate2.c +++ b/arch/arm/mach-pxa/stargate2.c @@ -152,7 +152,7 @@ static struct platform_device sht15 = { static struct regulator_consumer_supply stargate2_sensor_3_con[] = { { - .dev = &sht15.dev, + .dev_name = "sht15", .supply = "vcc", }, }; @@ -1006,6 +1006,7 @@ static void __init stargate2_init(void) #ifdef CONFIG_MACH_INTELMOTE2 MACHINE_START(INTELMOTE2, "IMOTE 2") .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c index 9fb38e80e076..736bfdc50ee6 100644 --- a/arch/arm/mach-pxa/tavorevb.c +++ b/arch/arm/mach-pxa/tavorevb.c @@ -491,6 +491,7 @@ MACHINE_START(TAVOREVB, "PXA930 Evaluation Board (aka TavorEVB)") /* Maintainer: Eric Miao <eric.miao@marvell.com> */ .atag_offset = 0x100, .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa3xx_init_irq, .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index b503049d6d26..3d6c9bd90de6 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c @@ -22,6 +22,7 @@ #include <asm/mach/time.h> #include <asm/sched_clock.h> #include <mach/regs-ost.h> +#include <mach/irqs.h> /* * This is PXA's sched_clock implementation. This has a resolution diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index 0f30af617d8f..2b6ac00b2cd9 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c @@ -558,6 +558,7 @@ MACHINE_START(TRIZEPS4, "Keith und Koep Trizeps IV module") .atag_offset = 0x100, .init_machine = trizeps4_init, .map_io = trizeps4_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, @@ -569,6 +570,7 @@ MACHINE_START(TRIZEPS4WL, "Keith und Koep Trizeps IV-WL module") .atag_offset = 0x100, .init_machine = trizeps4_init, .map_io = trizeps4_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c index 023d6ca789de..130379fb9d0f 100644 --- a/arch/arm/mach-pxa/viper.c +++ b/arch/arm/mach-pxa/viper.c @@ -57,6 +57,7 @@ #include <asm/mach-types.h> #include <asm/irq.h> #include <asm/sizes.h> +#include <asm/system_info.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -994,6 +995,7 @@ MACHINE_START(VIPER, "Arcom/Eurotech VIPER SBC") /* Maintainer: Marc Zyngier <maz@misterjones.org> */ .atag_offset = 0x100, .map_io = viper_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = viper_init_irq, .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index 1f5cfa96f6d6..c57ab636ea9c 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c @@ -718,6 +718,7 @@ static void __init vpac270_init(void) MACHINE_START(VPAC270, "Voipac PXA270") .atag_offset = 0x100, .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/xcep.c b/arch/arm/mach-pxa/xcep.c index 4bbe9a36fe74..4275713ccd10 100644 --- a/arch/arm/mach-pxa/xcep.c +++ b/arch/arm/mach-pxa/xcep.c @@ -182,6 +182,7 @@ MACHINE_START(XCEP, "Iskratel XCEP") .atag_offset = 0x100, .init_machine = xcep_init, .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c index b6476848b561..fa8619970841 100644 --- a/arch/arm/mach-pxa/z2.c +++ b/arch/arm/mach-pxa/z2.c @@ -721,6 +721,7 @@ static void __init z2_init(void) MACHINE_START(ZIPIT2, "Zipit Z2") .atag_offset = 0x100, .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index a4dd1c347050..af3d4f7646d7 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c @@ -32,6 +32,7 @@ #include <asm/mach-types.h> #include <asm/suspend.h> +#include <asm/system_info.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index acd329afc3ac..45868bb43cbd 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -33,7 +33,6 @@ #include <linux/clkdev.h> #include <linux/mtd/physmap.h> -#include <asm/system.h> #include <mach/hardware.h> #include <asm/irq.h> #include <asm/leds.h> diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h index 735b57aaf2d6..f8f2c0ac4c01 100644 --- a/arch/arm/mach-realview/core.h +++ b/arch/arm/mach-realview/core.h @@ -28,21 +28,11 @@ #include <asm/setup.h> #include <asm/leds.h> -#define AMBA_DEVICE(name,busid,base,plat) \ -static struct amba_device name##_device = { \ - .dev = { \ - .coherent_dma_mask = ~0, \ - .init_name = busid, \ - .platform_data = plat, \ - }, \ - .res = { \ - .start = REALVIEW_##base##_BASE, \ - .end = (REALVIEW_##base##_BASE) + SZ_4K - 1, \ - .flags = IORESOURCE_MEM, \ - }, \ - .dma_mask = ~0, \ - .irq = base##_IRQ, \ -} +#define APB_DEVICE(name, busid, base, plat) \ +static AMBA_APB_DEVICE(name, busid, 0, REALVIEW_##base##_BASE, base##_IRQ, plat) + +#define AHB_DEVICE(name, busid, base, plat) \ +static AMBA_AHB_DEVICE(name, busid, 0, REALVIEW_##base##_BASE, base##_IRQ, plat) struct machine_desc; diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c index eb55f05bef3a..57d9efba2956 100644 --- a/arch/arm/mach-realview/hotplug.c +++ b/arch/arm/mach-realview/hotplug.c @@ -13,6 +13,7 @@ #include <linux/smp.h> #include <asm/cacheflush.h> +#include <asm/cp15.h> #include <asm/smp_plat.h> extern volatile int pen_release; diff --git a/arch/arm/mach-realview/include/mach/entry-macro.S b/arch/arm/mach-realview/include/mach/entry-macro.S deleted file mode 100644 index e8a5179c2653..000000000000 --- a/arch/arm/mach-realview/include/mach/entry-macro.S +++ /dev/null @@ -1,16 +0,0 @@ -/* - * arch/arm/mach-realview/include/mach/entry-macro.S - * - * Low-level IRQ helper macros for RealView platforms - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm - diff --git a/arch/arm/mach-realview/include/mach/hardware.h b/arch/arm/mach-realview/include/mach/hardware.h index 8a638d15797f..281e71c97525 100644 --- a/arch/arm/mach-realview/include/mach/hardware.h +++ b/arch/arm/mach-realview/include/mach/hardware.h @@ -37,6 +37,6 @@ #else #define IO_ADDRESS(x) (x) #endif -#define __io_address(n) __io(IO_ADDRESS(n)) +#define __io_address(n) IOMEM(IO_ADDRESS(n)) #endif diff --git a/arch/arm/mach-realview/include/mach/io.h b/arch/arm/mach-realview/include/mach/io.h deleted file mode 100644 index f05bcdf605d8..000000000000 --- a/arch/arm/mach-realview/include/mach/io.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * arch/arm/mach-realview/include/mach/io.h - * - * 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. - * - * 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_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#endif diff --git a/arch/arm/mach-realview/include/mach/irqs-eb.h b/arch/arm/mach-realview/include/mach/irqs-eb.h index 204d5378f309..d6b5073692d2 100644 --- a/arch/arm/mach-realview/include/mach/irqs-eb.h +++ b/arch/arm/mach-realview/include/mach/irqs-eb.h @@ -96,16 +96,19 @@ #define IRQ_EB11MP_L220_SLAVE (IRQ_EB_GIC_START + 30) #define IRQ_EB11MP_L220_DECODE (IRQ_EB_GIC_START + 31) -#define IRQ_EB11MP_UART2 -1 -#define IRQ_EB11MP_UART3 -1 -#define IRQ_EB11MP_CLCD -1 -#define IRQ_EB11MP_DMA -1 -#define IRQ_EB11MP_WDOG -1 -#define IRQ_EB11MP_GPIO0 -1 -#define IRQ_EB11MP_GPIO1 -1 -#define IRQ_EB11MP_GPIO2 -1 -#define IRQ_EB11MP_SCI -1 -#define IRQ_EB11MP_SSP -1 +/* + * The 11MPcore tile leaves the following unconnected. + */ +#define IRQ_EB11MP_UART2 0 +#define IRQ_EB11MP_UART3 0 +#define IRQ_EB11MP_CLCD 0 +#define IRQ_EB11MP_DMA 0 +#define IRQ_EB11MP_WDOG 0 +#define IRQ_EB11MP_GPIO0 0 +#define IRQ_EB11MP_GPIO1 0 +#define IRQ_EB11MP_GPIO2 0 +#define IRQ_EB11MP_SCI 0 +#define IRQ_EB11MP_SSP 0 #define NR_GIC_EB11MP 2 diff --git a/arch/arm/mach-realview/include/mach/irqs-pb1176.h b/arch/arm/mach-realview/include/mach/irqs-pb1176.h index 5c3c625e3e04..708f84156f2c 100644 --- a/arch/arm/mach-realview/include/mach/irqs-pb1176.h +++ b/arch/arm/mach-realview/include/mach/irqs-pb1176.h @@ -40,6 +40,7 @@ #define IRQ_DC1176_L2CC (IRQ_DC1176_GIC_START + 13) #define IRQ_DC1176_RTC (IRQ_DC1176_GIC_START + 14) #define IRQ_DC1176_CLCD (IRQ_DC1176_GIC_START + 15) /* CLCD controller */ +#define IRQ_DC1176_GPIO0 (IRQ_DC1176_GIC_START + 16) #define IRQ_DC1176_SSP (IRQ_DC1176_GIC_START + 17) /* SSP port */ #define IRQ_DC1176_UART0 (IRQ_DC1176_GIC_START + 18) /* UART 0 on development chip */ #define IRQ_DC1176_UART1 (IRQ_DC1176_GIC_START + 19) /* UART 1 on development chip */ @@ -73,7 +74,6 @@ #define IRQ_PB1176_DMAC (IRQ_PB1176_GIC_START + 24) /* DMA controller */ #define IRQ_PB1176_RTC (IRQ_PB1176_GIC_START + 25) /* Real Time Clock */ -#define IRQ_PB1176_GPIO0 -1 #define IRQ_PB1176_SCTL -1 #define NR_GIC_PB1176 2 diff --git a/arch/arm/mach-realview/include/mach/system.h b/arch/arm/mach-realview/include/mach/system.h deleted file mode 100644 index 471b671159ce..000000000000 --- a/arch/arm/mach-realview/include/mach/system.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * arch/arm/mach-realview/include/mach/system.h - * - * Copyright (C) 2003 ARM Limited - * Copyright (C) 2000 Deep Blue Solutions Ltd - * - * 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_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - /* - * This should do all the clock switching - * and wait for interrupt tricks - */ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c index 9578145f2df0..baf382c5e776 100644 --- a/arch/arm/mach-realview/realview_eb.c +++ b/arch/arm/mach-realview/realview_eb.c @@ -36,7 +36,7 @@ #include <asm/pgtable.h> #include <asm/hardware/gic.h> #include <asm/hardware/cache-l2x0.h> -#include <asm/localtimer.h> +#include <asm/smp_twd.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -135,63 +135,63 @@ static struct pl022_ssp_controller ssp0_plat_data = { /* * These devices are connected via the core APB bridge */ -#define GPIO2_IRQ { IRQ_EB_GPIO2, NO_IRQ } -#define GPIO3_IRQ { IRQ_EB_GPIO3, NO_IRQ } +#define GPIO2_IRQ { IRQ_EB_GPIO2 } +#define GPIO3_IRQ { IRQ_EB_GPIO3 } -#define AACI_IRQ { IRQ_EB_AACI, NO_IRQ } +#define AACI_IRQ { IRQ_EB_AACI } #define MMCI0_IRQ { IRQ_EB_MMCI0A, IRQ_EB_MMCI0B } -#define KMI0_IRQ { IRQ_EB_KMI0, NO_IRQ } -#define KMI1_IRQ { IRQ_EB_KMI1, NO_IRQ } +#define KMI0_IRQ { IRQ_EB_KMI0 } +#define KMI1_IRQ { IRQ_EB_KMI1 } /* * These devices are connected directly to the multi-layer AHB switch */ -#define EB_SMC_IRQ { NO_IRQ, NO_IRQ } -#define MPMC_IRQ { NO_IRQ, NO_IRQ } -#define EB_CLCD_IRQ { IRQ_EB_CLCD, NO_IRQ } -#define DMAC_IRQ { IRQ_EB_DMA, NO_IRQ } +#define EB_SMC_IRQ { } +#define MPMC_IRQ { } +#define EB_CLCD_IRQ { IRQ_EB_CLCD } +#define DMAC_IRQ { IRQ_EB_DMA } /* * These devices are connected via the core APB bridge */ -#define SCTL_IRQ { NO_IRQ, NO_IRQ } -#define EB_WATCHDOG_IRQ { IRQ_EB_WDOG, NO_IRQ } -#define EB_GPIO0_IRQ { IRQ_EB_GPIO0, NO_IRQ } -#define GPIO1_IRQ { IRQ_EB_GPIO1, NO_IRQ } -#define EB_RTC_IRQ { IRQ_EB_RTC, NO_IRQ } +#define SCTL_IRQ { } +#define EB_WATCHDOG_IRQ { IRQ_EB_WDOG } +#define EB_GPIO0_IRQ { IRQ_EB_GPIO0 } +#define GPIO1_IRQ { IRQ_EB_GPIO1 } +#define EB_RTC_IRQ { IRQ_EB_RTC } /* * These devices are connected via the DMA APB bridge */ -#define SCI_IRQ { IRQ_EB_SCI, NO_IRQ } -#define EB_UART0_IRQ { IRQ_EB_UART0, NO_IRQ } -#define EB_UART1_IRQ { IRQ_EB_UART1, NO_IRQ } -#define EB_UART2_IRQ { IRQ_EB_UART2, NO_IRQ } -#define EB_UART3_IRQ { IRQ_EB_UART3, NO_IRQ } -#define EB_SSP_IRQ { IRQ_EB_SSP, NO_IRQ } +#define SCI_IRQ { IRQ_EB_SCI } +#define EB_UART0_IRQ { IRQ_EB_UART0 } +#define EB_UART1_IRQ { IRQ_EB_UART1 } +#define EB_UART2_IRQ { IRQ_EB_UART2 } +#define EB_UART3_IRQ { IRQ_EB_UART3 } +#define EB_SSP_IRQ { IRQ_EB_SSP } /* FPGA Primecells */ -AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL); -AMBA_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data); -AMBA_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL); -AMBA_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL); -AMBA_DEVICE(uart3, "fpga:uart3", EB_UART3, NULL); +APB_DEVICE(aaci, "fpga:aaci", AACI, NULL); +APB_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data); +APB_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL); +APB_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL); +APB_DEVICE(uart3, "fpga:uart3", EB_UART3, NULL); /* DevChip Primecells */ -AMBA_DEVICE(smc, "dev:smc", EB_SMC, NULL); -AMBA_DEVICE(clcd, "dev:clcd", EB_CLCD, &clcd_plat_data); -AMBA_DEVICE(dmac, "dev:dmac", DMAC, NULL); -AMBA_DEVICE(sctl, "dev:sctl", SCTL, NULL); -AMBA_DEVICE(wdog, "dev:wdog", EB_WATCHDOG, NULL); -AMBA_DEVICE(gpio0, "dev:gpio0", EB_GPIO0, &gpio0_plat_data); -AMBA_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data); -AMBA_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data); -AMBA_DEVICE(rtc, "dev:rtc", EB_RTC, NULL); -AMBA_DEVICE(sci0, "dev:sci0", SCI, NULL); -AMBA_DEVICE(uart0, "dev:uart0", EB_UART0, NULL); -AMBA_DEVICE(uart1, "dev:uart1", EB_UART1, NULL); -AMBA_DEVICE(uart2, "dev:uart2", EB_UART2, NULL); -AMBA_DEVICE(ssp0, "dev:ssp0", EB_SSP, &ssp0_plat_data); +AHB_DEVICE(smc, "dev:smc", EB_SMC, NULL); +AHB_DEVICE(clcd, "dev:clcd", EB_CLCD, &clcd_plat_data); +AHB_DEVICE(dmac, "dev:dmac", DMAC, NULL); +AHB_DEVICE(sctl, "dev:sctl", SCTL, NULL); +APB_DEVICE(wdog, "dev:wdog", EB_WATCHDOG, NULL); +APB_DEVICE(gpio0, "dev:gpio0", EB_GPIO0, &gpio0_plat_data); +APB_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data); +APB_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data); +APB_DEVICE(rtc, "dev:rtc", EB_RTC, NULL); +APB_DEVICE(sci0, "dev:sci0", SCI, NULL); +APB_DEVICE(uart0, "dev:uart0", EB_UART0, NULL); +APB_DEVICE(uart1, "dev:uart1", EB_UART1, NULL); +APB_DEVICE(uart2, "dev:uart2", EB_UART2, NULL); +APB_DEVICE(ssp0, "dev:ssp0", EB_SSP, &ssp0_plat_data); static struct amba_device *amba_devs[] __initdata = { &dmac_device, @@ -383,6 +383,23 @@ static void realview_eb11mp_fixup(void) realview_eb_isp1761_resources[1].end = IRQ_EB11MP_USB; } +#ifdef CONFIG_HAVE_ARM_TWD +static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, + REALVIEW_EB11MP_TWD_BASE, + IRQ_LOCALTIMER); + +static void __init realview_eb_twd_init(void) +{ + if (core_tile_eb11mp() || core_tile_a9mp()) { + int err = twd_local_timer_register(&twd_local_timer); + if (err) + pr_err("twd_local_timer_register failed %d\n", err); + } +} +#else +#define realview_eb_twd_init() do { } while(0) +#endif + static void __init realview_eb_timer_init(void) { unsigned int timer_irq; @@ -392,15 +409,13 @@ static void __init realview_eb_timer_init(void) timer2_va_base = __io_address(REALVIEW_EB_TIMER2_3_BASE); timer3_va_base = __io_address(REALVIEW_EB_TIMER2_3_BASE) + 0x20; - if (core_tile_eb11mp() || core_tile_a9mp()) { -#ifdef CONFIG_LOCAL_TIMERS - twd_base = __io_address(REALVIEW_EB11MP_TWD_BASE); -#endif + if (core_tile_eb11mp() || core_tile_a9mp()) timer_irq = IRQ_EB11MP_TIMER0_1; - } else + else timer_irq = IRQ_EB_TIMER0_1; realview_timer_init(timer_irq); + realview_eb_twd_init(); } static struct sys_timer realview_eb_timer = { diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c index e4abe94fb11a..b1d7cafa1a6d 100644 --- a/arch/arm/mach-realview/realview_pb1176.c +++ b/arch/arm/mach-realview/realview_pb1176.c @@ -132,50 +132,50 @@ static struct pl022_ssp_controller ssp0_plat_data = { /* * RealView PB1176 AMBA devices */ -#define GPIO2_IRQ { IRQ_PB1176_GPIO2, NO_IRQ } -#define GPIO3_IRQ { IRQ_PB1176_GPIO3, NO_IRQ } -#define AACI_IRQ { IRQ_PB1176_AACI, NO_IRQ } +#define GPIO2_IRQ { IRQ_PB1176_GPIO2 } +#define GPIO3_IRQ { IRQ_PB1176_GPIO3 } +#define AACI_IRQ { IRQ_PB1176_AACI } #define MMCI0_IRQ { IRQ_PB1176_MMCI0A, IRQ_PB1176_MMCI0B } -#define KMI0_IRQ { IRQ_PB1176_KMI0, NO_IRQ } -#define KMI1_IRQ { IRQ_PB1176_KMI1, NO_IRQ } -#define PB1176_SMC_IRQ { NO_IRQ, NO_IRQ } -#define MPMC_IRQ { NO_IRQ, NO_IRQ } -#define PB1176_CLCD_IRQ { IRQ_DC1176_CLCD, NO_IRQ } -#define SCTL_IRQ { NO_IRQ, NO_IRQ } -#define PB1176_WATCHDOG_IRQ { IRQ_DC1176_WATCHDOG, NO_IRQ } -#define PB1176_GPIO0_IRQ { IRQ_PB1176_GPIO0, NO_IRQ } -#define GPIO1_IRQ { IRQ_PB1176_GPIO1, NO_IRQ } -#define PB1176_RTC_IRQ { IRQ_DC1176_RTC, NO_IRQ } -#define SCI_IRQ { IRQ_PB1176_SCI, NO_IRQ } -#define PB1176_UART0_IRQ { IRQ_DC1176_UART0, NO_IRQ } -#define PB1176_UART1_IRQ { IRQ_DC1176_UART1, NO_IRQ } -#define PB1176_UART2_IRQ { IRQ_DC1176_UART2, NO_IRQ } -#define PB1176_UART3_IRQ { IRQ_DC1176_UART3, NO_IRQ } -#define PB1176_UART4_IRQ { IRQ_PB1176_UART4, NO_IRQ } -#define PB1176_SSP_IRQ { IRQ_DC1176_SSP, NO_IRQ } +#define KMI0_IRQ { IRQ_PB1176_KMI0 } +#define KMI1_IRQ { IRQ_PB1176_KMI1 } +#define PB1176_SMC_IRQ { } +#define MPMC_IRQ { } +#define PB1176_CLCD_IRQ { IRQ_DC1176_CLCD } +#define SCTL_IRQ { } +#define PB1176_WATCHDOG_IRQ { IRQ_DC1176_WATCHDOG } +#define PB1176_GPIO0_IRQ { IRQ_DC1176_GPIO0 } +#define GPIO1_IRQ { IRQ_PB1176_GPIO1 } +#define PB1176_RTC_IRQ { IRQ_DC1176_RTC } +#define SCI_IRQ { IRQ_PB1176_SCI } +#define PB1176_UART0_IRQ { IRQ_DC1176_UART0 } +#define PB1176_UART1_IRQ { IRQ_DC1176_UART1 } +#define PB1176_UART2_IRQ { IRQ_DC1176_UART2 } +#define PB1176_UART3_IRQ { IRQ_DC1176_UART3 } +#define PB1176_UART4_IRQ { IRQ_PB1176_UART4 } +#define PB1176_SSP_IRQ { IRQ_DC1176_SSP } /* FPGA Primecells */ -AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL); -AMBA_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data); -AMBA_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL); -AMBA_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL); -AMBA_DEVICE(uart4, "fpga:uart4", PB1176_UART4, NULL); +APB_DEVICE(aaci, "fpga:aaci", AACI, NULL); +APB_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data); +APB_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL); +APB_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL); +APB_DEVICE(uart4, "fpga:uart4", PB1176_UART4, NULL); /* DevChip Primecells */ -AMBA_DEVICE(smc, "dev:smc", PB1176_SMC, NULL); -AMBA_DEVICE(sctl, "dev:sctl", SCTL, NULL); -AMBA_DEVICE(wdog, "dev:wdog", PB1176_WATCHDOG, NULL); -AMBA_DEVICE(gpio0, "dev:gpio0", PB1176_GPIO0, &gpio0_plat_data); -AMBA_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data); -AMBA_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data); -AMBA_DEVICE(rtc, "dev:rtc", PB1176_RTC, NULL); -AMBA_DEVICE(sci0, "dev:sci0", SCI, NULL); -AMBA_DEVICE(uart0, "dev:uart0", PB1176_UART0, NULL); -AMBA_DEVICE(uart1, "dev:uart1", PB1176_UART1, NULL); -AMBA_DEVICE(uart2, "dev:uart2", PB1176_UART2, NULL); -AMBA_DEVICE(uart3, "dev:uart3", PB1176_UART3, NULL); -AMBA_DEVICE(ssp0, "dev:ssp0", PB1176_SSP, &ssp0_plat_data); -AMBA_DEVICE(clcd, "dev:clcd", PB1176_CLCD, &clcd_plat_data); +AHB_DEVICE(smc, "dev:smc", PB1176_SMC, NULL); +AHB_DEVICE(sctl, "dev:sctl", SCTL, NULL); +APB_DEVICE(wdog, "dev:wdog", PB1176_WATCHDOG, NULL); +APB_DEVICE(gpio0, "dev:gpio0", PB1176_GPIO0, &gpio0_plat_data); +APB_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data); +APB_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data); +APB_DEVICE(rtc, "dev:rtc", PB1176_RTC, NULL); +APB_DEVICE(sci0, "dev:sci0", SCI, NULL); +APB_DEVICE(uart0, "dev:uart0", PB1176_UART0, NULL); +APB_DEVICE(uart1, "dev:uart1", PB1176_UART1, NULL); +APB_DEVICE(uart2, "dev:uart2", PB1176_UART2, NULL); +APB_DEVICE(uart3, "dev:uart3", PB1176_UART3, NULL); +APB_DEVICE(ssp0, "dev:ssp0", PB1176_SSP, &ssp0_plat_data); +AHB_DEVICE(clcd, "dev:clcd", PB1176_CLCD, &clcd_plat_data); static struct amba_device *amba_devs[] __initdata = { &uart0_device, diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c index 2147335f66f5..a98c536e3327 100644 --- a/arch/arm/mach-realview/realview_pb11mp.c +++ b/arch/arm/mach-realview/realview_pb11mp.c @@ -36,7 +36,7 @@ #include <asm/pgtable.h> #include <asm/hardware/gic.h> #include <asm/hardware/cache-l2x0.h> -#include <asm/localtimer.h> +#include <asm/smp_twd.h> #include <asm/mach/arch.h> #include <asm/mach/flash.h> @@ -127,52 +127,52 @@ static struct pl022_ssp_controller ssp0_plat_data = { * RealView PB11MPCore AMBA devices */ -#define GPIO2_IRQ { IRQ_PB11MP_GPIO2, NO_IRQ } -#define GPIO3_IRQ { IRQ_PB11MP_GPIO3, NO_IRQ } -#define AACI_IRQ { IRQ_TC11MP_AACI, NO_IRQ } +#define GPIO2_IRQ { IRQ_PB11MP_GPIO2 } +#define GPIO3_IRQ { IRQ_PB11MP_GPIO3 } +#define AACI_IRQ { IRQ_TC11MP_AACI } #define MMCI0_IRQ { IRQ_TC11MP_MMCI0A, IRQ_TC11MP_MMCI0B } -#define KMI0_IRQ { IRQ_TC11MP_KMI0, NO_IRQ } -#define KMI1_IRQ { IRQ_TC11MP_KMI1, NO_IRQ } -#define PB11MP_SMC_IRQ { NO_IRQ, NO_IRQ } -#define MPMC_IRQ { NO_IRQ, NO_IRQ } -#define PB11MP_CLCD_IRQ { IRQ_PB11MP_CLCD, NO_IRQ } -#define DMAC_IRQ { IRQ_PB11MP_DMAC, NO_IRQ } -#define SCTL_IRQ { NO_IRQ, NO_IRQ } -#define PB11MP_WATCHDOG_IRQ { IRQ_PB11MP_WATCHDOG, NO_IRQ } -#define PB11MP_GPIO0_IRQ { IRQ_PB11MP_GPIO0, NO_IRQ } -#define GPIO1_IRQ { IRQ_PB11MP_GPIO1, NO_IRQ } -#define PB11MP_RTC_IRQ { IRQ_TC11MP_RTC, NO_IRQ } -#define SCI_IRQ { IRQ_PB11MP_SCI, NO_IRQ } -#define PB11MP_UART0_IRQ { IRQ_TC11MP_UART0, NO_IRQ } -#define PB11MP_UART1_IRQ { IRQ_TC11MP_UART1, NO_IRQ } -#define PB11MP_UART2_IRQ { IRQ_PB11MP_UART2, NO_IRQ } -#define PB11MP_UART3_IRQ { IRQ_PB11MP_UART3, NO_IRQ } -#define PB11MP_SSP_IRQ { IRQ_PB11MP_SSP, NO_IRQ } +#define KMI0_IRQ { IRQ_TC11MP_KMI0 } +#define KMI1_IRQ { IRQ_TC11MP_KMI1 } +#define PB11MP_SMC_IRQ { } +#define MPMC_IRQ { } +#define PB11MP_CLCD_IRQ { IRQ_PB11MP_CLCD } +#define DMAC_IRQ { IRQ_PB11MP_DMAC } +#define SCTL_IRQ { } +#define PB11MP_WATCHDOG_IRQ { IRQ_PB11MP_WATCHDOG } +#define PB11MP_GPIO0_IRQ { IRQ_PB11MP_GPIO0 } +#define GPIO1_IRQ { IRQ_PB11MP_GPIO1 } +#define PB11MP_RTC_IRQ { IRQ_TC11MP_RTC } +#define SCI_IRQ { IRQ_PB11MP_SCI } +#define PB11MP_UART0_IRQ { IRQ_TC11MP_UART0 } +#define PB11MP_UART1_IRQ { IRQ_TC11MP_UART1 } +#define PB11MP_UART2_IRQ { IRQ_PB11MP_UART2 } +#define PB11MP_UART3_IRQ { IRQ_PB11MP_UART3 } +#define PB11MP_SSP_IRQ { IRQ_PB11MP_SSP } /* FPGA Primecells */ -AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL); -AMBA_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data); -AMBA_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL); -AMBA_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL); -AMBA_DEVICE(uart3, "fpga:uart3", PB11MP_UART3, NULL); +APB_DEVICE(aaci, "fpga:aaci", AACI, NULL); +APB_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data); +APB_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL); +APB_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL); +APB_DEVICE(uart3, "fpga:uart3", PB11MP_UART3, NULL); /* DevChip Primecells */ -AMBA_DEVICE(smc, "dev:smc", PB11MP_SMC, NULL); -AMBA_DEVICE(sctl, "dev:sctl", SCTL, NULL); -AMBA_DEVICE(wdog, "dev:wdog", PB11MP_WATCHDOG, NULL); -AMBA_DEVICE(gpio0, "dev:gpio0", PB11MP_GPIO0, &gpio0_plat_data); -AMBA_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data); -AMBA_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data); -AMBA_DEVICE(rtc, "dev:rtc", PB11MP_RTC, NULL); -AMBA_DEVICE(sci0, "dev:sci0", SCI, NULL); -AMBA_DEVICE(uart0, "dev:uart0", PB11MP_UART0, NULL); -AMBA_DEVICE(uart1, "dev:uart1", PB11MP_UART1, NULL); -AMBA_DEVICE(uart2, "dev:uart2", PB11MP_UART2, NULL); -AMBA_DEVICE(ssp0, "dev:ssp0", PB11MP_SSP, &ssp0_plat_data); +AHB_DEVICE(smc, "dev:smc", PB11MP_SMC, NULL); +AHB_DEVICE(sctl, "dev:sctl", SCTL, NULL); +APB_DEVICE(wdog, "dev:wdog", PB11MP_WATCHDOG, NULL); +APB_DEVICE(gpio0, "dev:gpio0", PB11MP_GPIO0, &gpio0_plat_data); +APB_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data); +APB_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data); +APB_DEVICE(rtc, "dev:rtc", PB11MP_RTC, NULL); +APB_DEVICE(sci0, "dev:sci0", SCI, NULL); +APB_DEVICE(uart0, "dev:uart0", PB11MP_UART0, NULL); +APB_DEVICE(uart1, "dev:uart1", PB11MP_UART1, NULL); +APB_DEVICE(uart2, "dev:uart2", PB11MP_UART2, NULL); +APB_DEVICE(ssp0, "dev:ssp0", PB11MP_SSP, &ssp0_plat_data); /* Primecells on the NEC ISSP chip */ -AMBA_DEVICE(clcd, "issp:clcd", PB11MP_CLCD, &clcd_plat_data); -AMBA_DEVICE(dmac, "issp:dmac", DMAC, NULL); +AHB_DEVICE(clcd, "issp:clcd", PB11MP_CLCD, &clcd_plat_data); +AHB_DEVICE(dmac, "issp:dmac", DMAC, NULL); static struct amba_device *amba_devs[] __initdata = { &dmac_device, @@ -290,6 +290,21 @@ static void __init gic_init_irq(void) gic_cascade_irq(1, IRQ_TC11MP_PB_IRQ1); } +#ifdef CONFIG_HAVE_ARM_TWD +static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, + REALVIEW_TC11MP_TWD_BASE, + IRQ_LOCALTIMER); + +static void __init realview_pb11mp_twd_init(void) +{ + int err = twd_local_timer_register(&twd_local_timer); + if (err) + pr_err("twd_local_timer_register failed %d\n", err); +} +#else +#define realview_pb11mp_twd_init() do {} while(0) +#endif + static void __init realview_pb11mp_timer_init(void) { timer0_va_base = __io_address(REALVIEW_PB11MP_TIMER0_1_BASE); @@ -297,10 +312,8 @@ static void __init realview_pb11mp_timer_init(void) timer2_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE); timer3_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE) + 0x20; -#ifdef CONFIG_LOCAL_TIMERS - twd_base = __io_address(REALVIEW_TC11MP_TWD_BASE); -#endif realview_timer_init(IRQ_TC11MP_TIMER0_1); + realview_pb11mp_twd_init(); } static struct sys_timer realview_pb11mp_timer = { diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c index 25b2e59296f8..59650174e6ed 100644 --- a/arch/arm/mach-realview/realview_pba8.c +++ b/arch/arm/mach-realview/realview_pba8.c @@ -122,52 +122,52 @@ static struct pl022_ssp_controller ssp0_plat_data = { * RealView PBA8Core AMBA devices */ -#define GPIO2_IRQ { IRQ_PBA8_GPIO2, NO_IRQ } -#define GPIO3_IRQ { IRQ_PBA8_GPIO3, NO_IRQ } -#define AACI_IRQ { IRQ_PBA8_AACI, NO_IRQ } +#define GPIO2_IRQ { IRQ_PBA8_GPIO2 } +#define GPIO3_IRQ { IRQ_PBA8_GPIO3 } +#define AACI_IRQ { IRQ_PBA8_AACI } #define MMCI0_IRQ { IRQ_PBA8_MMCI0A, IRQ_PBA8_MMCI0B } -#define KMI0_IRQ { IRQ_PBA8_KMI0, NO_IRQ } -#define KMI1_IRQ { IRQ_PBA8_KMI1, NO_IRQ } -#define PBA8_SMC_IRQ { NO_IRQ, NO_IRQ } -#define MPMC_IRQ { NO_IRQ, NO_IRQ } -#define PBA8_CLCD_IRQ { IRQ_PBA8_CLCD, NO_IRQ } -#define DMAC_IRQ { IRQ_PBA8_DMAC, NO_IRQ } -#define SCTL_IRQ { NO_IRQ, NO_IRQ } -#define PBA8_WATCHDOG_IRQ { IRQ_PBA8_WATCHDOG, NO_IRQ } -#define PBA8_GPIO0_IRQ { IRQ_PBA8_GPIO0, NO_IRQ } -#define GPIO1_IRQ { IRQ_PBA8_GPIO1, NO_IRQ } -#define PBA8_RTC_IRQ { IRQ_PBA8_RTC, NO_IRQ } -#define SCI_IRQ { IRQ_PBA8_SCI, NO_IRQ } -#define PBA8_UART0_IRQ { IRQ_PBA8_UART0, NO_IRQ } -#define PBA8_UART1_IRQ { IRQ_PBA8_UART1, NO_IRQ } -#define PBA8_UART2_IRQ { IRQ_PBA8_UART2, NO_IRQ } -#define PBA8_UART3_IRQ { IRQ_PBA8_UART3, NO_IRQ } -#define PBA8_SSP_IRQ { IRQ_PBA8_SSP, NO_IRQ } +#define KMI0_IRQ { IRQ_PBA8_KMI0 } +#define KMI1_IRQ { IRQ_PBA8_KMI1 } +#define PBA8_SMC_IRQ { } +#define MPMC_IRQ { } +#define PBA8_CLCD_IRQ { IRQ_PBA8_CLCD } +#define DMAC_IRQ { IRQ_PBA8_DMAC } +#define SCTL_IRQ { } +#define PBA8_WATCHDOG_IRQ { IRQ_PBA8_WATCHDOG } +#define PBA8_GPIO0_IRQ { IRQ_PBA8_GPIO0 } +#define GPIO1_IRQ { IRQ_PBA8_GPIO1 } +#define PBA8_RTC_IRQ { IRQ_PBA8_RTC } +#define SCI_IRQ { IRQ_PBA8_SCI } +#define PBA8_UART0_IRQ { IRQ_PBA8_UART0 } +#define PBA8_UART1_IRQ { IRQ_PBA8_UART1 } +#define PBA8_UART2_IRQ { IRQ_PBA8_UART2 } +#define PBA8_UART3_IRQ { IRQ_PBA8_UART3 } +#define PBA8_SSP_IRQ { IRQ_PBA8_SSP } /* FPGA Primecells */ -AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL); -AMBA_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data); -AMBA_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL); -AMBA_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL); -AMBA_DEVICE(uart3, "fpga:uart3", PBA8_UART3, NULL); +APB_DEVICE(aaci, "fpga:aaci", AACI, NULL); +APB_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data); +APB_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL); +APB_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL); +APB_DEVICE(uart3, "fpga:uart3", PBA8_UART3, NULL); /* DevChip Primecells */ -AMBA_DEVICE(smc, "dev:smc", PBA8_SMC, NULL); -AMBA_DEVICE(sctl, "dev:sctl", SCTL, NULL); -AMBA_DEVICE(wdog, "dev:wdog", PBA8_WATCHDOG, NULL); -AMBA_DEVICE(gpio0, "dev:gpio0", PBA8_GPIO0, &gpio0_plat_data); -AMBA_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data); -AMBA_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data); -AMBA_DEVICE(rtc, "dev:rtc", PBA8_RTC, NULL); -AMBA_DEVICE(sci0, "dev:sci0", SCI, NULL); -AMBA_DEVICE(uart0, "dev:uart0", PBA8_UART0, NULL); -AMBA_DEVICE(uart1, "dev:uart1", PBA8_UART1, NULL); -AMBA_DEVICE(uart2, "dev:uart2", PBA8_UART2, NULL); -AMBA_DEVICE(ssp0, "dev:ssp0", PBA8_SSP, &ssp0_plat_data); +AHB_DEVICE(smc, "dev:smc", PBA8_SMC, NULL); +AHB_DEVICE(sctl, "dev:sctl", SCTL, NULL); +APB_DEVICE(wdog, "dev:wdog", PBA8_WATCHDOG, NULL); +APB_DEVICE(gpio0, "dev:gpio0", PBA8_GPIO0, &gpio0_plat_data); +APB_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data); +APB_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data); +APB_DEVICE(rtc, "dev:rtc", PBA8_RTC, NULL); +APB_DEVICE(sci0, "dev:sci0", SCI, NULL); +APB_DEVICE(uart0, "dev:uart0", PBA8_UART0, NULL); +APB_DEVICE(uart1, "dev:uart1", PBA8_UART1, NULL); +APB_DEVICE(uart2, "dev:uart2", PBA8_UART2, NULL); +APB_DEVICE(ssp0, "dev:ssp0", PBA8_SSP, &ssp0_plat_data); /* Primecells on the NEC ISSP chip */ -AMBA_DEVICE(clcd, "issp:clcd", PBA8_CLCD, &clcd_plat_data); -AMBA_DEVICE(dmac, "issp:dmac", DMAC, NULL); +AHB_DEVICE(clcd, "issp:clcd", PBA8_CLCD, &clcd_plat_data); +AHB_DEVICE(dmac, "issp:dmac", DMAC, NULL); static struct amba_device *amba_devs[] __initdata = { &dmac_device, diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c index ac715645b860..3f2f605624e9 100644 --- a/arch/arm/mach-realview/realview_pbx.c +++ b/arch/arm/mach-realview/realview_pbx.c @@ -144,52 +144,52 @@ static struct pl022_ssp_controller ssp0_plat_data = { * RealView PBXCore AMBA devices */ -#define GPIO2_IRQ { IRQ_PBX_GPIO2, NO_IRQ } -#define GPIO3_IRQ { IRQ_PBX_GPIO3, NO_IRQ } -#define AACI_IRQ { IRQ_PBX_AACI, NO_IRQ } +#define GPIO2_IRQ { IRQ_PBX_GPIO2 } +#define GPIO3_IRQ { IRQ_PBX_GPIO3 } +#define AACI_IRQ { IRQ_PBX_AACI } #define MMCI0_IRQ { IRQ_PBX_MMCI0A, IRQ_PBX_MMCI0B } -#define KMI0_IRQ { IRQ_PBX_KMI0, NO_IRQ } -#define KMI1_IRQ { IRQ_PBX_KMI1, NO_IRQ } -#define PBX_SMC_IRQ { NO_IRQ, NO_IRQ } -#define MPMC_IRQ { NO_IRQ, NO_IRQ } -#define PBX_CLCD_IRQ { IRQ_PBX_CLCD, NO_IRQ } -#define DMAC_IRQ { IRQ_PBX_DMAC, NO_IRQ } -#define SCTL_IRQ { NO_IRQ, NO_IRQ } -#define PBX_WATCHDOG_IRQ { IRQ_PBX_WATCHDOG, NO_IRQ } -#define PBX_GPIO0_IRQ { IRQ_PBX_GPIO0, NO_IRQ } -#define GPIO1_IRQ { IRQ_PBX_GPIO1, NO_IRQ } -#define PBX_RTC_IRQ { IRQ_PBX_RTC, NO_IRQ } -#define SCI_IRQ { IRQ_PBX_SCI, NO_IRQ } -#define PBX_UART0_IRQ { IRQ_PBX_UART0, NO_IRQ } -#define PBX_UART1_IRQ { IRQ_PBX_UART1, NO_IRQ } -#define PBX_UART2_IRQ { IRQ_PBX_UART2, NO_IRQ } -#define PBX_UART3_IRQ { IRQ_PBX_UART3, NO_IRQ } -#define PBX_SSP_IRQ { IRQ_PBX_SSP, NO_IRQ } +#define KMI0_IRQ { IRQ_PBX_KMI0 } +#define KMI1_IRQ { IRQ_PBX_KMI1 } +#define PBX_SMC_IRQ { } +#define MPMC_IRQ { } +#define PBX_CLCD_IRQ { IRQ_PBX_CLCD } +#define DMAC_IRQ { IRQ_PBX_DMAC } +#define SCTL_IRQ { } +#define PBX_WATCHDOG_IRQ { IRQ_PBX_WATCHDOG } +#define PBX_GPIO0_IRQ { IRQ_PBX_GPIO0 } +#define GPIO1_IRQ { IRQ_PBX_GPIO1 } +#define PBX_RTC_IRQ { IRQ_PBX_RTC } +#define SCI_IRQ { IRQ_PBX_SCI } +#define PBX_UART0_IRQ { IRQ_PBX_UART0 } +#define PBX_UART1_IRQ { IRQ_PBX_UART1 } +#define PBX_UART2_IRQ { IRQ_PBX_UART2 } +#define PBX_UART3_IRQ { IRQ_PBX_UART3 } +#define PBX_SSP_IRQ { IRQ_PBX_SSP } /* FPGA Primecells */ -AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL); -AMBA_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data); -AMBA_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL); -AMBA_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL); -AMBA_DEVICE(uart3, "fpga:uart3", PBX_UART3, NULL); +APB_DEVICE(aaci, "fpga:aaci", AACI, NULL); +APB_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data); +APB_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL); +APB_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL); +APB_DEVICE(uart3, "fpga:uart3", PBX_UART3, NULL); /* DevChip Primecells */ -AMBA_DEVICE(smc, "dev:smc", PBX_SMC, NULL); -AMBA_DEVICE(sctl, "dev:sctl", SCTL, NULL); -AMBA_DEVICE(wdog, "dev:wdog", PBX_WATCHDOG, NULL); -AMBA_DEVICE(gpio0, "dev:gpio0", PBX_GPIO0, &gpio0_plat_data); -AMBA_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data); -AMBA_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data); -AMBA_DEVICE(rtc, "dev:rtc", PBX_RTC, NULL); -AMBA_DEVICE(sci0, "dev:sci0", SCI, NULL); -AMBA_DEVICE(uart0, "dev:uart0", PBX_UART0, NULL); -AMBA_DEVICE(uart1, "dev:uart1", PBX_UART1, NULL); -AMBA_DEVICE(uart2, "dev:uart2", PBX_UART2, NULL); -AMBA_DEVICE(ssp0, "dev:ssp0", PBX_SSP, &ssp0_plat_data); +AHB_DEVICE(smc, "dev:smc", PBX_SMC, NULL); +AHB_DEVICE(sctl, "dev:sctl", SCTL, NULL); +APB_DEVICE(wdog, "dev:wdog", PBX_WATCHDOG, NULL); +APB_DEVICE(gpio0, "dev:gpio0", PBX_GPIO0, &gpio0_plat_data); +APB_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data); +APB_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data); +APB_DEVICE(rtc, "dev:rtc", PBX_RTC, NULL); +APB_DEVICE(sci0, "dev:sci0", SCI, NULL); +APB_DEVICE(uart0, "dev:uart0", PBX_UART0, NULL); +APB_DEVICE(uart1, "dev:uart1", PBX_UART1, NULL); +APB_DEVICE(uart2, "dev:uart2", PBX_UART2, NULL); +APB_DEVICE(ssp0, "dev:ssp0", PBX_SSP, &ssp0_plat_data); /* Primecells on the NEC ISSP chip */ -AMBA_DEVICE(clcd, "issp:clcd", PBX_CLCD, &clcd_plat_data); -AMBA_DEVICE(dmac, "issp:dmac", DMAC, NULL); +AHB_DEVICE(clcd, "issp:clcd", PBX_CLCD, &clcd_plat_data); +AHB_DEVICE(dmac, "issp:dmac", DMAC, NULL); static struct amba_device *amba_devs[] __initdata = { &dmac_device, @@ -298,6 +298,21 @@ static void __init gic_init_irq(void) } } +#ifdef CONFIG_HAVE_ARM_TWD +static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, + REALVIEW_PBX_TILE_TWD_BASE, + IRQ_LOCALTIMER); + +static void __init realview_pbx_twd_init(void) +{ + int err = twd_local_timer_register(&twd_local_timer); + if (err) + pr_err("twd_local_timer_register failed %d\n", err); +} +#else +#define realview_pbx_twd_init() do { } while(0) +#endif + static void __init realview_pbx_timer_init(void) { timer0_va_base = __io_address(REALVIEW_PBX_TIMER0_1_BASE); @@ -305,11 +320,8 @@ static void __init realview_pbx_timer_init(void) timer2_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE); timer3_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE) + 0x20; -#ifdef CONFIG_LOCAL_TIMERS - if (core_tile_pbx11mp() || core_tile_pbxa9mp()) - twd_base = __io_address(REALVIEW_PBX_TILE_TWD_BASE); -#endif realview_timer_init(IRQ_PBX_TIMER0_1); + realview_pbx_twd_init(); } static struct sys_timer realview_pbx_timer = { diff --git a/arch/arm/mach-rpc/Makefile b/arch/arm/mach-rpc/Makefile index aa77bc9efbbb..992e28b4ae9a 100644 --- a/arch/arm/mach-rpc/Makefile +++ b/arch/arm/mach-rpc/Makefile @@ -4,7 +4,7 @@ # Object file lists. -obj-y := dma.o irq.o riscpc.o +obj-y := dma.o ecard.o fiq.o irq.o riscpc.o time.o obj-m := obj-n := obj- := diff --git a/arch/arm/kernel/ecard.c b/arch/arm/mach-rpc/ecard.c index 1651d4950744..b91bc87b3dcf 100644 --- a/arch/arm/kernel/ecard.c +++ b/arch/arm/mach-rpc/ecard.c @@ -42,6 +42,7 @@ #include <linux/init.h> #include <linux/mutex.h> #include <linux/kthread.h> +#include <linux/irq.h> #include <linux/io.h> #include <asm/dma.h> @@ -54,10 +55,6 @@ #include "ecard.h" -#ifndef CONFIG_ARCH_RPC -#define HAVE_EXPMASK -#endif - struct ecard_request { void (*fn)(struct ecard_request *); ecard_t *ec; @@ -77,9 +74,6 @@ struct expcard_blacklist { static ecard_t *cards; static ecard_t *slot_to_expcard[MAX_ECARDS]; static unsigned int ectcr; -#ifdef HAS_EXPMASK -static unsigned int have_expmask; -#endif /* List of descriptions of cards which don't have an extended * identification, or chunk directories containing a description. @@ -391,22 +385,10 @@ int ecard_readchunk(struct in_chunk_dir *cd, ecard_t *ec, int id, int num) static void ecard_def_irq_enable(ecard_t *ec, int irqnr) { -#ifdef HAS_EXPMASK - if (irqnr < 4 && have_expmask) { - have_expmask |= 1 << irqnr; - __raw_writeb(have_expmask, EXPMASK_ENABLE); - } -#endif } static void ecard_def_irq_disable(ecard_t *ec, int irqnr) { -#ifdef HAS_EXPMASK - if (irqnr < 4 && have_expmask) { - have_expmask &= ~(1 << irqnr); - __raw_writeb(have_expmask, EXPMASK_ENABLE); - } -#endif } static int ecard_def_irq_pending(ecard_t *ec) @@ -446,7 +428,7 @@ static expansioncard_ops_t ecard_default_ops = { */ static void ecard_irq_unmask(struct irq_data *d) { - ecard_t *ec = slot_to_ecard(d->irq - 32); + ecard_t *ec = irq_data_get_irq_chip_data(d); if (ec) { if (!ec->ops) @@ -462,7 +444,7 @@ static void ecard_irq_unmask(struct irq_data *d) static void ecard_irq_mask(struct irq_data *d) { - ecard_t *ec = slot_to_ecard(d->irq - 32); + ecard_t *ec = irq_data_get_irq_chip_data(d); if (ec) { if (!ec->ops) @@ -579,7 +561,7 @@ ecard_irq_handler(unsigned int irq, struct irq_desc *desc) for (ec = cards; ec; ec = ec->next) { int pending; - if (!ec->claimed || ec->irq == NO_IRQ || ec->slot_no == 8) + if (!ec->claimed || !ec->irq || ec->slot_no == 8) continue; if (ec->ops && ec->ops->irqpending) @@ -598,83 +580,6 @@ ecard_irq_handler(unsigned int irq, struct irq_desc *desc) ecard_check_lockup(desc); } -#ifdef HAS_EXPMASK -static unsigned char priority_masks[] = -{ - 0xf0, 0xf1, 0xf3, 0xf7, 0xff, 0xff, 0xff, 0xff -}; - -static unsigned char first_set[] = -{ - 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00 -}; - -static void -ecard_irqexp_handler(unsigned int irq, struct irq_desc *desc) -{ - const unsigned int statusmask = 15; - unsigned int status; - - status = __raw_readb(EXPMASK_STATUS) & statusmask; - if (status) { - unsigned int slot = first_set[status]; - ecard_t *ec = slot_to_ecard(slot); - - if (ec->claimed) { - /* - * this ugly code is so that we can operate a - * prioritorising system: - * - * Card 0 highest priority - * Card 1 - * Card 2 - * Card 3 lowest priority - * - * Serial cards should go in 0/1, ethernet/scsi in 2/3 - * otherwise you will lose serial data at high speeds! - */ - generic_handle_irq(ec->irq); - } else { - printk(KERN_WARNING "card%d: interrupt from unclaimed " - "card???\n", slot); - have_expmask &= ~(1 << slot); - __raw_writeb(have_expmask, EXPMASK_ENABLE); - } - } else - printk(KERN_WARNING "Wild interrupt from backplane (masks)\n"); -} - -static int __init ecard_probeirqhw(void) -{ - ecard_t *ec; - int found; - - __raw_writeb(0x00, EXPMASK_ENABLE); - __raw_writeb(0xff, EXPMASK_STATUS); - found = (__raw_readb(EXPMASK_STATUS) & 15) == 0; - __raw_writeb(0xff, EXPMASK_ENABLE); - - if (found) { - printk(KERN_DEBUG "Expansion card interrupt " - "management hardware found\n"); - - /* for each card present, set a bit to '1' */ - have_expmask = 0x80000000; - - for (ec = cards; ec; ec = ec->next) - have_expmask |= 1 << ec->slot_no; - - __raw_writeb(have_expmask, EXPMASK_ENABLE); - } - - return found; -} -#else -#define ecard_irqexp_handler NULL -#define ecard_probeirqhw() (0) -#endif - static void __iomem *__ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed) { void __iomem *address = NULL; @@ -806,8 +711,8 @@ static struct expansion_card *__init ecard_alloc_card(int type, int slot) ec->slot_no = slot; ec->easi = type == ECARD_EASI; - ec->irq = NO_IRQ; - ec->fiq = NO_IRQ; + ec->irq = 0; + ec->fiq = 0; ec->dma = NO_DMA; ec->ops = &ecard_default_ops; @@ -978,8 +883,7 @@ EXPORT_SYMBOL(ecardm_iomap); * If bit 1 of the first byte of the card is set, then the * card does not exist. */ -static int __init -ecard_probe(int slot, card_type_t type) +static int __init ecard_probe(int slot, unsigned irq, card_type_t type) { ecard_t **ecp; ecard_t *ec; @@ -1033,18 +937,18 @@ ecard_probe(int slot, card_type_t type) break; } + ec->irq = irq; + /* * hook the interrupt handlers */ if (slot < 8) { - ec->irq = 32 + slot; irq_set_chip_and_handler(ec->irq, &ecard_chip, handle_level_irq); + irq_set_chip_data(ec->irq, ec); set_irq_flags(ec->irq, IRQF_VALID); } - if (slot == 8) - ec->irq = 11; #ifdef CONFIG_ARCH_RPC /* On RiscPC, only first two slots have DMA capability */ if (slot < 2) @@ -1074,28 +978,30 @@ ecard_probe(int slot, card_type_t type) static int __init ecard_init(void) { struct task_struct *task; - int slot, irqhw; + int slot, irqbase; + + irqbase = irq_alloc_descs(-1, 0, 8, -1); + if (irqbase < 0) + return irqbase; task = kthread_run(ecard_task, NULL, "kecardd"); if (IS_ERR(task)) { printk(KERN_ERR "Ecard: unable to create kernel thread: %ld\n", PTR_ERR(task)); + irq_free_descs(irqbase, 8); return PTR_ERR(task); } printk("Probing expansion cards\n"); for (slot = 0; slot < 8; slot ++) { - if (ecard_probe(slot, ECARD_EASI) == -ENODEV) - ecard_probe(slot, ECARD_IOC); + if (ecard_probe(slot, irqbase + slot, ECARD_EASI) == -ENODEV) + ecard_probe(slot, irqbase + slot, ECARD_IOC); } - ecard_probe(8, ECARD_IOC); - - irqhw = ecard_probeirqhw(); + ecard_probe(8, 11, ECARD_IOC); - irq_set_chained_handler(IRQ_EXPANSIONCARD, - irqhw ? ecard_irqexp_handler : ecard_irq_handler); + irq_set_chained_handler(IRQ_EXPANSIONCARD, ecard_irq_handler); ecard_proc_init(); diff --git a/arch/arm/kernel/ecard.h b/arch/arm/mach-rpc/ecard.h index 4642d436be2a..4642d436be2a 100644 --- a/arch/arm/kernel/ecard.h +++ b/arch/arm/mach-rpc/ecard.h diff --git a/arch/arm/mach-rpc/fiq.S b/arch/arm/mach-rpc/fiq.S new file mode 100644 index 000000000000..48ddd57db16e --- /dev/null +++ b/arch/arm/mach-rpc/fiq.S @@ -0,0 +1,16 @@ +#include <linux/linkage.h> +#include <asm/assembler.h> +#include <mach/hardware.h> +#include <mach/entry-macro.S> + + .text + + .global rpc_default_fiq_end +ENTRY(rpc_default_fiq_start) + mov r12, #ioc_base_high + .if ioc_base_low + orr r12, r12, #ioc_base_low + .endif + strb r12, [r12, #0x38] @ Disable FIQ register + subs pc, lr, #4 +rpc_default_fiq_end: diff --git a/arch/arm/mach-rpc/include/mach/entry-macro.S b/arch/arm/mach-rpc/include/mach/entry-macro.S index 4e7e54144093..7178368d7062 100644 --- a/arch/arm/mach-rpc/include/mach/entry-macro.S +++ b/arch/arm/mach-rpc/include/mach/entry-macro.S @@ -10,7 +10,3 @@ orr \base, \base, #ioc_base_low .endif .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm - diff --git a/arch/arm/mach-rpc/include/mach/hardware.h b/arch/arm/mach-rpc/include/mach/hardware.h index 050d63c74cc1..257166b21f3d 100644 --- a/arch/arm/mach-rpc/include/mach/hardware.h +++ b/arch/arm/mach-rpc/include/mach/hardware.h @@ -14,12 +14,6 @@ #include <mach/memory.h> -#ifndef __ASSEMBLY__ -#define IOMEM(x) ((void __iomem *)(unsigned long)(x)) -#else -#define IOMEM(x) x -#endif /* __ASSEMBLY__ */ - /* * What hardware must be present */ diff --git a/arch/arm/mach-rpc/include/mach/io.h b/arch/arm/mach-rpc/include/mach/io.h index 695f4ed2e11b..707071a7ea4e 100644 --- a/arch/arm/mach-rpc/include/mach/io.h +++ b/arch/arm/mach-rpc/include/mach/io.h @@ -28,9 +28,4 @@ */ #define __io(a) (PCIO_BASE + ((a) << 2)) -/* - * 1:1 mapping for ioremapped regions. - */ -#define __mem_pci(x) (x) - #endif diff --git a/arch/arm/mach-rpc/include/mach/irqs.h b/arch/arm/mach-rpc/include/mach/irqs.h index 3d2037496e38..6868e178274d 100644 --- a/arch/arm/mach-rpc/include/mach/irqs.h +++ b/arch/arm/mach-rpc/include/mach/irqs.h @@ -42,6 +42,4 @@ */ #define FIQ_START 64 -#define IRQ_TIMER IRQ_TIMER0 - #define NR_IRQS 128 diff --git a/arch/arm/mach-rpc/include/mach/system.h b/arch/arm/mach-rpc/include/mach/system.h deleted file mode 100644 index 359bab94b6af..000000000000 --- a/arch/arm/mach-rpc/include/mach/system.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/arm/mach-rpc/include/mach/system.h - * - * Copyright (C) 1996-1999 Russell King. - * - * 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. - */ -static inline void arch_idle(void) -{ - cpu_do_idle(); -} diff --git a/arch/arm/mach-rpc/irq.c b/arch/arm/mach-rpc/irq.c index 2e1b5309fbab..cf0e669eaf1a 100644 --- a/arch/arm/mach-rpc/irq.c +++ b/arch/arm/mach-rpc/irq.c @@ -5,6 +5,7 @@ #include <asm/mach/irq.h> #include <asm/hardware/iomd.h> #include <asm/irq.h> +#include <asm/fiq.h> static void iomd_ack_irq_a(struct irq_data *d) { @@ -112,6 +113,8 @@ static struct irq_chip iomd_fiq_chip = { .irq_unmask = iomd_unmask_irq_fiq, }; +extern unsigned char rpc_default_fiq_start, rpc_default_fiq_end; + void __init rpc_init_irq(void) { unsigned int irq, flags; @@ -121,6 +124,9 @@ void __init rpc_init_irq(void) iomd_writeb(0, IOMD_FIQMASK); iomd_writeb(0, IOMD_DMAMASK); + set_fiq_handler(&rpc_default_fiq_start, + &rpc_default_fiq_end - &rpc_default_fiq_start); + for (irq = 0; irq < NR_IRQS; irq++) { flags = IRQF_VALID; diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c index 3d44a59fc0df..f3fa259ce01f 100644 --- a/arch/arm/mach-rpc/riscpc.c +++ b/arch/arm/mach-rpc/riscpc.c @@ -28,6 +28,7 @@ #include <asm/page.h> #include <asm/domain.h> #include <asm/setup.h> +#include <asm/system_misc.h> #include <asm/mach/map.h> #include <asm/mach/arch.h> @@ -98,15 +99,9 @@ static void __init rpc_map_io(void) } static struct resource acornfb_resources[] = { - { /* VIDC */ - .start = 0x03400000, - .end = 0x035fffff, - .flags = IORESOURCE_MEM, - }, { - .start = IRQ_VSYNCPULSE, - .end = IRQ_VSYNCPULSE, - .flags = IORESOURCE_IRQ, - }, + /* VIDC */ + DEFINE_RES_MEM(0x03400000, 0x00200000), + DEFINE_RES_IRQ(IRQ_VSYNCPULSE), }; static struct platform_device acornfb_device = { @@ -120,11 +115,7 @@ static struct platform_device acornfb_device = { }; static struct resource iomd_resources[] = { - { - .start = 0x03200000, - .end = 0x0320ffff, - .flags = IORESOURCE_MEM, - }, + DEFINE_RES_MEM(0x03200000, 0x10000), }; static struct platform_device iomd_device = { @@ -134,18 +125,25 @@ static struct platform_device iomd_device = { .resource = iomd_resources, }; +static struct resource iomd_kart_resources[] = { + DEFINE_RES_IRQ(IRQ_KEYBOARDRX), + DEFINE_RES_IRQ(IRQ_KEYBOARDTX), +}; + static struct platform_device kbd_device = { .name = "kart", .id = -1, .dev = { .parent = &iomd_device.dev, }, + .num_resources = ARRAY_SIZE(iomd_kart_resources), + .resource = iomd_kart_resources, }; static struct plat_serial8250_port serial_platform_data[] = { { .mapbase = 0x03010fe0, - .irq = 10, + .irq = IRQ_SERIALPORT, .uartclk = 1843200, .regshift = 2, .iotype = UPIO_MEM, @@ -167,21 +165,9 @@ static struct pata_platform_info pata_platform_data = { }; static struct resource pata_resources[] = { - [0] = { - .start = 0x030107c0, - .end = 0x030107df, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 0x03010fd8, - .end = 0x03010fdb, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = IRQ_HARDDISK, - .end = IRQ_HARDDISK, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_MEM(0x030107c0, 0x20), + DEFINE_RES_MEM(0x03010fd8, 0x04), + DEFINE_RES_IRQ(IRQ_HARDDISK), }; static struct platform_device pata_device = { diff --git a/arch/arm/common/time-acorn.c b/arch/arm/mach-rpc/time.c index deeed561b168..581fca934bb3 100644 --- a/arch/arm/common/time-acorn.c +++ b/arch/arm/mach-rpc/time.c @@ -85,7 +85,7 @@ static struct irqaction ioc_timer_irq = { static void __init ioc_timer_init(void) { ioctime_init(); - setup_irq(IRQ_TIMER, &ioc_timer_irq); + setup_irq(IRQ_TIMER0, &ioc_timer_irq); } struct sys_timer ioc_timer = { diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index 5261a7ed0999..68d89cb96af0 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -2,42 +2,6 @@ # # Licensed under GPLv2 -config CPU_S3C2410 - bool - depends on ARCH_S3C2410 - select CPU_ARM920T - select S3C2410_CLOCK - select CPU_LLSERIAL_S3C2410 - select S3C2410_PM if PM - select S3C2410_CPUFREQ if CPU_FREQ_S3C24XX - help - Support for S3C2410 and S3C2410A family from the S3C24XX line - of Samsung Mobile CPUs. - -config CPU_S3C2410_DMA - bool - depends on S3C2410_DMA && (CPU_S3C2410 || CPU_S3C2442) - default y if CPU_S3C2410 || CPU_S3C2442 - help - DMA device selection for S3C2410 and compatible CPUs - -config S3C2410_PM - bool - help - Power Management code common to S3C2410 and better - -config SIMTEC_NOR - bool - help - Internal node to specify machine has simtec NOR mapping - -config MACH_BAST_IDE - bool - select HAVE_PATA_PLATFORM - help - Internal node for machines with an BAST style IDE - interface - # cpu frequency scaling support config S3C2410_CPUFREQ @@ -54,121 +18,3 @@ config S3C2410_PLLTABLE help Select the PLL table for the S3C2410 -menu "S3C2410 Machines" - -config ARCH_SMDK2410 - bool "SMDK2410/A9M2410" - select CPU_S3C2410 - select MACH_SMDK - help - Say Y here if you are using the SMDK2410 or the derived module A9M2410 - <http://www.fsforth.de> - -config ARCH_H1940 - bool "IPAQ H1940" - select CPU_S3C2410 - select PM_H1940 if PM - select S3C_DEV_USB_HOST - select S3C_DEV_NAND - select S3C2410_SETUP_TS - help - Say Y here if you are using the HP IPAQ H1940 - -config H1940BT - tristate "Control the state of H1940 bluetooth chip" - depends on ARCH_H1940 - select RFKILL - help - This is a simple driver that is able to control - the state of built in bluetooth chip on h1940. - -config PM_H1940 - bool - help - Internal node for H1940 and related PM - -config MACH_N30 - bool "Acer N30 family" - select CPU_S3C2410 - select MACH_N35 - select S3C_DEV_USB_HOST - select S3C_DEV_NAND - help - Say Y here if you want suppt for the Acer N30, Acer N35, - Navman PiN570, Yakumo AlphaX or Airis NC05 PDAs. - -config MACH_N35 - bool - help - Internal node in order to enable support for Acer N35 if Acer N30 is - selected. - -config ARCH_BAST - bool "Simtec Electronics BAST (EB2410ITX)" - select CPU_S3C2410 - select S3C2410_IOTIMING if S3C2410_CPUFREQ - select PM_SIMTEC if PM - select SIMTEC_NOR - select MACH_BAST_IDE - select S3C24XX_DCLK - select ISA - select S3C_DEV_HWMON - select S3C_DEV_USB_HOST - select S3C_DEV_NAND - help - Say Y here if you are using the Simtec Electronics EB2410ITX - development board (also known as BAST) - -config MACH_OTOM - bool "NexVision OTOM Board" - select CPU_S3C2410 - select S3C_DEV_USB_HOST - select S3C_DEV_NAND - help - Say Y here if you are using the Nex Vision OTOM board - -config MACH_AML_M5900 - bool "AML M5900 Series" - select CPU_S3C2410 - select PM_SIMTEC if PM - select S3C_DEV_USB_HOST - help - Say Y here if you are using the American Microsystems M5900 Series - <http://www.amltd.com> - -config BAST_PC104_IRQ - bool "BAST PC104 IRQ support" - depends on ARCH_BAST - default y - help - Say Y here to enable the PC104 IRQ routing on the - Simtec BAST (EB2410ITX) - -config MACH_TCT_HAMMER - bool "TCT Hammer Board" - select CPU_S3C2410 - select S3C_DEV_USB_HOST - help - Say Y here if you are using the TinCanTools Hammer Board - <http://www.tincantools.com> - -config MACH_VR1000 - bool "Thorcom VR1000" - select PM_SIMTEC if PM - select S3C24XX_DCLK - select SIMTEC_NOR - select MACH_BAST_IDE - select CPU_S3C2410 - select S3C_DEV_USB_HOST - help - Say Y here if you are using the Thorcom VR1000 board. - -config MACH_QT2410 - bool "QT2410" - select CPU_S3C2410 - select S3C_DEV_USB_HOST - select S3C_DEV_NAND - help - Say Y here if you are using the Armzone QT2410 - -endmenu diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile index 782fd81144e9..6b9a316e0041 100644 --- a/arch/arm/mach-s3c2410/Makefile +++ b/arch/arm/mach-s3c2410/Makefile @@ -9,32 +9,6 @@ obj-m := obj-n := obj- := -obj-$(CONFIG_CPU_S3C2410) += s3c2410.o -obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o -obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o -obj-$(CONFIG_S3C2410_PM) += pm.o sleep.o obj-$(CONFIG_S3C2410_CPUFREQ) += cpu-freq.o obj-$(CONFIG_S3C2410_PLLTABLE) += pll.o -# Machine support - -obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o -obj-$(CONFIG_ARCH_H1940) += mach-h1940.o -obj-$(CONFIG_H1940BT) += h1940-bluetooth.o -obj-$(CONFIG_PM_H1940) += pm-h1940.o -obj-$(CONFIG_MACH_N30) += mach-n30.o -obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o -obj-$(CONFIG_MACH_OTOM) += mach-otom.o -obj-$(CONFIG_MACH_AML_M5900) += mach-amlm5900.o -obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.o -obj-$(CONFIG_MACH_TCT_HAMMER) += mach-tct_hammer.o -obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o -obj-$(CONFIG_MACH_QT2410) += mach-qt2410.o - -# Common bits of machine support - -obj-$(CONFIG_SIMTEC_NOR) += nor-simtec.o - -# machine additions - -obj-$(CONFIG_MACH_BAST_IDE) += bast-ide.o diff --git a/arch/arm/mach-s3c2410/include/mach/spi.h b/arch/arm/mach-s3c2410/include/mach/spi.h deleted file mode 100644 index 4d9588373aa5..000000000000 --- a/arch/arm/mach-s3c2410/include/mach/spi.h +++ /dev/null @@ -1,38 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/spi.h - * - * Copyright (c) 2006 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * - * S3C2410 - SPI Controller platform_device info - * - * 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. -*/ - -#ifndef __ASM_ARCH_SPI_H -#define __ASM_ARCH_SPI_H __FILE__ - -struct s3c2410_spi_info { - int pin_cs; /* simple gpio cs */ - unsigned int num_cs; /* total chipselects */ - int bus_num; /* bus number to use. */ - - unsigned int use_fiq:1; /* use fiq */ - - void (*gpio_setup)(struct s3c2410_spi_info *spi, int enable); - void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol); -}; - -/* Standard setup / suspend routines for SPI GPIO pins. */ - -extern void s3c24xx_spi_gpiocfg_bus0_gpe11_12_13(struct s3c2410_spi_info *spi, - int enable); - -extern void s3c24xx_spi_gpiocfg_bus1_gpg5_6_7(struct s3c2410_spi_info *spi, - int enable); - -extern void s3c24xx_spi_gpiocfg_bus1_gpd8_9_10(struct s3c2410_spi_info *spi, - int enable); - -#endif /* __ASM_ARCH_SPI_H */ diff --git a/arch/arm/mach-s3c2410/include/mach/system.h b/arch/arm/mach-s3c2410/include/mach/system.h deleted file mode 100644 index 5e215c1a5c8f..000000000000 --- a/arch/arm/mach-s3c2410/include/mach/system.h +++ /dev/null @@ -1,54 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/system.h - * - * Copyright (c) 2003 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * - * S3C2410 - System function defines and includes - * - * 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 <linux/io.h> -#include <mach/hardware.h> - -#include <mach/map.h> -#include <mach/idle.h> - -#include <mach/regs-clock.h> - -void (*s3c24xx_idle)(void); - -void s3c24xx_default_idle(void) -{ - unsigned long tmp; - int i; - - /* idle the system by using the idle mode which will wait for an - * interrupt to happen before restarting the system. - */ - - /* Warning: going into idle state upsets jtag scanning */ - - __raw_writel(__raw_readl(S3C2410_CLKCON) | S3C2410_CLKCON_IDLE, - S3C2410_CLKCON); - - /* the samsung port seems to do a loop and then unset idle.. */ - for (i = 0; i < 50; i++) { - tmp += __raw_readl(S3C2410_CLKCON); /* ensure loop not optimised out */ - } - - /* this bit is not cleared on re-start... */ - - __raw_writel(__raw_readl(S3C2410_CLKCON) & ~S3C2410_CLKCON_IDLE, - S3C2410_CLKCON); -} - -static void arch_idle(void) -{ - if (s3c24xx_idle != NULL) - (s3c24xx_idle)(); - else - s3c24xx_default_idle(); -} diff --git a/arch/arm/mach-s3c2410/usb-simtec.h b/arch/arm/mach-s3c2410/usb-simtec.h deleted file mode 100644 index 03842ede9e71..000000000000 --- a/arch/arm/mach-s3c2410/usb-simtec.h +++ /dev/null @@ -1,16 +0,0 @@ -/* linux/arch/arm/mach-s3c2410/usb-simtec.h - * - * Copyright (c) 2004 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * - * http://www.simtec.co.uk/products/EB2410ITX/ - * - * Simtec BAST and Thorcom VR1000 USB port support functions - * - * 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. -*/ - -extern int usb_simtec_init(void); - diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig index b8b9029e9f2d..c5256f4e90bb 100644 --- a/arch/arm/mach-s3c2412/Kconfig +++ b/arch/arm/mach-s3c2412/Kconfig @@ -2,41 +2,6 @@ # # Licensed under GPLv2 -config CPU_S3C2412 - bool - depends on ARCH_S3C2410 - select CPU_ARM926T - select CPU_LLSERIAL_S3C2440 - select S3C2412_PM if PM - select S3C2412_DMA if S3C2410_DMA - help - Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line - -config CPU_S3C2412_ONLY - bool - depends on ARCH_S3C2410 && !CPU_S3C2410 && \ - !CPU_S3C2416 && !CPU_S3C2440 && !CPU_S3C2442 && \ - !CPU_S3C2443 && CPU_S3C2412 - default y if CPU_S3C2412 - -config S3C2412_DMA - bool - depends on CPU_S3C2412 - help - Internal config node for S3C2412 DMA support - -config S3C2412_PM - bool - select S3C2412_PM_SLEEP - help - Internal config node to apply S3C2412 power management - -config S3C2412_PM_SLEEP - bool - help - Internal config node to apply sleep for S3C2412 power management. - Can be selected by another SoCs with similar sleep procedure. - # Note, the S3C2412 IOtiming support is in plat-s3c24xx config S3C2412_CPUFREQ @@ -46,53 +11,3 @@ config S3C2412_CPUFREQ default y help CPU Frequency scaling support for S3C2412 and S3C2413 SoC CPUs. - -menu "S3C2412 Machines" - -config MACH_JIVE - bool "Logitech Jive" - select CPU_S3C2412 - select S3C_DEV_USB_HOST - select S3C_DEV_NAND - help - Say Y here if you are using the Logitech Jive. - -config MACH_JIVE_SHOW_BOOTLOADER - bool "Allow access to bootloader partitions in MTD (EXPERIMENTAL)" - depends on MACH_JIVE && EXPERIMENTAL - -config MACH_SMDK2413 - bool "SMDK2413" - select CPU_S3C2412 - select MACH_S3C2413 - select MACH_SMDK - select S3C_DEV_USB_HOST - select S3C_DEV_NAND - help - Say Y here if you are using an SMDK2413 - -config MACH_S3C2413 - bool - help - Internal node for S3C2413 version of SMDK2413, so that - machine_is_s3c2413() will work when MACH_SMDK2413 is - selected - -config MACH_SMDK2412 - bool "SMDK2412" - select MACH_SMDK2413 - help - Say Y here if you are using an SMDK2412 - - Note, this shares support with SMDK2413, so will automatically - select MACH_SMDK2413. - -config MACH_VSTMS - bool "VMSTMS" - select CPU_S3C2412 - select S3C_DEV_USB_HOST - select S3C_DEV_NAND - help - Say Y here if you are using an VSTMS board - -endmenu diff --git a/arch/arm/mach-s3c2412/Makefile b/arch/arm/mach-s3c2412/Makefile index 7e4d95fa8a97..41a6c279fb2f 100644 --- a/arch/arm/mach-s3c2412/Makefile +++ b/arch/arm/mach-s3c2412/Makefile @@ -9,16 +9,4 @@ obj-m := obj-n := obj- := -obj-$(CONFIG_CPU_S3C2412) += s3c2412.o -obj-$(CONFIG_CPU_S3C2412) += irq.o -obj-$(CONFIG_CPU_S3C2412) += clock.o -obj-$(CONFIG_S3C2412_DMA) += dma.o -obj-$(CONFIG_S3C2412_PM) += pm.o -obj-$(CONFIG_S3C2412_PM_SLEEP) += sleep.o obj-$(CONFIG_S3C2412_CPUFREQ) += cpu-freq.o - -# Machine support - -obj-$(CONFIG_MACH_JIVE) += mach-jive.o -obj-$(CONFIG_MACH_SMDK2413) += mach-smdk2413.o -obj-$(CONFIG_MACH_VSTMS) += mach-vstms.o diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig deleted file mode 100644 index 84c7b03e5a30..000000000000 --- a/arch/arm/mach-s3c2416/Kconfig +++ /dev/null @@ -1,60 +0,0 @@ -# arch/arm/mach-s3c2416/Kconfig -# -# Copyright 2009 Yauhen Kharuzhy <jekhor@gmail.com> -# -# Licensed under GPLv2 - -# note, this also supports the S3C2450 which is so similar it has the same -# ID code as the S3C2416. - -config CPU_S3C2416 - bool - depends on ARCH_S3C2410 - select CPU_ARM926T - select S3C2416_DMA if S3C2410_DMA - select CPU_LLSERIAL_S3C2440 - select SAMSUNG_CLKSRC - select S3C2443_CLOCK - help - Support for the S3C2416 SoC from the S3C24XX line - -config S3C2416_DMA - bool - depends on CPU_S3C2416 - help - Internal config node for S3C2416 DMA support - -config S3C2416_PM - bool - select S3C2412_PM_SLEEP - help - Internal config node to apply S3C2416 power management - -config S3C2416_SETUP_SDHCI - bool - select S3C2416_SETUP_SDHCI_GPIO - help - Internal helper functions for S3C2416 based SDHCI systems - -config S3C2416_SETUP_SDHCI_GPIO - bool - help - Common setup code for SDHCI gpio. - -menu "S3C2416 Machines" - -config MACH_SMDK2416 - bool "SMDK2416" - select CPU_S3C2416 - select MACH_SMDK - select S3C_DEV_FB - select S3C_DEV_HSMMC - select S3C_DEV_HSMMC1 - select S3C_DEV_NAND - select S3C_DEV_USB_HOST - select S3C2416_SETUP_SDHCI - select S3C2416_PM if PM - help - Say Y here if you are using an SMDK2416 - -endmenu diff --git a/arch/arm/mach-s3c2416/Makefile b/arch/arm/mach-s3c2416/Makefile deleted file mode 100644 index ca0cd227f873..000000000000 --- a/arch/arm/mach-s3c2416/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# arch/arm/mach-s3c2416/Makefile -# -# Copyright 2009 Yauhen Kharuzhy <jekhor@gmail.com> -# -# Licensed under GPLv2 - -obj-y := -obj-m := -obj-n := -obj- := - -obj-$(CONFIG_CPU_S3C2416) += s3c2416.o clock.o -obj-$(CONFIG_CPU_S3C2416) += irq.o -obj-$(CONFIG_S3C2416_PM) += pm.o -#obj-$(CONFIG_S3C2416_DMA) += dma.o - -# Device setup -obj-$(CONFIG_S3C2416_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o - -# Machine support - -obj-$(CONFIG_MACH_SMDK2416) += mach-smdk2416.o diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig index 914e620f1257..ece7a10fe3c6 100644 --- a/arch/arm/mach-s3c2440/Kconfig +++ b/arch/arm/mach-s3c2440/Kconfig @@ -2,35 +2,6 @@ # # Licensed under GPLv2 -config CPU_S3C2440 - bool - select CPU_ARM920T - select S3C2410_CLOCK - select S3C2410_PM if PM - select S3C2440_DMA if S3C2410_DMA - select CPU_S3C244X - select CPU_LLSERIAL_S3C2440 - help - Support for S3C2440 Samsung Mobile CPU based systems. - -config CPU_S3C2442 - bool - select CPU_ARM920T - select S3C2410_CLOCK - select S3C2410_PM if PM - select CPU_S3C244X - select CPU_LLSERIAL_S3C2440 - help - Support for S3C2442 Samsung Mobile CPU based systems. - -config CPU_S3C244X - bool - depends on CPU_S3C2440 || CPU_S3C2442 - help - Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems. - - - config S3C2440_CPUFREQ bool "S3C2440/S3C2442 CPU Frequency scaling support" depends on CPU_FREQ_S3C24XX && (CPU_S3C2440 || CPU_S3C2442) @@ -64,139 +35,3 @@ config S3C2440_PLL_16934400 default y if CPU_FREQ_S3C24XX_PLL help PLL tables for S3C2440 or S3C2442 CPUs with 16.934MHz crystals. - -config S3C2440_DMA - bool - depends on CPU_S3C2440 - help - Support for S3C2440 specific DMA code5A - -menu "S3C2440 and S3C2442 Machines" - -config MACH_ANUBIS - bool "Simtec Electronics ANUBIS" - select CPU_S3C2440 - select S3C24XX_DCLK - select PM_SIMTEC if PM - select HAVE_PATA_PLATFORM - select S3C24XX_GPIO_EXTRA64 - select S3C2440_XTAL_12000000 - select S3C_DEV_USB_HOST - help - Say Y here if you are using the Simtec Electronics ANUBIS - development system - -config MACH_NEO1973_GTA02 - bool "Openmoko GTA02 / Freerunner phone" - select CPU_S3C2442 - select MFD_PCF50633 - select PCF50633_GPIO - select I2C - select POWER_SUPPLY - select MACH_NEO1973 - select S3C2410_PWM - select S3C_DEV_USB_HOST - help - Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone - -config MACH_OSIRIS - bool "Simtec IM2440D20 (OSIRIS) module" - select CPU_S3C2440 - select S3C24XX_DCLK - select PM_SIMTEC if PM - select S3C24XX_GPIO_EXTRA128 - select S3C2440_XTAL_12000000 - select S3C2410_IOTIMING if S3C2440_CPUFREQ - select S3C_DEV_USB_HOST - select S3C_DEV_NAND - help - Say Y here if you are using the Simtec IM2440D20 module, also - known as the Osiris. - -config MACH_OSIRIS_DVS - tristate "Simtec IM2440D20 (OSIRIS) Dynamic Voltage Scaling driver" - depends on MACH_OSIRIS - select TPS65010 - help - Say Y/M here if you want to have dynamic voltage scaling support - on the Simtec IM2440D20 (OSIRIS) module via the TPS65011. - - The DVS driver alters the voltage supplied to the ARM core - depending on the frequency it is running at. The driver itself - does not do any of the frequency alteration, which is left up - to the cpufreq driver. - -config MACH_RX3715 - bool "HP iPAQ rx3715" - select CPU_S3C2440 - select S3C2440_XTAL_16934400 - select PM_H1940 if PM - select S3C_DEV_NAND - help - Say Y here if you are using the HP iPAQ rx3715. - -config ARCH_S3C2440 - bool "SMDK2440" - select CPU_S3C2440 - select S3C2440_XTAL_16934400 - select MACH_SMDK - select S3C_DEV_USB_HOST - select S3C_DEV_NAND - help - Say Y here if you are using the SMDK2440. - -config MACH_NEXCODER_2440 - bool "NexVision NEXCODER 2440 Light Board" - select CPU_S3C2440 - select S3C2440_XTAL_12000000 - select S3C_DEV_USB_HOST - select S3C_DEV_NAND - help - Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board - -config SMDK2440_CPU2440 - bool "SMDK2440 with S3C2440 CPU module" - default y if ARCH_S3C2440 - select S3C2440_XTAL_16934400 - select CPU_S3C2440 - -config SMDK2440_CPU2442 - bool "SMDM2440 with S3C2442 CPU module" - select CPU_S3C2442 - -config MACH_AT2440EVB - bool "Avantech AT2440EVB development board" - select CPU_S3C2440 - select S3C_DEV_USB_HOST - select S3C_DEV_NAND - help - Say Y here if you are using the AT2440EVB development board - -config MACH_MINI2440 - bool "MINI2440 development board" - select CPU_S3C2440 - select EEPROM_AT24 - select NEW_LEDS - select LEDS_CLASS - select LEDS_TRIGGER - select LEDS_TRIGGER_BACKLIGHT - select S3C_DEV_NAND - select S3C_DEV_USB_HOST - help - Say Y here to select support for the MINI2440. Is a 10cm x 10cm board - available via various sources. It can come with a 3.5" or 7" touch LCD. - -config MACH_RX1950 - bool "HP iPAQ rx1950" - select CPU_S3C2442 - select S3C24XX_DCLK - select PM_H1940 if PM - select I2C - select S3C2410_PWM - select S3C_DEV_NAND - select S3C2410_IOTIMING if S3C2440_CPUFREQ - select S3C2440_XTAL_16934400 - help - Say Y here if you're using HP iPAQ rx1950 - -endmenu diff --git a/arch/arm/mach-s3c2440/Makefile b/arch/arm/mach-s3c2440/Makefile index d5440fa34b04..c46092439814 100644 --- a/arch/arm/mach-s3c2440/Makefile +++ b/arch/arm/mach-s3c2440/Makefile @@ -9,33 +9,9 @@ obj-m := obj-n := obj- := -obj-$(CONFIG_CPU_S3C2440) += s3c2440.o dsc.o -obj-$(CONFIG_CPU_S3C2442) += s3c2442.o +obj-$(CONFIG_CPU_S3C2440) += dsc.o -obj-$(CONFIG_CPU_S3C2440) += irq.o -obj-$(CONFIG_CPU_S3C2440) += clock.o -obj-$(CONFIG_S3C2440_DMA) += dma.o - -obj-$(CONFIG_CPU_S3C244X) += s3c244x.o -obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o -obj-$(CONFIG_CPU_S3C244X) += s3c244x-clock.o obj-$(CONFIG_S3C2440_CPUFREQ) += s3c2440-cpufreq.o obj-$(CONFIG_S3C2440_PLL_12000000) += s3c2440-pll-12000000.o obj-$(CONFIG_S3C2440_PLL_16934400) += s3c2440-pll-16934400.o - -# Machine support - -obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o -obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o -obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o -obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o -obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o -obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o -obj-$(CONFIG_MACH_MINI2440) += mach-mini2440.o -obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o -obj-$(CONFIG_MACH_RX1950) += mach-rx1950.o - -# extra machine support - -obj-$(CONFIG_MACH_OSIRIS_DVS) += mach-osiris-dvs.o diff --git a/arch/arm/mach-s3c2440/common.h b/arch/arm/mach-s3c2440/common.h deleted file mode 100644 index 0c1eb1dfc534..000000000000 --- a/arch/arm/mach-s3c2440/common.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Common Header for S3C2440 machines - * - * 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. - */ - -#ifndef __ARCH_ARM_MACH_S3C2440_COMMON_H -#define __ARCH_ARM_MACH_S3C2440_COMMON_H - -void s3c244x_restart(char mode, const char *cmd); - -#endif /* __ARCH_ARM_MACH_S3C2440_COMMON_H */ diff --git a/arch/arm/mach-s3c2443/Kconfig b/arch/arm/mach-s3c2443/Kconfig deleted file mode 100644 index 8814031516ce..000000000000 --- a/arch/arm/mach-s3c2443/Kconfig +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2007 Simtec Electronics -# -# Licensed under GPLv2 - -config CPU_S3C2443 - bool - depends on ARCH_S3C2410 - select CPU_ARM920T - select S3C2443_DMA if S3C2410_DMA - select CPU_LLSERIAL_S3C2440 - select SAMSUNG_CLKSRC - select S3C2443_CLOCK - help - Support for the S3C2443 SoC from the S3C24XX line - -config S3C2443_DMA - bool - depends on CPU_S3C2443 - help - Internal config node for S3C2443 DMA support - -menu "S3C2443 Machines" - -config MACH_SMDK2443 - bool "SMDK2443" - select CPU_S3C2443 - select MACH_SMDK - select S3C_DEV_HSMMC1 - help - Say Y here if you are using an SMDK2443 - -endmenu diff --git a/arch/arm/mach-s3c2443/Makefile b/arch/arm/mach-s3c2443/Makefile deleted file mode 100644 index d1843c9eb8bd..000000000000 --- a/arch/arm/mach-s3c2443/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# arch/arm/mach-s3c2443/Makefile -# -# Copyright 2007 Simtec Electronics -# -# Licensed under GPLv2 - -obj-y := -obj-m := -obj-n := -obj- := - -obj-$(CONFIG_CPU_S3C2443) += s3c2443.o -obj-$(CONFIG_CPU_S3C2443) += irq.o -obj-$(CONFIG_CPU_S3C2443) += clock.o - -obj-$(CONFIG_S3C2443_DMA) += dma.o - -# Machine support - -obj-$(CONFIG_MACH_SMDK2443) += mach-smdk2443.o diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig new file mode 100644 index 000000000000..0f3a327ebcaa --- /dev/null +++ b/arch/arm/mach-s3c24xx/Kconfig @@ -0,0 +1,538 @@ +# arch/arm/mach-s3c24xx/Kconfig +# +# Copyright (c) 2012 Samsung Electronics Co., Ltd. +# http://www.samsung.com/ +# +# Copyright 2007 Simtec Electronics +# +# Licensed under GPLv2 + +if ARCH_S3C24XX + +menu "SAMSUNG S3C24XX SoCs Support" + +comment "S3C24XX SoCs" + +config CPU_S3C2410 + bool "SAMSUNG S3C2410" + default y + select CPU_ARM920T + select S3C2410_CLOCK + select CPU_LLSERIAL_S3C2410 + select S3C2410_PM if PM + select S3C2410_CPUFREQ if CPU_FREQ_S3C24XX + help + Support for S3C2410 and S3C2410A family from the S3C24XX line + of Samsung Mobile CPUs. + +config CPU_S3C2412 + bool "SAMSUNG S3C2412" + depends on ARCH_S3C24XX + select CPU_ARM926T + select CPU_LLSERIAL_S3C2440 + select S3C2412_PM if PM + select S3C2412_DMA if S3C24XX_DMA + help + Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line + +config CPU_S3C2416 + bool "SAMSUNG S3C2416/S3C2450" + depends on ARCH_S3C24XX + select CPU_ARM926T + select CPU_LLSERIAL_S3C2440 + select SAMSUNG_CLKSRC + select S3C2443_COMMON + select S3C2443_DMA if S3C24XX_DMA + select S3C2416_PM if PM + help + Support for the S3C2416 SoC from the S3C24XX line + +config CPU_S3C2440 + bool "SAMSUNG S3C2440" + select CPU_ARM920T + select CPU_LLSERIAL_S3C2440 + select S3C2410_CLOCK + select S3C2410_PM if PM + select S3C2440_DMA if S3C24XX_DMA + help + Support for S3C2440 Samsung Mobile CPU based systems. + +config CPU_S3C2442 + bool "SAMSUNG S3C2442" + select CPU_ARM920T + select CPU_LLSERIAL_S3C2440 + select S3C2410_CLOCK + select S3C2410_PM if PM + help + Support for S3C2442 Samsung Mobile CPU based systems. + +config CPU_S3C244X + def_bool y + depends on CPU_S3C2440 || CPU_S3C2442 + +config CPU_S3C2443 + bool "SAMSUNG S3C2443" + depends on ARCH_S3C24XX + select CPU_ARM920T + select CPU_LLSERIAL_S3C2440 + select SAMSUNG_CLKSRC + select S3C2443_COMMON + select S3C2443_DMA if S3C24XX_DMA + help + Support for the S3C2443 SoC from the S3C24XX line + +# common code + +config S3C24XX_SMDK + bool + help + Common machine code for SMDK2410 and SMDK2440 + +config S3C24XX_SIMTEC_AUDIO + bool + depends on (ARCH_BAST || MACH_VR1000 || MACH_OSIRIS || MACH_ANUBIS) + default y + help + Add audio devices for common Simtec S3C24XX boards + +config S3C24XX_SIMTEC_PM + bool + help + Common power management code for systems that are + compatible with the Simtec style of power management + +config S3C24XX_SIMTEC_USB + bool + help + USB management code for common Simtec S3C24XX boards + +config S3C24XX_SETUP_TS + bool + help + Compile in platform device definition for Samsung TouchScreen. + +# cpu-specific sections + +if CPU_S3C2410 + +config S3C2410_DMA + bool + depends on S3C24XX_DMA && (CPU_S3C2410 || CPU_S3C2442) + default y if CPU_S3C2410 || CPU_S3C2442 + help + DMA device selection for S3C2410 and compatible CPUs + +config S3C2410_PM + bool + help + Power Management code common to S3C2410 and better + +config S3C24XX_SIMTEC_NOR + bool + help + Internal node to specify machine has simtec NOR mapping + +config MACH_BAST_IDE + bool + select HAVE_PATA_PLATFORM + help + Internal node for machines with an BAST style IDE + interface + +comment "S3C2410 Boards" + +# +# The "S3C2410 Boards" list is ordered alphabetically by option text. +# (without ARCH_ or MACH_) +# + +config MACH_AML_M5900 + bool "AML M5900 Series" + select S3C24XX_SIMTEC_PM if PM + select S3C_DEV_USB_HOST + help + Say Y here if you are using the American Microsystems M5900 Series + <http://www.amltd.com> + +config ARCH_BAST + bool "Simtec Electronics BAST (EB2410ITX)" + select S3C2410_IOTIMING if S3C2410_CPUFREQ + select S3C24XX_SIMTEC_PM if PM + select S3C24XX_SIMTEC_NOR + select S3C24XX_SIMTEC_USB + select MACH_BAST_IDE + select S3C24XX_DCLK + select ISA + select S3C_DEV_HWMON + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + help + Say Y here if you are using the Simtec Electronics EB2410ITX + development board (also known as BAST) + +config BAST_PC104_IRQ + bool "BAST PC104 IRQ support" + depends on ARCH_BAST + default y + help + Say Y here to enable the PC104 IRQ routing on the + Simtec BAST (EB2410ITX) + +config ARCH_H1940 + bool "IPAQ H1940" + select PM_H1940 if PM + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + select S3C24XX_SETUP_TS + help + Say Y here if you are using the HP IPAQ H1940 + +config H1940BT + tristate "Control the state of H1940 bluetooth chip" + depends on ARCH_H1940 + select RFKILL + help + This is a simple driver that is able to control + the state of built in bluetooth chip on h1940. + +config PM_H1940 + bool + help + Internal node for H1940 and related PM + +config MACH_N30 + bool "Acer N30 family" + select MACH_N35 + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + help + Say Y here if you want suppt for the Acer N30, Acer N35, + Navman PiN570, Yakumo AlphaX or Airis NC05 PDAs. + +config MACH_OTOM + bool "NexVision OTOM Board" + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + help + Say Y here if you are using the Nex Vision OTOM board + +config MACH_QT2410 + bool "QT2410" + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + help + Say Y here if you are using the Armzone QT2410 + +config ARCH_SMDK2410 + bool "SMDK2410/A9M2410" + select S3C24XX_SMDK + help + Say Y here if you are using the SMDK2410 or the derived module A9M2410 + <http://www.fsforth.de> + +config MACH_TCT_HAMMER + bool "TCT Hammer Board" + select S3C_DEV_USB_HOST + help + Say Y here if you are using the TinCanTools Hammer Board + <http://www.tincantools.com> + +config MACH_VR1000 + bool "Thorcom VR1000" + select S3C24XX_SIMTEC_PM if PM + select S3C24XX_DCLK + select S3C24XX_SIMTEC_NOR + select MACH_BAST_IDE + select S3C_DEV_USB_HOST + select S3C24XX_SIMTEC_USB + help + Say Y here if you are using the Thorcom VR1000 board. + +endif # CPU_S3C2410 + +config S3C2412_PM_SLEEP + bool + help + Internal config node to apply sleep for S3C2412 power management. + Can be selected by another SoCs such as S3C2416 with similar + sleep procedure. + +if CPU_S3C2412 + +config CPU_S3C2412_ONLY + bool + depends on ARCH_S3C24XX && !CPU_S3C2410 && \ + !CPU_S3C2416 && !CPU_S3C2440 && !CPU_S3C2442 && \ + !CPU_S3C2443 && CPU_S3C2412 + default y + +config S3C2412_DMA + bool + help + Internal config node for S3C2412 DMA support + +config S3C2412_PM + bool + help + Internal config node to apply S3C2412 power management + +comment "S3C2412 Boards" + +# +# The "S3C2412 Boards" list is ordered alphabetically by option text. +# (without ARCH_ or MACH_) +# + +config MACH_JIVE + bool "Logitech Jive" + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + help + Say Y here if you are using the Logitech Jive. + +config MACH_JIVE_SHOW_BOOTLOADER + bool "Allow access to bootloader partitions in MTD (EXPERIMENTAL)" + depends on MACH_JIVE && EXPERIMENTAL + +config MACH_S3C2413 + bool + help + Internal node for S3C2413 version of SMDK2413, so that + machine_is_s3c2413() will work when MACH_SMDK2413 is + selected + +config MACH_SMDK2412 + bool "SMDK2412" + select MACH_SMDK2413 + help + Say Y here if you are using an SMDK2412 + + Note, this shares support with SMDK2413, so will automatically + select MACH_SMDK2413. + +config MACH_SMDK2413 + bool "SMDK2413" + select MACH_S3C2413 + select S3C24XX_SMDK + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + help + Say Y here if you are using an SMDK2413 + +config MACH_VSTMS + bool "VMSTMS" + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + help + Say Y here if you are using an VSTMS board + +endif # CPU_S3C2412 + +if CPU_S3C2416 + +config S3C2416_PM + bool + select S3C2412_PM_SLEEP + help + Internal config node to apply S3C2416 power management + +config S3C2416_SETUP_SDHCI + bool + select S3C2416_SETUP_SDHCI_GPIO + help + Internal helper functions for S3C2416 based SDHCI systems + +config S3C2416_SETUP_SDHCI_GPIO + bool + help + Common setup code for SDHCI gpio. + +comment "S3C2416 Boards" + +config MACH_SMDK2416 + bool "SMDK2416" + select S3C24XX_SMDK + select S3C_DEV_FB + select S3C_DEV_HSMMC + select S3C_DEV_HSMMC1 + select S3C_DEV_NAND + select S3C_DEV_USB_HOST + select S3C2416_SETUP_SDHCI + help + Say Y here if you are using an SMDK2416 + +endif # CPU_S3C2416 + +if CPU_S3C2440 + +config S3C2440_DMA + bool + help + Support for S3C2440 specific DMA code5A + +comment "S3C2440 Boards" + +# +# The "S3C2440 Boards" list is ordered alphabetically by option text. +# (without ARCH_ or MACH_) +# + +config MACH_ANUBIS + bool "Simtec Electronics ANUBIS" + select S3C24XX_DCLK + select S3C24XX_SIMTEC_PM if PM + select HAVE_PATA_PLATFORM + select S3C24XX_GPIO_EXTRA64 + select S3C2440_XTAL_12000000 + select S3C_DEV_USB_HOST + help + Say Y here if you are using the Simtec Electronics ANUBIS + development system + +config MACH_AT2440EVB + bool "Avantech AT2440EVB development board" + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + help + Say Y here if you are using the AT2440EVB development board + +config MACH_MINI2440 + bool "MINI2440 development board" + select EEPROM_AT24 + select NEW_LEDS + select LEDS_CLASS + select LEDS_TRIGGER + select LEDS_TRIGGER_BACKLIGHT + select S3C_DEV_NAND + select S3C_DEV_USB_HOST + help + Say Y here to select support for the MINI2440. Is a 10cm x 10cm board + available via various sources. It can come with a 3.5" or 7" touch LCD. + +config MACH_NEXCODER_2440 + bool "NexVision NEXCODER 2440 Light Board" + select S3C2440_XTAL_12000000 + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + help + Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board + +config MACH_OSIRIS + bool "Simtec IM2440D20 (OSIRIS) module" + select S3C24XX_DCLK + select S3C24XX_SIMTEC_PM if PM + select S3C24XX_GPIO_EXTRA128 + select S3C2440_XTAL_12000000 + select S3C2410_IOTIMING if S3C2440_CPUFREQ + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + help + Say Y here if you are using the Simtec IM2440D20 module, also + known as the Osiris. + +config MACH_OSIRIS_DVS + tristate "Simtec IM2440D20 (OSIRIS) Dynamic Voltage Scaling driver" + depends on MACH_OSIRIS + select TPS65010 + help + Say Y/M here if you want to have dynamic voltage scaling support + on the Simtec IM2440D20 (OSIRIS) module via the TPS65011. + + The DVS driver alters the voltage supplied to the ARM core + depending on the frequency it is running at. The driver itself + does not do any of the frequency alteration, which is left up + to the cpufreq driver. + +config MACH_RX3715 + bool "HP iPAQ rx3715" + select S3C2440_XTAL_16934400 + select PM_H1940 if PM + select S3C_DEV_NAND + help + Say Y here if you are using the HP iPAQ rx3715. + +config ARCH_S3C2440 + bool "SMDK2440" + select S3C2440_XTAL_16934400 + select S3C24XX_SMDK + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + help + Say Y here if you are using the SMDK2440. + +config SMDK2440_CPU2440 + bool "SMDK2440 with S3C2440 CPU module" + default y if ARCH_S3C2440 + select S3C2440_XTAL_16934400 + +endif # CPU_S3C2440 + +if CPU_S3C2442 + +comment "S3C2442 Boards" + +# +# The "S3C2442 Boards" list is ordered alphabetically by option text. +# (without ARCH_ or MACH_) +# + +config MACH_NEO1973_GTA02 + bool "Openmoko GTA02 / Freerunner phone" + select MFD_PCF50633 + select PCF50633_GPIO + select I2C + select POWER_SUPPLY + select MACH_NEO1973 + select S3C2410_PWM + select S3C_DEV_USB_HOST + help + Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone + +config MACH_RX1950 + bool "HP iPAQ rx1950" + select S3C24XX_DCLK + select PM_H1940 if PM + select I2C + select S3C2410_PWM + select S3C_DEV_NAND + select S3C2410_IOTIMING if S3C2440_CPUFREQ + select S3C2440_XTAL_16934400 + help + Say Y here if you're using HP iPAQ rx1950 + +config SMDK2440_CPU2442 + bool "SMDM2440 with S3C2442 CPU module" + +endif # CPU_S3C2440 + +if CPU_S3C2443 || CPU_S3C2416 + +config S3C2443_COMMON + bool + help + Common code for the S3C2443 and similar processors, which includes + the S3C2416 and S3C2450. + +config S3C2443_DMA + bool + help + Internal config node for S3C2443 DMA support + +endif # CPU_S3C2443 || CPU_S3C2416 + +if CPU_S3C2443 + +comment "S3C2443 Boards" + +config MACH_SMDK2443 + bool "SMDK2443" + select S3C24XX_SMDK + select S3C_DEV_HSMMC1 + help + Say Y here if you are using an SMDK2443 + +endif # CPU_S3C2443 + +endmenu # SAMSUNG S3C24XX SoCs Support + +endif # ARCH_S3C24XX diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile new file mode 100644 index 000000000000..3518fe812d5f --- /dev/null +++ b/arch/arm/mach-s3c24xx/Makefile @@ -0,0 +1,95 @@ +# arch/arm/mach-s3c24xx/Makefile +# +# Copyright (c) 2012 Samsung Electronics Co., Ltd. +# http://www.samsung.com/ +# +# Copyright 2007 Simtec Electronics +# +# Licensed under GPLv2 + +obj-y := +obj-m := +obj-n := +obj- := + +# core + +obj-$(CONFIG_CPU_S3C2410) += s3c2410.o +obj-$(CONFIG_S3C2410_DMA) += dma-s3c2410.o +obj-$(CONFIG_S3C2410_PM) += pm-s3c2410.o sleep-s3c2410.o + +obj-$(CONFIG_CPU_S3C2412) += s3c2412.o irq-s3c2412.o clock-s3c2412.o +obj-$(CONFIG_S3C2412_DMA) += dma-s3c2412.o +obj-$(CONFIG_S3C2412_PM) += pm-s3c2412.o +obj-$(CONFIG_S3C2412_PM_SLEEP) += sleep-s3c2412.o + +obj-$(CONFIG_CPU_S3C2416) += s3c2416.o irq-s3c2416.o clock-s3c2416.o +obj-$(CONFIG_S3C2416_PM) += pm-s3c2416.o + +obj-$(CONFIG_CPU_S3C2440) += s3c2440.o irq-s3c2440.o clock-s3c2440.o +obj-$(CONFIG_CPU_S3C2442) += s3c2442.o +obj-$(CONFIG_CPU_S3C244X) += s3c244x.o irq-s3c244x.o clock-s3c244x.o +obj-$(CONFIG_S3C2440_DMA) += dma-s3c2440.o + +obj-$(CONFIG_CPU_S3C2443) += s3c2443.o irq-s3c2443.o clock-s3c2443.o + +# common code + +obj-$(CONFIG_S3C2443_COMMON) += common-s3c2443.o +obj-$(CONFIG_S3C2443_DMA) += dma-s3c2443.o + +# +# machine support +# following is ordered alphabetically by option text. +# + +obj-$(CONFIG_MACH_AML_M5900) += mach-amlm5900.o +obj-$(CONFIG_ARCH_BAST) += mach-bast.o +obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.o +obj-$(CONFIG_ARCH_H1940) += mach-h1940.o +obj-$(CONFIG_H1940BT) += h1940-bluetooth.o +obj-$(CONFIG_PM_H1940) += pm-h1940.o +obj-$(CONFIG_MACH_N30) += mach-n30.o +obj-$(CONFIG_MACH_OTOM) += mach-otom.o +obj-$(CONFIG_MACH_QT2410) += mach-qt2410.o +obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o +obj-$(CONFIG_MACH_TCT_HAMMER) += mach-tct_hammer.o +obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o + +obj-$(CONFIG_MACH_JIVE) += mach-jive.o +obj-$(CONFIG_MACH_SMDK2413) += mach-smdk2413.o +obj-$(CONFIG_MACH_VSTMS) += mach-vstms.o + +obj-$(CONFIG_MACH_SMDK2416) += mach-smdk2416.o + +obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o +obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o +obj-$(CONFIG_MACH_MINI2440) += mach-mini2440.o +obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o +obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o +obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o +obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o + +obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o +obj-$(CONFIG_MACH_RX1950) += mach-rx1950.o + +obj-$(CONFIG_MACH_SMDK2443) += mach-smdk2443.o + +# common bits of machine support + +obj-$(CONFIG_S3C24XX_SMDK) += common-smdk.o +obj-$(CONFIG_S3C24XX_SIMTEC_AUDIO) += simtec-audio.o +obj-$(CONFIG_S3C24XX_SIMTEC_NOR) += simtec-nor.o +obj-$(CONFIG_S3C24XX_SIMTEC_PM) += simtec-pm.o +obj-$(CONFIG_S3C24XX_SIMTEC_USB) += simtec-usb.o + +# machine additions + +obj-$(CONFIG_MACH_BAST_IDE) += bast-ide.o +obj-$(CONFIG_MACH_OSIRIS_DVS) += mach-osiris-dvs.o + +# device setup + +obj-$(CONFIG_S3C2416_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o +obj-$(CONFIG_ARCH_S3C24XX) += setup-i2c.o +obj-$(CONFIG_S3C24XX_SETUP_TS) += setup-ts.o diff --git a/arch/arm/mach-s3c2410/Makefile.boot b/arch/arm/mach-s3c24xx/Makefile.boot index 4457605ba04a..4457605ba04a 100644 --- a/arch/arm/mach-s3c2410/Makefile.boot +++ b/arch/arm/mach-s3c24xx/Makefile.boot diff --git a/arch/arm/mach-s3c2410/bast-ide.c b/arch/arm/mach-s3c24xx/bast-ide.c index 298ececfa366..298ececfa366 100644 --- a/arch/arm/mach-s3c2410/bast-ide.c +++ b/arch/arm/mach-s3c24xx/bast-ide.c diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c24xx/bast-irq.c index ac7b2ad5c405..ac7b2ad5c405 100644 --- a/arch/arm/mach-s3c2410/bast-irq.c +++ b/arch/arm/mach-s3c24xx/bast-irq.c diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c24xx/clock-s3c2412.c index d10b695a9066..d10b695a9066 100644 --- a/arch/arm/mach-s3c2412/clock.c +++ b/arch/arm/mach-s3c24xx/clock-s3c2412.c diff --git a/arch/arm/mach-s3c2416/clock.c b/arch/arm/mach-s3c24xx/clock-s3c2416.c index 59f54d1d7f8b..dbc9ab4aaca2 100644 --- a/arch/arm/mach-s3c2416/clock.c +++ b/arch/arm/mach-s3c24xx/clock-s3c2416.c @@ -15,7 +15,6 @@ #include <linux/clk.h> #include <plat/s3c2416.h> -#include <plat/s3c2443.h> #include <plat/clock.h> #include <plat/clock-clksrc.h> #include <plat/cpu.h> @@ -132,12 +131,6 @@ static struct clk hsmmc0_clk = { .ctrlbit = S3C2416_HCLKCON_HSMMC0, }; -void __init_or_cpufreq s3c2416_setup_clocks(void) -{ - s3c2443_common_setup_clocks(s3c2416_get_pll); -} - - static struct clksrc_clk *clksrcs[] __initdata = { &hsspi_eplldiv, &hsspi_mux, diff --git a/arch/arm/mach-s3c2440/clock.c b/arch/arm/mach-s3c24xx/clock-s3c2440.c index 414364eb426c..414364eb426c 100644 --- a/arch/arm/mach-s3c2440/clock.c +++ b/arch/arm/mach-s3c24xx/clock-s3c2440.c diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c24xx/clock-s3c2443.c index 6dde2696f8f0..efb3ac359566 100644 --- a/arch/arm/mach-s3c2443/clock.c +++ b/arch/arm/mach-s3c24xx/clock-s3c2443.c @@ -179,11 +179,6 @@ static struct clk *clks[] __initdata = { &clk_hsmmc, }; -void __init_or_cpufreq s3c2443_setup_clocks(void) -{ - s3c2443_common_setup_clocks(s3c2443_get_mpll); -} - void __init s3c2443_init_clocks(int xtal) { unsigned long epllcon = __raw_readl(S3C2443_EPLLCON); @@ -196,8 +191,6 @@ void __init s3c2443_init_clocks(int xtal) armdiv, ARRAY_SIZE(armdiv), S3C2443_CLKDIV0_ARMDIV_MASK); - s3c2443_setup_clocks(); - s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) diff --git a/arch/arm/mach-s3c2440/s3c244x-clock.c b/arch/arm/mach-s3c24xx/clock-s3c244x.c index 6d9b688c442b..6d9b688c442b 100644 --- a/arch/arm/mach-s3c2440/s3c244x-clock.c +++ b/arch/arm/mach-s3c24xx/clock-s3c244x.c diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/mach-s3c24xx/common-s3c2443.c index 95e68190d593..460431589f39 100644 --- a/arch/arm/plat-s3c24xx/s3c2443-clock.c +++ b/arch/arm/mach-s3c24xx/common-s3c2443.c @@ -1,9 +1,18 @@ -/* linux/arch/arm/plat-s3c24xx/s3c2443-clock.c +/* + * Common code for SoCs starting with the S3C2443 * * Copyright (c) 2007, 2010 Simtec Electronics * Ben Dooks <ben@simtec.co.uk> * - * S3C2443 Clock control suport - common code + * 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> @@ -12,7 +21,6 @@ #include <mach/regs-s3c2443-clock.h> -#include <plat/s3c2443.h> #include <plat/clock.h> #include <plat/clock-clksrc.h> #include <plat/cpu.h> @@ -53,7 +61,7 @@ int s3c2443_clkcon_enable_s(struct clk *clk, int enable) * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as * such directly equating the two source clocks is impossible. */ -struct clk clk_mpllref = { +static struct clk clk_mpllref = { .name = "mpllref", .parent = &clk_xtal, }; @@ -160,6 +168,44 @@ static struct clk clk_prediv = { }, }; +/* hclk divider + * + * divides the prediv and provides the hclk. + */ + +static unsigned long s3c2443_hclkdiv_getrate(struct clk *clk) +{ + unsigned long rate = clk_get_rate(clk->parent); + unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0); + + clkdiv0 &= S3C2443_CLKDIV0_HCLKDIV_MASK; + + return rate / (clkdiv0 + 1); +} + +static struct clk_ops clk_h_ops = { + .get_rate = s3c2443_hclkdiv_getrate, +}; + +/* pclk divider + * + * divides the hclk and provides the pclk. + */ + +static unsigned long s3c2443_pclkdiv_getrate(struct clk *clk) +{ + unsigned long rate = clk_get_rate(clk->parent); + unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0); + + clkdiv0 = ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 1 : 0); + + return rate / (clkdiv0 + 1); +} + +static struct clk_ops clk_p_ops = { + .get_rate = s3c2443_pclkdiv_getrate, +}; + /* armdiv * * this clock is sourced from msysclk and can have a number of @@ -516,26 +562,15 @@ static struct clk hsmmc1_clk = { .ctrlbit = S3C2443_HCLKCON_HSMMC, }; -static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0) -{ - clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK; - - return clkcon0 + 1; -} - /* EPLLCON compatible enough to get on/off information */ void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll) { unsigned long epllcon = __raw_readl(S3C2443_EPLLCON); unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON); - unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0); struct clk *xtal_clk; unsigned long xtal; unsigned long pll; - unsigned long fclk; - unsigned long hclk; - unsigned long pclk; int ptr; xtal_clk = clk_get(NULL, "xtal"); @@ -544,18 +579,13 @@ void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll) pll = get_mpll(mpllcon, xtal); clk_msysclk.clk.rate = pll; - - fclk = clk_get_rate(&clk_armdiv); - hclk = s3c2443_prediv_getrate(&clk_prediv); - hclk /= s3c2443_get_hdiv(clkdiv0); - pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1); - - s3c24xx_setup_clocks(fclk, hclk, pclk); + clk_mpll.rate = pll; printk("CPU: MPLL %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n", - (mpllcon & S3C2443_PLLCON_OFF) ? "off":"on", - print_mhz(pll), print_mhz(fclk), - print_mhz(hclk), print_mhz(pclk)); + (mpllcon & S3C2443_PLLCON_OFF) ? "off" : "on", + print_mhz(pll), print_mhz(clk_get_rate(&clk_armdiv)), + print_mhz(clk_get_rate(&clk_h)), + print_mhz(clk_get_rate(&clk_p))); for (ptr = 0; ptr < ARRAY_SIZE(clksrc_clks); ptr++) s3c_set_clksrc(&clksrc_clks[ptr], true); @@ -568,7 +598,7 @@ void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll) } printk("CPU: EPLL %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n", - (epllcon & S3C2443_PLLCON_OFF) ? "off":"on", + (epllcon & S3C2443_PLLCON_OFF) ? "off" : "on", print_mhz(clk_get_rate(&clk_epll)), print_mhz(clk_get_rate(&clk_usb_bus))); } @@ -611,9 +641,13 @@ void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, nr_armdiv = nr_divs; armdivmask = divmask; - /* s3c2443 parents h and p clocks from prediv */ + /* s3c2443 parents h clock from prediv */ clk_h.parent = &clk_prediv; - clk_p.parent = &clk_prediv; + clk_h.ops = &clk_h_ops; + + /* and p clock from h clock */ + clk_p.parent = &clk_h; + clk_p.ops = &clk_p_ops; clk_usb_bus.parent = &clk_usb_bus_host.clk; clk_epll.parent = &clk_epllref.clk; diff --git a/arch/arm/plat-s3c24xx/common-smdk.c b/arch/arm/mach-s3c24xx/common-smdk.c index 084604be6ad1..084604be6ad1 100644 --- a/arch/arm/plat-s3c24xx/common-smdk.c +++ b/arch/arm/mach-s3c24xx/common-smdk.c diff --git a/arch/arm/mach-s3c2410/common.h b/arch/arm/mach-s3c24xx/common.h index f65dc8062961..c2f596e7bc2d 100644 --- a/arch/arm/mach-s3c2410/common.h +++ b/arch/arm/mach-s3c24xx/common.h @@ -1,17 +1,18 @@ /* - * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * Copyright (c) 2012 Samsung Electronics Co., Ltd. * http://www.samsung.com * - * Common Header for S3C2410 machines + * Common Header for S3C24XX SoCs * * 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. */ -#ifndef __ARCH_ARM_MACH_S3C2410_COMMON_H -#define __ARCH_ARM_MACH_S3C2410_COMMON_H +#ifndef __ARCH_ARM_MACH_S3C24XX_COMMON_H +#define __ARCH_ARM_MACH_S3C24XX_COMMON_H __FILE__ void s3c2410_restart(char mode, const char *cmd); +void s3c244x_restart(char mode, const char *cmd); -#endif /* __ARCH_ARM_MACH_S3C2410_COMMON_H */ +#endif /* __ARCH_ARM_MACH_S3C24XX_COMMON_H */ diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c24xx/dma-s3c2410.c index 4803338cf56e..4803338cf56e 100644 --- a/arch/arm/mach-s3c2410/dma.c +++ b/arch/arm/mach-s3c24xx/dma-s3c2410.c diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c24xx/dma-s3c2412.c index 38472ac920ff..38472ac920ff 100644 --- a/arch/arm/mach-s3c2412/dma.c +++ b/arch/arm/mach-s3c24xx/dma-s3c2412.c diff --git a/arch/arm/mach-s3c2440/dma.c b/arch/arm/mach-s3c24xx/dma-s3c2440.c index 5f0a0c8ef84f..5f0a0c8ef84f 100644 --- a/arch/arm/mach-s3c2440/dma.c +++ b/arch/arm/mach-s3c24xx/dma-s3c2440.c diff --git a/arch/arm/mach-s3c2443/dma.c b/arch/arm/mach-s3c24xx/dma-s3c2443.c index 14224517e621..e227c472a40a 100644 --- a/arch/arm/mach-s3c2443/dma.c +++ b/arch/arm/mach-s3c24xx/dma-s3c2443.c @@ -51,7 +51,7 @@ static struct s3c24xx_dma_map __initdata s3c2443_dma_mappings[] = { .name = "xdreq1", .channels = MAP(S3C2443_DMAREQSEL_XDREQ1), }, - [DMACH_SDI] = { + [DMACH_SDI] = { /* only on S3C2443 */ .name = "sdi", .channels = MAP(S3C2443_DMAREQSEL_SDI), }, @@ -59,7 +59,7 @@ static struct s3c24xx_dma_map __initdata s3c2443_dma_mappings[] = { .name = "spi0", .channels = MAP(S3C2443_DMAREQSEL_SPI0TX), }, - [DMACH_SPI1] = { + [DMACH_SPI1] = { /* only on S3C2443/S3C2450 */ .name = "spi1", .channels = MAP(S3C2443_DMAREQSEL_SPI1TX), }, @@ -71,11 +71,11 @@ static struct s3c24xx_dma_map __initdata s3c2443_dma_mappings[] = { .name = "uart1", .channels = MAP(S3C2443_DMAREQSEL_UART1_0), }, - [DMACH_UART2] = { + [DMACH_UART2] = { .name = "uart2", .channels = MAP(S3C2443_DMAREQSEL_UART2_0), }, - [DMACH_UART3] = { + [DMACH_UART3] = { .name = "uart3", .channels = MAP(S3C2443_DMAREQSEL_UART3_0), }, @@ -87,11 +87,11 @@ static struct s3c24xx_dma_map __initdata s3c2443_dma_mappings[] = { .name = "uart1", .channels = MAP(S3C2443_DMAREQSEL_UART1_1), }, - [DMACH_UART2_SRC2] = { + [DMACH_UART2_SRC2] = { .name = "uart2", .channels = MAP(S3C2443_DMAREQSEL_UART2_1), }, - [DMACH_UART3_SRC2] = { + [DMACH_UART3_SRC2] = { .name = "uart3", .channels = MAP(S3C2443_DMAREQSEL_UART3_1), }, @@ -142,6 +142,23 @@ static int __init s3c2443_dma_add(struct device *dev, return s3c24xx_dma_init_map(&s3c2443_dma_sel); } +#ifdef CONFIG_CPU_S3C2416 +/* S3C2416 DMA contains the same selection table as the S3C2443 */ +static struct subsys_interface s3c2416_dma_interface = { + .name = "s3c2416_dma", + .subsys = &s3c2416_subsys, + .add_dev = s3c2443_dma_add, +}; + +static int __init s3c2416_dma_init(void) +{ + return subsys_interface_register(&s3c2416_dma_interface); +} + +arch_initcall(s3c2416_dma_init); +#endif + +#ifdef CONFIG_CPU_S3C2443 static struct subsys_interface s3c2443_dma_interface = { .name = "s3c2443_dma", .subsys = &s3c2443_subsys, @@ -154,3 +171,4 @@ static int __init s3c2443_dma_init(void) } arch_initcall(s3c2443_dma_init); +#endif diff --git a/arch/arm/mach-s3c2410/h1940-bluetooth.c b/arch/arm/mach-s3c24xx/h1940-bluetooth.c index a5eeb62ce1c2..a5eeb62ce1c2 100644 --- a/arch/arm/mach-s3c2410/h1940-bluetooth.c +++ b/arch/arm/mach-s3c24xx/h1940-bluetooth.c diff --git a/arch/arm/mach-s3c2410/include/mach/anubis-cpld.h b/arch/arm/mach-s3c24xx/include/mach/anubis-cpld.h index 1b614d5a81f3..1b614d5a81f3 100644 --- a/arch/arm/mach-s3c2410/include/mach/anubis-cpld.h +++ b/arch/arm/mach-s3c24xx/include/mach/anubis-cpld.h diff --git a/arch/arm/mach-s3c2410/include/mach/anubis-irq.h b/arch/arm/mach-s3c24xx/include/mach/anubis-irq.h index a2a328134e34..a2a328134e34 100644 --- a/arch/arm/mach-s3c2410/include/mach/anubis-irq.h +++ b/arch/arm/mach-s3c24xx/include/mach/anubis-irq.h diff --git a/arch/arm/mach-s3c2410/include/mach/anubis-map.h b/arch/arm/mach-s3c24xx/include/mach/anubis-map.h index c9deb3a5b2c3..c9deb3a5b2c3 100644 --- a/arch/arm/mach-s3c2410/include/mach/anubis-map.h +++ b/arch/arm/mach-s3c24xx/include/mach/anubis-map.h diff --git a/arch/arm/mach-s3c2410/include/mach/bast-cpld.h b/arch/arm/mach-s3c24xx/include/mach/bast-cpld.h index bee2a7a932a0..bee2a7a932a0 100644 --- a/arch/arm/mach-s3c2410/include/mach/bast-cpld.h +++ b/arch/arm/mach-s3c24xx/include/mach/bast-cpld.h diff --git a/arch/arm/mach-s3c2410/include/mach/bast-irq.h b/arch/arm/mach-s3c24xx/include/mach/bast-irq.h index cac428c42e7f..cac428c42e7f 100644 --- a/arch/arm/mach-s3c2410/include/mach/bast-irq.h +++ b/arch/arm/mach-s3c24xx/include/mach/bast-irq.h diff --git a/arch/arm/mach-s3c2410/include/mach/bast-map.h b/arch/arm/mach-s3c24xx/include/mach/bast-map.h index 6e7dc9d0cf0e..6e7dc9d0cf0e 100644 --- a/arch/arm/mach-s3c2410/include/mach/bast-map.h +++ b/arch/arm/mach-s3c24xx/include/mach/bast-map.h diff --git a/arch/arm/mach-s3c2410/include/mach/bast-pmu.h b/arch/arm/mach-s3c24xx/include/mach/bast-pmu.h index 4c38b39b741d..4c38b39b741d 100644 --- a/arch/arm/mach-s3c2410/include/mach/bast-pmu.h +++ b/arch/arm/mach-s3c24xx/include/mach/bast-pmu.h diff --git a/arch/arm/mach-s3c2410/include/mach/debug-macro.S b/arch/arm/mach-s3c24xx/include/mach/debug-macro.S index 4135de87d1f7..4135de87d1f7 100644 --- a/arch/arm/mach-s3c2410/include/mach/debug-macro.S +++ b/arch/arm/mach-s3c24xx/include/mach/debug-macro.S diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c24xx/include/mach/dma.h index acbdfecd4186..acbdfecd4186 100644 --- a/arch/arm/mach-s3c2410/include/mach/dma.h +++ b/arch/arm/mach-s3c24xx/include/mach/dma.h diff --git a/arch/arm/mach-s3c2410/include/mach/entry-macro.S b/arch/arm/mach-s3c24xx/include/mach/entry-macro.S index 473b3cd37d9b..7615a14773fa 100644 --- a/arch/arm/mach-s3c2410/include/mach/entry-macro.S +++ b/arch/arm/mach-s3c24xx/include/mach/entry-macro.S @@ -25,9 +25,6 @@ .macro get_irqnr_preamble, base, tmp .endm - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp mov \base, #S3C24XX_VA_IRQ @@ -71,8 +68,3 @@ @@ exit here, Z flag unset if IRQ .endm - - /* currently don't need an disable_fiq macro */ - - .macro disable_fiq - .endm diff --git a/arch/arm/mach-s3c2410/include/mach/fb.h b/arch/arm/mach-s3c24xx/include/mach/fb.h index a957bc8ed44f..a957bc8ed44f 100644 --- a/arch/arm/mach-s3c2410/include/mach/fb.h +++ b/arch/arm/mach-s3c24xx/include/mach/fb.h diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-fns.h b/arch/arm/mach-s3c24xx/include/mach/gpio-fns.h index c53ad34c6579..c53ad34c6579 100644 --- a/arch/arm/mach-s3c2410/include/mach/gpio-fns.h +++ b/arch/arm/mach-s3c24xx/include/mach/gpio-fns.h diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h b/arch/arm/mach-s3c24xx/include/mach/gpio-nrs.h index 019ea86057f6..019ea86057f6 100644 --- a/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h +++ b/arch/arm/mach-s3c24xx/include/mach/gpio-nrs.h diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-track.h b/arch/arm/mach-s3c24xx/include/mach/gpio-track.h index c410a078622c..c410a078622c 100644 --- a/arch/arm/mach-s3c2410/include/mach/gpio-track.h +++ b/arch/arm/mach-s3c24xx/include/mach/gpio-track.h diff --git a/arch/arm/mach-s3c2410/include/mach/gpio.h b/arch/arm/mach-s3c24xx/include/mach/gpio.h index 6fac70f3484e..6fac70f3484e 100644 --- a/arch/arm/mach-s3c2410/include/mach/gpio.h +++ b/arch/arm/mach-s3c24xx/include/mach/gpio.h diff --git a/arch/arm/mach-s3c2440/include/mach/gta02.h b/arch/arm/mach-s3c24xx/include/mach/gta02.h index 3a56a229cac6..3a56a229cac6 100644 --- a/arch/arm/mach-s3c2440/include/mach/gta02.h +++ b/arch/arm/mach-s3c24xx/include/mach/gta02.h diff --git a/arch/arm/mach-s3c2410/include/mach/h1940-latch.h b/arch/arm/mach-s3c24xx/include/mach/h1940-latch.h index fc897d3a056c..fc897d3a056c 100644 --- a/arch/arm/mach-s3c2410/include/mach/h1940-latch.h +++ b/arch/arm/mach-s3c24xx/include/mach/h1940-latch.h diff --git a/arch/arm/mach-s3c2410/include/mach/h1940.h b/arch/arm/mach-s3c24xx/include/mach/h1940.h index 2aa683c8d3d6..2aa683c8d3d6 100644 --- a/arch/arm/mach-s3c2410/include/mach/h1940.h +++ b/arch/arm/mach-s3c24xx/include/mach/h1940.h diff --git a/arch/arm/mach-s3c2410/include/mach/hardware.h b/arch/arm/mach-s3c24xx/include/mach/hardware.h index aef5631eac58..aef5631eac58 100644 --- a/arch/arm/mach-s3c2410/include/mach/hardware.h +++ b/arch/arm/mach-s3c24xx/include/mach/hardware.h diff --git a/arch/arm/mach-s3c2410/include/mach/idle.h b/arch/arm/mach-s3c24xx/include/mach/idle.h index e9ddd706b16e..e9ddd706b16e 100644 --- a/arch/arm/mach-s3c2410/include/mach/idle.h +++ b/arch/arm/mach-s3c24xx/include/mach/idle.h diff --git a/arch/arm/mach-s3c2410/include/mach/io.h b/arch/arm/mach-s3c24xx/include/mach/io.h index 118749f37c4c..5dd1db4e2677 100644 --- a/arch/arm/mach-s3c2410/include/mach/io.h +++ b/arch/arm/mach-s3c24xx/include/mach/io.h @@ -208,9 +208,4 @@ DECLARE_IO(int,l,"") #define outsw(p,d,l) __raw_writesw(__ioaddr(p),d,l) #define outsl(p,d,l) __raw_writesl(__ioaddr(p),d,l) -/* - * 1:1 mapping for ioremapped regions. - */ -#define __mem_pci(x) (x) - #endif diff --git a/arch/arm/mach-s3c2410/include/mach/irqs.h b/arch/arm/mach-s3c24xx/include/mach/irqs.h index e53b2177319e..e53b2177319e 100644 --- a/arch/arm/mach-s3c2410/include/mach/irqs.h +++ b/arch/arm/mach-s3c24xx/include/mach/irqs.h diff --git a/arch/arm/mach-s3c2410/include/mach/leds-gpio.h b/arch/arm/mach-s3c24xx/include/mach/leds-gpio.h index d8a7672519b6..d8a7672519b6 100644 --- a/arch/arm/mach-s3c2410/include/mach/leds-gpio.h +++ b/arch/arm/mach-s3c24xx/include/mach/leds-gpio.h diff --git a/arch/arm/mach-s3c2410/include/mach/map.h b/arch/arm/mach-s3c24xx/include/mach/map.h index 78ae807f1281..78ae807f1281 100644 --- a/arch/arm/mach-s3c2410/include/mach/map.h +++ b/arch/arm/mach-s3c24xx/include/mach/map.h diff --git a/arch/arm/mach-s3c2410/include/mach/osiris-cpld.h b/arch/arm/mach-s3c24xx/include/mach/osiris-cpld.h index e9e36b0abbac..e9e36b0abbac 100644 --- a/arch/arm/mach-s3c2410/include/mach/osiris-cpld.h +++ b/arch/arm/mach-s3c24xx/include/mach/osiris-cpld.h diff --git a/arch/arm/mach-s3c2410/include/mach/osiris-map.h b/arch/arm/mach-s3c24xx/include/mach/osiris-map.h index 17380f848428..17380f848428 100644 --- a/arch/arm/mach-s3c2410/include/mach/osiris-map.h +++ b/arch/arm/mach-s3c24xx/include/mach/osiris-map.h diff --git a/arch/arm/mach-s3c2410/include/mach/otom-map.h b/arch/arm/mach-s3c24xx/include/mach/otom-map.h index f9277a52c145..f9277a52c145 100644 --- a/arch/arm/mach-s3c2410/include/mach/otom-map.h +++ b/arch/arm/mach-s3c24xx/include/mach/otom-map.h diff --git a/arch/arm/mach-s3c2410/include/mach/pm-core.h b/arch/arm/mach-s3c24xx/include/mach/pm-core.h index 2eef7e6f7675..2eef7e6f7675 100644 --- a/arch/arm/mach-s3c2410/include/mach/pm-core.h +++ b/arch/arm/mach-s3c24xx/include/mach/pm-core.h diff --git a/arch/arm/mach-s3c2410/include/mach/regs-clock.h b/arch/arm/mach-s3c24xx/include/mach/regs-clock.h index 3415b60082d7..3415b60082d7 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-clock.h +++ b/arch/arm/mach-s3c24xx/include/mach/regs-clock.h diff --git a/arch/arm/mach-s3c2410/include/mach/regs-dsc.h b/arch/arm/mach-s3c24xx/include/mach/regs-dsc.h index 98fd4a05587c..98fd4a05587c 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-dsc.h +++ b/arch/arm/mach-s3c24xx/include/mach/regs-dsc.h diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h b/arch/arm/mach-s3c24xx/include/mach/regs-gpio.h index cac1ad6b582c..cac1ad6b582c 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h +++ b/arch/arm/mach-s3c24xx/include/mach/regs-gpio.h diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h b/arch/arm/mach-s3c24xx/include/mach/regs-gpioj.h index 19575e061114..19575e061114 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h +++ b/arch/arm/mach-s3c24xx/include/mach/regs-gpioj.h diff --git a/arch/arm/mach-s3c2410/include/mach/regs-irq.h b/arch/arm/mach-s3c24xx/include/mach/regs-irq.h index 0f07ba30b1fb..0f07ba30b1fb 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-irq.h +++ b/arch/arm/mach-s3c24xx/include/mach/regs-irq.h diff --git a/arch/arm/mach-s3c2410/include/mach/regs-lcd.h b/arch/arm/mach-s3c24xx/include/mach/regs-lcd.h index ee8f040aff5f..ee8f040aff5f 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-lcd.h +++ b/arch/arm/mach-s3c24xx/include/mach/regs-lcd.h diff --git a/arch/arm/mach-s3c2410/include/mach/regs-mem.h b/arch/arm/mach-s3c24xx/include/mach/regs-mem.h index e0c67b0163d8..e0c67b0163d8 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-mem.h +++ b/arch/arm/mach-s3c24xx/include/mach/regs-mem.h diff --git a/arch/arm/mach-s3c2410/include/mach/regs-power.h b/arch/arm/mach-s3c24xx/include/mach/regs-power.h index 4932b87bdf3d..4932b87bdf3d 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-power.h +++ b/arch/arm/mach-s3c24xx/include/mach/regs-power.h diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2412-mem.h index fb6352515090..fb6352515090 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h +++ b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2412-mem.h diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2412.h b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2412.h index aa69dc79bc38..aa69dc79bc38 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-s3c2412.h +++ b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2412.h diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2416-mem.h index 2f31b74974af..2f31b74974af 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h +++ b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2416-mem.h diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2416.h index e443167efb87..e443167efb87 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h +++ b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2416.h diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2443-clock.h index c3feff3c0488..c3feff3c0488 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h +++ b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2443-clock.h diff --git a/arch/arm/mach-s3c2410/include/mach/regs-sdi.h b/arch/arm/mach-s3c24xx/include/mach/regs-sdi.h index cbf2d8884e30..cbf2d8884e30 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-sdi.h +++ b/arch/arm/mach-s3c24xx/include/mach/regs-sdi.h diff --git a/arch/arm/mach-s3c2410/include/mach/tick.h b/arch/arm/mach-s3c24xx/include/mach/tick.h index 544da41979db..544da41979db 100644 --- a/arch/arm/mach-s3c2410/include/mach/tick.h +++ b/arch/arm/mach-s3c24xx/include/mach/tick.h diff --git a/arch/arm/mach-s3c2410/include/mach/timex.h b/arch/arm/mach-s3c24xx/include/mach/timex.h index fe9ca1ffd51b..fe9ca1ffd51b 100644 --- a/arch/arm/mach-s3c2410/include/mach/timex.h +++ b/arch/arm/mach-s3c24xx/include/mach/timex.h diff --git a/arch/arm/mach-s3c2410/include/mach/uncompress.h b/arch/arm/mach-s3c24xx/include/mach/uncompress.h index 8b283f847daa..8b283f847daa 100644 --- a/arch/arm/mach-s3c2410/include/mach/uncompress.h +++ b/arch/arm/mach-s3c24xx/include/mach/uncompress.h diff --git a/arch/arm/mach-s3c2410/include/mach/vr1000-cpld.h b/arch/arm/mach-s3c24xx/include/mach/vr1000-cpld.h index e4119913d7c5..e4119913d7c5 100644 --- a/arch/arm/mach-s3c2410/include/mach/vr1000-cpld.h +++ b/arch/arm/mach-s3c24xx/include/mach/vr1000-cpld.h diff --git a/arch/arm/mach-s3c2410/include/mach/vr1000-irq.h b/arch/arm/mach-s3c24xx/include/mach/vr1000-irq.h index 47add133b8ee..47add133b8ee 100644 --- a/arch/arm/mach-s3c2410/include/mach/vr1000-irq.h +++ b/arch/arm/mach-s3c24xx/include/mach/vr1000-irq.h diff --git a/arch/arm/mach-s3c2410/include/mach/vr1000-map.h b/arch/arm/mach-s3c24xx/include/mach/vr1000-map.h index 99612fcc4eb2..99612fcc4eb2 100644 --- a/arch/arm/mach-s3c2410/include/mach/vr1000-map.h +++ b/arch/arm/mach-s3c24xx/include/mach/vr1000-map.h diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c24xx/irq-s3c2412.c index e65619ddbccc..e65619ddbccc 100644 --- a/arch/arm/mach-s3c2412/irq.c +++ b/arch/arm/mach-s3c24xx/irq-s3c2412.c diff --git a/arch/arm/mach-s3c2416/irq.c b/arch/arm/mach-s3c24xx/irq-s3c2416.c index fd49f35e448e..fd49f35e448e 100644 --- a/arch/arm/mach-s3c2416/irq.c +++ b/arch/arm/mach-s3c24xx/irq-s3c2416.c diff --git a/arch/arm/mach-s3c2440/irq.c b/arch/arm/mach-s3c24xx/irq-s3c2440.c index 4a18cde439cc..4a18cde439cc 100644 --- a/arch/arm/mach-s3c2440/irq.c +++ b/arch/arm/mach-s3c24xx/irq-s3c2440.c diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c24xx/irq-s3c2443.c index ac2829f56d12..ac2829f56d12 100644 --- a/arch/arm/mach-s3c2443/irq.c +++ b/arch/arm/mach-s3c24xx/irq-s3c2443.c diff --git a/arch/arm/mach-s3c2440/s3c244x-irq.c b/arch/arm/mach-s3c24xx/irq-s3c244x.c index 5fe8e58d3afd..5fe8e58d3afd 100644 --- a/arch/arm/mach-s3c2440/s3c244x-irq.c +++ b/arch/arm/mach-s3c24xx/irq-s3c244x.c diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c24xx/mach-amlm5900.c index 4220cc60de3c..4220cc60de3c 100644 --- a/arch/arm/mach-s3c2410/mach-amlm5900.c +++ b/arch/arm/mach-s3c24xx/mach-amlm5900.c diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c24xx/mach-anubis.c index 19b577bc09b8..60c72c54c21e 100644 --- a/arch/arm/mach-s3c2440/mach-anubis.c +++ b/arch/arm/mach-s3c24xx/mach-anubis.c @@ -55,6 +55,7 @@ #include <plat/cpu.h> #include <plat/audio-simtec.h> +#include "simtec.h" #include "common.h" #define COPYRIGHT ", Copyright 2005-2009 Simtec Electronics" diff --git a/arch/arm/mach-s3c2440/mach-at2440evb.c b/arch/arm/mach-s3c24xx/mach-at2440evb.c index d7ae49c90118..d7ae49c90118 100644 --- a/arch/arm/mach-s3c2440/mach-at2440evb.c +++ b/arch/arm/mach-s3c24xx/mach-at2440evb.c diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c24xx/mach-bast.c index feeaf73933dc..53219c02eca0 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c24xx/mach-bast.c @@ -64,8 +64,7 @@ #include <plat/gpio-cfg.h> #include <plat/audio-simtec.h> -#include "usb-simtec.h" -#include "nor-simtec.h" +#include "simtec.h" #include "common.h" #define COPYRIGHT ", Copyright 2004-2008 Simtec Electronics" diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c24xx/mach-gta02.c index 9a4a5bc008e6..ba5d85394105 100644 --- a/arch/arm/mach-s3c2440/mach-gta02.c +++ b/arch/arm/mach-s3c24xx/mach-gta02.c @@ -38,6 +38,7 @@ #include <linux/platform_device.h> #include <linux/serial_core.h> #include <linux/spi/spi.h> +#include <linux/spi/s3c24xx.h> #include <linux/mmc/host.h> @@ -73,7 +74,6 @@ #include <mach/regs-gpioj.h> #include <mach/fb.h> -#include <mach/spi.h> #include <plat/usb-control.h> #include <mach/regs-mem.h> #include <mach/hardware.h> @@ -258,7 +258,7 @@ static struct pcf50633_bl_platform_data gta02_backlight_data = { .ramp_time = 5, }; -struct pcf50633_platform_data gta02_pcf_pdata = { +static struct pcf50633_platform_data gta02_pcf_pdata = { .resumers = { [0] = PCF50633_INT1_USBINS | PCF50633_INT1_USBREM | @@ -404,7 +404,7 @@ static struct platform_device gta02_nor_flash = { }; -struct platform_device s3c24xx_pwm_device = { +static struct platform_device s3c24xx_pwm_device = { .name = "s3c24xx_pwm", .num_resources = 0, }; diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c24xx/mach-h1940.c index 41245a603981..6b21ba107eab 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c24xx/mach-h1940.c @@ -162,7 +162,7 @@ static int h1940_gpiolib_latch_get(struct gpio_chip *chip, return (latch_state >> (offset + 16)) & 1; } -struct gpio_chip h1940_latch_gpiochip = { +static struct gpio_chip h1940_latch_gpiochip = { .base = H1940_LATCH_GPIO(0), .owner = THIS_MODULE, .label = "H1940_LATCH", @@ -304,7 +304,7 @@ static const struct s3c_adc_bat_thresh bat_lut_acin[] = { { .volt = 3841, .cur = 0, .level = 0}, }; -int h1940_bat_init(void) +static int h1940_bat_init(void) { int ret; @@ -317,17 +317,17 @@ int h1940_bat_init(void) } -void h1940_bat_exit(void) +static void h1940_bat_exit(void) { gpio_free(H1940_LATCH_SM803_ENABLE); } -void h1940_enable_charger(void) +static void h1940_enable_charger(void) { gpio_set_value(H1940_LATCH_SM803_ENABLE, 1); } -void h1940_disable_charger(void) +static void h1940_disable_charger(void) { gpio_set_value(H1940_LATCH_SM803_ENABLE, 0); } @@ -364,7 +364,7 @@ static struct platform_device h1940_battery = { }, }; -DEFINE_SPINLOCK(h1940_blink_spin); +static DEFINE_SPINLOCK(h1940_blink_spin); int h1940_led_blink_set(unsigned gpio, int state, unsigned long *delay_on, unsigned long *delay_off) diff --git a/arch/arm/mach-s3c2412/mach-jive.c b/arch/arm/mach-s3c24xx/mach-jive.c index ae73ba34ecc6..ae73ba34ecc6 100644 --- a/arch/arm/mach-s3c2412/mach-jive.c +++ b/arch/arm/mach-s3c24xx/mach-jive.c diff --git a/arch/arm/mach-s3c2440/mach-mini2440.c b/arch/arm/mach-s3c24xx/mach-mini2440.c index 5d66fb218a41..5d66fb218a41 100644 --- a/arch/arm/mach-s3c2440/mach-mini2440.c +++ b/arch/arm/mach-s3c24xx/mach-mini2440.c diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c24xx/mach-n30.c index 383d00ca8f60..383d00ca8f60 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c24xx/mach-n30.c diff --git a/arch/arm/mach-s3c2440/mach-nexcoder.c b/arch/arm/mach-s3c24xx/mach-nexcoder.c index 5198e3e1c5be..5198e3e1c5be 100644 --- a/arch/arm/mach-s3c2440/mach-nexcoder.c +++ b/arch/arm/mach-s3c24xx/mach-nexcoder.c diff --git a/arch/arm/mach-s3c2440/mach-osiris-dvs.c b/arch/arm/mach-s3c24xx/mach-osiris-dvs.c index ad2792dfbee1..ad2792dfbee1 100644 --- a/arch/arm/mach-s3c2440/mach-osiris-dvs.c +++ b/arch/arm/mach-s3c24xx/mach-osiris-dvs.c diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c24xx/mach-osiris.c index c5daeb612a88..c5daeb612a88 100644 --- a/arch/arm/mach-s3c2440/mach-osiris.c +++ b/arch/arm/mach-s3c24xx/mach-osiris.c diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c24xx/mach-otom.c index 5f1e0eeb38a9..5f1e0eeb38a9 100644 --- a/arch/arm/mach-s3c2410/mach-otom.c +++ b/arch/arm/mach-s3c24xx/mach-otom.c diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c24xx/mach-qt2410.c index 91c16d9d2459..91c16d9d2459 100644 --- a/arch/arm/mach-s3c2410/mach-qt2410.c +++ b/arch/arm/mach-s3c24xx/mach-qt2410.c diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c24xx/mach-rx1950.c index 6f68abf44fab..200debb4c72d 100644 --- a/arch/arm/mach-s3c2440/mach-rx1950.c +++ b/arch/arm/mach-s3c24xx/mach-rx1950.c @@ -217,7 +217,7 @@ static const struct s3c_adc_bat_thresh bat_lut_acin[] = { { .volt = 3820, .cur = 0, .level = 0}, }; -int rx1950_bat_init(void) +static int rx1950_bat_init(void) { int ret; @@ -236,25 +236,25 @@ err_gpio1: return ret; } -void rx1950_bat_exit(void) +static void rx1950_bat_exit(void) { gpio_free(S3C2410_GPJ(2)); gpio_free(S3C2410_GPJ(3)); } -void rx1950_enable_charger(void) +static void rx1950_enable_charger(void) { gpio_direction_output(S3C2410_GPJ(2), 1); gpio_direction_output(S3C2410_GPJ(3), 1); } -void rx1950_disable_charger(void) +static void rx1950_disable_charger(void) { gpio_direction_output(S3C2410_GPJ(2), 0); gpio_direction_output(S3C2410_GPJ(3), 0); } -DEFINE_SPINLOCK(rx1950_blink_spin); +static DEFINE_SPINLOCK(rx1950_blink_spin); static int rx1950_led_blink_set(unsigned gpio, int state, unsigned long *delay_on, unsigned long *delay_off) @@ -382,7 +382,7 @@ static struct s3c2410fb_mach_info rx1950_lcd_cfg = { static struct pwm_device *lcd_pwm; -void rx1950_lcd_power(int enable) +static void rx1950_lcd_power(int enable) { int i; static int enabled; diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c24xx/mach-rx3715.c index 56af35447598..56af35447598 100644 --- a/arch/arm/mach-s3c2440/mach-rx3715.c +++ b/arch/arm/mach-s3c24xx/mach-rx3715.c diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c24xx/mach-smdk2410.c index bdc27e772876..bdc27e772876 100644 --- a/arch/arm/mach-s3c2410/mach-smdk2410.c +++ b/arch/arm/mach-s3c24xx/mach-smdk2410.c diff --git a/arch/arm/mach-s3c2412/mach-smdk2413.c b/arch/arm/mach-s3c24xx/mach-smdk2413.c index b11451b853d8..b11451b853d8 100644 --- a/arch/arm/mach-s3c2412/mach-smdk2413.c +++ b/arch/arm/mach-s3c24xx/mach-smdk2413.c diff --git a/arch/arm/mach-s3c2416/mach-smdk2416.c b/arch/arm/mach-s3c24xx/mach-smdk2416.c index eebe1e72b93e..30a44f806e01 100644 --- a/arch/arm/mach-s3c2416/mach-smdk2416.c +++ b/arch/arm/mach-s3c24xx/mach-smdk2416.c @@ -125,7 +125,7 @@ static struct s3c2410_uartcfg smdk2416_uartcfgs[] __initdata = { } }; -void smdk2416_hsudc_gpio_init(void) +static void smdk2416_hsudc_gpio_init(void) { s3c_gpio_setpull(S3C2410_GPH(14), S3C_GPIO_PULL_UP); s3c_gpio_setpull(S3C2410_GPF(2), S3C_GPIO_PULL_NONE); @@ -133,20 +133,20 @@ void smdk2416_hsudc_gpio_init(void) s3c2410_modify_misccr(S3C2416_MISCCR_SEL_SUSPND, 0); } -void smdk2416_hsudc_gpio_uninit(void) +static void smdk2416_hsudc_gpio_uninit(void) { s3c2410_modify_misccr(S3C2416_MISCCR_SEL_SUSPND, 1); s3c_gpio_setpull(S3C2410_GPH(14), S3C_GPIO_PULL_NONE); s3c_gpio_cfgpin(S3C2410_GPH(14), S3C_GPIO_SFN(0)); } -struct s3c24xx_hsudc_platdata smdk2416_hsudc_platdata = { +static struct s3c24xx_hsudc_platdata smdk2416_hsudc_platdata = { .epnum = 9, .gpio_init = smdk2416_hsudc_gpio_init, .gpio_uninit = smdk2416_hsudc_gpio_uninit, }; -struct s3c_fb_pd_win smdk2416_fb_win[] = { +static struct s3c_fb_pd_win smdk2416_fb_win[] = { [0] = { /* think this is the same as the smdk6410 */ .win_mode = { diff --git a/arch/arm/mach-s3c2440/mach-smdk2440.c b/arch/arm/mach-s3c24xx/mach-smdk2440.c index 83a1036d7dcb..83a1036d7dcb 100644 --- a/arch/arm/mach-s3c2440/mach-smdk2440.c +++ b/arch/arm/mach-s3c24xx/mach-smdk2440.c diff --git a/arch/arm/mach-s3c2443/mach-smdk2443.c b/arch/arm/mach-s3c24xx/mach-smdk2443.c index 209236956222..209236956222 100644 --- a/arch/arm/mach-s3c2443/mach-smdk2443.c +++ b/arch/arm/mach-s3c24xx/mach-smdk2443.c diff --git a/arch/arm/mach-s3c2410/mach-tct_hammer.c b/arch/arm/mach-s3c24xx/mach-tct_hammer.c index 1114666f0efb..1114666f0efb 100644 --- a/arch/arm/mach-s3c2410/mach-tct_hammer.c +++ b/arch/arm/mach-s3c24xx/mach-tct_hammer.c diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c24xx/mach-vr1000.c index dbe668a803ef..87608d45dac4 100644 --- a/arch/arm/mach-s3c2410/mach-vr1000.c +++ b/arch/arm/mach-s3c24xx/mach-vr1000.c @@ -51,8 +51,7 @@ #include <plat/iic.h> #include <plat/audio-simtec.h> -#include "usb-simtec.h" -#include "nor-simtec.h" +#include "simtec.h" #include "common.h" /* macros for virtual address mods for the io space entries */ diff --git a/arch/arm/mach-s3c2412/mach-vstms.c b/arch/arm/mach-s3c24xx/mach-vstms.c index 94bfaa1fb148..94bfaa1fb148 100644 --- a/arch/arm/mach-s3c2412/mach-vstms.c +++ b/arch/arm/mach-s3c24xx/mach-vstms.c diff --git a/arch/arm/mach-s3c2410/pm-h1940.S b/arch/arm/mach-s3c24xx/pm-h1940.S index c93bf2db9f4d..c93bf2db9f4d 100644 --- a/arch/arm/mach-s3c2410/pm-h1940.S +++ b/arch/arm/mach-s3c24xx/pm-h1940.S diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c24xx/pm-s3c2410.c index 03f706dd6009..03f706dd6009 100644 --- a/arch/arm/mach-s3c2410/pm.c +++ b/arch/arm/mach-s3c24xx/pm-s3c2410.c diff --git a/arch/arm/mach-s3c2412/pm.c b/arch/arm/mach-s3c24xx/pm-s3c2412.c index d04588506ec4..d04588506ec4 100644 --- a/arch/arm/mach-s3c2412/pm.c +++ b/arch/arm/mach-s3c24xx/pm-s3c2412.c diff --git a/arch/arm/mach-s3c2416/pm.c b/arch/arm/mach-s3c24xx/pm-s3c2416.c index 1bd4817b8eb8..1bd4817b8eb8 100644 --- a/arch/arm/mach-s3c2416/pm.c +++ b/arch/arm/mach-s3c24xx/pm-s3c2416.c diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c24xx/s3c2410.c index 061b6bb1a557..a3c5cb086ee2 100644 --- a/arch/arm/mach-s3c2410/s3c2410.c +++ b/arch/arm/mach-s3c24xx/s3c2410.c @@ -30,6 +30,7 @@ #include <mach/hardware.h> #include <asm/irq.h> +#include <asm/system_misc.h> #include <plat/cpu-freq.h> diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c24xx/s3c2412.c index aff6e85a97c6..d4bc7f960bbb 100644 --- a/arch/arm/mach-s3c2412/s3c2412.c +++ b/arch/arm/mach-s3c24xx/s3c2412.c @@ -31,8 +31,7 @@ #include <mach/hardware.h> #include <asm/proc-fns.h> #include <asm/irq.h> - -#include <mach/idle.h> +#include <asm/system_misc.h> #include <plat/cpu-freq.h> @@ -164,7 +163,7 @@ void __init s3c2412_map_io(void) /* set our idle function */ - s3c24xx_idle = s3c2412_idle; + arm_pm_idle = s3c2412_idle; /* register our io-tables */ diff --git a/arch/arm/mach-s3c2416/s3c2416.c b/arch/arm/mach-s3c24xx/s3c2416.c index 5287d2808d3e..7743fade50df 100644 --- a/arch/arm/mach-s3c2416/s3c2416.c +++ b/arch/arm/mach-s3c24xx/s3c2416.c @@ -43,8 +43,8 @@ #include <mach/hardware.h> #include <asm/proc-fns.h> #include <asm/irq.h> +#include <asm/system_misc.h> -#include <mach/idle.h> #include <mach/regs-s3c2443-clock.h> #include <plat/gpio-core.h> @@ -60,6 +60,7 @@ #include <plat/fb-core.h> #include <plat/nand-core.h> #include <plat/adc-core.h> +#include <plat/rtc-core.h> static struct map_desc s3c2416_iodesc[] __initdata = { IODESC_ENT(WATCHDOG), @@ -88,8 +89,6 @@ int __init s3c2416_init(void) { printk(KERN_INFO "S3C2416: Initializing architecture\n"); - /* s3c24xx_idle = s3c2416_idle; */ - /* change WDT IRQ number */ s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT; s3c_device_wdt.resource[1].end = IRQ_S3C2443_WDT; @@ -101,6 +100,7 @@ int __init s3c2416_init(void) s3c_fb_setname("s3c2443-fb"); s3c_adc_setname("s3c2416-adc"); + s3c_rtc_setname("s3c2416-rtc"); #ifdef CONFIG_PM register_syscore_ops(&s3c2416_pm_syscore_ops); diff --git a/arch/arm/mach-s3c2440/s3c2440.c b/arch/arm/mach-s3c24xx/s3c2440.c index 2b3dddb49af7..2b3dddb49af7 100644 --- a/arch/arm/mach-s3c2440/s3c2440.c +++ b/arch/arm/mach-s3c24xx/s3c2440.c diff --git a/arch/arm/mach-s3c2440/s3c2442.c b/arch/arm/mach-s3c24xx/s3c2442.c index 22cb7c94a8c8..22cb7c94a8c8 100644 --- a/arch/arm/mach-s3c2440/s3c2442.c +++ b/arch/arm/mach-s3c24xx/s3c2442.c diff --git a/arch/arm/mach-s3c2443/s3c2443.c b/arch/arm/mach-s3c24xx/s3c2443.c index b9deaeb0dfff..ab648ad8fa50 100644 --- a/arch/arm/mach-s3c2443/s3c2443.c +++ b/arch/arm/mach-s3c24xx/s3c2443.c @@ -29,6 +29,7 @@ #include <mach/hardware.h> #include <asm/irq.h> +#include <asm/system_misc.h> #include <mach/regs-s3c2443-clock.h> @@ -41,6 +42,7 @@ #include <plat/fb-core.h> #include <plat/nand-core.h> #include <plat/adc-core.h> +#include <plat/rtc-core.h> static struct map_desc s3c2443_iodesc[] __initdata = { IODESC_ENT(WATCHDOG), @@ -73,6 +75,7 @@ int __init s3c2443_init(void) s3c_fb_setname("s3c2443-fb"); s3c_adc_setname("s3c2443-adc"); + s3c_rtc_setname("s3c2443-rtc"); /* change WDT IRQ number */ s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT; diff --git a/arch/arm/mach-s3c2440/s3c244x.c b/arch/arm/mach-s3c24xx/s3c244x.c index d15852f642b7..6f74118f60c6 100644 --- a/arch/arm/mach-s3c2440/s3c244x.c +++ b/arch/arm/mach-s3c24xx/s3c244x.c @@ -23,6 +23,7 @@ #include <linux/clk.h> #include <linux/io.h> +#include <asm/system_misc.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/irq.h> diff --git a/arch/arm/plat-s3c24xx/setup-i2c.c b/arch/arm/mach-s3c24xx/setup-i2c.c index 9e90a7cbd1d6..9e90a7cbd1d6 100644 --- a/arch/arm/plat-s3c24xx/setup-i2c.c +++ b/arch/arm/mach-s3c24xx/setup-i2c.c diff --git a/arch/arm/mach-s3c2416/setup-sdhci-gpio.c b/arch/arm/mach-s3c24xx/setup-sdhci-gpio.c index f65cb3ef16ce..f65cb3ef16ce 100644 --- a/arch/arm/mach-s3c2416/setup-sdhci-gpio.c +++ b/arch/arm/mach-s3c24xx/setup-sdhci-gpio.c diff --git a/arch/arm/plat-s3c24xx/setup-ts.c b/arch/arm/mach-s3c24xx/setup-ts.c index ed2638663675..ed2638663675 100644 --- a/arch/arm/plat-s3c24xx/setup-ts.c +++ b/arch/arm/mach-s3c24xx/setup-ts.c diff --git a/arch/arm/plat-s3c24xx/simtec-audio.c b/arch/arm/mach-s3c24xx/simtec-audio.c index 6bc832e0d8ea..11881c9a38c0 100644 --- a/arch/arm/plat-s3c24xx/simtec-audio.c +++ b/arch/arm/mach-s3c24xx/simtec-audio.c @@ -27,6 +27,8 @@ #include <plat/audio-simtec.h> #include <plat/devs.h> +#include "simtec.h" + /* platform ops for audio */ static void simtec_audio_startup_lrroute(void) diff --git a/arch/arm/mach-s3c2410/nor-simtec.c b/arch/arm/mach-s3c24xx/simtec-nor.c index ad9f750f1e55..b9d6d4f92c03 100644 --- a/arch/arm/mach-s3c2410/nor-simtec.c +++ b/arch/arm/mach-s3c24xx/simtec-nor.c @@ -30,14 +30,12 @@ #include <mach/bast-map.h> #include <mach/bast-cpld.h> -#include "nor-simtec.h" +#include "simtec.h" static void simtec_nor_vpp(struct platform_device *pdev, int vpp) { unsigned int val; - unsigned long flags; - local_irq_save(flags); val = __raw_readb(BAST_VA_CTRL3); printk(KERN_DEBUG "%s(%d)\n", __func__, vpp); @@ -48,7 +46,6 @@ static void simtec_nor_vpp(struct platform_device *pdev, int vpp) val &= ~BAST_CPLD_CTRL3_ROMWEN; __raw_writeb(val, BAST_VA_CTRL3); - local_irq_restore(flags); } static struct physmap_flash_data simtec_nor_pdata = { diff --git a/arch/arm/plat-s3c24xx/pm-simtec.c b/arch/arm/mach-s3c24xx/simtec-pm.c index 699f93171297..699f93171297 100644 --- a/arch/arm/plat-s3c24xx/pm-simtec.c +++ b/arch/arm/mach-s3c24xx/simtec-pm.c diff --git a/arch/arm/mach-s3c2410/usb-simtec.c b/arch/arm/mach-s3c24xx/simtec-usb.c index 29bd3d987bec..d91c1a725139 100644 --- a/arch/arm/mach-s3c2410/usb-simtec.c +++ b/arch/arm/mach-s3c24xx/simtec-usb.c @@ -37,7 +37,7 @@ #include <plat/usb-control.h> #include <plat/devs.h> -#include "usb-simtec.h" +#include "simtec.h" /* control power and monitor over-current events on various Simtec * designed boards. diff --git a/arch/arm/mach-s3c2410/nor-simtec.h b/arch/arm/mach-s3c24xx/simtec.h index f619c1e0d0c8..ae8f4f9ad2ee 100644 --- a/arch/arm/mach-s3c2410/nor-simtec.h +++ b/arch/arm/mach-s3c24xx/simtec.h @@ -4,11 +4,18 @@ * http://armlinux.simtec.co.uk/ * Ben Dooks <ben@simtec.co.uk> * - * Simtec NOR mapping + * Simtec common functions * * 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. */ +struct s3c24xx_audio_simtec_pdata; + extern void nor_simtec_init(void); + +extern int usb_simtec_init(void); + +extern int simtec_audio_add(const char *codec_name, bool has_lr_routing, + struct s3c24xx_audio_simtec_pdata *pdata); diff --git a/arch/arm/mach-s3c2410/sleep.S b/arch/arm/mach-s3c24xx/sleep-s3c2410.S index dd5b6388a5a5..dd5b6388a5a5 100644 --- a/arch/arm/mach-s3c2410/sleep.S +++ b/arch/arm/mach-s3c24xx/sleep-s3c2410.S diff --git a/arch/arm/mach-s3c2412/sleep.S b/arch/arm/mach-s3c24xx/sleep-s3c2412.S index c82418ed714d..c82418ed714d 100644 --- a/arch/arm/mach-s3c2412/sleep.S +++ b/arch/arm/mach-s3c24xx/sleep-s3c2412.S diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig index dd20c66cd700..82c0915729ee 100644 --- a/arch/arm/mach-s3c64xx/Kconfig +++ b/arch/arm/mach-s3c64xx/Kconfig @@ -83,6 +83,11 @@ config S3C64XX_SETUP_SPI help Common setup code for SPI GPIO configurations +config S3C64XX_SETUP_USB_PHY + bool + help + Common setup code for USB PHY controller + # S36400 Macchine support config MACH_SMDK6400 @@ -157,6 +162,7 @@ config MACH_SMDK6410 select S3C64XX_SETUP_IDE select S3C64XX_SETUP_FB_24BPP select S3C64XX_SETUP_KEYPAD + select S3C64XX_SETUP_USB_PHY help Machine support for the Samsung SMDK6410 @@ -256,6 +262,7 @@ config MACH_SMARTQ select S3C_DEV_USB_HOST select S3C64XX_SETUP_SDHCI select S3C64XX_SETUP_FB_24BPP + select S3C64XX_SETUP_USB_PHY select SAMSUNG_DEV_ADC select SAMSUNG_DEV_PWM select SAMSUNG_DEV_TS @@ -283,6 +290,7 @@ config MACH_WLF_CRAGG_6410 select S3C64XX_SETUP_FB_24BPP select S3C64XX_SETUP_KEYPAD select S3C64XX_SETUP_SPI + select S3C64XX_SETUP_USB_PHY select SAMSUNG_DEV_ADC select SAMSUNG_DEV_KEYPAD select S3C_DEV_USB_HOST @@ -296,5 +304,6 @@ config MACH_WLF_CRAGG_6410 select S3C64XX_DEV_SPI0 select SAMSUNG_GPIO_EXTRA128 select I2C + select LEDS_GPIO_REGISTER help Machine support for the Wolfson Cragganmore S3C6410 variant. diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile index 1822ac2eba31..f9ce1dc28ce4 100644 --- a/arch/arm/mach-s3c64xx/Makefile +++ b/arch/arm/mach-s3c64xx/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_CPU_S3C6410) += s3c6410.o # PM obj-$(CONFIG_PM) += pm.o irq-pm.o sleep.o +obj-$(CONFIG_CPU_IDLE) += cpuidle.o # DMA support @@ -42,6 +43,7 @@ obj-$(CONFIG_S3C64XX_SETUP_IDE) += setup-ide.o obj-$(CONFIG_S3C64XX_SETUP_KEYPAD) += setup-keypad.o obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o obj-$(CONFIG_S3C64XX_SETUP_SPI) += setup-spi.o +obj-$(CONFIG_S3C64XX_SETUP_USB_PHY) += setup-usb-phy.o # Machine support diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c index aebbcc291b4e..52f079a691cb 100644 --- a/arch/arm/mach-s3c64xx/clock.c +++ b/arch/arm/mach-s3c64xx/clock.c @@ -207,6 +207,15 @@ static struct clk init_clocks_off[] = { .enable = s3c64xx_sclk_ctrl, .ctrlbit = S3C_CLKCON_SCLK_MMC2_48, }, { + .name = "ac97", + .parent = &clk_p, + .ctrlbit = S3C_CLKCON_PCLK_AC97, + }, { + .name = "cfcon", + .parent = &clk_h, + .enable = s3c64xx_hclk_ctrl, + .ctrlbit = S3C_CLKCON_HCLK_IHOST, + }, { .name = "dma0", .parent = &clk_h, .enable = s3c64xx_hclk_ctrl, @@ -216,6 +225,107 @@ static struct clk init_clocks_off[] = { .parent = &clk_h, .enable = s3c64xx_hclk_ctrl, .ctrlbit = S3C_CLKCON_HCLK_DMA1, + }, { + .name = "3dse", + .parent = &clk_h, + .enable = s3c64xx_hclk_ctrl, + .ctrlbit = S3C_CLKCON_HCLK_3DSE, + }, { + .name = "hclk_secur", + .parent = &clk_h, + .enable = s3c64xx_hclk_ctrl, + .ctrlbit = S3C_CLKCON_HCLK_SECUR, + }, { + .name = "sdma1", + .parent = &clk_h, + .enable = s3c64xx_hclk_ctrl, + .ctrlbit = S3C_CLKCON_HCLK_SDMA1, + }, { + .name = "sdma0", + .parent = &clk_h, + .enable = s3c64xx_hclk_ctrl, + .ctrlbit = S3C_CLKCON_HCLK_SDMA0, + }, { + .name = "hclk_jpeg", + .parent = &clk_h, + .enable = s3c64xx_hclk_ctrl, + .ctrlbit = S3C_CLKCON_HCLK_JPEG, + }, { + .name = "camif", + .parent = &clk_h, + .enable = s3c64xx_hclk_ctrl, + .ctrlbit = S3C_CLKCON_HCLK_CAMIF, + }, { + .name = "hclk_scaler", + .parent = &clk_h, + .enable = s3c64xx_hclk_ctrl, + .ctrlbit = S3C_CLKCON_HCLK_SCALER, + }, { + .name = "2d", + .parent = &clk_h, + .enable = s3c64xx_hclk_ctrl, + .ctrlbit = S3C_CLKCON_HCLK_2D, + }, { + .name = "tv", + .parent = &clk_h, + .enable = s3c64xx_hclk_ctrl, + .ctrlbit = S3C_CLKCON_HCLK_TV, + }, { + .name = "post0", + .parent = &clk_h, + .enable = s3c64xx_hclk_ctrl, + .ctrlbit = S3C_CLKCON_HCLK_POST0, + }, { + .name = "rot", + .parent = &clk_h, + .enable = s3c64xx_hclk_ctrl, + .ctrlbit = S3C_CLKCON_HCLK_ROT, + }, { + .name = "hclk_mfc", + .parent = &clk_h, + .enable = s3c64xx_hclk_ctrl, + .ctrlbit = S3C_CLKCON_HCLK_MFC, + }, { + .name = "pclk_mfc", + .parent = &clk_p, + .enable = s3c64xx_pclk_ctrl, + .ctrlbit = S3C_CLKCON_PCLK_MFC, + }, { + .name = "dac27", + .enable = s3c64xx_sclk_ctrl, + .ctrlbit = S3C_CLKCON_SCLK_DAC27, + }, { + .name = "tv27", + .enable = s3c64xx_sclk_ctrl, + .ctrlbit = S3C_CLKCON_SCLK_TV27, + }, { + .name = "scaler27", + .enable = s3c64xx_sclk_ctrl, + .ctrlbit = S3C_CLKCON_SCLK_SCALER27, + }, { + .name = "sclk_scaler", + .enable = s3c64xx_sclk_ctrl, + .ctrlbit = S3C_CLKCON_SCLK_SCALER, + }, { + .name = "post0_27", + .enable = s3c64xx_sclk_ctrl, + .ctrlbit = S3C_CLKCON_SCLK_POST0_27, + }, { + .name = "secur", + .enable = s3c64xx_sclk_ctrl, + .ctrlbit = S3C_CLKCON_SCLK_SECUR, + }, { + .name = "sclk_mfc", + .enable = s3c64xx_sclk_ctrl, + .ctrlbit = S3C_CLKCON_SCLK_MFC, + }, { + .name = "cam", + .enable = s3c64xx_sclk_ctrl, + .ctrlbit = S3C_CLKCON_SCLK_CAM, + }, { + .name = "sclk_jpeg", + .enable = s3c64xx_sclk_ctrl, + .ctrlbit = S3C_CLKCON_SCLK_JPEG, }, }; @@ -289,16 +399,7 @@ static struct clk init_clocks[] = { .name = "watchdog", .parent = &clk_p, .ctrlbit = S3C_CLKCON_PCLK_WDT, - }, { - .name = "ac97", - .parent = &clk_p, - .ctrlbit = S3C_CLKCON_PCLK_AC97, - }, { - .name = "cfcon", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_IHOST, - } + }, }; static struct clk clk_hsmmc0 = { diff --git a/arch/arm/mach-s3c64xx/common.c b/arch/arm/mach-s3c64xx/common.c index bee7dcd4df7c..b313380342a5 100644 --- a/arch/arm/mach-s3c64xx/common.c +++ b/arch/arm/mach-s3c64xx/common.c @@ -29,6 +29,7 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/hardware/vic.h> +#include <asm/system_misc.h> #include <mach/map.h> #include <mach/hardware.h> diff --git a/arch/arm/mach-s3c64xx/common.h b/arch/arm/mach-s3c64xx/common.h index 5eb9c9a7d73b..7a10be629aba 100644 --- a/arch/arm/mach-s3c64xx/common.h +++ b/arch/arm/mach-s3c64xx/common.h @@ -25,8 +25,6 @@ void s3c64xx_setup_clocks(void); void s3c64xx_restart(char mode, const char *cmd); -extern struct syscore_ops s3c64xx_irq_syscore_ops; - #ifdef CONFIG_CPU_S3C6400 extern int s3c6400_init(void); diff --git a/arch/arm/mach-s3c64xx/cpuidle.c b/arch/arm/mach-s3c64xx/cpuidle.c new file mode 100644 index 000000000000..179460f38db7 --- /dev/null +++ b/arch/arm/mach-s3c64xx/cpuidle.c @@ -0,0 +1,91 @@ +/* linux/arch/arm/mach-s3c64xx/cpuidle.c + * + * Copyright (c) 2011 Wolfson Microelectronics, plc + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.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. +*/ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/cpuidle.h> +#include <linux/io.h> +#include <linux/export.h> +#include <linux/time.h> + +#include <asm/proc-fns.h> + +#include <mach/map.h> + +#include <mach/regs-sys.h> +#include <mach/regs-syscon-power.h> + +static int s3c64xx_enter_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + struct timeval before, after; + unsigned long tmp; + int idle_time; + + local_irq_disable(); + do_gettimeofday(&before); + + /* Setup PWRCFG to enter idle mode */ + tmp = __raw_readl(S3C64XX_PWR_CFG); + tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK; + tmp |= S3C64XX_PWRCFG_CFG_WFI_IDLE; + __raw_writel(tmp, S3C64XX_PWR_CFG); + + cpu_do_idle(); + + do_gettimeofday(&after); + local_irq_enable(); + idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + + (after.tv_usec - before.tv_usec); + + dev->last_residency = idle_time; + return index; +} + +static struct cpuidle_state s3c64xx_cpuidle_set[] = { + [0] = { + .enter = s3c64xx_enter_idle, + .exit_latency = 1, + .target_residency = 1, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "IDLE", + .desc = "System active, ARM gated", + }, +}; + +static struct cpuidle_driver s3c64xx_cpuidle_driver = { + .name = "s3c64xx_cpuidle", + .owner = THIS_MODULE, + .state_count = ARRAY_SIZE(s3c64xx_cpuidle_set), +}; + +static struct cpuidle_device s3c64xx_cpuidle_device = { + .state_count = ARRAY_SIZE(s3c64xx_cpuidle_set), +}; + +static int __init s3c64xx_init_cpuidle(void) +{ + int ret; + + memcpy(s3c64xx_cpuidle_driver.states, s3c64xx_cpuidle_set, + sizeof(s3c64xx_cpuidle_set)); + cpuidle_register_driver(&s3c64xx_cpuidle_driver); + + ret = cpuidle_register_device(&s3c64xx_cpuidle_device); + if (ret) { + pr_err("Failed to register cpuidle device: %d\n", ret); + return ret; + } + + return 0; +} +device_initcall(s3c64xx_init_cpuidle); diff --git a/arch/arm/mach-s3c64xx/include/mach/entry-macro.S b/arch/arm/mach-s3c64xx/include/mach/entry-macro.S deleted file mode 100644 index dc2bc15142ce..000000000000 --- a/arch/arm/mach-s3c64xx/include/mach/entry-macro.S +++ /dev/null @@ -1,19 +0,0 @@ -/* arch/arm/mach-s3c6400/include/mach/entry-macro.S - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks <ben@simtec.co.uk> - * - * Low-level IRQ helper macros for the Samsung S3C64XX series - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. -*/ - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-s3c64xx/include/mach/io.h b/arch/arm/mach-s3c64xx/include/mach/io.h deleted file mode 100644 index de5716dbbd65..000000000000 --- a/arch/arm/mach-s3c64xx/include/mach/io.h +++ /dev/null @@ -1,18 +0,0 @@ -/* arch/arm/mach-s3c64xxinclude/mach/io.h - * - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben-linux@fluff.org> - * - * Default IO routines for S3C64XX based - */ - -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -/* No current ISA/PCI bus support. */ -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#define IO_SPACE_LIMIT (0xFFFFFFFF) - -#endif diff --git a/arch/arm/mach-s3c64xx/include/mach/system.h b/arch/arm/mach-s3c64xx/include/mach/system.h deleted file mode 100644 index 353ed4389ae7..000000000000 --- a/arch/arm/mach-s3c64xx/include/mach/system.h +++ /dev/null @@ -1,19 +0,0 @@ -/* linux/arch/arm/mach-s3c6400/include/mach/system.h - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S3C6400 - system implementation - */ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H __FILE__ - -static void arch_idle(void) -{ - /* nothing here yet */ -} - -#endif /* __ASM_ARCH_IRQ_H */ diff --git a/arch/arm/mach-s3c64xx/irq-pm.c b/arch/arm/mach-s3c64xx/irq-pm.c index 8bec61e242c7..0c7e1d960ca4 100644 --- a/arch/arm/mach-s3c64xx/irq-pm.c +++ b/arch/arm/mach-s3c64xx/irq-pm.c @@ -96,7 +96,7 @@ static void s3c64xx_irq_pm_resume(void) S3C_PMDBG("%s: IRQ configuration restored\n", __func__); } -struct syscore_ops s3c64xx_irq_syscore_ops = { +static struct syscore_ops s3c64xx_irq_syscore_ops = { .suspend = s3c64xx_irq_pm_suspend, .resume = s3c64xx_irq_pm_resume, }; diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c index 32a30f38ba0c..0ace108c3e3d 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c @@ -11,18 +11,38 @@ #include <linux/export.h> #include <linux/interrupt.h> #include <linux/i2c.h> +#include <linux/spi/spi.h> #include <linux/mfd/wm831x/irq.h> #include <linux/mfd/wm831x/gpio.h> #include <linux/mfd/wm8994/pdata.h> +#include <linux/regulator/machine.h> + #include <sound/wm5100.h> #include <sound/wm8996.h> #include <sound/wm8962.h> #include <sound/wm9081.h> +#include <plat/s3c64xx-spi.h> + #include <mach/crag6410.h> +static struct s3c64xx_spi_csinfo wm0010_spi_csinfo = { + .set_level = gpio_set_value, + .line = S3C64XX_GPC(3), +}; + +static struct spi_board_info wm1253_devs[] = { + [0] = { + .modalias = "wm0010", + .bus_num = 0, + .chip_select = 0, + .mode = SPI_MODE_0, + .controller_data = &wm0010_spi_csinfo, + }, +}; + static struct wm5100_pdata wm5100_pdata = { .ldo_ena = S3C64XX_GPN(7), .irq_flags = IRQF_TRIGGER_HIGH, @@ -135,6 +155,14 @@ static const struct i2c_board_info wm1259_devs[] = { }, }; +static struct regulator_init_data wm8994_ldo1 = { + .supply_regulator = "WALLVDD", +}; + +static struct regulator_init_data wm8994_ldo2 = { + .supply_regulator = "WALLVDD", +}; + static struct wm8994_pdata wm8994_pdata = { .gpio_base = CODEC_GPIO_BASE, .gpio_defaults = { @@ -142,8 +170,8 @@ static struct wm8994_pdata wm8994_pdata = { }, .irq_base = CODEC_IRQ_BASE, .ldo = { - { .supply = "WALLVDD" }, - { .supply = "WALLVDD" }, + { .init_data = &wm8994_ldo1, }, + { .init_data = &wm8994_ldo2, }, }, }; @@ -159,14 +187,21 @@ static __devinitdata const struct { const char *name; const struct i2c_board_info *i2c_devs; int num_i2c_devs; + const struct spi_board_info *spi_devs; + int num_spi_devs; } gf_mods[] = { { .id = 0x01, .name = "1250-EV1 Springbank" }, { .id = 0x02, .name = "1251-EV1 Jura" }, { .id = 0x03, .name = "1252-EV1 Glenlivet" }, { .id = 0x11, .name = "6249-EV2 Glenfarclas", }, + { .id = 0x14, .name = "6271-EV1 Lochnagar" }, + { .id = 0x15, .name = "XXXX-EV1 Bells" }, { .id = 0x21, .name = "1275-EV1 Mortlach" }, { .id = 0x25, .name = "1274-EV1 Glencadam" }, - { .id = 0x31, .name = "1253-EV1 Tomatin", }, + { .id = 0x31, .name = "1253-EV1 Tomatin", + .spi_devs = wm1253_devs, .num_spi_devs = ARRAY_SIZE(wm1253_devs) }, + { .id = 0x32, .name = "XXXX-EV1 Caol Illa" }, + { .id = 0x33, .name = "XXXX-EV1 Oban" }, { .id = 0x39, .name = "1254-EV1 Dallas Dhu", .i2c_devs = wm1254_devs, .num_i2c_devs = ARRAY_SIZE(wm1254_devs) }, { .id = 0x3a, .name = "1259-EV1 Tobermory", @@ -198,12 +233,16 @@ static __devinit int wlf_gf_module_probe(struct i2c_client *i2c, if (i < ARRAY_SIZE(gf_mods)) { dev_info(&i2c->dev, "%s revision %d\n", gf_mods[i].name, rev + 1); + for (j = 0; j < gf_mods[i].num_i2c_devs; j++) { if (!i2c_new_device(i2c->adapter, &(gf_mods[i].i2c_devs[j]))) dev_err(&i2c->dev, "Failed to register dev: %d\n", ret); } + + spi_register_board_info(gf_mods[i].spi_devs, + gf_mods[i].num_spi_devs); } else { dev_warn(&i2c->dev, "Unknown module ID 0x%x revision %d\n", id, rev + 1); diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c index 8077f650eb0e..e20bf5835365 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410.c @@ -19,7 +19,9 @@ #include <linux/io.h> #include <linux/init.h> #include <linux/gpio.h> +#include <linux/leds.h> #include <linux/delay.h> +#include <linux/mmc/host.h> #include <linux/regulator/machine.h> #include <linux/regulator/fixed.h> #include <linux/pwm_backlight.h> @@ -59,6 +61,7 @@ #include <plat/sdhci.h> #include <plat/gpio-cfg.h> #include <plat/s3c64xx-spi.h> +#include <plat/udc-hs.h> #include <plat/keypad.h> #include <plat/clock.h> @@ -298,6 +301,7 @@ static struct platform_device littlemill_device = { }; static struct regulator_consumer_supply wallvdd_consumers[] = { + REGULATOR_SUPPLY("SPKVDD", "1-001a"), REGULATOR_SUPPLY("SPKVDD1", "1-001a"), REGULATOR_SUPPLY("SPKVDD2", "1-001a"), REGULATOR_SUPPLY("SPKVDDL", "1-001a"), @@ -574,11 +578,19 @@ static struct s3c2410_platform_i2c i2c0_pdata = { .frequency = 400000, }; +static struct regulator_consumer_supply pvdd_1v2_consumers[] __initdata = { + REGULATOR_SUPPLY("DCVDD", "spi0.0"), + REGULATOR_SUPPLY("AVDD", "spi0.0"), +}; + static struct regulator_init_data pvdd_1v2 __initdata = { .constraints = { .name = "PVDD_1V2", - .always_on = 1, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, }, + + .consumer_supplies = pvdd_1v2_consumers, + .num_consumer_supplies = ARRAY_SIZE(pvdd_1v2_consumers), }; static struct regulator_consumer_supply pvdd_1v8_consumers[] __initdata = { @@ -592,6 +604,7 @@ static struct regulator_consumer_supply pvdd_1v8_consumers[] __initdata = { REGULATOR_SUPPLY("AVDD2", "1-001a"), REGULATOR_SUPPLY("DCVDD", "1-001a"), REGULATOR_SUPPLY("AVDD", "1-001a"), + REGULATOR_SUPPLY("DBVDD", "spi0.0"), }; static struct regulator_init_data pvdd_1v8 __initdata = { @@ -681,6 +694,7 @@ static void __init crag6410_map_io(void) static struct s3c_sdhci_platdata crag6410_hsmmc2_pdata = { .max_width = 4, .cd_type = S3C_SDHCI_CD_PERMANENT, + .host_caps = MMC_CAP_POWER_OFF_CARD, }; static void crag6410_cfg_sdhci0(struct platform_device *dev, int width) @@ -696,8 +710,59 @@ static struct s3c_sdhci_platdata crag6410_hsmmc0_pdata = { .max_width = 4, .cd_type = S3C_SDHCI_CD_INTERNAL, .cfg_gpio = crag6410_cfg_sdhci0, + .host_caps = MMC_CAP_POWER_OFF_CARD, +}; + +static const struct gpio_led gpio_leds[] = { + { + .name = "d13:green:", + .gpio = MMGPIO_GPIO_BASE + 0, + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, + { + .name = "d14:green:", + .gpio = MMGPIO_GPIO_BASE + 1, + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, + { + .name = "d15:green:", + .gpio = MMGPIO_GPIO_BASE + 2, + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, + { + .name = "d16:green:", + .gpio = MMGPIO_GPIO_BASE + 3, + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, + { + .name = "d17:green:", + .gpio = MMGPIO_GPIO_BASE + 4, + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, + { + .name = "d18:green:", + .gpio = MMGPIO_GPIO_BASE + 5, + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, + { + .name = "d19:green:", + .gpio = MMGPIO_GPIO_BASE + 6, + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, + { + .name = "d20:green:", + .gpio = MMGPIO_GPIO_BASE + 7, + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, }; +static const struct gpio_led_platform_data gpio_leds_pdata = { + .leds = gpio_leds, + .num_leds = ARRAY_SIZE(gpio_leds), +}; + +static struct s3c_hsotg_plat crag6410_hsotg_pdata; + static void __init crag6410_machine_init(void) { /* Open drain IRQs need pullups */ @@ -722,14 +787,18 @@ static void __init crag6410_machine_init(void) s3c_i2c0_set_platdata(&i2c0_pdata); s3c_i2c1_set_platdata(&i2c1_pdata); s3c_fb_set_platdata(&crag6410_lcd_pdata); + s3c_hsotg_set_platdata(&crag6410_hsotg_pdata); i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0)); i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1)); samsung_keypad_set_platdata(&crag6410_keypad_data); + s3c64xx_spi0_set_platdata(&s3c64xx_spi0_pdata, 0, 1); platform_add_devices(crag6410_devices, ARRAY_SIZE(crag6410_devices)); + gpio_led_register_device(-1, &gpio_leds_pdata); + regulator_has_full_constraints(); s3c64xx_pm_init(); diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c index ce31db136231..ce745e19aa27 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq.c +++ b/arch/arm/mach-s3c64xx/mach-smartq.c @@ -187,6 +187,8 @@ static struct s3c_hwmon_pdata smartq_hwmon_pdata __initdata = { }, }; +static struct s3c_hsotg_plat smartq_hsotg_pdata; + static int __init smartq_lcd_setup_gpio(void) { int ret; @@ -383,6 +385,7 @@ void __init smartq_map_io(void) void __init smartq_machine_init(void) { s3c_i2c0_set_platdata(NULL); + s3c_hsotg_set_platdata(&smartq_hsotg_pdata); s3c_hwmon_set_platdata(&smartq_hwmon_pdata); s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata); s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata); diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c index ca6fc204f0ea..d55bc96d9582 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6410.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c @@ -72,6 +72,7 @@ #include <plat/keypad.h> #include <plat/backlight.h> #include <plat/regs-fb-v4.h> +#include <plat/udc-hs.h> #include "common.h" @@ -631,6 +632,8 @@ static struct platform_pwm_backlight_data smdk6410_bl_data = { .pwm_id = 1, }; +static struct s3c_hsotg_plat smdk6410_hsotg_pdata; + static void __init smdk6410_map_io(void) { u32 tmp; @@ -659,6 +662,7 @@ static void __init smdk6410_machine_init(void) s3c_i2c0_set_platdata(NULL); s3c_i2c1_set_platdata(NULL); s3c_fb_set_platdata(&smdk6410_lcd_pdata); + s3c_hsotg_set_platdata(&smdk6410_hsotg_pdata); samsung_keypad_set_platdata(&smdk6410_keypad_data); diff --git a/arch/arm/mach-s3c64xx/setup-usb-phy.c b/arch/arm/mach-s3c64xx/setup-usb-phy.c new file mode 100644 index 000000000000..f6757e02d7db --- /dev/null +++ b/arch/arm/mach-s3c64xx/setup-usb-phy.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2011 Samsung Electronics Co.Ltd + * Author: Joonyoung Shim <jy0922.shim@samsung.com> + * + * 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. + * + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/platform_device.h> +#include <mach/map.h> +#include <mach/regs-sys.h> +#include <plat/cpu.h> +#include <plat/regs-usb-hsotg-phy.h> +#include <plat/usb-phy.h> + +static int s3c_usb_otgphy_init(struct platform_device *pdev) +{ + struct clk *xusbxti; + u32 phyclk; + + writel(readl(S3C64XX_OTHERS) | S3C64XX_OTHERS_USBMASK, S3C64XX_OTHERS); + + /* set clock frequency for PLL */ + phyclk = readl(S3C_PHYCLK) & ~S3C_PHYCLK_CLKSEL_MASK; + + xusbxti = clk_get(&pdev->dev, "xusbxti"); + if (xusbxti && !IS_ERR(xusbxti)) { + switch (clk_get_rate(xusbxti)) { + case 12 * MHZ: + phyclk |= S3C_PHYCLK_CLKSEL_12M; + break; + case 24 * MHZ: + phyclk |= S3C_PHYCLK_CLKSEL_24M; + break; + default: + case 48 * MHZ: + /* default reference clock */ + break; + } + clk_put(xusbxti); + } + + /* TODO: select external clock/oscillator */ + writel(phyclk | S3C_PHYCLK_CLK_FORCE, S3C_PHYCLK); + + /* set to normal OTG PHY */ + writel((readl(S3C_PHYPWR) & ~S3C_PHYPWR_NORMAL_MASK), S3C_PHYPWR); + mdelay(1); + + /* reset OTG PHY and Link */ + writel(S3C_RSTCON_PHY | S3C_RSTCON_HCLK | S3C_RSTCON_PHYCLK, + S3C_RSTCON); + udelay(20); /* at-least 10uS */ + writel(0, S3C_RSTCON); + + return 0; +} + +static int s3c_usb_otgphy_exit(struct platform_device *pdev) +{ + writel((readl(S3C_PHYPWR) | S3C_PHYPWR_ANALOG_POWERDOWN | + S3C_PHYPWR_OTG_DISABLE), S3C_PHYPWR); + + writel(readl(S3C64XX_OTHERS) & ~S3C64XX_OTHERS_USBMASK, S3C64XX_OTHERS); + + return 0; +} + +int s5p_usb_phy_init(struct platform_device *pdev, int type) +{ + if (type == S5P_USB_PHY_DEVICE) + return s3c_usb_otgphy_init(pdev); + + return -EINVAL; +} + +int s5p_usb_phy_exit(struct platform_device *pdev, int type) +{ + if (type == S5P_USB_PHY_DEVICE) + return s3c_usb_otgphy_exit(pdev); + + return -EINVAL; +} diff --git a/arch/arm/mach-s5p64x0/clock.c b/arch/arm/mach-s5p64x0/clock.c index 241d0e645c85..57e718957ef3 100644 --- a/arch/arm/mach-s5p64x0/clock.c +++ b/arch/arm/mach-s5p64x0/clock.c @@ -73,7 +73,7 @@ static const u32 clock_table[][3] = { {L2 * 1000, (3 << ARM_DIV_RATIO_SHIFT), (0 << S5P64X0_CLKDIV0_HCLK_SHIFT)}, }; -unsigned long s5p64x0_armclk_get_rate(struct clk *clk) +static unsigned long s5p64x0_armclk_get_rate(struct clk *clk) { unsigned long rate = clk_get_rate(clk->parent); u32 clkdiv; @@ -84,7 +84,8 @@ unsigned long s5p64x0_armclk_get_rate(struct clk *clk) return rate / (clkdiv + 1); } -unsigned long s5p64x0_armclk_round_rate(struct clk *clk, unsigned long rate) +static unsigned long s5p64x0_armclk_round_rate(struct clk *clk, + unsigned long rate) { u32 iter; @@ -96,7 +97,7 @@ unsigned long s5p64x0_armclk_round_rate(struct clk *clk, unsigned long rate) return clock_table[ARRAY_SIZE(clock_table) - 1][0]; } -int s5p64x0_armclk_set_rate(struct clk *clk, unsigned long rate) +static int s5p64x0_armclk_set_rate(struct clk *clk, unsigned long rate) { u32 round_tmp; u32 iter; @@ -148,7 +149,7 @@ int s5p64x0_armclk_set_rate(struct clk *clk, unsigned long rate) return 0; } -struct clk_ops s5p64x0_clkarm_ops = { +static struct clk_ops s5p64x0_clkarm_ops = { .get_rate = s5p64x0_armclk_get_rate, .set_rate = s5p64x0_armclk_set_rate, .round_rate = s5p64x0_armclk_round_rate, @@ -173,7 +174,7 @@ struct clksrc_clk clk_dout_mpll = { .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 4, .size = 1 }, }; -struct clk *clkset_hclk_low_list[] = { +static struct clk *clkset_hclk_low_list[] = { &clk_mout_apll.clk, &clk_mout_mpll.clk, }; diff --git a/arch/arm/mach-s5p64x0/common.c b/arch/arm/mach-s5p64x0/common.c index 52b89a376447..6e6a0a9d6778 100644 --- a/arch/arm/mach-s5p64x0/common.c +++ b/arch/arm/mach-s5p64x0/common.c @@ -27,6 +27,7 @@ #include <asm/irq.h> #include <asm/proc-fns.h> +#include <asm/system_misc.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/irq.h> @@ -146,15 +147,12 @@ static void s5p64x0_idle(void) { unsigned long val; - if (!need_resched()) { - val = __raw_readl(S5P64X0_PWR_CFG); - val &= ~(0x3 << 5); - val |= (0x1 << 5); - __raw_writel(val, S5P64X0_PWR_CFG); + val = __raw_readl(S5P64X0_PWR_CFG); + val &= ~(0x3 << 5); + val |= (0x1 << 5); + __raw_writel(val, S5P64X0_PWR_CFG); - cpu_do_idle(); - } - local_irq_enable(); + cpu_do_idle(); } /* @@ -286,7 +284,7 @@ int __init s5p64x0_init(void) printk(KERN_INFO "S5P64X0(S5P6440/S5P6450): Initializing architecture\n"); /* set idle function */ - pm_idle = s5p64x0_idle; + arm_pm_idle = s5p64x0_idle; return device_register(&s5p64x0_dev); } diff --git a/arch/arm/mach-s5p64x0/dma.c b/arch/arm/mach-s5p64x0/dma.c index f820c0744405..2ee5dc069b37 100644 --- a/arch/arm/mach-s5p64x0/dma.c +++ b/arch/arm/mach-s5p64x0/dma.c @@ -38,7 +38,7 @@ static u64 dma_dmamask = DMA_BIT_MASK(32); -u8 s5p6440_pdma_peri[] = { +static u8 s5p6440_pdma_peri[] = { DMACH_UART0_RX, DMACH_UART0_TX, DMACH_UART1_RX, @@ -63,12 +63,12 @@ u8 s5p6440_pdma_peri[] = { DMACH_SPI1_RX, }; -struct dma_pl330_platdata s5p6440_pdma_pdata = { +static struct dma_pl330_platdata s5p6440_pdma_pdata = { .nr_valid_peri = ARRAY_SIZE(s5p6440_pdma_peri), .peri_id = s5p6440_pdma_peri, }; -u8 s5p6450_pdma_peri[] = { +static u8 s5p6450_pdma_peri[] = { DMACH_UART0_RX, DMACH_UART0_TX, DMACH_UART1_RX, @@ -103,39 +103,27 @@ u8 s5p6450_pdma_peri[] = { DMACH_UART5_TX, }; -struct dma_pl330_platdata s5p6450_pdma_pdata = { +static struct dma_pl330_platdata s5p6450_pdma_pdata = { .nr_valid_peri = ARRAY_SIZE(s5p6450_pdma_peri), .peri_id = s5p6450_pdma_peri, }; -struct amba_device s5p64x0_device_pdma = { - .dev = { - .init_name = "dma-pl330", - .dma_mask = &dma_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .res = { - .start = S5P64X0_PA_PDMA, - .end = S5P64X0_PA_PDMA + SZ_4K, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_DMA0, NO_IRQ}, - .periphid = 0x00041330, -}; +static AMBA_AHB_DEVICE(s5p64x0_pdma, "dma-pl330", 0x00041330, + S5P64X0_PA_PDMA, {IRQ_DMA0}, NULL); static int __init s5p64x0_dma_init(void) { if (soc_is_s5p6450()) { dma_cap_set(DMA_SLAVE, s5p6450_pdma_pdata.cap_mask); dma_cap_set(DMA_CYCLIC, s5p6450_pdma_pdata.cap_mask); - s5p64x0_device_pdma.dev.platform_data = &s5p6450_pdma_pdata; + s5p64x0_pdma_device.dev.platform_data = &s5p6450_pdma_pdata; } else { dma_cap_set(DMA_SLAVE, s5p6440_pdma_pdata.cap_mask); dma_cap_set(DMA_CYCLIC, s5p6440_pdma_pdata.cap_mask); - s5p64x0_device_pdma.dev.platform_data = &s5p6440_pdma_pdata; + s5p64x0_pdma_device.dev.platform_data = &s5p6440_pdma_pdata; } - amba_device_register(&s5p64x0_device_pdma, &iomem_resource); + amba_device_register(&s5p64x0_pdma_device, &iomem_resource); return 0; } diff --git a/arch/arm/mach-s5p64x0/include/mach/entry-macro.S b/arch/arm/mach-s5p64x0/include/mach/entry-macro.S deleted file mode 100644 index fbb246d0a3df..000000000000 --- a/arch/arm/mach-s5p64x0/include/mach/entry-macro.S +++ /dev/null @@ -1,17 +0,0 @@ -/* linux/arch/arm/mach-s5p64x0/include/mach/entry-macro.S - * - * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Low-level IRQ helper macros for the Samsung S5P64X0 - * - * 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. -*/ - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-s5p64x0/include/mach/io.h b/arch/arm/mach-s5p64x0/include/mach/io.h deleted file mode 100644 index a3e095c02fb5..000000000000 --- a/arch/arm/mach-s5p64x0/include/mach/io.h +++ /dev/null @@ -1,25 +0,0 @@ -/* linux/arch/arm/mach-s5p64x0/include/mach/io.h - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben-linux@fluff.org> - * - * Default IO routines for S5P64X0 based - * - * 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. -*/ - -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -/* No current ISA/PCI bus support. */ -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#define IO_SPACE_LIMIT (0xFFFFFFFF) - -#endif diff --git a/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h b/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h index ff85b4b6e8d9..0ef47d1b7670 100644 --- a/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h +++ b/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h @@ -22,16 +22,9 @@ extern struct clksrc_clk clk_mout_epll; extern int s5p64x0_epll_enable(struct clk *clk, int enable); extern unsigned long s5p64x0_epll_get_rate(struct clk *clk); -extern unsigned long s5p64x0_armclk_get_rate(struct clk *clk); -extern unsigned long s5p64x0_armclk_round_rate(struct clk *clk, unsigned long rate); -extern int s5p64x0_armclk_set_rate(struct clk *clk, unsigned long rate); - -extern struct clk_ops s5p64x0_clkarm_ops; - extern struct clksrc_clk clk_armclk; extern struct clksrc_clk clk_dout_mpll; -extern struct clk *clkset_hclk_low_list[]; extern struct clksrc_sources clkset_hclk_low; extern int s5p64x0_pclk_ctrl(struct clk *clk, int enable); diff --git a/arch/arm/mach-s5p64x0/include/mach/system.h b/arch/arm/mach-s5p64x0/include/mach/system.h deleted file mode 100644 index cf26e0954a2f..000000000000 --- a/arch/arm/mach-s5p64x0/include/mach/system.h +++ /dev/null @@ -1,21 +0,0 @@ -/* linux/arch/arm/mach-s5p64x0/include/mach/system.h - * - * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * S5P64X0 - system support header - * - * 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. -*/ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H __FILE__ - -static void arch_idle(void) -{ - /* nothing here yet */ -} - -#endif /* __ASM_ARCH_SYSTEM_H */ diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c index 247194dd366c..16eca4ea2010 100644 --- a/arch/arm/mach-s5pc100/clock.c +++ b/arch/arm/mach-s5pc100/clock.c @@ -170,7 +170,7 @@ static struct clk *clk_src_mout_am_list[] = { [1] = &clk_div_apll2.clk, }; -struct clksrc_sources clk_src_mout_am = { +static struct clksrc_sources clk_src_mout_am = { .sources = clk_src_mout_am_list, .nr_sources = ARRAY_SIZE(clk_src_mout_am_list), }; @@ -212,7 +212,7 @@ static struct clk *clk_src_mout_onenand_list[] = { [1] = &clk_div_d1_bus.clk, }; -struct clksrc_sources clk_src_mout_onenand = { +static struct clksrc_sources clk_src_mout_onenand = { .sources = clk_src_mout_onenand_list, .nr_sources = ARRAY_SIZE(clk_src_mout_onenand_list), }; @@ -756,7 +756,7 @@ static struct clk *clk_src_group1_list[] = { [3] = &clk_mout_hpll.clk, }; -struct clksrc_sources clk_src_group1 = { +static struct clksrc_sources clk_src_group1 = { .sources = clk_src_group1_list, .nr_sources = ARRAY_SIZE(clk_src_group1_list), }; @@ -766,7 +766,7 @@ static struct clk *clk_src_group2_list[] = { [1] = &clk_div_mpll.clk, }; -struct clksrc_sources clk_src_group2 = { +static struct clksrc_sources clk_src_group2 = { .sources = clk_src_group2_list, .nr_sources = ARRAY_SIZE(clk_src_group2_list), }; @@ -780,7 +780,7 @@ static struct clk *clk_src_group3_list[] = { [5] = &clk_mout_hpll.clk, }; -struct clksrc_sources clk_src_group3 = { +static struct clksrc_sources clk_src_group3 = { .sources = clk_src_group3_list, .nr_sources = ARRAY_SIZE(clk_src_group3_list), }; @@ -806,7 +806,7 @@ static struct clk *clk_src_group4_list[] = { [5] = &clk_mout_hpll.clk, }; -struct clksrc_sources clk_src_group4 = { +static struct clksrc_sources clk_src_group4 = { .sources = clk_src_group4_list, .nr_sources = ARRAY_SIZE(clk_src_group4_list), }; @@ -831,7 +831,7 @@ static struct clk *clk_src_group5_list[] = { [4] = &clk_mout_hpll.clk, }; -struct clksrc_sources clk_src_group5 = { +static struct clksrc_sources clk_src_group5 = { .sources = clk_src_group5_list, .nr_sources = ARRAY_SIZE(clk_src_group5_list), }; @@ -854,7 +854,7 @@ static struct clk *clk_src_group6_list[] = { [2] = &clk_div_hdmi.clk, }; -struct clksrc_sources clk_src_group6 = { +static struct clksrc_sources clk_src_group6 = { .sources = clk_src_group6_list, .nr_sources = ARRAY_SIZE(clk_src_group6_list), }; @@ -866,7 +866,7 @@ static struct clk *clk_src_group7_list[] = { [3] = &clk_vclk54m, }; -struct clksrc_sources clk_src_group7 = { +static struct clksrc_sources clk_src_group7 = { .sources = clk_src_group7_list, .nr_sources = ARRAY_SIZE(clk_src_group7_list), }; @@ -877,7 +877,7 @@ static struct clk *clk_src_mmc0_list[] = { [2] = &clk_fin_epll, }; -struct clksrc_sources clk_src_mmc0 = { +static struct clksrc_sources clk_src_mmc0 = { .sources = clk_src_mmc0_list, .nr_sources = ARRAY_SIZE(clk_src_mmc0_list), }; @@ -889,7 +889,7 @@ static struct clk *clk_src_mmc12_list[] = { [3] = &clk_mout_hpll.clk, }; -struct clksrc_sources clk_src_mmc12 = { +static struct clksrc_sources clk_src_mmc12 = { .sources = clk_src_mmc12_list, .nr_sources = ARRAY_SIZE(clk_src_mmc12_list), }; @@ -901,7 +901,7 @@ static struct clk *clk_src_irda_usb_list[] = { [3] = &clk_mout_hpll.clk, }; -struct clksrc_sources clk_src_irda_usb = { +static struct clksrc_sources clk_src_irda_usb = { .sources = clk_src_irda_usb_list, .nr_sources = ARRAY_SIZE(clk_src_irda_usb_list), }; @@ -912,7 +912,7 @@ static struct clk *clk_src_pwi_list[] = { [2] = &clk_div_mpll.clk, }; -struct clksrc_sources clk_src_pwi = { +static struct clksrc_sources clk_src_pwi = { .sources = clk_src_pwi_list, .nr_sources = ARRAY_SIZE(clk_src_pwi_list), }; @@ -923,7 +923,7 @@ static struct clk *clk_sclk_spdif_list[] = { [2] = &clk_sclk_audio2.clk, }; -struct clksrc_sources clk_src_sclk_spdif = { +static struct clksrc_sources clk_src_sclk_spdif = { .sources = clk_sclk_spdif_list, .nr_sources = ARRAY_SIZE(clk_sclk_spdif_list), }; diff --git a/arch/arm/mach-s5pc100/common.c b/arch/arm/mach-s5pc100/common.c index c9095730a7f5..621908658861 100644 --- a/arch/arm/mach-s5pc100/common.c +++ b/arch/arm/mach-s5pc100/common.c @@ -27,6 +27,7 @@ #include <asm/irq.h> #include <asm/proc-fns.h> +#include <asm/system_misc.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/irq.h> @@ -129,14 +130,6 @@ static struct map_desc s5pc100_iodesc[] __initdata = { } }; -static void s5pc100_idle(void) -{ - if (!need_resched()) - cpu_do_idle(); - - local_irq_enable(); -} - /* * s5pc100_map_io * @@ -210,10 +203,6 @@ core_initcall(s5pc100_core_init); int __init s5pc100_init(void) { printk(KERN_INFO "S5PC100: Initializing architecture\n"); - - /* set idle function */ - pm_idle = s5pc100_idle; - return device_register(&s5pc100_dev); } diff --git a/arch/arm/mach-s5pc100/dma.c b/arch/arm/mach-s5pc100/dma.c index c841f4d313f2..afd8db2d5991 100644 --- a/arch/arm/mach-s5pc100/dma.c +++ b/arch/arm/mach-s5pc100/dma.c @@ -35,7 +35,7 @@ static u64 dma_dmamask = DMA_BIT_MASK(32); -u8 pdma0_peri[] = { +static u8 pdma0_peri[] = { DMACH_UART0_RX, DMACH_UART0_TX, DMACH_UART1_RX, @@ -68,28 +68,15 @@ u8 pdma0_peri[] = { DMACH_HSI_TX, }; -struct dma_pl330_platdata s5pc100_pdma0_pdata = { +static struct dma_pl330_platdata s5pc100_pdma0_pdata = { .nr_valid_peri = ARRAY_SIZE(pdma0_peri), .peri_id = pdma0_peri, }; -struct amba_device s5pc100_device_pdma0 = { - .dev = { - .init_name = "dma-pl330.0", - .dma_mask = &dma_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &s5pc100_pdma0_pdata, - }, - .res = { - .start = S5PC100_PA_PDMA0, - .end = S5PC100_PA_PDMA0 + SZ_4K, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_PDMA0, NO_IRQ}, - .periphid = 0x00041330, -}; +static AMBA_AHB_DEVICE(s5pc100_pdma0, "dma-pl330.0", 0x00041330, + S5PC100_PA_PDMA0, {IRQ_PDMA0}, &s5pc100_pdma0_pdata); -u8 pdma1_peri[] = { +static u8 pdma1_peri[] = { DMACH_UART0_RX, DMACH_UART0_TX, DMACH_UART1_RX, @@ -122,36 +109,23 @@ u8 pdma1_peri[] = { DMACH_MSM_REQ3, }; -struct dma_pl330_platdata s5pc100_pdma1_pdata = { +static struct dma_pl330_platdata s5pc100_pdma1_pdata = { .nr_valid_peri = ARRAY_SIZE(pdma1_peri), .peri_id = pdma1_peri, }; -struct amba_device s5pc100_device_pdma1 = { - .dev = { - .init_name = "dma-pl330.1", - .dma_mask = &dma_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &s5pc100_pdma1_pdata, - }, - .res = { - .start = S5PC100_PA_PDMA1, - .end = S5PC100_PA_PDMA1 + SZ_4K, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_PDMA1, NO_IRQ}, - .periphid = 0x00041330, -}; +static AMBA_AHB_DEVICE(s5pc100_pdma1, "dma-pl330.1", 0x00041330, + S5PC100_PA_PDMA1, {IRQ_PDMA1}, &s5pc100_pdma1_pdata); static int __init s5pc100_dma_init(void) { dma_cap_set(DMA_SLAVE, s5pc100_pdma0_pdata.cap_mask); dma_cap_set(DMA_CYCLIC, s5pc100_pdma0_pdata.cap_mask); - amba_device_register(&s5pc100_device_pdma0, &iomem_resource); + amba_device_register(&s5pc100_pdma0_device, &iomem_resource); dma_cap_set(DMA_SLAVE, s5pc100_pdma1_pdata.cap_mask); dma_cap_set(DMA_CYCLIC, s5pc100_pdma1_pdata.cap_mask); - amba_device_register(&s5pc100_device_pdma1, &iomem_resource); + amba_device_register(&s5pc100_pdma1_device, &iomem_resource); return 0; } diff --git a/arch/arm/mach-s5pc100/include/mach/entry-macro.S b/arch/arm/mach-s5pc100/include/mach/entry-macro.S index b8c242edfa22..bad0700457db 100644 --- a/arch/arm/mach-s5pc100/include/mach/entry-macro.S +++ b/arch/arm/mach-s5pc100/include/mach/entry-macro.S @@ -12,14 +12,8 @@ * warranty of any kind, whether express or implied. */ - .macro disable_fiq - .endm - .macro get_irqnr_preamble, base, tmp .endm - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp .endm diff --git a/arch/arm/mach-s5pc100/include/mach/io.h b/arch/arm/mach-s5pc100/include/mach/io.h deleted file mode 100644 index 819acf5eaf89..000000000000 --- a/arch/arm/mach-s5pc100/include/mach/io.h +++ /dev/null @@ -1,18 +0,0 @@ -/* arch/arm/mach-s5pc100/include/mach/io.h - * - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben-linux@fluff.org> - * - * Default IO routines for S5PC100 systems - */ - -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -/* No current ISA/PCI bus support. */ -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#define IO_SPACE_LIMIT (0xFFFFFFFF) - -#endif diff --git a/arch/arm/mach-s5pc100/include/mach/system.h b/arch/arm/mach-s5pc100/include/mach/system.h deleted file mode 100644 index afc96c298518..000000000000 --- a/arch/arm/mach-s5pc100/include/mach/system.h +++ /dev/null @@ -1,19 +0,0 @@ -/* linux/arch/arm/mach-s5pc100/include/mach/system.h - * - * Copyright 2009 Samsung Electronics Co. - * Byungho Min <bhmin@samsung.com> - * - * S5PC100 - system implementation - * - * Based on mach-s3c6400/include/mach/system.h - */ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H __FILE__ - -static void arch_idle(void) -{ - /* nothing here yet */ -} - -#endif /* __ASM_ARCH_IRQ_H */ diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig index 2cdc42e838b8..29594fc4fdf4 100644 --- a/arch/arm/mach-s5pv210/Kconfig +++ b/arch/arm/mach-s5pv210/Kconfig @@ -65,6 +65,11 @@ config S5PV210_SETUP_SPI help Common setup code for SPI GPIO configurations. +config S5PV210_SETUP_USB_PHY + bool + help + Common setup code for USB PHY controller + menu "S5PC110 Machines" config MACH_AQUILA @@ -107,6 +112,7 @@ config MACH_GONI select S5PV210_SETUP_KEYPAD select S5PV210_SETUP_SDHCI select S5PV210_SETUP_FIMC + select S5PV210_SETUP_USB_PHY help Machine support for Samsung GONI board S5PC110(MCP) is one of package option of S5PV210 @@ -118,6 +124,10 @@ config MACH_SMDKC110 select S3C_DEV_I2C2 select S3C_DEV_RTC select S3C_DEV_WDT + select S5P_DEV_FIMC0 + select S5P_DEV_FIMC1 + select S5P_DEV_FIMC2 + select S5P_DEV_MFC select SAMSUNG_DEV_IDE select S5PV210_SETUP_I2C1 select S5PV210_SETUP_I2C2 @@ -142,6 +152,11 @@ config MACH_SMDKV210 select S3C_DEV_I2C2 select S3C_DEV_RTC select S3C_DEV_WDT + select S5P_DEV_FIMC0 + select S5P_DEV_FIMC1 + select S5P_DEV_FIMC2 + select S5P_DEV_JPEG + select S5P_DEV_MFC select SAMSUNG_DEV_ADC select SAMSUNG_DEV_BACKLIGHT select SAMSUNG_DEV_IDE diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile index 76a121dd52b4..1c4e41998a10 100644 --- a/arch/arm/mach-s5pv210/Makefile +++ b/arch/arm/mach-s5pv210/Makefile @@ -39,3 +39,4 @@ obj-$(CONFIG_S5PV210_SETUP_IDE) += setup-ide.o obj-$(CONFIG_S5PV210_SETUP_KEYPAD) += setup-keypad.o obj-$(CONFIG_S5PV210_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o obj-$(CONFIG_S5PV210_SETUP_SPI) += setup-spi.o +obj-$(CONFIG_S5PV210_SETUP_USB_PHY) += setup-usb-phy.o diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index b9ec0c35379f..09609d50961d 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -340,6 +340,11 @@ static struct clk init_clocks_off[] = { .enable = s5pv210_clk_ip0_ctrl, .ctrlbit = (1 << 26), }, { + .name = "jpeg", + .parent = &clk_hclk_dsys.clk, + .enable = s5pv210_clk_ip0_ctrl, + .ctrlbit = (1 << 28), + }, { .name = "mfc", .devname = "s5p-mfc", .parent = &clk_pclk_psys.clk, diff --git a/arch/arm/mach-s5pv210/common.c b/arch/arm/mach-s5pv210/common.c index 9c1bcdcc12c3..4c9e9027df9a 100644 --- a/arch/arm/mach-s5pv210/common.c +++ b/arch/arm/mach-s5pv210/common.c @@ -142,14 +142,6 @@ static struct map_desc s5pv210_iodesc[] __initdata = { } }; -static void s5pv210_idle(void) -{ - if (!need_resched()) - cpu_do_idle(); - - local_irq_enable(); -} - void s5pv210_restart(char mode, const char *cmd) { __raw_writel(0x1, S5P_SWRESET); @@ -247,10 +239,6 @@ core_initcall(s5pv210_core_init); int __init s5pv210_init(void) { printk(KERN_INFO "S5PV210: Initializing architecture\n"); - - /* set idle function */ - pm_idle = s5pv210_idle; - return device_register(&s5pv210_dev); } diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c index a6113e0267f2..b8337e248b09 100644 --- a/arch/arm/mach-s5pv210/dma.c +++ b/arch/arm/mach-s5pv210/dma.c @@ -33,9 +33,7 @@ #include <mach/irqs.h> #include <mach/dma.h> -static u64 dma_dmamask = DMA_BIT_MASK(32); - -u8 pdma0_peri[] = { +static u8 pdma0_peri[] = { DMACH_UART0_RX, DMACH_UART0_TX, DMACH_UART1_RX, @@ -66,28 +64,15 @@ u8 pdma0_peri[] = { DMACH_SPDIF, }; -struct dma_pl330_platdata s5pv210_pdma0_pdata = { +static struct dma_pl330_platdata s5pv210_pdma0_pdata = { .nr_valid_peri = ARRAY_SIZE(pdma0_peri), .peri_id = pdma0_peri, }; -struct amba_device s5pv210_device_pdma0 = { - .dev = { - .init_name = "dma-pl330.0", - .dma_mask = &dma_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &s5pv210_pdma0_pdata, - }, - .res = { - .start = S5PV210_PA_PDMA0, - .end = S5PV210_PA_PDMA0 + SZ_4K, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_PDMA0, NO_IRQ}, - .periphid = 0x00041330, -}; +static AMBA_AHB_DEVICE(s5pv210_pdma0, "dma-pl330.0", 0x00041330, + S5PV210_PA_PDMA0, {IRQ_PDMA0}, &s5pv210_pdma0_pdata); -u8 pdma1_peri[] = { +static u8 pdma1_peri[] = { DMACH_UART0_RX, DMACH_UART0_TX, DMACH_UART1_RX, @@ -122,36 +107,23 @@ u8 pdma1_peri[] = { DMACH_PCM2_TX, }; -struct dma_pl330_platdata s5pv210_pdma1_pdata = { +static struct dma_pl330_platdata s5pv210_pdma1_pdata = { .nr_valid_peri = ARRAY_SIZE(pdma1_peri), .peri_id = pdma1_peri, }; -struct amba_device s5pv210_device_pdma1 = { - .dev = { - .init_name = "dma-pl330.1", - .dma_mask = &dma_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &s5pv210_pdma1_pdata, - }, - .res = { - .start = S5PV210_PA_PDMA1, - .end = S5PV210_PA_PDMA1 + SZ_4K, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_PDMA1, NO_IRQ}, - .periphid = 0x00041330, -}; +static AMBA_AHB_DEVICE(s5pv210_pdma1, "dma-pl330.1", 0x00041330, + S5PV210_PA_PDMA1, {IRQ_PDMA1}, &s5pv210_pdma1_pdata); static int __init s5pv210_dma_init(void) { dma_cap_set(DMA_SLAVE, s5pv210_pdma0_pdata.cap_mask); dma_cap_set(DMA_CYCLIC, s5pv210_pdma0_pdata.cap_mask); - amba_device_register(&s5pv210_device_pdma0, &iomem_resource); + amba_device_register(&s5pv210_pdma0_device, &iomem_resource); dma_cap_set(DMA_SLAVE, s5pv210_pdma1_pdata.cap_mask); dma_cap_set(DMA_CYCLIC, s5pv210_pdma1_pdata.cap_mask); - amba_device_register(&s5pv210_device_pdma1, &iomem_resource); + amba_device_register(&s5pv210_pdma1_device, &iomem_resource); return 0; } diff --git a/arch/arm/mach-s5pv210/include/mach/entry-macro.S b/arch/arm/mach-s5pv210/include/mach/entry-macro.S deleted file mode 100644 index bebca1b5d0b1..000000000000 --- a/arch/arm/mach-s5pv210/include/mach/entry-macro.S +++ /dev/null @@ -1,17 +0,0 @@ -/* linux/arch/arm/mach-s5pv210/include/mach/entry-macro.S - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Low-level IRQ helper macros for the Samsung S5PV210 - * - * 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. -*/ - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-s5pv210/include/mach/io.h b/arch/arm/mach-s5pv210/include/mach/io.h deleted file mode 100644 index 5ab9d560bc86..000000000000 --- a/arch/arm/mach-s5pv210/include/mach/io.h +++ /dev/null @@ -1,26 +0,0 @@ -/* linux/arch/arm/mach-s5pv210/include/mach/io.h - * - * Copyright 2008-2010 Ben Dooks <ben-linux@fluff.org> - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Based on arch/arm/mach-s5p6442/include/mach/io.h - * - * Default IO routines for S5PV210 - * - * 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. -*/ - -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H __FILE__ - -/* No current ISA/PCI bus support. */ -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#define IO_SPACE_LIMIT (0xFFFFFFFF) - -#endif /* __ASM_ARM_ARCH_IO_H */ diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h index 89c34b8f73bf..b7c8a1917ffc 100644 --- a/arch/arm/mach-s5pv210/include/mach/map.h +++ b/arch/arm/mach-s5pv210/include/mach/map.h @@ -90,6 +90,8 @@ #define S5PV210_PA_FIMC1 0xFB300000 #define S5PV210_PA_FIMC2 0xFB400000 +#define S5PV210_PA_JPEG 0xFB600000 + #define S5PV210_PA_SDO 0xF9000000 #define S5PV210_PA_VP 0xF9100000 #define S5PV210_PA_MIXER 0xF9200000 @@ -132,6 +134,8 @@ #define S5P_PA_SYSCON S5PV210_PA_SYSCON #define S5P_PA_TIMER S5PV210_PA_TIMER +#define S5P_PA_JPEG S5PV210_PA_JPEG + #define SAMSUNG_PA_ADC S5PV210_PA_ADC #define SAMSUNG_PA_CFCON S5PV210_PA_CFCON #define SAMSUNG_PA_KEYPAD S5PV210_PA_KEYPAD diff --git a/arch/arm/mach-s5pv210/include/mach/regs-sys.h b/arch/arm/mach-s5pv210/include/mach/regs-sys.h index 26691d39d0f4..cccb1eddaa38 100644 --- a/arch/arm/mach-s5pv210/include/mach/regs-sys.h +++ b/arch/arm/mach-s5pv210/include/mach/regs-sys.h @@ -13,7 +13,3 @@ #define S5PV210_USB_PHY_CON (S3C_VA_SYS + 0xE80C) #define S5PV210_USB_PHY0_EN (1 << 0) #define S5PV210_USB_PHY1_EN (1 << 1) - -/* compatibility defines for s3c-hsotg driver */ -#define S3C64XX_OTHERS S5PV210_USB_PHY_CON -#define S3C64XX_OTHERS_USBMASK S5PV210_USB_PHY0_EN diff --git a/arch/arm/mach-s5pv210/include/mach/system.h b/arch/arm/mach-s5pv210/include/mach/system.h deleted file mode 100644 index bf288ced860a..000000000000 --- a/arch/arm/mach-s5pv210/include/mach/system.h +++ /dev/null @@ -1,21 +0,0 @@ -/* linux/arch/arm/mach-s5pv210/include/mach/system.h - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5PV210 - system support header - * - * 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. -*/ - -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H __FILE__ - -static void arch_idle(void) -{ - /* nothing here yet */ -} - -#endif /* __ASM_ARCH_SYSTEM_H */ diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c index 5e734d025a6a..48d018f2332b 100644 --- a/arch/arm/mach-s5pv210/mach-aquila.c +++ b/arch/arm/mach-s5pv210/mach-aquila.c @@ -484,8 +484,8 @@ static struct wm8994_pdata wm8994_platform_data = { .gpio_defaults[8] = 0x0100, .gpio_defaults[9] = 0x0100, .gpio_defaults[10] = 0x0100, - .ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */ - .ldo[1] = { 0, NULL, &wm8994_ldo2_data }, + .ldo[0] = { S5PV210_MP03(6), &wm8994_ldo1_data }, /* XM0FRNB_2 */ + .ldo[1] = { 0, &wm8994_ldo2_data }, }; /* GPIO I2C PMIC */ @@ -616,6 +616,7 @@ static struct platform_device *aquila_devices[] __initdata = { &s5p_device_fimc0, &s5p_device_fimc1, &s5p_device_fimc2, + &s5p_device_fimc_md, &s5pv210_device_iis0, &wm8994_fixed_voltage0, &wm8994_fixed_voltage1, diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c index ff9152610439..a8933de3d627 100644 --- a/arch/arm/mach-s5pv210/mach-goni.c +++ b/arch/arm/mach-s5pv210/mach-goni.c @@ -674,8 +674,8 @@ static struct wm8994_pdata wm8994_platform_data = { .gpio_defaults[8] = 0x0100, .gpio_defaults[9] = 0x0100, .gpio_defaults[10] = 0x0100, - .ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */ - .ldo[1] = { 0, NULL, &wm8994_ldo2_data }, + .ldo[0] = { S5PV210_MP03(6), &wm8994_ldo1_data }, /* XM0FRNB_2 */ + .ldo[1] = { 0, &wm8994_ldo2_data }, }; /* GPIO I2C PMIC */ @@ -844,7 +844,7 @@ static struct s5p_fimc_isp_info goni_camera_sensors[] = { }, }; -struct s5p_platform_fimc goni_fimc_md_platdata __initdata = { +static struct s5p_platform_fimc goni_fimc_md_platdata __initdata = { .isp_info = goni_camera_sensors, .num_clients = ARRAY_SIZE(goni_camera_sensors), }; diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c index b323983b2c54..dfc29236321c 100644 --- a/arch/arm/mach-s5pv210/mach-smdkc110.c +++ b/arch/arm/mach-s5pv210/mach-smdkc110.c @@ -31,6 +31,7 @@ #include <plat/iic.h> #include <plat/pm.h> #include <plat/s5p-time.h> +#include <plat/mfc.h> #include "common.h" @@ -94,6 +95,13 @@ static struct platform_device *smdkc110_devices[] __initdata = { &s3c_device_i2c2, &s3c_device_rtc, &s3c_device_wdt, + &s5p_device_fimc0, + &s5p_device_fimc1, + &s5p_device_fimc2, + &s5p_device_fimc_md, + &s5p_device_mfc, + &s5p_device_mfc_l, + &s5p_device_mfc_r, }; static struct i2c_board_info smdkc110_i2c_devs0[] __initdata = { @@ -117,6 +125,11 @@ static void __init smdkc110_map_io(void) s5p_set_timer_source(S5P_PWM3, S5P_PWM4); } +static void __init smdkc110_reserve(void) +{ + s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20); +} + static void __init smdkc110_machine_init(void) { s3c_pm_init(); @@ -145,4 +158,5 @@ MACHINE_START(SMDKC110, "SMDKC110") .init_machine = smdkc110_machine_init, .timer = &s5p_timer, .restart = s5pv210_restart, + .reserve = &smdkc110_reserve, MACHINE_END diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c index dff9ea7b5bba..91d4ad8bcc73 100644 --- a/arch/arm/mach-s5pv210/mach-smdkv210.c +++ b/arch/arm/mach-s5pv210/mach-smdkv210.c @@ -46,6 +46,7 @@ #include <plat/s5p-time.h> #include <plat/backlight.h> #include <plat/regs-fb-v4.h> +#include <plat/mfc.h> #include "common.h" @@ -140,7 +141,7 @@ static struct dm9000_plat_data smdkv210_dm9000_platdata = { .dev_addr = { 0x00, 0x09, 0xc0, 0xff, 0xec, 0x48 }, }; -struct platform_device smdkv210_dm9000 = { +static struct platform_device smdkv210_dm9000 = { .name = "dm9000", .id = -1, .num_resources = ARRAY_SIZE(smdkv210_dm9000_resources), @@ -223,6 +224,14 @@ static struct platform_device *smdkv210_devices[] __initdata = { &s3c_device_rtc, &s3c_device_ts, &s3c_device_wdt, + &s5p_device_fimc0, + &s5p_device_fimc1, + &s5p_device_fimc2, + &s5p_device_fimc_md, + &s5p_device_jpeg, + &s5p_device_mfc, + &s5p_device_mfc_l, + &s5p_device_mfc_r, &s5pv210_device_ac97, &s5pv210_device_iis0, &s5pv210_device_spdif, @@ -282,6 +291,11 @@ static void __init smdkv210_map_io(void) s5p_set_timer_source(S5P_PWM2, S5P_PWM4); } +static void __init smdkv210_reserve(void) +{ + s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20); +} + static void __init smdkv210_machine_init(void) { s3c_pm_init(); @@ -319,4 +333,5 @@ MACHINE_START(SMDKV210, "SMDKV210") .init_machine = smdkv210_machine_init, .timer = &s5p_timer, .restart = s5pv210_restart, + .reserve = &smdkv210_reserve, MACHINE_END diff --git a/arch/arm/mach-s5pv210/setup-usb-phy.c b/arch/arm/mach-s5pv210/setup-usb-phy.c new file mode 100644 index 000000000000..be39cf4aa91b --- /dev/null +++ b/arch/arm/mach-s5pv210/setup-usb-phy.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2012 Samsung Electronics Co.Ltd + * Author: Joonyoung Shim <jy0922.shim@samsung.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 Foundationr + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/platform_device.h> +#include <mach/map.h> +#include <mach/regs-sys.h> +#include <plat/cpu.h> +#include <plat/regs-usb-hsotg-phy.h> +#include <plat/usb-phy.h> + +static int s5pv210_usb_otgphy_init(struct platform_device *pdev) +{ + struct clk *xusbxti; + u32 phyclk; + + writel(readl(S5PV210_USB_PHY_CON) | S5PV210_USB_PHY0_EN, + S5PV210_USB_PHY_CON); + + /* set clock frequency for PLL */ + phyclk = readl(S3C_PHYCLK) & ~S3C_PHYCLK_CLKSEL_MASK; + + xusbxti = clk_get(&pdev->dev, "xusbxti"); + if (xusbxti && !IS_ERR(xusbxti)) { + switch (clk_get_rate(xusbxti)) { + case 12 * MHZ: + phyclk |= S3C_PHYCLK_CLKSEL_12M; + break; + case 24 * MHZ: + phyclk |= S3C_PHYCLK_CLKSEL_24M; + break; + default: + case 48 * MHZ: + /* default reference clock */ + break; + } + clk_put(xusbxti); + } + + /* TODO: select external clock/oscillator */ + writel(phyclk | S3C_PHYCLK_CLK_FORCE, S3C_PHYCLK); + + /* set to normal OTG PHY */ + writel((readl(S3C_PHYPWR) & ~S3C_PHYPWR_NORMAL_MASK), S3C_PHYPWR); + mdelay(1); + + /* reset OTG PHY and Link */ + writel(S3C_RSTCON_PHY | S3C_RSTCON_HCLK | S3C_RSTCON_PHYCLK, + S3C_RSTCON); + udelay(20); /* at-least 10uS */ + writel(0, S3C_RSTCON); + + return 0; +} + +static int s5pv210_usb_otgphy_exit(struct platform_device *pdev) +{ + writel((readl(S3C_PHYPWR) | S3C_PHYPWR_ANALOG_POWERDOWN | + S3C_PHYPWR_OTG_DISABLE), S3C_PHYPWR); + + writel(readl(S5PV210_USB_PHY_CON) & ~S5PV210_USB_PHY0_EN, + S5PV210_USB_PHY_CON); + + return 0; +} + +int s5p_usb_phy_init(struct platform_device *pdev, int type) +{ + if (type == S5P_USB_PHY_DEVICE) + return s5pv210_usb_otgphy_init(pdev); + + return -EINVAL; +} + +int s5p_usb_phy_exit(struct platform_device *pdev, int type) +{ + if (type == S5P_USB_PHY_DEVICE) + return s5pv210_usb_otgphy_exit(pdev); + + return -EINVAL; +} diff --git a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile index ed7408d3216c..60b97ec01676 100644 --- a/arch/arm/mach-sa1100/Makefile +++ b/arch/arm/mach-sa1100/Makefile @@ -3,7 +3,7 @@ # # Common support -obj-y := clock.o generic.o irq.o dma.o time.o #nmi-oopser.o +obj-y := clock.o generic.o irq.o time.o #nmi-oopser.o obj-m := obj-n := obj- := diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c index 0c4b76ab4d8e..375d3f779a88 100644 --- a/arch/arm/mach-sa1100/assabet.c +++ b/arch/arm/mach-sa1100/assabet.c @@ -15,14 +15,16 @@ #include <linux/errno.h> #include <linux/ioport.h> #include <linux/serial_core.h> +#include <linux/mfd/ucb1x00.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/delay.h> #include <linux/mm.h> +#include <video/sa1100fb.h> + #include <mach/hardware.h> #include <asm/mach-types.h> -#include <asm/irq.h> #include <asm/setup.h> #include <asm/page.h> #include <asm/pgtable-hwdef.h> @@ -36,17 +38,18 @@ #include <asm/mach/serial_sa1100.h> #include <mach/assabet.h> #include <mach/mcp.h> +#include <mach/irqs.h> #include "generic.h" #define ASSABET_BCR_DB1110 \ - (ASSABET_BCR_SPK_OFF | ASSABET_BCR_QMUTE | \ + (ASSABET_BCR_SPK_OFF | \ ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED | \ ASSABET_BCR_RS232EN | ASSABET_BCR_LCD_12RGB | \ ASSABET_BCR_IRDA_MD0) #define ASSABET_BCR_DB1111 \ - (ASSABET_BCR_SPK_OFF | ASSABET_BCR_QMUTE | \ + (ASSABET_BCR_SPK_OFF | \ ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED | \ ASSABET_BCR_RS232EN | ASSABET_BCR_LCD_12RGB | \ ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_STEREO_LB | \ @@ -69,31 +72,10 @@ void ASSABET_BCR_frob(unsigned int mask, unsigned int val) EXPORT_SYMBOL(ASSABET_BCR_frob); -static void assabet_backlight_power(int on) -{ -#ifndef ASSABET_PAL_VIDEO - if (on) - ASSABET_BCR_set(ASSABET_BCR_LIGHT_ON); - else -#endif - ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON); -} - -/* - * Turn on/off the backlight. When turning the backlight on, - * we wait 500us after turning it on so we don't cause the - * supplies to droop when we enable the LCD controller (and - * cause a hard reset.) - */ -static void assabet_lcd_power(int on) +static void assabet_ucb1x00_reset(enum ucb1x00_reset state) { -#ifndef ASSABET_PAL_VIDEO - if (on) { - ASSABET_BCR_set(ASSABET_BCR_LCD_ON); - udelay(500); - } else -#endif - ASSABET_BCR_clear(ASSABET_BCR_LCD_ON); + if (state == UCB_RST_PROBE) + ASSABET_BCR_set(ASSABET_BCR_CODEC_RST); } @@ -152,15 +134,8 @@ static struct flash_platform_data assabet_flash_data = { }; static struct resource assabet_flash_resources[] = { - { - .start = SA1100_CS0_PHYS, - .end = SA1100_CS0_PHYS + SZ_32M - 1, - .flags = IORESOURCE_MEM, - }, { - .start = SA1100_CS1_PHYS, - .end = SA1100_CS1_PHYS + SZ_32M - 1, - .flags = IORESOURCE_MEM, - } + DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M), + DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_32M), }; @@ -199,18 +174,126 @@ static struct irda_platform_data assabet_irda_data = { .set_speed = assabet_irda_set_speed, }; +static struct ucb1x00_plat_data assabet_ucb1x00_data = { + .reset = assabet_ucb1x00_reset, + .gpio_base = -1, +}; + static struct mcp_plat_data assabet_mcp_data = { .mccr0 = MCCR0_ADM, .sclk_rate = 11981000, + .codec_pdata = &assabet_ucb1x00_data, +}; + +static void assabet_lcd_set_visual(u32 visual) +{ + u_int is_true_color = visual == FB_VISUAL_TRUECOLOR; + + if (machine_is_assabet()) { +#if 1 // phase 4 or newer Assabet's + if (is_true_color) + ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB); + else + ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB); +#else + // older Assabet's + if (is_true_color) + ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB); + else + ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB); +#endif + } +} + +#ifndef ASSABET_PAL_VIDEO +static void assabet_lcd_backlight_power(int on) +{ + if (on) + ASSABET_BCR_set(ASSABET_BCR_LIGHT_ON); + else + ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON); +} + +/* + * Turn on/off the backlight. When turning the backlight on, we wait + * 500us after turning it on so we don't cause the supplies to droop + * when we enable the LCD controller (and cause a hard reset.) + */ +static void assabet_lcd_power(int on) +{ + if (on) { + ASSABET_BCR_set(ASSABET_BCR_LCD_ON); + udelay(500); + } else + ASSABET_BCR_clear(ASSABET_BCR_LCD_ON); +} + +/* + * The assabet uses a sharp LQ039Q2DS54 LCD module. It is actually + * takes an RGB666 signal, but we provide it with an RGB565 signal + * instead (def_rgb_16). + */ +static struct sa1100fb_mach_info lq039q2ds54_info = { + .pixclock = 171521, .bpp = 16, + .xres = 320, .yres = 240, + + .hsync_len = 5, .vsync_len = 1, + .left_margin = 61, .upper_margin = 3, + .right_margin = 9, .lower_margin = 0, + + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + + .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, + .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2), + + .backlight_power = assabet_lcd_backlight_power, + .lcd_power = assabet_lcd_power, + .set_visual = assabet_lcd_set_visual, +}; +#else +static void assabet_pal_backlight_power(int on) +{ + ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON); +} + +static void assabet_pal_power(int on) +{ + ASSABET_BCR_clear(ASSABET_BCR_LCD_ON); +} + +static struct sa1100fb_mach_info pal_info = { + .pixclock = 67797, .bpp = 16, + .xres = 640, .yres = 512, + + .hsync_len = 64, .vsync_len = 6, + .left_margin = 125, .upper_margin = 70, + .right_margin = 115, .lower_margin = 36, + + .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, + .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512), + + .backlight_power = assabet_pal_backlight_power, + .lcd_power = assabet_pal_power, + .set_visual = assabet_lcd_set_visual, }; +#endif + +#ifdef CONFIG_ASSABET_NEPONSET +static struct resource neponset_resources[] = { + DEFINE_RES_MEM(0x10000000, 0x08000000), + DEFINE_RES_MEM(0x18000000, 0x04000000), + DEFINE_RES_MEM(0x40000000, SZ_8K), + DEFINE_RES_IRQ(IRQ_GPIO25), +}; +#endif static void __init assabet_init(void) { /* * Ensure that the power supply is in "high power" mode. */ - GPDR |= GPIO_GPIO16; GPSR = GPIO_GPIO16; + GPDR |= GPIO_GPIO16; /* * Ensure that these pins are set as outputs and are driving @@ -218,8 +301,16 @@ static void __init assabet_init(void) * the WS latch in the CPLD, and we don't float causing * excessive power drain. --rmk */ - GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM; GPCR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM; + GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM; + + /* + * Also set GPIO27 as an output; this is used to clock UART3 + * via the FPGA and as otherwise has no pullups or pulldowns, + * so stop it floating. + */ + GPCR = GPIO_GPIO27; + GPDR |= GPIO_GPIO27; /* * Set up registers for sleep mode. @@ -231,8 +322,7 @@ static void __init assabet_init(void) PPDR |= PPC_TXD3 | PPC_TXD1; PPSR |= PPC_TXD3 | PPC_TXD1; - sa1100fb_lcd_power = assabet_lcd_power; - sa1100fb_backlight_power = assabet_backlight_power; + sa11x0_ppc_configure_mcp(); if (machine_has_neponset()) { /* @@ -246,9 +336,17 @@ static void __init assabet_init(void) #ifndef CONFIG_ASSABET_NEPONSET printk( "Warning: Neponset detected but full support " "hasn't been configured in the kernel\n" ); +#else + platform_device_register_simple("neponset", 0, + neponset_resources, ARRAY_SIZE(neponset_resources)); #endif } +#ifndef ASSABET_PAL_VIDEO + sa11x0_register_lcd(&lq039q2ds54_info); +#else + sa11x0_register_lcd(&pal_video); +#endif sa11x0_register_mtd(&assabet_flash_data, assabet_flash_resources, ARRAY_SIZE(assabet_flash_resources)); sa11x0_register_irda(&assabet_irda_data); @@ -412,21 +510,8 @@ static void __init assabet_map_io(void) */ Ser1SDCR0 |= SDCR0_SUS; - if (machine_has_neponset()) { -#ifdef CONFIG_ASSABET_NEPONSET - extern void neponset_map_io(void); - - /* - * We map Neponset registers even if it isn't present since - * many drivers will try to probe their stuff (and fail). - * This is still more friendly than a kernel paging request - * crash. - */ - neponset_map_io(); -#endif - } else { + if (!machine_has_neponset()) sa1100_register_uart_fns(&assabet_port_fns); - } /* * When Neponset is attached, the first UART should be @@ -449,6 +534,7 @@ MACHINE_START(ASSABET, "Intel-Assabet") .atag_offset = 0x100, .fixup = fixup_assabet, .map_io = assabet_map_io, + .nr_irqs = SA1100_NR_IRQS, .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = assabet_init, diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c index b07a2c024cb7..e0f0c030258c 100644 --- a/arch/arm/mach-sa1100/badge4.c +++ b/arch/arm/mach-sa1100/badge4.c @@ -39,20 +39,27 @@ #include "generic.h" static struct resource sa1111_resources[] = { - [0] = { - .start = BADGE4_SA1111_BASE, - .end = BADGE4_SA1111_BASE + 0x00001fff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = BADGE4_IRQ_GPIO_SA1111, - .end = BADGE4_IRQ_GPIO_SA1111, - .flags = IORESOURCE_IRQ, - }, + [0] = DEFINE_RES_MEM(BADGE4_SA1111_BASE, 0x2000), + [1] = DEFINE_RES_IRQ(BADGE4_IRQ_GPIO_SA1111), }; +static int badge4_sa1111_enable(void *data, unsigned devid) +{ + if (devid == SA1111_DEVID_USB) + badge4_set_5V(BADGE4_5V_USB, 1); + return 0; +} + +static void badge4_sa1111_disable(void *data, unsigned devid) +{ + if (devid == SA1111_DEVID_USB) + badge4_set_5V(BADGE4_5V_USB, 0); +} + static struct sa1111_platform_data sa1111_info = { - .irq_base = IRQ_BOARD_END, + .disable_devs = SA1111_DEVID_PS2_MSE, + .enable = badge4_sa1111_enable, + .disable = badge4_sa1111_disable, }; static u64 sa1111_dmamask = 0xffffffffUL; @@ -121,11 +128,8 @@ static struct flash_platform_data badge4_flash_data = { .nr_parts = ARRAY_SIZE(badge4_partitions), }; -static struct resource badge4_flash_resource = { - .start = SA1100_CS0_PHYS, - .end = SA1100_CS0_PHYS + SZ_64M - 1, - .flags = IORESOURCE_MEM, -}; +static struct resource badge4_flash_resource = + DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_64M); static int five_v_on __initdata = 0; @@ -269,11 +273,6 @@ static struct map_desc badge4_io_desc[] __initdata = { .pfn = __phys_to_pfn(0x10000000), .length = 0x00100000, .type = MT_DEVICE - }, { /* SA-1111 */ - .virtual = 0xf4000000, - .pfn = __phys_to_pfn(0x48000000), - .length = 0x00100000, - .type = MT_DEVICE } }; @@ -304,6 +303,7 @@ static void __init badge4_map_io(void) MACHINE_START(BADGE4, "Hewlett-Packard Laboratories BadgePAD 4") .atag_offset = 0x100, .map_io = badge4_map_io, + .nr_irqs = SA1100_NR_IRQS, .init_irq = sa1100_init_irq, .timer = &sa1100_timer, #ifdef CONFIG_SA1111 diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c index 11bb6d0b9be3..4a61f60e0502 100644 --- a/arch/arm/mach-sa1100/cerf.c +++ b/arch/arm/mach-sa1100/cerf.c @@ -18,7 +18,6 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> -#include <asm/irq.h> #include <mach/hardware.h> #include <asm/setup.h> @@ -30,14 +29,11 @@ #include <mach/cerf.h> #include <mach/mcp.h> +#include <mach/irqs.h> #include "generic.h" static struct resource cerfuart2_resources[] = { - [0] = { - .start = 0x80030000, - .end = 0x8003ffff, - .flags = IORESOURCE_MEM, - }, + [0] = DEFINE_RES_MEM(0x80030000, SZ_64K), }; static struct platform_device cerfuart2_device = { @@ -87,11 +83,8 @@ static struct flash_platform_data cerf_flash_data = { .nr_parts = ARRAY_SIZE(cerf_partitions), }; -static struct resource cerf_flash_resource = { - .start = SA1100_CS0_PHYS, - .end = SA1100_CS0_PHYS + SZ_32M - 1, - .flags = IORESOURCE_MEM, -}; +static struct resource cerf_flash_resource = + DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M); static void __init cerf_init_irq(void) { @@ -128,6 +121,7 @@ static struct mcp_plat_data cerf_mcp_data = { static void __init cerf_init(void) { + sa11x0_ppc_configure_mcp(); platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices)); sa11x0_register_mtd(&cerf_flash_data, &cerf_flash_resource, 1); sa11x0_register_mcp(&cerf_mcp_data); @@ -136,6 +130,7 @@ static void __init cerf_init(void) MACHINE_START(CERF, "Intrinsyc CerfBoard/CerfCube") /* Maintainer: support@intrinsyc.com */ .map_io = cerf_map_io, + .nr_irqs = SA1100_NR_IRQS, .init_irq = cerf_init_irq, .timer = &sa1100_timer, .init_machine = cerf_init, diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c index dab3c6347a8f..172ebd0ee0a2 100644 --- a/arch/arm/mach-sa1100/clock.c +++ b/arch/arm/mach-sa1100/clock.c @@ -11,17 +11,29 @@ #include <linux/clk.h> #include <linux/spinlock.h> #include <linux/mutex.h> +#include <linux/io.h> +#include <linux/clkdev.h> #include <mach/hardware.h> -/* - * Very simple clock implementation - we only have one clock to deal with. - */ +struct clkops { + void (*enable)(struct clk *); + void (*disable)(struct clk *); +}; + struct clk { + const struct clkops *ops; unsigned int enabled; }; -static void clk_gpio27_enable(void) +#define DEFINE_CLK(_name, _ops) \ +struct clk clk_##_name = { \ + .ops = _ops, \ + } + +static DEFINE_SPINLOCK(clocks_lock); + +static void clk_gpio27_enable(struct clk *clk) { /* * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111: @@ -32,38 +44,24 @@ static void clk_gpio27_enable(void) TUCR = TUCR_3_6864MHz; } -static void clk_gpio27_disable(void) +static void clk_gpio27_disable(struct clk *clk) { TUCR = 0; GPDR &= ~GPIO_32_768kHz; GAFR &= ~GPIO_32_768kHz; } -static struct clk clk_gpio27; - -static DEFINE_SPINLOCK(clocks_lock); - -struct clk *clk_get(struct device *dev, const char *id) -{ - const char *devname = dev_name(dev); - - return strcmp(devname, "sa1111.0") ? ERR_PTR(-ENOENT) : &clk_gpio27; -} -EXPORT_SYMBOL(clk_get); - -void clk_put(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_put); - int clk_enable(struct clk *clk) { unsigned long flags; - spin_lock_irqsave(&clocks_lock, flags); - if (clk->enabled++ == 0) - clk_gpio27_enable(); - spin_unlock_irqrestore(&clocks_lock, flags); + if (clk) { + spin_lock_irqsave(&clocks_lock, flags); + if (clk->enabled++ == 0) + clk->ops->enable(clk); + spin_unlock_irqrestore(&clocks_lock, flags); + } + return 0; } EXPORT_SYMBOL(clk_enable); @@ -72,17 +70,31 @@ void clk_disable(struct clk *clk) { unsigned long flags; - WARN_ON(clk->enabled == 0); - - spin_lock_irqsave(&clocks_lock, flags); - if (--clk->enabled == 0) - clk_gpio27_disable(); - spin_unlock_irqrestore(&clocks_lock, flags); + if (clk) { + WARN_ON(clk->enabled == 0); + spin_lock_irqsave(&clocks_lock, flags); + if (--clk->enabled == 0) + clk->ops->disable(clk); + spin_unlock_irqrestore(&clocks_lock, flags); + } } EXPORT_SYMBOL(clk_disable); -unsigned long clk_get_rate(struct clk *clk) +const struct clkops clk_gpio27_ops = { + .enable = clk_gpio27_enable, + .disable = clk_gpio27_disable, +}; + +static DEFINE_CLK(gpio27, &clk_gpio27_ops); + +static struct clk_lookup sa11xx_clkregs[] = { + CLKDEV_INIT("sa1111.0", NULL, &clk_gpio27), + CLKDEV_INIT("sa1100-rtc", NULL, NULL), +}; + +static int __init sa11xx_clk_init(void) { - return 3686400; + clkdev_add_table(sa11xx_clkregs, ARRAY_SIZE(sa11xx_clkregs)); + return 0; } -EXPORT_SYMBOL(clk_get_rate); +core_initcall(sa11xx_clk_init); diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c index fd5652118ed1..c7f418b0cde9 100644 --- a/arch/arm/mach-sa1100/collie.c +++ b/arch/arm/mach-sa1100/collie.c @@ -22,15 +22,17 @@ #include <linux/tty.h> #include <linux/delay.h> #include <linux/platform_device.h> +#include <linux/mfd/ucb1x00.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/timer.h> #include <linux/gpio.h> #include <linux/pda_power.h> +#include <video/sa1100fb.h> + #include <mach/hardware.h> #include <asm/mach-types.h> -#include <asm/irq.h> #include <asm/page.h> #include <asm/setup.h> #include <mach/collie.h> @@ -44,15 +46,12 @@ #include <asm/mach/sharpsl_param.h> #include <asm/hardware/locomo.h> #include <mach/mcp.h> +#include <mach/irqs.h> #include "generic.h" static struct resource collie_scoop_resources[] = { - [0] = { - .start = 0x40800000, - .end = 0x40800fff, - .flags = IORESOURCE_MEM, - }, + [0] = DEFINE_RES_MEM(0x40800000, SZ_4K), }; static struct scoop_config collie_scoop_setup = { @@ -85,10 +84,14 @@ static struct scoop_pcmcia_config collie_pcmcia_config = { .num_devs = 1, }; +static struct ucb1x00_plat_data collie_ucb1x00_data = { + .gpio_base = COLLIE_TC35143_GPIO_BASE, +}; + static struct mcp_plat_data collie_mcp_data = { .mccr0 = MCCR0_ADM | MCCR0_ExtClk, .sclk_rate = 9216000, - .gpio_base = COLLIE_TC35143_GPIO_BASE, + .codec_pdata = &collie_ucb1x00_data, }; /* @@ -221,16 +224,8 @@ device_initcall(collie_uart_init); static struct resource locomo_resources[] = { - [0] = { - .start = 0x40000000, - .end = 0x40001fff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_GPIO25, - .end = IRQ_GPIO25, - .flags = IORESOURCE_IRQ, - }, + [0] = DEFINE_RES_MEM(0x40000000, SZ_8K), + [1] = DEFINE_RES_IRQ(IRQ_GPIO25), }; static struct locomo_platform_data locomo_info = { @@ -303,11 +298,25 @@ static struct flash_platform_data collie_flash_data = { }; static struct resource collie_flash_resources[] = { - { - .start = SA1100_CS0_PHYS, - .end = SA1100_CS0_PHYS + SZ_32M - 1, - .flags = IORESOURCE_MEM, - } + DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M), +}; + +static struct sa1100fb_mach_info collie_lcd_info = { + .pixclock = 171521, .bpp = 16, + .xres = 320, .yres = 240, + + .hsync_len = 5, .vsync_len = 1, + .left_margin = 11, .upper_margin = 2, + .right_margin = 30, .lower_margin = 0, + + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + + .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, + .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2), + +#ifdef CONFIG_BACKLIGHT_LOCOMO + .lcd_power = locomolcd_power +#endif }; static void __init collie_init(void) @@ -341,6 +350,10 @@ static void __init collie_init(void) collie_power_resource[0].start = gpio_to_irq(COLLIE_GPIO_AC_IN); collie_power_resource[0].end = gpio_to_irq(COLLIE_GPIO_AC_IN); + + sa11x0_ppc_configure_mcp(); + + platform_scoop_config = &collie_pcmcia_config; ret = platform_add_devices(devices, ARRAY_SIZE(devices)); @@ -348,6 +361,7 @@ static void __init collie_init(void) printk(KERN_WARNING "collie: Unable to register LoCoMo device\n"); } + sa11x0_register_lcd(&collie_lcd_info); sa11x0_register_mtd(&collie_flash_data, collie_flash_resources, ARRAY_SIZE(collie_flash_resources)); sa11x0_register_mcp(&collie_mcp_data); @@ -383,6 +397,7 @@ static void __init collie_map_io(void) MACHINE_START(COLLIE, "Sharp-Collie") .map_io = collie_map_io, + .nr_irqs = SA1100_NR_IRQS, .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = collie_init, diff --git a/arch/arm/mach-sa1100/dma.c b/arch/arm/mach-sa1100/dma.c deleted file mode 100644 index ad660350c296..000000000000 --- a/arch/arm/mach-sa1100/dma.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * arch/arm/mach-sa1100/dma.c - * - * Support functions for the SA11x0 internal DMA channels. - * - * Copyright (C) 2000, 2001 by Nicolas Pitre - * - * 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 <linux/module.h> -#include <linux/interrupt.h> -#include <linux/init.h> -#include <linux/spinlock.h> -#include <linux/errno.h> - -#include <asm/system.h> -#include <asm/irq.h> -#include <mach/hardware.h> -#include <mach/dma.h> - - -#undef DEBUG -#ifdef DEBUG -#define DPRINTK( s, arg... ) printk( "dma<%p>: " s, regs , ##arg ) -#else -#define DPRINTK( x... ) -#endif - - -typedef struct { - const char *device_id; /* device name */ - u_long device; /* this channel device, 0 if unused*/ - dma_callback_t callback; /* to call when DMA completes */ - void *data; /* ... with private data ptr */ -} sa1100_dma_t; - -static sa1100_dma_t dma_chan[SA1100_DMA_CHANNELS]; - -static DEFINE_SPINLOCK(dma_list_lock); - - -static irqreturn_t dma_irq_handler(int irq, void *dev_id) -{ - dma_regs_t *dma_regs = dev_id; - sa1100_dma_t *dma = dma_chan + (((u_int)dma_regs >> 5) & 7); - int status = dma_regs->RdDCSR; - - if (status & (DCSR_ERROR)) { - printk(KERN_CRIT "DMA on \"%s\" caused an error\n", dma->device_id); - dma_regs->ClrDCSR = DCSR_ERROR; - } - - dma_regs->ClrDCSR = status & (DCSR_DONEA | DCSR_DONEB); - if (dma->callback) { - if (status & DCSR_DONEA) - dma->callback(dma->data); - if (status & DCSR_DONEB) - dma->callback(dma->data); - } - return IRQ_HANDLED; -} - - -/** - * sa1100_request_dma - allocate one of the SA11x0's DMA channels - * @device: The SA11x0 peripheral targeted by this request - * @device_id: An ascii name for the claiming device - * @callback: Function to be called when the DMA completes - * @data: A cookie passed back to the callback function - * @dma_regs: Pointer to the location of the allocated channel's identifier - * - * This function will search for a free DMA channel and returns the - * address of the hardware registers for that channel as the channel - * identifier. This identifier is written to the location pointed by - * @dma_regs. The list of possible values for @device are listed into - * arch/arm/mach-sa1100/include/mach/dma.h as a dma_device_t enum. - * - * Note that reading from a port and writing to the same port are - * actually considered as two different streams requiring separate - * DMA registrations. - * - * The @callback function is called from interrupt context when one - * of the two possible DMA buffers in flight has terminated. That - * function has to be small and efficient while posponing more complex - * processing to a lower priority execution context. - * - * If no channels are available, or if the desired @device is already in - * use by another DMA channel, then an error code is returned. This - * function must be called before any other DMA calls. - **/ - -int sa1100_request_dma (dma_device_t device, const char *device_id, - dma_callback_t callback, void *data, - dma_regs_t **dma_regs) -{ - sa1100_dma_t *dma = NULL; - dma_regs_t *regs; - int i, err; - - *dma_regs = NULL; - - err = 0; - spin_lock(&dma_list_lock); - for (i = 0; i < SA1100_DMA_CHANNELS; i++) { - if (dma_chan[i].device == device) { - err = -EBUSY; - break; - } else if (!dma_chan[i].device && !dma) { - dma = &dma_chan[i]; - } - } - if (!err) { - if (dma) - dma->device = device; - else - err = -ENOSR; - } - spin_unlock(&dma_list_lock); - if (err) - return err; - - i = dma - dma_chan; - regs = (dma_regs_t *)&DDAR(i); - err = request_irq(IRQ_DMA0 + i, dma_irq_handler, IRQF_DISABLED, - device_id, regs); - if (err) { - printk(KERN_ERR - "%s: unable to request IRQ %d for %s\n", - __func__, IRQ_DMA0 + i, device_id); - dma->device = 0; - return err; - } - - *dma_regs = regs; - dma->device_id = device_id; - dma->callback = callback; - dma->data = data; - - regs->ClrDCSR = - (DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB | - DCSR_IE | DCSR_ERROR | DCSR_RUN); - regs->DDAR = device; - - return 0; -} - - -/** - * sa1100_free_dma - free a SA11x0 DMA channel - * @regs: identifier for the channel to free - * - * This clears all activities on a given DMA channel and releases it - * for future requests. The @regs identifier is provided by a - * successful call to sa1100_request_dma(). - **/ - -void sa1100_free_dma(dma_regs_t *regs) -{ - int i; - - for (i = 0; i < SA1100_DMA_CHANNELS; i++) - if (regs == (dma_regs_t *)&DDAR(i)) - break; - if (i >= SA1100_DMA_CHANNELS) { - printk(KERN_ERR "%s: bad DMA identifier\n", __func__); - return; - } - - if (!dma_chan[i].device) { - printk(KERN_ERR "%s: Trying to free free DMA\n", __func__); - return; - } - - regs->ClrDCSR = - (DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB | - DCSR_IE | DCSR_ERROR | DCSR_RUN); - free_irq(IRQ_DMA0 + i, regs); - dma_chan[i].device = 0; -} - - -/** - * sa1100_start_dma - submit a data buffer for DMA - * @regs: identifier for the channel to use - * @dma_ptr: buffer physical (or bus) start address - * @size: buffer size - * - * This function hands the given data buffer to the hardware for DMA - * access. If another buffer is already in flight then this buffer - * will be queued so the DMA engine will switch to it automatically - * when the previous one is done. The DMA engine is actually toggling - * between two buffers so at most 2 successful calls can be made before - * one of them terminates and the callback function is called. - * - * The @regs identifier is provided by a successful call to - * sa1100_request_dma(). - * - * The @size must not be larger than %MAX_DMA_SIZE. If a given buffer - * is larger than that then it's the caller's responsibility to split - * it into smaller chunks and submit them separately. If this is the - * case then a @size of %CUT_DMA_SIZE is recommended to avoid ending - * up with too small chunks. The callback function can be used to chain - * submissions of buffer chunks. - * - * Error return values: - * %-EOVERFLOW: Given buffer size is too big. - * %-EBUSY: Both DMA buffers are already in use. - * %-EAGAIN: Both buffers were busy but one of them just completed - * but the interrupt handler has to execute first. - * - * This function returs 0 on success. - **/ - -int sa1100_start_dma(dma_regs_t *regs, dma_addr_t dma_ptr, u_int size) -{ - unsigned long flags; - u_long status; - int ret; - - if (dma_ptr & 3) - printk(KERN_WARNING "DMA: unaligned start address (0x%08lx)\n", - (unsigned long)dma_ptr); - - if (size > MAX_DMA_SIZE) - return -EOVERFLOW; - - local_irq_save(flags); - status = regs->RdDCSR; - - /* If both DMA buffers are started, there's nothing else we can do. */ - if ((status & (DCSR_STRTA | DCSR_STRTB)) == (DCSR_STRTA | DCSR_STRTB)) { - DPRINTK("start: st %#x busy\n", status); - ret = -EBUSY; - goto out; - } - - if (((status & DCSR_BIU) && (status & DCSR_STRTB)) || - (!(status & DCSR_BIU) && !(status & DCSR_STRTA))) { - if (status & DCSR_DONEA) { - /* give a chance for the interrupt to be processed */ - ret = -EAGAIN; - goto out; - } - regs->DBSA = dma_ptr; - regs->DBTA = size; - regs->SetDCSR = DCSR_STRTA | DCSR_IE | DCSR_RUN; - DPRINTK("start a=%#x s=%d on A\n", dma_ptr, size); - } else { - if (status & DCSR_DONEB) { - /* give a chance for the interrupt to be processed */ - ret = -EAGAIN; - goto out; - } - regs->DBSB = dma_ptr; - regs->DBTB = size; - regs->SetDCSR = DCSR_STRTB | DCSR_IE | DCSR_RUN; - DPRINTK("start a=%#x s=%d on B\n", dma_ptr, size); - } - ret = 0; - -out: - local_irq_restore(flags); - return ret; -} - - -/** - * sa1100_get_dma_pos - return current DMA position - * @regs: identifier for the channel to use - * - * This function returns the current physical (or bus) address for the - * given DMA channel. If the channel is running i.e. not in a stopped - * state then the caller must disable interrupts prior calling this - * function and process the returned value before re-enabling them to - * prevent races with the completion interrupt handler and the callback - * function. The validation of the returned value is the caller's - * responsibility as well -- the hardware seems to return out of range - * values when the DMA engine completes a buffer. - * - * The @regs identifier is provided by a successful call to - * sa1100_request_dma(). - **/ - -dma_addr_t sa1100_get_dma_pos(dma_regs_t *regs) -{ - int status; - - /* - * We must determine whether buffer A or B is active. - * Two possibilities: either we are in the middle of - * a buffer, or the DMA controller just switched to the - * next toggle but the interrupt hasn't been serviced yet. - * The former case is straight forward. In the later case, - * we'll do like if DMA is just at the end of the previous - * toggle since all registers haven't been reset yet. - * This goes around the edge case and since we're always - * a little behind anyways it shouldn't make a big difference. - * If DMA has been stopped prior calling this then the - * position is exact. - */ - status = regs->RdDCSR; - if ((!(status & DCSR_BIU) && (status & DCSR_STRTA)) || - ( (status & DCSR_BIU) && !(status & DCSR_STRTB))) - return regs->DBSA; - else - return regs->DBSB; -} - - -/** - * sa1100_reset_dma - reset a DMA channel - * @regs: identifier for the channel to use - * - * This function resets and reconfigure the given DMA channel. This is - * particularly useful after a sleep/wakeup event. - * - * The @regs identifier is provided by a successful call to - * sa1100_request_dma(). - **/ - -void sa1100_reset_dma(dma_regs_t *regs) -{ - int i; - - for (i = 0; i < SA1100_DMA_CHANNELS; i++) - if (regs == (dma_regs_t *)&DDAR(i)) - break; - if (i >= SA1100_DMA_CHANNELS) { - printk(KERN_ERR "%s: bad DMA identifier\n", __func__); - return; - } - - regs->ClrDCSR = - (DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB | - DCSR_IE | DCSR_ERROR | DCSR_RUN); - regs->DDAR = dma_chan[i].device; -} - - -EXPORT_SYMBOL(sa1100_request_dma); -EXPORT_SYMBOL(sa1100_free_dma); -EXPORT_SYMBOL(sa1100_start_dma); -EXPORT_SYMBOL(sa1100_get_dma_pos); -EXPORT_SYMBOL(sa1100_reset_dma); - diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index bb10ee2cb89f..7c524b4e415d 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c @@ -14,17 +14,22 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/delay.h> +#include <linux/dma-mapping.h> #include <linux/pm.h> #include <linux/cpufreq.h> #include <linux/ioport.h> #include <linux/platform_device.h> +#include <video/sa1100fb.h> + #include <asm/div64.h> -#include <mach/hardware.h> -#include <asm/system.h> #include <asm/mach/map.h> #include <asm/mach/flash.h> #include <asm/irq.h> +#include <asm/system_misc.h> + +#include <mach/hardware.h> +#include <mach/irqs.h> #include "generic.h" @@ -149,16 +154,8 @@ static void sa11x0_register_device(struct platform_device *dev, void *data) static struct resource sa11x0udc_resources[] = { - [0] = { - .start = __PREG(Ser0UDCCR), - .end = __PREG(Ser0UDCCR) + 0xffff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_Ser0UDC, - .end = IRQ_Ser0UDC, - .flags = IORESOURCE_IRQ, - }, + [0] = DEFINE_RES_MEM(__PREG(Ser0UDCCR), SZ_64K), + [1] = DEFINE_RES_IRQ(IRQ_Ser0UDC), }; static u64 sa11x0udc_dma_mask = 0xffffffffUL; @@ -175,16 +172,8 @@ static struct platform_device sa11x0udc_device = { }; static struct resource sa11x0uart1_resources[] = { - [0] = { - .start = __PREG(Ser1UTCR0), - .end = __PREG(Ser1UTCR0) + 0xffff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_Ser1UART, - .end = IRQ_Ser1UART, - .flags = IORESOURCE_IRQ, - }, + [0] = DEFINE_RES_MEM(__PREG(Ser1UTCR0), SZ_64K), + [1] = DEFINE_RES_IRQ(IRQ_Ser1UART), }; static struct platform_device sa11x0uart1_device = { @@ -195,16 +184,8 @@ static struct platform_device sa11x0uart1_device = { }; static struct resource sa11x0uart3_resources[] = { - [0] = { - .start = __PREG(Ser3UTCR0), - .end = __PREG(Ser3UTCR0) + 0xffff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_Ser3UART, - .end = IRQ_Ser3UART, - .flags = IORESOURCE_IRQ, - }, + [0] = DEFINE_RES_MEM(__PREG(Ser3UTCR0), SZ_64K), + [1] = DEFINE_RES_IRQ(IRQ_Ser3UART), }; static struct platform_device sa11x0uart3_device = { @@ -215,16 +196,9 @@ static struct platform_device sa11x0uart3_device = { }; static struct resource sa11x0mcp_resources[] = { - [0] = { - .start = __PREG(Ser4MCCR0), - .end = __PREG(Ser4MCCR0) + 0xffff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_Ser4MCP, - .end = IRQ_Ser4MCP, - .flags = IORESOURCE_IRQ, - }, + [0] = DEFINE_RES_MEM(__PREG(Ser4MCCR0), SZ_64K), + [1] = DEFINE_RES_MEM(__PREG(Ser4MCCR1), 4), + [2] = DEFINE_RES_IRQ(IRQ_Ser4MCP), }; static u64 sa11x0mcp_dma_mask = 0xffffffffUL; @@ -240,22 +214,24 @@ static struct platform_device sa11x0mcp_device = { .resource = sa11x0mcp_resources, }; +void __init sa11x0_ppc_configure_mcp(void) +{ + /* Setup the PPC unit for the MCP */ + PPDR &= ~PPC_RXD4; + PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM; + PSDR |= PPC_RXD4; + PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); +} + void sa11x0_register_mcp(struct mcp_plat_data *data) { sa11x0_register_device(&sa11x0mcp_device, data); } static struct resource sa11x0ssp_resources[] = { - [0] = { - .start = 0x80070000, - .end = 0x8007ffff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_Ser4SSP, - .end = IRQ_Ser4SSP, - .flags = IORESOURCE_IRQ, - }, + [0] = DEFINE_RES_MEM(0x80070000, SZ_64K), + [1] = DEFINE_RES_IRQ(IRQ_Ser4SSP), }; static u64 sa11x0ssp_dma_mask = 0xffffffffUL; @@ -272,16 +248,8 @@ static struct platform_device sa11x0ssp_device = { }; static struct resource sa11x0fb_resources[] = { - [0] = { - .start = 0xb0100000, - .end = 0xb010ffff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_LCD, - .end = IRQ_LCD, - .flags = IORESOURCE_IRQ, - }, + [0] = DEFINE_RES_MEM(0xb0100000, SZ_64K), + [1] = DEFINE_RES_IRQ(IRQ_LCD), }; static struct platform_device sa11x0fb_device = { @@ -294,6 +262,11 @@ static struct platform_device sa11x0fb_device = { .resource = sa11x0fb_resources, }; +void sa11x0_register_lcd(struct sa1100fb_mach_info *inf) +{ + sa11x0_register_device(&sa11x0fb_device, inf); +} + static struct platform_device sa11x0pcmcia_device = { .name = "sa11x0-pcmcia", .id = -1, @@ -314,23 +287,10 @@ void sa11x0_register_mtd(struct flash_platform_data *flash, } static struct resource sa11x0ir_resources[] = { - { - .start = __PREG(Ser2UTCR0), - .end = __PREG(Ser2UTCR0) + 0x24 - 1, - .flags = IORESOURCE_MEM, - }, { - .start = __PREG(Ser2HSCR0), - .end = __PREG(Ser2HSCR0) + 0x1c - 1, - .flags = IORESOURCE_MEM, - }, { - .start = __PREG(Ser2HSCR2), - .end = __PREG(Ser2HSCR2) + 0x04 - 1, - .flags = IORESOURCE_MEM, - }, { - .start = IRQ_Ser2ICP, - .end = IRQ_Ser2ICP, - .flags = IORESOURCE_IRQ, - } + DEFINE_RES_MEM(__PREG(Ser2UTCR0), 0x24), + DEFINE_RES_MEM(__PREG(Ser2HSCR0), 0x1c), + DEFINE_RES_MEM(__PREG(Ser2HSCR2), 0x04), + DEFINE_RES_IRQ(IRQ_Ser2ICP), }; static struct platform_device sa11x0ir_device = { @@ -345,9 +305,40 @@ void sa11x0_register_irda(struct irda_platform_data *irda) sa11x0_register_device(&sa11x0ir_device, irda); } +static struct resource sa1100_rtc_resources[] = { + DEFINE_RES_MEM(0x90010000, 0x9001003f), + DEFINE_RES_IRQ_NAMED(IRQ_RTC1Hz, "rtc 1Hz"), + DEFINE_RES_IRQ_NAMED(IRQ_RTCAlrm, "rtc alarm"), +}; + static struct platform_device sa11x0rtc_device = { .name = "sa1100-rtc", .id = -1, + .num_resources = ARRAY_SIZE(sa1100_rtc_resources), + .resource = sa1100_rtc_resources, +}; + +static struct resource sa11x0dma_resources[] = { + DEFINE_RES_MEM(DMA_PHYS, DMA_SIZE), + DEFINE_RES_IRQ(IRQ_DMA0), + DEFINE_RES_IRQ(IRQ_DMA1), + DEFINE_RES_IRQ(IRQ_DMA2), + DEFINE_RES_IRQ(IRQ_DMA3), + DEFINE_RES_IRQ(IRQ_DMA4), + DEFINE_RES_IRQ(IRQ_DMA5), +}; + +static u64 sa11x0dma_dma_mask = DMA_BIT_MASK(32); + +static struct platform_device sa11x0dma_device = { + .name = "sa11x0-dma", + .id = -1, + .dev = { + .dma_mask = &sa11x0dma_dma_mask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(sa11x0dma_resources), + .resource = sa11x0dma_resources, }; static struct platform_device *sa11x0_devices[] __initdata = { @@ -356,8 +347,8 @@ static struct platform_device *sa11x0_devices[] __initdata = { &sa11x0uart3_device, &sa11x0ssp_device, &sa11x0pcmcia_device, - &sa11x0fb_device, &sa11x0rtc_device, + &sa11x0dma_device, }; static int __init sa1100_init(void) @@ -368,12 +359,6 @@ static int __init sa1100_init(void) arch_initcall(sa1100_init); -void (*sa1100fb_backlight_power)(int on); -void (*sa1100fb_lcd_power)(int on); - -EXPORT_SYMBOL(sa1100fb_backlight_power); -EXPORT_SYMBOL(sa1100fb_lcd_power); - /* * Common I/O mapping: @@ -428,7 +413,7 @@ void __init sa1100_map_io(void) * the MBGNT signal false to ensure the SA1111 doesn't own the * SDRAM bus. */ -void __init sa1110_mb_disable(void) +void sa1110_mb_disable(void) { unsigned long flags; @@ -447,7 +432,7 @@ void __init sa1110_mb_disable(void) * If the system is going to use the SA-1111 DMA engines, set up * the memory bus request/grant pins. */ -void __devinit sa1110_mb_enable(void) +void sa1110_mb_enable(void) { unsigned long flags; diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h index 33268cf6be36..9eb3b3cd5a63 100644 --- a/arch/arm/mach-sa1100/generic.h +++ b/arch/arm/mach-sa1100/generic.h @@ -16,9 +16,6 @@ extern void sa11x0_restart(char, const char *); mi->bank[__nr].start = (__start), \ mi->bank[__nr].size = (__size) -extern void (*sa1100fb_backlight_power)(int on); -extern void (*sa1100fb_lcd_power)(int on); - extern void sa1110_mb_enable(void); extern void sa1110_mb_disable(void); @@ -39,4 +36,8 @@ struct irda_platform_data; void sa11x0_register_irda(struct irda_platform_data *irda); struct mcp_plat_data; +void sa11x0_ppc_configure_mcp(void); void sa11x0_register_mcp(struct mcp_plat_data *data); + +struct sa1100fb_mach_info; +void sa11x0_register_lcd(struct sa1100fb_mach_info *inf); diff --git a/arch/arm/mach-sa1100/h3100.c b/arch/arm/mach-sa1100/h3100.c index 1e6b3c105ba6..b2e8d0f418e0 100644 --- a/arch/arm/mach-sa1100/h3100.c +++ b/arch/arm/mach-sa1100/h3100.c @@ -14,11 +14,14 @@ #include <linux/kernel.h> #include <linux/gpio.h> +#include <video/sa1100fb.h> + #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/irda.h> #include <mach/h3xxx.h> +#include <mach/irqs.h> #include "generic.h" @@ -36,13 +39,28 @@ static void h3100_lcd_power(int enable) } } +static struct sa1100fb_mach_info h3100_lcd_info = { + .pixclock = 406977, .bpp = 4, + .xres = 320, .yres = 240, + + .hsync_len = 26, .vsync_len = 41, + .left_margin = 4, .upper_margin = 0, + .right_margin = 4, .lower_margin = 0, + + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .cmap_greyscale = 1, + .cmap_inverse = 1, + + .lccr0 = LCCR0_Mono | LCCR0_4PixMono | LCCR0_Sngl | LCCR0_Pas, + .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2), + + .lcd_power = h3100_lcd_power, +}; static void __init h3100_map_io(void) { h3xxx_map_io(); - sa1100fb_lcd_power = h3100_lcd_power; - /* Older bootldrs put GPIO2-9 in alternate mode on the assumption that they are used for video */ GAFR &= ~0x000001fb; @@ -80,12 +98,15 @@ static void __init h3100_mach_init(void) { h3xxx_init_gpio(h3100_default_gpio, ARRAY_SIZE(h3100_default_gpio)); h3xxx_mach_init(); + + sa11x0_register_lcd(&h3100_lcd_info); sa11x0_register_irda(&h3100_irda_data); } MACHINE_START(H3100, "Compaq iPAQ H3100") .atag_offset = 0x100, .map_io = h3100_map_io, + .nr_irqs = SA1100_NR_IRQS, .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = h3100_mach_init, diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c index 6b58e7460ecf..cb6659f294fe 100644 --- a/arch/arm/mach-sa1100/h3600.c +++ b/arch/arm/mach-sa1100/h3600.c @@ -14,11 +14,14 @@ #include <linux/kernel.h> #include <linux/gpio.h> +#include <video/sa1100fb.h> + #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/irda.h> #include <mach/h3xxx.h> +#include <mach/irqs.h> #include "generic.h" @@ -56,11 +59,35 @@ err2: gpio_free(H3XXX_EGPIO_LCD_ON); err1: return; } +static const struct sa1100fb_rgb h3600_rgb_16 = { + .red = { .offset = 12, .length = 4, }, + .green = { .offset = 7, .length = 4, }, + .blue = { .offset = 1, .length = 4, }, + .transp = { .offset = 0, .length = 0, }, +}; + +static struct sa1100fb_mach_info h3600_lcd_info = { + .pixclock = 174757, .bpp = 16, + .xres = 320, .yres = 240, + + .hsync_len = 3, .vsync_len = 3, + .left_margin = 12, .upper_margin = 10, + .right_margin = 17, .lower_margin = 1, + + .cmap_static = 1, + + .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, + .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2), + + .rgb[RGB_16] = &h3600_rgb_16, + + .lcd_power = h3600_lcd_power, +}; + + static void __init h3600_map_io(void) { h3xxx_map_io(); - - sa1100fb_lcd_power = h3600_lcd_power; } /* @@ -121,12 +148,15 @@ static void __init h3600_mach_init(void) { h3xxx_init_gpio(h3600_default_gpio, ARRAY_SIZE(h3600_default_gpio)); h3xxx_mach_init(); + + sa11x0_register_lcd(&h3600_lcd_info); sa11x0_register_irda(&h3600_irda_data); } MACHINE_START(H3600, "Compaq iPAQ H3600") .atag_offset = 0x100, .map_io = h3600_map_io, + .nr_irqs = SA1100_NR_IRQS, .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = h3600_mach_init, diff --git a/arch/arm/mach-sa1100/h3xxx.c b/arch/arm/mach-sa1100/h3xxx.c index b0784c974c2d..63150e1ffe9e 100644 --- a/arch/arm/mach-sa1100/h3xxx.c +++ b/arch/arm/mach-sa1100/h3xxx.c @@ -109,11 +109,8 @@ static struct flash_platform_data h3xxx_flash_data = { .nr_parts = ARRAY_SIZE(h3xxx_partitions), }; -static struct resource h3xxx_flash_resource = { - .start = SA1100_CS0_PHYS, - .end = SA1100_CS0_PHYS + SZ_32M - 1, - .flags = IORESOURCE_MEM, -}; +static struct resource h3xxx_flash_resource = + DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M); /* @@ -186,11 +183,7 @@ static struct sa1100_port_fns h3xxx_port_fns __initdata = { */ static struct resource egpio_resources[] = { - [0] = { - .start = H3600_EGPIO_PHYS, - .end = H3600_EGPIO_PHYS + 0x4 - 1, - .flags = IORESOURCE_MEM, - }, + [0] = DEFINE_RES_MEM(H3600_EGPIO_PHYS, 0x4), }; static struct htc_egpio_chip egpio_chips[] = { diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c index c01bb36db940..5535475bf583 100644 --- a/arch/arm/mach-sa1100/hackkit.c +++ b/arch/arm/mach-sa1100/hackkit.c @@ -22,12 +22,10 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> -#include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/setup.h> #include <asm/page.h> #include <asm/pgtable.h> -#include <asm/irq.h> #include <asm/mach/arch.h> #include <asm/mach/flash.h> @@ -35,6 +33,9 @@ #include <asm/mach/irq.h> #include <asm/mach/serial_sa1100.h> +#include <mach/hardware.h> +#include <mach/irqs.h> + #include "generic.h" /********************************************************************** @@ -179,11 +180,8 @@ static struct flash_platform_data hackkit_flash_data = { .nr_parts = ARRAY_SIZE(hackkit_partitions), }; -static struct resource hackkit_flash_resource = { - .start = SA1100_CS0_PHYS, - .end = SA1100_CS0_PHYS + SZ_32M, - .flags = IORESOURCE_MEM, -}; +static struct resource hackkit_flash_resource = + DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M); static void __init hackkit_init(void) { @@ -197,6 +195,7 @@ static void __init hackkit_init(void) MACHINE_START(HACKKIT, "HackKit Cpu Board") .atag_offset = 0x100, .map_io = hackkit_map_io, + .nr_irqs = SA1100_NR_IRQS, .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = hackkit_init, diff --git a/arch/arm/mach-sa1100/include/mach/SA-1100.h b/arch/arm/mach-sa1100/include/mach/SA-1100.h index bae8296f5dbf..3f2d1b60188c 100644 --- a/arch/arm/mach-sa1100/include/mach/SA-1100.h +++ b/arch/arm/mach-sa1100/include/mach/SA-1100.h @@ -1590,224 +1590,9 @@ /* * Direct Memory Access (DMA) control registers - * - * Registers - * DDAR0 Direct Memory Access (DMA) Device Address Register - * channel 0 (read/write). - * DCSR0 Direct Memory Access (DMA) Control and Status - * Register channel 0 (read/write). - * DBSA0 Direct Memory Access (DMA) Buffer Start address - * register A channel 0 (read/write). - * DBTA0 Direct Memory Access (DMA) Buffer Transfer count - * register A channel 0 (read/write). - * DBSB0 Direct Memory Access (DMA) Buffer Start address - * register B channel 0 (read/write). - * DBTB0 Direct Memory Access (DMA) Buffer Transfer count - * register B channel 0 (read/write). - * - * DDAR1 Direct Memory Access (DMA) Device Address Register - * channel 1 (read/write). - * DCSR1 Direct Memory Access (DMA) Control and Status - * Register channel 1 (read/write). - * DBSA1 Direct Memory Access (DMA) Buffer Start address - * register A channel 1 (read/write). - * DBTA1 Direct Memory Access (DMA) Buffer Transfer count - * register A channel 1 (read/write). - * DBSB1 Direct Memory Access (DMA) Buffer Start address - * register B channel 1 (read/write). - * DBTB1 Direct Memory Access (DMA) Buffer Transfer count - * register B channel 1 (read/write). - * - * DDAR2 Direct Memory Access (DMA) Device Address Register - * channel 2 (read/write). - * DCSR2 Direct Memory Access (DMA) Control and Status - * Register channel 2 (read/write). - * DBSA2 Direct Memory Access (DMA) Buffer Start address - * register A channel 2 (read/write). - * DBTA2 Direct Memory Access (DMA) Buffer Transfer count - * register A channel 2 (read/write). - * DBSB2 Direct Memory Access (DMA) Buffer Start address - * register B channel 2 (read/write). - * DBTB2 Direct Memory Access (DMA) Buffer Transfer count - * register B channel 2 (read/write). - * - * DDAR3 Direct Memory Access (DMA) Device Address Register - * channel 3 (read/write). - * DCSR3 Direct Memory Access (DMA) Control and Status - * Register channel 3 (read/write). - * DBSA3 Direct Memory Access (DMA) Buffer Start address - * register A channel 3 (read/write). - * DBTA3 Direct Memory Access (DMA) Buffer Transfer count - * register A channel 3 (read/write). - * DBSB3 Direct Memory Access (DMA) Buffer Start address - * register B channel 3 (read/write). - * DBTB3 Direct Memory Access (DMA) Buffer Transfer count - * register B channel 3 (read/write). - * - * DDAR4 Direct Memory Access (DMA) Device Address Register - * channel 4 (read/write). - * DCSR4 Direct Memory Access (DMA) Control and Status - * Register channel 4 (read/write). - * DBSA4 Direct Memory Access (DMA) Buffer Start address - * register A channel 4 (read/write). - * DBTA4 Direct Memory Access (DMA) Buffer Transfer count - * register A channel 4 (read/write). - * DBSB4 Direct Memory Access (DMA) Buffer Start address - * register B channel 4 (read/write). - * DBTB4 Direct Memory Access (DMA) Buffer Transfer count - * register B channel 4 (read/write). - * - * DDAR5 Direct Memory Access (DMA) Device Address Register - * channel 5 (read/write). - * DCSR5 Direct Memory Access (DMA) Control and Status - * Register channel 5 (read/write). - * DBSA5 Direct Memory Access (DMA) Buffer Start address - * register A channel 5 (read/write). - * DBTA5 Direct Memory Access (DMA) Buffer Transfer count - * register A channel 5 (read/write). - * DBSB5 Direct Memory Access (DMA) Buffer Start address - * register B channel 5 (read/write). - * DBTB5 Direct Memory Access (DMA) Buffer Transfer count - * register B channel 5 (read/write). */ - -#define DMASp 0x00000020 /* DMA control reg. Space [byte] */ - -#define DDAR(Nb) __REG(0xB0000000 + (Nb)*DMASp) /* DMA Device Address Reg. channel [0..5] */ -#define SetDCSR(Nb) __REG(0xB0000004 + (Nb)*DMASp) /* Set DMA Control & Status Reg. channel [0..5] (write) */ -#define ClrDCSR(Nb) __REG(0xB0000008 + (Nb)*DMASp) /* Clear DMA Control & Status Reg. channel [0..5] (write) */ -#define RdDCSR(Nb) __REG(0xB000000C + (Nb)*DMASp) /* Read DMA Control & Status Reg. channel [0..5] (read) */ -#define DBSA(Nb) __REG(0xB0000010 + (Nb)*DMASp) /* DMA Buffer Start address reg. A channel [0..5] */ -#define DBTA(Nb) __REG(0xB0000014 + (Nb)*DMASp) /* DMA Buffer Transfer count reg. A channel [0..5] */ -#define DBSB(Nb) __REG(0xB0000018 + (Nb)*DMASp) /* DMA Buffer Start address reg. B channel [0..5] */ -#define DBTB(Nb) __REG(0xB000001C + (Nb)*DMASp) /* DMA Buffer Transfer count reg. B channel [0..5] */ - -#define DDAR_RW 0x00000001 /* device data Read/Write */ -#define DDAR_DevWr (DDAR_RW*0) /* Device data Write */ - /* (memory -> device) */ -#define DDAR_DevRd (DDAR_RW*1) /* Device data Read */ - /* (device -> memory) */ -#define DDAR_E 0x00000002 /* big/little Endian device */ -#define DDAR_LtlEnd (DDAR_E*0) /* Little Endian device */ -#define DDAR_BigEnd (DDAR_E*1) /* Big Endian device */ -#define DDAR_BS 0x00000004 /* device Burst Size */ -#define DDAR_Brst4 (DDAR_BS*0) /* Burst-of-4 device */ -#define DDAR_Brst8 (DDAR_BS*1) /* Burst-of-8 device */ -#define DDAR_DW 0x00000008 /* device Data Width */ -#define DDAR_8BitDev (DDAR_DW*0) /* 8-Bit Device */ -#define DDAR_16BitDev (DDAR_DW*1) /* 16-Bit Device */ -#define DDAR_DS Fld (4, 4) /* Device Select */ -#define DDAR_Ser0UDCTr /* Ser. port 0 UDC Transmit */ \ - (0x0 << FShft (DDAR_DS)) -#define DDAR_Ser0UDCRc /* Ser. port 0 UDC Receive */ \ - (0x1 << FShft (DDAR_DS)) -#define DDAR_Ser1SDLCTr /* Ser. port 1 SDLC Transmit */ \ - (0x2 << FShft (DDAR_DS)) -#define DDAR_Ser1SDLCRc /* Ser. port 1 SDLC Receive */ \ - (0x3 << FShft (DDAR_DS)) -#define DDAR_Ser1UARTTr /* Ser. port 1 UART Transmit */ \ - (0x4 << FShft (DDAR_DS)) -#define DDAR_Ser1UARTRc /* Ser. port 1 UART Receive */ \ - (0x5 << FShft (DDAR_DS)) -#define DDAR_Ser2ICPTr /* Ser. port 2 ICP Transmit */ \ - (0x6 << FShft (DDAR_DS)) -#define DDAR_Ser2ICPRc /* Ser. port 2 ICP Receive */ \ - (0x7 << FShft (DDAR_DS)) -#define DDAR_Ser3UARTTr /* Ser. port 3 UART Transmit */ \ - (0x8 << FShft (DDAR_DS)) -#define DDAR_Ser3UARTRc /* Ser. port 3 UART Receive */ \ - (0x9 << FShft (DDAR_DS)) -#define DDAR_Ser4MCP0Tr /* Ser. port 4 MCP 0 Transmit */ \ - /* (audio) */ \ - (0xA << FShft (DDAR_DS)) -#define DDAR_Ser4MCP0Rc /* Ser. port 4 MCP 0 Receive */ \ - /* (audio) */ \ - (0xB << FShft (DDAR_DS)) -#define DDAR_Ser4MCP1Tr /* Ser. port 4 MCP 1 Transmit */ \ - /* (telecom) */ \ - (0xC << FShft (DDAR_DS)) -#define DDAR_Ser4MCP1Rc /* Ser. port 4 MCP 1 Receive */ \ - /* (telecom) */ \ - (0xD << FShft (DDAR_DS)) -#define DDAR_Ser4SSPTr /* Ser. port 4 SSP Transmit */ \ - (0xE << FShft (DDAR_DS)) -#define DDAR_Ser4SSPRc /* Ser. port 4 SSP Receive */ \ - (0xF << FShft (DDAR_DS)) -#define DDAR_DA Fld (24, 8) /* Device Address */ -#define DDAR_DevAdd(Add) /* Device Address */ \ - (((Add) & 0xF0000000) | \ - (((Add) & 0X003FFFFC) << (FShft (DDAR_DA) - 2))) -#define DDAR_Ser0UDCWr /* Ser. port 0 UDC Write */ \ - (DDAR_DevWr + DDAR_Brst8 + DDAR_8BitDev + \ - DDAR_Ser0UDCTr + DDAR_DevAdd (__PREG(Ser0UDCDR))) -#define DDAR_Ser0UDCRd /* Ser. port 0 UDC Read */ \ - (DDAR_DevRd + DDAR_Brst8 + DDAR_8BitDev + \ - DDAR_Ser0UDCRc + DDAR_DevAdd (__PREG(Ser0UDCDR))) -#define DDAR_Ser1UARTWr /* Ser. port 1 UART Write */ \ - (DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \ - DDAR_Ser1UARTTr + DDAR_DevAdd (__PREG(Ser1UTDR))) -#define DDAR_Ser1UARTRd /* Ser. port 1 UART Read */ \ - (DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \ - DDAR_Ser1UARTRc + DDAR_DevAdd (__PREG(Ser1UTDR))) -#define DDAR_Ser1SDLCWr /* Ser. port 1 SDLC Write */ \ - (DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \ - DDAR_Ser1SDLCTr + DDAR_DevAdd (__PREG(Ser1SDDR))) -#define DDAR_Ser1SDLCRd /* Ser. port 1 SDLC Read */ \ - (DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \ - DDAR_Ser1SDLCRc + DDAR_DevAdd (__PREG(Ser1SDDR))) -#define DDAR_Ser2UARTWr /* Ser. port 2 UART Write */ \ - (DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \ - DDAR_Ser2ICPTr + DDAR_DevAdd (__PREG(Ser2UTDR))) -#define DDAR_Ser2UARTRd /* Ser. port 2 UART Read */ \ - (DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \ - DDAR_Ser2ICPRc + DDAR_DevAdd (__PREG(Ser2UTDR))) -#define DDAR_Ser2HSSPWr /* Ser. port 2 HSSP Write */ \ - (DDAR_DevWr + DDAR_Brst8 + DDAR_8BitDev + \ - DDAR_Ser2ICPTr + DDAR_DevAdd (__PREG(Ser2HSDR))) -#define DDAR_Ser2HSSPRd /* Ser. port 2 HSSP Read */ \ - (DDAR_DevRd + DDAR_Brst8 + DDAR_8BitDev + \ - DDAR_Ser2ICPRc + DDAR_DevAdd (__PREG(Ser2HSDR))) -#define DDAR_Ser3UARTWr /* Ser. port 3 UART Write */ \ - (DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \ - DDAR_Ser3UARTTr + DDAR_DevAdd (__PREG(Ser3UTDR))) -#define DDAR_Ser3UARTRd /* Ser. port 3 UART Read */ \ - (DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \ - DDAR_Ser3UARTRc + DDAR_DevAdd (__PREG(Ser3UTDR))) -#define DDAR_Ser4MCP0Wr /* Ser. port 4 MCP 0 Write (audio) */ \ - (DDAR_DevWr + DDAR_Brst4 + DDAR_16BitDev + \ - DDAR_Ser4MCP0Tr + DDAR_DevAdd (__PREG(Ser4MCDR0))) -#define DDAR_Ser4MCP0Rd /* Ser. port 4 MCP 0 Read (audio) */ \ - (DDAR_DevRd + DDAR_Brst4 + DDAR_16BitDev + \ - DDAR_Ser4MCP0Rc + DDAR_DevAdd (__PREG(Ser4MCDR0))) -#define DDAR_Ser4MCP1Wr /* Ser. port 4 MCP 1 Write */ \ - /* (telecom) */ \ - (DDAR_DevWr + DDAR_Brst4 + DDAR_16BitDev + \ - DDAR_Ser4MCP1Tr + DDAR_DevAdd (__PREG(Ser4MCDR1))) -#define DDAR_Ser4MCP1Rd /* Ser. port 4 MCP 1 Read */ \ - /* (telecom) */ \ - (DDAR_DevRd + DDAR_Brst4 + DDAR_16BitDev + \ - DDAR_Ser4MCP1Rc + DDAR_DevAdd (__PREG(Ser4MCDR1))) -#define DDAR_Ser4SSPWr /* Ser. port 4 SSP Write (16 bits) */ \ - (DDAR_DevWr + DDAR_Brst4 + DDAR_16BitDev + \ - DDAR_Ser4SSPTr + DDAR_DevAdd (__PREG(Ser4SSDR))) -#define DDAR_Ser4SSPRd /* Ser. port 4 SSP Read (16 bits) */ \ - (DDAR_DevRd + DDAR_Brst4 + DDAR_16BitDev + \ - DDAR_Ser4SSPRc + DDAR_DevAdd (__PREG(Ser4SSDR))) - -#define DCSR_RUN 0x00000001 /* DMA running */ -#define DCSR_IE 0x00000002 /* DMA Interrupt Enable */ -#define DCSR_ERROR 0x00000004 /* DMA ERROR */ -#define DCSR_DONEA 0x00000008 /* DONE DMA transfer buffer A */ -#define DCSR_STRTA 0x00000010 /* STaRTed DMA transfer buffer A */ -#define DCSR_DONEB 0x00000020 /* DONE DMA transfer buffer B */ -#define DCSR_STRTB 0x00000040 /* STaRTed DMA transfer buffer B */ -#define DCSR_BIU 0x00000080 /* DMA Buffer In Use */ -#define DCSR_BufA (DCSR_BIU*0) /* DMA Buffer A in use */ -#define DCSR_BufB (DCSR_BIU*1) /* DMA Buffer B in use */ - -#define DBT_TC Fld (13, 0) /* Transfer Count */ -#define DBTA_TCA DBT_TC /* Transfer Count buffer A */ -#define DBTB_TCB DBT_TC /* Transfer Count buffer B */ +#define DMA_SIZE (6 * 0x20) +#define DMA_PHYS 0xb0000000 /* @@ -1903,16 +1688,6 @@ #define LCD_Int100_0A 0xF /* LCD Intensity = 100.0% = 1 */ /* (Alternative) */ -#define LCCR0 __REG(0xB0100000) /* LCD Control Reg. 0 */ -#define LCSR __REG(0xB0100004) /* LCD Status Reg. */ -#define DBAR1 __REG(0xB0100010) /* LCD DMA Base Address Reg. channel 1 */ -#define DCAR1 __REG(0xB0100014) /* LCD DMA Current Address Reg. channel 1 */ -#define DBAR2 __REG(0xB0100018) /* LCD DMA Base Address Reg. channel 2 */ -#define DCAR2 __REG(0xB010001C) /* LCD DMA Current Address Reg. channel 2 */ -#define LCCR1 __REG(0xB0100020) /* LCD Control Reg. 1 */ -#define LCCR2 __REG(0xB0100024) /* LCD Control Reg. 2 */ -#define LCCR3 __REG(0xB0100028) /* LCD Control Reg. 3 */ - #define LCCR0_LEN 0x00000001 /* LCD ENable */ #define LCCR0_CMS 0x00000002 /* Color/Monochrome display Select */ #define LCCR0_Color (LCCR0_CMS*0) /* Color display */ diff --git a/arch/arm/mach-sa1100/include/mach/assabet.h b/arch/arm/mach-sa1100/include/mach/assabet.h index 28c2cf50c259..307391488c22 100644 --- a/arch/arm/mach-sa1100/include/mach/assabet.h +++ b/arch/arm/mach-sa1100/include/mach/assabet.h @@ -85,21 +85,18 @@ extern void ASSABET_BCR_frob(unsigned int mask, unsigned int set); #define ASSABET_BSR_RAD_RI (1 << 31) -/* GPIOs for which the generic definition doesn't say much */ +/* GPIOs (bitmasks) for which the generic definition doesn't say much */ #define ASSABET_GPIO_RADIO_IRQ GPIO_GPIO (14) /* Radio interrupt request */ #define ASSABET_GPIO_PS_MODE_SYNC GPIO_GPIO (16) /* Power supply mode/sync */ #define ASSABET_GPIO_STEREO_64FS_CLK GPIO_GPIO (19) /* SSP UDA1341 clock input */ -#define ASSABET_GPIO_CF_IRQ GPIO_GPIO (21) /* CF IRQ */ -#define ASSABET_GPIO_CF_CD GPIO_GPIO (22) /* CF CD */ -#define ASSABET_GPIO_CF_BVD2 GPIO_GPIO (24) /* CF BVD */ #define ASSABET_GPIO_GFX_IRQ GPIO_GPIO (24) /* Graphics IRQ */ -#define ASSABET_GPIO_CF_BVD1 GPIO_GPIO (25) /* CF BVD */ #define ASSABET_GPIO_BATT_LOW GPIO_GPIO (26) /* Low battery */ #define ASSABET_GPIO_RCLK GPIO_GPIO (26) /* CCLK/2 */ -#define ASSABET_IRQ_GPIO_CF_IRQ IRQ_GPIO21 -#define ASSABET_IRQ_GPIO_CF_CD IRQ_GPIO22 -#define ASSABET_IRQ_GPIO_CF_BVD2 IRQ_GPIO24 -#define ASSABET_IRQ_GPIO_CF_BVD1 IRQ_GPIO25 +/* These are gpiolib GPIO numbers, not bitmasks */ +#define ASSABET_GPIO_CF_IRQ 21 /* CF IRQ */ +#define ASSABET_GPIO_CF_CD 22 /* CF CD */ +#define ASSABET_GPIO_CF_BVD2 24 /* CF BVD / IOSPKR */ +#define ASSABET_GPIO_CF_BVD1 25 /* CF BVD / IOSTSCHG */ #endif diff --git a/arch/arm/mach-sa1100/include/mach/cerf.h b/arch/arm/mach-sa1100/include/mach/cerf.h index c3ac3d0f9465..88fd9c006ce0 100644 --- a/arch/arm/mach-sa1100/include/mach/cerf.h +++ b/arch/arm/mach-sa1100/include/mach/cerf.h @@ -14,15 +14,10 @@ #define CERF_ETH_IO 0xf0000000 #define CERF_ETH_IRQ IRQ_GPIO26 -#define CERF_GPIO_CF_BVD2 GPIO_GPIO (19) -#define CERF_GPIO_CF_BVD1 GPIO_GPIO (20) -#define CERF_GPIO_CF_RESET GPIO_GPIO (21) -#define CERF_GPIO_CF_IRQ GPIO_GPIO (22) -#define CERF_GPIO_CF_CD GPIO_GPIO (23) - -#define CERF_IRQ_GPIO_CF_BVD2 IRQ_GPIO19 -#define CERF_IRQ_GPIO_CF_BVD1 IRQ_GPIO20 -#define CERF_IRQ_GPIO_CF_IRQ IRQ_GPIO22 -#define CERF_IRQ_GPIO_CF_CD IRQ_GPIO23 +#define CERF_GPIO_CF_BVD2 19 +#define CERF_GPIO_CF_BVD1 20 +#define CERF_GPIO_CF_RESET 21 +#define CERF_GPIO_CF_IRQ 22 +#define CERF_GPIO_CF_CD 23 #endif // _INCLUDE_CERF_H_ diff --git a/arch/arm/mach-sa1100/include/mach/collie.h b/arch/arm/mach-sa1100/include/mach/collie.h index 52acda7061b7..f33679d2d3ee 100644 --- a/arch/arm/mach-sa1100/include/mach/collie.h +++ b/arch/arm/mach-sa1100/include/mach/collie.h @@ -1,7 +1,7 @@ /* * arch/arm/mach-sa1100/include/mach/collie.h * - * This file contains the hardware specific definitions for Assabet + * This file contains the hardware specific definitions for Collie * Only include this file from SA1100-specific files. * * ChangeLog: @@ -13,6 +13,7 @@ #ifndef __ASM_ARCH_COLLIE_H #define __ASM_ARCH_COLLIE_H +extern void locomolcd_power(int on); #define COLLIE_SCOOP_GPIO_BASE (GPIO_MAX + 1) #define COLLIE_GPIO_CHARGE_ON (COLLIE_SCOOP_GPIO_BASE + 0) diff --git a/arch/arm/mach-sa1100/include/mach/dma.h b/arch/arm/mach-sa1100/include/mach/dma.h deleted file mode 100644 index dda1b351310d..000000000000 --- a/arch/arm/mach-sa1100/include/mach/dma.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * arch/arm/mach-sa1100/include/mach/dma.h - * - * Generic SA1100 DMA support - * - * Copyright (C) 2000 Nicolas Pitre - * - */ - -#ifndef __ASM_ARCH_DMA_H -#define __ASM_ARCH_DMA_H - -#include "hardware.h" - - -/* - * The SA1100 has six internal DMA channels. - */ -#define SA1100_DMA_CHANNELS 6 - -/* - * Maximum physical DMA buffer size - */ -#define MAX_DMA_SIZE 0x1fff -#define CUT_DMA_SIZE 0x1000 - -/* - * All possible SA1100 devices a DMA channel can be attached to. - */ -typedef enum { - DMA_Ser0UDCWr = DDAR_Ser0UDCWr, /* Ser. port 0 UDC Write */ - DMA_Ser0UDCRd = DDAR_Ser0UDCRd, /* Ser. port 0 UDC Read */ - DMA_Ser1UARTWr = DDAR_Ser1UARTWr, /* Ser. port 1 UART Write */ - DMA_Ser1UARTRd = DDAR_Ser1UARTRd, /* Ser. port 1 UART Read */ - DMA_Ser1SDLCWr = DDAR_Ser1SDLCWr, /* Ser. port 1 SDLC Write */ - DMA_Ser1SDLCRd = DDAR_Ser1SDLCRd, /* Ser. port 1 SDLC Read */ - DMA_Ser2UARTWr = DDAR_Ser2UARTWr, /* Ser. port 2 UART Write */ - DMA_Ser2UARTRd = DDAR_Ser2UARTRd, /* Ser. port 2 UART Read */ - DMA_Ser2HSSPWr = DDAR_Ser2HSSPWr, /* Ser. port 2 HSSP Write */ - DMA_Ser2HSSPRd = DDAR_Ser2HSSPRd, /* Ser. port 2 HSSP Read */ - DMA_Ser3UARTWr = DDAR_Ser3UARTWr, /* Ser. port 3 UART Write */ - DMA_Ser3UARTRd = DDAR_Ser3UARTRd, /* Ser. port 3 UART Read */ - DMA_Ser4MCP0Wr = DDAR_Ser4MCP0Wr, /* Ser. port 4 MCP 0 Write (audio) */ - DMA_Ser4MCP0Rd = DDAR_Ser4MCP0Rd, /* Ser. port 4 MCP 0 Read (audio) */ - DMA_Ser4MCP1Wr = DDAR_Ser4MCP1Wr, /* Ser. port 4 MCP 1 Write */ - DMA_Ser4MCP1Rd = DDAR_Ser4MCP1Rd, /* Ser. port 4 MCP 1 Read */ - DMA_Ser4SSPWr = DDAR_Ser4SSPWr, /* Ser. port 4 SSP Write (16 bits) */ - DMA_Ser4SSPRd = DDAR_Ser4SSPRd /* Ser. port 4 SSP Read (16 bits) */ -} dma_device_t; - -typedef struct { - volatile u_long DDAR; - volatile u_long SetDCSR; - volatile u_long ClrDCSR; - volatile u_long RdDCSR; - volatile dma_addr_t DBSA; - volatile u_long DBTA; - volatile dma_addr_t DBSB; - volatile u_long DBTB; -} dma_regs_t; - -typedef void (*dma_callback_t)(void *data); - -/* - * DMA function prototypes - */ - -extern int sa1100_request_dma( dma_device_t device, const char *device_id, - dma_callback_t callback, void *data, - dma_regs_t **regs ); -extern void sa1100_free_dma( dma_regs_t *regs ); -extern int sa1100_start_dma( dma_regs_t *regs, dma_addr_t dma_ptr, u_int size ); -extern dma_addr_t sa1100_get_dma_pos(dma_regs_t *regs); -extern void sa1100_reset_dma(dma_regs_t *regs); - -/** - * sa1100_stop_dma - stop DMA in progress - * @regs: identifier for the channel to use - * - * This stops DMA without clearing buffer pointers. Unlike - * sa1100_clear_dma() this allows subsequent use of sa1100_resume_dma() - * or sa1100_get_dma_pos(). - * - * The @regs identifier is provided by a successful call to - * sa1100_request_dma(). - **/ - -#define sa1100_stop_dma(regs) ((regs)->ClrDCSR = DCSR_IE|DCSR_RUN) - -/** - * sa1100_resume_dma - resume DMA on a stopped channel - * @regs: identifier for the channel to use - * - * This resumes DMA on a channel previously stopped with - * sa1100_stop_dma(). - * - * The @regs identifier is provided by a successful call to - * sa1100_request_dma(). - **/ - -#define sa1100_resume_dma(regs) ((regs)->SetDCSR = DCSR_IE|DCSR_RUN) - -/** - * sa1100_clear_dma - clear DMA pointers - * @regs: identifier for the channel to use - * - * This clear any DMA state so the DMA engine is ready to restart - * with new buffers through sa1100_start_dma(). Any buffers in flight - * are discarded. - * - * The @regs identifier is provided by a successful call to - * sa1100_request_dma(). - **/ - -#define sa1100_clear_dma(regs) ((regs)->ClrDCSR = DCSR_IE|DCSR_RUN|DCSR_STRTA|DCSR_STRTB) - -#endif /* _ASM_ARCH_DMA_H */ diff --git a/arch/arm/mach-sa1100/include/mach/entry-macro.S b/arch/arm/mach-sa1100/include/mach/entry-macro.S index 6aa13c46c5d3..8cf7630bf024 100644 --- a/arch/arm/mach-sa1100/include/mach/entry-macro.S +++ b/arch/arm/mach-sa1100/include/mach/entry-macro.S @@ -8,17 +8,11 @@ * warranty of any kind, whether express or implied. */ - .macro disable_fiq - .endm - .macro get_irqnr_preamble, base, tmp mov \base, #0xfa000000 @ ICIP = 0xfa050000 add \base, \base, #0x00050000 .endm - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \irqstat, [\base] @ get irqs ldr \irqnr, [\base, #4] @ ICMR = 0xfa050004 diff --git a/arch/arm/mach-sa1100/include/mach/io.h b/arch/arm/mach-sa1100/include/mach/io.h deleted file mode 100644 index dfc27ff08344..000000000000 --- a/arch/arm/mach-sa1100/include/mach/io.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * arch/arm/mach-sa1100/include/mach/io.h - * - * Copyright (C) 1997-1999 Russell King - * - * Modifications: - * 06-12-1997 RMK Created. - * 07-04-1999 RMK Major cleanup - */ -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -/* - * __io() is required to be an equivalent mapping to __mem_pci() for - * SOC_COMMON to work. - */ -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#endif diff --git a/arch/arm/mach-sa1100/include/mach/irqs.h b/arch/arm/mach-sa1100/include/mach/irqs.h index d18f21abef80..3790298b7142 100644 --- a/arch/arm/mach-sa1100/include/mach/irqs.h +++ b/arch/arm/mach-sa1100/include/mach/irqs.h @@ -71,22 +71,19 @@ /* * Figure out the MAX IRQ number. * - * If we have an SA1111, the max IRQ is S1_BVD1_STSCHG+1. - * If we have an LoCoMo, the max IRQ is IRQ_BOARD_START + 4 - * Otherwise, we have the standard IRQs only. + * Neponset, SA1111 and UCB1x00 are sparse IRQ aware, so can dynamically + * allocate their IRQs above NR_IRQS. + * + * LoCoMo has 4 additional IRQs, but is not sparse IRQ aware, and so has + * to be included in the NR_IRQS calculation. */ -#ifdef CONFIG_SA1111 -#define NR_IRQS (IRQ_BOARD_END + 55) -#elif defined(CONFIG_SHARP_LOCOMO) -#define NR_IRQS (IRQ_BOARD_START + 4) +#ifdef CONFIG_SHARP_LOCOMO +#define NR_IRQS_LOCOMO 4 #else -#define NR_IRQS (IRQ_BOARD_START) +#define NR_IRQS_LOCOMO 0 #endif -/* - * Board specific IRQs. Define them here. - * Do not surround them with ifdefs. - */ -#define IRQ_NEPONSET_SMC9196 (IRQ_BOARD_START + 0) -#define IRQ_NEPONSET_USAR (IRQ_BOARD_START + 1) -#define IRQ_NEPONSET_SA1111 (IRQ_BOARD_START + 2) +#ifndef NR_IRQS +#define NR_IRQS (IRQ_BOARD_START + NR_IRQS_LOCOMO) +#endif +#define SA1100_NR_IRQS (IRQ_BOARD_START + NR_IRQS_LOCOMO) diff --git a/arch/arm/mach-sa1100/include/mach/mcp.h b/arch/arm/mach-sa1100/include/mach/mcp.h index ed1a331508a7..4b2860ae3828 100644 --- a/arch/arm/mach-sa1100/include/mach/mcp.h +++ b/arch/arm/mach-sa1100/include/mach/mcp.h @@ -16,7 +16,7 @@ struct mcp_plat_data { u32 mccr0; u32 mccr1; unsigned int sclk_rate; - int gpio_base; + void *codec_pdata; }; #endif diff --git a/arch/arm/mach-sa1100/include/mach/nanoengine.h b/arch/arm/mach-sa1100/include/mach/nanoengine.h index 14f8382d0665..5ebd469a31f2 100644 --- a/arch/arm/mach-sa1100/include/mach/nanoengine.h +++ b/arch/arm/mach-sa1100/include/mach/nanoengine.h @@ -16,12 +16,12 @@ #include <mach/irqs.h> -#define GPIO_PC_READY0 GPIO_GPIO(11) /* ready for socket 0 (active high)*/ -#define GPIO_PC_READY1 GPIO_GPIO(12) /* ready for socket 1 (active high) */ -#define GPIO_PC_CD0 GPIO_GPIO(13) /* detect for socket 0 (active low) */ -#define GPIO_PC_CD1 GPIO_GPIO(14) /* detect for socket 1 (active low) */ -#define GPIO_PC_RESET0 GPIO_GPIO(15) /* reset socket 0 */ -#define GPIO_PC_RESET1 GPIO_GPIO(16) /* reset socket 1 */ +#define GPIO_PC_READY0 11 /* ready for socket 0 (active high)*/ +#define GPIO_PC_READY1 12 /* ready for socket 1 (active high) */ +#define GPIO_PC_CD0 13 /* detect for socket 0 (active low) */ +#define GPIO_PC_CD1 14 /* detect for socket 1 (active low) */ +#define GPIO_PC_RESET0 15 /* reset socket 0 */ +#define GPIO_PC_RESET1 16 /* reset socket 1 */ #define NANOENGINE_IRQ_GPIO_PCI IRQ_GPIO0 #define NANOENGINE_IRQ_GPIO_PC_READY0 IRQ_GPIO11 diff --git a/arch/arm/mach-sa1100/include/mach/neponset.h b/arch/arm/mach-sa1100/include/mach/neponset.h index ffe2bc45eed0..5516a52a329d 100644 --- a/arch/arm/mach-sa1100/include/mach/neponset.h +++ b/arch/arm/mach-sa1100/include/mach/neponset.h @@ -15,54 +15,6 @@ /* * Neponset definitions: */ - -#define NEPONSET_CPLD_BASE (0x10000000) -#define Nep_p2v( x ) ((x) - NEPONSET_CPLD_BASE + 0xf3000000) -#define Nep_v2p( x ) ((x) - 0xf3000000 + NEPONSET_CPLD_BASE) - -#define _IRR 0x10000024 /* Interrupt Reason Register */ -#define _AUD_CTL 0x100000c0 /* Audio controls (RW) */ -#define _MDM_CTL_0 0x100000b0 /* Modem control 0 (RW) */ -#define _MDM_CTL_1 0x100000b4 /* Modem control 1 (RW) */ -#define _NCR_0 0x100000a0 /* Control Register (RW) */ -#define _KP_X_OUT 0x10000090 /* Keypad row write (RW) */ -#define _KP_Y_IN 0x10000080 /* Keypad column read (RO) */ -#define _SWPK 0x10000020 /* Switch pack (RO) */ -#define _WHOAMI 0x10000000 /* System ID Register (RO) */ - -#define _LEDS 0x10000010 /* LEDs [31:0] (WO) */ - -#define IRR (*((volatile u_char *) Nep_p2v(_IRR))) -#define AUD_CTL (*((volatile u_char *) Nep_p2v(_AUD_CTL))) -#define MDM_CTL_0 (*((volatile u_char *) Nep_p2v(_MDM_CTL_0))) -#define MDM_CTL_1 (*((volatile u_char *) Nep_p2v(_MDM_CTL_1))) -#define NCR_0 (*((volatile u_char *) Nep_p2v(_NCR_0))) -#define KP_X_OUT (*((volatile u_char *) Nep_p2v(_KP_X_OUT))) -#define KP_Y_IN (*((volatile u_char *) Nep_p2v(_KP_Y_IN))) -#define SWPK (*((volatile u_char *) Nep_p2v(_SWPK))) -#define WHOAMI (*((volatile u_char *) Nep_p2v(_WHOAMI))) - -#define LEDS (*((volatile Word *) Nep_p2v(_LEDS))) - -#define IRR_ETHERNET (1<<0) -#define IRR_USAR (1<<1) -#define IRR_SA1111 (1<<2) - -#define AUD_SEL_1341 (1<<0) -#define AUD_MUTE_1341 (1<<1) - -#define MDM_CTL0_RTS1 (1 << 0) -#define MDM_CTL0_DTR1 (1 << 1) -#define MDM_CTL0_RTS2 (1 << 2) -#define MDM_CTL0_DTR2 (1 << 3) - -#define MDM_CTL1_CTS1 (1 << 0) -#define MDM_CTL1_DSR1 (1 << 1) -#define MDM_CTL1_DCD1 (1 << 2) -#define MDM_CTL1_CTS2 (1 << 3) -#define MDM_CTL1_DSR2 (1 << 4) -#define MDM_CTL1_DCD2 (1 << 5) - #define NCR_GP01_OFF (1<<0) #define NCR_TP_PWR_EN (1<<1) #define NCR_MS_PWR_EN (1<<2) @@ -71,4 +23,8 @@ #define NCR_A0VPP (1<<5) #define NCR_A1VPP (1<<6) +void neponset_ncr_frob(unsigned int, unsigned int); +#define neponset_ncr_set(v) neponset_ncr_frob(0, v) +#define neponset_ncr_clear(v) neponset_ncr_frob(v, 0) + #endif diff --git a/arch/arm/mach-sa1100/include/mach/shannon.h b/arch/arm/mach-sa1100/include/mach/shannon.h index ec27d6e12140..fff39e02b496 100644 --- a/arch/arm/mach-sa1100/include/mach/shannon.h +++ b/arch/arm/mach-sa1100/include/mach/shannon.h @@ -21,16 +21,12 @@ #define SHANNON_GPIO_U3_RTS GPIO_GPIO (19) /* ?? */ #define SHANNON_GPIO_U3_CTS GPIO_GPIO (20) /* ?? */ #define SHANNON_GPIO_SENSE_12V GPIO_GPIO (21) /* Input, 12v flash unprotect detected */ -#define SHANNON_GPIO_DISP_EN GPIO_GPIO (22) /* out */ +#define SHANNON_GPIO_DISP_EN 22 /* out */ /* XXX GPIO 23 unaccounted for */ -#define SHANNON_GPIO_EJECT_0 GPIO_GPIO (24) /* in */ -#define SHANNON_IRQ_GPIO_EJECT_0 IRQ_GPIO24 -#define SHANNON_GPIO_EJECT_1 GPIO_GPIO (25) /* in */ -#define SHANNON_IRQ_GPIO_EJECT_1 IRQ_GPIO25 -#define SHANNON_GPIO_RDY_0 GPIO_GPIO (26) /* in */ -#define SHANNON_IRQ_GPIO_RDY_0 IRQ_GPIO26 -#define SHANNON_GPIO_RDY_1 GPIO_GPIO (27) /* in */ -#define SHANNON_IRQ_GPIO_RDY_1 IRQ_GPIO27 +#define SHANNON_GPIO_EJECT_0 24 /* in */ +#define SHANNON_GPIO_EJECT_1 25 /* in */ +#define SHANNON_GPIO_RDY_0 26 /* in */ +#define SHANNON_GPIO_RDY_1 27 /* in */ /* MCP UCB codec GPIO pins... */ diff --git a/arch/arm/mach-sa1100/include/mach/simpad.h b/arch/arm/mach-sa1100/include/mach/simpad.h index db28118103eb..cdea671e8931 100644 --- a/arch/arm/mach-sa1100/include/mach/simpad.h +++ b/arch/arm/mach-sa1100/include/mach/simpad.h @@ -39,10 +39,8 @@ /*--- PCMCIA ---*/ -#define GPIO_CF_CD GPIO_GPIO24 -#define GPIO_CF_IRQ GPIO_GPIO1 -#define IRQ_GPIO_CF_IRQ IRQ_GPIO1 -#define IRQ_GPIO_CF_CD IRQ_GPIO24 +#define GPIO_CF_CD 24 +#define GPIO_CF_IRQ 1 /*--- SmartCard ---*/ #define GPIO_SMART_CARD GPIO_GPIO10 diff --git a/arch/arm/mach-sa1100/include/mach/system.h b/arch/arm/mach-sa1100/include/mach/system.h deleted file mode 100644 index e17b208f76d4..000000000000 --- a/arch/arm/mach-sa1100/include/mach/system.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * arch/arm/mach-sa1100/include/mach/system.h - * - * Copyright (c) 1999 Nicolas Pitre <nico@fluxnic.net> - */ -static inline void arch_idle(void) -{ - cpu_do_idle(); -} diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c index dfbf824a69fa..516ccc25d7fd 100644 --- a/arch/arm/mach-sa1100/irq.c +++ b/arch/arm/mach-sa1100/irq.c @@ -17,6 +17,7 @@ #include <linux/syscore_ops.h> #include <mach/hardware.h> +#include <mach/irqs.h> #include <asm/mach/irq.h> #include "generic.h" @@ -221,11 +222,8 @@ static struct irq_chip sa1100_normal_chip = { .irq_set_wake = sa1100_set_wake, }; -static struct resource irq_resource = { - .name = "irqs", - .start = 0x90050000, - .end = 0x9005ffff, -}; +static struct resource irq_resource = + DEFINE_RES_MEM_NAMED(0x90050000, SZ_64K, "irqs"); static struct sa1100irq_state { unsigned int saved; diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c index ee121d6f0480..ca7a7e834720 100644 --- a/arch/arm/mach-sa1100/jornada720.c +++ b/arch/arm/mach-sa1100/jornada720.c @@ -23,9 +23,7 @@ #include <linux/mtd/partitions.h> #include <video/s1d13xxxfb.h> -#include <mach/hardware.h> #include <asm/hardware/sa1111.h> -#include <asm/irq.h> #include <asm/page.h> #include <asm/mach-types.h> #include <asm/setup.h> @@ -34,6 +32,9 @@ #include <asm/mach/map.h> #include <asm/mach/serial_sa1100.h> +#include <mach/hardware.h> +#include <mach/irqs.h> + #include "generic.h" /* @@ -46,7 +47,7 @@ /* memory space (line 52 of HP's doc) */ #define SA1111REGSTART 0x40000000 -#define SA1111REGLEN 0x00001fff +#define SA1111REGLEN 0x00002000 #define EPSONREGSTART 0x48000000 #define EPSONREGLEN 0x00100000 #define EPSONFBSTART 0x48200000 @@ -174,16 +175,8 @@ static struct s1d13xxxfb_pdata s1d13xxxfb_data = { }; static struct resource s1d13xxxfb_resources[] = { - [0] = { - .start = EPSONFBSTART, - .end = EPSONFBSTART + EPSONFBLEN, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = EPSONREGSTART, - .end = EPSONREGSTART + EPSONREGLEN, - .flags = IORESOURCE_MEM, - } + [0] = DEFINE_RES_MEM(EPSONFBSTART, EPSONFBLEN), + [1] = DEFINE_RES_MEM(EPSONREGSTART, EPSONREGLEN), }; static struct platform_device s1d13xxxfb_device = { @@ -197,20 +190,12 @@ static struct platform_device s1d13xxxfb_device = { }; static struct resource sa1111_resources[] = { - [0] = { - .start = SA1111REGSTART, - .end = SA1111REGSTART + SA1111REGLEN, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_GPIO1, - .end = IRQ_GPIO1, - .flags = IORESOURCE_IRQ, - }, + [0] = DEFINE_RES_MEM(SA1111REGSTART, SA1111REGLEN), + [1] = DEFINE_RES_IRQ(IRQ_GPIO1), }; static struct sa1111_platform_data sa1111_info = { - .irq_base = IRQ_BOARD_END, + .disable_devs = SA1111_DEVID_PS2_MSE, }; static u64 sa1111_dmamask = 0xffffffffUL; @@ -284,11 +269,6 @@ static struct map_desc jornada720_io_desc[] __initdata = { .pfn = __phys_to_pfn(EPSONFBSTART), .length = EPSONFBLEN, .type = MT_DEVICE - }, { /* SA-1111 */ - .virtual = 0xf4000000, - .pfn = __phys_to_pfn(SA1111REGSTART), - .length = SA1111REGLEN, - .type = MT_DEVICE } }; @@ -352,11 +332,8 @@ static struct flash_platform_data jornada720_flash_data = { .nr_parts = ARRAY_SIZE(jornada720_partitions), }; -static struct resource jornada720_flash_resource = { - .start = SA1100_CS0_PHYS, - .end = SA1100_CS0_PHYS + SZ_32M - 1, - .flags = IORESOURCE_MEM, -}; +static struct resource jornada720_flash_resource = + DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M); static void __init jornada720_mach_init(void) { @@ -367,6 +344,7 @@ MACHINE_START(JORNADA720, "HP Jornada 720") /* Maintainer: Kristoffer Ericson <Kristoffer.Ericson@gmail.com> */ .atag_offset = 0x100, .map_io = jornada720_map_io, + .nr_irqs = SA1100_NR_IRQS, .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = jornada720_mach_init, diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c index af4e2761f3db..eb6534e0b0d0 100644 --- a/arch/arm/mach-sa1100/lart.c +++ b/arch/arm/mach-sa1100/lart.c @@ -6,6 +6,8 @@ #include <linux/kernel.h> #include <linux/tty.h> +#include <video/sa1100fb.h> + #include <mach/hardware.h> #include <asm/setup.h> #include <asm/mach-types.h> @@ -15,6 +17,7 @@ #include <asm/mach/map.h> #include <asm/mach/serial_sa1100.h> #include <mach/mcp.h> +#include <mach/irqs.h> #include "generic.h" @@ -26,8 +29,86 @@ static struct mcp_plat_data lart_mcp_data = { .sclk_rate = 11981000, }; +#ifdef LART_GREY_LCD +static struct sa1100fb_mach_info lart_grey_info = { + .pixclock = 150000, .bpp = 4, + .xres = 320, .yres = 240, + + .hsync_len = 1, .vsync_len = 1, + .left_margin = 4, .upper_margin = 0, + .right_margin = 2, .lower_margin = 0, + + .cmap_greyscale = 1, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + + .lccr0 = LCCR0_Mono | LCCR0_Sngl | LCCR0_Pas | LCCR0_4PixMono, + .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512), +}; +#endif +#ifdef LART_COLOR_LCD +static struct sa1100fb_mach_info lart_color_info = { + .pixclock = 150000, .bpp = 16, + .xres = 320, .yres = 240, + + .hsync_len = 2, .vsync_len = 3, + .left_margin = 69, .upper_margin = 14, + .right_margin = 8, .lower_margin = 4, + + .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, + .lccr3 = LCCR3_OutEnH | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512), +}; +#endif +#ifdef LART_VIDEO_OUT +static struct sa1100fb_mach_info lart_video_info = { + .pixclock = 39721, .bpp = 16, + .xres = 640, .yres = 480, + + .hsync_len = 95, .vsync_len = 2, + .left_margin = 40, .upper_margin = 32, + .right_margin = 24, .lower_margin = 11, + + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + + .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, + .lccr3 = LCCR3_OutEnL | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512), +}; +#endif + +#ifdef LART_KIT01_LCD +static struct sa1100fb_mach_info lart_kit01_info = { + .pixclock = 63291, .bpp = 16, + .xres = 640, .yres = 480, + + .hsync_len = 64, .vsync_len = 3, + .left_margin = 122, .upper_margin = 45, + .right_margin = 10, .lower_margin = 10, + + .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, + .lccr3 = LCCR3_OutEnH | LCCR3_PixFlEdg +}; +#endif + static void __init lart_init(void) { + struct sa1100fb_mach_info *inf = NULL; + +#ifdef LART_GREY_LCD + inf = &lart_grey_info; +#endif +#ifdef LART_COLOR_LCD + inf = &lart_color_info; +#endif +#ifdef LART_VIDEO_OUT + inf = &lart_video_info; +#endif +#ifdef LART_KIT01_LCD + inf = &lart_kit01_info; +#endif + + if (inf) + sa11x0_register_lcd(inf); + + sa11x0_ppc_configure_mcp(); sa11x0_register_mcp(&lart_mcp_data); } @@ -63,6 +144,7 @@ static void __init lart_map_io(void) MACHINE_START(LART, "LART") .atag_offset = 0x100, .map_io = lart_map_io, + .nr_irqs = SA1100_NR_IRQS, .init_irq = sa1100_init_irq, .init_machine = lart_init, .timer = &sa1100_timer, diff --git a/arch/arm/mach-sa1100/leds-assabet.c b/arch/arm/mach-sa1100/leds-assabet.c index 64e9b4b11b54..3699176bca94 100644 --- a/arch/arm/mach-sa1100/leds-assabet.c +++ b/arch/arm/mach-sa1100/leds-assabet.c @@ -13,7 +13,6 @@ #include <mach/hardware.h> #include <asm/leds.h> -#include <asm/system.h> #include <mach/assabet.h> #include "leds.h" diff --git a/arch/arm/mach-sa1100/leds-badge4.c b/arch/arm/mach-sa1100/leds-badge4.c index cf1e38458b81..f99fac3eedb6 100644 --- a/arch/arm/mach-sa1100/leds-badge4.c +++ b/arch/arm/mach-sa1100/leds-badge4.c @@ -14,7 +14,6 @@ #include <mach/hardware.h> #include <asm/leds.h> -#include <asm/system.h> #include "leds.h" diff --git a/arch/arm/mach-sa1100/leds-cerf.c b/arch/arm/mach-sa1100/leds-cerf.c index 259b48e0be89..040540fb7d8a 100644 --- a/arch/arm/mach-sa1100/leds-cerf.c +++ b/arch/arm/mach-sa1100/leds-cerf.c @@ -7,7 +7,6 @@ #include <mach/hardware.h> #include <asm/leds.h> -#include <asm/system.h> #include "leds.h" diff --git a/arch/arm/mach-sa1100/leds-hackkit.c b/arch/arm/mach-sa1100/leds-hackkit.c index 2bce137462e4..6a2352436e62 100644 --- a/arch/arm/mach-sa1100/leds-hackkit.c +++ b/arch/arm/mach-sa1100/leds-hackkit.c @@ -13,7 +13,6 @@ #include <mach/hardware.h> #include <asm/leds.h> -#include <asm/system.h> #include "leds.h" diff --git a/arch/arm/mach-sa1100/leds-lart.c b/arch/arm/mach-sa1100/leds-lart.c index 0505a1fdcdb2..a51830c60e53 100644 --- a/arch/arm/mach-sa1100/leds-lart.c +++ b/arch/arm/mach-sa1100/leds-lart.c @@ -13,7 +13,6 @@ #include <mach/hardware.h> #include <asm/leds.h> -#include <asm/system.h> #include "leds.h" diff --git a/arch/arm/mach-sa1100/nanoengine.c b/arch/arm/mach-sa1100/nanoengine.c index 85f6ee672225..8f6446b9f025 100644 --- a/arch/arm/mach-sa1100/nanoengine.c +++ b/arch/arm/mach-sa1100/nanoengine.c @@ -28,6 +28,7 @@ #include <mach/hardware.h> #include <mach/nanoengine.h> +#include <mach/irqs.h> #include "generic.h" @@ -58,15 +59,8 @@ static struct flash_platform_data nanoengine_flash_data = { }; static struct resource nanoengine_flash_resources[] = { - { - .start = SA1100_CS0_PHYS, - .end = SA1100_CS0_PHYS + SZ_32M - 1, - .flags = IORESOURCE_MEM, - }, { - .start = SA1100_CS1_PHYS, - .end = SA1100_CS1_PHYS + SZ_32M - 1, - .flags = IORESOURCE_MEM, - } + DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M), + DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_32M), }; static struct map_desc nanoengine_io_desc[] __initdata = { @@ -114,6 +108,7 @@ static void __init nanoengine_init(void) MACHINE_START(NANOENGINE, "BSE nanoEngine") .atag_offset = 0x100, .map_io = nanoengine_map_io, + .nr_irqs = SA1100_NR_IRQS, .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = nanoengine_init, diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index b4fa53a1427e..6c58f01b358a 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c @@ -1,89 +1,104 @@ /* * linux/arch/arm/mach-sa1100/neponset.c - * */ -#include <linux/kernel.h> +#include <linux/err.h> #include <linux/init.h> -#include <linux/tty.h> #include <linux/ioport.h> -#include <linux/serial_core.h> +#include <linux/irq.h> +#include <linux/kernel.h> +#include <linux/module.h> #include <linux/platform_device.h> +#include <linux/pm.h> +#include <linux/serial_core.h> +#include <linux/slab.h> -#include <mach/hardware.h> #include <asm/mach-types.h> -#include <asm/irq.h> #include <asm/mach/map.h> -#include <asm/mach/irq.h> #include <asm/mach/serial_sa1100.h> -#include <mach/assabet.h> -#include <mach/neponset.h> #include <asm/hardware/sa1111.h> #include <asm/sizes.h> -/* - * Install handler for Neponset IRQ. Note that we have to loop here - * since the ETHERNET and USAR IRQs are level based, and we need to - * ensure that the IRQ signal is deasserted before returning. This - * is rather unfortunate. - */ -static void -neponset_irq_handler(unsigned int irq, struct irq_desc *desc) -{ - unsigned int irr; - - while (1) { - /* - * Acknowledge the parent IRQ. - */ - desc->irq_data.chip->irq_ack(&desc->irq_data); - - /* - * Read the interrupt reason register. Let's have all - * active IRQ bits high. Note: there is a typo in the - * Neponset user's guide for the SA1111 IRR level. - */ - irr = IRR ^ (IRR_ETHERNET | IRR_USAR); - - if ((irr & (IRR_ETHERNET | IRR_USAR | IRR_SA1111)) == 0) - break; - - /* - * Since there is no individual mask, we have to - * mask the parent IRQ. This is safe, since we'll - * recheck the register for any pending IRQs. - */ - if (irr & (IRR_ETHERNET | IRR_USAR)) { - desc->irq_data.chip->irq_mask(&desc->irq_data); - - /* - * Ack the interrupt now to prevent re-entering - * this neponset handler. Again, this is safe - * since we'll check the IRR register prior to - * leaving. - */ - desc->irq_data.chip->irq_ack(&desc->irq_data); +#include <mach/hardware.h> +#include <mach/assabet.h> +#include <mach/neponset.h> +#include <mach/irqs.h> + +#define NEP_IRQ_SMC91X 0 +#define NEP_IRQ_USAR 1 +#define NEP_IRQ_SA1111 2 +#define NEP_IRQ_NR 3 + +#define WHOAMI 0x00 +#define LEDS 0x10 +#define SWPK 0x20 +#define IRR 0x24 +#define KP_Y_IN 0x80 +#define KP_X_OUT 0x90 +#define NCR_0 0xa0 +#define MDM_CTL_0 0xb0 +#define MDM_CTL_1 0xb4 +#define AUD_CTL 0xc0 + +#define IRR_ETHERNET (1 << 0) +#define IRR_USAR (1 << 1) +#define IRR_SA1111 (1 << 2) + +#define MDM_CTL0_RTS1 (1 << 0) +#define MDM_CTL0_DTR1 (1 << 1) +#define MDM_CTL0_RTS2 (1 << 2) +#define MDM_CTL0_DTR2 (1 << 3) + +#define MDM_CTL1_CTS1 (1 << 0) +#define MDM_CTL1_DSR1 (1 << 1) +#define MDM_CTL1_DCD1 (1 << 2) +#define MDM_CTL1_CTS2 (1 << 3) +#define MDM_CTL1_DSR2 (1 << 4) +#define MDM_CTL1_DCD2 (1 << 5) + +#define AUD_SEL_1341 (1 << 0) +#define AUD_MUTE_1341 (1 << 1) - if (irr & IRR_ETHERNET) { - generic_handle_irq(IRQ_NEPONSET_SMC9196); - } +extern void sa1110_mb_disable(void); - if (irr & IRR_USAR) { - generic_handle_irq(IRQ_NEPONSET_USAR); - } +struct neponset_drvdata { + void __iomem *base; + struct platform_device *sa1111; + struct platform_device *smc91x; + unsigned irq_base; +#ifdef CONFIG_PM_SLEEP + u32 ncr0; + u32 mdm_ctl_0; +#endif +}; - desc->irq_data.chip->irq_unmask(&desc->irq_data); - } +static void __iomem *nep_base; - if (irr & IRR_SA1111) { - generic_handle_irq(IRQ_NEPONSET_SA1111); - } +void neponset_ncr_frob(unsigned int mask, unsigned int val) +{ + void __iomem *base = nep_base; + + if (base) { + unsigned long flags; + unsigned v; + + local_irq_save(flags); + v = readb_relaxed(base + NCR_0); + writeb_relaxed((v & ~mask) | val, base + NCR_0); + local_irq_restore(flags); + } else { + WARN(1, "nep_base unset\n"); } } static void neponset_set_mctrl(struct uart_port *port, u_int mctrl) { - u_int mdm_ctl0 = MDM_CTL_0; + void __iomem *base = nep_base; + u_int mdm_ctl0; + if (!base) + return; + + mdm_ctl0 = readb_relaxed(base + MDM_CTL_0); if (port->mapbase == _Ser1UTCR0) { if (mctrl & TIOCM_RTS) mdm_ctl0 &= ~MDM_CTL0_RTS2; @@ -106,14 +121,19 @@ static void neponset_set_mctrl(struct uart_port *port, u_int mctrl) mdm_ctl0 |= MDM_CTL0_DTR1; } - MDM_CTL_0 = mdm_ctl0; + writeb_relaxed(mdm_ctl0, base + MDM_CTL_0); } static u_int neponset_get_mctrl(struct uart_port *port) { + void __iomem *base = nep_base; u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR; - u_int mdm_ctl1 = MDM_CTL_1; + u_int mdm_ctl1; + + if (!base) + return ret; + mdm_ctl1 = readb_relaxed(base + MDM_CTL_1); if (port->mapbase == _Ser1UTCR0) { if (mdm_ctl1 & MDM_CTL1_DCD2) ret &= ~TIOCM_CD; @@ -138,209 +158,278 @@ static struct sa1100_port_fns neponset_port_fns __devinitdata = { .get_mctrl = neponset_get_mctrl, }; -static int __devinit neponset_probe(struct platform_device *dev) +/* + * Install handler for Neponset IRQ. Note that we have to loop here + * since the ETHERNET and USAR IRQs are level based, and we need to + * ensure that the IRQ signal is deasserted before returning. This + * is rather unfortunate. + */ +static void neponset_irq_handler(unsigned int irq, struct irq_desc *desc) { - sa1100_register_uart_fns(&neponset_port_fns); + struct neponset_drvdata *d = irq_desc_get_handler_data(desc); + unsigned int irr; - /* - * Install handler for GPIO25. - */ - irq_set_irq_type(IRQ_GPIO25, IRQ_TYPE_EDGE_RISING); - irq_set_chained_handler(IRQ_GPIO25, neponset_irq_handler); + while (1) { + /* + * Acknowledge the parent IRQ. + */ + desc->irq_data.chip->irq_ack(&desc->irq_data); - /* - * We would set IRQ_GPIO25 to be a wake-up IRQ, but - * unfortunately something on the Neponset activates - * this IRQ on sleep (ethernet?) - */ -#if 0 - enable_irq_wake(IRQ_GPIO25); -#endif + /* + * Read the interrupt reason register. Let's have all + * active IRQ bits high. Note: there is a typo in the + * Neponset user's guide for the SA1111 IRR level. + */ + irr = readb_relaxed(d->base + IRR); + irr ^= IRR_ETHERNET | IRR_USAR; - /* - * Setup other Neponset IRQs. SA1111 will be done by the - * generic SA1111 code. - */ - irq_set_handler(IRQ_NEPONSET_SMC9196, handle_simple_irq); - set_irq_flags(IRQ_NEPONSET_SMC9196, IRQF_VALID | IRQF_PROBE); - irq_set_handler(IRQ_NEPONSET_USAR, handle_simple_irq); - set_irq_flags(IRQ_NEPONSET_USAR, IRQF_VALID | IRQF_PROBE); + if ((irr & (IRR_ETHERNET | IRR_USAR | IRR_SA1111)) == 0) + break; - /* - * Disable GPIO 0/1 drivers so the buttons work on the module. - */ - NCR_0 = NCR_GP01_OFF; + /* + * Since there is no individual mask, we have to + * mask the parent IRQ. This is safe, since we'll + * recheck the register for any pending IRQs. + */ + if (irr & (IRR_ETHERNET | IRR_USAR)) { + desc->irq_data.chip->irq_mask(&desc->irq_data); - return 0; -} + /* + * Ack the interrupt now to prevent re-entering + * this neponset handler. Again, this is safe + * since we'll check the IRR register prior to + * leaving. + */ + desc->irq_data.chip->irq_ack(&desc->irq_data); -#ifdef CONFIG_PM + if (irr & IRR_ETHERNET) + generic_handle_irq(d->irq_base + NEP_IRQ_SMC91X); -/* - * LDM power management. - */ -static unsigned int neponset_saved_state; + if (irr & IRR_USAR) + generic_handle_irq(d->irq_base + NEP_IRQ_USAR); -static int neponset_suspend(struct platform_device *dev, pm_message_t state) -{ - /* - * Save state. - */ - neponset_saved_state = NCR_0; + desc->irq_data.chip->irq_unmask(&desc->irq_data); + } - return 0; + if (irr & IRR_SA1111) + generic_handle_irq(d->irq_base + NEP_IRQ_SA1111); + } } -static int neponset_resume(struct platform_device *dev) +/* Yes, we really do not have any kind of masking or unmasking */ +static void nochip_noop(struct irq_data *irq) { - NCR_0 = neponset_saved_state; - - return 0; } -#else -#define neponset_suspend NULL -#define neponset_resume NULL -#endif - -static struct platform_driver neponset_device_driver = { - .probe = neponset_probe, - .suspend = neponset_suspend, - .resume = neponset_resume, - .driver = { - .name = "neponset", - }, -}; - -static struct resource neponset_resources[] = { - [0] = { - .start = 0x10000000, - .end = 0x17ffffff, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device neponset_device = { - .name = "neponset", - .id = 0, - .num_resources = ARRAY_SIZE(neponset_resources), - .resource = neponset_resources, -}; - -static struct resource sa1111_resources[] = { - [0] = { - .start = 0x40000000, - .end = 0x40001fff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_NEPONSET_SA1111, - .end = IRQ_NEPONSET_SA1111, - .flags = IORESOURCE_IRQ, - }, +static struct irq_chip nochip = { + .name = "neponset", + .irq_ack = nochip_noop, + .irq_mask = nochip_noop, + .irq_unmask = nochip_noop, }; static struct sa1111_platform_data sa1111_info = { - .irq_base = IRQ_BOARD_END, + .disable_devs = SA1111_DEVID_PS2_MSE, }; -static u64 sa1111_dmamask = 0xffffffffUL; +static int __devinit neponset_probe(struct platform_device *dev) +{ + struct neponset_drvdata *d; + struct resource *nep_res, *sa1111_res, *smc91x_res; + struct resource sa1111_resources[] = { + DEFINE_RES_MEM(0x40000000, SZ_8K), + { .flags = IORESOURCE_IRQ }, + }; + struct platform_device_info sa1111_devinfo = { + .parent = &dev->dev, + .name = "sa1111", + .id = 0, + .res = sa1111_resources, + .num_res = ARRAY_SIZE(sa1111_resources), + .data = &sa1111_info, + .size_data = sizeof(sa1111_info), + .dma_mask = 0xffffffffUL, + }; + struct resource smc91x_resources[] = { + DEFINE_RES_MEM_NAMED(SA1100_CS3_PHYS, + 0x02000000, "smc91x-regs"), + DEFINE_RES_MEM_NAMED(SA1100_CS3_PHYS + 0x02000000, + 0x02000000, "smc91x-attrib"), + { .flags = IORESOURCE_IRQ }, + }; + struct platform_device_info smc91x_devinfo = { + .parent = &dev->dev, + .name = "smc91x", + .id = 0, + .res = smc91x_resources, + .num_res = ARRAY_SIZE(smc91x_resources), + }; + int ret, irq; + + if (nep_base) + return -EBUSY; + + irq = ret = platform_get_irq(dev, 0); + if (ret < 0) + goto err_alloc; + + nep_res = platform_get_resource(dev, IORESOURCE_MEM, 0); + smc91x_res = platform_get_resource(dev, IORESOURCE_MEM, 1); + sa1111_res = platform_get_resource(dev, IORESOURCE_MEM, 2); + if (!nep_res || !smc91x_res || !sa1111_res) { + ret = -ENXIO; + goto err_alloc; + } -static struct platform_device sa1111_device = { - .name = "sa1111", - .id = 0, - .dev = { - .dma_mask = &sa1111_dmamask, - .coherent_dma_mask = 0xffffffff, - .platform_data = &sa1111_info, - }, - .num_resources = ARRAY_SIZE(sa1111_resources), - .resource = sa1111_resources, -}; + d = kzalloc(sizeof(*d), GFP_KERNEL); + if (!d) { + ret = -ENOMEM; + goto err_alloc; + } -static struct resource smc91x_resources[] = { - [0] = { - .name = "smc91x-regs", - .start = SA1100_CS3_PHYS, - .end = SA1100_CS3_PHYS + 0x01ffffff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_NEPONSET_SMC9196, - .end = IRQ_NEPONSET_SMC9196, - .flags = IORESOURCE_IRQ, - }, - [2] = { - .name = "smc91x-attrib", - .start = SA1100_CS3_PHYS + 0x02000000, - .end = SA1100_CS3_PHYS + 0x03ffffff, - .flags = IORESOURCE_MEM, - }, -}; + d->base = ioremap(nep_res->start, SZ_4K); + if (!d->base) { + ret = -ENOMEM; + goto err_ioremap; + } -static struct platform_device smc91x_device = { - .name = "smc91x", - .id = 0, - .num_resources = ARRAY_SIZE(smc91x_resources), - .resource = smc91x_resources, -}; + if (readb_relaxed(d->base + WHOAMI) != 0x11) { + dev_warn(&dev->dev, "Neponset board detected, but wrong ID: %02x\n", + readb_relaxed(d->base + WHOAMI)); + ret = -ENODEV; + goto err_id; + } -static struct platform_device *devices[] __initdata = { - &neponset_device, - &sa1111_device, - &smc91x_device, -}; + ret = irq_alloc_descs(-1, IRQ_BOARD_START, NEP_IRQ_NR, -1); + if (ret <= 0) { + dev_err(&dev->dev, "unable to allocate %u irqs: %d\n", + NEP_IRQ_NR, ret); + if (ret == 0) + ret = -ENOMEM; + goto err_irq_alloc; + } -extern void sa1110_mb_disable(void); + d->irq_base = ret; -static int __init neponset_init(void) -{ - platform_driver_register(&neponset_device_driver); + irq_set_chip_and_handler(d->irq_base + NEP_IRQ_SMC91X, &nochip, + handle_simple_irq); + set_irq_flags(d->irq_base + NEP_IRQ_SMC91X, IRQF_VALID | IRQF_PROBE); + irq_set_chip_and_handler(d->irq_base + NEP_IRQ_USAR, &nochip, + handle_simple_irq); + set_irq_flags(d->irq_base + NEP_IRQ_USAR, IRQF_VALID | IRQF_PROBE); + irq_set_chip(d->irq_base + NEP_IRQ_SA1111, &nochip); - /* - * The Neponset is only present on the Assabet machine type. - */ - if (!machine_is_assabet()) - return -ENODEV; + irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING); + irq_set_handler_data(irq, d); + irq_set_chained_handler(irq, neponset_irq_handler); /* - * Ensure that the memory bus request/grant signals are setup, - * and the grant is held in its inactive state, whether or not - * we actually have a Neponset attached. + * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately + * something on the Neponset activates this IRQ on sleep (eth?) */ +#if 0 + enable_irq_wake(irq); +#endif + + dev_info(&dev->dev, "Neponset daughter board, providing IRQ%u-%u\n", + d->irq_base, d->irq_base + NEP_IRQ_NR - 1); + nep_base = d->base; + + sa1100_register_uart_fns(&neponset_port_fns); + + /* Ensure that the memory bus request/grant signals are setup */ sa1110_mb_disable(); - if (!machine_has_neponset()) { - printk(KERN_DEBUG "Neponset expansion board not present\n"); - return -ENODEV; - } + /* Disable GPIO 0/1 drivers so the buttons work on the Assabet */ + writeb_relaxed(NCR_GP01_OFF, d->base + NCR_0); - if (WHOAMI != 0x11) { - printk(KERN_WARNING "Neponset board detected, but " - "wrong ID: %02x\n", WHOAMI); - return -ENODEV; - } + sa1111_resources[0].parent = sa1111_res; + sa1111_resources[1].start = d->irq_base + NEP_IRQ_SA1111; + sa1111_resources[1].end = d->irq_base + NEP_IRQ_SA1111; + d->sa1111 = platform_device_register_full(&sa1111_devinfo); + + smc91x_resources[0].parent = smc91x_res; + smc91x_resources[1].parent = smc91x_res; + smc91x_resources[2].start = d->irq_base + NEP_IRQ_SMC91X; + smc91x_resources[2].end = d->irq_base + NEP_IRQ_SMC91X; + d->smc91x = platform_device_register_full(&smc91x_devinfo); + + platform_set_drvdata(dev, d); - return platform_add_devices(devices, ARRAY_SIZE(devices)); + return 0; + + err_irq_alloc: + err_id: + iounmap(d->base); + err_ioremap: + kfree(d); + err_alloc: + return ret; } -subsys_initcall(neponset_init); +static int __devexit neponset_remove(struct platform_device *dev) +{ + struct neponset_drvdata *d = platform_get_drvdata(dev); + int irq = platform_get_irq(dev, 0); + + if (!IS_ERR(d->sa1111)) + platform_device_unregister(d->sa1111); + if (!IS_ERR(d->smc91x)) + platform_device_unregister(d->smc91x); + irq_set_chained_handler(irq, NULL); + irq_free_descs(d->irq_base, NEP_IRQ_NR); + nep_base = NULL; + iounmap(d->base); + kfree(d); -static struct map_desc neponset_io_desc[] __initdata = { - { /* System Registers */ - .virtual = 0xf3000000, - .pfn = __phys_to_pfn(0x10000000), - .length = SZ_1M, - .type = MT_DEVICE - }, { /* SA-1111 */ - .virtual = 0xf4000000, - .pfn = __phys_to_pfn(0x40000000), - .length = SZ_1M, - .type = MT_DEVICE - } + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int neponset_suspend(struct device *dev) +{ + struct neponset_drvdata *d = dev_get_drvdata(dev); + + d->ncr0 = readb_relaxed(d->base + NCR_0); + d->mdm_ctl_0 = readb_relaxed(d->base + MDM_CTL_0); + + return 0; +} + +static int neponset_resume(struct device *dev) +{ + struct neponset_drvdata *d = dev_get_drvdata(dev); + + writeb_relaxed(d->ncr0, d->base + NCR_0); + writeb_relaxed(d->mdm_ctl_0, d->base + MDM_CTL_0); + + return 0; +} + +static const struct dev_pm_ops neponset_pm_ops = { + .suspend_noirq = neponset_suspend, + .resume_noirq = neponset_resume, + .freeze_noirq = neponset_suspend, + .restore_noirq = neponset_resume, +}; +#define PM_OPS &neponset_pm_ops +#else +#define PM_OPS NULL +#endif + +static struct platform_driver neponset_device_driver = { + .probe = neponset_probe, + .remove = __devexit_p(neponset_remove), + .driver = { + .name = "neponset", + .owner = THIS_MODULE, + .pm = PM_OPS, + }, }; -void __init neponset_map_io(void) +static int __init neponset_init(void) { - iotable_init(neponset_io_desc, ARRAY_SIZE(neponset_io_desc)); + return platform_driver_register(&neponset_device_driver); } + +subsys_initcall(neponset_init); diff --git a/arch/arm/mach-sa1100/pci-nanoengine.c b/arch/arm/mach-sa1100/pci-nanoengine.c index 0d01ca788922..b49108b890a8 100644 --- a/arch/arm/mach-sa1100/pci-nanoengine.c +++ b/arch/arm/mach-sa1100/pci-nanoengine.c @@ -135,12 +135,8 @@ struct pci_bus * __init pci_nanoengine_scan_bus(int nr, struct pci_sys_data *sys &sys->resources); } -static struct resource pci_io_ports = { - .name = "PCI IO", - .start = 0x400, - .end = 0x7FF, - .flags = IORESOURCE_IO, -}; +static struct resource pci_io_ports = + DEFINE_RES_IO_NAMED(0x400, 0x400, "PCI IO"); static struct resource pci_non_prefetchable_memory = { .name = "PCI non-prefetchable", @@ -244,9 +240,11 @@ static int __init pci_nanoengine_setup_resources(struct pci_sys_data *sys) printk(KERN_ERR "PCI: unable to allocate prefetchable\n"); return -EBUSY; } - pci_add_resource(&sys->resources, &pci_io_ports); - pci_add_resource(&sys->resources, &pci_non_prefetchable_memory); - pci_add_resource(&sys->resources, &pci_prefetchable_memory); + pci_add_resource_offset(&sys->resources, &pci_io_ports, sys->io_offset); + pci_add_resource_offset(&sys->resources, + &pci_non_prefetchable_memory, sys->mem_offset); + pci_add_resource_offset(&sys->resources, + &pci_prefetchable_memory, sys->mem_offset); return 1; } diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c index 9307df053533..1602575a0d5c 100644 --- a/arch/arm/mach-sa1100/pleb.c +++ b/arch/arm/mach-sa1100/pleb.c @@ -37,17 +37,9 @@ #define IRQ_GPIO_ETH0_IRQ IRQ_GPIO21 static struct resource smc91x_resources[] = { - [0] = { - .start = PLEB_ETH0_P, - .end = PLEB_ETH0_P | 0x03ffffff, - .flags = IORESOURCE_MEM, - }, + [0] = DEFINE_RES_MEM(PLEB_ETH0_P, 0x04000000), #if 0 /* Autoprobe instead, to get rising/falling edge characteristic right */ - [1] = { - .start = IRQ_GPIO_ETH0_IRQ, - .end = IRQ_GPIO_ETH0_IRQ, - .flags = IORESOURCE_IRQ, - }, + [1] = DEFINE_RES_IRQ(IRQ_GPIO_ETH0_IRQ), #endif }; @@ -70,16 +62,8 @@ static struct platform_device *devices[] __initdata = { * the two SA1100 lowest chip select outputs. */ static struct resource pleb_flash_resources[] = { - [0] = { - .start = SA1100_CS0_PHYS, - .end = SA1100_CS0_PHYS + SZ_8M - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = SA1100_CS1_PHYS, - .end = SA1100_CS1_PHYS + SZ_8M - 1, - .flags = IORESOURCE_MEM, - } + [0] = DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_8M), + [1] = DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_8M), }; @@ -147,6 +131,7 @@ static void __init pleb_map_io(void) MACHINE_START(PLEB, "PLEB") .map_io = pleb_map_io, + .nr_irqs = SA1100_NR_IRQS, .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = pleb_init, diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c index bf85b8b259d5..2fa499ec6afe 100644 --- a/arch/arm/mach-sa1100/pm.c +++ b/arch/arm/mach-sa1100/pm.c @@ -30,7 +30,6 @@ #include <mach/hardware.h> #include <asm/memory.h> #include <asm/suspend.h> -#include <asm/system.h> #include <asm/mach/time.h> extern int sa1100_finish_suspend(unsigned long); diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c index 318b2b766a0b..ca8bf59b9047 100644 --- a/arch/arm/mach-sa1100/shannon.c +++ b/arch/arm/mach-sa1100/shannon.c @@ -9,6 +9,8 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> +#include <video/sa1100fb.h> + #include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/setup.h> @@ -19,6 +21,7 @@ #include <asm/mach/serial_sa1100.h> #include <mach/mcp.h> #include <mach/shannon.h> +#include <mach/irqs.h> #include "generic.h" @@ -46,19 +49,32 @@ static struct flash_platform_data shannon_flash_data = { .nr_parts = ARRAY_SIZE(shannon_partitions), }; -static struct resource shannon_flash_resource = { - .start = SA1100_CS0_PHYS, - .end = SA1100_CS0_PHYS + SZ_4M - 1, - .flags = IORESOURCE_MEM, -}; +static struct resource shannon_flash_resource = + DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_4M); static struct mcp_plat_data shannon_mcp_data = { .mccr0 = MCCR0_ADM, .sclk_rate = 11981000, }; +static struct sa1100fb_mach_info shannon_lcd_info = { + .pixclock = 152500, .bpp = 8, + .xres = 640, .yres = 480, + + .hsync_len = 4, .vsync_len = 3, + .left_margin = 2, .upper_margin = 0, + .right_margin = 1, .lower_margin = 0, + + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + + .lccr0 = LCCR0_Color | LCCR0_Dual | LCCR0_Pas, + .lccr3 = LCCR3_ACBsDiv(512), +}; + static void __init shannon_init(void) { + sa11x0_ppc_configure_mcp(); + sa11x0_register_lcd(&shannon_lcd_info); sa11x0_register_mtd(&shannon_flash_data, &shannon_flash_resource, 1); sa11x0_register_mcp(&shannon_mcp_data); } @@ -84,6 +100,7 @@ static void __init shannon_map_io(void) MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)") .atag_offset = 0x100, .map_io = shannon_map_io, + .nr_irqs = SA1100_NR_IRQS, .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = shannon_init, diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c index e17c04d6e324..3efae03cb3d7 100644 --- a/arch/arm/mach-sa1100/simpad.c +++ b/arch/arm/mach-sa1100/simpad.c @@ -7,15 +7,15 @@ #include <linux/kernel.h> #include <linux/tty.h> #include <linux/proc_fs.h> -#include <linux/string.h> +#include <linux/string.h> #include <linux/pm.h> #include <linux/platform_device.h> +#include <linux/mfd/ucb1x00.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/io.h> #include <linux/gpio.h> -#include <asm/irq.h> #include <mach/hardware.h> #include <asm/setup.h> @@ -26,6 +26,7 @@ #include <asm/mach/serial_sa1100.h> #include <mach/mcp.h> #include <mach/simpad.h> +#include <mach/irqs.h> #include <linux/serial_core.h> #include <linux/ioport.h> @@ -176,21 +177,18 @@ static struct flash_platform_data simpad_flash_data = { static struct resource simpad_flash_resources [] = { - { - .start = SA1100_CS0_PHYS, - .end = SA1100_CS0_PHYS + SZ_16M -1, - .flags = IORESOURCE_MEM, - }, { - .start = SA1100_CS1_PHYS, - .end = SA1100_CS1_PHYS + SZ_16M -1, - .flags = IORESOURCE_MEM, - } + DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_16M), + DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_16M), +}; + +static struct ucb1x00_plat_data simpad_ucb1x00_data = { + .gpio_base = SIMPAD_UCB1X00_GPIO_BASE, }; static struct mcp_plat_data simpad_mcp_data = { .mccr0 = MCCR0_ADM, .sclk_rate = 11981000, - .gpio_base = SIMPAD_UCB1X00_GPIO_BASE, + .codec_pdata = &simpad_ucb1x00_data, }; @@ -376,6 +374,7 @@ static int __init simpad_init(void) pm_power_off = simpad_power_off; + sa11x0_ppc_configure_mcp(); sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources, ARRAY_SIZE(simpad_flash_resources)); sa11x0_register_mcp(&simpad_mcp_data); @@ -394,6 +393,7 @@ MACHINE_START(SIMPAD, "Simpad") /* Maintainer: Holger Freyther */ .atag_offset = 0x100, .map_io = simpad_map_io, + .nr_irqs = SA1100_NR_IRQS, .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .restart = sa11x0_restart, diff --git a/arch/arm/mach-sa1100/sleep.S b/arch/arm/mach-sa1100/sleep.S index e8223315b442..30cc6721665b 100644 --- a/arch/arm/mach-sa1100/sleep.S +++ b/arch/arm/mach-sa1100/sleep.S @@ -26,27 +26,36 @@ * * Causes sa11x0 to enter sleep state * + * Must be aligned to a cacheline. */ - + .balign 32 ENTRY(sa1100_finish_suspend) @ disable clock switching mcr p15, 0, r1, c15, c2, 2 - @ Adjust memory timing before lowering CPU clock - @ Clock speed adjustment without changing memory timing makes - @ CPU hang in some cases - ldr r0, =MDREFR - ldr r1, [r0] - orr r1, r1, #MDREFR_K1DB2 - str r1, [r0] + ldr r6, =MDREFR + ldr r4, [r6] + orr r4, r4, #MDREFR_K1DB2 + ldr r5, =PPCR + + @ Pre-load __udelay into the I-cache + mov r0, #1 + bl __udelay + mov r0, r0 + + @ The following must all exist in a single cache line to + @ avoid accessing memory until this sequence is complete, + @ otherwise we occasionally hang. + + @ Adjust memory timing before lowering CPU clock + str r4, [r6] @ delay 90us and set CPU PLL to lowest speed @ fixes resume problem on high speed SA1110 mov r0, #90 bl __udelay - ldr r0, =PPCR mov r1, #0 - str r1, [r0] + str r1, [r5] mov r0, #90 bl __udelay @@ -85,12 +94,10 @@ ENTRY(sa1100_finish_suspend) bic r5, r5, #FMsk(MSC_RT) bic r5, r5, #FMsk(MSC_RT)<<16 - ldr r6, =MDREFR - ldr r7, [r6] -bic r7, r7, #0x0000FF00 -bic r7, r7, #0x000000F0 -orr r8, r7, #MDREFR_SLFRSH + bic r7, r7, #0x0000FF00 + bic r7, r7, #0x000000F0 + orr r8, r7, #MDREFR_SLFRSH ldr r9, =MDCNFG ldr r10, [r9] diff --git a/arch/arm/mach-sa1100/ssp.c b/arch/arm/mach-sa1100/ssp.c index b20ff93b84a5..e22fca9ad5ec 100644 --- a/arch/arm/mach-sa1100/ssp.c +++ b/arch/arm/mach-sa1100/ssp.c @@ -19,8 +19,8 @@ #include <linux/init.h> #include <linux/io.h> -#include <asm/irq.h> #include <mach/hardware.h> +#include <mach/irqs.h> #include <asm/hardware/ssp.h> #define TIMEOUT 100000 diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c index 69e33535dee6..6af26e8d55e6 100644 --- a/arch/arm/mach-sa1100/time.c +++ b/arch/arm/mach-sa1100/time.c @@ -18,6 +18,7 @@ #include <asm/mach/time.h> #include <asm/sched_clock.h> #include <mach/hardware.h> +#include <mach/irqs.h> static u32 notrace sa1100_read_sched_clock(void) { diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c index a851c254ad6c..2704bcd869cd 100644 --- a/arch/arm/mach-shark/core.c +++ b/arch/arm/mach-shark/core.c @@ -15,6 +15,7 @@ #include <asm/mach-types.h> #include <asm/leds.h> #include <asm/param.h> +#include <asm/system_misc.h> #include <asm/mach/map.h> #include <asm/mach/arch.h> @@ -149,10 +150,16 @@ static struct sys_timer shark_timer = { .init = shark_timer_init, }; +static void shark_init_early(void) +{ + disable_hlt(); +} + MACHINE_START(SHARK, "Shark") /* Maintainer: Alexander Schulz */ .atag_offset = 0x3000, .map_io = shark_map_io, + .init_early = shark_init_early, .init_irq = shark_init_irq, .timer = &shark_timer, .dma_zone_size = SZ_4M, diff --git a/arch/arm/mach-shark/include/mach/entry-macro.S b/arch/arm/mach-shark/include/mach/entry-macro.S index 0bb6cc626eb7..5901b09fc96a 100644 --- a/arch/arm/mach-shark/include/mach/entry-macro.S +++ b/arch/arm/mach-shark/include/mach/entry-macro.S @@ -7,16 +7,10 @@ * License version 2. This program is licensed "as is" without any * warranty of any kind, whether express or implied. */ - .macro disable_fiq - .endm - .macro get_irqnr_preamble, base, tmp mov \base, #0xe0000000 .endm - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp mov \irqstat, #0x0C diff --git a/arch/arm/mach-shark/include/mach/io.h b/arch/arm/mach-shark/include/mach/io.h index 9ccbcecc430b..1a45fc01ff1d 100644 --- a/arch/arm/mach-shark/include/mach/io.h +++ b/arch/arm/mach-shark/include/mach/io.h @@ -15,6 +15,4 @@ #define __io(a) ((void __iomem *)(0xe0000000 + (a))) -#define __mem_pci(addr) (addr) - #endif diff --git a/arch/arm/mach-shark/include/mach/system.h b/arch/arm/mach-shark/include/mach/system.h deleted file mode 100644 index 1b2f2c5050a8..000000000000 --- a/arch/arm/mach-shark/include/mach/system.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/arm/mach-shark/include/mach/system.h - * - * by Alexander Schulz - */ -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ -} - -#endif diff --git a/arch/arm/mach-shark/leds.c b/arch/arm/mach-shark/leds.c index ccd49189bbd0..25609076921f 100644 --- a/arch/arm/mach-shark/leds.c +++ b/arch/arm/mach-shark/leds.c @@ -23,7 +23,6 @@ #include <linux/io.h> #include <asm/leds.h> -#include <asm/system.h> #define LED_STATE_ENABLED 1 #define LED_STATE_CLAIMED 2 diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 060e5644c49c..34560cab45d9 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -100,6 +100,10 @@ config MACH_MARZEN comment "SH-Mobile System Configuration" +config CPU_HAS_INTEVT + bool + default y + menu "Memory configuration" config MEMORY_START diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 7ad6954c46cd..e7c2590b75d9 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -16,7 +16,6 @@ obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o clock-r8a7779.o intc-r8a7779.o # SMP objects smp-y := platsmp.o headsmp.o smp-$(CONFIG_HOTPLUG_CPU) += hotplug.o -smp-$(CONFIG_LOCAL_TIMERS) += localtimer.o smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index 12c431f3443f..cb224a344af0 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c @@ -43,12 +43,11 @@ #include <video/sh_mipi_dsi.h> #include <sound/sh_fsi.h> #include <mach/hardware.h> +#include <mach/irqs.h> #include <mach/sh73a0.h> #include <mach/common.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/time.h> #include <asm/hardware/gic.h> #include <asm/hardware/cache-l2x0.h> #include <asm/traps.h> @@ -477,27 +476,6 @@ static struct platform_device *ag5evm_devices[] __initdata = { &sdhi1_device, }; -static struct map_desc ag5evm_io_desc[] __initdata = { - /* create a 1:1 entity map for 0xe6xxxxxx - * used by CPGA, INTC and PFC. - */ - { - .virtual = 0xe6000000, - .pfn = __phys_to_pfn(0xe6000000), - .length = 256 << 20, - .type = MT_DEVICE_NONSHARED - }, -}; - -static void __init ag5evm_map_io(void) -{ - iotable_init(ag5evm_io_desc, ARRAY_SIZE(ag5evm_io_desc)); - - /* setup early devices and console here as well */ - sh73a0_add_early_devices(); - shmobile_setup_console(); -} - static void __init ag5evm_init(void) { sh73a0_pinmux_init(); @@ -607,28 +585,18 @@ static void __init ag5evm_init(void) #ifdef CONFIG_CACHE_L2X0 /* Shared attribute override enable, 64K*8way */ - l2x0_init(__io(0xf0100000), 0x00460000, 0xc2000fff); + l2x0_init(IOMEM(0xf0100000), 0x00460000, 0xc2000fff); #endif sh73a0_add_standard_devices(); platform_add_devices(ag5evm_devices, ARRAY_SIZE(ag5evm_devices)); } -static void __init ag5evm_timer_init(void) -{ - sh73a0_clock_init(); - shmobile_timer.init(); - return; -} - -struct sys_timer ag5evm_timer = { - .init = ag5evm_timer_init, -}; - MACHINE_START(AG5EVM, "ag5evm") - .map_io = ag5evm_map_io, + .map_io = sh73a0_map_io, + .init_early = sh73a0_add_early_devices, .nr_irqs = NR_IRQS_LEGACY, .init_irq = sh73a0_init_irq, .handle_irq = gic_handle_irq, .init_machine = ag5evm_init, - .timer = &ag5evm_timer, + .timer = &shmobile_timer, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index f90ba5b850a3..b56dde2732bb 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -61,8 +61,6 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/time.h> #include <asm/setup.h> /* @@ -1188,26 +1186,6 @@ static struct i2c_board_info i2c1_devices[] = { }, }; -static struct map_desc ap4evb_io_desc[] __initdata = { - /* create a 1:1 entity map for 0xe6xxxxxx - * used by CPGA, INTC and PFC. - */ - { - .virtual = 0xe6000000, - .pfn = __phys_to_pfn(0xe6000000), - .length = 256 << 20, - .type = MT_DEVICE_NONSHARED - }, -}; - -static void __init ap4evb_map_io(void) -{ - iotable_init(ap4evb_io_desc, ARRAY_SIZE(ap4evb_io_desc)); - - /* setup early devices and console here as well */ - sh7372_add_early_devices(); - shmobile_setup_console(); -} #define GPIO_PORT9CR 0xE6051009 #define GPIO_PORT10CR 0xE605100A @@ -1217,6 +1195,9 @@ static void __init ap4evb_init(void) u32 srcr4; struct clk *clk; + /* External clock source */ + clk_set_rate(&sh7372_dv_clki_clk, 27000000); + sh7372_pinmux_init(); /* enable SCIFA0 */ @@ -1453,23 +1434,11 @@ static void __init ap4evb_init(void) pm_clk_add(&lcdc1_device.dev, "hdmi"); } -static void __init ap4evb_timer_init(void) -{ - sh7372_clock_init(); - shmobile_timer.init(); - - /* External clock source */ - clk_set_rate(&sh7372_dv_clki_clk, 27000000); -} - -static struct sys_timer ap4evb_timer = { - .init = ap4evb_timer_init, -}; - MACHINE_START(AP4EVB, "ap4evb") - .map_io = ap4evb_map_io, + .map_io = sh7372_map_io, + .init_early = sh7372_add_early_devices, .init_irq = sh7372_init_irq, .handle_irq = shmobile_handle_irq_intc, .init_machine = ap4evb_init, - .timer = &ap4evb_timer, + .timer = &shmobile_timer, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-bonito.c b/arch/arm/mach-shmobile/board-bonito.c index c79baa9ef61b..81fd95f7f52a 100644 --- a/arch/arm/mach-shmobile/board-bonito.c +++ b/arch/arm/mach-shmobile/board-bonito.c @@ -35,6 +35,7 @@ #include <asm/mach/time.h> #include <asm/hardware/cache-l2x0.h> #include <mach/r8a7740.h> +#include <mach/irqs.h> #include <video/sh_mobile_lcdc.h> /* @@ -328,28 +329,6 @@ static struct platform_device *bonito_base_devices[] __initdata = { * map I/O */ static struct map_desc bonito_io_desc[] __initdata = { - /* - * for CPGA/INTC/PFC - * 0xe6000000-0xefffffff -> 0xe6000000-0xefffffff - */ - { - .virtual = 0xe6000000, - .pfn = __phys_to_pfn(0xe6000000), - .length = 160 << 20, - .type = MT_DEVICE_NONSHARED - }, -#ifdef CONFIG_CACHE_L2X0 - /* - * for l2x0_init() - * 0xf0100000-0xf0101000 -> 0xf0002000-0xf0003000 - */ - { - .virtual = 0xf0002000, - .pfn = __phys_to_pfn(0xf0100000), - .length = PAGE_SIZE, - .type = MT_DEVICE_NONSHARED - }, -#endif /* * for FPGA (0x1800000-0x19ffffff) * 0x18000000-0x18002000 -> 0xf0003000-0xf0005000 @@ -364,11 +343,8 @@ static struct map_desc bonito_io_desc[] __initdata = { static void __init bonito_map_io(void) { + r8a7740_map_io(); iotable_init(bonito_io_desc, ARRAY_SIZE(bonito_io_desc)); - - /* setup early devices and console here as well */ - r8a7740_add_early_devices(); - shmobile_setup_console(); } /* @@ -395,7 +371,7 @@ static void __init bonito_init(void) #ifdef CONFIG_CACHE_L2X0 /* Early BRESP enable, Shared attribute override enable, 32K*8way */ - l2x0_init(__io(0xf0002000), 0x40440000, 0x82000fff); + l2x0_init(IOMEM(0xf0002000), 0x40440000, 0x82000fff); #endif r8a7740_add_standard_devices(); @@ -492,7 +468,7 @@ static void __init bonito_init(void) } } -static void __init bonito_timer_init(void) +static void __init bonito_earlytimer_init(void) { u16 val; u8 md_ck = 0; @@ -507,17 +483,22 @@ static void __init bonito_timer_init(void) md_ck |= MD_CK0; r8a7740_clock_init(md_ck); - shmobile_timer.init(); + shmobile_earlytimer_init(); } -struct sys_timer bonito_timer = { - .init = bonito_timer_init, -}; +void __init bonito_add_early_devices(void) +{ + r8a7740_add_early_devices(); + + /* override timer setup with board-specific code */ + shmobile_timer.init = bonito_earlytimer_init; +} MACHINE_START(BONITO, "bonito") .map_io = bonito_map_io, + .init_early = bonito_add_early_devices, .init_irq = r8a7740_init_irq, .handle_irq = shmobile_handle_irq_intc, .init_machine = bonito_init, - .timer = &bonito_timer, + .timer = &shmobile_timer, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-g3evm.c b/arch/arm/mach-shmobile/board-g3evm.c index 72d557281b1f..39b6cf85ced6 100644 --- a/arch/arm/mach-shmobile/board-g3evm.c +++ b/arch/arm/mach-shmobile/board-g3evm.c @@ -33,12 +33,11 @@ #include <linux/input.h> #include <linux/input/sh_keysc.h> #include <linux/dma-mapping.h> +#include <mach/irqs.h> #include <mach/sh7367.h> #include <mach/common.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/time.h> /* * IrDA @@ -246,27 +245,6 @@ static struct platform_device *g3evm_devices[] __initdata = { &irda_device, }; -static struct map_desc g3evm_io_desc[] __initdata = { - /* create a 1:1 entity map for 0xe6xxxxxx - * used by CPGA, INTC and PFC. - */ - { - .virtual = 0xe6000000, - .pfn = __phys_to_pfn(0xe6000000), - .length = 256 << 20, - .type = MT_DEVICE_NONSHARED - }, -}; - -static void __init g3evm_map_io(void) -{ - iotable_init(g3evm_io_desc, ARRAY_SIZE(g3evm_io_desc)); - - /* setup early devices and console here as well */ - sh7367_add_early_devices(); - shmobile_setup_console(); -} - static void __init g3evm_init(void) { sh7367_pinmux_init(); @@ -354,20 +332,11 @@ static void __init g3evm_init(void) platform_add_devices(g3evm_devices, ARRAY_SIZE(g3evm_devices)); } -static void __init g3evm_timer_init(void) -{ - sh7367_clock_init(); - shmobile_timer.init(); -} - -static struct sys_timer g3evm_timer = { - .init = g3evm_timer_init, -}; - MACHINE_START(G3EVM, "g3evm") - .map_io = g3evm_map_io, + .map_io = sh7367_map_io, + .init_early = sh7367_add_early_devices, .init_irq = sh7367_init_irq, .handle_irq = shmobile_handle_irq_intc, .init_machine = g3evm_init, - .timer = &g3evm_timer, + .timer = &shmobile_timer, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c index 2220b885cff5..0e5a39c670bc 100644 --- a/arch/arm/mach-shmobile/board-g4evm.c +++ b/arch/arm/mach-shmobile/board-g4evm.c @@ -34,12 +34,11 @@ #include <linux/mmc/sh_mobile_sdhi.h> #include <linux/gpio.h> #include <linux/dma-mapping.h> +#include <mach/irqs.h> #include <mach/sh7377.h> #include <mach/common.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/time.h> /* * SDHI @@ -260,27 +259,6 @@ static struct platform_device *g4evm_devices[] __initdata = { &sdhi1_device, }; -static struct map_desc g4evm_io_desc[] __initdata = { - /* create a 1:1 entity map for 0xe6xxxxxx - * used by CPGA, INTC and PFC. - */ - { - .virtual = 0xe6000000, - .pfn = __phys_to_pfn(0xe6000000), - .length = 256 << 20, - .type = MT_DEVICE_NONSHARED - }, -}; - -static void __init g4evm_map_io(void) -{ - iotable_init(g4evm_io_desc, ARRAY_SIZE(g4evm_io_desc)); - - /* setup early devices and console here as well */ - sh7377_add_early_devices(); - shmobile_setup_console(); -} - #define GPIO_SDHID0_D0 0xe60520fc #define GPIO_SDHID0_D1 0xe60520fd #define GPIO_SDHID0_D2 0xe60520fe @@ -397,20 +375,11 @@ static void __init g4evm_init(void) platform_add_devices(g4evm_devices, ARRAY_SIZE(g4evm_devices)); } -static void __init g4evm_timer_init(void) -{ - sh7377_clock_init(); - shmobile_timer.init(); -} - -static struct sys_timer g4evm_timer = { - .init = g4evm_timer_init, -}; - MACHINE_START(G4EVM, "g4evm") - .map_io = g4evm_map_io, + .map_io = sh7377_map_io, + .init_early = sh7377_add_early_devices, .init_irq = sh7377_init_irq, .handle_irq = shmobile_handle_irq_intc, .init_machine = g4evm_init, - .timer = &g4evm_timer, + .timer = &shmobile_timer, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-kota2.c b/arch/arm/mach-shmobile/board-kota2.c index c8e7ca23fc06..200dcd42a3a0 100644 --- a/arch/arm/mach-shmobile/board-kota2.c +++ b/arch/arm/mach-shmobile/board-kota2.c @@ -39,11 +39,11 @@ #include <linux/mfd/tmio.h> #include <linux/mmc/sh_mobile_sdhi.h> #include <mach/hardware.h> +#include <mach/irqs.h> #include <mach/sh73a0.h> #include <mach/common.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <asm/mach/map.h> #include <asm/mach/time.h> #include <asm/hardware/gic.h> #include <asm/hardware/cache-l2x0.h> @@ -409,27 +409,6 @@ static struct platform_device *kota2_devices[] __initdata = { &sdhi1_device, }; -static struct map_desc kota2_io_desc[] __initdata = { - /* create a 1:1 entity map for 0xe6xxxxxx - * used by CPGA, INTC and PFC. - */ - { - .virtual = 0xe6000000, - .pfn = __phys_to_pfn(0xe6000000), - .length = 256 << 20, - .type = MT_DEVICE_NONSHARED - }, -}; - -static void __init kota2_map_io(void) -{ - iotable_init(kota2_io_desc, ARRAY_SIZE(kota2_io_desc)); - - /* setup early devices and console here as well */ - sh73a0_add_early_devices(); - shmobile_setup_console(); -} - static void __init kota2_init(void) { sh73a0_pinmux_init(); @@ -529,28 +508,18 @@ static void __init kota2_init(void) #ifdef CONFIG_CACHE_L2X0 /* Early BRESP enable, Shared attribute override enable, 64K*8way */ - l2x0_init(__io(0xf0100000), 0x40460000, 0x82000fff); + l2x0_init(IOMEM(0xf0100000), 0x40460000, 0x82000fff); #endif sh73a0_add_standard_devices(); platform_add_devices(kota2_devices, ARRAY_SIZE(kota2_devices)); } -static void __init kota2_timer_init(void) -{ - sh73a0_clock_init(); - shmobile_timer.init(); - return; -} - -struct sys_timer kota2_timer = { - .init = kota2_timer_init, -}; - MACHINE_START(KOTA2, "kota2") - .map_io = kota2_map_io, + .map_io = sh73a0_map_io, + .init_early = sh73a0_add_early_devices, .nr_irqs = NR_IRQS_LEGACY, .init_irq = sh73a0_init_irq, .handle_irq = gic_handle_irq, .init_machine = kota2_init, - .timer = &kota2_timer, + .timer = &shmobile_timer, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index 865d56d96299..f49e28abe0ab 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c @@ -39,6 +39,7 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/mtd/physmap.h> +#include <linux/mtd/sh_flctl.h> #include <linux/pm_clock.h> #include <linux/smsc911x.h> #include <linux/sh_intc.h> @@ -54,11 +55,10 @@ #include <sound/sh_fsi.h> #include <mach/common.h> +#include <mach/irqs.h> #include <mach/sh7372.h> #include <asm/mach/arch.h> -#include <asm/mach/time.h> -#include <asm/mach/map.h> #include <asm/mach-types.h> /* @@ -957,6 +957,50 @@ static struct platform_device fsi_ak4643_device = { }, }; +/* FLCTL */ +static struct mtd_partition nand_partition_info[] = { + { + .name = "system", + .offset = 0, + .size = 128 * 1024 * 1024, + }, + { + .name = "userdata", + .offset = MTDPART_OFS_APPEND, + .size = 256 * 1024 * 1024, + }, + { + .name = "cache", + .offset = MTDPART_OFS_APPEND, + .size = 128 * 1024 * 1024, + }, +}; + +static struct resource nand_flash_resources[] = { + [0] = { + .start = 0xe6a30000, + .end = 0xe6a3009b, + .flags = IORESOURCE_MEM, + } +}; + +static struct sh_flctl_platform_data nand_flash_data = { + .parts = nand_partition_info, + .nr_parts = ARRAY_SIZE(nand_partition_info), + .flcmncr_val = CLK_16B_12L_4H | TYPESEL_SET + | SHBUSSEL | SEL_16BIT | SNAND_E, + .use_holden = 1, +}; + +static struct platform_device nand_flash_device = { + .name = "sh_flctl", + .resource = nand_flash_resources, + .num_resources = ARRAY_SIZE(nand_flash_resources), + .dev = { + .platform_data = &nand_flash_data, + }, +}; + /* * The card detect pin of the top SD/MMC slot (CN7) is active low and is * connected to GPIO A22 of SH7372 (GPIO_PORT41). @@ -1260,6 +1304,7 @@ static struct platform_device *mackerel_devices[] __initdata = { &fsi_device, &fsi_ak4643_device, &fsi_hdmi_device, + &nand_flash_device, &sdhi0_device, #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) &sdhi1_device, @@ -1329,31 +1374,6 @@ static struct i2c_board_info i2c1_devices[] = { }, }; -static struct map_desc mackerel_io_desc[] __initdata = { - /* create a 1:1 entity map for 0xe6xxxxxx - * used by CPGA, INTC and PFC. - */ - { - .virtual = 0xe6000000, - .pfn = __phys_to_pfn(0xe6000000), - .length = 256 << 20, - .type = MT_DEVICE_NONSHARED - }, -}; - -static void __init mackerel_map_io(void) -{ - iotable_init(mackerel_io_desc, ARRAY_SIZE(mackerel_io_desc)); - /* DMA memory at 0xff200000 - 0xffdfffff. The default 2MB size isn't - * enough to allocate the frame buffer memory. - */ - init_consistent_dma_size(12 << 20); - - /* setup early devices and console here as well */ - sh7372_add_early_devices(); - shmobile_setup_console(); -} - #define GPIO_PORT9CR 0xE6051009 #define GPIO_PORT10CR 0xE605100A #define GPIO_PORT167CR 0xE60520A7 @@ -1366,6 +1386,9 @@ static void __init mackerel_init(void) struct clk *clk; int ret; + /* External clock source */ + clk_set_rate(&sh7372_dv_clki_clk, 27000000); + sh7372_pinmux_init(); /* enable SCIFA0 */ @@ -1511,6 +1534,30 @@ static void __init mackerel_init(void) gpio_request(GPIO_FN_MMCCMD0, NULL); gpio_request(GPIO_FN_MMCCLK0, NULL); + /* FLCTL */ + gpio_request(GPIO_FN_D0_NAF0, NULL); + gpio_request(GPIO_FN_D1_NAF1, NULL); + gpio_request(GPIO_FN_D2_NAF2, NULL); + gpio_request(GPIO_FN_D3_NAF3, NULL); + gpio_request(GPIO_FN_D4_NAF4, NULL); + gpio_request(GPIO_FN_D5_NAF5, NULL); + gpio_request(GPIO_FN_D6_NAF6, NULL); + gpio_request(GPIO_FN_D7_NAF7, NULL); + gpio_request(GPIO_FN_D8_NAF8, NULL); + gpio_request(GPIO_FN_D9_NAF9, NULL); + gpio_request(GPIO_FN_D10_NAF10, NULL); + gpio_request(GPIO_FN_D11_NAF11, NULL); + gpio_request(GPIO_FN_D12_NAF12, NULL); + gpio_request(GPIO_FN_D13_NAF13, NULL); + gpio_request(GPIO_FN_D14_NAF14, NULL); + gpio_request(GPIO_FN_D15_NAF15, NULL); + gpio_request(GPIO_FN_FCE0, NULL); + gpio_request(GPIO_FN_WE0_FWE, NULL); + gpio_request(GPIO_FN_FRB, NULL); + gpio_request(GPIO_FN_A4_FOE, NULL); + gpio_request(GPIO_FN_A5_FCDE, NULL); + gpio_request(GPIO_FN_RD_FSC, NULL); + /* enable GPS module (GT-720F) */ gpio_request(GPIO_FN_SCIFA2_TXD1, NULL); gpio_request(GPIO_FN_SCIFA2_RXD1, NULL); @@ -1555,6 +1602,7 @@ static void __init mackerel_init(void) sh7372_add_device_to_domain(&sh7372_a4mp, &fsi_device); sh7372_add_device_to_domain(&sh7372_a3sp, &usbhs0_device); sh7372_add_device_to_domain(&sh7372_a3sp, &usbhs1_device); + sh7372_add_device_to_domain(&sh7372_a3sp, &nand_flash_device); sh7372_add_device_to_domain(&sh7372_a3sp, &sh_mmcif_device); sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi0_device); #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) @@ -1569,23 +1617,11 @@ static void __init mackerel_init(void) pm_clk_add(&hdmi_lcdc_device.dev, "hdmi"); } -static void __init mackerel_timer_init(void) -{ - sh7372_clock_init(); - shmobile_timer.init(); - - /* External clock source */ - clk_set_rate(&sh7372_dv_clki_clk, 27000000); -} - -static struct sys_timer mackerel_timer = { - .init = mackerel_timer_init, -}; - MACHINE_START(MACKEREL, "mackerel") - .map_io = mackerel_map_io, + .map_io = sh7372_map_io, + .init_early = sh7372_add_early_devices, .init_irq = sh7372_init_irq, .handle_irq = shmobile_handle_irq_intc, .init_machine = mackerel_init, - .timer = &mackerel_timer, + .timer = &shmobile_timer, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c index f0e02c0ce99f..ef0e13bf0b3a 100644 --- a/arch/arm/mach-shmobile/board-marzen.c +++ b/arch/arm/mach-shmobile/board-marzen.c @@ -31,10 +31,9 @@ #include <mach/hardware.h> #include <mach/r8a7779.h> #include <mach/common.h> +#include <mach/irqs.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/time.h> #include <asm/hardware/gic.h> #include <asm/traps.h> @@ -72,49 +71,6 @@ static struct platform_device *marzen_devices[] __initdata = { ð_device, }; -static struct map_desc marzen_io_desc[] __initdata = { - /* 2M entity map for 0xf0000000 (MPCORE) */ - { - .virtual = 0xf0000000, - .pfn = __phys_to_pfn(0xf0000000), - .length = SZ_2M, - .type = MT_DEVICE_NONSHARED - }, - /* 16M entity map for 0xfexxxxxx (DMAC-S/HPBREG/INTC2/LRAM/DBSC) */ - { - .virtual = 0xfe000000, - .pfn = __phys_to_pfn(0xfe000000), - .length = SZ_16M, - .type = MT_DEVICE_NONSHARED - }, -}; - -static void __init marzen_map_io(void) -{ - iotable_init(marzen_io_desc, ARRAY_SIZE(marzen_io_desc)); -} - -static void __init marzen_init_early(void) -{ - r8a7779_add_early_devices(); - - /* Early serial console setup is not included here due to - * memory map collisions. The SCIF serial ports in r8a7779 - * are difficult to entity map 1:1 due to collision with the - * virtual memory range used by the coherent DMA code on ARM. - * - * Anyone wanting to debug early can remove UPF_IOREMAP from - * the sh-sci serial console platform data, adjust mapbase - * to a static M:N virt:phys mapping that needs to be added to - * the mappings passed with iotable_init() above. - * - * Then add a call to shmobile_setup_console() from this function. - * - * As a final step pass earlyprint=sh-sci.2,115200 on the kernel - * command line. - */ -} - static void __init marzen_init(void) { r8a7779_pinmux_init(); @@ -135,23 +91,12 @@ static void __init marzen_init(void) platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices)); } -static void __init marzen_timer_init(void) -{ - r8a7779_clock_init(); - shmobile_timer.init(); - return; -} - -struct sys_timer marzen_timer = { - .init = marzen_timer_init, -}; - MACHINE_START(MARZEN, "marzen") - .map_io = marzen_map_io, - .init_early = marzen_init_early, + .map_io = r8a7779_map_io, + .init_early = r8a7779_add_early_devices, .nr_irqs = NR_IRQS_LEGACY, .init_irq = r8a7779_init_irq, .handle_irq = gic_handle_irq, .init_machine = marzen_init, - .timer = &marzen_timer, + .timer = &shmobile_timer, MACHINE_END diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c index 3b35b9afc001..99c4d743a99c 100644 --- a/arch/arm/mach-shmobile/clock-r8a7740.c +++ b/arch/arm/mach-shmobile/clock-r8a7740.c @@ -93,7 +93,7 @@ static unsigned long div_recalc(struct clk *clk) return clk->parent->rate / (int)(clk->priv); } -static struct clk_ops div_clk_ops = { +static struct sh_clk_ops div_clk_ops = { .recalc = div_recalc, }; @@ -125,7 +125,7 @@ static struct clk extal2_div2_clk = { .parent = &extal2_clk, }; -static struct clk_ops followparent_clk_ops = { +static struct sh_clk_ops followparent_clk_ops = { .recalc = followparent_recalc, }; @@ -156,7 +156,7 @@ static unsigned long pllc01_recalc(struct clk *clk) return clk->parent->rate * mult; } -static struct clk_ops pllc01_clk_ops = { +static struct sh_clk_ops pllc01_clk_ops = { .recalc = pllc01_recalc, }; @@ -376,7 +376,7 @@ void __init r8a7740_clock_init(u8 md_ck) clkdev_add_table(lookups, ARRAY_SIZE(lookups)); if (!ret) - clk_init(); + shmobile_clk_init(); else panic("failed to setup r8a7740 clocks\n"); } diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c index b4b0e8cd096d..7d6e9fe47b56 100644 --- a/arch/arm/mach-shmobile/clock-r8a7779.c +++ b/arch/arm/mach-shmobile/clock-r8a7779.c @@ -107,7 +107,7 @@ static unsigned long mul4_recalc(struct clk *clk) return clk->parent->rate * 4; } -static struct clk_ops mul4_clk_ops = { +static struct sh_clk_ops mul4_clk_ops = { .recalc = mul4_recalc, }; @@ -170,7 +170,7 @@ void __init r8a7779_clock_init(void) clkdev_add_table(lookups, ARRAY_SIZE(lookups)); if (!ret) - clk_init(); + shmobile_clk_init(); else panic("failed to setup r8a7779 clocks\n"); } diff --git a/arch/arm/mach-shmobile/clock-sh7367.c b/arch/arm/mach-shmobile/clock-sh7367.c index 5218c34a9cc6..006e7b5d304c 100644 --- a/arch/arm/mach-shmobile/clock-sh7367.c +++ b/arch/arm/mach-shmobile/clock-sh7367.c @@ -74,7 +74,7 @@ static unsigned long div2_recalc(struct clk *clk) return clk->parent->rate / 2; } -static struct clk_ops div2_clk_ops = { +static struct sh_clk_ops div2_clk_ops = { .recalc = div2_recalc, }; @@ -101,7 +101,7 @@ static unsigned long pllc1_recalc(struct clk *clk) return clk->parent->rate * mult; } -static struct clk_ops pllc1_clk_ops = { +static struct sh_clk_ops pllc1_clk_ops = { .recalc = pllc1_recalc, }; @@ -128,7 +128,7 @@ static unsigned long pllc2_recalc(struct clk *clk) return clk->parent->rate * mult; } -static struct clk_ops pllc2_clk_ops = { +static struct sh_clk_ops pllc2_clk_ops = { .recalc = pllc2_recalc, }; @@ -349,7 +349,7 @@ void __init sh7367_clock_init(void) clkdev_add_table(lookups, ARRAY_SIZE(lookups)); if (!ret) - clk_init(); + shmobile_clk_init(); else panic("failed to setup sh7367 clocks\n"); } diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index 293456d8dcfd..94d1f88246d3 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c @@ -89,7 +89,7 @@ static unsigned long div2_recalc(struct clk *clk) return clk->parent->rate / 2; } -static struct clk_ops div2_clk_ops = { +static struct sh_clk_ops div2_clk_ops = { .recalc = div2_recalc, }; @@ -128,7 +128,7 @@ static unsigned long pllc01_recalc(struct clk *clk) return clk->parent->rate * mult; } -static struct clk_ops pllc01_clk_ops = { +static struct sh_clk_ops pllc01_clk_ops = { .recalc = pllc01_recalc, }; @@ -276,7 +276,7 @@ static int pllc2_set_parent(struct clk *clk, struct clk *parent) return 0; } -static struct clk_ops pllc2_clk_ops = { +static struct sh_clk_ops pllc2_clk_ops = { .recalc = pllc2_recalc, .round_rate = pllc2_round_rate, .set_rate = pllc2_set_rate, @@ -468,7 +468,7 @@ static int fsidiv_set_rate(struct clk *clk, unsigned long rate) return 0; } -static struct clk_ops fsidiv_clk_ops = { +static struct sh_clk_ops fsidiv_clk_ops = { .recalc = fsidiv_recalc, .round_rate = fsidiv_round_rate, .set_rate = fsidiv_set_rate, @@ -511,7 +511,7 @@ enum { MSTP001, MSTP000, MSTP223, MSTP218, MSTP217, MSTP216, MSTP214, MSTP208, MSTP207, MSTP206, MSTP205, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, - MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312, + MSTP328, MSTP323, MSTP322, MSTP315, MSTP314, MSTP313, MSTP312, MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP407, MSTP406, MSTP405, MSTP404, MSTP403, MSTP400, MSTP_NR }; @@ -553,6 +553,7 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */ [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */ [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */ + [MSTP315] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 15, 0), /* FLCTL*/ [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */ [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */ [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */ @@ -653,6 +654,7 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */ CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */ CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP322]), /* USB0 */ + CLKDEV_DEV_ID("sh_flctl.0", &mstp_clks[MSTP315]), /* FLCTL */ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */ @@ -710,7 +712,7 @@ void __init sh7372_clock_init(void) clkdev_add_table(lookups, ARRAY_SIZE(lookups)); if (!ret) - clk_init(); + shmobile_clk_init(); else panic("failed to setup sh7372 clocks\n"); diff --git a/arch/arm/mach-shmobile/clock-sh7377.c b/arch/arm/mach-shmobile/clock-sh7377.c index 8cee7b151ae3..0798a15936c3 100644 --- a/arch/arm/mach-shmobile/clock-sh7377.c +++ b/arch/arm/mach-shmobile/clock-sh7377.c @@ -77,7 +77,7 @@ static unsigned long div2_recalc(struct clk *clk) return clk->parent->rate / 2; } -static struct clk_ops div2_clk_ops = { +static struct sh_clk_ops div2_clk_ops = { .recalc = div2_recalc, }; @@ -110,7 +110,7 @@ static unsigned long pllc1_recalc(struct clk *clk) return clk->parent->rate * mult; } -static struct clk_ops pllc1_clk_ops = { +static struct sh_clk_ops pllc1_clk_ops = { .recalc = pllc1_recalc, }; @@ -137,7 +137,7 @@ static unsigned long pllc2_recalc(struct clk *clk) return clk->parent->rate * mult; } -static struct clk_ops pllc2_clk_ops = { +static struct sh_clk_ops pllc2_clk_ops = { .recalc = pllc2_recalc, }; @@ -360,7 +360,7 @@ void __init sh7377_clock_init(void) clkdev_add_table(lookups, ARRAY_SIZE(lookups)); if (!ret) - clk_init(); + shmobile_clk_init(); else panic("failed to setup sh7377 clocks\n"); } diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c index 7727cca6136c..472d1f5361e5 100644 --- a/arch/arm/mach-shmobile/clock-sh73a0.c +++ b/arch/arm/mach-shmobile/clock-sh73a0.c @@ -88,7 +88,7 @@ static unsigned long div2_recalc(struct clk *clk) return clk->parent->rate / 2; } -static struct clk_ops div2_clk_ops = { +static struct sh_clk_ops div2_clk_ops = { .recalc = div2_recalc, }; @@ -97,7 +97,7 @@ static unsigned long div7_recalc(struct clk *clk) return clk->parent->rate / 7; } -static struct clk_ops div7_clk_ops = { +static struct sh_clk_ops div7_clk_ops = { .recalc = div7_recalc, }; @@ -106,7 +106,7 @@ static unsigned long div13_recalc(struct clk *clk) return clk->parent->rate / 13; } -static struct clk_ops div13_clk_ops = { +static struct sh_clk_ops div13_clk_ops = { .recalc = div13_recalc, }; @@ -122,7 +122,7 @@ static struct clk extal2_div2_clk = { .parent = &sh73a0_extal2_clk, }; -static struct clk_ops main_clk_ops = { +static struct sh_clk_ops main_clk_ops = { .recalc = followparent_recalc, }; @@ -156,7 +156,7 @@ static unsigned long pll_recalc(struct clk *clk) return clk->parent->rate * mult; } -static struct clk_ops pll_clk_ops = { +static struct sh_clk_ops pll_clk_ops = { .recalc = pll_recalc, }; @@ -438,7 +438,7 @@ static int dsiphy_set_rate(struct clk *clk, unsigned long rate) return 0; } -static struct clk_ops dsiphy_clk_ops = { +static struct sh_clk_ops dsiphy_clk_ops = { .recalc = dsiphy_recalc, .round_rate = dsiphy_round_rate, .set_rate = dsiphy_set_rate, @@ -620,7 +620,7 @@ void __init sh73a0_clock_init(void) clkdev_add_table(lookups, ARRAY_SIZE(lookups)); if (!ret) - clk_init(); + shmobile_clk_init(); else panic("failed to setup sh73a0 clocks\n"); } diff --git a/arch/arm/mach-shmobile/clock.c b/arch/arm/mach-shmobile/clock.c index 31654d78b96b..e816ca9bd213 100644 --- a/arch/arm/mach-shmobile/clock.c +++ b/arch/arm/mach-shmobile/clock.c @@ -24,7 +24,7 @@ #include <linux/sh_clk.h> #include <linux/export.h> -int __init clk_init(void) +int __init shmobile_clk_init(void) { /* Kick the child clocks.. */ recalculate_root_clocks(); diff --git a/arch/arm/mach-shmobile/cpuidle.c b/arch/arm/mach-shmobile/cpuidle.c index 1b2334277e85..7e6559105d40 100644 --- a/arch/arm/mach-shmobile/cpuidle.c +++ b/arch/arm/mach-shmobile/cpuidle.c @@ -13,7 +13,7 @@ #include <linux/suspend.h> #include <linux/module.h> #include <linux/err.h> -#include <asm/system.h> +#include <asm/cpuidle.h> #include <asm/io.h> static void shmobile_enter_wfi(void) @@ -29,37 +29,19 @@ static int shmobile_cpuidle_enter(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { - ktime_t before, after; - - before = ktime_get(); - - local_irq_disable(); - local_fiq_disable(); - shmobile_cpuidle_modes[index](); - local_irq_enable(); - local_fiq_enable(); - - after = ktime_get(); - dev->last_residency = ktime_to_ns(ktime_sub(after, before)) >> 10; - return index; } static struct cpuidle_device shmobile_cpuidle_dev; static struct cpuidle_driver shmobile_cpuidle_driver = { - .name = "shmobile_cpuidle", - .owner = THIS_MODULE, - .states[0] = { - .name = "C1", - .desc = "WFI", - .exit_latency = 1, - .target_residency = 1 * 2, - .flags = CPUIDLE_FLAG_TIME_VALID, - }, - .safe_state_index = 0, /* C1 */ - .state_count = 1, + .name = "shmobile_cpuidle", + .owner = THIS_MODULE, + .en_core_tk_irqen = 1, + .states[0] = ARM_CPUIDLE_WFI_STATE, + .safe_state_index = 0, /* C1 */ + .state_count = 1, }; void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv); diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h index e4b945e271e7..83ad3fe0a75f 100644 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h @@ -1,12 +1,15 @@ #ifndef __ARCH_MACH_COMMON_H #define __ARCH_MACH_COMMON_H +extern void shmobile_earlytimer_init(void); extern struct sys_timer shmobile_timer; +struct twd_local_timer; +void shmobile_twd_init(struct twd_local_timer *twd_local_timer); extern void shmobile_setup_console(void); extern void shmobile_secondary_vector(void); extern int shmobile_platform_cpu_kill(unsigned int cpu); struct clk; -extern int clk_init(void); +extern int shmobile_clk_init(void); extern void shmobile_handle_irq_intc(struct pt_regs *); extern struct platform_suspend_ops shmobile_suspend_ops; struct cpuidle_driver; @@ -14,6 +17,7 @@ extern void (*shmobile_cpuidle_modes[])(void); extern void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv); extern void sh7367_init_irq(void); +extern void sh7367_map_io(void); extern void sh7367_add_early_devices(void); extern void sh7367_add_standard_devices(void); extern void sh7367_clock_init(void); @@ -22,6 +26,7 @@ extern struct clk sh7367_extalb1_clk; extern struct clk sh7367_extal2_clk; extern void sh7377_init_irq(void); +extern void sh7377_map_io(void); extern void sh7377_add_early_devices(void); extern void sh7377_add_standard_devices(void); extern void sh7377_clock_init(void); @@ -30,6 +35,7 @@ extern struct clk sh7377_extalc1_clk; extern struct clk sh7377_extal2_clk; extern void sh7372_init_irq(void); +extern void sh7372_map_io(void); extern void sh7372_add_early_devices(void); extern void sh7372_add_standard_devices(void); extern void sh7372_clock_init(void); @@ -41,6 +47,7 @@ extern struct clk sh7372_extal1_clk; extern struct clk sh7372_extal2_clk; extern void sh73a0_init_irq(void); +extern void sh73a0_map_io(void); extern void sh73a0_add_early_devices(void); extern void sh73a0_add_standard_devices(void); extern void sh73a0_clock_init(void); @@ -56,12 +63,14 @@ extern int sh73a0_boot_secondary(unsigned int cpu); extern void sh73a0_smp_prepare_cpus(void); extern void r8a7740_init_irq(void); +extern void r8a7740_map_io(void); extern void r8a7740_add_early_devices(void); extern void r8a7740_add_standard_devices(void); extern void r8a7740_clock_init(u8 md_ck); extern void r8a7740_pinmux_init(void); extern void r8a7779_init_irq(void); +extern void r8a7779_map_io(void); extern void r8a7779_add_early_devices(void); extern void r8a7779_add_standard_devices(void); extern void r8a7779_clock_init(void); diff --git a/arch/arm/mach-shmobile/include/mach/entry-macro.S b/arch/arm/mach-shmobile/include/mach/entry-macro.S deleted file mode 100644 index 2a57b2964ee9..000000000000 --- a/arch/arm/mach-shmobile/include/mach/entry-macro.S +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2010 Paul Mundt - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-shmobile/include/mach/io.h b/arch/arm/mach-shmobile/include/mach/io.h deleted file mode 100644 index 7339fe46cb7c..000000000000 --- a/arch/arm/mach-shmobile/include/mach/io.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __ASM_MACH_IO_H -#define __ASM_MACH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -#define __io(a) ((void __iomem *)(a)) -#define __mem_pci(a) (a) - -#endif /* __ASM_MACH_IO_H */ diff --git a/arch/arm/mach-shmobile/include/mach/irqs.h b/arch/arm/mach-shmobile/include/mach/irqs.h index dcb714f4d75a..4e686cc201fc 100644 --- a/arch/arm/mach-shmobile/include/mach/irqs.h +++ b/arch/arm/mach-shmobile/include/mach/irqs.h @@ -1,15 +1,11 @@ #ifndef __ASM_MACH_IRQS_H #define __ASM_MACH_IRQS_H -#define NR_IRQS 1024 +#include <linux/sh_intc.h> /* GIC */ #define gic_spi(nr) ((nr) + 32) -/* INTCA */ -#define evt2irq(evt) (((evt) >> 5) - 16) -#define irq2evt(irq) (((irq) + 16) << 5) - /* INTCS */ #define INTCS_VECT_BASE 0x2200 #define INTCS_VECT(n, vect) INTC_VECT((n), INTCS_VECT_BASE + (vect)) diff --git a/arch/arm/mach-shmobile/include/mach/system.h b/arch/arm/mach-shmobile/include/mach/system.h index 956ac18ddbf9..540eaff08f34 100644 --- a/arch/arm/mach-shmobile/include/mach/system.h +++ b/arch/arm/mach-shmobile/include/mach/system.h @@ -1,10 +1,7 @@ #ifndef __ASM_ARCH_SYSTEM_H #define __ASM_ARCH_SYSTEM_H -static inline void arch_idle(void) -{ - cpu_do_idle(); -} +#include <asm/system_misc.h> static inline void arch_reset(char mode, const char *cmd) { diff --git a/arch/arm/mach-shmobile/intc-r8a7740.c b/arch/arm/mach-shmobile/intc-r8a7740.c index 272c84c20c83..09c42afcb22d 100644 --- a/arch/arm/mach-shmobile/intc-r8a7740.c +++ b/arch/arm/mach-shmobile/intc-r8a7740.c @@ -25,6 +25,7 @@ #include <linux/io.h> #include <linux/sh_intc.h> #include <mach/intc.h> +#include <mach/irqs.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-shmobile/intc-r8a7779.c b/arch/arm/mach-shmobile/intc-r8a7779.c index 5d92fcde2bc3..550b23df4fd4 100644 --- a/arch/arm/mach-shmobile/intc-r8a7779.c +++ b/arch/arm/mach-shmobile/intc-r8a7779.c @@ -42,8 +42,8 @@ static int r8a7779_set_wake(struct irq_data *data, unsigned int on) void __init r8a7779_init_irq(void) { - void __iomem *gic_dist_base = __io(0xf0001000); - void __iomem *gic_cpu_base = __io(0xf0000100); + void __iomem *gic_dist_base = IOMEM(0xf0001000); + void __iomem *gic_cpu_base = IOMEM(0xf0000100); /* use GIC to handle interrupts */ gic_init(0, 29, gic_dist_base, gic_cpu_base); diff --git a/arch/arm/mach-shmobile/intc-sh7367.c b/arch/arm/mach-shmobile/intc-sh7367.c index cfde9bfc3669..5bf776495b75 100644 --- a/arch/arm/mach-shmobile/intc-sh7367.c +++ b/arch/arm/mach-shmobile/intc-sh7367.c @@ -23,6 +23,7 @@ #include <linux/io.h> #include <linux/sh_intc.h> #include <mach/intc.h> +#include <mach/irqs.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-shmobile/intc-sh7372.c b/arch/arm/mach-shmobile/intc-sh7372.c index 89afcaba99a1..6447e0af52d4 100644 --- a/arch/arm/mach-shmobile/intc-sh7372.c +++ b/arch/arm/mach-shmobile/intc-sh7372.c @@ -23,6 +23,7 @@ #include <linux/io.h> #include <linux/sh_intc.h> #include <mach/intc.h> +#include <mach/irqs.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-shmobile/intc-sh7377.c b/arch/arm/mach-shmobile/intc-sh7377.c index 2af4e6e9bc5b..b84a460a3405 100644 --- a/arch/arm/mach-shmobile/intc-sh7377.c +++ b/arch/arm/mach-shmobile/intc-sh7377.c @@ -23,6 +23,7 @@ #include <linux/io.h> #include <linux/sh_intc.h> #include <mach/intc.h> +#include <mach/irqs.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c index 9857595eaa79..ee447404c857 100644 --- a/arch/arm/mach-shmobile/intc-sh73a0.c +++ b/arch/arm/mach-shmobile/intc-sh73a0.c @@ -24,6 +24,7 @@ #include <linux/io.h> #include <linux/sh_intc.h> #include <mach/intc.h> +#include <mach/irqs.h> #include <mach/sh73a0.h> #include <asm/hardware/gic.h> #include <asm/mach-types.h> @@ -420,8 +421,8 @@ static irqreturn_t sh73a0_pint1_demux(int irq, void *dev_id) void __init sh73a0_init_irq(void) { - void __iomem *gic_dist_base = __io(0xf0001000); - void __iomem *gic_cpu_base = __io(0xf0000100); + void __iomem *gic_dist_base = IOMEM(0xf0001000); + void __iomem *gic_cpu_base = IOMEM(0xf0000100); void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE); int k, n; diff --git a/arch/arm/mach-shmobile/localtimer.c b/arch/arm/mach-shmobile/localtimer.c deleted file mode 100644 index ad9ccc9900c8..000000000000 --- a/arch/arm/mach-shmobile/localtimer.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * SMP support for R-Mobile / SH-Mobile - local timer portion - * - * Copyright (C) 2010 Magnus Damm - * - * Based on vexpress, Copyright (C) 2002 ARM Ltd, All Rights Reserved - * - * 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 <linux/init.h> -#include <linux/smp.h> -#include <linux/clockchips.h> -#include <asm/smp_twd.h> -#include <asm/localtimer.h> - -/* - * Setup the local clock events for a CPU. - */ -int __cpuinit local_timer_setup(struct clock_event_device *evt) -{ - evt->irq = 29; - twd_timer_setup(evt); - return 0; -} diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c index 993381257f69..45fa3924c6a1 100644 --- a/arch/arm/mach-shmobile/platsmp.c +++ b/arch/arm/mach-shmobile/platsmp.c @@ -17,7 +17,6 @@ #include <linux/smp.h> #include <linux/io.h> #include <asm/hardware/gic.h> -#include <asm/localtimer.h> #include <asm/mach-types.h> #include <mach/common.h> diff --git a/arch/arm/mach-shmobile/pm-r8a7779.c b/arch/arm/mach-shmobile/pm-r8a7779.c index c38ba7b43ef8..a18a4ae16d2b 100644 --- a/arch/arm/mach-shmobile/pm-r8a7779.c +++ b/arch/arm/mach-shmobile/pm-r8a7779.c @@ -18,7 +18,6 @@ #include <linux/irq.h> #include <linux/interrupt.h> #include <linux/console.h> -#include <asm/system.h> #include <asm/io.h> #include <mach/common.h> #include <mach/r8a7779.h> diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c index fcf8b1761aef..a3bdb12acde9 100644 --- a/arch/arm/mach-shmobile/pm-sh7372.c +++ b/arch/arm/mach-shmobile/pm-sh7372.c @@ -21,7 +21,6 @@ #include <linux/irq.h> #include <linux/bitrev.h> #include <linux/console.h> -#include <asm/system.h> #include <asm/io.h> #include <asm/tlbflush.h> #include <asm/suspend.h> diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c index 986dca6b3fad..14edb5cffa7f 100644 --- a/arch/arm/mach-shmobile/setup-r8a7740.c +++ b/arch/arm/mach-shmobile/setup-r8a7740.c @@ -25,8 +25,42 @@ #include <linux/serial_sci.h> #include <linux/sh_timer.h> #include <mach/r8a7740.h> +#include <mach/common.h> +#include <mach/irqs.h> #include <asm/mach-types.h> +#include <asm/mach/map.h> #include <asm/mach/arch.h> +#include <asm/mach/time.h> + +static struct map_desc r8a7740_io_desc[] __initdata = { + /* + * for CPGA/INTC/PFC + * 0xe6000000-0xefffffff -> 0xe6000000-0xefffffff + */ + { + .virtual = 0xe6000000, + .pfn = __phys_to_pfn(0xe6000000), + .length = 160 << 20, + .type = MT_DEVICE_NONSHARED + }, +#ifdef CONFIG_CACHE_L2X0 + /* + * for l2x0_init() + * 0xf0100000-0xf0101000 -> 0xf0002000-0xf0003000 + */ + { + .virtual = 0xf0002000, + .pfn = __phys_to_pfn(0xf0100000), + .length = PAGE_SIZE, + .type = MT_DEVICE_NONSHARED + }, +#endif +}; + +void __init r8a7740_map_io(void) +{ + iotable_init(r8a7740_io_desc, ARRAY_SIZE(r8a7740_io_desc)); +} /* SCIFA0 */ static struct plat_sci_port scif0_platform_data = { @@ -345,8 +379,20 @@ void __init r8a7740_add_standard_devices(void) ARRAY_SIZE(r8a7740_late_devices)); } +static void __init r8a7740_earlytimer_init(void) +{ + r8a7740_clock_init(0); + shmobile_earlytimer_init(); +} + void __init r8a7740_add_early_devices(void) { early_platform_add_devices(r8a7740_early_devices, ARRAY_SIZE(r8a7740_early_devices)); + + /* setup early console here as well */ + shmobile_setup_console(); + + /* override timer setup with soc-specific code */ + shmobile_timer.init = r8a7740_earlytimer_init; } diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index 4725663bd032..12c6f529ab89 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -29,10 +29,36 @@ #include <linux/sh_intc.h> #include <linux/sh_timer.h> #include <mach/hardware.h> +#include <mach/irqs.h> #include <mach/r8a7779.h> #include <mach/common.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> +#include <asm/mach/time.h> +#include <asm/mach/map.h> +#include <asm/hardware/cache-l2x0.h> + +static struct map_desc r8a7779_io_desc[] __initdata = { + /* 2M entity map for 0xf0000000 (MPCORE) */ + { + .virtual = 0xf0000000, + .pfn = __phys_to_pfn(0xf0000000), + .length = SZ_2M, + .type = MT_DEVICE_NONSHARED + }, + /* 16M entity map for 0xfexxxxxx (DMAC-S/HPBREG/INTC2/LRAM/DBSC) */ + { + .virtual = 0xfe000000, + .pfn = __phys_to_pfn(0xfe000000), + .length = SZ_16M, + .type = MT_DEVICE_NONSHARED + }, +}; + +void __init r8a7779_map_io(void) +{ + iotable_init(r8a7779_io_desc, ARRAY_SIZE(r8a7779_io_desc)); +} static struct plat_sci_port scif0_platform_data = { .mapbase = 0xffe40000, @@ -219,6 +245,10 @@ static struct platform_device *r8a7779_late_devices[] __initdata = { void __init r8a7779_add_standard_devices(void) { +#ifdef CONFIG_CACHE_L2X0 + /* Early BRESP enable, Shared attribute override enable, 64K*16way */ + l2x0_init((void __iomem __force *)(0xf0100000), 0x40470000, 0x82000fff); +#endif r8a7779_pm_init(); r8a7779_init_pm_domain(&r8a7779_sh4a); @@ -232,8 +262,33 @@ void __init r8a7779_add_standard_devices(void) ARRAY_SIZE(r8a7779_late_devices)); } +static void __init r8a7779_earlytimer_init(void) +{ + r8a7779_clock_init(); + shmobile_earlytimer_init(); +} + void __init r8a7779_add_early_devices(void) { early_platform_add_devices(r8a7779_early_devices, ARRAY_SIZE(r8a7779_early_devices)); + + /* Early serial console setup is not included here due to + * memory map collisions. The SCIF serial ports in r8a7779 + * are difficult to entity map 1:1 due to collision with the + * virtual memory range used by the coherent DMA code on ARM. + * + * Anyone wanting to debug early can remove UPF_IOREMAP from + * the sh-sci serial console platform data, adjust mapbase + * to a static M:N virt:phys mapping that needs to be added to + * the mappings passed with iotable_init() above. + * + * Then add a call to shmobile_setup_console() from this function. + * + * As a final step pass earlyprint=sh-sci.2,115200 on the kernel + * command line in case of the marzen board. + */ + + /* override timer setup with soc-specific code */ + shmobile_timer.init = r8a7779_earlytimer_init; } diff --git a/arch/arm/mach-shmobile/setup-sh7367.c b/arch/arm/mach-shmobile/setup-sh7367.c index e546017f15de..2e3074ab75b3 100644 --- a/arch/arm/mach-shmobile/setup-sh7367.c +++ b/arch/arm/mach-shmobile/setup-sh7367.c @@ -29,8 +29,29 @@ #include <linux/serial_sci.h> #include <linux/sh_timer.h> #include <mach/hardware.h> +#include <mach/common.h> +#include <mach/irqs.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/time.h> + +static struct map_desc sh7367_io_desc[] __initdata = { + /* create a 1:1 entity map for 0xe6xxxxxx + * used by CPGA, INTC and PFC. + */ + { + .virtual = 0xe6000000, + .pfn = __phys_to_pfn(0xe6000000), + .length = 256 << 20, + .type = MT_DEVICE_NONSHARED + }, +}; + +void __init sh7367_map_io(void) +{ + iotable_init(sh7367_io_desc, ARRAY_SIZE(sh7367_io_desc)); +} /* SCIFA0 */ static struct plat_sci_port scif0_platform_data = { @@ -435,6 +456,12 @@ void __init sh7367_add_standard_devices(void) ARRAY_SIZE(sh7367_devices)); } +static void __init sh7367_earlytimer_init(void) +{ + sh7367_clock_init(); + shmobile_earlytimer_init(); +} + #define SYMSTPCR2 0xe6158048 #define SYMSTPCR2_CMT1 (1 << 29) @@ -445,4 +472,10 @@ void __init sh7367_add_early_devices(void) early_platform_add_devices(sh7367_early_devices, ARRAY_SIZE(sh7367_early_devices)); + + /* setup early console here as well */ + shmobile_setup_console(); + + /* override timer setup with soc-specific code */ + shmobile_timer.init = sh7367_earlytimer_init; } diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index cccf91b8fae1..2fe8f83ca124 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c @@ -31,10 +31,38 @@ #include <linux/sh_intc.h> #include <linux/sh_timer.h> #include <linux/pm_domain.h> +#include <linux/dma-mapping.h> #include <mach/hardware.h> +#include <mach/irqs.h> #include <mach/sh7372.h> +#include <mach/common.h> +#include <asm/mach/map.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> +#include <asm/mach/time.h> + +static struct map_desc sh7372_io_desc[] __initdata = { + /* create a 1:1 entity map for 0xe6xxxxxx + * used by CPGA, INTC and PFC. + */ + { + .virtual = 0xe6000000, + .pfn = __phys_to_pfn(0xe6000000), + .length = 256 << 20, + .type = MT_DEVICE_NONSHARED + }, +}; + +void __init sh7372_map_io(void) +{ + iotable_init(sh7372_io_desc, ARRAY_SIZE(sh7372_io_desc)); + + /* + * DMA memory at 0xff200000 - 0xffdfffff. The default 2MB size isn't + * enough to allocate the frame buffer memory. + */ + init_consistent_dma_size(12 << 20); +} /* SCIFA0 */ static struct plat_sci_port scif0_platform_data = { @@ -1047,8 +1075,20 @@ void __init sh7372_add_standard_devices(void) sh7372_add_device_to_domain(&sh7372_a4r, &tmu01_device); } +static void __init sh7372_earlytimer_init(void) +{ + sh7372_clock_init(); + shmobile_earlytimer_init(); +} + void __init sh7372_add_early_devices(void) { early_platform_add_devices(sh7372_early_devices, ARRAY_SIZE(sh7372_early_devices)); + + /* setup early console here as well */ + shmobile_setup_console(); + + /* override timer setup with soc-specific code */ + shmobile_timer.init = sh7372_earlytimer_init; } diff --git a/arch/arm/mach-shmobile/setup-sh7377.c b/arch/arm/mach-shmobile/setup-sh7377.c index bb405b8e459b..d576a6abbade 100644 --- a/arch/arm/mach-shmobile/setup-sh7377.c +++ b/arch/arm/mach-shmobile/setup-sh7377.c @@ -30,8 +30,29 @@ #include <linux/sh_intc.h> #include <linux/sh_timer.h> #include <mach/hardware.h> +#include <mach/common.h> +#include <asm/mach/map.h> +#include <mach/irqs.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> +#include <asm/mach/time.h> + +static struct map_desc sh7377_io_desc[] __initdata = { + /* create a 1:1 entity map for 0xe6xxxxxx + * used by CPGA, INTC and PFC. + */ + { + .virtual = 0xe6000000, + .pfn = __phys_to_pfn(0xe6000000), + .length = 256 << 20, + .type = MT_DEVICE_NONSHARED + }, +}; + +void __init sh7377_map_io(void) +{ + iotable_init(sh7377_io_desc, ARRAY_SIZE(sh7377_io_desc)); +} /* SCIFA0 */ static struct plat_sci_port scif0_platform_data = { @@ -456,6 +477,12 @@ void __init sh7377_add_standard_devices(void) ARRAY_SIZE(sh7377_devices)); } +static void __init sh7377_earlytimer_init(void) +{ + sh7377_clock_init(); + shmobile_earlytimer_init(); +} + #define SMSTPCR3 0xe615013c #define SMSTPCR3_CMT1 (1 << 29) @@ -466,4 +493,10 @@ void __init sh7377_add_early_devices(void) early_platform_add_devices(sh7377_early_devices, ARRAY_SIZE(sh7377_early_devices)); + + /* setup early console here as well */ + shmobile_setup_console(); + + /* override timer setup with soc-specific code */ + shmobile_timer.init = sh7377_earlytimer_init; } diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index 20e71e5cace4..5bebffc10455 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c @@ -31,9 +31,30 @@ #include <linux/sh_intc.h> #include <linux/sh_timer.h> #include <mach/hardware.h> +#include <mach/irqs.h> #include <mach/sh73a0.h> +#include <mach/common.h> #include <asm/mach-types.h> +#include <asm/mach/map.h> #include <asm/mach/arch.h> +#include <asm/mach/time.h> + +static struct map_desc sh73a0_io_desc[] __initdata = { + /* create a 1:1 entity map for 0xe6xxxxxx + * used by CPGA, INTC and PFC. + */ + { + .virtual = 0xe6000000, + .pfn = __phys_to_pfn(0xe6000000), + .length = 256 << 20, + .type = MT_DEVICE_NONSHARED + }, +}; + +void __init sh73a0_map_io(void) +{ + iotable_init(sh73a0_io_desc, ARRAY_SIZE(sh73a0_io_desc)); +} static struct plat_sci_port scif0_platform_data = { .mapbase = 0xe6c40000, @@ -667,8 +688,20 @@ void __init sh73a0_add_standard_devices(void) ARRAY_SIZE(sh73a0_late_devices)); } +static void __init sh73a0_earlytimer_init(void) +{ + sh73a0_clock_init(); + shmobile_earlytimer_init(); +} + void __init sh73a0_add_early_devices(void) { early_platform_add_devices(sh73a0_early_devices, ARRAY_SIZE(sh73a0_early_devices)); + + /* setup early console here as well */ + shmobile_setup_console(); + + /* override timer setup with soc-specific code */ + shmobile_timer.init = sh73a0_earlytimer_init; } diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c index 4fe2e9eaf501..b62e19d4c9af 100644 --- a/arch/arm/mach-shmobile/smp-r8a7779.c +++ b/arch/arm/mach-shmobile/smp-r8a7779.c @@ -30,7 +30,7 @@ #include <asm/smp_twd.h> #include <asm/hardware/gic.h> -#define AVECR 0xfe700040 +#define AVECR IOMEM(0xfe700040) static struct r8a7779_pm_ch r8a7779_ch_cpu1 = { .chan_offs = 0x40, /* PWRSR0 .. PWRER0 */ @@ -64,6 +64,8 @@ static void __iomem *scu_base_addr(void) static DEFINE_SPINLOCK(scu_lock); static unsigned long tmp; +static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29); + static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) { void __iomem *scu_base = scu_base_addr(); @@ -82,11 +84,7 @@ unsigned int __init r8a7779_get_core_count(void) { void __iomem *scu_base = scu_base_addr(); -#ifdef CONFIG_HAVE_ARM_TWD - /* twd_base needs to be initialized before percpu_timer_setup() */ - twd_base = (void __iomem *)0xf0000600; -#endif - + shmobile_twd_init(&twd_local_timer); return scu_get_core_count(scu_base); } @@ -140,7 +138,7 @@ void __init r8a7779_smp_prepare_cpus(void) scu_enable(scu_base_addr()); /* Map the reset vector (in headsmp.S) */ - __raw_writel(__pa(shmobile_secondary_vector), __io(AVECR)); + __raw_writel(__pa(shmobile_secondary_vector), AVECR); /* enable cache coherency on CPU0 */ modify_scu_cpu_psr(0, 3 << (cpu * 8)); diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c index 2d0d4212be41..14ad8b052f1a 100644 --- a/arch/arm/mach-shmobile/smp-sh73a0.c +++ b/arch/arm/mach-shmobile/smp-sh73a0.c @@ -28,11 +28,11 @@ #include <asm/smp_twd.h> #include <asm/hardware/gic.h> -#define WUPCR 0xe6151010 -#define SRESCR 0xe6151018 -#define PSTR 0xe6151040 -#define SBAR 0xe6180020 -#define APARMBAREA 0xe6f10020 +#define WUPCR IOMEM(0xe6151010) +#define SRESCR IOMEM(0xe6151018) +#define PSTR IOMEM(0xe6151040) +#define SBAR IOMEM(0xe6180020) +#define APARMBAREA IOMEM(0xe6f10020) static void __iomem *scu_base_addr(void) { @@ -42,6 +42,8 @@ static void __iomem *scu_base_addr(void) static DEFINE_SPINLOCK(scu_lock); static unsigned long tmp; +static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29); + static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) { void __iomem *scu_base = scu_base_addr(); @@ -60,11 +62,7 @@ unsigned int __init sh73a0_get_core_count(void) { void __iomem *scu_base = scu_base_addr(); -#ifdef CONFIG_HAVE_ARM_TWD - /* twd_base needs to be initialized before percpu_timer_setup() */ - twd_base = (void __iomem *)0xf0000600; -#endif - + shmobile_twd_init(&twd_local_timer); return scu_get_core_count(scu_base); } @@ -80,10 +78,10 @@ int __cpuinit sh73a0_boot_secondary(unsigned int cpu) /* enable cache coherency */ modify_scu_cpu_psr(0, 3 << (cpu * 8)); - if (((__raw_readl(__io(PSTR)) >> (4 * cpu)) & 3) == 3) - __raw_writel(1 << cpu, __io(WUPCR)); /* wake up */ + if (((__raw_readl(PSTR) >> (4 * cpu)) & 3) == 3) + __raw_writel(1 << cpu, WUPCR); /* wake up */ else - __raw_writel(1 << cpu, __io(SRESCR)); /* reset */ + __raw_writel(1 << cpu, SRESCR); /* reset */ return 0; } @@ -95,8 +93,8 @@ void __init sh73a0_smp_prepare_cpus(void) scu_enable(scu_base_addr()); /* Map the reset vector (in headsmp.S) */ - __raw_writel(0, __io(APARMBAREA)); /* 4k */ - __raw_writel(__pa(shmobile_secondary_vector), __io(SBAR)); + __raw_writel(0, APARMBAREA); /* 4k */ + __raw_writel(__pa(shmobile_secondary_vector), SBAR); /* enable cache coherency on CPU0 */ modify_scu_cpu_psr(0, 3 << (cpu * 8)); diff --git a/arch/arm/mach-shmobile/suspend.c b/arch/arm/mach-shmobile/suspend.c index c1febe13f709..4d1b86a49923 100644 --- a/arch/arm/mach-shmobile/suspend.c +++ b/arch/arm/mach-shmobile/suspend.c @@ -12,8 +12,8 @@ #include <linux/suspend.h> #include <linux/module.h> #include <linux/err.h> -#include <asm/system.h> #include <asm/io.h> +#include <asm/system_misc.h> static int shmobile_suspend_default_enter(suspend_state_t suspend_state) { diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c index 895794b543cd..2fba5f3d1c8a 100644 --- a/arch/arm/mach-shmobile/timer.c +++ b/arch/arm/mach-shmobile/timer.c @@ -20,6 +20,7 @@ */ #include <linux/platform_device.h> #include <asm/mach/time.h> +#include <asm/smp_twd.h> static void __init shmobile_late_time_init(void) { @@ -36,11 +37,24 @@ static void __init shmobile_late_time_init(void) early_platform_driver_probe("earlytimer", 2, 0); } -static void __init shmobile_timer_init(void) +void __init shmobile_earlytimer_init(void) { late_time_init = shmobile_late_time_init; } +static void __init shmobile_timer_init(void) +{ +} + +void __init shmobile_twd_init(struct twd_local_timer *twd_local_timer) +{ +#ifdef CONFIG_HAVE_ARM_TWD + int err = twd_local_timer_register(twd_local_timer); + if (err) + pr_err("twd_local_timer_register failed %d\n", err); +#endif +} + struct sys_timer shmobile_timer = { .init = shmobile_timer_init, }; diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c index f67860cd649f..6c4841f55223 100644 --- a/arch/arm/mach-spear3xx/clock.c +++ b/arch/arm/mach-spear3xx/clock.c @@ -12,6 +12,7 @@ */ #include <linux/init.h> +#include <linux/io.h> #include <linux/kernel.h> #include <asm/mach-types.h> #include <plat/clock.h> diff --git a/arch/arm/mach-spear3xx/include/mach/entry-macro.S b/arch/arm/mach-spear3xx/include/mach/entry-macro.S deleted file mode 100644 index de3bb41c8e9e..000000000000 --- a/arch/arm/mach-spear3xx/include/mach/entry-macro.S +++ /dev/null @@ -1,18 +0,0 @@ -/* - * arch/arm/mach-spear3xx/include/mach/entry-macro.S - * - * Low-level IRQ helper macros for SPEAr3xx machine family - * - * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar<viresh.kumar@st.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-spear3xx/include/mach/io.h b/arch/arm/mach-spear3xx/include/mach/io.h deleted file mode 100644 index 30cff8a1f6b5..000000000000 --- a/arch/arm/mach-spear3xx/include/mach/io.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/arm/mach-spear3xx/include/mach/io.h - * - * IO definitions for SPEAr3xx machine family - * - * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar<viresh.kumar@st.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __MACH_IO_H -#define __MACH_IO_H - -#include <plat/io.h> - -#endif /* __MACH_IO_H */ diff --git a/arch/arm/mach-spear3xx/include/mach/system.h b/arch/arm/mach-spear3xx/include/mach/system.h deleted file mode 100644 index 92cee6335c90..000000000000 --- a/arch/arm/mach-spear3xx/include/mach/system.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/arm/mach-spear3xx/include/mach/system.h - * - * SPEAr3xx Machine family specific architecture functions - * - * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar<viresh.kumar@st.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __MACH_SYSTEM_H -#define __MACH_SYSTEM_H - -#include <plat/system.h> - -#endif /* __MACH_SYSTEM_H */ diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c index 4f7f5182dd4d..f7db66812abb 100644 --- a/arch/arm/mach-spear3xx/spear300.c +++ b/arch/arm/mach-spear3xx/spear300.c @@ -430,18 +430,8 @@ static struct pl061_platform_data gpio1_plat_data = { .irq_base = SPEAR300_GPIO1_INT_BASE, }; -struct amba_device spear300_gpio1_device = { - .dev = { - .init_name = "gpio1", - .platform_data = &gpio1_plat_data, - }, - .res = { - .start = SPEAR300_GPIO_BASE, - .end = SPEAR300_GPIO_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = {SPEAR300_VIRQ_GPIO1, NO_IRQ}, -}; +AMBA_APB_DEVICE(spear300_gpio1, "gpio1", 0, SPEAR300_GPIO_BASE, + {SPEAR300_VIRQ_GPIO1}, &gpio1_plat_data); /* spear300 routines */ void __init spear300_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs, diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c index 10af45da86a0..b1733c37f209 100644 --- a/arch/arm/mach-spear3xx/spear3xx.c +++ b/arch/arm/mach-spear3xx/spear3xx.c @@ -28,31 +28,12 @@ static struct pl061_platform_data gpio_plat_data = { .irq_base = SPEAR3XX_GPIO_INT_BASE, }; -struct amba_device spear3xx_gpio_device = { - .dev = { - .init_name = "gpio", - .platform_data = &gpio_plat_data, - }, - .res = { - .start = SPEAR3XX_ICM3_GPIO_BASE, - .end = SPEAR3XX_ICM3_GPIO_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = {SPEAR3XX_IRQ_BASIC_GPIO, NO_IRQ}, -}; +AMBA_APB_DEVICE(spear3xx_gpio, "gpio", 0, SPEAR3XX_ICM3_GPIO_BASE, + {SPEAR3XX_IRQ_BASIC_GPIO}, &gpio_plat_data); /* uart device registration */ -struct amba_device spear3xx_uart_device = { - .dev = { - .init_name = "uart", - }, - .res = { - .start = SPEAR3XX_ICM1_UART_BASE, - .end = SPEAR3XX_ICM1_UART_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = {SPEAR3XX_IRQ_UART, NO_IRQ}, -}; +AMBA_APB_DEVICE(spear3xx_uart, "uart", 0, SPEAR3XX_ICM1_UART_BASE, + {SPEAR3XX_IRQ_UART}, NULL); /* Do spear3xx familiy common initialization part here */ void __init spear3xx_init(void) diff --git a/arch/arm/mach-spear6xx/Kconfig b/arch/arm/mach-spear6xx/Kconfig index ff4ae5ba00f1..fbe298bd1d92 100644 --- a/arch/arm/mach-spear6xx/Kconfig +++ b/arch/arm/mach-spear6xx/Kconfig @@ -5,11 +5,12 @@ if ARCH_SPEAR6XX menu "SPEAr6xx Implementations" -config BOARD_SPEAR600_EVB - bool "SPEAr600 Evaluation Board" +config BOARD_SPEAR600_DT + bool "SPEAr600 generic board configured via device-tree" select MACH_SPEAR600 + select USE_OF help - Supports ST SPEAr600 Evaluation Board + Supports ST SPEAr600 boards configured via the device-tree endmenu diff --git a/arch/arm/mach-spear6xx/Makefile b/arch/arm/mach-spear6xx/Makefile index cc1a4d82d459..76e5750552fc 100644 --- a/arch/arm/mach-spear6xx/Makefile +++ b/arch/arm/mach-spear6xx/Makefile @@ -4,9 +4,3 @@ # common files obj-y += clock.o spear6xx.o - -# spear600 specific files -obj-$(CONFIG_MACH_SPEAR600) += spear600.o - -# spear600 boards files -obj-$(CONFIG_BOARD_SPEAR600_EVB) += spear600_evb.o diff --git a/arch/arm/mach-spear6xx/clock.c b/arch/arm/mach-spear6xx/clock.c index ac70e0d88fef..a86499a8a15f 100644 --- a/arch/arm/mach-spear6xx/clock.c +++ b/arch/arm/mach-spear6xx/clock.c @@ -12,6 +12,7 @@ */ #include <linux/init.h> +#include <linux/io.h> #include <linux/kernel.h> #include <plat/clock.h> #include <mach/misc_regs.h> @@ -641,8 +642,8 @@ static struct clk_lookup spear_clk_lookups[] = { { .con_id = "gpt0_synth_clk", .clk = &gpt0_synth_clk}, { .con_id = "gpt2_synth_clk", .clk = &gpt2_synth_clk}, { .con_id = "gpt3_synth_clk", .clk = &gpt3_synth_clk}, - { .dev_id = "uart0", .clk = &uart0_clk}, - { .dev_id = "uart1", .clk = &uart1_clk}, + { .dev_id = "d0000000.serial", .clk = &uart0_clk}, + { .dev_id = "d0080000.serial", .clk = &uart1_clk}, { .dev_id = "firda", .clk = &firda_clk}, { .dev_id = "clcd", .clk = &clcd_clk}, { .dev_id = "gpt0", .clk = &gpt0_clk}, @@ -655,20 +656,20 @@ static struct clk_lookup spear_clk_lookups[] = { { .con_id = "usbh.1_clk", .clk = &usbh1_clk}, /* clock derived from ahb clk */ { .con_id = "apb_clk", .clk = &apb_clk}, - { .dev_id = "i2c_designware.0", .clk = &i2c_clk}, + { .dev_id = "d0200000.i2c", .clk = &i2c_clk}, { .dev_id = "dma", .clk = &dma_clk}, { .dev_id = "jpeg", .clk = &jpeg_clk}, { .dev_id = "gmac", .clk = &gmac_clk}, { .dev_id = "smi", .clk = &smi_clk}, - { .con_id = "fsmc", .clk = &fsmc_clk}, + { .dev_id = "fsmc-nand", .clk = &fsmc_clk}, /* clock derived from apb clk */ { .dev_id = "adc", .clk = &adc_clk}, { .dev_id = "ssp-pl022.0", .clk = &ssp0_clk}, { .dev_id = "ssp-pl022.1", .clk = &ssp1_clk}, { .dev_id = "ssp-pl022.2", .clk = &ssp2_clk}, - { .dev_id = "gpio0", .clk = &gpio0_clk}, - { .dev_id = "gpio1", .clk = &gpio1_clk}, - { .dev_id = "gpio2", .clk = &gpio2_clk}, + { .dev_id = "f0100000.gpio", .clk = &gpio0_clk}, + { .dev_id = "fc980000.gpio", .clk = &gpio1_clk}, + { .dev_id = "d8100000.gpio", .clk = &gpio2_clk}, }; void __init spear6xx_clk_init(void) diff --git a/arch/arm/mach-spear6xx/include/mach/entry-macro.S b/arch/arm/mach-spear6xx/include/mach/entry-macro.S deleted file mode 100644 index d490a910d925..000000000000 --- a/arch/arm/mach-spear6xx/include/mach/entry-macro.S +++ /dev/null @@ -1,18 +0,0 @@ -/* - * arch/arm/mach-spear6xx/include/mach/entry-macro.S - * - * Low-level IRQ helper macros for SPEAr6xx machine family - * - * Copyright (C) 2009 ST Microelectronics - * Rajeev Kumar<rajeev-dlh.kumar@st.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-spear6xx/include/mach/io.h b/arch/arm/mach-spear6xx/include/mach/io.h deleted file mode 100644 index fb7c106cea94..000000000000 --- a/arch/arm/mach-spear6xx/include/mach/io.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * arch/arm/mach-spear6xx/include/mach/io.h - * - * IO definitions for SPEAr6xx machine family - * - * Copyright (C) 2009 ST Microelectronics - * Rajeev Kumar Kumar<rajeev-dlh.kumar@st.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __MACH_IO_H -#define __MACH_IO_H - -#include <plat/io.h> - -#endif /* __MACH_IO_H */ - diff --git a/arch/arm/mach-spear6xx/include/mach/system.h b/arch/arm/mach-spear6xx/include/mach/system.h deleted file mode 100644 index 0b1d2be81cfb..000000000000 --- a/arch/arm/mach-spear6xx/include/mach/system.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/arm/mach-spear6xx/include/mach/system.h - * - * SPEAr6xx Machine family specific architecture functions - * - * Copyright (C) 2009 ST Microelectronics - * Rajeev Kumar<rajeev-dlh.kumar@st.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __MACH_SYSTEM_H -#define __MACH_SYSTEM_H - -#include <plat/system.h> - -#endif /* __MACH_SYSTEM_H */ diff --git a/arch/arm/mach-spear6xx/spear600.c b/arch/arm/mach-spear6xx/spear600.c deleted file mode 100644 index d0e6eeae9b04..000000000000 --- a/arch/arm/mach-spear6xx/spear600.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * arch/arm/mach-spear6xx/spear600.c - * - * SPEAr600 machine source file - * - * Copyright (C) 2009 ST Microelectronics - * Rajeev Kumar<rajeev-dlh.kumar@st.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include <linux/ptrace.h> -#include <asm/irq.h> -#include <mach/generic.h> -#include <mach/hardware.h> - -/* Add spear600 specific devices here */ - -void __init spear600_init(void) -{ - /* call spear6xx family common init function */ - spear6xx_init(); -} diff --git a/arch/arm/mach-spear6xx/spear600_evb.c b/arch/arm/mach-spear6xx/spear600_evb.c deleted file mode 100644 index c6e4254741cc..000000000000 --- a/arch/arm/mach-spear6xx/spear600_evb.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * arch/arm/mach-spear6xx/spear600_evb.c - * - * SPEAr600 evaluation board source file - * - * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar<viresh.kumar@st.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include <asm/hardware/vic.h> -#include <asm/mach/arch.h> -#include <asm/mach-types.h> -#include <mach/generic.h> -#include <mach/hardware.h> - -static struct amba_device *amba_devs[] __initdata = { - &gpio_device[0], - &gpio_device[1], - &gpio_device[2], - &uart_device[0], - &uart_device[1], -}; - -static struct platform_device *plat_devs[] __initdata = { -}; - -static void __init spear600_evb_init(void) -{ - unsigned int i; - - /* call spear600 machine init function */ - spear600_init(); - - /* Add Platform Devices */ - platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs)); - - /* Add Amba Devices */ - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) - amba_device_register(amba_devs[i], &iomem_resource); -} - -MACHINE_START(SPEAR600, "ST-SPEAR600-EVB") - .atag_offset = 0x100, - .map_io = spear6xx_map_io, - .init_irq = spear6xx_init_irq, - .handle_irq = vic_handle_irq, - .timer = &spear6xx_timer, - .init_machine = spear600_evb_init, - .restart = spear_restart, -MACHINE_END diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c index e0f6628c8b2c..2ed8b14c82c8 100644 --- a/arch/arm/mach-spear6xx/spear6xx.c +++ b/arch/arm/mach-spear6xx/spear6xx.c @@ -6,111 +6,21 @@ * Copyright (C) 2009 ST Microelectronics * Rajeev Kumar<rajeev-dlh.kumar@st.com> * + * Copyright 2012 Stefan Roese <sr@denx.de> + * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any * warranty of any kind, whether express or implied. */ -#include <linux/types.h> -#include <linux/amba/pl061.h> -#include <linux/ptrace.h> -#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h> #include <asm/hardware/vic.h> -#include <asm/irq.h> #include <asm/mach/arch.h> #include <mach/generic.h> #include <mach/hardware.h> -#include <mach/irqs.h> - -/* Add spear6xx machines common devices here */ -/* uart device registration */ -struct amba_device uart_device[] = { - { - .dev = { - .init_name = "uart0", - }, - .res = { - .start = SPEAR6XX_ICM1_UART0_BASE, - .end = SPEAR6XX_ICM1_UART0_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_UART_0, NO_IRQ}, - }, { - .dev = { - .init_name = "uart1", - }, - .res = { - .start = SPEAR6XX_ICM1_UART1_BASE, - .end = SPEAR6XX_ICM1_UART1_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_UART_1, NO_IRQ}, - } -}; - -/* gpio device registration */ -static struct pl061_platform_data gpio_plat_data[] = { - { - .gpio_base = 0, - .irq_base = SPEAR_GPIO0_INT_BASE, - }, { - .gpio_base = 8, - .irq_base = SPEAR_GPIO1_INT_BASE, - }, { - .gpio_base = 16, - .irq_base = SPEAR_GPIO2_INT_BASE, - }, -}; - -struct amba_device gpio_device[] = { - { - .dev = { - .init_name = "gpio0", - .platform_data = &gpio_plat_data[0], - }, - .res = { - .start = SPEAR6XX_CPU_GPIO_BASE, - .end = SPEAR6XX_CPU_GPIO_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_LOCAL_GPIO, NO_IRQ}, - }, { - .dev = { - .init_name = "gpio1", - .platform_data = &gpio_plat_data[1], - }, - .res = { - .start = SPEAR6XX_ICM3_GPIO_BASE, - .end = SPEAR6XX_ICM3_GPIO_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_BASIC_GPIO, NO_IRQ}, - }, { - .dev = { - .init_name = "gpio2", - .platform_data = &gpio_plat_data[2], - }, - .res = { - .start = SPEAR6XX_ICM2_GPIO_BASE, - .end = SPEAR6XX_ICM2_GPIO_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_APPL_GPIO, NO_IRQ}, - } -}; - -/* This will add devices, and do machine specific tasks */ -void __init spear6xx_init(void) -{ - /* nothing to do for now */ -} - -/* This will initialize vic */ -void __init spear6xx_init_irq(void) -{ - vic_init((void __iomem *)VA_SPEAR6XX_CPU_VIC_PRI_BASE, 0, ~0, 0); - vic_init((void __iomem *)VA_SPEAR6XX_CPU_VIC_SEC_BASE, 32, ~0, 0); -} /* Following will create static virtual/physical mappings */ static struct map_desc spear6xx_io_desc[] __initdata = { @@ -181,3 +91,33 @@ static void __init spear6xx_timer_init(void) struct sys_timer spear6xx_timer = { .init = spear6xx_timer_init, }; + +static void __init spear600_dt_init(void) +{ + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +} + +static const char *spear600_dt_board_compat[] = { + "st,spear600", + NULL +}; + +static const struct of_device_id vic_of_match[] __initconst = { + { .compatible = "arm,pl190-vic", .data = vic_of_init, }, + { /* Sentinel */ } +}; + +static void __init spear6xx_dt_init_irq(void) +{ + of_irq_init(vic_of_match); +} + +DT_MACHINE_START(SPEAR600_DT, "ST SPEAr600 (Flattened Device Tree)") + .map_io = spear6xx_map_io, + .init_irq = spear6xx_dt_init_irq, + .handle_irq = vic_handle_irq, + .timer = &spear6xx_timer, + .init_machine = spear600_dt_init, + .restart = spear_restart, + .dt_compat = spear600_dt_board_compat, +MACHINE_END diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 32b420a90c3d..d0f2546706ca 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -10,8 +10,16 @@ config ARCH_TEGRA_2x_SOC select PINCTRL select PINCTRL_TEGRA20 select USB_ARCH_HAS_EHCI if USB_SUPPORT - select USB_ULPI if USB_SUPPORT + select USB_ULPI if USB select USB_ULPI_VIEWPORT if USB_SUPPORT + select ARM_ERRATA_720789 + select ARM_ERRATA_742230 + select ARM_ERRATA_751472 + select ARM_ERRATA_754327 + select ARM_ERRATA_764369 + select PL310_ERRATA_727915 if CACHE_L2X0 + select PL310_ERRATA_769419 if CACHE_L2X0 + select CPU_FREQ_TABLE if CPU_FREQ help Support for NVIDIA Tegra AP20 and T20 processors, based on the ARM CortexA9MP CPU and the ARM PL310 L2 cache controller @@ -24,9 +32,15 @@ config ARCH_TEGRA_3x_SOC select PINCTRL select PINCTRL_TEGRA30 select USB_ARCH_HAS_EHCI if USB_SUPPORT - select USB_ULPI if USB_SUPPORT + select USB_ULPI if USB select USB_ULPI_VIEWPORT if USB_SUPPORT select USE_OF + select ARM_ERRATA_743622 + select ARM_ERRATA_751472 + select ARM_ERRATA_754322 + select ARM_ERRATA_764369 + select PL310_ERRATA_769419 if CACHE_L2X0 + select CPU_FREQ_TABLE if CPU_FREQ help Support for NVIDIA Tegra T30 processor family, based on the ARM CortexA9MP CPU and the ARM PL310 L2 cache controller diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index e120ff54f663..d87d968115ec 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -7,15 +7,21 @@ obj-y += clock.o obj-y += timer.o obj-y += pinmux.o obj-y += fuse.o +obj-y += pmc.o +obj-y += flowctrl.o +obj-$(CONFIG_CPU_IDLE) += cpuidle.o +obj-$(CONFIG_CPU_IDLE) += sleep.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += powergate.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pinmux-tegra20-tables.o obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pinmux-tegra30-tables.o obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o -obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o +obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_clocks.o +obj-$(CONFIG_SMP) += platsmp.o headsmp.o +obj-$(CONFIG_SMP) += reset.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o -obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o +obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o apbio.o obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o obj-$(CONFIG_TEGRA_PCI) += pcie.o obj-$(CONFIG_USB_SUPPORT) += usb_phy.o diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c new file mode 100644 index 000000000000..e75451e517bd --- /dev/null +++ b/arch/arm/mach-tegra/apbio.c @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2010 NVIDIA Corporation. + * Copyright (C) 2010 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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/kernel.h> +#include <linux/io.h> +#include <linux/dma-mapping.h> +#include <linux/spinlock.h> +#include <linux/completion.h> +#include <linux/sched.h> +#include <linux/mutex.h> + +#include <mach/dma.h> +#include <mach/iomap.h> + +#include "apbio.h" + +static DEFINE_MUTEX(tegra_apb_dma_lock); + +static struct tegra_dma_channel *tegra_apb_dma; +static u32 *tegra_apb_bb; +static dma_addr_t tegra_apb_bb_phys; +static DECLARE_COMPLETION(tegra_apb_wait); + +bool tegra_apb_init(void) +{ + struct tegra_dma_channel *ch; + + mutex_lock(&tegra_apb_dma_lock); + + /* Check to see if we raced to setup */ + if (tegra_apb_dma) + goto out; + + ch = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT | + TEGRA_DMA_SHARED); + + if (!ch) + goto out_fail; + + tegra_apb_bb = dma_alloc_coherent(NULL, sizeof(u32), + &tegra_apb_bb_phys, GFP_KERNEL); + if (!tegra_apb_bb) { + pr_err("%s: can not allocate bounce buffer\n", __func__); + tegra_dma_free_channel(ch); + goto out_fail; + } + + tegra_apb_dma = ch; +out: + mutex_unlock(&tegra_apb_dma_lock); + return true; + +out_fail: + mutex_unlock(&tegra_apb_dma_lock); + return false; +} + +static void apb_dma_complete(struct tegra_dma_req *req) +{ + complete(&tegra_apb_wait); +} + +u32 tegra_apb_readl(unsigned long offset) +{ + struct tegra_dma_req req; + int ret; + + if (!tegra_apb_dma && !tegra_apb_init()) + return readl(IO_TO_VIRT(offset)); + + mutex_lock(&tegra_apb_dma_lock); + req.complete = apb_dma_complete; + req.to_memory = 1; + req.dest_addr = tegra_apb_bb_phys; + req.dest_bus_width = 32; + req.dest_wrap = 1; + req.source_addr = offset; + req.source_bus_width = 32; + req.source_wrap = 4; + req.req_sel = TEGRA_DMA_REQ_SEL_CNTR; + req.size = 4; + + INIT_COMPLETION(tegra_apb_wait); + + tegra_dma_enqueue_req(tegra_apb_dma, &req); + + ret = wait_for_completion_timeout(&tegra_apb_wait, + msecs_to_jiffies(50)); + + if (WARN(ret == 0, "apb read dma timed out")) { + tegra_dma_dequeue_req(tegra_apb_dma, &req); + *(u32 *)tegra_apb_bb = 0; + } + + mutex_unlock(&tegra_apb_dma_lock); + return *((u32 *)tegra_apb_bb); +} + +void tegra_apb_writel(u32 value, unsigned long offset) +{ + struct tegra_dma_req req; + int ret; + + if (!tegra_apb_dma && !tegra_apb_init()) { + writel(value, IO_TO_VIRT(offset)); + return; + } + + mutex_lock(&tegra_apb_dma_lock); + *((u32 *)tegra_apb_bb) = value; + req.complete = apb_dma_complete; + req.to_memory = 0; + req.dest_addr = offset; + req.dest_wrap = 4; + req.dest_bus_width = 32; + req.source_addr = tegra_apb_bb_phys; + req.source_bus_width = 32; + req.source_wrap = 1; + req.req_sel = TEGRA_DMA_REQ_SEL_CNTR; + req.size = 4; + + INIT_COMPLETION(tegra_apb_wait); + + tegra_dma_enqueue_req(tegra_apb_dma, &req); + + ret = wait_for_completion_timeout(&tegra_apb_wait, + msecs_to_jiffies(50)); + + if (WARN(ret == 0, "apb write dma timed out")) + tegra_dma_dequeue_req(tegra_apb_dma, &req); + + mutex_unlock(&tegra_apb_dma_lock); +} diff --git a/arch/arm/mach-tegra/include/mach/system.h b/arch/arm/mach-tegra/apbio.h index a312988bf6f8..8b49e8c89a64 100644 --- a/arch/arm/mach-tegra/include/mach/system.h +++ b/arch/arm/mach-tegra/apbio.h @@ -1,12 +1,7 @@ /* - * arch/arm/mach-tegra/include/mach/system.h - * + * Copyright (C) 2010 NVIDIA Corporation. * Copyright (C) 2010 Google, Inc. * - * Author: - * Colin Cross <ccross@google.com> - * Erik Gilling <konkers@google.com> - * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and * may be copied, distributed, and modified under those terms. @@ -18,11 +13,27 @@ * */ -#ifndef __MACH_TEGRA_SYSTEM_H -#define __MACH_TEGRA_SYSTEM_H +#ifndef __MACH_TEGRA_APBIO_H +#define __MACH_TEGRA_APBIO_H + +#ifdef CONFIG_TEGRA_SYSTEM_DMA + +u32 tegra_apb_readl(unsigned long offset); +void tegra_apb_writel(u32 value, unsigned long offset); + +#else +#include <asm/io.h> +#include <mach/io.h> -static inline void arch_idle(void) +static inline u32 tegra_apb_readl(unsigned long offset) { + return readl(IO_TO_VIRT(offset)); } +static inline void tegra_apb_writel(u32 value, unsigned long offset) +{ + writel(value, IO_TO_VIRT(offset)); +} +#endif + #endif diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c index 7a95e0bc4aba..0952494f481a 100644 --- a/arch/arm/mach-tegra/board-dt-tegra20.c +++ b/arch/arm/mach-tegra/board-dt-tegra20.c @@ -68,11 +68,11 @@ struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S2_BASE, "tegra-i2s.1", NULL), OF_DEV_AUXDATA("nvidia,tegra20-das", TEGRA_APB_MISC_DAS_BASE, "tegra-das", NULL), OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB_BASE, "tegra-ehci.0", - &tegra_ehci1_device.dev.platform_data), + &tegra_ehci1_pdata), OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB2_BASE, "tegra-ehci.1", - &tegra_ehci2_device.dev.platform_data), + &tegra_ehci2_pdata), OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB3_BASE, "tegra-ehci.2", - &tegra_ehci3_device.dev.platform_data), + &tegra_ehci3_pdata), {} }; @@ -131,11 +131,7 @@ static void __init tegra_dt_init(void) } static const char *tegra20_dt_board_compat[] = { - "compulab,trimslice", - "nvidia,harmony", - "compal,paz00", - "nvidia,seaboard", - "nvidia,ventana", + "nvidia,tegra20", NULL }; diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c index 3c197e2440b7..5f7c03e972f3 100644 --- a/arch/arm/mach-tegra/board-dt-tegra30.c +++ b/arch/arm/mach-tegra/board-dt-tegra30.c @@ -34,20 +34,42 @@ #include <asm/hardware/gic.h> #include "board.h" +#include "clock.h" static struct of_device_id tegra_dt_match_table[] __initdata = { { .compatible = "simple-bus", }, {} }; +struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = { + OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000000, "sdhci-tegra.0", NULL), + OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000200, "sdhci-tegra.1", NULL), + OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000400, "sdhci-tegra.2", NULL), + OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000600, "sdhci-tegra.3", NULL), + OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C000, "tegra-i2c.0", NULL), + OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C400, "tegra-i2c.1", NULL), + OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C500, "tegra-i2c.2", NULL), + OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C700, "tegra-i2c.3", NULL), + OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000D000, "tegra-i2c.4", NULL), + {} +}; + +static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = { + /* name parent rate enabled */ + { "uarta", "pll_p", 408000000, true }, + { NULL, NULL, 0, 0}, +}; + static void __init tegra30_dt_init(void) { + tegra_clk_init_from_table(tegra_dt_clk_init_table); + of_platform_populate(NULL, tegra_dt_match_table, - NULL, NULL); + tegra30_auxdata_lookup, NULL); } static const char *tegra30_dt_board_compat[] = { - "nvidia,cardhu", + "nvidia,tegra30", NULL }; diff --git a/arch/arm/mach-tegra/board-harmony-pinmux.c b/arch/arm/mach-tegra/board-harmony-pinmux.c index 465808c8ac0b..1af85bccc0f1 100644 --- a/arch/arm/mach-tegra/board-harmony-pinmux.c +++ b/arch/arm/mach-tegra/board-harmony-pinmux.c @@ -53,7 +53,7 @@ static struct tegra_pingroup_config harmony_pinmux[] = { {TEGRA_PINGROUP_GME, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, {TEGRA_PINGROUP_GPU, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, - {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, @@ -112,10 +112,10 @@ static struct tegra_pingroup_config harmony_pinmux[] = { {TEGRA_PINGROUP_SDC, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, {TEGRA_PINGROUP_SDD, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, - {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, + {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, diff --git a/arch/arm/mach-tegra/board-harmony-power.c b/arch/arm/mach-tegra/board-harmony-power.c index 21d1285731b3..82f32300796c 100644 --- a/arch/arm/mach-tegra/board-harmony-power.c +++ b/arch/arm/mach-tegra/board-harmony-power.c @@ -18,31 +18,27 @@ #include <linux/i2c.h> #include <linux/platform_device.h> #include <linux/gpio.h> -#include <linux/io.h> #include <linux/regulator/machine.h> #include <linux/mfd/tps6586x.h> -#include <mach/iomap.h> #include <mach/irqs.h> #include "board-harmony.h" -#define PMC_CTRL 0x0 -#define PMC_CTRL_INTR_LOW (1 << 17) - static struct regulator_consumer_supply tps658621_ldo0_supply[] = { REGULATOR_SUPPLY("pex_clk", NULL), }; static struct regulator_init_data ldo0_data = { .constraints = { - .min_uV = 1250 * 1000, + .min_uV = 3300 * 1000, .max_uV = 3300 * 1000, .valid_modes_mask = (REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY), .valid_ops_mask = (REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE), + .apply_uV = 1, }, .num_consumer_supplies = ARRAY_SIZE(tps658621_ldo0_supply), .consumer_supplies = tps658621_ldo0_supply, @@ -114,16 +110,6 @@ static struct i2c_board_info __initdata harmony_regulators[] = { int __init harmony_regulator_init(void) { - void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); - u32 pmc_ctrl; - - /* - * Configure the power management controller to trigger PMU - * interrupts when low - */ - pmc_ctrl = readl(pmc + PMC_CTRL); - writel(pmc_ctrl | PMC_CTRL_INTR_LOW, pmc + PMC_CTRL); - i2c_register_board_info(3, harmony_regulators, 1); return 0; diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c index 789bdc9e8f91..c00aadb01e09 100644 --- a/arch/arm/mach-tegra/board-harmony.c +++ b/arch/arm/mach-tegra/board-harmony.c @@ -101,7 +101,6 @@ static struct wm8903_platform_data harmony_wm8903_pdata = { static struct i2c_board_info __initdata wm8903_board_info = { I2C_BOARD_INFO("wm8903", 0x1a), .platform_data = &harmony_wm8903_pdata, - .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_CDC_IRQ), }; static void __init harmony_i2c_init(void) @@ -111,6 +110,7 @@ static void __init harmony_i2c_init(void) platform_device_register(&tegra_i2c_device3); platform_device_register(&tegra_i2c_device4); + wm8903_board_info.irq = gpio_to_irq(TEGRA_GPIO_CDC_IRQ); i2c_register_board_info(0, &wm8903_board_info, 1); } diff --git a/arch/arm/mach-tegra/board-seaboard.c b/arch/arm/mach-tegra/board-seaboard.c index ebac65f52510..d669847f0485 100644 --- a/arch/arm/mach-tegra/board-seaboard.c +++ b/arch/arm/mach-tegra/board-seaboard.c @@ -159,7 +159,6 @@ static struct platform_device *seaboard_devices[] __initdata = { static struct i2c_board_info __initdata isl29018_device = { I2C_BOARD_INFO("isl29018", 0x44), - .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_ISL29018_IRQ), }; static struct i2c_board_info __initdata adt7461_device = { @@ -183,7 +182,6 @@ static struct wm8903_platform_data wm8903_pdata = { static struct i2c_board_info __initdata wm8903_device = { I2C_BOARD_INFO("wm8903", 0x1a), .platform_data = &wm8903_pdata, - .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_CDC_IRQ), }; static int seaboard_ehci_init(void) @@ -214,7 +212,10 @@ static void __init seaboard_i2c_init(void) gpio_request(TEGRA_GPIO_ISL29018_IRQ, "isl29018"); gpio_direction_input(TEGRA_GPIO_ISL29018_IRQ); + isl29018_device.irq = gpio_to_irq(TEGRA_GPIO_ISL29018_IRQ); i2c_register_board_info(0, &isl29018_device, 1); + + wm8903_device.irq = gpio_to_irq(TEGRA_GPIO_CDC_IRQ); i2c_register_board_info(0, &wm8903_device, 1); i2c_register_board_info(3, &adt7461_device, 1); diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c index 8337068a4abe..8dad8d18cb49 100644 --- a/arch/arm/mach-tegra/clock.c +++ b/arch/arm/mach-tegra/clock.c @@ -399,6 +399,28 @@ void tegra_periph_reset_assert(struct clk *c) } EXPORT_SYMBOL(tegra_periph_reset_assert); +/* Several extended clock configuration bits (e.g., clock routing, clock + * phase control) are included in PLL and peripheral clock source + * registers. */ +int tegra_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting) +{ + int ret = 0; + unsigned long flags; + + spin_lock_irqsave(&c->spinlock, flags); + + if (!c->ops || !c->ops->clk_cfg_ex) { + ret = -ENOSYS; + goto out; + } + ret = c->ops->clk_cfg_ex(c, p, setting); + +out: + spin_unlock_irqrestore(&c->spinlock, flags); + + return ret; +} + #ifdef CONFIG_DEBUG_FS static int __clk_lock_all_spinlocks(void) diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h index 5c44106616c5..bc300657deba 100644 --- a/arch/arm/mach-tegra/clock.h +++ b/arch/arm/mach-tegra/clock.h @@ -24,6 +24,8 @@ #include <linux/list.h> #include <linux/spinlock.h> +#include <mach/clk.h> + #define DIV_BUS (1 << 0) #define DIV_U71 (1 << 1) #define DIV_U71_FIXED (1 << 2) @@ -39,7 +41,16 @@ #define PERIPH_MANUAL_RESET (1 << 12) #define PLL_ALT_MISC_REG (1 << 13) #define PLLU (1 << 14) +#define PLLX (1 << 15) +#define MUX_PWM (1 << 16) +#define MUX8 (1 << 17) +#define DIV_U71_UART (1 << 18) +#define MUX_CLK_OUT (1 << 19) +#define PLLM (1 << 20) +#define DIV_U71_INT (1 << 21) +#define DIV_U71_IDLE (1 << 22) #define ENABLE_ON_INIT (1 << 28) +#define PERIPH_ON_APB (1 << 29) struct clk; @@ -65,6 +76,8 @@ struct clk_ops { int (*set_rate)(struct clk *, unsigned long); long (*round_rate)(struct clk *, unsigned long); void (*reset)(struct clk *, bool); + int (*clk_cfg_ex)(struct clk *, + enum tegra_clk_ex_param, u32); }; enum clk_state { @@ -114,6 +127,7 @@ struct clk { unsigned long vco_max; const struct clk_pll_freq_table *freq_table; int lock_delay; + unsigned long fixed_rate; } pll; struct { u32 sel; @@ -146,6 +160,7 @@ struct tegra_clk_init_table { }; void tegra2_init_clocks(void); +void tegra30_init_clocks(void); void clk_init(struct clk *clk); struct clk *tegra_get_clock_by_name(const char *name); int clk_reparent(struct clk *c, struct clk *parent); diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c index a2eb90169aed..22df10fb9972 100644 --- a/arch/arm/mach-tegra/common.c +++ b/arch/arm/mach-tegra/common.c @@ -27,11 +27,29 @@ #include <asm/hardware/gic.h> #include <mach/iomap.h> -#include <mach/system.h> +#include <mach/powergate.h> #include "board.h" #include "clock.h" #include "fuse.h" +#include "pmc.h" + +/* + * Storage for debug-macro.S's state. + * + * This must be in .data not .bss so that it gets initialized each time the + * kernel is loaded. The data is declared here rather than debug-macro.S so + * that multiple inclusions of debug-macro.S point at the same data. + */ +#define TEGRA_DEBUG_UART_OFFSET (TEGRA_DEBUG_UART_BASE & 0xFFFF) +u32 tegra_uart_config[3] = { + /* Debug UART initialization required */ + 1, + /* Debug UART physical address */ + (u32)(IO_APB_PHYS + TEGRA_DEBUG_UART_OFFSET), + /* Debug UART virtual address */ + (u32)(IO_APB_VIRT + TEGRA_DEBUG_UART_OFFSET), +}; #ifdef CONFIG_OF static const struct of_device_id tegra_dt_irq_match[] __initconst = { @@ -100,11 +118,17 @@ void __init tegra20_init_early(void) tegra2_init_clocks(); tegra_clk_init_from_table(tegra20_clk_init_table); tegra_init_cache(0x331, 0x441); + tegra_pmc_init(); + tegra_powergate_init(); } #endif #ifdef CONFIG_ARCH_TEGRA_3x_SOC void __init tegra30_init_early(void) { + tegra_init_fuse(); + tegra30_init_clocks(); tegra_init_cache(0x441, 0x551); + tegra_pmc_init(); + tegra_powergate_init(); } #endif diff --git a/arch/arm/mach-tegra/cpu-tegra.c b/arch/arm/mach-tegra/cpu-tegra.c index bb5ce39b733b..7a065f0cf633 100644 --- a/arch/arm/mach-tegra/cpu-tegra.c +++ b/arch/arm/mach-tegra/cpu-tegra.c @@ -30,7 +30,6 @@ #include <linux/io.h> #include <linux/suspend.h> -#include <asm/system.h> #include <mach/clk.h> diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c new file mode 100644 index 000000000000..d83a8c0296f5 --- /dev/null +++ b/arch/arm/mach-tegra/cpuidle.c @@ -0,0 +1,107 @@ +/* + * arch/arm/mach-tegra/cpuidle.c + * + * CPU idle driver for Tegra CPUs + * + * Copyright (c) 2010-2012, NVIDIA Corporation. + * Copyright (c) 2011 Google, Inc. + * Author: Colin Cross <ccross@android.com> + * Gary King <gking@nvidia.com> + * + * Rework for 3.3 by Peter De Schrijver <pdeschrijver@nvidia.com> + * + * 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/kernel.h> +#include <linux/module.h> +#include <linux/cpu.h> +#include <linux/cpuidle.h> +#include <linux/hrtimer.h> + +#include <mach/iomap.h> + +extern void tegra_cpu_wfi(void); + +static int tegra_idle_enter_lp3(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index); + +struct cpuidle_driver tegra_idle_driver = { + .name = "tegra_idle", + .owner = THIS_MODULE, + .state_count = 1, + .states = { + [0] = { + .enter = tegra_idle_enter_lp3, + .exit_latency = 10, + .target_residency = 10, + .power_usage = 600, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "LP3", + .desc = "CPU flow-controlled", + }, + }, +}; + +static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device); + +static int tegra_idle_enter_lp3(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) +{ + ktime_t enter, exit; + s64 us; + + local_irq_disable(); + local_fiq_disable(); + + enter = ktime_get(); + + tegra_cpu_wfi(); + + exit = ktime_sub(ktime_get(), enter); + us = ktime_to_us(exit); + + local_fiq_enable(); + local_irq_enable(); + + dev->last_residency = us; + + return index; +} + +static int __init tegra_cpuidle_init(void) +{ + int ret; + unsigned int cpu; + struct cpuidle_device *dev; + struct cpuidle_driver *drv = &tegra_idle_driver; + + ret = cpuidle_register_driver(&tegra_idle_driver); + if (ret) { + pr_err("CPUidle driver registration failed\n"); + return ret; + } + + for_each_possible_cpu(cpu) { + dev = &per_cpu(tegra_idle_device, cpu); + dev->cpu = cpu; + + dev->state_count = drv->state_count; + ret = cpuidle_register_device(dev); + if (ret) { + pr_err("CPU%u: CPUidle device registration failed\n", + cpu); + return ret; + } + } + return 0; +} +device_initcall(tegra_cpuidle_init); diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c index 7a2a02dbd632..5f6b867e20b4 100644 --- a/arch/arm/mach-tegra/devices.c +++ b/arch/arm/mach-tegra/devices.c @@ -23,7 +23,6 @@ #include <linux/fsl_devices.h> #include <linux/serial_8250.h> #include <linux/i2c-tegra.h> -#include <linux/platform_data/tegra_usb.h> #include <asm/pmu.h> #include <mach/irqs.h> #include <mach/iomap.h> @@ -446,18 +445,18 @@ static struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = { .clk = "cdev2", }; -static struct tegra_ehci_platform_data tegra_ehci1_pdata = { +struct tegra_ehci_platform_data tegra_ehci1_pdata = { .operating_mode = TEGRA_USB_OTG, .power_down_on_bus_suspend = 1, }; -static struct tegra_ehci_platform_data tegra_ehci2_pdata = { +struct tegra_ehci_platform_data tegra_ehci2_pdata = { .phy_config = &tegra_ehci2_ulpi_phy_config, .operating_mode = TEGRA_USB_HOST, .power_down_on_bus_suspend = 1, }; -static struct tegra_ehci_platform_data tegra_ehci3_pdata = { +struct tegra_ehci_platform_data tegra_ehci3_pdata = { .operating_mode = TEGRA_USB_HOST, .power_down_on_bus_suspend = 1, }; diff --git a/arch/arm/mach-tegra/devices.h b/arch/arm/mach-tegra/devices.h index 873ecb2f8ae6..ec455679b219 100644 --- a/arch/arm/mach-tegra/devices.h +++ b/arch/arm/mach-tegra/devices.h @@ -20,6 +20,11 @@ #define __MACH_TEGRA_DEVICES_H #include <linux/platform_device.h> +#include <linux/platform_data/tegra_usb.h> + +extern struct tegra_ehci_platform_data tegra_ehci1_pdata; +extern struct tegra_ehci_platform_data tegra_ehci2_pdata; +extern struct tegra_ehci_platform_data tegra_ehci3_pdata; extern struct platform_device tegra_gpio_device; extern struct platform_device tegra_pinmux_device; diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c index c0cf967e47d3..abea4f6e2dd5 100644 --- a/arch/arm/mach-tegra/dma.c +++ b/arch/arm/mach-tegra/dma.c @@ -33,6 +33,8 @@ #include <mach/iomap.h> #include <mach/suspend.h> +#include "apbio.h" + #define APB_DMA_GEN 0x000 #define GEN_ENABLE (1<<31) @@ -50,8 +52,6 @@ #define CSR_ONCE (1<<27) #define CSR_FLOW (1<<21) #define CSR_REQ_SEL_SHIFT 16 -#define CSR_REQ_SEL_MASK (0x1F<<CSR_REQ_SEL_SHIFT) -#define CSR_REQ_SEL_INVALID (31<<CSR_REQ_SEL_SHIFT) #define CSR_WCOUNT_SHIFT 2 #define CSR_WCOUNT_MASK 0xFFFC @@ -133,6 +133,7 @@ struct tegra_dma_channel { static bool tegra_dma_initialized; static DEFINE_MUTEX(tegra_dma_lock); +static DEFINE_SPINLOCK(enable_lock); static DECLARE_BITMAP(channel_usage, NV_DMA_MAX_CHANNELS); static struct tegra_dma_channel dma_channels[NV_DMA_MAX_CHANNELS]; @@ -180,36 +181,94 @@ static void tegra_dma_stop(struct tegra_dma_channel *ch) static int tegra_dma_cancel(struct tegra_dma_channel *ch) { - u32 csr; unsigned long irq_flags; spin_lock_irqsave(&ch->lock, irq_flags); while (!list_empty(&ch->list)) list_del(ch->list.next); - csr = readl(ch->addr + APB_DMA_CHAN_CSR); - csr &= ~CSR_REQ_SEL_MASK; - csr |= CSR_REQ_SEL_INVALID; - writel(csr, ch->addr + APB_DMA_CHAN_CSR); - tegra_dma_stop(ch); spin_unlock_irqrestore(&ch->lock, irq_flags); return 0; } +static unsigned int get_channel_status(struct tegra_dma_channel *ch, + struct tegra_dma_req *req, bool is_stop_dma) +{ + void __iomem *addr = IO_ADDRESS(TEGRA_APB_DMA_BASE); + unsigned int status; + + if (is_stop_dma) { + /* + * STOP the DMA and get the transfer count. + * Getting the transfer count is tricky. + * - Globally disable DMA on all channels + * - Read the channel's status register to know the number + * of pending bytes to be transfered. + * - Stop the dma channel + * - Globally re-enable DMA to resume other transfers + */ + spin_lock(&enable_lock); + writel(0, addr + APB_DMA_GEN); + udelay(20); + status = readl(ch->addr + APB_DMA_CHAN_STA); + tegra_dma_stop(ch); + writel(GEN_ENABLE, addr + APB_DMA_GEN); + spin_unlock(&enable_lock); + if (status & STA_ISE_EOC) { + pr_err("Got Dma Int here clearing"); + writel(status, ch->addr + APB_DMA_CHAN_STA); + } + req->status = TEGRA_DMA_REQ_ERROR_ABORTED; + } else { + status = readl(ch->addr + APB_DMA_CHAN_STA); + } + return status; +} + +/* should be called with the channel lock held */ +static unsigned int dma_active_count(struct tegra_dma_channel *ch, + struct tegra_dma_req *req, unsigned int status) +{ + unsigned int to_transfer; + unsigned int req_transfer_count; + unsigned int bytes_transferred; + + to_transfer = ((status & STA_COUNT_MASK) >> STA_COUNT_SHIFT) + 1; + req_transfer_count = ch->req_transfer_count + 1; + bytes_transferred = req_transfer_count; + if (status & STA_BUSY) + bytes_transferred -= to_transfer; + /* + * In continuous transfer mode, DMA only tracks the count of the + * half DMA buffer. So, if the DMA already finished half the DMA + * then add the half buffer to the completed count. + */ + if (ch->mode & TEGRA_DMA_MODE_CONTINOUS) { + if (req->buffer_status == TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL) + bytes_transferred += req_transfer_count; + if (status & STA_ISE_EOC) + bytes_transferred += req_transfer_count; + } + bytes_transferred *= 4; + return bytes_transferred; +} + int tegra_dma_dequeue_req(struct tegra_dma_channel *ch, struct tegra_dma_req *_req) { - unsigned int csr; unsigned int status; struct tegra_dma_req *req = NULL; int found = 0; unsigned long irq_flags; - int to_transfer; - int req_transfer_count; + int stop = 0; spin_lock_irqsave(&ch->lock, irq_flags); + + if (list_entry(ch->list.next, struct tegra_dma_req, node) == _req) + stop = 1; + list_for_each_entry(req, &ch->list, node) { if (req == _req) { list_del(&req->node); @@ -222,47 +281,12 @@ int tegra_dma_dequeue_req(struct tegra_dma_channel *ch, return 0; } - /* STOP the DMA and get the transfer count. - * Getting the transfer count is tricky. - * - Change the source selector to invalid to stop the DMA from - * FIFO to memory. - * - Read the status register to know the number of pending - * bytes to be transferred. - * - Finally stop or program the DMA to the next buffer in the - * list. - */ - csr = readl(ch->addr + APB_DMA_CHAN_CSR); - csr &= ~CSR_REQ_SEL_MASK; - csr |= CSR_REQ_SEL_INVALID; - writel(csr, ch->addr + APB_DMA_CHAN_CSR); - - /* Get the transfer count */ - status = readl(ch->addr + APB_DMA_CHAN_STA); - to_transfer = (status & STA_COUNT_MASK) >> STA_COUNT_SHIFT; - req_transfer_count = ch->req_transfer_count; - req_transfer_count += 1; - to_transfer += 1; - - req->bytes_transferred = req_transfer_count; - - if (status & STA_BUSY) - req->bytes_transferred -= to_transfer; - - /* In continuous transfer mode, DMA only tracks the count of the - * half DMA buffer. So, if the DMA already finished half the DMA - * then add the half buffer to the completed count. - * - * FIXME: There can be a race here. What if the req to - * dequue happens at the same time as the DMA just moved to - * the new buffer and SW didn't yet received the interrupt? - */ - if (ch->mode & TEGRA_DMA_MODE_CONTINOUS) - if (req->buffer_status == TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL) - req->bytes_transferred += req_transfer_count; + if (!stop) + goto skip_stop_dma; - req->bytes_transferred *= 4; + status = get_channel_status(ch, req, true); + req->bytes_transferred = dma_active_count(ch, req, status); - tegra_dma_stop(ch); if (!list_empty(&ch->list)) { /* if the list is not empty, queue the next request */ struct tegra_dma_req *next_req; @@ -270,6 +294,8 @@ int tegra_dma_dequeue_req(struct tegra_dma_channel *ch, typeof(*next_req), node); tegra_dma_update_hw(ch, next_req); } + +skip_stop_dma: req->status = -TEGRA_DMA_REQ_ERROR_ABORTED; spin_unlock_irqrestore(&ch->lock, irq_flags); @@ -357,7 +383,7 @@ struct tegra_dma_channel *tegra_dma_allocate_channel(int mode) int channel; struct tegra_dma_channel *ch = NULL; - if (WARN_ON(!tegra_dma_initialized)) + if (!tegra_dma_initialized) return NULL; mutex_lock(&tegra_dma_lock); diff --git a/arch/arm/mach-tegra/flowctrl.c b/arch/arm/mach-tegra/flowctrl.c new file mode 100644 index 000000000000..fef66a7486ed --- /dev/null +++ b/arch/arm/mach-tegra/flowctrl.c @@ -0,0 +1,62 @@ +/* + * arch/arm/mach-tegra/flowctrl.c + * + * functions and macros to control the flowcontroller + * + * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/io.h> + +#include <mach/iomap.h> + +#include "flowctrl.h" + +u8 flowctrl_offset_halt_cpu[] = { + FLOW_CTRL_HALT_CPU0_EVENTS, + FLOW_CTRL_HALT_CPU1_EVENTS, + FLOW_CTRL_HALT_CPU1_EVENTS + 8, + FLOW_CTRL_HALT_CPU1_EVENTS + 16, +}; + +u8 flowctrl_offset_cpu_csr[] = { + FLOW_CTRL_CPU0_CSR, + FLOW_CTRL_CPU1_CSR, + FLOW_CTRL_CPU1_CSR + 8, + FLOW_CTRL_CPU1_CSR + 16, +}; + +static void flowctrl_update(u8 offset, u32 value) +{ + void __iomem *addr = IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + offset; + + writel(value, addr); + + /* ensure the update has reached the flow controller */ + wmb(); + readl_relaxed(addr); +} + +void flowctrl_write_cpu_csr(unsigned int cpuid, u32 value) +{ + return flowctrl_update(flowctrl_offset_halt_cpu[cpuid], value); +} + +void flowctrl_write_cpu_halt(unsigned int cpuid, u32 value) +{ + return flowctrl_update(flowctrl_offset_cpu_csr[cpuid], value); +} diff --git a/arch/arm/mach-tegra/flowctrl.h b/arch/arm/mach-tegra/flowctrl.h new file mode 100644 index 000000000000..19428173855e --- /dev/null +++ b/arch/arm/mach-tegra/flowctrl.h @@ -0,0 +1,42 @@ +/* + * arch/arm/mach-tegra/flowctrl.h + * + * functions and macros to control the flowcontroller + * + * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __MACH_TEGRA_FLOWCTRL_H +#define __MACH_TEGRA_FLOWCTRL_H + +#define FLOW_CTRL_HALT_CPU0_EVENTS 0x0 +#define FLOW_CTRL_WAITEVENT (2 << 29) +#define FLOW_CTRL_WAIT_FOR_INTERRUPT (4 << 29) +#define FLOW_CTRL_JTAG_RESUME (1 << 28) +#define FLOW_CTRL_HALT_CPU_IRQ (1 << 10) +#define FLOW_CTRL_HALT_CPU_FIQ (1 << 8) +#define FLOW_CTRL_CPU0_CSR 0x8 +#define FLOW_CTRL_CSR_INTR_FLAG (1 << 15) +#define FLOW_CTRL_CSR_EVENT_FLAG (1 << 14) +#define FLOW_CTRL_CSR_ENABLE (1 << 0) +#define FLOW_CTRL_HALT_CPU1_EVENTS 0x14 +#define FLOW_CTRL_CPU1_CSR 0x18 + +#ifndef __ASSEMBLY__ +void flowctrl_write_cpu_csr(unsigned int cpuid, u32 value); +void flowctrl_write_cpu_halt(unsigned int cpuid, u32 value); +#endif + +#endif diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c index ea49bd93c6b9..f946d129423c 100644 --- a/arch/arm/mach-tegra/fuse.c +++ b/arch/arm/mach-tegra/fuse.c @@ -19,68 +19,113 @@ #include <linux/kernel.h> #include <linux/io.h> -#include <linux/module.h> +#include <linux/export.h> #include <mach/iomap.h> #include "fuse.h" +#include "apbio.h" #define FUSE_UID_LOW 0x108 #define FUSE_UID_HIGH 0x10c #define FUSE_SKU_INFO 0x110 #define FUSE_SPARE_BIT 0x200 -static inline u32 fuse_readl(unsigned long offset) +int tegra_sku_id; +int tegra_cpu_process_id; +int tegra_core_process_id; +int tegra_chip_id; +enum tegra_revision tegra_revision; + +/* The BCT to use at boot is specified by board straps that can be read + * through a APB misc register and decoded. 2 bits, i.e. 4 possible BCTs. + */ +int tegra_bct_strapping; + +#define STRAP_OPT 0x008 +#define GMI_AD0 (1 << 4) +#define GMI_AD1 (1 << 5) +#define RAM_ID_MASK (GMI_AD0 | GMI_AD1) +#define RAM_CODE_SHIFT 4 + +static const char *tegra_revision_name[TEGRA_REVISION_MAX] = { + [TEGRA_REVISION_UNKNOWN] = "unknown", + [TEGRA_REVISION_A01] = "A01", + [TEGRA_REVISION_A02] = "A02", + [TEGRA_REVISION_A03] = "A03", + [TEGRA_REVISION_A03p] = "A03 prime", + [TEGRA_REVISION_A04] = "A04", +}; + +static inline u32 tegra_fuse_readl(unsigned long offset) { - return readl(IO_TO_VIRT(TEGRA_FUSE_BASE + offset)); + return tegra_apb_readl(TEGRA_FUSE_BASE + offset); } -static inline void fuse_writel(u32 value, unsigned long offset) +static inline bool get_spare_fuse(int bit) { - writel(value, IO_TO_VIRT(TEGRA_FUSE_BASE + offset)); + return tegra_fuse_readl(FUSE_SPARE_BIT + bit * 4); +} + +static enum tegra_revision tegra_get_revision(u32 id) +{ + u32 minor_rev = (id >> 16) & 0xf; + + switch (minor_rev) { + case 1: + return TEGRA_REVISION_A01; + case 2: + return TEGRA_REVISION_A02; + case 3: + if (tegra_chip_id == TEGRA20 && + (get_spare_fuse(18) || get_spare_fuse(19))) + return TEGRA_REVISION_A03p; + else + return TEGRA_REVISION_A03; + case 4: + return TEGRA_REVISION_A04; + default: + return TEGRA_REVISION_UNKNOWN; + } } void tegra_init_fuse(void) { + u32 id; + u32 reg = readl(IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48)); reg |= 1 << 28; writel(reg, IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48)); - pr_info("Tegra SKU: %d CPU Process: %d Core Process: %d\n", - tegra_sku_id(), tegra_cpu_process_id(), - tegra_core_process_id()); + reg = tegra_fuse_readl(FUSE_SKU_INFO); + tegra_sku_id = reg & 0xFF; + + reg = tegra_fuse_readl(FUSE_SPARE_BIT); + tegra_cpu_process_id = (reg >> 6) & 3; + + reg = tegra_fuse_readl(FUSE_SPARE_BIT); + tegra_core_process_id = (reg >> 12) & 3; + + reg = tegra_apb_readl(TEGRA_APB_MISC_BASE + STRAP_OPT); + tegra_bct_strapping = (reg & RAM_ID_MASK) >> RAM_CODE_SHIFT; + + id = readl_relaxed(IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804); + tegra_chip_id = (id >> 8) & 0xff; + + tegra_revision = tegra_get_revision(id); + + pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n", + tegra_revision_name[tegra_revision], + tegra_sku_id, tegra_cpu_process_id, + tegra_core_process_id); } unsigned long long tegra_chip_uid(void) { unsigned long long lo, hi; - lo = fuse_readl(FUSE_UID_LOW); - hi = fuse_readl(FUSE_UID_HIGH); + lo = tegra_fuse_readl(FUSE_UID_LOW); + hi = tegra_fuse_readl(FUSE_UID_HIGH); return (hi << 32ull) | lo; } EXPORT_SYMBOL(tegra_chip_uid); - -int tegra_sku_id(void) -{ - int sku_id; - u32 reg = fuse_readl(FUSE_SKU_INFO); - sku_id = reg & 0xFF; - return sku_id; -} - -int tegra_cpu_process_id(void) -{ - int cpu_process_id; - u32 reg = fuse_readl(FUSE_SPARE_BIT); - cpu_process_id = (reg >> 6) & 3; - return cpu_process_id; -} - -int tegra_core_process_id(void) -{ - int core_process_id; - u32 reg = fuse_readl(FUSE_SPARE_BIT); - core_process_id = (reg >> 12) & 3; - return core_process_id; -} diff --git a/arch/arm/mach-tegra/fuse.h b/arch/arm/mach-tegra/fuse.h index 584b2e27dbda..d2107b2cb85a 100644 --- a/arch/arm/mach-tegra/fuse.h +++ b/arch/arm/mach-tegra/fuse.h @@ -1,6 +1,4 @@ /* - * arch/arm/mach-tegra/fuse.c - * * Copyright (C) 2010 Google, Inc. * * Author: @@ -17,8 +15,38 @@ * */ +#ifndef __MACH_TEGRA_FUSE_H +#define __MACH_TEGRA_FUSE_H + +enum tegra_revision { + TEGRA_REVISION_UNKNOWN = 0, + TEGRA_REVISION_A01, + TEGRA_REVISION_A02, + TEGRA_REVISION_A03, + TEGRA_REVISION_A03p, + TEGRA_REVISION_A04, + TEGRA_REVISION_MAX, +}; + +#define SKU_ID_T20 8 +#define SKU_ID_T25SE 20 +#define SKU_ID_AP25 23 +#define SKU_ID_T25 24 +#define SKU_ID_AP25E 27 +#define SKU_ID_T25E 28 + +#define TEGRA20 0x20 +#define TEGRA30 0x30 + +extern int tegra_sku_id; +extern int tegra_cpu_process_id; +extern int tegra_core_process_id; +extern int tegra_chip_id; +extern enum tegra_revision tegra_revision; + +extern int tegra_bct_strapping; + unsigned long long tegra_chip_uid(void); -int tegra_sku_id(void); -int tegra_cpu_process_id(void); -int tegra_core_process_id(void); void tegra_init_fuse(void); + +#endif diff --git a/arch/arm/mach-tegra/headsmp.S b/arch/arm/mach-tegra/headsmp.S index b5349b2f13d2..fef9c2c51370 100644 --- a/arch/arm/mach-tegra/headsmp.S +++ b/arch/arm/mach-tegra/headsmp.S @@ -1,6 +1,23 @@ #include <linux/linkage.h> #include <linux/init.h> +#include <asm/cache.h> + +#include <mach/iomap.h> + +#include "flowctrl.h" +#include "reset.h" + +#define APB_MISC_GP_HIDREV 0x804 +#define PMC_SCRATCH41 0x140 + +#define RESET_DATA(x) ((TEGRA_RESET_##x)*4) + + .macro mov32, reg, val + movw \reg, #:lower16:\val + movt \reg, #:upper16:\val + .endm + .section ".text.head", "ax" __CPUINIT @@ -47,15 +64,149 @@ ENTRY(v7_invalidate_l1) mov pc, lr ENDPROC(v7_invalidate_l1) + ENTRY(tegra_secondary_startup) - msr cpsr_fsxc, #0xd3 bl v7_invalidate_l1 - mrc p15, 0, r0, c0, c0, 5 - and r0, r0, #15 - ldr r1, =0x6000f100 - str r0, [r1] -1: ldr r2, [r1] - cmp r0, r2 - beq 1b + /* Enable coresight */ + mov32 r0, 0xC5ACCE55 + mcr p14, 0, r0, c7, c12, 6 b secondary_startup ENDPROC(tegra_secondary_startup) + + .align L1_CACHE_SHIFT +ENTRY(__tegra_cpu_reset_handler_start) + +/* + * __tegra_cpu_reset_handler: + * + * Common handler for all CPU reset events. + * + * Register usage within the reset handler: + * + * R7 = CPU present (to the OS) mask + * R8 = CPU in LP1 state mask + * R9 = CPU in LP2 state mask + * R10 = CPU number + * R11 = CPU mask + * R12 = pointer to reset handler data + * + * NOTE: This code is copied to IRAM. All code and data accesses + * must be position-independent. + */ + + .align L1_CACHE_SHIFT +ENTRY(__tegra_cpu_reset_handler) + + cpsid aif, 0x13 @ SVC mode, interrupts disabled + mrc p15, 0, r10, c0, c0, 5 @ MPIDR + and r10, r10, #0x3 @ R10 = CPU number + mov r11, #1 + mov r11, r11, lsl r10 @ R11 = CPU mask + adr r12, __tegra_cpu_reset_handler_data + +#ifdef CONFIG_SMP + /* Does the OS know about this CPU? */ + ldr r7, [r12, #RESET_DATA(MASK_PRESENT)] + tst r7, r11 @ if !present + bleq __die @ CPU not present (to OS) +#endif + +#ifdef CONFIG_ARCH_TEGRA_2x_SOC + /* Are we on Tegra20? */ + mov32 r6, TEGRA_APB_MISC_BASE + ldr r0, [r6, #APB_MISC_GP_HIDREV] + and r0, r0, #0xff00 + cmp r0, #(0x20 << 8) + bne 1f + /* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */ + mov32 r6, TEGRA_PMC_BASE + mov r0, #0 + cmp r10, #0 + strne r0, [r6, #PMC_SCRATCH41] +1: +#endif + +#ifdef CONFIG_SMP + /* + * Can only be secondary boot (initial or hotplug) but CPU 0 + * cannot be here. + */ + cmp r10, #0 + bleq __die @ CPU0 cannot be here + ldr lr, [r12, #RESET_DATA(STARTUP_SECONDARY)] + cmp lr, #0 + bleq __die @ no secondary startup handler + bx lr +#endif + +/* + * We don't know why the CPU reset. Just kill it. + * The LR register will contain the address we died at + 4. + */ + +__die: + sub lr, lr, #4 + mov32 r7, TEGRA_PMC_BASE + str lr, [r7, #PMC_SCRATCH41] + + mov32 r7, TEGRA_CLK_RESET_BASE + + /* Are we on Tegra20? */ + mov32 r6, TEGRA_APB_MISC_BASE + ldr r0, [r6, #APB_MISC_GP_HIDREV] + and r0, r0, #0xff00 + cmp r0, #(0x20 << 8) + bne 1f + +#ifdef CONFIG_ARCH_TEGRA_2x_SOC + mov32 r0, 0x1111 + mov r1, r0, lsl r10 + str r1, [r7, #0x340] @ CLK_RST_CPU_CMPLX_SET +#endif +1: +#ifdef CONFIG_ARCH_TEGRA_3x_SOC + mov32 r6, TEGRA_FLOW_CTRL_BASE + + cmp r10, #0 + moveq r1, #FLOW_CTRL_HALT_CPU0_EVENTS + moveq r2, #FLOW_CTRL_CPU0_CSR + movne r1, r10, lsl #3 + addne r2, r1, #(FLOW_CTRL_CPU1_CSR-8) + addne r1, r1, #(FLOW_CTRL_HALT_CPU1_EVENTS-8) + + /* Clear CPU "event" and "interrupt" flags and power gate + it when halting but not before it is in the "WFI" state. */ + ldr r0, [r6, +r2] + orr r0, r0, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG + orr r0, r0, #FLOW_CTRL_CSR_ENABLE + str r0, [r6, +r2] + + /* Unconditionally halt this CPU */ + mov r0, #FLOW_CTRL_WAITEVENT + str r0, [r6, +r1] + ldr r0, [r6, +r1] @ memory barrier + + dsb + isb + wfi @ CPU should be power gated here + + /* If the CPU didn't power gate above just kill it's clock. */ + + mov r0, r11, lsl #8 + str r0, [r7, #348] @ CLK_CPU_CMPLX_SET +#endif + + /* If the CPU still isn't dead, just spin here. */ + b . +ENDPROC(__tegra_cpu_reset_handler) + + .align L1_CACHE_SHIFT + .type __tegra_cpu_reset_handler_data, %object + .globl __tegra_cpu_reset_handler_data +__tegra_cpu_reset_handler_data: + .rept TEGRA_RESET_DATA_SIZE + .long 0 + .endr + .align L1_CACHE_SHIFT + +ENTRY(__tegra_cpu_reset_handler_end) diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c index f3294040d357..d8dc9ddd6d18 100644 --- a/arch/arm/mach-tegra/hotplug.c +++ b/arch/arm/mach-tegra/hotplug.c @@ -13,6 +13,7 @@ #include <linux/smp.h> #include <asm/cacheflush.h> +#include <asm/cp15.h> static inline void cpu_enter_lowpower(void) { diff --git a/arch/arm/mach-tegra/include/mach/clk.h b/arch/arm/mach-tegra/include/mach/clk.h index fc3ecb66de08..d97e403303a0 100644 --- a/arch/arm/mach-tegra/include/mach/clk.h +++ b/arch/arm/mach-tegra/include/mach/clk.h @@ -22,10 +22,20 @@ struct clk; +enum tegra_clk_ex_param { + TEGRA_CLK_VI_INP_SEL, + TEGRA_CLK_DTV_INVERT, + TEGRA_CLK_NAND_PAD_DIV2_ENB, + TEGRA_CLK_PLLD_CSI_OUT_ENB, + TEGRA_CLK_PLLD_DSI_OUT_ENB, + TEGRA_CLK_PLLD_MIPI_MUX_SEL, +}; + void tegra_periph_reset_deassert(struct clk *c); void tegra_periph_reset_assert(struct clk *c); unsigned long clk_get_rate_all_locked(struct clk *c); void tegra2_sdmmc_tap_delay(struct clk *c, int delay); +int tegra_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting); #endif diff --git a/arch/arm/mach-tegra/include/mach/debug-macro.S b/arch/arm/mach-tegra/include/mach/debug-macro.S index 619abc63aee8..8ce0661b8a3d 100644 --- a/arch/arm/mach-tegra/include/mach/debug-macro.S +++ b/arch/arm/mach-tegra/include/mach/debug-macro.S @@ -1,11 +1,17 @@ /* * arch/arm/mach-tegra/include/mach/debug-macro.S * - * Copyright (C) 2010 Google, Inc. + * Copyright (C) 2010,2011 Google, Inc. + * Copyright (C) 2011-2012 NVIDIA CORPORATION. All Rights Reserved. * * Author: * Colin Cross <ccross@google.com> * Erik Gilling <konkers@google.com> + * Doug Anderson <dianders@chromium.org> + * Stephen Warren <swarren@nvidia.com> + * + * Portions based on mach-omap2's debug-macro.S + * Copyright (C) 1994-1999 Russell King * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -18,18 +24,77 @@ * */ -#include <mach/io.h> +#include <linux/serial_reg.h> + #include <mach/iomap.h> +#include <mach/irammap.h> + + .macro addruart, rp, rv, tmp + adr \rp, 99f @ actual addr of 99f + ldr \rv, [\rp] @ linked addr is stored there + sub \rv, \rv, \rp @ offset between the two + ldr \rp, [\rp, #4] @ linked tegra_uart_config + sub \tmp, \rp, \rv @ actual tegra_uart_config + ldr \rp, [\tmp] @ Load tegra_uart_config + cmp \rp, #1 @ needs intitialization? + bne 100f @ no; go load the addresses + mov \rv, #0 @ yes; record init is done + str \rv, [\tmp] + mov \rp, #TEGRA_IRAM_BASE @ See if cookie is in IRAM + ldr \rv, [\rp, #TEGRA_IRAM_DEBUG_UART_OFFSET] + movw \rp, #TEGRA_IRAM_DEBUG_UART_COOKIE & 0xffff + movt \rp, #TEGRA_IRAM_DEBUG_UART_COOKIE >> 16 + cmp \rv, \rp @ Cookie present? + bne 100f @ No, use default UART + mov \rp, #TEGRA_IRAM_BASE @ Load UART address from IRAM + ldr \rv, [\rp, #TEGRA_IRAM_DEBUG_UART_OFFSET + 4] + str \rv, [\tmp, #4] @ Store in tegra_uart_phys + sub \rv, \rv, #IO_APB_PHYS @ Calculate virt address + add \rv, \rv, #IO_APB_VIRT + str \rv, [\tmp, #8] @ Store in tegra_uart_virt + b 100f + + .align +99: .word . + .word tegra_uart_config + .ltorg + +100: ldr \rp, [\tmp, #4] @ Load tegra_uart_phys + ldr \rv, [\tmp, #8] @ Load tegra_uart_virt + .endm + +#define UART_SHIFT 2 + +/* + * Code below is swiped from <asm/hardware/debug-8250.S>, but add an extra + * check to make sure that we aren't in the CONFIG_TEGRA_DEBUG_UART_NONE case. + * We use the fact that all 5 valid UART addresses all have something in the + * 2nd-to-lowest byte. + */ - .macro addruart, rp, rv, tmp - ldr \rp, =IO_APB_PHYS @ physical - ldr \rv, =IO_APB_VIRT @ virtual - orr \rp, \rp, #(TEGRA_DEBUG_UART_BASE & 0xFF) - orr \rp, \rp, #(TEGRA_DEBUG_UART_BASE & 0xFF00) - orr \rv, \rv, #(TEGRA_DEBUG_UART_BASE & 0xFF) - orr \rv, \rv, #(TEGRA_DEBUG_UART_BASE & 0xFF00) - .endm + .macro senduart, rd, rx + tst \rx, #0x0000ff00 + strneb \rd, [\rx, #UART_TX << UART_SHIFT] +1001: + .endm -#define UART_SHIFT 2 -#include <asm/hardware/debug-8250.S> + .macro busyuart, rd, rx + tst \rx, #0x0000ff00 + beq 1002f +1001: ldrb \rd, [\rx, #UART_LSR << UART_SHIFT] + and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE + teq \rd, #UART_LSR_TEMT | UART_LSR_THRE + bne 1001b +1002: + .endm + .macro waituart, rd, rx +#ifdef FLOW_CONTROL + tst \rx, #0x0000ff00 + beq 1002f +1001: ldrb \rd, [\rx, #UART_MSR << UART_SHIFT] + tst \rd, #UART_MSR_CTS + beq 1001b +1002: +#endif + .endm diff --git a/arch/arm/mach-tegra/include/mach/entry-macro.S b/arch/arm/mach-tegra/include/mach/entry-macro.S deleted file mode 100644 index e577cfe27e72..000000000000 --- a/arch/arm/mach-tegra/include/mach/entry-macro.S +++ /dev/null @@ -1,20 +0,0 @@ -/* arch/arm/mach-tegra/include/mach/entry-macro.S - * - * Copyright (C) 2009 Palm, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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. - * - */ - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-tegra/include/mach/gpio-tegra.h b/arch/arm/mach-tegra/include/mach/gpio-tegra.h index 87d37fdf5084..6140820555e1 100644 --- a/arch/arm/mach-tegra/include/mach/gpio-tegra.h +++ b/arch/arm/mach-tegra/include/mach/gpio-tegra.h @@ -25,8 +25,6 @@ #define TEGRA_NR_GPIOS INT_GPIO_NR -#define TEGRA_GPIO_TO_IRQ(gpio) (INT_GPIO_BASE + (gpio)) - struct tegra_gpio_table { int gpio; /* GPIO number */ bool enable; /* Enable for GPIO at init? */ diff --git a/arch/arm/mach-tegra/include/mach/io.h b/arch/arm/mach-tegra/include/mach/io.h index f15defffb5d2..fe700f9ce7dc 100644 --- a/arch/arm/mach-tegra/include/mach/io.h +++ b/arch/arm/mach-tegra/include/mach/io.h @@ -23,56 +23,8 @@ #define IO_SPACE_LIMIT 0xffff -/* On TEGRA, many peripherals are very closely packed in - * two 256MB io windows (that actually only use about 64KB - * at the start of each). - * - * We will just map the first 1MB of each window (to minimize - * pt entries needed) and provide a macro to transform physical - * io addresses to an appropriate void __iomem *. - * - */ - -#ifdef __ASSEMBLY__ -#define IOMEM(x) (x) -#else -#define IOMEM(x) ((void __force __iomem *)(x)) -#endif - -#define IO_IRAM_PHYS 0x40000000 -#define IO_IRAM_VIRT IOMEM(0xFE400000) -#define IO_IRAM_SIZE SZ_256K - -#define IO_CPU_PHYS 0x50040000 -#define IO_CPU_VIRT IOMEM(0xFE000000) -#define IO_CPU_SIZE SZ_16K - -#define IO_PPSB_PHYS 0x60000000 -#define IO_PPSB_VIRT IOMEM(0xFE200000) -#define IO_PPSB_SIZE SZ_1M - -#define IO_APB_PHYS 0x70000000 -#define IO_APB_VIRT IOMEM(0xFE300000) -#define IO_APB_SIZE SZ_1M - -#define IO_TO_VIRT_BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz))) -#define IO_TO_VIRT_XLATE(p, pst, vst) (((p) - (pst) + (vst))) - -#define IO_TO_VIRT(n) ( \ - IO_TO_VIRT_BETWEEN((n), IO_PPSB_PHYS, IO_PPSB_SIZE) ? \ - IO_TO_VIRT_XLATE((n), IO_PPSB_PHYS, IO_PPSB_VIRT) : \ - IO_TO_VIRT_BETWEEN((n), IO_APB_PHYS, IO_APB_SIZE) ? \ - IO_TO_VIRT_XLATE((n), IO_APB_PHYS, IO_APB_VIRT) : \ - IO_TO_VIRT_BETWEEN((n), IO_CPU_PHYS, IO_CPU_SIZE) ? \ - IO_TO_VIRT_XLATE((n), IO_CPU_PHYS, IO_CPU_VIRT) : \ - IO_TO_VIRT_BETWEEN((n), IO_IRAM_PHYS, IO_IRAM_SIZE) ? \ - IO_TO_VIRT_XLATE((n), IO_IRAM_PHYS, IO_IRAM_VIRT) : \ - NULL) - #ifndef __ASSEMBLER__ -#define IO_ADDRESS(n) (IO_TO_VIRT(n)) - #ifdef CONFIG_TEGRA_PCI extern void __iomem *tegra_pcie_io_base; @@ -88,7 +40,6 @@ static inline void __iomem *__io(unsigned long addr) #endif #define __io(a) __io(a) -#define __mem_pci(a) (a) #endif diff --git a/arch/arm/mach-tegra/include/mach/iomap.h b/arch/arm/mach-tegra/include/mach/iomap.h index 19dec3ac0854..7e76da73121c 100644 --- a/arch/arm/mach-tegra/include/mach/iomap.h +++ b/arch/arm/mach-tegra/include/mach/iomap.h @@ -74,6 +74,9 @@ #define TEGRA_QUATERNARY_ICTLR_BASE 0x60004300 #define TEGRA_QUATERNARY_ICTLR_SIZE SZ_64 +#define TEGRA_QUINARY_ICTLR_BASE 0x60004400 +#define TEGRA_QUINARY_ICTLR_SIZE SZ_64 + #define TEGRA_TMR1_BASE 0x60005000 #define TEGRA_TMR1_SIZE SZ_8 @@ -110,6 +113,9 @@ #define TEGRA_AHB_GIZMO_BASE 0x6000C004 #define TEGRA_AHB_GIZMO_SIZE 0x10C +#define TEGRA_SB_BASE 0x6000C200 +#define TEGRA_SB_SIZE 256 + #define TEGRA_STATMON_BASE 0x6000C400 #define TEGRA_STATMON_SIZE SZ_1K @@ -271,4 +277,46 @@ # define TEGRA_DEBUG_UART_BASE TEGRA_UARTE_BASE #endif +/* On TEGRA, many peripherals are very closely packed in + * two 256MB io windows (that actually only use about 64KB + * at the start of each). + * + * We will just map the first 1MB of each window (to minimize + * pt entries needed) and provide a macro to transform physical + * io addresses to an appropriate void __iomem *. + * + */ + +#define IO_IRAM_PHYS 0x40000000 +#define IO_IRAM_VIRT IOMEM(0xFE400000) +#define IO_IRAM_SIZE SZ_256K + +#define IO_CPU_PHYS 0x50040000 +#define IO_CPU_VIRT IOMEM(0xFE000000) +#define IO_CPU_SIZE SZ_16K + +#define IO_PPSB_PHYS 0x60000000 +#define IO_PPSB_VIRT IOMEM(0xFE200000) +#define IO_PPSB_SIZE SZ_1M + +#define IO_APB_PHYS 0x70000000 +#define IO_APB_VIRT IOMEM(0xFE300000) +#define IO_APB_SIZE SZ_1M + +#define IO_TO_VIRT_BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz))) +#define IO_TO_VIRT_XLATE(p, pst, vst) (((p) - (pst) + (vst))) + +#define IO_TO_VIRT(n) ( \ + IO_TO_VIRT_BETWEEN((n), IO_PPSB_PHYS, IO_PPSB_SIZE) ? \ + IO_TO_VIRT_XLATE((n), IO_PPSB_PHYS, IO_PPSB_VIRT) : \ + IO_TO_VIRT_BETWEEN((n), IO_APB_PHYS, IO_APB_SIZE) ? \ + IO_TO_VIRT_XLATE((n), IO_APB_PHYS, IO_APB_VIRT) : \ + IO_TO_VIRT_BETWEEN((n), IO_CPU_PHYS, IO_CPU_SIZE) ? \ + IO_TO_VIRT_XLATE((n), IO_CPU_PHYS, IO_CPU_VIRT) : \ + IO_TO_VIRT_BETWEEN((n), IO_IRAM_PHYS, IO_IRAM_SIZE) ? \ + IO_TO_VIRT_XLATE((n), IO_IRAM_PHYS, IO_IRAM_VIRT) : \ + NULL) + +#define IO_ADDRESS(n) (IO_TO_VIRT(n)) + #endif diff --git a/arch/arm/mach-tegra/include/mach/irammap.h b/arch/arm/mach-tegra/include/mach/irammap.h new file mode 100644 index 000000000000..0cbe63261854 --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/irammap.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __MACH_TEGRA_IRAMMAP_H +#define __MACH_TEGRA_IRAMMAP_H + +#include <asm/sizes.h> + +/* The first 1K of IRAM is permanently reserved for the CPU reset handler */ +#define TEGRA_IRAM_RESET_HANDLER_OFFSET 0 +#define TEGRA_IRAM_RESET_HANDLER_SIZE SZ_1K + +/* + * These locations are written to by uncompress.h, and read by debug-macro.S. + * The first word holds the cookie value if the data is valid. The second + * word holds the UART physical address. + */ +#define TEGRA_IRAM_DEBUG_UART_OFFSET SZ_1K +#define TEGRA_IRAM_DEBUG_UART_SIZE 8 +#define TEGRA_IRAM_DEBUG_UART_COOKIE 0x55415254 + +#endif diff --git a/arch/arm/mach-tegra/include/mach/irqs.h b/arch/arm/mach-tegra/include/mach/irqs.h index a2146cd6867d..aad1a2c1d714 100644 --- a/arch/arm/mach-tegra/include/mach/irqs.h +++ b/arch/arm/mach-tegra/include/mach/irqs.h @@ -165,11 +165,12 @@ #define INT_QUAD_RES_30 (INT_QUAD_BASE + 30) #define INT_QUAD_RES_31 (INT_QUAD_BASE + 31) -#define INT_MAIN_NR (INT_QUAD_BASE + 32 - INT_PRI_BASE) - +/* Tegra30 has 5 banks of 32 IRQs */ +#define INT_MAIN_NR (32 * 5) #define INT_GPIO_BASE (INT_PRI_BASE + INT_MAIN_NR) -#define INT_GPIO_NR (28 * 8) +/* Tegra30 has 8 banks of 32 GPIOs */ +#define INT_GPIO_NR (32 * 8) #define TEGRA_NR_IRQS (INT_GPIO_BASE + INT_GPIO_NR) diff --git a/arch/arm/mach-tegra/include/mach/powergate.h b/arch/arm/mach-tegra/include/mach/powergate.h index 39c396d2ddb0..4752b1a68f35 100644 --- a/arch/arm/mach-tegra/include/mach/powergate.h +++ b/arch/arm/mach-tegra/include/mach/powergate.h @@ -27,8 +27,21 @@ #define TEGRA_POWERGATE_VDEC 4 #define TEGRA_POWERGATE_L2 5 #define TEGRA_POWERGATE_MPE 6 -#define TEGRA_NUM_POWERGATE 7 +#define TEGRA_POWERGATE_HEG 7 +#define TEGRA_POWERGATE_SATA 8 +#define TEGRA_POWERGATE_CPU1 9 +#define TEGRA_POWERGATE_CPU2 10 +#define TEGRA_POWERGATE_CPU3 11 +#define TEGRA_POWERGATE_CELP 12 +#define TEGRA_POWERGATE_3D1 13 +#define TEGRA_POWERGATE_CPU0 TEGRA_POWERGATE_CPU +#define TEGRA_POWERGATE_3D0 TEGRA_POWERGATE_3D + +int __init tegra_powergate_init(void); + +int tegra_cpu_powergate_id(int cpuid); +int tegra_powergate_is_powered(int id); int tegra_powergate_power_on(int id); int tegra_powergate_power_off(int id); int tegra_powergate_remove_clamping(int id); diff --git a/arch/arm/mach-tegra/include/mach/smmu.h b/arch/arm/mach-tegra/include/mach/smmu.h new file mode 100644 index 000000000000..dad403a9cf00 --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/smmu.h @@ -0,0 +1,63 @@ +/* + * IOMMU API for SMMU in Tegra30 + * + * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MACH_SMMU_H +#define MACH_SMMU_H + +enum smmu_hwgrp { + HWGRP_AFI, + HWGRP_AVPC, + HWGRP_DC, + HWGRP_DCB, + HWGRP_EPP, + HWGRP_G2, + HWGRP_HC, + HWGRP_HDA, + HWGRP_ISP, + HWGRP_MPE, + HWGRP_NV, + HWGRP_NV2, + HWGRP_PPCS, + HWGRP_SATA, + HWGRP_VDE, + HWGRP_VI, + + HWGRP_COUNT, + + HWGRP_END = ~0, +}; + +#define HWG_AFI (1 << HWGRP_AFI) +#define HWG_AVPC (1 << HWGRP_AVPC) +#define HWG_DC (1 << HWGRP_DC) +#define HWG_DCB (1 << HWGRP_DCB) +#define HWG_EPP (1 << HWGRP_EPP) +#define HWG_G2 (1 << HWGRP_G2) +#define HWG_HC (1 << HWGRP_HC) +#define HWG_HDA (1 << HWGRP_HDA) +#define HWG_ISP (1 << HWGRP_ISP) +#define HWG_MPE (1 << HWGRP_MPE) +#define HWG_NV (1 << HWGRP_NV) +#define HWG_NV2 (1 << HWGRP_NV2) +#define HWG_PPCS (1 << HWGRP_PPCS) +#define HWG_SATA (1 << HWGRP_SATA) +#define HWG_VDE (1 << HWGRP_VDE) +#define HWG_VI (1 << HWGRP_VI) + +#endif /* MACH_SMMU_H */ diff --git a/arch/arm/mach-tegra/include/mach/uncompress.h b/arch/arm/mach-tegra/include/mach/uncompress.h index 4e8323770c79..5a440f315e57 100644 --- a/arch/arm/mach-tegra/include/mach/uncompress.h +++ b/arch/arm/mach-tegra/include/mach/uncompress.h @@ -2,10 +2,14 @@ * arch/arm/mach-tegra/include/mach/uncompress.h * * Copyright (C) 2010 Google, Inc. + * Copyright (C) 2011 Google, Inc. + * Copyright (C) 2011-2012 NVIDIA CORPORATION. All Rights Reserved. * * Author: * Colin Cross <ccross@google.com> * Erik Gilling <konkers@google.com> + * Doug Anderson <dianders@chromium.org> + * Stephen Warren <swarren@nvidia.com> * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -25,36 +29,130 @@ #include <linux/serial_reg.h> #include <mach/iomap.h> +#include <mach/irammap.h> + +#define BIT(x) (1 << (x)) +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +#define DEBUG_UART_SHIFT 2 + +volatile u8 *uart; static void putc(int c) { - volatile u8 *uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE; - int shift = 2; - if (uart == NULL) return; - while (!(uart[UART_LSR << shift] & UART_LSR_THRE)) + while (!(uart[UART_LSR << DEBUG_UART_SHIFT] & UART_LSR_THRE)) barrier(); - uart[UART_TX << shift] = c; + uart[UART_TX << DEBUG_UART_SHIFT] = c; } static inline void flush(void) { } +static inline void save_uart_address(void) +{ + u32 *buf = (u32 *)(TEGRA_IRAM_BASE + TEGRA_IRAM_DEBUG_UART_OFFSET); + + if (uart) { + buf[0] = TEGRA_IRAM_DEBUG_UART_COOKIE; + buf[1] = (u32)uart; + } else + buf[0] = 0; +} + +/* + * Setup before decompression. This is where we do UART selection for + * earlyprintk and init the uart_base register. + */ static inline void arch_decomp_setup(void) { - volatile u8 *uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE; - int shift = 2; + static const struct { + u32 base; + u32 reset_reg; + u32 clock_reg; + u32 bit; + } uarts[] = { + { + TEGRA_UARTA_BASE, + TEGRA_CLK_RESET_BASE + 0x04, + TEGRA_CLK_RESET_BASE + 0x10, + 6, + }, + { + TEGRA_UARTB_BASE, + TEGRA_CLK_RESET_BASE + 0x04, + TEGRA_CLK_RESET_BASE + 0x10, + 7, + }, + { + TEGRA_UARTC_BASE, + TEGRA_CLK_RESET_BASE + 0x08, + TEGRA_CLK_RESET_BASE + 0x14, + 23, + }, + { + TEGRA_UARTD_BASE, + TEGRA_CLK_RESET_BASE + 0x0c, + TEGRA_CLK_RESET_BASE + 0x18, + 1, + }, + { + TEGRA_UARTE_BASE, + TEGRA_CLK_RESET_BASE + 0x0c, + TEGRA_CLK_RESET_BASE + 0x18, + 2, + }, + }; + int i; + volatile u32 *apb_misc = (volatile u32 *)TEGRA_APB_MISC_BASE; + u32 chip, div; + + /* + * Look for the first UART that: + * a) Is not in reset. + * b) Is clocked. + * c) Has a 'D' in the scratchpad register. + * + * Note that on Tegra30, the first two conditions are required, since + * if not true, accesses to the UART scratch register will hang. + * Tegra20 doesn't have this issue. + * + * The intent is that the bootloader will tell the kernel which UART + * to use by setting up those conditions. If nothing found, we'll fall + * back to what's specified in TEGRA_DEBUG_UART_BASE. + */ + for (i = 0; i < ARRAY_SIZE(uarts); i++) { + if (*(u8 *)uarts[i].reset_reg & BIT(uarts[i].bit)) + continue; + if (!(*(u8 *)uarts[i].clock_reg & BIT(uarts[i].bit))) + continue; + + uart = (volatile u8 *)uarts[i].base; + if (uart[UART_SCR << DEBUG_UART_SHIFT] != 'D') + continue; + + break; + } + if (i == ARRAY_SIZE(uarts)) + uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE; + save_uart_address(); if (uart == NULL) return; - uart[UART_LCR << shift] |= UART_LCR_DLAB; - uart[UART_DLL << shift] = 0x75; - uart[UART_DLM << shift] = 0x0; - uart[UART_LCR << shift] = 3; + chip = (apb_misc[0x804 / 4] >> 8) & 0xff; + if (chip == 0x20) + div = 0x0075; + else + div = 0x00dd; + + uart[UART_LCR << DEBUG_UART_SHIFT] |= UART_LCR_DLAB; + uart[UART_DLL << DEBUG_UART_SHIFT] = div & 0xff; + uart[UART_DLM << DEBUG_UART_SHIFT] = div >> 8; + uart[UART_LCR << DEBUG_UART_SHIFT] = 3; } static inline void arch_decomp_wdog(void) diff --git a/arch/arm/mach-tegra/io.c b/arch/arm/mach-tegra/io.c index d23ee2db2827..58b4baf9c483 100644 --- a/arch/arm/mach-tegra/io.c +++ b/arch/arm/mach-tegra/io.c @@ -26,6 +26,7 @@ #include <asm/page.h> #include <asm/mach/map.h> +#include <mach/iomap.h> #include "board.h" diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c index 4e1afcd54fae..2f5bd2db8e1f 100644 --- a/arch/arm/mach-tegra/irq.c +++ b/arch/arm/mach-tegra/irq.c @@ -44,14 +44,16 @@ #define ICTLR_COP_IER_CLR 0x38 #define ICTLR_COP_IEP_CLASS 0x3c -#define NUM_ICTLRS 4 #define FIRST_LEGACY_IRQ 32 +static int num_ictlrs; + static void __iomem *ictlr_reg_base[] = { IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE), IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE), IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE), IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE), + IO_ADDRESS(TEGRA_QUINARY_ICTLR_BASE), }; static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg) @@ -60,7 +62,7 @@ static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg) u32 mask; BUG_ON(irq < FIRST_LEGACY_IRQ || - irq >= FIRST_LEGACY_IRQ + NUM_ICTLRS * 32); + irq >= FIRST_LEGACY_IRQ + num_ictlrs * 32); base = ictlr_reg_base[(irq - FIRST_LEGACY_IRQ) / 32]; mask = BIT((irq - FIRST_LEGACY_IRQ) % 32); @@ -113,8 +115,18 @@ static int tegra_retrigger(struct irq_data *d) void __init tegra_init_irq(void) { int i; + void __iomem *distbase; + + distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE); + num_ictlrs = readl_relaxed(distbase + GIC_DIST_CTR) & 0x1f; + + if (num_ictlrs > ARRAY_SIZE(ictlr_reg_base)) { + WARN(1, "Too many (%d) interrupt controllers found. Maximum is %d.", + num_ictlrs, ARRAY_SIZE(ictlr_reg_base)); + num_ictlrs = ARRAY_SIZE(ictlr_reg_base); + } - for (i = 0; i < NUM_ICTLRS; i++) { + for (i = 0; i < num_ictlrs; i++) { void __iomem *ictlr = ictlr_reg_base[i]; writel(~0, ictlr + ICTLR_CPU_IER_CLR); writel(0, ictlr + ICTLR_CPU_IEP_CLASS); @@ -131,6 +143,6 @@ void __init tegra_init_irq(void) * initialized elsewhere under DT. */ if (!of_have_populated_dt()) - gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE), + gic_init(0, 29, distbase, IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100)); } diff --git a/arch/arm/mach-tegra/localtimer.c b/arch/arm/mach-tegra/localtimer.c deleted file mode 100644 index e91d681d45a2..000000000000 --- a/arch/arm/mach-tegra/localtimer.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * arch/arm/mach-tegra/localtimer.c - * - * Copyright (C) 2002 ARM Ltd. - * All Rights Reserved - * - * 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 <linux/init.h> -#include <linux/smp.h> -#include <linux/clockchips.h> -#include <asm/irq.h> -#include <asm/smp_twd.h> -#include <asm/localtimer.h> - -/* - * Setup the local clock events for a CPU. - */ -int __cpuinit local_timer_setup(struct clock_event_device *evt) -{ - evt->irq = IRQ_LOCALTIMER; - twd_timer_setup(evt); - return 0; -} diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c index af8b63435727..54a816ff3847 100644 --- a/arch/arm/mach-tegra/pcie.c +++ b/arch/arm/mach-tegra/pcie.c @@ -408,7 +408,7 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) pp->res[0].flags = IORESOURCE_IO; if (request_resource(&ioport_resource, &pp->res[0])) panic("Request PCIe IO resource failed\n"); - pci_add_resource(&sys->resources, &pp->res[0]); + pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset); /* * IORESOURCE_MEM @@ -427,7 +427,7 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) pp->res[1].flags = IORESOURCE_MEM; if (request_resource(&iomem_resource, &pp->res[1])) panic("Request PCIe Memory resource failed\n"); - pci_add_resource(&sys->resources, &pp->res[1]); + pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset); /* * IORESOURCE_MEM | IORESOURCE_PREFETCH @@ -446,7 +446,7 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) pp->res[2].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; if (request_resource(&iomem_resource, &pp->res[2])) panic("Request PCIe Prefetch Memory resource failed\n"); - pci_add_resource(&sys->resources, &pp->res[2]); + pci_add_resource_offset(&sys->resources, &pp->res[2], sys->mem_offset); return 1; } @@ -585,10 +585,10 @@ static void tegra_pcie_setup_translations(void) afi_writel(0, AFI_MSI_BAR_SZ); } -static void tegra_pcie_enable_controller(void) +static int tegra_pcie_enable_controller(void) { u32 val, reg; - int i; + int i, timeout; /* Enable slot clock and pulse the reset signals */ for (i = 0, reg = AFI_PEX0_CTRL; i < 2; i++, reg += 0x8) { @@ -639,8 +639,14 @@ static void tegra_pcie_enable_controller(void) pads_writel(0xfa5cfa5c, 0xc8); /* Wait for the PLL to lock */ + timeout = 300; do { val = pads_readl(PADS_PLL_CTL); + usleep_range(1000, 1000); + if (--timeout == 0) { + pr_err("Tegra PCIe error: timeout waiting for PLL\n"); + return -EBUSY; + } } while (!(val & PADS_PLL_CTL_LOCKDET)); /* turn off IDDQ override */ @@ -671,7 +677,7 @@ static void tegra_pcie_enable_controller(void) /* Disable all execptions */ afi_writel(0, AFI_FPCI_ERROR_MASKS); - return; + return 0; } static void tegra_pcie_xclk_clamp(bool clamp) @@ -921,7 +927,9 @@ int __init tegra_pcie_init(bool init_port0, bool init_port1) if (err) return err; - tegra_pcie_enable_controller(); + err = tegra_pcie_enable_controller(); + if (err) + return err; /* setup the AFI address translations */ tegra_pcie_setup_translations(); diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c index 7d2b5d03c1df..1a208dbf682f 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c @@ -24,19 +24,31 @@ #include <asm/mach-types.h> #include <asm/smp_scu.h> +#include <mach/clk.h> #include <mach/iomap.h> +#include <mach/powergate.h> + +#include "fuse.h" +#include "flowctrl.h" +#include "reset.h" extern void tegra_secondary_startup(void); -static DEFINE_SPINLOCK(boot_lock); static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE); #define EVP_CPU_RESET_VECTOR \ (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100) #define CLK_RST_CONTROLLER_CLK_CPU_CMPLX \ (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x4c) +#define CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET \ + (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x340) #define CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR \ (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x344) +#define CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR \ + (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x34c) + +#define CPU_CLOCK(cpu) (0x1<<(8+cpu)) +#define CPU_RESET(cpu) (0x1111ul<<(cpu)) void __cpuinit platform_secondary_init(unsigned int cpu) { @@ -47,63 +59,106 @@ void __cpuinit platform_secondary_init(unsigned int cpu) */ gic_secondary_init(0); - /* - * Synchronise with the boot thread. - */ - spin_lock(&boot_lock); - spin_unlock(&boot_lock); } -int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) +static int tegra20_power_up_cpu(unsigned int cpu) { - unsigned long old_boot_vector; - unsigned long boot_vector; - unsigned long timeout; u32 reg; - /* - * set synchronisation state between this boot processor - * and the secondary one - */ - spin_lock(&boot_lock); + /* Enable the CPU clock. */ + reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX); + writel(reg & ~CPU_CLOCK(cpu), CLK_RST_CONTROLLER_CLK_CPU_CMPLX); + barrier(); + reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX); + /* Clear flow controller CSR. */ + flowctrl_write_cpu_csr(cpu, 0); - /* set the reset vector to point to the secondary_startup routine */ + return 0; +} - boot_vector = virt_to_phys(tegra_secondary_startup); - old_boot_vector = readl(EVP_CPU_RESET_VECTOR); - writel(boot_vector, EVP_CPU_RESET_VECTOR); +static int tegra30_power_up_cpu(unsigned int cpu) +{ + u32 reg; + int ret, pwrgateid; + unsigned long timeout; - /* enable cpu clock on cpu1 */ - reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX); - writel(reg & ~(1<<9), CLK_RST_CONTROLLER_CLK_CPU_CMPLX); + pwrgateid = tegra_cpu_powergate_id(cpu); + if (pwrgateid < 0) + return pwrgateid; + + /* If this is the first boot, toggle powergates directly. */ + if (!tegra_powergate_is_powered(pwrgateid)) { + ret = tegra_powergate_power_on(pwrgateid); + if (ret) + return ret; + + /* Wait for the power to come up. */ + timeout = jiffies + 10*HZ; + while (tegra_powergate_is_powered(pwrgateid)) { + if (time_after(jiffies, timeout)) + return -ETIMEDOUT; + udelay(10); + } + } - reg = (1<<13) | (1<<9) | (1<<5) | (1<<1); - writel(reg, CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR); + /* CPU partition is powered. Enable the CPU clock. */ + writel(CPU_CLOCK(cpu), CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR); + reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR); + udelay(10); - smp_wmb(); - flush_cache_all(); + /* Remove I/O clamps. */ + ret = tegra_powergate_remove_clamping(pwrgateid); + udelay(10); - /* unhalt the cpu */ - writel(0, IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + 0x14); + /* Clear flow controller CSR. */ + flowctrl_write_cpu_csr(cpu, 0); - timeout = jiffies + (1 * HZ); - while (time_before(jiffies, timeout)) { - if (readl(EVP_CPU_RESET_VECTOR) != boot_vector) - break; - udelay(10); - } + return 0; +} + +int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + int status; - /* put the old boot vector back */ - writel(old_boot_vector, EVP_CPU_RESET_VECTOR); + /* + * Force the CPU into reset. The CPU must remain in reset when the + * flow controller state is cleared (which will cause the flow + * controller to stop driving reset if the CPU has been power-gated + * via the flow controller). This will have no effect on first boot + * of the CPU since it should already be in reset. + */ + writel(CPU_RESET(cpu), CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET); + dmb(); /* - * now the secondary core is starting up let it run its - * calibrations, then wait for it to finish + * Unhalt the CPU. If the flow controller was used to power-gate the + * CPU this will cause the flow controller to stop driving reset. + * The CPU will remain in reset because the clock and reset block + * is now driving reset. */ - spin_unlock(&boot_lock); + flowctrl_write_cpu_halt(cpu, 0); + + switch (tegra_chip_id) { + case TEGRA20: + status = tegra20_power_up_cpu(cpu); + break; + case TEGRA30: + status = tegra30_power_up_cpu(cpu); + break; + default: + status = -EINVAL; + break; + } - return 0; + if (status) + goto done; + + /* Take the CPU out of reset. */ + writel(CPU_RESET(cpu), CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR); + wmb(); +done: + return status; } /* @@ -128,6 +183,6 @@ void __init smp_init_cpus(void) void __init platform_smp_prepare_cpus(unsigned int max_cpus) { - + tegra_cpu_reset_handler_init(); scu_enable(scu_base); } diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c new file mode 100644 index 000000000000..7af6a54404be --- /dev/null +++ b/arch/arm/mach-tegra/pmc.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>. + * + */ + +#include <linux/kernel.h> +#include <linux/io.h> +#include <linux/of.h> + +#include <mach/iomap.h> + +#define PMC_CTRL 0x0 +#define PMC_CTRL_INTR_LOW (1 << 17) + +static inline u32 tegra_pmc_readl(u32 reg) +{ + return readl(IO_ADDRESS(TEGRA_PMC_BASE + reg)); +} + +static inline void tegra_pmc_writel(u32 val, u32 reg) +{ + writel(val, IO_ADDRESS(TEGRA_PMC_BASE + reg)); +} + +#ifdef CONFIG_OF +static const struct of_device_id matches[] __initconst = { + { .compatible = "nvidia,tegra20-pmc" }, + { } +}; +#endif + +void __init tegra_pmc_init(void) +{ + /* + * For now, Harmony is the only board that uses the PMC, and it wants + * the signal inverted. Seaboard would too if it used the PMC. + * Hopefully by the time other boards want to use the PMC, everything + * will be device-tree, or they also want it inverted. + */ + bool invert_interrupt = true; + u32 val; + +#ifdef CONFIG_OF + if (of_have_populated_dt()) { + struct device_node *np; + + invert_interrupt = false; + + np = of_find_matching_node(NULL, matches); + if (np) { + if (of_find_property(np, "nvidia,invert-interrupt", + NULL)) + invert_interrupt = true; + } + } +#endif + + val = tegra_pmc_readl(PMC_CTRL); + if (invert_interrupt) + val |= PMC_CTRL_INTR_LOW; + else + val &= ~PMC_CTRL_INTR_LOW; + tegra_pmc_writel(val, PMC_CTRL); +} diff --git a/arch/arm/mach-highbank/include/mach/system.h b/arch/arm/mach-tegra/pmc.h index b1d8b5fbe373..8995ee4a8768 100644 --- a/arch/arm/mach-highbank/include/mach/system.h +++ b/arch/arm/mach-tegra/pmc.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Calxeda, Inc. + * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -10,15 +10,14 @@ * 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, see <http://www.gnu.org/licenses/>. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * */ -#ifndef __MACH_SYSTEM_H -#define __MACH_SYSTEM_H -static inline void arch_idle(void) -{ - cpu_do_idle(); -} +#ifndef __MACH_TEGRA_PMC_H +#define __MACH_TEGRA_PMC_H + +void tegra_pmc_init(void); #endif diff --git a/arch/arm/mach-tegra/powergate.c b/arch/arm/mach-tegra/powergate.c index 948306491a59..c238699ae86f 100644 --- a/arch/arm/mach-tegra/powergate.c +++ b/arch/arm/mach-tegra/powergate.c @@ -31,6 +31,8 @@ #include <mach/iomap.h> #include <mach/powergate.h> +#include "fuse.h" + #define PWRGATE_TOGGLE 0x30 #define PWRGATE_TOGGLE_START (1 << 8) @@ -38,6 +40,16 @@ #define PWRGATE_STATUS 0x38 +static int tegra_num_powerdomains; +static int tegra_num_cpu_domains; +static u8 *tegra_cpu_domains; +static u8 tegra30_cpu_domains[] = { + TEGRA_POWERGATE_CPU0, + TEGRA_POWERGATE_CPU1, + TEGRA_POWERGATE_CPU2, + TEGRA_POWERGATE_CPU3, +}; + static DEFINE_SPINLOCK(tegra_powergate_lock); static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); @@ -75,7 +87,7 @@ static int tegra_powergate_set(int id, bool new_state) int tegra_powergate_power_on(int id) { - if (id < 0 || id >= TEGRA_NUM_POWERGATE) + if (id < 0 || id >= tegra_num_powerdomains) return -EINVAL; return tegra_powergate_set(id, true); @@ -83,17 +95,18 @@ int tegra_powergate_power_on(int id) int tegra_powergate_power_off(int id) { - if (id < 0 || id >= TEGRA_NUM_POWERGATE) + if (id < 0 || id >= tegra_num_powerdomains) return -EINVAL; return tegra_powergate_set(id, false); } -static bool tegra_powergate_is_powered(int id) +int tegra_powergate_is_powered(int id) { u32 status; - WARN_ON(id < 0 || id >= TEGRA_NUM_POWERGATE); + if (id < 0 || id >= tegra_num_powerdomains) + return -EINVAL; status = pmc_read(PWRGATE_STATUS) & (1 << id); return !!status; @@ -103,7 +116,7 @@ int tegra_powergate_remove_clamping(int id) { u32 mask; - if (id < 0 || id >= TEGRA_NUM_POWERGATE) + if (id < 0 || id >= tegra_num_powerdomains) return -EINVAL; /* @@ -156,6 +169,34 @@ err_power: return ret; } +int tegra_cpu_powergate_id(int cpuid) +{ + if (cpuid > 0 && cpuid < tegra_num_cpu_domains) + return tegra_cpu_domains[cpuid]; + + return -EINVAL; +} + +int __init tegra_powergate_init(void) +{ + switch (tegra_chip_id) { + case TEGRA20: + tegra_num_powerdomains = 7; + break; + case TEGRA30: + tegra_num_powerdomains = 14; + tegra_num_cpu_domains = 4; + tegra_cpu_domains = tegra30_cpu_domains; + break; + default: + /* Unknown Tegra variant. Disable powergating */ + tegra_num_powerdomains = 0; + break; + } + + return 0; +} + #ifdef CONFIG_DEBUG_FS static const char * const powergate_name[] = { @@ -175,7 +216,7 @@ static int powergate_show(struct seq_file *s, void *data) seq_printf(s, " powergate powered\n"); seq_printf(s, "------------------\n"); - for (i = 0; i < TEGRA_NUM_POWERGATE; i++) + for (i = 0; i < tegra_num_powerdomains; i++) seq_printf(s, " %9s %7s\n", powergate_name[i], tegra_powergate_is_powered(i) ? "yes" : "no"); return 0; diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c new file mode 100644 index 000000000000..4d6a2ee99c3b --- /dev/null +++ b/arch/arm/mach-tegra/reset.c @@ -0,0 +1,84 @@ +/* + * arch/arm/mach-tegra/reset.c + * + * Copyright (C) 2011,2012 NVIDIA Corporation. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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/io.h> +#include <linux/cpumask.h> +#include <linux/bitops.h> + +#include <asm/cacheflush.h> +#include <asm/hardware/cache-l2x0.h> + +#include <mach/iomap.h> +#include <mach/irammap.h> + +#include "reset.h" +#include "fuse.h" + +#define TEGRA_IRAM_RESET_BASE (TEGRA_IRAM_BASE + \ + TEGRA_IRAM_RESET_HANDLER_OFFSET) + +static bool is_enabled; + +static void tegra_cpu_reset_handler_enable(void) +{ + void __iomem *iram_base = IO_ADDRESS(TEGRA_IRAM_RESET_BASE); + void __iomem *evp_cpu_reset = + IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE + 0x100); + void __iomem *sb_ctrl = IO_ADDRESS(TEGRA_SB_BASE); + u32 reg; + + BUG_ON(is_enabled); + BUG_ON(tegra_cpu_reset_handler_size > TEGRA_IRAM_RESET_HANDLER_SIZE); + + memcpy(iram_base, (void *)__tegra_cpu_reset_handler_start, + tegra_cpu_reset_handler_size); + + /* + * NOTE: This must be the one and only write to the EVP CPU reset + * vector in the entire system. + */ + writel(TEGRA_IRAM_RESET_BASE + tegra_cpu_reset_handler_offset, + evp_cpu_reset); + wmb(); + reg = readl(evp_cpu_reset); + + /* + * Prevent further modifications to the physical reset vector. + * NOTE: Has no effect on chips prior to Tegra30. + */ + if (tegra_chip_id != TEGRA20) { + reg = readl(sb_ctrl); + reg |= 2; + writel(reg, sb_ctrl); + wmb(); + } + + is_enabled = true; +} + +void __init tegra_cpu_reset_handler_init(void) +{ + +#ifdef CONFIG_SMP + __tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_PRESENT] = + *((u32 *)cpu_present_mask); + __tegra_cpu_reset_handler_data[TEGRA_RESET_STARTUP_SECONDARY] = + virt_to_phys((void *)tegra_secondary_startup); +#endif + + tegra_cpu_reset_handler_enable(); +} diff --git a/arch/arm/mach-tegra/reset.h b/arch/arm/mach-tegra/reset.h new file mode 100644 index 000000000000..de88bf851dd3 --- /dev/null +++ b/arch/arm/mach-tegra/reset.h @@ -0,0 +1,50 @@ +/* + * arch/arm/mach-tegra/reset.h + * + * CPU reset dispatcher. + * + * Copyright (c) 2011, NVIDIA Corporation. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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_TEGRA_RESET_H +#define __MACH_TEGRA_RESET_H + +#define TEGRA_RESET_MASK_PRESENT 0 +#define TEGRA_RESET_MASK_LP1 1 +#define TEGRA_RESET_MASK_LP2 2 +#define TEGRA_RESET_STARTUP_SECONDARY 3 +#define TEGRA_RESET_STARTUP_LP2 4 +#define TEGRA_RESET_STARTUP_LP1 5 +#define TEGRA_RESET_DATA_SIZE 6 + +#ifndef __ASSEMBLY__ + +extern unsigned long __tegra_cpu_reset_handler_data[TEGRA_RESET_DATA_SIZE]; + +void __tegra_cpu_reset_handler_start(void); +void __tegra_cpu_reset_handler(void); +void __tegra_cpu_reset_handler_end(void); +void tegra_secondary_startup(void); + +#define tegra_cpu_reset_handler_offset \ + ((u32)__tegra_cpu_reset_handler - \ + (u32)__tegra_cpu_reset_handler_start) + +#define tegra_cpu_reset_handler_size \ + (__tegra_cpu_reset_handler_end - \ + __tegra_cpu_reset_handler_start) + +void __init tegra_cpu_reset_handler_init(void); + +#endif +#endif diff --git a/arch/arm/mach-tegra/sleep.S b/arch/arm/mach-tegra/sleep.S new file mode 100644 index 000000000000..5b20197bae7f --- /dev/null +++ b/arch/arm/mach-tegra/sleep.S @@ -0,0 +1,93 @@ +/* + * arch/arm/mach-tegra/sleep.S + * + * Copyright (c) 2010-2011, NVIDIA Corporation. + * Copyright (c) 2011, Google, Inc. + * + * Author: Colin Cross <ccross@android.com> + * Gary King <gking@nvidia.com> + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <linux/linkage.h> + +#include <asm/assembler.h> + +#include <mach/iomap.h> + +#include "flowctrl.h" + +#define TEGRA_FLOW_CTRL_VIRT (TEGRA_FLOW_CTRL_BASE - IO_PPSB_PHYS \ + + IO_PPSB_VIRT) + +/* returns the offset of the flow controller halt register for a cpu */ +.macro cpu_to_halt_reg rd, rcpu + cmp \rcpu, #0 + subne \rd, \rcpu, #1 + movne \rd, \rd, lsl #3 + addne \rd, \rd, #0x14 + moveq \rd, #0 +.endm + +/* returns the offset of the flow controller csr register for a cpu */ +.macro cpu_to_csr_reg rd, rcpu + cmp \rcpu, #0 + subne \rd, \rcpu, #1 + movne \rd, \rd, lsl #3 + addne \rd, \rd, #0x18 + moveq \rd, #8 +.endm + +/* returns the ID of the current processor */ +.macro cpu_id, rd + mrc p15, 0, \rd, c0, c0, 5 + and \rd, \rd, #0xF +.endm + +/* loads a 32-bit value into a register without a data access */ +.macro mov32, reg, val + movw \reg, #:lower16:\val + movt \reg, #:upper16:\val +.endm + +/* + * tegra_cpu_wfi + * + * puts current CPU in clock-gated wfi using the flow controller + * + * corrupts r0-r3 + * must be called with MMU on + */ + +ENTRY(tegra_cpu_wfi) + cpu_id r0 + cpu_to_halt_reg r1, r0 + cpu_to_csr_reg r2, r0 + mov32 r0, TEGRA_FLOW_CTRL_VIRT + mov r3, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG + str r3, [r0, r2] @ clear event & interrupt status + mov r3, #FLOW_CTRL_WAIT_FOR_INTERRUPT | FLOW_CTRL_JTAG_RESUME + str r3, [r0, r1] @ put flow controller in wait irq mode + dsb + wfi + mov r3, #0 + str r3, [r0, r1] @ clear flow controller halt status + mov r3, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG + str r3, [r0, r2] @ clear event & interrupt status + dsb + mov pc, lr +ENDPROC(tegra_cpu_wfi) + diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c index ff9e6b6c0460..592a4eeb5328 100644 --- a/arch/arm/mach-tegra/tegra2_clocks.c +++ b/arch/arm/mach-tegra/tegra2_clocks.c @@ -720,7 +720,7 @@ static void tegra2_pllx_clk_init(struct clk *c) { tegra2_pll_clk_init(c); - if (tegra_sku_id() == 7) + if (tegra_sku_id == 7) c->max_rate = 750000000; } @@ -1143,15 +1143,35 @@ static void tegra2_emc_clk_init(struct clk *c) static long tegra2_emc_clk_round_rate(struct clk *c, unsigned long rate) { - long new_rate = rate; + long emc_rate; + long clk_rate; - new_rate = tegra_emc_round_rate(new_rate); - if (new_rate < 0) + /* + * The slowest entry in the EMC clock table that is at least as + * fast as rate. + */ + emc_rate = tegra_emc_round_rate(rate); + if (emc_rate < 0) return c->max_rate; - BUG_ON(new_rate != tegra2_periph_clk_round_rate(c, new_rate)); + /* + * The fastest rate the PLL will generate that is at most the + * requested rate. + */ + clk_rate = tegra2_periph_clk_round_rate(c, emc_rate); + + /* + * If this fails, and emc_rate > clk_rate, it's because the maximum + * rate in the EMC tables is larger than the maximum rate of the EMC + * clock. The EMC clock's max rate is the rate it was running when the + * kernel booted. Such a mismatch is probably due to using the wrong + * BCT, i.e. using a Tegra20 BCT with an EMC table written for Tegra25. + */ + WARN_ONCE(emc_rate != clk_rate, + "emc_rate %ld != clk_rate %ld", + emc_rate, clk_rate); - return new_rate; + return emc_rate; } static int tegra2_emc_clk_set_rate(struct clk *c, unsigned long rate) diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c index 0f7ae6e90b55..5070d833bdd1 100644 --- a/arch/arm/mach-tegra/tegra2_emc.c +++ b/arch/arm/mach-tegra/tegra2_emc.c @@ -16,14 +16,19 @@ */ #include <linux/kernel.h> +#include <linux/device.h> #include <linux/clk.h> #include <linux/err.h> #include <linux/io.h> #include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/platform_data/tegra_emc.h> #include <mach/iomap.h> #include "tegra2_emc.h" +#include "fuse.h" #ifdef CONFIG_TEGRA_EMC_SCALING_ENABLE static bool emc_enable = true; @@ -32,18 +37,17 @@ static bool emc_enable; #endif module_param(emc_enable, bool, 0644); -static void __iomem *emc = IO_ADDRESS(TEGRA_EMC_BASE); -static const struct tegra_emc_table *tegra_emc_table; -static int tegra_emc_table_size; +static struct platform_device *emc_pdev; +static void __iomem *emc_regbase; static inline void emc_writel(u32 val, unsigned long addr) { - writel(val, emc + addr); + writel(val, emc_regbase + addr); } static inline u32 emc_readl(unsigned long addr) { - return readl(emc + addr); + return readl(emc_regbase + addr); } static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = { @@ -98,15 +102,15 @@ static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = { /* Select the closest EMC rate that is higher than the requested rate */ long tegra_emc_round_rate(unsigned long rate) { + struct tegra_emc_pdata *pdata; int i; int best = -1; unsigned long distance = ULONG_MAX; - if (!tegra_emc_table) + if (!emc_pdev) return -EINVAL; - if (!emc_enable) - return -EINVAL; + pdata = emc_pdev->dev.platform_data; pr_debug("%s: %lu\n", __func__, rate); @@ -116,10 +120,10 @@ long tegra_emc_round_rate(unsigned long rate) */ rate = rate / 2 / 1000; - for (i = 0; i < tegra_emc_table_size; i++) { - if (tegra_emc_table[i].rate >= rate && - (tegra_emc_table[i].rate - rate) < distance) { - distance = tegra_emc_table[i].rate - rate; + for (i = 0; i < pdata->num_tables; i++) { + if (pdata->tables[i].rate >= rate && + (pdata->tables[i].rate - rate) < distance) { + distance = pdata->tables[i].rate - rate; best = i; } } @@ -127,9 +131,9 @@ long tegra_emc_round_rate(unsigned long rate) if (best < 0) return -EINVAL; - pr_debug("%s: using %lu\n", __func__, tegra_emc_table[best].rate); + pr_debug("%s: using %lu\n", __func__, pdata->tables[best].rate); - return tegra_emc_table[best].rate * 2 * 1000; + return pdata->tables[best].rate * 2 * 1000; } /* @@ -142,37 +146,211 @@ long tegra_emc_round_rate(unsigned long rate) */ int tegra_emc_set_rate(unsigned long rate) { + struct tegra_emc_pdata *pdata; int i; int j; - if (!tegra_emc_table) + if (!emc_pdev) return -EINVAL; + pdata = emc_pdev->dev.platform_data; + /* * The EMC clock rate is twice the bus rate, and the bus rate is * measured in kHz */ rate = rate / 2 / 1000; - for (i = 0; i < tegra_emc_table_size; i++) - if (tegra_emc_table[i].rate == rate) + for (i = 0; i < pdata->num_tables; i++) + if (pdata->tables[i].rate == rate) break; - if (i >= tegra_emc_table_size) + if (i >= pdata->num_tables) return -EINVAL; pr_debug("%s: setting to %lu\n", __func__, rate); for (j = 0; j < TEGRA_EMC_NUM_REGS; j++) - emc_writel(tegra_emc_table[i].regs[j], emc_reg_addr[j]); + emc_writel(pdata->tables[i].regs[j], emc_reg_addr[j]); - emc_readl(tegra_emc_table[i].regs[TEGRA_EMC_NUM_REGS - 1]); + emc_readl(pdata->tables[i].regs[TEGRA_EMC_NUM_REGS - 1]); return 0; } -void tegra_init_emc(const struct tegra_emc_table *table, int table_size) +#ifdef CONFIG_OF +static struct device_node *tegra_emc_ramcode_devnode(struct device_node *np) +{ + struct device_node *iter; + u32 reg; + + for_each_child_of_node(np, iter) { + if (of_property_read_u32(np, "nvidia,ram-code", ®)) + continue; + if (reg == tegra_bct_strapping) + return of_node_get(iter); + } + + return NULL; +} + +static struct tegra_emc_pdata *tegra_emc_dt_parse_pdata( + struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct device_node *tnp, *iter; + struct tegra_emc_pdata *pdata; + int ret, i, num_tables; + + if (!np) + return NULL; + + if (of_find_property(np, "nvidia,use-ram-code", NULL)) { + tnp = tegra_emc_ramcode_devnode(np); + if (!tnp) + dev_warn(&pdev->dev, + "can't find emc table for ram-code 0x%02x\n", + tegra_bct_strapping); + } else + tnp = of_node_get(np); + + if (!tnp) + return NULL; + + num_tables = 0; + for_each_child_of_node(tnp, iter) + if (of_device_is_compatible(iter, "nvidia,tegra20-emc-table")) + num_tables++; + + if (!num_tables) { + pdata = NULL; + goto out; + } + + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + pdata->tables = devm_kzalloc(&pdev->dev, + sizeof(*pdata->tables) * num_tables, + GFP_KERNEL); + + i = 0; + for_each_child_of_node(tnp, iter) { + u32 prop; + + ret = of_property_read_u32(iter, "clock-frequency", &prop); + if (ret) { + dev_err(&pdev->dev, "no clock-frequency in %s\n", + iter->full_name); + continue; + } + pdata->tables[i].rate = prop; + + ret = of_property_read_u32_array(iter, "nvidia,emc-registers", + pdata->tables[i].regs, + TEGRA_EMC_NUM_REGS); + if (ret) { + dev_err(&pdev->dev, + "malformed emc-registers property in %s\n", + iter->full_name); + continue; + } + + i++; + } + pdata->num_tables = i; + +out: + of_node_put(tnp); + return pdata; +} +#else +static struct tegra_emc_pdata *tegra_emc_dt_parse_pdata( + struct platform_device *pdev) +{ + return NULL; +} +#endif + +static struct tegra_emc_pdata __devinit *tegra_emc_fill_pdata(struct platform_device *pdev) +{ + struct clk *c = clk_get_sys(NULL, "emc"); + struct tegra_emc_pdata *pdata; + unsigned long khz; + int i; + + WARN_ON(pdev->dev.platform_data); + BUG_ON(IS_ERR_OR_NULL(c)); + + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + pdata->tables = devm_kzalloc(&pdev->dev, sizeof(*pdata->tables), + GFP_KERNEL); + + pdata->tables[0].rate = clk_get_rate(c) / 2 / 1000; + + for (i = 0; i < TEGRA_EMC_NUM_REGS; i++) + pdata->tables[0].regs[i] = emc_readl(emc_reg_addr[i]); + + pdata->num_tables = 1; + + khz = pdata->tables[0].rate; + dev_info(&pdev->dev, "no tables provided, using %ld kHz emc, " + "%ld kHz mem\n", khz * 2, khz); + + return pdata; +} + +static int __devinit tegra_emc_probe(struct platform_device *pdev) +{ + struct tegra_emc_pdata *pdata; + struct resource *res; + + if (!emc_enable) { + dev_err(&pdev->dev, "disabled per module parameter\n"); + return -ENODEV; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "missing register base\n"); + return -ENOMEM; + } + + emc_regbase = devm_request_and_ioremap(&pdev->dev, res); + if (!emc_regbase) { + dev_err(&pdev->dev, "failed to remap registers\n"); + return -ENOMEM; + } + + pdata = pdev->dev.platform_data; + + if (!pdata) + pdata = tegra_emc_dt_parse_pdata(pdev); + + if (!pdata) + pdata = tegra_emc_fill_pdata(pdev); + + pdev->dev.platform_data = pdata; + + emc_pdev = pdev; + + return 0; +} + +static struct of_device_id tegra_emc_of_match[] __devinitdata = { + { .compatible = "nvidia,tegra20-emc", }, + { }, +}; + +static struct platform_driver tegra_emc_driver = { + .driver = { + .name = "tegra-emc", + .owner = THIS_MODULE, + .of_match_table = tegra_emc_of_match, + }, + .probe = tegra_emc_probe, +}; + +static int __init tegra_emc_init(void) { - tegra_emc_table = table; - tegra_emc_table_size = table_size; + return platform_driver_register(&tegra_emc_driver); } +device_initcall(tegra_emc_init); diff --git a/arch/arm/mach-tegra/tegra2_emc.h b/arch/arm/mach-tegra/tegra2_emc.h index 19f08cb31603..f61409b54cb7 100644 --- a/arch/arm/mach-tegra/tegra2_emc.h +++ b/arch/arm/mach-tegra/tegra2_emc.h @@ -15,13 +15,10 @@ * */ -#define TEGRA_EMC_NUM_REGS 46 - -struct tegra_emc_table { - unsigned long rate; - u32 regs[TEGRA_EMC_NUM_REGS]; -}; +#ifndef __MACH_TEGRA_TEGRA2_EMC_H_ +#define __MACH_TEGRA_TEGRA2_EMC_H int tegra_emc_set_rate(unsigned long rate); long tegra_emc_round_rate(unsigned long rate); -void tegra_init_emc(const struct tegra_emc_table *table, int table_size); + +#endif diff --git a/arch/arm/mach-tegra/tegra30_clocks.c b/arch/arm/mach-tegra/tegra30_clocks.c new file mode 100644 index 000000000000..6d08b53f92d2 --- /dev/null +++ b/arch/arm/mach-tegra/tegra30_clocks.c @@ -0,0 +1,3099 @@ +/* + * arch/arm/mach-tegra/tegra30_clocks.c + * + * Copyright (c) 2010-2011 NVIDIA CORPORATION. All rights reserved. + * + * 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; version 2 of the License. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/list.h> +#include <linux/spinlock.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/cpufreq.h> +#include <linux/syscore_ops.h> + +#include <asm/clkdev.h> + +#include <mach/iomap.h> + +#include "clock.h" +#include "fuse.h" + +#define USE_PLL_LOCK_BITS 0 + +#define RST_DEVICES_L 0x004 +#define RST_DEVICES_H 0x008 +#define RST_DEVICES_U 0x00C +#define RST_DEVICES_V 0x358 +#define RST_DEVICES_W 0x35C +#define RST_DEVICES_SET_L 0x300 +#define RST_DEVICES_CLR_L 0x304 +#define RST_DEVICES_SET_V 0x430 +#define RST_DEVICES_CLR_V 0x434 +#define RST_DEVICES_NUM 5 + +#define CLK_OUT_ENB_L 0x010 +#define CLK_OUT_ENB_H 0x014 +#define CLK_OUT_ENB_U 0x018 +#define CLK_OUT_ENB_V 0x360 +#define CLK_OUT_ENB_W 0x364 +#define CLK_OUT_ENB_SET_L 0x320 +#define CLK_OUT_ENB_CLR_L 0x324 +#define CLK_OUT_ENB_SET_V 0x440 +#define CLK_OUT_ENB_CLR_V 0x444 +#define CLK_OUT_ENB_NUM 5 + +#define RST_DEVICES_V_SWR_CPULP_RST_DIS (0x1 << 1) +#define CLK_OUT_ENB_V_CLK_ENB_CPULP_EN (0x1 << 1) + +#define PERIPH_CLK_TO_BIT(c) (1 << (c->u.periph.clk_num % 32)) +#define PERIPH_CLK_TO_RST_REG(c) \ + periph_clk_to_reg((c), RST_DEVICES_L, RST_DEVICES_V, 4) +#define PERIPH_CLK_TO_RST_SET_REG(c) \ + periph_clk_to_reg((c), RST_DEVICES_SET_L, RST_DEVICES_SET_V, 8) +#define PERIPH_CLK_TO_RST_CLR_REG(c) \ + periph_clk_to_reg((c), RST_DEVICES_CLR_L, RST_DEVICES_CLR_V, 8) + +#define PERIPH_CLK_TO_ENB_REG(c) \ + periph_clk_to_reg((c), CLK_OUT_ENB_L, CLK_OUT_ENB_V, 4) +#define PERIPH_CLK_TO_ENB_SET_REG(c) \ + periph_clk_to_reg((c), CLK_OUT_ENB_SET_L, CLK_OUT_ENB_SET_V, 8) +#define PERIPH_CLK_TO_ENB_CLR_REG(c) \ + periph_clk_to_reg((c), CLK_OUT_ENB_CLR_L, CLK_OUT_ENB_CLR_V, 8) + +#define CLK_MASK_ARM 0x44 +#define MISC_CLK_ENB 0x48 + +#define OSC_CTRL 0x50 +#define OSC_CTRL_OSC_FREQ_MASK (0xF<<28) +#define OSC_CTRL_OSC_FREQ_13MHZ (0x0<<28) +#define OSC_CTRL_OSC_FREQ_19_2MHZ (0x4<<28) +#define OSC_CTRL_OSC_FREQ_12MHZ (0x8<<28) +#define OSC_CTRL_OSC_FREQ_26MHZ (0xC<<28) +#define OSC_CTRL_OSC_FREQ_16_8MHZ (0x1<<28) +#define OSC_CTRL_OSC_FREQ_38_4MHZ (0x5<<28) +#define OSC_CTRL_OSC_FREQ_48MHZ (0x9<<28) +#define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK) + +#define OSC_CTRL_PLL_REF_DIV_MASK (3<<26) +#define OSC_CTRL_PLL_REF_DIV_1 (0<<26) +#define OSC_CTRL_PLL_REF_DIV_2 (1<<26) +#define OSC_CTRL_PLL_REF_DIV_4 (2<<26) + +#define OSC_FREQ_DET 0x58 +#define OSC_FREQ_DET_TRIG (1<<31) + +#define OSC_FREQ_DET_STATUS 0x5C +#define OSC_FREQ_DET_BUSY (1<<31) +#define OSC_FREQ_DET_CNT_MASK 0xFFFF + +#define PERIPH_CLK_SOURCE_I2S1 0x100 +#define PERIPH_CLK_SOURCE_EMC 0x19c +#define PERIPH_CLK_SOURCE_OSC 0x1fc +#define PERIPH_CLK_SOURCE_NUM1 \ + ((PERIPH_CLK_SOURCE_OSC - PERIPH_CLK_SOURCE_I2S1) / 4) + +#define PERIPH_CLK_SOURCE_G3D2 0x3b0 +#define PERIPH_CLK_SOURCE_SE 0x42c +#define PERIPH_CLK_SOURCE_NUM2 \ + ((PERIPH_CLK_SOURCE_SE - PERIPH_CLK_SOURCE_G3D2) / 4 + 1) + +#define AUDIO_DLY_CLK 0x49c +#define AUDIO_SYNC_CLK_SPDIF 0x4b4 +#define PERIPH_CLK_SOURCE_NUM3 \ + ((AUDIO_SYNC_CLK_SPDIF - AUDIO_DLY_CLK) / 4 + 1) + +#define PERIPH_CLK_SOURCE_NUM (PERIPH_CLK_SOURCE_NUM1 + \ + PERIPH_CLK_SOURCE_NUM2 + \ + PERIPH_CLK_SOURCE_NUM3) + +#define CPU_SOFTRST_CTRL 0x380 + +#define PERIPH_CLK_SOURCE_DIVU71_MASK 0xFF +#define PERIPH_CLK_SOURCE_DIVU16_MASK 0xFFFF +#define PERIPH_CLK_SOURCE_DIV_SHIFT 0 +#define PERIPH_CLK_SOURCE_DIVIDLE_SHIFT 8 +#define PERIPH_CLK_SOURCE_DIVIDLE_VAL 50 +#define PERIPH_CLK_UART_DIV_ENB (1<<24) +#define PERIPH_CLK_VI_SEL_EX_SHIFT 24 +#define PERIPH_CLK_VI_SEL_EX_MASK (0x3<<PERIPH_CLK_VI_SEL_EX_SHIFT) +#define PERIPH_CLK_NAND_DIV_EX_ENB (1<<8) +#define PERIPH_CLK_DTV_POLARITY_INV (1<<25) + +#define AUDIO_SYNC_SOURCE_MASK 0x0F +#define AUDIO_SYNC_DISABLE_BIT 0x10 +#define AUDIO_SYNC_TAP_NIBBLE_SHIFT(c) ((c->reg_shift - 24) * 4) + +#define PLL_BASE 0x0 +#define PLL_BASE_BYPASS (1<<31) +#define PLL_BASE_ENABLE (1<<30) +#define PLL_BASE_REF_ENABLE (1<<29) +#define PLL_BASE_OVERRIDE (1<<28) +#define PLL_BASE_LOCK (1<<27) +#define PLL_BASE_DIVP_MASK (0x7<<20) +#define PLL_BASE_DIVP_SHIFT 20 +#define PLL_BASE_DIVN_MASK (0x3FF<<8) +#define PLL_BASE_DIVN_SHIFT 8 +#define PLL_BASE_DIVM_MASK (0x1F) +#define PLL_BASE_DIVM_SHIFT 0 + +#define PLL_OUT_RATIO_MASK (0xFF<<8) +#define PLL_OUT_RATIO_SHIFT 8 +#define PLL_OUT_OVERRIDE (1<<2) +#define PLL_OUT_CLKEN (1<<1) +#define PLL_OUT_RESET_DISABLE (1<<0) + +#define PLL_MISC(c) \ + (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc) +#define PLL_MISC_LOCK_ENABLE(c) \ + (((c)->flags & (PLLU | PLLD)) ? (1<<22) : (1<<18)) + +#define PLL_MISC_DCCON_SHIFT 20 +#define PLL_MISC_CPCON_SHIFT 8 +#define PLL_MISC_CPCON_MASK (0xF<<PLL_MISC_CPCON_SHIFT) +#define PLL_MISC_LFCON_SHIFT 4 +#define PLL_MISC_LFCON_MASK (0xF<<PLL_MISC_LFCON_SHIFT) +#define PLL_MISC_VCOCON_SHIFT 0 +#define PLL_MISC_VCOCON_MASK (0xF<<PLL_MISC_VCOCON_SHIFT) +#define PLLD_MISC_CLKENABLE (1<<30) + +#define PLLU_BASE_POST_DIV (1<<20) + +#define PLLD_BASE_DSIB_MUX_SHIFT 25 +#define PLLD_BASE_DSIB_MUX_MASK (1<<PLLD_BASE_DSIB_MUX_SHIFT) +#define PLLD_BASE_CSI_CLKENABLE (1<<26) +#define PLLD_MISC_DSI_CLKENABLE (1<<30) +#define PLLD_MISC_DIV_RST (1<<23) +#define PLLD_MISC_DCCON_SHIFT 12 + +#define PLLDU_LFCON_SET_DIVN 600 + +/* FIXME: OUT_OF_TABLE_CPCON per pll */ +#define OUT_OF_TABLE_CPCON 0x8 + +#define SUPER_CLK_MUX 0x00 +#define SUPER_STATE_SHIFT 28 +#define SUPER_STATE_MASK (0xF << SUPER_STATE_SHIFT) +#define SUPER_STATE_STANDBY (0x0 << SUPER_STATE_SHIFT) +#define SUPER_STATE_IDLE (0x1 << SUPER_STATE_SHIFT) +#define SUPER_STATE_RUN (0x2 << SUPER_STATE_SHIFT) +#define SUPER_STATE_IRQ (0x3 << SUPER_STATE_SHIFT) +#define SUPER_STATE_FIQ (0x4 << SUPER_STATE_SHIFT) +#define SUPER_LP_DIV2_BYPASS (0x1 << 16) +#define SUPER_SOURCE_MASK 0xF +#define SUPER_FIQ_SOURCE_SHIFT 12 +#define SUPER_IRQ_SOURCE_SHIFT 8 +#define SUPER_RUN_SOURCE_SHIFT 4 +#define SUPER_IDLE_SOURCE_SHIFT 0 + +#define SUPER_CLK_DIVIDER 0x04 +#define SUPER_CLOCK_DIV_U71_SHIFT 16 +#define SUPER_CLOCK_DIV_U71_MASK (0xff << SUPER_CLOCK_DIV_U71_SHIFT) +/* guarantees safe cpu backup */ +#define SUPER_CLOCK_DIV_U71_MIN 0x2 + +#define BUS_CLK_DISABLE (1<<3) +#define BUS_CLK_DIV_MASK 0x3 + +#define PMC_CTRL 0x0 + #define PMC_CTRL_BLINK_ENB (1 << 7) + +#define PMC_DPD_PADS_ORIDE 0x1c + #define PMC_DPD_PADS_ORIDE_BLINK_ENB (1 << 20) + +#define PMC_BLINK_TIMER_DATA_ON_SHIFT 0 +#define PMC_BLINK_TIMER_DATA_ON_MASK 0x7fff +#define PMC_BLINK_TIMER_ENB (1 << 15) +#define PMC_BLINK_TIMER_DATA_OFF_SHIFT 16 +#define PMC_BLINK_TIMER_DATA_OFF_MASK 0xffff + +#define PMC_PLLP_WB0_OVERRIDE 0xf8 +#define PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE (1 << 12) + +#define UTMIP_PLL_CFG2 0x488 +#define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xfff) << 6) +#define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x) (((x) & 0x3f) << 18) +#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN (1 << 0) +#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN (1 << 2) +#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN (1 << 4) + +#define UTMIP_PLL_CFG1 0x484 +#define UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 27) +#define UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0) +#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN (1 << 14) +#define UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN (1 << 12) +#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN (1 << 16) + +#define PLLE_BASE_CML_ENABLE (1<<31) +#define PLLE_BASE_ENABLE (1<<30) +#define PLLE_BASE_DIVCML_SHIFT 24 +#define PLLE_BASE_DIVCML_MASK (0xf<<PLLE_BASE_DIVCML_SHIFT) +#define PLLE_BASE_DIVP_SHIFT 16 +#define PLLE_BASE_DIVP_MASK (0x3f<<PLLE_BASE_DIVP_SHIFT) +#define PLLE_BASE_DIVN_SHIFT 8 +#define PLLE_BASE_DIVN_MASK (0xFF<<PLLE_BASE_DIVN_SHIFT) +#define PLLE_BASE_DIVM_SHIFT 0 +#define PLLE_BASE_DIVM_MASK (0xFF<<PLLE_BASE_DIVM_SHIFT) +#define PLLE_BASE_DIV_MASK \ + (PLLE_BASE_DIVCML_MASK | PLLE_BASE_DIVP_MASK | \ + PLLE_BASE_DIVN_MASK | PLLE_BASE_DIVM_MASK) +#define PLLE_BASE_DIV(m, n, p, cml) \ + (((cml)<<PLLE_BASE_DIVCML_SHIFT) | ((p)<<PLLE_BASE_DIVP_SHIFT) | \ + ((n)<<PLLE_BASE_DIVN_SHIFT) | ((m)<<PLLE_BASE_DIVM_SHIFT)) + +#define PLLE_MISC_SETUP_BASE_SHIFT 16 +#define PLLE_MISC_SETUP_BASE_MASK (0xFFFF<<PLLE_MISC_SETUP_BASE_SHIFT) +#define PLLE_MISC_READY (1<<15) +#define PLLE_MISC_LOCK (1<<11) +#define PLLE_MISC_LOCK_ENABLE (1<<9) +#define PLLE_MISC_SETUP_EX_SHIFT 2 +#define PLLE_MISC_SETUP_EX_MASK (0x3<<PLLE_MISC_SETUP_EX_SHIFT) +#define PLLE_MISC_SETUP_MASK \ + (PLLE_MISC_SETUP_BASE_MASK | PLLE_MISC_SETUP_EX_MASK) +#define PLLE_MISC_SETUP_VALUE \ + ((0x7<<PLLE_MISC_SETUP_BASE_SHIFT) | (0x0<<PLLE_MISC_SETUP_EX_SHIFT)) + +#define PLLE_SS_CTRL 0x68 +#define PLLE_SS_INCINTRV_SHIFT 24 +#define PLLE_SS_INCINTRV_MASK (0x3f<<PLLE_SS_INCINTRV_SHIFT) +#define PLLE_SS_INC_SHIFT 16 +#define PLLE_SS_INC_MASK (0xff<<PLLE_SS_INC_SHIFT) +#define PLLE_SS_MAX_SHIFT 0 +#define PLLE_SS_MAX_MASK (0x1ff<<PLLE_SS_MAX_SHIFT) +#define PLLE_SS_COEFFICIENTS_MASK \ + (PLLE_SS_INCINTRV_MASK | PLLE_SS_INC_MASK | PLLE_SS_MAX_MASK) +#define PLLE_SS_COEFFICIENTS_12MHZ \ + ((0x18<<PLLE_SS_INCINTRV_SHIFT) | (0x1<<PLLE_SS_INC_SHIFT) | \ + (0x24<<PLLE_SS_MAX_SHIFT)) +#define PLLE_SS_DISABLE ((1<<12) | (1<<11) | (1<<10)) + +#define PLLE_AUX 0x48c +#define PLLE_AUX_PLLP_SEL (1<<2) +#define PLLE_AUX_CML_SATA_ENABLE (1<<1) +#define PLLE_AUX_CML_PCIE_ENABLE (1<<0) + +#define PMC_SATA_PWRGT 0x1ac +#define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE (1<<5) +#define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL (1<<4) + +#define ROUND_DIVIDER_UP 0 +#define ROUND_DIVIDER_DOWN 1 + +/* FIXME: recommended safety delay after lock is detected */ +#define PLL_POST_LOCK_DELAY 100 + +/** +* Structure defining the fields for USB UTMI clocks Parameters. +*/ +struct utmi_clk_param { + /* Oscillator Frequency in KHz */ + u32 osc_frequency; + /* UTMIP PLL Enable Delay Count */ + u8 enable_delay_count; + /* UTMIP PLL Stable count */ + u8 stable_count; + /* UTMIP PLL Active delay count */ + u8 active_delay_count; + /* UTMIP PLL Xtal frequency count */ + u8 xtal_freq_count; +}; + +static const struct utmi_clk_param utmi_parameters[] = { + { + .osc_frequency = 13000000, + .enable_delay_count = 0x02, + .stable_count = 0x33, + .active_delay_count = 0x05, + .xtal_freq_count = 0x7F + }, + { + .osc_frequency = 19200000, + .enable_delay_count = 0x03, + .stable_count = 0x4B, + .active_delay_count = 0x06, + .xtal_freq_count = 0xBB}, + { + .osc_frequency = 12000000, + .enable_delay_count = 0x02, + .stable_count = 0x2F, + .active_delay_count = 0x04, + .xtal_freq_count = 0x76 + }, + { + .osc_frequency = 26000000, + .enable_delay_count = 0x04, + .stable_count = 0x66, + .active_delay_count = 0x09, + .xtal_freq_count = 0xFE + }, + { + .osc_frequency = 16800000, + .enable_delay_count = 0x03, + .stable_count = 0x41, + .active_delay_count = 0x0A, + .xtal_freq_count = 0xA4 + }, +}; + +static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE); +static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE); +static void __iomem *misc_gp_hidrev_base = IO_ADDRESS(TEGRA_APB_MISC_BASE); + +#define MISC_GP_HIDREV 0x804 + +/* + * Some peripheral clocks share an enable bit, so refcount the enable bits + * in registers CLK_ENABLE_L, ... CLK_ENABLE_W + */ +static int tegra_periph_clk_enable_refcount[CLK_OUT_ENB_NUM * 32]; + +#define clk_writel(value, reg) \ + __raw_writel(value, (u32)reg_clk_base + (reg)) +#define clk_readl(reg) \ + __raw_readl((u32)reg_clk_base + (reg)) +#define pmc_writel(value, reg) \ + __raw_writel(value, (u32)reg_pmc_base + (reg)) +#define pmc_readl(reg) \ + __raw_readl((u32)reg_pmc_base + (reg)) +#define chipid_readl() \ + __raw_readl((u32)misc_gp_hidrev_base + MISC_GP_HIDREV) + +#define clk_writel_delay(value, reg) \ + do { \ + __raw_writel((value), (u32)reg_clk_base + (reg)); \ + udelay(2); \ + } while (0) + + +static inline int clk_set_div(struct clk *c, u32 n) +{ + return clk_set_rate(c, (clk_get_rate(c->parent) + n-1) / n); +} + +static inline u32 periph_clk_to_reg( + struct clk *c, u32 reg_L, u32 reg_V, int offs) +{ + u32 reg = c->u.periph.clk_num / 32; + BUG_ON(reg >= RST_DEVICES_NUM); + if (reg < 3) + reg = reg_L + (reg * offs); + else + reg = reg_V + ((reg - 3) * offs); + return reg; +} + +static unsigned long clk_measure_input_freq(void) +{ + u32 clock_autodetect; + clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET); + do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY); + clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS); + if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3) { + return 12000000; + } else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3) { + return 13000000; + } else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3) { + return 19200000; + } else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3) { + return 26000000; + } else if (clock_autodetect >= 1025 - 3 && clock_autodetect <= 1025 + 3) { + return 16800000; + } else if (clock_autodetect >= 2344 - 3 && clock_autodetect <= 2344 + 3) { + return 38400000; + } else if (clock_autodetect >= 2928 - 3 && clock_autodetect <= 2928 + 3) { + return 48000000; + } else { + pr_err("%s: Unexpected clock autodetect value %d", __func__, + clock_autodetect); + BUG(); + return 0; + } +} + +static int clk_div71_get_divider(unsigned long parent_rate, unsigned long rate, + u32 flags, u32 round_mode) +{ + s64 divider_u71 = parent_rate; + if (!rate) + return -EINVAL; + + if (!(flags & DIV_U71_INT)) + divider_u71 *= 2; + if (round_mode == ROUND_DIVIDER_UP) + divider_u71 += rate - 1; + do_div(divider_u71, rate); + if (flags & DIV_U71_INT) + divider_u71 *= 2; + + if (divider_u71 - 2 < 0) + return 0; + + if (divider_u71 - 2 > 255) + return -EINVAL; + + return divider_u71 - 2; +} + +static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate) +{ + s64 divider_u16; + + divider_u16 = parent_rate; + if (!rate) + return -EINVAL; + divider_u16 += rate - 1; + do_div(divider_u16, rate); + + if (divider_u16 - 1 < 0) + return 0; + + if (divider_u16 - 1 > 0xFFFF) + return -EINVAL; + + return divider_u16 - 1; +} + +/* clk_m functions */ +static unsigned long tegra30_clk_m_autodetect_rate(struct clk *c) +{ + u32 osc_ctrl = clk_readl(OSC_CTRL); + u32 auto_clock_control = osc_ctrl & ~OSC_CTRL_OSC_FREQ_MASK; + u32 pll_ref_div = osc_ctrl & OSC_CTRL_PLL_REF_DIV_MASK; + + c->rate = clk_measure_input_freq(); + switch (c->rate) { + case 12000000: + auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ; + BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); + break; + case 13000000: + auto_clock_control |= OSC_CTRL_OSC_FREQ_13MHZ; + BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); + break; + case 19200000: + auto_clock_control |= OSC_CTRL_OSC_FREQ_19_2MHZ; + BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); + break; + case 26000000: + auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ; + BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); + break; + case 16800000: + auto_clock_control |= OSC_CTRL_OSC_FREQ_16_8MHZ; + BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); + break; + case 38400000: + auto_clock_control |= OSC_CTRL_OSC_FREQ_38_4MHZ; + BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_2); + break; + case 48000000: + auto_clock_control |= OSC_CTRL_OSC_FREQ_48MHZ; + BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_4); + break; + default: + pr_err("%s: Unexpected clock rate %ld", __func__, c->rate); + BUG(); + } + clk_writel(auto_clock_control, OSC_CTRL); + return c->rate; +} + +static void tegra30_clk_m_init(struct clk *c) +{ + pr_debug("%s on clock %s\n", __func__, c->name); + tegra30_clk_m_autodetect_rate(c); +} + +static int tegra30_clk_m_enable(struct clk *c) +{ + pr_debug("%s on clock %s\n", __func__, c->name); + return 0; +} + +static void tegra30_clk_m_disable(struct clk *c) +{ + pr_debug("%s on clock %s\n", __func__, c->name); + WARN(1, "Attempting to disable main SoC clock\n"); +} + +static struct clk_ops tegra_clk_m_ops = { + .init = tegra30_clk_m_init, + .enable = tegra30_clk_m_enable, + .disable = tegra30_clk_m_disable, +}; + +static struct clk_ops tegra_clk_m_div_ops = { + .enable = tegra30_clk_m_enable, +}; + +/* PLL reference divider functions */ +static void tegra30_pll_ref_init(struct clk *c) +{ + u32 pll_ref_div = clk_readl(OSC_CTRL) & OSC_CTRL_PLL_REF_DIV_MASK; + pr_debug("%s on clock %s\n", __func__, c->name); + + switch (pll_ref_div) { + case OSC_CTRL_PLL_REF_DIV_1: + c->div = 1; + break; + case OSC_CTRL_PLL_REF_DIV_2: + c->div = 2; + break; + case OSC_CTRL_PLL_REF_DIV_4: + c->div = 4; + break; + default: + pr_err("%s: Invalid pll ref divider %d", __func__, pll_ref_div); + BUG(); + } + c->mul = 1; + c->state = ON; +} + +static struct clk_ops tegra_pll_ref_ops = { + .init = tegra30_pll_ref_init, + .enable = tegra30_clk_m_enable, + .disable = tegra30_clk_m_disable, +}; + +/* super clock functions */ +/* "super clocks" on tegra30 have two-stage muxes, fractional 7.1 divider and + * clock skipping super divider. We will ignore the clock skipping divider, + * since we can't lower the voltage when using the clock skip, but we can if + * we lower the PLL frequency. We will use 7.1 divider for CPU super-clock + * only when its parent is a fixed rate PLL, since we can't change PLL rate + * in this case. + */ +static void tegra30_super_clk_init(struct clk *c) +{ + u32 val; + int source; + int shift; + const struct clk_mux_sel *sel; + val = clk_readl(c->reg + SUPER_CLK_MUX); + c->state = ON; + BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) && + ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE)); + shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ? + SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT; + source = (val >> shift) & SUPER_SOURCE_MASK; + if (c->flags & DIV_2) + source |= val & SUPER_LP_DIV2_BYPASS; + for (sel = c->inputs; sel->input != NULL; sel++) { + if (sel->value == source) + break; + } + BUG_ON(sel->input == NULL); + c->parent = sel->input; + + if (c->flags & DIV_U71) { + /* Init safe 7.1 divider value (does not affect PLLX path) */ + clk_writel(SUPER_CLOCK_DIV_U71_MIN << SUPER_CLOCK_DIV_U71_SHIFT, + c->reg + SUPER_CLK_DIVIDER); + c->mul = 2; + c->div = 2; + if (!(c->parent->flags & PLLX)) + c->div += SUPER_CLOCK_DIV_U71_MIN; + } else + clk_writel(0, c->reg + SUPER_CLK_DIVIDER); +} + +static int tegra30_super_clk_enable(struct clk *c) +{ + return 0; +} + +static void tegra30_super_clk_disable(struct clk *c) +{ + /* since tegra 3 has 2 CPU super clocks - low power lp-mode clock and + geared up g-mode super clock - mode switch may request to disable + either of them; accept request with no affect on h/w */ +} + +static int tegra30_super_clk_set_parent(struct clk *c, struct clk *p) +{ + u32 val; + const struct clk_mux_sel *sel; + int shift; + + val = clk_readl(c->reg + SUPER_CLK_MUX); + BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) && + ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE)); + shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ? + SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT; + for (sel = c->inputs; sel->input != NULL; sel++) { + if (sel->input == p) { + /* For LP mode super-clock switch between PLLX direct + and divided-by-2 outputs is allowed only when other + than PLLX clock source is current parent */ + if ((c->flags & DIV_2) && (p->flags & PLLX) && + ((sel->value ^ val) & SUPER_LP_DIV2_BYPASS)) { + if (c->parent->flags & PLLX) + return -EINVAL; + val ^= SUPER_LP_DIV2_BYPASS; + clk_writel_delay(val, c->reg); + } + val &= ~(SUPER_SOURCE_MASK << shift); + val |= (sel->value & SUPER_SOURCE_MASK) << shift; + + /* 7.1 divider for CPU super-clock does not affect + PLLX path */ + if (c->flags & DIV_U71) { + u32 div = 0; + if (!(p->flags & PLLX)) { + div = clk_readl(c->reg + + SUPER_CLK_DIVIDER); + div &= SUPER_CLOCK_DIV_U71_MASK; + div >>= SUPER_CLOCK_DIV_U71_SHIFT; + } + c->div = div + 2; + c->mul = 2; + } + + if (c->refcnt) + clk_enable(p); + + clk_writel_delay(val, c->reg); + + if (c->refcnt && c->parent) + clk_disable(c->parent); + + clk_reparent(c, p); + return 0; + } + } + return -EINVAL; +} + +/* + * Do not use super clocks "skippers", since dividing using a clock skipper + * does not allow the voltage to be scaled down. Instead adjust the rate of + * the parent clock. This requires that the parent of a super clock have no + * other children, otherwise the rate will change underneath the other + * children. Special case: if fixed rate PLL is CPU super clock parent the + * rate of this PLL can't be changed, and it has many other children. In + * this case use 7.1 fractional divider to adjust the super clock rate. + */ +static int tegra30_super_clk_set_rate(struct clk *c, unsigned long rate) +{ + if ((c->flags & DIV_U71) && (c->parent->flags & PLL_FIXED)) { + int div = clk_div71_get_divider(c->parent->u.pll.fixed_rate, + rate, c->flags, ROUND_DIVIDER_DOWN); + div = max(div, SUPER_CLOCK_DIV_U71_MIN); + + clk_writel(div << SUPER_CLOCK_DIV_U71_SHIFT, + c->reg + SUPER_CLK_DIVIDER); + c->div = div + 2; + c->mul = 2; + return 0; + } + return clk_set_rate(c->parent, rate); +} + +static struct clk_ops tegra_super_ops = { + .init = tegra30_super_clk_init, + .enable = tegra30_super_clk_enable, + .disable = tegra30_super_clk_disable, + .set_parent = tegra30_super_clk_set_parent, + .set_rate = tegra30_super_clk_set_rate, +}; + +static int tegra30_twd_clk_set_rate(struct clk *c, unsigned long rate) +{ + /* The input value 'rate' is the clock rate of the CPU complex. */ + c->rate = (rate * c->mul) / c->div; + return 0; +} + +static struct clk_ops tegra30_twd_ops = { + .set_rate = tegra30_twd_clk_set_rate, +}; + +/* Blink output functions */ + +static void tegra30_blink_clk_init(struct clk *c) +{ + u32 val; + + val = pmc_readl(PMC_CTRL); + c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF; + c->mul = 1; + val = pmc_readl(c->reg); + + if (val & PMC_BLINK_TIMER_ENB) { + unsigned int on_off; + + on_off = (val >> PMC_BLINK_TIMER_DATA_ON_SHIFT) & + PMC_BLINK_TIMER_DATA_ON_MASK; + val >>= PMC_BLINK_TIMER_DATA_OFF_SHIFT; + val &= PMC_BLINK_TIMER_DATA_OFF_MASK; + on_off += val; + /* each tick in the blink timer is 4 32KHz clocks */ + c->div = on_off * 4; + } else { + c->div = 1; + } +} + +static int tegra30_blink_clk_enable(struct clk *c) +{ + u32 val; + + val = pmc_readl(PMC_DPD_PADS_ORIDE); + pmc_writel(val | PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE); + + val = pmc_readl(PMC_CTRL); + pmc_writel(val | PMC_CTRL_BLINK_ENB, PMC_CTRL); + + return 0; +} + +static void tegra30_blink_clk_disable(struct clk *c) +{ + u32 val; + + val = pmc_readl(PMC_CTRL); + pmc_writel(val & ~PMC_CTRL_BLINK_ENB, PMC_CTRL); + + val = pmc_readl(PMC_DPD_PADS_ORIDE); + pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE); +} + +static int tegra30_blink_clk_set_rate(struct clk *c, unsigned long rate) +{ + unsigned long parent_rate = clk_get_rate(c->parent); + if (rate >= parent_rate) { + c->div = 1; + pmc_writel(0, c->reg); + } else { + unsigned int on_off; + u32 val; + + on_off = DIV_ROUND_UP(parent_rate / 8, rate); + c->div = on_off * 8; + + val = (on_off & PMC_BLINK_TIMER_DATA_ON_MASK) << + PMC_BLINK_TIMER_DATA_ON_SHIFT; + on_off &= PMC_BLINK_TIMER_DATA_OFF_MASK; + on_off <<= PMC_BLINK_TIMER_DATA_OFF_SHIFT; + val |= on_off; + val |= PMC_BLINK_TIMER_ENB; + pmc_writel(val, c->reg); + } + + return 0; +} + +static struct clk_ops tegra_blink_clk_ops = { + .init = &tegra30_blink_clk_init, + .enable = &tegra30_blink_clk_enable, + .disable = &tegra30_blink_clk_disable, + .set_rate = &tegra30_blink_clk_set_rate, +}; + +/* PLL Functions */ +static int tegra30_pll_clk_wait_for_lock(struct clk *c, u32 lock_reg, + u32 lock_bit) +{ +#if USE_PLL_LOCK_BITS + int i; + for (i = 0; i < c->u.pll.lock_delay; i++) { + if (clk_readl(lock_reg) & lock_bit) { + udelay(PLL_POST_LOCK_DELAY); + return 0; + } + udelay(2); /* timeout = 2 * lock time */ + } + pr_err("Timed out waiting for lock bit on pll %s", c->name); + return -1; +#endif + udelay(c->u.pll.lock_delay); + + return 0; +} + + +static void tegra30_utmi_param_configure(struct clk *c) +{ + u32 reg; + int i; + unsigned long main_rate = + clk_get_rate(c->parent->parent); + + for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) { + if (main_rate == utmi_parameters[i].osc_frequency) + break; + } + + if (i >= ARRAY_SIZE(utmi_parameters)) { + pr_err("%s: Unexpected main rate %lu\n", __func__, main_rate); + return; + } + + reg = clk_readl(UTMIP_PLL_CFG2); + + /* Program UTMIP PLL stable and active counts */ + /* [FIXME] arclk_rst.h says WRONG! This should be 1ms -> 0x50 Check! */ + reg &= ~UTMIP_PLL_CFG2_STABLE_COUNT(~0); + reg |= UTMIP_PLL_CFG2_STABLE_COUNT( + utmi_parameters[i].stable_count); + + reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0); + + reg |= UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT( + utmi_parameters[i].active_delay_count); + + /* Remove power downs from UTMIP PLL control bits */ + reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN; + reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN; + reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN; + + clk_writel(reg, UTMIP_PLL_CFG2); + + /* Program UTMIP PLL delay and oscillator frequency counts */ + reg = clk_readl(UTMIP_PLL_CFG1); + reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0); + + reg |= UTMIP_PLL_CFG1_ENABLE_DLY_COUNT( + utmi_parameters[i].enable_delay_count); + + reg &= ~UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(~0); + reg |= UTMIP_PLL_CFG1_XTAL_FREQ_COUNT( + utmi_parameters[i].xtal_freq_count); + + /* Remove power downs from UTMIP PLL control bits */ + reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN; + reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN; + reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN; + + clk_writel(reg, UTMIP_PLL_CFG1); +} + +static void tegra30_pll_clk_init(struct clk *c) +{ + u32 val = clk_readl(c->reg + PLL_BASE); + + c->state = (val & PLL_BASE_ENABLE) ? ON : OFF; + + if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) { + const struct clk_pll_freq_table *sel; + unsigned long input_rate = clk_get_rate(c->parent); + for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) { + if (sel->input_rate == input_rate && + sel->output_rate == c->u.pll.fixed_rate) { + c->mul = sel->n; + c->div = sel->m * sel->p; + return; + } + } + pr_err("Clock %s has unknown fixed frequency\n", c->name); + BUG(); + } else if (val & PLL_BASE_BYPASS) { + c->mul = 1; + c->div = 1; + } else { + c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT; + c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT; + if (c->flags & PLLU) + c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2; + else + c->div *= (0x1 << ((val & PLL_BASE_DIVP_MASK) >> + PLL_BASE_DIVP_SHIFT)); + if (c->flags & PLL_FIXED) { + unsigned long rate = clk_get_rate_locked(c); + BUG_ON(rate != c->u.pll.fixed_rate); + } + } + + if (c->flags & PLLU) + tegra30_utmi_param_configure(c); +} + +static int tegra30_pll_clk_enable(struct clk *c) +{ + u32 val; + pr_debug("%s on clock %s\n", __func__, c->name); + +#if USE_PLL_LOCK_BITS + val = clk_readl(c->reg + PLL_MISC(c)); + val |= PLL_MISC_LOCK_ENABLE(c); + clk_writel(val, c->reg + PLL_MISC(c)); +#endif + val = clk_readl(c->reg + PLL_BASE); + val &= ~PLL_BASE_BYPASS; + val |= PLL_BASE_ENABLE; + clk_writel(val, c->reg + PLL_BASE); + + if (c->flags & PLLM) { + val = pmc_readl(PMC_PLLP_WB0_OVERRIDE); + val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE; + pmc_writel(val, PMC_PLLP_WB0_OVERRIDE); + } + + tegra30_pll_clk_wait_for_lock(c, c->reg + PLL_BASE, PLL_BASE_LOCK); + + return 0; +} + +static void tegra30_pll_clk_disable(struct clk *c) +{ + u32 val; + pr_debug("%s on clock %s\n", __func__, c->name); + + val = clk_readl(c->reg); + val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE); + clk_writel(val, c->reg); + + if (c->flags & PLLM) { + val = pmc_readl(PMC_PLLP_WB0_OVERRIDE); + val &= ~PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE; + pmc_writel(val, PMC_PLLP_WB0_OVERRIDE); + } +} + +static int tegra30_pll_clk_set_rate(struct clk *c, unsigned long rate) +{ + u32 val, p_div, old_base; + unsigned long input_rate; + const struct clk_pll_freq_table *sel; + struct clk_pll_freq_table cfg; + + pr_debug("%s: %s %lu\n", __func__, c->name, rate); + + if (c->flags & PLL_FIXED) { + int ret = 0; + if (rate != c->u.pll.fixed_rate) { + pr_err("%s: Can not change %s fixed rate %lu to %lu\n", + __func__, c->name, c->u.pll.fixed_rate, rate); + ret = -EINVAL; + } + return ret; + } + + if (c->flags & PLLM) { + if (rate != clk_get_rate_locked(c)) { + pr_err("%s: Can not change memory %s rate in flight\n", + __func__, c->name); + return -EINVAL; + } + return 0; + } + + p_div = 0; + input_rate = clk_get_rate(c->parent); + + /* Check if the target rate is tabulated */ + for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) { + if (sel->input_rate == input_rate && sel->output_rate == rate) { + if (c->flags & PLLU) { + BUG_ON(sel->p < 1 || sel->p > 2); + if (sel->p == 1) + p_div = PLLU_BASE_POST_DIV; + } else { + BUG_ON(sel->p < 1); + for (val = sel->p; val > 1; val >>= 1) + p_div++; + p_div <<= PLL_BASE_DIVP_SHIFT; + } + break; + } + } + + /* Configure out-of-table rate */ + if (sel->input_rate == 0) { + unsigned long cfreq; + BUG_ON(c->flags & PLLU); + sel = &cfg; + + switch (input_rate) { + case 12000000: + case 26000000: + cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2000000; + break; + case 13000000: + cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2600000; + break; + case 16800000: + case 19200000: + cfreq = (rate <= 1200000 * 1000) ? 1200000 : 2400000; + break; + default: + pr_err("%s: Unexpected reference rate %lu\n", + __func__, input_rate); + BUG(); + } + + /* Raise VCO to guarantee 0.5% accuracy */ + for (cfg.output_rate = rate; cfg.output_rate < 200 * cfreq; + cfg.output_rate <<= 1) + p_div++; + + cfg.p = 0x1 << p_div; + cfg.m = input_rate / cfreq; + cfg.n = cfg.output_rate / cfreq; + cfg.cpcon = OUT_OF_TABLE_CPCON; + + if ((cfg.m > (PLL_BASE_DIVM_MASK >> PLL_BASE_DIVM_SHIFT)) || + (cfg.n > (PLL_BASE_DIVN_MASK >> PLL_BASE_DIVN_SHIFT)) || + (p_div > (PLL_BASE_DIVP_MASK >> PLL_BASE_DIVP_SHIFT)) || + (cfg.output_rate > c->u.pll.vco_max)) { + pr_err("%s: Failed to set %s out-of-table rate %lu\n", + __func__, c->name, rate); + return -EINVAL; + } + p_div <<= PLL_BASE_DIVP_SHIFT; + } + + c->mul = sel->n; + c->div = sel->m * sel->p; + + old_base = val = clk_readl(c->reg + PLL_BASE); + val &= ~(PLL_BASE_DIVM_MASK | PLL_BASE_DIVN_MASK | + ((c->flags & PLLU) ? PLLU_BASE_POST_DIV : PLL_BASE_DIVP_MASK)); + val |= (sel->m << PLL_BASE_DIVM_SHIFT) | + (sel->n << PLL_BASE_DIVN_SHIFT) | p_div; + if (val == old_base) + return 0; + + if (c->state == ON) { + tegra30_pll_clk_disable(c); + val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE); + } + clk_writel(val, c->reg + PLL_BASE); + + if (c->flags & PLL_HAS_CPCON) { + val = clk_readl(c->reg + PLL_MISC(c)); + val &= ~PLL_MISC_CPCON_MASK; + val |= sel->cpcon << PLL_MISC_CPCON_SHIFT; + if (c->flags & (PLLU | PLLD)) { + val &= ~PLL_MISC_LFCON_MASK; + if (sel->n >= PLLDU_LFCON_SET_DIVN) + val |= 0x1 << PLL_MISC_LFCON_SHIFT; + } else if (c->flags & (PLLX | PLLM)) { + val &= ~(0x1 << PLL_MISC_DCCON_SHIFT); + if (rate >= (c->u.pll.vco_max >> 1)) + val |= 0x1 << PLL_MISC_DCCON_SHIFT; + } + clk_writel(val, c->reg + PLL_MISC(c)); + } + + if (c->state == ON) + tegra30_pll_clk_enable(c); + + return 0; +} + +static struct clk_ops tegra_pll_ops = { + .init = tegra30_pll_clk_init, + .enable = tegra30_pll_clk_enable, + .disable = tegra30_pll_clk_disable, + .set_rate = tegra30_pll_clk_set_rate, +}; + +static int +tegra30_plld_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting) +{ + u32 val, mask, reg; + + switch (p) { + case TEGRA_CLK_PLLD_CSI_OUT_ENB: + mask = PLLD_BASE_CSI_CLKENABLE; + reg = c->reg + PLL_BASE; + break; + case TEGRA_CLK_PLLD_DSI_OUT_ENB: + mask = PLLD_MISC_DSI_CLKENABLE; + reg = c->reg + PLL_MISC(c); + break; + case TEGRA_CLK_PLLD_MIPI_MUX_SEL: + if (!(c->flags & PLL_ALT_MISC_REG)) { + mask = PLLD_BASE_DSIB_MUX_MASK; + reg = c->reg + PLL_BASE; + break; + } + /* fall through - error since PLLD2 does not have MUX_SEL control */ + default: + return -EINVAL; + } + + val = clk_readl(reg); + if (setting) + val |= mask; + else + val &= ~mask; + clk_writel(val, reg); + return 0; +} + +static struct clk_ops tegra_plld_ops = { + .init = tegra30_pll_clk_init, + .enable = tegra30_pll_clk_enable, + .disable = tegra30_pll_clk_disable, + .set_rate = tegra30_pll_clk_set_rate, + .clk_cfg_ex = tegra30_plld_clk_cfg_ex, +}; + +static void tegra30_plle_clk_init(struct clk *c) +{ + u32 val; + + val = clk_readl(PLLE_AUX); + c->parent = (val & PLLE_AUX_PLLP_SEL) ? + tegra_get_clock_by_name("pll_p") : + tegra_get_clock_by_name("pll_ref"); + + val = clk_readl(c->reg + PLL_BASE); + c->state = (val & PLLE_BASE_ENABLE) ? ON : OFF; + c->mul = (val & PLLE_BASE_DIVN_MASK) >> PLLE_BASE_DIVN_SHIFT; + c->div = (val & PLLE_BASE_DIVM_MASK) >> PLLE_BASE_DIVM_SHIFT; + c->div *= (val & PLLE_BASE_DIVP_MASK) >> PLLE_BASE_DIVP_SHIFT; +} + +static void tegra30_plle_clk_disable(struct clk *c) +{ + u32 val; + pr_debug("%s on clock %s\n", __func__, c->name); + + val = clk_readl(c->reg + PLL_BASE); + val &= ~(PLLE_BASE_CML_ENABLE | PLLE_BASE_ENABLE); + clk_writel(val, c->reg + PLL_BASE); +} + +static void tegra30_plle_training(struct clk *c) +{ + u32 val; + + /* PLLE is already disabled, and setup cleared; + * create falling edge on PLLE IDDQ input */ + val = pmc_readl(PMC_SATA_PWRGT); + val |= PMC_SATA_PWRGT_PLLE_IDDQ_VALUE; + pmc_writel(val, PMC_SATA_PWRGT); + + val = pmc_readl(PMC_SATA_PWRGT); + val |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL; + pmc_writel(val, PMC_SATA_PWRGT); + + val = pmc_readl(PMC_SATA_PWRGT); + val &= ~PMC_SATA_PWRGT_PLLE_IDDQ_VALUE; + pmc_writel(val, PMC_SATA_PWRGT); + + do { + val = clk_readl(c->reg + PLL_MISC(c)); + } while (!(val & PLLE_MISC_READY)); +} + +static int tegra30_plle_configure(struct clk *c, bool force_training) +{ + u32 val; + const struct clk_pll_freq_table *sel; + unsigned long rate = c->u.pll.fixed_rate; + unsigned long input_rate = clk_get_rate(c->parent); + + for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) { + if (sel->input_rate == input_rate && sel->output_rate == rate) + break; + } + + if (sel->input_rate == 0) + return -ENOSYS; + + /* disable PLLE, clear setup fiels */ + tegra30_plle_clk_disable(c); + + val = clk_readl(c->reg + PLL_MISC(c)); + val &= ~(PLLE_MISC_LOCK_ENABLE | PLLE_MISC_SETUP_MASK); + clk_writel(val, c->reg + PLL_MISC(c)); + + /* training */ + val = clk_readl(c->reg + PLL_MISC(c)); + if (force_training || (!(val & PLLE_MISC_READY))) + tegra30_plle_training(c); + + /* configure dividers, setup, disable SS */ + val = clk_readl(c->reg + PLL_BASE); + val &= ~PLLE_BASE_DIV_MASK; + val |= PLLE_BASE_DIV(sel->m, sel->n, sel->p, sel->cpcon); + clk_writel(val, c->reg + PLL_BASE); + c->mul = sel->n; + c->div = sel->m * sel->p; + + val = clk_readl(c->reg + PLL_MISC(c)); + val |= PLLE_MISC_SETUP_VALUE; + val |= PLLE_MISC_LOCK_ENABLE; + clk_writel(val, c->reg + PLL_MISC(c)); + + val = clk_readl(PLLE_SS_CTRL); + val |= PLLE_SS_DISABLE; + clk_writel(val, PLLE_SS_CTRL); + + /* enable and lock PLLE*/ + val = clk_readl(c->reg + PLL_BASE); + val |= (PLLE_BASE_CML_ENABLE | PLLE_BASE_ENABLE); + clk_writel(val, c->reg + PLL_BASE); + + tegra30_pll_clk_wait_for_lock(c, c->reg + PLL_MISC(c), PLLE_MISC_LOCK); + + return 0; +} + +static int tegra30_plle_clk_enable(struct clk *c) +{ + pr_debug("%s on clock %s\n", __func__, c->name); + return tegra30_plle_configure(c, !c->set); +} + +static struct clk_ops tegra_plle_ops = { + .init = tegra30_plle_clk_init, + .enable = tegra30_plle_clk_enable, + .disable = tegra30_plle_clk_disable, +}; + +/* Clock divider ops */ +static void tegra30_pll_div_clk_init(struct clk *c) +{ + if (c->flags & DIV_U71) { + u32 divu71; + u32 val = clk_readl(c->reg); + val >>= c->reg_shift; + c->state = (val & PLL_OUT_CLKEN) ? ON : OFF; + if (!(val & PLL_OUT_RESET_DISABLE)) + c->state = OFF; + + divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT; + c->div = (divu71 + 2); + c->mul = 2; + } else if (c->flags & DIV_2) { + c->state = ON; + if (c->flags & (PLLD | PLLX)) { + c->div = 2; + c->mul = 1; + } else + BUG(); + } else { + c->state = ON; + c->div = 1; + c->mul = 1; + } +} + +static int tegra30_pll_div_clk_enable(struct clk *c) +{ + u32 val; + u32 new_val; + + pr_debug("%s: %s\n", __func__, c->name); + if (c->flags & DIV_U71) { + val = clk_readl(c->reg); + new_val = val >> c->reg_shift; + new_val &= 0xFFFF; + + new_val |= PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE; + + val &= ~(0xFFFF << c->reg_shift); + val |= new_val << c->reg_shift; + clk_writel_delay(val, c->reg); + return 0; + } else if (c->flags & DIV_2) { + return 0; + } + return -EINVAL; +} + +static void tegra30_pll_div_clk_disable(struct clk *c) +{ + u32 val; + u32 new_val; + + pr_debug("%s: %s\n", __func__, c->name); + if (c->flags & DIV_U71) { + val = clk_readl(c->reg); + new_val = val >> c->reg_shift; + new_val &= 0xFFFF; + + new_val &= ~(PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE); + + val &= ~(0xFFFF << c->reg_shift); + val |= new_val << c->reg_shift; + clk_writel_delay(val, c->reg); + } +} + +static int tegra30_pll_div_clk_set_rate(struct clk *c, unsigned long rate) +{ + u32 val; + u32 new_val; + int divider_u71; + unsigned long parent_rate = clk_get_rate(c->parent); + + pr_debug("%s: %s %lu\n", __func__, c->name, rate); + if (c->flags & DIV_U71) { + divider_u71 = clk_div71_get_divider( + parent_rate, rate, c->flags, ROUND_DIVIDER_UP); + if (divider_u71 >= 0) { + val = clk_readl(c->reg); + new_val = val >> c->reg_shift; + new_val &= 0xFFFF; + if (c->flags & DIV_U71_FIXED) + new_val |= PLL_OUT_OVERRIDE; + new_val &= ~PLL_OUT_RATIO_MASK; + new_val |= divider_u71 << PLL_OUT_RATIO_SHIFT; + + val &= ~(0xFFFF << c->reg_shift); + val |= new_val << c->reg_shift; + clk_writel_delay(val, c->reg); + c->div = divider_u71 + 2; + c->mul = 2; + return 0; + } + } else if (c->flags & DIV_2) + return clk_set_rate(c->parent, rate * 2); + + return -EINVAL; +} + +static long tegra30_pll_div_clk_round_rate(struct clk *c, unsigned long rate) +{ + int divider; + unsigned long parent_rate = clk_get_rate(c->parent); + pr_debug("%s: %s %lu\n", __func__, c->name, rate); + + if (c->flags & DIV_U71) { + divider = clk_div71_get_divider( + parent_rate, rate, c->flags, ROUND_DIVIDER_UP); + if (divider < 0) + return divider; + return DIV_ROUND_UP(parent_rate * 2, divider + 2); + } else if (c->flags & DIV_2) + /* no rounding - fixed DIV_2 dividers pass rate to parent PLL */ + return rate; + + return -EINVAL; +} + +static struct clk_ops tegra_pll_div_ops = { + .init = tegra30_pll_div_clk_init, + .enable = tegra30_pll_div_clk_enable, + .disable = tegra30_pll_div_clk_disable, + .set_rate = tegra30_pll_div_clk_set_rate, + .round_rate = tegra30_pll_div_clk_round_rate, +}; + +/* Periph clk ops */ +static inline u32 periph_clk_source_mask(struct clk *c) +{ + if (c->flags & MUX8) + return 7 << 29; + else if (c->flags & MUX_PWM) + return 3 << 28; + else if (c->flags & MUX_CLK_OUT) + return 3 << (c->u.periph.clk_num + 4); + else if (c->flags & PLLD) + return PLLD_BASE_DSIB_MUX_MASK; + else + return 3 << 30; +} + +static inline u32 periph_clk_source_shift(struct clk *c) +{ + if (c->flags & MUX8) + return 29; + else if (c->flags & MUX_PWM) + return 28; + else if (c->flags & MUX_CLK_OUT) + return c->u.periph.clk_num + 4; + else if (c->flags & PLLD) + return PLLD_BASE_DSIB_MUX_SHIFT; + else + return 30; +} + +static void tegra30_periph_clk_init(struct clk *c) +{ + u32 val = clk_readl(c->reg); + const struct clk_mux_sel *mux = 0; + const struct clk_mux_sel *sel; + if (c->flags & MUX) { + for (sel = c->inputs; sel->input != NULL; sel++) { + if (((val & periph_clk_source_mask(c)) >> + periph_clk_source_shift(c)) == sel->value) + mux = sel; + } + BUG_ON(!mux); + + c->parent = mux->input; + } else { + c->parent = c->inputs[0].input; + } + + if (c->flags & DIV_U71) { + u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK; + if ((c->flags & DIV_U71_UART) && + (!(val & PERIPH_CLK_UART_DIV_ENB))) { + divu71 = 0; + } + if (c->flags & DIV_U71_IDLE) { + val &= ~(PERIPH_CLK_SOURCE_DIVU71_MASK << + PERIPH_CLK_SOURCE_DIVIDLE_SHIFT); + val |= (PERIPH_CLK_SOURCE_DIVIDLE_VAL << + PERIPH_CLK_SOURCE_DIVIDLE_SHIFT); + clk_writel(val, c->reg); + } + c->div = divu71 + 2; + c->mul = 2; + } else if (c->flags & DIV_U16) { + u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK; + c->div = divu16 + 1; + c->mul = 1; + } else { + c->div = 1; + c->mul = 1; + } + + c->state = ON; + if (!(clk_readl(PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_BIT(c))) + c->state = OFF; + if (!(c->flags & PERIPH_NO_RESET)) + if (clk_readl(PERIPH_CLK_TO_RST_REG(c)) & PERIPH_CLK_TO_BIT(c)) + c->state = OFF; +} + +static int tegra30_periph_clk_enable(struct clk *c) +{ + pr_debug("%s on clock %s\n", __func__, c->name); + + tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++; + if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 1) + return 0; + + clk_writel_delay(PERIPH_CLK_TO_BIT(c), PERIPH_CLK_TO_ENB_SET_REG(c)); + if (!(c->flags & PERIPH_NO_RESET) && + !(c->flags & PERIPH_MANUAL_RESET)) { + if (clk_readl(PERIPH_CLK_TO_RST_REG(c)) & + PERIPH_CLK_TO_BIT(c)) { + udelay(5); /* reset propagation delay */ + clk_writel(PERIPH_CLK_TO_BIT(c), + PERIPH_CLK_TO_RST_CLR_REG(c)); + } + } + return 0; +} + +static void tegra30_periph_clk_disable(struct clk *c) +{ + unsigned long val; + pr_debug("%s on clock %s\n", __func__, c->name); + + if (c->refcnt) + tegra_periph_clk_enable_refcount[c->u.periph.clk_num]--; + + if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] == 0) { + /* If peripheral is in the APB bus then read the APB bus to + * flush the write operation in apb bus. This will avoid the + * peripheral access after disabling clock*/ + if (c->flags & PERIPH_ON_APB) + val = chipid_readl(); + + clk_writel_delay( + PERIPH_CLK_TO_BIT(c), PERIPH_CLK_TO_ENB_CLR_REG(c)); + } +} + +static void tegra30_periph_clk_reset(struct clk *c, bool assert) +{ + unsigned long val; + pr_debug("%s %s on clock %s\n", __func__, + assert ? "assert" : "deassert", c->name); + + if (!(c->flags & PERIPH_NO_RESET)) { + if (assert) { + /* If peripheral is in the APB bus then read the APB + * bus to flush the write operation in apb bus. This + * will avoid the peripheral access after disabling + * clock */ + if (c->flags & PERIPH_ON_APB) + val = chipid_readl(); + + clk_writel(PERIPH_CLK_TO_BIT(c), + PERIPH_CLK_TO_RST_SET_REG(c)); + } else + clk_writel(PERIPH_CLK_TO_BIT(c), + PERIPH_CLK_TO_RST_CLR_REG(c)); + } +} + +static int tegra30_periph_clk_set_parent(struct clk *c, struct clk *p) +{ + u32 val; + const struct clk_mux_sel *sel; + pr_debug("%s: %s %s\n", __func__, c->name, p->name); + + if (!(c->flags & MUX)) + return (p == c->parent) ? 0 : (-EINVAL); + + for (sel = c->inputs; sel->input != NULL; sel++) { + if (sel->input == p) { + val = clk_readl(c->reg); + val &= ~periph_clk_source_mask(c); + val |= (sel->value << periph_clk_source_shift(c)); + + if (c->refcnt) + clk_enable(p); + + clk_writel_delay(val, c->reg); + + if (c->refcnt && c->parent) + clk_disable(c->parent); + + clk_reparent(c, p); + return 0; + } + } + + return -EINVAL; +} + +static int tegra30_periph_clk_set_rate(struct clk *c, unsigned long rate) +{ + u32 val; + int divider; + unsigned long parent_rate = clk_get_rate(c->parent); + + if (c->flags & DIV_U71) { + divider = clk_div71_get_divider( + parent_rate, rate, c->flags, ROUND_DIVIDER_UP); + if (divider >= 0) { + val = clk_readl(c->reg); + val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK; + val |= divider; + if (c->flags & DIV_U71_UART) { + if (divider) + val |= PERIPH_CLK_UART_DIV_ENB; + else + val &= ~PERIPH_CLK_UART_DIV_ENB; + } + clk_writel_delay(val, c->reg); + c->div = divider + 2; + c->mul = 2; + return 0; + } + } else if (c->flags & DIV_U16) { + divider = clk_div16_get_divider(parent_rate, rate); + if (divider >= 0) { + val = clk_readl(c->reg); + val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK; + val |= divider; + clk_writel_delay(val, c->reg); + c->div = divider + 1; + c->mul = 1; + return 0; + } + } else if (parent_rate <= rate) { + c->div = 1; + c->mul = 1; + return 0; + } + return -EINVAL; +} + +static long tegra30_periph_clk_round_rate(struct clk *c, + unsigned long rate) +{ + int divider; + unsigned long parent_rate = clk_get_rate(c->parent); + pr_debug("%s: %s %lu\n", __func__, c->name, rate); + + if (c->flags & DIV_U71) { + divider = clk_div71_get_divider( + parent_rate, rate, c->flags, ROUND_DIVIDER_UP); + if (divider < 0) + return divider; + + return DIV_ROUND_UP(parent_rate * 2, divider + 2); + } else if (c->flags & DIV_U16) { + divider = clk_div16_get_divider(parent_rate, rate); + if (divider < 0) + return divider; + return DIV_ROUND_UP(parent_rate, divider + 1); + } + return -EINVAL; +} + +static struct clk_ops tegra_periph_clk_ops = { + .init = &tegra30_periph_clk_init, + .enable = &tegra30_periph_clk_enable, + .disable = &tegra30_periph_clk_disable, + .set_parent = &tegra30_periph_clk_set_parent, + .set_rate = &tegra30_periph_clk_set_rate, + .round_rate = &tegra30_periph_clk_round_rate, + .reset = &tegra30_periph_clk_reset, +}; + + +/* Periph extended clock configuration ops */ +static int +tegra30_vi_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting) +{ + if (p == TEGRA_CLK_VI_INP_SEL) { + u32 val = clk_readl(c->reg); + val &= ~PERIPH_CLK_VI_SEL_EX_MASK; + val |= (setting << PERIPH_CLK_VI_SEL_EX_SHIFT) & + PERIPH_CLK_VI_SEL_EX_MASK; + clk_writel(val, c->reg); + return 0; + } + return -EINVAL; +} + +static struct clk_ops tegra_vi_clk_ops = { + .init = &tegra30_periph_clk_init, + .enable = &tegra30_periph_clk_enable, + .disable = &tegra30_periph_clk_disable, + .set_parent = &tegra30_periph_clk_set_parent, + .set_rate = &tegra30_periph_clk_set_rate, + .round_rate = &tegra30_periph_clk_round_rate, + .clk_cfg_ex = &tegra30_vi_clk_cfg_ex, + .reset = &tegra30_periph_clk_reset, +}; + +static int +tegra30_nand_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting) +{ + if (p == TEGRA_CLK_NAND_PAD_DIV2_ENB) { + u32 val = clk_readl(c->reg); + if (setting) + val |= PERIPH_CLK_NAND_DIV_EX_ENB; + else + val &= ~PERIPH_CLK_NAND_DIV_EX_ENB; + clk_writel(val, c->reg); + return 0; + } + return -EINVAL; +} + +static struct clk_ops tegra_nand_clk_ops = { + .init = &tegra30_periph_clk_init, + .enable = &tegra30_periph_clk_enable, + .disable = &tegra30_periph_clk_disable, + .set_parent = &tegra30_periph_clk_set_parent, + .set_rate = &tegra30_periph_clk_set_rate, + .round_rate = &tegra30_periph_clk_round_rate, + .clk_cfg_ex = &tegra30_nand_clk_cfg_ex, + .reset = &tegra30_periph_clk_reset, +}; + + +static int +tegra30_dtv_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting) +{ + if (p == TEGRA_CLK_DTV_INVERT) { + u32 val = clk_readl(c->reg); + if (setting) + val |= PERIPH_CLK_DTV_POLARITY_INV; + else + val &= ~PERIPH_CLK_DTV_POLARITY_INV; + clk_writel(val, c->reg); + return 0; + } + return -EINVAL; +} + +static struct clk_ops tegra_dtv_clk_ops = { + .init = &tegra30_periph_clk_init, + .enable = &tegra30_periph_clk_enable, + .disable = &tegra30_periph_clk_disable, + .set_parent = &tegra30_periph_clk_set_parent, + .set_rate = &tegra30_periph_clk_set_rate, + .round_rate = &tegra30_periph_clk_round_rate, + .clk_cfg_ex = &tegra30_dtv_clk_cfg_ex, + .reset = &tegra30_periph_clk_reset, +}; + +static int tegra30_dsib_clk_set_parent(struct clk *c, struct clk *p) +{ + const struct clk_mux_sel *sel; + struct clk *d = tegra_get_clock_by_name("pll_d"); + + pr_debug("%s: %s %s\n", __func__, c->name, p->name); + + for (sel = c->inputs; sel->input != NULL; sel++) { + if (sel->input == p) { + if (c->refcnt) + clk_enable(p); + + /* The DSIB parent selection bit is in PLLD base + register - can not do direct r-m-w, must be + protected by PLLD lock */ + tegra_clk_cfg_ex( + d, TEGRA_CLK_PLLD_MIPI_MUX_SEL, sel->value); + + if (c->refcnt && c->parent) + clk_disable(c->parent); + + clk_reparent(c, p); + return 0; + } + } + + return -EINVAL; +} + +static struct clk_ops tegra_dsib_clk_ops = { + .init = &tegra30_periph_clk_init, + .enable = &tegra30_periph_clk_enable, + .disable = &tegra30_periph_clk_disable, + .set_parent = &tegra30_dsib_clk_set_parent, + .set_rate = &tegra30_periph_clk_set_rate, + .round_rate = &tegra30_periph_clk_round_rate, + .reset = &tegra30_periph_clk_reset, +}; + +/* pciex clock support only reset function */ +static struct clk_ops tegra_pciex_clk_ops = { + .reset = tegra30_periph_clk_reset, +}; + +/* Output clock ops */ + +static DEFINE_SPINLOCK(clk_out_lock); + +static void tegra30_clk_out_init(struct clk *c) +{ + const struct clk_mux_sel *mux = 0; + const struct clk_mux_sel *sel; + u32 val = pmc_readl(c->reg); + + c->state = (val & (0x1 << c->u.periph.clk_num)) ? ON : OFF; + c->mul = 1; + c->div = 1; + + for (sel = c->inputs; sel->input != NULL; sel++) { + if (((val & periph_clk_source_mask(c)) >> + periph_clk_source_shift(c)) == sel->value) + mux = sel; + } + BUG_ON(!mux); + c->parent = mux->input; +} + +static int tegra30_clk_out_enable(struct clk *c) +{ + u32 val; + unsigned long flags; + + pr_debug("%s on clock %s\n", __func__, c->name); + + spin_lock_irqsave(&clk_out_lock, flags); + val = pmc_readl(c->reg); + val |= (0x1 << c->u.periph.clk_num); + pmc_writel(val, c->reg); + spin_unlock_irqrestore(&clk_out_lock, flags); + + return 0; +} + +static void tegra30_clk_out_disable(struct clk *c) +{ + u32 val; + unsigned long flags; + + pr_debug("%s on clock %s\n", __func__, c->name); + + spin_lock_irqsave(&clk_out_lock, flags); + val = pmc_readl(c->reg); + val &= ~(0x1 << c->u.periph.clk_num); + pmc_writel(val, c->reg); + spin_unlock_irqrestore(&clk_out_lock, flags); +} + +static int tegra30_clk_out_set_parent(struct clk *c, struct clk *p) +{ + u32 val; + unsigned long flags; + const struct clk_mux_sel *sel; + + pr_debug("%s: %s %s\n", __func__, c->name, p->name); + + for (sel = c->inputs; sel->input != NULL; sel++) { + if (sel->input == p) { + if (c->refcnt) + clk_enable(p); + + spin_lock_irqsave(&clk_out_lock, flags); + val = pmc_readl(c->reg); + val &= ~periph_clk_source_mask(c); + val |= (sel->value << periph_clk_source_shift(c)); + pmc_writel(val, c->reg); + spin_unlock_irqrestore(&clk_out_lock, flags); + + if (c->refcnt && c->parent) + clk_disable(c->parent); + + clk_reparent(c, p); + return 0; + } + } + return -EINVAL; +} + +static struct clk_ops tegra_clk_out_ops = { + .init = &tegra30_clk_out_init, + .enable = &tegra30_clk_out_enable, + .disable = &tegra30_clk_out_disable, + .set_parent = &tegra30_clk_out_set_parent, +}; + + +/* Clock doubler ops */ +static void tegra30_clk_double_init(struct clk *c) +{ + u32 val = clk_readl(c->reg); + c->mul = val & (0x1 << c->reg_shift) ? 1 : 2; + c->div = 1; + c->state = ON; + if (!(clk_readl(PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_BIT(c))) + c->state = OFF; +}; + +static int tegra30_clk_double_set_rate(struct clk *c, unsigned long rate) +{ + u32 val; + unsigned long parent_rate = clk_get_rate(c->parent); + if (rate == parent_rate) { + val = clk_readl(c->reg) | (0x1 << c->reg_shift); + clk_writel(val, c->reg); + c->mul = 1; + c->div = 1; + return 0; + } else if (rate == 2 * parent_rate) { + val = clk_readl(c->reg) & (~(0x1 << c->reg_shift)); + clk_writel(val, c->reg); + c->mul = 2; + c->div = 1; + return 0; + } + return -EINVAL; +} + +static struct clk_ops tegra_clk_double_ops = { + .init = &tegra30_clk_double_init, + .enable = &tegra30_periph_clk_enable, + .disable = &tegra30_periph_clk_disable, + .set_rate = &tegra30_clk_double_set_rate, +}; + +/* Audio sync clock ops */ +static int tegra30_sync_source_set_rate(struct clk *c, unsigned long rate) +{ + c->rate = rate; + return 0; +} + +static struct clk_ops tegra_sync_source_ops = { + .set_rate = &tegra30_sync_source_set_rate, +}; + +static void tegra30_audio_sync_clk_init(struct clk *c) +{ + int source; + const struct clk_mux_sel *sel; + u32 val = clk_readl(c->reg); + c->state = (val & AUDIO_SYNC_DISABLE_BIT) ? OFF : ON; + source = val & AUDIO_SYNC_SOURCE_MASK; + for (sel = c->inputs; sel->input != NULL; sel++) + if (sel->value == source) + break; + BUG_ON(sel->input == NULL); + c->parent = sel->input; +} + +static int tegra30_audio_sync_clk_enable(struct clk *c) +{ + u32 val = clk_readl(c->reg); + clk_writel((val & (~AUDIO_SYNC_DISABLE_BIT)), c->reg); + return 0; +} + +static void tegra30_audio_sync_clk_disable(struct clk *c) +{ + u32 val = clk_readl(c->reg); + clk_writel((val | AUDIO_SYNC_DISABLE_BIT), c->reg); +} + +static int tegra30_audio_sync_clk_set_parent(struct clk *c, struct clk *p) +{ + u32 val; + const struct clk_mux_sel *sel; + for (sel = c->inputs; sel->input != NULL; sel++) { + if (sel->input == p) { + val = clk_readl(c->reg); + val &= ~AUDIO_SYNC_SOURCE_MASK; + val |= sel->value; + + if (c->refcnt) + clk_enable(p); + + clk_writel(val, c->reg); + + if (c->refcnt && c->parent) + clk_disable(c->parent); + + clk_reparent(c, p); + return 0; + } + } + + return -EINVAL; +} + +static struct clk_ops tegra_audio_sync_clk_ops = { + .init = tegra30_audio_sync_clk_init, + .enable = tegra30_audio_sync_clk_enable, + .disable = tegra30_audio_sync_clk_disable, + .set_parent = tegra30_audio_sync_clk_set_parent, +}; + +/* cml0 (pcie), and cml1 (sata) clock ops */ +static void tegra30_cml_clk_init(struct clk *c) +{ + u32 val = clk_readl(c->reg); + c->state = val & (0x1 << c->u.periph.clk_num) ? ON : OFF; +} + +static int tegra30_cml_clk_enable(struct clk *c) +{ + u32 val = clk_readl(c->reg); + val |= (0x1 << c->u.periph.clk_num); + clk_writel(val, c->reg); + return 0; +} + +static void tegra30_cml_clk_disable(struct clk *c) +{ + u32 val = clk_readl(c->reg); + val &= ~(0x1 << c->u.periph.clk_num); + clk_writel(val, c->reg); +} + +static struct clk_ops tegra_cml_clk_ops = { + .init = &tegra30_cml_clk_init, + .enable = &tegra30_cml_clk_enable, + .disable = &tegra30_cml_clk_disable, +}; + +/* Clock definitions */ +static struct clk tegra_clk_32k = { + .name = "clk_32k", + .rate = 32768, + .ops = NULL, + .max_rate = 32768, +}; + +static struct clk tegra_clk_m = { + .name = "clk_m", + .flags = ENABLE_ON_INIT, + .ops = &tegra_clk_m_ops, + .reg = 0x1fc, + .reg_shift = 28, + .max_rate = 48000000, +}; + +static struct clk tegra_clk_m_div2 = { + .name = "clk_m_div2", + .ops = &tegra_clk_m_div_ops, + .parent = &tegra_clk_m, + .mul = 1, + .div = 2, + .state = ON, + .max_rate = 24000000, +}; + +static struct clk tegra_clk_m_div4 = { + .name = "clk_m_div4", + .ops = &tegra_clk_m_div_ops, + .parent = &tegra_clk_m, + .mul = 1, + .div = 4, + .state = ON, + .max_rate = 12000000, +}; + +static struct clk tegra_pll_ref = { + .name = "pll_ref", + .flags = ENABLE_ON_INIT, + .ops = &tegra_pll_ref_ops, + .parent = &tegra_clk_m, + .max_rate = 26000000, +}; + +static struct clk_pll_freq_table tegra_pll_c_freq_table[] = { + { 12000000, 1040000000, 520, 6, 1, 8}, + { 13000000, 1040000000, 480, 6, 1, 8}, + { 16800000, 1040000000, 495, 8, 1, 8}, /* actual: 1039.5 MHz */ + { 19200000, 1040000000, 325, 6, 1, 6}, + { 26000000, 1040000000, 520, 13, 1, 8}, + + { 12000000, 832000000, 416, 6, 1, 8}, + { 13000000, 832000000, 832, 13, 1, 8}, + { 16800000, 832000000, 396, 8, 1, 8}, /* actual: 831.6 MHz */ + { 19200000, 832000000, 260, 6, 1, 8}, + { 26000000, 832000000, 416, 13, 1, 8}, + + { 12000000, 624000000, 624, 12, 1, 8}, + { 13000000, 624000000, 624, 13, 1, 8}, + { 16800000, 600000000, 520, 14, 1, 8}, + { 19200000, 624000000, 520, 16, 1, 8}, + { 26000000, 624000000, 624, 26, 1, 8}, + + { 12000000, 600000000, 600, 12, 1, 8}, + { 13000000, 600000000, 600, 13, 1, 8}, + { 16800000, 600000000, 500, 14, 1, 8}, + { 19200000, 600000000, 375, 12, 1, 6}, + { 26000000, 600000000, 600, 26, 1, 8}, + + { 12000000, 520000000, 520, 12, 1, 8}, + { 13000000, 520000000, 520, 13, 1, 8}, + { 16800000, 520000000, 495, 16, 1, 8}, /* actual: 519.75 MHz */ + { 19200000, 520000000, 325, 12, 1, 6}, + { 26000000, 520000000, 520, 26, 1, 8}, + + { 12000000, 416000000, 416, 12, 1, 8}, + { 13000000, 416000000, 416, 13, 1, 8}, + { 16800000, 416000000, 396, 16, 1, 8}, /* actual: 415.8 MHz */ + { 19200000, 416000000, 260, 12, 1, 6}, + { 26000000, 416000000, 416, 26, 1, 8}, + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct clk tegra_pll_c = { + .name = "pll_c", + .flags = PLL_HAS_CPCON, + .ops = &tegra_pll_ops, + .reg = 0x80, + .parent = &tegra_pll_ref, + .max_rate = 1400000000, + .u.pll = { + .input_min = 2000000, + .input_max = 31000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 20000000, + .vco_max = 1400000000, + .freq_table = tegra_pll_c_freq_table, + .lock_delay = 300, + }, +}; + +static struct clk tegra_pll_c_out1 = { + .name = "pll_c_out1", + .ops = &tegra_pll_div_ops, + .flags = DIV_U71, + .parent = &tegra_pll_c, + .reg = 0x84, + .reg_shift = 0, + .max_rate = 700000000, +}; + +static struct clk_pll_freq_table tegra_pll_m_freq_table[] = { + { 12000000, 666000000, 666, 12, 1, 8}, + { 13000000, 666000000, 666, 13, 1, 8}, + { 16800000, 666000000, 555, 14, 1, 8}, + { 19200000, 666000000, 555, 16, 1, 8}, + { 26000000, 666000000, 666, 26, 1, 8}, + { 12000000, 600000000, 600, 12, 1, 8}, + { 13000000, 600000000, 600, 13, 1, 8}, + { 16800000, 600000000, 500, 14, 1, 8}, + { 19200000, 600000000, 375, 12, 1, 6}, + { 26000000, 600000000, 600, 26, 1, 8}, + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct clk tegra_pll_m = { + .name = "pll_m", + .flags = PLL_HAS_CPCON | PLLM, + .ops = &tegra_pll_ops, + .reg = 0x90, + .parent = &tegra_pll_ref, + .max_rate = 800000000, + .u.pll = { + .input_min = 2000000, + .input_max = 31000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 20000000, + .vco_max = 1200000000, + .freq_table = tegra_pll_m_freq_table, + .lock_delay = 300, + }, +}; + +static struct clk tegra_pll_m_out1 = { + .name = "pll_m_out1", + .ops = &tegra_pll_div_ops, + .flags = DIV_U71, + .parent = &tegra_pll_m, + .reg = 0x94, + .reg_shift = 0, + .max_rate = 600000000, +}; + +static struct clk_pll_freq_table tegra_pll_p_freq_table[] = { + { 12000000, 216000000, 432, 12, 2, 8}, + { 13000000, 216000000, 432, 13, 2, 8}, + { 16800000, 216000000, 360, 14, 2, 8}, + { 19200000, 216000000, 360, 16, 2, 8}, + { 26000000, 216000000, 432, 26, 2, 8}, + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct clk tegra_pll_p = { + .name = "pll_p", + .flags = ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON, + .ops = &tegra_pll_ops, + .reg = 0xa0, + .parent = &tegra_pll_ref, + .max_rate = 432000000, + .u.pll = { + .input_min = 2000000, + .input_max = 31000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 20000000, + .vco_max = 1400000000, + .freq_table = tegra_pll_p_freq_table, + .lock_delay = 300, + .fixed_rate = 408000000, + }, +}; + +static struct clk tegra_pll_p_out1 = { + .name = "pll_p_out1", + .ops = &tegra_pll_div_ops, + .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, + .parent = &tegra_pll_p, + .reg = 0xa4, + .reg_shift = 0, + .max_rate = 432000000, +}; + +static struct clk tegra_pll_p_out2 = { + .name = "pll_p_out2", + .ops = &tegra_pll_div_ops, + .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, + .parent = &tegra_pll_p, + .reg = 0xa4, + .reg_shift = 16, + .max_rate = 432000000, +}; + +static struct clk tegra_pll_p_out3 = { + .name = "pll_p_out3", + .ops = &tegra_pll_div_ops, + .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, + .parent = &tegra_pll_p, + .reg = 0xa8, + .reg_shift = 0, + .max_rate = 432000000, +}; + +static struct clk tegra_pll_p_out4 = { + .name = "pll_p_out4", + .ops = &tegra_pll_div_ops, + .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED, + .parent = &tegra_pll_p, + .reg = 0xa8, + .reg_shift = 16, + .max_rate = 432000000, +}; + +static struct clk_pll_freq_table tegra_pll_a_freq_table[] = { + { 9600000, 564480000, 294, 5, 1, 4}, + { 9600000, 552960000, 288, 5, 1, 4}, + { 9600000, 24000000, 5, 2, 1, 1}, + + { 28800000, 56448000, 49, 25, 1, 1}, + { 28800000, 73728000, 64, 25, 1, 1}, + { 28800000, 24000000, 5, 6, 1, 1}, + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct clk tegra_pll_a = { + .name = "pll_a", + .flags = PLL_HAS_CPCON, + .ops = &tegra_pll_ops, + .reg = 0xb0, + .parent = &tegra_pll_p_out1, + .max_rate = 700000000, + .u.pll = { + .input_min = 2000000, + .input_max = 31000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 20000000, + .vco_max = 1400000000, + .freq_table = tegra_pll_a_freq_table, + .lock_delay = 300, + }, +}; + +static struct clk tegra_pll_a_out0 = { + .name = "pll_a_out0", + .ops = &tegra_pll_div_ops, + .flags = DIV_U71, + .parent = &tegra_pll_a, + .reg = 0xb4, + .reg_shift = 0, + .max_rate = 100000000, +}; + +static struct clk_pll_freq_table tegra_pll_d_freq_table[] = { + { 12000000, 216000000, 216, 12, 1, 4}, + { 13000000, 216000000, 216, 13, 1, 4}, + { 16800000, 216000000, 180, 14, 1, 4}, + { 19200000, 216000000, 180, 16, 1, 4}, + { 26000000, 216000000, 216, 26, 1, 4}, + + { 12000000, 594000000, 594, 12, 1, 8}, + { 13000000, 594000000, 594, 13, 1, 8}, + { 16800000, 594000000, 495, 14, 1, 8}, + { 19200000, 594000000, 495, 16, 1, 8}, + { 26000000, 594000000, 594, 26, 1, 8}, + + { 12000000, 1000000000, 1000, 12, 1, 12}, + { 13000000, 1000000000, 1000, 13, 1, 12}, + { 19200000, 1000000000, 625, 12, 1, 8}, + { 26000000, 1000000000, 1000, 26, 1, 12}, + + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct clk tegra_pll_d = { + .name = "pll_d", + .flags = PLL_HAS_CPCON | PLLD, + .ops = &tegra_plld_ops, + .reg = 0xd0, + .parent = &tegra_pll_ref, + .max_rate = 1000000000, + .u.pll = { + .input_min = 2000000, + .input_max = 40000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 40000000, + .vco_max = 1000000000, + .freq_table = tegra_pll_d_freq_table, + .lock_delay = 1000, + }, +}; + +static struct clk tegra_pll_d_out0 = { + .name = "pll_d_out0", + .ops = &tegra_pll_div_ops, + .flags = DIV_2 | PLLD, + .parent = &tegra_pll_d, + .max_rate = 500000000, +}; + +static struct clk tegra_pll_d2 = { + .name = "pll_d2", + .flags = PLL_HAS_CPCON | PLL_ALT_MISC_REG | PLLD, + .ops = &tegra_plld_ops, + .reg = 0x4b8, + .parent = &tegra_pll_ref, + .max_rate = 1000000000, + .u.pll = { + .input_min = 2000000, + .input_max = 40000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 40000000, + .vco_max = 1000000000, + .freq_table = tegra_pll_d_freq_table, + .lock_delay = 1000, + }, +}; + +static struct clk tegra_pll_d2_out0 = { + .name = "pll_d2_out0", + .ops = &tegra_pll_div_ops, + .flags = DIV_2 | PLLD, + .parent = &tegra_pll_d2, + .max_rate = 500000000, +}; + +static struct clk_pll_freq_table tegra_pll_u_freq_table[] = { + { 12000000, 480000000, 960, 12, 2, 12}, + { 13000000, 480000000, 960, 13, 2, 12}, + { 16800000, 480000000, 400, 7, 2, 5}, + { 19200000, 480000000, 200, 4, 2, 3}, + { 26000000, 480000000, 960, 26, 2, 12}, + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct clk tegra_pll_u = { + .name = "pll_u", + .flags = PLL_HAS_CPCON | PLLU, + .ops = &tegra_pll_ops, + .reg = 0xc0, + .parent = &tegra_pll_ref, + .max_rate = 480000000, + .u.pll = { + .input_min = 2000000, + .input_max = 40000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 480000000, + .vco_max = 960000000, + .freq_table = tegra_pll_u_freq_table, + .lock_delay = 1000, + }, +}; + +static struct clk_pll_freq_table tegra_pll_x_freq_table[] = { + /* 1.7 GHz */ + { 12000000, 1700000000, 850, 6, 1, 8}, + { 13000000, 1700000000, 915, 7, 1, 8}, /* actual: 1699.2 MHz */ + { 16800000, 1700000000, 708, 7, 1, 8}, /* actual: 1699.2 MHz */ + { 19200000, 1700000000, 885, 10, 1, 8}, /* actual: 1699.2 MHz */ + { 26000000, 1700000000, 850, 13, 1, 8}, + + /* 1.6 GHz */ + { 12000000, 1600000000, 800, 6, 1, 8}, + { 13000000, 1600000000, 738, 6, 1, 8}, /* actual: 1599.0 MHz */ + { 16800000, 1600000000, 857, 9, 1, 8}, /* actual: 1599.7 MHz */ + { 19200000, 1600000000, 500, 6, 1, 8}, + { 26000000, 1600000000, 800, 13, 1, 8}, + + /* 1.5 GHz */ + { 12000000, 1500000000, 750, 6, 1, 8}, + { 13000000, 1500000000, 923, 8, 1, 8}, /* actual: 1499.8 MHz */ + { 16800000, 1500000000, 625, 7, 1, 8}, + { 19200000, 1500000000, 625, 8, 1, 8}, + { 26000000, 1500000000, 750, 13, 1, 8}, + + /* 1.4 GHz */ + { 12000000, 1400000000, 700, 6, 1, 8}, + { 13000000, 1400000000, 969, 9, 1, 8}, /* actual: 1399.7 MHz */ + { 16800000, 1400000000, 1000, 12, 1, 8}, + { 19200000, 1400000000, 875, 12, 1, 8}, + { 26000000, 1400000000, 700, 13, 1, 8}, + + /* 1.3 GHz */ + { 12000000, 1300000000, 975, 9, 1, 8}, + { 13000000, 1300000000, 1000, 10, 1, 8}, + { 16800000, 1300000000, 928, 12, 1, 8}, /* actual: 1299.2 MHz */ + { 19200000, 1300000000, 812, 12, 1, 8}, /* actual: 1299.2 MHz */ + { 26000000, 1300000000, 650, 13, 1, 8}, + + /* 1.2 GHz */ + { 12000000, 1200000000, 1000, 10, 1, 8}, + { 13000000, 1200000000, 923, 10, 1, 8}, /* actual: 1199.9 MHz */ + { 16800000, 1200000000, 1000, 14, 1, 8}, + { 19200000, 1200000000, 1000, 16, 1, 8}, + { 26000000, 1200000000, 600, 13, 1, 8}, + + /* 1.1 GHz */ + { 12000000, 1100000000, 825, 9, 1, 8}, + { 13000000, 1100000000, 846, 10, 1, 8}, /* actual: 1099.8 MHz */ + { 16800000, 1100000000, 982, 15, 1, 8}, /* actual: 1099.8 MHz */ + { 19200000, 1100000000, 859, 15, 1, 8}, /* actual: 1099.5 MHz */ + { 26000000, 1100000000, 550, 13, 1, 8}, + + /* 1 GHz */ + { 12000000, 1000000000, 1000, 12, 1, 8}, + { 13000000, 1000000000, 1000, 13, 1, 8}, + { 16800000, 1000000000, 833, 14, 1, 8}, /* actual: 999.6 MHz */ + { 19200000, 1000000000, 625, 12, 1, 8}, + { 26000000, 1000000000, 1000, 26, 1, 8}, + + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct clk tegra_pll_x = { + .name = "pll_x", + .flags = PLL_HAS_CPCON | PLL_ALT_MISC_REG | PLLX, + .ops = &tegra_pll_ops, + .reg = 0xe0, + .parent = &tegra_pll_ref, + .max_rate = 1700000000, + .u.pll = { + .input_min = 2000000, + .input_max = 31000000, + .cf_min = 1000000, + .cf_max = 6000000, + .vco_min = 20000000, + .vco_max = 1700000000, + .freq_table = tegra_pll_x_freq_table, + .lock_delay = 300, + }, +}; + +static struct clk tegra_pll_x_out0 = { + .name = "pll_x_out0", + .ops = &tegra_pll_div_ops, + .flags = DIV_2 | PLLX, + .parent = &tegra_pll_x, + .max_rate = 850000000, +}; + + +static struct clk_pll_freq_table tegra_pll_e_freq_table[] = { + /* PLLE special case: use cpcon field to store cml divider value */ + { 12000000, 100000000, 150, 1, 18, 11}, + { 216000000, 100000000, 200, 18, 24, 13}, + { 0, 0, 0, 0, 0, 0 }, +}; + +static struct clk tegra_pll_e = { + .name = "pll_e", + .flags = PLL_ALT_MISC_REG, + .ops = &tegra_plle_ops, + .reg = 0xe8, + .max_rate = 100000000, + .u.pll = { + .input_min = 12000000, + .input_max = 216000000, + .cf_min = 12000000, + .cf_max = 12000000, + .vco_min = 1200000000, + .vco_max = 2400000000U, + .freq_table = tegra_pll_e_freq_table, + .lock_delay = 300, + .fixed_rate = 100000000, + }, +}; + +static struct clk tegra_cml0_clk = { + .name = "cml0", + .parent = &tegra_pll_e, + .ops = &tegra_cml_clk_ops, + .reg = PLLE_AUX, + .max_rate = 100000000, + .u.periph = { + .clk_num = 0, + }, +}; + +static struct clk tegra_cml1_clk = { + .name = "cml1", + .parent = &tegra_pll_e, + .ops = &tegra_cml_clk_ops, + .reg = PLLE_AUX, + .max_rate = 100000000, + .u.periph = { + .clk_num = 1, + }, +}; + +static struct clk tegra_pciex_clk = { + .name = "pciex", + .parent = &tegra_pll_e, + .ops = &tegra_pciex_clk_ops, + .max_rate = 100000000, + .u.periph = { + .clk_num = 74, + }, +}; + +/* Audio sync clocks */ +#define SYNC_SOURCE(_id) \ + { \ + .name = #_id "_sync", \ + .rate = 24000000, \ + .max_rate = 24000000, \ + .ops = &tegra_sync_source_ops \ + } +static struct clk tegra_sync_source_list[] = { + SYNC_SOURCE(spdif_in), + SYNC_SOURCE(i2s0), + SYNC_SOURCE(i2s1), + SYNC_SOURCE(i2s2), + SYNC_SOURCE(i2s3), + SYNC_SOURCE(i2s4), + SYNC_SOURCE(vimclk), +}; + +static struct clk_mux_sel mux_audio_sync_clk[] = { + { .input = &tegra_sync_source_list[0], .value = 0}, + { .input = &tegra_sync_source_list[1], .value = 1}, + { .input = &tegra_sync_source_list[2], .value = 2}, + { .input = &tegra_sync_source_list[3], .value = 3}, + { .input = &tegra_sync_source_list[4], .value = 4}, + { .input = &tegra_sync_source_list[5], .value = 5}, + { .input = &tegra_pll_a_out0, .value = 6}, + { .input = &tegra_sync_source_list[6], .value = 7}, + { 0, 0 } +}; + +#define AUDIO_SYNC_CLK(_id, _index) \ + { \ + .name = #_id, \ + .inputs = mux_audio_sync_clk, \ + .reg = 0x4A0 + (_index) * 4, \ + .max_rate = 24000000, \ + .ops = &tegra_audio_sync_clk_ops \ + } +static struct clk tegra_clk_audio_list[] = { + AUDIO_SYNC_CLK(audio0, 0), + AUDIO_SYNC_CLK(audio1, 1), + AUDIO_SYNC_CLK(audio2, 2), + AUDIO_SYNC_CLK(audio3, 3), + AUDIO_SYNC_CLK(audio4, 4), + AUDIO_SYNC_CLK(audio, 5), /* SPDIF */ +}; + +#define AUDIO_SYNC_2X_CLK(_id, _index) \ + { \ + .name = #_id "_2x", \ + .flags = PERIPH_NO_RESET, \ + .max_rate = 48000000, \ + .ops = &tegra_clk_double_ops, \ + .reg = 0x49C, \ + .reg_shift = 24 + (_index), \ + .parent = &tegra_clk_audio_list[(_index)], \ + .u.periph = { \ + .clk_num = 113 + (_index), \ + }, \ + } +static struct clk tegra_clk_audio_2x_list[] = { + AUDIO_SYNC_2X_CLK(audio0, 0), + AUDIO_SYNC_2X_CLK(audio1, 1), + AUDIO_SYNC_2X_CLK(audio2, 2), + AUDIO_SYNC_2X_CLK(audio3, 3), + AUDIO_SYNC_2X_CLK(audio4, 4), + AUDIO_SYNC_2X_CLK(audio, 5), /* SPDIF */ +}; + +#define MUX_I2S_SPDIF(_id, _index) \ +static struct clk_mux_sel mux_pllaout0_##_id##_2x_pllp_clkm[] = { \ + {.input = &tegra_pll_a_out0, .value = 0}, \ + {.input = &tegra_clk_audio_2x_list[(_index)], .value = 1}, \ + {.input = &tegra_pll_p, .value = 2}, \ + {.input = &tegra_clk_m, .value = 3}, \ + { 0, 0}, \ +} +MUX_I2S_SPDIF(audio0, 0); +MUX_I2S_SPDIF(audio1, 1); +MUX_I2S_SPDIF(audio2, 2); +MUX_I2S_SPDIF(audio3, 3); +MUX_I2S_SPDIF(audio4, 4); +MUX_I2S_SPDIF(audio, 5); /* SPDIF */ + +/* External clock outputs (through PMC) */ +#define MUX_EXTERN_OUT(_id) \ +static struct clk_mux_sel mux_clkm_clkm2_clkm4_extern##_id[] = { \ + {.input = &tegra_clk_m, .value = 0}, \ + {.input = &tegra_clk_m_div2, .value = 1}, \ + {.input = &tegra_clk_m_div4, .value = 2}, \ + {.input = NULL, .value = 3}, /* placeholder */ \ + { 0, 0}, \ +} +MUX_EXTERN_OUT(1); +MUX_EXTERN_OUT(2); +MUX_EXTERN_OUT(3); + +static struct clk_mux_sel *mux_extern_out_list[] = { + mux_clkm_clkm2_clkm4_extern1, + mux_clkm_clkm2_clkm4_extern2, + mux_clkm_clkm2_clkm4_extern3, +}; + +#define CLK_OUT_CLK(_id) \ + { \ + .name = "clk_out_" #_id, \ + .lookup = { \ + .dev_id = "clk_out_" #_id, \ + .con_id = "extern" #_id, \ + }, \ + .ops = &tegra_clk_out_ops, \ + .reg = 0x1a8, \ + .inputs = mux_clkm_clkm2_clkm4_extern##_id, \ + .flags = MUX_CLK_OUT, \ + .max_rate = 216000000, \ + .u.periph = { \ + .clk_num = (_id - 1) * 8 + 2, \ + }, \ + } +static struct clk tegra_clk_out_list[] = { + CLK_OUT_CLK(1), + CLK_OUT_CLK(2), + CLK_OUT_CLK(3), +}; + +/* called after peripheral external clocks are initialized */ +static void init_clk_out_mux(void) +{ + int i; + struct clk *c; + + /* output clock con_id is the name of peripheral + external clock connected to input 3 of the output mux */ + for (i = 0; i < ARRAY_SIZE(tegra_clk_out_list); i++) { + c = tegra_get_clock_by_name( + tegra_clk_out_list[i].lookup.con_id); + if (!c) + pr_err("%s: could not find clk %s\n", __func__, + tegra_clk_out_list[i].lookup.con_id); + mux_extern_out_list[i][3].input = c; + } +} + +/* Peripheral muxes */ +static struct clk_mux_sel mux_sclk[] = { + { .input = &tegra_clk_m, .value = 0}, + { .input = &tegra_pll_c_out1, .value = 1}, + { .input = &tegra_pll_p_out4, .value = 2}, + { .input = &tegra_pll_p_out3, .value = 3}, + { .input = &tegra_pll_p_out2, .value = 4}, + /* { .input = &tegra_clk_d, .value = 5}, - no use on tegra30 */ + { .input = &tegra_clk_32k, .value = 6}, + { .input = &tegra_pll_m_out1, .value = 7}, + { 0, 0}, +}; + +static struct clk tegra_clk_sclk = { + .name = "sclk", + .inputs = mux_sclk, + .reg = 0x28, + .ops = &tegra_super_ops, + .max_rate = 334000000, + .min_rate = 40000000, +}; + +static struct clk tegra_clk_blink = { + .name = "blink", + .parent = &tegra_clk_32k, + .reg = 0x40, + .ops = &tegra_blink_clk_ops, + .max_rate = 32768, +}; + +static struct clk_mux_sel mux_pllm_pllc_pllp_plla[] = { + { .input = &tegra_pll_m, .value = 0}, + { .input = &tegra_pll_c, .value = 1}, + { .input = &tegra_pll_p, .value = 2}, + { .input = &tegra_pll_a_out0, .value = 3}, + { 0, 0}, +}; + +static struct clk_mux_sel mux_pllp_pllc_pllm_clkm[] = { + { .input = &tegra_pll_p, .value = 0}, + { .input = &tegra_pll_c, .value = 1}, + { .input = &tegra_pll_m, .value = 2}, + { .input = &tegra_clk_m, .value = 3}, + { 0, 0}, +}; + +static struct clk_mux_sel mux_pllp_clkm[] = { + { .input = &tegra_pll_p, .value = 0}, + { .input = &tegra_clk_m, .value = 3}, + { 0, 0}, +}; + +static struct clk_mux_sel mux_pllp_plld_pllc_clkm[] = { + {.input = &tegra_pll_p, .value = 0}, + {.input = &tegra_pll_d_out0, .value = 1}, + {.input = &tegra_pll_c, .value = 2}, + {.input = &tegra_clk_m, .value = 3}, + { 0, 0}, +}; + +static struct clk_mux_sel mux_pllp_pllm_plld_plla_pllc_plld2_clkm[] = { + {.input = &tegra_pll_p, .value = 0}, + {.input = &tegra_pll_m, .value = 1}, + {.input = &tegra_pll_d_out0, .value = 2}, + {.input = &tegra_pll_a_out0, .value = 3}, + {.input = &tegra_pll_c, .value = 4}, + {.input = &tegra_pll_d2_out0, .value = 5}, + {.input = &tegra_clk_m, .value = 6}, + { 0, 0}, +}; + +static struct clk_mux_sel mux_plla_pllc_pllp_clkm[] = { + { .input = &tegra_pll_a_out0, .value = 0}, + /* { .input = &tegra_pll_c, .value = 1}, no use on tegra30 */ + { .input = &tegra_pll_p, .value = 2}, + { .input = &tegra_clk_m, .value = 3}, + { 0, 0}, +}; + +static struct clk_mux_sel mux_pllp_pllc_clk32_clkm[] = { + {.input = &tegra_pll_p, .value = 0}, + {.input = &tegra_pll_c, .value = 1}, + {.input = &tegra_clk_32k, .value = 2}, + {.input = &tegra_clk_m, .value = 3}, + { 0, 0}, +}; + +static struct clk_mux_sel mux_pllp_pllc_clkm_clk32[] = { + {.input = &tegra_pll_p, .value = 0}, + {.input = &tegra_pll_c, .value = 1}, + {.input = &tegra_clk_m, .value = 2}, + {.input = &tegra_clk_32k, .value = 3}, + { 0, 0}, +}; + +static struct clk_mux_sel mux_pllp_pllc_pllm[] = { + {.input = &tegra_pll_p, .value = 0}, + {.input = &tegra_pll_c, .value = 1}, + {.input = &tegra_pll_m, .value = 2}, + { 0, 0}, +}; + +static struct clk_mux_sel mux_clk_m[] = { + { .input = &tegra_clk_m, .value = 0}, + { 0, 0}, +}; + +static struct clk_mux_sel mux_pllp_out3[] = { + { .input = &tegra_pll_p_out3, .value = 0}, + { 0, 0}, +}; + +static struct clk_mux_sel mux_plld_out0[] = { + { .input = &tegra_pll_d_out0, .value = 0}, + { 0, 0}, +}; + +static struct clk_mux_sel mux_plld_out0_plld2_out0[] = { + { .input = &tegra_pll_d_out0, .value = 0}, + { .input = &tegra_pll_d2_out0, .value = 1}, + { 0, 0}, +}; + +static struct clk_mux_sel mux_clk_32k[] = { + { .input = &tegra_clk_32k, .value = 0}, + { 0, 0}, +}; + +static struct clk_mux_sel mux_plla_clk32_pllp_clkm_plle[] = { + { .input = &tegra_pll_a_out0, .value = 0}, + { .input = &tegra_clk_32k, .value = 1}, + { .input = &tegra_pll_p, .value = 2}, + { .input = &tegra_clk_m, .value = 3}, + { .input = &tegra_pll_e, .value = 4}, + { 0, 0}, +}; + +static struct clk_mux_sel mux_cclk_g[] = { + { .input = &tegra_clk_m, .value = 0}, + { .input = &tegra_pll_c, .value = 1}, + { .input = &tegra_clk_32k, .value = 2}, + { .input = &tegra_pll_m, .value = 3}, + { .input = &tegra_pll_p, .value = 4}, + { .input = &tegra_pll_p_out4, .value = 5}, + { .input = &tegra_pll_p_out3, .value = 6}, + { .input = &tegra_pll_x, .value = 8}, + { 0, 0}, +}; + +static struct clk tegra_clk_cclk_g = { + .name = "cclk_g", + .flags = DIV_U71 | DIV_U71_INT, + .inputs = mux_cclk_g, + .reg = 0x368, + .ops = &tegra_super_ops, + .max_rate = 1700000000, +}; + +static struct clk tegra30_clk_twd = { + .parent = &tegra_clk_cclk_g, + .name = "twd", + .ops = &tegra30_twd_ops, + .max_rate = 1400000000, /* Same as tegra_clk_cpu_cmplx.max_rate */ + .mul = 1, + .div = 2, +}; + +#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _max, _inputs, _flags) \ + { \ + .name = _name, \ + .lookup = { \ + .dev_id = _dev, \ + .con_id = _con, \ + }, \ + .ops = &tegra_periph_clk_ops, \ + .reg = _reg, \ + .inputs = _inputs, \ + .flags = _flags, \ + .max_rate = _max, \ + .u.periph = { \ + .clk_num = _clk_num, \ + }, \ + } + +#define PERIPH_CLK_EX(_name, _dev, _con, _clk_num, _reg, _max, _inputs, \ + _flags, _ops) \ + { \ + .name = _name, \ + .lookup = { \ + .dev_id = _dev, \ + .con_id = _con, \ + }, \ + .ops = _ops, \ + .reg = _reg, \ + .inputs = _inputs, \ + .flags = _flags, \ + .max_rate = _max, \ + .u.periph = { \ + .clk_num = _clk_num, \ + }, \ + } + +#define SHARED_CLK(_name, _dev, _con, _parent, _id, _div, _mode)\ + { \ + .name = _name, \ + .lookup = { \ + .dev_id = _dev, \ + .con_id = _con, \ + }, \ + .ops = &tegra_clk_shared_bus_ops, \ + .parent = _parent, \ + .u.shared_bus_user = { \ + .client_id = _id, \ + .client_div = _div, \ + .mode = _mode, \ + }, \ + } +struct clk tegra_list_clks[] = { + PERIPH_CLK("apbdma", "tegra-dma", NULL, 34, 0, 26000000, mux_clk_m, 0), + PERIPH_CLK("rtc", "rtc-tegra", NULL, 4, 0, 32768, mux_clk_32k, PERIPH_NO_RESET | PERIPH_ON_APB), + PERIPH_CLK("kbc", "tegra-kbc", NULL, 36, 0, 32768, mux_clk_32k, PERIPH_NO_RESET | PERIPH_ON_APB), + PERIPH_CLK("timer", "timer", NULL, 5, 0, 26000000, mux_clk_m, 0), + PERIPH_CLK("kfuse", "kfuse-tegra", NULL, 40, 0, 26000000, mux_clk_m, 0), + PERIPH_CLK("fuse", "fuse-tegra", "fuse", 39, 0, 26000000, mux_clk_m, PERIPH_ON_APB), + PERIPH_CLK("fuse_burn", "fuse-tegra", "fuse_burn", 39, 0, 26000000, mux_clk_m, PERIPH_ON_APB), + PERIPH_CLK("apbif", "tegra30-ahub", "apbif", 107, 0, 26000000, mux_clk_m, 0), + PERIPH_CLK("i2s0", "tegra30-i2s.0", NULL, 30, 0x1d8, 26000000, mux_pllaout0_audio0_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB), + PERIPH_CLK("i2s1", "tegra30-i2s.1", NULL, 11, 0x100, 26000000, mux_pllaout0_audio1_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB), + PERIPH_CLK("i2s2", "tegra30-i2s.2", NULL, 18, 0x104, 26000000, mux_pllaout0_audio2_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB), + PERIPH_CLK("i2s3", "tegra30-i2s.3", NULL, 101, 0x3bc, 26000000, mux_pllaout0_audio3_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB), + PERIPH_CLK("i2s4", "tegra30-i2s.4", NULL, 102, 0x3c0, 26000000, mux_pllaout0_audio4_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB), + PERIPH_CLK("spdif_out", "tegra30-spdif", "spdif_out", 10, 0x108, 100000000, mux_pllaout0_audio_2x_pllp_clkm, MUX | DIV_U71 | PERIPH_ON_APB), + PERIPH_CLK("spdif_in", "tegra30-spdif", "spdif_in", 10, 0x10c, 100000000, mux_pllp_pllc_pllm, MUX | DIV_U71 | PERIPH_ON_APB), + PERIPH_CLK("pwm", "pwm", NULL, 17, 0x110, 432000000, mux_pllp_pllc_clk32_clkm, MUX | MUX_PWM | DIV_U71 | PERIPH_ON_APB), + PERIPH_CLK("d_audio", "tegra30-ahub", "d_audio", 106, 0x3d0, 48000000, mux_plla_pllc_pllp_clkm, MUX | DIV_U71), + PERIPH_CLK("dam0", "tegra30-dam.0", NULL, 108, 0x3d8, 48000000, mux_plla_pllc_pllp_clkm, MUX | DIV_U71), + PERIPH_CLK("dam1", "tegra30-dam.1", NULL, 109, 0x3dc, 48000000, mux_plla_pllc_pllp_clkm, MUX | DIV_U71), + PERIPH_CLK("dam2", "tegra30-dam.2", NULL, 110, 0x3e0, 48000000, mux_plla_pllc_pllp_clkm, MUX | DIV_U71), + PERIPH_CLK("hda", "tegra30-hda", "hda", 125, 0x428, 108000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("hda2codec_2x", "tegra30-hda", "hda2codec", 111, 0x3e4, 48000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("hda2hdmi", "tegra30-hda", "hda2hdmi", 128, 0, 48000000, mux_clk_m, 0), + PERIPH_CLK("sbc1", "spi_tegra.0", NULL, 41, 0x134, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB), + PERIPH_CLK("sbc2", "spi_tegra.1", NULL, 44, 0x118, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB), + PERIPH_CLK("sbc3", "spi_tegra.2", NULL, 46, 0x11c, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB), + PERIPH_CLK("sbc4", "spi_tegra.3", NULL, 68, 0x1b4, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB), + PERIPH_CLK("sbc5", "spi_tegra.4", NULL, 104, 0x3c8, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB), + PERIPH_CLK("sbc6", "spi_tegra.5", NULL, 105, 0x3cc, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB), + PERIPH_CLK("sata_oob", "tegra_sata_oob", NULL, 123, 0x420, 216000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("sata", "tegra_sata", NULL, 124, 0x424, 216000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("sata_cold", "tegra_sata_cold", NULL, 129, 0, 48000000, mux_clk_m, 0), + PERIPH_CLK_EX("ndflash", "tegra_nand", NULL, 13, 0x160, 240000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71, &tegra_nand_clk_ops), + PERIPH_CLK("ndspeed", "tegra_nand_speed", NULL, 80, 0x3f8, 240000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("vfir", "vfir", NULL, 7, 0x168, 72000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB), + PERIPH_CLK("sdmmc1", "sdhci-tegra.0", NULL, 14, 0x150, 208000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */ + PERIPH_CLK("sdmmc2", "sdhci-tegra.1", NULL, 9, 0x154, 104000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */ + PERIPH_CLK("sdmmc3", "sdhci-tegra.2", NULL, 69, 0x1bc, 208000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */ + PERIPH_CLK("sdmmc4", "sdhci-tegra.3", NULL, 15, 0x164, 104000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */ + PERIPH_CLK("vcp", "tegra-avp", "vcp", 29, 0, 250000000, mux_clk_m, 0), + PERIPH_CLK("bsea", "tegra-avp", "bsea", 62, 0, 250000000, mux_clk_m, 0), + PERIPH_CLK("bsev", "tegra-aes", "bsev", 63, 0, 250000000, mux_clk_m, 0), + PERIPH_CLK("vde", "vde", NULL, 61, 0x1c8, 520000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_INT), + PERIPH_CLK("csite", "csite", NULL, 73, 0x1d4, 144000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* max rate ??? */ + PERIPH_CLK("la", "la", NULL, 76, 0x1f8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), + PERIPH_CLK("owr", "tegra_w1", NULL, 71, 0x1cc, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB), + PERIPH_CLK("nor", "nor", NULL, 42, 0x1d0, 127000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* requires min voltage */ + PERIPH_CLK("mipi", "mipi", NULL, 50, 0x174, 60000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB), /* scales with voltage */ + PERIPH_CLK("i2c1", "tegra-i2c.0", NULL, 12, 0x124, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB), + PERIPH_CLK("i2c2", "tegra-i2c.1", NULL, 54, 0x198, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB), + PERIPH_CLK("i2c3", "tegra-i2c.2", NULL, 67, 0x1b8, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB), + PERIPH_CLK("i2c4", "tegra-i2c.3", NULL, 103, 0x3c4, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB), + PERIPH_CLK("i2c5", "tegra-i2c.4", NULL, 47, 0x128, 26000000, mux_pllp_clkm, MUX | DIV_U16 | PERIPH_ON_APB), + PERIPH_CLK("uarta", "tegra_uart.0", NULL, 6, 0x178, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), + PERIPH_CLK("uartb", "tegra_uart.1", NULL, 7, 0x17c, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), + PERIPH_CLK("uartc", "tegra_uart.2", NULL, 55, 0x1a0, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), + PERIPH_CLK("uartd", "tegra_uart.3", NULL, 65, 0x1c0, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), + PERIPH_CLK("uarte", "tegra_uart.4", NULL, 66, 0x1c4, 800000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), + PERIPH_CLK("uarta_dbg", "serial8250.0", "uarta", 6, 0x178, 800000000, mux_pllp_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), + PERIPH_CLK("uartb_dbg", "serial8250.0", "uartb", 7, 0x17c, 800000000, mux_pllp_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), + PERIPH_CLK("uartc_dbg", "serial8250.0", "uartc", 55, 0x1a0, 800000000, mux_pllp_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), + PERIPH_CLK("uartd_dbg", "serial8250.0", "uartd", 65, 0x1c0, 800000000, mux_pllp_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), + PERIPH_CLK("uarte_dbg", "serial8250.0", "uarte", 66, 0x1c4, 800000000, mux_pllp_clkm, MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB), + PERIPH_CLK_EX("vi", "tegra_camera", "vi", 20, 0x148, 425000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT, &tegra_vi_clk_ops), + PERIPH_CLK("3d", "3d", NULL, 24, 0x158, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE | PERIPH_MANUAL_RESET), + PERIPH_CLK("3d2", "3d2", NULL, 98, 0x3b0, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE | PERIPH_MANUAL_RESET), + PERIPH_CLK("2d", "2d", NULL, 21, 0x15c, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE), + PERIPH_CLK("vi_sensor", "tegra_camera", "vi_sensor", 20, 0x1a8, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_NO_RESET), + PERIPH_CLK("epp", "epp", NULL, 19, 0x16c, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT), + PERIPH_CLK("mpe", "mpe", NULL, 60, 0x170, 520000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT), + PERIPH_CLK("host1x", "host1x", NULL, 28, 0x180, 260000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | DIV_U71_INT), + PERIPH_CLK("cve", "cve", NULL, 49, 0x140, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */ + PERIPH_CLK("tvo", "tvo", NULL, 49, 0x188, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */ + PERIPH_CLK_EX("dtv", "dtv", NULL, 79, 0x1dc, 250000000, mux_clk_m, 0, &tegra_dtv_clk_ops), + PERIPH_CLK("hdmi", "hdmi", NULL, 51, 0x18c, 148500000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm, MUX | MUX8 | DIV_U71), + PERIPH_CLK("tvdac", "tvdac", NULL, 53, 0x194, 220000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */ + PERIPH_CLK("disp1", "tegradc.0", NULL, 27, 0x138, 600000000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm, MUX | MUX8), + PERIPH_CLK("disp2", "tegradc.1", NULL, 26, 0x13c, 600000000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm, MUX | MUX8), + PERIPH_CLK("usbd", "fsl-tegra-udc", NULL, 22, 0, 480000000, mux_clk_m, 0), /* requires min voltage */ + PERIPH_CLK("usb2", "tegra-ehci.1", NULL, 58, 0, 480000000, mux_clk_m, 0), /* requires min voltage */ + PERIPH_CLK("usb3", "tegra-ehci.2", NULL, 59, 0, 480000000, mux_clk_m, 0), /* requires min voltage */ + PERIPH_CLK("dsia", "tegradc.0", "dsia", 48, 0, 500000000, mux_plld_out0, 0), + PERIPH_CLK_EX("dsib", "tegradc.1", "dsib", 82, 0xd0, 500000000, mux_plld_out0_plld2_out0, MUX | PLLD, &tegra_dsib_clk_ops), + PERIPH_CLK("csi", "tegra_camera", "csi", 52, 0, 102000000, mux_pllp_out3, 0), + PERIPH_CLK("isp", "tegra_camera", "isp", 23, 0, 150000000, mux_clk_m, 0), /* same frequency as VI */ + PERIPH_CLK("csus", "tegra_camera", "csus", 92, 0, 150000000, mux_clk_m, PERIPH_NO_RESET), + + PERIPH_CLK("tsensor", "tegra-tsensor", NULL, 100, 0x3b8, 216000000, mux_pllp_pllc_clkm_clk32, MUX | DIV_U71), + PERIPH_CLK("actmon", "actmon", NULL, 119, 0x3e8, 216000000, mux_pllp_pllc_clk32_clkm, MUX | DIV_U71), + PERIPH_CLK("extern1", "extern1", NULL, 120, 0x3ec, 216000000, mux_plla_clk32_pllp_clkm_plle, MUX | MUX8 | DIV_U71), + PERIPH_CLK("extern2", "extern2", NULL, 121, 0x3f0, 216000000, mux_plla_clk32_pllp_clkm_plle, MUX | MUX8 | DIV_U71), + PERIPH_CLK("extern3", "extern3", NULL, 122, 0x3f4, 216000000, mux_plla_clk32_pllp_clkm_plle, MUX | MUX8 | DIV_U71), + PERIPH_CLK("i2cslow", "i2cslow", NULL, 81, 0x3fc, 26000000, mux_pllp_pllc_clk32_clkm, MUX | DIV_U71 | PERIPH_ON_APB), + PERIPH_CLK("pcie", "tegra-pcie", "pcie", 70, 0, 250000000, mux_clk_m, 0), + PERIPH_CLK("afi", "tegra-pcie", "afi", 72, 0, 250000000, mux_clk_m, 0), + PERIPH_CLK("se", "se", NULL, 127, 0x42c, 520000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_INT), +}; + +#define CLK_DUPLICATE(_name, _dev, _con) \ + { \ + .name = _name, \ + .lookup = { \ + .dev_id = _dev, \ + .con_id = _con, \ + }, \ + } + +/* Some clocks may be used by different drivers depending on the board + * configuration. List those here to register them twice in the clock lookup + * table under two names. + */ +struct clk_duplicate tegra_clk_duplicates[] = { + CLK_DUPLICATE("usbd", "utmip-pad", NULL), + CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL), + CLK_DUPLICATE("usbd", "tegra-otg", NULL), + CLK_DUPLICATE("hdmi", "tegradc.0", "hdmi"), + CLK_DUPLICATE("hdmi", "tegradc.1", "hdmi"), + CLK_DUPLICATE("dsib", "tegradc.0", "dsib"), + CLK_DUPLICATE("dsia", "tegradc.1", "dsia"), + CLK_DUPLICATE("pwm", "tegra_pwm.0", NULL), + CLK_DUPLICATE("pwm", "tegra_pwm.1", NULL), + CLK_DUPLICATE("pwm", "tegra_pwm.2", NULL), + CLK_DUPLICATE("pwm", "tegra_pwm.3", NULL), + CLK_DUPLICATE("bsev", "tegra-avp", "bsev"), + CLK_DUPLICATE("bsev", "nvavp", "bsev"), + CLK_DUPLICATE("vde", "tegra-aes", "vde"), + CLK_DUPLICATE("bsea", "tegra-aes", "bsea"), + CLK_DUPLICATE("bsea", "nvavp", "bsea"), + CLK_DUPLICATE("cml1", "tegra_sata_cml", NULL), + CLK_DUPLICATE("cml0", "tegra_pcie", "cml"), + CLK_DUPLICATE("pciex", "tegra_pcie", "pciex"), + CLK_DUPLICATE("i2c1", "tegra-i2c-slave.0", NULL), + CLK_DUPLICATE("i2c2", "tegra-i2c-slave.1", NULL), + CLK_DUPLICATE("i2c3", "tegra-i2c-slave.2", NULL), + CLK_DUPLICATE("i2c4", "tegra-i2c-slave.3", NULL), + CLK_DUPLICATE("i2c5", "tegra-i2c-slave.4", NULL), + CLK_DUPLICATE("sbc1", "spi_slave_tegra.0", NULL), + CLK_DUPLICATE("sbc2", "spi_slave_tegra.1", NULL), + CLK_DUPLICATE("sbc3", "spi_slave_tegra.2", NULL), + CLK_DUPLICATE("sbc4", "spi_slave_tegra.3", NULL), + CLK_DUPLICATE("sbc5", "spi_slave_tegra.4", NULL), + CLK_DUPLICATE("sbc6", "spi_slave_tegra.5", NULL), + CLK_DUPLICATE("twd", "smp_twd", NULL), + CLK_DUPLICATE("vcp", "nvavp", "vcp"), +}; + +struct clk *tegra_ptr_clks[] = { + &tegra_clk_32k, + &tegra_clk_m, + &tegra_clk_m_div2, + &tegra_clk_m_div4, + &tegra_pll_ref, + &tegra_pll_m, + &tegra_pll_m_out1, + &tegra_pll_c, + &tegra_pll_c_out1, + &tegra_pll_p, + &tegra_pll_p_out1, + &tegra_pll_p_out2, + &tegra_pll_p_out3, + &tegra_pll_p_out4, + &tegra_pll_a, + &tegra_pll_a_out0, + &tegra_pll_d, + &tegra_pll_d_out0, + &tegra_pll_d2, + &tegra_pll_d2_out0, + &tegra_pll_u, + &tegra_pll_x, + &tegra_pll_x_out0, + &tegra_pll_e, + &tegra_clk_cclk_g, + &tegra_cml0_clk, + &tegra_cml1_clk, + &tegra_pciex_clk, + &tegra_clk_sclk, + &tegra_clk_blink, + &tegra30_clk_twd, +}; + + +static void tegra30_init_one_clock(struct clk *c) +{ + clk_init(c); + INIT_LIST_HEAD(&c->shared_bus_list); + if (!c->lookup.dev_id && !c->lookup.con_id) + c->lookup.con_id = c->name; + c->lookup.clk = c; + clkdev_add(&c->lookup); +} + +void __init tegra30_init_clocks(void) +{ + int i; + struct clk *c; + + for (i = 0; i < ARRAY_SIZE(tegra_ptr_clks); i++) + tegra30_init_one_clock(tegra_ptr_clks[i]); + + for (i = 0; i < ARRAY_SIZE(tegra_list_clks); i++) + tegra30_init_one_clock(&tegra_list_clks[i]); + + for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) { + c = tegra_get_clock_by_name(tegra_clk_duplicates[i].name); + if (!c) { + pr_err("%s: Unknown duplicate clock %s\n", __func__, + tegra_clk_duplicates[i].name); + continue; + } + + tegra_clk_duplicates[i].lookup.clk = c; + clkdev_add(&tegra_clk_duplicates[i].lookup); + } + + for (i = 0; i < ARRAY_SIZE(tegra_sync_source_list); i++) + tegra30_init_one_clock(&tegra_sync_source_list[i]); + for (i = 0; i < ARRAY_SIZE(tegra_clk_audio_list); i++) + tegra30_init_one_clock(&tegra_clk_audio_list[i]); + for (i = 0; i < ARRAY_SIZE(tegra_clk_audio_2x_list); i++) + tegra30_init_one_clock(&tegra_clk_audio_2x_list[i]); + + init_clk_out_mux(); + for (i = 0; i < ARRAY_SIZE(tegra_clk_out_list); i++) + tegra30_init_one_clock(&tegra_clk_out_list[i]); + +} diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c index 1d1acda4f3e0..1eed8d4a80ef 100644 --- a/arch/arm/mach-tegra/timer.c +++ b/arch/arm/mach-tegra/timer.c @@ -28,7 +28,7 @@ #include <linux/io.h> #include <asm/mach/time.h> -#include <asm/localtimer.h> +#include <asm/smp_twd.h> #include <asm/sched_clock.h> #include <mach/iomap.h> @@ -162,6 +162,21 @@ static struct irqaction tegra_timer_irq = { .irq = INT_TMR3, }; +#ifdef CONFIG_HAVE_ARM_TWD +static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, + TEGRA_ARM_PERIF_BASE + 0x600, + IRQ_LOCALTIMER); + +static void __init tegra_twd_init(void) +{ + int err = twd_local_timer_register(&twd_local_timer); + if (err) + pr_err("twd_local_timer_register failed %d\n", err); +} +#else +#define tegra_twd_init() do {} while(0) +#endif + static void __init tegra_init_timer(void) { struct clk *clk; @@ -188,10 +203,6 @@ static void __init tegra_init_timer(void) else clk_enable(clk); -#ifdef CONFIG_HAVE_ARM_TWD - twd_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x600); -#endif - switch (rate) { case 12000000: timer_writel(0x000b, TIMERUS_USEC_CFG); @@ -231,6 +242,7 @@ static void __init tegra_init_timer(void) tegra_clockevent.cpumask = cpu_all_mask; tegra_clockevent.irq = tegra_timer_irq.irq; clockevents_register_device(&tegra_clockevent); + tegra_twd_init(); } struct sys_timer tegra_timer = { diff --git a/arch/arm/mach-tegra/usb_phy.c b/arch/arm/mach-tegra/usb_phy.c index ad321f9e2bb8..c5b2ac04e2a0 100644 --- a/arch/arm/mach-tegra/usb_phy.c +++ b/arch/arm/mach-tegra/usb_phy.c @@ -22,6 +22,7 @@ #include <linux/delay.h> #include <linux/slab.h> #include <linux/err.h> +#include <linux/export.h> #include <linux/platform_device.h> #include <linux/io.h> #include <linux/gpio.h> @@ -730,6 +731,7 @@ err0: kfree(phy); return ERR_PTR(err); } +EXPORT_SYMBOL_GPL(tegra_usb_phy_open); int tegra_usb_phy_power_on(struct tegra_usb_phy *phy) { @@ -738,6 +740,7 @@ int tegra_usb_phy_power_on(struct tegra_usb_phy *phy) else return utmi_phy_power_on(phy); } +EXPORT_SYMBOL_GPL(tegra_usb_phy_power_on); void tegra_usb_phy_power_off(struct tegra_usb_phy *phy) { @@ -746,18 +749,21 @@ void tegra_usb_phy_power_off(struct tegra_usb_phy *phy) else utmi_phy_power_off(phy); } +EXPORT_SYMBOL_GPL(tegra_usb_phy_power_off); void tegra_usb_phy_preresume(struct tegra_usb_phy *phy) { if (!phy_is_ulpi(phy)) utmi_phy_preresume(phy); } +EXPORT_SYMBOL_GPL(tegra_usb_phy_preresume); void tegra_usb_phy_postresume(struct tegra_usb_phy *phy) { if (!phy_is_ulpi(phy)) utmi_phy_postresume(phy); } +EXPORT_SYMBOL_GPL(tegra_usb_phy_postresume); void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy, enum tegra_usb_phy_port_speed port_speed) @@ -765,24 +771,28 @@ void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy, if (!phy_is_ulpi(phy)) utmi_phy_restore_start(phy, port_speed); } +EXPORT_SYMBOL_GPL(tegra_ehci_phy_restore_start); void tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy) { if (!phy_is_ulpi(phy)) utmi_phy_restore_end(phy); } +EXPORT_SYMBOL_GPL(tegra_ehci_phy_restore_end); void tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy) { if (!phy_is_ulpi(phy)) utmi_phy_clk_disable(phy); } +EXPORT_SYMBOL_GPL(tegra_usb_phy_clk_disable); void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy) { if (!phy_is_ulpi(phy)) utmi_phy_clk_enable(phy); } +EXPORT_SYMBOL_GPL(tegra_usb_phy_clk_enable); void tegra_usb_phy_close(struct tegra_usb_phy *phy) { @@ -794,3 +804,4 @@ void tegra_usb_phy_close(struct tegra_usb_phy *phy) clk_put(phy->pll_u); kfree(phy); } +EXPORT_SYMBOL_GPL(tegra_usb_phy_close); diff --git a/arch/arm/mach-u300/Makefile b/arch/arm/mach-u300/Makefile index 285538124e5e..fd3a5c382f47 100644 --- a/arch/arm/mach-u300/Makefile +++ b/arch/arm/mach-u300/Makefile @@ -8,7 +8,6 @@ obj-n := obj- := obj-$(CONFIG_ARCH_U300) += u300.o -obj-$(CONFIG_MMC) += mmc.o obj-$(CONFIG_SPI_PL022) += spi.o obj-$(CONFIG_MACH_U300_SPIDUMMY) += dummyspichip.o obj-$(CONFIG_I2C_STU300) += i2c.o diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index a7b3f36e2262..1621ad07d284 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -18,6 +18,7 @@ #include <linux/termios.h> #include <linux/dmaengine.h> #include <linux/amba/bus.h> +#include <linux/amba/mmci.h> #include <linux/amba/serial.h> #include <linux/platform_device.h> #include <linux/gpio.h> @@ -44,9 +45,9 @@ #include <mach/gpio-u300.h> #include "clock.h" -#include "mmc.h" #include "spi.h" #include "i2c.h" +#include "u300-gpio.h" /* * Static I/O mappings that are needed for booting the U300 platforms. The @@ -95,19 +96,9 @@ static struct amba_pl011_data uart0_plat_data = { #endif }; -static struct amba_device uart0_device = { - .dev = { - .coherent_dma_mask = ~0, - .init_name = "uart0", /* Slow device at 0x3000 offset */ - .platform_data = &uart0_plat_data, - }, - .res = { - .start = U300_UART0_BASE, - .end = U300_UART0_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_U300_UART0, NO_IRQ }, -}; +/* Slow device at 0x3000 offset */ +static AMBA_APB_DEVICE(uart0, "uart0", 0, U300_UART0_BASE, + { IRQ_U300_UART0 }, &uart0_plat_data); /* The U335 have an additional UART1 on the APP CPU */ #ifdef CONFIG_MACH_U300_BS335 @@ -119,72 +110,42 @@ static struct amba_pl011_data uart1_plat_data = { #endif }; -static struct amba_device uart1_device = { - .dev = { - .coherent_dma_mask = ~0, - .init_name = "uart1", /* Fast device at 0x7000 offset */ - .platform_data = &uart1_plat_data, - }, - .res = { - .start = U300_UART1_BASE, - .end = U300_UART1_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = { IRQ_U300_UART1, NO_IRQ }, -}; +/* Fast device at 0x7000 offset */ +static AMBA_APB_DEVICE(uart1, "uart1", 0, U300_UART1_BASE, + { IRQ_U300_UART1 }, &uart1_plat_data); #endif -static struct amba_device pl172_device = { - .dev = { - .init_name = "pl172", /* AHB device at 0x4000 offset */ - .platform_data = NULL, - }, - .res = { - .start = U300_EMIF_CFG_BASE, - .end = U300_EMIF_CFG_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, -}; +/* AHB device at 0x4000 offset */ +static AMBA_APB_DEVICE(pl172, "pl172", 0, U300_EMIF_CFG_BASE, { }, NULL); +/* Fast device at 0x6000 offset */ +static AMBA_APB_DEVICE(pl022, "pl022", 0, U300_SPI_BASE, + { IRQ_U300_SPI }, NULL); -/* - * Everything within this next ifdef deals with external devices connected to - * the APP SPI bus. - */ -static struct amba_device pl022_device = { - .dev = { - .coherent_dma_mask = ~0, - .init_name = "pl022", /* Fast device at 0x6000 offset */ - }, - .res = { - .start = U300_SPI_BASE, - .end = U300_SPI_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_U300_SPI, NO_IRQ }, - /* - * This device has a DMA channel but the Linux driver does not use - * it currently. - */ -}; +/* Fast device at 0x1000 offset */ +#define U300_MMCSD_IRQS { IRQ_U300_MMCSD_MCIINTR0, IRQ_U300_MMCSD_MCIINTR1 } -static struct amba_device mmcsd_device = { - .dev = { - .init_name = "mmci", /* Fast device at 0x1000 offset */ - .platform_data = NULL, /* Added later */ - }, - .res = { - .start = U300_MMCSD_BASE, - .end = U300_MMCSD_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - .irq = {IRQ_U300_MMCSD_MCIINTR0, IRQ_U300_MMCSD_MCIINTR1 }, +static struct mmci_platform_data mmcsd_platform_data = { /* - * This device has a DMA channel but the Linux driver does not use - * it currently. + * Do not set ocr_mask or voltage translation function, + * we have a regulator we can control instead. */ + .f_max = 24000000, + .gpio_wp = -1, + .gpio_cd = U300_GPIO_PIN_MMC_CD, + .cd_invert = true, + .capabilities = MMC_CAP_MMC_HIGHSPEED | + MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, +#ifdef CONFIG_COH901318 + .dma_filter = coh901318_filter_id, + .dma_rx_param = (void *) U300_DMA_MMCSD_RX_TX, + /* Don't specify a TX channel, this RX channel is bidirectional */ +#endif }; +static AMBA_APB_DEVICE(mmcsd, "mmci", 0, U300_MMCSD_BASE, + U300_MMCSD_IRQS, &mmcsd_platform_data); + /* * The order of device declaration may be important, since some devices * have dependencies on other devices being initialized first. @@ -1583,6 +1544,8 @@ static struct fsmc_nand_platform_data nand_platform_data = { .nr_partitions = ARRAY_SIZE(u300_partitions), .options = NAND_SKIP_BBTSCAN, .width = FSMC_NAND_BW8, + .ale_off = PLAT_NAND_ALE, + .cle_off = PLAT_NAND_CLE, }; static struct platform_device nand_device = { @@ -1883,16 +1846,6 @@ void __init u300_init_devices(void) writew(val, U300_SYSCON_VBASE + U300_SYSCON_SMCR); } -static int core_module_init(void) -{ - /* - * This needs to be initialized later: it needs the input framework - * to be initialized first. - */ - return mmc_init(&mmcsd_device); -} -module_init(core_module_init); - /* Forward declare this function from the watchdog */ void coh901327_watchdog_reset(void); diff --git a/arch/arm/mach-u300/include/mach/entry-macro.S b/arch/arm/mach-u300/include/mach/entry-macro.S deleted file mode 100644 index 7181d6ac6651..000000000000 --- a/arch/arm/mach-u300/include/mach/entry-macro.S +++ /dev/null @@ -1,16 +0,0 @@ -/* - * - * arch-arm/mach-u300/include/mach/entry-macro.S - * - * - * Copyright (C) 2006-2009 ST-Ericsson AB - * License terms: GNU General Public License (GPL) version 2 - * Low-level IRQ helper macros for ST-Ericsson U300 - * Author: Linus Walleij <linus.walleij@stericsson.com> - */ - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-u300/include/mach/io.h b/arch/arm/mach-u300/include/mach/io.h deleted file mode 100644 index 5d6b4c13b3a0..000000000000 --- a/arch/arm/mach-u300/include/mach/io.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * - * arch/arm/mach-u300/include/mach/io.h - * - * - * Copyright (C) 2006-2009 ST-Ericsson AB - * License terms: GNU General Public License (GPL) version 2 - * Dummy IO map for being able to use writew()/readw(), - * writel()/readw() and similar accessor functions. - * Author: Linus Walleij <linus.walleij@stericsson.com> - */ -#ifndef __MACH_IO_H -#define __MACH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#endif diff --git a/arch/arm/mach-u300/include/mach/system.h b/arch/arm/mach-u300/include/mach/system.h deleted file mode 100644 index 574d46e38290..000000000000 --- a/arch/arm/mach-u300/include/mach/system.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * - * arch/arm/mach-u300/include/mach/system.h - * - * - * Copyright (C) 2007-2009 ST-Ericsson AB - * License terms: GNU General Public License (GPL) version 2 - * System shutdown and reset functions. - * Author: Linus Walleij <linus.walleij@stericsson.com> - */ -static inline void arch_idle(void) -{ - cpu_do_idle(); -} diff --git a/arch/arm/mach-u300/include/mach/u300-regs.h b/arch/arm/mach-u300/include/mach/u300-regs.h index 035fdc9dbdb0..65f87c523892 100644 --- a/arch/arm/mach-u300/include/mach/u300-regs.h +++ b/arch/arm/mach-u300/include/mach/u300-regs.h @@ -18,18 +18,17 @@ * the defines are used for setting up the I/O memory mapping. */ -#ifdef __ASSEMBLER__ -#define IOMEM(a) (a) -#else -#define IOMEM(a) (void __iomem *) a -#endif - /* NAND Flash CS0 */ #define U300_NAND_CS0_PHYS_BASE 0x80000000 /* NFIF */ #define U300_NAND_IF_PHYS_BASE 0x9f800000 +/* ALE, CLE offset for FSMC NAND */ +#define PLAT_NAND_CLE (1 << 16) +#define PLAT_NAND_ALE (1 << 17) + + /* AHB Peripherals */ #define U300_AHB_PER_PHYS_BASE 0xa0000000 #define U300_AHB_PER_VIRT_BASE 0xff010000 diff --git a/arch/arm/mach-u300/mmc.c b/arch/arm/mach-u300/mmc.c deleted file mode 100644 index 05abd6ad9fab..000000000000 --- a/arch/arm/mach-u300/mmc.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * arch/arm/mach-u300/mmc.c - * - * - * Copyright (C) 2009 ST-Ericsson SA - * License terms: GNU General Public License (GPL) version 2 - * - * Author: Linus Walleij <linus.walleij@stericsson.com> - * Author: Johan Lundin - * Author: Jonas Aaberg <jonas.aberg@stericsson.com> - */ -#include <linux/device.h> -#include <linux/amba/bus.h> -#include <linux/mmc/host.h> -#include <linux/dmaengine.h> -#include <linux/amba/mmci.h> -#include <linux/slab.h> -#include <mach/coh901318.h> -#include <mach/dma_channels.h> - -#include "u300-gpio.h" -#include "mmc.h" - -static struct mmci_platform_data mmc0_plat_data = { - /* - * Do not set ocr_mask or voltage translation function, - * we have a regulator we can control instead. - */ - /* Nominally 2.85V on our platform */ - .f_max = 24000000, - .gpio_wp = -1, - .gpio_cd = U300_GPIO_PIN_MMC_CD, - .cd_invert = true, - .capabilities = MMC_CAP_MMC_HIGHSPEED | - MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, -#ifdef CONFIG_COH901318 - .dma_filter = coh901318_filter_id, - .dma_rx_param = (void *) U300_DMA_MMCSD_RX_TX, - /* Don't specify a TX channel, this RX channel is bidirectional */ -#endif -}; - -int __devinit mmc_init(struct amba_device *adev) -{ - struct device *mmcsd_device = &adev->dev; - int ret = 0; - - mmcsd_device->platform_data = &mmc0_plat_data; - - return ret; -} diff --git a/arch/arm/mach-u300/mmc.h b/arch/arm/mach-u300/mmc.h deleted file mode 100644 index 92b85125abb3..000000000000 --- a/arch/arm/mach-u300/mmc.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * - * arch/arm/mach-u300/mmc.h - * - * - * Copyright (C) 2009 ST-Ericsson AB - * License terms: GNU General Public License (GPL) version 2 - * - * Author: Jonas Aaberg <jonas.aberg@stericsson.com> - */ -#ifndef MMC_H -#define MMC_H - -#include <linux/amba/bus.h> - -int __devinit mmc_init(struct amba_device *adev); - -#endif diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index c59e8b892d6b..880d02ec89d4 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -8,47 +8,62 @@ config UX500_SOC_COMMON select PL310_ERRATA_753970 select ARM_ERRATA_754322 select ARM_ERRATA_764369 - -menu "Ux500 SoC" + select CACHE_L2X0 config UX500_SOC_DB5500 - bool "DB5500" + bool select MFD_DB5500_PRCMU config UX500_SOC_DB8500 - bool "DB8500" + bool select MFD_DB8500_PRCMU select REGULATOR_DB8500_PRCMU - -endmenu + select CPU_FREQ_TABLE if CPU_FREQ menu "Ux500 target platform (boards)" -config MACH_U8500 - bool "U8500 Development platform" - depends on UX500_SOC_DB8500 - select TPS6105X +config MACH_MOP500 + bool "U8500 Development platform, MOP500 versions" + select UX500_SOC_DB8500 + select I2C + select I2C_NOMADIK + select SOC_BUS help - Include support for the mop500 development platform. + Include support for the MOP500 development platform. config MACH_HREFV60 - bool "U85000 Development platform, HREFv60 version" - depends on UX500_SOC_DB8500 - help - Include support for the HREFv60 new development platform. + bool "U8500 Development platform, HREFv60 version" + select MACH_MOP500 + help + Include support for the HREFv60 new development platform. + Includes HREFv70, v71 etc. config MACH_SNOWBALL bool "U8500 Snowball platform" - depends on UX500_SOC_DB8500 - select MACH_U8500 + select MACH_MOP500 help Include support for the snowball development platform. config MACH_U5500 bool "U5500 Development platform" - depends on UX500_SOC_DB5500 + select UX500_SOC_DB5500 help Include support for the U5500 development platform. + +config UX500_AUTO_PLATFORM + def_bool y + depends on !MACH_U5500 + select MACH_MOP500 + help + At least one platform needs to be selected in order to build + a working kernel. If everything else is disabled, this + automatically enables MACH_MOP500. + +config MACH_UX500_DT + bool "Generic U8500 support using device tree" + depends on MACH_MOP500 + select USE_OF + endmenu config UX500_DEBUG_UART diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index 6bd2f451c185..465b9ec9510a 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile @@ -7,7 +7,7 @@ obj-y := clock.o cpu.o devices.o devices-common.o \ obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o -obj-$(CONFIG_MACH_U8500) += board-mop500.o board-mop500-sdi.o \ +obj-$(CONFIG_MACH_MOP500) += board-mop500.o board-mop500-sdi.o \ board-mop500-regulators.o \ board-mop500-uib.o board-mop500-stuib.o \ board-mop500-u8500uib.o \ @@ -15,7 +15,6 @@ obj-$(CONFIG_MACH_U8500) += board-mop500.o board-mop500-sdi.o \ obj-$(CONFIG_MACH_U5500) += board-u5500.o board-u5500-sdi.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o -obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o obj-$(CONFIG_U5500_MODEM_IRQ) += modem-irq-db5500.o obj-$(CONFIG_U5500_MBOX) += mbox-db5500.o diff --git a/arch/arm/mach-ux500/Makefile.boot b/arch/arm/mach-ux500/Makefile.boot index ff0a4b5b0a82..dd5cd00e2554 100644 --- a/arch/arm/mach-ux500/Makefile.boot +++ b/arch/arm/mach-ux500/Makefile.boot @@ -2,3 +2,4 @@ params_phys-y := 0x00000100 initrd_phys-y := 0x00800000 +dtb-$(CONFIG_MACH_SNOWBALL) += snowball.dtb diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c index 74bfcff2bdf3..f5413dca532c 100644 --- a/arch/arm/mach-ux500/board-mop500-pins.c +++ b/arch/arm/mach-ux500/board-mop500-pins.c @@ -6,6 +6,7 @@ #include <linux/kernel.h> #include <linux/init.h> +#include <linux/bug.h> #include <asm/mach-types.h> #include <plat/pincfg.h> diff --git a/arch/arm/mach-ux500/board-mop500-regulators.c b/arch/arm/mach-ux500/board-mop500-regulators.c index 2735d03996cf..52426a425787 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.c +++ b/arch/arm/mach-ux500/board-mop500-regulators.c @@ -74,6 +74,26 @@ static struct regulator_consumer_supply ab8500_vtvout_consumers[] = { REGULATOR_SUPPLY("vddadc", "ab8500-gpadc.0"), }; +static struct regulator_consumer_supply ab8500_vaud_consumers[] = { + /* AB8500 audio-codec main supply */ + REGULATOR_SUPPLY("vaud", "ab8500-codec.0"), +}; + +static struct regulator_consumer_supply ab8500_vamic1_consumers[] = { + /* AB8500 audio-codec Mic1 supply */ + REGULATOR_SUPPLY("vamic1", "ab8500-codec.0"), +}; + +static struct regulator_consumer_supply ab8500_vamic2_consumers[] = { + /* AB8500 audio-codec Mic2 supply */ + REGULATOR_SUPPLY("vamic2", "ab8500-codec.0"), +}; + +static struct regulator_consumer_supply ab8500_vdmic_consumers[] = { + /* AB8500 audio-codec DMic supply */ + REGULATOR_SUPPLY("vdmic", "ab8500-codec.0"), +}; + static struct regulator_consumer_supply ab8500_vintcore_consumers[] = { /* SoC core supply, no device */ REGULATOR_SUPPLY("v-intcore", NULL), @@ -323,6 +343,8 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { .name = "V-AUD", .valid_ops_mask = REGULATOR_CHANGE_STATUS, }, + .num_consumer_supplies = ARRAY_SIZE(ab8500_vaud_consumers), + .consumer_supplies = ab8500_vaud_consumers, }, /* supply for v-anamic1 VAMic1-LDO */ [AB8500_LDO_ANAMIC1] = { @@ -330,6 +352,8 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { .name = "V-AMIC1", .valid_ops_mask = REGULATOR_CHANGE_STATUS, }, + .num_consumer_supplies = ARRAY_SIZE(ab8500_vamic1_consumers), + .consumer_supplies = ab8500_vamic1_consumers, }, /* supply for v-amic2, VAMIC2 LDO, reuse constants for AMIC1 */ [AB8500_LDO_ANAMIC2] = { @@ -337,6 +361,8 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { .name = "V-AMIC2", .valid_ops_mask = REGULATOR_CHANGE_STATUS, }, + .num_consumer_supplies = ARRAY_SIZE(ab8500_vamic2_consumers), + .consumer_supplies = ab8500_vamic2_consumers, }, /* supply for v-dmic, VDMIC LDO */ [AB8500_LDO_DMIC] = { @@ -344,6 +370,8 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { .name = "V-DMIC", .valid_ops_mask = REGULATOR_CHANGE_STATUS, }, + .num_consumer_supplies = ARRAY_SIZE(ab8500_vdmic_consumers), + .consumer_supplies = ab8500_vdmic_consumers, }, /* supply for v-intcore12, VINTCORE12 LDO */ [AB8500_LDO_INTCORE] = { diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c index 5dde4d4ebe88..920251cf834c 100644 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/arch/arm/mach-ux500/board-mop500-sdi.c @@ -31,21 +31,13 @@ * SDI 0 (MicroSD slot) */ -/* MMCIPOWER bits */ -#define MCI_DATA2DIREN (1 << 2) -#define MCI_CMDDIREN (1 << 3) -#define MCI_DATA0DIREN (1 << 4) -#define MCI_DATA31DIREN (1 << 5) -#define MCI_FBCLKEN (1 << 7) - /* GPIO pins used by the sdi0 level shifter */ static int sdi0_en = -1; static int sdi0_vsel = -1; -static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd, - unsigned char power_mode) +static int mop500_sdi0_ios_handler(struct device *dev, struct mmc_ios *ios) { - switch (power_mode) { + switch (ios->power_mode) { case MMC_POWER_UP: case MMC_POWER_ON: /* @@ -65,8 +57,7 @@ static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd, break; } - return MCI_FBCLKEN | MCI_CMDDIREN | MCI_DATA0DIREN | - MCI_DATA2DIREN | MCI_DATA31DIREN; + return 0; } #ifdef CONFIG_STE_DMA40 @@ -90,13 +81,17 @@ static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = { #endif static struct mmci_platform_data mop500_sdi0_data = { - .vdd_handler = mop500_sdi0_vdd_handler, + .ios_handler = mop500_sdi0_ios_handler, .ocr_mask = MMC_VDD_29_30, .f_max = 50000000, .capabilities = MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED, .gpio_wp = -1, + .sigdir = MCI_ST_FBCLKEN | + MCI_ST_CMDDIREN | + MCI_ST_DATA0DIREN | + MCI_ST_DATA2DIREN, #ifdef CONFIG_STE_DMA40 .dma_filter = stedma40_filter, .dma_rx_param = &mop500_sdi0_dma_cfg_rx, @@ -104,7 +99,7 @@ static struct mmci_platform_data mop500_sdi0_data = { #endif }; -static void sdi0_configure(void) +static void sdi0_configure(struct device *parent) { int ret; @@ -123,15 +118,15 @@ static void sdi0_configure(void) gpio_direction_output(sdi0_en, 1); /* Add the device, force v2 to subrevision 1 */ - db8500_add_sdi0(&mop500_sdi0_data, U8500_SDI_V2_PERIPHID); + db8500_add_sdi0(parent, &mop500_sdi0_data, U8500_SDI_V2_PERIPHID); } -void mop500_sdi_tc35892_init(void) +void mop500_sdi_tc35892_init(struct device *parent) { mop500_sdi0_data.gpio_cd = GPIO_SDMMC_CD; sdi0_en = GPIO_SDMMC_EN; sdi0_vsel = GPIO_SDMMC_1V8_3V_SEL; - sdi0_configure(); + sdi0_configure(parent); } /* @@ -246,12 +241,13 @@ static struct mmci_platform_data mop500_sdi4_data = { #endif }; -void __init mop500_sdi_init(void) +void __init mop500_sdi_init(struct device *parent) { /* PoP:ed eMMC */ - db8500_add_sdi2(&mop500_sdi2_data, U8500_SDI_V2_PERIPHID); + db8500_add_sdi2(parent, &mop500_sdi2_data, U8500_SDI_V2_PERIPHID); /* On-board eMMC */ - db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID); + db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID); + /* * On boards with the TC35892 GPIO expander, sdi0 will finally * be added when the TC35892 initializes and calls @@ -259,31 +255,31 @@ void __init mop500_sdi_init(void) */ } -void __init snowball_sdi_init(void) +void __init snowball_sdi_init(struct device *parent) { /* On Snowball MMC_CAP_SD_HIGHSPEED isn't supported (Hardware issue?) */ mop500_sdi0_data.capabilities &= ~MMC_CAP_SD_HIGHSPEED; /* On-board eMMC */ - db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID); + db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID); /* External Micro SD slot */ mop500_sdi0_data.gpio_cd = SNOWBALL_SDMMC_CD_GPIO; mop500_sdi0_data.cd_invert = true; sdi0_en = SNOWBALL_SDMMC_EN_GPIO; sdi0_vsel = SNOWBALL_SDMMC_1V8_3V_GPIO; - sdi0_configure(); + sdi0_configure(parent); } -void __init hrefv60_sdi_init(void) +void __init hrefv60_sdi_init(struct device *parent) { /* PoP:ed eMMC */ - db8500_add_sdi2(&mop500_sdi2_data, U8500_SDI_V2_PERIPHID); + db8500_add_sdi2(parent, &mop500_sdi2_data, U8500_SDI_V2_PERIPHID); /* On-board eMMC */ - db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID); + db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID); /* External Micro SD slot */ mop500_sdi0_data.gpio_cd = HREFV60_SDMMC_CD_GPIO; sdi0_en = HREFV60_SDMMC_EN_GPIO; sdi0_vsel = HREFV60_SDMMC_1V8_3V_GPIO; - sdi0_configure(); + sdi0_configure(parent); /* WLAN SDIO channel */ - db8500_add_sdi1(&mop500_sdi1_data, U8500_SDI_V2_PERIPHID); + db8500_add_sdi1(parent, &mop500_sdi1_data, U8500_SDI_V2_PERIPHID); } diff --git a/arch/arm/mach-ux500/board-mop500-u8500uib.c b/arch/arm/mach-ux500/board-mop500-u8500uib.c index feb5744d98b7..ead91c968ff4 100644 --- a/arch/arm/mach-ux500/board-mop500-u8500uib.c +++ b/arch/arm/mach-ux500/board-mop500-u8500uib.c @@ -8,7 +8,6 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/i2c.h> -#include <linux/gpio.h> #include <linux/interrupt.h> #include <linux/mfd/tc3589x.h> #include <linux/input/matrix_keypad.h> diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 5c00712907d1..77d03c1fbd04 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -30,6 +30,9 @@ #include <linux/gpio_keys.h> #include <linux/delay.h> +#include <linux/of.h> +#include <linux/of_platform.h> + #include <linux/leds.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -72,7 +75,7 @@ static struct platform_device snowball_led_dev = { }; static struct ab8500_gpio_platform_data ab8500_gpio_pdata = { - .gpio_base = MOP500_AB8500_GPIO(0), + .gpio_base = MOP500_AB8500_PIN_GPIO(1), .irq_base = MOP500_AB8500_VIR_GPIO_IRQ_BASE, /* config_reg is the initial configuration of ab8500 pins. * The pins can be configured as GPIO or alt functions based @@ -226,7 +229,12 @@ static struct tps6105x_platform_data mop500_tps61052_data = { static void mop500_tc35892_init(struct tc3589x *tc3589x, unsigned int base) { - mop500_sdi_tc35892_init(); + struct device *parent = NULL; +#if 0 + /* FIXME: Is the sdi actually part of tc3589x? */ + parent = tc3589x->dev; +#endif + mop500_sdi_tc35892_init(parent); } static struct tc3589x_gpio_platform_data mop500_tc35892_gpio_data = { @@ -353,12 +361,12 @@ U8500_I2C_CONTROLLER(1, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST); U8500_I2C_CONTROLLER(2, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST); U8500_I2C_CONTROLLER(3, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST); -static void __init mop500_i2c_init(void) +static void __init mop500_i2c_init(struct device *parent) { - db8500_add_i2c0(&u8500_i2c0_data); - db8500_add_i2c1(&u8500_i2c1_data); - db8500_add_i2c2(&u8500_i2c2_data); - db8500_add_i2c3(&u8500_i2c3_data); + db8500_add_i2c0(parent, &u8500_i2c0_data); + db8500_add_i2c1(parent, &u8500_i2c1_data); + db8500_add_i2c2(parent, &u8500_i2c2_data); + db8500_add_i2c3(parent, &u8500_i2c3_data); } static struct gpio_keys_button mop500_gpio_keys[] = { @@ -435,7 +443,7 @@ static struct stedma40_chan_cfg ssp0_dma_cfg_tx = { }; #endif -static struct pl022_ssp_controller ssp0_platform_data = { +static struct pl022_ssp_controller ssp0_plat = { .bus_id = 0, #ifdef CONFIG_STE_DMA40 .enable_dma = 1, @@ -451,9 +459,9 @@ static struct pl022_ssp_controller ssp0_platform_data = { .num_chipselect = 5, }; -static void __init mop500_spi_init(void) +static void __init mop500_spi_init(struct device *parent) { - db8500_add_ssp0(&ssp0_platform_data); + db8500_add_ssp0(parent, &ssp0_plat); } #ifdef CONFIG_STE_DMA40 @@ -587,11 +595,11 @@ static struct amba_pl011_data uart2_plat = { #endif }; -static void __init mop500_uart_init(void) +static void __init mop500_uart_init(struct device *parent) { - db8500_add_uart0(&uart0_plat); - db8500_add_uart1(&uart1_plat); - db8500_add_uart2(&uart2_plat); + db8500_add_uart0(parent, &uart0_plat); + db8500_add_uart1(parent, &uart1_plat); + db8500_add_uart2(parent, &uart2_plat); } static struct platform_device *snowball_platform_devs[] __initdata = { @@ -603,21 +611,27 @@ static struct platform_device *snowball_platform_devs[] __initdata = { static void __init mop500_init_machine(void) { + struct device *parent = NULL; int i2c0_devs; + int i; mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR; - u8500_init_devices(); + parent = u8500_init_devices(); mop500_pins_init(); + /* FIXME: parent of ab8500 should be prcmu */ + for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++) + mop500_platform_devs[i]->dev.parent = parent; + platform_add_devices(mop500_platform_devs, ARRAY_SIZE(mop500_platform_devs)); - mop500_i2c_init(); - mop500_sdi_init(); - mop500_spi_init(); - mop500_uart_init(); + mop500_i2c_init(parent); + mop500_sdi_init(parent); + mop500_spi_init(parent); + mop500_uart_init(parent); i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices); @@ -631,19 +645,24 @@ static void __init mop500_init_machine(void) static void __init snowball_init_machine(void) { + struct device *parent = NULL; int i2c0_devs; + int i; - u8500_init_devices(); + parent = u8500_init_devices(); snowball_pins_init(); + for (i = 0; i < ARRAY_SIZE(snowball_platform_devs); i++) + snowball_platform_devs[i]->dev.parent = parent; + platform_add_devices(snowball_platform_devs, ARRAY_SIZE(snowball_platform_devs)); - mop500_i2c_init(); - snowball_sdi_init(); - mop500_spi_init(); - mop500_uart_init(); + mop500_i2c_init(parent); + snowball_sdi_init(parent); + mop500_spi_init(parent); + mop500_uart_init(parent); i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices); i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs); @@ -656,7 +675,9 @@ static void __init snowball_init_machine(void) static void __init hrefv60_init_machine(void) { + struct device *parent = NULL; int i2c0_devs; + int i; /* * The HREFv60 board removed a GPIO expander and routed @@ -665,17 +686,20 @@ static void __init hrefv60_init_machine(void) */ mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO; - u8500_init_devices(); + parent = u8500_init_devices(); hrefv60_pins_init(); + for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++) + mop500_platform_devs[i]->dev.parent = parent; + platform_add_devices(mop500_platform_devs, ARRAY_SIZE(mop500_platform_devs)); - mop500_i2c_init(); - hrefv60_sdi_init(); - mop500_spi_init(); - mop500_uart_init(); + mop500_i2c_init(parent); + hrefv60_sdi_init(parent); + mop500_spi_init(parent); + mop500_uart_init(parent); i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices); @@ -718,3 +742,94 @@ MACHINE_START(SNOWBALL, "Calao Systems Snowball platform") .handle_irq = gic_handle_irq, .init_machine = snowball_init_machine, MACHINE_END + +#ifdef CONFIG_MACH_UX500_DT + +struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = { + OF_DEV_AUXDATA("arm,pl011", 0x80120000, "uart0", &uart0_plat), + OF_DEV_AUXDATA("arm,pl011", 0x80121000, "uart1", &uart1_plat), + OF_DEV_AUXDATA("arm,pl011", 0x80007000, "uart2", &uart2_plat), + OF_DEV_AUXDATA("arm,pl022", 0x80002000, "ssp0", &ssp0_plat), + {}, +}; + +static const struct of_device_id u8500_soc_node[] = { + /* only create devices below soc node */ + { .compatible = "stericsson,db8500", }, + { }, +}; + +static void __init u8500_init_machine(void) +{ + struct device *parent = NULL; + int i2c0_devs; + int i; + + parent = u8500_init_devices(); + i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices); + + for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++) + mop500_platform_devs[i]->dev.parent = parent; + for (i = 0; i < ARRAY_SIZE(snowball_platform_devs); i++) + snowball_platform_devs[i]->dev.parent = parent; + + /* automatically probe child nodes of db8500 device */ + of_platform_populate(NULL, u8500_soc_node, u8500_auxdata_lookup, parent); + + if (of_machine_is_compatible("st-ericsson,mop500")) { + mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR; + mop500_pins_init(); + + platform_add_devices(mop500_platform_devs, + ARRAY_SIZE(mop500_platform_devs)); + + mop500_sdi_init(parent); + } else if (of_machine_is_compatible("calaosystems,snowball-a9500")) { + snowball_pins_init(); + platform_add_devices(snowball_platform_devs, + ARRAY_SIZE(snowball_platform_devs)); + + snowball_sdi_init(parent); + } else if (of_machine_is_compatible("st-ericsson,hrefv60+")) { + /* + * The HREFv60 board removed a GPIO expander and routed + * all these GPIO pins to the internal GPIO controller + * instead. + */ + mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO; + i2c0_devs -= NUM_PRE_V60_I2C0_DEVICES; + hrefv60_pins_init(); + platform_add_devices(mop500_platform_devs, + ARRAY_SIZE(mop500_platform_devs)); + + hrefv60_sdi_init(parent); + } + mop500_i2c_init(parent); + + i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs); + i2c_register_board_info(2, mop500_i2c2_devices, + ARRAY_SIZE(mop500_i2c2_devices)); + + /* This board has full regulator constraints */ + regulator_has_full_constraints(); +} + +static const char * u8500_dt_board_compat[] = { + "calaosystems,snowball-a9500", + "st-ericsson,hrefv60+", + "st-ericsson,u8500", + "st-ericsson,mop500", + NULL, +}; + + +DT_MACHINE_START(U8500_DT, "ST-Ericsson U8500 platform (Device Tree Support)") + .map_io = u8500_map_io, + .init_irq = ux500_init_irq, + /* we re-use nomadik timer here */ + .timer = &ux500_timer, + .handle_irq = gic_handle_irq, + .init_machine = u8500_init_machine, + .dt_compat = u8500_dt_board_compat, +MACHINE_END +#endif diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h index f926d3db6207..fdcfa8721bb4 100644 --- a/arch/arm/mach-ux500/board-mop500.h +++ b/arch/arm/mach-ux500/board-mop500.h @@ -63,7 +63,7 @@ * because the AB8500 GPIO pins are enumbered starting from 1, so the value in * parens matches the GPIO pin number in the data sheet. */ -#define MOP500_AB8500_GPIO(x) (MOP500_EGPIO_END + (x) - 1) +#define MOP500_AB8500_PIN_GPIO(x) (MOP500_EGPIO_END + (x) - 1) /*Snowball AB8500 GPIO */ #define SNOWBALL_VSMPS2_1V8_GPIO MOP500_AB8500_PIN_GPIO(1) /* SYSCLKREQ2/GPIO1 */ #define SNOWBALL_PM_GPIO1_GPIO MOP500_AB8500_PIN_GPIO(2) /* SYSCLKREQ3/GPIO2 */ @@ -75,10 +75,10 @@ struct i2c_board_info; -extern void mop500_sdi_init(void); -extern void snowball_sdi_init(void); -extern void hrefv60_sdi_init(void); -extern void mop500_sdi_tc35892_init(void); +extern void mop500_sdi_init(struct device *parent); +extern void snowball_sdi_init(struct device *parent); +extern void hrefv60_sdi_init(struct device *parent); +extern void mop500_sdi_tc35892_init(struct device *parent); void __init mop500_u8500uib_init(void); void __init mop500_stuib_init(void); void __init mop500_pins_init(void); diff --git a/arch/arm/mach-ux500/board-u5500-sdi.c b/arch/arm/mach-ux500/board-u5500-sdi.c index 63c3f8058ffc..836112eedde7 100644 --- a/arch/arm/mach-ux500/board-u5500-sdi.c +++ b/arch/arm/mach-ux500/board-u5500-sdi.c @@ -66,9 +66,9 @@ static struct mmci_platform_data u5500_sdi0_data = { #endif }; -void __init u5500_sdi_init(void) +void __init u5500_sdi_init(struct device *parent) { nmk_config_pins(u5500_sdi_pins, ARRAY_SIZE(u5500_sdi_pins)); - db5500_add_sdi0(&u5500_sdi0_data); + db5500_add_sdi0(parent, &u5500_sdi0_data); } diff --git a/arch/arm/mach-ux500/board-u5500.c b/arch/arm/mach-ux500/board-u5500.c index 9de9e9c4dbbb..0ff4be72a809 100644 --- a/arch/arm/mach-ux500/board-u5500.c +++ b/arch/arm/mach-ux500/board-u5500.c @@ -97,9 +97,9 @@ static struct i2c_board_info __initdata u5500_i2c2_devices[] = { }, }; -static void __init u5500_i2c_init(void) +static void __init u5500_i2c_init(struct device *parent) { - db5500_add_i2c2(&u5500_i2c2_data); + db5500_add_i2c2(parent, &u5500_i2c2_data); i2c_register_board_info(2, ARRAY_AND_SIZE(u5500_i2c2_devices)); } @@ -126,20 +126,27 @@ static struct platform_device *u5500_platform_devices[] __initdata = { &ab5500_device, }; -static void __init u5500_uart_init(void) +static void __init u5500_uart_init(struct device *parent) { - db5500_add_uart0(NULL); - db5500_add_uart1(NULL); - db5500_add_uart2(NULL); + db5500_add_uart0(parent, NULL); + db5500_add_uart1(parent, NULL); + db5500_add_uart2(parent, NULL); } static void __init u5500_init_machine(void) { - u5500_init_devices(); + struct device *parent = NULL; + int i; + + parent = u5500_init_devices(); nmk_config_pins(u5500_pins, ARRAY_SIZE(u5500_pins)); - u5500_i2c_init(); - u5500_sdi_init(); - u5500_uart_init(); + + u5500_i2c_init(parent); + u5500_sdi_init(parent); + u5500_uart_init(parent); + + for (i = 0; i < ARRAY_SIZE(u5500_platform_devices); i++) + u5500_platform_devices[i]->dev.parent = parent; platform_add_devices(u5500_platform_devices, ARRAY_SIZE(u5500_platform_devices)); diff --git a/arch/arm/mach-ux500/cache-l2x0.c b/arch/arm/mach-ux500/cache-l2x0.c index da5569d83d58..77a75ed0df67 100644 --- a/arch/arm/mach-ux500/cache-l2x0.c +++ b/arch/arm/mach-ux500/cache-l2x0.c @@ -5,6 +5,8 @@ */ #include <linux/io.h> +#include <linux/of.h> + #include <asm/cacheflush.h> #include <asm/hardware/cache-l2x0.h> #include <mach/hardware.h> @@ -45,7 +47,10 @@ static int __init ux500_l2x0_init(void) ux500_l2x0_unlock(); /* 64KB way size, 8 way associativity, force WA */ - l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff); + if (of_have_populated_dt()) + l2x0_of_init(0x3e060000, 0xc0000fff); + else + l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff); /* * We can't disable l2 as we are in non secure mode, currently diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c index 737907537004..ec35f0aa5665 100644 --- a/arch/arm/mach-ux500/clock.c +++ b/arch/arm/mach-ux500/clock.c @@ -223,6 +223,13 @@ int clk_set_rate(struct clk *clk, unsigned long rate) } EXPORT_SYMBOL(clk_set_rate); +int clk_set_parent(struct clk *clk, struct clk *parent) +{ + /*TODO*/ + return -ENOSYS; +} +EXPORT_SYMBOL(clk_set_parent); + static void clk_prcmu_enable(struct clk *clk) { void __iomem *cg_set_reg = __io_address(U8500_PRCMU_BASE) diff --git a/arch/arm/mach-ux500/clock.h b/arch/arm/mach-ux500/clock.h index 074490705229..d776ada08dbf 100644 --- a/arch/arm/mach-ux500/clock.h +++ b/arch/arm/mach-ux500/clock.h @@ -21,6 +21,7 @@ struct clkops { void (*enable) (struct clk *); void (*disable) (struct clk *); unsigned long (*get_rate) (struct clk *); + int (*set_parent)(struct clk *, struct clk *); }; /** diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c index 18aa5c05c69e..bca47f32082f 100644 --- a/arch/arm/mach-ux500/cpu-db5500.c +++ b/arch/arm/mach-ux500/cpu-db5500.c @@ -147,13 +147,13 @@ static resource_size_t __initdata db5500_gpio_base[] = { U5500_GPIOBANK7_BASE, }; -static void __init db5500_add_gpios(void) +static void __init db5500_add_gpios(struct device *parent) { struct nmk_gpio_platform_data pdata = { /* No custom data yet */ }; - dbx500_add_gpios(ARRAY_AND_SIZE(db5500_gpio_base), + dbx500_add_gpios(parent, ARRAY_AND_SIZE(db5500_gpio_base), IRQ_DB5500_GPIO0, &pdata); } @@ -212,14 +212,36 @@ static int usb_db5500_tx_dma_cfg[] = { DB5500_DMA_DEV38_USB_OTG_OEP_8 }; -void __init u5500_init_devices(void) +static const char *db5500_read_soc_id(void) { - db5500_add_gpios(); + return kasprintf(GFP_KERNEL, "u5500 currently unsupported\n"); +} + +static struct device * __init db5500_soc_device_init(void) +{ + const char *soc_id = db5500_read_soc_id(); + + return ux500_soc_device_init(soc_id); +} + +struct device * __init u5500_init_devices(void) +{ + struct device *parent; + int i; + + parent = db5500_soc_device_init(); + + db5500_add_gpios(parent); db5500_pmu_init(); - db5500_dma_init(); - db5500_add_rtc(); - db5500_add_usb(usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg); + db5500_dma_init(parent); + db5500_add_rtc(parent); + db5500_add_usb(parent, usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg); + + for (i = 0; i < ARRAY_SIZE(db5500_platform_devs); i++) + db5500_platform_devs[i]->dev.parent = parent; platform_add_devices(db5500_platform_devs, ARRAY_SIZE(db5500_platform_devs)); + + return parent; } diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 7176ee7491ab..9bd8163896cf 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -24,6 +24,7 @@ #include <mach/setup.h> #include <mach/devices.h> #include <mach/usb.h> +#include <mach/db8500-regs.h> #include "devices-db8500.h" #include "ste-dma40-db8500.h" @@ -132,13 +133,13 @@ static resource_size_t __initdata db8500_gpio_base[] = { U8500_GPIOBANK8_BASE, }; -static void __init db8500_add_gpios(void) +static void __init db8500_add_gpios(struct device *parent) { struct nmk_gpio_platform_data pdata = { .supports_sleepmode = true, }; - dbx500_add_gpios(ARRAY_AND_SIZE(db8500_gpio_base), + dbx500_add_gpios(parent, ARRAY_AND_SIZE(db8500_gpio_base), IRQ_DB8500_GPIO0, &pdata); } @@ -164,17 +165,44 @@ static int usb_db8500_tx_dma_cfg[] = { DB8500_DMA_DEV39_USB_OTG_OEP_8 }; +static const char *db8500_read_soc_id(void) +{ + void __iomem *uid = __io_address(U8500_BB_UID_BASE); + + return kasprintf(GFP_KERNEL, "%08x%08x%08x%08x%08x", + readl((u32 *)uid+1), + readl((u32 *)uid+1), readl((u32 *)uid+2), + readl((u32 *)uid+3), readl((u32 *)uid+4)); +} + +static struct device * __init db8500_soc_device_init(void) +{ + const char *soc_id = db8500_read_soc_id(); + + return ux500_soc_device_init(soc_id); +} + /* * This function is called from the board init */ -void __init u8500_init_devices(void) +struct device * __init u8500_init_devices(void) { - db8500_add_rtc(); - db8500_add_gpios(); - db8500_add_usb(usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg); + struct device *parent; + int i; + + parent = db8500_soc_device_init(); + + db8500_add_rtc(parent); + db8500_add_gpios(parent); + db8500_add_usb(parent, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg); + + platform_device_register_data(parent, + "cpufreq-u8500", -1, NULL, 0); + + for (i = 0; i < ARRAY_SIZE(platform_devs); i++) + platform_devs[i]->dev.parent = parent; - platform_device_register_simple("cpufreq-u8500", -1, NULL, 0); platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); - return ; + return parent; } diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index f41857494375..d11f3892a27d 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c @@ -2,6 +2,7 @@ * Copyright (C) ST-Ericsson SA 2010 * * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson + * Author: Lee Jones <lee.jones@linaro.org> for ST-Ericsson * License terms: GNU General Public License (GPL) version 2 */ @@ -11,10 +12,15 @@ #include <linux/mfd/db8500-prcmu.h> #include <linux/mfd/db5500-prcmu.h> #include <linux/clksrc-dbx500-prcmu.h> +#include <linux/sys_soc.h> +#include <linux/err.h> +#include <linux/slab.h> +#include <linux/stat.h> +#include <linux/of.h> +#include <linux/of_irq.h> #include <asm/hardware/gic.h> #include <asm/mach/map.h> -#include <asm/localtimer.h> #include <mach/hardware.h> #include <mach/setup.h> @@ -24,6 +30,11 @@ void __iomem *_PRCMU_BASE; +static const struct of_device_id ux500_dt_irq_match[] = { + { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, }, + {}, +}; + void __init ux500_init_irq(void) { void __iomem *dist_base; @@ -38,7 +49,12 @@ void __init ux500_init_irq(void) } else ux500_unknown_soc(); - gic_init(0, 29, dist_base, cpu_base); +#ifdef CONFIG_OF + if (of_have_populated_dt()) + of_irq_init(ux500_dt_irq_match); + else +#endif + gic_init(0, 29, dist_base, cpu_base); /* * Init clocks here so that they are available for system timer @@ -50,3 +66,73 @@ void __init ux500_init_irq(void) db8500_prcmu_early_init(); clk_init(); } + +static const char * __init ux500_get_machine(void) +{ + return kasprintf(GFP_KERNEL, "DB%4x", dbx500_partnumber()); +} + +static const char * __init ux500_get_family(void) +{ + return kasprintf(GFP_KERNEL, "ux500"); +} + +static const char * __init ux500_get_revision(void) +{ + unsigned int rev = dbx500_revision(); + + if (rev == 0x01) + return kasprintf(GFP_KERNEL, "%s", "ED"); + else if (rev >= 0xA0) + return kasprintf(GFP_KERNEL, "%d.%d", + (rev >> 4) - 0xA + 1, rev & 0xf); + + return kasprintf(GFP_KERNEL, "%s", "Unknown"); +} + +static ssize_t ux500_get_process(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + if (dbx500_id.process == 0x00) + return sprintf(buf, "Standard\n"); + + return sprintf(buf, "%02xnm\n", dbx500_id.process); +} + +static void __init soc_info_populate(struct soc_device_attribute *soc_dev_attr, + const char *soc_id) +{ + soc_dev_attr->soc_id = soc_id; + soc_dev_attr->machine = ux500_get_machine(); + soc_dev_attr->family = ux500_get_family(); + soc_dev_attr->revision = ux500_get_revision(); +} + +struct device_attribute ux500_soc_attr = + __ATTR(process, S_IRUGO, ux500_get_process, NULL); + +struct device * __init ux500_soc_device_init(const char *soc_id) +{ + struct device *parent; + struct soc_device *soc_dev; + struct soc_device_attribute *soc_dev_attr; + + soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + if (!soc_dev_attr) + return ERR_PTR(-ENOMEM); + + soc_info_populate(soc_dev_attr, soc_id); + + soc_dev = soc_device_register(soc_dev_attr); + if (IS_ERR_OR_NULL(soc_dev)) { + kfree(soc_dev_attr); + return NULL; + } + + parent = soc_device_to_device(soc_dev); + if (!IS_ERR_OR_NULL(parent)) + device_create_file(parent, &ux500_soc_attr); + + return parent; +} diff --git a/arch/arm/mach-ux500/devices-common.c b/arch/arm/mach-ux500/devices-common.c index c563e5418d80..c5312a4b49f5 100644 --- a/arch/arm/mach-ux500/devices-common.c +++ b/arch/arm/mach-ux500/devices-common.c @@ -20,35 +20,31 @@ #include "devices-common.h" struct amba_device * -dbx500_add_amba_device(const char *name, resource_size_t base, - int irq, void *pdata, unsigned int periphid) +dbx500_add_amba_device(struct device *parent, const char *name, + resource_size_t base, int irq, void *pdata, + unsigned int periphid) { struct amba_device *dev; int ret; - dev = kzalloc(sizeof *dev, GFP_KERNEL); + dev = amba_device_alloc(name, base, SZ_4K); if (!dev) return ERR_PTR(-ENOMEM); - dev->dev.init_name = name; - - dev->res.start = base; - dev->res.end = base + SZ_4K - 1; - dev->res.flags = IORESOURCE_MEM; - dev->dma_mask = DMA_BIT_MASK(32); dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); dev->irq[0] = irq; - dev->irq[1] = NO_IRQ; dev->periphid = periphid; dev->dev.platform_data = pdata; - ret = amba_device_register(dev, &iomem_resource); + dev->dev.parent = parent; + + ret = amba_device_add(dev, &iomem_resource); if (ret) { - kfree(dev); + amba_device_put(dev); return ERR_PTR(ret); } @@ -56,60 +52,7 @@ dbx500_add_amba_device(const char *name, resource_size_t base, } static struct platform_device * -dbx500_add_platform_device(const char *name, int id, void *pdata, - struct resource *res, int resnum) -{ - struct platform_device *dev; - int ret; - - dev = platform_device_alloc(name, id); - if (!dev) - return ERR_PTR(-ENOMEM); - - dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); - dev->dev.dma_mask = &dev->dev.coherent_dma_mask; - - ret = platform_device_add_resources(dev, res, resnum); - if (ret) - goto out_free; - - dev->dev.platform_data = pdata; - - ret = platform_device_add(dev); - if (ret) - goto out_free; - - return dev; - -out_free: - platform_device_put(dev); - return ERR_PTR(ret); -} - -struct platform_device * -dbx500_add_platform_device_4k1irq(const char *name, int id, - resource_size_t base, - int irq, void *pdata) -{ - struct resource resources[] = { - [0] = { - .start = base, - .end = base + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = irq, - .end = irq, - .flags = IORESOURCE_IRQ, - } - }; - - return dbx500_add_platform_device(name, id, pdata, resources, - ARRAY_SIZE(resources)); -} - -static struct platform_device * -dbx500_add_gpio(int id, resource_size_t addr, int irq, +dbx500_add_gpio(struct device *parent, int id, resource_size_t addr, int irq, struct nmk_gpio_platform_data *pdata) { struct resource resources[] = { @@ -125,13 +68,18 @@ dbx500_add_gpio(int id, resource_size_t addr, int irq, } }; - return platform_device_register_resndata(NULL, "gpio", id, - resources, ARRAY_SIZE(resources), - pdata, sizeof(*pdata)); + return platform_device_register_resndata( + parent, + "gpio", + id, + resources, + ARRAY_SIZE(resources), + pdata, + sizeof(*pdata)); } -void dbx500_add_gpios(resource_size_t *base, int num, int irq, - struct nmk_gpio_platform_data *pdata) +void dbx500_add_gpios(struct device *parent, resource_size_t *base, int num, + int irq, struct nmk_gpio_platform_data *pdata) { int first = 0; int i; @@ -141,6 +89,6 @@ void dbx500_add_gpios(resource_size_t *base, int num, int irq, pdata->first_irq = NOMADIK_GPIO_TO_IRQ(first); pdata->num_gpio = 32; - dbx500_add_gpio(i, base[i], irq, pdata); + dbx500_add_gpio(parent, i, base[i], irq, pdata); } } diff --git a/arch/arm/mach-ux500/devices-common.h b/arch/arm/mach-ux500/devices-common.h index 7825705033bf..39c74ec82add 100644 --- a/arch/arm/mach-ux500/devices-common.h +++ b/arch/arm/mach-ux500/devices-common.h @@ -8,80 +8,89 @@ #ifndef __DEVICES_COMMON_H #define __DEVICES_COMMON_H -extern struct amba_device * -dbx500_add_amba_device(const char *name, resource_size_t base, - int irq, void *pdata, unsigned int periphid); +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> +#include <linux/sys_soc.h> +#include <plat/i2c.h> -extern struct platform_device * -dbx500_add_platform_device_4k1irq(const char *name, int id, - resource_size_t base, - int irq, void *pdata); +extern struct amba_device * +dbx500_add_amba_device(struct device *parent, const char *name, + resource_size_t base, int irq, void *pdata, + unsigned int periphid); struct spi_master_cntlr; static inline struct amba_device * -dbx500_add_msp_spi(const char *name, resource_size_t base, int irq, +dbx500_add_msp_spi(struct device *parent, const char *name, + resource_size_t base, int irq, struct spi_master_cntlr *pdata) { - return dbx500_add_amba_device(name, base, irq, pdata, 0); + return dbx500_add_amba_device(parent, name, base, irq, + pdata, 0); } static inline struct amba_device * -dbx500_add_spi(const char *name, resource_size_t base, int irq, - struct spi_master_cntlr *pdata, +dbx500_add_spi(struct device *parent, const char *name, resource_size_t base, + int irq, struct spi_master_cntlr *pdata, u32 periphid) { - return dbx500_add_amba_device(name, base, irq, pdata, periphid); + return dbx500_add_amba_device(parent, name, base, irq, + pdata, periphid); } struct mmci_platform_data; static inline struct amba_device * -dbx500_add_sdi(const char *name, resource_size_t base, int irq, - struct mmci_platform_data *pdata, - u32 periphid) +dbx500_add_sdi(struct device *parent, const char *name, resource_size_t base, + int irq, struct mmci_platform_data *pdata, u32 periphid) { - return dbx500_add_amba_device(name, base, irq, pdata, periphid); + return dbx500_add_amba_device(parent, name, base, irq, + pdata, periphid); } struct amba_pl011_data; static inline struct amba_device * -dbx500_add_uart(const char *name, resource_size_t base, int irq, - struct amba_pl011_data *pdata) +dbx500_add_uart(struct device *parent, const char *name, resource_size_t base, + int irq, struct amba_pl011_data *pdata) { - return dbx500_add_amba_device(name, base, irq, pdata, 0); + return dbx500_add_amba_device(parent, name, base, irq, pdata, 0); } struct nmk_i2c_controller; static inline struct platform_device * -dbx500_add_i2c(int id, resource_size_t base, int irq, - struct nmk_i2c_controller *pdata) -{ - return dbx500_add_platform_device_4k1irq("nmk-i2c", id, base, irq, - pdata); -} - -struct msp_i2s_platform_data; - -static inline struct platform_device * -dbx500_add_msp_i2s(int id, resource_size_t base, int irq, - struct msp_i2s_platform_data *pdata) +dbx500_add_i2c(struct device *parent, int id, resource_size_t base, int irq, + struct nmk_i2c_controller *data) { - return dbx500_add_platform_device_4k1irq("MSP_I2S", id, base, irq, - pdata); + struct resource res[] = { + DEFINE_RES_MEM(base, SZ_4K), + DEFINE_RES_IRQ(irq), + }; + + struct platform_device_info pdevinfo = { + .parent = parent, + .name = "nmk-i2c", + .id = id, + .res = res, + .num_res = ARRAY_SIZE(res), + .data = data, + .size_data = sizeof(*data), + .dma_mask = DMA_BIT_MASK(32), + }; + + return platform_device_register_full(&pdevinfo); } static inline struct amba_device * -dbx500_add_rtc(resource_size_t base, int irq) +dbx500_add_rtc(struct device *parent, resource_size_t base, int irq) { - return dbx500_add_amba_device("rtc-pl031", base, irq, NULL, 0); + return dbx500_add_amba_device(parent, "rtc-pl031", base, irq, NULL, 0); } struct nmk_gpio_platform_data; -void dbx500_add_gpios(resource_size_t *base, int num, int irq, - struct nmk_gpio_platform_data *pdata); +void dbx500_add_gpios(struct device *parent, resource_size_t *base, int num, + int irq, struct nmk_gpio_platform_data *pdata); #endif diff --git a/arch/arm/mach-ux500/devices-db5500.h b/arch/arm/mach-ux500/devices-db5500.h index 0c4bccd02b90..e70955502c35 100644 --- a/arch/arm/mach-ux500/devices-db5500.h +++ b/arch/arm/mach-ux500/devices-db5500.h @@ -10,70 +10,90 @@ #include "devices-common.h" -#define db5500_add_i2c1(pdata) \ - dbx500_add_i2c(1, U5500_I2C1_BASE, IRQ_DB5500_I2C1, pdata) -#define db5500_add_i2c2(pdata) \ - dbx500_add_i2c(2, U5500_I2C2_BASE, IRQ_DB5500_I2C2, pdata) -#define db5500_add_i2c3(pdata) \ - dbx500_add_i2c(3, U5500_I2C3_BASE, IRQ_DB5500_I2C3, pdata) +#define db5500_add_i2c1(parent, pdata) \ + dbx500_add_i2c(parent, 1, U5500_I2C1_BASE, IRQ_DB5500_I2C1, pdata) +#define db5500_add_i2c2(parent, pdata) \ + dbx500_add_i2c(parent, 2, U5500_I2C2_BASE, IRQ_DB5500_I2C2, pdata) +#define db5500_add_i2c3(parent, pdata) \ + dbx500_add_i2c(parent, 3, U5500_I2C3_BASE, IRQ_DB5500_I2C3, pdata) -#define db5500_add_msp0_i2s(pdata) \ - dbx500_add_msp_i2s(0, U5500_MSP0_BASE, IRQ_DB5500_MSP0, pdata) -#define db5500_add_msp1_i2s(pdata) \ - dbx500_add_msp_i2s(1, U5500_MSP1_BASE, IRQ_DB5500_MSP1, pdata) -#define db5500_add_msp2_i2s(pdata) \ - dbx500_add_msp_i2s(2, U5500_MSP2_BASE, IRQ_DB5500_MSP2, pdata) +#define db5500_add_msp0_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp0", U5500_MSP0_BASE, \ + IRQ_DB5500_MSP0, pdata) +#define db5500_add_msp1_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp1", U5500_MSP1_BASE, \ + IRQ_DB5500_MSP1, pdata) +#define db5500_add_msp2_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp2", U5500_MSP2_BASE, \ + IRQ_DB5500_MSP2, pdata) -#define db5500_add_msp0_spi(pdata) \ - dbx500_add_msp_spi("msp0", U5500_MSP0_BASE, IRQ_DB5500_MSP0, pdata) -#define db5500_add_msp1_spi(pdata) \ - dbx500_add_msp_spi("msp1", U5500_MSP1_BASE, IRQ_DB5500_MSP1, pdata) -#define db5500_add_msp2_spi(pdata) \ - dbx500_add_msp_spi("msp2", U5500_MSP2_BASE, IRQ_DB5500_MSP2, pdata) +#define db5500_add_msp0_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp0", U5500_MSP0_BASE, \ + IRQ_DB5500_MSP0, pdata) +#define db5500_add_msp1_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp1", U5500_MSP1_BASE, \ + IRQ_DB5500_MSP1, pdata) +#define db5500_add_msp2_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp2", U5500_MSP2_BASE, \ + IRQ_DB5500_MSP2, pdata) -#define db5500_add_rtc() \ - dbx500_add_rtc(U5500_RTC_BASE, IRQ_DB5500_RTC); +#define db5500_add_rtc(parent) \ + dbx500_add_rtc(parent, U5500_RTC_BASE, IRQ_DB5500_RTC); -#define db5500_add_usb(rx_cfg, tx_cfg) \ - ux500_add_usb(U5500_USBOTG_BASE, IRQ_DB5500_USBOTG, rx_cfg, tx_cfg) +#define db5500_add_usb(parent, rx_cfg, tx_cfg) \ + ux500_add_usb(parent, U5500_USBOTG_BASE, \ + IRQ_DB5500_USBOTG, rx_cfg, tx_cfg) -#define db5500_add_sdi0(pdata) \ - dbx500_add_sdi("sdi0", U5500_SDI0_BASE, IRQ_DB5500_SDMMC0, pdata, \ +#define db5500_add_sdi0(parent, pdata) \ + dbx500_add_sdi(parent, "sdi0", U5500_SDI0_BASE, \ + IRQ_DB5500_SDMMC0, pdata, \ 0x10480180) -#define db5500_add_sdi1(pdata) \ - dbx500_add_sdi("sdi1", U5500_SDI1_BASE, IRQ_DB5500_SDMMC1, pdata, \ +#define db5500_add_sdi1(parent, pdata) \ + dbx500_add_sdi(parent, "sdi1", U5500_SDI1_BASE, \ + IRQ_DB5500_SDMMC1, pdata, \ 0x10480180) -#define db5500_add_sdi2(pdata) \ - dbx500_add_sdi("sdi2", U5500_SDI2_BASE, IRQ_DB5500_SDMMC2, pdata \ +#define db5500_add_sdi2(parent, pdata) \ + dbx500_add_sdi(parent, "sdi2", U5500_SDI2_BASE, \ + IRQ_DB5500_SDMMC2, pdata \ 0x10480180) -#define db5500_add_sdi3(pdata) \ - dbx500_add_sdi("sdi3", U5500_SDI3_BASE, IRQ_DB5500_SDMMC3, pdata \ +#define db5500_add_sdi3(parent, pdata) \ + dbx500_add_sdi(parent, "sdi3", U5500_SDI3_BASE, \ + IRQ_DB5500_SDMMC3, pdata \ 0x10480180) -#define db5500_add_sdi4(pdata) \ - dbx500_add_sdi("sdi4", U5500_SDI4_BASE, IRQ_DB5500_SDMMC4, pdata \ +#define db5500_add_sdi4(parent, pdata) \ + dbx500_add_sdi(parent, "sdi4", U5500_SDI4_BASE, \ + IRQ_DB5500_SDMMC4, pdata \ 0x10480180) /* This one has a bad peripheral ID in the U5500 silicon */ -#define db5500_add_spi0(pdata) \ - dbx500_add_spi("spi0", U5500_SPI0_BASE, IRQ_DB5500_SPI0, pdata, \ +#define db5500_add_spi0(parent, pdata) \ + dbx500_add_spi(parent, "spi0", U5500_SPI0_BASE, \ + IRQ_DB5500_SPI0, pdata, \ 0x10080023) -#define db5500_add_spi1(pdata) \ - dbx500_add_spi("spi1", U5500_SPI1_BASE, IRQ_DB5500_SPI1, pdata, \ +#define db5500_add_spi1(parent, pdata) \ + dbx500_add_spi(parent, "spi1", U5500_SPI1_BASE, \ + IRQ_DB5500_SPI1, pdata, \ 0x10080023) -#define db5500_add_spi2(pdata) \ - dbx500_add_spi("spi2", U5500_SPI2_BASE, IRQ_DB5500_SPI2, pdata \ +#define db5500_add_spi2(parent, pdata) \ + dbx500_add_spi(parent, "spi2", U5500_SPI2_BASE, \ + IRQ_DB5500_SPI2, pdata \ 0x10080023) -#define db5500_add_spi3(pdata) \ - dbx500_add_spi("spi3", U5500_SPI3_BASE, IRQ_DB5500_SPI3, pdata \ +#define db5500_add_spi3(parent, pdata) \ + dbx500_add_spi(parent, "spi3", U5500_SPI3_BASE, \ + IRQ_DB5500_SPI3, pdata \ 0x10080023) -#define db5500_add_uart0(plat) \ - dbx500_add_uart("uart0", U5500_UART0_BASE, IRQ_DB5500_UART0, plat) -#define db5500_add_uart1(plat) \ - dbx500_add_uart("uart1", U5500_UART1_BASE, IRQ_DB5500_UART1, plat) -#define db5500_add_uart2(plat) \ - dbx500_add_uart("uart2", U5500_UART2_BASE, IRQ_DB5500_UART2, plat) -#define db5500_add_uart3(plat) \ - dbx500_add_uart("uart3", U5500_UART3_BASE, IRQ_DB5500_UART3, plat) +#define db5500_add_uart0(parent, plat) \ + dbx500_add_uart(parent, "uart0", U5500_UART0_BASE, \ + IRQ_DB5500_UART0, plat) +#define db5500_add_uart1(parent, plat) \ + dbx500_add_uart(parent, "uart1", U5500_UART1_BASE, \ + IRQ_DB5500_UART1, plat) +#define db5500_add_uart2(parent, plat) \ + dbx500_add_uart(parent, "uart2", U5500_UART2_BASE, \ + IRQ_DB5500_UART2, plat) +#define db5500_add_uart3(parent, plat) \ + dbx500_add_uart(parent, "uart3", U5500_UART3_BASE, \ + IRQ_DB5500_UART3, plat) #endif diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c index a7c6cdc9b11e..6e66d3777ed5 100644 --- a/arch/arm/mach-ux500/devices-db8500.c +++ b/arch/arm/mach-ux500/devices-db8500.c @@ -101,6 +101,9 @@ static const dma_addr_t dma40_tx_map[DB8500_DMA_NR_DEV] = { [DB8500_DMA_DEV41_SD_MM3_TX] = -1, [DB8500_DMA_DEV42_SD_MM4_TX] = -1, [DB8500_DMA_DEV43_SD_MM5_TX] = -1, + [DB8500_DMA_DEV14_MSP2_TX] = U8500_MSP2_BASE + MSP_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV30_MSP1_TX] = U8500_MSP1_BASE + MSP_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV31_MSP0_TX_SLIM0_CH0_TX] = U8500_MSP0_BASE + MSP_TX_RX_REG_OFFSET, }; /* Mapping between source event lines and physical device address */ @@ -133,6 +136,9 @@ static const dma_addr_t dma40_rx_map[DB8500_DMA_NR_DEV] = { [DB8500_DMA_DEV41_SD_MM3_RX] = -1, [DB8500_DMA_DEV42_SD_MM4_RX] = -1, [DB8500_DMA_DEV43_SD_MM5_RX] = -1, + [DB8500_DMA_DEV14_MSP2_RX] = U8500_MSP2_BASE + MSP_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV30_MSP3_RX] = U8500_MSP3_BASE + MSP_TX_RX_REG_OFFSET, + [DB8500_DMA_DEV31_MSP0_RX_SLIM0_CH0_RX] = U8500_MSP0_BASE + MSP_TX_RX_REG_OFFSET, }; /* Reserved event lines for memcpy only */ diff --git a/arch/arm/mach-ux500/devices-db8500.h b/arch/arm/mach-ux500/devices-db8500.h index cbd4a9ae8109..9fd93e9da529 100644 --- a/arch/arm/mach-ux500/devices-db8500.h +++ b/arch/arm/mach-ux500/devices-db8500.h @@ -14,88 +14,114 @@ struct ske_keypad_platform_data; struct pl022_ssp_controller; static inline struct platform_device * -db8500_add_ske_keypad(struct ske_keypad_platform_data *pdata) +db8500_add_ske_keypad(struct device *parent, + struct ske_keypad_platform_data *pdata, + size_t size) { - return dbx500_add_platform_device_4k1irq("nmk-ske-keypad", -1, - U8500_SKE_BASE, - IRQ_DB8500_KB, pdata); + struct resource resources[] = { + DEFINE_RES_MEM(U8500_SKE_BASE, SZ_4K), + DEFINE_RES_IRQ(IRQ_DB8500_KB), + }; + + return platform_device_register_resndata(parent, "nmk-ske-keypad", -1, + resources, 2, pdata, size); } static inline struct amba_device * -db8500_add_ssp(const char *name, resource_size_t base, int irq, - struct pl022_ssp_controller *pdata) +db8500_add_ssp(struct device *parent, const char *name, resource_size_t base, + int irq, struct pl022_ssp_controller *pdata) { - return dbx500_add_amba_device(name, base, irq, pdata, 0); + return dbx500_add_amba_device(parent, name, base, irq, pdata, 0); } -#define db8500_add_i2c0(pdata) \ - dbx500_add_i2c(0, U8500_I2C0_BASE, IRQ_DB8500_I2C0, pdata) -#define db8500_add_i2c1(pdata) \ - dbx500_add_i2c(1, U8500_I2C1_BASE, IRQ_DB8500_I2C1, pdata) -#define db8500_add_i2c2(pdata) \ - dbx500_add_i2c(2, U8500_I2C2_BASE, IRQ_DB8500_I2C2, pdata) -#define db8500_add_i2c3(pdata) \ - dbx500_add_i2c(3, U8500_I2C3_BASE, IRQ_DB8500_I2C3, pdata) -#define db8500_add_i2c4(pdata) \ - dbx500_add_i2c(4, U8500_I2C4_BASE, IRQ_DB8500_I2C4, pdata) - -#define db8500_add_msp0_i2s(pdata) \ - dbx500_add_msp_i2s(0, U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata) -#define db8500_add_msp1_i2s(pdata) \ - dbx500_add_msp_i2s(1, U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata) -#define db8500_add_msp2_i2s(pdata) \ - dbx500_add_msp_i2s(2, U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata) -#define db8500_add_msp3_i2s(pdata) \ - dbx500_add_msp_i2s(3, U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata) - -#define db8500_add_msp0_spi(pdata) \ - dbx500_add_msp_spi("msp0", U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata) -#define db8500_add_msp1_spi(pdata) \ - dbx500_add_msp_spi("msp1", U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata) -#define db8500_add_msp2_spi(pdata) \ - dbx500_add_msp_spi("msp2", U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata) -#define db8500_add_msp3_spi(pdata) \ - dbx500_add_msp_spi("msp3", U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata) - -#define db8500_add_rtc() \ - dbx500_add_rtc(U8500_RTC_BASE, IRQ_DB8500_RTC); - -#define db8500_add_usb(rx_cfg, tx_cfg) \ - ux500_add_usb(U8500_USBOTG_BASE, IRQ_DB8500_USBOTG, rx_cfg, tx_cfg) - -#define db8500_add_sdi0(pdata, pid) \ - dbx500_add_sdi("sdi0", U8500_SDI0_BASE, IRQ_DB8500_SDMMC0, pdata, pid) -#define db8500_add_sdi1(pdata, pid) \ - dbx500_add_sdi("sdi1", U8500_SDI1_BASE, IRQ_DB8500_SDMMC1, pdata, pid) -#define db8500_add_sdi2(pdata, pid) \ - dbx500_add_sdi("sdi2", U8500_SDI2_BASE, IRQ_DB8500_SDMMC2, pdata, pid) -#define db8500_add_sdi3(pdata, pid) \ - dbx500_add_sdi("sdi3", U8500_SDI3_BASE, IRQ_DB8500_SDMMC3, pdata, pid) -#define db8500_add_sdi4(pdata, pid) \ - dbx500_add_sdi("sdi4", U8500_SDI4_BASE, IRQ_DB8500_SDMMC4, pdata, pid) -#define db8500_add_sdi5(pdata, pid) \ - dbx500_add_sdi("sdi5", U8500_SDI5_BASE, IRQ_DB8500_SDMMC5, pdata, pid) - -#define db8500_add_ssp0(pdata) \ - db8500_add_ssp("ssp0", U8500_SSP0_BASE, IRQ_DB8500_SSP0, pdata) -#define db8500_add_ssp1(pdata) \ - db8500_add_ssp("ssp1", U8500_SSP1_BASE, IRQ_DB8500_SSP1, pdata) - -#define db8500_add_spi0(pdata) \ - dbx500_add_spi("spi0", U8500_SPI0_BASE, IRQ_DB8500_SPI0, pdata, 0) -#define db8500_add_spi1(pdata) \ - dbx500_add_spi("spi1", U8500_SPI1_BASE, IRQ_DB8500_SPI1, pdata, 0) -#define db8500_add_spi2(pdata) \ - dbx500_add_spi("spi2", U8500_SPI2_BASE, IRQ_DB8500_SPI2, pdata, 0) -#define db8500_add_spi3(pdata) \ - dbx500_add_spi("spi3", U8500_SPI3_BASE, IRQ_DB8500_SPI3, pdata, 0) - -#define db8500_add_uart0(pdata) \ - dbx500_add_uart("uart0", U8500_UART0_BASE, IRQ_DB8500_UART0, pdata) -#define db8500_add_uart1(pdata) \ - dbx500_add_uart("uart1", U8500_UART1_BASE, IRQ_DB8500_UART1, pdata) -#define db8500_add_uart2(pdata) \ - dbx500_add_uart("uart2", U8500_UART2_BASE, IRQ_DB8500_UART2, pdata) +#define db8500_add_i2c0(parent, pdata) \ + dbx500_add_i2c(parent, 0, U8500_I2C0_BASE, IRQ_DB8500_I2C0, pdata) +#define db8500_add_i2c1(parent, pdata) \ + dbx500_add_i2c(parent, 1, U8500_I2C1_BASE, IRQ_DB8500_I2C1, pdata) +#define db8500_add_i2c2(parent, pdata) \ + dbx500_add_i2c(parent, 2, U8500_I2C2_BASE, IRQ_DB8500_I2C2, pdata) +#define db8500_add_i2c3(parent, pdata) \ + dbx500_add_i2c(parent, 3, U8500_I2C3_BASE, IRQ_DB8500_I2C3, pdata) +#define db8500_add_i2c4(parent, pdata) \ + dbx500_add_i2c(parent, 4, U8500_I2C4_BASE, IRQ_DB8500_I2C4, pdata) + +#define db8500_add_msp0_i2s(parent, pdata) \ + dbx500_add_msp_i2s(parent, 0, U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata) +#define db8500_add_msp1_i2s(parent, pdata) \ + dbx500_add_msp_i2s(parent, 1, U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata) +#define db8500_add_msp2_i2s(parent, pdata) \ + dbx500_add_msp_i2s(parent, 2, U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata) +#define db8500_add_msp3_i2s(parent, pdata) \ + dbx500_add_msp_i2s(parent, 3, U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata) + +#define db8500_add_msp0_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp0", U8500_MSP0_BASE, \ + IRQ_DB8500_MSP0, pdata) +#define db8500_add_msp1_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp1", U8500_MSP1_BASE, \ + IRQ_DB8500_MSP1, pdata) +#define db8500_add_msp2_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp2", U8500_MSP2_BASE, \ + IRQ_DB8500_MSP2, pdata) +#define db8500_add_msp3_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp3", U8500_MSP3_BASE, \ + IRQ_DB8500_MSP1, pdata) + +#define db8500_add_rtc(parent) \ + dbx500_add_rtc(parent, U8500_RTC_BASE, IRQ_DB8500_RTC); + +#define db8500_add_usb(parent, rx_cfg, tx_cfg) \ + ux500_add_usb(parent, U8500_USBOTG_BASE, \ + IRQ_DB8500_USBOTG, rx_cfg, tx_cfg) + +#define db8500_add_sdi0(parent, pdata, pid) \ + dbx500_add_sdi(parent, "sdi0", U8500_SDI0_BASE, \ + IRQ_DB8500_SDMMC0, pdata, pid) +#define db8500_add_sdi1(parent, pdata, pid) \ + dbx500_add_sdi(parent, "sdi1", U8500_SDI1_BASE, \ + IRQ_DB8500_SDMMC1, pdata, pid) +#define db8500_add_sdi2(parent, pdata, pid) \ + dbx500_add_sdi(parent, "sdi2", U8500_SDI2_BASE, \ + IRQ_DB8500_SDMMC2, pdata, pid) +#define db8500_add_sdi3(parent, pdata, pid) \ + dbx500_add_sdi(parent, "sdi3", U8500_SDI3_BASE, \ + IRQ_DB8500_SDMMC3, pdata, pid) +#define db8500_add_sdi4(parent, pdata, pid) \ + dbx500_add_sdi(parent, "sdi4", U8500_SDI4_BASE, \ + IRQ_DB8500_SDMMC4, pdata, pid) +#define db8500_add_sdi5(parent, pdata, pid) \ + dbx500_add_sdi(parent, "sdi5", U8500_SDI5_BASE, \ + IRQ_DB8500_SDMMC5, pdata, pid) + +#define db8500_add_ssp0(parent, pdata) \ + db8500_add_ssp(parent, "ssp0", U8500_SSP0_BASE, \ + IRQ_DB8500_SSP0, pdata) +#define db8500_add_ssp1(parent, pdata) \ + db8500_add_ssp(parent, "ssp1", U8500_SSP1_BASE, \ + IRQ_DB8500_SSP1, pdata) + +#define db8500_add_spi0(parent, pdata) \ + dbx500_add_spi(parent, "spi0", U8500_SPI0_BASE, \ + IRQ_DB8500_SPI0, pdata, 0) +#define db8500_add_spi1(parent, pdata) \ + dbx500_add_spi(parent, "spi1", U8500_SPI1_BASE, \ + IRQ_DB8500_SPI1, pdata, 0) +#define db8500_add_spi2(parent, pdata) \ + dbx500_add_spi(parent, "spi2", U8500_SPI2_BASE, \ + IRQ_DB8500_SPI2, pdata, 0) +#define db8500_add_spi3(parent, pdata) \ + dbx500_add_spi(parent, "spi3", U8500_SPI3_BASE, \ + IRQ_DB8500_SPI3, pdata, 0) + +#define db8500_add_uart0(parent, pdata) \ + dbx500_add_uart(parent, "uart0", U8500_UART0_BASE, \ + IRQ_DB8500_UART0, pdata) +#define db8500_add_uart1(parent, pdata) \ + dbx500_add_uart(parent, "uart1", U8500_UART1_BASE, \ + IRQ_DB8500_UART1, pdata) +#define db8500_add_uart2(parent, pdata) \ + dbx500_add_uart(parent, "uart2", U8500_UART2_BASE, \ + IRQ_DB8500_UART2, pdata) #endif diff --git a/arch/arm/mach-ux500/dma-db5500.c b/arch/arm/mach-ux500/dma-db5500.c index 1cfab68ae417..41e9470fa0e6 100644 --- a/arch/arm/mach-ux500/dma-db5500.c +++ b/arch/arm/mach-ux500/dma-db5500.c @@ -125,10 +125,11 @@ static struct platform_device dma40_device = { .resource = dma40_resources }; -void __init db5500_dma_init(void) +void __init db5500_dma_init(struct device *parent) { int ret; + dma40_device.dev.parent = parent; ret = platform_device_register(&dma40_device); if (ret) dev_err(&dma40_device.dev, "unable to register device: %d\n", ret); diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h index 80e10f50282e..9ec20b96d8f2 100644 --- a/arch/arm/mach-ux500/include/mach/db8500-regs.h +++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h @@ -161,4 +161,7 @@ #define U8500_MODEM_BASE 0xe000000 #define U8500_APE_BASE 0x6000000 +/* SoC identification number information */ +#define U8500_BB_UID_BASE (U8500_BACKUPRAM1_BASE + 0xFC0) + #endif diff --git a/arch/arm/mach-ux500/include/mach/entry-macro.S b/arch/arm/mach-ux500/include/mach/entry-macro.S deleted file mode 100644 index e16299e1020a..000000000000 --- a/arch/arm/mach-ux500/include/mach/entry-macro.S +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Low-level IRQ helper macros for U8500 platforms - * - * Copyright (C) 2009 ST-Ericsson. - * - * This file is a copy of ARM Realview platform. - * -just satisfied checkpatch script. - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h index b6ba26a1367d..f84698936d36 100644 --- a/arch/arm/mach-ux500/include/mach/hardware.h +++ b/arch/arm/mach-ux500/include/mach/hardware.h @@ -23,13 +23,15 @@ (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + U8500_IO_VIRTUAL) /* typesafe io address */ -#define __io_address(n) __io(IO_ADDRESS(n)) +#define __io_address(n) IOMEM(IO_ADDRESS(n)) /* Used by some plat-nomadik code */ #define io_p2v(n) __io_address(n) #include <mach/db8500-regs.h> #include <mach/db5500-regs.h> +#define MSP_TX_RX_REG_OFFSET 0 + #ifndef __ASSEMBLY__ #include <mach/id.h> diff --git a/arch/arm/mach-ux500/include/mach/io.h b/arch/arm/mach-ux500/include/mach/io.h deleted file mode 100644 index 1cf3f44ce5b2..000000000000 --- a/arch/arm/mach-ux500/include/mach/io.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * arch/arm/mach-u8500/include/mach/io.h - * - * Copyright (C) 1997-1999 Russell King - * - * Modifications: - * 06-12-1997 RMK Created. - * 07-04-1999 RMK Major cleanup - */ -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -/* - * We don't actually have real ISA nor PCI buses, but there is so many - * drivers out there that might just work if we fake them... - */ -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#endif diff --git a/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h index d2d4131435a6..7d34c52798b5 100644 --- a/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h +++ b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h @@ -13,7 +13,7 @@ #define MOP500_AB8500_IRQ_BASE IRQ_BOARD_START #define MOP500_AB8500_IRQ_END (MOP500_AB8500_IRQ_BASE \ - + AB8500_NR_IRQS) + + AB8500_MAX_NR_IRQS) /* TC35892 */ #define TC35892_NR_INTERNAL_IRQS 8 diff --git a/arch/arm/mach-ux500/include/mach/irqs.h b/arch/arm/mach-ux500/include/mach/irqs.h index 9db68d264c5f..c23a6b5f0c4e 100644 --- a/arch/arm/mach-ux500/include/mach/irqs.h +++ b/arch/arm/mach-ux500/include/mach/irqs.h @@ -43,7 +43,7 @@ /* This will be overridden by board-specific irq headers */ #define IRQ_BOARD_END IRQ_BOARD_START -#ifdef CONFIG_MACH_U8500 +#ifdef CONFIG_MACH_MOP500 #include <mach/irqs-board-mop500.h> #endif diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h index a7d363fdb4cd..3dc00ffa7bfa 100644 --- a/arch/arm/mach-ux500/include/mach/setup.h +++ b/arch/arm/mach-ux500/include/mach/setup.h @@ -18,17 +18,16 @@ void __init ux500_map_io(void); extern void __init u5500_map_io(void); extern void __init u8500_map_io(void); -extern void __init u5500_init_devices(void); -extern void __init u8500_init_devices(void); +extern struct device * __init u5500_init_devices(void); +extern struct device * __init u8500_init_devices(void); extern void __init ux500_init_irq(void); -extern void __init u5500_sdi_init(void); +extern void __init u5500_sdi_init(struct device *parent); -extern void __init db5500_dma_init(void); +extern void __init db5500_dma_init(struct device *parent); -/* We re-use nomadik_timer for this platform */ -extern void nmdk_timer_init(void); +extern struct device *ux500_soc_device_init(const char *soc_id); struct amba_device; extern void __init amba_add_devices(struct amba_device *devs[], int num); diff --git a/arch/arm/mach-ux500/include/mach/system.h b/arch/arm/mach-ux500/include/mach/system.h deleted file mode 100644 index 258e5c919c24..000000000000 --- a/arch/arm/mach-ux500/include/mach/system.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2009 ST-Ericsson. - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - /* - * This should do all the clock switching - * and wait for interrupt tricks - */ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-ux500/include/mach/usb.h b/arch/arm/mach-ux500/include/mach/usb.h index d3739d418813..4c1cc50a595a 100644 --- a/arch/arm/mach-ux500/include/mach/usb.h +++ b/arch/arm/mach-ux500/include/mach/usb.h @@ -20,6 +20,6 @@ struct ux500_musb_board_data { bool (*dma_filter)(struct dma_chan *chan, void *filter_param); }; -void ux500_add_usb(resource_size_t base, int irq, int *dma_rx_cfg, - int *dma_tx_cfg); +void ux500_add_usb(struct device *parent, resource_size_t base, + int irq, int *dma_rx_cfg, int *dma_tx_cfg); #endif diff --git a/arch/arm/mach-ux500/localtimer.c b/arch/arm/mach-ux500/localtimer.c deleted file mode 100644 index 5ba113309a0b..000000000000 --- a/arch/arm/mach-ux500/localtimer.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2008-2009 ST-Ericsson - * Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> - * - * This file is heavily based on relaview platform, almost a copy. - * - * Copyright (C) 2002 ARM Ltd. - * - * 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 <linux/init.h> -#include <linux/smp.h> -#include <linux/clockchips.h> - -#include <asm/irq.h> -#include <asm/smp_twd.h> -#include <asm/localtimer.h> - -/* - * Setup the local clock events for a CPU. - */ -int __cpuinit local_timer_setup(struct clock_event_device *evt) -{ - evt->irq = IRQ_LOCALTIMER; - twd_timer_setup(evt); - return 0; -} diff --git a/arch/arm/mach-ux500/timer.c b/arch/arm/mach-ux500/timer.c index aea467d04ff7..d37df98b5c32 100644 --- a/arch/arm/mach-ux500/timer.c +++ b/arch/arm/mach-ux500/timer.c @@ -7,29 +7,52 @@ #include <linux/io.h> #include <linux/errno.h> #include <linux/clksrc-dbx500-prcmu.h> +#include <linux/of.h> -#include <asm/localtimer.h> +#include <asm/smp_twd.h> #include <plat/mtu.h> #include <mach/setup.h> #include <mach/hardware.h> +#include <mach/irqs.h> + +#ifdef CONFIG_HAVE_ARM_TWD +static DEFINE_TWD_LOCAL_TIMER(u5500_twd_local_timer, + U5500_TWD_BASE, IRQ_LOCALTIMER); +static DEFINE_TWD_LOCAL_TIMER(u8500_twd_local_timer, + U8500_TWD_BASE, IRQ_LOCALTIMER); + +static void __init ux500_twd_init(void) +{ + struct twd_local_timer *twd_local_timer; + int err; + + twd_local_timer = cpu_is_u5500() ? &u5500_twd_local_timer : + &u8500_twd_local_timer; + + if (of_have_populated_dt()) + twd_local_timer_of_register(); + else { + err = twd_local_timer_register(twd_local_timer); + if (err) + pr_err("twd_local_timer_register failed %d\n", err); + } +} +#else +#define ux500_twd_init() do { } while(0) +#endif static void __init ux500_timer_init(void) { + void __iomem *mtu_timer_base; void __iomem *prcmu_timer_base; if (cpu_is_u5500()) { -#ifdef CONFIG_LOCAL_TIMERS - twd_base = __io_address(U5500_TWD_BASE); -#endif - mtu_base = __io_address(U5500_MTU0_BASE); + mtu_timer_base = __io_address(U5500_MTU0_BASE); prcmu_timer_base = __io_address(U5500_PRCMU_TIMER_3_BASE); } else if (cpu_is_u8500()) { -#ifdef CONFIG_LOCAL_TIMERS - twd_base = __io_address(U8500_TWD_BASE); -#endif - mtu_base = __io_address(U8500_MTU0_BASE); + mtu_timer_base = __io_address(U8500_MTU0_BASE); prcmu_timer_base = __io_address(U8500_PRCMU_TIMER_4_BASE); } else { ux500_unknown_soc(); @@ -52,8 +75,9 @@ static void __init ux500_timer_init(void) * */ - nmdk_timer_init(); + nmdk_timer_init(mtu_timer_base); clksrc_dbx500_prcmu_init(prcmu_timer_base); + ux500_twd_init(); } static void ux500_timer_reset(void) diff --git a/arch/arm/mach-ux500/usb.c b/arch/arm/mach-ux500/usb.c index 9f9e1c203061..a74af389bc63 100644 --- a/arch/arm/mach-ux500/usb.c +++ b/arch/arm/mach-ux500/usb.c @@ -7,6 +7,7 @@ #include <linux/platform_device.h> #include <linux/usb/musb.h> #include <linux/dma-mapping.h> + #include <plat/ste_dma40.h> #include <mach/hardware.h> #include <mach/usb.h> @@ -140,8 +141,8 @@ static inline void ux500_usb_dma_update_tx_ch_config(int *dst_dev_type) musb_dma_tx_ch[idx].dst_dev_type = dst_dev_type[idx]; } -void ux500_add_usb(resource_size_t base, int irq, int *dma_rx_cfg, - int *dma_tx_cfg) +void ux500_add_usb(struct device *parent, resource_size_t base, int irq, + int *dma_rx_cfg, int *dma_tx_cfg) { ux500_musb_device.resource[0].start = base; ux500_musb_device.resource[0].end = base + SZ_64K - 1; @@ -151,5 +152,7 @@ void ux500_add_usb(resource_size_t base, int irq, int *dma_rx_cfg, ux500_usb_dma_update_rx_ch_config(dma_rx_cfg); ux500_usb_dma_update_tx_ch_config(dma_tx_cfg); + ux500_musb_device.dev.parent = parent; + platform_device_register(&ux500_musb_device); } diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 008ce22b9a06..6bbd74e950ab 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -36,7 +36,6 @@ #include <linux/clkdev.h> #include <linux/mtd/physmap.h> -#include <asm/system.h> #include <asm/irq.h> #include <asm/leds.h> #include <asm/hardware/arm_timer.h> @@ -585,58 +584,58 @@ static struct pl022_ssp_controller ssp0_plat_data = { .num_chipselect = 1, }; -#define AACI_IRQ { IRQ_AACI, NO_IRQ } +#define AACI_IRQ { IRQ_AACI } #define MMCI0_IRQ { IRQ_MMCI0A,IRQ_SIC_MMCI0B } -#define KMI0_IRQ { IRQ_SIC_KMI0, NO_IRQ } -#define KMI1_IRQ { IRQ_SIC_KMI1, NO_IRQ } +#define KMI0_IRQ { IRQ_SIC_KMI0 } +#define KMI1_IRQ { IRQ_SIC_KMI1 } /* * These devices are connected directly to the multi-layer AHB switch */ -#define SMC_IRQ { NO_IRQ, NO_IRQ } -#define MPMC_IRQ { NO_IRQ, NO_IRQ } -#define CLCD_IRQ { IRQ_CLCDINT, NO_IRQ } -#define DMAC_IRQ { IRQ_DMAINT, NO_IRQ } +#define SMC_IRQ { } +#define MPMC_IRQ { } +#define CLCD_IRQ { IRQ_CLCDINT } +#define DMAC_IRQ { IRQ_DMAINT } /* * These devices are connected via the core APB bridge */ -#define SCTL_IRQ { NO_IRQ, NO_IRQ } -#define WATCHDOG_IRQ { IRQ_WDOGINT, NO_IRQ } -#define GPIO0_IRQ { IRQ_GPIOINT0, NO_IRQ } -#define GPIO1_IRQ { IRQ_GPIOINT1, NO_IRQ } -#define RTC_IRQ { IRQ_RTCINT, NO_IRQ } +#define SCTL_IRQ { } +#define WATCHDOG_IRQ { IRQ_WDOGINT } +#define GPIO0_IRQ { IRQ_GPIOINT0 } +#define GPIO1_IRQ { IRQ_GPIOINT1 } +#define RTC_IRQ { IRQ_RTCINT } /* * These devices are connected via the DMA APB bridge */ -#define SCI_IRQ { IRQ_SCIINT, NO_IRQ } -#define UART0_IRQ { IRQ_UARTINT0, NO_IRQ } -#define UART1_IRQ { IRQ_UARTINT1, NO_IRQ } -#define UART2_IRQ { IRQ_UARTINT2, NO_IRQ } -#define SSP_IRQ { IRQ_SSPINT, NO_IRQ } +#define SCI_IRQ { IRQ_SCIINT } +#define UART0_IRQ { IRQ_UARTINT0 } +#define UART1_IRQ { IRQ_UARTINT1 } +#define UART2_IRQ { IRQ_UARTINT2 } +#define SSP_IRQ { IRQ_SSPINT } /* FPGA Primecells */ -AMBA_DEVICE(aaci, "fpga:04", AACI, NULL); -AMBA_DEVICE(mmc0, "fpga:05", MMCI0, &mmc0_plat_data); -AMBA_DEVICE(kmi0, "fpga:06", KMI0, NULL); -AMBA_DEVICE(kmi1, "fpga:07", KMI1, NULL); +APB_DEVICE(aaci, "fpga:04", AACI, NULL); +APB_DEVICE(mmc0, "fpga:05", MMCI0, &mmc0_plat_data); +APB_DEVICE(kmi0, "fpga:06", KMI0, NULL); +APB_DEVICE(kmi1, "fpga:07", KMI1, NULL); /* DevChip Primecells */ -AMBA_DEVICE(smc, "dev:00", SMC, NULL); -AMBA_DEVICE(mpmc, "dev:10", MPMC, NULL); -AMBA_DEVICE(clcd, "dev:20", CLCD, &clcd_plat_data); -AMBA_DEVICE(dmac, "dev:30", DMAC, NULL); -AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL); -AMBA_DEVICE(wdog, "dev:e1", WATCHDOG, NULL); -AMBA_DEVICE(gpio0, "dev:e4", GPIO0, &gpio0_plat_data); -AMBA_DEVICE(gpio1, "dev:e5", GPIO1, &gpio1_plat_data); -AMBA_DEVICE(rtc, "dev:e8", RTC, NULL); -AMBA_DEVICE(sci0, "dev:f0", SCI, NULL); -AMBA_DEVICE(uart0, "dev:f1", UART0, NULL); -AMBA_DEVICE(uart1, "dev:f2", UART1, NULL); -AMBA_DEVICE(uart2, "dev:f3", UART2, NULL); -AMBA_DEVICE(ssp0, "dev:f4", SSP, &ssp0_plat_data); +AHB_DEVICE(smc, "dev:00", SMC, NULL); +AHB_DEVICE(mpmc, "dev:10", MPMC, NULL); +AHB_DEVICE(clcd, "dev:20", CLCD, &clcd_plat_data); +AHB_DEVICE(dmac, "dev:30", DMAC, NULL); +APB_DEVICE(sctl, "dev:e0", SCTL, NULL); +APB_DEVICE(wdog, "dev:e1", WATCHDOG, NULL); +APB_DEVICE(gpio0, "dev:e4", GPIO0, &gpio0_plat_data); +APB_DEVICE(gpio1, "dev:e5", GPIO1, &gpio1_plat_data); +APB_DEVICE(rtc, "dev:e8", RTC, NULL); +APB_DEVICE(sci0, "dev:f0", SCI, NULL); +APB_DEVICE(uart0, "dev:f1", UART0, NULL); +APB_DEVICE(uart1, "dev:f2", UART1, NULL); +APB_DEVICE(uart2, "dev:f3", UART2, NULL); +APB_DEVICE(ssp0, "dev:f4", SSP, &ssp0_plat_data); static struct amba_device *amba_devs[] __initdata = { &dmac_device, diff --git a/arch/arm/mach-versatile/core.h b/arch/arm/mach-versatile/core.h index 2ef2f555f315..683e60776a85 100644 --- a/arch/arm/mach-versatile/core.h +++ b/arch/arm/mach-versatile/core.h @@ -36,20 +36,10 @@ extern unsigned int mmc_status(struct device *dev); extern struct of_dev_auxdata versatile_auxdata_lookup[]; #endif -#define AMBA_DEVICE(name,busid,base,plat) \ -static struct amba_device name##_device = { \ - .dev = { \ - .coherent_dma_mask = ~0, \ - .init_name = busid, \ - .platform_data = plat, \ - }, \ - .res = { \ - .start = VERSATILE_##base##_BASE, \ - .end = (VERSATILE_##base##_BASE) + SZ_4K - 1,\ - .flags = IORESOURCE_MEM, \ - }, \ - .dma_mask = ~0, \ - .irq = base##_IRQ, \ -} +#define APB_DEVICE(name, busid, base, plat) \ +static AMBA_APB_DEVICE(name, busid, 0, VERSATILE_##base##_BASE, base##_IRQ, plat) + +#define AHB_DEVICE(name, busid, base, plat) \ +static AMBA_AHB_DEVICE(name, busid, 0, VERSATILE_##base##_BASE, base##_IRQ, plat) #endif diff --git a/arch/arm/mach-versatile/include/mach/entry-macro.S b/arch/arm/mach-versatile/include/mach/entry-macro.S deleted file mode 100644 index b6f0dbf122ee..000000000000 --- a/arch/arm/mach-versatile/include/mach/entry-macro.S +++ /dev/null @@ -1,15 +0,0 @@ -/* - * arch/arm/mach-versatile/include/mach/entry-macro.S - * - * Low-level IRQ helper macros for Versatile platforms - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-versatile/include/mach/io.h b/arch/arm/mach-versatile/include/mach/io.h deleted file mode 100644 index f067c14c7182..000000000000 --- a/arch/arm/mach-versatile/include/mach/io.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * arch/arm/mach-versatile/include/mach/io.h - * - * 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. - * - * 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_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#endif diff --git a/arch/arm/mach-versatile/include/mach/system.h b/arch/arm/mach-versatile/include/mach/system.h deleted file mode 100644 index f3fa347895f0..000000000000 --- a/arch/arm/mach-versatile/include/mach/system.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * arch/arm/mach-versatile/include/mach/system.h - * - * Copyright (C) 2003 ARM Limited - * Copyright (C) 2000 Deep Blue Solutions Ltd - * - * 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_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - /* - * This should do all the clock switching - * and wait for interrupt tricks - */ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c index 90069bce23bc..d2268be8c34c 100644 --- a/arch/arm/mach-versatile/pci.c +++ b/arch/arm/mach-versatile/pci.c @@ -24,7 +24,6 @@ #include <mach/hardware.h> #include <asm/irq.h> -#include <asm/system.h> #include <asm/mach/pci.h> /* @@ -191,7 +190,7 @@ static struct resource pre_mem = { .flags = IORESOURCE_MEM | IORESOURCE_PREFETCH, }; -static int __init pci_versatile_setup_resources(struct list_head *resources) +static int __init pci_versatile_setup_resources(struct pci_sys_data *sys) { int ret = 0; @@ -219,9 +218,9 @@ static int __init pci_versatile_setup_resources(struct list_head *resources) * the mem resource for this bus * the prefetch mem resource for this bus */ - pci_add_resource(resources, &io_mem); - pci_add_resource(resources, &non_mem); - pci_add_resource(resources, &pre_mem); + pci_add_resource_offset(&sys->resources, &io_mem, sys->io_offset); + pci_add_resource_offset(&sys->resources, &non_mem, sys->mem_offset); + pci_add_resource_offset(&sys->resources, &pre_mem, sys->mem_offset); goto out; @@ -250,7 +249,7 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys) if (nr == 0) { sys->mem_offset = 0; - ret = pci_versatile_setup_resources(&sys->resources); + ret = pci_versatile_setup_resources(sys); if (ret < 0) { printk("pci_versatile_setup: resources... oops?\n"); goto out; diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c index 9581c197500c..19738331bd3d 100644 --- a/arch/arm/mach-versatile/versatile_pb.c +++ b/arch/arm/mach-versatile/versatile_pb.c @@ -58,28 +58,28 @@ static struct pl061_platform_data gpio3_plat_data = { .irq_base = IRQ_GPIO3_START, }; -#define UART3_IRQ { IRQ_SIC_UART3, NO_IRQ } -#define SCI1_IRQ { IRQ_SIC_SCI3, NO_IRQ } +#define UART3_IRQ { IRQ_SIC_UART3 } +#define SCI1_IRQ { IRQ_SIC_SCI3 } #define MMCI1_IRQ { IRQ_MMCI1A, IRQ_SIC_MMCI1B } /* * These devices are connected via the core APB bridge */ -#define GPIO2_IRQ { IRQ_GPIOINT2, NO_IRQ } -#define GPIO3_IRQ { IRQ_GPIOINT3, NO_IRQ } +#define GPIO2_IRQ { IRQ_GPIOINT2 } +#define GPIO3_IRQ { IRQ_GPIOINT3 } /* * These devices are connected via the DMA APB bridge */ /* FPGA Primecells */ -AMBA_DEVICE(uart3, "fpga:09", UART3, NULL); -AMBA_DEVICE(sci1, "fpga:0a", SCI1, NULL); -AMBA_DEVICE(mmc1, "fpga:0b", MMCI1, &mmc1_plat_data); +APB_DEVICE(uart3, "fpga:09", UART3, NULL); +APB_DEVICE(sci1, "fpga:0a", SCI1, NULL); +APB_DEVICE(mmc1, "fpga:0b", MMCI1, &mmc1_plat_data); /* DevChip Primecells */ -AMBA_DEVICE(gpio2, "dev:e6", GPIO2, &gpio2_plat_data); -AMBA_DEVICE(gpio3, "dev:e7", GPIO3, &gpio3_plat_data); +APB_DEVICE(gpio2, "dev:e6", GPIO2, &gpio2_plat_data); +APB_DEVICE(gpio3, "dev:e7", GPIO3, &gpio3_plat_data); static struct amba_device *amba_devs[] __initdata = { &uart3_device, diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig index 88c3ba151e87..cf8730d35e70 100644 --- a/arch/arm/mach-vexpress/Kconfig +++ b/arch/arm/mach-vexpress/Kconfig @@ -1,14 +1,55 @@ menu "Versatile Express platform type" depends on ARCH_VEXPRESS +config ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA + bool + select ARM_ERRATA_720789 + select ARM_ERRATA_751472 + select PL310_ERRATA_753970 if CACHE_PL310 + help + Provides common dependencies for Versatile Express platforms + based on Cortex-A5 and Cortex-A9 processors. In order to + build a working kernel, you must also enable relevant core + tile support or Flattened Device Tree based support options. + config ARCH_VEXPRESS_CA9X4 bool "Versatile Express Cortex-A9x4 tile" + select ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA + select ARM_GIC select CPU_V7 + select HAVE_SMP + select MIGHT_HAVE_CACHE_L2X0 + +config ARCH_VEXPRESS_DT + bool "Device Tree support for Versatile Express platforms" + select ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA select ARM_GIC - select ARM_ERRATA_720789 - select ARM_ERRATA_751472 - select PL310_ERRATA_753970 + select ARM_PATCH_PHYS_VIRT + select AUTO_ZRELADDR + select CPU_V7 select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 + select USE_OF + help + New Versatile Express platforms require Flattened Device Tree to + be passed to the kernel. + + This option enables support for systems using Cortex processor based + ARM core and logic (FPGA) tiles on the Versatile Express motherboard, + for example: + + - CoreTile Express A5x2 (V2P-CA5s) + - CoreTile Express A9x4 (V2P-CA9) + - CoreTile Express A15x2 (V2P-CA15) + - LogicTile Express 13MG (V2F-2XV6) with A5, A7, A9 or A15 SMMs + (Soft Macrocell Models) + - Versatile Express RTSMs (Models) + + You must boot using a Flattened Device Tree in order to use these + platforms. The traditional (ATAGs) boot method is not usable on + these boards with this option. + + If your bootloader supports Flattened Device Tree based booting, + say Y here. endmenu diff --git a/arch/arm/mach-vexpress/Makefile.boot b/arch/arm/mach-vexpress/Makefile.boot index 8630b3d10a4d..909f85ebf5f4 100644 --- a/arch/arm/mach-vexpress/Makefile.boot +++ b/arch/arm/mach-vexpress/Makefile.boot @@ -1,3 +1,9 @@ +# Those numbers are used only by the non-DT V2P-CA9 platform +# The DT-enabled ones require CONFIG_AUTO_ZRELADDR=y zreladdr-y += 0x60008000 params_phys-y := 0x60000100 initrd_phys-y := 0x60800000 + +dtb-$(CONFIG_ARCH_VEXPRESS_DT) += vexpress-v2p-ca5s.dtb \ + vexpress-v2p-ca9.dtb \ + vexpress-v2p-ca15-tc1.dtb diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h index f4397159c173..a3a4980770bd 100644 --- a/arch/arm/mach-vexpress/core.h +++ b/arch/arm/mach-vexpress/core.h @@ -1,19 +1,7 @@ -#define __MMIO_P2V(x) (((x) & 0xfffff) | (((x) & 0x0f000000) >> 4) | 0xf8000000) -#define MMIO_P2V(x) ((void __iomem *)__MMIO_P2V(x)) +/* 2MB large area for motherboard's peripherals static mapping */ +#define V2M_PERIPH 0xf8000000 -#define AMBA_DEVICE(name,busid,base,plat) \ -struct amba_device name##_device = { \ - .dev = { \ - .coherent_dma_mask = ~0UL, \ - .init_name = busid, \ - .platform_data = plat, \ - }, \ - .res = { \ - .start = base, \ - .end = base + SZ_4K - 1, \ - .flags = IORESOURCE_MEM, \ - }, \ - .dma_mask = ~0UL, \ - .irq = IRQ_##base, \ - /* .dma = DMA_##base,*/ \ -} +/* Tile's peripherals static mappings should start here */ +#define V2T_PERIPH 0xf8200000 + +void vexpress_dt_smp_map_io(void); diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c index b1e87c184e54..c65cc3b462a5 100644 --- a/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/arch/arm/mach-vexpress/ct-ca9x4.c @@ -30,57 +30,40 @@ #include <plat/clcd.h> -#define V2M_PA_CS7 0x10000000 - static struct map_desc ct_ca9x4_io_desc[] __initdata = { { - .virtual = __MMIO_P2V(CT_CA9X4_MPIC), - .pfn = __phys_to_pfn(CT_CA9X4_MPIC), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = __MMIO_P2V(CT_CA9X4_SP804_TIMER), - .pfn = __phys_to_pfn(CT_CA9X4_SP804_TIMER), - .length = SZ_4K, - .type = MT_DEVICE, - }, { - .virtual = __MMIO_P2V(CT_CA9X4_L2CC), - .pfn = __phys_to_pfn(CT_CA9X4_L2CC), - .length = SZ_4K, - .type = MT_DEVICE, + .virtual = V2T_PERIPH, + .pfn = __phys_to_pfn(CT_CA9X4_MPIC), + .length = SZ_8K, + .type = MT_DEVICE, }, }; static void __init ct_ca9x4_map_io(void) { -#ifdef CONFIG_LOCAL_TIMERS - twd_base = MMIO_P2V(A9_MPCORE_TWD); -#endif iotable_init(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc)); } -static void __init ct_ca9x4_init_irq(void) +#ifdef CONFIG_HAVE_ARM_TWD +static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, A9_MPCORE_TWD, IRQ_LOCALTIMER); + +static void __init ca9x4_twd_init(void) { - gic_init(0, 29, MMIO_P2V(A9_MPCORE_GIC_DIST), - MMIO_P2V(A9_MPCORE_GIC_CPU)); + int err = twd_local_timer_register(&twd_local_timer); + if (err) + pr_err("twd_local_timer_register failed %d\n", err); } +#else +#define ca9x4_twd_init() do {} while(0) +#endif -#if 0 -static void __init ct_ca9x4_timer_init(void) +static void __init ct_ca9x4_init_irq(void) { - writel(0, MMIO_P2V(CT_CA9X4_TIMER0) + TIMER_CTRL); - writel(0, MMIO_P2V(CT_CA9X4_TIMER1) + TIMER_CTRL); - - sp804_clocksource_init(MMIO_P2V(CT_CA9X4_TIMER1), "ct-timer1"); - sp804_clockevents_init(MMIO_P2V(CT_CA9X4_TIMER0), IRQ_CT_CA9X4_TIMER0, - "ct-timer0"); + gic_init(0, 29, ioremap(A9_MPCORE_GIC_DIST, SZ_4K), + ioremap(A9_MPCORE_GIC_CPU, SZ_256)); + ca9x4_twd_init(); } -static struct sys_timer ct_ca9x4_timer = { - .init = ct_ca9x4_timer_init, -}; -#endif - static void ct_ca9x4_clcd_enable(struct clcd_fb *fb) { v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE_DB1, 0); @@ -109,10 +92,10 @@ static struct clcd_board ct_ca9x4_clcd_data = { .remove = versatile_clcd_remove_dma, }; -static AMBA_DEVICE(clcd, "ct:clcd", CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data); -static AMBA_DEVICE(dmc, "ct:dmc", CT_CA9X4_DMC, NULL); -static AMBA_DEVICE(smc, "ct:smc", CT_CA9X4_SMC, NULL); -static AMBA_DEVICE(gpio, "ct:gpio", CT_CA9X4_GPIO, NULL); +static AMBA_AHB_DEVICE(clcd, "ct:clcd", 0, CT_CA9X4_CLCDC, IRQ_CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data); +static AMBA_APB_DEVICE(dmc, "ct:dmc", 0, CT_CA9X4_DMC, IRQ_CT_CA9X4_DMC, NULL); +static AMBA_APB_DEVICE(smc, "ct:smc", 0, CT_CA9X4_SMC, IRQ_CT_CA9X4_SMC, NULL); +static AMBA_APB_DEVICE(gpio, "ct:gpio", 0, CT_CA9X4_GPIO, IRQ_CT_CA9X4_GPIO, NULL); static struct amba_device *ct_ca9x4_amba_devs[] __initdata = { &clcd_device, @@ -201,7 +184,7 @@ static void __init ct_ca9x4_init(void) int i; #ifdef CONFIG_CACHE_L2X0 - void __iomem *l2x0_base = MMIO_P2V(CT_CA9X4_L2CC); + void __iomem *l2x0_base = ioremap(CT_CA9X4_L2CC, SZ_4K); /* set RAM latencies to 1 cycle for this core tile. */ writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL); @@ -217,9 +200,17 @@ static void __init ct_ca9x4_init(void) } #ifdef CONFIG_SMP +static void *ct_ca9x4_scu_base __initdata; + static void __init ct_ca9x4_init_cpu_map(void) { - int i, ncores = scu_get_core_count(MMIO_P2V(A9_MPCORE_SCU)); + int i, ncores; + + ct_ca9x4_scu_base = ioremap(A9_MPCORE_SCU, SZ_128); + if (WARN_ON(!ct_ca9x4_scu_base)) + return; + + ncores = scu_get_core_count(ct_ca9x4_scu_base); if (ncores > nr_cpu_ids) { pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", @@ -235,7 +226,7 @@ static void __init ct_ca9x4_init_cpu_map(void) static void __init ct_ca9x4_smp_enable(unsigned int max_cpus) { - scu_enable(MMIO_P2V(A9_MPCORE_SCU)); + scu_enable(ct_ca9x4_scu_base); } #endif diff --git a/arch/arm/mach-vexpress/hotplug.c b/arch/arm/mach-vexpress/hotplug.c index 3034a4dab4a1..c504a72b94d6 100644 --- a/arch/arm/mach-vexpress/hotplug.c +++ b/arch/arm/mach-vexpress/hotplug.c @@ -14,7 +14,7 @@ #include <asm/cacheflush.h> #include <asm/smp_plat.h> -#include <asm/system.h> +#include <asm/cp15.h> extern volatile int pen_release; diff --git a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h index a34d3d4faae1..84acf8439d4b 100644 --- a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h +++ b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h @@ -22,9 +22,6 @@ #define CT_CA9X4_SYSWDT (0x1e007000) #define CT_CA9X4_L2CC (0x1e00a000) -#define CT_CA9X4_TIMER0 (CT_CA9X4_SP804_TIMER + 0x000) -#define CT_CA9X4_TIMER1 (CT_CA9X4_SP804_TIMER + 0x020) - #define A9_MPCORE_SCU (CT_CA9X4_MPIC + 0x0000) #define A9_MPCORE_GIC_CPU (CT_CA9X4_MPIC + 0x0100) #define A9_MPCORE_GIT (CT_CA9X4_MPIC + 0x0200) @@ -35,7 +32,7 @@ * Interrupts. Those in {} are for AMBA devices */ #define IRQ_CT_CA9X4_CLCDC { 76 } -#define IRQ_CT_CA9X4_DMC { -1 } +#define IRQ_CT_CA9X4_DMC { 0 } #define IRQ_CT_CA9X4_SMC { 77, 78 } #define IRQ_CT_CA9X4_TIMER0 80 #define IRQ_CT_CA9X4_TIMER1 81 diff --git a/arch/arm/mach-vexpress/include/mach/debug-macro.S b/arch/arm/mach-vexpress/include/mach/debug-macro.S index fd9e6c7ea49f..fa8224794e0b 100644 --- a/arch/arm/mach-vexpress/include/mach/debug-macro.S +++ b/arch/arm/mach-vexpress/include/mach/debug-macro.S @@ -10,12 +10,34 @@ * published by the Free Software Foundation. */ -#define DEBUG_LL_UART_OFFSET 0x00009000 +#define DEBUG_LL_PHYS_BASE 0x10000000 +#define DEBUG_LL_UART_OFFSET 0x00009000 + +#define DEBUG_LL_PHYS_BASE_RS1 0x1c000000 +#define DEBUG_LL_UART_OFFSET_RS1 0x00090000 + +#define DEBUG_LL_VIRT_BASE 0xf8000000 .macro addruart,rp,rv,tmp - mov \rp, #DEBUG_LL_UART_OFFSET - orr \rv, \rp, #0xf8000000 @ virtual base - orr \rp, \rp, #0x10000000 @ physical base + + @ Make an educated guess regarding the memory map: + @ - the original A9 core tile, which has MPCore peripherals + @ located at 0x1e000000, should use UART at 0x10009000 + @ - all other (RS1 complaint) tiles use UART mapped + @ at 0x1c090000 + mrc p15, 4, \tmp, c15, c0, 0 + cmp \tmp, #0x1e000000 + + @ Original memory map + moveq \rp, #DEBUG_LL_UART_OFFSET + orreq \rv, \rp, #DEBUG_LL_VIRT_BASE + orreq \rp, \rp, #DEBUG_LL_PHYS_BASE + + @ RS1 memory map + movne \rp, #DEBUG_LL_UART_OFFSET_RS1 + orrne \rv, \rp, #DEBUG_LL_VIRT_BASE + orrne \rp, \rp, #DEBUG_LL_PHYS_BASE_RS1 + .endm #include <asm/hardware/debug-pl01x.S> diff --git a/arch/arm/mach-vexpress/include/mach/entry-macro.S b/arch/arm/mach-vexpress/include/mach/entry-macro.S deleted file mode 100644 index a14f9e62ca92..000000000000 --- a/arch/arm/mach-vexpress/include/mach/entry-macro.S +++ /dev/null @@ -1,5 +0,0 @@ - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-vexpress/include/mach/io.h b/arch/arm/mach-vexpress/include/mach/io.h deleted file mode 100644 index 13522d86685e..000000000000 --- a/arch/arm/mach-vexpress/include/mach/io.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * arch/arm/mach-vexpress/include/mach/io.h - * - * 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. - * - * 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_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#endif diff --git a/arch/arm/mach-vexpress/include/mach/irqs.h b/arch/arm/mach-vexpress/include/mach/irqs.h index 7054cbfc9de5..4b10ee7657a6 100644 --- a/arch/arm/mach-vexpress/include/mach/irqs.h +++ b/arch/arm/mach-vexpress/include/mach/irqs.h @@ -1,4 +1,4 @@ #define IRQ_LOCALTIMER 29 #define IRQ_LOCALWDOG 30 -#define NR_IRQS 128 +#define NR_IRQS 256 diff --git a/arch/arm/mach-vexpress/include/mach/motherboard.h b/arch/arm/mach-vexpress/include/mach/motherboard.h index 0a3a37518405..31a92890893d 100644 --- a/arch/arm/mach-vexpress/include/mach/motherboard.h +++ b/arch/arm/mach-vexpress/include/mach/motherboard.h @@ -39,33 +39,30 @@ #define V2M_CF (V2M_PA_CS7 + 0x0001a000) #define V2M_CLCD (V2M_PA_CS7 + 0x0001f000) -#define V2M_SYS_ID (V2M_SYSREGS + 0x000) -#define V2M_SYS_SW (V2M_SYSREGS + 0x004) -#define V2M_SYS_LED (V2M_SYSREGS + 0x008) -#define V2M_SYS_100HZ (V2M_SYSREGS + 0x024) -#define V2M_SYS_FLAGS (V2M_SYSREGS + 0x030) -#define V2M_SYS_FLAGSSET (V2M_SYSREGS + 0x030) -#define V2M_SYS_FLAGSCLR (V2M_SYSREGS + 0x034) -#define V2M_SYS_NVFLAGS (V2M_SYSREGS + 0x038) -#define V2M_SYS_NVFLAGSSET (V2M_SYSREGS + 0x038) -#define V2M_SYS_NVFLAGSCLR (V2M_SYSREGS + 0x03c) -#define V2M_SYS_MCI (V2M_SYSREGS + 0x048) -#define V2M_SYS_FLASH (V2M_SYSREGS + 0x03c) -#define V2M_SYS_CFGSW (V2M_SYSREGS + 0x058) -#define V2M_SYS_24MHZ (V2M_SYSREGS + 0x05c) -#define V2M_SYS_MISC (V2M_SYSREGS + 0x060) -#define V2M_SYS_DMA (V2M_SYSREGS + 0x064) -#define V2M_SYS_PROCID0 (V2M_SYSREGS + 0x084) -#define V2M_SYS_PROCID1 (V2M_SYSREGS + 0x088) -#define V2M_SYS_CFGDATA (V2M_SYSREGS + 0x0a0) -#define V2M_SYS_CFGCTRL (V2M_SYSREGS + 0x0a4) -#define V2M_SYS_CFGSTAT (V2M_SYSREGS + 0x0a8) - -#define V2M_TIMER0 (V2M_TIMER01 + 0x000) -#define V2M_TIMER1 (V2M_TIMER01 + 0x020) - -#define V2M_TIMER2 (V2M_TIMER23 + 0x000) -#define V2M_TIMER3 (V2M_TIMER23 + 0x020) +/* + * Offsets from SYSREGS base + */ +#define V2M_SYS_ID 0x000 +#define V2M_SYS_SW 0x004 +#define V2M_SYS_LED 0x008 +#define V2M_SYS_100HZ 0x024 +#define V2M_SYS_FLAGS 0x030 +#define V2M_SYS_FLAGSSET 0x030 +#define V2M_SYS_FLAGSCLR 0x034 +#define V2M_SYS_NVFLAGS 0x038 +#define V2M_SYS_NVFLAGSSET 0x038 +#define V2M_SYS_NVFLAGSCLR 0x03c +#define V2M_SYS_MCI 0x048 +#define V2M_SYS_FLASH 0x03c +#define V2M_SYS_CFGSW 0x058 +#define V2M_SYS_24MHZ 0x05c +#define V2M_SYS_MISC 0x060 +#define V2M_SYS_DMA 0x064 +#define V2M_SYS_PROCID0 0x084 +#define V2M_SYS_PROCID1 0x088 +#define V2M_SYS_CFGDATA 0x0a0 +#define V2M_SYS_CFGCTRL 0x0a4 +#define V2M_SYS_CFGSTAT 0x0a8 /* @@ -117,6 +114,13 @@ int v2m_cfg_write(u32 devfn, u32 data); int v2m_cfg_read(u32 devfn, u32 *data); +void v2m_flags_set(u32 data); + +/* + * Miscellaneous + */ +#define SYS_MISC_MASTERSITE (1 << 14) +#define SYS_PROCIDx_HBI_MASK 0xfff /* * Core tile IDs diff --git a/arch/arm/mach-vexpress/include/mach/system.h b/arch/arm/mach-vexpress/include/mach/system.h deleted file mode 100644 index f653a8e265bd..000000000000 --- a/arch/arm/mach-vexpress/include/mach/system.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * arch/arm/mach-vexpress/include/mach/system.h - * - * Copyright (C) 2003 ARM Limited - * Copyright (C) 2000 Deep Blue Solutions Ltd - * - * 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_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -static inline void arch_idle(void) -{ - /* - * This should do all the clock switching - * and wait for interrupt tricks - */ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mach-vexpress/include/mach/uncompress.h b/arch/arm/mach-vexpress/include/mach/uncompress.h index 7972c5748d0e..7dab5596b868 100644 --- a/arch/arm/mach-vexpress/include/mach/uncompress.h +++ b/arch/arm/mach-vexpress/include/mach/uncompress.h @@ -22,7 +22,27 @@ #define AMBA_UART_CR(base) (*(volatile unsigned char *)((base) + 0x30)) #define AMBA_UART_FR(base) (*(volatile unsigned char *)((base) + 0x18)) -#define get_uart_base() (0x10000000 + 0x00009000) +#define UART_BASE 0x10009000 +#define UART_BASE_RS1 0x1c090000 + +static unsigned long get_uart_base(void) +{ + unsigned long mpcore_periph; + + /* + * Make an educated guess regarding the memory map: + * - the original A9 core tile, which has MPCore peripherals + * located at 0x1e000000, should use UART at 0x10009000 + * - all other (RS1 complaint) tiles use UART mapped + * at 0x1c090000 + */ + asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (mpcore_periph)); + + if (mpcore_periph == 0x1e000000) + return UART_BASE; + else + return UART_BASE_RS1; +} /* * This does not append a newline diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c index 124ffb169093..14ba1128ae8d 100644 --- a/arch/arm/mach-vexpress/platsmp.c +++ b/arch/arm/mach-vexpress/platsmp.c @@ -12,21 +12,168 @@ #include <linux/errno.h> #include <linux/smp.h> #include <linux/io.h> +#include <linux/of_fdt.h> + +#include <asm/smp_scu.h> +#include <asm/hardware/gic.h> +#include <asm/mach/map.h> #include <mach/motherboard.h> -#define V2M_PA_CS7 0x10000000 #include "core.h" extern void versatile_secondary_startup(void); +#if defined(CONFIG_OF) + +static enum { + GENERIC_SCU, + CORTEX_A9_SCU, +} vexpress_dt_scu __initdata = GENERIC_SCU; + +static struct map_desc vexpress_dt_cortex_a9_scu_map __initdata = { + .virtual = V2T_PERIPH, + /* .pfn set in vexpress_dt_init_cortex_a9_scu() */ + .length = SZ_128, + .type = MT_DEVICE, +}; + +static void *vexpress_dt_cortex_a9_scu_base __initdata; + +const static char *vexpress_dt_cortex_a9_match[] __initconst = { + "arm,cortex-a5-scu", + "arm,cortex-a9-scu", + NULL +}; + +static int __init vexpress_dt_find_scu(unsigned long node, + const char *uname, int depth, void *data) +{ + if (of_flat_dt_match(node, vexpress_dt_cortex_a9_match)) { + phys_addr_t phys_addr; + __be32 *reg = of_get_flat_dt_prop(node, "reg", NULL); + + if (WARN_ON(!reg)) + return -EINVAL; + + phys_addr = be32_to_cpup(reg); + vexpress_dt_scu = CORTEX_A9_SCU; + + vexpress_dt_cortex_a9_scu_map.pfn = __phys_to_pfn(phys_addr); + iotable_init(&vexpress_dt_cortex_a9_scu_map, 1); + vexpress_dt_cortex_a9_scu_base = ioremap(phys_addr, SZ_256); + if (WARN_ON(!vexpress_dt_cortex_a9_scu_base)) + return -EFAULT; + } + + return 0; +} + +void __init vexpress_dt_smp_map_io(void) +{ + if (initial_boot_params) + WARN_ON(of_scan_flat_dt(vexpress_dt_find_scu, NULL)); +} + +static int __init vexpress_dt_cpus_num(unsigned long node, const char *uname, + int depth, void *data) +{ + static int prev_depth = -1; + static int nr_cpus = -1; + + if (prev_depth > depth && nr_cpus > 0) + return nr_cpus; + + if (nr_cpus < 0 && strcmp(uname, "cpus") == 0) + nr_cpus = 0; + + if (nr_cpus >= 0) { + const char *device_type = of_get_flat_dt_prop(node, + "device_type", NULL); + + if (device_type && strcmp(device_type, "cpu") == 0) + nr_cpus++; + } + + prev_depth = depth; + + return 0; +} + +static void __init vexpress_dt_smp_init_cpus(void) +{ + int ncores = 0, i; + + switch (vexpress_dt_scu) { + case GENERIC_SCU: + ncores = of_scan_flat_dt(vexpress_dt_cpus_num, NULL); + break; + case CORTEX_A9_SCU: + ncores = scu_get_core_count(vexpress_dt_cortex_a9_scu_base); + break; + default: + WARN_ON(1); + break; + } + + if (ncores < 2) + return; + + if (ncores > nr_cpu_ids) { + pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", + ncores, nr_cpu_ids); + ncores = nr_cpu_ids; + } + + for (i = 0; i < ncores; ++i) + set_cpu_possible(i, true); + + set_smp_cross_call(gic_raise_softirq); +} + +static void __init vexpress_dt_smp_prepare_cpus(unsigned int max_cpus) +{ + int i; + + switch (vexpress_dt_scu) { + case GENERIC_SCU: + for (i = 0; i < max_cpus; i++) + set_cpu_present(i, true); + break; + case CORTEX_A9_SCU: + scu_enable(vexpress_dt_cortex_a9_scu_base); + break; + default: + WARN_ON(1); + break; + } +} + +#else + +static void __init vexpress_dt_smp_init_cpus(void) +{ + WARN_ON(1); +} + +void __init vexpress_dt_smp_prepare_cpus(unsigned int max_cpus) +{ + WARN_ON(1); +} + +#endif + /* * Initialise the CPU possible map early - this describes the CPUs * which may be present or become present in the system. */ void __init smp_init_cpus(void) { - ct_desc->init_cpu_map(); + if (ct_desc) + ct_desc->init_cpu_map(); + else + vexpress_dt_smp_init_cpus(); + } void __init platform_smp_prepare_cpus(unsigned int max_cpus) @@ -35,7 +182,10 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus) * Initialise the present map, which describes the set of CPUs * actually populated at the present time. */ - ct_desc->smp_enable(max_cpus); + if (ct_desc) + ct_desc->smp_enable(max_cpus); + else + vexpress_dt_smp_prepare_cpus(max_cpus); /* * Write the address of secondary startup into the @@ -43,7 +193,5 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus) * until it receives a soft interrupt, and then the * secondary CPU branches to this address. */ - writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR)); - writel(virt_to_phys(versatile_secondary_startup), - MMIO_P2V(V2M_SYS_FLAGSSET)); + v2m_flags_set(virt_to_phys(versatile_secondary_startup)); } diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index b4a28ca0e50a..47cdcca5a7e7 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c @@ -6,6 +6,10 @@ #include <linux/amba/mmci.h> #include <linux/io.h> #include <linux/init.h> +#include <linux/of_address.h> +#include <linux/of_fdt.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/ata_platform.h> #include <linux/smsc911x.h> @@ -21,6 +25,8 @@ #include <asm/mach/map.h> #include <asm/mach/time.h> #include <asm/hardware/arm_timer.h> +#include <asm/hardware/cache-l2x0.h> +#include <asm/hardware/gic.h> #include <asm/hardware/timer-sp.h> #include <asm/hardware/sp810.h> #include <asm/hardware/gic.h> @@ -40,29 +46,45 @@ static struct map_desc v2m_io_desc[] __initdata = { { - .virtual = __MMIO_P2V(V2M_PA_CS7), + .virtual = V2M_PERIPH, .pfn = __phys_to_pfn(V2M_PA_CS7), .length = SZ_128K, .type = MT_DEVICE, }, }; -static void __init v2m_timer_init(void) +static void __iomem *v2m_sysreg_base; + +static void __init v2m_sysctl_init(void __iomem *base) { u32 scctrl; + if (WARN_ON(!base)) + return; + /* Select 1MHz TIMCLK as the reference clock for SP804 timers */ - scctrl = readl(MMIO_P2V(V2M_SYSCTL + SCCTRL)); + scctrl = readl(base + SCCTRL); scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK; scctrl |= SCCTRL_TIMEREN1SEL_TIMCLK; - writel(scctrl, MMIO_P2V(V2M_SYSCTL + SCCTRL)); + writel(scctrl, base + SCCTRL); +} + +static void __init v2m_sp804_init(void __iomem *base, unsigned int irq) +{ + if (WARN_ON(!base || irq == NO_IRQ)) + return; + + writel(0, base + TIMER_1_BASE + TIMER_CTRL); + writel(0, base + TIMER_2_BASE + TIMER_CTRL); - writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL); - writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL); + sp804_clocksource_init(base + TIMER_2_BASE, "v2m-timer1"); + sp804_clockevents_init(base + TIMER_1_BASE, irq, "v2m-timer0"); +} - sp804_clocksource_init(MMIO_P2V(V2M_TIMER1), "v2m-timer1"); - sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0, - "v2m-timer0"); +static void __init v2m_timer_init(void) +{ + v2m_sysctl_init(ioremap(V2M_SYSCTL, SZ_4K)); + v2m_sp804_init(ioremap(V2M_TIMER01, SZ_4K), IRQ_V2M_TIMER0); } static struct sys_timer v2m_timer = { @@ -82,14 +104,14 @@ int v2m_cfg_write(u32 devfn, u32 data) devfn |= SYS_CFG_START | SYS_CFG_WRITE; spin_lock(&v2m_cfg_lock); - val = readl(MMIO_P2V(V2M_SYS_CFGSTAT)); - writel(val & ~SYS_CFG_COMPLETE, MMIO_P2V(V2M_SYS_CFGSTAT)); + val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT); + writel(val & ~SYS_CFG_COMPLETE, v2m_sysreg_base + V2M_SYS_CFGSTAT); - writel(data, MMIO_P2V(V2M_SYS_CFGDATA)); - writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL)); + writel(data, v2m_sysreg_base + V2M_SYS_CFGDATA); + writel(devfn, v2m_sysreg_base + V2M_SYS_CFGCTRL); do { - val = readl(MMIO_P2V(V2M_SYS_CFGSTAT)); + val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT); } while (val == 0); spin_unlock(&v2m_cfg_lock); @@ -103,22 +125,28 @@ int v2m_cfg_read(u32 devfn, u32 *data) devfn |= SYS_CFG_START; spin_lock(&v2m_cfg_lock); - writel(0, MMIO_P2V(V2M_SYS_CFGSTAT)); - writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL)); + writel(0, v2m_sysreg_base + V2M_SYS_CFGSTAT); + writel(devfn, v2m_sysreg_base + V2M_SYS_CFGCTRL); mb(); do { cpu_relax(); - val = readl(MMIO_P2V(V2M_SYS_CFGSTAT)); + val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT); } while (val == 0); - *data = readl(MMIO_P2V(V2M_SYS_CFGDATA)); + *data = readl(v2m_sysreg_base + V2M_SYS_CFGDATA); spin_unlock(&v2m_cfg_lock); return !!(val & SYS_CFG_ERR); } +void __init v2m_flags_set(u32 data) +{ + writel(~0, v2m_sysreg_base + V2M_SYS_FLAGSCLR); + writel(data, v2m_sysreg_base + V2M_SYS_FLAGSSET); +} + static struct resource v2m_pcie_i2c_resource = { .start = V2M_SERIAL_BUS_PCI, @@ -204,7 +232,7 @@ static struct platform_device v2m_usb_device = { static void v2m_flash_set_vpp(struct platform_device *pdev, int on) { - writel(on != 0, MMIO_P2V(V2M_SYS_FLASH)); + writel(on != 0, v2m_sysreg_base + V2M_SYS_FLASH); } static struct physmap_flash_data v2m_flash_data = { @@ -258,7 +286,7 @@ static struct platform_device v2m_cf_device = { static unsigned int v2m_mmci_status(struct device *dev) { - return readl(MMIO_P2V(V2M_SYS_MCI)) & (1 << 0); + return readl(v2m_sysreg_base + V2M_SYS_MCI) & (1 << 0); } static struct mmci_platform_data v2m_mmci_data = { @@ -266,16 +294,16 @@ static struct mmci_platform_data v2m_mmci_data = { .status = v2m_mmci_status, }; -static AMBA_DEVICE(aaci, "mb:aaci", V2M_AACI, NULL); -static AMBA_DEVICE(mmci, "mb:mmci", V2M_MMCI, &v2m_mmci_data); -static AMBA_DEVICE(kmi0, "mb:kmi0", V2M_KMI0, NULL); -static AMBA_DEVICE(kmi1, "mb:kmi1", V2M_KMI1, NULL); -static AMBA_DEVICE(uart0, "mb:uart0", V2M_UART0, NULL); -static AMBA_DEVICE(uart1, "mb:uart1", V2M_UART1, NULL); -static AMBA_DEVICE(uart2, "mb:uart2", V2M_UART2, NULL); -static AMBA_DEVICE(uart3, "mb:uart3", V2M_UART3, NULL); -static AMBA_DEVICE(wdt, "mb:wdt", V2M_WDT, NULL); -static AMBA_DEVICE(rtc, "mb:rtc", V2M_RTC, NULL); +static AMBA_APB_DEVICE(aaci, "mb:aaci", 0, V2M_AACI, IRQ_V2M_AACI, NULL); +static AMBA_APB_DEVICE(mmci, "mb:mmci", 0, V2M_MMCI, IRQ_V2M_MMCI, &v2m_mmci_data); +static AMBA_APB_DEVICE(kmi0, "mb:kmi0", 0, V2M_KMI0, IRQ_V2M_KMI0, NULL); +static AMBA_APB_DEVICE(kmi1, "mb:kmi1", 0, V2M_KMI1, IRQ_V2M_KMI1, NULL); +static AMBA_APB_DEVICE(uart0, "mb:uart0", 0, V2M_UART0, IRQ_V2M_UART0, NULL); +static AMBA_APB_DEVICE(uart1, "mb:uart1", 0, V2M_UART1, IRQ_V2M_UART1, NULL); +static AMBA_APB_DEVICE(uart2, "mb:uart2", 0, V2M_UART2, IRQ_V2M_UART2, NULL); +static AMBA_APB_DEVICE(uart3, "mb:uart3", 0, V2M_UART3, IRQ_V2M_UART3, NULL); +static AMBA_APB_DEVICE(wdt, "mb:wdt", 0, V2M_WDT, IRQ_V2M_WDT, NULL); +static AMBA_APB_DEVICE(rtc, "mb:rtc", 0, V2M_RTC, IRQ_V2M_RTC, NULL); static struct amba_device *v2m_amba_devs[] __initdata = { &aaci_device, @@ -371,7 +399,7 @@ static void __init v2m_init_early(void) { ct_desc->init_early(); clkdev_add_table(v2m_lookups, ARRAY_SIZE(v2m_lookups)); - versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000); + versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000); } static void v2m_power_off(void) @@ -400,20 +428,23 @@ static void __init v2m_populate_ct_desc(void) u32 current_tile_id; ct_desc = NULL; - current_tile_id = readl(MMIO_P2V(V2M_SYS_PROCID0)) & V2M_CT_ID_MASK; + current_tile_id = readl(v2m_sysreg_base + V2M_SYS_PROCID0) + & V2M_CT_ID_MASK; for (i = 0; i < ARRAY_SIZE(ct_descs) && !ct_desc; ++i) if (ct_descs[i]->id == current_tile_id) ct_desc = ct_descs[i]; if (!ct_desc) - panic("vexpress: failed to populate core tile description " - "for tile ID 0x%8x\n", current_tile_id); + panic("vexpress: this kernel does not support core tile ID 0x%08x when booting via ATAGs.\n" + "You may need a device tree blob or a different kernel to boot on this board.\n", + current_tile_id); } static void __init v2m_map_io(void) { iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc)); + v2m_sysreg_base = ioremap(V2M_SYSREGS, SZ_4K); v2m_populate_ct_desc(); ct_desc->map_io(); } @@ -452,3 +483,205 @@ MACHINE_START(VEXPRESS, "ARM-Versatile Express") .init_machine = v2m_init, .restart = v2m_restart, MACHINE_END + +#if defined(CONFIG_ARCH_VEXPRESS_DT) + +static struct map_desc v2m_rs1_io_desc __initdata = { + .virtual = V2M_PERIPH, + .pfn = __phys_to_pfn(0x1c000000), + .length = SZ_2M, + .type = MT_DEVICE, +}; + +static int __init v2m_dt_scan_memory_map(unsigned long node, const char *uname, + int depth, void *data) +{ + const char **map = data; + + if (strcmp(uname, "motherboard") != 0) + return 0; + + *map = of_get_flat_dt_prop(node, "arm,v2m-memory-map", NULL); + + return 1; +} + +void __init v2m_dt_map_io(void) +{ + const char *map = NULL; + + of_scan_flat_dt(v2m_dt_scan_memory_map, &map); + + if (map && strcmp(map, "rs1") == 0) + iotable_init(&v2m_rs1_io_desc, 1); + else + iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc)); + +#if defined(CONFIG_SMP) + vexpress_dt_smp_map_io(); +#endif +} + +static struct clk_lookup v2m_dt_lookups[] = { + { /* AMBA bus clock */ + .con_id = "apb_pclk", + .clk = &dummy_apb_pclk, + }, { /* SP804 timers */ + .dev_id = "sp804", + .con_id = "v2m-timer0", + .clk = &v2m_sp804_clk, + }, { /* SP804 timers */ + .dev_id = "sp804", + .con_id = "v2m-timer1", + .clk = &v2m_sp804_clk, + }, { /* PL180 MMCI */ + .dev_id = "mb:mmci", /* 10005000.mmci */ + .clk = &osc2_clk, + }, { /* PL050 KMI0 */ + .dev_id = "10006000.kmi", + .clk = &osc2_clk, + }, { /* PL050 KMI1 */ + .dev_id = "10007000.kmi", + .clk = &osc2_clk, + }, { /* PL011 UART0 */ + .dev_id = "10009000.uart", + .clk = &osc2_clk, + }, { /* PL011 UART1 */ + .dev_id = "1000a000.uart", + .clk = &osc2_clk, + }, { /* PL011 UART2 */ + .dev_id = "1000b000.uart", + .clk = &osc2_clk, + }, { /* PL011 UART3 */ + .dev_id = "1000c000.uart", + .clk = &osc2_clk, + }, { /* SP805 WDT */ + .dev_id = "1000f000.wdt", + .clk = &v2m_ref_clk, + }, { /* PL111 CLCD */ + .dev_id = "1001f000.clcd", + .clk = &osc1_clk, + }, + /* RS1 memory map */ + { /* PL180 MMCI */ + .dev_id = "mb:mmci", /* 1c050000.mmci */ + .clk = &osc2_clk, + }, { /* PL050 KMI0 */ + .dev_id = "1c060000.kmi", + .clk = &osc2_clk, + }, { /* PL050 KMI1 */ + .dev_id = "1c070000.kmi", + .clk = &osc2_clk, + }, { /* PL011 UART0 */ + .dev_id = "1c090000.uart", + .clk = &osc2_clk, + }, { /* PL011 UART1 */ + .dev_id = "1c0a0000.uart", + .clk = &osc2_clk, + }, { /* PL011 UART2 */ + .dev_id = "1c0b0000.uart", + .clk = &osc2_clk, + }, { /* PL011 UART3 */ + .dev_id = "1c0c0000.uart", + .clk = &osc2_clk, + }, { /* SP805 WDT */ + .dev_id = "1c0f0000.wdt", + .clk = &v2m_ref_clk, + }, { /* PL111 CLCD */ + .dev_id = "1c1f0000.clcd", + .clk = &osc1_clk, + }, +}; + +void __init v2m_dt_init_early(void) +{ + struct device_node *node; + u32 dt_hbi; + + node = of_find_compatible_node(NULL, NULL, "arm,vexpress-sysreg"); + v2m_sysreg_base = of_iomap(node, 0); + if (WARN_ON(!v2m_sysreg_base)) + return; + + /* Confirm board type against DT property, if available */ + if (of_property_read_u32(allnodes, "arm,hbi", &dt_hbi) == 0) { + u32 misc = readl(v2m_sysreg_base + V2M_SYS_MISC); + u32 id = readl(v2m_sysreg_base + (misc & SYS_MISC_MASTERSITE ? + V2M_SYS_PROCID1 : V2M_SYS_PROCID0)); + u32 hbi = id & SYS_PROCIDx_HBI_MASK; + + if (WARN_ON(dt_hbi != hbi)) + pr_warning("vexpress: DT HBI (%x) is not matching " + "hardware (%x)!\n", dt_hbi, hbi); + } + + clkdev_add_table(v2m_dt_lookups, ARRAY_SIZE(v2m_dt_lookups)); + versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000); +} + +static struct of_device_id vexpress_irq_match[] __initdata = { + { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, }, + {} +}; + +static void __init v2m_dt_init_irq(void) +{ + of_irq_init(vexpress_irq_match); +} + +static void __init v2m_dt_timer_init(void) +{ + struct device_node *node; + const char *path; + int err; + + node = of_find_compatible_node(NULL, NULL, "arm,sp810"); + v2m_sysctl_init(of_iomap(node, 0)); + + err = of_property_read_string(of_aliases, "arm,v2m_timer", &path); + if (WARN_ON(err)) + return; + node = of_find_node_by_path(path); + v2m_sp804_init(of_iomap(node, 0), irq_of_parse_and_map(node, 0)); +} + +static struct sys_timer v2m_dt_timer = { + .init = v2m_dt_timer_init, +}; + +static struct of_dev_auxdata v2m_dt_auxdata_lookup[] __initdata = { + OF_DEV_AUXDATA("arm,vexpress-flash", V2M_NOR0, "physmap-flash", + &v2m_flash_data), + OF_DEV_AUXDATA("arm,primecell", V2M_MMCI, "mb:mmci", &v2m_mmci_data), + /* RS1 memory map */ + OF_DEV_AUXDATA("arm,vexpress-flash", 0x08000000, "physmap-flash", + &v2m_flash_data), + OF_DEV_AUXDATA("arm,primecell", 0x1c050000, "mb:mmci", &v2m_mmci_data), + {} +}; + +static void __init v2m_dt_init(void) +{ + l2x0_of_init(0x00400000, 0xfe0fffff); + of_platform_populate(NULL, of_default_bus_match_table, + v2m_dt_auxdata_lookup, NULL); + pm_power_off = v2m_power_off; +} + +const static char *v2m_dt_match[] __initconst = { + "arm,vexpress", + NULL, +}; + +DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express") + .dt_compat = v2m_dt_match, + .map_io = v2m_dt_map_io, + .init_early = v2m_dt_init_early, + .init_irq = v2m_dt_init_irq, + .timer = &v2m_dt_timer, + .init_machine = v2m_dt_init, + .handle_irq = gic_handle_irq, + .restart = v2m_restart, +MACHINE_END + +#endif diff --git a/arch/arm/mach-vt8500/include/mach/entry-macro.S b/arch/arm/mach-vt8500/include/mach/entry-macro.S index 92684c7eaed3..367d1b55fb9a 100644 --- a/arch/arm/mach-vt8500/include/mach/entry-macro.S +++ b/arch/arm/mach-vt8500/include/mach/entry-macro.S @@ -8,18 +8,12 @@ * warranty of any kind, whether express or implied. */ - .macro disable_fiq - .endm - .macro get_irqnr_preamble, base, tmp @ physical 0xd8140000 is virtual 0xf8140000 mov \base, #0xf8000000 orr \base, \base, #0x00140000 .endm - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \irqnr, [\base] cmp \irqnr, #63 @ may be false positive, check interrupt status diff --git a/arch/arm/mach-vt8500/include/mach/io.h b/arch/arm/mach-vt8500/include/mach/io.h deleted file mode 100644 index 46181eecf273..000000000000 --- a/arch/arm/mach-vt8500/include/mach/io.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * arch/arm/mach-vt8500/include/mach/io.h - * - * Copyright (C) 2010 Alexey Charkov - * - * 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_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -#define __io(a) __typesafe_io((a) + 0xf0000000) -#define __mem_pci(a) (a) - -#endif diff --git a/arch/arm/mach-vt8500/include/mach/system.h b/arch/arm/mach-vt8500/include/mach/system.h index d6c757eaf26b..58fa8010ee61 100644 --- a/arch/arm/mach-vt8500/include/mach/system.h +++ b/arch/arm/mach-vt8500/include/mach/system.h @@ -7,11 +7,6 @@ /* PM Software Reset request register */ #define VT8500_PMSR_VIRT 0xf8130060 -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - static inline void arch_reset(char mode, const char *cmd) { writel(1, VT8500_PMSR_VIRT); diff --git a/arch/arm/mach-w90x900/cpu.c b/arch/arm/mach-w90x900/cpu.c index 9a0661992909..9e4dd8b63c4a 100644 --- a/arch/arm/mach-w90x900/cpu.c +++ b/arch/arm/mach-w90x900/cpu.c @@ -28,6 +28,7 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> #include <asm/irq.h> +#include <asm/system_misc.h> #include <mach/hardware.h> #include <mach/regs-serial.h> diff --git a/arch/arm/mach-w90x900/dev.c b/arch/arm/mach-w90x900/dev.c index 78110befb7a9..48f5b9fdfb7f 100644 --- a/arch/arm/mach-w90x900/dev.c +++ b/arch/arm/mach-w90x900/dev.c @@ -27,6 +27,7 @@ #include <linux/spi/spi.h> #include <linux/spi/flash.h> +#include <asm/system_misc.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/irq.h> @@ -530,6 +531,7 @@ static struct platform_device *nuc900_public_dev[] __initdata = { void __init nuc900_board_init(struct platform_device **device, int size) { + disable_hlt(); platform_add_devices(device, size); platform_add_devices(nuc900_public_dev, ARRAY_SIZE(nuc900_public_dev)); spi_register_board_info(nuc900_spi_board_info, diff --git a/arch/arm/mach-w90x900/include/mach/entry-macro.S b/arch/arm/mach-w90x900/include/mach/entry-macro.S index d39aca5be9ee..e286daca6827 100644 --- a/arch/arm/mach-w90x900/include/mach/entry-macro.S +++ b/arch/arm/mach-w90x900/include/mach/entry-macro.S @@ -15,9 +15,6 @@ .macro get_irqnr_preamble, base, tmp .endm - .macro arch_ret_to_user, tmp1, tmp2 - .endm - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp mov \base, #AIC_BA @@ -27,8 +24,3 @@ cmp \irqnr, #0 .endm - - /* currently don't need an disable_fiq macro */ - - .macro disable_fiq - .endm diff --git a/arch/arm/mach-w90x900/include/mach/io.h b/arch/arm/mach-w90x900/include/mach/io.h deleted file mode 100644 index d96ab99df05b..000000000000 --- a/arch/arm/mach-w90x900/include/mach/io.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * arch/arm/mach-w90x900/include/mach/io.h - * - * Copyright (c) 2008 Nuvoton technology corporation - * All rights reserved. - * - * Wan ZongShun <mcuos.com@gmail.com> - * - * Based on arch/arm/mach-s3c2410/include/mach/io.h - * - * 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. - * - */ - -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -/* - * 1:1 mapping for ioremapped regions. - */ - -#define __mem_pci(a) (a) -#define __io(a) __typesafe_io(a) - -#endif diff --git a/arch/arm/mach-w90x900/include/mach/system.h b/arch/arm/mach-w90x900/include/mach/system.h deleted file mode 100644 index 2aaeb9311619..000000000000 --- a/arch/arm/mach-w90x900/include/mach/system.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/arm/mach-w90x900/include/mach/system.h - * - * Copyright (c) 2008 Nuvoton technology corporation - * All rights reserved. - * - * Wan ZongShun <mcuos.com@gmail.com> - * - * Based on arch/arm/mach-s3c2410/include/mach/system.h - * - * 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. - * - */ -static void arch_idle(void) -{ -} diff --git a/arch/arm/mach-zynq/include/mach/entry-macro.S b/arch/arm/mach-zynq/include/mach/entry-macro.S deleted file mode 100644 index d621fb732569..000000000000 --- a/arch/arm/mach-zynq/include/mach/entry-macro.S +++ /dev/null @@ -1,27 +0,0 @@ -/* - * arch/arm/mach-zynq/include/mach/entry-macro.S - * - * Low-level IRQ helper macros - * - * Copyright (C) 2011 Xilinx - * - * based on arch/plat-mxc/include/mach/entry-macro.S - * - * Copyright (C) 2007 Lennert Buytenhek <buytenh@wantstofly.org> - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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. - */ - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/mach-zynq/include/mach/io.h b/arch/arm/mach-zynq/include/mach/io.h deleted file mode 100644 index 39d9885e0e9a..000000000000 --- a/arch/arm/mach-zynq/include/mach/io.h +++ /dev/null @@ -1,33 +0,0 @@ -/* arch/arm/mach-zynq/include/mach/io.h - * - * Copyright (C) 2011 Xilinx - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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_IO_H__ -#define __MACH_IO_H__ - -/* Allow IO space to be anywhere in the memory */ - -#define IO_SPACE_LIMIT 0xffff - -/* IO address mapping macros, nothing special at this time but required */ - -#ifdef __ASSEMBLER__ -#define IOMEM(x) (x) -#else -#define IOMEM(x) ((void __force __iomem *)(x)) -#endif - -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#endif diff --git a/arch/arm/mach-zynq/include/mach/system.h b/arch/arm/mach-zynq/include/mach/system.h deleted file mode 100644 index 8e88e0b8d2ba..000000000000 --- a/arch/arm/mach-zynq/include/mach/system.h +++ /dev/null @@ -1,23 +0,0 @@ -/* arch/arm/mach-zynq/include/mach/system.h - * - * Copyright (C) 2011 Xilinx - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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_SYSTEM_H__ -#define __MACH_SYSTEM_H__ - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 7edef9121632..7c8a7d8467bf 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -723,7 +723,7 @@ config CPU_HIGH_VECTOR bool "Select the High exception vector" help Say Y here to select high exception vector(0xFFFF0000~). - The exception vector can be vary depending on the platform + The exception vector can vary depending on the platform design in nommu mode. If your platform needs to select high exception vector, say Y. Otherwise or if you are unsure, say N, and the low exception diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index caf14dc059e5..9107231aacc5 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -22,7 +22,8 @@ #include <linux/sched.h> #include <linux/uaccess.h> -#include <asm/system.h> +#include <asm/cp15.h> +#include <asm/system_info.h> #include <asm/unaligned.h> #include "fault.h" diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c index e0b0e7a4ec68..dd3d59122cc3 100644 --- a/arch/arm/mm/cache-feroceon-l2.c +++ b/arch/arm/mm/cache-feroceon-l2.c @@ -15,6 +15,7 @@ #include <linux/init.h> #include <linux/highmem.h> #include <asm/cacheflush.h> +#include <asm/cp15.h> #include <plat/cache-feroceon-l2.h> /* diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index b1e192ba8c24..a53fd2aaa2f4 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -30,13 +30,13 @@ static void __iomem *l2x0_base; static DEFINE_RAW_SPINLOCK(l2x0_lock); -static uint32_t l2x0_way_mask; /* Bitmask of active ways */ -static uint32_t l2x0_size; +static u32 l2x0_way_mask; /* Bitmask of active ways */ +static u32 l2x0_size; struct l2x0_regs l2x0_saved_regs; struct l2x0_of_data { - void (*setup)(const struct device_node *, __u32 *, __u32 *); + void (*setup)(const struct device_node *, u32 *, u32 *); void (*save)(void); void (*resume)(void); }; @@ -288,7 +288,7 @@ static void l2x0_disable(void) raw_spin_unlock_irqrestore(&l2x0_lock, flags); } -static void l2x0_unlock(__u32 cache_id) +static void l2x0_unlock(u32 cache_id) { int lockregs; int i; @@ -307,11 +307,11 @@ static void l2x0_unlock(__u32 cache_id) } } -void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) +void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask) { - __u32 aux; - __u32 cache_id; - __u32 way_size = 0; + u32 aux; + u32 cache_id; + u32 way_size = 0; int ways; const char *type; @@ -388,7 +388,7 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) #ifdef CONFIG_OF static void __init l2x0_of_setup(const struct device_node *np, - __u32 *aux_val, __u32 *aux_mask) + u32 *aux_val, u32 *aux_mask) { u32 data[2] = { 0, 0 }; u32 tag = 0; @@ -422,7 +422,7 @@ static void __init l2x0_of_setup(const struct device_node *np, } static void __init pl310_of_setup(const struct device_node *np, - __u32 *aux_val, __u32 *aux_mask) + u32 *aux_val, u32 *aux_mask) { u32 data[3] = { 0, 0, 0 }; u32 tag[3] = { 0, 0, 0 }; @@ -548,7 +548,7 @@ static const struct of_device_id l2x0_ids[] __initconst = { {} }; -int __init l2x0_of_init(__u32 aux_val, __u32 aux_mask) +int __init l2x0_of_init(u32 aux_val, u32 aux_mask) { struct device_node *np; struct l2x0_of_data *data; diff --git a/arch/arm/mm/cache-tauros2.c b/arch/arm/mm/cache-tauros2.c index 50868651890f..1fbca05fe906 100644 --- a/arch/arm/mm/cache-tauros2.c +++ b/arch/arm/mm/cache-tauros2.c @@ -16,6 +16,7 @@ #include <linux/init.h> #include <asm/cacheflush.h> +#include <asm/cp15.h> #include <asm/hardware/cache-tauros2.h> diff --git a/arch/arm/mm/cache-xsc3l2.c b/arch/arm/mm/cache-xsc3l2.c index 5a32020471e3..6c3edeb66e74 100644 --- a/arch/arm/mm/cache-xsc3l2.c +++ b/arch/arm/mm/cache-xsc3l2.c @@ -18,7 +18,7 @@ */ #include <linux/init.h> #include <linux/highmem.h> -#include <asm/system.h> +#include <asm/cp15.h> #include <asm/cputype.h> #include <asm/cacheflush.h> diff --git a/arch/arm/mm/copypage-v4mc.c b/arch/arm/mm/copypage-v4mc.c index ec8c3befb9c8..1267e64133b9 100644 --- a/arch/arm/mm/copypage-v4mc.c +++ b/arch/arm/mm/copypage-v4mc.c @@ -23,10 +23,6 @@ #include "mm.h" -/* - * 0xffff8000 to 0xffffffff is reserved for any ARM architecture - * specific hacks for copying pages efficiently. - */ #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ L_PTE_MT_MINICACHE) @@ -78,10 +74,9 @@ void v4_mc_copy_user_highpage(struct page *to, struct page *from, raw_spin_lock(&minicache_lock); - set_pte_ext(TOP_PTE(0xffff8000), pfn_pte(page_to_pfn(from), minicache_pgprot), 0); - flush_tlb_kernel_page(0xffff8000); + set_top_pte(COPYPAGE_MINICACHE, mk_pte(from, minicache_pgprot)); - mc_copy_user_page((void *)0xffff8000, kto); + mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto); raw_spin_unlock(&minicache_lock); diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c index 8b03a5814d00..b9bcc9d79176 100644 --- a/arch/arm/mm/copypage-v6.c +++ b/arch/arm/mm/copypage-v6.c @@ -24,9 +24,6 @@ #error FIX ME #endif -#define from_address (0xffff8000) -#define to_address (0xffffc000) - static DEFINE_RAW_SPINLOCK(v6_lock); /* @@ -90,14 +87,11 @@ static void v6_copy_user_highpage_aliasing(struct page *to, */ raw_spin_lock(&v6_lock); - set_pte_ext(TOP_PTE(from_address) + offset, pfn_pte(page_to_pfn(from), PAGE_KERNEL), 0); - set_pte_ext(TOP_PTE(to_address) + offset, pfn_pte(page_to_pfn(to), PAGE_KERNEL), 0); - - kfrom = from_address + (offset << PAGE_SHIFT); - kto = to_address + (offset << PAGE_SHIFT); + kfrom = COPYPAGE_V6_FROM + (offset << PAGE_SHIFT); + kto = COPYPAGE_V6_TO + (offset << PAGE_SHIFT); - flush_tlb_kernel_page(kfrom); - flush_tlb_kernel_page(kto); + set_top_pte(kfrom, mk_pte(from, PAGE_KERNEL)); + set_top_pte(kto, mk_pte(to, PAGE_KERNEL)); copy_page((void *)kto, (void *)kfrom); @@ -111,8 +105,7 @@ static void v6_copy_user_highpage_aliasing(struct page *to, */ static void v6_clear_user_highpage_aliasing(struct page *page, unsigned long vaddr) { - unsigned int offset = CACHE_COLOUR(vaddr); - unsigned long to = to_address + (offset << PAGE_SHIFT); + unsigned long to = COPYPAGE_V6_TO + (CACHE_COLOUR(vaddr) << PAGE_SHIFT); /* FIXME: not highmem safe */ discard_old_kernel_data(page_address(page)); @@ -123,8 +116,7 @@ static void v6_clear_user_highpage_aliasing(struct page *page, unsigned long vad */ raw_spin_lock(&v6_lock); - set_pte_ext(TOP_PTE(to_address) + offset, pfn_pte(page_to_pfn(page), PAGE_KERNEL), 0); - flush_tlb_kernel_page(to); + set_top_pte(to, mk_pte(page, PAGE_KERNEL)); clear_page((void *)to); raw_spin_unlock(&v6_lock); diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c index 439d106ae638..0fb85025344d 100644 --- a/arch/arm/mm/copypage-xscale.c +++ b/arch/arm/mm/copypage-xscale.c @@ -23,12 +23,6 @@ #include "mm.h" -/* - * 0xffff8000 to 0xffffffff is reserved for any ARM architecture - * specific hacks for copying pages efficiently. - */ -#define COPYPAGE_MINICACHE 0xffff8000 - #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ L_PTE_MT_MINICACHE) @@ -100,8 +94,7 @@ void xscale_mc_copy_user_highpage(struct page *to, struct page *from, raw_spin_lock(&minicache_lock); - set_pte_ext(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(page_to_pfn(from), minicache_pgprot), 0); - flush_tlb_kernel_page(COPYPAGE_MINICACHE); + set_top_pte(COPYPAGE_MINICACHE, mk_pte(from, minicache_pgprot)); mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto); diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 1aa664a1999f..db23ae4aaaab 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -214,7 +214,8 @@ static int __init consistent_init(void) core_initcall(consistent_init); static void * -__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot) +__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot, + const void *caller) { struct arm_vmregion *c; size_t align; @@ -241,7 +242,7 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot) * Allocate a virtual address in the consistent mapping region. */ c = arm_vmregion_alloc(&consistent_head, align, size, - gfp & ~(__GFP_DMA | __GFP_HIGHMEM)); + gfp & ~(__GFP_DMA | __GFP_HIGHMEM), caller); if (c) { pte_t *pte; int idx = CONSISTENT_PTE_INDEX(c->vm_start); @@ -320,14 +321,14 @@ static void __dma_free_remap(void *cpu_addr, size_t size) #else /* !CONFIG_MMU */ -#define __dma_alloc_remap(page, size, gfp, prot) page_address(page) +#define __dma_alloc_remap(page, size, gfp, prot, c) page_address(page) #define __dma_free_remap(addr, size) do { } while (0) #endif /* CONFIG_MMU */ static void * __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, - pgprot_t prot) + pgprot_t prot, const void *caller) { struct page *page; void *addr; @@ -349,7 +350,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, return NULL; if (!arch_is_coherent()) - addr = __dma_alloc_remap(page, size, gfp, prot); + addr = __dma_alloc_remap(page, size, gfp, prot, caller); else addr = page_address(page); @@ -374,7 +375,8 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gf return memory; return __dma_alloc(dev, size, handle, gfp, - pgprot_dmacoherent(pgprot_kernel)); + pgprot_dmacoherent(pgprot_kernel), + __builtin_return_address(0)); } EXPORT_SYMBOL(dma_alloc_coherent); @@ -386,7 +388,8 @@ void * dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) { return __dma_alloc(dev, size, handle, gfp, - pgprot_writecombine(pgprot_kernel)); + pgprot_writecombine(pgprot_kernel), + __builtin_return_address(0)); } EXPORT_SYMBOL(dma_alloc_writecombine); @@ -723,6 +726,9 @@ EXPORT_SYMBOL(dma_set_mask); static int __init dma_debug_do_init(void) { +#ifdef CONFIG_MMU + arm_vmregion_create_proc("dma-mappings", &consistent_head); +#endif dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); return 0; } diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index bb7eac381a8e..f07467533365 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -21,8 +21,9 @@ #include <linux/perf_event.h> #include <asm/exception.h> -#include <asm/system.h> #include <asm/pgtable.h> +#include <asm/system_misc.h> +#include <asm/system_info.h> #include <asm/tlbflush.h> #include "fault.h" @@ -164,7 +165,8 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr, struct siginfo si; #ifdef CONFIG_DEBUG_USER - if (user_debug & UDBG_SEGV) { + if (((user_debug & UDBG_SEGV) && (sig == SIGSEGV)) || + ((user_debug & UDBG_BUS) && (sig == SIGBUS))) { printk(KERN_DEBUG "%s: unhandled page fault (%d) at 0x%08lx, code 0x%03x\n", tsk->comm, sig, addr, fsr); show_pte(tsk->mm, addr); @@ -318,7 +320,7 @@ retry: */ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr); - if (flags & FAULT_FLAG_ALLOW_RETRY) { + if (!(fault & VM_FAULT_ERROR) && flags & FAULT_FLAG_ALLOW_RETRY) { if (fault & VM_FAULT_MAJOR) { tsk->maj_flt++; perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index 1a8d4aa821be..77458548e031 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -16,22 +16,18 @@ #include <asm/cachetype.h> #include <asm/highmem.h> #include <asm/smp_plat.h> -#include <asm/system.h> #include <asm/tlbflush.h> #include "mm.h" #ifdef CONFIG_CPU_CACHE_VIPT -#define ALIAS_FLUSH_START 0xffff4000 - static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr) { - unsigned long to = ALIAS_FLUSH_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT); + unsigned long to = FLUSH_ALIAS_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT); const int zero = 0; - set_pte_ext(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL), 0); - flush_tlb_kernel_page(to); + set_top_pte(to, pfn_pte(pfn, PAGE_KERNEL)); asm( "mcrr p15, 0, %1, %0, c14\n" " mcr p15, 0, %2, c7, c10, 4" @@ -42,13 +38,12 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr) static void flush_icache_alias(unsigned long pfn, unsigned long vaddr, unsigned long len) { - unsigned long colour = CACHE_COLOUR(vaddr); + unsigned long va = FLUSH_ALIAS_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT); unsigned long offset = vaddr & (PAGE_SIZE - 1); unsigned long to; - set_pte_ext(TOP_PTE(ALIAS_FLUSH_START) + colour, pfn_pte(pfn, PAGE_KERNEL), 0); - to = ALIAS_FLUSH_START + (colour << PAGE_SHIFT) + offset; - flush_tlb_kernel_page(to); + set_top_pte(va, pfn_pte(pfn, PAGE_KERNEL)); + to = va + offset; flush_icache_range(to, to + len); } diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c index 5a21505d7550..21b9e1bf9b77 100644 --- a/arch/arm/mm/highmem.c +++ b/arch/arm/mm/highmem.c @@ -69,15 +69,14 @@ void *kmap_atomic(struct page *page) * With debugging enabled, kunmap_atomic forces that entry to 0. * Make sure it was indeed properly unmapped. */ - BUG_ON(!pte_none(*(TOP_PTE(vaddr)))); + BUG_ON(!pte_none(get_top_pte(vaddr))); #endif - set_pte_ext(TOP_PTE(vaddr), mk_pte(page, kmap_prot), 0); /* * When debugging is off, kunmap_atomic leaves the previous mapping - * in place, so this TLB flush ensures the TLB is updated with the - * new mapping. + * in place, so the contained TLB flush ensures the TLB is updated + * with the new mapping. */ - local_flush_tlb_kernel_page(vaddr); + set_top_pte(vaddr, mk_pte(page, kmap_prot)); return (void *)vaddr; } @@ -96,8 +95,7 @@ void __kunmap_atomic(void *kvaddr) __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE); #ifdef CONFIG_DEBUG_HIGHMEM BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); - set_pte_ext(TOP_PTE(vaddr), __pte(0), 0); - local_flush_tlb_kernel_page(vaddr); + set_top_pte(vaddr, __pte(0)); #else (void) idx; /* to kill a warning */ #endif @@ -121,10 +119,9 @@ void *kmap_atomic_pfn(unsigned long pfn) idx = type + KM_TYPE_NR * smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); #ifdef CONFIG_DEBUG_HIGHMEM - BUG_ON(!pte_none(*(TOP_PTE(vaddr)))); + BUG_ON(!pte_none(get_top_pte(vaddr))); #endif - set_pte_ext(TOP_PTE(vaddr), pfn_pte(pfn, kmap_prot), 0); - local_flush_tlb_kernel_page(vaddr); + set_top_pte(vaddr, pfn_pte(pfn, kmap_prot)); return (void *)vaddr; } @@ -132,11 +129,9 @@ void *kmap_atomic_pfn(unsigned long pfn) struct page *kmap_atomic_to_page(const void *ptr) { unsigned long vaddr = (unsigned long)ptr; - pte_t *pte; if (vaddr < FIXADDR_START) return virt_to_page(ptr); - pte = TOP_PTE(vaddr); - return pte_page(*pte); + return pte_page(get_top_pte(vaddr)); } diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c index feacf4c76712..ab88ed4f8e08 100644 --- a/arch/arm/mm/idmap.c +++ b/arch/arm/mm/idmap.c @@ -5,6 +5,7 @@ #include <asm/pgalloc.h> #include <asm/pgtable.h> #include <asm/sections.h> +#include <asm/system_info.h> pgd_t *idmap_pgd; diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 245a55a0a5bb..595079fa9d1d 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -658,7 +658,9 @@ void __init mem_init(void) #ifdef CONFIG_HIGHMEM " pkmap : 0x%08lx - 0x%08lx (%4ld MB)\n" #endif +#ifdef CONFIG_MODULES " modules : 0x%08lx - 0x%08lx (%4ld MB)\n" +#endif " .text : 0x%p" " - 0x%p" " (%4d kB)\n" " .init : 0x%p" " - 0x%p" " (%4d kB)\n" " .data : 0x%p" " - 0x%p" " (%4d kB)\n" @@ -677,7 +679,9 @@ void __init mem_init(void) MLM(PKMAP_BASE, (PKMAP_BASE) + (LAST_PKMAP) * (PAGE_SIZE)), #endif +#ifdef CONFIG_MODULES MLM(MODULES_VADDR, MODULES_END), +#endif MLK_ROUNDUP(_text, _etext), MLK_ROUNDUP(__init_begin, __init_end), diff --git a/arch/arm/mm/iomap.c b/arch/arm/mm/iomap.c index e62956e12030..4614208369f1 100644 --- a/arch/arm/mm/iomap.c +++ b/arch/arm/mm/iomap.c @@ -32,9 +32,6 @@ EXPORT_SYMBOL(pcibios_min_io); unsigned long pcibios_min_mem = 0x01000000; EXPORT_SYMBOL(pcibios_min_mem); -unsigned int pci_flags = PCI_REASSIGN_ALL_RSRC; -EXPORT_SYMBOL(pci_flags); - void pci_iounmap(struct pci_dev *dev, void __iomem *addr) { if ((unsigned long)addr >= VMALLOC_START && diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index 80632e8d7538..4f55f5062ab7 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c @@ -26,12 +26,14 @@ #include <linux/vmalloc.h> #include <linux/io.h> +#include <asm/cp15.h> #include <asm/cputype.h> #include <asm/cacheflush.h> #include <asm/mmu_context.h> #include <asm/pgalloc.h> #include <asm/tlbflush.h> #include <asm/sizes.h> +#include <asm/system_info.h> #include <asm/mach/map.h> #include "mm.h" @@ -306,11 +308,15 @@ __arm_ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size, } EXPORT_SYMBOL(__arm_ioremap_pfn); +void __iomem * (*arch_ioremap_caller)(unsigned long, size_t, + unsigned int, void *) = + __arm_ioremap_caller; + void __iomem * __arm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype) { - return __arm_ioremap_caller(phys_addr, size, mtype, - __builtin_return_address(0)); + return arch_ioremap_caller(phys_addr, size, mtype, + __builtin_return_address(0)); } EXPORT_SYMBOL(__arm_ioremap); @@ -369,4 +375,11 @@ void __iounmap(volatile void __iomem *io_addr) vunmap(addr); } -EXPORT_SYMBOL(__iounmap); + +void (*arch_iounmap)(volatile void __iomem *) = __iounmap; + +void __arm_iounmap(volatile void __iomem *io_addr) +{ + arch_iounmap(io_addr); +} +EXPORT_SYMBOL(__arm_iounmap); diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index 70f6d3ea4834..27f4a619b35d 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h @@ -3,7 +3,31 @@ /* the upper-most page table pointer */ extern pmd_t *top_pmd; -#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) +/* + * 0xffff8000 to 0xffffffff is reserved for any ARM architecture + * specific hacks for copying pages efficiently, while 0xffff4000 + * is reserved for VIPT aliasing flushing by generic code. + * + * Note that we don't allow VIPT aliasing caches with SMP. + */ +#define COPYPAGE_MINICACHE 0xffff8000 +#define COPYPAGE_V6_FROM 0xffff8000 +#define COPYPAGE_V6_TO 0xffffc000 +/* PFN alias flushing, for VIPT caches */ +#define FLUSH_ALIAS_START 0xffff4000 + +static inline void set_top_pte(unsigned long va, pte_t pte) +{ + pte_t *ptep = pte_offset_kernel(top_pmd, va); + set_pte_ext(ptep, pte, 0); + local_flush_tlb_kernel_page(va); +} + +static inline pte_t get_top_pte(unsigned long va) +{ + pte_t *ptep = pte_offset_kernel(top_pmd, va); + return *ptep; +} static inline pmd_t *pmd_off_k(unsigned long virt) { diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 94c5a0c94f5e..b86f8933ff91 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -17,6 +17,7 @@ #include <linux/fs.h> #include <linux/vmalloc.h> +#include <asm/cp15.h> #include <asm/cputype.h> #include <asm/sections.h> #include <asm/cachetype.h> @@ -25,6 +26,7 @@ #include <asm/smp_plat.h> #include <asm/tlb.h> #include <asm/highmem.h> +#include <asm/system_info.h> #include <asm/traps.h> #include <asm/mach/arch.h> @@ -997,11 +999,14 @@ static void __init devicemaps_init(struct machine_desc *mdesc) { struct map_desc map; unsigned long addr; + void *vectors; /* * Allocate the vector page early. */ - vectors_page = early_alloc(PAGE_SIZE); + vectors = early_alloc(PAGE_SIZE); + + early_trap_init(vectors); for (addr = VMALLOC_START; addr; addr += PMD_SIZE) pmd_clear(pmd_off_k(addr)); @@ -1041,7 +1046,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc) * location (0xffff0000). If we aren't using high-vectors, also * create a mapping at the low-vectors virtual address. */ - map.pfn = __phys_to_pfn(virt_to_phys(vectors_page)); + map.pfn = __phys_to_pfn(virt_to_phys(vectors)); map.virtual = 0xffff0000; map.length = PAGE_SIZE; map.type = MT_HIGH_VECTORS; diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index 4fc6794cca4b..d51225f90ae2 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -13,6 +13,7 @@ #include <asm/sections.h> #include <asm/page.h> #include <asm/setup.h> +#include <asm/traps.h> #include <asm/mach/arch.h> #include "mm.h" @@ -39,6 +40,7 @@ void __init sanity_check_meminfo(void) */ void __init paging_init(struct machine_desc *mdesc) { + early_trap_init((void *)CONFIG_VECTORS_BASE); bootmem_init(); } @@ -86,13 +88,17 @@ void __iomem *__arm_ioremap(unsigned long phys_addr, size_t size, } EXPORT_SYMBOL(__arm_ioremap); +void __iomem * (*arch_ioremap_caller)(unsigned long, size_t, unsigned int, void *); + void __iomem *__arm_ioremap_caller(unsigned long phys_addr, size_t size, unsigned int mtype, void *caller) { return __arm_ioremap(phys_addr, size, mtype); } -void __iounmap(volatile void __iomem *addr) +void (*arch_iounmap)(volatile void __iomem *); + +void __arm_iounmap(volatile void __iomem *addr) { } -EXPORT_SYMBOL(__iounmap); +EXPORT_SYMBOL(__arm_iounmap); diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c index a3e78ccabd65..0acb089d0f70 100644 --- a/arch/arm/mm/pgd.c +++ b/arch/arm/mm/pgd.c @@ -12,6 +12,7 @@ #include <linux/highmem.h> #include <linux/slab.h> +#include <asm/cp15.h> #include <asm/pgalloc.h> #include <asm/page.h> #include <asm/tlbflush.h> diff --git a/arch/arm/mm/proc-fa526.S b/arch/arm/mm/proc-fa526.S index 272558a133a3..d217e9795d74 100644 --- a/arch/arm/mm/proc-fa526.S +++ b/arch/arm/mm/proc-fa526.S @@ -22,7 +22,6 @@ #include <asm/pgtable.h> #include <asm/page.h> #include <asm/ptrace.h> -#include <asm/system.h> #include "proc-macros.S" diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index f1c8486f7501..c2e2b66f72b5 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -255,6 +255,18 @@ __v7_setup: mcr p15, 0, r5, c10, c2, 0 @ write PRRR mcr p15, 0, r6, c10, c2, 1 @ write NMRR #endif +#ifndef CONFIG_ARM_THUMBEE + mrc p15, 0, r0, c0, c1, 0 @ read ID_PFR0 for ThumbEE + and r0, r0, #(0xf << 12) @ ThumbEE enabled field + teq r0, #(1 << 12) @ check if ThumbEE is present + bne 1f + mov r5, #0 + mcr p14, 6, r5, c1, c0, 0 @ Initialize TEEHBR to 0 + mrc p14, 6, r0, c0, c0, 0 @ load TEECR + orr r0, r0, #1 @ set the 1st bit in order to + mcr p14, 6, r0, c0, c0, 0 @ stop userspace TEEHBR access +1: +#endif adr r5, v7_crval ldmia r5, {r5, r6} #ifdef CONFIG_CPU_ENDIAN_BE8 diff --git a/arch/arm/mm/vmregion.c b/arch/arm/mm/vmregion.c index 036fdbfdd62f..a631016e1f8f 100644 --- a/arch/arm/mm/vmregion.c +++ b/arch/arm/mm/vmregion.c @@ -1,5 +1,8 @@ +#include <linux/fs.h> #include <linux/spinlock.h> #include <linux/list.h> +#include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/slab.h> #include "vmregion.h" @@ -36,7 +39,7 @@ struct arm_vmregion * arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align, - size_t size, gfp_t gfp) + size_t size, gfp_t gfp, const void *caller) { unsigned long start = head->vm_start, addr = head->vm_end; unsigned long flags; @@ -52,6 +55,8 @@ arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align, if (!new) goto out; + new->caller = caller; + spin_lock_irqsave(&head->vm_lock, flags); addr = rounddown(addr - size, align); @@ -129,3 +134,72 @@ void arm_vmregion_free(struct arm_vmregion_head *head, struct arm_vmregion *c) kfree(c); } + +#ifdef CONFIG_PROC_FS +static int arm_vmregion_show(struct seq_file *m, void *p) +{ + struct arm_vmregion *c = list_entry(p, struct arm_vmregion, vm_list); + + seq_printf(m, "0x%08lx-0x%08lx %7lu", c->vm_start, c->vm_end, + c->vm_end - c->vm_start); + if (c->caller) + seq_printf(m, " %pS", (void *)c->caller); + seq_putc(m, '\n'); + return 0; +} + +static void *arm_vmregion_start(struct seq_file *m, loff_t *pos) +{ + struct arm_vmregion_head *h = m->private; + spin_lock_irq(&h->vm_lock); + return seq_list_start(&h->vm_list, *pos); +} + +static void *arm_vmregion_next(struct seq_file *m, void *p, loff_t *pos) +{ + struct arm_vmregion_head *h = m->private; + return seq_list_next(p, &h->vm_list, pos); +} + +static void arm_vmregion_stop(struct seq_file *m, void *p) +{ + struct arm_vmregion_head *h = m->private; + spin_unlock_irq(&h->vm_lock); +} + +static const struct seq_operations arm_vmregion_ops = { + .start = arm_vmregion_start, + .stop = arm_vmregion_stop, + .next = arm_vmregion_next, + .show = arm_vmregion_show, +}; + +static int arm_vmregion_open(struct inode *inode, struct file *file) +{ + struct arm_vmregion_head *h = PDE(inode)->data; + int ret = seq_open(file, &arm_vmregion_ops); + if (!ret) { + struct seq_file *m = file->private_data; + m->private = h; + } + return ret; +} + +static const struct file_operations arm_vmregion_fops = { + .open = arm_vmregion_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +int arm_vmregion_create_proc(const char *path, struct arm_vmregion_head *h) +{ + proc_create_data(path, S_IRUSR, NULL, &arm_vmregion_fops, h); + return 0; +} +#else +int arm_vmregion_create_proc(const char *path, struct arm_vmregion_head *h) +{ + return 0; +} +#endif diff --git a/arch/arm/mm/vmregion.h b/arch/arm/mm/vmregion.h index 15e9f044db9f..162be662c088 100644 --- a/arch/arm/mm/vmregion.h +++ b/arch/arm/mm/vmregion.h @@ -19,11 +19,14 @@ struct arm_vmregion { unsigned long vm_end; struct page *vm_pages; int vm_active; + const void *caller; }; -struct arm_vmregion *arm_vmregion_alloc(struct arm_vmregion_head *, size_t, size_t, gfp_t); +struct arm_vmregion *arm_vmregion_alloc(struct arm_vmregion_head *, size_t, size_t, gfp_t, const void *); struct arm_vmregion *arm_vmregion_find(struct arm_vmregion_head *, unsigned long); struct arm_vmregion *arm_vmregion_find_remove(struct arm_vmregion_head *, unsigned long); void arm_vmregion_free(struct arm_vmregion_head *, struct arm_vmregion *); +int arm_vmregion_create_proc(const char *, struct arm_vmregion_head *); + #endif diff --git a/arch/arm/net/Makefile b/arch/arm/net/Makefile new file mode 100644 index 000000000000..c2c10841b6be --- /dev/null +++ b/arch/arm/net/Makefile @@ -0,0 +1,3 @@ +# ARM-specific networking code + +obj-$(CONFIG_BPF_JIT) += bpf_jit_32.o diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c new file mode 100644 index 000000000000..62135849f48b --- /dev/null +++ b/arch/arm/net/bpf_jit_32.c @@ -0,0 +1,915 @@ +/* + * Just-In-Time compiler for BPF filters on 32bit ARM + * + * Copyright (c) 2011 Mircea Gherzan <mgherzan@gmail.com> + * + * 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; version 2 of the License. + */ + +#include <linux/bitops.h> +#include <linux/compiler.h> +#include <linux/errno.h> +#include <linux/filter.h> +#include <linux/moduleloader.h> +#include <linux/netdevice.h> +#include <linux/string.h> +#include <linux/slab.h> +#include <asm/cacheflush.h> +#include <asm/hwcap.h> + +#include "bpf_jit_32.h" + +/* + * ABI: + * + * r0 scratch register + * r4 BPF register A + * r5 BPF register X + * r6 pointer to the skb + * r7 skb->data + * r8 skb_headlen(skb) + */ + +#define r_scratch ARM_R0 +/* r1-r3 are (also) used for the unaligned loads on the non-ARMv7 slowpath */ +#define r_off ARM_R1 +#define r_A ARM_R4 +#define r_X ARM_R5 +#define r_skb ARM_R6 +#define r_skb_data ARM_R7 +#define r_skb_hl ARM_R8 + +#define SCRATCH_SP_OFFSET 0 +#define SCRATCH_OFF(k) (SCRATCH_SP_OFFSET + (k)) + +#define SEEN_MEM ((1 << BPF_MEMWORDS) - 1) +#define SEEN_MEM_WORD(k) (1 << (k)) +#define SEEN_X (1 << BPF_MEMWORDS) +#define SEEN_CALL (1 << (BPF_MEMWORDS + 1)) +#define SEEN_SKB (1 << (BPF_MEMWORDS + 2)) +#define SEEN_DATA (1 << (BPF_MEMWORDS + 3)) + +#define FLAG_NEED_X_RESET (1 << 0) + +struct jit_ctx { + const struct sk_filter *skf; + unsigned idx; + unsigned prologue_bytes; + int ret0_fp_idx; + u32 seen; + u32 flags; + u32 *offsets; + u32 *target; +#if __LINUX_ARM_ARCH__ < 7 + u16 epilogue_bytes; + u16 imm_count; + u32 *imms; +#endif +}; + +int bpf_jit_enable __read_mostly; + +static u64 jit_get_skb_b(struct sk_buff *skb, unsigned offset) +{ + u8 ret; + int err; + + err = skb_copy_bits(skb, offset, &ret, 1); + + return (u64)err << 32 | ret; +} + +static u64 jit_get_skb_h(struct sk_buff *skb, unsigned offset) +{ + u16 ret; + int err; + + err = skb_copy_bits(skb, offset, &ret, 2); + + return (u64)err << 32 | ntohs(ret); +} + +static u64 jit_get_skb_w(struct sk_buff *skb, unsigned offset) +{ + u32 ret; + int err; + + err = skb_copy_bits(skb, offset, &ret, 4); + + return (u64)err << 32 | ntohl(ret); +} + +/* + * Wrapper that handles both OABI and EABI and assures Thumb2 interworking + * (where the assembly routines like __aeabi_uidiv could cause problems). + */ +static u32 jit_udiv(u32 dividend, u32 divisor) +{ + return dividend / divisor; +} + +static inline void _emit(int cond, u32 inst, struct jit_ctx *ctx) +{ + if (ctx->target != NULL) + ctx->target[ctx->idx] = inst | (cond << 28); + + ctx->idx++; +} + +/* + * Emit an instruction that will be executed unconditionally. + */ +static inline void emit(u32 inst, struct jit_ctx *ctx) +{ + _emit(ARM_COND_AL, inst, ctx); +} + +static u16 saved_regs(struct jit_ctx *ctx) +{ + u16 ret = 0; + + if ((ctx->skf->len > 1) || + (ctx->skf->insns[0].code == BPF_S_RET_A)) + ret |= 1 << r_A; + +#ifdef CONFIG_FRAME_POINTER + ret |= (1 << ARM_FP) | (1 << ARM_IP) | (1 << ARM_LR) | (1 << ARM_PC); +#else + if (ctx->seen & SEEN_CALL) + ret |= 1 << ARM_LR; +#endif + if (ctx->seen & (SEEN_DATA | SEEN_SKB)) + ret |= 1 << r_skb; + if (ctx->seen & SEEN_DATA) + ret |= (1 << r_skb_data) | (1 << r_skb_hl); + if (ctx->seen & SEEN_X) + ret |= 1 << r_X; + + return ret; +} + +static inline int mem_words_used(struct jit_ctx *ctx) +{ + /* yes, we do waste some stack space IF there are "holes" in the set" */ + return fls(ctx->seen & SEEN_MEM); +} + +static inline bool is_load_to_a(u16 inst) +{ + switch (inst) { + case BPF_S_LD_W_LEN: + case BPF_S_LD_W_ABS: + case BPF_S_LD_H_ABS: + case BPF_S_LD_B_ABS: + case BPF_S_ANC_CPU: + case BPF_S_ANC_IFINDEX: + case BPF_S_ANC_MARK: + case BPF_S_ANC_PROTOCOL: + case BPF_S_ANC_RXHASH: + case BPF_S_ANC_QUEUE: + return true; + default: + return false; + } +} + +static void build_prologue(struct jit_ctx *ctx) +{ + u16 reg_set = saved_regs(ctx); + u16 first_inst = ctx->skf->insns[0].code; + u16 off; + +#ifdef CONFIG_FRAME_POINTER + emit(ARM_MOV_R(ARM_IP, ARM_SP), ctx); + emit(ARM_PUSH(reg_set), ctx); + emit(ARM_SUB_I(ARM_FP, ARM_IP, 4), ctx); +#else + if (reg_set) + emit(ARM_PUSH(reg_set), ctx); +#endif + + if (ctx->seen & (SEEN_DATA | SEEN_SKB)) + emit(ARM_MOV_R(r_skb, ARM_R0), ctx); + + if (ctx->seen & SEEN_DATA) { + off = offsetof(struct sk_buff, data); + emit(ARM_LDR_I(r_skb_data, r_skb, off), ctx); + /* headlen = len - data_len */ + off = offsetof(struct sk_buff, len); + emit(ARM_LDR_I(r_skb_hl, r_skb, off), ctx); + off = offsetof(struct sk_buff, data_len); + emit(ARM_LDR_I(r_scratch, r_skb, off), ctx); + emit(ARM_SUB_R(r_skb_hl, r_skb_hl, r_scratch), ctx); + } + + if (ctx->flags & FLAG_NEED_X_RESET) + emit(ARM_MOV_I(r_X, 0), ctx); + + /* do not leak kernel data to userspace */ + if ((first_inst != BPF_S_RET_K) && !(is_load_to_a(first_inst))) + emit(ARM_MOV_I(r_A, 0), ctx); + + /* stack space for the BPF_MEM words */ + if (ctx->seen & SEEN_MEM) + emit(ARM_SUB_I(ARM_SP, ARM_SP, mem_words_used(ctx) * 4), ctx); +} + +static void build_epilogue(struct jit_ctx *ctx) +{ + u16 reg_set = saved_regs(ctx); + + if (ctx->seen & SEEN_MEM) + emit(ARM_ADD_I(ARM_SP, ARM_SP, mem_words_used(ctx) * 4), ctx); + + reg_set &= ~(1 << ARM_LR); + +#ifdef CONFIG_FRAME_POINTER + /* the first instruction of the prologue was: mov ip, sp */ + reg_set &= ~(1 << ARM_IP); + reg_set |= (1 << ARM_SP); + emit(ARM_LDM(ARM_SP, reg_set), ctx); +#else + if (reg_set) { + if (ctx->seen & SEEN_CALL) + reg_set |= 1 << ARM_PC; + emit(ARM_POP(reg_set), ctx); + } + + if (!(ctx->seen & SEEN_CALL)) + emit(ARM_BX(ARM_LR), ctx); +#endif +} + +static int16_t imm8m(u32 x) +{ + u32 rot; + + for (rot = 0; rot < 16; rot++) + if ((x & ~ror32(0xff, 2 * rot)) == 0) + return rol32(x, 2 * rot) | (rot << 8); + + return -1; +} + +#if __LINUX_ARM_ARCH__ < 7 + +static u16 imm_offset(u32 k, struct jit_ctx *ctx) +{ + unsigned i = 0, offset; + u16 imm; + + /* on the "fake" run we just count them (duplicates included) */ + if (ctx->target == NULL) { + ctx->imm_count++; + return 0; + } + + while ((i < ctx->imm_count) && ctx->imms[i]) { + if (ctx->imms[i] == k) + break; + i++; + } + + if (ctx->imms[i] == 0) + ctx->imms[i] = k; + + /* constants go just after the epilogue */ + offset = ctx->offsets[ctx->skf->len]; + offset += ctx->prologue_bytes; + offset += ctx->epilogue_bytes; + offset += i * 4; + + ctx->target[offset / 4] = k; + + /* PC in ARM mode == address of the instruction + 8 */ + imm = offset - (8 + ctx->idx * 4); + + return imm; +} + +#endif /* __LINUX_ARM_ARCH__ */ + +/* + * Move an immediate that's not an imm8m to a core register. + */ +static inline void emit_mov_i_no8m(int rd, u32 val, struct jit_ctx *ctx) +{ +#if __LINUX_ARM_ARCH__ < 7 + emit(ARM_LDR_I(rd, ARM_PC, imm_offset(val, ctx)), ctx); +#else + emit(ARM_MOVW(rd, val & 0xffff), ctx); + if (val > 0xffff) + emit(ARM_MOVT(rd, val >> 16), ctx); +#endif +} + +static inline void emit_mov_i(int rd, u32 val, struct jit_ctx *ctx) +{ + int imm12 = imm8m(val); + + if (imm12 >= 0) + emit(ARM_MOV_I(rd, imm12), ctx); + else + emit_mov_i_no8m(rd, val, ctx); +} + +#if __LINUX_ARM_ARCH__ < 6 + +static void emit_load_be32(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx) +{ + _emit(cond, ARM_LDRB_I(ARM_R3, r_addr, 1), ctx); + _emit(cond, ARM_LDRB_I(ARM_R1, r_addr, 0), ctx); + _emit(cond, ARM_LDRB_I(ARM_R2, r_addr, 3), ctx); + _emit(cond, ARM_LSL_I(ARM_R3, ARM_R3, 16), ctx); + _emit(cond, ARM_LDRB_I(ARM_R0, r_addr, 2), ctx); + _emit(cond, ARM_ORR_S(ARM_R3, ARM_R3, ARM_R1, SRTYPE_LSL, 24), ctx); + _emit(cond, ARM_ORR_R(ARM_R3, ARM_R3, ARM_R2), ctx); + _emit(cond, ARM_ORR_S(r_res, ARM_R3, ARM_R0, SRTYPE_LSL, 8), ctx); +} + +static void emit_load_be16(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx) +{ + _emit(cond, ARM_LDRB_I(ARM_R1, r_addr, 0), ctx); + _emit(cond, ARM_LDRB_I(ARM_R2, r_addr, 1), ctx); + _emit(cond, ARM_ORR_S(r_res, ARM_R2, ARM_R1, SRTYPE_LSL, 8), ctx); +} + +static inline void emit_swap16(u8 r_dst, u8 r_src, struct jit_ctx *ctx) +{ + emit(ARM_LSL_R(ARM_R1, r_src, 8), ctx); + emit(ARM_ORR_S(r_dst, ARM_R1, r_src, SRTYPE_LSL, 8), ctx); + emit(ARM_LSL_I(r_dst, r_dst, 8), ctx); + emit(ARM_LSL_R(r_dst, r_dst, 8), ctx); +} + +#else /* ARMv6+ */ + +static void emit_load_be32(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx) +{ + _emit(cond, ARM_LDR_I(r_res, r_addr, 0), ctx); +#ifdef __LITTLE_ENDIAN + _emit(cond, ARM_REV(r_res, r_res), ctx); +#endif +} + +static void emit_load_be16(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx) +{ + _emit(cond, ARM_LDRH_I(r_res, r_addr, 0), ctx); +#ifdef __LITTLE_ENDIAN + _emit(cond, ARM_REV16(r_res, r_res), ctx); +#endif +} + +static inline void emit_swap16(u8 r_dst __maybe_unused, + u8 r_src __maybe_unused, + struct jit_ctx *ctx __maybe_unused) +{ +#ifdef __LITTLE_ENDIAN + emit(ARM_REV16(r_dst, r_src), ctx); +#endif +} + +#endif /* __LINUX_ARM_ARCH__ < 6 */ + + +/* Compute the immediate value for a PC-relative branch. */ +static inline u32 b_imm(unsigned tgt, struct jit_ctx *ctx) +{ + u32 imm; + + if (ctx->target == NULL) + return 0; + /* + * BPF allows only forward jumps and the offset of the target is + * still the one computed during the first pass. + */ + imm = ctx->offsets[tgt] + ctx->prologue_bytes - (ctx->idx * 4 + 8); + + return imm >> 2; +} + +#define OP_IMM3(op, r1, r2, imm_val, ctx) \ + do { \ + imm12 = imm8m(imm_val); \ + if (imm12 < 0) { \ + emit_mov_i_no8m(r_scratch, imm_val, ctx); \ + emit(op ## _R((r1), (r2), r_scratch), ctx); \ + } else { \ + emit(op ## _I((r1), (r2), imm12), ctx); \ + } \ + } while (0) + +static inline void emit_err_ret(u8 cond, struct jit_ctx *ctx) +{ + if (ctx->ret0_fp_idx >= 0) { + _emit(cond, ARM_B(b_imm(ctx->ret0_fp_idx, ctx)), ctx); + /* NOP to keep the size constant between passes */ + emit(ARM_MOV_R(ARM_R0, ARM_R0), ctx); + } else { + _emit(cond, ARM_MOV_I(ARM_R0, 0), ctx); + _emit(cond, ARM_B(b_imm(ctx->skf->len, ctx)), ctx); + } +} + +static inline void emit_blx_r(u8 tgt_reg, struct jit_ctx *ctx) +{ +#if __LINUX_ARM_ARCH__ < 5 + emit(ARM_MOV_R(ARM_LR, ARM_PC), ctx); + + if (elf_hwcap & HWCAP_THUMB) + emit(ARM_BX(tgt_reg), ctx); + else + emit(ARM_MOV_R(ARM_PC, tgt_reg), ctx); +#else + emit(ARM_BLX_R(tgt_reg), ctx); +#endif +} + +static inline void emit_udiv(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx) +{ +#if __LINUX_ARM_ARCH__ == 7 + if (elf_hwcap & HWCAP_IDIVA) { + emit(ARM_UDIV(rd, rm, rn), ctx); + return; + } +#endif + if (rm != ARM_R0) + emit(ARM_MOV_R(ARM_R0, rm), ctx); + if (rn != ARM_R1) + emit(ARM_MOV_R(ARM_R1, rn), ctx); + + ctx->seen |= SEEN_CALL; + emit_mov_i(ARM_R3, (u32)jit_udiv, ctx); + emit_blx_r(ARM_R3, ctx); + + if (rd != ARM_R0) + emit(ARM_MOV_R(rd, ARM_R0), ctx); +} + +static inline void update_on_xread(struct jit_ctx *ctx) +{ + if (!(ctx->seen & SEEN_X)) + ctx->flags |= FLAG_NEED_X_RESET; + + ctx->seen |= SEEN_X; +} + +static int build_body(struct jit_ctx *ctx) +{ + void *load_func[] = {jit_get_skb_b, jit_get_skb_h, jit_get_skb_w}; + const struct sk_filter *prog = ctx->skf; + const struct sock_filter *inst; + unsigned i, load_order, off, condt; + int imm12; + u32 k; + + for (i = 0; i < prog->len; i++) { + inst = &(prog->insns[i]); + /* K as an immediate value operand */ + k = inst->k; + + /* compute offsets only in the fake pass */ + if (ctx->target == NULL) + ctx->offsets[i] = ctx->idx * 4; + + switch (inst->code) { + case BPF_S_LD_IMM: + emit_mov_i(r_A, k, ctx); + break; + case BPF_S_LD_W_LEN: + ctx->seen |= SEEN_SKB; + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4); + emit(ARM_LDR_I(r_A, r_skb, + offsetof(struct sk_buff, len)), ctx); + break; + case BPF_S_LD_MEM: + /* A = scratch[k] */ + ctx->seen |= SEEN_MEM_WORD(k); + emit(ARM_LDR_I(r_A, ARM_SP, SCRATCH_OFF(k)), ctx); + break; + case BPF_S_LD_W_ABS: + load_order = 2; + goto load; + case BPF_S_LD_H_ABS: + load_order = 1; + goto load; + case BPF_S_LD_B_ABS: + load_order = 0; +load: + /* the interpreter will deal with the negative K */ + if ((int)k < 0) + return -ENOTSUPP; + emit_mov_i(r_off, k, ctx); +load_common: + ctx->seen |= SEEN_DATA | SEEN_CALL; + + if (load_order > 0) { + emit(ARM_SUB_I(r_scratch, r_skb_hl, + 1 << load_order), ctx); + emit(ARM_CMP_R(r_scratch, r_off), ctx); + condt = ARM_COND_HS; + } else { + emit(ARM_CMP_R(r_skb_hl, r_off), ctx); + condt = ARM_COND_HI; + } + + _emit(condt, ARM_ADD_R(r_scratch, r_off, r_skb_data), + ctx); + + if (load_order == 0) + _emit(condt, ARM_LDRB_I(r_A, r_scratch, 0), + ctx); + else if (load_order == 1) + emit_load_be16(condt, r_A, r_scratch, ctx); + else if (load_order == 2) + emit_load_be32(condt, r_A, r_scratch, ctx); + + _emit(condt, ARM_B(b_imm(i + 1, ctx)), ctx); + + /* the slowpath */ + emit_mov_i(ARM_R3, (u32)load_func[load_order], ctx); + emit(ARM_MOV_R(ARM_R0, r_skb), ctx); + /* the offset is already in R1 */ + emit_blx_r(ARM_R3, ctx); + /* check the result of skb_copy_bits */ + emit(ARM_CMP_I(ARM_R1, 0), ctx); + emit_err_ret(ARM_COND_NE, ctx); + emit(ARM_MOV_R(r_A, ARM_R0), ctx); + break; + case BPF_S_LD_W_IND: + load_order = 2; + goto load_ind; + case BPF_S_LD_H_IND: + load_order = 1; + goto load_ind; + case BPF_S_LD_B_IND: + load_order = 0; +load_ind: + OP_IMM3(ARM_ADD, r_off, r_X, k, ctx); + goto load_common; + case BPF_S_LDX_IMM: + ctx->seen |= SEEN_X; + emit_mov_i(r_X, k, ctx); + break; + case BPF_S_LDX_W_LEN: + ctx->seen |= SEEN_X | SEEN_SKB; + emit(ARM_LDR_I(r_X, r_skb, + offsetof(struct sk_buff, len)), ctx); + break; + case BPF_S_LDX_MEM: + ctx->seen |= SEEN_X | SEEN_MEM_WORD(k); + emit(ARM_LDR_I(r_X, ARM_SP, SCRATCH_OFF(k)), ctx); + break; + case BPF_S_LDX_B_MSH: + /* x = ((*(frame + k)) & 0xf) << 2; */ + ctx->seen |= SEEN_X | SEEN_DATA | SEEN_CALL; + /* the interpreter should deal with the negative K */ + if (k < 0) + return -1; + /* offset in r1: we might have to take the slow path */ + emit_mov_i(r_off, k, ctx); + emit(ARM_CMP_R(r_skb_hl, r_off), ctx); + + /* load in r0: common with the slowpath */ + _emit(ARM_COND_HI, ARM_LDRB_R(ARM_R0, r_skb_data, + ARM_R1), ctx); + /* + * emit_mov_i() might generate one or two instructions, + * the same holds for emit_blx_r() + */ + _emit(ARM_COND_HI, ARM_B(b_imm(i + 1, ctx) - 2), ctx); + + emit(ARM_MOV_R(ARM_R0, r_skb), ctx); + /* r_off is r1 */ + emit_mov_i(ARM_R3, (u32)jit_get_skb_b, ctx); + emit_blx_r(ARM_R3, ctx); + /* check the return value of skb_copy_bits */ + emit(ARM_CMP_I(ARM_R1, 0), ctx); + emit_err_ret(ARM_COND_NE, ctx); + + emit(ARM_AND_I(r_X, ARM_R0, 0x00f), ctx); + emit(ARM_LSL_I(r_X, r_X, 2), ctx); + break; + case BPF_S_ST: + ctx->seen |= SEEN_MEM_WORD(k); + emit(ARM_STR_I(r_A, ARM_SP, SCRATCH_OFF(k)), ctx); + break; + case BPF_S_STX: + update_on_xread(ctx); + ctx->seen |= SEEN_MEM_WORD(k); + emit(ARM_STR_I(r_X, ARM_SP, SCRATCH_OFF(k)), ctx); + break; + case BPF_S_ALU_ADD_K: + /* A += K */ + OP_IMM3(ARM_ADD, r_A, r_A, k, ctx); + break; + case BPF_S_ALU_ADD_X: + update_on_xread(ctx); + emit(ARM_ADD_R(r_A, r_A, r_X), ctx); + break; + case BPF_S_ALU_SUB_K: + /* A -= K */ + OP_IMM3(ARM_SUB, r_A, r_A, k, ctx); + break; + case BPF_S_ALU_SUB_X: + update_on_xread(ctx); + emit(ARM_SUB_R(r_A, r_A, r_X), ctx); + break; + case BPF_S_ALU_MUL_K: + /* A *= K */ + emit_mov_i(r_scratch, k, ctx); + emit(ARM_MUL(r_A, r_A, r_scratch), ctx); + break; + case BPF_S_ALU_MUL_X: + update_on_xread(ctx); + emit(ARM_MUL(r_A, r_A, r_X), ctx); + break; + case BPF_S_ALU_DIV_K: + /* current k == reciprocal_value(userspace k) */ + emit_mov_i(r_scratch, k, ctx); + /* A = top 32 bits of the product */ + emit(ARM_UMULL(r_scratch, r_A, r_A, r_scratch), ctx); + break; + case BPF_S_ALU_DIV_X: + update_on_xread(ctx); + emit(ARM_CMP_I(r_X, 0), ctx); + emit_err_ret(ARM_COND_EQ, ctx); + emit_udiv(r_A, r_A, r_X, ctx); + break; + case BPF_S_ALU_OR_K: + /* A |= K */ + OP_IMM3(ARM_ORR, r_A, r_A, k, ctx); + break; + case BPF_S_ALU_OR_X: + update_on_xread(ctx); + emit(ARM_ORR_R(r_A, r_A, r_X), ctx); + break; + case BPF_S_ALU_AND_K: + /* A &= K */ + OP_IMM3(ARM_AND, r_A, r_A, k, ctx); + break; + case BPF_S_ALU_AND_X: + update_on_xread(ctx); + emit(ARM_AND_R(r_A, r_A, r_X), ctx); + break; + case BPF_S_ALU_LSH_K: + if (unlikely(k > 31)) + return -1; + emit(ARM_LSL_I(r_A, r_A, k), ctx); + break; + case BPF_S_ALU_LSH_X: + update_on_xread(ctx); + emit(ARM_LSL_R(r_A, r_A, r_X), ctx); + break; + case BPF_S_ALU_RSH_K: + if (unlikely(k > 31)) + return -1; + emit(ARM_LSR_I(r_A, r_A, k), ctx); + break; + case BPF_S_ALU_RSH_X: + update_on_xread(ctx); + emit(ARM_LSR_R(r_A, r_A, r_X), ctx); + break; + case BPF_S_ALU_NEG: + /* A = -A */ + emit(ARM_RSB_I(r_A, r_A, 0), ctx); + break; + case BPF_S_JMP_JA: + /* pc += K */ + emit(ARM_B(b_imm(i + k + 1, ctx)), ctx); + break; + case BPF_S_JMP_JEQ_K: + /* pc += (A == K) ? pc->jt : pc->jf */ + condt = ARM_COND_EQ; + goto cmp_imm; + case BPF_S_JMP_JGT_K: + /* pc += (A > K) ? pc->jt : pc->jf */ + condt = ARM_COND_HI; + goto cmp_imm; + case BPF_S_JMP_JGE_K: + /* pc += (A >= K) ? pc->jt : pc->jf */ + condt = ARM_COND_HS; +cmp_imm: + imm12 = imm8m(k); + if (imm12 < 0) { + emit_mov_i_no8m(r_scratch, k, ctx); + emit(ARM_CMP_R(r_A, r_scratch), ctx); + } else { + emit(ARM_CMP_I(r_A, imm12), ctx); + } +cond_jump: + if (inst->jt) + _emit(condt, ARM_B(b_imm(i + inst->jt + 1, + ctx)), ctx); + if (inst->jf) + _emit(condt ^ 1, ARM_B(b_imm(i + inst->jf + 1, + ctx)), ctx); + break; + case BPF_S_JMP_JEQ_X: + /* pc += (A == X) ? pc->jt : pc->jf */ + condt = ARM_COND_EQ; + goto cmp_x; + case BPF_S_JMP_JGT_X: + /* pc += (A > X) ? pc->jt : pc->jf */ + condt = ARM_COND_HI; + goto cmp_x; + case BPF_S_JMP_JGE_X: + /* pc += (A >= X) ? pc->jt : pc->jf */ + condt = ARM_COND_CS; +cmp_x: + update_on_xread(ctx); + emit(ARM_CMP_R(r_A, r_X), ctx); + goto cond_jump; + case BPF_S_JMP_JSET_K: + /* pc += (A & K) ? pc->jt : pc->jf */ + condt = ARM_COND_NE; + /* not set iff all zeroes iff Z==1 iff EQ */ + + imm12 = imm8m(k); + if (imm12 < 0) { + emit_mov_i_no8m(r_scratch, k, ctx); + emit(ARM_TST_R(r_A, r_scratch), ctx); + } else { + emit(ARM_TST_I(r_A, imm12), ctx); + } + goto cond_jump; + case BPF_S_JMP_JSET_X: + /* pc += (A & X) ? pc->jt : pc->jf */ + update_on_xread(ctx); + condt = ARM_COND_NE; + emit(ARM_TST_R(r_A, r_X), ctx); + goto cond_jump; + case BPF_S_RET_A: + emit(ARM_MOV_R(ARM_R0, r_A), ctx); + goto b_epilogue; + case BPF_S_RET_K: + if ((k == 0) && (ctx->ret0_fp_idx < 0)) + ctx->ret0_fp_idx = i; + emit_mov_i(ARM_R0, k, ctx); +b_epilogue: + if (i != ctx->skf->len - 1) + emit(ARM_B(b_imm(prog->len, ctx)), ctx); + break; + case BPF_S_MISC_TAX: + /* X = A */ + ctx->seen |= SEEN_X; + emit(ARM_MOV_R(r_X, r_A), ctx); + break; + case BPF_S_MISC_TXA: + /* A = X */ + update_on_xread(ctx); + emit(ARM_MOV_R(r_A, r_X), ctx); + break; + case BPF_S_ANC_PROTOCOL: + /* A = ntohs(skb->protocol) */ + ctx->seen |= SEEN_SKB; + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, + protocol) != 2); + off = offsetof(struct sk_buff, protocol); + emit(ARM_LDRH_I(r_scratch, r_skb, off), ctx); + emit_swap16(r_A, r_scratch, ctx); + break; + case BPF_S_ANC_CPU: + /* r_scratch = current_thread_info() */ + OP_IMM3(ARM_BIC, r_scratch, ARM_SP, THREAD_SIZE - 1, ctx); + /* A = current_thread_info()->cpu */ + BUILD_BUG_ON(FIELD_SIZEOF(struct thread_info, cpu) != 4); + off = offsetof(struct thread_info, cpu); + emit(ARM_LDR_I(r_A, r_scratch, off), ctx); + break; + case BPF_S_ANC_IFINDEX: + /* A = skb->dev->ifindex */ + ctx->seen |= SEEN_SKB; + off = offsetof(struct sk_buff, dev); + emit(ARM_LDR_I(r_scratch, r_skb, off), ctx); + + emit(ARM_CMP_I(r_scratch, 0), ctx); + emit_err_ret(ARM_COND_EQ, ctx); + + BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, + ifindex) != 4); + off = offsetof(struct net_device, ifindex); + emit(ARM_LDR_I(r_A, r_scratch, off), ctx); + break; + case BPF_S_ANC_MARK: + ctx->seen |= SEEN_SKB; + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4); + off = offsetof(struct sk_buff, mark); + emit(ARM_LDR_I(r_A, r_skb, off), ctx); + break; + case BPF_S_ANC_RXHASH: + ctx->seen |= SEEN_SKB; + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, rxhash) != 4); + off = offsetof(struct sk_buff, rxhash); + emit(ARM_LDR_I(r_A, r_skb, off), ctx); + break; + case BPF_S_ANC_QUEUE: + ctx->seen |= SEEN_SKB; + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, + queue_mapping) != 2); + BUILD_BUG_ON(offsetof(struct sk_buff, + queue_mapping) > 0xff); + off = offsetof(struct sk_buff, queue_mapping); + emit(ARM_LDRH_I(r_A, r_skb, off), ctx); + break; + default: + return -1; + } + } + + /* compute offsets only during the first pass */ + if (ctx->target == NULL) + ctx->offsets[i] = ctx->idx * 4; + + return 0; +} + + +void bpf_jit_compile(struct sk_filter *fp) +{ + struct jit_ctx ctx; + unsigned tmp_idx; + unsigned alloc_size; + + if (!bpf_jit_enable) + return; + + memset(&ctx, 0, sizeof(ctx)); + ctx.skf = fp; + ctx.ret0_fp_idx = -1; + + ctx.offsets = kzalloc(GFP_KERNEL, 4 * (ctx.skf->len + 1)); + if (ctx.offsets == NULL) + return; + + /* fake pass to fill in the ctx->seen */ + if (unlikely(build_body(&ctx))) + goto out; + + tmp_idx = ctx.idx; + build_prologue(&ctx); + ctx.prologue_bytes = (ctx.idx - tmp_idx) * 4; + +#if __LINUX_ARM_ARCH__ < 7 + tmp_idx = ctx.idx; + build_epilogue(&ctx); + ctx.epilogue_bytes = (ctx.idx - tmp_idx) * 4; + + ctx.idx += ctx.imm_count; + if (ctx.imm_count) { + ctx.imms = kzalloc(GFP_KERNEL, 4 * ctx.imm_count); + if (ctx.imms == NULL) + goto out; + } +#else + /* there's nothing after the epilogue on ARMv7 */ + build_epilogue(&ctx); +#endif + + alloc_size = 4 * ctx.idx; + ctx.target = module_alloc(max(sizeof(struct work_struct), + alloc_size)); + if (unlikely(ctx.target == NULL)) + goto out; + + ctx.idx = 0; + build_prologue(&ctx); + build_body(&ctx); + build_epilogue(&ctx); + + flush_icache_range((u32)ctx.target, (u32)(ctx.target + ctx.idx)); + +#if __LINUX_ARM_ARCH__ < 7 + if (ctx.imm_count) + kfree(ctx.imms); +#endif + + if (bpf_jit_enable > 1) + print_hex_dump(KERN_INFO, "BPF JIT code: ", + DUMP_PREFIX_ADDRESS, 16, 4, ctx.target, + alloc_size, false); + + fp->bpf_func = (void *)ctx.target; +out: + kfree(ctx.offsets); + return; +} + +static void bpf_jit_free_worker(struct work_struct *work) +{ + module_free(NULL, work); +} + +void bpf_jit_free(struct sk_filter *fp) +{ + struct work_struct *work; + + if (fp->bpf_func != sk_run_filter) { + work = (struct work_struct *)fp->bpf_func; + + INIT_WORK(work, bpf_jit_free_worker); + schedule_work(work); + } +} diff --git a/arch/arm/net/bpf_jit_32.h b/arch/arm/net/bpf_jit_32.h new file mode 100644 index 000000000000..99ae5e3f46d2 --- /dev/null +++ b/arch/arm/net/bpf_jit_32.h @@ -0,0 +1,190 @@ +/* + * Just-In-Time compiler for BPF filters on 32bit ARM + * + * Copyright (c) 2011 Mircea Gherzan <mgherzan@gmail.com> + * + * 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; version 2 of the License. + */ + +#ifndef PFILTER_OPCODES_ARM_H +#define PFILTER_OPCODES_ARM_H + +#define ARM_R0 0 +#define ARM_R1 1 +#define ARM_R2 2 +#define ARM_R3 3 +#define ARM_R4 4 +#define ARM_R5 5 +#define ARM_R6 6 +#define ARM_R7 7 +#define ARM_R8 8 +#define ARM_R9 9 +#define ARM_R10 10 +#define ARM_FP 11 +#define ARM_IP 12 +#define ARM_SP 13 +#define ARM_LR 14 +#define ARM_PC 15 + +#define ARM_COND_EQ 0x0 +#define ARM_COND_NE 0x1 +#define ARM_COND_CS 0x2 +#define ARM_COND_HS ARM_COND_CS +#define ARM_COND_CC 0x3 +#define ARM_COND_LO ARM_COND_CC +#define ARM_COND_MI 0x4 +#define ARM_COND_PL 0x5 +#define ARM_COND_VS 0x6 +#define ARM_COND_VC 0x7 +#define ARM_COND_HI 0x8 +#define ARM_COND_LS 0x9 +#define ARM_COND_GE 0xa +#define ARM_COND_LT 0xb +#define ARM_COND_GT 0xc +#define ARM_COND_LE 0xd +#define ARM_COND_AL 0xe + +/* register shift types */ +#define SRTYPE_LSL 0 +#define SRTYPE_LSR 1 +#define SRTYPE_ASR 2 +#define SRTYPE_ROR 3 + +#define ARM_INST_ADD_R 0x00800000 +#define ARM_INST_ADD_I 0x02800000 + +#define ARM_INST_AND_R 0x00000000 +#define ARM_INST_AND_I 0x02000000 + +#define ARM_INST_BIC_R 0x01c00000 +#define ARM_INST_BIC_I 0x03c00000 + +#define ARM_INST_B 0x0a000000 +#define ARM_INST_BX 0x012FFF10 +#define ARM_INST_BLX_R 0x012fff30 + +#define ARM_INST_CMP_R 0x01500000 +#define ARM_INST_CMP_I 0x03500000 + +#define ARM_INST_LDRB_I 0x05d00000 +#define ARM_INST_LDRB_R 0x07d00000 +#define ARM_INST_LDRH_I 0x01d000b0 +#define ARM_INST_LDR_I 0x05900000 + +#define ARM_INST_LDM 0x08900000 + +#define ARM_INST_LSL_I 0x01a00000 +#define ARM_INST_LSL_R 0x01a00010 + +#define ARM_INST_LSR_I 0x01a00020 +#define ARM_INST_LSR_R 0x01a00030 + +#define ARM_INST_MOV_R 0x01a00000 +#define ARM_INST_MOV_I 0x03a00000 +#define ARM_INST_MOVW 0x03000000 +#define ARM_INST_MOVT 0x03400000 + +#define ARM_INST_MUL 0x00000090 + +#define ARM_INST_POP 0x08bd0000 +#define ARM_INST_PUSH 0x092d0000 + +#define ARM_INST_ORR_R 0x01800000 +#define ARM_INST_ORR_I 0x03800000 + +#define ARM_INST_REV 0x06bf0f30 +#define ARM_INST_REV16 0x06bf0fb0 + +#define ARM_INST_RSB_I 0x02600000 + +#define ARM_INST_SUB_R 0x00400000 +#define ARM_INST_SUB_I 0x02400000 + +#define ARM_INST_STR_I 0x05800000 + +#define ARM_INST_TST_R 0x01100000 +#define ARM_INST_TST_I 0x03100000 + +#define ARM_INST_UDIV 0x0730f010 + +#define ARM_INST_UMULL 0x00800090 + +/* register */ +#define _AL3_R(op, rd, rn, rm) ((op ## _R) | (rd) << 12 | (rn) << 16 | (rm)) +/* immediate */ +#define _AL3_I(op, rd, rn, imm) ((op ## _I) | (rd) << 12 | (rn) << 16 | (imm)) + +#define ARM_ADD_R(rd, rn, rm) _AL3_R(ARM_INST_ADD, rd, rn, rm) +#define ARM_ADD_I(rd, rn, imm) _AL3_I(ARM_INST_ADD, rd, rn, imm) + +#define ARM_AND_R(rd, rn, rm) _AL3_R(ARM_INST_AND, rd, rn, rm) +#define ARM_AND_I(rd, rn, imm) _AL3_I(ARM_INST_AND, rd, rn, imm) + +#define ARM_BIC_R(rd, rn, rm) _AL3_R(ARM_INST_BIC, rd, rn, rm) +#define ARM_BIC_I(rd, rn, imm) _AL3_I(ARM_INST_BIC, rd, rn, imm) + +#define ARM_B(imm24) (ARM_INST_B | ((imm24) & 0xffffff)) +#define ARM_BX(rm) (ARM_INST_BX | (rm)) +#define ARM_BLX_R(rm) (ARM_INST_BLX_R | (rm)) + +#define ARM_CMP_R(rn, rm) _AL3_R(ARM_INST_CMP, 0, rn, rm) +#define ARM_CMP_I(rn, imm) _AL3_I(ARM_INST_CMP, 0, rn, imm) + +#define ARM_LDR_I(rt, rn, off) (ARM_INST_LDR_I | (rt) << 12 | (rn) << 16 \ + | (off)) +#define ARM_LDRB_I(rt, rn, off) (ARM_INST_LDRB_I | (rt) << 12 | (rn) << 16 \ + | (off)) +#define ARM_LDRB_R(rt, rn, rm) (ARM_INST_LDRB_R | (rt) << 12 | (rn) << 16 \ + | (rm)) +#define ARM_LDRH_I(rt, rn, off) (ARM_INST_LDRH_I | (rt) << 12 | (rn) << 16 \ + | (((off) & 0xf0) << 4) | ((off) & 0xf)) + +#define ARM_LDM(rn, regs) (ARM_INST_LDM | (rn) << 16 | (regs)) + +#define ARM_LSL_R(rd, rn, rm) (_AL3_R(ARM_INST_LSL, rd, 0, rn) | (rm) << 8) +#define ARM_LSL_I(rd, rn, imm) (_AL3_I(ARM_INST_LSL, rd, 0, rn) | (imm) << 7) + +#define ARM_LSR_R(rd, rn, rm) (_AL3_R(ARM_INST_LSR, rd, 0, rn) | (rm) << 8) +#define ARM_LSR_I(rd, rn, imm) (_AL3_I(ARM_INST_LSR, rd, 0, rn) | (imm) << 7) + +#define ARM_MOV_R(rd, rm) _AL3_R(ARM_INST_MOV, rd, 0, rm) +#define ARM_MOV_I(rd, imm) _AL3_I(ARM_INST_MOV, rd, 0, imm) + +#define ARM_MOVW(rd, imm) \ + (ARM_INST_MOVW | ((imm) >> 12) << 16 | (rd) << 12 | ((imm) & 0x0fff)) + +#define ARM_MOVT(rd, imm) \ + (ARM_INST_MOVT | ((imm) >> 12) << 16 | (rd) << 12 | ((imm) & 0x0fff)) + +#define ARM_MUL(rd, rm, rn) (ARM_INST_MUL | (rd) << 16 | (rm) << 8 | (rn)) + +#define ARM_POP(regs) (ARM_INST_POP | (regs)) +#define ARM_PUSH(regs) (ARM_INST_PUSH | (regs)) + +#define ARM_ORR_R(rd, rn, rm) _AL3_R(ARM_INST_ORR, rd, rn, rm) +#define ARM_ORR_I(rd, rn, imm) _AL3_I(ARM_INST_ORR, rd, rn, imm) +#define ARM_ORR_S(rd, rn, rm, type, rs) \ + (ARM_ORR_R(rd, rn, rm) | (type) << 5 | (rs) << 7) + +#define ARM_REV(rd, rm) (ARM_INST_REV | (rd) << 12 | (rm)) +#define ARM_REV16(rd, rm) (ARM_INST_REV16 | (rd) << 12 | (rm)) + +#define ARM_RSB_I(rd, rn, imm) _AL3_I(ARM_INST_RSB, rd, rn, imm) + +#define ARM_SUB_R(rd, rn, rm) _AL3_R(ARM_INST_SUB, rd, rn, rm) +#define ARM_SUB_I(rd, rn, imm) _AL3_I(ARM_INST_SUB, rd, rn, imm) + +#define ARM_STR_I(rt, rn, off) (ARM_INST_STR_I | (rt) << 12 | (rn) << 16 \ + | (off)) + +#define ARM_TST_R(rn, rm) _AL3_R(ARM_INST_TST, 0, rn, rm) +#define ARM_TST_I(rn, imm) _AL3_I(ARM_INST_TST, 0, rn, imm) + +#define ARM_UDIV(rd, rn, rm) (ARM_INST_UDIV | (rd) << 16 | (rn) | (rm) << 8) + +#define ARM_UMULL(rd_lo, rd_hi, rn, rm) (ARM_INST_UMULL | (rd_hi) << 16 \ + | (rd_lo) << 12 | (rm) << 8 | rn) + +#endif /* PFILTER_OPCODES_ARM_H */ diff --git a/arch/arm/nwfpe/fpa11.c b/arch/arm/nwfpe/fpa11.c index cc60acde84d9..2782ebcc2ed3 100644 --- a/arch/arm/nwfpe/fpa11.c +++ b/arch/arm/nwfpe/fpa11.c @@ -28,7 +28,6 @@ #include <linux/compiler.h> #include <linux/string.h> -#include <asm/system.h> /* Reset the FPA11 chip. Called to initialize and reset the emulator. */ static void resetFPA11(void) diff --git a/arch/arm/plat-iop/i2c.c b/arch/arm/plat-iop/i2c.c index 4efe392859ee..88215ad031a2 100644 --- a/arch/arm/plat-iop/i2c.c +++ b/arch/arm/plat-iop/i2c.c @@ -23,7 +23,6 @@ #include <asm/page.h> #include <asm/mach/map.h> #include <asm/setup.h> -#include <asm/system.h> #include <asm/memory.h> #include <mach/hardware.h> #include <asm/hardware/iop3xx.h> diff --git a/arch/arm/plat-iop/pci.c b/arch/arm/plat-iop/pci.c index f4d40a27111e..0da42058a20f 100644 --- a/arch/arm/plat-iop/pci.c +++ b/arch/arm/plat-iop/pci.c @@ -20,7 +20,6 @@ #include <linux/io.h> #include <asm/irq.h> #include <asm/signal.h> -#include <asm/system.h> #include <mach/hardware.h> #include <asm/mach/pci.h> #include <asm/hardware/iop3xx.h> @@ -215,8 +214,8 @@ int iop3xx_pci_setup(int nr, struct pci_sys_data *sys) sys->mem_offset = IOP3XX_PCI_LOWER_MEM_PA - *IOP3XX_OMWTVR0; sys->io_offset = IOP3XX_PCI_LOWER_IO_PA - *IOP3XX_OIOWTVR; - pci_add_resource(&sys->resources, &res[0]); - pci_add_resource(&sys->resources, &res[1]); + pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset); + pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset); return 1; } diff --git a/arch/arm/plat-iop/restart.c b/arch/arm/plat-iop/restart.c index 6a85a0c502e6..33fa699a4d28 100644 --- a/arch/arm/plat-iop/restart.c +++ b/arch/arm/plat-iop/restart.c @@ -8,6 +8,7 @@ * published by the Free Software Foundation. */ #include <asm/hardware/iop3xx.h> +#include <asm/system_misc.h> #include <mach/hardware.h> void iop3xx_restart(char mode, const char *cmd) diff --git a/arch/arm/plat-mxc/3ds_debugboard.c b/arch/arm/plat-mxc/3ds_debugboard.c index d1e31fa1b0c3..5cac2c540f4f 100644 --- a/arch/arm/plat-mxc/3ds_debugboard.c +++ b/arch/arm/plat-mxc/3ds_debugboard.c @@ -80,7 +80,7 @@ static struct smsc911x_platform_config smsc911x_config = { static struct platform_device smsc_lan9217_device = { .name = "smsc911x", - .id = 0, + .id = -1, .dev = { .platform_data = &smsc911x_config, }, diff --git a/arch/arm/plat-mxc/avic.c b/arch/arm/plat-mxc/avic.c index 55f15699a383..689f81f9593b 100644 --- a/arch/arm/plat-mxc/avic.c +++ b/arch/arm/plat-mxc/avic.c @@ -60,7 +60,7 @@ static int avic_irq_set_priority(unsigned char irq, unsigned char prio) unsigned int mask = 0x0F << irq % 8 * 4; if (irq >= AVIC_NUM_IRQS) - return -EINVAL;; + return -EINVAL; temp = __raw_readl(avic_base + AVIC_NIPRIORITY(irq / 8)); temp &= ~mask; diff --git a/arch/arm/plat-mxc/cpu.c b/arch/arm/plat-mxc/cpu.c index f5b7e0fa237f..220dd6f93126 100644 --- a/arch/arm/plat-mxc/cpu.c +++ b/arch/arm/plat-mxc/cpu.c @@ -1,5 +1,6 @@ #include <linux/module.h> +#include <linux/io.h> #include <mach/hardware.h> unsigned int __mxc_cpu_type; @@ -18,3 +19,26 @@ void imx_print_silicon_rev(const char *cpu, int srev) pr_info("CPU identified as %s, silicon rev %d.%d\n", cpu, (srev >> 4) & 0xf, srev & 0xf); } + +void __init imx_set_aips(void __iomem *base) +{ + unsigned int reg; +/* + * Set all MPROTx to be non-bufferable, trusted for R/W, + * not forced to user-mode. + */ + __raw_writel(0x77777777, base + 0x0); + __raw_writel(0x77777777, base + 0x4); + +/* + * Set all OPACRx to be non-bufferable, to not require + * supervisor privilege level for access, allow for + * write access and untrusted master access. + */ + __raw_writel(0x0, base + 0x40); + __raw_writel(0x0, base + 0x44); + __raw_writel(0x0, base + 0x48); + __raw_writel(0x0, base + 0x4C); + reg = __raw_readl(base + 0x50) & 0x00FFFFFF; + __raw_writel(reg, base + 0x50); +} diff --git a/arch/arm/plat-mxc/devices/platform-ahci-imx.c b/arch/arm/plat-mxc/devices/platform-ahci-imx.c index d8a56aee521b..ade4a1c4e2a3 100644 --- a/arch/arm/plat-mxc/devices/platform-ahci-imx.c +++ b/arch/arm/plat-mxc/devices/platform-ahci-imx.c @@ -60,9 +60,9 @@ static int imx_sata_init(struct device *dev, void __iomem *addr) dev_err(dev, "no sata clock.\n"); return PTR_ERR(sata_clk); } - ret = clk_enable(sata_clk); + ret = clk_prepare_enable(sata_clk); if (ret) { - dev_err(dev, "can't enable sata clock.\n"); + dev_err(dev, "can't prepare/enable sata clock.\n"); goto put_sata_clk; } @@ -73,9 +73,9 @@ static int imx_sata_init(struct device *dev, void __iomem *addr) ret = PTR_ERR(sata_ref_clk); goto release_sata_clk; } - ret = clk_enable(sata_ref_clk); + ret = clk_prepare_enable(sata_ref_clk); if (ret) { - dev_err(dev, "can't enable sata ref clock.\n"); + dev_err(dev, "can't prepare/enable sata ref clock.\n"); goto put_sata_ref_clk; } @@ -104,11 +104,11 @@ static int imx_sata_init(struct device *dev, void __iomem *addr) return 0; release_sata_ref_clk: - clk_disable(sata_ref_clk); + clk_disable_unprepare(sata_ref_clk); put_sata_ref_clk: clk_put(sata_ref_clk); release_sata_clk: - clk_disable(sata_clk); + clk_disable_unprepare(sata_clk); put_sata_clk: clk_put(sata_clk); @@ -117,10 +117,10 @@ put_sata_clk: static void imx_sata_exit(struct device *dev) { - clk_disable(sata_ref_clk); + clk_disable_unprepare(sata_ref_clk); clk_put(sata_ref_clk); - clk_disable(sata_clk); + clk_disable_unprepare(sata_clk); clk_put(sata_clk); } diff --git a/arch/arm/plat-mxc/epit.c b/arch/arm/plat-mxc/epit.c index d3467f818c33..9129c9e7d532 100644 --- a/arch/arm/plat-mxc/epit.c +++ b/arch/arm/plat-mxc/epit.c @@ -203,7 +203,7 @@ static int __init epit_clockevent_init(struct clk *timer_clk) void __init epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq) { - clk_enable(timer_clk); + clk_prepare_enable(timer_clk); timer_base = base; diff --git a/arch/arm/plat-mxc/include/mach/board-mx31ads.h b/arch/arm/plat-mxc/include/mach/board-mx31ads.h deleted file mode 100644 index 94b60dd47137..000000000000 --- a/arch/arm/plat-mxc/include/mach/board-mx31ads.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -/* - * 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. - */ - -#ifndef __ASM_ARCH_MXC_BOARD_MX31ADS_H__ -#define __ASM_ARCH_MXC_BOARD_MX31ADS_H__ - -#include <mach/hardware.h> - -/* - * These symbols are used by drivers/net/cs89x0.c. - * This is ugly as hell, but we have to provide them until - * someone fixed the driver. - */ - -/* Base address of PBC controller */ -#define PBC_BASE_ADDRESS MX31_CS4_BASE_ADDR_VIRT -/* Offsets for the PBC Controller register */ - -/* Ethernet Controller IO base address */ -#define PBC_CS8900A_IOBASE 0x020000 - -#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START) - -#define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8) - -#endif /* __ASM_ARCH_MXC_BOARD_MX31ADS_H__ */ diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h index 1bf0df81bdc6..0319c4a0cafa 100644 --- a/arch/arm/plat-mxc/include/mach/common.h +++ b/arch/arm/plat-mxc/include/mach/common.h @@ -65,6 +65,7 @@ extern int mx51_clocks_init(unsigned long ckil, unsigned long osc, unsigned long ckih1, unsigned long ckih2); extern int mx53_clocks_init(unsigned long ckil, unsigned long osc, unsigned long ckih1, unsigned long ckih2); +extern int mx27_clocks_init_dt(void); extern int mx51_clocks_init_dt(void); extern int mx53_clocks_init_dt(void); extern int mx6q_clocks_init(void); @@ -75,6 +76,7 @@ extern void mxc_restart(char, const char *); extern void mxc_arch_reset_init(void __iomem *); extern int mx53_revision(void); extern int mx53_display_revision(void); +extern void imx_set_aips(void __iomem *); enum mxc_cpu_pwr_mode { WAIT_CLOCKED, /* wfi only */ @@ -84,6 +86,14 @@ enum mxc_cpu_pwr_mode { STOP_POWER_OFF, /* STOP + SRPG */ }; +enum mx3_cpu_pwr_mode { + MX3_RUN, + MX3_WAIT, + MX3_DOZE, + MX3_SLEEP, +}; + +extern void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode); extern void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode); extern void imx_print_silicon_rev(const char *cpu, int srev); diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S index 6e192c4a391a..8ddda365f1a0 100644 --- a/arch/arm/plat-mxc/include/mach/debug-macro.S +++ b/arch/arm/plat-mxc/include/mach/debug-macro.S @@ -24,7 +24,7 @@ #define UART_PADDR MX51_UART1_BASE_ADDR #elif defined (CONFIG_DEBUG_IMX50_IMX53_UART) #define UART_PADDR MX53_UART1_BASE_ADDR -#elif defined (CONFIG_DEBUG_IMX6Q_UART) +#elif defined (CONFIG_DEBUG_IMX6Q_UART4) #define UART_PADDR MX6Q_UART4_BASE_ADDR #endif diff --git a/arch/arm/plat-mxc/include/mach/dma.h b/arch/arm/plat-mxc/include/mach/dma.h index 233d0a5e2d68..1b9080385b46 100644 --- a/arch/arm/plat-mxc/include/mach/dma.h +++ b/arch/arm/plat-mxc/include/mach/dma.h @@ -60,8 +60,7 @@ static inline int imx_dma_is_ipu(struct dma_chan *chan) static inline int imx_dma_is_general_purpose(struct dma_chan *chan) { - return !strcmp(dev_name(chan->device->dev), "imx31-sdma") || - !strcmp(dev_name(chan->device->dev), "imx35-sdma") || + return strstr(dev_name(chan->device->dev), "sdma") || !strcmp(dev_name(chan->device->dev), "imx-dma"); } diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S deleted file mode 100644 index def5d30cb67e..000000000000 --- a/arch/arm/plat-mxc/include/mach/entry-macro.S +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (C) 2007 Lennert Buytenhek <buytenh@wantstofly.org> - * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -/* - * 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. - */ - - .macro disable_fiq - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h index a599f01f8b92..0630513554de 100644 --- a/arch/arm/plat-mxc/include/mach/hardware.h +++ b/arch/arm/plat-mxc/include/mach/hardware.h @@ -22,11 +22,8 @@ #include <asm/sizes.h> -#ifdef __ASSEMBLER__ -#define IOMEM(addr) (addr) -#else -#define IOMEM(addr) ((void __force __iomem *)(addr)) -#endif +#define addr_in_module(addr, mod) \ + ((unsigned long)(addr) - mod ## _BASE_ADDR < mod ## _SIZE) #define IMX_IO_P2V_MODULE(addr, module) \ (((addr) - module ## _BASE_ADDR) < module ## _SIZE ? \ diff --git a/arch/arm/plat-mxc/include/mach/io.h b/arch/arm/plat-mxc/include/mach/io.h deleted file mode 100644 index 338300b18b00..000000000000 --- a/arch/arm/plat-mxc/include/mach/io.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -/* - * 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. - */ - -#ifndef __ASM_ARCH_MXC_IO_H__ -#define __ASM_ARCH_MXC_IO_H__ - -/* Allow IO space to be anywhere in the memory */ -#define IO_SPACE_LIMIT 0xffffffff - -#define __arch_ioremap __imx_ioremap -#define __arch_iounmap __iounmap - -#define addr_in_module(addr, mod) \ - ((unsigned long)(addr) - mod ## _BASE_ADDR < mod ## _SIZE) - -extern void __iomem *(*imx_ioremap)(unsigned long, size_t, unsigned int); - -static inline void __iomem * -__imx_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype) -{ - if (imx_ioremap != NULL) - return imx_ioremap(phys_addr, size, mtype); - else - return __arm_ioremap(phys_addr, size, mtype); -} - -/* io address mapping macro */ -#define __io(a) __typesafe_io(a) - -#define __mem_pci(a) (a) - -#endif diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx25.h b/arch/arm/plat-mxc/include/mach/iomux-mx25.h index f0726d48df22..c61ec0fc10d4 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx25.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx25.h @@ -139,15 +139,15 @@ #define MX25_PAD_NFRB__GPIO_3_31 IOMUX_PAD(0x27c, 0x084, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_D15__D15 IOMUX_PAD(0x280, 0x088, 0x00, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_D15__LD16 IOMUX_PAD(0x280, 0x088, 0x01, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_D15__LD16 IOMUX_PAD(0x280, 0x088, 0x01, 0, 0, PAD_CTL_SRE_FAST) #define MX25_PAD_D15__GPIO_4_5 IOMUX_PAD(0x280, 0x088, 0x05, 0, 0, NO_PAD_CTRL) #define MX25_PAD_D14__D14 IOMUX_PAD(0x284, 0x08c, 0x00, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_D14__LD17 IOMUX_PAD(0x284, 0x08c, 0x01, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_D14__LD17 IOMUX_PAD(0x284, 0x08c, 0x01, 0, 0, PAD_CTL_SRE_FAST) #define MX25_PAD_D14__GPIO_4_6 IOMUX_PAD(0x284, 0x08c, 0x05, 0, 0, NO_PAD_CTRL) #define MX25_PAD_D13__D13 IOMUX_PAD(0x288, 0x090, 0x00, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_D13__LD18 IOMUX_PAD(0x288, 0x090, 0x01, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_D13__LD18 IOMUX_PAD(0x288, 0x090, 0x01, 0, 0, PAD_CTL_SRE_FAST) #define MX25_PAD_D13__GPIO_4_7 IOMUX_PAD(0x288, 0x090, 0x05, 0, 0, NO_PAD_CTRL) #define MX25_PAD_D12__D12 IOMUX_PAD(0x28c, 0x094, 0x00, 0, 0, NO_PAD_CTRL) @@ -192,54 +192,54 @@ #define MX25_PAD_D0__D0 IOMUX_PAD(0x2bc, 0x0c4, 0x00, 0, 0, NO_PAD_CTRL) #define MX25_PAD_D0__GPIO_4_20 IOMUX_PAD(0x2bc, 0x0c4, 0x05, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD0__LD0 IOMUX_PAD(0x2c0, 0x0c8, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_LD0__LD0 IOMUX_PAD(0x2c0, 0x0c8, 0x10, 0, 0, PAD_CTL_SRE_FAST) #define MX25_PAD_LD0__CSI_D0 IOMUX_PAD(0x2c0, 0x0c8, 0x12, 0x488, 0, NO_PAD_CTRL) #define MX25_PAD_LD0__GPIO_2_15 IOMUX_PAD(0x2c0, 0x0c8, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD1__LD1 IOMUX_PAD(0x2c4, 0x0cc, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_LD1__LD1 IOMUX_PAD(0x2c4, 0x0cc, 0x10, 0, 0, PAD_CTL_SRE_FAST) #define MX25_PAD_LD1__CSI_D1 IOMUX_PAD(0x2c4, 0x0cc, 0x12, 0x48c, 0, NO_PAD_CTRL) #define MX25_PAD_LD1__GPIO_2_16 IOMUX_PAD(0x2c4, 0x0cc, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD2__LD2 IOMUX_PAD(0x2c8, 0x0d0, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_LD2__LD2 IOMUX_PAD(0x2c8, 0x0d0, 0x10, 0, 0, PAD_CTL_SRE_FAST) #define MX25_PAD_LD2__GPIO_2_17 IOMUX_PAD(0x2c8, 0x0d0, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD3__LD3 IOMUX_PAD(0x2cc, 0x0d4, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_LD3__LD3 IOMUX_PAD(0x2cc, 0x0d4, 0x10, 0, 0, PAD_CTL_SRE_FAST) #define MX25_PAD_LD3__GPIO_2_18 IOMUX_PAD(0x2cc, 0x0d4, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD4__LD4 IOMUX_PAD(0x2d0, 0x0d8, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_LD4__LD4 IOMUX_PAD(0x2d0, 0x0d8, 0x10, 0, 0, PAD_CTL_SRE_FAST) #define MX25_PAD_LD4__GPIO_2_19 IOMUX_PAD(0x2d0, 0x0d8, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD5__LD5 IOMUX_PAD(0x2d4, 0x0dc, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_LD5__LD5 IOMUX_PAD(0x2d4, 0x0dc, 0x10, 0, 0, PAD_CTL_SRE_FAST) #define MX25_PAD_LD5__GPIO_1_19 IOMUX_PAD(0x2d4, 0x0dc, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD6__LD6 IOMUX_PAD(0x2d8, 0x0e0, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_LD6__LD6 IOMUX_PAD(0x2d8, 0x0e0, 0x10, 0, 0, PAD_CTL_SRE_FAST) #define MX25_PAD_LD6__GPIO_1_20 IOMUX_PAD(0x2d8, 0x0e0, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD7__LD7 IOMUX_PAD(0x2dc, 0x0e4, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_LD7__LD7 IOMUX_PAD(0x2dc, 0x0e4, 0x10, 0, 0, PAD_CTL_SRE_FAST) #define MX25_PAD_LD7__GPIO_1_21 IOMUX_PAD(0x2dc, 0x0e4, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD8__LD8 IOMUX_PAD(0x2e0, 0x0e8, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_LD8__LD8 IOMUX_PAD(0x2e0, 0x0e8, 0x10, 0, 0, PAD_CTL_SRE_FAST) #define MX25_PAD_LD8__FEC_TX_ERR IOMUX_PAD(0x2e0, 0x0e8, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD9__LD9 IOMUX_PAD(0x2e4, 0x0ec, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_LD9__LD9 IOMUX_PAD(0x2e4, 0x0ec, 0x10, 0, 0, PAD_CTL_SRE_FAST) #define MX25_PAD_LD9__FEC_COL IOMUX_PAD(0x2e4, 0x0ec, 0x15, 0x504, 1, NO_PAD_CTRL) -#define MX25_PAD_LD10__LD10 IOMUX_PAD(0x2e8, 0x0f0, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_LD10__LD10 IOMUX_PAD(0x2e8, 0x0f0, 0x10, 0, 0, PAD_CTL_SRE_FAST) #define MX25_PAD_LD10__FEC_RX_ER IOMUX_PAD(0x2e8, 0x0f0, 0x15, 0x518, 1, NO_PAD_CTRL) -#define MX25_PAD_LD11__LD11 IOMUX_PAD(0x2ec, 0x0f4, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_LD11__LD11 IOMUX_PAD(0x2ec, 0x0f4, 0x10, 0, 0, PAD_CTL_SRE_FAST) #define MX25_PAD_LD11__FEC_RDATA2 IOMUX_PAD(0x2ec, 0x0f4, 0x15, 0x50c, 1, NO_PAD_CTRL) -#define MX25_PAD_LD12__LD12 IOMUX_PAD(0x2f0, 0x0f8, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_LD12__LD12 IOMUX_PAD(0x2f0, 0x0f8, 0x10, 0, 0, PAD_CTL_SRE_FAST) #define MX25_PAD_LD12__FEC_RDATA3 IOMUX_PAD(0x2f0, 0x0f8, 0x15, 0x510, 1, NO_PAD_CTRL) -#define MX25_PAD_LD13__LD13 IOMUX_PAD(0x2f4, 0x0fc, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_LD13__LD13 IOMUX_PAD(0x2f4, 0x0fc, 0x10, 0, 0, PAD_CTL_SRE_FAST) #define MX25_PAD_LD13__FEC_TDATA2 IOMUX_PAD(0x2f4, 0x0fc, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD14__LD14 IOMUX_PAD(0x2f8, 0x100, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_LD14__LD14 IOMUX_PAD(0x2f8, 0x100, 0x10, 0, 0, PAD_CTL_SRE_FAST) #define MX25_PAD_LD14__FEC_TDATA3 IOMUX_PAD(0x2f8, 0x100, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD15__LD15 IOMUX_PAD(0x2fc, 0x104, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_LD15__LD15 IOMUX_PAD(0x2fc, 0x104, 0x10, 0, 0, PAD_CTL_SRE_FAST) #define MX25_PAD_LD15__FEC_RX_CLK IOMUX_PAD(0x2fc, 0x104, 0x15, 0x514, 1, NO_PAD_CTRL) #define MX25_PAD_HSYNC__HSYNC IOMUX_PAD(0x300, 0x108, 0x10, 0, 0, NO_PAD_CTRL) @@ -468,11 +468,11 @@ #define MX25_PAD_GPIO_C__CAN2_TX IOMUX_PAD(0x3f8, 0x1fc, 0x16, 0, 0, PAD_CTL_PUS_22K_UP) #define MX25_PAD_GPIO_D__GPIO_D IOMUX_PAD(0x3fc, 0x200, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_GPIO_E__LD16 IOMUX_PAD(0x400, 0x204, 0x02, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_GPIO_E__LD16 IOMUX_PAD(0x400, 0x204, 0x02, 0, 0, PAD_CTL_SRE_FAST) #define MX25_PAD_GPIO_D__CAN2_RX IOMUX_PAD(0x3fc, 0x200, 0x16, 0x484, 1, PAD_CTL_PUS_22K_UP) #define MX25_PAD_GPIO_E__GPIO_E IOMUX_PAD(0x400, 0x204, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_GPIO_F__LD17 IOMUX_PAD(0x404, 0x208, 0x02, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_GPIO_F__LD17 IOMUX_PAD(0x404, 0x208, 0x02, 0, 0, PAD_CTL_SRE_FAST) #define MX25_PAD_GPIO_E__AUD7_TXD IOMUX_PAD(0x400, 0x204, 0x14, 0, 0, NO_PAD_CTRL) #define MX25_PAD_GPIO_F__GPIO_F IOMUX_PAD(0x404, 0x208, 0x10, 0, 0, NO_PAD_CTRL) diff --git a/arch/arm/plat-mxc/include/mach/system.h b/arch/arm/plat-mxc/include/mach/system.h deleted file mode 100644 index 13ad0df2e860..000000000000 --- a/arch/arm/plat-mxc/include/mach/system.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 1999 ARM Limited - * Copyright (C) 2000 Deep Blue Solutions Ltd - * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved. - * - * 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 __ASM_ARCH_MXC_SYSTEM_H__ -#define __ASM_ARCH_MXC_SYSTEM_H__ - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif /* __ASM_ARCH_MXC_SYSTEM_H__ */ diff --git a/arch/arm/plat-mxc/pwm.c b/arch/arm/plat-mxc/pwm.c index e032717f7d02..c0cab2270dd1 100644 --- a/arch/arm/plat-mxc/pwm.c +++ b/arch/arm/plat-mxc/pwm.c @@ -132,7 +132,7 @@ int pwm_enable(struct pwm_device *pwm) int rc = 0; if (!pwm->clk_enabled) { - rc = clk_enable(pwm->clk); + rc = clk_prepare_enable(pwm->clk); if (!rc) pwm->clk_enabled = 1; } @@ -145,7 +145,7 @@ void pwm_disable(struct pwm_device *pwm) writel(0, pwm->mmio_base + MX3_PWMCR); if (pwm->clk_enabled) { - clk_disable(pwm->clk); + clk_disable_unprepare(pwm->clk); pwm->clk_enabled = 0; } } diff --git a/arch/arm/plat-mxc/system.c b/arch/arm/plat-mxc/system.c index 3599bf2cfd4f..1996c3e3b8fe 100644 --- a/arch/arm/plat-mxc/system.c +++ b/arch/arm/plat-mxc/system.c @@ -25,8 +25,8 @@ #include <mach/hardware.h> #include <mach/common.h> +#include <asm/system_misc.h> #include <asm/proc-fns.h> -#include <asm/system.h> #include <asm/mach-types.h> void __iomem *(*imx_ioremap)(unsigned long, size_t, unsigned int) = NULL; @@ -48,7 +48,7 @@ void mxc_restart(char mode, const char *cmd) clk = clk_get_sys("imx2-wdt.0", NULL); if (!IS_ERR(clk)) - clk_enable(clk); + clk_prepare_enable(clk); wcr_enable = (1 << 2); } diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c index 1c96cdb4c35e..7daf7c9a413b 100644 --- a/arch/arm/plat-mxc/time.c +++ b/arch/arm/plat-mxc/time.c @@ -283,7 +283,7 @@ void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq) { uint32_t tctl_val; - clk_enable(timer_clk); + clk_prepare_enable(timer_clk); timer_base = base; diff --git a/arch/arm/plat-nomadik/Kconfig b/arch/arm/plat-nomadik/Kconfig index bca4914b4b9d..4c48c8b60b54 100644 --- a/arch/arm/plat-nomadik/Kconfig +++ b/arch/arm/plat-nomadik/Kconfig @@ -23,7 +23,6 @@ config HAS_MTU config NOMADIK_MTU_SCHED_CLOCK bool depends on HAS_MTU - select HAVE_SCHED_CLOCK help Use the Multi Timer Unit as the sched_clock. diff --git a/arch/arm/plat-nomadik/include/plat/mtu.h b/arch/arm/plat-nomadik/include/plat/mtu.h index 6508e7694a4b..582641f3dc01 100644 --- a/arch/arm/plat-nomadik/include/plat/mtu.h +++ b/arch/arm/plat-nomadik/include/plat/mtu.h @@ -1,9 +1,7 @@ #ifndef __PLAT_MTU_H #define __PLAT_MTU_H -/* should be set by the platform code */ -extern void __iomem *mtu_base; - +void nmdk_timer_init(void __iomem *base); void nmdk_clkevt_reset(void); void nmdk_clksrc_reset(void); diff --git a/arch/arm/plat-nomadik/include/plat/ste_dma40.h b/arch/arm/plat-nomadik/include/plat/ste_dma40.h index fd0ee84c45d1..9ff93b065686 100644 --- a/arch/arm/plat-nomadik/include/plat/ste_dma40.h +++ b/arch/arm/plat-nomadik/include/plat/ste_dma40.h @@ -200,8 +200,7 @@ dma_async_tx_descriptor *stedma40_slave_mem(struct dma_chan *chan, sg.dma_address = addr; sg.length = size; - return chan->device->device_prep_slave_sg(chan, &sg, 1, - direction, flags); + return dmaengine_prep_slave_sg(chan, &sg, 1, direction, flags); } #else diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c index ad1b45b605a4..9222e5522a43 100644 --- a/arch/arm/plat-nomadik/timer.c +++ b/arch/arm/plat-nomadik/timer.c @@ -21,12 +21,6 @@ #include <asm/sched_clock.h> /* - * Guaranteed runtime conversion range in seconds for - * the clocksource and clockevent. - */ -#define MTU_MIN_RANGE 4 - -/* * The MTU device hosts four different counters, with 4 set of * registers. These are register names. */ @@ -66,12 +60,11 @@ #define MTU_PCELL2 0xff8 #define MTU_PCELL3 0xffC +static void __iomem *mtu_base; static bool clkevt_periodic; static u32 clk_prescale; static u32 nmdk_cycle; /* write-once */ -void __iomem *mtu_base; /* Assigned by machine code */ - #ifdef CONFIG_NOMADIK_MTU_SCHED_CLOCK /* * Override the global weak sched_clock symbol with this @@ -103,7 +96,6 @@ static int nmdk_clkevt_next(unsigned long evt, struct clock_event_device *ev) void nmdk_clkevt_reset(void) { if (clkevt_periodic) { - /* Timer: configure load and background-load, and fire it up */ writel(nmdk_cycle, mtu_base + MTU_LR(1)); writel(nmdk_cycle, mtu_base + MTU_BGLR(1)); @@ -121,7 +113,6 @@ void nmdk_clkevt_reset(void) static void nmdk_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev) { - switch (mode) { case CLOCK_EVT_MODE_PERIODIC: clkevt_periodic = true; @@ -183,15 +174,16 @@ void nmdk_clksrc_reset(void) mtu_base + MTU_CR(0)); } -void __init nmdk_timer_init(void) +void __init nmdk_timer_init(void __iomem *base) { unsigned long rate; struct clk *clk0; + mtu_base = base; clk0 = clk_get_sys("mtu0", NULL); BUG_ON(IS_ERR(clk0)); - - clk_enable(clk0); + BUG_ON(clk_prepare(clk0) < 0); + BUG_ON(clk_enable(clk0) < 0); /* * Tick rate is 2.4MHz for Nomadik and 2.4Mhz, 100MHz or 133 MHz @@ -224,17 +216,8 @@ void __init nmdk_timer_init(void) setup_sched_clock(nomadik_read_sched_clock, 32, rate); #endif - /* Timer 1 is used for events */ - - clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE); - - nmdk_clkevt.max_delta_ns = - clockevent_delta2ns(0xffffffff, &nmdk_clkevt); - nmdk_clkevt.min_delta_ns = - clockevent_delta2ns(0x00000002, &nmdk_clkevt); - nmdk_clkevt.cpumask = cpumask_of(0); - - /* Register irq and clockevents */ + /* Timer 1 is used for events, register irq and clockevents */ setup_irq(IRQ_MTU0, &nmdk_timer_irq); - clockevents_register_device(&nmdk_clkevt); + nmdk_clkevt.cpumask = cpumask_of(0); + clockevents_config_and_register(&nmdk_clkevt, rate, 2, 0xffffffffU); } diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index 8f81503a4df7..ad95c7a5d009 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -14,8 +14,10 @@ config ARCH_OMAP1 select CLKDEV_LOOKUP select CLKSRC_MMIO select GENERIC_IRQ_CHIP + select IRQ_DOMAIN select HAVE_IDE select NEED_MACH_MEMORY_H + select NEED_MACH_IO_H if PCCARD help "Systems based on omap7xx, omap15xx or omap16xx" @@ -24,6 +26,8 @@ config ARCH_OMAP2PLUS select CLKDEV_LOOKUP select GENERIC_IRQ_CHIP select OMAP_DM_TIMER + select USE_OF + select PROC_DEVICETREE if PROC_FS help "Systems based on OMAP2, OMAP3 or OMAP4" diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index 567e4b54f245..62ec5c452792 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c @@ -20,7 +20,6 @@ #include <linux/clk.h> #include <linux/mutex.h> #include <linux/cpufreq.h> -#include <linux/debugfs.h> #include <linux/io.h> #include <plat/clock.h> @@ -399,32 +398,6 @@ struct clk dummy_ck = { .ops = &clkops_null, }; -#ifdef CONFIG_CPU_FREQ -void clk_init_cpufreq_table(struct cpufreq_frequency_table **table) -{ - unsigned long flags; - - if (!arch_clock || !arch_clock->clk_init_cpufreq_table) - return; - - spin_lock_irqsave(&clockfw_lock, flags); - arch_clock->clk_init_cpufreq_table(table); - spin_unlock_irqrestore(&clockfw_lock, flags); -} - -void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table) -{ - unsigned long flags; - - if (!arch_clock || !arch_clock->clk_exit_cpufreq_table) - return; - - spin_lock_irqsave(&clockfw_lock, flags); - arch_clock->clk_exit_cpufreq_table(table); - spin_unlock_irqrestore(&clockfw_lock, flags); -} -#endif - /* * */ @@ -442,6 +415,8 @@ static int __init clk_disable_unused(void) return 0; pr_info("clock: disabling unused clocks to save power\n"); + + spin_lock_irqsave(&clockfw_lock, flags); list_for_each_entry(ck, &clocks, node) { if (ck->ops == &clkops_null) continue; @@ -449,10 +424,9 @@ static int __init clk_disable_unused(void) if (ck->usecount > 0 || !ck->enable_reg) continue; - spin_lock_irqsave(&clockfw_lock, flags); arch_clock->clk_disable_unused(ck); - spin_unlock_irqrestore(&clockfw_lock, flags); } + spin_unlock_irqrestore(&clockfw_lock, flags); return 0; } diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c index 5f0f2292b7fb..5068fe5a6910 100644 --- a/arch/arm/plat-omap/counter_32k.c +++ b/arch/arm/plat-omap/counter_32k.c @@ -21,6 +21,7 @@ #include <asm/sched_clock.h> +#include <plat/hardware.h> #include <plat/common.h> #include <plat/board.h> diff --git a/arch/arm/plat-omap/debug-leds.c b/arch/arm/plat-omap/debug-leds.c index 61a1ec2a6af4..39407cbe34c6 100644 --- a/arch/arm/plat-omap/debug-leds.c +++ b/arch/arm/plat-omap/debug-leds.c @@ -15,7 +15,6 @@ #include <mach/hardware.h> #include <asm/leds.h> -#include <asm/system.h> #include <asm/mach-types.h> #include <plat/fpga.h> diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 002fb4d96bbc..ecdb3da0dea9 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -36,7 +36,6 @@ #include <linux/slab.h> #include <linux/delay.h> -#include <asm/system.h> #include <mach/hardware.h> #include <plat/dma.h> @@ -164,6 +163,8 @@ static inline void set_gdma_dev(int req, int dev) } #else #define set_gdma_dev(req, dev) do {} while (0) +#define omap_readl(reg) 0 +#define omap_writel(val, reg) do {} while (0) #endif void omap_set_dma_priority(int lch, int dst_port, int priority) @@ -2125,7 +2126,7 @@ static int __devexit omap_system_dma_remove(struct platform_device *pdev) static struct platform_driver omap_system_dma_driver = { .probe = omap_system_dma_probe, - .remove = omap_system_dma_remove, + .remove = __devexit_p(omap_system_dma_remove), .driver = { .name = "omap_dma_system" }, diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index af3b92be8459..652139c0339e 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -43,6 +43,8 @@ #include <plat/dmtimer.h> +#include <mach/hardware.h> + static LIST_HEAD(omap_timer_list); static DEFINE_SPINLOCK(dm_timer_lock); @@ -80,9 +82,9 @@ static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg, static void omap_timer_restore_context(struct omap_dm_timer *timer) { - omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_OFFSET, - timer->context.tiocp_cfg); - if (timer->revision > 1) + __raw_writel(timer->context.tiocp_cfg, + timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET); + if (timer->revision == 1) __raw_writel(timer->context.tistat, timer->sys_stat); __raw_writel(timer->context.tisr, timer->irq_stat); @@ -357,6 +359,19 @@ int omap_dm_timer_stop(struct omap_dm_timer *timer) __omap_dm_timer_stop(timer, timer->posted, rate); + if (timer->loses_context && timer->get_context_loss_count) + timer->ctx_loss_count = + timer->get_context_loss_count(&timer->pdev->dev); + + /* + * Since the register values are computed and written within + * __omap_dm_timer_stop, we need to use read to retrieve the + * context. + */ + timer->context.tclr = + omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); + timer->context.tisr = __raw_readl(timer->irq_stat); + omap_dm_timer_disable(timer); return 0; } EXPORT_SYMBOL_GPL(omap_dm_timer_stop); diff --git a/arch/arm/plat-omap/include/plat/board-ams-delta.h b/arch/arm/plat-omap/include/plat/board-ams-delta.h index 51b102dc906b..ad6f865d1f16 100644 --- a/arch/arm/plat-omap/include/plat/board-ams-delta.h +++ b/arch/arm/plat-omap/include/plat/board-ams-delta.h @@ -28,33 +28,8 @@ #if defined (CONFIG_MACH_AMS_DELTA) -#define AMS_DELTA_LATCH1_PHYS 0x01000000 -#define AMS_DELTA_LATCH1_VIRT 0xEA000000 -#define AMS_DELTA_MODEM_PHYS 0x04000000 -#define AMS_DELTA_MODEM_VIRT 0xEB000000 -#define AMS_DELTA_LATCH2_PHYS 0x08000000 -#define AMS_DELTA_LATCH2_VIRT 0xEC000000 - -#define AMS_DELTA_LATCH1_LED_CAMERA 0x01 -#define AMS_DELTA_LATCH1_LED_ADVERT 0x02 -#define AMS_DELTA_LATCH1_LED_EMAIL 0x04 -#define AMS_DELTA_LATCH1_LED_HANDSFREE 0x08 -#define AMS_DELTA_LATCH1_LED_VOICEMAIL 0x10 -#define AMS_DELTA_LATCH1_LED_VOICE 0x20 - -#define AMS_DELTA_LATCH2_LCD_VBLEN 0x0001 -#define AMS_DELTA_LATCH2_LCD_NDISP 0x0002 -#define AMS_DELTA_LATCH2_NAND_NCE 0x0004 -#define AMS_DELTA_LATCH2_NAND_NRE 0x0008 -#define AMS_DELTA_LATCH2_NAND_NWP 0x0010 -#define AMS_DELTA_LATCH2_NAND_NWE 0x0020 -#define AMS_DELTA_LATCH2_NAND_ALE 0x0040 -#define AMS_DELTA_LATCH2_NAND_CLE 0x0080 -#define AMD_DELTA_LATCH2_KEYBRD_PWR 0x0100 -#define AMD_DELTA_LATCH2_KEYBRD_DATA 0x0200 #define AMD_DELTA_LATCH2_SCARD_RSTIN 0x0400 #define AMD_DELTA_LATCH2_SCARD_CMDVCC 0x0800 -#define AMS_DELTA_LATCH2_MODEM_NRESET 0x1000 #define AMS_DELTA_LATCH2_MODEM_CODEC 0x2000 #define AMS_DELTA_GPIO_PIN_KEYBRD_DATA 0 @@ -66,9 +41,29 @@ #define AMS_DELTA_GPIO_PIN_CONFIG 11 #define AMS_DELTA_GPIO_PIN_NAND_RB 12 +#define AMS_DELTA_GPIO_PIN_LCD_VBLEN 240 +#define AMS_DELTA_GPIO_PIN_LCD_NDISP 241 +#define AMS_DELTA_GPIO_PIN_NAND_NCE 242 +#define AMS_DELTA_GPIO_PIN_NAND_NRE 243 +#define AMS_DELTA_GPIO_PIN_NAND_NWP 244 +#define AMS_DELTA_GPIO_PIN_NAND_NWE 245 +#define AMS_DELTA_GPIO_PIN_NAND_ALE 246 +#define AMS_DELTA_GPIO_PIN_NAND_CLE 247 +#define AMS_DELTA_GPIO_PIN_KEYBRD_PWR 248 +#define AMS_DELTA_GPIO_PIN_KEYBRD_DATAOUT 249 +#define AMS_DELTA_GPIO_PIN_SCARD_RSTIN 250 +#define AMS_DELTA_GPIO_PIN_SCARD_CMDVCC 251 +#define AMS_DELTA_GPIO_PIN_MODEM_NRESET 252 +#define AMS_DELTA_GPIO_PIN_MODEM_CODEC 253 + +#define AMS_DELTA_LATCH2_GPIO_BASE AMS_DELTA_GPIO_PIN_LCD_VBLEN +#define AMS_DELTA_LATCH2_NGPIO 16 + #ifndef __ASSEMBLY__ -void ams_delta_latch1_write(u8 mask, u8 value); -void ams_delta_latch2_write(u16 mask, u16 value); +void ams_delta_latch_write(int base, int ngpio, u16 mask, u16 value); +#define ams_delta_latch2_write(mask, value) \ + ams_delta_latch_write(AMS_DELTA_LATCH2_GPIO_BASE, \ + AMS_DELTA_LATCH2_NGPIO, (mask), (value)) #endif #endif /* CONFIG_MACH_AMS_DELTA */ diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h index 240a7b9fd946..d0ef57c1d71b 100644 --- a/arch/arm/plat-omap/include/plat/clock.h +++ b/arch/arm/plat-omap/include/plat/clock.h @@ -272,8 +272,6 @@ struct clk { #endif }; -struct cpufreq_frequency_table; - struct clk_functions { int (*clk_enable)(struct clk *clk); void (*clk_disable)(struct clk *clk); @@ -283,10 +281,6 @@ struct clk_functions { void (*clk_allow_idle)(struct clk *clk); void (*clk_deny_idle)(struct clk *clk); void (*clk_disable_unused)(struct clk *clk); -#ifdef CONFIG_CPU_FREQ - void (*clk_init_cpufreq_table)(struct cpufreq_frequency_table **); - void (*clk_exit_cpufreq_table)(struct cpufreq_frequency_table **); -#endif }; extern int mpurate; @@ -301,10 +295,6 @@ extern void recalculate_root_clocks(void); extern unsigned long followparent_recalc(struct clk *clk); extern void clk_enable_init_clocks(void); unsigned long omap_fixed_divisor_recalc(struct clk *clk); -#ifdef CONFIG_CPU_FREQ -extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table); -extern void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table); -#endif extern struct clk *omap_clk_get_by_name(const char *name); extern int omap_clk_enable_autoidle_all(void); extern int omap_clk_disable_autoidle_all(void); diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index 6b51086fce18..dc6a86bf2172 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -250,7 +250,6 @@ IS_AM_SUBCLASS(335x, 0x335) * cpu_is_omap2423(): True for OMAP2423 * cpu_is_omap2430(): True for OMAP2430 * cpu_is_omap3430(): True for OMAP3430 - * cpu_is_omap4430(): True for OMAP4430 * cpu_is_omap3505(): True for OMAP3505 * cpu_is_omap3517(): True for OMAP3517 */ @@ -299,7 +298,6 @@ IS_OMAP_TYPE(3517, 0x3517) #define cpu_is_omap3505() 0 #define cpu_is_omap3517() 0 #define cpu_is_omap3430() 0 -#define cpu_is_omap4430() 0 #define cpu_is_omap3630() 0 /* @@ -451,7 +449,12 @@ IS_OMAP_TYPE(3517, 0x3517) #define OMAP447X_CLASS 0x44700044 #define OMAP4470_REV_ES1_0 (OMAP447X_CLASS | (0x10 << 8)) -void omap2_check_revision(void); +void omap2xxx_check_revision(void); +void omap3xxx_check_revision(void); +void omap4xxx_check_revision(void); +void omap3xxx_check_features(void); +void ti81xx_check_features(void); +void omap4xxx_check_features(void); /* * Runtime detection of OMAP3 features diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index 9e86ee0aed0a..2f6e9924a814 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h @@ -158,17 +158,6 @@ #define OMAP_MPUIO(nr) (OMAP_MAX_GPIO_LINES + (nr)) #define OMAP_GPIO_IS_MPUIO(nr) ((nr) >= OMAP_MAX_GPIO_LINES) -#define OMAP_GPIO_IRQ(nr) (OMAP_GPIO_IS_MPUIO(nr) ? \ - IH_MPUIO_BASE + ((nr) & 0x0f) : \ - IH_GPIO_BASE + (nr)) - -#define METHOD_MPUIO 0 -#define METHOD_GPIO_1510 1 -#define METHOD_GPIO_1610 2 -#define METHOD_GPIO_7XX 3 -#define METHOD_GPIO_24XX 5 -#define METHOD_GPIO_44XX 6 - struct omap_gpio_dev_attr { int bank_width; /* GPIO bank width */ bool dbck_flag; /* dbck required or not - True for OMAP3&4 */ @@ -184,10 +173,21 @@ struct omap_gpio_reg_offs { u16 irqstatus; u16 irqstatus2; u16 irqenable; + u16 irqenable2; u16 set_irqenable; u16 clr_irqenable; u16 debounce; u16 debounce_en; + u16 ctrl; + u16 wkup_en; + u16 leveldetect0; + u16 leveldetect1; + u16 risingdetect; + u16 fallingdetect; + u16 irqctrl; + u16 edgectrl1; + u16 edgectrl2; + u16 pinctrl; bool irqenable_inv; }; @@ -198,45 +198,30 @@ struct omap_gpio_platform_data { int bank_width; /* GPIO bank width */ int bank_stride; /* Only needed for omap1 MPUIO */ bool dbck_flag; /* dbck required or not - True for OMAP3&4 */ + bool loses_context; /* whether the bank would ever lose context */ + bool is_mpuio; /* whether the bank is of type MPUIO */ + u32 non_wakeup_gpios; struct omap_gpio_reg_offs *regs; -}; -/* TODO: Analyze removing gpio_bank_count usage from driver code */ -extern int gpio_bank_count; + /* Return context loss count due to PM states changing */ + int (*get_context_loss_count)(struct device *dev); +}; extern void omap2_gpio_prepare_for_idle(int off_mode); extern void omap2_gpio_resume_after_idle(void); extern void omap_set_gpio_debounce(int gpio, int enable); extern void omap_set_gpio_debounce_time(int gpio, int enable); -extern void omap_gpio_save_context(void); -extern void omap_gpio_restore_context(void); /*-------------------------------------------------------------------------*/ -/* Wrappers for "new style" GPIO calls, using the new infrastructure +/* + * Wrappers for "new style" GPIO calls, using the new infrastructure * which lets us plug in FPGA, I2C, and other implementations. - * * + * * The original OMAP-specific calls should eventually be removed. */ #include <linux/errno.h> #include <asm-generic/gpio.h> -static inline int irq_to_gpio(unsigned irq) -{ - int tmp; - - /* omap1 SOC mpuio */ - if (cpu_class_is_omap1() && (irq < (IH_MPUIO_BASE + 16))) - return (irq - IH_MPUIO_BASE) + OMAP_MAX_GPIO_LINES; - - /* SOC gpio */ - tmp = irq - IH_GPIO_BASE; - if (tmp < OMAP_MAX_GPIO_LINES) - return tmp; - - /* we don't supply reverse mappings for non-SOC gpios */ - return -EIO; -} - #endif diff --git a/arch/arm/plat-omap/include/plat/keypad.h b/arch/arm/plat-omap/include/plat/keypad.h index 793ce9d53294..a6b21eddb212 100644 --- a/arch/arm/plat-omap/include/plat/keypad.h +++ b/arch/arm/plat-omap/include/plat/keypad.h @@ -12,6 +12,8 @@ #ifndef CONFIG_ARCH_OMAP1 #warning Please update the board to use matrix-keypad driver +#define omap_readw(reg) 0 +#define omap_writew(val, reg) do {} while (0) #endif #include <linux/input/matrix_keypad.h> diff --git a/arch/arm/plat-omap/include/plat/mcspi.h b/arch/arm/plat-omap/include/plat/mcspi.h index 3d51b18131cc..a357eb26bd25 100644 --- a/arch/arm/plat-omap/include/plat/mcspi.h +++ b/arch/arm/plat-omap/include/plat/mcspi.h @@ -18,9 +18,6 @@ struct omap2_mcspi_dev_attr { struct omap2_mcspi_device_config { unsigned turbo_mode:1; - - /* Do we want one channel enabled at the same time? */ - unsigned single_channel:1; }; #endif diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h index f75946c3293d..7a38750c0079 100644 --- a/arch/arm/plat-omap/include/plat/mmc.h +++ b/arch/arm/plat-omap/include/plat/mmc.h @@ -137,8 +137,6 @@ struct omap_mmc_platform_data { int (*set_power)(struct device *dev, int slot, int power_on, int vdd); int (*get_ro)(struct device *dev, int slot); - int (*set_sleep)(struct device *dev, int slot, int sleep, - int vdd, int cardsleep); void (*remux)(struct device *dev, int slot, int power_on); /* Call back before enabling / disabling regulators */ void (*before_set_reg)(struct device *dev, int slot, diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h index 51423d2727a5..4327b2c90c3d 100644 --- a/arch/arm/plat-omap/include/plat/omap_device.h +++ b/arch/arm/plat-omap/include/plat/omap_device.h @@ -36,7 +36,7 @@ #include <plat/omap_hwmod.h> -extern struct device omap_device_parent; +extern struct dev_pm_domain omap_device_pm_domain; /* omap_device._state values */ #define OMAP_DEVICE_STATE_UNKNOWN 0 @@ -100,6 +100,13 @@ struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id, struct omap_device_pm_latency *pm_lats, int pm_lats_cnt, int is_early_device); +struct omap_device *omap_device_alloc(struct platform_device *pdev, + struct omap_hwmod **ohs, int oh_cnt, + struct omap_device_pm_latency *pm_lats, + int pm_lats_cnt); +void omap_device_delete(struct omap_device *od); +int omap_device_register(struct platform_device *pdev); + void __iomem *omap_device_get_rt_va(struct omap_device *od); struct device *omap_device_get_by_hwmod_name(const char *oh_name); diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 647010109afa..8070145ccb98 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -47,17 +47,17 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2; * with the original PRCM protocol defined for OMAP2420 */ #define SYSC_TYPE1_MIDLEMODE_SHIFT 12 -#define SYSC_TYPE1_MIDLEMODE_MASK (0x3 << SYSC_MIDLEMODE_SHIFT) +#define SYSC_TYPE1_MIDLEMODE_MASK (0x3 << SYSC_TYPE1_MIDLEMODE_SHIFT) #define SYSC_TYPE1_CLOCKACTIVITY_SHIFT 8 -#define SYSC_TYPE1_CLOCKACTIVITY_MASK (0x3 << SYSC_CLOCKACTIVITY_SHIFT) +#define SYSC_TYPE1_CLOCKACTIVITY_MASK (0x3 << SYSC_TYPE1_CLOCKACTIVITY_SHIFT) #define SYSC_TYPE1_SIDLEMODE_SHIFT 3 -#define SYSC_TYPE1_SIDLEMODE_MASK (0x3 << SYSC_SIDLEMODE_SHIFT) +#define SYSC_TYPE1_SIDLEMODE_MASK (0x3 << SYSC_TYPE1_SIDLEMODE_SHIFT) #define SYSC_TYPE1_ENAWAKEUP_SHIFT 2 -#define SYSC_TYPE1_ENAWAKEUP_MASK (1 << SYSC_ENAWAKEUP_SHIFT) +#define SYSC_TYPE1_ENAWAKEUP_MASK (1 << SYSC_TYPE1_ENAWAKEUP_SHIFT) #define SYSC_TYPE1_SOFTRESET_SHIFT 1 -#define SYSC_TYPE1_SOFTRESET_MASK (1 << SYSC_SOFTRESET_SHIFT) +#define SYSC_TYPE1_SOFTRESET_MASK (1 << SYSC_TYPE1_SOFTRESET_SHIFT) #define SYSC_TYPE1_AUTOIDLE_SHIFT 0 -#define SYSC_TYPE1_AUTOIDLE_MASK (1 << SYSC_AUTOIDLE_SHIFT) +#define SYSC_TYPE1_AUTOIDLE_MASK (1 << SYSC_TYPE1_AUTOIDLE_SHIFT) /* * OCP SYSCONFIG bit shifts/masks TYPE2. These are for IPs compliant @@ -484,7 +484,6 @@ struct omap_hwmod_class { * @main_clk: main clock: OMAP clock name * @_clk: pointer to the main struct clk (filled in at runtime) * @opt_clks: other device clocks that drivers can request (0..*) - * @vdd_name: voltage domain name * @voltdm: pointer to voltage domain (filled in at runtime) * @masters: ptr to array of OCP ifs that this hwmod can initiate on * @slaves: ptr to array of OCP ifs that this hwmod can respond on @@ -528,7 +527,6 @@ struct omap_hwmod { struct omap_hwmod_opt_clk *opt_clks; char *clkdm_name; struct clockdomain *clkdm; - char *vdd_name; struct omap_hwmod_ocp_if **masters; /* connect to *_IA */ struct omap_hwmod_ocp_if **slaves; /* connect to *_TA */ void *dev_attr; diff --git a/arch/arm/plat-omap/include/plat/remoteproc.h b/arch/arm/plat-omap/include/plat/remoteproc.h new file mode 100644 index 000000000000..b10eac89e2e9 --- /dev/null +++ b/arch/arm/plat-omap/include/plat/remoteproc.h @@ -0,0 +1,57 @@ +/* + * Remote Processor - omap-specific bits + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Copyright (C) 2011 Google, Inc. + * + * 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. + * + * 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 _PLAT_REMOTEPROC_H +#define _PLAT_REMOTEPROC_H + +struct rproc_ops; +struct platform_device; + +/* + * struct omap_rproc_pdata - omap remoteproc's platform data + * @name: the remoteproc's name + * @oh_name: omap hwmod device + * @oh_name_opt: optional, secondary omap hwmod device + * @firmware: name of firmware file to load + * @mbox_name: name of omap mailbox device to use with this rproc + * @ops: start/stop rproc handlers + * @device_enable: omap-specific handler for enabling a device + * @device_shutdown: omap-specific handler for shutting down a device + */ +struct omap_rproc_pdata { + const char *name; + const char *oh_name; + const char *oh_name_opt; + const char *firmware; + const char *mbox_name; + const struct rproc_ops *ops; + int (*device_enable) (struct platform_device *pdev); + int (*device_shutdown) (struct platform_device *pdev); +}; + +#if defined(CONFIG_OMAP_REMOTEPROC) || defined(CONFIG_OMAP_REMOTEPROC_MODULE) + +void __init omap_rproc_reserve_cma(void); + +#else + +void __init omap_rproc_reserve_cma(void) +{ +} + +#endif + +#endif /* _PLAT_REMOTEPROC_H */ diff --git a/arch/arm/plat-omap/include/plat/sdrc.h b/arch/arm/plat-omap/include/plat/sdrc.h index 925b12b500dc..9bb978ecd884 100644 --- a/arch/arm/plat-omap/include/plat/sdrc.h +++ b/arch/arm/plat-omap/include/plat/sdrc.h @@ -16,7 +16,6 @@ * published by the Free Software Foundation. */ -#include <mach/io.h> /* SDRC register offsets - read/write with sdrc_{read,write}_reg() */ diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h index 198d1e6a4a6c..b073e5f2b190 100644 --- a/arch/arm/plat-omap/include/plat/serial.h +++ b/arch/arm/plat-omap/include/plat/serial.h @@ -110,7 +110,6 @@ struct omap_board_data; struct omap_uart_port_info; extern void omap_serial_init(void); -extern int omap_uart_can_sleep(void); extern void omap_serial_board_init(struct omap_uart_port_info *platform_data); extern void omap_serial_init_port(struct omap_board_data *bdata, struct omap_uart_port_info *platform_data); diff --git a/arch/arm/plat-omap/include/plat/sram.h b/arch/arm/plat-omap/include/plat/sram.h index 75aa1b2bef51..227ae2657554 100644 --- a/arch/arm/plat-omap/include/plat/sram.h +++ b/arch/arm/plat-omap/include/plat/sram.h @@ -101,4 +101,5 @@ static inline void omap_push_sram_idle(void) {} #else #define OMAP4_SRAM_PA 0x40300000 #endif +#define AM33XX_SRAM_PA 0x40300000 #endif diff --git a/arch/arm/plat-omap/include/plat/system.h b/arch/arm/plat-omap/include/plat/system.h deleted file mode 100644 index 8e5ebd74b129..000000000000 --- a/arch/arm/plat-omap/include/plat/system.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copied from arch/arm/mach-sa1100/include/mach/system.h - * Copyright (c) 1999 Nicolas Pitre <nico@fluxnic.net> - */ -#ifndef __ASM_ARCH_SYSTEM_H -#define __ASM_ARCH_SYSTEM_H - -#include <asm/proc-fns.h> - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - -#endif diff --git a/arch/arm/plat-omap/include/plat/tc.h b/arch/arm/plat-omap/include/plat/tc.h index d2fcd789bb9a..1b4b2da86203 100644 --- a/arch/arm/plat-omap/include/plat/tc.h +++ b/arch/arm/plat-omap/include/plat/tc.h @@ -84,23 +84,6 @@ #define EMIFS_CCS(n) (EMIFS_CS0_CONFIG + (4 * (n))) #define EMIFS_ACS(n) (EMIFS_ACS0 + (4 * (n))) -/* Almost all documentation for chip and board memory maps assumes - * BM is clear. Most devel boards have a switch to control booting - * from NOR flash (using external chipselect 3) rather than mask ROM, - * which uses BM to interchange the physical CS0 and CS3 addresses. - */ -static inline u32 omap_cs0_phys(void) -{ - return (omap_readl(EMIFS_CONFIG) & OMAP_EMIFS_CONFIG_BM) - ? OMAP_CS3_PHYS : 0; -} - -static inline u32 omap_cs3_phys(void) -{ - return (omap_readl(EMIFS_CONFIG) & OMAP_EMIFS_CONFIG_BM) - ? 0 : OMAP_CS3_PHYS; -} - #endif /* __ASSEMBLER__ */ #endif /* __ASM_ARCH_TC_H */ diff --git a/arch/arm/plat-omap/include/plat/uncompress.h b/arch/arm/plat-omap/include/plat/uncompress.h index 6ee90495ca4c..cc3f11ba7a99 100644 --- a/arch/arm/plat-omap/include/plat/uncompress.h +++ b/arch/arm/plat-omap/include/plat/uncompress.h @@ -160,6 +160,7 @@ static inline void __arch_decomp_setup(unsigned long arch_id) DEBUG_LL_OMAP3(3, igep0020); DEBUG_LL_OMAP3(3, igep0030); DEBUG_LL_OMAP3(3, nokia_rm680); + DEBUG_LL_OMAP3(3, nokia_rm696); DEBUG_LL_OMAP3(3, nokia_rx51); DEBUG_LL_OMAP3(3, omap3517evm); DEBUG_LL_OMAP3(3, omap3_beagle); diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h index dc864b580da0..762eeb0626c1 100644 --- a/arch/arm/plat-omap/include/plat/usb.h +++ b/arch/arm/plat-omap/include/plat/usb.h @@ -3,6 +3,7 @@ #ifndef __ASM_ARCH_OMAP_USB_H #define __ASM_ARCH_OMAP_USB_H +#include <linux/io.h> #include <linux/usb/musb.h> #include <plat/board.h> @@ -105,6 +106,45 @@ extern int omap4430_phy_set_clk(struct device *dev, int on); extern int omap4430_phy_init(struct device *dev); extern int omap4430_phy_exit(struct device *dev); extern int omap4430_phy_suspend(struct device *dev, int suspend); + +/* + * NOTE: Please update omap USB drivers to use ioremap + read/write + */ + +#define OMAP2_L4_IO_OFFSET 0xb2000000 +#define OMAP2_L4_IO_ADDRESS(pa) IOMEM((pa) + OMAP2_L4_IO_OFFSET) + +static inline u8 omap_readb(u32 pa) +{ + return __raw_readb(OMAP2_L4_IO_ADDRESS(pa)); +} + +static inline u16 omap_readw(u32 pa) +{ + return __raw_readw(OMAP2_L4_IO_ADDRESS(pa)); +} + +static inline u32 omap_readl(u32 pa) +{ + return __raw_readl(OMAP2_L4_IO_ADDRESS(pa)); +} + +static inline void omap_writeb(u8 v, u32 pa) +{ + __raw_writeb(v, OMAP2_L4_IO_ADDRESS(pa)); +} + + +static inline void omap_writew(u16 v, u32 pa) +{ + __raw_writew(v, OMAP2_L4_IO_ADDRESS(pa)); +} + +static inline void omap_writel(u32 v, u32 pa) +{ + __raw_writel(v, OMAP2_L4_IO_ADDRESS(pa)); +} + #endif extern void am35x_musb_reset(void); diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index ad80112c2275..ad32621aa52e 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -307,7 +307,7 @@ static void omap_mbox_fini(struct omap_mbox *mbox) if (!--mbox->use_count) { free_irq(mbox->irq, mbox); tasklet_kill(&mbox->txq->tasklet); - flush_work_sync(&mbox->rxq->work); + flush_work_sync(&mbox->rxq->work); mbox_queue_free(mbox->txq); mbox_queue_free(mbox->rxq); } diff --git a/arch/arm/plat-omap/mux.c b/arch/arm/plat-omap/mux.c index 0d4aa0d5876c..cff8712122bb 100644 --- a/arch/arm/plat-omap/mux.c +++ b/arch/arm/plat-omap/mux.c @@ -26,8 +26,11 @@ #include <linux/init.h> #include <linux/kernel.h> #include <linux/io.h> -#include <asm/system.h> #include <linux/spinlock.h> + +#include <asm/system.h> + +#include <plat/cpu.h> #include <plat/mux.h> #ifdef CONFIG_OMAP_MUX diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c index 3dc3801aace4..5a97b4d98d41 100644 --- a/arch/arm/plat-omap/omap-pm-noop.c +++ b/arch/arm/plat-omap/omap-pm-noop.c @@ -319,7 +319,7 @@ int omap_pm_get_dev_context_loss_count(struct device *dev) if (WARN_ON(!dev)) return -ENODEV; - if (dev->parent == &omap_device_parent) { + if (dev->pm_domain == &omap_device_pm_domain) { count = omap_device_get_context_loss_count(pdev); } else { WARN_ONCE(off_mode_enabled, "omap_pm: using dummy context loss counter; device %s should be converted to omap_device", diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index e8d98693d2dd..d50cbc6385bd 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -1,3 +1,4 @@ + /* * omap_device implementation * @@ -97,14 +98,7 @@ #define USE_WAKEUP_LAT 0 #define IGNORE_WAKEUP_LAT 1 -static int omap_device_register(struct platform_device *pdev); static int omap_early_device_register(struct platform_device *pdev); -static struct omap_device *omap_device_alloc(struct platform_device *pdev, - struct omap_hwmod **ohs, int oh_cnt, - struct omap_device_pm_latency *pm_lats, - int pm_lats_cnt); -static void omap_device_delete(struct omap_device *od); - static struct omap_device_pm_latency omap_default_latency[] = { { @@ -320,8 +314,6 @@ static void _add_hwmod_clocks_clkdev(struct omap_device *od, } -static struct dev_pm_domain omap_device_pm_domain; - /** * omap_device_build_from_dt - build an omap_device with multiple hwmods * @pdev_name: name of the platform_device driver to use @@ -348,7 +340,7 @@ static int omap_device_build_from_dt(struct platform_device *pdev) oh_cnt = of_property_count_strings(node, "ti,hwmods"); if (!oh_cnt || IS_ERR_VALUE(oh_cnt)) { - dev_warn(&pdev->dev, "No 'hwmods' to build omap_device\n"); + dev_dbg(&pdev->dev, "No 'hwmods' to build omap_device\n"); return -ENODEV; } @@ -509,7 +501,7 @@ static int omap_device_fill_resources(struct omap_device *od, * * Returns an struct omap_device pointer or ERR_PTR() on error; */ -static struct omap_device *omap_device_alloc(struct platform_device *pdev, +struct omap_device *omap_device_alloc(struct platform_device *pdev, struct omap_hwmod **ohs, int oh_cnt, struct omap_device_pm_latency *pm_lats, int pm_lats_cnt) @@ -591,7 +583,7 @@ oda_exit1: return ERR_PTR(ret); } -static void omap_device_delete(struct omap_device *od) +void omap_device_delete(struct omap_device *od) { if (!od) return; @@ -619,7 +611,7 @@ static void omap_device_delete(struct omap_device *od) * information. Returns ERR_PTR(-EINVAL) if @oh is NULL; otherwise, * passes along the return value of omap_device_build_ss(). */ -struct platform_device *omap_device_build(const char *pdev_name, int pdev_id, +struct platform_device __init *omap_device_build(const char *pdev_name, int pdev_id, struct omap_hwmod *oh, void *pdata, int pdata_len, struct omap_device_pm_latency *pm_lats, @@ -652,7 +644,7 @@ struct platform_device *omap_device_build(const char *pdev_name, int pdev_id, * platform_device record. Returns an ERR_PTR() on error, or passes * along the return value of omap_device_register(). */ -struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id, +struct platform_device __init *omap_device_build_ss(const char *pdev_name, int pdev_id, struct omap_hwmod **ohs, int oh_cnt, void *pdata, int pdata_len, struct omap_device_pm_latency *pm_lats, @@ -717,7 +709,7 @@ odbs_exit: * platform_early_add_device() on the underlying platform_device. * Returns 0 by default. */ -static int omap_early_device_register(struct platform_device *pdev) +static int __init omap_early_device_register(struct platform_device *pdev) { struct platform_device *devices[1]; @@ -762,14 +754,12 @@ static int _od_suspend_noirq(struct device *dev) struct omap_device *od = to_omap_device(pdev); int ret; - if (od->flags & OMAP_DEVICE_NO_IDLE_ON_SUSPEND) - return pm_generic_suspend_noirq(dev); - ret = pm_generic_suspend_noirq(dev); if (!ret && !pm_runtime_status_suspended(dev)) { if (pm_generic_runtime_suspend(dev) == 0) { - omap_device_idle(pdev); + if (!(od->flags & OMAP_DEVICE_NO_IDLE_ON_SUSPEND)) + omap_device_idle(pdev); od->flags |= OMAP_DEVICE_SUSPENDED; } } @@ -782,13 +772,11 @@ static int _od_resume_noirq(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct omap_device *od = to_omap_device(pdev); - if (od->flags & OMAP_DEVICE_NO_IDLE_ON_SUSPEND) - return pm_generic_resume_noirq(dev); - if ((od->flags & OMAP_DEVICE_SUSPENDED) && !pm_runtime_status_suspended(dev)) { od->flags &= ~OMAP_DEVICE_SUSPENDED; - omap_device_enable(pdev); + if (!(od->flags & OMAP_DEVICE_NO_IDLE_ON_SUSPEND)) + omap_device_enable(pdev); pm_generic_runtime_resume(dev); } @@ -799,7 +787,7 @@ static int _od_resume_noirq(struct device *dev) #define _od_resume_noirq NULL #endif -static struct dev_pm_domain omap_device_pm_domain = { +struct dev_pm_domain omap_device_pm_domain = { .ops = { SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume, _od_runtime_idle) @@ -817,11 +805,10 @@ static struct dev_pm_domain omap_device_pm_domain = { * platform_device_register() on the underlying platform_device. * Returns the return value of platform_device_register(). */ -static int omap_device_register(struct platform_device *pdev) +int omap_device_register(struct platform_device *pdev) { pr_debug("omap_device: %s: registering\n", pdev->name); - pdev->dev.parent = &omap_device_parent; pdev->dev.pm_domain = &omap_device_pm_domain; return platform_device_add(pdev); } @@ -1130,11 +1117,6 @@ int omap_device_enable_clocks(struct omap_device *od) return 0; } -struct device omap_device_parent = { - .init_name = "omap", - .parent = &platform_bus, -}; - static struct notifier_block platform_nb = { .notifier_call = _omap_device_notifier_call, }; @@ -1142,6 +1124,6 @@ static struct notifier_block platform_nb = { static int __init omap_device_init(void) { bus_register_notifier(&platform_bus_type, &platform_nb); - return device_register(&omap_device_parent); + return 0; } core_initcall(omap_device_init); diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 4243bdcc87bc..eec98afa0f83 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -31,11 +31,10 @@ #include "sram.h" -/* XXX These "sideways" includes are a sign that something is wrong */ -#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) -# include "../mach-omap2/prm2xxx_3xxx.h" -# include "../mach-omap2/sdrc.h" -#endif +/* XXX These "sideways" includes will disappear when sram.c becomes a driver */ +#include "../mach-omap2/iomap.h" +#include "../mach-omap2/prm2xxx_3xxx.h" +#include "../mach-omap2/sdrc.h" #define OMAP1_SRAM_PA 0x20000000 #define OMAP2_SRAM_PUB_PA (OMAP2_SRAM_PA + 0xf800) @@ -86,7 +85,7 @@ static int is_sram_locked(void) __raw_writel(0xCFDE, OMAP24XX_VA_READPERM0); /* all i-read */ __raw_writel(0xCFDE, OMAP24XX_VA_WRITEPERM0); /* all i-write */ } - if (cpu_is_omap34xx()) { + if (cpu_is_omap34xx() && !cpu_is_am33xx()) { __raw_writel(0xFFFF, OMAP34XX_VA_REQINFOPERM0); /* all q-vects */ __raw_writel(0xFFFF, OMAP34XX_VA_READPERM0); /* all i-read */ __raw_writel(0xFFFF, OMAP34XX_VA_WRITEPERM0); /* all i-write */ @@ -124,7 +123,10 @@ static void __init omap_detect_sram(void) omap_sram_size = 0x800; /* 2K */ } } else { - if (cpu_is_omap34xx()) { + if (cpu_is_am33xx()) { + omap_sram_start = AM33XX_SRAM_PA; + omap_sram_size = 0x10000; /* 64K */ + } else if (cpu_is_omap34xx()) { omap_sram_start = OMAP3_SRAM_PA; omap_sram_size = 0x10000; /* 64K */ } else if (cpu_is_omap44xx()) { @@ -368,6 +370,11 @@ static inline int omap34xx_sram_init(void) return 0; } +static inline int am33xx_sram_init(void) +{ + return 0; +} + int __init omap_sram_init(void) { omap_detect_sram(); @@ -379,6 +386,8 @@ int __init omap_sram_init(void) omap242x_sram_init(); else if (cpu_is_omap2430()) omap243x_sram_init(); + else if (cpu_is_am33xx()) + am33xx_sram_init(); else if (cpu_is_omap34xx()) omap34xx_sram_init(); diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c index f3570884883e..d2bbfd1cb0b5 100644 --- a/arch/arm/plat-omap/usb.c +++ b/arch/arm/plat-omap/usb.c @@ -29,6 +29,10 @@ #include <plat/usb.h> #include <plat/board.h> +#include <mach/hardware.h> + +#include "../mach-omap2/common.h" + #ifdef CONFIG_ARCH_OMAP_OTG void __init diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c index 089899a7db72..74daf5ed1432 100644 --- a/arch/arm/plat-orion/common.c +++ b/arch/arm/plat-orion/common.c @@ -21,6 +21,7 @@ #include <plat/orion_wdt.h> #include <plat/mv_xor.h> #include <plat/ehci-orion.h> +#include <mach/bridge-regs.h> /* Fill in the resources structure and link it into the platform device structure. There is always a memory region, and nearly @@ -568,13 +569,17 @@ void __init orion_spi_1_init(unsigned long mapbase, ****************************************************************************/ static struct orion_wdt_platform_data orion_wdt_data; +static struct resource orion_wdt_resource = + DEFINE_RES_MEM(TIMER_VIRT_BASE, 0x28); + static struct platform_device orion_wdt_device = { .name = "orion_wdt", .id = -1, .dev = { .platform_data = &orion_wdt_data, }, - .num_resources = 0, + .resource = &orion_wdt_resource, + .num_resources = 1, }; void __init orion_wdt_init(unsigned long tclk) diff --git a/arch/arm/plat-orion/include/plat/audio.h b/arch/arm/plat-orion/include/plat/audio.h index 885f8abd927b..d6a55bd2e578 100644 --- a/arch/arm/plat-orion/include/plat/audio.h +++ b/arch/arm/plat-orion/include/plat/audio.h @@ -2,7 +2,6 @@ #define __PLAT_AUDIO_H struct kirkwood_asoc_platform_data { - u32 tclk; int burst; }; #endif diff --git a/arch/arm/plat-pxa/dma.c b/arch/arm/plat-pxa/dma.c index 2d3c19d7c7b1..79ef102e3b2b 100644 --- a/arch/arm/plat-pxa/dma.c +++ b/arch/arm/plat-pxa/dma.c @@ -20,7 +20,6 @@ #include <linux/errno.h> #include <linux/dma-mapping.h> -#include <asm/system.h> #include <asm/irq.h> #include <asm/memory.h> #include <mach/hardware.h> diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig index d8973ac46bc4..21bf6adb9198 100644 --- a/arch/arm/plat-s3c24xx/Kconfig +++ b/arch/arm/plat-s3c24xx/Kconfig @@ -4,7 +4,7 @@ config PLAT_S3C24XX bool - depends on ARCH_S3C2410 + depends on ARCH_S3C24XX default y select NO_IOPORT select ARCH_REQUIRE_GPIOLIB @@ -44,12 +44,6 @@ config S3C2410_CLOCK Clock code for the S3C2410, and similar processors which is currently includes the S3C2410, S3C2440, S3C2442. -config S3C2443_CLOCK - bool - help - Clock code for the S3C2443 and similar processors, which includes - the S3C2416 and S3C2450. - config S3C24XX_DCLK bool help @@ -76,15 +70,9 @@ config S3C24XX_GPIO_EXTRA128 Add an extra 128 gpio numbers to the available GPIO pool. This is available for boards that need extra gpios for external devices. -config PM_SIMTEC - bool - help - Common power management code for systems that are - compatible with the Simtec style of power management - -config S3C2410_DMA +config S3C24XX_DMA bool "S3C2410 DMA support" - depends on ARCH_S3C2410 + depends on ARCH_S3C24XX select S3C_DMA help S3C2410 DMA support. This is needed for drivers like sound which @@ -93,31 +81,11 @@ config S3C2410_DMA config S3C2410_DMA_DEBUG bool "S3C2410 DMA support debug" - depends on ARCH_S3C2410 && S3C2410_DMA + depends on ARCH_S3C24XX && S3C2410_DMA help Enable debugging output for the DMA code. This option sends info to the kernel log, at priority KERN_DEBUG. -# SPI default pin configuration code - -config S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13 - bool - help - SPI GPIO configuration code for BUS0 when connected to - GPE11, GPE12 and GPE13. - -config S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7 - bool - help - SPI GPIO configuration code for BUS 1 when connected to - GPG5, GPG6 and GPG7. - -config S3C24XX_SPI_BUS1_GPD8_GPD9_GPD10 - bool - help - SPI GPIO configuration code for BUS 1 when connected to - GPD8, GPD9 and GPD10. - # common code for s3c24xx based machines, such as the SMDKs. # cpu frequency items common between s3c2410 and s3c2440/s3c2442 @@ -145,21 +113,4 @@ config S3C2412_IOTIMING Intel node to select io timing code that is common to the s3c2412 and the s3c2443. -config MACH_SMDK - bool - help - Common machine code for SMDK2410 and SMDK2440 - -config S3C24XX_SIMTEC_AUDIO - bool - depends on (ARCH_BAST || MACH_VR1000 || MACH_OSIRIS || MACH_ANUBIS) - default y - help - Add audio devices for common Simtec S3C24XX boards - -config S3C2410_SETUP_TS - bool - help - Compile in platform device definition for Samsung TouchScreen. - endif diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile index b2b01125de66..2467b800cc76 100644 --- a/arch/arm/plat-s3c24xx/Makefile +++ b/arch/arm/plat-s3c24xx/Makefile @@ -23,28 +23,11 @@ obj-$(CONFIG_CPU_FREQ_S3C24XX_DEBUGFS) += cpu-freq-debugfs.o # Architecture dependent builds -obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_PM) += irq-pm.o obj-$(CONFIG_PM) += sleep.o obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o -obj-$(CONFIG_S3C2443_CLOCK) += s3c2443-clock.o -obj-$(CONFIG_S3C2410_DMA) += dma.o +obj-$(CONFIG_S3C24XX_DMA) += dma.o obj-$(CONFIG_S3C2410_IOTIMING) += s3c2410-iotiming.o obj-$(CONFIG_S3C2412_IOTIMING) += s3c2412-iotiming.o obj-$(CONFIG_S3C2410_CPUFREQ_UTILS) += s3c2410-cpufreq-utils.o - -# device specific setup and/or initialisation -obj-$(CONFIG_ARCH_S3C2410) += setup-i2c.o -obj-$(CONFIG_S3C2410_SETUP_TS) += setup-ts.o - -# SPI gpio central GPIO functions - -obj-$(CONFIG_S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13) += spi-bus0-gpe11_12_13.o -obj-$(CONFIG_S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7) += spi-bus1-gpg5_6_7.o -obj-$(CONFIG_S3C24XX_SPI_BUS1_GPD8_GPD9_GPD10) += spi-bus1-gpd8_9_10.o - -# machine common support - -obj-$(CONFIG_MACH_SMDK) += common-smdk.o -obj-$(CONFIG_S3C24XX_SIMTEC_AUDIO) += simtec-audio.o diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c index 21f1fda8b661..290942d9adda 100644 --- a/arch/arm/plat-s3c24xx/cpu.c +++ b/arch/arm/plat-s3c24xx/cpu.c @@ -32,8 +32,11 @@ #include <linux/io.h> #include <mach/hardware.h> +#include <mach/regs-clock.h> #include <asm/irq.h> #include <asm/cacheflush.h> +#include <asm/system_info.h> +#include <asm/system_misc.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -190,8 +193,34 @@ static unsigned long s3c24xx_read_idcode_v4(void) return __raw_readl(S3C2410_GSTATUS1); } +static void s3c24xx_default_idle(void) +{ + unsigned long tmp; + int i; + + /* idle the system by using the idle mode which will wait for an + * interrupt to happen before restarting the system. + */ + + /* Warning: going into idle state upsets jtag scanning */ + + __raw_writel(__raw_readl(S3C2410_CLKCON) | S3C2410_CLKCON_IDLE, + S3C2410_CLKCON); + + /* the samsung port seems to do a loop and then unset idle.. */ + for (i = 0; i < 50; i++) + tmp += __raw_readl(S3C2410_CLKCON); /* ensure loop not optimised out */ + + /* this bit is not cleared on re-start... */ + + __raw_writel(__raw_readl(S3C2410_CLKCON) & ~S3C2410_CLKCON_IDLE, + S3C2410_CLKCON); +} + void __init s3c24xx_init_io(struct map_desc *mach_desc, int size) { + arm_pm_idle = s3c24xx_default_idle; + /* initialise the io descriptors we need for initialisation */ iotable_init(mach_desc, size); iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc)); diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index 2bab4c99a234..28f898f75380 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c @@ -27,7 +27,6 @@ #include <linux/errno.h> #include <linux/io.h> -#include <asm/system.h> #include <asm/irq.h> #include <mach/hardware.h> #include <mach/dma.h> diff --git a/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c b/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c deleted file mode 100644 index 704175b0573f..000000000000 --- a/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c +++ /dev/null @@ -1,36 +0,0 @@ -/* linux/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c - * - * Copyright (c) 2008 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks <ben@simtec.co.uk> - * - * S3C24XX SPI - gpio configuration for bus 0 on gpe11,12,13 - * - * 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. -*/ - -#include <linux/kernel.h> -#include <linux/gpio.h> - -#include <mach/spi.h> -#include <mach/regs-gpio.h> - -void s3c24xx_spi_gpiocfg_bus0_gpe11_12_13(struct s3c2410_spi_info *spi, - int enable) -{ - if (enable) { - s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPE13_SPICLK0); - s3c_gpio_cfgpin(S3C2410_GPE(12), S3C2410_GPE12_SPIMOSI0); - s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPE11_SPIMISO0); - s3c2410_gpio_pullup(S3C2410_GPE(11), 0); - s3c2410_gpio_pullup(S3C2410_GPE(13), 0); - } else { - s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_INPUT); - s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPIO_INPUT); - s3c_gpio_setpull(S3C2410_GPE(11), S3C_GPIO_PULL_NONE); - s3c_gpio_setpull(S3C2410_GPE(12), S3C_GPIO_PULL_NONE); - s3c_gpio_setpull(S3C2410_GPE(13), S3C_GPIO_PULL_NONE); - } -} diff --git a/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c deleted file mode 100644 index 72457afd6255..000000000000 --- a/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c +++ /dev/null @@ -1,38 +0,0 @@ -/* linux/arch/arm/plat-s3c24xx/spi-bus0-gpd8_9_10.c - * - * Copyright (c) 2008 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks <ben@simtec.co.uk> - * - * S3C24XX SPI - gpio configuration for bus 1 on gpd8,9,10 - * - * 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. -*/ - -#include <linux/kernel.h> -#include <linux/gpio.h> - -#include <mach/spi.h> -#include <mach/regs-gpio.h> - -void s3c24xx_spi_gpiocfg_bus1_gpd8_9_10(struct s3c2410_spi_info *spi, - int enable) -{ - - printk(KERN_INFO "%s(%d)\n", __func__, enable); - if (enable) { - s3c_gpio_cfgpin(S3C2410_GPD(10), S3C2440_GPD10_SPICLK1); - s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2440_GPD9_SPIMOSI1); - s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2440_GPD8_SPIMISO1); - s3c2410_gpio_pullup(S3C2410_GPD(10), 0); - s3c2410_gpio_pullup(S3C2410_GPD(9), 0); - } else { - s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT); - s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT); - s3c_gpio_setpull(S3C2410_GPD(10), S3C_GPIO_PULL_NONE); - s3c_gpio_setpull(S3C2410_GPD(9), S3C_GPIO_PULL_NONE); - s3c_gpio_setpull(S3C2410_GPD(8), S3C_GPIO_PULL_NONE); - } -} diff --git a/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c b/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c deleted file mode 100644 index c3972b645d13..000000000000 --- a/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c +++ /dev/null @@ -1,36 +0,0 @@ -/* linux/arch/arm/plat-s3c24xx/spi-bus0-gpg5_6_7.c - * - * Copyright (c) 2008 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks <ben@simtec.co.uk> - * - * S3C24XX SPI - gpio configuration for bus 1 on gpg5,6,7 - * - * 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. -*/ - -#include <linux/kernel.h> -#include <linux/gpio.h> - -#include <mach/spi.h> -#include <mach/regs-gpio.h> - -void s3c24xx_spi_gpiocfg_bus1_gpg5_6_7(struct s3c2410_spi_info *spi, - int enable) -{ - if (enable) { - s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPG7_SPICLK1); - s3c_gpio_cfgpin(S3C2410_GPG(6), S3C2410_GPG6_SPIMOSI1); - s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPG5_SPIMISO1); - s3c2410_gpio_pullup(S3C2410_GPG(5), 0); - s3c2410_gpio_pullup(S3C2410_GPG(6), 0); - } else { - s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPIO_INPUT); - s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_INPUT); - s3c_gpio_setpull(S3C2410_GPG(5), S3C_GPIO_PULL_NONE); - s3c_gpio_setpull(S3C2410_GPG(6), S3C_GPIO_PULL_NONE); - s3c_gpio_setpull(S3C2410_GPG(7), S3C_GPIO_PULL_NONE); - } -} diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig index 8167ce66188c..96bea3202304 100644 --- a/arch/arm/plat-s5p/Kconfig +++ b/arch/arm/plat-s5p/Kconfig @@ -9,8 +9,8 @@ config PLAT_S5P bool depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS) default y - select ARM_VIC if !ARCH_EXYNOS4 - select ARM_GIC if ARCH_EXYNOS4 + select ARM_VIC if !ARCH_EXYNOS + select ARM_GIC if ARCH_EXYNOS select GIC_NON_BANKED if ARCH_EXYNOS4 select NO_IOPORT select ARCH_REQUIRE_GPIOLIB @@ -40,6 +40,10 @@ config S5P_HRT help Use the High Resolution timer support +config S5P_DEV_UART + def_bool y + depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210) + config S5P_PM bool help @@ -80,6 +84,16 @@ config S5P_DEV_FIMC3 help Compile in platform device definitions for FIMC controller 3 +config S5P_DEV_JPEG + bool + help + Compile in platform device definitions for JPEG codec + +config S5P_DEV_G2D + bool + help + Compile in platform device definitions for G2D device + config S5P_DEV_FIMD0 bool help diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile index 30d8c3016e6b..4bd824136659 100644 --- a/arch/arm/plat-s5p/Makefile +++ b/arch/arm/plat-s5p/Makefile @@ -12,7 +12,6 @@ obj- := # Core files -obj-y += dev-uart.o obj-y += clock.o obj-y += irq.o obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o @@ -23,5 +22,7 @@ obj-$(CONFIG_S5P_SLEEP) += sleep.o obj-$(CONFIG_S5P_HRT) += s5p-time.o # devices + +obj-$(CONFIG_S5P_DEV_UART) += dev-uart.o obj-$(CONFIG_S5P_DEV_MFC) += dev-mfc.o obj-$(CONFIG_S5P_SETUP_MIPIPHY) += setup-mipiphy.o diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c index 963edea7f7e7..f68a9bb11948 100644 --- a/arch/arm/plat-s5p/clock.c +++ b/arch/arm/plat-s5p/clock.c @@ -61,6 +61,20 @@ struct clk clk_fout_apll = { .id = -1, }; +/* BPLL clock output */ + +struct clk clk_fout_bpll = { + .name = "fout_bpll", + .id = -1, +}; + +/* CPLL clock output */ + +struct clk clk_fout_cpll = { + .name = "fout_cpll", + .id = -1, +}; + /* MPLL clock output * No need .ctrlbit, this is always on */ @@ -101,6 +115,28 @@ struct clksrc_sources clk_src_apll = { .nr_sources = ARRAY_SIZE(clk_src_apll_list), }; +/* Possible clock sources for BPLL Mux */ +static struct clk *clk_src_bpll_list[] = { + [0] = &clk_fin_bpll, + [1] = &clk_fout_bpll, +}; + +struct clksrc_sources clk_src_bpll = { + .sources = clk_src_bpll_list, + .nr_sources = ARRAY_SIZE(clk_src_bpll_list), +}; + +/* Possible clock sources for CPLL Mux */ +static struct clk *clk_src_cpll_list[] = { + [0] = &clk_fin_cpll, + [1] = &clk_fout_cpll, +}; + +struct clksrc_sources clk_src_cpll = { + .sources = clk_src_cpll_list, + .nr_sources = ARRAY_SIZE(clk_src_cpll_list), +}; + /* Possible clock sources for MPLL Mux */ static struct clk *clk_src_mpll_list[] = { [0] = &clk_fin_mpll, diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c index c496b359c371..139c050918c5 100644 --- a/arch/arm/plat-s5p/irq-eint.c +++ b/arch/arm/plat-s5p/irq-eint.c @@ -200,7 +200,7 @@ static struct irq_chip s5p_irq_vic_eint = { #endif }; -int __init s5p_init_irq_eint(void) +static int __init s5p_init_irq_eint(void) { int irq; diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c index 1fdfaa4599ce..82c7311017a2 100644 --- a/arch/arm/plat-s5p/irq-gpioint.c +++ b/arch/arm/plat-s5p/irq-gpioint.c @@ -41,7 +41,7 @@ struct s5p_gpioint_bank { void (*handler)(unsigned int, struct irq_desc *); }; -LIST_HEAD(banks); +static LIST_HEAD(banks); static int s5p_gpioint_set_type(struct irq_data *d, unsigned int type) { diff --git a/arch/arm/plat-s5p/irq-pm.c b/arch/arm/plat-s5p/irq-pm.c index 327acb3a4464..d1bfecae6c9f 100644 --- a/arch/arm/plat-s5p/irq-pm.c +++ b/arch/arm/plat-s5p/irq-pm.c @@ -39,19 +39,32 @@ unsigned long s3c_irqwake_eintallow = 0xffffffffL; int s3c_irq_wake(struct irq_data *data, unsigned int state) { unsigned long irqbit; + unsigned int irq_rtc_tic, irq_rtc_alarm; + +#ifdef CONFIG_ARCH_EXYNOS + if (soc_is_exynos5250()) { + irq_rtc_tic = EXYNOS5_IRQ_RTC_TIC; + irq_rtc_alarm = EXYNOS5_IRQ_RTC_ALARM; + } else { + irq_rtc_tic = EXYNOS4_IRQ_RTC_TIC; + irq_rtc_alarm = EXYNOS4_IRQ_RTC_ALARM; + } +#else + irq_rtc_tic = IRQ_RTC_TIC; + irq_rtc_alarm = IRQ_RTC_ALARM; +#endif + + if (data->irq == irq_rtc_tic || data->irq == irq_rtc_alarm) { + irqbit = 1 << (data->irq + 1 - irq_rtc_alarm); - switch (data->irq) { - case IRQ_RTC_TIC: - case IRQ_RTC_ALARM: - irqbit = 1 << (data->irq + 1 - IRQ_RTC_ALARM); if (!state) s3c_irqwake_intmask |= irqbit; else s3c_irqwake_intmask &= ~irqbit; - break; - default: + } else { return -ENOENT; } + return 0; } diff --git a/arch/arm/plat-s5p/sleep.S b/arch/arm/plat-s5p/sleep.S index 0fd591bfc9fd..006bd01eda02 100644 --- a/arch/arm/plat-s5p/sleep.S +++ b/arch/arm/plat-s5p/sleep.S @@ -23,9 +23,18 @@ */ #include <linux/linkage.h> -#include <asm/assembler.h> +#include <asm/asm-offsets.h> +#include <asm/hardware/cache-l2x0.h> - .text +/* + * The following code is located into the .data section. This is to + * allow l2x0_regs_phys to be accessed with a relative load while we + * can't rely on any MMU translation. We could have put l2x0_regs_phys + * in the .text section as well, but some setups might insist on it to + * be truly read-only. (Reference from: arch/arm/kernel/sleep.S) + */ + .data + .align /* * sleep magic, to allow the bootloader to check for an valid @@ -39,11 +48,34 @@ * s3c_cpu_resume * * resume code entry for bootloader to call - * - * we must put this code here in the data segment as we have no - * other way of restoring the stack pointer after sleep, and we - * must not write to the code segment (code is read-only) */ ENTRY(s3c_cpu_resume) +#ifdef CONFIG_CACHE_L2X0 + adr r0, l2x0_regs_phys + ldr r0, [r0] + ldr r1, [r0, #L2X0_R_PHY_BASE] + ldr r2, [r1, #L2X0_CTRL] + tst r2, #0x1 + bne resume_l2on + ldr r2, [r0, #L2X0_R_AUX_CTRL] + str r2, [r1, #L2X0_AUX_CTRL] + ldr r2, [r0, #L2X0_R_TAG_LATENCY] + str r2, [r1, #L2X0_TAG_LATENCY_CTRL] + ldr r2, [r0, #L2X0_R_DATA_LATENCY] + str r2, [r1, #L2X0_DATA_LATENCY_CTRL] + ldr r2, [r0, #L2X0_R_PREFETCH_CTRL] + str r2, [r1, #L2X0_PREFETCH_CTRL] + ldr r2, [r0, #L2X0_R_PWR_CTRL] + str r2, [r1, #L2X0_POWER_CTRL] + mov r2, #1 + str r2, [r1, #L2X0_CTRL] +resume_l2on: +#endif b cpu_resume +ENDPROC(s3c_cpu_resume) +#ifdef CONFIG_CACHE_L2X0 + .globl l2x0_regs_phys +l2x0_regs_phys: + .long 0 +#endif diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index 6a2abe67c8b2..a0ffc77da809 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -205,7 +205,7 @@ config S3C_DEV_USB_HSOTG config S3C_DEV_WDT bool - default y if ARCH_S3C2410 + default y if ARCH_S3C24XX help Complie in platform device definition for Watchdog Timer @@ -264,7 +264,7 @@ config SAMSUNG_DEV_KEYPAD config SAMSUNG_DEV_PWM bool - default y if ARCH_S3C2410 + default y if ARCH_S3C24XX help Compile in platform device definition for PWM Timer @@ -302,6 +302,7 @@ comment "Power management" config SAMSUNG_PM_DEBUG bool "S3C2410 PM Suspend debug" depends on PM + select DEBUG_LL help Say Y here if you want verbose debugging from the PM Suspend and Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c index 10f71179071f..65c5eca475e7 100644 --- a/arch/arm/plat-samsung/clock.c +++ b/arch/arm/plat-samsung/clock.c @@ -84,31 +84,35 @@ static int clk_null_enable(struct clk *clk, int enable) int clk_enable(struct clk *clk) { + unsigned long flags; + if (IS_ERR(clk) || clk == NULL) return -EINVAL; clk_enable(clk->parent); - spin_lock(&clocks_lock); + spin_lock_irqsave(&clocks_lock, flags); if ((clk->usage++) == 0) (clk->enable)(clk, 1); - spin_unlock(&clocks_lock); + spin_unlock_irqrestore(&clocks_lock, flags); return 0; } void clk_disable(struct clk *clk) { + unsigned long flags; + if (IS_ERR(clk) || clk == NULL) return; - spin_lock(&clocks_lock); + spin_lock_irqsave(&clocks_lock, flags); if ((--clk->usage) == 0) (clk->enable)(clk, 0); - spin_unlock(&clocks_lock); + spin_unlock_irqrestore(&clocks_lock, flags); clk_disable(clk->parent); } diff --git a/arch/arm/plat-samsung/cpu.c b/arch/arm/plat-samsung/cpu.c index 81c06d44c11e..46b426e8aff5 100644 --- a/arch/arm/plat-samsung/cpu.c +++ b/arch/arm/plat-samsung/cpu.c @@ -15,7 +15,6 @@ #include <linux/init.h> #include <linux/io.h> -#include <asm/system.h> #include <mach/map.h> #include <plat/cpu.h> diff --git a/arch/arm/plat-samsung/dev-backlight.c b/arch/arm/plat-samsung/dev-backlight.c index a976c023b286..5f197dcaf10c 100644 --- a/arch/arm/plat-samsung/dev-backlight.c +++ b/arch/arm/plat-samsung/dev-backlight.c @@ -77,7 +77,7 @@ static struct platform_device samsung_dfl_bl_device __initdata = { * @gpio_info: structure containing GPIO info for PWM timer * @bl_data: structure containing Backlight control data */ -void samsung_bl_set(struct samsung_bl_gpio_info *gpio_info, +void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info, struct platform_pwm_backlight_data *bl_data) { int ret = 0; @@ -115,6 +115,8 @@ void samsung_bl_set(struct samsung_bl_gpio_info *gpio_info, samsung_bl_data->init = bl_data->init; if (bl_data->notify) samsung_bl_data->notify = bl_data->notify; + if (bl_data->notify_after) + samsung_bl_data->notify_after = bl_data->notify_after; if (bl_data->exit) samsung_bl_data->exit = bl_data->exit; if (bl_data->check_fb) diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c index d21d744e4d99..8b928f9bc1c3 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/plat-samsung/devs.c @@ -57,6 +57,7 @@ #include <plat/sdhci.h> #include <plat/ts.h> #include <plat/udc.h> +#include <plat/udc-hs.h> #include <plat/usb-control.h> #include <plat/usb-phy.h> #include <plat/regs-iic.h> @@ -267,6 +268,52 @@ struct platform_device s5p_device_fimc3 = { }; #endif /* CONFIG_S5P_DEV_FIMC3 */ +/* G2D */ + +#ifdef CONFIG_S5P_DEV_G2D +static struct resource s5p_g2d_resource[] = { + [0] = { + .start = S5P_PA_G2D, + .end = S5P_PA_G2D + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_2D, + .end = IRQ_2D, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device s5p_device_g2d = { + .name = "s5p-g2d", + .id = 0, + .num_resources = ARRAY_SIZE(s5p_g2d_resource), + .resource = s5p_g2d_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; +#endif /* CONFIG_S5P_DEV_G2D */ + +#ifdef CONFIG_S5P_DEV_JPEG +static struct resource s5p_jpeg_resource[] = { + [0] = DEFINE_RES_MEM(S5P_PA_JPEG, SZ_4K), + [1] = DEFINE_RES_IRQ(IRQ_JPEG), +}; + +struct platform_device s5p_device_jpeg = { + .name = "s5p-jpeg", + .id = 0, + .num_resources = ARRAY_SIZE(s5p_jpeg_resource), + .resource = s5p_jpeg_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; +#endif /* CONFIG_S5P_DEV_JPEG */ + /* FIMD0 */ #ifdef CONFIG_S5P_DEV_FIMD0 @@ -744,17 +791,6 @@ struct platform_device s3c_device_iis = { }; #endif /* CONFIG_PLAT_S3C24XX */ -#ifdef CONFIG_CPU_S3C2440 -struct platform_device s3c2412_device_iis = { - .name = "s3c2412-iis", - .id = -1, - .dev = { - .dma_mask = &samsung_device_dma_mask, - .coherent_dma_mask = DMA_BIT_MASK(32), - } -}; -#endif /* CONFIG_CPU_S3C2440 */ - /* IDE CFCON */ #ifdef CONFIG_SAMSUNG_DEV_IDE @@ -769,7 +805,7 @@ struct platform_device s3c_device_cfcon = { .resource = s3c_cfcon_resource, }; -void s3c_ide_set_platdata(struct s3c_ide_platdata *pdata) +void __init s3c_ide_set_platdata(struct s3c_ide_platdata *pdata) { s3c_set_platdata(pdata, sizeof(struct s3c_ide_platdata), &s3c_device_cfcon); @@ -887,7 +923,7 @@ struct platform_device s5p_device_mfc_r = { #ifdef CONFIG_S5P_DEV_CSIS0 static struct resource s5p_mipi_csis0_resource[] = { - [0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS0, SZ_4K), + [0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS0, SZ_16K), [1] = DEFINE_RES_IRQ(IRQ_MIPI_CSIS0), }; @@ -901,7 +937,7 @@ struct platform_device s5p_device_mipi_csis0 = { #ifdef CONFIG_S5P_DEV_CSIS1 static struct resource s5p_mipi_csis1_resource[] = { - [0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS1, SZ_4K), + [0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS1, SZ_16K), [1] = DEFINE_RES_IRQ(IRQ_MIPI_CSIS1), }; @@ -1049,7 +1085,7 @@ struct platform_device s3c64xx_device_onenand1 = { .resource = s3c64xx_onenand1_resources, }; -void s3c64xx_onenand1_set_platdata(struct onenand_platform_data *pdata) +void __init s3c64xx_onenand1_set_platdata(struct onenand_platform_data *pdata) { s3c_set_platdata(pdata, sizeof(struct onenand_platform_data), &s3c64xx_device_onenand1); @@ -1078,7 +1114,7 @@ static struct resource s5p_pmu_resource[] = { DEFINE_RES_IRQ(IRQ_PMU) }; -struct platform_device s5p_device_pmu = { +static struct platform_device s5p_device_pmu = { .name = "arm-pmu", .id = ARM_PMU_DEVICE_CPU, .num_resources = ARRAY_SIZE(s5p_pmu_resource), @@ -1423,6 +1459,19 @@ struct platform_device s3c_device_usb_hsotg = { .coherent_dma_mask = DMA_BIT_MASK(32), }, }; + +void __init s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd) +{ + struct s3c_hsotg_plat *npd; + + npd = s3c_set_platdata(pd, sizeof(struct s3c_hsotg_plat), + &s3c_device_usb_hsotg); + + if (!npd->phy_init) + npd->phy_init = s5p_usb_phy_init; + if (!npd->phy_exit) + npd->phy_exit = s5p_usb_phy_exit; +} #endif /* CONFIG_S3C_DEV_USB_HSOTG */ /* USB High Spped 2.0 Device (Gadget) */ diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c index 0747c77a2fd5..eb9f4f534006 100644 --- a/arch/arm/plat-samsung/dma-ops.c +++ b/arch/arm/plat-samsung/dma-ops.c @@ -79,11 +79,11 @@ static int samsung_dmadev_prepare(unsigned ch, info->len, offset_in_page(info->buf)); sg_dma_address(&sg) = info->buf; - desc = chan->device->device_prep_slave_sg(chan, + desc = dmaengine_prep_slave_sg(chan, &sg, 1, info->direction, DMA_PREP_INTERRUPT); break; case DMA_CYCLIC: - desc = chan->device->device_prep_dma_cyclic(chan, + desc = dmaengine_prep_dma_cyclic(chan, info->buf, info->len, info->period, info->direction); break; default: @@ -116,7 +116,7 @@ static inline int samsung_dmadev_flush(unsigned ch) return dmaengine_terminate_all((struct dma_chan *)ch); } -struct samsung_dma_ops dmadev_ops = { +static struct samsung_dma_ops dmadev_ops = { .request = samsung_dmadev_request, .release = samsung_dmadev_release, .prepare = samsung_dmadev_prepare, diff --git a/arch/arm/plat-samsung/include/plat/audio-simtec.h b/arch/arm/plat-samsung/include/plat/audio-simtec.h index 5345364e7420..376af5286a3e 100644 --- a/arch/arm/plat-samsung/include/plat/audio-simtec.h +++ b/arch/arm/plat-samsung/include/plat/audio-simtec.h @@ -32,6 +32,3 @@ struct s3c24xx_audio_simtec_pdata { void (*startup)(void); }; - -extern int simtec_audio_add(const char *codec_name, bool has_lr_routing, - struct s3c24xx_audio_simtec_pdata *pdata); diff --git a/arch/arm/plat-samsung/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h index 73c66d4d10fa..a62753dc15ba 100644 --- a/arch/arm/plat-samsung/include/plat/clock.h +++ b/arch/arm/plat-samsung/include/plat/clock.h @@ -79,6 +79,10 @@ extern struct clk clk_epll; extern struct clk clk_xtal; extern struct clk clk_ext; +/* S3C2443/S3C2416 specific clocks */ +extern struct clksrc_clk clk_epllref; +extern struct clksrc_clk clk_esysclk; + /* S3C64XX specific clocks */ extern struct clk clk_h2; extern struct clk clk_27m; @@ -114,7 +118,23 @@ extern void s3c24xx_setup_clocks(unsigned long fclk, extern void s3c2410_setup_clocks(void); extern void s3c2412_setup_clocks(void); extern void s3c244x_setup_clocks(void); -extern void s3c2443_setup_clocks(void); + +/* S3C2410 specific clock functions */ + +extern int s3c2410_baseclk_add(void); + +/* S3C2443/S3C2416 specific clock functions */ + +typedef unsigned int (*pll_fn)(unsigned int reg, unsigned int base); + +extern void s3c2443_common_setup_clocks(pll_fn get_mpll); +extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, + unsigned int *divs, int nr_divs, + int divmask); + +extern int s3c2443_clkcon_enable_h(struct clk *clk, int enable); +extern int s3c2443_clkcon_enable_p(struct clk *clk, int enable); +extern int s3c2443_clkcon_enable_s(struct clk *clk, int enable); /* S3C64XX specific functions and clocks */ diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h index 73cb3cfd0685..787ceaca0be8 100644 --- a/arch/arm/plat-samsung/include/plat/cpu.h +++ b/arch/arm/plat-samsung/include/plat/cpu.h @@ -42,6 +42,9 @@ extern unsigned long samsung_cpu_id; #define EXYNOS4412_CPU_ID 0xE4412200 #define EXYNOS4_CPU_MASK 0xFFFE0000 +#define EXYNOS5250_SOC_ID 0x43520000 +#define EXYNOS5_SOC_MASK 0xFFFFF000 + #define IS_SAMSUNG_CPU(name, id, mask) \ static inline int is_samsung_##name(void) \ { \ @@ -58,6 +61,7 @@ IS_SAMSUNG_CPU(s5pv210, S5PV210_CPU_ID, S5PV210_CPU_MASK) IS_SAMSUNG_CPU(exynos4210, EXYNOS4210_CPU_ID, EXYNOS4_CPU_MASK) IS_SAMSUNG_CPU(exynos4212, EXYNOS4212_CPU_ID, EXYNOS4_CPU_MASK) IS_SAMSUNG_CPU(exynos4412, EXYNOS4412_CPU_ID, EXYNOS4_CPU_MASK) +IS_SAMSUNG_CPU(exynos5250, EXYNOS5250_SOC_ID, EXYNOS5_SOC_MASK) #if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2412) || \ defined(CONFIG_CPU_S3C2416) || defined(CONFIG_CPU_S3C2440) || \ @@ -120,6 +124,12 @@ IS_SAMSUNG_CPU(exynos4412, EXYNOS4412_CPU_ID, EXYNOS4_CPU_MASK) #define EXYNOS4210_REV_1_0 (0x10) #define EXYNOS4210_REV_1_1 (0x11) +#if defined(CONFIG_SOC_EXYNOS5250) +# define soc_is_exynos5250() is_samsung_exynos5250() +#else +# define soc_is_exynos5250() 0 +#endif + #define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE } #ifndef MHZ diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h index 4214ea0ff8fe..2155d4af62a3 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h @@ -26,6 +26,8 @@ struct s3c24xx_uart_resources { extern struct s3c24xx_uart_resources s3c2410_uart_resources[]; extern struct s3c24xx_uart_resources s3c64xx_uart_resources[]; extern struct s3c24xx_uart_resources s5p_uart_resources[]; +extern struct s3c24xx_uart_resources exynos4_uart_resources[]; +extern struct s3c24xx_uart_resources exynos5_uart_resources[]; extern struct platform_device *s3c24xx_uart_devs[]; extern struct platform_device *s3c24xx_uart_src[]; @@ -79,6 +81,8 @@ extern struct platform_device s5p_device_fimc1; extern struct platform_device s5p_device_fimc2; extern struct platform_device s5p_device_fimc3; extern struct platform_device s5p_device_fimc_md; +extern struct platform_device s5p_device_jpeg; +extern struct platform_device s5p_device_g2d; extern struct platform_device s5p_device_fimd0; extern struct platform_device s5p_device_hdmi; extern struct platform_device s5p_device_i2c_hdmiphy; diff --git a/arch/arm/plat-samsung/include/plat/dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h index c5eaad529de5..0670f37aaaed 100644 --- a/arch/arm/plat-samsung/include/plat/dma-pl330.h +++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h @@ -82,6 +82,22 @@ enum dma_ch { DMACH_SLIMBUS4_TX, DMACH_SLIMBUS5_RX, DMACH_SLIMBUS5_TX, + DMACH_MIPI_HSI0, + DMACH_MIPI_HSI1, + DMACH_MIPI_HSI2, + DMACH_MIPI_HSI3, + DMACH_MIPI_HSI4, + DMACH_MIPI_HSI5, + DMACH_MIPI_HSI6, + DMACH_MIPI_HSI7, + DMACH_MTOM_0, + DMACH_MTOM_1, + DMACH_MTOM_2, + DMACH_MTOM_3, + DMACH_MTOM_4, + DMACH_MTOM_5, + DMACH_MTOM_6, + DMACH_MTOM_7, /* END Marker, also used to denote a reserved channel */ DMACH_MAX, }; diff --git a/arch/arm/plat-samsung/include/plat/regs-dma.h b/arch/arm/plat-samsung/include/plat/regs-dma.h index 178bccbe4804..a7d622ef16af 100644 --- a/arch/arm/plat-samsung/include/plat/regs-dma.h +++ b/arch/arm/plat-samsung/include/plat/regs-dma.h @@ -119,7 +119,7 @@ #define S3C2412_DMAREQSEL_UART2_1 S3C2412_DMAREQSEL_SRC(24) #endif /* CONFIG_CPU_S3C2412 */ -#ifdef CONFIG_CPU_S3C2443 +#if defined(CONFIG_CPU_S3C2416) || defined(CONFIG_CPU_S3C2443) #define S3C2443_DMAREQSEL_SRC(x) ((x) << 1) diff --git a/arch/arm/plat-samsung/include/plat/regs-rtc.h b/arch/arm/plat-samsung/include/plat/regs-rtc.h index 30b7cc14cef5..0f8263e93eea 100644 --- a/arch/arm/plat-samsung/include/plat/regs-rtc.h +++ b/arch/arm/plat-samsung/include/plat/regs-rtc.h @@ -18,51 +18,54 @@ #define S3C2410_INTP_ALM (1 << 1) #define S3C2410_INTP_TIC (1 << 0) -#define S3C2410_RTCCON S3C2410_RTCREG(0x40) -#define S3C2410_RTCCON_RTCEN (1<<0) -#define S3C2410_RTCCON_CLKSEL (1<<1) -#define S3C2410_RTCCON_CNTSEL (1<<2) -#define S3C2410_RTCCON_CLKRST (1<<3) -#define S3C64XX_RTCCON_TICEN (1<<8) +#define S3C2410_RTCCON S3C2410_RTCREG(0x40) +#define S3C2410_RTCCON_RTCEN (1 << 0) +#define S3C2410_RTCCON_CNTSEL (1 << 2) +#define S3C2410_RTCCON_CLKRST (1 << 3) +#define S3C2443_RTCCON_TICSEL (1 << 4) +#define S3C64XX_RTCCON_TICEN (1 << 8) -#define S3C64XX_RTCCON_TICMSK (0xF<<7) -#define S3C64XX_RTCCON_TICSHT (7) +#define S3C2410_TICNT S3C2410_RTCREG(0x44) +#define S3C2410_TICNT_ENABLE (1 << 7) -#define S3C2410_TICNT S3C2410_RTCREG(0x44) -#define S3C2410_TICNT_ENABLE (1<<7) +/* S3C2443: tick count is 15 bit wide + * TICNT[6:0] contains upper 7 bits + * TICNT1[7:0] contains lower 8 bits + */ +#define S3C2443_TICNT_PART(x) ((x & 0x7f00) >> 8) +#define S3C2443_TICNT1 S3C2410_RTCREG(0x4C) +#define S3C2443_TICNT1_PART(x) (x & 0xff) -#define S3C2410_RTCALM S3C2410_RTCREG(0x50) -#define S3C2410_RTCALM_ALMEN (1<<6) -#define S3C2410_RTCALM_YEAREN (1<<5) -#define S3C2410_RTCALM_MONEN (1<<4) -#define S3C2410_RTCALM_DAYEN (1<<3) -#define S3C2410_RTCALM_HOUREN (1<<2) -#define S3C2410_RTCALM_MINEN (1<<1) -#define S3C2410_RTCALM_SECEN (1<<0) +/* S3C2416: tick count is 32 bit wide + * TICNT[6:0] contains bits [14:8] + * TICNT1[7:0] contains lower 8 bits + * TICNT2[16:0] contains upper 17 bits + */ +#define S3C2416_TICNT2 S3C2410_RTCREG(0x48) +#define S3C2416_TICNT2_PART(x) ((x & 0xffff8000) >> 15) -#define S3C2410_RTCALM_ALL \ - S3C2410_RTCALM_ALMEN | S3C2410_RTCALM_YEAREN | S3C2410_RTCALM_MONEN |\ - S3C2410_RTCALM_DAYEN | S3C2410_RTCALM_HOUREN | S3C2410_RTCALM_MINEN |\ - S3C2410_RTCALM_SECEN +#define S3C2410_RTCALM S3C2410_RTCREG(0x50) +#define S3C2410_RTCALM_ALMEN (1 << 6) +#define S3C2410_RTCALM_YEAREN (1 << 5) +#define S3C2410_RTCALM_MONEN (1 << 4) +#define S3C2410_RTCALM_DAYEN (1 << 3) +#define S3C2410_RTCALM_HOUREN (1 << 2) +#define S3C2410_RTCALM_MINEN (1 << 1) +#define S3C2410_RTCALM_SECEN (1 << 0) +#define S3C2410_ALMSEC S3C2410_RTCREG(0x54) +#define S3C2410_ALMMIN S3C2410_RTCREG(0x58) +#define S3C2410_ALMHOUR S3C2410_RTCREG(0x5c) -#define S3C2410_ALMSEC S3C2410_RTCREG(0x54) -#define S3C2410_ALMMIN S3C2410_RTCREG(0x58) -#define S3C2410_ALMHOUR S3C2410_RTCREG(0x5c) - -#define S3C2410_ALMDATE S3C2410_RTCREG(0x60) -#define S3C2410_ALMMON S3C2410_RTCREG(0x64) -#define S3C2410_ALMYEAR S3C2410_RTCREG(0x68) - -#define S3C2410_RTCRST S3C2410_RTCREG(0x6c) - -#define S3C2410_RTCSEC S3C2410_RTCREG(0x70) -#define S3C2410_RTCMIN S3C2410_RTCREG(0x74) -#define S3C2410_RTCHOUR S3C2410_RTCREG(0x78) -#define S3C2410_RTCDATE S3C2410_RTCREG(0x7c) -#define S3C2410_RTCDAY S3C2410_RTCREG(0x80) -#define S3C2410_RTCMON S3C2410_RTCREG(0x84) -#define S3C2410_RTCYEAR S3C2410_RTCREG(0x88) +#define S3C2410_ALMDATE S3C2410_RTCREG(0x60) +#define S3C2410_ALMMON S3C2410_RTCREG(0x64) +#define S3C2410_ALMYEAR S3C2410_RTCREG(0x68) +#define S3C2410_RTCSEC S3C2410_RTCREG(0x70) +#define S3C2410_RTCMIN S3C2410_RTCREG(0x74) +#define S3C2410_RTCHOUR S3C2410_RTCREG(0x78) +#define S3C2410_RTCDATE S3C2410_RTCREG(0x7c) +#define S3C2410_RTCMON S3C2410_RTCREG(0x84) +#define S3C2410_RTCYEAR S3C2410_RTCREG(0x88) #endif /* __ASM_ARCH_REGS_RTC_H */ diff --git a/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h index a111ad871833..fcf279662067 100644 --- a/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h +++ b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h @@ -25,8 +25,9 @@ #define S3C_HSOTG_PHYREG(x) ((x) + S3C_VA_USB_HSPHY) #define S3C_PHYPWR S3C_HSOTG_PHYREG(0x00) -#define SRC_PHYPWR_OTG_DISABLE (1 << 4) -#define SRC_PHYPWR_ANALOG_POWERDOWN (1 << 3) +#define S3C_PHYPWR_NORMAL_MASK (0x19 << 0) +#define S3C_PHYPWR_OTG_DISABLE (1 << 4) +#define S3C_PHYPWR_ANALOG_POWERDOWN (1 << 3) #define SRC_PHYPWR_FORCE_SUSPEND (1 << 1) #define S3C_PHYCLK S3C_HSOTG_PHYREG(0x04) @@ -42,7 +43,7 @@ #define S3C_RSTCON S3C_HSOTG_PHYREG(0x08) #define S3C_RSTCON_PHYCLK (1 << 2) -#define S3C_RSTCON_HCLK (1 << 2) +#define S3C_RSTCON_HCLK (1 << 1) #define S3C_RSTCON_PHY (1 << 0) #define S3C_PHYTUNE S3C_HSOTG_PHYREG(0x20) diff --git a/arch/arm/plat-samsung/include/plat/rtc-core.h b/arch/arm/plat-samsung/include/plat/rtc-core.h new file mode 100644 index 000000000000..21d8594d37ca --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/rtc-core.h @@ -0,0 +1,27 @@ +/* linux/arch/arm/plat-samsung/include/plat/rtc-core.h + * + * Copyright (c) 2011 Heiko Stuebner <heiko@sntech.de> + * + * Samsung RTC Controller core functions + * + * 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. +*/ + +#ifndef __ASM_PLAT_RTC_CORE_H +#define __ASM_PLAT_RTC_CORE_H __FILE__ + +/* These functions are only for use with the core support code, such as + * the cpu specific initialisation code + */ + +/* re-define device name depending on support. */ +static inline void s3c_rtc_setname(char *name) +{ +#if defined(CONFIG_SAMSUNG_DEV_RTC) || defined(CONFIG_PLAT_S3C24XX) + s3c_device_rtc.name = name; +#endif +} + +#endif /* __ASM_PLAT_RTC_CORE_H */ diff --git a/arch/arm/plat-samsung/include/plat/s3c2410.h b/arch/arm/plat-samsung/include/plat/s3c2410.h index 3986497dd3f7..55b0e5f51e97 100644 --- a/arch/arm/plat-samsung/include/plat/s3c2410.h +++ b/arch/arm/plat-samsung/include/plat/s3c2410.h @@ -29,5 +29,3 @@ extern void s3c2410_init_clocks(int xtal); #define s3c2410_init NULL #define s3c2410a_init NULL #endif - -extern int s3c2410_baseclk_add(void); diff --git a/arch/arm/plat-samsung/include/plat/s3c2443.h b/arch/arm/plat-samsung/include/plat/s3c2443.h index dce05b43d51c..a5b794ff838b 100644 --- a/arch/arm/plat-samsung/include/plat/s3c2443.h +++ b/arch/arm/plat-samsung/include/plat/s3c2443.h @@ -32,23 +32,3 @@ extern void s3c2443_restart(char mode, const char *cmd); #define s3c2443_init NULL #define s3c2443_restart NULL #endif - -/* common code used by s3c2443 and others. - * note, not to be used outside of arch/arm/mach-s3c* */ - -struct clk; /* some files don't need clk.h otherwise */ - -typedef unsigned int (*pll_fn)(unsigned int reg, unsigned int base); - -extern void s3c2443_common_setup_clocks(pll_fn get_mpll); -extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, - unsigned int *divs, int nr_divs, - int divmask); - -extern int s3c2443_clkcon_enable_h(struct clk *clk, int enable); -extern int s3c2443_clkcon_enable_p(struct clk *clk, int enable); -extern int s3c2443_clkcon_enable_s(struct clk *clk, int enable); - -extern struct clksrc_clk clk_epllref; -extern struct clksrc_clk clk_esysclk; -extern struct clksrc_clk clk_msysclk; diff --git a/arch/arm/plat-samsung/include/plat/s5p-clock.h b/arch/arm/plat-samsung/include/plat/s5p-clock.h index 984bf9e7bc89..1de4b32f98e9 100644 --- a/arch/arm/plat-samsung/include/plat/s5p-clock.h +++ b/arch/arm/plat-samsung/include/plat/s5p-clock.h @@ -18,6 +18,8 @@ #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) #define clk_fin_apll clk_ext_xtal_mux +#define clk_fin_bpll clk_ext_xtal_mux +#define clk_fin_cpll clk_ext_xtal_mux #define clk_fin_mpll clk_ext_xtal_mux #define clk_fin_epll clk_ext_xtal_mux #define clk_fin_dpll clk_ext_xtal_mux @@ -29,6 +31,8 @@ extern struct clk clk_xusbxti; extern struct clk clk_48m; extern struct clk s5p_clk_27m; extern struct clk clk_fout_apll; +extern struct clk clk_fout_bpll; +extern struct clk clk_fout_cpll; extern struct clk clk_fout_mpll; extern struct clk clk_fout_epll; extern struct clk clk_fout_dpll; @@ -37,6 +41,8 @@ extern struct clk clk_arm; extern struct clk clk_vpll; extern struct clksrc_sources clk_src_apll; +extern struct clksrc_sources clk_src_bpll; +extern struct clksrc_sources clk_src_cpll; extern struct clksrc_sources clk_src_mpll; extern struct clksrc_sources clk_src_epll; extern struct clksrc_sources clk_src_dpll; diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h index f82f888b91a9..317e246ffc56 100644 --- a/arch/arm/plat-samsung/include/plat/sdhci.h +++ b/arch/arm/plat-samsung/include/plat/sdhci.h @@ -40,6 +40,7 @@ enum clk_types { * struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI * @max_width: The maximum number of data bits supported. * @host_caps: Standard MMC host capabilities bit field. + * @host_caps2: The second standard MMC host capabilities bit field. * @cd_type: Type of Card Detection method (see cd_types enum above) * @clk_type: Type of clock divider method (see clk_types enum above) * @ext_cd_init: Initialize external card detect subsystem. Called on @@ -63,6 +64,7 @@ enum clk_types { struct s3c_sdhci_platdata { unsigned int max_width; unsigned int host_caps; + unsigned int host_caps2; unsigned int pm_caps; enum cd_types cd_type; enum clk_types clk_type; diff --git a/arch/arm/plat-samsung/include/plat/udc-hs.h b/arch/arm/plat-samsung/include/plat/udc-hs.h index a22a4f2eea94..c9e3667cb2b1 100644 --- a/arch/arm/plat-samsung/include/plat/udc-hs.h +++ b/arch/arm/plat-samsung/include/plat/udc-hs.h @@ -26,4 +26,9 @@ enum s3c_hsotg_dmamode { struct s3c_hsotg_plat { enum s3c_hsotg_dmamode dma; unsigned int is_osc : 1; + + int (*phy_init)(struct platform_device *pdev, int type); + int (*phy_exit)(struct platform_device *pdev, int type); }; + +extern void s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd); diff --git a/arch/arm/plat-samsung/include/plat/uncompress.h b/arch/arm/plat-samsung/include/plat/uncompress.h index ee48e12a1e72..7e068d182c3d 100644 --- a/arch/arm/plat-samsung/include/plat/uncompress.h +++ b/arch/arm/plat-samsung/include/plat/uncompress.h @@ -37,7 +37,9 @@ static void arch_detect_cpu(void); /* how many bytes we allow into the FIFO at a time in FIFO mode */ #define FIFO_MAX (14) +#ifdef S3C_PA_UART #define uart_base S3C_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT) +#endif static __inline__ void uart_wr(unsigned int reg, unsigned int val) diff --git a/arch/arm/plat-samsung/irq-vic-timer.c b/arch/arm/plat-samsung/irq-vic-timer.c index 51583cd30164..f980cf3d2baa 100644 --- a/arch/arm/plat-samsung/irq-vic-timer.c +++ b/arch/arm/plat-samsung/irq-vic-timer.c @@ -19,6 +19,7 @@ #include <linux/io.h> #include <mach/map.h> +#include <plat/cpu.h> #include <plat/irq-vic-timer.h> #include <plat/regs-timer.h> @@ -57,6 +58,21 @@ void __init s3c_init_vic_timer_irq(unsigned int num, unsigned int timer_irq) struct irq_chip_type *ct; unsigned int i; +#ifdef CONFIG_ARCH_EXYNOS + if (soc_is_exynos5250()) { + pirq[0] = EXYNOS5_IRQ_TIMER0_VIC; + pirq[1] = EXYNOS5_IRQ_TIMER1_VIC; + pirq[2] = EXYNOS5_IRQ_TIMER2_VIC; + pirq[3] = EXYNOS5_IRQ_TIMER3_VIC; + pirq[4] = EXYNOS5_IRQ_TIMER4_VIC; + } else { + pirq[0] = EXYNOS4_IRQ_TIMER0_VIC; + pirq[1] = EXYNOS4_IRQ_TIMER1_VIC; + pirq[2] = EXYNOS4_IRQ_TIMER2_VIC; + pirq[3] = EXYNOS4_IRQ_TIMER3_VIC; + pirq[4] = EXYNOS4_IRQ_TIMER4_VIC; + } +#endif s3c_tgc = irq_alloc_generic_chip("s3c-timer", 1, timer_irq, S3C64XX_TINT_CSTAT, handle_level_irq); diff --git a/arch/arm/plat-samsung/platformdata.c b/arch/arm/plat-samsung/platformdata.c index 0f707184eae0..fa78aa710ed1 100644 --- a/arch/arm/plat-samsung/platformdata.c +++ b/arch/arm/plat-samsung/platformdata.c @@ -53,6 +53,8 @@ void s3c_sdhci_set_platdata(struct s3c_sdhci_platdata *pd, set->cfg_gpio = pd->cfg_gpio; if (pd->host_caps) set->host_caps |= pd->host_caps; + if (pd->host_caps2) + set->host_caps2 |= pd->host_caps2; if (pd->pm_caps) set->pm_caps |= pd->pm_caps; if (pd->clk_type) diff --git a/arch/arm/plat-samsung/time.c b/arch/arm/plat-samsung/time.c index e3bb806bbafe..4dcb11c3d894 100644 --- a/arch/arm/plat-samsung/time.c +++ b/arch/arm/plat-samsung/time.c @@ -28,7 +28,6 @@ #include <linux/io.h> #include <linux/platform_device.h> -#include <asm/system.h> #include <asm/leds.h> #include <asm/mach-types.h> diff --git a/arch/arm/plat-spear/include/plat/hardware.h b/arch/arm/plat-spear/include/plat/hardware.h index 66d677225d15..70187d763e26 100644 --- a/arch/arm/plat-spear/include/plat/hardware.h +++ b/arch/arm/plat-spear/include/plat/hardware.h @@ -14,10 +14,4 @@ #ifndef __PLAT_HARDWARE_H #define __PLAT_HARDWARE_H -#ifndef __ASSEMBLY__ -#define IOMEM(x) ((void __iomem __force *)(x)) -#else -#define IOMEM(x) (x) -#endif - #endif /* __PLAT_HARDWARE_H */ diff --git a/arch/arm/plat-spear/include/plat/io.h b/arch/arm/plat-spear/include/plat/io.h deleted file mode 100644 index 4d4ba822b3eb..000000000000 --- a/arch/arm/plat-spear/include/plat/io.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * arch/arm/plat-spear/include/plat/io.h - * - * IO definitions for SPEAr platform - * - * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar<viresh.kumar@st.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __PLAT_IO_H -#define __PLAT_IO_H - -#define IO_SPACE_LIMIT 0xFFFFFFFF - -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#endif /* __PLAT_IO_H */ diff --git a/arch/arm/plat-spear/include/plat/keyboard.h b/arch/arm/plat-spear/include/plat/keyboard.h index c16cc31ecbed..0562f134621d 100644 --- a/arch/arm/plat-spear/include/plat/keyboard.h +++ b/arch/arm/plat-spear/include/plat/keyboard.h @@ -159,11 +159,4 @@ struct kbd_platform_data { unsigned int mode; }; -/* This function is used to set platform data field of pdev->dev */ -static inline void -kbd_set_plat_data(struct platform_device *pdev, struct kbd_platform_data *data) -{ - pdev->dev.platform_data = data; -} - #endif /* __PLAT_KEYBOARD_H */ diff --git a/arch/arm/plat-spear/include/plat/system.h b/arch/arm/plat-spear/include/plat/system.h deleted file mode 100644 index 86c6f83b44cc..000000000000 --- a/arch/arm/plat-spear/include/plat/system.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * arch/arm/plat-spear/include/plat/system.h - * - * SPEAr platform specific architecture functions - * - * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar<viresh.kumar@st.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __PLAT_SYSTEM_H -#define __PLAT_SYSTEM_H - -static inline void arch_idle(void) -{ - /* - * This should do all the clock switching - * and wait for interrupt tricks - */ - cpu_do_idle(); -} - -#endif /* __PLAT_SYSTEM_H */ diff --git a/arch/arm/plat-spear/restart.c b/arch/arm/plat-spear/restart.c index 2b4e3d82957c..16f203e78d89 100644 --- a/arch/arm/plat-spear/restart.c +++ b/arch/arm/plat-spear/restart.c @@ -11,6 +11,7 @@ * warranty of any kind, whether express or implied. */ #include <linux/io.h> +#include <asm/system_misc.h> #include <asm/hardware/sp810.h> #include <mach/hardware.h> #include <mach/generic.h> diff --git a/arch/arm/plat-versatile/Kconfig b/arch/arm/plat-versatile/Kconfig index 52353beb369d..043f7b02a9e7 100644 --- a/arch/arm/plat-versatile/Kconfig +++ b/arch/arm/plat-versatile/Kconfig @@ -11,7 +11,6 @@ config PLAT_VERSATILE_LEDS depends on ARCH_REALVIEW || ARCH_VERSATILE config PLAT_VERSATILE_SCHED_CLOCK - def_bool y if !ARCH_INTEGRATOR_AP - select HAVE_SCHED_CLOCK + def_bool y endif diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile index 69714db47c33..a5cb1945bdcc 100644 --- a/arch/arm/plat-versatile/Makefile +++ b/arch/arm/plat-versatile/Makefile @@ -1,5 +1,4 @@ obj-y := clock.o -obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o diff --git a/arch/arm/plat-versatile/localtimer.c b/arch/arm/plat-versatile/localtimer.c deleted file mode 100644 index 0fb3961999b5..000000000000 --- a/arch/arm/plat-versatile/localtimer.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * linux/arch/arm/plat-versatile/localtimer.c - * - * Copyright (C) 2002 ARM Ltd. - * All Rights Reserved - * - * 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 <linux/init.h> -#include <linux/smp.h> -#include <linux/clockchips.h> - -#include <asm/smp_twd.h> -#include <asm/localtimer.h> -#include <mach/irqs.h> - -/* - * Setup the local clock events for a CPU. - */ -int __cpuinit local_timer_setup(struct clock_event_device *evt) -{ - evt->irq = IRQ_LOCALTIMER; - twd_timer_setup(evt); - return 0; -} diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 8f3ccddbdafd..858748eaa144 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -18,7 +18,9 @@ #include <linux/smp.h> #include <linux/init.h> +#include <asm/cp15.h> #include <asm/cputype.h> +#include <asm/system_info.h> #include <asm/thread_notify.h> #include <asm/vfp.h> |